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 |