mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-22 10:29:35 +00:00
Implement local-exec TLS on PowerPC.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@157935 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
70a07c7fc4
commit
fd42ed676e
@ -176,6 +176,8 @@ public:
|
||||
VK_PPC_DARWIN_LO16, // lo16(symbol)
|
||||
VK_PPC_GAS_HA16, // symbol@ha
|
||||
VK_PPC_GAS_LO16, // symbol@l
|
||||
VK_PPC_TPREL16_HA, // symbol@tprel@ha
|
||||
VK_PPC_TPREL16_LO, // symbol@tprel@l
|
||||
|
||||
VK_Mips_GPREL,
|
||||
VK_Mips_GOT_CALL,
|
||||
|
@ -202,6 +202,8 @@ StringRef MCSymbolRefExpr::getVariantKindName(VariantKind Kind) {
|
||||
case VK_PPC_DARWIN_LO16: return "lo16";
|
||||
case VK_PPC_GAS_HA16: return "ha";
|
||||
case VK_PPC_GAS_LO16: return "l";
|
||||
case VK_PPC_TPREL16_HA: return "tprel@ha";
|
||||
case VK_PPC_TPREL16_LO: return "tprel@l";
|
||||
case VK_Mips_GPREL: return "GPREL";
|
||||
case VK_Mips_GOT_CALL: return "GOT_CALL";
|
||||
case VK_Mips_GOT16: return "GOT16";
|
||||
|
@ -50,21 +50,27 @@ namespace llvm {
|
||||
/// and jumps to external functions on Tiger and earlier.
|
||||
MO_DARWIN_STUB = 1,
|
||||
|
||||
/// MO_LO16, MO_HA16 - lo16(symbol) and ha16(symbol)
|
||||
MO_LO16 = 4, MO_HA16 = 8,
|
||||
|
||||
/// MO_PIC_FLAG - If this bit is set, the symbol reference is relative to
|
||||
/// the function's picbase, e.g. lo16(symbol-picbase).
|
||||
MO_PIC_FLAG = 16,
|
||||
MO_PIC_FLAG = 4,
|
||||
|
||||
/// MO_NLP_FLAG - If this bit is set, the symbol reference is actually to
|
||||
/// the non_lazy_ptr for the global, e.g. lo16(symbol$non_lazy_ptr-picbase).
|
||||
MO_NLP_FLAG = 32,
|
||||
MO_NLP_FLAG = 8,
|
||||
|
||||
/// MO_NLP_HIDDEN_FLAG - If this bit is set, the symbol reference is to a
|
||||
/// symbol with hidden visibility. This causes a different kind of
|
||||
/// non-lazy-pointer to be generated.
|
||||
MO_NLP_HIDDEN_FLAG = 64
|
||||
MO_NLP_HIDDEN_FLAG = 16,
|
||||
|
||||
/// The next are not flags but distinct values.
|
||||
MO_ACCESS_MASK = 224,
|
||||
|
||||
/// MO_LO16, MO_HA16 - lo16(symbol) and ha16(symbol)
|
||||
MO_LO16 = 32, MO_HA16 = 64,
|
||||
|
||||
MO_TPREL16_HA = 96,
|
||||
MO_TPREL16_LO = 128
|
||||
};
|
||||
} // end namespace PPCII
|
||||
|
||||
|
@ -905,6 +905,7 @@ bool PPCTargetLowering::SelectAddressRegImm(SDValue N, SDValue &Disp,
|
||||
&& "Cannot handle constant offsets yet!");
|
||||
Disp = N.getOperand(1).getOperand(0); // The global address.
|
||||
assert(Disp.getOpcode() == ISD::TargetGlobalAddress ||
|
||||
Disp.getOpcode() == ISD::TargetGlobalTLSAddress ||
|
||||
Disp.getOpcode() == ISD::TargetConstantPool ||
|
||||
Disp.getOpcode() == ISD::TargetJumpTable);
|
||||
Base = N.getOperand(0);
|
||||
@ -1220,6 +1221,30 @@ SDValue PPCTargetLowering::LowerBlockAddress(SDValue Op,
|
||||
return LowerLabelRef(TgtBAHi, TgtBALo, isPIC, DAG);
|
||||
}
|
||||
|
||||
SDValue PPCTargetLowering::LowerGlobalTLSAddress(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
|
||||
GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);
|
||||
DebugLoc dl = GA->getDebugLoc();
|
||||
const GlobalValue *GV = GA->getGlobal();
|
||||
EVT PtrVT = getPointerTy();
|
||||
bool is64bit = PPCSubTarget.isPPC64();
|
||||
|
||||
TLSModel::Model model = getTargetMachine().getTLSModel(GV);
|
||||
|
||||
SDValue TGAHi = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
|
||||
PPCII::MO_TPREL16_HA);
|
||||
SDValue TGALo = DAG.getTargetGlobalAddress(GV, dl, PtrVT, 0,
|
||||
PPCII::MO_TPREL16_LO);
|
||||
|
||||
if (model != TLSModel::LocalExec)
|
||||
llvm_unreachable("only local-exec TLS mode supported");
|
||||
SDValue R13 = DAG.getRegister(is64bit ? PPC::X13 : PPC::R13,
|
||||
is64bit ? MVT::i64 : MVT::i32);
|
||||
SDValue Hi = DAG.getNode(PPCISD::Hi, dl, PtrVT, TGAHi, R13);
|
||||
return DAG.getNode(PPCISD::Lo, dl, PtrVT, TGALo, Hi);
|
||||
}
|
||||
|
||||
SDValue PPCTargetLowering::LowerGlobalAddress(SDValue Op,
|
||||
SelectionDAG &DAG) const {
|
||||
EVT PtrVT = Op.getValueType();
|
||||
@ -4565,7 +4590,7 @@ SDValue PPCTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
|
||||
case ISD::ConstantPool: return LowerConstantPool(Op, DAG);
|
||||
case ISD::BlockAddress: return LowerBlockAddress(Op, DAG);
|
||||
case ISD::GlobalAddress: return LowerGlobalAddress(Op, DAG);
|
||||
case ISD::GlobalTLSAddress: llvm_unreachable("TLS not implemented for PPC");
|
||||
case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
|
||||
case ISD::JumpTable: return LowerJumpTable(Op, DAG);
|
||||
case ISD::SETCC: return LowerSETCC(Op, DAG);
|
||||
case ISD::INIT_TRAMPOLINE: return LowerINIT_TRAMPOLINE(Op, DAG);
|
||||
|
@ -389,6 +389,7 @@ namespace llvm {
|
||||
SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const;
|
||||
SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const;
|
||||
|
@ -357,6 +357,9 @@ def ADDIC8 : DForm_2<12, (outs G8RC:$rD), (ins G8RC:$rA, s16imm64:$imm),
|
||||
def ADDI8 : DForm_2<14, (outs G8RC:$rD), (ins G8RC:$rA, s16imm64:$imm),
|
||||
"addi $rD, $rA, $imm", IntGeneral,
|
||||
[(set G8RC:$rD, (add G8RC:$rA, immSExt16:$imm))]>;
|
||||
def ADDI8L : DForm_2<14, (outs G8RC:$rD), (ins G8RC:$rA, symbolLo64:$imm),
|
||||
"addi $rD, $rA, $imm", IntGeneral,
|
||||
[(set G8RC:$rD, (add G8RC:$rA, immSExt16:$imm))]>;
|
||||
def ADDIS8 : DForm_2<15, (outs G8RC:$rD), (ins G8RC:$rA, symbolHi64:$imm),
|
||||
"addis $rD, $rA, $imm", IntGeneral,
|
||||
[(set G8RC:$rD, (add G8RC:$rA, imm16ShiftedSExt:$imm))]>;
|
||||
@ -773,6 +776,10 @@ def : Pat<(PPChi tjumptable:$in , 0), (LIS8 tjumptable:$in)>;
|
||||
def : Pat<(PPClo tjumptable:$in , 0), (LI8 tjumptable:$in)>;
|
||||
def : Pat<(PPChi tblockaddress:$in, 0), (LIS8 tblockaddress:$in)>;
|
||||
def : Pat<(PPClo tblockaddress:$in, 0), (LI8 tblockaddress:$in)>;
|
||||
def : Pat<(PPChi tglobaltlsaddr:$g, G8RC:$in),
|
||||
(ADDIS8 G8RC:$in, tglobaltlsaddr:$g)>;
|
||||
def : Pat<(PPClo tglobaltlsaddr:$g, G8RC:$in),
|
||||
(ADDI8L G8RC:$in, tglobaltlsaddr:$g)>;
|
||||
def : Pat<(add G8RC:$in, (PPChi tglobaladdr:$g, 0)),
|
||||
(ADDIS8 G8RC:$in, tglobaladdr:$g)>;
|
||||
def : Pat<(add G8RC:$in, (PPChi tconstpool:$g, 0)),
|
||||
|
@ -854,6 +854,9 @@ let PPC970_Unit = 1 in { // FXU Operations.
|
||||
def ADDI : DForm_2<14, (outs GPRC:$rD), (ins GPRC:$rA, s16imm:$imm),
|
||||
"addi $rD, $rA, $imm", IntGeneral,
|
||||
[(set GPRC:$rD, (add GPRC:$rA, immSExt16:$imm))]>;
|
||||
def ADDIL : DForm_2<14, (outs GPRC:$rD), (ins GPRC:$rA, symbolLo:$imm),
|
||||
"addi $rD, $rA, $imm", IntGeneral,
|
||||
[(set GPRC:$rD, (add GPRC:$rA, immSExt16:$imm))]>;
|
||||
let Defs = [CARRY] in {
|
||||
def ADDIC : DForm_2<12, (outs GPRC:$rD), (ins GPRC:$rA, s16imm:$imm),
|
||||
"addic $rD, $rA, $imm", IntGeneral,
|
||||
@ -1418,6 +1421,10 @@ def : Pat<(PPChi tjumptable:$in, 0), (LIS tjumptable:$in)>;
|
||||
def : Pat<(PPClo tjumptable:$in, 0), (LI tjumptable:$in)>;
|
||||
def : Pat<(PPChi tblockaddress:$in, 0), (LIS tblockaddress:$in)>;
|
||||
def : Pat<(PPClo tblockaddress:$in, 0), (LI tblockaddress:$in)>;
|
||||
def : Pat<(PPChi tglobaltlsaddr:$g, GPRC:$in),
|
||||
(ADDIS GPRC:$in, tglobaltlsaddr:$g)>;
|
||||
def : Pat<(PPClo tglobaltlsaddr:$g, GPRC:$in),
|
||||
(ADDIL GPRC:$in, tglobaltlsaddr:$g)>;
|
||||
def : Pat<(add GPRC:$in, (PPChi tglobaladdr:$g, 0)),
|
||||
(ADDIS GPRC:$in, tglobaladdr:$g)>;
|
||||
def : Pat<(add GPRC:$in, (PPChi tconstpool:$g, 0)),
|
||||
|
@ -99,10 +99,22 @@ static MCOperand GetSymbolRef(const MachineOperand &MO, const MCSymbol *Symbol,
|
||||
MCContext &Ctx = Printer.OutContext;
|
||||
MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;
|
||||
|
||||
if (MO.getTargetFlags() & PPCII::MO_LO16)
|
||||
RefKind = isDarwin ? MCSymbolRefExpr::VK_PPC_DARWIN_LO16 : MCSymbolRefExpr::VK_PPC_GAS_LO16;
|
||||
else if (MO.getTargetFlags() & PPCII::MO_HA16)
|
||||
RefKind = isDarwin ? MCSymbolRefExpr::VK_PPC_DARWIN_HA16 : MCSymbolRefExpr::VK_PPC_GAS_HA16;
|
||||
unsigned access = MO.getTargetFlags() & PPCII::MO_ACCESS_MASK;
|
||||
|
||||
switch (access) {
|
||||
case PPCII::MO_HA16: RefKind = isDarwin ?
|
||||
MCSymbolRefExpr::VK_PPC_DARWIN_HA16 :
|
||||
MCSymbolRefExpr::VK_PPC_GAS_HA16;
|
||||
break;
|
||||
case PPCII::MO_LO16: RefKind = isDarwin ?
|
||||
MCSymbolRefExpr::VK_PPC_DARWIN_LO16 :
|
||||
MCSymbolRefExpr::VK_PPC_GAS_LO16;
|
||||
break;
|
||||
case PPCII::MO_TPREL16_HA: RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_HA;
|
||||
break;
|
||||
case PPCII::MO_TPREL16_LO: RefKind = MCSymbolRefExpr::VK_PPC_TPREL16_LO;
|
||||
break;
|
||||
}
|
||||
|
||||
// FIXME: This isn't right, but we don't have a good way to express this in
|
||||
// the MC Level, see below.
|
||||
|
16
test/CodeGen/PowerPC/tls.ll
Normal file
16
test/CodeGen/PowerPC/tls.ll
Normal file
@ -0,0 +1,16 @@
|
||||
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-freebsd10.0"
|
||||
; RUN: llc < %s -march=ppc64 | FileCheck %s
|
||||
|
||||
@a = thread_local global i32 0, align 4
|
||||
|
||||
;CHECK: localexec:
|
||||
define i32 @localexec() nounwind {
|
||||
entry:
|
||||
;CHECK: addis [[REG1:[0-9]+]], 13, a@tprel@ha
|
||||
;CHECK-NEXT: li [[REG2:[0-9]+]], 42
|
||||
;CHECK-NEXT: addi [[REG1]], [[REG1]], a@tprel@l
|
||||
;CHECK-NEXT: stw [[REG2]], 0([[REG1]])
|
||||
store i32 42, i32* @a, align 4
|
||||
ret i32 0
|
||||
}
|
Loading…
Reference in New Issue
Block a user