[patch] Thumb-2 add PC misassembly
Paul Brook
paul@codesourcery.com
Wed Jul 12 23:54:00 GMT 2006
More information about the Binutils mailing list
Wed Jul 12 23:54:00 GMT 2006
- Previous message (by thread): Strange linking error
- Next message (by thread): [patch] Thumb-2 add PC misassembly
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
In Thumb-2 "add reg, pc, #imm" should be assembled to the addw instruction, not add.w (PC is not a valid source for the latter). The patch below fixes this. It also uses the addw instruction in other cases where the immediate is not valid for a normal add. The same applies for sub. Tested with cross to arm-none-eabi. Ok? 2006-07-13 Paul Brook <paul@codesourcery.com> 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. Index: bfd/bfd-in2.h =================================================================== RCS file: /var/cvsroot/src-cvs/src/bfd/bfd-in2.h,v retrieving revision 1.395 diff -u -p -r1.395 bfd-in2.h --- bfd/bfd-in2.h 19 Jun 2006 13:17:43 -0000 1.395 +++ bfd/bfd-in2.h 12 Jul 2006 23:08:38 -0000 @@ -2966,6 +2966,7 @@ pc-relative or some form of GOT-indirect 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, Index: bfd/libbfd.h =================================================================== RCS file: /var/cvsroot/src-cvs/src/bfd/libbfd.h,v retrieving revision 1.184 diff -u -p -r1.184 libbfd.h --- bfd/libbfd.h 19 Jun 2006 13:17:44 -0000 1.184 +++ bfd/libbfd.h 12 Jul 2006 23:08:38 -0000 @@ -1263,6 +1263,7 @@ static const char *const bfd_reloc_code_ "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", Index: bfd/reloc.c =================================================================== RCS file: /var/cvsroot/src-cvs/src/bfd/reloc.c,v retrieving revision 1.155 diff -u -p -r1.155 reloc.c --- bfd/reloc.c 15 Jun 2006 11:03:00 -0000 1.155 +++ bfd/reloc.c 12 Jul 2006 23:08:31 -0000 @@ -2822,6 +2822,8 @@ ENUMX ENUMX BFD_RELOC_ARM_T32_IMMEDIATE ENUMX + BFD_RELOC_ARM_T32_ADD_IMM +ENUMX BFD_RELOC_ARM_T32_IMM12 ENUMX BFD_RELOC_ARM_T32_ADD_PC12 Index: gas/config/tc-arm.c =================================================================== RCS file: /var/cvsroot/src-cvs/src/gas/config/tc-arm.c,v retrieving revision 1.278 diff -u -p -r1.278 tc-arm.c --- gas/config/tc-arm.c 21 Jun 2006 14:20:24 -0000 1.278 +++ gas/config/tc-arm.c 12 Jul 2006 23:43:25 -0000 @@ -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 AT 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 AT 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) Index: gas/testsuite/gas/arm/thumb2_add.d =================================================================== RCS file: gas/testsuite/gas/arm/thumb2_add.d diff -N gas/testsuite/gas/arm/thumb2_add.d --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gas/testsuite/gas/arm/thumb2_add.d 12 Jul 2006 23:25:39 -0000 @@ -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 Index: gas/testsuite/gas/arm/thumb2_add.s =================================================================== RCS file: gas/testsuite/gas/arm/thumb2_add.s diff -N gas/testsuite/gas/arm/thumb2_add.s --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ gas/testsuite/gas/arm/thumb2_add.s 12 Jul 2006 23:24:04 -0000 @@ -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
- Previous message (by thread): Strange linking error
- Next message (by thread): [patch] Thumb-2 add PC misassembly
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Binutils mailing list