[llvm-commits] CVS: llvm/lib/Target/ARM/ARMAsmPrinter.cpp ARMConstantPoolValue.cpp ARMConstantPoolValue.h ARMISelLowering.cpp ARMISelLowering.h ARMInstrInfo.td ARMInstrThumb.td ARMTargetAsmInfo.cpp
Lauro Ramos Venancio
lauro.venancio at gmail.com
Fri Apr 27 06:55:05 PDT 2007
Changes in directory llvm/lib/Target/ARM:
ARMAsmPrinter.cpp updated: 1.67 -> 1.68
ARMConstantPoolValue.cpp updated: 1.3 -> 1.4
ARMConstantPoolValue.h updated: 1.3 -> 1.4
ARMISelLowering.cpp updated: 1.46 -> 1.47
ARMISelLowering.h updated: 1.14 -> 1.15
ARMInstrInfo.td updated: 1.96 -> 1.97
ARMInstrThumb.td updated: 1.23 -> 1.24
ARMTargetAsmInfo.cpp updated: 1.14 -> 1.15
---
Log message:
ARM TLS: implement "general dynamic", "initial exec" and "local exec" models.
---
Diffs of the changes: (+157 -13)
ARMAsmPrinter.cpp | 16 ++++++--
ARMConstantPoolValue.cpp | 19 ++++++----
ARMConstantPoolValue.h | 8 +++-
ARMISelLowering.cpp | 89 +++++++++++++++++++++++++++++++++++++++++++++++
ARMISelLowering.h | 9 ++++
ARMInstrInfo.td | 15 +++++++
ARMInstrThumb.td | 12 ++++++
ARMTargetAsmInfo.cpp | 2 +
8 files changed, 157 insertions(+), 13 deletions(-)
Index: llvm/lib/Target/ARM/ARMAsmPrinter.cpp
diff -u llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.67 llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.68
--- llvm/lib/Target/ARM/ARMAsmPrinter.cpp:1.67 Wed Apr 25 09:50:40 2007
+++ llvm/lib/Target/ARM/ARMAsmPrinter.cpp Fri Apr 27 08:54:47 2007
@@ -134,10 +134,14 @@
} else
O << Name;
if (ACPV->hasModifier()) O << "(" << ACPV->getModifier() << ")";
- if (ACPV->getPCAdjustment() != 0)
+ if (ACPV->getPCAdjustment() != 0) {
O << "-(" << TAI->getPrivateGlobalPrefix() << "PC"
<< utostr(ACPV->getLabelId())
- << "+" << (unsigned)ACPV->getPCAdjustment() << ")";
+ << "+" << (unsigned)ACPV->getPCAdjustment();
+ if (ACPV->mustAddCurrentAddress())
+ O << "-.";
+ O << ")";
+ }
O << "\n";
// If the constant pool value is a extern weak symbol, remember to emit
@@ -869,9 +873,13 @@
SwitchToDataSection(SectionName.c_str());
} else {
if (C->isNullValue() && !NoZerosInBSS && TAI->getBSSSection())
- SwitchToDataSection(TAI->getBSSSection(), I);
+ SwitchToDataSection(I->isThreadLocal() ? TAI->getTLSBSSSection() :
+ TAI->getBSSSection(), I);
else if (!I->isConstant())
- SwitchToDataSection(TAI->getDataSection(), I);
+ SwitchToDataSection(I->isThreadLocal() ? TAI->getTLSDataSection() :
+ TAI->getDataSection(), I);
+ else if (I->isThreadLocal())
+ SwitchToDataSection(TAI->getTLSDataSection());
else {
// Read-only data.
bool HasReloc = C->ContainsRelocations();
Index: llvm/lib/Target/ARM/ARMConstantPoolValue.cpp
diff -u llvm/lib/Target/ARM/ARMConstantPoolValue.cpp:1.3 llvm/lib/Target/ARM/ARMConstantPoolValue.cpp:1.4
--- llvm/lib/Target/ARM/ARMConstantPoolValue.cpp:1.3 Sat Apr 21 19:04:12 2007
+++ llvm/lib/Target/ARM/ARMConstantPoolValue.cpp Fri Apr 27 08:54:47 2007
@@ -20,18 +20,20 @@
ARMConstantPoolValue::ARMConstantPoolValue(GlobalValue *gv, unsigned id,
ARMCP::ARMCPKind k,
unsigned char PCAdj,
- const char *Modif)
+ const char *Modif,
+ bool AddCA)
: MachineConstantPoolValue((const Type*)gv->getType()),
GV(gv), S(NULL), LabelId(id), Kind(k), PCAdjust(PCAdj),
- Modifier(Modif) {}
+ Modifier(Modif), AddCurrentAddress(AddCA) {}
ARMConstantPoolValue::ARMConstantPoolValue(const char *s, unsigned id,
ARMCP::ARMCPKind k,
unsigned char PCAdj,
- const char *Modif)
+ const char *Modif,
+ bool AddCA)
: MachineConstantPoolValue((const Type*)Type::Int32Ty),
GV(NULL), S(s), LabelId(id), Kind(k), PCAdjust(PCAdj),
- Modifier(Modif) {}
+ Modifier(Modif), AddCurrentAddress(AddCA) {}
ARMConstantPoolValue::ARMConstantPoolValue(GlobalValue *gv,
ARMCP::ARMCPKind k,
@@ -78,6 +80,11 @@
if (isNonLazyPointer()) O << "$non_lazy_ptr";
else if (isStub()) O << "$stub";
if (Modifier) O << "(" << Modifier << ")";
- if (PCAdjust != 0) O << "-(LPIC" << LabelId << "+"
- << (unsigned)PCAdjust << ")";
+ if (PCAdjust != 0) {
+ O << "-(LPIC" << LabelId << "+"
+ << (unsigned)PCAdjust;
+ if (AddCurrentAddress)
+ O << "-.";
+ O << ")";
+ }
}
Index: llvm/lib/Target/ARM/ARMConstantPoolValue.h
diff -u llvm/lib/Target/ARM/ARMConstantPoolValue.h:1.3 llvm/lib/Target/ARM/ARMConstantPoolValue.h:1.4
--- llvm/lib/Target/ARM/ARMConstantPoolValue.h:1.3 Sat Apr 21 19:04:12 2007
+++ llvm/lib/Target/ARM/ARMConstantPoolValue.h Fri Apr 27 08:54:47 2007
@@ -37,14 +37,17 @@
unsigned char PCAdjust; // Extra adjustment if constantpool is pc relative.
// 8 for ARM, 4 for Thumb.
const char *Modifier; // GV modifier i.e. (&GV(modifier)-(LPIC+8))
+ bool AddCurrentAddress;
public:
ARMConstantPoolValue(GlobalValue *gv, unsigned id,
ARMCP::ARMCPKind Kind = ARMCP::CPValue,
- unsigned char PCAdj = 0, const char *Modifier = NULL);
+ unsigned char PCAdj = 0, const char *Modifier = NULL,
+ bool AddCurrentAddress = false);
ARMConstantPoolValue(const char *s, unsigned id,
ARMCP::ARMCPKind Kind = ARMCP::CPValue,
- unsigned char PCAdj = 0, const char *Modifier = NULL);
+ unsigned char PCAdj = 0, const char *Modifier = NULL,
+ bool AddCurrentAddress = false);
ARMConstantPoolValue(GlobalValue *GV, ARMCP::ARMCPKind Kind,
const char *Modifier);
@@ -53,6 +56,7 @@
const char *getSymbol() const { return S; }
const char *getModifier() const { return Modifier; }
bool hasModifier() const { return Modifier != NULL; }
+ bool mustAddCurrentAddress() const { return AddCurrentAddress; }
unsigned getLabelId() const { return LabelId; }
bool isNonLazyPointer() const { return Kind == ARMCP::CPNonLazyPtr; }
bool isStub() const { return Kind == ARMCP::CPStub; }
Index: llvm/lib/Target/ARM/ARMISelLowering.cpp
diff -u llvm/lib/Target/ARM/ARMISelLowering.cpp:1.46 llvm/lib/Target/ARM/ARMISelLowering.cpp:1.47
--- llvm/lib/Target/ARM/ARMISelLowering.cpp:1.46 Fri Apr 27 03:15:43 2007
+++ llvm/lib/Target/ARM/ARMISelLowering.cpp Fri Apr 27 08:54:47 2007
@@ -186,6 +186,7 @@
setOperationAction(ISD::GlobalAddress, MVT::i32, Custom);
setOperationAction(ISD::ConstantPool, MVT::i32, Custom);
setOperationAction(ISD::GLOBAL_OFFSET_TABLE, MVT::i32, Custom);
+ setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom);
// Expand mem operations genericly.
setOperationAction(ISD::MEMSET , MVT::Other, Expand);
@@ -293,6 +294,8 @@
case ARMISD::FMRRD: return "ARMISD::FMRRD";
case ARMISD::FMDRR: return "ARMISD::FMDRR";
+
+ case ARMISD::THREAD_POINTER:return "ARMISD::THREAD_POINTER";
}
}
@@ -701,6 +704,91 @@
return DAG.getNode(ARMISD::Wrapper, MVT::i32, Res);
}
+// Lower ISD::GlobalTLSAddress using the "general dynamic" model
+SDOperand
+ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
+ SelectionDAG &DAG) {
+ MVT::ValueType PtrVT = getPointerTy();
+ unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8;
+ ARMConstantPoolValue *CPV =
+ new ARMConstantPoolValue(GA->getGlobal(), ARMPCLabelIndex, ARMCP::CPValue,
+ PCAdj, "tlsgd", true);
+ SDOperand Argument = DAG.getTargetConstantPool(CPV, PtrVT, 2);
+ Argument = DAG.getNode(ARMISD::Wrapper, MVT::i32, Argument);
+ Argument = DAG.getLoad(PtrVT, DAG.getEntryNode(), Argument, NULL, 0);
+ SDOperand Chain = Argument.getValue(1);
+
+ SDOperand PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32);
+ Argument = DAG.getNode(ARMISD::PIC_ADD, PtrVT, Argument, PICLabel);
+
+ // call __tls_get_addr.
+ ArgListTy Args;
+ ArgListEntry Entry;
+ Entry.Node = Argument;
+ Entry.Ty = (const Type *) Type::Int32Ty;
+ Args.push_back(Entry);
+ std::pair<SDOperand, SDOperand> CallResult =
+ LowerCallTo(Chain, (const Type *) Type::Int32Ty, false, false,
+ CallingConv::C, false,
+ DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG);
+ return CallResult.first;
+}
+
+// Lower ISD::GlobalTLSAddress using the "initial exec" or
+// "local exec" model.
+SDOperand
+ARMTargetLowering::LowerToTLSExecModels(GlobalAddressSDNode *GA,
+ SelectionDAG &DAG) {
+ GlobalValue *GV = GA->getGlobal();
+ SDOperand Offset;
+ SDOperand Chain = DAG.getEntryNode();
+ MVT::ValueType PtrVT = getPointerTy();
+ // Get the Thread Pointer
+ SDOperand ThreadPointer = DAG.getNode(ARMISD::THREAD_POINTER, PtrVT);
+
+ if (GV->isDeclaration()){
+ // initial exec model
+ unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8;
+ ARMConstantPoolValue *CPV =
+ new ARMConstantPoolValue(GA->getGlobal(), ARMPCLabelIndex, ARMCP::CPValue,
+ PCAdj, "gottpoff", true);
+ Offset = DAG.getTargetConstantPool(CPV, PtrVT, 2);
+ Offset = DAG.getNode(ARMISD::Wrapper, MVT::i32, Offset);
+ Offset = DAG.getLoad(PtrVT, Chain, Offset, NULL, 0);
+ Chain = Offset.getValue(1);
+
+ SDOperand PICLabel = DAG.getConstant(ARMPCLabelIndex++, MVT::i32);
+ Offset = DAG.getNode(ARMISD::PIC_ADD, PtrVT, Offset, PICLabel);
+
+ Offset = DAG.getLoad(PtrVT, Chain, Offset, NULL, 0);
+ } else {
+ // local exec model
+ ARMConstantPoolValue *CPV =
+ new ARMConstantPoolValue(GV, ARMCP::CPValue, "tpoff");
+ Offset = DAG.getTargetConstantPool(CPV, PtrVT, 2);
+ Offset = DAG.getNode(ARMISD::Wrapper, MVT::i32, Offset);
+ Offset = DAG.getLoad(PtrVT, Chain, Offset, NULL, 0);
+ }
+
+ // The address of the thread local variable is the add of the thread
+ // pointer with the offset of the variable.
+ return DAG.getNode(ISD::ADD, PtrVT, ThreadPointer, Offset);
+}
+
+SDOperand
+ARMTargetLowering::LowerGlobalTLSAddress(SDOperand Op, SelectionDAG &DAG) {
+ // TODO: implement the "local dynamic" model
+ assert(Subtarget->isTargetELF() &&
+ "TLS not implemented for non-ELF targets");
+ GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);
+ // If the relocation model is PIC, use the "General Dynamic" TLS Model,
+ // otherwise use the "Local Exec" TLS Model
+ if (getTargetMachine().getRelocationModel() == Reloc::PIC_)
+ return LowerToTLSGeneralDynamicModel(GA, DAG);
+ else
+ return LowerToTLSExecModels(GA, DAG);
+}
+
SDOperand ARMTargetLowering::LowerGlobalAddressELF(SDOperand Op,
SelectionDAG &DAG) {
MVT::ValueType PtrVT = getPointerTy();
@@ -1249,6 +1337,7 @@
case ISD::GlobalAddress:
return Subtarget->isTargetDarwin() ? LowerGlobalAddressDarwin(Op, DAG) :
LowerGlobalAddressELF(Op, DAG);
+ case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG);
case ISD::CALL: return LowerCALL(Op, DAG);
case ISD::RET: return LowerRET(Op, DAG);
case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG, Subtarget);
Index: llvm/lib/Target/ARM/ARMISelLowering.h
diff -u llvm/lib/Target/ARM/ARMISelLowering.h:1.14 llvm/lib/Target/ARM/ARMISelLowering.h:1.15
--- llvm/lib/Target/ARM/ARMISelLowering.h:1.14 Sat Apr 21 19:04:12 2007
+++ llvm/lib/Target/ARM/ARMISelLowering.h Fri Apr 27 08:54:47 2007
@@ -63,7 +63,9 @@
RRX, // V = RRX X, Flag -> srl X, 1 + shift in carry flag.
FMRRD, // double to two gprs.
- FMDRR // Two gprs to double.
+ FMDRR, // Two gprs to double.
+
+ THREAD_POINTER
};
}
@@ -125,6 +127,11 @@
SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerGlobalAddressDarwin(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerGlobalAddressELF(SDOperand Op, SelectionDAG &DAG);
+ SDOperand LowerGlobalTLSAddress(SDOperand Op, SelectionDAG &DAG);
+ SDOperand LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA,
+ SelectionDAG &DAG);
+ SDOperand LowerToTLSExecModels(GlobalAddressSDNode *GA,
+ SelectionDAG &DAG);
SDOperand LowerGLOBAL_OFFSET_TABLE(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG);
SDOperand LowerBR_JT(SDOperand Op, SelectionDAG &DAG);
Index: llvm/lib/Target/ARM/ARMInstrInfo.td
diff -u llvm/lib/Target/ARM/ARMInstrInfo.td:1.96 llvm/lib/Target/ARM/ARMInstrInfo.td:1.97
--- llvm/lib/Target/ARM/ARMInstrInfo.td:1.96 Tue Apr 17 17:39:58 2007
+++ llvm/lib/Target/ARM/ARMInstrInfo.td Fri Apr 27 08:54:47 2007
@@ -39,6 +39,8 @@
def SDT_ARMPICAdd : SDTypeProfile<1, 2, [SDTCisSameAs<0, 1>,
SDTCisPtrTy<1>, SDTCisVT<2, i32>]>;
+def SDT_ARMThreadPointer : SDTypeProfile<1, 0, [SDTCisPtrTy<0>]>;
+
// Node definitions.
def ARMWrapper : SDNode<"ARMISD::Wrapper", SDTIntUnaryOp>;
def ARMWrapperJT : SDNode<"ARMISD::WrapperJT", SDTIntBinOp>;
@@ -79,6 +81,8 @@
def ARMsra_flag : SDNode<"ARMISD::SRA_FLAG", SDTIntUnaryOp, [SDNPOutFlag]>;
def ARMrrx : SDNode<"ARMISD::RRX" , SDTIntUnaryOp, [SDNPInFlag ]>;
+def ARMthread_pointer: SDNode<"ARMISD::THREAD_POINTER", SDT_ARMThreadPointer>;
+
//===----------------------------------------------------------------------===//
// ARM Instruction Predicate Definitions.
//
@@ -1068,6 +1072,17 @@
!strconcat("${:private}PCRELL${:uid}:\n\t",
"add $dst, pc, #PCRELV${:uid}")),
[]>;
+//===----------------------------------------------------------------------===//
+// TLS Instructions
+//
+
+// __aeabi_read_tp preserves the registers r1-r3.
+let isCall = 1,
+ Defs = [R0, R12, LR] in {
+ def TPsoft : AI<(ops),
+ "bl __aeabi_read_tp",
+ [(set R0, ARMthread_pointer)]>;
+}
//===----------------------------------------------------------------------===//
// Non-Instruction Patterns
Index: llvm/lib/Target/ARM/ARMInstrThumb.td
diff -u llvm/lib/Target/ARM/ARMInstrThumb.td:1.23 llvm/lib/Target/ARM/ARMInstrThumb.td:1.24
--- llvm/lib/Target/ARM/ARMInstrThumb.td:1.23 Fri Apr 27 02:50:02 2007
+++ llvm/lib/Target/ARM/ARMInstrThumb.td Fri Apr 27 08:54:47 2007
@@ -524,6 +524,18 @@
[]>;
//===----------------------------------------------------------------------===//
+// TLS Instructions
+//
+
+// __aeabi_read_tp preserves the registers r1-r3.
+let isCall = 1,
+ Defs = [R0, LR] in {
+ def tTPsoft : TIx2<(ops),
+ "bl __aeabi_read_tp",
+ [(set R0, ARMthread_pointer)]>;
+}
+
+//===----------------------------------------------------------------------===//
// Non-Instruction Patterns
//
Index: llvm/lib/Target/ARM/ARMTargetAsmInfo.cpp
diff -u llvm/lib/Target/ARM/ARMTargetAsmInfo.cpp:1.14 llvm/lib/Target/ARM/ARMTargetAsmInfo.cpp:1.15
--- llvm/lib/Target/ARM/ARMTargetAsmInfo.cpp:1.14 Mon Apr 23 15:04:35 2007
+++ llvm/lib/Target/ARM/ARMTargetAsmInfo.cpp Fri Apr 27 08:54:47 2007
@@ -70,6 +70,8 @@
StaticCtorsSection = "\t.section .ctors,\"aw\",%progbits";
StaticDtorsSection = "\t.section .dtors,\"aw\",%progbits";
}
+ TLSDataSection = "\t.section .tdata,\"awT\",%progbits";
+ TLSBSSSection = "\t.section .tbss,\"awT\",%nobits";
}
ZeroDirective = "\t.space\t";
More information about the llvm-commits
mailing list