| 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:
|
|
|