diff options
author | Jim Wilson <jim.wilson@linaro.org> | 2016-12-13 08:35:31 -0800 |
---|---|---|
committer | Jim Wilson <jim.wilson@linaro.org> | 2016-12-13 08:44:31 -0800 |
commit | 963201cf5d29c4dc718b5fb3507e085b302ff896 (patch) | |
tree | 399bbe473e1c5cbd0ea5d16902081b6e8ac82eed /sim | |
parent | 9282b95ab7bfe1cdf471e9dd609ae0ea7bbed925 (diff) | |
download | binutils-963201cf5d29c4dc718b5fb3507e085b302ff896.zip binutils-963201cf5d29c4dc718b5fb3507e085b302ff896.tar.gz binutils-963201cf5d29c4dc718b5fb3507e085b302ff896.tar.bz2 |
Fix aarch64 sim bug with adds64, and add testcases for last 3 bug fixes.
sim/aarch64
* simulator.c (NEG, POS): Move before set_flags_for_add64.
(set_flags_for_add64): Replace with a modified copy of
set_flags_for_sub64.
sim/testsuite/sim/aarch64
* testutils.inc (pass): Move .Lpass to start.
(fail): Move .Lfail to start. Return 1 instead of 0.
(start): Moved .Lpass and .Lfail to here.
* adds.s: New.
* fstur.s: New.
* tbnz.s: New.
Diffstat (limited to 'sim')
-rw-r--r-- | sim/aarch64/ChangeLog | 6 | ||||
-rw-r--r-- | sim/aarch64/simulator.c | 51 | ||||
-rw-r--r-- | sim/testsuite/sim/aarch64/ChangeLog | 9 | ||||
-rw-r--r-- | sim/testsuite/sim/aarch64/adds.s | 81 | ||||
-rw-r--r-- | sim/testsuite/sim/aarch64/fstur.s | 136 | ||||
-rw-r--r-- | sim/testsuite/sim/aarch64/tbnz.s | 55 | ||||
-rw-r--r-- | sim/testsuite/sim/aarch64/testutils.inc | 16 |
7 files changed, 309 insertions, 45 deletions
diff --git a/sim/aarch64/ChangeLog b/sim/aarch64/ChangeLog index 2eca54d..2346a49 100644 --- a/sim/aarch64/ChangeLog +++ b/sim/aarch64/ChangeLog @@ -1,3 +1,9 @@ +2016-12-13 Jim Wilson <jim.wilson@linaro.org> + + * simulator.c (NEG, POS): Move before set_flags_for_add64. + (set_flags_for_add64): Replace with a modified copy of + set_flags_for_sub64. + 2016-12-03 Jim Wilson <jim.wilson@linaro.org> * simulator.c (tbnz, tbz): Cast 1 to uint64_t before shifting. diff --git a/sim/aarch64/simulator.c b/sim/aarch64/simulator.c index 34fd17d..e6406dc 100644 --- a/sim/aarch64/simulator.c +++ b/sim/aarch64/simulator.c @@ -1659,55 +1659,34 @@ set_flags_for_add32 (sim_cpu *cpu, int32_t value1, int32_t value2) aarch64_set_CPSR (cpu, flags); } +#define NEG(a) (((a) & signbit) == signbit) +#define POS(a) (((a) & signbit) == 0) + static void set_flags_for_add64 (sim_cpu *cpu, uint64_t value1, uint64_t value2) { - int64_t sval1 = value1; - int64_t sval2 = value2; - uint64_t result = value1 + value2; - int64_t sresult = sval1 + sval2; - uint32_t flags = 0; + uint64_t result = value1 + value2; + uint32_t flags = 0; + uint64_t signbit = 1ULL << 63; if (result == 0) flags |= Z; - if (result & (1ULL << 63)) + if (NEG (result)) flags |= N; - if (sval1 < 0) - { - if (sval2 < 0) - { - /* Negative plus a negative. Overflow happens if - the result is greater than either of the operands. */ - if (sresult > sval1 || sresult > sval2) - flags |= V; - } - /* else Negative plus a positive. Overflow cannot happen. */ - } - else /* value1 is +ve. */ - { - if (sval2 < 0) - { - /* Overflow can only occur if we computed "0 - MININT". */ - if (sval1 == 0 && sval2 == (1LL << 63)) - flags |= V; - } - else - { - /* Postive plus positive - overflow has happened if the - result is smaller than either of the operands. */ - if (result < value1 || result < value2) - flags |= V | C; - } - } + if ( (NEG (value1) && NEG (value2)) + || (NEG (value1) && POS (result)) + || (NEG (value2) && POS (result))) + flags |= C; + + if ( (NEG (value1) && NEG (value2) && POS (result)) + || (POS (value1) && POS (value2) && NEG (result))) + flags |= V; aarch64_set_CPSR (cpu, flags); } -#define NEG(a) (((a) & signbit) == signbit) -#define POS(a) (((a) & signbit) == 0) - static void set_flags_for_sub32 (sim_cpu *cpu, uint32_t value1, uint32_t value2) { diff --git a/sim/testsuite/sim/aarch64/ChangeLog b/sim/testsuite/sim/aarch64/ChangeLog index 8aacf49..ff047e3 100644 --- a/sim/testsuite/sim/aarch64/ChangeLog +++ b/sim/testsuite/sim/aarch64/ChangeLog @@ -1,3 +1,12 @@ +2016-12-13 Jim Wilson <jim.wilson@linaro.org> + + * testutils.inc (pass): Move .Lpass to start. + (fail): Move .Lfail to start. Return 1 instead of 0. + (start): Moved .Lpass and .Lfail to here. + * adds.s: New. + * fstur.s: New. + * tbnz.s: New. + 2015-11-24 Nick Clifton <nickc@redhat.com> * pass.s, allinsn.exp, testutils.inc: New files. diff --git a/sim/testsuite/sim/aarch64/adds.s b/sim/testsuite/sim/aarch64/adds.s new file mode 100644 index 0000000..2bc240c --- /dev/null +++ b/sim/testsuite/sim/aarch64/adds.s @@ -0,0 +1,81 @@ +# mach: aarch64 + +# Check the basic integer compare instructions: adds, adds64, subs, subs64. +# For add, check value pairs 1 and -1 (Z), -1 and -1 (N), 2 and -1 (C), +# and MIN_INT and -1 (V), +# For sub, negate the second value. + +.include "testutils.inc" + + start + mov w0, #1 + mov w1, #-1 + adds w2, w0, w1 + bne .Lfailure + mov w0, #-1 + mov w1, #-1 + adds w2, w0, w1 + bpl .Lfailure + mov w0, #2 + mov w1, #-1 + adds w2, w0, w1 + bcc .Lfailure + mov w0, #0x80000000 + mov w1, #-1 + adds w2, w0, w1 + bvc .Lfailure + + mov x0, #1 + mov x1, #-1 + adds x2, x0, x1 + bne .Lfailure + mov x0, #-1 + mov x1, #-1 + adds x2, x0, x1 + bpl .Lfailure + mov x0, #2 + mov x1, #-1 + adds x2, x0, x1 + bcc .Lfailure + mov x0, #0x8000000000000000 + mov x1, #-1 + adds x2, x0, x1 + bvc .Lfailure + + mov w0, #1 + mov w1, #1 + subs w2, w0, w1 + bne .Lfailure + mov w0, #-1 + mov w1, #1 + subs w2, w0, w1 + bpl .Lfailure + mov w0, #2 + mov w1, #1 + subs w2, w0, w1 + bcc .Lfailure + mov w0, #0x80000000 + mov w1, #1 + subs w2, w0, w1 + bvc .Lfailure + + mov x0, #1 + mov x1, #1 + subs x2, x0, x1 + bne .Lfailure + mov x0, #-1 + mov x1, #1 + subs x2, x0, x1 + bpl .Lfailure + mov x0, #2 + mov x1, #1 + subs x2, x0, x1 + bcc .Lfailure + mov x0, #0x8000000000000000 + mov x1, #1 + subs x2, x0, x1 + bvc .Lfailure + + pass +.Lfailure: + fail diff --git a/sim/testsuite/sim/aarch64/fstur.s b/sim/testsuite/sim/aarch64/fstur.s new file mode 100644 index 0000000..2206ae5 --- /dev/null +++ b/sim/testsuite/sim/aarch64/fstur.s @@ -0,0 +1,136 @@ +# mach: aarch64 + +# Check the FP store unscaled offset instructions: fsturs, fsturd, fsturq. +# Check the values -1, and XXX_MAX, which tests all bits. +# Check with offsets -256 and 255, which tests all bits. +# Also tests the FP load unscaled offset instructions: fldurs, fldurd, fldurq. + +.include "testutils.inc" + + .data +fm1: + .word 3212836864 +fmax: + .word 2139095039 +ftmp: + .word 0 + +dm1: + .word 0 + .word -1074790400 +dmax: + .word 4294967295 + .word 2146435071 +dtmp: + .word 0 + .word 0 + +ldm1: + .word 0 + .word 0 + .word 0 + .word -1073807360 +ldmax: + .word 4294967295 + .word 4294967295 + .word 4294967295 + .word 2147418111 +ldtmp: + .word 0 + .word 0 + .word 0 + .word 0 + + start + adrp x1, ftmp + add x1, x1, :lo12:ftmp + + adrp x0, fm1 + add x0, x0, :lo12:fm1 + sub x5, x0, #255 + sub x6, x1, #255 + movi d2, #0 + ldur s2, [x5, #255] + stur s2, [x6, #255] + ldr w3, [x0] + ldr w4, [x1] + cmp w3, w4 + bne .Lfailure + + adrp x0, fmax + add x0, x0, :lo12:fmax + add x5, x0, #256 + add x6, x1, #256 + movi d2, #0 + ldur s2, [x5, #-256] + stur s2, [x6, #-256] + ldr w3, [x0] + ldr w4, [x1] + cmp w3, w4 + bne .Lfailure + + adrp x1, dtmp + add x1, x1, :lo12:dtmp + + adrp x0, dm1 + add x0, x0, :lo12:dm1 + sub x5, x0, #255 + sub x6, x1, #255 + movi d2, #0 + ldur d2, [x5, #255] + stur d2, [x6, #255] + ldr x3, [x0] + ldr x4, [x1] + cmp x3, x4 + bne .Lfailure + + adrp x0, dmax + add x0, x0, :lo12:dmax + add x5, x0, #256 + add x6, x1, #256 + movi d2, #0 + ldur d2, [x5, #-256] + stur d2, [x6, #-256] + ldr x3, [x0] + ldr x4, [x1] + cmp x3, x4 + bne .Lfailure + + adrp x1, ldtmp + add x1, x1, :lo12:ldtmp + + adrp x0, ldm1 + add x0, x0, :lo12:ldm1 + sub x5, x0, #255 + sub x6, x1, #255 + movi v2.2d, #0 + ldur q2, [x5, #255] + stur q2, [x6, #255] + ldr x3, [x0] + ldr x4, [x1] + cmp x3, x4 + bne .Lfailure + ldr x3, [x0, 8] + ldr x4, [x1, 8] + cmp x3, x4 + bne .Lfailure + + adrp x0, ldmax + add x0, x0, :lo12:ldmax + add x5, x0, #256 + add x6, x1, #256 + movi v2.2d, #0 + ldur q2, [x5, #-256] + stur q2, [x6, #-256] + ldr x3, [x0] + ldr x4, [x1] + cmp x3, x4 + bne .Lfailure + ldr x3, [x0, 8] + ldr x4, [x1, 8] + cmp x3, x4 + bne .Lfailure + + pass +.Lfailure: + fail diff --git a/sim/testsuite/sim/aarch64/tbnz.s b/sim/testsuite/sim/aarch64/tbnz.s new file mode 100644 index 0000000..2416101 --- /dev/null +++ b/sim/testsuite/sim/aarch64/tbnz.s @@ -0,0 +1,55 @@ +# mach: aarch64 + +# Check the test-bit-and-branch instructions: tbnz, and tbz. +# We check the edge condition bit positions: 0, 1<<31, 1<<32, 1<<63. + +.include "testutils.inc" + + start + mov x0, #1 + tbnz x0, #0, .L1 + fail +.L1: + tbz x0, #0, .Lfailure + mov x0, #0xFFFFFFFFFFFFFFFE + tbnz x0, #0, .Lfailure + tbz x0, #0, .L2 + fail +.L2: + + mov x0, #0x80000000 + tbnz x0, #31, .L3 + fail +.L3: + tbz x0, #31, .Lfailure + mov x0, #0xFFFFFFFF7FFFFFFF + tbnz x0, #31, .Lfailure + tbz x0, #31, .L4 + fail +.L4: + + mov x0, #0x100000000 + tbnz x0, #32, .L5 + fail +.L5: + tbz x0, #32, .Lfailure + mov x0, #0xFFFFFFFEFFFFFFFF + tbnz x0, #32, .Lfailure + tbz x0, #32, .L6 + fail +.L6: + + mov x0, #0x8000000000000000 + tbnz x0, #63, .L7 + fail +.L7: + tbz x0, #63, .Lfailure + mov x0, #0x7FFFFFFFFFFFFFFF + tbnz x0, #63, .Lfailure + tbz x0, #63, .L8 + fail +.L8: + + pass +.Lfailure: + fail diff --git a/sim/testsuite/sim/aarch64/testutils.inc b/sim/testsuite/sim/aarch64/testutils.inc index c8897aa..1fc9bc8 100644 --- a/sim/testsuite/sim/aarch64/testutils.inc +++ b/sim/testsuite/sim/aarch64/testutils.inc @@ -43,10 +43,6 @@ swiwrite 5 exit 0 - - .data -.Lpass: - .asciz "pass\n" .endm # MACRO: fail @@ -56,16 +52,18 @@ adrp x1, .Lfail add x1, x1, :lo12:.Lfail swiwrite 5 - exit 0 - - .data -.Lfail: - .asciz "fail\n" + exit 1 .endm # MACRO: start # All assembler tests should start with a call to "start" .macro start + .data +.Lpass: + .asciz "pass\n" +.Lfail: + .asciz "fail\n" + .text .global _start _start: |