From 16805f35a33326502c977fc25b3521e3623b21c6 Mon Sep 17 00:00:00 2001 From: Paul Brook Date: Tue, 18 Jul 2006 16:44:47 +0000 Subject: [PATCH] 2006-07-18 Paul Brook bfd/ * bfd-in2.h: Regenerate. * libbfd.h: Regenerate. * reloc.c: Add BFD_RELOC_ARM_T32_ADD_IMM. gas/ * tc-arm.c (do_t_add_sub): Use addw/subw when source is PC. (md_convert_frag): Use correct reloc for add_pc. Use BFD_RELOC_ARM_T32_ADD_IMM for normal add/sum. (md_apply_fix): Handle BFD_RELOC_ARM_T32_ADD_IMM. (arm_force_relocation): Handle BFD_RELOC_ARM_T32_ADD_IMM. gas/testsuite/ * gas/arm/thumb2_add.d: New test. * gas/arm/thumb2_add.s: New test. --- bfd/ChangeLog | 6 ++++ bfd/bfd-in2.h | 1 + bfd/libbfd.h | 1 + bfd/reloc.c | 2 ++ gas/ChangeLog | 8 +++++ gas/config/tc-arm.c | 52 ++++++++++++++++++++++-------- gas/testsuite/ChangeLog | 5 +++ gas/testsuite/gas/arm/thumb2_add.d | 18 +++++++++++ gas/testsuite/gas/arm/thumb2_add.s | 20 ++++++++++++ 9 files changed, 100 insertions(+), 13 deletions(-) create mode 100644 gas/testsuite/gas/arm/thumb2_add.d create mode 100644 gas/testsuite/gas/arm/thumb2_add.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 6c4773ed28a..4ce004e63e2 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,9 @@ +2006-07-18 Paul Brook + + * bfd-in2.h: Regenerate. + * libbfd.h: Regenerate. + * reloc.c: Add BFD_RELOC_ARM_T32_ADD_IMM. + 2006-07-18 Nick Clifton * elfxx-mips.c (_bfd_mips_elf_common_definition): New function. diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index df3bae8945c..381ae55640f 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -2966,6 +2966,7 @@ pc-relative or some form of GOT-indirect relocation. */ BFD_RELOC_ARM_IMMEDIATE, BFD_RELOC_ARM_ADRL_IMMEDIATE, BFD_RELOC_ARM_T32_IMMEDIATE, + BFD_RELOC_ARM_T32_ADD_IMM, BFD_RELOC_ARM_T32_IMM12, BFD_RELOC_ARM_T32_ADD_PC12, BFD_RELOC_ARM_SHIFT_IMM, diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 0f41f5f2d1b..0aa704604f6 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -1263,6 +1263,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_ARM_IMMEDIATE", "BFD_RELOC_ARM_ADRL_IMMEDIATE", "BFD_RELOC_ARM_T32_IMMEDIATE", + "BFD_RELOC_ARM_T32_ADD_IMM", "BFD_RELOC_ARM_T32_IMM12", "BFD_RELOC_ARM_T32_ADD_PC12", "BFD_RELOC_ARM_SHIFT_IMM", diff --git a/bfd/reloc.c b/bfd/reloc.c index 414a41cef5f..60ebf36f033 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -2821,6 +2821,8 @@ ENUMX BFD_RELOC_ARM_ADRL_IMMEDIATE ENUMX BFD_RELOC_ARM_T32_IMMEDIATE +ENUMX + BFD_RELOC_ARM_T32_ADD_IMM ENUMX BFD_RELOC_ARM_T32_IMM12 ENUMX diff --git a/gas/ChangeLog b/gas/ChangeLog index 80c46cd276c..6b414dc1f2c 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,11 @@ +2006-07-18 Paul Brook + + * tc-arm.c (do_t_add_sub): Use addw/subw when source is PC. + (md_convert_frag): Use correct reloc for add_pc. Use + BFD_RELOC_ARM_T32_ADD_IMM for normal add/sum. + (md_apply_fix): Handle BFD_RELOC_ARM_T32_ADD_IMM. + (arm_force_relocation): Handle BFD_RELOC_ARM_T32_ADD_IMM. + 2006-07-17 Mat Hostetter * symbols.c (report_op_error): Fix pasto. Don't use as_bad_where diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 1bfe5b307a3..fe9d77521fc 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -8186,13 +8186,13 @@ do_t_add_sub (void) narrow = (current_it_mask != 0); if (!inst.operands[2].isreg) { + int add; + + add = (inst.instruction == T_MNEM_add + || inst.instruction == T_MNEM_adds); opcode = 0; if (inst.size_req != 4) { - int add; - - add = (inst.instruction == T_MNEM_add - || inst.instruction == T_MNEM_adds); /* Attempt to use a narrow opcode, with relaxation if appropriate. */ if (Rd == REG_SP && Rs == REG_SP && !flags) @@ -8222,12 +8222,24 @@ do_t_add_sub (void) if (inst.size_req == 4 || (inst.size_req != 2 && !opcode)) { - /* ??? Convert large immediates to addw/subw. */ - inst.instruction = THUMB_OP32 (inst.instruction); - inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000; + if (Rs == REG_PC) + { + /* Always use addw/subw. */ + inst.instruction = add ? 0xf20f0000 : 0xf2af0000; + inst.reloc.type = BFD_RELOC_ARM_T32_IMM12; + } + else + { + inst.instruction = THUMB_OP32 (inst.instruction); + inst.instruction = (inst.instruction & 0xe1ffffff) + | 0x10000000; + if (flags) + inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE; + else + inst.reloc.type = BFD_RELOC_ARM_T32_ADD_IMM; + } inst.instruction |= inst.operands[0].reg << 8; inst.instruction |= inst.operands[1].reg << 16; - inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE; } } else @@ -16136,7 +16148,10 @@ md_convert_frag (bfd *abfd, segT asec ATTRIBUTE_UNUSED, fragS *fragp) insn = THUMB_OP32 (opcode); insn |= (old_op & 0xf0) << 4; put_thumb32_insn (buf, insn); - reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE; + if (opcode == T_MNEM_add_pc) + reloc_type = BFD_RELOC_ARM_T32_IMM12; + else + reloc_type = BFD_RELOC_ARM_T32_ADD_IMM; } else reloc_type = BFD_RELOC_ARM_THUMB_ADD; @@ -16153,7 +16168,10 @@ md_convert_frag (bfd *abfd, segT asec ATTRIBUTE_UNUSED, fragS *fragp) insn |= (old_op & 0xf0) << 4; insn |= (old_op & 0xf) << 16; put_thumb32_insn (buf, insn); - reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE; + if (insn & (1 << 20)) + reloc_type = BFD_RELOC_ARM_T32_ADD_IMM; + else + reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE; } else reloc_type = BFD_RELOC_ARM_THUMB_ADD; @@ -17561,6 +17579,7 @@ md_apply_fix (fixS * fixP, break; case BFD_RELOC_ARM_T32_IMMEDIATE: + case BFD_RELOC_ARM_T32_ADD_IMM: case BFD_RELOC_ARM_T32_IMM12: case BFD_RELOC_ARM_T32_ADD_PC12: /* We claim that this fixup has been processed here, @@ -17581,15 +17600,21 @@ md_apply_fix (fixS * fixP, newval <<= 16; newval |= md_chars_to_number (buf+2, THUMB_SIZE); - /* FUTURE: Implement analogue of negate_data_op for T32. */ - if (fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE) + newimm = FAIL; + if (fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE + || fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM) { newimm = encode_thumb32_immediate (value); if (newimm == (unsigned int) FAIL) newimm = thumb32_negate_data_op (&newval, value); } - else + if (fixP->fx_r_type != BFD_RELOC_ARM_T32_IMMEDIATE + && newimm == (unsigned int) FAIL) { + /* Turn add/sum into addw/subw. */ + if (fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM) + newval = (newval & 0xfeffffff) | 0x02000000; + /* 12 bit immediate for addw/subw. */ if (value < 0) { @@ -18608,6 +18633,7 @@ arm_force_relocation (struct fix * fixp) if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE + || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMM12 || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_PC12) diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index 327364b152f..16b48ac8a80 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2006-07-18 Paul Brook + + * gas/arm/thumb2_add.d: New test. + * gas/arm/thumb2_add.s: New test. + 2006-07-18 Maciej W. Rozycki * gas/mips/mips4.s, gas/mips/mips4.d: Enable the "pref" test. Change diff --git a/gas/testsuite/gas/arm/thumb2_add.d b/gas/testsuite/gas/arm/thumb2_add.d new file mode 100644 index 00000000000..6331acfc2f4 --- /dev/null +++ b/gas/testsuite/gas/arm/thumb2_add.d @@ -0,0 +1,18 @@ +# as: -march=armv6kt2 +# objdump: -dr --prefix-addresses --show-raw-insn + +.*: +file format .*arm.* + +Disassembly of section .text: +0+000 <[^>]+> f60f 0000 addw r0, pc, #2048 ; 0x800 +0+004 <[^>]+> f20f 0900 addw r9, pc, #0 ; 0x0 +0+008 <[^>]+> f20f 4900 addw r9, pc, #1024 ; 0x400 +0+00c <[^>]+> f509 6880 add.w r8, r9, #1024 ; 0x400 +0+010 <[^>]+> f209 1801 addw r8, r9, #257 ; 0x101 +0+014 <[^>]+> f201 1301 addw r3, r1, #257 ; 0x101 +0+018 <[^>]+> f6af 0000 subw r0, pc, #2048 ; 0x800 +0+01c <[^>]+> f2af 0900 subw r9, pc, #0 ; 0x0 +0+020 <[^>]+> f2af 4900 subw r9, pc, #1024 ; 0x400 +0+024 <[^>]+> f5a9 6880 sub.w r8, r9, #1024 ; 0x400 +0+028 <[^>]+> f2a9 1801 subw r8, r9, #257 ; 0x101 +0+02c <[^>]+> f2a1 1301 subw r3, r1, #257 ; 0x101 diff --git a/gas/testsuite/gas/arm/thumb2_add.s b/gas/testsuite/gas/arm/thumb2_add.s new file mode 100644 index 00000000000..72d1bb1aff0 --- /dev/null +++ b/gas/testsuite/gas/arm/thumb2_add.s @@ -0,0 +1,20 @@ + .syntax unified + .text + .align 2 + .global thumb2_add + .thumb + .thumb_func + .type thumb2_add, %function +thumb2_add: + add r0, pc, #0x800 + add r9, pc, #0 + add r9, pc, #0x400 + add r8, r9, #0x400 + add r8, r9, #0x101 + add r3, r1, #0x101 + sub r0, pc, #0x800 + sub r9, pc, #0 + sub r9, pc, #0x400 + sub r8, r9, #0x400 + sub r8, r9, #0x101 + sub r3, r1, #0x101 -- 2.30.2