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 16def 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 22def 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. 28def HasHWSign24Bit : Predicate<"Subtarget.device()" 29 "->getGeneration() > AMDGPUDeviceInfo::HD5XXX">; 30 31// Predicate that is set to true if 64bit operations are supported or not 32def HasHW64Bit : Predicate<"Subtarget.device()" 33 "->usesHardware(AMDGPUDeviceInfo::LongOps)">; 34def HasSW64Bit : Predicate<"Subtarget.device()" 35 "->usesSoftware(AMDGPUDeviceInfo::LongOps)">; 36 37// Predicate that is set to true if the timer register is supported 38def HasTmrRegister : Predicate<"Subtarget.device()" 39 "->isSupported(AMDGPUDeviceInfo::TmrReg)">; 40// Predicate that is true if we are at least evergreen series 41def HasDeviceIDInst : Predicate<"Subtarget.device()" 42 "->getGeneration() >= AMDGPUDeviceInfo::HD5XXX">; 43 44// Predicate that is true if we have region address space. 45def hasRegionAS : Predicate<"Subtarget.device()" 46 "->usesHardware(AMDGPUDeviceInfo::RegionMem)">; 47 48// Predicate that is false if we don't have region address space. 49def 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 54def HasHW64Mul : Predicate<"Subtarget.calVersion()" 55 ">= CAL_VERSION_SC_139" 56 "&& Subtarget.device()" 57 "->getGeneration() >=" 58 "AMDGPUDeviceInfo::HD5XXX">; 59def 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 62def HasHW64DivMod : Predicate<"Subtarget.device()" 63 "->usesHardware(AMDGPUDeviceInfo::HW64BitDivMod)">; 64def HasSW64DivMod : Predicate<"Subtarget.device()" 65 "->usesSoftware(AMDGPUDeviceInfo::HW64BitDivMod)">; 66 67// Predicate that is set to true if 64bit pointer are used. 68def Has64BitPtr : Predicate<"Subtarget.is64bit()">; 69def Has32BitPtr : Predicate<"!Subtarget.is64bit()">; 70//===--------------------------------------------------------------------===// 71// Custom Operands 72//===--------------------------------------------------------------------===// 73def brtarget : Operand<OtherVT>; 74 75//===--------------------------------------------------------------------===// 76// Custom Selection DAG Type Profiles 77//===--------------------------------------------------------------------===// 78//===----------------------------------------------------------------------===// 79// Generic Profile Types 80//===----------------------------------------------------------------------===// 81 82def SDTIL_GenBinaryOp : SDTypeProfile<1, 2, [ 83 SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2> 84 ]>; 85def SDTIL_GenTernaryOp : SDTypeProfile<1, 3, [ 86 SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisSameAs<2, 3> 87 ]>; 88def 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 96def 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//===----------------------------------------------------------------------===// 106def IL_brcond : SDNode<"AMDGPUISD::BRANCH_COND", SDTIL_BRCond, [SDNPHasChain]>; 107 108//===----------------------------------------------------------------------===// 109// Call/Return DAG Nodes 110//===----------------------------------------------------------------------===// 111def IL_retflag : SDNode<"AMDGPUISD::RET_FLAG", SDTNone, 112 [SDNPHasChain, SDNPOptInGlue]>; 113 114//===--------------------------------------------------------------------===// 115// Instructions 116//===--------------------------------------------------------------------===// 117// Floating point math functions 118def IL_div_inf : SDNode<"AMDGPUISD::DIV_INF", SDTIL_GenBinaryOp>; 119def IL_mad : SDNode<"AMDGPUISD::MAD", SDTIL_GenTernaryOp>; 120 121//===----------------------------------------------------------------------===// 122// Integer functions 123//===----------------------------------------------------------------------===// 124def IL_umul : SDNode<"AMDGPUISD::UMUL" , SDTIntBinOp, 125 [SDNPCommutative, SDNPAssociative]>; 126 127//===----------------------------------------------------------------------===// 128// Vector functions 129//===----------------------------------------------------------------------===// 130def IL_vbuild : SDNode<"AMDGPUISD::VBUILD", SDTIL_GenVecBuild, 131 []>; 132 133//===--------------------------------------------------------------------===// 134// Custom Pattern DAG Nodes 135//===--------------------------------------------------------------------===// 136def 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 145def global_load : PatFrag<(ops node:$ptr), (load node:$ptr), [{ 146 return isGlobalLoad(dyn_cast<LoadSDNode>(N)); 147}]>; 148// Constant address space loads 149def 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//===----------------------------------------------------------------------===// 156def ADDR : ComplexPattern<i32, 2, "SelectADDR", [], []>; 157def ADDRF : ComplexPattern<i32, 2, "SelectADDR", [frameindex], []>; 158def ADDR64 : ComplexPattern<i64, 2, "SelectADDR64", [], []>; 159def ADDR64F : ComplexPattern<i64, 2, "SelectADDR64", [frameindex], []>; 160 161//===----------------------------------------------------------------------===// 162// Instruction format classes 163//===----------------------------------------------------------------------===// 164class 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 182multiclass 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 194multiclass 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 201multiclass 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//===--------------------------------------------------------------------===// 211include "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//===---------------------------------------------------------------------===// 220let 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//===---------------------------------------------------------------------===// 230let 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