diff options
author | Nick Clifton <nickc@redhat.com> | 2009-06-18 16:36:05 +0000 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2009-06-18 16:36:05 +0000 |
commit | 3a21c15a776c549411131dbb9f26d4e0f9b87d57 (patch) | |
tree | ab7aaa3dedcc05125fc05e15f786c28b140a2df4 /gas/config/tc-arm.c | |
parent | c2e61a4e9360e392834047c62d7ef60eb2d77a40 (diff) | |
download | gdb-3a21c15a776c549411131dbb9f26d4e0f9b87d57.zip gdb-3a21c15a776c549411131dbb9f26d4e0f9b87d57.tar.gz gdb-3a21c15a776c549411131dbb9f26d4e0f9b87d57.tar.bz2 |
PR 10169
* gas/tc-arm.c (do_t_ssat): Move common code from here...
(do_t_usat): ... and here to...
(do_t_ssat_usat): New function: ... here. Add code to check that
the shift value, if present, is in range.
* gas/arm/thumb2_bad_reg.s: Add tests for SSAT and USAT with an
out of range shift.
* gas/arm/thumb2_bad_reg.l: Update expected error messages.
Diffstat (limited to 'gas/config/tc-arm.c')
-rw-r--r-- | gas/config/tc-arm.c | 54 |
1 files changed, 21 insertions, 33 deletions
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 67d8cc9..1190696 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -10654,7 +10654,7 @@ do_t_smc (void) } static void -do_t_ssat (void) +do_t_ssat_usat (int bias) { unsigned Rd, Rn; @@ -10665,24 +10665,37 @@ do_t_ssat (void) reject_bad_reg (Rn); inst.instruction |= Rd << 8; - inst.instruction |= inst.operands[1].imm - 1; + inst.instruction |= inst.operands[1].imm - bias; inst.instruction |= Rn << 16; if (inst.operands[3].present) { + offsetT shift_amount = inst.reloc.exp.X_add_number; + + inst.reloc.type = BFD_RELOC_UNUSED; + constraint (inst.reloc.exp.X_op != O_constant, _("expression too complex")); - if (inst.reloc.exp.X_add_number != 0) + if (shift_amount != 0) { + constraint (shift_amount > 31, + _("shift expression is too large")); + if (inst.operands[3].shift_kind == SHIFT_ASR) - inst.instruction |= 0x00200000; /* sh bit */ - inst.instruction |= (inst.reloc.exp.X_add_number & 0x1c) << 10; - inst.instruction |= (inst.reloc.exp.X_add_number & 0x03) << 6; + inst.instruction |= 0x00200000; /* sh bit. */ + + inst.instruction |= (shift_amount & 0x1c) << 10; + inst.instruction |= (shift_amount & 0x03) << 6; } - inst.reloc.type = BFD_RELOC_UNUSED; } } + +static void +do_t_ssat (void) +{ + do_t_ssat_usat (1); +} static void do_t_ssat16 (void) @@ -10818,32 +10831,7 @@ do_t_tb (void) static void do_t_usat (void) { - unsigned Rd, Rn; - - Rd = inst.operands[0].reg; - Rn = inst.operands[2].reg; - - reject_bad_reg (Rd); - reject_bad_reg (Rn); - - inst.instruction |= Rd << 8; - inst.instruction |= inst.operands[1].imm; - inst.instruction |= Rn << 16; - - if (inst.operands[3].present) - { - constraint (inst.reloc.exp.X_op != O_constant, - _("expression too complex")); - if (inst.reloc.exp.X_add_number != 0) - { - if (inst.operands[3].shift_kind == SHIFT_ASR) - inst.instruction |= 0x00200000; /* sh bit */ - - inst.instruction |= (inst.reloc.exp.X_add_number & 0x1c) << 10; - inst.instruction |= (inst.reloc.exp.X_add_number & 0x03) << 6; - } - inst.reloc.type = BFD_RELOC_UNUSED; - } + do_t_ssat_usat (0); } static void |