aboutsummaryrefslogtreecommitdiff
path: root/lib/Target/X86/X86ISelLowering.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/X86/X86ISelLowering.cpp')
-rw-r--r--lib/Target/X86/X86ISelLowering.cpp324
1 files changed, 267 insertions, 57 deletions
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index bc8f8f46d4..ffaf04cea7 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -146,6 +146,12 @@ static TargetLoweringObjectFile *createTLOF(X86TargetMachine &TM) {
if (Subtarget->isTargetLinux())
return new X86LinuxTargetObjectFile();
+
+ // @LOCALMOD-BEGIN
+ if (Subtarget->isTargetNaCl())
+ return new TargetLoweringObjectFileNaCl();
+ // @LOCALMOD-END
+
if (Subtarget->isTargetELF())
return new TargetLoweringObjectFileELF();
if (Subtarget->isTargetCOFF() && !Subtarget->isTargetEnvMacho())
@@ -158,7 +164,9 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
Subtarget = &TM.getSubtarget<X86Subtarget>();
X86ScalarSSEf64 = Subtarget->hasSSE2();
X86ScalarSSEf32 = Subtarget->hasSSE1();
- X86StackPtr = Subtarget->is64Bit() ? X86::RSP : X86::ESP;
+ // @LOCALMOD-START
+ X86StackPtr = Subtarget->has64BitPointers() ? X86::RSP : X86::ESP;
+ // @LOCALMOD-END
RegInfo = TM.getRegisterInfo();
TD = getTargetData();
@@ -535,7 +543,7 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
setOperationAction(ISD::EHSELECTION, MVT::i64, Expand);
setOperationAction(ISD::EXCEPTIONADDR, MVT::i32, Expand);
setOperationAction(ISD::EHSELECTION, MVT::i32, Expand);
- if (Subtarget->is64Bit()) {
+ if (Subtarget->has64BitPointers()) {
setExceptionPointerRegister(X86::RAX);
setExceptionSelectorRegister(X86::RDX);
} else {
@@ -553,7 +561,7 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
// VASTART needs to be custom lowered to use the VarArgsFrameIndex
setOperationAction(ISD::VASTART , MVT::Other, Custom);
setOperationAction(ISD::VAEND , MVT::Other, Expand);
- if (Subtarget->is64Bit()) {
+ if (Subtarget->is64Bit() && !Subtarget->isTargetWin64()) {
setOperationAction(ISD::VAARG , MVT::Other, Custom);
setOperationAction(ISD::VACOPY , MVT::Other, Custom);
} else {
@@ -565,13 +573,16 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand);
if (Subtarget->isTargetCOFF() && !Subtarget->isTargetEnvMacho())
- setOperationAction(ISD::DYNAMIC_STACKALLOC, Subtarget->is64Bit() ?
+ setOperationAction(ISD::DYNAMIC_STACKALLOC,
+ Subtarget->has64BitPointers() ? // @LOCALMOD
MVT::i64 : MVT::i32, Custom);
else if (TM.Options.EnableSegmentedStacks)
- setOperationAction(ISD::DYNAMIC_STACKALLOC, Subtarget->is64Bit() ?
+ setOperationAction(ISD::DYNAMIC_STACKALLOC,
+ Subtarget->has64BitPointers() ? // @LOCALMOD
MVT::i64 : MVT::i32, Custom);
else
- setOperationAction(ISD::DYNAMIC_STACKALLOC, Subtarget->is64Bit() ?
+ setOperationAction(ISD::DYNAMIC_STACKALLOC,
+ Subtarget->has64BitPointers() ? // @LOCALMOD
MVT::i64 : MVT::i32, Expand);
if (!TM.Options.UseSoftFloat && X86ScalarSSEf64) {
@@ -1249,6 +1260,14 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
setTargetDAGCombine(ISD::MUL);
setTargetDAGCombine(ISD::XOR);
+ // @LOCALMOD-BEGIN
+ if (Subtarget->isTargetNaCl()) {
+ setOperationAction(ISD::NACL_TP_TLS_OFFSET, MVT::i32, Custom);
+ setOperationAction(ISD::NACL_TP_TDB_OFFSET, MVT::i32, Custom);
+ setOperationAction(ISD::NACL_TARGET_ARCH, MVT::i32, Custom);
+ }
+ // @LOCALMOD-END
+
computeRegisterProperties();
// On Darwin, -Os means optimize for size without hurting performance,
@@ -1593,7 +1612,16 @@ X86TargetLowering::LowerReturn(SDValue Chain,
"SRetReturnReg should have been set in LowerFormalArguments().");
SDValue Val = DAG.getCopyFromReg(Chain, dl, Reg, getPointerTy());
- Chain = DAG.getCopyToReg(Chain, dl, X86::RAX, Val, Flag);
+ // @LOCALMOD-START
+ if (Subtarget->isTargetNaCl()) {
+ // NaCl 64 uses 32-bit pointers, so there might be some zero-ext needed.
+ SDValue Zext = DAG.getZExtOrTrunc(Val, dl, MVT::i64);
+ Chain = DAG.getCopyToReg(Chain, dl, X86::RAX, Zext, Flag);
+ } else {
+ Chain = DAG.getCopyToReg(Chain, dl, X86::RAX, Val, Flag);
+ }
+ // @LOCALMOD-END
+
Flag = Chain.getValue(1);
// RAX now acts like a return value.
@@ -1863,6 +1891,18 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain,
Fn->getName() == "main")
FuncInfo->setForceFramePointer(true);
+ // @LOCALMOD-START
+ if (Subtarget->isTargetNaCl64()) {
+ FuncInfo->setForceFramePointer(true);
+ }
+ // @TODO(pdox): This shouldn't be necessary, but there is a bug
+ // where hasFP() changes during stack-slot spilling after register
+ // allocation has allocated ebp. Look into this.
+ if (Subtarget->isTargetNaCl32()) {
+ FuncInfo->setForceFramePointer(true);
+ }
+ // @LOCALMOD-END
+
MachineFrameInfo *MFI = MF.getFrameInfo();
bool Is64Bit = Subtarget->is64Bit();
bool IsWindows = Subtarget->isTargetWindows();
@@ -1957,7 +1997,9 @@ X86TargetLowering::LowerFormalArguments(SDValue Chain,
X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
unsigned Reg = FuncInfo->getSRetReturnReg();
if (!Reg) {
- Reg = MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i64));
+ // @LOCALMOD
+ Reg = MF.getRegInfo().createVirtualRegister(
+ getRegClassFor(getPointerTy()));
FuncInfo->setSRetReturnReg(Reg);
}
SDValue Copy = DAG.getCopyToReg(DAG.getEntryNode(), dl, Reg, InVals[0]);
@@ -2647,7 +2689,8 @@ X86TargetLowering::GetAlignedArgumentStackSize(unsigned StackSize,
unsigned StackAlignment = TFI.getStackAlignment();
uint64_t AlignMask = StackAlignment - 1;
int64_t Offset = StackSize;
- uint64_t SlotSize = TD->getPointerSize();
+ // @LOCALMOD
+ uint64_t SlotSize = Subtarget->is64Bit() ? 8 : 4;
if ( (Offset & AlignMask) <= (StackAlignment - SlotSize) ) {
// Number smaller than 12 so just add the difference.
Offset += ((StackAlignment - SlotSize) - (Offset & AlignMask));
@@ -3015,13 +3058,14 @@ SDValue X86TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const {
if (ReturnAddrIndex == 0) {
// Set up a frame object for the return address.
- uint64_t SlotSize = TD->getPointerSize();
+ uint64_t SlotSize = Subtarget->is64Bit() ? 8 : 4; // @LOCALMOD
ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize,
false);
FuncInfo->setRAIndex(ReturnAddrIndex);
}
- return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy());
+ return DAG.getFrameIndex(ReturnAddrIndex, // @LOCALMOD
+ Subtarget->is64Bit() ? MVT::i64 : MVT::i32);
}
@@ -7460,7 +7504,8 @@ X86TargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) const {
static SDValue
GetTLSADDR(SelectionDAG &DAG, SDValue Chain, GlobalAddressSDNode *GA,
SDValue *InFlag, const EVT PtrVT, unsigned ReturnReg,
- unsigned char OperandFlags, bool LocalDynamic = false) {
+ unsigned char OperandFlags,
+ unsigned Opcode = X86ISD::TLSADDR) { // @LOCALMOD
MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
DebugLoc dl = GA->getDebugLoc();
@@ -7468,16 +7513,12 @@ GetTLSADDR(SelectionDAG &DAG, SDValue Chain, GlobalAddressSDNode *GA,
GA->getValueType(0),
GA->getOffset(),
OperandFlags);
-
- X86ISD::NodeType CallType = LocalDynamic ? X86ISD::TLSBASEADDR
- : X86ISD::TLSADDR;
-
if (InFlag) {
SDValue Ops[] = { Chain, TGA, *InFlag };
- Chain = DAG.getNode(CallType, dl, NodeTys, Ops, 3);
+ Chain = DAG.getNode(Opcode, dl, NodeTys, Ops, 3); // @LOCALMOD
} else {
SDValue Ops[] = { Chain, TGA };
- Chain = DAG.getNode(CallType, dl, NodeTys, Ops, 2);
+ Chain = DAG.getNode(Opcode, dl, NodeTys, Ops, 2); // @LOCALMOD
}
// TLSADDR will be codegen'ed as call. Inform MFI that function has calls.
@@ -7509,6 +7550,52 @@ LowerToTLSGeneralDynamicModel64(GlobalAddressSDNode *GA, SelectionDAG &DAG,
X86::RAX, X86II::MO_TLSGD);
}
+// Lower ISD::GlobalTLSAddress using the "initial exec" or "local exec" model.
+static SDValue
+LowerToTLSExecCall(GlobalAddressSDNode *GA, SelectionDAG &DAG,
+ const EVT PtrVT, TLSModel::Model model, bool is64Bit) {
+
+ // See: http://code.google.com/p/nativeclient/issues/detail?id=1685
+ unsigned char TargetFlag;
+ unsigned Opcode;
+ if (model == TLSModel::LocalExec) {
+ TargetFlag = is64Bit ? X86II::MO_TPOFF : X86II::MO_NTPOFF;
+ Opcode = X86ISD::TLSADDR_LE;
+ } else if (model == TLSModel::InitialExec) {
+ TargetFlag = is64Bit ? X86II::MO_GOTTPOFF : X86II::MO_INDNTPOFF;
+ Opcode = X86ISD::TLSADDR_IE;
+ } else {
+ llvm_unreachable("Unknown TLS model");
+ }
+
+ return GetTLSADDR(DAG, DAG.getEntryNode(), GA, NULL, PtrVT,
+ X86::EAX, // PtrVT is 32-bit.
+ TargetFlag, Opcode);
+}
+
+// @LOCALMOD-START
+// Lower TLS accesses to a function call, rather than use segment registers.
+// Lower ISD::GlobalTLSAddress for NaCl 64 bit.
+static SDValue
+LowerToTLSNaCl64(GlobalAddressSDNode *GA, SelectionDAG &DAG,
+ const EVT PtrVT, TLSModel::Model model) {
+
+ // See: http://code.google.com/p/nativeclient/issues/detail?id=1685
+ unsigned char TargetFlag;
+ unsigned Opcode;
+ if (model == TLSModel::GeneralDynamic || model == TLSModel::LocalDynamic) {
+ TargetFlag = X86II::MO_TLSGD;
+ Opcode = X86ISD::TLSADDR;
+ } else {
+ return LowerToTLSExecCall(GA, DAG, PtrVT, model, true);
+ }
+
+ return GetTLSADDR(DAG, DAG.getEntryNode(), GA, NULL, PtrVT,
+ X86::EAX, // PtrVT is 32-bit.
+ TargetFlag, Opcode);
+}
+// @LOCALMOD-END
+
static SDValue LowerToTLSLocalDynamicModel(GlobalAddressSDNode *GA,
SelectionDAG &DAG,
const EVT PtrVT,
@@ -7523,14 +7610,16 @@ static SDValue LowerToTLSLocalDynamicModel(GlobalAddressSDNode *GA,
SDValue Base;
if (is64Bit) {
Base = GetTLSADDR(DAG, DAG.getEntryNode(), GA, NULL, PtrVT, X86::RAX,
- X86II::MO_TLSLD, /*LocalDynamic=*/true);
+ X86II::MO_TLSLD,
+ /*Opcode=*/X86ISD::TLSBASEADDR); // @LOCALMOD
} else {
SDValue InFlag;
SDValue Chain = DAG.getCopyToReg(DAG.getEntryNode(), dl, X86::EBX,
DAG.getNode(X86ISD::GlobalBaseReg, DebugLoc(), PtrVT), InFlag);
InFlag = Chain.getValue(1);
Base = GetTLSADDR(DAG, Chain, GA, &InFlag, PtrVT, X86::EAX,
- X86II::MO_TLSLDM, /*LocalDynamic=*/true);
+ X86II::MO_TLSLDM,
+ /*Opcode=*/X86ISD::TLSBASEADDR); // @LOCALMOD
}
// Note: the CleanupLocalDynamicTLSPass will remove redundant computations
@@ -7614,6 +7703,11 @@ X86TargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {
if (Subtarget->isTargetELF()) {
TLSModel::Model model = getTargetMachine().getTLSModel(GV);
+ // @LOCALMOD-START
+ if (Subtarget->isTargetNaCl64())
+ return LowerToTLSNaCl64(GA, DAG, getPointerTy(), model);
+ // @LOCALMOD-END
+
switch (model) {
case TLSModel::GeneralDynamic:
if (Subtarget->is64Bit())
@@ -7624,9 +7718,16 @@ X86TargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {
Subtarget->is64Bit());
case TLSModel::InitialExec:
case TLSModel::LocalExec:
- return LowerToTLSExecModel(GA, DAG, getPointerTy(), model,
+ // @LOCALMOD-START
+ if (llvm::TLSUseCall) {
+ return LowerToTLSExecCall(GA, DAG, getPointerTy(), model,
+ Subtarget->is64Bit());
+ } else {
+ return LowerToTLSExecModel(GA, DAG, getPointerTy(), model,
Subtarget->is64Bit(),
getTargetMachine().getRelocationModel() == Reloc::PIC_);
+ }
+ // @LOCALMOD-END
}
llvm_unreachable("Unknown TLS model.");
}
@@ -8476,13 +8577,31 @@ SDValue X86TargetLowering::EmitTest(SDValue Op, unsigned X86CC,
break;
}
+ // @LOCALMOD-BEGIN
+ // This function only peeks at the data dependencies of the DAG to find
+ // an arith op that also defines EFLAGS. However, function calls may
+ // clobber EFLAGS and the data dependencies do not show that.
+ // When that occurs, EFLAGS must be copied via PUSHF and POPF.
+ // The problem is that NaCl does not allow PUSHF and POPF.
+ // We could try to detect such clobbers for NaCl, but for now, we
+ // keep this code simple, and bail out for NaCl. A further
+ // PeepholeOptimizer pass can do a similar optimization
+ // (see optimizeCompareInstr in X86InstrInfo.cpp), so it's not *so*
+ // bad. This function also converts "add op, -1" to DEC, which can
+ // help fold load/stores:
+ // (store m, (add (load m), -1)) -> (dec m)
+ // So we lose out on that.
+ // BUG=http://code.google.com/p/nativeclient/issues/detail?id=2711
+ bool ConservativeForNaCl = Subtarget->isTargetNaCl();
+
// See if we can use the EFLAGS value from the operand instead of
// doing a separate TEST. TEST always sets OF and CF to 0, so unless
// we prove that the arithmetic won't overflow, we can't use OF or CF.
- if (Op.getResNo() != 0 || NeedOF || NeedCF)
+ if (Op.getResNo() != 0 || NeedOF || NeedCF || ConservativeForNaCl)
// Emit a CMP with 0, which is the TEST pattern.
return DAG.getNode(X86ISD::CMP, dl, MVT::i32, Op,
DAG.getConstant(0, Op.getValueType()));
+ // @LOCALMOD-END
unsigned Opcode = 0;
unsigned NumOperands = 0;
@@ -8712,6 +8831,10 @@ SDValue X86TargetLowering::ConvertCmpIfNecessary(SDValue Cmp,
/// if it's possible.
SDValue X86TargetLowering::LowerToBT(SDValue And, ISD::CondCode CC,
DebugLoc dl, SelectionDAG &DAG) const {
+ // @LOCALMOD: NaCl validator rejects BT, BTS, and BTC.
+ if (Subtarget->isTargetNaCl())
+ return SDValue();
+
SDValue Op0 = And.getOperand(0);
SDValue Op1 = And.getOperand(1);
if (Op0.getOpcode() == ISD::TRUNCATE)
@@ -9528,14 +9651,14 @@ X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
SDValue Size = Op.getOperand(1);
// FIXME: Ensure alignment here
- bool Is64Bit = Subtarget->is64Bit();
- EVT SPTy = Is64Bit ? MVT::i64 : MVT::i32;
+ bool Has64BitPointers = Subtarget->has64BitPointers(); // @LOCALMOD
+ EVT SPTy = Has64BitPointers ? MVT::i64 : MVT::i32; // @LOCALMOD
if (getTargetMachine().Options.EnableSegmentedStacks) {
MachineFunction &MF = DAG.getMachineFunction();
MachineRegisterInfo &MRI = MF.getRegInfo();
- if (Is64Bit) {
+ if (Subtarget->is64Bit()) { // @LOCALMOD
// The 64 bit implementation of segmented stacks needs to clobber both r10
// r11. This makes it impossible to use it along with nested parameters.
const Function *F = MF.getFunction();
@@ -9548,7 +9671,7 @@ X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
}
const TargetRegisterClass *AddrRegClass =
- getRegClassFor(Subtarget->is64Bit() ? MVT::i64:MVT::i32);
+ getRegClassFor(Has64BitPointers ? MVT::i64:MVT::i32); // @LOCALMOD
unsigned Vreg = MRI.createVirtualRegister(AddrRegClass);
Chain = DAG.getCopyToReg(Chain, dl, Vreg, Size);
SDValue Value = DAG.getNode(X86ISD::SEG_ALLOCA, dl, SPTy, Chain,
@@ -9557,7 +9680,7 @@ X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
return DAG.getMergeValues(Ops1, 2, dl);
} else {
SDValue Flag;
- unsigned Reg = (Subtarget->is64Bit() ? X86::RAX : X86::EAX);
+ unsigned Reg = (Has64BitPointers ? X86::RAX : X86::EAX); // @LOCALMOD
Chain = DAG.getCopyToReg(Chain, dl, Reg, Size, Flag);
Flag = Chain.getValue(1);
@@ -9594,6 +9717,7 @@ SDValue X86TargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {
// fp_offset (48 - 48 + 8 * 16)
// overflow_arg_area (point to parameters coming in memory).
// reg_save_area
+ unsigned PointerSize = TD->getPointerSize(); // @LOCALMOD
SmallVector<SDValue, 8> MemOps;
SDValue FIN = Op.getOperand(1);
// Store gp_offset
@@ -9616,7 +9740,7 @@ SDValue X86TargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {
FIN = DAG.getNode(ISD::ADD, DL, getPointerTy(),
FIN, DAG.getIntPtrConstant(4));
SDValue OVFIN = DAG.getFrameIndex(FuncInfo->getVarArgsFrameIndex(),
- getPointerTy());
+ getPointerTy()); // @LOCALMOD
Store = DAG.getStore(Op.getOperand(0), DL, OVFIN, FIN,
MachinePointerInfo(SV, 8),
false, false, 0);
@@ -9624,11 +9748,12 @@ SDValue X86TargetLowering::LowerVASTART(SDValue Op, SelectionDAG &DAG) const {
// Store ptr to reg_save_area.
FIN = DAG.getNode(ISD::ADD, DL, getPointerTy(),
- FIN, DAG.getIntPtrConstant(8));
+ FIN, DAG.getIntPtrConstant(PointerSize)); // @LOCALMOD
SDValue RSFIN = DAG.getFrameIndex(FuncInfo->getRegSaveFrameIndex(),
- getPointerTy());
+ getPointerTy()); // @LOCALMOD
Store = DAG.getStore(Op.getOperand(0), DL, RSFIN, FIN,
- MachinePointerInfo(SV, 16), false, false, 0);
+ MachinePointerInfo(SV, 8+PointerSize), // @LOCALMOD
+ false, false, 0);
MemOps.push_back(Store);
return DAG.getNode(ISD::TokenFactor, DL, MVT::Other,
&MemOps[0], MemOps.size());
@@ -9638,7 +9763,8 @@ SDValue X86TargetLowering::LowerVAARG(SDValue Op, SelectionDAG &DAG) const {
assert(Subtarget->is64Bit() &&
"LowerVAARG only handles 64-bit va_arg!");
assert((Subtarget->isTargetLinux() ||
- Subtarget->isTargetDarwin()) &&
+ Subtarget->isTargetDarwin() ||
+ Subtarget->isTargetNaCl()) && // @LOCALMOD
"Unhandled target in LowerVAARG");
assert(Op.getNode()->getNumOperands() == 4);
SDValue Chain = Op.getOperand(0);
@@ -9712,11 +9838,56 @@ static SDValue LowerVACOPY(SDValue Op, const X86Subtarget *Subtarget,
DebugLoc DL = Op.getDebugLoc();
return DAG.getMemcpy(Chain, DL, DstPtr, SrcPtr,
- DAG.getIntPtrConstant(24), 8, /*isVolatile*/false,
+ // @LOCALMOD-START
+ // Size is actually 8 + 2 * pointer size and align
+ // is the pointer ABI alignment but we don't have a
+ // pointer to TD in this static function
+ DAG.getIntPtrConstant(Subtarget->has64BitPointers() ?
+ 24 : 16),
+ Subtarget->has64BitPointers() ? 8 : 4,
+ /*isVolatile*/false,
+ // @LOCALMOD-END
false,
MachinePointerInfo(DstSV), MachinePointerInfo(SrcSV));
}
+//////////////////////////////////////////////////////////////////////
+// NaCl TLS setup / layout intrinsics.
+// See: native_client/src/untrusted/stubs/tls_params.h
+SDValue X86TargetLowering::LowerNaClTpTlsOffset(SDValue Op,
+ SelectionDAG &DAG) const {
+ // ssize_t __nacl_tp_tls_offset (size_t tls_size) {
+ // return -tls_size;
+ // }
+ DebugLoc dl = Op.getDebugLoc();
+ return DAG.getNode(ISD::SUB, dl, Op.getValueType().getSimpleVT(),
+ DAG.getConstant(0, Op.getValueType().getSimpleVT()),
+ Op.getOperand(0));
+}
+
+SDValue X86TargetLowering::LowerNaClTpTdbOffset(SDValue Op,
+ SelectionDAG &DAG) const {
+ // ssize_t __nacl_tp_tdb_offset (size_t tdb_size) {
+ // return 0;
+ // }
+ return DAG.getConstant(0, Op.getValueType().getSimpleVT());
+}
+
+SDValue
+X86TargetLowering::LowerNaClTargetArch(SDValue Op, SelectionDAG &DAG) const {
+ // int __nacl_target_arch () {
+ // return (is_64_bit ?
+ // PnaclTargetArchitectureX86_64 :
+ // PnaclTargetArchitectureX86_32);
+ // }
+ return DAG.getConstant((Subtarget->is64Bit() ?
+ PnaclTargetArchitectureX86_64 :
+ PnaclTargetArchitectureX86_32),
+ Op.getValueType().getSimpleVT());
+}
+
+//////////////////////////////////////////////////////////////////////
+
// getTargetVShiftNOde - Handle vector element shifts where the shift amount
// may or may not be a constant. Takes immediate version of shift as input.
static SDValue getTargetVShiftNode(unsigned Opc, DebugLoc dl, EVT VT,
@@ -10341,8 +10512,10 @@ SDValue X86TargetLowering::LowerRETURNADDR(SDValue Op,
if (Depth > 0) {
SDValue FrameAddr = LowerFRAMEADDR(Op, DAG);
SDValue Offset =
- DAG.getConstant(TD->getPointerSize(),
- Subtarget->is64Bit() ? MVT::i64 : MVT::i32);
+ // @LOCALMOD-BEGIN
+ DAG.getConstant(Subtarget->is64Bit() ? 8 : 4,
+ getPointerTy());
+ // @LOCALMOD-END
return DAG.getLoad(getPointerTy(), dl, DAG.getEntryNode(),
DAG.getNode(ISD::ADD, dl, getPointerTy(),
FrameAddr, Offset),
@@ -10362,7 +10535,7 @@ SDValue X86TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
EVT VT = Op.getValueType();
DebugLoc dl = Op.getDebugLoc(); // FIXME probably not meaningful
unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
- unsigned FrameReg = Subtarget->is64Bit() ? X86::RBP : X86::EBP;
+ unsigned FrameReg = Subtarget->has64BitPointers() ? X86::RBP : X86::EBP; // @LOCALMOD
SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, VT);
while (Depth--)
FrameAddr = DAG.getLoad(VT, dl, DAG.getEntryNode(), FrameAddr,
@@ -10373,7 +10546,10 @@ SDValue X86TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
SDValue X86TargetLowering::LowerFRAME_TO_ARGS_OFFSET(SDValue Op,
SelectionDAG &DAG) const {
- return DAG.getIntPtrConstant(2*TD->getPointerSize());
+ // @LOCALMOD-START
+ int SlotSize = Subtarget->is64Bit() ? 8 : 4;
+ return DAG.getIntPtrConstant(2*SlotSize);
+ // @LOCALMOD-END
}
SDValue X86TargetLowering::LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const {
@@ -10381,14 +10557,17 @@ SDValue X86TargetLowering::LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const {
SDValue Offset = Op.getOperand(1);
SDValue Handler = Op.getOperand(2);
DebugLoc dl = Op.getDebugLoc();
+ // @LOCALMOD-START
+ bool Has64BitPtrs = Subtarget->has64BitPointers();
SDValue Frame = DAG.getCopyFromReg(DAG.getEntryNode(), dl,
- Subtarget->is64Bit() ? X86::RBP : X86::EBP,
+ Has64BitPtrs ? X86::RBP : X86::EBP,
getPointerTy());
- unsigned StoreAddrReg = (Subtarget->is64Bit() ? X86::RCX : X86::ECX);
-
+ unsigned StoreAddrReg = (Has64BitPtrs ? X86::RCX : X86::ECX);
+ int SlotSize = Subtarget->is64Bit() ? 8 : 4;
SDValue StoreAddr = DAG.getNode(ISD::ADD, dl, getPointerTy(), Frame,
- DAG.getIntPtrConstant(TD->getPointerSize()));
+ DAG.getIntPtrConstant(SlotSize));
+ // @LOCALMOD-END
StoreAddr = DAG.getNode(ISD::ADD, dl, getPointerTy(), StoreAddr, Offset);
Chain = DAG.getStore(Chain, dl, Handler, StoreAddr, MachinePointerInfo(),
false, false, 0);
@@ -11445,6 +11624,11 @@ SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
case ISD::SUBE: return LowerADDC_ADDE_SUBC_SUBE(Op, DAG);
case ISD::ADD: return LowerADD(Op, DAG);
case ISD::SUB: return LowerSUB(Op, DAG);
+ // @LOCALMOD-BEGIN
+ case ISD::NACL_TP_TLS_OFFSET: return LowerNaClTpTlsOffset(Op, DAG);
+ case ISD::NACL_TP_TDB_OFFSET: return LowerNaClTpTdbOffset(Op, DAG);
+ case ISD::NACL_TARGET_ARCH: return LowerNaClTargetArch(Op, DAG);
+ // @LOCALMOD-END
}
}
@@ -11707,6 +11891,8 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
case X86ISD::FRCP: return "X86ISD::FRCP";
case X86ISD::TLSADDR: return "X86ISD::TLSADDR";
case X86ISD::TLSBASEADDR: return "X86ISD::TLSBASEADDR";
+ case X86ISD::TLSADDR_LE: return "X86ISD::TLSADDR_LE"; // @LOCALMOD
+ case X86ISD::TLSADDR_IE: return "X86ISD::TLSADDR_IE"; // @LOCALMOD
case X86ISD::TLSCALL: return "X86ISD::TLSCALL";
case X86ISD::EH_RETURN: return "X86ISD::EH_RETURN";
case X86ISD::TC_RETURN: return "X86ISD::TC_RETURN";
@@ -12619,9 +12805,11 @@ X86TargetLowering::EmitVAARG64WithCustomInserter(
MachineInstr::mmo_iterator MMOEnd = MI->memoperands_end();
// Machine Information
+ bool IsNaCl = Subtarget->isTargetNaCl(); // @LOCALMOD
const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
MachineRegisterInfo &MRI = MBB->getParent()->getRegInfo();
- const TargetRegisterClass *AddrRegClass = getRegClassFor(MVT::i64);
+ const TargetRegisterClass *AddrRegClass =
+ getRegClassFor(getPointerTy()); // @LOCALMOD
const TargetRegisterClass *OffsetRegClass = getRegClassFor(MVT::i32);
DebugLoc DL = MI->getDebugLoc();
@@ -12649,7 +12837,7 @@ X86TargetLowering::EmitVAARG64WithCustomInserter(
MachineBasicBlock *overflowMBB;
MachineBasicBlock *offsetMBB;
MachineBasicBlock *endMBB;
-
+
unsigned OffsetDestReg = 0; // Argument address computed by offsetMBB
unsigned OverflowDestReg = 0; // Argument address computed by overflowMBB
unsigned OffsetReg = 0;
@@ -12730,29 +12918,39 @@ X86TargetLowering::EmitVAARG64WithCustomInserter(
}
// In offsetMBB, emit code to use the reg_save_area.
+ unsigned Opc; // @LOCALMOD
if (offsetMBB) {
assert(OffsetReg != 0);
// Read the reg_save_area address.
unsigned RegSaveReg = MRI.createVirtualRegister(AddrRegClass);
- BuildMI(offsetMBB, DL, TII->get(X86::MOV64rm), RegSaveReg)
+ Opc = IsNaCl ? X86::MOV32rm : X86::MOV64rm; // @LOCALMOD
+ BuildMI(offsetMBB, DL, TII->get(Opc), RegSaveReg) // @LOCALMOD
.addOperand(Base)
.addOperand(Scale)
.addOperand(Index)
- .addDisp(Disp, 16)
+ .addDisp(Disp, 8+TD->getPointerSize()) // @LOCALMOD
.addOperand(Segment)
.setMemRefs(MMOBegin, MMOEnd);
// Zero-extend the offset
- unsigned OffsetReg64 = MRI.createVirtualRegister(AddrRegClass);
- BuildMI(offsetMBB, DL, TII->get(X86::SUBREG_TO_REG), OffsetReg64)
- .addImm(0)
- .addReg(OffsetReg)
- .addImm(X86::sub_32bit);
+ // @LOCALMOD-BEGIN
+ unsigned OffsetRegExt;
+ if (IsNaCl) {
+ OffsetRegExt = OffsetReg;
+ } else {
+ OffsetRegExt = MRI.createVirtualRegister(AddrRegClass);
+ BuildMI(offsetMBB, DL, TII->get(X86::SUBREG_TO_REG), OffsetRegExt)
+ .addImm(0)
+ .addReg(OffsetReg)
+ .addImm(X86::sub_32bit);
+ }
+ // @LOCALMOD-END
// Add the offset to the reg_save_area to get the final address.
- BuildMI(offsetMBB, DL, TII->get(X86::ADD64rr), OffsetDestReg)
- .addReg(OffsetReg64)
+ Opc = IsNaCl ? X86::ADD32rr : X86::ADD64rr; // @LOCALMOD
+ BuildMI(offsetMBB, DL, TII->get(Opc), OffsetDestReg)
+ .addReg(OffsetRegExt) // @LOCALMOD
.addReg(RegSaveReg);
// Compute the offset for the next argument
@@ -12782,7 +12980,8 @@ X86TargetLowering::EmitVAARG64WithCustomInserter(
// Load the overflow_area address into a register.
unsigned OverflowAddrReg = MRI.createVirtualRegister(AddrRegClass);
- BuildMI(overflowMBB, DL, TII->get(X86::MOV64rm), OverflowAddrReg)
+ Opc = IsNaCl ? X86::MOV32rm : X86::MOV64rm; // @LOCALMOD
+ BuildMI(overflowMBB, DL, TII->get(Opc), OverflowAddrReg)
.addOperand(Base)
.addOperand(Scale)
.addOperand(Index)
@@ -12798,11 +12997,13 @@ X86TargetLowering::EmitVAARG64WithCustomInserter(
unsigned TmpReg = MRI.createVirtualRegister(AddrRegClass);
// aligned_addr = (addr + (align-1)) & ~(align-1)
- BuildMI(overflowMBB, DL, TII->get(X86::ADD64ri32), TmpReg)
+ Opc = IsNaCl ? X86::ADD32ri : X86::ADD64ri32; // @LOCALMOD
+ BuildMI(overflowMBB, DL, TII->get(Opc), TmpReg)
.addReg(OverflowAddrReg)
.addImm(Align-1);
- BuildMI(overflowMBB, DL, TII->get(X86::AND64ri32), OverflowDestReg)
+ Opc = IsNaCl ? X86::AND32ri : X86::AND64ri32; // @LOCALMOD
+ BuildMI(overflowMBB, DL, TII->get(Opc), OverflowDestReg)
.addReg(TmpReg)
.addImm(~(uint64_t)(Align-1));
} else {
@@ -12813,12 +13014,14 @@ X86TargetLowering::EmitVAARG64WithCustomInserter(
// Compute the next overflow address after this argument.
// (the overflow address should be kept 8-byte aligned)
unsigned NextAddrReg = MRI.createVirtualRegister(AddrRegClass);
- BuildMI(overflowMBB, DL, TII->get(X86::ADD64ri32), NextAddrReg)
+ Opc = IsNaCl ? X86::ADD32ri : X86::ADD64ri32; // @LOCALMOD
+ BuildMI(overflowMBB, DL, TII->get(Opc), NextAddrReg)
.addReg(OverflowDestReg)
.addImm(ArgSizeA8);
// Store the new overflow address.
- BuildMI(overflowMBB, DL, TII->get(X86::MOV64mr))
+ Opc = IsNaCl ? X86::MOV32mr : X86::MOV64mr; // @LOCALMOD
+ BuildMI(overflowMBB, DL, TII->get(Opc))
.addOperand(Base)
.addOperand(Scale)
.addOperand(Index)
@@ -13466,6 +13669,7 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
return EmitVAStartSaveXMMRegsWithCustomInserter(MI, BB);
case X86::VAARG_64:
+ case X86::NACL_CG_VAARG_64:
return EmitVAARG64WithCustomInserter(MI, BB);
}
}
@@ -15095,6 +15299,12 @@ static SDValue PerformOrCombine(SDNode *N, SelectionDAG &DAG,
}
unsigned Bits = VT.getSizeInBits();
+ // @LOCALMOD-START
+ // Due to a limitation in NaCl's 32-bit validator,
+ // 16-bit shld instructions are illegal in 32-bit NaCl.
+ if (Subtarget->isTargetNaCl() && !Subtarget->is64Bit() && Bits == 16)
+ return SDValue();
+ // @LOCALMOD-END
if (ShAmt1.getOpcode() == ISD::SUB) {
SDValue Sum = ShAmt1.getOperand(0);
if (ConstantSDNode *SumC = dyn_cast<ConstantSDNode>(Sum)) {