diff options
author | Joseph Myers <joseph@codesourcery.com> | 2009-01-29 11:46:02 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2009-01-29 11:46:02 +0000 |
commit | 17828f45df981ed69e1e9a8eb2e5ec72cd0efbfe (patch) | |
tree | 6924eaa22d60eb7e317c296419743b1cf8c1fd5c /gas/config | |
parent | ec0c103cff45e1e96cc8c97c7989c1d8f6c53d72 (diff) | |
download | gdb-17828f45df981ed69e1e9a8eb2e5ec72cd0efbfe.zip gdb-17828f45df981ed69e1e9a8eb2e5ec72cd0efbfe.tar.gz gdb-17828f45df981ed69e1e9a8eb2e5ec72cd0efbfe.tar.bz2 |
gas:
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.
gas/testsuite:
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.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-arm.c | 39 |
1 files changed, 30 insertions, 9 deletions
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 |