aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog11
-rw-r--r--gas/config/tc-arm.c85
-rw-r--r--gas/testsuite/ChangeLog6
-rw-r--r--gas/testsuite/gas/arm/thumb32.d78
-rw-r--r--gas/testsuite/gas/arm/thumb32.s3
5 files changed, 120 insertions, 63 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 0e0b516..1d7eb05 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,5 +1,16 @@
2005-07-29 Paul Brook <paul@codesourcery.com>
+ * config/tc-arm.c (T16_32_TAB): Add "addr". Fix encoding of push and
+ pop.
+ (do_t_addr): Implement 32-bit variant.
+ (do_t_push_pop): Make some errors warnings. Handle single register
+ 32-bit case.
+ (insns): Use tCE for adr.
+ (md_pcrel_from_section): Handle BFD_RELOC_ARM_T32_ADD_PC12.
+ (md_apply_fix): Ditto.
+
+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.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 12b4add..754bc4c 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -5748,6 +5748,7 @@ encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
X(adcs, 4140, eb500000), \
X(add, 1c00, eb000000), \
X(adds, 1c00, eb100000), \
+ X(adr, 000f, f20f0000), \
X(and, 4000, ea000000), \
X(ands, 4000, ea100000), \
X(asr, 1000, fa40f000), \
@@ -5781,8 +5782,8 @@ encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
X(negs, 4240, f1d00000), /* rsbs #0 */ \
X(orr, 4300, ea400000), \
X(orrs, 4300, ea500000), \
- X(pop, bc00, e8ad0000), /* ldmia sp!,... */ \
- X(push, b400, e8bd0000), /* stmia sp!,... */ \
+ X(pop, bc00, e8bd0000), /* ldmia sp!,... */ \
+ X(push, b400, e92d0000), /* stmdb sp!,... */ \
X(rev, ba00, fa90f080), \
X(rev16, ba40, fa90f090), \
X(revsh, bac0, fa90f0b0), \
@@ -5963,11 +5964,24 @@ do_t_add_sub (void)
static void
do_t_adr (void)
{
- inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
- inst.reloc.exp.X_add_number -= 4; /* PC relative adjust. */
- inst.reloc.pc_rel = 1;
+ if (unified_syntax && inst.size_req != 2)
+ {
+ /* Always generate a 32-bit opcode;
+ section relaxation will shrink it later if possible. */
+ inst.instruction = THUMB_OP32 (inst.instruction);
+ inst.instruction |= inst.operands[0].reg << 8;
+ inst.reloc.type = BFD_RELOC_ARM_T32_ADD_PC12;
+ inst.reloc.pc_rel = 1;
+ }
+ else
+ {
+ inst.instruction = THUMB_OP16 (inst.instruction);
+ inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
+ inst.reloc.exp.X_add_number -= 4; /* PC relative adjust. */
+ inst.reloc.pc_rel = 1;
- inst.instruction |= inst.operands[0].reg << 4;
+ inst.instruction |= inst.operands[0].reg << 4;
+ }
}
/* Arithmetic instructions for which there is just one 16-bit
@@ -6948,39 +6962,52 @@ do_t_pld (void)
static void
do_t_push_pop (void)
{
+ unsigned mask;
+
constraint (inst.operands[0].writeback,
_("push/pop do not support {reglist}^"));
constraint (inst.reloc.type != BFD_RELOC_UNUSED,
_("expression too complex"));
- if ((inst.operands[0].imm & ~0xff) == 0)
+ mask = inst.operands[0].imm;
+ if ((mask & ~0xff) == 0)
inst.instruction = THUMB_OP16 (inst.instruction);
else if ((inst.instruction == T_MNEM_push
- && (inst.operands[0].imm & ~0xff) == 1 << REG_LR)
+ && (mask & ~0xff) == 1 << REG_LR)
|| (inst.instruction == T_MNEM_pop
- && (inst.operands[0].imm & ~0xff) == 1 << REG_PC))
+ && (mask & ~0xff) == 1 << REG_PC))
{
inst.instruction = THUMB_OP16 (inst.instruction);
inst.instruction |= THUMB_PP_PC_LR;
- inst.operands[0].imm &= 0xff;
+ mask &= 0xff;
}
else if (unified_syntax)
{
- if (inst.operands[1].imm & (1 << 13))
- as_warn (_("SP should not be in register list"));
+ if (mask & (1 << 13))
+ inst.error = _("SP not allowed in register list");
if (inst.instruction == T_MNEM_push)
{
- if (inst.operands[1].imm & (1 << 15))
- as_warn (_("PC should not be in register list"));
+ if (mask & (1 << 15))
+ inst.error = _("PC not allowed in register list");
}
else
{
- if (inst.operands[1].imm & (1 << 14)
- && inst.operands[1].imm & (1 << 15))
- as_warn (_("LR and PC should not both be in register list"));
+ if (mask & (1 << 14)
+ && mask & (1 << 15))
+ inst.error = _("LR and PC should not both be in register list");
}
-
- inst.instruction = THUMB_OP32 (inst.instruction);
+ if ((mask & (mask - 1)) == 0)
+ {
+ /* Single register push/pop implemented as str/ldr. */
+ if (inst.instruction == T_MNEM_push)
+ inst.instruction = 0xf84d0d04; /* str reg, [sp, #-4]! */
+ else
+ inst.instruction = 0xf85d0b04; /* ldr reg, [sp], #4 */
+ mask = ffs(mask) - 1;
+ mask <<= 12;
+ }
+ else
+ inst.instruction = THUMB_OP32 (inst.instruction);
}
else
{
@@ -6988,7 +7015,7 @@ do_t_push_pop (void)
return;
}
- inst.instruction |= inst.operands[0].imm;
+ inst.instruction |= mask;
}
static void
@@ -8205,7 +8232,7 @@ static const struct asm_opcode insns[] =
TCE(bl, b000000, f000f800, 1, (EXPr), branch, t_branch23),
/* Pseudo ops. */
- TCE(adr, 28f0000, 000f, 2, (RR, EXP), adr, t_adr),
+ tCE(adr, 28f0000, adr, 2, (RR, EXP), adr, t_adr),
C3(adrl, 28f0000, 2, (RR, EXP), adrl),
tCE(nop, 1a00000, nop, 1, (oI255c), nop, t_nop),
@@ -10010,6 +10037,7 @@ md_pcrel_from_section (fixS * fixP, segT seg)
case BFD_RELOC_ARM_THUMB_OFFSET:
case BFD_RELOC_ARM_T32_OFFSET_IMM:
+ case BFD_RELOC_ARM_T32_ADD_PC12:
return (base + 4) & ~3;
/* Thumb branches are simply offset by +4. */
@@ -10532,6 +10560,7 @@ md_apply_fix (fixS * fixP,
case BFD_RELOC_ARM_T32_IMMEDIATE:
case BFD_RELOC_ARM_T32_IMM12:
+ case BFD_RELOC_ARM_T32_ADD_PC12:
/* 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. */
@@ -10550,17 +10579,23 @@ md_apply_fix (fixS * fixP,
newval <<= 16;
newval |= md_chars_to_number (buf+2, THUMB_SIZE);
- if (fixP->fx_r_type == BFD_RELOC_ARM_T32_IMM12)
+ /* FUTURE: Implement analogue of negate_data_op for T32. */
+ if (fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE)
+ newimm = encode_thumb32_immediate (value);
+ else
{
+ /* 12 bit immediate for addw/subw. */
+ if (value < 0)
+ {
+ value = -value;
+ newval ^= 0x00a00000;
+ }
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)
{
as_bad_where (fixP->fx_file, fixP->fx_line,
diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog
index 3638c67..579441c 100644
--- a/gas/testsuite/ChangeLog
+++ b/gas/testsuite/ChangeLog
@@ -1,5 +1,11 @@
2005-07-29 Paul Brook <paul@codesourcery.com>
+ * gas/arm/thumb32.d: Fix expected output for writeback addressing
+ modes. Add single high reg push/pop test.
+ * gas/asm/thumb32.s: Add single high reg push/pop test.
+
+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.
diff --git a/gas/testsuite/gas/arm/thumb32.d b/gas/testsuite/gas/arm/thumb32.d
index 530ec0b..a2758b2 100644
--- a/gas/testsuite/gas/arm/thumb32.d
+++ b/gas/testsuite/gas/arm/thumb32.d
@@ -500,10 +500,10 @@ Disassembly of section .text:
0+59a <[^>]+> f895 1000 ldrb\.w r1, \[r5\]
0+59e <[^>]+> f895 1330 ldrb\.w r1, \[r5, #816\]
0+5a2 <[^>]+> f815 1c30 ldrb\.w r1, \[r5, #-48\]
-0+5a6 <[^>]+> f815 1b30 ldrb\.w r1, \[r5, #48\]!
-0+5aa <[^>]+> f815 1930 ldrb\.w r1, \[r5, #-48\]!
-0+5ae <[^>]+> f815 1f30 ldrb\.w r1, \[r5\], #48
-0+5b2 <[^>]+> f815 1d30 ldrb\.w r1, \[r5\], #-48
+0+5a6 <[^>]+> f815 1b30 ldrb\.w r1, \[r5\], #48
+0+5aa <[^>]+> f815 1930 ldrb\.w r1, \[r5\], #-48
+0+5ae <[^>]+> f815 1f30 ldrb\.w r1, \[r5, #48\]!
+0+5b2 <[^>]+> f815 1d30 ldrb\.w r1, \[r5, #-48\]!
0+5b6 <[^>]+> 5d29 ldrb r1, \[r5, r4\]
0+5b8 <[^>]+> f819 100c ldrb\.w r1, \[r9, ip\]
0+5bc <[^>]+> f89f 10ac ldrb\.w r1, \[pc, #172\] ; 0+66c <[^>]+>
@@ -511,10 +511,10 @@ Disassembly of section .text:
0+5c4 <[^>]+> f995 1000 ldrsb\.w r1, \[r5\]
0+5c8 <[^>]+> f995 1330 ldrsb\.w r1, \[r5, #816\]
0+5cc <[^>]+> f915 1c30 ldrsb\.w r1, \[r5, #-48\]
-0+5d0 <[^>]+> f915 1b30 ldrsb\.w r1, \[r5, #48\]!
-0+5d4 <[^>]+> f915 1930 ldrsb\.w r1, \[r5, #-48\]!
-0+5d8 <[^>]+> f915 1f30 ldrsb\.w r1, \[r5\], #48
-0+5dc <[^>]+> f915 1d30 ldrsb\.w r1, \[r5\], #-48
+0+5d0 <[^>]+> f915 1b30 ldrsb\.w r1, \[r5\], #48
+0+5d4 <[^>]+> f915 1930 ldrsb\.w r1, \[r5\], #-48
+0+5d8 <[^>]+> f915 1f30 ldrsb\.w r1, \[r5, #48\]!
+0+5dc <[^>]+> f915 1d30 ldrsb\.w r1, \[r5, #-48\]!
0+5e0 <[^>]+> 5729 ldrsb r1, \[r5, r4\]
0+5e2 <[^>]+> f919 100c ldrsb\.w r1, \[r9, ip\]
0+5e6 <[^>]+> f99f 1084 ldrsb\.w r1, \[pc, #132\] ; 0+66c <[^>]+>
@@ -522,10 +522,10 @@ Disassembly of section .text:
0+5ee <[^>]+> f8b5 1000 ldrh\.w r1, \[r5\]
0+5f2 <[^>]+> f8b5 1330 ldrh\.w r1, \[r5, #816\]
0+5f6 <[^>]+> f835 1c30 ldrh\.w r1, \[r5, #-48\]
-0+5fa <[^>]+> f835 1b30 ldrh\.w r1, \[r5, #48\]!
-0+5fe <[^>]+> f835 1930 ldrh\.w r1, \[r5, #-48\]!
-0+602 <[^>]+> f835 1f30 ldrh\.w r1, \[r5\], #48
-0+606 <[^>]+> f835 1d30 ldrh\.w r1, \[r5\], #-48
+0+5fa <[^>]+> f835 1b30 ldrh\.w r1, \[r5\], #48
+0+5fe <[^>]+> f835 1930 ldrh\.w r1, \[r5\], #-48
+0+602 <[^>]+> f835 1f30 ldrh\.w r1, \[r5, #48\]!
+0+606 <[^>]+> f835 1d30 ldrh\.w r1, \[r5, #-48\]!
0+60a <[^>]+> 5b29 ldrh r1, \[r5, r4\]
0+60c <[^>]+> f839 100c ldrh\.w r1, \[r9, ip\]
0+610 <[^>]+> f8bf 1058 ldrh\.w r1, \[pc, #88\] ; 0+66c <[^>]+>
@@ -533,10 +533,10 @@ Disassembly of section .text:
0+618 <[^>]+> f9b5 1000 ldrsh\.w r1, \[r5\]
0+61c <[^>]+> f9b5 1330 ldrsh\.w r1, \[r5, #816\]
0+620 <[^>]+> f935 1c30 ldrsh\.w r1, \[r5, #-48\]
-0+624 <[^>]+> f935 1b30 ldrsh\.w r1, \[r5, #48\]!
-0+628 <[^>]+> f935 1930 ldrsh\.w r1, \[r5, #-48\]!
-0+62c <[^>]+> f935 1f30 ldrsh\.w r1, \[r5\], #48
-0+630 <[^>]+> f935 1d30 ldrsh\.w r1, \[r5\], #-48
+0+624 <[^>]+> f935 1b30 ldrsh\.w r1, \[r5\], #48
+0+628 <[^>]+> f935 1930 ldrsh\.w r1, \[r5\], #-48
+0+62c <[^>]+> f935 1f30 ldrsh\.w r1, \[r5, #48\]!
+0+630 <[^>]+> f935 1d30 ldrsh\.w r1, \[r5, #-48\]!
0+634 <[^>]+> 5f29 ldrsh r1, \[r5, r4\]
0+636 <[^>]+> f939 100c ldrsh\.w r1, \[r9, ip\]
0+63a <[^>]+> f9bf 1030 ldrsh\.w r1, \[pc, #48\] ; 0+66c <[^>]+>
@@ -544,10 +544,10 @@ Disassembly of section .text:
0+642 <[^>]+> f8d5 1000 ldr\.w r1, \[r5\]
0+646 <[^>]+> f8d5 1330 ldr\.w r1, \[r5, #816\]
0+64a <[^>]+> f855 1c30 ldr\.w r1, \[r5, #-48\]
-0+64e <[^>]+> f855 1b30 ldr\.w r1, \[r5, #48\]!
-0+652 <[^>]+> f855 1930 ldr\.w r1, \[r5, #-48\]!
-0+656 <[^>]+> f855 1f30 ldr\.w r1, \[r5\], #48
-0+65a <[^>]+> f855 1d30 ldr\.w r1, \[r5\], #-48
+0+64e <[^>]+> f855 1b30 ldr\.w r1, \[r5\], #48
+0+652 <[^>]+> f855 1930 ldr\.w r1, \[r5\], #-48
+0+656 <[^>]+> f855 1f30 ldr\.w r1, \[r5, #48\]!
+0+65a <[^>]+> f855 1d30 ldr\.w r1, \[r5, #-48\]!
0+65e <[^>]+> 5929 ldr r1, \[r5, r4\]
0+660 <[^>]+> f859 100c ldr\.w r1, \[r9, ip\]
0+664 <[^>]+> f8df 1004 ldr\.w r1, \[pc, #4\] ; 0+66c <[^>]+>
@@ -555,10 +555,10 @@ Disassembly of section .text:
0+66c <[^>]+> f885 1000 strb\.w r1, \[r5\]
0+670 <[^>]+> f885 1330 strb\.w r1, \[r5, #816\]
0+674 <[^>]+> f805 1c30 strb\.w r1, \[r5, #-48\]
-0+678 <[^>]+> f805 1b30 strb\.w r1, \[r5, #48\]!
-0+67c <[^>]+> f805 1930 strb\.w r1, \[r5, #-48\]!
-0+680 <[^>]+> f805 1f30 strb\.w r1, \[r5\], #48
-0+684 <[^>]+> f805 1d30 strb\.w r1, \[r5\], #-48
+0+678 <[^>]+> f805 1b30 strb\.w r1, \[r5\], #48
+0+67c <[^>]+> f805 1930 strb\.w r1, \[r5\], #-48
+0+680 <[^>]+> f805 1f30 strb\.w r1, \[r5, #48\]!
+0+684 <[^>]+> f805 1d30 strb\.w r1, \[r5, #-48\]!
0+688 <[^>]+> 5529 strb r1, \[r5, r4\]
0+68a <[^>]+> f809 100c strb\.w r1, \[r9, ip\]
0+68e <[^>]+> f88f 1086 strb\.w r1, \[pc, #134\] ; 0+716 <[^>]+>
@@ -566,10 +566,10 @@ Disassembly of section .text:
0+696 <[^>]+> f8a5 1000 strh\.w r1, \[r5\]
0+69a <[^>]+> f8a5 1330 strh\.w r1, \[r5, #816\]
0+69e <[^>]+> f825 1c30 strh\.w r1, \[r5, #-48\]
-0+6a2 <[^>]+> f825 1b30 strh\.w r1, \[r5, #48\]!
-0+6a6 <[^>]+> f825 1930 strh\.w r1, \[r5, #-48\]!
-0+6aa <[^>]+> f825 1f30 strh\.w r1, \[r5\], #48
-0+6ae <[^>]+> f825 1d30 strh\.w r1, \[r5\], #-48
+0+6a2 <[^>]+> f825 1b30 strh\.w r1, \[r5\], #48
+0+6a6 <[^>]+> f825 1930 strh\.w r1, \[r5\], #-48
+0+6aa <[^>]+> f825 1f30 strh\.w r1, \[r5, #48\]!
+0+6ae <[^>]+> f825 1d30 strh\.w r1, \[r5, #-48\]!
0+6b2 <[^>]+> 5329 strh r1, \[r5, r4\]
0+6b4 <[^>]+> f829 100c strh\.w r1, \[r9, ip\]
0+6b8 <[^>]+> f8af 105a strh\.w r1, \[pc, #90\] ; 0+716 <[^>]+>
@@ -577,10 +577,10 @@ Disassembly of section .text:
0+6c0 <[^>]+> f8c5 1000 str\.w r1, \[r5\]
0+6c4 <[^>]+> f8c5 1330 str\.w r1, \[r5, #816\]
0+6c8 <[^>]+> f845 1c30 str\.w r1, \[r5, #-48\]
-0+6cc <[^>]+> f845 1b30 str\.w r1, \[r5, #48\]!
-0+6d0 <[^>]+> f845 1930 str\.w r1, \[r5, #-48\]!
-0+6d4 <[^>]+> f845 1f30 str\.w r1, \[r5\], #48
-0+6d8 <[^>]+> f845 1d30 str\.w r1, \[r5\], #-48
+0+6cc <[^>]+> f845 1b30 str\.w r1, \[r5\], #48
+0+6d0 <[^>]+> f845 1930 str\.w r1, \[r5\], #-48
+0+6d4 <[^>]+> f845 1f30 str\.w r1, \[r5, #48\]!
+0+6d8 <[^>]+> f845 1d30 str\.w r1, \[r5, #-48\]!
0+6dc <[^>]+> 5129 str r1, \[r5, r4\]
0+6de <[^>]+> f849 100c str\.w r1, \[r9, ip\]
0+6e2 <[^>]+> f8cf 1032 str\.w r1, \[pc, #50\] ; 0+716 <[^>]+>
@@ -588,10 +588,10 @@ Disassembly of section .text:
0+6ea <[^>]+> f895 f000 pld \[r5\]
0+6ee <[^>]+> f895 f330 pld \[r5, #816\]
0+6f2 <[^>]+> f815 fc30 pld \[r5, #-48\]
-0+6f6 <[^>]+> f815 fb30 pld \[r5, #48\]!
-0+6fa <[^>]+> f815 f930 pld \[r5, #-48\]!
-0+6fe <[^>]+> f815 ff30 pld \[r5\], #48
-0+702 <[^>]+> f815 fd30 pld \[r5\], #-48
+0+6f6 <[^>]+> f815 fb30 pld \[r5\], #48
+0+6fa <[^>]+> f815 f930 pld \[r5\], #-48
+0+6fe <[^>]+> f815 ff30 pld \[r5, #48\]!
+0+702 <[^>]+> f815 fd30 pld \[r5, #-48\]!
0+706 <[^>]+> f815 f000 pld \[r5, r0\]
0+70a <[^>]+> f819 f000 pld \[r9, r0\]
0+70e <[^>]+> f89f f006 pld \[pc, #6\] ; 0+716 <[^>]+>
@@ -758,8 +758,8 @@ Disassembly of section .text:
0+956 <[^>]+> bc01 pop \{r0\}
0+958 <[^>]+> b502 push \{r1, lr\}
0+95a <[^>]+> bd02 pop \{r1, pc\}
-0+95c <[^>]+> e8bd 1f00 ldmia\.w sp!, \{r8, r9, sl, fp, ip\}
-0+960 <[^>]+> e8ad 1f00 stmia\.w sp!, \{r8, r9, sl, fp, ip\}
+0+95c <[^>]+> e92d 1f00 stmdb sp!, \{r8, r9, sl, fp, ip\}
+0+960 <[^>]+> e8bd 1f00 ldmia\.w sp!, \{r8, r9, sl, fp, ip\}
0+964 <[^>]+> fa92 f113 qadd16 r1, r2, r3
0+968 <[^>]+> fa82 f113 qadd8 r1, r2, r3
0+96c <[^>]+> faa2 f113 qaddsubx r1, r2, r3
@@ -1019,3 +1019,5 @@ Disassembly of section .text:
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\]
+0+d20 <[^>]+> f84d 8d04 str.w r8, \[sp, #-4\]!
+0+d24 <[^>]+> f85d 8b04 ldr.w r8, \[sp\], #4
diff --git a/gas/testsuite/gas/arm/thumb32.s b/gas/testsuite/gas/arm/thumb32.s
index 096b445..5189ef0 100644
--- a/gas/testsuite/gas/arm/thumb32.s
+++ b/gas/testsuite/gas/arm/thumb32.s
@@ -753,3 +753,6 @@ xta:
tbb [r0, r9]
tbh [pc, r7, lsl #1]
tbh [r0, r8, lsl #1]
+
+ push {r8}
+ pop {r8}