mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-14 00:32:55 +00:00
Lower constant pools and jump tables via TOC on PPC64/SVR4.
In collaboration with Adhemerval Zanella. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@162562 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
bd7684c94c
commit
9fb8b49380
@ -171,7 +171,8 @@ public:
|
||||
VK_ARM_GOTTPOFF,
|
||||
VK_ARM_TARGET1,
|
||||
|
||||
VK_PPC_TOC,
|
||||
VK_PPC_TOC, // TOC base
|
||||
VK_PPC_TOC_ENTRY, // TOC entry
|
||||
VK_PPC_DARWIN_HA16, // ha16(symbol)
|
||||
VK_PPC_DARWIN_LO16, // lo16(symbol)
|
||||
VK_PPC_GAS_HA16, // symbol@ha
|
||||
|
@ -197,7 +197,8 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
|
||||
case VK_ARM_GOTTPOFF: return "(gottpoff)";
|
||||
case VK_ARM_TLSGD: return "(tlsgd)";
|
||||
case VK_ARM_TARGET1: return "(target1)";
|
||||
case VK_PPC_TOC: return "toc";
|
||||
case VK_PPC_TOC: return "tocbase";
|
||||
case VK_PPC_TOC_ENTRY: return "toc";
|
||||
case VK_PPC_DARWIN_HA16: return "ha16";
|
||||
case VK_PPC_DARWIN_LO16: return "lo16";
|
||||
case VK_PPC_GAS_HA16: return "ha";
|
||||
|
@ -345,23 +345,32 @@ void PPCAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
OutStreamer.EmitLabel(PICBase);
|
||||
return;
|
||||
}
|
||||
case PPC::LDtocJTI:
|
||||
case PPC::LDtocCPT:
|
||||
case PPC::LDtoc: {
|
||||
// Transform %X3 = LDtoc <ga:@min1>, %X2
|
||||
LowerPPCMachineInstrToMCInst(MI, TmpInst, *this, Subtarget.isDarwin());
|
||||
|
||||
|
||||
// Change the opcode to LD, and the global address operand to be a
|
||||
// reference to the TOC entry we will synthesize later.
|
||||
TmpInst.setOpcode(PPC::LD);
|
||||
const MachineOperand &MO = MI->getOperand(1);
|
||||
assert(MO.isGlobal());
|
||||
|
||||
// Map symbol -> label of TOC entry.
|
||||
MCSymbol *&TOCEntry = TOC[Mang->getSymbol(MO.getGlobal())];
|
||||
|
||||
// Map symbol -> label of TOC entry
|
||||
assert(MO.isGlobal() || MO.isCPI() || MO.isJTI());
|
||||
MCSymbol *MOSymbol = 0;
|
||||
if (MO.isGlobal())
|
||||
MOSymbol = Mang->getSymbol(MO.getGlobal());
|
||||
else if (MO.isCPI())
|
||||
MOSymbol = GetCPISymbol(MO.getIndex());
|
||||
else if (MO.isJTI())
|
||||
MOSymbol = GetJTISymbol(MO.getIndex());
|
||||
MCSymbol *&TOCEntry = TOC[MOSymbol];
|
||||
if (TOCEntry == 0)
|
||||
TOCEntry = GetTempSymbol("C", TOCLabelID++);
|
||||
|
||||
|
||||
const MCExpr *Exp =
|
||||
MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC,
|
||||
MCSymbolRefExpr::Create(TOCEntry, MCSymbolRefExpr::VK_PPC_TOC_ENTRY,
|
||||
OutContext);
|
||||
TmpInst.getOperand(1) = MCOperand::CreateExpr(Exp);
|
||||
OutStreamer.EmitInstruction(TmpInst);
|
||||
|
@ -1204,6 +1204,14 @@ SDValue PPCTargetLowering::LowerConstantPool(SDValue Op,
|
||||
ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op);
|
||||
const Constant *C = CP->getConstVal();
|
||||
|
||||
// 64-bit SVR4 ABI code is always position-independent.
|
||||
// The actual address of the GlobalValue is stored in the TOC.
|
||||
if (PPCSubTarget.isSVR4ABI() && PPCSubTarget.isPPC64()) {
|
||||
SDValue GA = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment(), 0);
|
||||
return DAG.getNode(PPCISD::TOC_ENTRY, CP->getDebugLoc(), MVT::i64, GA,
|
||||
DAG.getRegister(PPC::X2, MVT::i64));
|
||||
}
|
||||
|
||||
unsigned MOHiFlag, MOLoFlag;
|
||||
bool isPIC = GetLabelAccessInfo(DAG.getTarget(), MOHiFlag, MOLoFlag);
|
||||
SDValue CPIHi =
|
||||
@ -1217,6 +1225,14 @@ SDValue PPCTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) const {
|
||||
EVT PtrVT = Op.getValueType();
|
||||
JumpTableSDNode *JT = cast<JumpTableSDNode>(Op);
|
||||
|
||||
// 64-bit SVR4 ABI code is always position-independent.
|
||||
// The actual address of the GlobalValue is stored in the TOC.
|
||||
if (PPCSubTarget.isSVR4ABI() && PPCSubTarget.isPPC64()) {
|
||||
SDValue GA = DAG.getTargetJumpTable(JT->getIndex(), PtrVT);
|
||||
return DAG.getNode(PPCISD::TOC_ENTRY, JT->getDebugLoc(), MVT::i64, GA,
|
||||
DAG.getRegister(PPC::X2, MVT::i64));
|
||||
}
|
||||
|
||||
unsigned MOHiFlag, MOLoFlag;
|
||||
bool isPIC = GetLabelAccessInfo(DAG.getTarget(), MOHiFlag, MOLoFlag);
|
||||
SDValue JTIHi = DAG.getTargetJumpTable(JT->getIndex(), PtrVT, MOHiFlag);
|
||||
|
@ -624,6 +624,14 @@ def LDtoc: Pseudo<(outs G8RC:$rD), (ins tocentry:$disp, G8RC:$reg),
|
||||
"",
|
||||
[(set G8RC:$rD,
|
||||
(PPCtoc_entry tglobaladdr:$disp, G8RC:$reg))]>, isPPC64;
|
||||
def LDtocJTI: Pseudo<(outs G8RC:$rD), (ins tocentry:$disp, G8RC:$reg),
|
||||
"",
|
||||
[(set G8RC:$rD,
|
||||
(PPCtoc_entry tjumptable:$disp, G8RC:$reg))]>, isPPC64;
|
||||
def LDtocCPT: Pseudo<(outs G8RC:$rD), (ins tocentry:$disp, G8RC:$reg),
|
||||
"",
|
||||
[(set G8RC:$rD,
|
||||
(PPCtoc_entry tconstpool:$disp, G8RC:$reg))]>, isPPC64;
|
||||
|
||||
let hasSideEffects = 1 in {
|
||||
let RST = 2, DS_RA = 0 in // FIXME: Should be a pseudo.
|
||||
|
67
test/CodeGen/PowerPC/ppc64-toc.ll
Normal file
67
test/CodeGen/PowerPC/ppc64-toc.ll
Normal file
@ -0,0 +1,67 @@
|
||||
; RUN: llc < %s | FileCheck %s
|
||||
target datalayout = "E-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v128:128:128-n32:64"
|
||||
target triple = "powerpc64-unknown-linux-gnu"
|
||||
|
||||
@double_array = global [32 x double] zeroinitializer, align 8
|
||||
@number64 = global i64 10, align 8
|
||||
@internal_static_var.x = internal unnamed_addr global i64 0, align 8
|
||||
|
||||
define i64 @access_int64(i64 %a) nounwind readonly {
|
||||
entry:
|
||||
; CHECK: access_int64:
|
||||
; CHECK-NEXT: .align 3
|
||||
; CHECK-NEXT: .quad .L.access_int64
|
||||
; CHECK-NEXT: .quad .TOC.@tocbase
|
||||
; CHECK-NEXT: .text
|
||||
%0 = load i64* @number64, align 8
|
||||
; CHECK: ld {{[0-9]+}}, .LC{{[0-9]+}}@toc(2)
|
||||
%cmp = icmp eq i64 %0, %a
|
||||
%conv1 = zext i1 %cmp to i64
|
||||
ret i64 %conv1
|
||||
}
|
||||
|
||||
define i64 @internal_static_var(i64 %a) nounwind {
|
||||
entry:
|
||||
; CHECK: internal_static_var:
|
||||
; CHECK: ld {{[0-9]+}}, .LC{{[0-9]+}}@toc(2)
|
||||
%0 = load i64* @internal_static_var.x, align 8
|
||||
%cmp = icmp eq i64 %0, %a
|
||||
%conv1 = zext i1 %cmp to i64
|
||||
ret i64 %conv1
|
||||
}
|
||||
|
||||
define i32 @access_double(double %a) nounwind readnone {
|
||||
entry:
|
||||
; CHECK: access_double:
|
||||
; CHECK: ld {{[0-9]+}}, .LC{{[0-9]+}}@toc(2)
|
||||
%cmp = fcmp oeq double %a, 2.000000e+00
|
||||
%conv = zext i1 %cmp to i32
|
||||
ret i32 %conv
|
||||
}
|
||||
|
||||
|
||||
define i32 @access_double_array(double %a, i32 %i) nounwind readonly {
|
||||
entry:
|
||||
; CHECK: access_double_array:
|
||||
%idxprom = sext i32 %i to i64
|
||||
%arrayidx = getelementptr inbounds [32 x double]* @double_array, i64 0, i64 %idxprom
|
||||
%0 = load double* %arrayidx, align 8
|
||||
; CHECK: ld {{[0-9]+}}, .LC{{[0-9]+}}@toc(2)
|
||||
%cmp = fcmp oeq double %0, %a
|
||||
%conv = zext i1 %cmp to i32
|
||||
ret i32 %conv
|
||||
}
|
||||
|
||||
; Check the creation of 4 .tc entries:
|
||||
; * int64_t global 'number64'
|
||||
; * double constant 2.0
|
||||
; * double array 'double_array'
|
||||
; * static int64_t 'x' accessed within '@internal_static_var'
|
||||
; CHECK: .LC{{[0-9]+}}:
|
||||
; CHECK-NEXT: .tc {{[\._a-zA-Z0-9]+}}[TC],{{[\._a-zA-Z0-9]+}}
|
||||
; CHECK-NEXT: .LC{{[0-9]+}}:
|
||||
; CHECK-NEXT: .tc {{[\._a-zA-Z0-9]+}}[TC],{{[\._a-zA-Z0-9]+}}
|
||||
; CHECK-NEXT: .LC{{[0-9]+}}:
|
||||
; CHECK-NEXT: .tc {{[\._a-zA-Z0-9]+}}[TC],{{[\._a-zA-Z0-9]+}}
|
||||
; CHECK-NEXT: .LC{{[0-9]+}}:
|
||||
; CHECK-NEXT: .tc {{[\._a-zA-Z0-9]+}}[TC],{{[\._a-zA-Z0-9]+}}
|
Loading…
x
Reference in New Issue
Block a user