diff options
-rw-r--r-- | gas/ChangeLog | 6 | ||||
-rw-r--r-- | gas/config/tc-arm.c | 39 | ||||
-rw-r--r-- | gas/testsuite/ChangeLog | 11 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/t16-bad.l | 3 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/t16-bad.s | 5 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/thumb2_mul-bad.d | 3 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/thumb2_mul-bad.l | 8 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/thumb2_mul-bad.s | 20 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/thumb2_mul.d | 19 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/thumb2_mul.s | 29 |
10 files changed, 134 insertions, 9 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 200b9e7..4cf7901 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,9 @@ +2009-01-29 Paul Brook <paul@codesourcery.com> + Mark Mitchell <mark@codesourcery.com> + + * config/tc-arm.c (do_t_mul): In Thumb-2 mode, use 16-bit encoding + of MUL when possible. + 2009-01-29 Nick Clifton <nickc@redhat.com> * config/tc-mep.h (DIFF_EXPR_OK): Do not define. diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index e97e0a3..f7bca73 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -9879,24 +9879,35 @@ do_t_msr (void) static void do_t_mul (void) { + bfd_boolean narrow; + if (!inst.operands[2].present) inst.operands[2].reg = inst.operands[0].reg; - /* There is no 32-bit MULS and no 16-bit MUL. */ - if (unified_syntax && inst.instruction == T_MNEM_mul) + if (unified_syntax) { - inst.instruction = THUMB_OP32 (inst.instruction); - inst.instruction |= inst.operands[0].reg << 8; - inst.instruction |= inst.operands[1].reg << 16; - inst.instruction |= inst.operands[2].reg << 0; + if (inst.size_req == 4 + || (inst.operands[0].reg != inst.operands[1].reg + && inst.operands[0].reg != inst.operands[2].reg) + || inst.operands[1].reg > 7 + || inst.operands[2].reg > 7) + narrow = FALSE; + else if (inst.instruction == T_MNEM_muls) + narrow = (current_it_mask == 0); + else + narrow = (current_it_mask != 0); } else { - constraint (!unified_syntax - && inst.instruction == T_MNEM_muls, BAD_THUMB32); - constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7, + constraint (inst.instruction == T_MNEM_muls, BAD_THUMB32); + constraint (inst.operands[1].reg > 7 || inst.operands[2].reg > 7, BAD_HIREG); + narrow = TRUE; + } + if (narrow) + { + /* 16-bit MULS/Conditional MUL. */ inst.instruction = THUMB_OP16 (inst.instruction); inst.instruction |= inst.operands[0].reg; @@ -9907,6 +9918,16 @@ do_t_mul (void) else constraint (1, _("dest must overlap one source register")); } + else + { + constraint(inst.instruction != T_MNEM_mul, + _("Thumb-2 MUL must not set flags")); + /* 32-bit MUL. */ + inst.instruction = THUMB_OP32 (inst.instruction); + inst.instruction |= inst.operands[0].reg << 8; + inst.instruction |= inst.operands[1].reg << 16; + inst.instruction |= inst.operands[2].reg << 0; + } } static void diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index d3d84d9..034ce59 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2009-01-29 Paul Brook <paul@codesourcery.com> + Mark Mitchell <mark@codesourcery.com> + + * gas/arm/thumb2_mul.s: New file. + * gas/arm/thumb2_mul.d: Likewise. + * gas/arm/thumb2_mul-bad.s: Likewise. + * gas/arm/thumb2_mul-bad.d: Likewise. + * gas/arm/thumb2_mul-bad.l: Likewise. + * gas/arm/t16-bad.s: Add tests for"mul" with high registers. + * gas/arm/t16-bad.l: Update accordingly. + 2009-01-29 Nick Clifton <nickc@redhat.com> * gas/all/gas.exp: Expect forward test to fail for MeP. diff --git a/gas/testsuite/gas/arm/t16-bad.l b/gas/testsuite/gas/arm/t16-bad.l index 80cf045..cf224f2 100644 --- a/gas/testsuite/gas/arm/t16-bad.l +++ b/gas/testsuite/gas/arm/t16-bad.l @@ -185,3 +185,6 @@ [^:]*:135: Error: Thumb does not support the 2-argument form of this instruction -- `cpsid ai,#5' [^:]*:138: Error: Thumb does not support conditional execution [^:]*:141: Error: cannot honor width suffix -- `add r0,r1' +[^:]*:145: Error: lo register required -- `mul r0,r0,r8' +[^:]*:146: Error: lo register required -- `mul r0,r8,r0' +[^:]*:147: Error: dest must overlap one source register -- `mul r8,r0,r0' diff --git a/gas/testsuite/gas/arm/t16-bad.s b/gas/testsuite/gas/arm/t16-bad.s index 165413f..9d2ced3 100644 --- a/gas/testsuite/gas/arm/t16-bad.s +++ b/gas/testsuite/gas/arm/t16-bad.s @@ -140,3 +140,8 @@ l: .syntax unified add r0, r1 + @ Multiply + .syntax divided + mul r0, r0, r8 + mul r0, r8, r0 + mul r8, r0, r0 diff --git a/gas/testsuite/gas/arm/thumb2_mul-bad.d b/gas/testsuite/gas/arm/thumb2_mul-bad.d new file mode 100644 index 0000000..c09bf42 --- /dev/null +++ b/gas/testsuite/gas/arm/thumb2_mul-bad.d @@ -0,0 +1,3 @@ +#name: Invalid Thumb-2 multiply instructions +#as: -march=armv6kt2 +#error-output: thumb2_mul-bad.l diff --git a/gas/testsuite/gas/arm/thumb2_mul-bad.l b/gas/testsuite/gas/arm/thumb2_mul-bad.l new file mode 100644 index 0000000..7b7a044 --- /dev/null +++ b/gas/testsuite/gas/arm/thumb2_mul-bad.l @@ -0,0 +1,8 @@ +[^:]*: Assembler messages: +[^:]*:10: Error: cannot honor width suffix -- `muleq.n r0,r0,r8' +[^:]*:12: Error: cannot honor width suffix -- `muleq.n r0,r1,r1' +[^:]*:13: Error: cannot honor width suffix -- `muleq.n r0,r1,r2' +[^:]*:15: Error: Thumb-2 MUL must not set flags -- `mulseq r0,r0,r1' +[^:]*:17: Error: Thumb-2 MUL must not set flags -- `muls.w r0,r0,r1' +[^:]*:19: Error: Thumb-2 MUL must not set flags -- `muls r0,r0,r8' +[^:]*:20: Error: Thumb-2 MUL must not set flags -- `muls r0,r8,r0' diff --git a/gas/testsuite/gas/arm/thumb2_mul-bad.s b/gas/testsuite/gas/arm/thumb2_mul-bad.s new file mode 100644 index 0000000..aa02847 --- /dev/null +++ b/gas/testsuite/gas/arm/thumb2_mul-bad.s @@ -0,0 +1,20 @@ + .syntax unified + .text + .align 2 + .global thumb2_mul + .thumb + .thumb_func +thumb2_mul: + itttt eq + # Cannot use 16-bit encoding because of use of high register. + muleq.n r0, r0, r8 + # Cannot use 16-bit encoding because source does not match destination. + muleq.n r0, r1, r1 + muleq.n r0, r1, r2 + # There is no conditional "muls". + mulseq r0, r0, r1 + # There is no 32-bit "muls". + muls.w r0, r0, r1 + # Cannot use high registers with "muls". + muls r0, r0, r8 + muls r0, r8, r0 diff --git a/gas/testsuite/gas/arm/thumb2_mul.d b/gas/testsuite/gas/arm/thumb2_mul.d new file mode 100644 index 0000000..11943c4 --- /dev/null +++ b/gas/testsuite/gas/arm/thumb2_mul.d @@ -0,0 +1,19 @@ +# as: -march=armv6kt2 +# objdump: -dr --prefix-addresses --show-raw-insn + +.*: +file format .*arm.* + +Disassembly of section .text: +0+000 <[^>]+> bf04 itt eq +0+002 <[^>]+> 4348 muleq r0, r1 +0+004 <[^>]+> 4348 muleq r0, r1 +0+006 <[^>]+> bf02 ittt eq +0+008 <[^>]+> fb00 f008 muleq.w r0, r0, r8 +0+00c <[^>]+> fb08 f000 muleq.w r0, r8, r0 +0+010 <[^>]+> fb00 f808 muleq.w r8, r0, r8 +0+014 <[^>]+> bf04 itt eq +0+016 <[^>]+> fb01 f001 muleq.w r0, r1, r1 +0+01a <[^>]+> fb01 f002 muleq.w r0, r1, r2 +0+01e <[^>]+> bf04 itt eq +0+020 <[^>]+> fb01 f000 muleq.w r0, r1, r0 +0+024 <[^>]+> fb00 f001 muleq.w r0, r0, r1 diff --git a/gas/testsuite/gas/arm/thumb2_mul.s b/gas/testsuite/gas/arm/thumb2_mul.s new file mode 100644 index 0000000..e6d7a65 --- /dev/null +++ b/gas/testsuite/gas/arm/thumb2_mul.s @@ -0,0 +1,29 @@ + .syntax unified + .text + .align 2 + .global thumb2_mul + .thumb + .thumb_func +thumb2_mul: + # These can use the 16-bit encoding. + itt eq + muleq r0, r1, r0 + muleq r0, r0, r1 + # These must use the 32-bit encoding because they involve + # high registers. + ittt eq + muleq r0, r0, r8 + muleq r0, r8, r0 + muleq r8, r0, r8 + # These must use the 32-bit encoding because the source and + # destination do not match. + itt eq + muleq r0, r1, r1 + muleq r0, r1, r2 + # These must use the 32-bit encoding because of the explicit + # suffix. + itt eq + muleq.w r0, r1, r0 + muleq.w r0, r0, r1 + + |