diff options
Diffstat (limited to 'gas')
-rw-r--r-- | gas/ChangeLog | 11 | ||||
-rw-r--r-- | gas/config/tc-arm.c | 85 | ||||
-rw-r--r-- | gas/testsuite/ChangeLog | 6 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/thumb32.d | 78 | ||||
-rw-r--r-- | gas/testsuite/gas/arm/thumb32.s | 3 |
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} |