Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(704)

Unified Diff: lib/Target/X86/X86ISelLowering.cpp

Side-by-side diff isn't available for this file because of its large size.
Issue 939073008: Rebased PNaCl localmods in LLVM to 223109 (Closed)
Patch Set: undo localmod Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
Download patch
« no previous file with comments | « lib/Target/X86/X86ISelLowering.h ('k') | lib/Target/X86/X86InstrCompiler.td » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/Target/X86/X86ISelLowering.cpp
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index 7faa58cf377071749e58f215b7bcf7d1adb0913b..88d7ffaf10f0c636049bfa99f2bd3b9445d2b333 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -206,6 +206,10 @@ X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM)
Subtarget = &TM.getSubtarget<X86Subtarget>();
X86ScalarSSEf64 = Subtarget->hasSSE2();
X86ScalarSSEf32 = Subtarget->hasSSE1();
+ // @LOCALMOD-START
+ X86StackPtr = Subtarget->isTarget64BitLP64() ? X86::RSP : X86::ESP;
+ // @LOCALMOD-END
+
TD = getDataLayout();
resetOperationActions();
@@ -246,7 +250,8 @@ void X86TargetLowering::resetOperationActions() {
setSchedulingPreference(Sched::RegPressure);
const X86RegisterInfo *RegInfo =
TM.getSubtarget<X86Subtarget>().getRegisterInfo();
- setStackPointerRegisterToSaveRestore(RegInfo->getStackRegister());
+ (void)RegInfo; // @LOCALMOD
+ setStackPointerRegisterToSaveRestore(X86StackPtr); // @LOCALMOD
// Bypass expensive divides on Atom when compiling with O2
if (TM.getOptLevel() >= CodeGenOpt::Default) {
@@ -620,7 +625,7 @@ void X86TargetLowering::resetOperationActions() {
setOperationAction(ISD::EH_LABEL, MVT::Other, Expand);
}
- if (Subtarget->is64Bit()) {
+ if (Subtarget->has64BitPointers()) { // @LOCALMOD
setExceptionPointerRegister(X86::RAX);
setExceptionSelectorRegister(X86::RDX);
} else {
@@ -2073,7 +2078,17 @@ X86TargetLowering::LowerReturn(SDValue Chain,
unsigned RetValReg
= (Subtarget->is64Bit() && !Subtarget->isTarget64BitILP32()) ?
X86::RAX : X86::EAX;
- Chain = DAG.getCopyToReg(Chain, dl, RetValReg, Val, Flag);
+
+ // @LOCALMOD-BEGIN
+ if (Subtarget->isTargetNaCl()) {
+ RetValReg = Subtarget->isTarget64BitILP32() ? X86::EAX : X86::RAX;
+ // 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, RetValReg, Val, Flag);
+ }
+ // @LOCALMOD-END
Flag = Chain.getValue(1);
// RAX/EAX now acts like a return value.
@@ -2904,7 +2919,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
} else if (!IsSibcall && (!isTailCall || isByVal)) {
assert(VA.isMemLoc());
if (!StackPtr.getNode())
- StackPtr = DAG.getCopyFromReg(Chain, dl, RegInfo->getStackRegister(),
+ StackPtr = DAG.getCopyFromReg(Chain, dl, X86StackPtr, // @LOCALMOD
getPointerTy());
MemOpChains.push_back(LowerMemOpCallTo(Chain, StackPtr, Arg,
dl, DAG, VA, Flags));
@@ -3005,7 +3020,7 @@ X86TargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI,
SDValue Source = DAG.getIntPtrConstant(VA.getLocMemOffset());
if (!StackPtr.getNode())
StackPtr = DAG.getCopyFromReg(Chain, dl,
- RegInfo->getStackRegister(),
+ X86StackPtr, // @LOCALMOD
getPointerTy());
Source = DAG.getNode(ISD::ADD, dl, getPointerTy(), StackPtr, Source);
@@ -3635,7 +3650,8 @@ SDValue X86TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) const {
FuncInfo->setRAIndex(ReturnAddrIndex);
}
- return DAG.getFrameIndex(ReturnAddrIndex, getPointerTy());
+ return DAG.getFrameIndex(ReturnAddrIndex, // @LOCALMOD
+ Subtarget->is64Bit() ? MVT::i64 : MVT::i32);
}
bool X86::isOffsetSuitableForCodeModel(int64_t Offset, CodeModel::Model M,
@@ -13198,7 +13214,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, bool LocalDynamic = false,
+ unsigned Opcode = ISD::DELETED_NODE) { // @LOCALMOD
MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue);
SDLoc dl(GA);
@@ -13207,8 +13224,15 @@ GetTLSADDR(SelectionDAG &DAG, SDValue Chain, GlobalAddressSDNode *GA,
GA->getOffset(),
OperandFlags);
- X86ISD::NodeType CallType = LocalDynamic ? X86ISD::TLSBASEADDR
- : X86ISD::TLSADDR;
+ // @LOCALMOD - changed type for casting
+ unsigned CallType = LocalDynamic ? X86ISD::TLSBASEADDR
+ : X86ISD::TLSADDR;
+
+ // @LOCALMOD-START
+ // If Opcode was explicitly overridden, use it as the call type.
+ if (Opcode != ISD::DELETED_NODE)
+ CallType = Opcode;
+ // @LOCALMOD-END
if (InFlag) {
SDValue Ops[] = { Chain, TGA, *InFlag };
@@ -13248,6 +13272,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, false, 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, false, Opcode);
+}
+// @LOCALMOD-END
+
static SDValue LowerToTLSLocalDynamicModel(GlobalAddressSDNode *GA,
SelectionDAG &DAG,
const EVT PtrVT,
@@ -13351,6 +13421,11 @@ X86TargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {
if (Subtarget->isTargetELF()) {
TLSModel::Model model = DAG.getTarget().getTLSModel(GV);
+ // @LOCALMOD-START
+ if (Subtarget->isTargetNaCl64())
+ return LowerToTLSNaCl64(GA, DAG, getPointerTy(), model);
+ // @LOCALMOD-END
+
switch (model) {
case TLSModel::GeneralDynamic:
if (Subtarget->is64Bit())
@@ -13361,9 +13436,16 @@ X86TargetLowering::LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const {
Subtarget->is64Bit());
case TLSModel::InitialExec:
case TLSModel::LocalExec:
+ // @LOCALMOD-START
+ if (llvm::TLSUseCall && Subtarget->isTargetNaCl()) {
+ return LowerToTLSExecCall(GA, DAG, getPointerTy(), model,
+ Subtarget->is64Bit());
+ } else {
return LowerToTLSExecModel(
GA, DAG, getPointerTy(), model, Subtarget->is64Bit(),
DAG.getTarget().getRelocationModel() == Reloc::PIC_);
+ }
+ // @LOCALMOD-END
}
llvm_unreachable("Unknown TLS model.");
}
@@ -14635,6 +14717,23 @@ SDValue X86TargetLowering::EmitTest(SDValue Op, unsigned X86CC, SDLoc dl,
return DAG.getNode(X86ISD::CMP, dl, MVT::i32, Op,
DAG.getConstant(0, Op.getValueType()));
+ // @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();
+
// CF and OF aren't always set the way we want. Determine which
// of these we need.
bool NeedCF = false;
@@ -14671,7 +14770,7 @@ SDValue X86TargetLowering::EmitTest(SDValue Op, unsigned X86CC, SDLoc dl,
// 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.
//if (Op.getValueType() == MVT::i1)
// return DAG.getNode(X86ISD::CMP, dl, MVT::i1, Op,
@@ -14679,6 +14778,7 @@ SDValue X86TargetLowering::EmitTest(SDValue Op, unsigned X86CC, SDLoc dl,
return DAG.getNode(X86ISD::CMP, dl, MVT::i32, Op,
DAG.getConstant(0, Op.getValueType()));
}
+ // @LOCALMOD-END
unsigned Opcode = 0;
unsigned NumOperands = 0;
@@ -14992,6 +15092,10 @@ static bool isAllOnes(SDValue V) {
/// if it's possible.
SDValue X86TargetLowering::LowerToBT(SDValue And, ISD::CondCode CC,
SDLoc 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)
@@ -16475,7 +16579,8 @@ X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
const X86RegisterInfo *RegInfo = static_cast<const X86RegisterInfo *>(
DAG.getSubtarget().getRegisterInfo());
- unsigned SPReg = RegInfo->getStackRegister();
+ (void)RegInfo; // @LOCALMOD
+ unsigned SPReg = X86StackPtr; // @LOCALMOD
SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, SPTy);
Chain = SP.getValue(1);
@@ -16511,6 +16616,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(0); // @LOCALMOD
SmallVector<SDValue, 8> MemOps;
SDValue FIN = Op.getOperand(1);
// Store gp_offset
@@ -16541,11 +16647,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());
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);
}
@@ -16554,7 +16661,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);
@@ -16629,7 +16737,15 @@ static SDValue LowerVACOPY(SDValue Op, const X86Subtarget *Subtarget,
SDLoc DL(Op);
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));
}
@@ -16949,7 +17065,26 @@ static SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, const X86Subtarget *Subtarget
switch (IntNo) {
default: return SDValue(); // Don't custom lower most intrinsics.
-
+ // @LOCALMOD-BEGIN
+ case Intrinsic::nacl_read_tp: {
+ EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy();
+ if (Subtarget->is64Bit() || llvm::TLSUseCall) {
+ // Call __nacl_read_tp() to get the thread pointer.
+ unsigned PtrSize = PtrVT.getSizeInBits();
+ IntegerType *RetTy = Type::getIntNTy(*DAG.getContext(), PtrSize);
+ SDValue ReadTpFunction = DAG.getExternalSymbol("__nacl_read_tp", PtrVT);
+ X86TargetLowering::ArgListTy Args;
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ return TLI.LowerCallTo(TargetLowering::CallLoweringInfo(DAG)
+ .setChain(DAG.getEntryNode())
+ .setCallee(CallingConv::C, RetTy, ReadTpFunction,
+ std::move(Args), 0)).first;
+ } else {
+ // Get %gs:0, which contains the thread pointer on x86-32.
+ return DAG.getNode(X86ISD::THREAD_POINTER_FROM_GS, dl, PtrVT);
+ }
+ }
+ // @LOCALMOD-END
// Arithmetic intrinsics.
case Intrinsic::x86_sse2_pmulu_dq:
case Intrinsic::x86_avx2_pmulu_dq:
@@ -17632,7 +17767,8 @@ SDValue X86TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const {
unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
const X86RegisterInfo *RegInfo = static_cast<const X86RegisterInfo *>(
DAG.getSubtarget().getRegisterInfo());
- unsigned FrameReg = RegInfo->getFrameRegister(DAG.getMachineFunction());
+ unsigned FrameReg = RegInfo->getPtrSizedFrameRegister(
+ DAG.getMachineFunction());
assert(((FrameReg == X86::RBP && VT == MVT::i64) ||
(FrameReg == X86::EBP && VT == MVT::i32)) &&
"Invalid Frame Register!");
@@ -17670,15 +17806,23 @@ SDValue X86TargetLowering::LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const {
SDValue Handler = Op.getOperand(2);
SDLoc dl (Op);
+ // @LOCALMOD-START
+ bool Has64BitPointers = Subtarget->has64BitPointers();
EVT PtrVT = getPointerTy();
const X86RegisterInfo *RegInfo = static_cast<const X86RegisterInfo *>(
DAG.getSubtarget().getRegisterInfo());
- unsigned FrameReg = RegInfo->getFrameRegister(DAG.getMachineFunction());
+ unsigned FrameReg;
+ if (Subtarget->isTargetNaCl()) {
+ FrameReg = Subtarget->has64BitPointers() ? X86::RBP : X86::EBP;
+ } else {
+ FrameReg = RegInfo->getFrameRegister(DAG.getMachineFunction());
+ }
assert(((FrameReg == X86::RBP && PtrVT == MVT::i64) ||
(FrameReg == X86::EBP && PtrVT == MVT::i32)) &&
"Invalid Frame Register!");
SDValue Frame = DAG.getCopyFromReg(DAG.getEntryNode(), dl, FrameReg, PtrVT);
- unsigned StoreAddrReg = (PtrVT == MVT::i64) ? X86::RCX : X86::ECX;
+ unsigned StoreAddrReg = Has64BitPointers ? X86::RCX : X86::ECX;
+ // @LOCALMOD-END
SDValue StoreAddr = DAG.getNode(ISD::ADD, dl, PtrVT, Frame,
DAG.getIntPtrConstant(RegInfo->getSlotSize()));
@@ -20228,10 +20372,12 @@ X86TargetLowering::EmitVAARG64WithCustomInserter(
MachineInstr::mmo_iterator MMOBegin = MI->memoperands_begin();
MachineInstr::mmo_iterator MMOEnd = MI->memoperands_end();
+ bool IsNaCl = Subtarget->isTargetNaCl(); // @LOCALMOD
// Machine Information
const TargetInstrInfo *TII = MBB->getParent()->getSubtarget().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();
@@ -20339,29 +20485,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(0)) // @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
@@ -20391,7 +20547,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)
@@ -20407,11 +20564,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 {
@@ -20422,12 +20581,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)
@@ -20821,6 +20982,25 @@ X86TargetLowering::EmitLoweredWinAlloca(MachineInstr *MI,
return BB;
}
+// @LOCALMOD-BEGIN
+MachineBasicBlock *
+X86TargetLowering::EmitLoweredThreadPointerFromGs(MachineInstr *MI,
+ MachineBasicBlock *BB) const {
+ const TargetInstrInfo *TII = BB->getParent()->getSubtarget().getInstrInfo();
+ DebugLoc DL = MI->getDebugLoc();
+ // This generates "movl %gs:0, %DEST", which fetches the thread
+ // pointer on x86-32.
+ BuildMI(*BB, MI, DL, TII->get(X86::MOV32rm), MI->getOperand(0).getReg())
+ .addReg(/*Base=*/0)
+ .addImm(/*Scale=*/1)
+ .addReg(/*IndexReg=*/0)
+ .addImm(/*Disp=*/0)
+ .addReg(/*Segment=*/X86::GS);
+ MI->eraseFromParent();
+ return BB;
+}
+// @LOCALMOD-END
+
MachineBasicBlock *
X86TargetLowering::EmitLoweredTLSCall(MachineInstr *MI,
MachineBasicBlock *BB) const {
@@ -21192,6 +21372,10 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
case X86::SEG_ALLOCA_32:
case X86::SEG_ALLOCA_64:
return EmitLoweredSegAlloca(MI, BB);
+ // @LOCALMOD-BEGIN
+ case X86::THREAD_POINTER_FROM_GS:
+ return EmitLoweredThreadPointerFromGs(MI, BB);
+ // @LOCALMOD-END
case X86::TLSCall_32:
case X86::TLSCall_64:
return EmitLoweredTLSCall(MI, BB);
@@ -21336,6 +21520,7 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
return EmitVAStartSaveXMMRegsWithCustomInserter(MI, BB);
case X86::VAARG_64:
+ case X86::NACL_CG_VAARG_64: // @LOCALMOD
return EmitVAARG64WithCustomInserter(MI, BB);
case X86::EH_SjLj_SetJmp32:
« no previous file with comments | « lib/Target/X86/X86ISelLowering.h ('k') | lib/Target/X86/X86InstrCompiler.td » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698