| OLD | NEW |
| 1 //===-- ARMISelLowering.cpp - ARM DAG Lowering Implementation -------------===// | 1 //===-- ARMISelLowering.cpp - ARM DAG Lowering Implementation -------------===// |
| 2 // | 2 // |
| 3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This file defines the interfaces that ARM uses to lower LLVM code into a | 10 // This file defines the interfaces that ARM uses to lower LLVM code into a |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 #include "llvm/IR/Instructions.h" | 42 #include "llvm/IR/Instructions.h" |
| 43 #include "llvm/IR/Intrinsics.h" | 43 #include "llvm/IR/Intrinsics.h" |
| 44 #include "llvm/IR/Type.h" | 44 #include "llvm/IR/Type.h" |
| 45 #include "llvm/MC/MCSectionMachO.h" | 45 #include "llvm/MC/MCSectionMachO.h" |
| 46 #include "llvm/Support/CommandLine.h" | 46 #include "llvm/Support/CommandLine.h" |
| 47 #include "llvm/Support/Debug.h" | 47 #include "llvm/Support/Debug.h" |
| 48 #include "llvm/Support/ErrorHandling.h" | 48 #include "llvm/Support/ErrorHandling.h" |
| 49 #include "llvm/Support/MathExtras.h" | 49 #include "llvm/Support/MathExtras.h" |
| 50 #include "llvm/Target/TargetOptions.h" | 50 #include "llvm/Target/TargetOptions.h" |
| 51 #include <utility> | 51 #include <utility> |
| 52 |
| 52 using namespace llvm; | 53 using namespace llvm; |
| 53 | 54 |
| 54 #define DEBUG_TYPE "arm-isel" | 55 #define DEBUG_TYPE "arm-isel" |
| 55 | 56 |
| 56 STATISTIC(NumTailCalls, "Number of tail calls"); | 57 STATISTIC(NumTailCalls, "Number of tail calls"); |
| 57 STATISTIC(NumMovwMovt, "Number of GAs materialized with movw + movt"); | 58 STATISTIC(NumMovwMovt, "Number of GAs materialized with movw + movt"); |
| 58 STATISTIC(NumLoopByVals, "Number of loops generated for byval arguments"); | 59 STATISTIC(NumLoopByVals, "Number of loops generated for byval arguments"); |
| 59 | 60 |
| 60 cl::opt<bool> | 61 cl::opt<bool> |
| 61 EnableARMLongCalls("arm-long-calls", cl::Hidden, | 62 EnableARMLongCalls("arm-long-calls", cl::Hidden, |
| 62 cl::desc("Generate calls via indirect call instructions"), | 63 cl::desc("Generate calls via indirect call instructions"), |
| 63 cl::init(false)); | 64 cl::init(false)); |
| 64 | 65 |
| 65 static cl::opt<bool> | 66 static cl::opt<bool> |
| 66 ARMInterworking("arm-interworking", cl::Hidden, | 67 ARMInterworking("arm-interworking", cl::Hidden, |
| 67 cl::desc("Enable / disable ARM interworking (for debugging only)"), | 68 cl::desc("Enable / disable ARM interworking (for debugging only)"), |
| 68 cl::init(true)); | 69 cl::init(true)); |
| 69 | 70 |
| 71 // @LOCALMOD-START |
| 72 // PNaCl's build of compiler-rt does not define __aeabi_* functions for ARM |
| 73 // yet. For Non-SFI NaCl, where we don't use "nacl" in the target triple, |
| 74 // we use the following option to turn off use of the __aeabi_* functions. |
| 75 // TODO(mseaborn): In the longer term, it would be cleaner to change the |
| 76 // compiler-rt build to define __aeabi_* functions. |
| 77 cl::opt<bool> |
| 78 llvm::EnableARMAEABIFunctions("arm-enable-aeabi-functions", |
| 79 cl::desc("Allow using ARM __aeabi_* functions in generated code"), |
| 80 cl::init(true)); |
| 81 // @LOCALMOD-END |
| 82 |
| 70 namespace { | 83 namespace { |
| 71 class ARMCCState : public CCState { | 84 class ARMCCState : public CCState { |
| 72 public: | 85 public: |
| 73 ARMCCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF, | 86 ARMCCState(CallingConv::ID CC, bool isVarArg, MachineFunction &MF, |
| 74 SmallVectorImpl<CCValAssign> &locs, LLVMContext &C, | 87 SmallVectorImpl<CCValAssign> &locs, LLVMContext &C, |
| 75 ParmContext PC) | 88 ParmContext PC) |
| 76 : CCState(CC, isVarArg, MF, locs, C) { | 89 : CCState(CC, isVarArg, MF, locs, C) { |
| 77 assert(((PC == Call) || (PC == Prologue)) && | 90 assert(((PC == Call) || (PC == Prologue)) && |
| 78 "ARMCCState users must specify whether their context is call" | 91 "ARMCCState users must specify whether their context is call" |
| 79 "or prologue generation."); | 92 "or prologue generation."); |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 setLibcallName(RTLIB::SINTTOFP_I32_F32, "__floatsisfvfp"); | 253 setLibcallName(RTLIB::SINTTOFP_I32_F32, "__floatsisfvfp"); |
| 241 setLibcallName(RTLIB::UINTTOFP_I32_F32, "__floatunssisfvfp"); | 254 setLibcallName(RTLIB::UINTTOFP_I32_F32, "__floatunssisfvfp"); |
| 242 } | 255 } |
| 243 } | 256 } |
| 244 | 257 |
| 245 // These libcalls are not available in 32-bit. | 258 // These libcalls are not available in 32-bit. |
| 246 setLibcallName(RTLIB::SHL_I128, nullptr); | 259 setLibcallName(RTLIB::SHL_I128, nullptr); |
| 247 setLibcallName(RTLIB::SRL_I128, nullptr); | 260 setLibcallName(RTLIB::SRL_I128, nullptr); |
| 248 setLibcallName(RTLIB::SRA_I128, nullptr); | 261 setLibcallName(RTLIB::SRA_I128, nullptr); |
| 249 | 262 |
| 263 // @LOCALMOD: use standard names and calling conventions for pnacl |
| 250 if (Subtarget->isAAPCS_ABI() && !Subtarget->isTargetMachO() && | 264 if (Subtarget->isAAPCS_ABI() && !Subtarget->isTargetMachO() && |
| 251 !Subtarget->isTargetWindows()) { | 265 !Subtarget->isTargetWindows() && !Subtarget->isTargetNaCl() && |
| 266 EnableARMAEABIFunctions) { |
| 252 static const struct { | 267 static const struct { |
| 253 const RTLIB::Libcall Op; | 268 const RTLIB::Libcall Op; |
| 254 const char * const Name; | 269 const char * const Name; |
| 255 const CallingConv::ID CC; | 270 const CallingConv::ID CC; |
| 256 const ISD::CondCode Cond; | 271 const ISD::CondCode Cond; |
| 257 } LibraryCalls[] = { | 272 } LibraryCalls[] = { |
| 258 // Double-precision floating-point arithmetic helper functions | 273 // Double-precision floating-point arithmetic helper functions |
| 259 // RTABI chapter 4.1.2, Table 2 | 274 // RTABI chapter 4.1.2, Table 2 |
| 260 { RTLIB::ADD_F64, "__aeabi_dadd", CallingConv::ARM_AAPCS, ISD::SETCC_INVAL
ID }, | 275 { RTLIB::ADD_F64, "__aeabi_dadd", CallingConv::ARM_AAPCS, ISD::SETCC_INVAL
ID }, |
| 261 { RTLIB::DIV_F64, "__aeabi_ddiv", CallingConv::ARM_AAPCS, ISD::SETCC_INVAL
ID }, | 276 { RTLIB::DIV_F64, "__aeabi_ddiv", CallingConv::ARM_AAPCS, ISD::SETCC_INVAL
ID }, |
| (...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 728 } else { | 743 } else { |
| 729 setOperationAction(ISD::SDIVREM, MVT::i32, Expand); | 744 setOperationAction(ISD::SDIVREM, MVT::i32, Expand); |
| 730 setOperationAction(ISD::UDIVREM, MVT::i32, Expand); | 745 setOperationAction(ISD::UDIVREM, MVT::i32, Expand); |
| 731 } | 746 } |
| 732 | 747 |
| 733 setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); | 748 setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); |
| 734 setOperationAction(ISD::ConstantPool, MVT::i32, Custom); | 749 setOperationAction(ISD::ConstantPool, MVT::i32, Custom); |
| 735 setOperationAction(ISD::GLOBAL_OFFSET_TABLE, MVT::i32, Custom); | 750 setOperationAction(ISD::GLOBAL_OFFSET_TABLE, MVT::i32, Custom); |
| 736 setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom); | 751 setOperationAction(ISD::GlobalTLSAddress, MVT::i32, Custom); |
| 737 setOperationAction(ISD::BlockAddress, MVT::i32, Custom); | 752 setOperationAction(ISD::BlockAddress, MVT::i32, Custom); |
| 738 | 753 // @LOCALMOD-START |
| 754 if (!Subtarget->useInlineJumpTables()) |
| 755 setOperationAction(ISD::JumpTable, MVT::i32, Custom); |
| 756 // @LOCALMOD-END |
| 757 |
| 739 setOperationAction(ISD::TRAP, MVT::Other, Legal); | 758 setOperationAction(ISD::TRAP, MVT::Other, Legal); |
| 740 | 759 |
| 741 // Use the default implementation. | 760 // Use the default implementation. |
| 742 setOperationAction(ISD::VASTART, MVT::Other, Custom); | 761 setOperationAction(ISD::VASTART, MVT::Other, Custom); |
| 743 setOperationAction(ISD::VAARG, MVT::Other, Expand); | 762 setOperationAction(ISD::VAARG, MVT::Other, Expand); |
| 744 setOperationAction(ISD::VACOPY, MVT::Other, Expand); | 763 setOperationAction(ISD::VACOPY, MVT::Other, Expand); |
| 745 setOperationAction(ISD::VAEND, MVT::Other, Expand); | 764 setOperationAction(ISD::VAEND, MVT::Other, Expand); |
| 746 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); | 765 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); |
| 747 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); | 766 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); |
| 748 | 767 |
| 749 if (!Subtarget->isTargetMachO()) { | 768 if (!Subtarget->isTargetMachO()) { |
| 750 // Non-MachO platforms may return values in these registers via the | 769 // Non-MachO platforms may return values in these registers via the |
| 751 // personality function. | 770 // personality function. |
| 752 setExceptionPointerRegister(ARM::R0); | 771 // @LOCALMOD-START |
| 753 setExceptionSelectorRegister(ARM::R1); | 772 if (Subtarget->isTargetNaCl()) { |
| 773 // we use the first caller saved regs here |
| 774 // c.f.: llvm-gcc/llvm-gcc-4.2/gcc/unwind-dw2.c::uw_install_context |
| 775 // NOTE: these are related to the _Unwind_PNaClSetResult{0,1} functions |
| 776 setExceptionPointerRegister(ARM::R4); |
| 777 setExceptionSelectorRegister(ARM::R5); |
| 778 |
| 779 setOperationAction(ISD::FRAME_TO_ARGS_OFFSET, MVT::i32, Custom); |
| 780 |
| 781 setOperationAction(ISD::EH_RETURN, MVT::Other, Custom); |
| 782 } else { |
| 783 setExceptionPointerRegister(ARM::R0); |
| 784 setExceptionSelectorRegister(ARM::R1); |
| 785 } |
| 786 // @LOCALMOD-END |
| 754 } | 787 } |
| 755 | 788 |
| 756 if (Subtarget->getTargetTriple().isWindowsItaniumEnvironment()) | 789 if (Subtarget->getTargetTriple().isWindowsItaniumEnvironment()) |
| 757 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom); | 790 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Custom); |
| 758 else | 791 else |
| 759 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); | 792 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32, Expand); |
| 760 | 793 |
| 761 // ARMv6 Thumb1 (except for CPUs that support dmb / dsb) and earlier use | 794 // ARMv6 Thumb1 (except for CPUs that support dmb / dsb) and earlier use |
| 762 // the default expansion. If we are targeting a single threaded system, | 795 // the default expansion. If we are targeting a single threaded system, |
| 763 // then set them all for expand so we can lower them later into their | 796 // then set them all for expand so we can lower them later into their |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 832 setOperationAction(ISD::SELECT, MVT::f32, Custom); | 865 setOperationAction(ISD::SELECT, MVT::f32, Custom); |
| 833 setOperationAction(ISD::SELECT, MVT::f64, Custom); | 866 setOperationAction(ISD::SELECT, MVT::f64, Custom); |
| 834 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); | 867 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); |
| 835 setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); | 868 setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); |
| 836 setOperationAction(ISD::SELECT_CC, MVT::f64, Custom); | 869 setOperationAction(ISD::SELECT_CC, MVT::f64, Custom); |
| 837 | 870 |
| 838 setOperationAction(ISD::BRCOND, MVT::Other, Expand); | 871 setOperationAction(ISD::BRCOND, MVT::Other, Expand); |
| 839 setOperationAction(ISD::BR_CC, MVT::i32, Custom); | 872 setOperationAction(ISD::BR_CC, MVT::i32, Custom); |
| 840 setOperationAction(ISD::BR_CC, MVT::f32, Custom); | 873 setOperationAction(ISD::BR_CC, MVT::f32, Custom); |
| 841 setOperationAction(ISD::BR_CC, MVT::f64, Custom); | 874 setOperationAction(ISD::BR_CC, MVT::f64, Custom); |
| 842 setOperationAction(ISD::BR_JT, MVT::Other, Custom); | 875 // @LOCALMOD-START |
| 843 | 876 //setOperationAction(ISD::BR_JT, MVT::Other, Custom); |
| 877 setOperationAction(ISD::BR_JT, MVT::Other, |
| 878 Subtarget->useInlineJumpTables() ? Custom : Expand); |
| 879 // @LOCALMOD-END |
| 880 |
| 844 // We don't support sin/cos/fmod/copysign/pow | 881 // We don't support sin/cos/fmod/copysign/pow |
| 845 setOperationAction(ISD::FSIN, MVT::f64, Expand); | 882 setOperationAction(ISD::FSIN, MVT::f64, Expand); |
| 846 setOperationAction(ISD::FSIN, MVT::f32, Expand); | 883 setOperationAction(ISD::FSIN, MVT::f32, Expand); |
| 847 setOperationAction(ISD::FCOS, MVT::f32, Expand); | 884 setOperationAction(ISD::FCOS, MVT::f32, Expand); |
| 848 setOperationAction(ISD::FCOS, MVT::f64, Expand); | 885 setOperationAction(ISD::FCOS, MVT::f64, Expand); |
| 849 setOperationAction(ISD::FSINCOS, MVT::f64, Expand); | 886 setOperationAction(ISD::FSINCOS, MVT::f64, Expand); |
| 850 setOperationAction(ISD::FSINCOS, MVT::f32, Expand); | 887 setOperationAction(ISD::FSINCOS, MVT::f32, Expand); |
| 851 setOperationAction(ISD::FREM, MVT::f64, Expand); | 888 setOperationAction(ISD::FREM, MVT::f64, Expand); |
| 852 setOperationAction(ISD::FREM, MVT::f32, Expand); | 889 setOperationAction(ISD::FREM, MVT::f32, Expand); |
| 853 if (!TM.Options.UseSoftFloat && Subtarget->hasVFP2() && | 890 if (!TM.Options.UseSoftFloat && Subtarget->hasVFP2() && |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 } | 1036 } |
| 1000 return std::make_pair(RRC, Cost); | 1037 return std::make_pair(RRC, Cost); |
| 1001 } | 1038 } |
| 1002 | 1039 |
| 1003 const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const { | 1040 const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const { |
| 1004 switch (Opcode) { | 1041 switch (Opcode) { |
| 1005 default: return nullptr; | 1042 default: return nullptr; |
| 1006 case ARMISD::Wrapper: return "ARMISD::Wrapper"; | 1043 case ARMISD::Wrapper: return "ARMISD::Wrapper"; |
| 1007 case ARMISD::WrapperPIC: return "ARMISD::WrapperPIC"; | 1044 case ARMISD::WrapperPIC: return "ARMISD::WrapperPIC"; |
| 1008 case ARMISD::WrapperJT: return "ARMISD::WrapperJT"; | 1045 case ARMISD::WrapperJT: return "ARMISD::WrapperJT"; |
| 1046 // @LOCALMOD-START |
| 1047 case ARMISD::WrapperJT2: return "ARMISD::WrapperJT2"; |
| 1048 case ARMISD::EH_RETURN: return "ARMISD::EH_RETURN"; |
| 1049 // @LOCALMOD-END |
| 1009 case ARMISD::CALL: return "ARMISD::CALL"; | 1050 case ARMISD::CALL: return "ARMISD::CALL"; |
| 1010 case ARMISD::CALL_PRED: return "ARMISD::CALL_PRED"; | 1051 case ARMISD::CALL_PRED: return "ARMISD::CALL_PRED"; |
| 1011 case ARMISD::CALL_NOLINK: return "ARMISD::CALL_NOLINK"; | 1052 case ARMISD::CALL_NOLINK: return "ARMISD::CALL_NOLINK"; |
| 1012 case ARMISD::tCALL: return "ARMISD::tCALL"; | 1053 case ARMISD::tCALL: return "ARMISD::tCALL"; |
| 1013 case ARMISD::BRCOND: return "ARMISD::BRCOND"; | 1054 case ARMISD::BRCOND: return "ARMISD::BRCOND"; |
| 1014 case ARMISD::BR_JT: return "ARMISD::BR_JT"; | 1055 case ARMISD::BR_JT: return "ARMISD::BR_JT"; |
| 1015 case ARMISD::BR2_JT: return "ARMISD::BR2_JT"; | 1056 case ARMISD::BR2_JT: return "ARMISD::BR2_JT"; |
| 1016 case ARMISD::RET_FLAG: return "ARMISD::RET_FLAG"; | 1057 case ARMISD::RET_FLAG: return "ARMISD::RET_FLAG"; |
| 1017 case ARMISD::INTRET_FLAG: return "ARMISD::INTRET_FLAG"; | 1058 case ARMISD::INTRET_FLAG: return "ARMISD::INTRET_FLAG"; |
| 1018 case ARMISD::PIC_ADD: return "ARMISD::PIC_ADD"; | 1059 case ARMISD::PIC_ADD: return "ARMISD::PIC_ADD"; |
| (...skipping 1358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2377 if (CP->isMachineConstantPoolEntry()) | 2418 if (CP->isMachineConstantPoolEntry()) |
| 2378 Res = DAG.getTargetConstantPool(CP->getMachineCPVal(), PtrVT, | 2419 Res = DAG.getTargetConstantPool(CP->getMachineCPVal(), PtrVT, |
| 2379 CP->getAlignment()); | 2420 CP->getAlignment()); |
| 2380 else | 2421 else |
| 2381 Res = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, | 2422 Res = DAG.getTargetConstantPool(CP->getConstVal(), PtrVT, |
| 2382 CP->getAlignment()); | 2423 CP->getAlignment()); |
| 2383 return DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Res); | 2424 return DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Res); |
| 2384 } | 2425 } |
| 2385 | 2426 |
| 2386 unsigned ARMTargetLowering::getJumpTableEncoding() const { | 2427 unsigned ARMTargetLowering::getJumpTableEncoding() const { |
| 2387 return MachineJumpTableInfo::EK_Inline; | 2428 // @LOCALMOD-BEGIN |
| 2429 if (Subtarget->useInlineJumpTables()) { |
| 2430 return MachineJumpTableInfo::EK_Inline; |
| 2431 } else { |
| 2432 // TODO: Find a better way to call the super-class. |
| 2433 return TargetLowering::getJumpTableEncoding(); |
| 2434 } |
| 2435 // @LOCALMOD-END |
| 2388 } | 2436 } |
| 2389 | 2437 |
| 2390 SDValue ARMTargetLowering::LowerBlockAddress(SDValue Op, | 2438 SDValue ARMTargetLowering::LowerBlockAddress(SDValue Op, |
| 2391 SelectionDAG &DAG) const { | 2439 SelectionDAG &DAG) const { |
| 2392 MachineFunction &MF = DAG.getMachineFunction(); | 2440 MachineFunction &MF = DAG.getMachineFunction(); |
| 2393 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); | 2441 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); |
| 2394 unsigned ARMPCLabelIndex = 0; | 2442 unsigned ARMPCLabelIndex = 0; |
| 2395 SDLoc DL(Op); | 2443 SDLoc DL(Op); |
| 2396 EVT PtrVT = getPointerTy(); | 2444 EVT PtrVT = getPointerTy(); |
| 2397 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress(); | 2445 const BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 2410 CPAddr = DAG.getNode(ARMISD::Wrapper, DL, PtrVT, CPAddr); | 2458 CPAddr = DAG.getNode(ARMISD::Wrapper, DL, PtrVT, CPAddr); |
| 2411 SDValue Result = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), CPAddr, | 2459 SDValue Result = DAG.getLoad(PtrVT, DL, DAG.getEntryNode(), CPAddr, |
| 2412 MachinePointerInfo::getConstantPool(), | 2460 MachinePointerInfo::getConstantPool(), |
| 2413 false, false, false, 0); | 2461 false, false, false, 0); |
| 2414 if (RelocM == Reloc::Static) | 2462 if (RelocM == Reloc::Static) |
| 2415 return Result; | 2463 return Result; |
| 2416 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32); | 2464 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32); |
| 2417 return DAG.getNode(ARMISD::PIC_ADD, DL, PtrVT, Result, PICLabel); | 2465 return DAG.getNode(ARMISD::PIC_ADD, DL, PtrVT, Result, PICLabel); |
| 2418 } | 2466 } |
| 2419 | 2467 |
| 2468 // @LOCALMOD-START |
| 2469 // more conventional jumptable implementation |
| 2470 SDValue ARMTargetLowering::LowerJumpTable(SDValue Op, SelectionDAG &DAG) const { |
| 2471 assert(!Subtarget->useInlineJumpTables() && |
| 2472 "inline jump tables not custom lowered"); |
| 2473 const SDLoc dl(Op); |
| 2474 EVT PTy = getPointerTy(); |
| 2475 JumpTableSDNode *JT = cast<JumpTableSDNode>(Op); |
| 2476 SDValue JTI = DAG.getTargetJumpTable(JT->getIndex(), PTy); |
| 2477 return DAG.getNode(ARMISD::WrapperJT2, dl, MVT::i32, JTI); |
| 2478 } |
| 2479 // @LOCALMOD-END |
| 2480 |
| 2420 // Lower ISD::GlobalTLSAddress using the "general dynamic" model | 2481 // Lower ISD::GlobalTLSAddress using the "general dynamic" model |
| 2421 SDValue | 2482 SDValue |
| 2422 ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, | 2483 ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, |
| 2423 SelectionDAG &DAG) const { | 2484 SelectionDAG &DAG) const { |
| 2424 SDLoc dl(GA); | 2485 SDLoc dl(GA); |
| 2425 EVT PtrVT = getPointerTy(); | 2486 EVT PtrVT = getPointerTy(); |
| 2487 // @LOCALMOD-BEGIN |
| 2488 SDValue Chain; |
| 2489 SDValue Argument; |
| 2490 |
| 2491 if (!Subtarget->useConstIslands()) { |
| 2492 // With constant islands "disabled" (moved to rodata), this constant pool |
| 2493 // entry is no longer in text, and simultaneous PC relativeness |
| 2494 // and CP Addr relativeness is no longer expressible. |
| 2495 // So, instead of having: |
| 2496 // |
| 2497 // .LCPI12_0: |
| 2498 // .long var(tlsgd)-((.LPC12_0+8) - .) |
| 2499 // ... |
| 2500 // ldr r2, .LCPI12_0 |
| 2501 // .LPC12_0: |
| 2502 // add r0, pc, r2 |
| 2503 // |
| 2504 // we have: |
| 2505 // |
| 2506 // .LCPI12_0: |
| 2507 // .long var(tlsgd) |
| 2508 // ... |
| 2509 // // get addr of .LCPI12_0 into r2 |
| 2510 // ldr r0, [r2] |
| 2511 // add r0, r2, r0 |
| 2512 // (1) No longer subtracting pc, so no longer adding that back |
| 2513 // (2) Not adding "." in the CP entry, so adding it via instructions. |
| 2514 // |
| 2515 unsigned char PCAdj = 0; |
| 2516 MachineFunction &MF = DAG.getMachineFunction(); |
| 2517 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); |
| 2518 unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); |
| 2519 ARMConstantPoolValue *CPV = |
| 2520 ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex, |
| 2521 ARMCP::CPValue, PCAdj, ARMCP::TLSGD, |
| 2522 false); |
| 2523 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); |
| 2524 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); |
| 2525 Argument = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr, |
| 2526 MachinePointerInfo::getConstantPool(), |
| 2527 false, false, false, 0); |
| 2528 Chain = Argument.getValue(1); |
| 2529 Argument = DAG.getNode(ISD::ADD, dl, PtrVT, Argument, CPAddr); |
| 2530 } else { // sort of @LOCALMOD-END |
| 2426 unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8; | 2531 unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8; |
| 2427 MachineFunction &MF = DAG.getMachineFunction(); | 2532 MachineFunction &MF = DAG.getMachineFunction(); |
| 2428 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); | 2533 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); |
| 2429 unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); | 2534 unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); |
| 2430 ARMConstantPoolValue *CPV = | 2535 ARMConstantPoolValue *CPV = |
| 2431 ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex, | 2536 ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex, |
| 2432 ARMCP::CPValue, PCAdj, ARMCP::TLSGD, true); | 2537 ARMCP::CPValue, PCAdj, ARMCP::TLSGD, true); |
| 2433 SDValue Argument = DAG.getTargetConstantPool(CPV, PtrVT, 4); | 2538 /*SDValue*/ Argument = DAG.getTargetConstantPool(CPV, PtrVT, 4); // @LOCALMOD |
| 2434 Argument = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Argument); | 2539 Argument = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Argument); |
| 2435 Argument = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Argument, | 2540 Argument = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), Argument, |
| 2436 MachinePointerInfo::getConstantPool(), | 2541 MachinePointerInfo::getConstantPool(), |
| 2437 false, false, false, 0); | 2542 false, false, false, 0); |
| 2438 SDValue Chain = Argument.getValue(1); | 2543 /*SDValue*/ Chain = Argument.getValue(1); // @LOCALMOD |
| 2439 | 2544 |
| 2440 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32); | 2545 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32); |
| 2441 Argument = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Argument, PICLabel); | 2546 Argument = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Argument, PICLabel); |
| 2547 } // @LOCALMOD-END |
| 2442 | 2548 |
| 2443 // call __tls_get_addr. | 2549 // call __tls_get_addr. |
| 2444 ArgListTy Args; | 2550 ArgListTy Args; |
| 2445 ArgListEntry Entry; | 2551 ArgListEntry Entry; |
| 2446 Entry.Node = Argument; | 2552 Entry.Node = Argument; |
| 2447 Entry.Ty = (Type *) Type::getInt32Ty(*DAG.getContext()); | 2553 Entry.Ty = (Type *) Type::getInt32Ty(*DAG.getContext()); |
| 2448 Args.push_back(Entry); | 2554 Args.push_back(Entry); |
| 2449 | 2555 |
| 2450 // FIXME: is there useful debug info available here? | 2556 // FIXME: is there useful debug info available here? |
| 2451 TargetLowering::CallLoweringInfo CLI(DAG); | 2557 TargetLowering::CallLoweringInfo CLI(DAG); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2469 SDValue Offset; | 2575 SDValue Offset; |
| 2470 SDValue Chain = DAG.getEntryNode(); | 2576 SDValue Chain = DAG.getEntryNode(); |
| 2471 EVT PtrVT = getPointerTy(); | 2577 EVT PtrVT = getPointerTy(); |
| 2472 // Get the Thread Pointer | 2578 // Get the Thread Pointer |
| 2473 SDValue ThreadPointer = DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT); | 2579 SDValue ThreadPointer = DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT); |
| 2474 | 2580 |
| 2475 if (model == TLSModel::InitialExec) { | 2581 if (model == TLSModel::InitialExec) { |
| 2476 MachineFunction &MF = DAG.getMachineFunction(); | 2582 MachineFunction &MF = DAG.getMachineFunction(); |
| 2477 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); | 2583 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); |
| 2478 unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); | 2584 unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); |
| 2479 // Initial exec model. | 2585 |
| 2480 unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8; | 2586 // @LOCALMOD-BEGIN |
| 2481 ARMConstantPoolValue *CPV = | 2587 if (!Subtarget->useConstIslands()) { |
| 2588 // Similar to change to LowerToTLSGeneralDynamicModel, and |
| 2589 // for the same reason. |
| 2590 unsigned char PCAdj = 0; |
| 2591 ARMConstantPoolValue *CPV = |
| 2592 ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex, |
| 2593 ARMCP::CPValue, PCAdj, ARMCP::GOTTPOFF, |
| 2594 false); |
| 2595 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); |
| 2596 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); |
| 2597 Offset = DAG.getLoad(PtrVT, dl, Chain, CPAddr, |
| 2598 MachinePointerInfo::getConstantPool(), |
| 2599 false, false, false, 0); |
| 2600 Chain = Offset.getValue(1); |
| 2601 |
| 2602 Offset = DAG.getNode(ISD::ADD, dl, PtrVT, Offset, CPAddr); |
| 2603 |
| 2604 Offset = DAG.getLoad(PtrVT, dl, Chain, Offset, |
| 2605 MachinePointerInfo::getConstantPool(), |
| 2606 false, false, false, 0); |
| 2607 } else { // sort of @LOCALMOD-END (indentation) |
| 2608 // Initial exec model. |
| 2609 unsigned char PCAdj = Subtarget->isThumb() ? 4 : 8; |
| 2610 ARMConstantPoolValue *CPV = |
| 2482 ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex, | 2611 ARMConstantPoolConstant::Create(GA->getGlobal(), ARMPCLabelIndex, |
| 2483 ARMCP::CPValue, PCAdj, ARMCP::GOTTPOFF, | 2612 ARMCP::CPValue, PCAdj, ARMCP::GOTTPOFF, |
| 2484 true); | 2613 true); |
| 2485 Offset = DAG.getTargetConstantPool(CPV, PtrVT, 4); | 2614 Offset = DAG.getTargetConstantPool(CPV, PtrVT, 4); |
| 2486 Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset); | 2615 Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset); |
| 2487 Offset = DAG.getLoad(PtrVT, dl, Chain, Offset, | 2616 Offset = DAG.getLoad(PtrVT, dl, Chain, Offset, |
| 2488 MachinePointerInfo::getConstantPool(), | 2617 MachinePointerInfo::getConstantPool(), |
| 2489 false, false, false, 0); | 2618 false, false, false, 0); |
| 2490 Chain = Offset.getValue(1); | 2619 Chain = Offset.getValue(1); |
| 2491 | 2620 |
| 2492 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32); | 2621 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32); |
| 2493 Offset = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Offset, PICLabel); | 2622 Offset = DAG.getNode(ARMISD::PIC_ADD, dl, PtrVT, Offset, PICLabel); |
| 2494 | 2623 |
| 2495 Offset = DAG.getLoad(PtrVT, dl, Chain, Offset, | 2624 Offset = DAG.getLoad(PtrVT, dl, Chain, Offset, |
| 2496 MachinePointerInfo::getConstantPool(), | 2625 MachinePointerInfo::getConstantPool(), |
| 2497 false, false, false, 0); | 2626 false, false, false, 0); |
| 2627 } // @LOCALMOD-END |
| 2498 } else { | 2628 } else { |
| 2499 // local exec model | 2629 // local exec model |
| 2500 assert(model == TLSModel::LocalExec); | 2630 assert(model == TLSModel::LocalExec); |
| 2501 ARMConstantPoolValue *CPV = | 2631 ARMConstantPoolValue *CPV = |
| 2502 ARMConstantPoolConstant::Create(GV, ARMCP::TPOFF); | 2632 ARMConstantPoolConstant::Create(GV, ARMCP::TPOFF); |
| 2503 Offset = DAG.getTargetConstantPool(CPV, PtrVT, 4); | 2633 Offset = DAG.getTargetConstantPool(CPV, PtrVT, 4); |
| 2504 Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset); | 2634 Offset = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, Offset); |
| 2505 Offset = DAG.getLoad(PtrVT, dl, Chain, Offset, | 2635 Offset = DAG.getLoad(PtrVT, dl, Chain, Offset, |
| 2506 MachinePointerInfo::getConstantPool(), | 2636 MachinePointerInfo::getConstantPool(), |
| 2507 false, false, false, 0); | 2637 false, false, false, 0); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2627 | 2757 |
| 2628 SDValue ARMTargetLowering::LowerGLOBAL_OFFSET_TABLE(SDValue Op, | 2758 SDValue ARMTargetLowering::LowerGLOBAL_OFFSET_TABLE(SDValue Op, |
| 2629 SelectionDAG &DAG) const { | 2759 SelectionDAG &DAG) const { |
| 2630 assert(Subtarget->isTargetELF() && | 2760 assert(Subtarget->isTargetELF() && |
| 2631 "GLOBAL OFFSET TABLE not implemented for non-ELF targets"); | 2761 "GLOBAL OFFSET TABLE not implemented for non-ELF targets"); |
| 2632 MachineFunction &MF = DAG.getMachineFunction(); | 2762 MachineFunction &MF = DAG.getMachineFunction(); |
| 2633 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); | 2763 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); |
| 2634 unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); | 2764 unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); |
| 2635 EVT PtrVT = getPointerTy(); | 2765 EVT PtrVT = getPointerTy(); |
| 2636 SDLoc dl(Op); | 2766 SDLoc dl(Op); |
| 2767 |
| 2768 // @LOCALMOD-BEGIN |
| 2769 if (!Subtarget->useConstIslands()) { |
| 2770 // With constant islands "disabled" (moved to rodata), the constant pool |
| 2771 // entry is no longer in text, and the PC relativeness is |
| 2772 // no longer expressible. |
| 2773 // |
| 2774 // Instead of having: |
| 2775 // |
| 2776 // .LCPI12_0: |
| 2777 // .long _GLOBAL_OFFSET_TABLE_-(.LPC12_0+8) |
| 2778 // ... |
| 2779 // ldr r2, .LCPI12_0 |
| 2780 // .LPC12_0: |
| 2781 // add r0, pc, r2 |
| 2782 // |
| 2783 // Things to try: |
| 2784 // (1) get the address of the GOT through a pc-relative MOVW / MOVT. |
| 2785 // |
| 2786 // movw r0, :lower16:_GLOBAL_OFFSET_TABLE_ - (.LPC12_0 + 8) |
| 2787 // movt r0, :upper16:_GLOBAL_OFFSET_TABLE_ - (.LPC12_0 + 8) |
| 2788 // .LPC12_0: |
| 2789 // add r0, pc, r0 |
| 2790 // |
| 2791 // (2) Make the constant pool entry relative to its own location |
| 2792 // |
| 2793 // .LCPI12_0: |
| 2794 // .long _GLOBAL_OFFSET_TABLE_-. |
| 2795 // ... |
| 2796 // // get address of LCPI12_0 into r0 (possibly 3 instructions for PIC) |
| 2797 // ldr r1, [r0] |
| 2798 // add r1, r0, r1 |
| 2799 // |
| 2800 // We will try (1) for now, since (2) takes about 3 more instructions |
| 2801 // (and one of them is a load). |
| 2802 return DAG.getNode(ARMISD::WrapperGOT, dl, MVT::i32); |
| 2803 } |
| 2804 // @LOCALMOD-END |
| 2637 unsigned PCAdj = Subtarget->isThumb() ? 4 : 8; | 2805 unsigned PCAdj = Subtarget->isThumb() ? 4 : 8; |
| 2638 ARMConstantPoolValue *CPV = | 2806 ARMConstantPoolValue *CPV = |
| 2639 ARMConstantPoolSymbol::Create(*DAG.getContext(), "_GLOBAL_OFFSET_TABLE_", | 2807 ARMConstantPoolSymbol::Create(*DAG.getContext(), "_GLOBAL_OFFSET_TABLE_", |
| 2640 ARMPCLabelIndex, PCAdj); | 2808 ARMPCLabelIndex, PCAdj); |
| 2641 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); | 2809 SDValue CPAddr = DAG.getTargetConstantPool(CPV, PtrVT, 4); |
| 2642 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); | 2810 CPAddr = DAG.getNode(ARMISD::Wrapper, dl, MVT::i32, CPAddr); |
| 2643 SDValue Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr, | 2811 SDValue Result = DAG.getLoad(PtrVT, dl, DAG.getEntryNode(), CPAddr, |
| 2644 MachinePointerInfo::getConstantPool(), | 2812 MachinePointerInfo::getConstantPool(), |
| 2645 false, false, false, 0); | 2813 false, false, false, 0); |
| 2646 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32); | 2814 SDValue PICLabel = DAG.getConstant(ARMPCLabelIndex, MVT::i32); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 2668 const ARMSubtarget *Subtarget) const { | 2836 const ARMSubtarget *Subtarget) const { |
| 2669 unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); | 2837 unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue(); |
| 2670 SDLoc dl(Op); | 2838 SDLoc dl(Op); |
| 2671 switch (IntNo) { | 2839 switch (IntNo) { |
| 2672 default: return SDValue(); // Don't custom lower most intrinsics. | 2840 default: return SDValue(); // Don't custom lower most intrinsics. |
| 2673 case Intrinsic::arm_rbit: { | 2841 case Intrinsic::arm_rbit: { |
| 2674 assert(Op.getOperand(1).getValueType() == MVT::i32 && | 2842 assert(Op.getOperand(1).getValueType() == MVT::i32 && |
| 2675 "RBIT intrinsic must have i32 type!"); | 2843 "RBIT intrinsic must have i32 type!"); |
| 2676 return DAG.getNode(ARMISD::RBIT, dl, MVT::i32, Op.getOperand(1)); | 2844 return DAG.getNode(ARMISD::RBIT, dl, MVT::i32, Op.getOperand(1)); |
| 2677 } | 2845 } |
| 2846 case Intrinsic::nacl_read_tp: // @LOCALMOD |
| 2678 case Intrinsic::arm_thread_pointer: { | 2847 case Intrinsic::arm_thread_pointer: { |
| 2679 EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); | 2848 EVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); |
| 2680 return DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT); | 2849 return DAG.getNode(ARMISD::THREAD_POINTER, dl, PtrVT); |
| 2681 } | 2850 } |
| 2682 case Intrinsic::eh_sjlj_lsda: { | 2851 case Intrinsic::eh_sjlj_lsda: { |
| 2683 MachineFunction &MF = DAG.getMachineFunction(); | 2852 MachineFunction &MF = DAG.getMachineFunction(); |
| 2684 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); | 2853 ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); |
| 2685 unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); | 2854 unsigned ARMPCLabelIndex = AFI->createPICLabelUId(); |
| 2686 EVT PtrVT = getPointerTy(); | 2855 EVT PtrVT = getPointerTy(); |
| 2687 Reloc::Model RelocM = getTargetMachine().getRelocationModel(); | 2856 Reloc::Model RelocM = getTargetMachine().getRelocationModel(); |
| (...skipping 3383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6071 SDValue N00 = SkipExtensionForVMULL(N0->getOperand(0).getNode(), DAG); | 6240 SDValue N00 = SkipExtensionForVMULL(N0->getOperand(0).getNode(), DAG); |
| 6072 SDValue N01 = SkipExtensionForVMULL(N0->getOperand(1).getNode(), DAG); | 6241 SDValue N01 = SkipExtensionForVMULL(N0->getOperand(1).getNode(), DAG); |
| 6073 EVT Op1VT = Op1.getValueType(); | 6242 EVT Op1VT = Op1.getValueType(); |
| 6074 return DAG.getNode(N0->getOpcode(), DL, VT, | 6243 return DAG.getNode(N0->getOpcode(), DL, VT, |
| 6075 DAG.getNode(NewOpc, DL, VT, | 6244 DAG.getNode(NewOpc, DL, VT, |
| 6076 DAG.getNode(ISD::BITCAST, DL, Op1VT, N00), Op1), | 6245 DAG.getNode(ISD::BITCAST, DL, Op1VT, N00), Op1), |
| 6077 DAG.getNode(NewOpc, DL, VT, | 6246 DAG.getNode(NewOpc, DL, VT, |
| 6078 DAG.getNode(ISD::BITCAST, DL, Op1VT, N01), Op1)); | 6247 DAG.getNode(ISD::BITCAST, DL, Op1VT, N01), Op1)); |
| 6079 } | 6248 } |
| 6080 | 6249 |
| 6250 // @LOCALMOD-START |
| 6251 // An EH_RETURN is the result of lowering llvm.eh.return.i32 which in turn is |
| 6252 // generated from __builtin_eh_return (offset, handler) |
| 6253 // The effect of this is to adjust the stack pointer by "offset" |
| 6254 // and then branch to "handler". |
| 6255 SDValue ARMTargetLowering::LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) |
| 6256 const { |
| 6257 SDValue Chain = Op.getOperand(0); |
| 6258 SDValue Offset = Op.getOperand(1); |
| 6259 SDValue Handler = Op.getOperand(2); |
| 6260 SDLoc dl(Op); |
| 6261 |
| 6262 // Store stack offset in R2, jump target in R3, dummy return value in R0 |
| 6263 // The dummy return value is needed to make the use-def chains happy, |
| 6264 // because the EH_RETURN instruction uses the isReturn attribute, which |
| 6265 // means preceding code needs to define the return register (R0 on ARM). |
| 6266 // http://code.google.com/p/nativeclient/issues/detail?id=2643 |
| 6267 unsigned OffsetReg = ARM::R2; |
| 6268 unsigned AddrReg = ARM::R3; |
| 6269 unsigned ReturnReg = ARM::R0; |
| 6270 Chain = DAG.getCopyToReg(Chain, dl, OffsetReg, Offset); |
| 6271 Chain = DAG.getCopyToReg(Chain, dl, AddrReg, Handler); |
| 6272 Chain = DAG.getCopyToReg(Chain, dl, ReturnReg, DAG.getIntPtrConstant(0)); |
| 6273 return DAG.getNode(ARMISD::EH_RETURN, dl, |
| 6274 MVT::Other, |
| 6275 Chain, |
| 6276 DAG.getRegister(OffsetReg, MVT::i32), |
| 6277 DAG.getRegister(AddrReg, getPointerTy())); |
| 6278 } |
| 6279 // @LOCALMOD-END |
| 6280 |
| 6281 |
| 6081 static SDValue | 6282 static SDValue |
| 6082 LowerSDIV_v4i8(SDValue X, SDValue Y, SDLoc dl, SelectionDAG &DAG) { | 6283 LowerSDIV_v4i8(SDValue X, SDValue Y, SDLoc dl, SelectionDAG &DAG) { |
| 6083 // Convert to float | 6284 // Convert to float |
| 6084 // float4 xf = vcvt_f32_s32(vmovl_s16(a.lo)); | 6285 // float4 xf = vcvt_f32_s32(vmovl_s16(a.lo)); |
| 6085 // float4 yf = vcvt_f32_s32(vmovl_s16(b.lo)); | 6286 // float4 yf = vcvt_f32_s32(vmovl_s16(b.lo)); |
| 6086 X = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, X); | 6287 X = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, X); |
| 6087 Y = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, Y); | 6288 Y = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::v4i32, Y); |
| 6088 X = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, X); | 6289 X = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, X); |
| 6089 Y = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, Y); | 6290 Y = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::v4f32, Y); |
| 6090 // Get reciprocal estimate. | 6291 // Get reciprocal estimate. |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6383 Cycles32, DAG.getConstant(0, MVT::i32)); | 6584 Cycles32, DAG.getConstant(0, MVT::i32)); |
| 6384 Results.push_back(Cycles64); | 6585 Results.push_back(Cycles64); |
| 6385 Results.push_back(OutChain); | 6586 Results.push_back(OutChain); |
| 6386 } | 6587 } |
| 6387 | 6588 |
| 6388 SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { | 6589 SDValue ARMTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { |
| 6389 switch (Op.getOpcode()) { | 6590 switch (Op.getOpcode()) { |
| 6390 default: llvm_unreachable("Don't know how to custom lower this!"); | 6591 default: llvm_unreachable("Don't know how to custom lower this!"); |
| 6391 case ISD::ConstantPool: return LowerConstantPool(Op, DAG); | 6592 case ISD::ConstantPool: return LowerConstantPool(Op, DAG); |
| 6392 case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); | 6593 case ISD::BlockAddress: return LowerBlockAddress(Op, DAG); |
| 6594 case ISD::JumpTable: return LowerJumpTable(Op, DAG); // @LOCALMOD |
| 6393 case ISD::GlobalAddress: | 6595 case ISD::GlobalAddress: |
| 6394 switch (Subtarget->getTargetTriple().getObjectFormat()) { | 6596 switch (Subtarget->getTargetTriple().getObjectFormat()) { |
| 6395 default: llvm_unreachable("unknown object format"); | 6597 default: llvm_unreachable("unknown object format"); |
| 6396 case Triple::COFF: | 6598 case Triple::COFF: |
| 6397 return LowerGlobalAddressWindows(Op, DAG); | 6599 return LowerGlobalAddressWindows(Op, DAG); |
| 6398 case Triple::ELF: | 6600 case Triple::ELF: |
| 6399 return LowerGlobalAddressELF(Op, DAG); | 6601 return LowerGlobalAddressELF(Op, DAG); |
| 6400 case Triple::MachO: | 6602 case Triple::MachO: |
| 6401 return LowerGlobalAddressDarwin(Op, DAG); | 6603 return LowerGlobalAddressDarwin(Op, DAG); |
| 6402 } | 6604 } |
| 6403 case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); | 6605 case ISD::GlobalTLSAddress: return LowerGlobalTLSAddress(Op, DAG); |
| 6404 case ISD::SELECT: return LowerSELECT(Op, DAG); | 6606 case ISD::SELECT: return LowerSELECT(Op, DAG); |
| 6405 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); | 6607 case ISD::SELECT_CC: return LowerSELECT_CC(Op, DAG); |
| 6406 case ISD::BR_CC: return LowerBR_CC(Op, DAG); | 6608 case ISD::BR_CC: return LowerBR_CC(Op, DAG); |
| 6407 case ISD::BR_JT: return LowerBR_JT(Op, DAG); | 6609 case ISD::BR_JT: return LowerBR_JT(Op, DAG); |
| 6408 case ISD::VASTART: return LowerVASTART(Op, DAG); | 6610 case ISD::VASTART: return LowerVASTART(Op, DAG); |
| 6409 case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG, Subtarget); | 6611 case ISD::ATOMIC_FENCE: return LowerATOMIC_FENCE(Op, DAG, Subtarget); |
| 6410 case ISD::PREFETCH: return LowerPREFETCH(Op, DAG, Subtarget); | 6612 case ISD::PREFETCH: return LowerPREFETCH(Op, DAG, Subtarget); |
| 6411 case ISD::SINT_TO_FP: | 6613 case ISD::SINT_TO_FP: |
| 6412 case ISD::UINT_TO_FP: return LowerINT_TO_FP(Op, DAG); | 6614 case ISD::UINT_TO_FP: return LowerINT_TO_FP(Op, DAG); |
| 6413 case ISD::FP_TO_SINT: | 6615 case ISD::FP_TO_SINT: |
| 6414 case ISD::FP_TO_UINT: return LowerFP_TO_INT(Op, DAG); | 6616 case ISD::FP_TO_UINT: return LowerFP_TO_INT(Op, DAG); |
| 6415 case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG); | 6617 case ISD::FCOPYSIGN: return LowerFCOPYSIGN(Op, DAG); |
| 6416 case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); | 6618 case ISD::RETURNADDR: return LowerRETURNADDR(Op, DAG); |
| 6417 case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); | 6619 case ISD::FRAMEADDR: return LowerFRAMEADDR(Op, DAG); |
| 6620 // @LOCALMOD-START |
| 6621 // The exact semantics of this ISD are not completely clear. |
| 6622 // LLVM seems to always point the fp after the push ra and the old fp, i.e. |
| 6623 // two register slots after the beginning of the stack frame. |
| 6624 // It is not clear what happens when there is no frame pointer but |
| 6625 // but llvm unlike gcc seems to always force one when this node is |
| 6626 // encountered. |
| 6627 case ISD::FRAME_TO_ARGS_OFFSET: return DAG.getIntPtrConstant(2*4); |
| 6628 case ISD::EH_RETURN: return LowerEH_RETURN(Op, DAG); |
| 6629 // @LOCALMOD-END |
| 6630 |
| 6418 case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG); | 6631 case ISD::GLOBAL_OFFSET_TABLE: return LowerGLOBAL_OFFSET_TABLE(Op, DAG); |
| 6419 case ISD::EH_SJLJ_SETJMP: return LowerEH_SJLJ_SETJMP(Op, DAG); | 6632 case ISD::EH_SJLJ_SETJMP: return LowerEH_SJLJ_SETJMP(Op, DAG); |
| 6420 case ISD::EH_SJLJ_LONGJMP: return LowerEH_SJLJ_LONGJMP(Op, DAG); | 6633 case ISD::EH_SJLJ_LONGJMP: return LowerEH_SJLJ_LONGJMP(Op, DAG); |
| 6421 case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG, | 6634 case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG, |
| 6422 Subtarget); | 6635 Subtarget); |
| 6423 case ISD::BITCAST: return ExpandBITCAST(Op.getNode(), DAG); | 6636 case ISD::BITCAST: return ExpandBITCAST(Op.getNode(), DAG); |
| 6424 case ISD::SHL: | 6637 case ISD::SHL: |
| 6425 case ISD::SRL: | 6638 case ISD::SRL: |
| 6426 case ISD::SRA: return LowerShift(Op.getNode(), DAG, Subtarget); | 6639 case ISD::SRA: return LowerShift(Op.getNode(), DAG, Subtarget); |
| 6427 case ISD::SHL_PARTS: return LowerShiftLeftParts(Op, DAG); | 6640 case ISD::SHL_PARTS: return LowerShiftLeftParts(Op, DAG); |
| (...skipping 3870 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10298 /// offset pointer and addressing mode by reference if the node's address | 10511 /// offset pointer and addressing mode by reference if the node's address |
| 10299 /// can be legally represented as pre-indexed load / store address. | 10512 /// can be legally represented as pre-indexed load / store address. |
| 10300 bool | 10513 bool |
| 10301 ARMTargetLowering::getPreIndexedAddressParts(SDNode *N, SDValue &Base, | 10514 ARMTargetLowering::getPreIndexedAddressParts(SDNode *N, SDValue &Base, |
| 10302 SDValue &Offset, | 10515 SDValue &Offset, |
| 10303 ISD::MemIndexedMode &AM, | 10516 ISD::MemIndexedMode &AM, |
| 10304 SelectionDAG &DAG) const { | 10517 SelectionDAG &DAG) const { |
| 10305 if (Subtarget->isThumb1Only()) | 10518 if (Subtarget->isThumb1Only()) |
| 10306 return false; | 10519 return false; |
| 10307 | 10520 |
| 10521 // @LOCALMOD-START |
| 10522 // Avoid two reg addressing mode for loads and stores |
| 10523 const bool restrict_addressing_modes_for_nacl = Subtarget->isTargetNaCl() && |
| 10524 (N->getOpcode() == ISD::LOAD || N->getOpcode() == ISD::STORE); |
| 10525 if (restrict_addressing_modes_for_nacl) { |
| 10526 return false; |
| 10527 } |
| 10528 // @LOCALMOD-END |
| 10529 |
| 10308 EVT VT; | 10530 EVT VT; |
| 10309 SDValue Ptr; | 10531 SDValue Ptr; |
| 10310 bool isSEXTLoad = false; | 10532 bool isSEXTLoad = false; |
| 10311 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) { | 10533 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) { |
| 10312 Ptr = LD->getBasePtr(); | 10534 Ptr = LD->getBasePtr(); |
| 10313 VT = LD->getMemoryVT(); | 10535 VT = LD->getMemoryVT(); |
| 10314 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD; | 10536 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD; |
| 10315 } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) { | 10537 } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) { |
| 10316 Ptr = ST->getBasePtr(); | 10538 Ptr = ST->getBasePtr(); |
| 10317 VT = ST->getMemoryVT(); | 10539 VT = ST->getMemoryVT(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 10336 /// getPostIndexedAddressParts - returns true by value, base pointer and | 10558 /// getPostIndexedAddressParts - returns true by value, base pointer and |
| 10337 /// offset pointer and addressing mode by reference if this node can be | 10559 /// offset pointer and addressing mode by reference if this node can be |
| 10338 /// combined with a load / store to form a post-indexed load / store. | 10560 /// combined with a load / store to form a post-indexed load / store. |
| 10339 bool ARMTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op, | 10561 bool ARMTargetLowering::getPostIndexedAddressParts(SDNode *N, SDNode *Op, |
| 10340 SDValue &Base, | 10562 SDValue &Base, |
| 10341 SDValue &Offset, | 10563 SDValue &Offset, |
| 10342 ISD::MemIndexedMode &AM, | 10564 ISD::MemIndexedMode &AM, |
| 10343 SelectionDAG &DAG) const { | 10565 SelectionDAG &DAG) const { |
| 10344 if (Subtarget->isThumb1Only()) | 10566 if (Subtarget->isThumb1Only()) |
| 10345 return false; | 10567 return false; |
| 10346 | 10568 // @LOCALMOD-START |
| 10569 // Avoid two reg addressing mode for loads and stores |
| 10570 const bool restrict_addressing_modes_for_nacl = Subtarget->isTargetNaCl() && |
| 10571 (N->getOpcode() == ISD::LOAD || N->getOpcode() == ISD::STORE); |
| 10572 if (restrict_addressing_modes_for_nacl) { |
| 10573 return false; |
| 10574 } |
| 10575 // @LOCALMOD-END |
| 10347 EVT VT; | 10576 EVT VT; |
| 10348 SDValue Ptr; | 10577 SDValue Ptr; |
| 10349 bool isSEXTLoad = false; | 10578 bool isSEXTLoad = false; |
| 10350 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) { | 10579 if (LoadSDNode *LD = dyn_cast<LoadSDNode>(N)) { |
| 10351 VT = LD->getMemoryVT(); | 10580 VT = LD->getMemoryVT(); |
| 10352 Ptr = LD->getBasePtr(); | 10581 Ptr = LD->getBasePtr(); |
| 10353 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD; | 10582 isSEXTLoad = LD->getExtensionType() == ISD::SEXTLOAD; |
| 10354 } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) { | 10583 } else if (StoreSDNode *ST = dyn_cast<StoreSDNode>(N)) { |
| 10355 VT = ST->getMemoryVT(); | 10584 VT = ST->getMemoryVT(); |
| 10356 Ptr = ST->getBasePtr(); | 10585 Ptr = ST->getBasePtr(); |
| (...skipping 916 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11273 if (getEffectiveCallingConv(CallConv, isVarArg) != | 11502 if (getEffectiveCallingConv(CallConv, isVarArg) != |
| 11274 CallingConv::ARM_AAPCS_VFP) | 11503 CallingConv::ARM_AAPCS_VFP) |
| 11275 return false; | 11504 return false; |
| 11276 | 11505 |
| 11277 HABaseType Base = HA_UNKNOWN; | 11506 HABaseType Base = HA_UNKNOWN; |
| 11278 uint64_t Members = 0; | 11507 uint64_t Members = 0; |
| 11279 bool result = isHomogeneousAggregate(Ty, Base, Members); | 11508 bool result = isHomogeneousAggregate(Ty, Base, Members); |
| 11280 DEBUG(dbgs() << "isHA: " << result << " "; Ty->dump()); | 11509 DEBUG(dbgs() << "isHA: " << result << " "; Ty->dump()); |
| 11281 return result; | 11510 return result; |
| 11282 } | 11511 } |
| OLD | NEW |