a426b286c8
patch for r263619, and unify all the URLs to point to svnweb.
201 lines
7.9 KiB
Diff
201 lines
7.9 KiB
Diff
Pull in r199775 from upstream llvm trunk (by Venkatraman Govindaraju):
|
|
|
|
[Sparc] Do not add PC to _GLOBAL_OFFSET_TABLE_ address to access GOT in absolute code.
|
|
Fixes PR#18521
|
|
|
|
Introduced here: http://svnweb.freebsd.org/changeset/base/262261
|
|
|
|
Index: lib/Target/Sparc/SparcAsmPrinter.cpp
|
|
===================================================================
|
|
--- lib/Target/Sparc/SparcAsmPrinter.cpp
|
|
+++ lib/Target/Sparc/SparcAsmPrinter.cpp
|
|
@@ -65,18 +65,24 @@ namespace {
|
|
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
|
|
unsigned AsmVariant, const char *ExtraCode,
|
|
raw_ostream &O);
|
|
+
|
|
+ void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI);
|
|
+
|
|
};
|
|
} // end of anonymous namespace
|
|
|
|
-static MCOperand createPCXCallOP(MCSymbol *Label,
|
|
- MCContext &OutContext)
|
|
-{
|
|
- const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Label,
|
|
+static MCOperand createSparcMCOperand(SparcMCExpr::VariantKind Kind,
|
|
+ MCSymbol *Sym, MCContext &OutContext) {
|
|
+ const MCSymbolRefExpr *MCSym = MCSymbolRefExpr::Create(Sym,
|
|
OutContext);
|
|
- const SparcMCExpr *expr = SparcMCExpr::Create(SparcMCExpr::VK_Sparc_None,
|
|
- MCSym, OutContext);
|
|
+ const SparcMCExpr *expr = SparcMCExpr::Create(Kind, MCSym, OutContext);
|
|
return MCOperand::CreateExpr(expr);
|
|
+
|
|
}
|
|
+static MCOperand createPCXCallOP(MCSymbol *Label,
|
|
+ MCContext &OutContext) {
|
|
+ return createSparcMCOperand(SparcMCExpr::VK_Sparc_None, Label, OutContext);
|
|
+}
|
|
|
|
static MCOperand createPCXRelExprOp(SparcMCExpr::VariantKind Kind,
|
|
MCSymbol *GOTLabel, MCSymbol *StartLabel,
|
|
@@ -115,43 +121,101 @@ static void EmitSETHI(MCStreamer &OutStreamer,
|
|
OutStreamer.EmitInstruction(SETHIInst);
|
|
}
|
|
|
|
-static void EmitOR(MCStreamer &OutStreamer, MCOperand &RS1,
|
|
- MCOperand &Imm, MCOperand &RD)
|
|
+static void EmitBinary(MCStreamer &OutStreamer, unsigned Opcode,
|
|
+ MCOperand &RS1, MCOperand &Src2, MCOperand &RD)
|
|
{
|
|
- MCInst ORInst;
|
|
- ORInst.setOpcode(SP::ORri);
|
|
- ORInst.addOperand(RD);
|
|
- ORInst.addOperand(RS1);
|
|
- ORInst.addOperand(Imm);
|
|
- OutStreamer.EmitInstruction(ORInst);
|
|
+ MCInst Inst;
|
|
+ Inst.setOpcode(Opcode);
|
|
+ Inst.addOperand(RD);
|
|
+ Inst.addOperand(RS1);
|
|
+ Inst.addOperand(Src2);
|
|
+ OutStreamer.EmitInstruction(Inst);
|
|
}
|
|
|
|
+static void EmitOR(MCStreamer &OutStreamer,
|
|
+ MCOperand &RS1, MCOperand &Imm, MCOperand &RD) {
|
|
+ EmitBinary(OutStreamer, SP::ORri, RS1, Imm, RD);
|
|
+}
|
|
+
|
|
static void EmitADD(MCStreamer &OutStreamer,
|
|
- MCOperand &RS1, MCOperand &RS2, MCOperand &RD)
|
|
-{
|
|
- MCInst ADDInst;
|
|
- ADDInst.setOpcode(SP::ADDrr);
|
|
- ADDInst.addOperand(RD);
|
|
- ADDInst.addOperand(RS1);
|
|
- ADDInst.addOperand(RS2);
|
|
- OutStreamer.EmitInstruction(ADDInst);
|
|
+ MCOperand &RS1, MCOperand &RS2, MCOperand &RD) {
|
|
+ EmitBinary(OutStreamer, SP::ADDrr, RS1, RS2, RD);
|
|
}
|
|
|
|
-static void LowerGETPCXAndEmitMCInsts(const MachineInstr *MI,
|
|
- MCStreamer &OutStreamer,
|
|
- MCContext &OutContext)
|
|
+static void EmitSHL(MCStreamer &OutStreamer,
|
|
+ MCOperand &RS1, MCOperand &Imm, MCOperand &RD) {
|
|
+ EmitBinary(OutStreamer, SP::SLLri, RS1, Imm, RD);
|
|
+}
|
|
+
|
|
+
|
|
+static void EmitHiLo(MCStreamer &OutStreamer, MCSymbol *GOTSym,
|
|
+ SparcMCExpr::VariantKind HiKind,
|
|
+ SparcMCExpr::VariantKind LoKind,
|
|
+ MCOperand &RD,
|
|
+ MCContext &OutContext) {
|
|
+
|
|
+ MCOperand hi = createSparcMCOperand(HiKind, GOTSym, OutContext);
|
|
+ MCOperand lo = createSparcMCOperand(LoKind, GOTSym, OutContext);
|
|
+ EmitSETHI(OutStreamer, hi, RD);
|
|
+ EmitOR(OutStreamer, RD, lo, RD);
|
|
+}
|
|
+
|
|
+void SparcAsmPrinter::LowerGETPCXAndEmitMCInsts(const MachineInstr *MI)
|
|
{
|
|
- const MachineOperand &MO = MI->getOperand(0);
|
|
- MCSymbol *StartLabel = OutContext.CreateTempSymbol();
|
|
- MCSymbol *EndLabel = OutContext.CreateTempSymbol();
|
|
- MCSymbol *SethiLabel = OutContext.CreateTempSymbol();
|
|
MCSymbol *GOTLabel =
|
|
OutContext.GetOrCreateSymbol(Twine("_GLOBAL_OFFSET_TABLE_"));
|
|
|
|
+ const MachineOperand &MO = MI->getOperand(0);
|
|
assert(MO.getReg() != SP::O7 &&
|
|
"%o7 is assigned as destination for getpcx!");
|
|
|
|
MCOperand MCRegOP = MCOperand::CreateReg(MO.getReg());
|
|
+
|
|
+
|
|
+ if (TM.getRelocationModel() != Reloc::PIC_) {
|
|
+ // Just load the address of GOT to MCRegOP.
|
|
+ switch(TM.getCodeModel()) {
|
|
+ default:
|
|
+ llvm_unreachable("Unsupported absolute code model");
|
|
+ case CodeModel::Small:
|
|
+ EmitHiLo(OutStreamer, GOTLabel,
|
|
+ SparcMCExpr::VK_Sparc_HI, SparcMCExpr::VK_Sparc_LO,
|
|
+ MCRegOP, OutContext);
|
|
+ break;
|
|
+ case CodeModel::Medium: {
|
|
+ EmitHiLo(OutStreamer, GOTLabel,
|
|
+ SparcMCExpr::VK_Sparc_H44, SparcMCExpr::VK_Sparc_M44,
|
|
+ MCRegOP, OutContext);
|
|
+ MCOperand imm = MCOperand::CreateExpr(MCConstantExpr::Create(12,
|
|
+ OutContext));
|
|
+ EmitSHL(OutStreamer, MCRegOP, imm, MCRegOP);
|
|
+ MCOperand lo = createSparcMCOperand(SparcMCExpr::VK_Sparc_L44,
|
|
+ GOTLabel, OutContext);
|
|
+ EmitOR(OutStreamer, MCRegOP, lo, MCRegOP);
|
|
+ break;
|
|
+ }
|
|
+ case CodeModel::Large: {
|
|
+ EmitHiLo(OutStreamer, GOTLabel,
|
|
+ SparcMCExpr::VK_Sparc_HH, SparcMCExpr::VK_Sparc_HM,
|
|
+ MCRegOP, OutContext);
|
|
+ MCOperand imm = MCOperand::CreateExpr(MCConstantExpr::Create(32,
|
|
+ OutContext));
|
|
+ EmitSHL(OutStreamer, MCRegOP, imm, MCRegOP);
|
|
+ // Use register %o7 to load the lower 32 bits.
|
|
+ MCOperand RegO7 = MCOperand::CreateReg(SP::O7);
|
|
+ EmitHiLo(OutStreamer, GOTLabel,
|
|
+ SparcMCExpr::VK_Sparc_HI, SparcMCExpr::VK_Sparc_LO,
|
|
+ RegO7, OutContext);
|
|
+ EmitADD(OutStreamer, MCRegOP, RegO7, MCRegOP);
|
|
+ }
|
|
+ }
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ MCSymbol *StartLabel = OutContext.CreateTempSymbol();
|
|
+ MCSymbol *EndLabel = OutContext.CreateTempSymbol();
|
|
+ MCSymbol *SethiLabel = OutContext.CreateTempSymbol();
|
|
+
|
|
MCOperand RegO7 = MCOperand::CreateReg(SP::O7);
|
|
|
|
// <StartLabel>:
|
|
@@ -187,7 +251,7 @@ void SparcAsmPrinter::EmitInstruction(const Machin
|
|
// FIXME: Debug Value.
|
|
return;
|
|
case SP::GETPCX:
|
|
- LowerGETPCXAndEmitMCInsts(MI, OutStreamer, OutContext);
|
|
+ LowerGETPCXAndEmitMCInsts(MI);
|
|
return;
|
|
}
|
|
MachineBasicBlock::const_instr_iterator I = MI;
|
|
Index: test/CodeGen/SPARC/tls.ll
|
|
===================================================================
|
|
--- test/CodeGen/SPARC/tls.ll
|
|
+++ test/CodeGen/SPARC/tls.ll
|
|
@@ -38,8 +38,7 @@ entry:
|
|
|
|
|
|
; v8abs-LABEL: test_tls_extern
|
|
-; v8abs: or {{%[goli][0-7]}}, %lo(_GLOBAL_OFFSET_TABLE_+{{.+}}), [[PC:%[goli][0-7]]]
|
|
-; v8abs: add [[PC]], %o7, %[[GOTBASE:[goli][0-7]]]
|
|
+; v8abs: or {{%[goli][0-7]}}, %lo(_GLOBAL_OFFSET_TABLE_), %[[GOTBASE:[goli][0-7]]]
|
|
; v8abs: sethi %tie_hi22(extern_symbol), [[R1:%[goli][0-7]]]
|
|
; v8abs: add [[R1]], %tie_lo10(extern_symbol), %[[R2:[goli][0-7]]]
|
|
; v8abs: ld [%[[GOTBASE]]+%[[R2]]], [[R3:%[goli][0-7]]], %tie_ld(extern_symbol)
|
|
@@ -47,8 +46,7 @@ entry:
|
|
; v8abs: ld [%[[R4]]]
|
|
|
|
; v9abs-LABEL: test_tls_extern
|
|
-; v9abs: or {{%[goli][0-7]}}, %lo(_GLOBAL_OFFSET_TABLE_+{{.+}}), [[PC:%[goli][0-7]]]
|
|
-; v9abs: add [[PC]], %o7, %[[GOTBASE:[goli][0-7]]]
|
|
+; v9abs: or {{%[goli][0-7]}}, %l44(_GLOBAL_OFFSET_TABLE_), %[[GOTBASE:[goli][0-7]]]
|
|
; v9abs: sethi %tie_hi22(extern_symbol), [[R1:%[goli][0-7]]]
|
|
; v9abs: add [[R1]], %tie_lo10(extern_symbol), %[[R2:[goli][0-7]]]
|
|
; v9abs: ldx [%[[GOTBASE]]+%[[R2]]], [[R3:%[goli][0-7]]], %tie_ldx(extern_symbol)
|