From 838ec33e0c7aac35905e4e008d3448ad6f5e087b Mon Sep 17 00:00:00 2001 From: Asiri Rathnayake Date: Tue, 9 Dec 2014 13:14:58 +0000 Subject: [PATCH] Fix modified immediate bug reported by MC Hammer. Instructions of the form [ADD Rd, pc, #imm] are manually aliased in processInstruction() to use ADR. To accomodate this, mod_imm handling had to be tweaked a bit. Turns out it was the manual aliasing that must be tweaked to accommodate mod_imms instead. More information about the parsed instruction is available at the point where processInstruction() is invoked, which makes it easier to detect a mod_imm at that point rather than trying to detect a potential alias when a mod_imm is being prepped. Added a test case and fixed some white spaces as well. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223772 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 17 ++++++----------- test/MC/ARM/basic-arm-instructions.s | 11 +++++++---- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index b080c92820f..e2f7dfb17f9 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -1860,16 +1860,7 @@ public: if (isImm()) return addImmOperands(Inst, N); - if (Inst.getOpcode() == ARM::ADDri && - Inst.getOperand(1).getReg() == ARM::PC) { - // Instructions of the form [ADD , pc, #imm] are manually aliased - // in processInstruction() to use ADR. We must keep the immediate in - // its unencoded form in order to not clash with this aliasing. - Inst.addOperand(MCOperand::CreateImm(ARM_AM::rotr32(ModImm.Bits, - ModImm.Rot))); - } else { - Inst.addOperand(MCOperand::CreateImm(ModImm.Bits | (ModImm.Rot << 7))); - } + Inst.addOperand(MCOperand::CreateImm(ModImm.Bits | (ModImm.Rot << 7))); } void addModImmNotOperands(MCInst &Inst, unsigned N) const { @@ -6680,7 +6671,11 @@ bool ARMAsmParser::processInstruction(MCInst &Inst, TmpInst.setOpcode(ARM::ADR); TmpInst.addOperand(Inst.getOperand(0)); if (Inst.getOperand(2).isImm()) { - TmpInst.addOperand(Inst.getOperand(2)); + // Immediate (mod_imm) will be in its encoded form, we must unencode it + // before passing it to the ADR instruction. + unsigned Enc = Inst.getOperand(2).getImm(); + TmpInst.addOperand(MCOperand::CreateImm( + ARM_AM::rotr32(Enc & 0xFF, (Enc & 0xF00) >> 7))); } else { // Turn PC-relative expression into absolute expression. // Reading PC provides the start of the current instruction + 8 and diff --git a/test/MC/ARM/basic-arm-instructions.s b/test/MC/ARM/basic-arm-instructions.s index 038ed70c4f2..616674e5635 100644 --- a/test/MC/ARM/basic-arm-instructions.s +++ b/test/MC/ARM/basic-arm-instructions.s @@ -228,11 +228,13 @@ Lforward: add r6, r7, ror r9 add r4, r5, rrx - add r0, #-4 - add r4, r5, #-21 - add r0, pc, #0xc0000000 + add r0, #-4 + add r4, r5, #-21 + add r0, pc, #0xc0000000 + addseq r0,pc,#0xc0000000 - add r0, pc, #(Lback - .) + + add r0, pc, #(Lback - .) @ CHECK: add r4, r5, #61440 @ encoding: [0x0f,0x4a,0x85,0xe2] @ CHECK: add r4, r5, #61440 @ encoding: [0x0f,0x4a,0x85,0xe2] @@ -284,6 +286,7 @@ Lforward: @ CHECK: sub r0, r0, #4 @ encoding: [0x04,0x00,0x40,0xe2] @ CHECK: sub r4, r5, #21 @ encoding: [0x15,0x40,0x45,0xe2] @ CHECK: adr r0, #-1073741824 @ encoding: [0x03,0x01,0x8f,0xe2] +@ CHECK: addseq r0, pc, #-1073741824 @ encoding: [0x03,0x01,0x9f,0x02] @ CHECK: Ltmp0: @ CHECK-NEXT: Ltmp1: @ CHECK-NEXT: adr r0, (Ltmp1+8)+(Lback-Ltmp0) @ encoding: [A,A,0x0f'A',0xe2'A'] -- 2.11.0