[llvm] r198904 - Fix a bug with the ARM thumb2 CBNZ and CBNZ instructions that
Kevin Enderby
enderby at apple.com
Thu Jan 9 16:43:32 PST 2014
Author: enderby
Date: Thu Jan 9 18:43:32 2014
New Revision: 198904
URL: http://llvm.org/viewvc/llvm-project?rev=198904&view=rev
Log:
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
Added:
llvm/trunk/test/MC/ARM/thumb2-cbn-to-next-inst.s
Modified:
llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
Modified: llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp?rev=198904&r1=198903&r2=198904&view=diff
==============================================================================
--- llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp (original)
+++ llvm/trunk/lib/Target/ARM/MCTargetDesc/ARMAsmBackend.cpp Thu Jan 9 18:43:32 2014
@@ -155,6 +155,8 @@ static unsigned getRelaxedOpcode(unsigne
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
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(con
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);
Added: llvm/trunk/test/MC/ARM/thumb2-cbn-to-next-inst.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/ARM/thumb2-cbn-to-next-inst.s?rev=198904&view=auto
==============================================================================
--- llvm/trunk/test/MC/ARM/thumb2-cbn-to-next-inst.s (added)
+++ llvm/trunk/test/MC/ARM/thumb2-cbn-to-next-inst.s Thu Jan 9 18:43:32 2014
@@ -0,0 +1,33 @@
+@ RUN: llvm-mc -triple thumbv7-apple-darwin -filetype=obj -o %t.o %s
+@ RUN: llvm-objdump -triple thumbv7-apple-darwin -d %t.o | FileCheck %s
+
+.thumb
+start:
+.thumb_func start
+ add r1, r2, r3
+ cbnz r2, L1 @ this can't be encoded, must turn into a nop
+L1:
+ add r4, r5, r6
+ cbnz r2, L2
+ sub r7, r8, r9
+L2:
+ add r7, r8, r9
+ cbz r2, L3 @ this can't be encoded, must turn into a nop
+L3:
+ add r10, r11, r12
+ cbz r2, L4
+ sub r7, r8, r9
+L4:
+ add r3, r4, r5
+
+@ CHECK: 0: 02 eb 03 01 add.w r1, r2, r3
+@ CHECK: 4: 00 bf nop
+@ CHECK: 6: 05 eb 06 04 add.w r4, r5, r6
+@ CHECK: a: 0a b9 cbnz r2, #2
+@ CHECK: c: a8 eb 09 07 sub.w r7, r8, r9
+@ CHECK: 10: 08 eb 09 07 add.w r7, r8, r9
+@ CHECK: 14: 00 bf nop
+@ CHECK: 16: 0b eb 0c 0a add.w r10, r11, r12
+@ CHECK: 1a: 0a b1 cbz r2, #2
+@ CHECK: 1c: a8 eb 09 07 sub.w r7, r8, r9
+@ CHECK: 20: 04 eb 05 03 add.w r3, r4, r5
More information about the llvm-commits
mailing list