summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
diff options
context:
space:
mode:
authorEvan Cheng <evan.cheng@apple.com>2009-07-25 00:33:29 +0000
committerEvan Cheng <evan.cheng@apple.com>2009-07-25 00:33:29 +0000
commitf3a1fce8ae411ea7135bc48495e09538d492929e (patch)
tree04b6da3b544e2edbe87580c4d28fc0e898bdc455 /llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
parentbcf2ae6aa56af3668906e1aed9687a3228d55188 (diff)
downloadbcm5719-llvm-f3a1fce8ae411ea7135bc48495e09538d492929e.tar.gz
bcm5719-llvm-f3a1fce8ae411ea7135bc48495e09538d492929e.zip
Change Thumb2 jumptable codegen to one that uses two level jumps:
Before: adr r12, #LJTI3_0_0 ldr pc, [r12, +r0, lsl #2] LJTI3_0_0: .long LBB3_24 .long LBB3_30 .long LBB3_31 .long LBB3_32 After: adr r12, #LJTI3_0_0 add pc, r12, +r0, lsl #2 LJTI3_0_0: b.w LBB3_24 b.w LBB3_30 b.w LBB3_31 b.w LBB3_32 This has several advantages. 1. This will make it easier to optimize this to a TBB / TBH instruction + (smaller) table. 2. This eliminate the need for ugly asm printer hack to force the address into thumb addresses (bit 0 is one). 3. Same codegen for pic and non-pic. 4. This eliminate the need to align the table so constantpool island pass won't have to over-estimate the size. Based on my calculation, the later is probably slightly faster as well since ldr pc with shifter address is very slow. That is, it should be a win as long as the HW implementation can do a reasonable job of branch predict the second branch. llvm-svn: 77024
Diffstat (limited to 'llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp')
-rw-r--r--llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp47
1 files changed, 27 insertions, 20 deletions
diff --git a/llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
index 4d21d5cfd90..cffbecd764b 100644
--- a/llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
+++ b/llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
@@ -160,6 +160,7 @@ namespace {
void printCPInstOperand(const MachineInstr *MI, int OpNum,
const char *Modifier);
void printJTBlockOperand(const MachineInstr *MI, int OpNum);
+ void printJT2BlockOperand(const MachineInstr *MI, int OpNum);
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
unsigned AsmVariant, const char *ExtraCode);
@@ -907,6 +908,8 @@ void ARMAsmPrinter::printCPInstOperand(const MachineInstr *MI, int OpNum,
}
void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum) {
+ assert(!Subtarget->isThumb2() && "Thumb2 should use double-jump jumptables!");
+
const MachineOperand &MO1 = MI->getOperand(OpNum);
const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
unsigned JTI = MO1.getIndex();
@@ -922,23 +925,13 @@ void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum) {
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
bool UseSet= TAI->getSetDirective() && TM.getRelocationModel() == Reloc::PIC_;
- bool NeedBit0 = Subtarget->isTargetDarwin() && Subtarget->isThumb2();
SmallPtrSet<MachineBasicBlock*, 8> JTSets;
for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
MachineBasicBlock *MBB = JTBBs[i];
- if (UseSet && JTSets.insert(MBB)) {
- // FIXME: Temporary workaround for an assembler bug. The assembler isn't
- // setting the bit zero to 1 even though it is a thumb address.
- if (NeedBit0) {
- O << TAI->getSetDirective() << ' ' << TAI->getPrivateGlobalPrefix()
- << getFunctionNumber() << '_' << JTI << '_' << MO2.getImm()
- << "_set_" << MBB->getNumber() << ",(";
- printBasicBlockLabel(MBB, false, false, false);
- O << '-' << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
- << '_' << JTI << '_' << MO2.getImm() << "+1)\n";
- } else
- printPICJumpTableSetLabel(JTI, MO2.getImm(), MBB);
- }
+ bool isNew = JTSets.insert(MBB);
+
+ if (UseSet && isNew)
+ printPICJumpTableSetLabel(JTI, MO2.getImm(), MBB);
O << JTEntryDirective << ' ';
if (UseSet)
@@ -952,19 +945,33 @@ void ARMAsmPrinter::printJTBlockOperand(const MachineInstr *MI, int OpNum) {
O << '-' << TAI->getPrivateGlobalPrefix() << "JTI"
<< getFunctionNumber() << '_' << JTI << '_' << MO2.getImm();
} else {
- // FIXME: Temporary workaround for an assembler bug. The assembler isn't
- // setting the bit zero to 1 even though it is a thumb address.
- if (NeedBit0)
- O << '(';
printBasicBlockLabel(MBB, false, false, false);
- if (NeedBit0)
- O << "+1)";
}
if (i != e-1)
O << '\n';
}
}
+void ARMAsmPrinter::printJT2BlockOperand(const MachineInstr *MI, int OpNum) {
+ const MachineOperand &MO1 = MI->getOperand(OpNum);
+ const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
+ unsigned JTI = MO1.getIndex();
+ O << TAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
+ << '_' << JTI << '_' << MO2.getImm() << ":\n";
+
+ const MachineFunction *MF = MI->getParent()->getParent();
+ const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
+ const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
+ const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
+ for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
+ MachineBasicBlock *MBB = JTBBs[i];
+ O << "\tb.w ";
+ printBasicBlockLabel(MBB, false, false, false);
+ if (i != e-1)
+ O << '\n';
+ }
+}
+
bool ARMAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNum,
unsigned AsmVariant, const char *ExtraCode){
OpenPOWER on IntegriCloud