aboutsummaryrefslogtreecommitdiff
path: root/gas/config/tc-arm.c
diff options
context:
space:
mode:
authorNick Clifton <nickc@redhat.com>2009-06-18 16:36:05 +0000
committerNick Clifton <nickc@redhat.com>2009-06-18 16:36:05 +0000
commit3a21c15a776c549411131dbb9f26d4e0f9b87d57 (patch)
treeab7aaa3dedcc05125fc05e15f786c28b140a2df4 /gas/config/tc-arm.c
parentc2e61a4e9360e392834047c62d7ef60eb2d77a40 (diff)
downloadgdb-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.c54
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