diff options
Diffstat (limited to 'lib/Target/ARM/ARMISelLowering.cpp')
-rw-r--r-- | lib/Target/ARM/ARMISelLowering.cpp | 409 |
1 files changed, 356 insertions, 53 deletions
diff --git a/lib/Target/ARM/ARMISelLowering.cpp b/lib/Target/ARM/ARMISelLowering.cpp index c48fa763b4..89bed8b823 100644 --- a/lib/Target/ARM/ARMISelLowering.cpp +++ b/lib/Target/ARM/ARMISelLowering.cpp @@ -48,6 +48,15 @@ #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" + +// @LOCALMOD-START +namespace llvm { + extern cl::opt<bool> FlagSfiLoad; + extern cl::opt<bool> FlagSfiStore; + extern cl::opt<bool> FlagSfiDisableCP; +} +// @LOCALMOD-END + using namespace llvm; STATISTIC(NumTailCalls, "Number of tail calls"); @@ -71,6 +80,7 @@ ARMInterworking("arm-interworking", cl::Hidden, cl::init(true)); namespace { + class ARMCCState : public CCState { public: ARMCCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF, @@ -259,8 +269,8 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) setLibcallName(RTLIB::SHL_I128, 0); setLibcallName(RTLIB::SRL_I128, 0); setLibcallName(RTLIB::SRA_I128, 0); - - if (Subtarget->isAAPCS_ABI() && !Subtarget->isTargetDarwin()) { + // @LOCALMOD: use standard names and calling conventions for pnacl + if (!Subtarget->isTargetNaCl() && Subtarget->isAAPCS_ABI() && !Subtarget->isTargetDarwin()) { // Double-precision floating-point arithmetic helper functions // RTABI chapter 4.1.2, Table 2 setLibcallName(RTLIB::ADD_F64, "__aeabi_dadd"); @@ -650,9 +660,14 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) setOperationAction(ISD::GLOBAL_OFFSET_TABLE, MVT::i32, Custom); setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom); setOperationAction(ISD::BlockAddress, MVT::i32, Custom); - + // @LOCALMOD-START + if (!Subtarget->useInlineJumpTables()) + setOperationAction(ISD::JumpTable, MVT::i32, Custom); + // @LOCALMOD-END + setOperationAction(ISD::TRAP, MVT::Other, Legal); + // Use the default implementation. setOperationAction(ISD::VASTART, MVT::Other, Custom); setOperationAction(ISD::VAARG, MVT::Other, Expand); @@ -665,9 +680,18 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) // Non-Darwin platforms may return values in these registers via the // personality function. setOperationAction(ISD::EHSELECTION, MVT::i32, Expand); + // @LOCALMOD-START setOperationAction(ISD::EXCEPTIONADDR, MVT::i32, Expand); - setExceptionPointerRegister(ARM::R0); - setExceptionSelectorRegister(ARM::R1); + // we use the first caller saved regs here + // c.f.: llvm-gcc/llvm-gcc-4.2/gcc/unwind-dw2.c::uw_install_context + // NOTE: these are related to the _Unwind_PNaClSetResult{0,1} functions + setExceptionPointerRegister(ARM::R4); + setExceptionSelectorRegister(ARM::R5); + + setOperationAction(ISD::FRAME_TO_ARGS_OFFSET, MVT::i32, Custom); + + setOperationAction(ISD::EH_RETURN, MVT::Other, Custom); + // @LOCALMOD-END } setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); @@ -753,8 +777,12 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) setOperationAction(ISD::BR_CC, MVT::i32, Custom); setOperationAction(ISD::BR_CC, MVT::f32, Custom); setOperationAction(ISD::BR_CC, MVT::f64, Custom); - setOperationAction(ISD::BR_JT, MVT::Other, Custom); - + // @LOCALMOD-START + //setOperationAction(ISD::BR_JT, MVT::Other, Custom); + setOperationAction(ISD::BR_JT, MVT::Other, + Subtarget->useInlineJumpTables() ? Custom : Expand); + // @LOCALMOD-END + // We don't support sin/cos/fmod/copysign/pow setOperationAction(ISD::FSIN, MVT::f64, Expand); setOperationAction(ISD::FSIN, MVT::f32, Expand); @@ -791,6 +819,16 @@ ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) } } + // @LOCALMOD-BEGIN + if (Subtarget->isTargetNaCl()) { + setOperationAction(ISD::NACL_THREAD_STACK_PADDING, MVT::i32, Custom); + setOperationAction(ISD::NACL_TP_ALIGN, MVT::i32, Custom); + 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 + // We have target-specific dag combine patterns for the following nodes: // ARMISD::VMOVRRD - No need to call setTargetDAGCombine setTargetDAGCombine(ISD::ADD); @@ -885,6 +923,10 @@ const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const { case ARMISD::WrapperDYN: return "ARMISD::WrapperDYN"; case ARMISD::WrapperPIC: return "ARMISD::WrapperPIC"; case ARMISD::WrapperJT: return "ARMISD::WrapperJT"; + // @LOCALMOD-START + case ARMISD::WrapperJT2: return "ARMISD::WrapperJT2"; + case ARMISD::EH_RETURN: return "ARMISD::EH_RETURN"; + // @LOCALMOD-END case ARMISD::CALL: return "ARMISD::CALL"; case ARMISD::CALL_PRED: return "ARMISD::CALL_PRED"; case ARMISD::CALL_NOLINK: return "ARMISD::CALL_NOLINK"; @@ -1660,6 +1702,15 @@ ARMTargetLowering::HandleByVal(CCState *State, unsigned &size) const { assert((State->getCallOrPrologue() == Prologue || State->getCallOrPrologue() == Call) && "unhandled ParmContext"); + + // @LOCALMOD-BEGIN + // This mechanism tries to split a byval argument between registers + // and the stack. It doesn't work correctly yet, so disable it. + // This leaves the entire byval argument on the stack. + // PR11018. + return; + // @LOCALMOD-END + if ((!State->isFirstByValRegValid()) && (ARM::R0 <= reg) && (reg <= ARM::R3)) { State->setFirstByValReg(reg); @@ -2044,7 +2095,14 @@ static SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) { } unsigned ARMTargetLowering::getJumpTableEncoding() const { - return MachineJumpTableInfo::EK_Inline; + // @LOCALMOD-BEGIN + if (Subtarget->useInlineJumpTables()) { + return MachineJumpTableInfo::EK_Inline; + } else { + // TODO: Find a better way to call the super-class. + return TargetLowering::getJumpTableEncoding(); + } + // @LOCALMOD-END } SDValue ARMTargetLowering::LowerBlockAddress(SDValue Op, @@ -2077,28 +2135,137 @@ SDValue ARMTargetLowering::LowerBlockAddress(SDValue Op, return DAG.getNode(ARMISD::PIC_ADD, DL, PtrVT, Result, PICLabel); } +// @LOCALMOD-START +// more conventional jumptable implementation +SDValue ARMTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) const { + assert(!Subtarget->useInlineJumpTables() && + "inline jump tables not custom lowered"); + const DebugLoc dl = Op.getDebugLoc(); + EVT PTy = getPointerTy(); + JumpTableSDNode *JT = cast<JumpTableSDNode>(Op); + SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PTy); + return DAG.getNode(ARMISD::WrapperJT2, dl, MVT::i32, JTI); +} + +////////////////////////////////////////////////////////////////////// +// NaCl TLS setup / layout intrinsics. +// See: native_client/src/untrusted/stubs/tls_params.h +SDValue ARMTargetLowering::LowerNaClTpAlign(SDValue Op, + SelectionDAG &DAG) const { + // size_t __nacl_tp_alignment () { + // return 4; + // } + return DAG.getConstant(4, Op.getValueType().getSimpleVT()); +} + +SDValue ARMTargetLowering::LowerNaClTpTlsOffset(SDValue Op, + SelectionDAG &DAG) const { + // ssize_t __nacl_tp_tls_offset (size_t tls_size) { + // return 8; + // } + return DAG.getConstant(8, Op.getValueType().getSimpleVT()); +} + +SDValue ARMTargetLowering::LowerNaClTpTdbOffset(SDValue Op, + SelectionDAG &DAG) const { + // ssize_t __nacl_tp_tdb_offset (size_t tdb_size) { + // return -tdb_size; + // } + DebugLoc dl = Op.getDebugLoc(); + return DAG.getNode(ISD::SUB, dl, Op.getValueType().getSimpleVT(), + DAG.getConstant(0, Op.getValueType().getSimpleVT()), + Op.getOperand(0)); +} + +SDValue +ARMTargetLowering::LowerNaClThreadStackPadding(SDValue Op, + SelectionDAG &DAG) const { + // size_t __nacl_thread_stack_padding () { + // return 0; + // } + return DAG.getConstant(0, Op.getValueType().getSimpleVT()); +} + +SDValue +ARMTargetLowering::LowerNaClTargetArch(SDValue Op, SelectionDAG &DAG) const { + // size_t __nacl_target_arch () { + // return PnaclTargetArchitectureARM_32; + // } + return DAG.getConstant(PnaclTargetArchitectureARM_32, + Op.getValueType().getSimpleVT()); +} + +////////////////////////////////////////////////////////////////////// + +// @LOCALMOD-END + // Lower ISD::GlobalTLSAddress using the "general dynamic" model SDValue ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, SelectionDAG &DAG) const { DebugLoc dl = GA->getDebugLoc(); EVT PtrVT = getPointerTy(); - unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8; - MachineFunction &MF = DAG.getMachineFunction(); - ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); - unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); - ARMConstantPoolValue *CPV = - ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex, - ARMCP::CPValue, PCAdj, ARMCP::TLSGD, true); - SDValue Argument = DAG.getTargetConstantPool(CPV, PtrVT, 4); - Argument = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Argument); - Argument = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Argument, - MachinePointerInfo::getConstantPool(), - false, false, false, 0); - SDValue Chain = Argument.getValue(1); + // @LOCALMOD-BEGIN + SDValue Chain; + SDValue Argument; + + if (FlagSfiDisableCP) { + // With constant pools "disabled" (moved to rodata), this constant pool + // entry is no longer in text, and simultaneous PC relativeness + // and CP Addr relativeness is no longer expressible. + // So, instead of having: + // + // .LCPI12_0: + // .long var(tlsgd)-((.LPC12_0+8) - .) + // ... + // ldr r2, .LCPI12_0 + // .LPC12_0: + // add r0, pc, r2 + // + // we have: + // + // .LCPI12_0: + // .long var(tlsgd) + // ... + // // get addr of .LCPI12_0 into r2 + // ldr r0, [r2] + // add r0, r2, r0 + // (1) No longer subtracting pc, so no longer adding that back + // (2) Not adding "." in the CP entry, so adding it via instructions. + // + unsigned char PCAdj = 0; + MachineFunction &MF = DAG.getMachineFunction(); + ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); + unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); + ARMConstantPoolValue *CPV = + ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex, + ARMCP::CPValue, PCAdj, ARMCP::TLSGD, + false); + SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); + CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); + Argument = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr, + MachinePointerInfo::getConstantPool(), + false, false, false, 0); + Chain = Argument.getValue(1); + Argument = DAG.getNode(ISD::ADD, dl, PtrVT, Argument, CPAddr); + } else { // sort of @LOCALMOD-END + unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8; + MachineFunction &MF = DAG.getMachineFunction(); + ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); + unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); + ARMConstantPoolValue *CPV = + ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex, + ARMCP::CPValue, PCAdj, ARMCP::TLSGD, true); + Argument = DAG.getTargetConstantPool(CPV, PtrVT, 4); // @ LOCALMOD + Argument = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Argument); + Argument = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Argument, + MachinePointerInfo::getConstantPool(), + false, false, false, 0); + Chain = Argument.getValue(1); // @LOCALMOD - SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32); - Argument = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Argument, PICLabel); + SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32); + Argument = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Argument, PICLabel); + } // @LOCALMOD-END // call __tls_get_addr. ArgListTy Args; @@ -2135,25 +2302,49 @@ ARMTargetLowering::LowerToTLSExecModels(GlobalAddressSDNode *GA, MachineFunction &MF = DAG.getMachineFunction(); ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); - // Initial exec model. - unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8; - ARMConstantPoolValue *CPV = + + // @LOCALMOD-BEGIN + if (FlagSfiDisableCP) { + // Similar to change to LowerToTLSGeneralDynamicModel, and + // for the same reason. + unsigned char PCAdj = 0; + ARMConstantPoolValue *CPV = + ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex, + ARMCP::CPValue, PCAdj, ARMCP::GOTTPOFF, + false); + SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); + CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); + Offset = DAG.getLoad(PtrVT, dl, Chain, CPAddr, + MachinePointerInfo::getConstantPool(), + false, false, false, 0); + Chain = Offset.getValue(1); + + Offset = DAG.getNode(ISD::ADD, dl, PtrVT, Offset, CPAddr); + + Offset = DAG.getLoad(PtrVT, dl, Chain, Offset, + MachinePointerInfo::getConstantPool(), + false, false, false, 0); + } else { // sort of @LOCALMOD-END (indentation) + // Initial exec model. + unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8; + ARMConstantPoolValue *CPV = ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex, ARMCP::CPValue, PCAdj, ARMCP::GOTTPOFF, true); - Offset = DAG.getTargetConstantPool(CPV, PtrVT, 4); - Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset); - Offset = DAG.getLoad(PtrVT, dl, Chain, Offset, - MachinePointerInfo::getConstantPool(), - false, false, false, 0); - Chain = Offset.getValue(1); + Offset = DAG.getTargetConstantPool(CPV, PtrVT, 4); + Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset); + Offset = DAG.getLoad(PtrVT, dl, Chain, Offset, + MachinePointerInfo::getConstantPool(), + false, false, false, 0); + Chain = Offset.getValue(1); - SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32); - Offset = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Offset, PICLabel); + SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32); + Offset = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Offset, PICLabel); - Offset = DAG.getLoad(PtrVT, dl, Chain, Offset, - MachinePointerInfo::getConstantPool(), - false, false, false, 0); + Offset = DAG.getLoad(PtrVT, dl, Chain, Offset, + MachinePointerInfo::getConstantPool(), + false, false, false, 0); + } // @LOCALMOD-END } else { // local exec model assert(model == TLSModel::LocalExec); @@ -2305,17 +2496,55 @@ SDValue ARMTargetLowering::LowerGLOBAL_OFFSET_TABLE(SDValue Op, unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); EVT PtrVT = getPointerTy(); DebugLoc dl = Op.getDebugLoc(); - unsigned PCAdj = Subtarget->isThumb() ? 4 : 8; + + // @LOCALMOD-BEGIN + if (FlagSfiDisableCP) { + // With constant pools "disabled" (moved to rodata), the constant pool + // entry is no longer in text, and the PC relativeness is + // no longer expressible. + // + // Instead of having: + // + // .LCPI12_0: + // .long _GLOBAL_OFFSET_TABLE_-(.LPC12_0+8) + // ... + // ldr r2, .LCPI12_0 + // .LPC12_0: + // add r0, pc, r2 + // + // Things to try: + // (1) get the address of the GOT through a pc-relative MOVW / MOVT. + // + // movw r0, :lower16:_GLOBAL_OFFSET_TABLE_ - (.LPC12_0 + 8) + // movt r0, :upper16:_GLOBAL_OFFSET_TABLE_ - (.LPC12_0 + 8) + // .LPC12_0: + // add r0, pc, r0 + // + // (2) Make the constant pool entry relative to its own location + // + // .LCPI12_0: + // .long _GLOBAL_OFFSET_TABLE_-. + // ... + // // get address of LCPI12_0 into r0 (possibly 3 instructions for PIC) + // ldr r1, [r0] + // add r1, r0, r1 + // + // We will try (1) for now, since (2) takes about 3 more instructions + // (and one of them is a load). + return DAG.getNode(ARMISD::WrapperGOT, dl, MVT::i32); + } else { // Sort of LOCALMOD-END (indentation only + unsigned PCAdj = Subtarget->isThumb() ? 4 : 8; ARMConstantPoolValue *CPV = ARMConstantPoolSymbol::Create(*DAG.getContext(), "_GLOBAL_OFFSET_TABLE_", ARMPCLabelIndex, PCAdj); - SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); - CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); - SDValue Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr, - MachinePointerInfo::getConstantPool(), - false, false, false, 0); - SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32); - return DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel); + SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); + CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); + SDValue Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr, + MachinePointerInfo::getConstantPool(), + false, false, false, 0); + SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32); + return DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Result, PICLabel); + } // @LOCALMOD-END } SDValue @@ -2707,10 +2936,9 @@ ARMTargetLowering::LowerFormalArguments(SDValue Chain, // Since they could be overwritten by lowering of arguments in case of // a tail call. if (Flags.isByVal()) { - unsigned VARegSize, VARegSaveSize; - computeRegArea(CCInfo, MF, VARegSize, VARegSaveSize); - VarArgStyleRegisters(CCInfo, DAG, dl, Chain, 0); - unsigned Bytes = Flags.getByValSize() - VARegSize; + // LOCALMOD-BEGIN (PR11018) + unsigned Bytes = Flags.getByValSize(); + // @LOCALMOD-END if (Bytes == 0) Bytes = 1; // Don't create zero-sized stack objects. int FI = MFI->CreateFixedObject(Bytes, VA.getLocMemOffset(), false); @@ -4898,7 +5126,7 @@ static SDValue LowerMUL(SDValue Op, SelectionDAG &DAG) { "unexpected types for extended operands to VMULL"); return DAG.getNode(NewOpc, DL, VT, Op0, Op1); } - + // Optimizing (zext A + zext B) * C, to (VMULL A, C) + (VMULL B, C) during // isel lowering to take advantage of no-stall back to back vmul + vmla. // vmull q0, d4, d6 @@ -4917,6 +5145,39 @@ static SDValue LowerMUL(SDValue Op, SelectionDAG &DAG) { DAG.getNode(ISD::BITCAST, DL, Op1VT, N01), Op1)); } +// @LOCALMOD-START +// An EH_RETURN is the result of lowering llvm.eh.return.i32 which in turn is +// generated from __builtin_eh_return (offset, handler) +// The effect of this is to adjust the stack pointer by "offset" +// and then branch to "handler". +SDValue ARMTargetLowering::LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) + const { + MachineFunction &MF = DAG.getMachineFunction(); + SDValue Chain = Op.getOperand(0); + SDValue Offset = Op.getOperand(1); + SDValue Handler = Op.getOperand(2); + DebugLoc dl = Op.getDebugLoc(); + + // Store stack offset in R2, jump target in R3, dummy return value in R0 + // The dummy return value is needed to make the use-def chains happy, + // because the EH_RETURN instruction uses the isReturn attribute, which + // means preceding code needs to define the return register (R0 on ARM). + // http://code.google.com/p/nativeclient/issues/detail?id=2643 + unsigned OffsetReg = ARM::R2; + unsigned AddrReg = ARM::R3; + unsigned ReturnReg = ARM::R0; + Chain = DAG.getCopyToReg(Chain, dl, OffsetReg, Offset); + Chain = DAG.getCopyToReg(Chain, dl, AddrReg, Handler); + Chain = DAG.getCopyToReg(Chain, dl, ReturnReg, DAG.getIntPtrConstant(0)); + return DAG.getNode(ARMISD::EH_RETURN, dl, + MVT::Other, + Chain, + DAG.getRegister(OffsetReg, MVT::i32), + DAG.getRegister(AddrReg, getPointerTy())); + } +// @LOCALMOD-END + + static SDValue LowerSDIV_v4i8(SDValue X, SDValue Y, DebugLoc dl, SelectionDAG &DAG) { // Convert to float @@ -5162,7 +5423,8 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { default: llvm_unreachable("Don't know how to custom lower this!"); case ISD::ConstantPool: return LowerConstantPool(Op, DAG); case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); - case ISD::GlobalAddress: + case ISD::JumpTable: return LowerJumpTable(Op, DAG); // @LOCALMOD + case ISD::GlobalAddress: return Subtarget->isTargetDarwin() ? LowerGlobalAddressDarwin(Op, DAG) : LowerGlobalAddressELF(Op, DAG); case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); @@ -5181,6 +5443,17 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG); case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); + // @LOCALMOD-START + // The exact semantics of this ISD are not completely clear. + // LLVM seems to always point the fp after the push ra and the old fp, i.e. + // two register slots after the beginning of the stack frame. + // It is not clear what happens when there is no frame pointer but + // but llvm unlike gcc seems to always force one when this node is + // encountered. + case ISD::FRAME_TO_ARGS_OFFSET: return DAG.getIntPtrConstant(2*4); + case ISD::EH_RETURN: return LowerEH_RETURN(Op, DAG); + // @LOCALMOD-END + case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG); case ISD::EH_SJLJ_SETJMP: return LowerEH_SJLJ_SETJMP(Op, DAG); case ISD::EH_SJLJ_LONGJMP: return LowerEH_SJLJ_LONGJMP(Op, DAG); @@ -5211,6 +5484,14 @@ SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { case ISD::SUBE: return LowerADDC_ADDE_SUBC_SUBE(Op, DAG); case ISD::ATOMIC_LOAD: case ISD::ATOMIC_STORE: return LowerAtomicLoadStore(Op, DAG); + // @LOCALMOD-BEGIN + case ISD::NACL_THREAD_STACK_PADDING: + return LowerNaClThreadStackPadding(Op, DAG); + case ISD::NACL_TP_ALIGN: return LowerNaClTpAlign(Op, DAG); + 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 } } @@ -6391,7 +6672,11 @@ EmitStructByval(MachineInstr *MI, MachineBasicBlock *BB) const { AddDefaultPred(BuildMI(BB, dl, TII->get(ARM::t2MOVTi16), varEnd) .addReg(VReg1) .addImm(LoopSize >> 16)); - } else { + } else if (FlagSfiDisableCP) { // @LOCALMOD-START + BuildMI(BB, dl, TII->get(ARM::MOVi32imm)) + .addReg(varEnd, RegState::Define) + .addImm(LoopSize); + } else { // @LOCALMOD-END MachineConstantPool *ConstantPool = MF->getConstantPool(); Type *Int32Ty = Type::getInt32Ty(MF->getFunction()->getContext()); const Constant *C = ConstantInt::get(Int32Ty, LoopSize); @@ -9120,6 +9405,16 @@ ARMTargetLowering::getPreIndexedAddressParts(SDNode *N, SDValue &Base, if (Subtarget->isThumb1Only()) return false; + // @LOCALMOD-START + // Avoid two reg addressing mode for loads and stores + const bool restrict_addressing_modes_for_nacl = + ((FlagSfiLoad && N->getOpcode() == ISD::LOAD) || + (FlagSfiStore && N->getOpcode() == ISD::STORE)); + if (restrict_addressing_modes_for_nacl) { + return false; + } + // @LOCALMOD-END + EVT VT; SDValue Ptr; bool isSEXTLoad = false; @@ -9158,7 +9453,15 @@ bool ARMTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op, SelectionDAG &DAG) const { if (Subtarget->isThumb1Only()) return false; - + // @LOCALMOD-START + // Avoid two reg addressing mode for loads and stores + const bool restrict_addressing_modes_for_nacl = + ((FlagSfiLoad && N->getOpcode() == ISD::LOAD) || + (FlagSfiStore && N->getOpcode() == ISD::STORE)); + if (restrict_addressing_modes_for_nacl) { + return false; + } + // @LOCALMOD-END EVT VT; SDValue Ptr; bool isSEXTLoad = false; |