aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorPaul Brook <paul@codesourcery.com>2005-07-29 17:28:33 +0000
committerPaul Brook <paul@codesourcery.com>2005-07-29 17:28:33 +0000
commit92e90b6eb3b2c77ecc6b93fe96f0896b24039ec2 (patch)
treec9de5afa742e0bd95d6056789c136d85e1a6d16c /gas
parent0facbdf5c2ef772b4c43b7041b72e32c8210eab9 (diff)
downloadgdb-92e90b6eb3b2c77ecc6b93fe96f0896b24039ec2.zip
gdb-92e90b6eb3b2c77ecc6b93fe96f0896b24039ec2.tar.gz
gdb-92e90b6eb3b2c77ecc6b93fe96f0896b24039ec2.tar.bz2
2005-07-29 Paul Brook <paul@codesourcery.com>
bfd/ * reloc.c (BFD_RELOC_ARM_T32_IMM12): Add. * bfd-in2.h: Regeenrate. * libbfd.h: Regenerate. gas/ * config/tc-arm.c (parse_tb): New function. (enum operand_parse_code): Add OP_TB. (parse_operands): Handle OP_TB. (do_t_add_sub_w, do_t_tb): New functions. (insns): Add entries for addw, subw, tbb and tbh. (md_apply_fix): Handle BFD_RELOC_ARM_T32_IMM12. gas/testsuite/ * gas/arm/thumb32.s: Add tests for addw, subw, tbb and tbh. * gas/arm/thumb32.d: Ditto. opcodes/ * arm-dis.c (thumb32_opc): Fix addressing mode for tbh. (print_insn_thumb32): Fix decoding of thumb2 'I' operands.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog9
-rw-r--r--gas/config/tc-arm.c103
-rw-r--r--gas/testsuite/ChangeLog5
-rw-r--r--gas/testsuite/gas/arm/thumb32.d8
-rw-r--r--gas/testsuite/gas/arm/thumb32.s8
5 files changed, 132 insertions, 1 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 5bdaec6..0e0b516 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,12 @@
+2005-07-29 Paul Brook <paul@codesourcery.com>
+
+ * config/tc-arm.c (parse_tb): New function.
+ (enum operand_parse_code): Add OP_TB.
+ (parse_operands): Handle OP_TB.
+ (do_t_add_sub_w, do_t_tb): New functions.
+ (insns): Add entries for addw, subw, tbb and tbh.
+ (md_apply_fix): Handle BFD_RELOC_ARM_T32_IMM12.
+
2005-07-29 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com>
* config/tc-m32r.c (m32r_check_fixup): Fixed X_op check.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 0c9911f..12b4add 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -3491,6 +3491,55 @@ parse_cond (char **str)
return c->value;
}
+/* Parse the operands of a table branch instruction. Similar to a memory
+ operand. */
+static int
+parse_tb (char **str)
+{
+ char * p = *str;
+ int reg;
+
+ if (skip_past_char (&p, '[') == FAIL)
+ return FAIL;
+
+ if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
+ {
+ inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
+ return FAIL;
+ }
+ inst.operands[0].reg = reg;
+
+ if (skip_past_comma (&p) == FAIL)
+ return FAIL;
+
+ if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
+ {
+ inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
+ return FAIL;
+ }
+ inst.operands[0].imm = reg;
+
+ if (skip_past_comma (&p) == SUCCESS)
+ {
+ if (parse_shift (&p, 0, SHIFT_LSL_IMMEDIATE) == FAIL)
+ return FAIL;
+ if (inst.reloc.exp.X_add_number != 1)
+ {
+ inst.error = _("invalid shift");
+ return FAIL;
+ }
+ inst.operands[0].shifted = 1;
+ }
+
+ if (skip_past_char (&p, ']') == FAIL)
+ {
+ inst.error = _("']' expected");
+ return FAIL;
+ }
+ *str = p;
+ return SUCCESS;
+}
+
/* Matcher codes for parse_operands. */
enum operand_parse_code
{
@@ -3546,6 +3595,7 @@ enum operand_parse_code
OP_ENDI, /* Endianness specifier */
OP_PSR, /* CPSR/SPSR mask for msr */
OP_COND, /* conditional code */
+ OP_TB, /* Table branch. */
OP_RRnpc_I0, /* ARM register or literal 0 */
OP_RR_EXr, /* ARM register or expression with opt. reloc suff. */
@@ -3787,6 +3837,10 @@ parse_operands (char *str, const unsigned char *pattern)
case OP_PSR: val = parse_psr (&str); break;
case OP_COND: val = parse_cond (&str); break;
+ case OP_TB:
+ po_misc_or_fail (parse_tb (&str));
+ break;
+
/* Register lists */
case OP_REGLST:
val = parse_reg_list (&str);
@@ -5774,6 +5828,20 @@ static const unsigned int thumb_op32[] = { T16_32_TAB };
/* Thumb instruction encoders, in alphabetical order. */
+/* ADDW or SUBW. */
+static void
+do_t_add_sub_w (void)
+{
+ int Rd, Rn;
+
+ Rd = inst.operands[0].reg;
+ Rn = inst.operands[1].reg;
+
+ constraint (Rd == 15, _("PC not allowed as destination"));
+ inst.instruction |= (Rn << 16) | (Rd << 8);
+ inst.reloc.type = BFD_RELOC_ARM_T32_IMM12;
+}
+
/* Parse an add or subtract instruction. We get here with inst.instruction
equalling any of THUMB_OPCODE_add, adds, sub, or subs. */
@@ -7224,6 +7292,21 @@ do_t_swi (void)
}
static void
+do_t_tb (void)
+{
+ int half;
+
+ half = (inst.instruction & 0x10) != 0;
+ constraint (inst.operands[0].imm == 15,
+ _("PC is not a valid index register"));
+ constraint (!half && inst.operands[0].shifted,
+ _("instruction does not allow shifted index"));
+ constraint (half && !inst.operands[0].shifted,
+ _("instruction requires shifted index"));
+ inst.instruction |= (inst.operands[0].reg << 16) | inst.operands[0].imm;
+}
+
+static void
do_t_usat (void)
{
inst.instruction |= inst.operands[0].reg << 8;
@@ -8464,6 +8547,15 @@ static const struct asm_opcode insns[] =
TUE(ittee, 0, bf09, 1, (COND), it, t_it),
TUE(iteee, 0, bf01, 1, (COND), it, t_it),
+ /* Thumb2 only instructions. */
+#undef ARM_VARIANT
+#define ARM_VARIANT 0
+
+ TCE(addw, 0, f2000000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
+ TCE(subw, 0, f2a00000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
+ TCE(tbb, 0, e8d0f000, 1, (TB), 0, t_tb),
+ TCE(tbh, 0, e8d0f010, 1, (TB), 0, t_tb),
+
#undef ARM_VARIANT
#define ARM_VARIANT FPU_FPA_EXT_V1 /* Core FPA instruction set (V1). */
CE(wfs, e200110, 1, (RR), rd),
@@ -10439,6 +10531,7 @@ md_apply_fix (fixS * fixP,
break;
case BFD_RELOC_ARM_T32_IMMEDIATE:
+ case BFD_RELOC_ARM_T32_IMM12:
/* We claim that this fixup has been processed here,
even if in fact we generate an error because we do
not have a reloc for it, so tc_gen_reloc will reject it. */
@@ -10457,7 +10550,15 @@ md_apply_fix (fixS * fixP,
newval <<= 16;
newval |= md_chars_to_number (buf+2, THUMB_SIZE);
- newimm = encode_thumb32_immediate (value);
+ if (fixP->fx_r_type == BFD_RELOC_ARM_T32_IMM12)
+ {
+ if (value > 0xfff)
+ newimm = (unsigned int) FAIL;
+ else
+ newimm = value;
+ }
+ else
+ newimm = encode_thumb32_immediate (value);
/* FUTURE: Implement analogue of negate_data_op for T32. */
if (newimm == (unsigned int)FAIL)
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index a1183a8..3638c67 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2005-07-29 Paul Brook <paul@codesourcery.com>
+
+ * gas/arm/thumb32.s: Add tests for addw, subw, tbb and tbh.
+ * gas/arm/thumb32.d: Ditto.
+
2005-07-27 Jan Beulich <jbeulich@novell.com>
* gas/ia64/unwind-bad.l: Uncomment patterns matching new warnings.
diff --git a/gas/testsuite/gas/arm/thumb32.d b/gas/testsuite/gas/arm/thumb32.d
index a74253e..530ec0b 100644
--- a/gas/testsuite/gas/arm/thumb32.d
+++ b/gas/testsuite/gas/arm/thumb32.d
@@ -1011,3 +1011,11 @@ Disassembly of section .text:
0+cf4 <[^>]+> f8df 1155 ldr\.w r1, \[pc, #341\] ; 0+e4d <[^>]+>
0+cf8 <[^>]+> f85f 12aa ldr\.w r1, \[pc, #-682\] ; 0+a52 <[^>]+>
0+cfc <[^>]+> f85f 1155 ldr\.w r1, \[pc, #-341\] ; 0+bab <[^>]+>
+0+d00 <[^>]+> f200 0900 addw r9, r0, #0 ; 0x0
+0+d04 <[^>]+> f60f 76ff addw r6, pc, #4095 ; 0xfff
+0+d08 <[^>]+> f6a9 2685 subw r6, r9, #2693 ; 0xa85
+0+d0c <[^>]+> f2a9 567a subw r6, r9, #1402 ; 0x57a
+0+d10 <[^>]+> e8df f006 tbb \[pc, r6\]
+0+d14 <[^>]+> e8d0 f009 tbb \[r0, r9\]
+0+d18 <[^>]+> e8df f017 tbh \[pc, r7, lsl #1\]
+0+d1c <[^>]+> e8d0 f018 tbh \[r0, r8, lsl #1\]
diff --git a/gas/testsuite/gas/arm/thumb32.s b/gas/testsuite/gas/arm/thumb32.s
index 4baf4ff..096b445 100644
--- a/gas/testsuite/gas/arm/thumb32.s
+++ b/gas/testsuite/gas/arm/thumb32.s
@@ -745,3 +745,11 @@ xta:
ldpcimm ldrh
ldpcimm ldrsh
ldpcimm ldr
+ addw r9, r0, #0
+ addw r6, pc, #0xfff
+ subw r6, r9, #0xa85
+ subw r6, r9, #0x57a
+ tbb [pc, r6]
+ tbb [r0, r9]
+ tbh [pc, r7, lsl #1]
+ tbh [r0, r8, lsl #1]