mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-25 12:49:50 +00:00
Add start of support for MC instruction printer of ARM jump tables. Filling in
the rest of it is next up. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114500 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
8614167572
commit
882ef2b76a
@ -91,6 +91,8 @@ namespace {
|
||||
return "ARM Assembly Printer";
|
||||
}
|
||||
|
||||
void EmitJumpTable(const MachineInstr *MI);
|
||||
void EmitJump2Table(const MachineInstr *MI);
|
||||
void printInstructionThroughMCStreamer(const MachineInstr *MI);
|
||||
|
||||
|
||||
@ -1383,6 +1385,59 @@ static MCSymbol *getPICLabel(const char *Prefix, unsigned FunctionNumber,
|
||||
return Label;
|
||||
}
|
||||
|
||||
void ARMAsmPrinter::EmitJump2Table(const MachineInstr *MI) {
|
||||
unsigned Opcode = MI->getOpcode();
|
||||
int OpNum = (Opcode == ARM::t2BR_JT) ? 2 : 1;
|
||||
const MachineOperand &MO1 = MI->getOperand(OpNum);
|
||||
const MachineOperand &MO2 = MI->getOperand(OpNum+1); // Unique Id
|
||||
unsigned JTI = MO1.getIndex();
|
||||
|
||||
// Emit a label for the jump table.
|
||||
MCSymbol *JTISymbol = GetARMJTIPICJumpTableLabel2(JTI, MO2.getImm());
|
||||
OutStreamer.EmitLabel(JTISymbol);
|
||||
|
||||
// Emit each entry of the table.
|
||||
const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
|
||||
const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
|
||||
const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
|
||||
bool ByteOffset = false, HalfWordOffset = false;
|
||||
if (MI->getOpcode() == ARM::t2TBB)
|
||||
ByteOffset = true;
|
||||
else if (MI->getOpcode() == ARM::t2TBH)
|
||||
HalfWordOffset = true;
|
||||
|
||||
for (unsigned i = 0, e = JTBBs.size(); i != e; ++i) {
|
||||
MachineBasicBlock *MBB = JTBBs[i];
|
||||
// If this isn't a TBB or TBH, the entries are direct branch instructions.
|
||||
if (!ByteOffset && !HalfWordOffset) {
|
||||
MCInst BrInst;
|
||||
BrInst.setOpcode(ARM::t2B);
|
||||
BrInst.addOperand(MCOperand::CreateExpr(MCSymbolRefExpr::Create(
|
||||
MBB->getSymbol(), OutContext)));
|
||||
OutStreamer.EmitInstruction(BrInst);
|
||||
continue;
|
||||
}
|
||||
// Otherwise it's an offset from the dispatch instruction. Construct an
|
||||
// MCExpr for the entry.
|
||||
assert(0 && "FIXME: TB[BH] jump table!!");
|
||||
|
||||
#if 0
|
||||
if (ByteOffset)
|
||||
O << MAI->getData8bitsDirective();
|
||||
else if (HalfWordOffset)
|
||||
O << MAI->getData16bitsDirective();
|
||||
|
||||
if (ByteOffset || HalfWordOffset)
|
||||
O << '(' << *MBB->getSymbol() << "-" << *JTISymbol << ")/2";
|
||||
else
|
||||
O << "\tb.w " << *MBB->getSymbol();
|
||||
|
||||
if (i != e-1)
|
||||
O << '\n';
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
|
||||
ARMMCInstLower MCInstLowering(OutContext, *Mang, *this);
|
||||
switch (MI->getOpcode()) {
|
||||
@ -1592,6 +1647,23 @@ void ARMAsmPrinter::printInstructionThroughMCStreamer(const MachineInstr *MI) {
|
||||
|
||||
return;
|
||||
}
|
||||
case ARM::t2TBB:
|
||||
case ARM::t2TBH:
|
||||
case ARM::t2BR_JT: {
|
||||
// Lower and emit the instruction itself, then the jump table following it.
|
||||
MCInst TmpInst;
|
||||
MCInstLowering.Lower(MI, TmpInst);
|
||||
OutStreamer.EmitInstruction(TmpInst);
|
||||
|
||||
EmitJump2Table(MI);
|
||||
return;
|
||||
}
|
||||
case ARM::tBR_JTr:
|
||||
case ARM::BR_JTr:
|
||||
case ARM::BR_JTm:
|
||||
case ARM::BR_JTadd:
|
||||
abort();
|
||||
break;
|
||||
}
|
||||
|
||||
MCInst TmpInst;
|
||||
|
@ -99,6 +99,8 @@ public:
|
||||
void printRegisterList(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
||||
void printCPInstOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O,
|
||||
const char *Modifier);
|
||||
// The jump table instructions have custom handling in ARMAsmPrinter
|
||||
// to output the jump table. Nothing further is necessary here.
|
||||
void printJTBlockOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O) {}
|
||||
void printJT2BlockOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O) {}
|
||||
void printTBAddrMode(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
||||
|
Loading…
Reference in New Issue
Block a user