diff options
author | Asiri Rathnayake <asiri.rathnayake@arm.com> | 2014-12-09 13:14:58 +0000 |
---|---|---|
committer | Asiri Rathnayake <asiri.rathnayake@arm.com> | 2014-12-09 13:14:58 +0000 |
commit | 7835e9b232f372e718d6ca5da024ab2819f9a0cb (patch) | |
tree | 94ac823c53afedabe870dbfd3abc8859478f8390 /llvm/lib | |
parent | 423236bf0b66b18761c917585fef54dc85594761 (diff) | |
download | bcm5719-llvm-7835e9b232f372e718d6ca5da024ab2819f9a0cb.tar.gz bcm5719-llvm-7835e9b232f372e718d6ca5da024ab2819f9a0cb.zip |
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.
llvm-svn: 223772
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 17 |
1 files changed, 6 insertions, 11 deletions
diff --git a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index b080c92820f..e2f7dfb17f9 100644 --- a/llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/llvm/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 <rd>, 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 |