Home | History | Annotate | Download | only in radeon
      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