Index: lib/Target/ARM/ARMMCInstLower.cpp |
diff --git a/lib/Target/ARM/ARMMCInstLower.cpp b/lib/Target/ARM/ARMMCInstLower.cpp |
index 023f5f8e37a003536a381626db10164b0db00ab7..7bbdfa0f3c6b47baf80f1a373b0187062aa83a14 100644 |
--- a/lib/Target/ARM/ARMMCInstLower.cpp |
+++ b/lib/Target/ARM/ARMMCInstLower.cpp |
@@ -127,3 +127,57 @@ void llvm::LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, |
OutMI.addOperand(MCOp); |
} |
} |
+ |
+// @LOCALMOD-BEGIN |
+// Unlike LowerARMMachineInstrToMCInst, the opcode has already been set. |
+// Otherwise, this is like LowerARMMachineInstrToMCInst, but with special |
+// handling where the "immediate" is PC Relative |
+// (used for MOVi16PIC / MOVTi16PIC, etc. -- see .td file) |
+void llvm::LowerARMMachineInstrToMCInstPCRel(const MachineInstr *MI, |
+ MCInst &OutMI, |
+ ARMAsmPrinter &AP, |
+ unsigned ImmIndex, |
+ unsigned PCIndex, |
+ MCSymbol *PCLabel, |
+ unsigned PCAdjustment) { |
+ |
+ for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { |
+ if (i == ImmIndex) { |
+ MCContext &Ctx = AP.OutContext; |
+ const MCExpr *PCRelExpr = MCSymbolRefExpr::Create(PCLabel, Ctx); |
+ if (PCAdjustment) { |
+ const MCExpr *AdjExpr = MCConstantExpr::Create(PCAdjustment, Ctx); |
+ PCRelExpr = MCBinaryExpr::CreateAdd(PCRelExpr, AdjExpr, Ctx); |
+ } |
+ |
+ // Get the usual symbol operand, then subtract the PCRelExpr. |
+ const MachineOperand &MOImm = MI->getOperand(ImmIndex); |
+ MCOperand SymOp; |
+ bool DidLower = AP.lowerOperand(MOImm, SymOp); |
+ assert (DidLower && "Immediate-like operand should have been lowered"); |
+ |
+ const MCExpr *Expr = SymOp.getExpr(); |
+ ARMMCExpr::VariantKind TargetKind = ARMMCExpr::VK_ARM_None; |
+ /* Unwrap and rewrap the ARMMCExpr */ |
+ if (Expr->getKind() == MCExpr::Target) { |
+ const ARMMCExpr *TargetExpr = cast<ARMMCExpr>(Expr); |
+ TargetKind = TargetExpr->getKind(); |
+ Expr = TargetExpr->getSubExpr(); |
+ } |
+ Expr = MCBinaryExpr::CreateSub(Expr, PCRelExpr, Ctx); |
+ if (TargetKind != ARMMCExpr::VK_ARM_None) { |
+ Expr = ARMMCExpr::Create(TargetKind, Expr, Ctx); |
+ } |
+ MCOperand MCOp = MCOperand::CreateExpr(Expr); |
+ OutMI.addOperand(MCOp); |
+ } else if (i == PCIndex) { // dummy index already handled as PCLabel |
+ continue; |
+ } else { |
+ MCOperand MCOp; |
+ if (AP.lowerOperand(MI->getOperand(i), MCOp)) { |
+ OutMI.addOperand(MCOp); |
+ } |
+ } |
+ } |
+} |
+// @LOCALMOD-END |