From 17828f45df981ed69e1e9a8eb2e5ec72cd0efbfe Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Thu, 29 Jan 2009 11:46:02 +0000 Subject: [PATCH] gas: 2009-01-29 Paul Brook Mark Mitchell * config/tc-arm.c (do_t_mul): In Thumb-2 mode, use 16-bit encoding of MUL when possible. gas/testsuite: 2009-01-29 Paul Brook Mark Mitchell * 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. --- gas/ChangeLog | 6 ++++ gas/config/tc-arm.c | 39 ++++++++++++++++++++------ gas/testsuite/ChangeLog | 11 ++++++++ gas/testsuite/gas/arm/t16-bad.l | 3 ++ gas/testsuite/gas/arm/t16-bad.s | 5 ++++ gas/testsuite/gas/arm/thumb2_mul-bad.d | 3 ++ gas/testsuite/gas/arm/thumb2_mul-bad.l | 8 ++++++ gas/testsuite/gas/arm/thumb2_mul-bad.s | 20 +++++++++++++ gas/testsuite/gas/arm/thumb2_mul.d | 19 +++++++++++++ gas/testsuite/gas/arm/thumb2_mul.s | 29 +++++++++++++++++++ 10 files changed, 134 insertions(+), 9 deletions(-) create mode 100644 gas/testsuite/gas/arm/thumb2_mul-bad.d create mode 100644 gas/testsuite/gas/arm/thumb2_mul-bad.l create mode 100644 gas/testsuite/gas/arm/thumb2_mul-bad.s create mode 100644 gas/testsuite/gas/arm/thumb2_mul.d create mode 100644 gas/testsuite/gas/arm/thumb2_mul.s diff --git a/gas/ChangeLog b/gas/ChangeLog index 200b9e7faae..4cf790177ec 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,9 @@ +2009-01-29 Paul Brook + Mark Mitchell + + * config/tc-arm.c (do_t_mul): In Thumb-2 mode, use 16-bit encoding + of MUL when possible. + 2009-01-29 Nick Clifton * 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 e97e0a3c697..f7bca73c64b 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 d3d84d90c94..034ce59aedc 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,14 @@ +2009-01-29 Paul Brook + Mark Mitchell + + * 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 * 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 80cf045ba1e..cf224f285b2 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 165413f18fe..9d2ced3ca3d 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 00000000000..c09bf428441 --- /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 00000000000..7b7a04483a3 --- /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 00000000000..aa02847a46c --- /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 00000000000..11943c48576 --- /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 00000000000..e6d7a653e19 --- /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 + + -- 2.30.2