#include "llvm/CodeGen/PseudoSourceValue.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/ErrorHandling.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
static cl::opt<bool>
SelectionDAG &DAG) const {
if (usesGlobalOffsetTable())
return DAG.getGLOBAL_OFFSET_TABLE(getPointerTy());
- if (!Subtarget->isPICStyleRIPRel())
+ if (!Subtarget->is64Bit())
// This doesn't have DebugLoc associated with it, but is not really the
// same as a Register.
return DAG.getNode(X86ISD::GlobalBaseReg, DebugLoc::getUnknownLoc(),
return Table;
}
-/// getFunctionAlignment - Return the alignment of this function.
+/// getFunctionAlignment - Return the Log2 alignment of this function.
unsigned X86TargetLowering::getFunctionAlignment(const Function *F) const {
return F->hasFnAttr(Attribute::OptimizeForSize) ? 1 : 4;
}
SmallVector<CCValAssign, 16> RVLocs;
unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
- CCState CCInfo(CC, isVarArg, getTargetMachine(), RVLocs);
+ CCState CCInfo(CC, isVarArg, getTargetMachine(), RVLocs, DAG.getContext());
CCInfo.AnalyzeReturn(Op.getNode(), RetCC_X86);
// If this is the first return lowered for this function, add the regs to the
SmallVector<CCValAssign, 16> RVLocs;
bool isVarArg = TheCall->isVarArg();
bool Is64Bit = Subtarget->is64Bit();
- CCState CCInfo(CallingConv, isVarArg, getTargetMachine(), RVLocs);
+ CCState CCInfo(CallingConv, isVarArg, getTargetMachine(),
+ RVLocs, DAG.getContext());
CCInfo.AnalyzeCallResult(TheCall, RetCC_X86);
SmallVector<SDValue, 8> ResultVals;
// If this is x86-64, and we disabled SSE, we can't return FP values
if ((CopyVT == MVT::f32 || CopyVT == MVT::f64) &&
((Is64Bit || TheCall->isInreg()) && !Subtarget->hasSSE1())) {
- cerr << "SSE register return with SSE disabled\n";
- exit(1);
+ llvm_report_error("SSE register return with SSE disabled");
}
// If this is a call to a function that returns an fp value on the floating
}
-/// CallRequiresGOTInRegister - Check whether the call requires the GOT pointer
-/// in a register before calling.
-bool X86TargetLowering::CallRequiresGOTPtrInReg(bool Is64Bit, bool IsTailCall) {
- return !IsTailCall && !Is64Bit &&
- getTargetMachine().getRelocationModel() == Reloc::PIC_ &&
- Subtarget->isPICStyleGOT();
-}
-
-/// CallRequiresFnAddressInReg - Check whether the call requires the function
-/// address to be loaded in a register.
-bool
-X86TargetLowering::CallRequiresFnAddressInReg(bool Is64Bit, bool IsTailCall) {
- return !Is64Bit && IsTailCall &&
- getTargetMachine().getRelocationModel() == Reloc::PIC_ &&
- Subtarget->isPICStyleGOT();
-}
-
/// CreateCopyOfByValArgument - Make a copy of an aggregate at address specified
/// by "Src" to address "Dst" with size and alignment information specified by
/// the specific parameter attribute. The copy will be passed as a byval
// Assign locations to all of the incoming arguments.
SmallVector<CCValAssign, 16> ArgLocs;
- CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs);
+ CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs, DAG.getContext());
CCInfo.AnalyzeFormalArguments(Op.getNode(), CCAssignFnForNode(CC));
SmallVector<SDValue, 8> ArgValues;
// Analyze operands of the call, assigning locations to each operand.
SmallVector<CCValAssign, 16> ArgLocs;
- CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs);
+ CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs, DAG.getContext());
CCInfo.AnalyzeCallOperands(TheCall, CCAssignFnForNode(CC));
// Get a count of how many bytes are to be pushed on the stack.
InFlag = Chain.getValue(1);
}
- // ELF / PIC requires GOT in the EBX register before function calls via PLT
- // GOT pointer.
- if (CallRequiresGOTPtrInReg(Is64Bit, IsTailCall)) {
- Chain = DAG.getCopyToReg(Chain, dl, X86::EBX,
- DAG.getNode(X86ISD::GlobalBaseReg,
- DebugLoc::getUnknownLoc(),
- getPointerTy()),
- InFlag);
- InFlag = Chain.getValue(1);
- }
- // If we are tail calling and generating PIC/GOT style code load the address
- // of the callee into ecx. The value in ecx is used as target of the tail
- // jump. This is done to circumvent the ebx/callee-saved problem for tail
- // calls on PIC/GOT architectures. Normally we would just put the address of
- // GOT into ebx and then call target@PLT. But for tail callss ebx would be
- // restored (since ebx is callee saved) before jumping to the target@PLT.
- if (CallRequiresFnAddressInReg(Is64Bit, IsTailCall)) {
- // Note: The actual moving to ecx is done further down.
- GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee);
- if (G && !G->getGlobal()->hasHiddenVisibility() &&
- !G->getGlobal()->hasProtectedVisibility())
- Callee = LowerGlobalAddress(Callee, DAG);
- else if (isa<ExternalSymbolSDNode>(Callee))
- Callee = LowerExternalSymbol(Callee,DAG);
+
+ if (Subtarget->isPICStyleGOT()) {
+ // ELF / PIC requires GOT in the EBX register before function calls via PLT
+ // GOT pointer.
+ if (!IsTailCall) {
+ Chain = DAG.getCopyToReg(Chain, dl, X86::EBX,
+ DAG.getNode(X86ISD::GlobalBaseReg,
+ DebugLoc::getUnknownLoc(),
+ getPointerTy()),
+ InFlag);
+ InFlag = Chain.getValue(1);
+ } else {
+ // If we are tail calling and generating PIC/GOT style code load the
+ // address of the callee into ECX. The value in ecx is used as target of
+ // the tail jump. This is done to circumvent the ebx/callee-saved problem
+ // for tail calls on PIC/GOT architectures. Normally we would just put the
+ // address of GOT into ebx and then call target@PLT. But for tail calls
+ // ebx would be restored (since ebx is callee saved) before jumping to the
+ // target@PLT.
+
+ // Note: The actual moving to ECX is done further down.
+ GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee);
+ if (G && !G->getGlobal()->hasHiddenVisibility() &&
+ !G->getGlobal()->hasProtectedVisibility())
+ Callee = LowerGlobalAddress(Callee, DAG);
+ else if (isa<ExternalSymbolSDNode>(Callee))
+ Callee = LowerExternalSymbol(Callee, DAG);
+ }
}
if (Is64Bit && isVarArg) {
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
// We should use extra load for direct calls to dllimported functions in
// non-JIT mode.
- if (!Subtarget->GVRequiresExtraLoad(G->getGlobal(),
- getTargetMachine(), true))
- Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy(),
- G->getOffset());
+ GlobalValue *GV = G->getGlobal();
+ if (!Subtarget->GVRequiresExtraLoad(GV, getTargetMachine(), true)) {
+ unsigned char OpFlags = 0;
+
+ // On ELF targets, in both X86-64 and X86-32 mode, direct calls to
+ // external symbols most go through the PLT in PIC mode. If the symbol
+ // has hidden or protected visibility, or if it is static or local, then
+ // we don't need to use the PLT - we can directly call it.
+ if (Subtarget->isTargetELF() &&
+ getTargetMachine().getRelocationModel() == Reloc::PIC_ &&
+ GV->hasDefaultVisibility() && !GV->hasLocalLinkage()) {
+ OpFlags = X86II::MO_PLT;
+ } else if (Subtarget->isPICStyleStub() &&
+ (GV->isDeclaration() || GV->isWeakForLinker()) &&
+ Subtarget->getDarwinVers() < 9) {
+ // PC-relative references to external symbols should go through $stub,
+ // unless we're building with the leopard linker or later, which
+ // automatically synthesizes these stubs.
+ OpFlags = X86II::MO_DARWIN_STUB;
+ }
+
+ Callee = DAG.getTargetGlobalAddress(GV, getPointerTy(),
+ G->getOffset(), OpFlags);
+ }
} else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
- Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy());
+ unsigned char OpFlags = 0;
+
+ // On ELF targets, in either X86-64 or X86-32 mode, direct calls to external
+ // symbols should go through the PLT.
+ if (Subtarget->isTargetELF() &&
+ getTargetMachine().getRelocationModel() == Reloc::PIC_) {
+ OpFlags = X86II::MO_PLT;
+ } else if (Subtarget->isPICStyleStub() &&
+ Subtarget->getDarwinVers() < 9) {
+ // PC-relative references to external symbols should go through $stub,
+ // unless we're building with the leopard linker or later, which
+ // automatically synthesizes these stubs.
+ OpFlags = X86II::MO_DARWIN_STUB;
+ }
+
+ Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy(),
+ OpFlags);
} else if (IsTailCall) {
unsigned Opc = Is64Bit ? X86::R11 : X86::EAX;
RegsToPass[i].second.getValueType()));
// Add an implicit use GOT pointer in EBX.
- if (!IsTailCall && !Is64Bit &&
- getTargetMachine().getRelocationModel() == Reloc::PIC_ &&
- Subtarget->isPICStyleGOT())
+ if (!IsTailCall && Subtarget->isPICStyleGOT())
Ops.push_back(DAG.getRegister(X86::EBX, getPointerTy()));
// Add an implicit use of AL for x86 vararg functions.
return false;
if (CheckTailCallReturnConstraints(TheCall, Ret)) {
- MachineFunction &MF = DAG.getMachineFunction();
- unsigned CallerCC = MF.getFunction()->getCallingConv();
- unsigned CalleeCC= TheCall->getCallingConv();
- if (CalleeCC == CallingConv::Fast && CallerCC == CalleeCC) {
- SDValue Callee = TheCall->getCallee();
- // On x86/32Bit PIC/GOT tail calls are supported.
- if (getTargetMachine().getRelocationModel() != Reloc::PIC_ ||
- !Subtarget->isPICStyleGOT()|| !Subtarget->is64Bit())
- return true;
-
- // Can only do local tail calls (in same module, hidden or protected) on
- // x86_64 PIC/GOT at the moment.
- if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
- return G->getGlobal()->hasHiddenVisibility()
- || G->getGlobal()->hasProtectedVisibility();
- }
+ unsigned CallerCC =
+ DAG.getMachineFunction().getFunction()->getCallingConv();
+ unsigned CalleeCC = TheCall->getCallingConv();
+ if (CalleeCC == CallingConv::Fast && CallerCC == CalleeCC)
+ return true;
}
return false;
// global base reg.
unsigned char OpFlag = 0;
unsigned WrapperKind = X86ISD::Wrapper;
- if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
- if (Subtarget->isPICStyleStub())
- OpFlag = X86II::MO_PIC_BASE_OFFSET;
- else if (Subtarget->isPICStyleGOT())
- OpFlag = X86II::MO_GOTOFF;
- else if (Subtarget->isPICStyleRIPRel() &&
- getTargetMachine().getCodeModel() == CodeModel::Small)
- WrapperKind = X86ISD::WrapperRIP;
+
+ if (Subtarget->is64Bit() &&
+ getTargetMachine().getCodeModel() == CodeModel::Small) {
+ WrapperKind = X86ISD::WrapperRIP;
+ } else if (Subtarget->isPICStyleGOT()) {
+ OpFlag = X86II::MO_GOTOFF;
+ } else if (Subtarget->isPICStyleStub() &&
+ getTargetMachine().getRelocationModel() == Reloc::PIC_) {
+ OpFlag = X86II::MO_PIC_BASE_OFFSET;
}
SDValue Result = DAG.getTargetConstantPool(CP->getConstVal(), getPointerTy(),
// global base reg.
unsigned char OpFlag = 0;
unsigned WrapperKind = X86ISD::Wrapper;
- if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
- if (Subtarget->isPICStyleStub())
- OpFlag = X86II::MO_PIC_BASE_OFFSET;
- else if (Subtarget->isPICStyleGOT())
- OpFlag = X86II::MO_GOTOFF;
- else if (Subtarget->isPICStyleRIPRel())
- WrapperKind = X86ISD::WrapperRIP;
+
+ if (Subtarget->is64Bit()) {
+ WrapperKind = X86ISD::WrapperRIP;
+ } else if (Subtarget->isPICStyleGOT()) {
+ OpFlag = X86II::MO_GOTOFF;
+ } else if (Subtarget->isPICStyleStub() &&
+ getTargetMachine().getRelocationModel() == Reloc::PIC_) {
+ OpFlag = X86II::MO_PIC_BASE_OFFSET;
}
SDValue Result = DAG.getTargetJumpTable(JT->getIndex(), getPointerTy(),
// global base reg.
unsigned char OpFlag = 0;
unsigned WrapperKind = X86ISD::Wrapper;
- if (getTargetMachine().getRelocationModel() == Reloc::PIC_) {
- if (Subtarget->isPICStyleStub())
- OpFlag = X86II::MO_PIC_BASE_OFFSET;
- else if (Subtarget->isPICStyleGOT())
- OpFlag = X86II::MO_GOTOFF;
- else if (Subtarget->isPICStyleRIPRel())
- WrapperKind = X86ISD::WrapperRIP;
+ if (Subtarget->is64Bit()) {
+ WrapperKind = X86ISD::WrapperRIP;
+ } else if (Subtarget->isPICStyleGOT()) {
+ OpFlag = X86II::MO_GOTOFF;
+ } else if (Subtarget->isPICStyleStub() &&
+ getTargetMachine().getRelocationModel() == Reloc::PIC_) {
+ OpFlag = X86II::MO_PIC_BASE_OFFSET;
}
SDValue Result = DAG.getTargetExternalSymbol(Sym, getPointerTy(), OpFlag);
// With PIC, the address is actually $g + Offset.
if (getTargetMachine().getRelocationModel() == Reloc::PIC_ &&
- !Subtarget->isPICStyleRIPRel()) {
+ !Subtarget->is64Bit()) {
Result = DAG.getNode(ISD::ADD, DL, getPointerTy(),
DAG.getNode(X86ISD::GlobalBaseReg,
DebugLoc::getUnknownLoc(),
X86TargetLowering::LowerGlobalAddress(const GlobalValue *GV, DebugLoc dl,
int64_t Offset,
SelectionDAG &DAG) const {
- bool IsPic = getTargetMachine().getRelocationModel() == Reloc::PIC_;
+ bool IsPIC = getTargetMachine().getRelocationModel() == Reloc::PIC_;
bool ExtraLoadRequired =
Subtarget->GVRequiresExtraLoad(GV, getTargetMachine(), false);
// Create the TargetGlobalAddress node, folding in the constant
// offset if it is legal.
SDValue Result;
- if (!IsPic && !ExtraLoadRequired && isInt32(Offset)) {
+ if (!IsPIC && !ExtraLoadRequired && isInt32(Offset)) {
+ // A direct static reference to a global.
Result = DAG.getTargetGlobalAddress(GV, getPointerTy(), Offset);
Offset = 0;
} else {
unsigned char OpFlags = 0;
- if (Subtarget->isPICStyleRIPRel() &&
- getTargetMachine().getRelocationModel() != Reloc::Static) {
+ if (GV->hasDLLImportLinkage())
+ OpFlags = X86II::MO_DLLIMPORT;
+ else if (Subtarget->isPICStyleRIPRel()) {
if (ExtraLoadRequired)
OpFlags = X86II::MO_GOTPCREL;
- } else if (Subtarget->isPICStyleGOT() &&
- getTargetMachine().getRelocationModel() == Reloc::PIC_) {
+ } else if (Subtarget->isPICStyleGOT()) {
if (ExtraLoadRequired)
OpFlags = X86II::MO_GOT;
else
OpFlags = X86II::MO_GOTOFF;
+ } else if (Subtarget->isPICStyleStub()) {
+ // In darwin, we have multiple different stub types, and we have both PIC
+ // and -mdynamic-no-pic. Determine whether we have a stub reference
+ // and/or whether the reference is relative to the PIC base or not.
+
+ // Link-once, declaration, or Weakly-linked global variables need
+ // non-lazily-resolved stubs.
+ if (!ExtraLoadRequired) {
+ // Not a stub reference.
+ OpFlags = IsPIC ? X86II::MO_PIC_BASE_OFFSET : 0;
+ } else if (!GV->hasHiddenVisibility()) {
+ // Non-hidden $non_lazy_ptr reference.
+ OpFlags = IsPIC ? X86II::MO_DARWIN_NONLAZY_PIC_BASE :
+ X86II::MO_DARWIN_NONLAZY;
+ } else {
+ // Hidden $non_lazy_ptr reference.
+ OpFlags = IsPIC ? X86II::MO_DARWIN_HIDDEN_NONLAZY_PIC_BASE :
+ X86II::MO_DARWIN_HIDDEN_NONLAZY;
+ }
}
Result = DAG.getTargetGlobalAddress(GV, getPointerTy(), 0, OpFlags);
}
- if (Subtarget->isPICStyleRIPRel() &&
+ if (Subtarget->is64Bit() &&
getTargetMachine().getCodeModel() == CodeModel::Small)
Result = DAG.getNode(X86ISD::WrapperRIP, dl, getPointerTy(), Result);
else
Result = DAG.getNode(X86ISD::Wrapper, dl, getPointerTy(), Result);
// With PIC, the address is actually $g + Offset.
- if (IsPic && !Subtarget->isPICStyleRIPRel()) {
+ if (IsPIC && !Subtarget->is64Bit()) {
Result = DAG.getNode(ISD::ADD, dl, getPointerTy(),
DAG.getNode(X86ISD::GlobalBaseReg, dl, getPointerTy()),
Result);
Args.push_back(Entry);
std::pair<SDValue,SDValue> CallResult =
LowerCallTo(Chain, Type::VoidTy, false, false, false, false,
- CallingConv::C, false,
+ 0, CallingConv::C, false,
DAG.getExternalSymbol(bzeroEntry, IntPtr), Args, DAG, dl);
return CallResult.second;
}
SDValue SrcPtr = Op.getOperand(1);
SDValue SrcSV = Op.getOperand(2);
- assert(0 && "VAArgInst is not yet implemented for x86-64!");
- abort();
+ llvm_report_error("VAArgInst is not yet implemented for x86-64!");
return SDValue();
}
case Intrinsic::x86_mmx_psrai_d:
NewIntNo = Intrinsic::x86_mmx_psra_d;
break;
- default: abort(); // Can't reach here.
+ default: LLVM_UNREACHABLE("Impossible intrinsic"); // Can't reach here.
}
break;
}
InRegCount += (TD->getTypeSizeInBits(*I) + 31) / 32;
if (InRegCount > 2) {
- cerr << "Nest register in use - reduce number of inreg parameters!\n";
- abort();
+ llvm_report_error("Nest register in use - reduce number of inreg parameters!");
}
}
break;
continue;
}
}
-
+
// Otherwise, this isn't something we can handle, reject it.
return;
}
+ // If we require an extra load to get this address, as in PIC mode, we
+ // can't accept it.
+ if (Subtarget->GVRequiresExtraLoad(GA->getGlobal(),
+ getTargetMachine(), false))
+ return;
if (hasMemory)
Op = LowerGlobalAddress(GA->getGlobal(), Op.getDebugLoc(), Offset, DAG);