diff options
author | Kevin Enderby <enderby@apple.com> | 2014-01-10 00:43:32 +0000 |
---|---|---|
committer | Kevin Enderby <enderby@apple.com> | 2014-01-10 00:43:32 +0000 |
commit | 9bd296ab55bfcbfe73280474aa4ce3b5f017a0cc (patch) | |
tree | e1ee3261d86326ec848bba301c57bbb36276ef9b /llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | |
parent | 7073a2da151ec12428a9386411e61bf2727f0533 (diff) | |
download | bcm5719-llvm-9bd296ab55bfcbfe73280474aa4ce3b5f017a0cc.tar.gz bcm5719-llvm-9bd296ab55bfcbfe73280474aa4ce3b5f017a0cc.zip |
Fix a bug with the ARM thumb2 CBNZ and CBNZ instructions that
branch to the next instruction. This can not be encoded but can be
turned into a NOP.
rdar://15062072
llvm-svn: 198904
Diffstat (limited to 'llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp index fecab9f5d49..20dce218ea3 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp @@ -155,6 +155,8 @@ static unsigned getRelaxedOpcode(unsigned Op) { case ARM::tLDRpci: return ARM::t2LDRpci; case ARM::tADR: return ARM::t2ADR; case ARM::tB: return ARM::t2B; + case ARM::tCBZ: return ARM::tHINT; + case ARM::tCBNZ: return ARM::tHINT; } } @@ -196,6 +198,12 @@ bool ARMAsmBackend::fixupNeedsRelaxation(const MCFixup &Fixup, int64_t Offset = int64_t(Value) - 4; return Offset > 1020 || Offset < 0 || Offset & 3; } + case ARM::fixup_arm_thumb_cb: + // If we have a Thumb CBZ or CBNZ instruction and its target is the next + // instruction it is is actually out of range for the instruction. + // It will be changed to a NOP. + int64_t Offset = (Value & ~1); + return Offset == 2; } llvm_unreachable("Unexpected fixup kind in fixupNeedsRelaxation()!"); } @@ -212,7 +220,18 @@ void ARMAsmBackend::relaxInstruction(const MCInst &Inst, MCInst &Res) const { report_fatal_error("unexpected instruction to relax: " + OS.str()); } - // The instructions we're relaxing have (so far) the same operands. + // If we are changing Thumb CBZ or CBNZ instruction to a NOP, aka tHINT, we + // have to change the operands too. + if ((Inst.getOpcode() == ARM::tCBZ || Inst.getOpcode() == ARM::tCBNZ) && + RelaxedOp == ARM::tHINT) { + Res.setOpcode(RelaxedOp); + Res.addOperand(MCOperand::CreateImm(0)); + Res.addOperand(MCOperand::CreateImm(14)); + Res.addOperand(MCOperand::CreateReg(0)); + return; + } + + // The rest of instructions we're relaxing have the same operands. // We just need to update to the proper opcode. Res = Inst; Res.setOpcode(RelaxedOp); |