From ad1ec76feafa1a5a4d22511042f689e55dec3653 Mon Sep 17 00:00:00 2001 From: Paul Brook Date: Wed, 2 May 2007 22:16:21 +0000 Subject: [PATCH] bpabi.S (aeabi_lcmp): Fix result on overflow. 2007-05-02 Paul Brook gcc/ * config/arm/bpabi.S (aeabi_lcmp): Fix result on overflow. gcc/testsuite/ * gcc.dg/arm-eabi1.c: Move debug output. Augment lcmp/ulcmp tests. From-SVN: r124361 --- gcc/ChangeLog | 4 ++ gcc/config/arm/bpabi.S | 17 +++++-- gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.dg/arm-eabi1.c | 82 ++++++++++++++++++++++++++++---- 4 files changed, 94 insertions(+), 13 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9a6552de86c..acc7956c77c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2007-05-02 Paul Brook + + * config/arm/bpabi.S (aeabi_lcmp): Fix result on overflow. + 2007-05-02 Andrew Pinski PR middle-end/29715 diff --git a/gcc/config/arm/bpabi.S b/gcc/config/arm/bpabi.S index c9f6d21c06d..1f083465980 100644 --- a/gcc/config/arm/bpabi.S +++ b/gcc/config/arm/bpabi.S @@ -42,11 +42,18 @@ #ifdef L_aeabi_lcmp ARM_FUNC_START aeabi_lcmp - subs ip, xxl, yyl - sbcs ip, xxh, yyh - do_it eq - COND(sub,s,eq) ip, xxl, yyl - mov r0, ip + cmp xxh, yyh + do_it lt + movlt r0, #-1 + do_it gt + movgt r0, #1 + do_it ne + RETc(ne) + subs r0, xxl, yyl + do_it lo + movlo r0, #-1 + do_it hi + movhi r0, #1 RET FUNC_END aeabi_lcmp diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d2918d77262..ce5e78cbfce 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2007-05-02 Paul Brook + + * gcc.dg/arm-eabi1.c: Move debug output. Augment lcmp/ulcmp tests. + 2007-05-02 Eric Christopher * gcc.dg/cpp/if-div.c: New file. diff --git a/gcc/testsuite/gcc.dg/arm-eabi1.c b/gcc/testsuite/gcc.dg/arm-eabi1.c index 6a8d0e044b1..06af6710299 100644 --- a/gcc/testsuite/gcc.dg/arm-eabi1.c +++ b/gcc/testsuite/gcc.dg/arm-eabi1.c @@ -85,11 +85,11 @@ extern long long __eabi_uwrite8 (long long, void *); type a1; \ type b1; \ \ - fprintf (stderr, "%d: Test %s == %s\n", __LINE__, #a, #b); \ a1 = a; \ b1 = b; \ if (abs (a1 - b1) > epsilon) \ { \ + fprintf (stderr, "%d: Test %s == %s\n", __LINE__, #a, #b); \ fprintf (stderr, "%d: " format " != " format "\n", \ __LINE__, a1, b1); \ abort (); \ @@ -103,9 +103,56 @@ extern long long __eabi_uwrite8 (long long, void *); #define feq(a, b) eq (a, b, float, fabs, fepsilon, "%f") #define deq(a, b) eq (a, b, double, fabs, depsilon, "%g") +#define NUM_CMP_VALUES 6 + +/* Values picked to cover a range of small, large, positive and negative. */ +static unsigned int cmp_val[NUM_CMP_VALUES] = +{ + 0, + 1, + 0x40000000, + 0x80000000, + 0xc0000000, + 0xffffffff +}; + +/* All combinations for each of the above values. */ +#define ulcmp(l, s, m) \ + s, l, l, l, l, l, m, s, l, l, l, l, \ + m, m, s, l, l, l, m, m, m, s, l, l, \ + m, m, m, m, s, l, m, m, m, m, m, s + +#define lcmp(l, s, m) \ + s, l, l, m, m, m, m, s, l, m, m, m, \ + m, m, s, m, m, m, l, l, l, s, l, l, \ + l, l, l, m, s, l, l, l, l, m, m, s + +/* All combinations of the above for high/low words. */ +static int lcmp_results[] = +{ + lcmp(ulcmp(-1, -1, -1), ulcmp(-1, 0, 1), ulcmp(1, 1, 1)) +}; + +static int ulcmp_results[] = +{ + ulcmp(ulcmp(-1, -1, -1), ulcmp(-1, 0, 1), ulcmp(1, 1, 1)) +}; + +static int signof(int i) +{ + if (i < 0) + return -1; + + if (i == 0) + return 0; + + return 1; +} + int main () { unsigned char bytes[256]; - int i; + int i, j, k, n; + int *result; /* Table 2. Double-precision floating-point arithmetic. */ deq (__aeabi_dadd (dzero, done), done); @@ -234,12 +281,31 @@ int main () { leq (__aeabi_llsl (2LL, 1), 4LL); leq (__aeabi_llsr (-1LL, 63), 1); leq (__aeabi_lasr (-1LL, 63), -1); - ieq (__aeabi_lcmp (0LL, 1LL), -1); - ieq (__aeabi_lcmp (0LL, 0LL), 0); - ieq (__aeabi_lcmp (1LL, 0LL), 1); - ieq (__aeabi_ulcmp (0LL, 1LL), -1); - ieq (__aeabi_ulcmp (0LL, 0LL), 0); - ieq (__aeabi_ulcmp (1LL, 0LL), 1); + + result = lcmp_results; + for (i = 0; i < NUM_CMP_VALUES; i++) + for (j = 0; j < NUM_CMP_VALUES; j++) + for (k = 0; k < NUM_CMP_VALUES; k++) + for (n = 0; n < NUM_CMP_VALUES; n++) + { + ieq (signof (__aeabi_lcmp + (((long long)cmp_val[i] << 32) | cmp_val[k], + ((long long)cmp_val[j] << 32) | cmp_val[n])), + *result); + result++; + } + result = ulcmp_results; + for (i = 0; i < NUM_CMP_VALUES; i++) + for (j = 0; j < NUM_CMP_VALUES; j++) + for (k = 0; k < NUM_CMP_VALUES; k++) + for (n = 0; n < NUM_CMP_VALUES; n++) + { + ieq (signof (__aeabi_ulcmp + (((long long)cmp_val[i] << 32) | cmp_val[k], + ((long long)cmp_val[j] << 32) | cmp_val[n])), + *result); + result++; + } ieq (__aeabi_idiv (-550, 11), -50); ueq (__aeabi_uidiv (4000000000U, 1000000U), 4000U); -- 2.30.2