1 //===------------ AMDILInstrInfo.td - AMDIL Target ------*-tablegen-*------===// 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 describes the AMDIL instructions in TableGen format. 11 // 12 //===----------------------------------------------------------------------===// 13 // AMDIL Instruction Predicate Definitions 14 // Predicate that is set to true if the hardware supports double precision 15 // divide 16 def HasHWDDiv : Predicate<"Subtarget.device()" 17 "->getGeneration() > AMDGPUDeviceInfo::HD4XXX && " 18 "Subtarget.device()->usesHardware(AMDGPUDeviceInfo::DoubleOps)">; 19 20 // Predicate that is set to true if the hardware supports double, but not double 21 // precision divide in hardware 22 def HasSWDDiv : Predicate<"Subtarget.device()" 23 "->getGeneration() == AMDGPUDeviceInfo::HD4XXX &&" 24 "Subtarget.device()->usesHardware(AMDGPUDeviceInfo::DoubleOps)">; 25 26 // Predicate that is set to true if the hardware support 24bit signed 27 // math ops. Otherwise a software expansion to 32bit math ops is used instead. 28 def HasHWSign24Bit : Predicate<"Subtarget.device()" 29 "->getGeneration() > AMDGPUDeviceInfo::HD5XXX">; 30 31 // Predicate that is set to true if 64bit operations are supported or not 32 def HasHW64Bit : Predicate<"Subtarget.device()" 33 "->usesHardware(AMDGPUDeviceInfo::LongOps)">; 34 def HasSW64Bit : Predicate<"Subtarget.device()" 35 "->usesSoftware(AMDGPUDeviceInfo::LongOps)">; 36 37 // Predicate that is set to true if the timer register is supported 38 def HasTmrRegister : Predicate<"Subtarget.device()" 39 "->isSupported(AMDGPUDeviceInfo::TmrReg)">; 40 // Predicate that is true if we are at least evergreen series 41 def HasDeviceIDInst : Predicate<"Subtarget.device()" 42 "->getGeneration() >= AMDGPUDeviceInfo::HD5XXX">; 43 44 // Predicate that is true if we have region address space. 45 def hasRegionAS : Predicate<"Subtarget.device()" 46 "->usesHardware(AMDGPUDeviceInfo::RegionMem)">; 47 48 // Predicate that is false if we don't have region address space. 49 def noRegionAS : Predicate<"!Subtarget.device()" 50 "->isSupported(AMDGPUDeviceInfo::RegionMem)">; 51 52 53 // Predicate that is set to true if 64bit Mul is supported in the IL or not 54 def HasHW64Mul : Predicate<"Subtarget.calVersion()" 55 ">= CAL_VERSION_SC_139" 56 "&& Subtarget.device()" 57 "->getGeneration() >=" 58 "AMDGPUDeviceInfo::HD5XXX">; 59 def HasSW64Mul : Predicate<"Subtarget.calVersion()" 60 "< CAL_VERSION_SC_139">; 61 // Predicate that is set to true if 64bit Div/Mod is supported in the IL or not 62 def HasHW64DivMod : Predicate<"Subtarget.device()" 63 "->usesHardware(AMDGPUDeviceInfo::HW64BitDivMod)">; 64 def HasSW64DivMod : Predicate<"Subtarget.device()" 65 "->usesSoftware(AMDGPUDeviceInfo::HW64BitDivMod)">; 66 67 // Predicate that is set to true if 64bit pointer are used. 68 def Has64BitPtr : Predicate<"Subtarget.is64bit()">; 69 def Has32BitPtr : Predicate<"!Subtarget.is64bit()">; 70 //===--------------------------------------------------------------------===// 71 // Custom Operands 72 //===--------------------------------------------------------------------===// 73 def brtarget : Operand<OtherVT>; 74 75 //===--------------------------------------------------------------------===// 76 // Custom Selection DAG Type Profiles 77 //===--------------------------------------------------------------------===// 78 //===----------------------------------------------------------------------===// 79 // Generic Profile Types 80 //===----------------------------------------------------------------------===// 81 82 def SDTIL_GenBinaryOp : SDTypeProfile<1, 2, [ 83 SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2> 84 ]>; 85 def SDTIL_GenTernaryOp : SDTypeProfile<1, 3, [ 86 SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisSameAs<2, 3> 87 ]>; 88 def SDTIL_GenVecBuild : SDTypeProfile<1, 1, [ 89 SDTCisEltOfVec<1, 0> 90 ]>; 91 92 //===----------------------------------------------------------------------===// 93 // Flow Control Profile Types 94 //===----------------------------------------------------------------------===// 95 // Branch instruction where second and third are basic blocks 96 def SDTIL_BRCond : SDTypeProfile<0, 2, [ 97 SDTCisVT<0, OtherVT> 98 ]>; 99 100 //===--------------------------------------------------------------------===// 101 // Custom Selection DAG Nodes 102 //===--------------------------------------------------------------------===// 103 //===----------------------------------------------------------------------===// 104 // Flow Control DAG Nodes 105 //===----------------------------------------------------------------------===// 106 def IL_brcond : SDNode<"AMDGPUISD::BRANCH_COND", SDTIL_BRCond, [SDNPHasChain]>; 107 108 //===----------------------------------------------------------------------===// 109 // Call/Return DAG Nodes 110 //===----------------------------------------------------------------------===// 111 def IL_retflag : SDNode<"AMDGPUISD::RET_FLAG", SDTNone, 112 [SDNPHasChain, SDNPOptInGlue]>; 113 114 //===--------------------------------------------------------------------===// 115 // Instructions 116 //===--------------------------------------------------------------------===// 117 // Floating point math functions 118 def IL_div_inf : SDNode<"AMDGPUISD::DIV_INF", SDTIL_GenBinaryOp>; 119 def IL_mad : SDNode<"AMDGPUISD::MAD", SDTIL_GenTernaryOp>; 120 121 //===----------------------------------------------------------------------===// 122 // Integer functions 123 //===----------------------------------------------------------------------===// 124 def IL_umul : SDNode<"AMDGPUISD::UMUL" , SDTIntBinOp, 125 [SDNPCommutative, SDNPAssociative]>; 126 127 //===----------------------------------------------------------------------===// 128 // Vector functions 129 //===----------------------------------------------------------------------===// 130 def IL_vbuild : SDNode<"AMDGPUISD::VBUILD", SDTIL_GenVecBuild, 131 []>; 132 133 //===--------------------------------------------------------------------===// 134 // Custom Pattern DAG Nodes 135 //===--------------------------------------------------------------------===// 136 def global_store : PatFrag<(ops node:$val, node:$ptr), 137 (store node:$val, node:$ptr), [{ 138 return isGlobalStore(dyn_cast<StoreSDNode>(N)); 139 }]>; 140 141 //===----------------------------------------------------------------------===// 142 // Load pattern fragments 143 //===----------------------------------------------------------------------===// 144 // Global address space loads 145 def global_load : PatFrag<(ops node:$ptr), (load node:$ptr), [{ 146 return isGlobalLoad(dyn_cast<LoadSDNode>(N)); 147 }]>; 148 // Constant address space loads 149 def constant_load : PatFrag<(ops node:$ptr), (load node:$ptr), [{ 150 return isConstantLoad(dyn_cast<LoadSDNode>(N), -1); 151 }]>; 152 153 //===----------------------------------------------------------------------===// 154 // Complex addressing mode patterns 155 //===----------------------------------------------------------------------===// 156 def ADDR : ComplexPattern<i32, 2, "SelectADDR", [], []>; 157 def ADDRF : ComplexPattern<i32, 2, "SelectADDR", [frameindex], []>; 158 def ADDR64 : ComplexPattern<i64, 2, "SelectADDR64", [], []>; 159 def ADDR64F : ComplexPattern<i64, 2, "SelectADDR64", [frameindex], []>; 160 161 //===----------------------------------------------------------------------===// 162 // Instruction format classes 163 //===----------------------------------------------------------------------===// 164 class ILFormat<dag outs, dag ins, string asmstr, list<dag> pattern> 165 : Instruction { 166 167 let Namespace = "AMDGPU"; 168 dag OutOperandList = outs; 169 dag InOperandList = ins; 170 let Pattern = pattern; 171 let AsmString = !strconcat(asmstr, "\n"); 172 let isPseudo = 1; 173 let Itinerary = NullALU; 174 bit hasIEEEFlag = 0; 175 bit hasZeroOpFlag = 0; 176 } 177 178 //===--------------------------------------------------------------------===// 179 // Multiclass Instruction formats 180 //===--------------------------------------------------------------------===// 181 // Multiclass that handles branch instructions 182 multiclass BranchConditional<SDNode Op> { 183 def _i32 : ILFormat<(outs), 184 (ins brtarget:$target, GPRI32:$src0), 185 "; i32 Pseudo branch instruction", 186 [(Op bb:$target, GPRI32:$src0)]>; 187 def _f32 : ILFormat<(outs), 188 (ins brtarget:$target, GPRF32:$src0), 189 "; f32 Pseudo branch instruction", 190 [(Op bb:$target, GPRF32:$src0)]>; 191 } 192 193 // Only scalar types should generate flow control 194 multiclass BranchInstr<string name> { 195 def _i32 : ILFormat<(outs), (ins GPRI32:$src), 196 !strconcat(name, " $src"), []>; 197 def _f32 : ILFormat<(outs), (ins GPRF32:$src), 198 !strconcat(name, " $src"), []>; 199 } 200 // Only scalar types should generate flow control 201 multiclass BranchInstr2<string name> { 202 def _i32 : ILFormat<(outs), (ins GPRI32:$src0, GPRI32:$src1), 203 !strconcat(name, " $src0, $src1"), []>; 204 def _f32 : ILFormat<(outs), (ins GPRF32:$src0, GPRF32:$src1), 205 !strconcat(name, " $src0, $src1"), []>; 206 } 207 208 //===--------------------------------------------------------------------===// 209 // Intrinsics support 210 //===--------------------------------------------------------------------===// 211 include "AMDILIntrinsics.td" 212 213 //===--------------------------------------------------------------------===// 214 // Instructions support 215 //===--------------------------------------------------------------------===// 216 //===---------------------------------------------------------------------===// 217 // Custom Inserter for Branches and returns, this eventually will be a 218 // seperate pass 219 //===---------------------------------------------------------------------===// 220 let isTerminator = 1, usesCustomInserter = 1 in { 221 def BRANCH : ILFormat<(outs), (ins brtarget:$target), 222 "; Pseudo unconditional branch instruction", 223 [(br bb:$target)]>; 224 defm BRANCH_COND : BranchConditional<IL_brcond>; 225 } 226 227 //===---------------------------------------------------------------------===// 228 // Flow and Program control Instructions 229 //===---------------------------------------------------------------------===// 230 let isTerminator=1 in { 231 def SWITCH : ILFormat< (outs), (ins GPRI32:$src), 232 !strconcat("SWITCH", " $src"), []>; 233 def CASE : ILFormat< (outs), (ins GPRI32:$src), 234 !strconcat("CASE", " $src"), []>; 235 def BREAK : ILFormat< (outs), (ins), 236 "BREAK", []>; 237 def CONTINUE : ILFormat< (outs), (ins), 238 "CONTINUE", []>; 239 def DEFAULT : ILFormat< (outs), (ins), 240 "DEFAULT", []>; 241 def ELSE : ILFormat< (outs), (ins), 242 "ELSE", []>; 243 def ENDSWITCH : ILFormat< (outs), (ins), 244 "ENDSWITCH", []>; 245 def ENDMAIN : ILFormat< (outs), (ins), 246 "ENDMAIN", []>; 247 def END : ILFormat< (outs), (ins), 248 "END", []>; 249 def ENDFUNC : ILFormat< (outs), (ins), 250 "ENDFUNC", []>; 251 def ENDIF : ILFormat< (outs), (ins), 252 "ENDIF", []>; 253 def WHILELOOP : ILFormat< (outs), (ins), 254 "WHILE", []>; 255 def ENDLOOP : ILFormat< (outs), (ins), 256 "ENDLOOP", []>; 257 def FUNC : ILFormat< (outs), (ins), 258 "FUNC", []>; 259 def RETDYN : ILFormat< (outs), (ins), 260 "RET_DYN", []>; 261 // This opcode has custom swizzle pattern encoded in Swizzle Encoder 262 defm IF_LOGICALNZ : BranchInstr<"IF_LOGICALNZ">; 263 // This opcode has custom swizzle pattern encoded in Swizzle Encoder 264 defm IF_LOGICALZ : BranchInstr<"IF_LOGICALZ">; 265 // This opcode has custom swizzle pattern encoded in Swizzle Encoder 266 defm BREAK_LOGICALNZ : BranchInstr<"BREAK_LOGICALNZ">; 267 // This opcode has custom swizzle pattern encoded in Swizzle Encoder 268 defm BREAK_LOGICALZ : BranchInstr<"BREAK_LOGICALZ">; 269 // This opcode has custom swizzle pattern encoded in Swizzle Encoder 270 defm CONTINUE_LOGICALNZ : BranchInstr<"CONTINUE_LOGICALNZ">; 271 // This opcode has custom swizzle pattern encoded in Swizzle Encoder 272 defm CONTINUE_LOGICALZ : BranchInstr<"CONTINUE_LOGICALZ">; 273 defm IFC : BranchInstr2<"IFC">; 274 defm BREAKC : BranchInstr2<"BREAKC">; 275 defm CONTINUEC : BranchInstr2<"CONTINUEC">; 276 } 277