Jia Liu | b22310f | 2012-02-18 12:03:15 +0000 | [diff] [blame] | 1 | //===-- HexagonISelLowering.h - Hexagon DAG Lowering Interface --*- C++ -*-===// |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 2 | // |
| 3 | // The LLVM Compiler Infrastructure |
| 4 | // |
| 5 | // This file is distributed under the University of Illinois Open Source |
| 6 | // License. See LICENSE.TXT for details. |
| 7 | // |
| 8 | //===----------------------------------------------------------------------===// |
| 9 | // |
| 10 | // This file defines the interfaces that Hexagon uses to lower LLVM code into a |
| 11 | // selection DAG. |
| 12 | // |
| 13 | //===----------------------------------------------------------------------===// |
| 14 | |
Benjamin Kramer | a7c40ef | 2014-08-13 16:26:38 +0000 | [diff] [blame] | 15 | #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H |
| 16 | #define LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 17 | |
Craig Topper | b25fda9 | 2012-03-17 18:46:09 +0000 | [diff] [blame] | 18 | #include "Hexagon.h" |
Eugene Zelenko | 58655bb | 2016-12-17 01:09:05 +0000 | [diff] [blame] | 19 | #include "llvm/ADT/StringRef.h" |
| 20 | #include "llvm/CodeGen/ISDOpcodes.h" |
| 21 | #include "llvm/CodeGen/MachineValueType.h" |
| 22 | #include "llvm/CodeGen/SelectionDAGNodes.h" |
David Blaikie | b3bde2e | 2017-11-17 01:07:10 +0000 | [diff] [blame] | 23 | #include "llvm/CodeGen/TargetLowering.h" |
Eugene Zelenko | 58655bb | 2016-12-17 01:09:05 +0000 | [diff] [blame] | 24 | #include "llvm/CodeGen/ValueTypes.h" |
Chandler Carruth | 9fb823b | 2013-01-02 11:36:10 +0000 | [diff] [blame] | 25 | #include "llvm/IR/CallingConv.h" |
Eugene Zelenko | 58655bb | 2016-12-17 01:09:05 +0000 | [diff] [blame] | 26 | #include "llvm/IR/InlineAsm.h" |
Eugene Zelenko | 58655bb | 2016-12-17 01:09:05 +0000 | [diff] [blame] | 27 | #include <cstdint> |
| 28 | #include <utility> |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 29 | |
| 30 | namespace llvm { |
Eugene Zelenko | 58655bb | 2016-12-17 01:09:05 +0000 | [diff] [blame] | 31 | |
| 32 | namespace HexagonISD { |
| 33 | |
Matthias Braun | d04893f | 2015-05-07 21:33:59 +0000 | [diff] [blame] | 34 | enum NodeType : unsigned { |
Krzysztof Parzyszek | 952d951 | 2015-04-22 21:17:00 +0000 | [diff] [blame] | 35 | OP_BEGIN = ISD::BUILTIN_OP_END, |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 36 | |
Krzysztof Parzyszek | 952d951 | 2015-04-22 21:17:00 +0000 | [diff] [blame] | 37 | CONST32 = OP_BEGIN, |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 38 | CONST32_GP, // For marking data present in GP. |
Krzysztof Parzyszek | 4fa2a9f | 2015-04-22 16:43:53 +0000 | [diff] [blame] | 39 | ALLOCA, |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 40 | |
Krzysztof Parzyszek | 21dc8bd | 2015-12-18 20:19:30 +0000 | [diff] [blame] | 41 | AT_GOT, // Index in GOT. |
| 42 | AT_PCREL, // Offset relative to PC. |
Colin LeMahieu | 60a99e6 | 2015-03-10 20:04:44 +0000 | [diff] [blame] | 43 | |
Krzysztof Parzyszek | be976d4 | 2016-08-12 11:12:02 +0000 | [diff] [blame] | 44 | CALL, // Function call. |
| 45 | CALLnr, // Function call that does not return. |
Colin LeMahieu | 2e3a26d | 2015-01-16 17:05:27 +0000 | [diff] [blame] | 46 | CALLR, |
| 47 | |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 48 | RET_FLAG, // Return with a flag operand. |
Krzysztof Parzyszek | 4211334 | 2015-03-19 16:33:08 +0000 | [diff] [blame] | 49 | BARRIER, // Memory barrier. |
| 50 | JT, // Jump table. |
| 51 | CP, // Constant pool. |
Krzysztof Parzyszek | 952d951 | 2015-04-22 21:17:00 +0000 | [diff] [blame] | 52 | |
Colin LeMahieu | 383c36e | 2014-12-05 18:24:06 +0000 | [diff] [blame] | 53 | COMBINE, |
Krzysztof Parzyszek | f85dd9f | 2017-07-10 20:16:44 +0000 | [diff] [blame] | 54 | VSPLAT, |
| 55 | VASL, |
| 56 | VASR, |
| 57 | VLSR, |
Krzysztof Parzyszek | 952d951 | 2015-04-22 21:17:00 +0000 | [diff] [blame] | 58 | |
| 59 | INSERT, |
Krzysztof Parzyszek | 952d951 | 2015-04-22 21:17:00 +0000 | [diff] [blame] | 60 | EXTRACTU, |
Krzysztof Parzyszek | c168c01 | 2015-12-03 16:47:20 +0000 | [diff] [blame] | 61 | VCOMBINE, |
Krzysztof Parzyszek | 302a9d4 | 2017-07-14 19:02:32 +0000 | [diff] [blame] | 62 | VPACKE, |
| 63 | VPACKO, |
Krzysztof Parzyszek | 7d37dd8 | 2017-12-06 16:40:37 +0000 | [diff] [blame] | 64 | VEXTRACTW, |
| 65 | VINSERTW0, |
| 66 | VROR, |
Jyotsna Verma | 5ed5181 | 2013-05-01 21:37:34 +0000 | [diff] [blame] | 67 | TC_RETURN, |
Colin LeMahieu | 68b2e05 | 2015-01-06 19:03:20 +0000 | [diff] [blame] | 68 | EH_RETURN, |
Krzysztof Parzyszek | 952d951 | 2015-04-22 21:17:00 +0000 | [diff] [blame] | 69 | DCFETCH, |
Krzysztof Parzyszek | ab57c2b | 2017-02-22 22:28:47 +0000 | [diff] [blame] | 70 | READCYCLE, |
Krzysztof Parzyszek | e4ce92c | 2017-12-20 20:49:43 +0000 | [diff] [blame] | 71 | VZERO, |
Krzysztof Parzyszek | 952d951 | 2015-04-22 21:17:00 +0000 | [diff] [blame] | 72 | |
| 73 | OP_END |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 74 | }; |
Eugene Zelenko | 58655bb | 2016-12-17 01:09:05 +0000 | [diff] [blame] | 75 | |
| 76 | } // end namespace HexagonISD |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 77 | |
Eric Christopher | d737b76 | 2015-02-02 22:11:36 +0000 | [diff] [blame] | 78 | class HexagonSubtarget; |
| 79 | |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 80 | class HexagonTargetLowering : public TargetLowering { |
| 81 | int VarArgsFrameOffset; // Frame offset to start of varargs area. |
Eugene Zelenko | 58655bb | 2016-12-17 01:09:05 +0000 | [diff] [blame] | 82 | const HexagonTargetMachine &HTM; |
| 83 | const HexagonSubtarget &Subtarget; |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 84 | |
Krzysztof Parzyszek | 952d951 | 2015-04-22 21:17:00 +0000 | [diff] [blame] | 85 | bool CanReturnSmallStruct(const Function* CalleeFn, unsigned& RetSize) |
| 86 | const; |
Craig Topper | 18e69f4 | 2016-04-15 06:20:21 +0000 | [diff] [blame] | 87 | void promoteLdStType(MVT VT, MVT PromotedLdStVT); |
Krzysztof Parzyszek | 4211334 | 2015-03-19 16:33:08 +0000 | [diff] [blame] | 88 | |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 89 | public: |
Eric Christopher | d737b76 | 2015-02-02 22:11:36 +0000 | [diff] [blame] | 90 | explicit HexagonTargetLowering(const TargetMachine &TM, |
Krzysztof Parzyszek | 952d951 | 2015-04-22 21:17:00 +0000 | [diff] [blame] | 91 | const HexagonSubtarget &ST); |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 92 | |
Krzysztof Parzyszek | 7d37dd8 | 2017-12-06 16:40:37 +0000 | [diff] [blame] | 93 | bool isHVXVectorType(MVT Ty) const; |
| 94 | |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 95 | /// IsEligibleForTailCallOptimization - Check whether the call is eligible |
| 96 | /// for tail call optimization. Targets which want to do tail call |
| 97 | /// optimization should implement this function. |
Krzysztof Parzyszek | 952d951 | 2015-04-22 21:17:00 +0000 | [diff] [blame] | 98 | bool IsEligibleForTailCallOptimization(SDValue Callee, |
| 99 | CallingConv::ID CalleeCC, bool isVarArg, bool isCalleeStructRet, |
| 100 | bool isCallerStructRet, const SmallVectorImpl<ISD::OutputArg> &Outs, |
| 101 | const SmallVectorImpl<SDValue> &OutVals, |
| 102 | const SmallVectorImpl<ISD::InputArg> &Ins, SelectionDAG& DAG) const; |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 103 | |
Krzysztof Parzyszek | a8ab1b7 | 2017-12-11 18:57:54 +0000 | [diff] [blame] | 104 | bool getTgtMemIntrinsic(IntrinsicInfo &Info, const CallInst &I, |
Matt Arsenault | 7d7adf4 | 2017-12-14 22:34:10 +0000 | [diff] [blame] | 105 | MachineFunction &MF, |
Krzysztof Parzyszek | a8ab1b7 | 2017-12-11 18:57:54 +0000 | [diff] [blame] | 106 | unsigned Intrinsic) const override; |
| 107 | |
Craig Topper | 906c2cd | 2014-04-29 07:58:16 +0000 | [diff] [blame] | 108 | bool isTruncateFree(Type *Ty1, Type *Ty2) const override; |
| 109 | bool isTruncateFree(EVT VT1, EVT VT2) const override; |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 110 | |
Craig Topper | 906c2cd | 2014-04-29 07:58:16 +0000 | [diff] [blame] | 111 | bool allowTruncateForTailCall(Type *Ty1, Type *Ty2) const override; |
Tim Northover | a441585 | 2013-08-06 09:12:35 +0000 | [diff] [blame] | 112 | |
Krzysztof Parzyszek | bd8ef4b | 2016-08-19 13:34:31 +0000 | [diff] [blame] | 113 | /// Return true if an FMA operation is faster than a pair of mul and add |
| 114 | /// instructions. fmuladd intrinsics will be expanded to FMAs when this |
| 115 | /// method returns true (and FMAs are legal), otherwise fmuladd is |
| 116 | /// expanded to mul + add. |
| 117 | bool isFMAFasterThanFMulAndFAdd(EVT) const override; |
| 118 | |
Krzysztof Parzyszek | 4211334 | 2015-03-19 16:33:08 +0000 | [diff] [blame] | 119 | // Should we expand the build vector with shuffles? |
| 120 | bool shouldExpandBuildVectorWithShuffles(EVT VT, |
Krzysztof Parzyszek | 952d951 | 2015-04-22 21:17:00 +0000 | [diff] [blame] | 121 | unsigned DefinedValues) const override; |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 122 | |
Zvi Rackover | 1b73682 | 2017-07-26 08:06:58 +0000 | [diff] [blame] | 123 | bool isShuffleMaskLegal(ArrayRef<int> Mask, EVT VT) const override; |
Krzysztof Parzyszek | 5439a70 | 2017-12-18 18:21:01 +0000 | [diff] [blame] | 124 | TargetLoweringBase::LegalizeTypeAction getPreferredVectorAction(EVT VT) |
| 125 | const override; |
Krzysztof Parzyszek | d19d050 | 2016-09-13 21:16:07 +0000 | [diff] [blame] | 126 | |
Krzysztof Parzyszek | 4211334 | 2015-03-19 16:33:08 +0000 | [diff] [blame] | 127 | SDValue LowerOperation(SDValue Op, SelectionDAG &DAG) const override; |
Craig Topper | 906c2cd | 2014-04-29 07:58:16 +0000 | [diff] [blame] | 128 | const char *getTargetNodeName(unsigned Opcode) const override; |
Krzysztof Parzyszek | 6a8e5f4 | 2017-11-29 19:58:10 +0000 | [diff] [blame] | 129 | |
| 130 | SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) const; |
Krzysztof Parzyszek | 4211334 | 2015-03-19 16:33:08 +0000 | [diff] [blame] | 131 | SDValue LowerCONCAT_VECTORS(SDValue Op, SelectionDAG &DAG) const; |
Krzysztof Parzyszek | 6a8e5f4 | 2017-11-29 19:58:10 +0000 | [diff] [blame] | 132 | SDValue LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; |
| 133 | SDValue LowerEXTRACT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const; |
Krzysztof Parzyszek | 6a8e5f4 | 2017-11-29 19:58:10 +0000 | [diff] [blame] | 134 | SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) const; |
Krzysztof Parzyszek | 7d37dd8 | 2017-12-06 16:40:37 +0000 | [diff] [blame] | 135 | SDValue LowerINSERT_SUBVECTOR(SDValue Op, SelectionDAG &DAG) const; |
Krzysztof Parzyszek | 0bd55a7 | 2016-07-29 16:44:27 +0000 | [diff] [blame] | 136 | SDValue LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) const; |
| 137 | SDValue LowerVECTOR_SHIFT(SDValue Op, SelectionDAG &DAG) const; |
Krzysztof Parzyszek | 6a8e5f4 | 2017-11-29 19:58:10 +0000 | [diff] [blame] | 138 | |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 139 | SDValue LowerDYNAMIC_STACKALLOC(SDValue Op, SelectionDAG &DAG) const; |
| 140 | SDValue LowerINLINEASM(SDValue Op, SelectionDAG &DAG) const; |
Krzysztof Parzyszek | 6895b2c | 2016-02-18 13:58:38 +0000 | [diff] [blame] | 141 | SDValue LowerPREFETCH(SDValue Op, SelectionDAG &DAG) const; |
Krzysztof Parzyszek | ab57c2b | 2017-02-22 22:28:47 +0000 | [diff] [blame] | 142 | SDValue LowerREADCYCLECOUNTER(SDValue Op, SelectionDAG &DAG) const; |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 143 | SDValue LowerEH_LABEL(SDValue Op, SelectionDAG &DAG) const; |
Jyotsna Verma | 5ed5181 | 2013-05-01 21:37:34 +0000 | [diff] [blame] | 144 | SDValue LowerEH_RETURN(SDValue Op, SelectionDAG &DAG) const; |
Benjamin Kramer | bdc4956 | 2016-06-12 15:39:02 +0000 | [diff] [blame] | 145 | SDValue |
| 146 | LowerFormalArguments(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, |
| 147 | const SmallVectorImpl<ISD::InputArg> &Ins, |
| 148 | const SDLoc &dl, SelectionDAG &DAG, |
| 149 | SmallVectorImpl<SDValue> &InVals) const override; |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 150 | SDValue LowerGLOBALADDRESS(SDValue Op, SelectionDAG &DAG) const; |
Jyotsna Verma | 2ba0c0b | 2013-03-07 19:10:28 +0000 | [diff] [blame] | 151 | SDValue LowerBlockAddress(SDValue Op, SelectionDAG &DAG) const; |
Krzysztof Parzyszek | 7a737d1 | 2016-02-18 15:42:57 +0000 | [diff] [blame] | 152 | SDValue LowerGlobalTLSAddress(SDValue Op, SelectionDAG &DAG) const; |
| 153 | SDValue LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, |
| 154 | SelectionDAG &DAG) const; |
| 155 | SDValue LowerToTLSInitialExecModel(GlobalAddressSDNode *GA, |
| 156 | SelectionDAG &DAG) const; |
| 157 | SDValue LowerToTLSLocalExecModel(GlobalAddressSDNode *GA, |
| 158 | SelectionDAG &DAG) const; |
| 159 | SDValue GetDynamicTLSAddr(SelectionDAG &DAG, SDValue Chain, |
Krzysztof Parzyszek | 1aaf41a | 2017-02-17 22:14:51 +0000 | [diff] [blame] | 160 | GlobalAddressSDNode *GA, SDValue InFlag, EVT PtrVT, |
Krzysztof Parzyszek | 7a737d1 | 2016-02-18 15:42:57 +0000 | [diff] [blame] | 161 | unsigned ReturnReg, unsigned char OperandFlags) const; |
Krzysztof Parzyszek | 21dc8bd | 2015-12-18 20:19:30 +0000 | [diff] [blame] | 162 | SDValue LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG) const; |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 163 | |
Justin Holewinski | aa58397 | 2012-05-25 16:35:28 +0000 | [diff] [blame] | 164 | SDValue LowerCall(TargetLowering::CallLoweringInfo &CLI, |
Krzysztof Parzyszek | 952d951 | 2015-04-22 21:17:00 +0000 | [diff] [blame] | 165 | SmallVectorImpl<SDValue> &InVals) const override; |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 166 | SDValue LowerCallResult(SDValue Chain, SDValue InFlag, |
Benjamin Kramer | bdc4956 | 2016-06-12 15:39:02 +0000 | [diff] [blame] | 167 | CallingConv::ID CallConv, bool isVarArg, |
| 168 | const SmallVectorImpl<ISD::InputArg> &Ins, |
| 169 | const SDLoc &dl, SelectionDAG &DAG, |
| 170 | SmallVectorImpl<SDValue> &InVals, |
| 171 | const SmallVectorImpl<SDValue> &OutVals, |
| 172 | SDValue Callee) const; |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 173 | |
Krzysztof Parzyszek | 4211334 | 2015-03-19 16:33:08 +0000 | [diff] [blame] | 174 | SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG) const; |
| 175 | SDValue LowerVSELECT(SDValue Op, SelectionDAG &DAG) const; |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 176 | SDValue LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) const; |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 177 | SDValue LowerATOMIC_FENCE(SDValue Op, SelectionDAG& DAG) const; |
| 178 | SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) const; |
| 179 | |
Krzysztof Parzyszek | 5619952 | 2017-04-13 15:05:51 +0000 | [diff] [blame] | 180 | bool CanLowerReturn(CallingConv::ID CallConv, |
| 181 | MachineFunction &MF, bool isVarArg, |
| 182 | const SmallVectorImpl<ISD::OutputArg> &Outs, |
| 183 | LLVMContext &Context) const override; |
| 184 | |
Benjamin Kramer | bdc4956 | 2016-06-12 15:39:02 +0000 | [diff] [blame] | 185 | SDValue LowerReturn(SDValue Chain, CallingConv::ID CallConv, bool isVarArg, |
| 186 | const SmallVectorImpl<ISD::OutputArg> &Outs, |
| 187 | const SmallVectorImpl<SDValue> &OutVals, |
| 188 | const SDLoc &dl, SelectionDAG &DAG) const override; |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 189 | |
Matt Arsenault | 3138075 | 2017-04-18 21:16:46 +0000 | [diff] [blame] | 190 | bool mayBeEmittedAsTailCall(const CallInst *CI) const override; |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 191 | |
Joseph Tremoulet | f748c89 | 2015-11-07 01:11:31 +0000 | [diff] [blame] | 192 | /// If a physical register, this returns the register that receives the |
| 193 | /// exception address on entry to an EH pad. |
| 194 | unsigned |
| 195 | getExceptionPointerRegister(const Constant *PersonalityFn) const override { |
| 196 | return Hexagon::R0; |
| 197 | } |
| 198 | |
| 199 | /// If a physical register, this returns the register that receives the |
| 200 | /// exception typeid on entry to a landing pad. |
| 201 | unsigned |
| 202 | getExceptionSelectorRegister(const Constant *PersonalityFn) const override { |
| 203 | return Hexagon::R1; |
| 204 | } |
| 205 | |
Krzysztof Parzyszek | 952d951 | 2015-04-22 21:17:00 +0000 | [diff] [blame] | 206 | SDValue LowerVASTART(SDValue Op, SelectionDAG &DAG) const; |
| 207 | SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG) const; |
Krzysztof Parzyszek | 21dc8bd | 2015-12-18 20:19:30 +0000 | [diff] [blame] | 208 | SDValue LowerJumpTable(SDValue Op, SelectionDAG &DAG) const; |
Eugene Zelenko | 58655bb | 2016-12-17 01:09:05 +0000 | [diff] [blame] | 209 | |
Mehdi Amini | 44ede33 | 2015-07-09 02:09:04 +0000 | [diff] [blame] | 210 | EVT getSetCCResultType(const DataLayout &, LLVMContext &C, |
| 211 | EVT VT) const override { |
Juergen Ributzka | 34c652d | 2013-11-13 01:57:54 +0000 | [diff] [blame] | 212 | if (!VT.isVector()) |
| 213 | return MVT::i1; |
| 214 | else |
| 215 | return EVT::getVectorVT(C, MVT::i1, VT.getVectorNumElements()); |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 216 | } |
| 217 | |
Craig Topper | 906c2cd | 2014-04-29 07:58:16 +0000 | [diff] [blame] | 218 | bool getPostIndexedAddressParts(SDNode *N, SDNode *Op, |
| 219 | SDValue &Base, SDValue &Offset, |
| 220 | ISD::MemIndexedMode &AM, |
| 221 | SelectionDAG &DAG) const override; |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 222 | |
Krzysztof Parzyszek | ca3b532 | 2016-05-18 14:34:51 +0000 | [diff] [blame] | 223 | ConstraintType getConstraintType(StringRef Constraint) const override; |
| 224 | |
Eric Christopher | 11e4df7 | 2015-02-26 22:38:43 +0000 | [diff] [blame] | 225 | std::pair<unsigned, const TargetRegisterClass *> |
| 226 | getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI, |
Benjamin Kramer | 9bfb627 | 2015-07-05 19:29:18 +0000 | [diff] [blame] | 227 | StringRef Constraint, MVT VT) const override; |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 228 | |
Benjamin Kramer | 9bfb627 | 2015-07-05 19:29:18 +0000 | [diff] [blame] | 229 | unsigned |
| 230 | getInlineAsmMemConstraint(StringRef ConstraintCode) const override { |
Daniel Sanders | 49f643c | 2015-03-17 14:37:39 +0000 | [diff] [blame] | 231 | if (ConstraintCode == "o") |
| 232 | return InlineAsm::Constraint_o; |
Daniel Sanders | 49f643c | 2015-03-17 14:37:39 +0000 | [diff] [blame] | 233 | return TargetLowering::getInlineAsmMemConstraint(ConstraintCode); |
Daniel Sanders | bf5b80f | 2015-03-16 13:13:41 +0000 | [diff] [blame] | 234 | } |
| 235 | |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 236 | // Intrinsics |
Craig Topper | 906c2cd | 2014-04-29 07:58:16 +0000 | [diff] [blame] | 237 | SDValue LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) const; |
Krzysztof Parzyszek | 6895b2c | 2016-02-18 13:58:38 +0000 | [diff] [blame] | 238 | SDValue LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const; |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 239 | /// isLegalAddressingMode - Return true if the addressing mode represented |
| 240 | /// by AM is legal for this target, for a load/store of the specified type. |
| 241 | /// The type may be VoidTy, in which case only return true if the addressing |
| 242 | /// mode is legal for a load/store of any legal type. |
| 243 | /// TODO: Handle pre/postinc as well. |
Mehdi Amini | 0cdec1e | 2015-07-09 02:09:40 +0000 | [diff] [blame] | 244 | bool isLegalAddressingMode(const DataLayout &DL, const AddrMode &AM, |
Jonas Paulsson | 024e319 | 2017-07-21 11:59:37 +0000 | [diff] [blame] | 245 | Type *Ty, unsigned AS, |
| 246 | Instruction *I = nullptr) const override; |
Krzysztof Parzyszek | 21dc8bd | 2015-12-18 20:19:30 +0000 | [diff] [blame] | 247 | /// Return true if folding a constant offset with the given GlobalAddress |
| 248 | /// is legal. It is frequently not legal in PIC relocation models. |
| 249 | bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override; |
| 250 | |
Craig Topper | 906c2cd | 2014-04-29 07:58:16 +0000 | [diff] [blame] | 251 | bool isFPImmLegal(const APFloat &Imm, EVT VT) const override; |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 252 | |
| 253 | /// isLegalICmpImmediate - Return true if the specified immediate is legal |
| 254 | /// icmp immediate, that is the target has icmp instructions which can |
| 255 | /// compare a register against the immediate without having to materialize |
| 256 | /// the immediate into a register. |
Craig Topper | 906c2cd | 2014-04-29 07:58:16 +0000 | [diff] [blame] | 257 | bool isLegalICmpImmediate(int64_t Imm) const override; |
Krzysztof Parzyszek | feaf7b8 | 2015-07-09 14:51:21 +0000 | [diff] [blame] | 258 | |
Krzysztof Parzyszek | 3e409e1 | 2016-08-02 18:34:31 +0000 | [diff] [blame] | 259 | EVT getOptimalMemOpType(uint64_t Size, unsigned DstAlign, |
| 260 | unsigned SrcAlign, bool IsMemset, bool ZeroMemset, bool MemcpyStrSrc, |
| 261 | MachineFunction &MF) const override; |
| 262 | |
Krzysztof Parzyszek | 2d65ea7 | 2016-03-28 15:43:03 +0000 | [diff] [blame] | 263 | bool allowsMisalignedMemoryAccesses(EVT VT, unsigned AddrSpace, |
| 264 | unsigned Align, bool *Fast) const override; |
| 265 | |
Krzysztof Parzyszek | 21dc8bd | 2015-12-18 20:19:30 +0000 | [diff] [blame] | 266 | /// Returns relocation base for the given PIC jumptable. |
| 267 | SDValue getPICJumpTableRelocBase(SDValue Table, SelectionDAG &DAG) |
| 268 | const override; |
| 269 | |
Krzysztof Parzyszek | feaf7b8 | 2015-07-09 14:51:21 +0000 | [diff] [blame] | 270 | // Handling of atomic RMW instructions. |
Krzysztof Parzyszek | feaf7b8 | 2015-07-09 14:51:21 +0000 | [diff] [blame] | 271 | Value *emitLoadLinked(IRBuilder<> &Builder, Value *Addr, |
| 272 | AtomicOrdering Ord) const override; |
| 273 | Value *emitStoreConditional(IRBuilder<> &Builder, Value *Val, |
| 274 | Value *Addr, AtomicOrdering Ord) const override; |
Ahmed Bougacha | 5246867 | 2015-09-11 17:08:28 +0000 | [diff] [blame] | 275 | AtomicExpansionKind shouldExpandAtomicLoadInIR(LoadInst *LI) const override; |
Krzysztof Parzyszek | feaf7b8 | 2015-07-09 14:51:21 +0000 | [diff] [blame] | 276 | bool shouldExpandAtomicStoreInIR(StoreInst *SI) const override; |
Krzysztof Parzyszek | f228c95 | 2016-06-22 16:07:10 +0000 | [diff] [blame] | 277 | bool shouldExpandAtomicCmpXchgInIR(AtomicCmpXchgInst *AI) const override; |
| 278 | |
Ahmed Bougacha | 9d67713 | 2015-09-11 17:08:17 +0000 | [diff] [blame] | 279 | AtomicExpansionKind |
| 280 | shouldExpandAtomicRMWInIR(AtomicRMWInst *AI) const override { |
| 281 | return AtomicExpansionKind::LLSC; |
Krzysztof Parzyszek | feaf7b8 | 2015-07-09 14:51:21 +0000 | [diff] [blame] | 282 | } |
Krzysztof Parzyszek | 08ff888 | 2015-11-26 18:38:27 +0000 | [diff] [blame] | 283 | |
Krzysztof Parzyszek | 6a8e5f4 | 2017-11-29 19:58:10 +0000 | [diff] [blame] | 284 | private: |
Krzysztof Parzyszek | e4ce92c | 2017-12-20 20:49:43 +0000 | [diff] [blame] | 285 | bool getBuildVectorConstInts(ArrayRef<SDValue> Values, MVT VecTy, |
| 286 | SelectionDAG &DAG, |
| 287 | MutableArrayRef<ConstantInt*> Consts) const; |
Krzysztof Parzyszek | 039d4d9 | 2017-12-07 17:37:28 +0000 | [diff] [blame] | 288 | SDValue buildVector32(ArrayRef<SDValue> Elem, const SDLoc &dl, MVT VecTy, |
| 289 | SelectionDAG &DAG) const; |
| 290 | SDValue buildVector64(ArrayRef<SDValue> Elem, const SDLoc &dl, MVT VecTy, |
| 291 | SelectionDAG &DAG) const; |
| 292 | SDValue extractVector(SDValue VecV, SDValue IdxV, const SDLoc &dl, |
| 293 | MVT ValTy, MVT ResTy, SelectionDAG &DAG) const; |
| 294 | SDValue insertVector(SDValue VecV, SDValue ValV, SDValue IdxV, |
| 295 | const SDLoc &dl, MVT ValTy, SelectionDAG &DAG) const; |
| 296 | bool isUndef(SDValue Op) const { |
| 297 | if (Op.isMachineOpcode()) |
| 298 | return Op.getMachineOpcode() == TargetOpcode::IMPLICIT_DEF; |
| 299 | return Op.getOpcode() == ISD::UNDEF; |
| 300 | } |
| 301 | SDValue getNode(unsigned MachineOpc, const SDLoc &dl, MVT Ty, |
| 302 | ArrayRef<SDValue> Ops, SelectionDAG &DAG) const { |
| 303 | SDNode *N = DAG.getMachineNode(MachineOpc, dl, Ty, Ops); |
| 304 | return SDValue(N, 0); |
| 305 | } |
Krzysztof Parzyszek | e4ce92c | 2017-12-20 20:49:43 +0000 | [diff] [blame] | 306 | SDValue getZero(const SDLoc &dl, MVT Ty, SelectionDAG &DAG) const; |
Krzysztof Parzyszek | 039d4d9 | 2017-12-07 17:37:28 +0000 | [diff] [blame] | 307 | |
| 308 | using VectorPair = std::pair<SDValue, SDValue>; |
| 309 | using TypePair = std::pair<MVT, MVT>; |
| 310 | |
| 311 | SDValue getInt(unsigned IntId, MVT ResTy, ArrayRef<SDValue> Ops, |
| 312 | const SDLoc &dl, SelectionDAG &DAG) const; |
| 313 | |
Krzysztof Parzyszek | 6a8e5f4 | 2017-11-29 19:58:10 +0000 | [diff] [blame] | 314 | MVT ty(SDValue Op) const { |
| 315 | return Op.getValueType().getSimpleVT(); |
| 316 | } |
Krzysztof Parzyszek | 039d4d9 | 2017-12-07 17:37:28 +0000 | [diff] [blame] | 317 | TypePair ty(const VectorPair &Ops) const { |
| 318 | return { Ops.first.getValueType().getSimpleVT(), |
| 319 | Ops.second.getValueType().getSimpleVT() }; |
| 320 | } |
Krzysztof Parzyszek | 6a8e5f4 | 2017-11-29 19:58:10 +0000 | [diff] [blame] | 321 | MVT tyScalar(MVT Ty) const { |
| 322 | if (!Ty.isVector()) |
| 323 | return Ty; |
| 324 | return MVT::getIntegerVT(Ty.getSizeInBits()); |
| 325 | } |
Krzysztof Parzyszek | 7d37dd8 | 2017-12-06 16:40:37 +0000 | [diff] [blame] | 326 | MVT tyVector(MVT Ty, MVT ElemTy) const { |
| 327 | if (Ty.isVector() && Ty.getVectorElementType() == ElemTy) |
| 328 | return Ty; |
| 329 | unsigned TyWidth = Ty.getSizeInBits(), ElemWidth = ElemTy.getSizeInBits(); |
| 330 | assert((TyWidth % ElemWidth) == 0); |
| 331 | return MVT::getVectorVT(ElemTy, TyWidth/ElemWidth); |
| 332 | } |
Krzysztof Parzyszek | 6a8e5f4 | 2017-11-29 19:58:10 +0000 | [diff] [blame] | 333 | |
Krzysztof Parzyszek | 7d37dd8 | 2017-12-06 16:40:37 +0000 | [diff] [blame] | 334 | MVT typeJoin(const TypePair &Tys) const; |
| 335 | TypePair typeSplit(MVT Ty) const; |
Krzysztof Parzyszek | 7d37dd8 | 2017-12-06 16:40:37 +0000 | [diff] [blame] | 336 | MVT typeExtElem(MVT VecTy, unsigned Factor) const; |
| 337 | MVT typeTruncElem(MVT VecTy, unsigned Factor) const; |
| 338 | |
| 339 | SDValue opJoin(const VectorPair &Ops, const SDLoc &dl, |
| 340 | SelectionDAG &DAG) const; |
| 341 | VectorPair opSplit(SDValue Vec, const SDLoc &dl, SelectionDAG &DAG) const; |
| 342 | SDValue opCastElem(SDValue Vec, MVT ElemTy, SelectionDAG &DAG) const; |
| 343 | |
| 344 | SDValue convertToByteIndex(SDValue ElemIdx, MVT ElemTy, |
| 345 | SelectionDAG &DAG) const; |
| 346 | SDValue getIndexInWord32(SDValue Idx, MVT ElemTy, SelectionDAG &DAG) const; |
Krzysztof Parzyszek | 039d4d9 | 2017-12-07 17:37:28 +0000 | [diff] [blame] | 347 | SDValue getByteShuffle(const SDLoc &dl, SDValue Op0, SDValue Op1, |
| 348 | ArrayRef<int> Mask, SelectionDAG &DAG) const; |
Krzysztof Parzyszek | 7d37dd8 | 2017-12-06 16:40:37 +0000 | [diff] [blame] | 349 | |
Krzysztof Parzyszek | e4ce92c | 2017-12-20 20:49:43 +0000 | [diff] [blame] | 350 | MVT getVecBoolVT() const; |
| 351 | |
| 352 | SDValue buildHvxVectorSingle(ArrayRef<SDValue> Values, const SDLoc &dl, |
| 353 | MVT VecTy, SelectionDAG &DAG) const; |
| 354 | SDValue buildHvxVectorPred(ArrayRef<SDValue> Values, const SDLoc &dl, |
| 355 | MVT VecTy, SelectionDAG &DAG) const; |
| 356 | |
Krzysztof Parzyszek | 7d37dd8 | 2017-12-06 16:40:37 +0000 | [diff] [blame] | 357 | SDValue LowerHvxBuildVector(SDValue Op, SelectionDAG &DAG) const; |
| 358 | SDValue LowerHvxExtractElement(SDValue Op, SelectionDAG &DAG) const; |
| 359 | SDValue LowerHvxInsertElement(SDValue Op, SelectionDAG &DAG) const; |
| 360 | SDValue LowerHvxExtractSubvector(SDValue Op, SelectionDAG &DAG) const; |
| 361 | SDValue LowerHvxInsertSubvector(SDValue Op, SelectionDAG &DAG) const; |
Krzysztof Parzyszek | 039d4d9 | 2017-12-07 17:37:28 +0000 | [diff] [blame] | 362 | SDValue LowerHvxMul(SDValue Op, SelectionDAG &DAG) const; |
Krzysztof Parzyszek | 4707605 | 2017-12-14 21:28:48 +0000 | [diff] [blame] | 363 | SDValue LowerHvxSetCC(SDValue Op, SelectionDAG &DAG) const; |
Krzysztof Parzyszek | 6b589e5 | 2017-12-18 18:32:27 +0000 | [diff] [blame] | 364 | SDValue LowerHvxExtend(SDValue Op, SelectionDAG &DAG) const; |
Krzysztof Parzyszek | 7d37dd8 | 2017-12-06 16:40:37 +0000 | [diff] [blame] | 365 | |
Krzysztof Parzyszek | 08ff888 | 2015-11-26 18:38:27 +0000 | [diff] [blame] | 366 | std::pair<const TargetRegisterClass*, uint8_t> |
| 367 | findRepresentativeClass(const TargetRegisterInfo *TRI, MVT VT) |
| 368 | const override; |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 369 | }; |
Eugene Zelenko | 58655bb | 2016-12-17 01:09:05 +0000 | [diff] [blame] | 370 | |
Tony Linthicum | 1213a7a | 2011-12-12 21:14:40 +0000 | [diff] [blame] | 371 | } // end namespace llvm |
| 372 | |
Eugene Zelenko | 58655bb | 2016-12-17 01:09:05 +0000 | [diff] [blame] | 373 | #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONISELLOWERING_H |