| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 1 | //===-- VOPInstructions.td - Vector Instruction Defintions ----------------===// |
| 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 | |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 10 | // dummies for outer let |
| 11 | class LetDummies { |
| 12 | bit isCommutable; |
| 13 | bit isConvertibleToThreeAddress; |
| 14 | bit isMoveImm; |
| 15 | bit isReMaterializable; |
| 16 | bit isAsCheapAsAMove; |
| 17 | bit VOPAsmPrefer32Bit; |
| 18 | Predicate SubtargetPredicate; |
| 19 | string Constraints; |
| 20 | string DisableEncoding; |
| 21 | list<SchedReadWrite> SchedRW; |
| 22 | list<Register> Uses; |
| 23 | list<Register> Defs; |
| 24 | } |
| 25 | |
| 26 | class VOP <string opName> { |
| 27 | string OpName = opName; |
| 28 | } |
| 29 | |
| 30 | class VOPAnyCommon <dag outs, dag ins, string asm, list<dag> pattern> : |
| 31 | InstSI <outs, ins, asm, pattern> { |
| 32 | |
| 33 | let mayLoad = 0; |
| 34 | let mayStore = 0; |
| 35 | let hasSideEffects = 0; |
| 36 | let UseNamedOperandTable = 1; |
| 37 | let VALU = 1; |
| Matt Arsenault | eff1ad8 | 2016-11-18 04:42:59 +0000 | [diff] [blame] | 38 | let Uses = [EXEC]; |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 39 | } |
| 40 | |
| Nicolai Haehnle | 4f850ea | 2018-03-26 13:56:53 +0000 | [diff] [blame] | 41 | class VOP_Pseudo <string opName, string suffix, VOPProfile P, dag outs, dag ins, |
| 42 | string asm, list<dag> pattern> : |
| 43 | InstSI <outs, ins, asm, pattern>, |
| 44 | VOP <opName>, |
| 45 | SIMCInstr <opName#suffix, SIEncodingFamily.NONE>, |
| 46 | MnemonicAlias<opName#suffix, opName> { |
| 47 | |
| 48 | let isPseudo = 1; |
| 49 | let isCodeGenOnly = 1; |
| 50 | let UseNamedOperandTable = 1; |
| 51 | |
| 52 | string Mnemonic = opName; |
| 53 | VOPProfile Pfl = P; |
| 54 | |
| 55 | string AsmOperands; |
| 56 | } |
| 57 | |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 58 | class VOP3Common <dag outs, dag ins, string asm = "", |
| 59 | list<dag> pattern = [], bit HasMods = 0, |
| 60 | bit VOP3Only = 0> : |
| 61 | VOPAnyCommon <outs, ins, asm, pattern> { |
| 62 | |
| 63 | // Using complex patterns gives VOP3 patterns a very high complexity rating, |
| Simon Pilgrim | e995a808 | 2016-11-18 11:04:02 +0000 | [diff] [blame] | 64 | // but standalone patterns are almost always preferred, so we need to adjust the |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 65 | // priority lower. The goal is to use a high number to reduce complexity to |
| 66 | // zero (or less than zero). |
| 67 | let AddedComplexity = -1000; |
| 68 | |
| 69 | let VOP3 = 1; |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 70 | |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 71 | let AsmVariantName = AMDGPUAsmVariants.VOP3; |
| Sam Kolton | 10ac2fd | 2017-07-07 15:21:52 +0000 | [diff] [blame] | 72 | let AsmMatchConverter = !if(!eq(HasMods,1), "cvtVOP3", ""); |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 73 | |
| 74 | let isCodeGenOnly = 0; |
| 75 | |
| 76 | int Size = 8; |
| 77 | |
| 78 | // Because SGPRs may be allowed if there are multiple operands, we |
| 79 | // need a post-isel hook to insert copies in order to avoid |
| 80 | // violating constant bus requirements. |
| 81 | let hasPostISelHook = 1; |
| 82 | } |
| 83 | |
| Matt Arsenault | 9be7b0d | 2017-02-27 18:49:11 +0000 | [diff] [blame] | 84 | class VOP3_Pseudo <string opName, VOPProfile P, list<dag> pattern = [], |
| Dmitry Preobrazhensky | abf2839 | 2017-07-21 13:54:11 +0000 | [diff] [blame] | 85 | bit VOP3Only = 0, bit isVOP3P = 0, bit isVop3OpSel = 0> : |
| Nicolai Haehnle | 4f850ea | 2018-03-26 13:56:53 +0000 | [diff] [blame] | 86 | VOP_Pseudo <opName, "_e64", P, P.Outs64, |
| 87 | !if(isVop3OpSel, |
| 88 | P.InsVOP3OpSel, |
| 89 | !if(!and(isVOP3P, P.IsPacked), P.InsVOP3P, P.Ins64)), |
| 90 | "", pattern> { |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 91 | |
| Dmitry Preobrazhensky | abf2839 | 2017-07-21 13:54:11 +0000 | [diff] [blame] | 92 | let VOP3_OPSEL = isVop3OpSel; |
| Dmitry Preobrazhensky | 682a654 | 2017-11-17 15:15:40 +0000 | [diff] [blame] | 93 | let IsPacked = P.IsPacked; |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 94 | |
| Nicolai Haehnle | 4f850ea | 2018-03-26 13:56:53 +0000 | [diff] [blame] | 95 | let AsmOperands = !if(isVop3OpSel, |
| 96 | P.AsmVOP3OpSel, |
| 97 | !if(!and(isVOP3P, P.IsPacked), P.AsmVOP3P, P.Asm64)); |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 98 | |
| 99 | let Size = 8; |
| 100 | let mayLoad = 0; |
| 101 | let mayStore = 0; |
| 102 | let hasSideEffects = 0; |
| 103 | let SubtargetPredicate = isGCN; |
| 104 | |
| 105 | // Because SGPRs may be allowed if there are multiple operands, we |
| 106 | // need a post-isel hook to insert copies in order to avoid |
| 107 | // violating constant bus requirements. |
| 108 | let hasPostISelHook = 1; |
| 109 | |
| 110 | // Using complex patterns gives VOP3 patterns a very high complexity rating, |
| Simon Pilgrim | e995a808 | 2016-11-18 11:04:02 +0000 | [diff] [blame] | 111 | // but standalone patterns are almost always preferred, so we need to adjust the |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 112 | // priority lower. The goal is to use a high number to reduce complexity to |
| 113 | // zero (or less than zero). |
| 114 | let AddedComplexity = -1000; |
| 115 | |
| 116 | let VOP3 = 1; |
| 117 | let VALU = 1; |
| Matt Arsenault | d5c6515 | 2017-02-22 23:27:53 +0000 | [diff] [blame] | 118 | let FPClamp = P.HasFPClamp; |
| Matt Arsenault | ab4a5cd | 2017-08-31 23:53:50 +0000 | [diff] [blame] | 119 | let IntClamp = P.HasIntClamp; |
| 120 | let ClampLo = P.HasClampLo; |
| 121 | let ClampHi = P.HasClampHi; |
| 122 | |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 123 | let Uses = [EXEC]; |
| 124 | |
| 125 | let AsmVariantName = AMDGPUAsmVariants.VOP3; |
| 126 | let AsmMatchConverter = |
| Dmitry Preobrazhensky | 682a654 | 2017-11-17 15:15:40 +0000 | [diff] [blame] | 127 | !if(isVOP3P, |
| Sam Kolton | 10ac2fd | 2017-07-07 15:21:52 +0000 | [diff] [blame] | 128 | "cvtVOP3P", |
| Dmitry Preobrazhensky | 682a654 | 2017-11-17 15:15:40 +0000 | [diff] [blame] | 129 | !if(!or(P.HasModifiers, !or(P.HasOMod, P.HasIntClamp)), |
| 130 | "cvtVOP3", |
| 131 | "")); |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 132 | } |
| 133 | |
| Matt Arsenault | 9be7b0d | 2017-02-27 18:49:11 +0000 | [diff] [blame] | 134 | class VOP3P_Pseudo <string opName, VOPProfile P, list<dag> pattern = []> : |
| 135 | VOP3_Pseudo<opName, P, pattern, 1, 1> { |
| 136 | let VOP3P = 1; |
| 137 | } |
| 138 | |
| Nicolai Haehnle | 4f850ea | 2018-03-26 13:56:53 +0000 | [diff] [blame] | 139 | class VOP3_Real <VOP_Pseudo ps, int EncodingFamily> : |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 140 | InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []>, |
| 141 | SIMCInstr <ps.PseudoInstr, EncodingFamily> { |
| 142 | |
| 143 | let isPseudo = 0; |
| 144 | let isCodeGenOnly = 0; |
| Matt Arsenault | 9be7b0d | 2017-02-27 18:49:11 +0000 | [diff] [blame] | 145 | let UseNamedOperandTable = 1; |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 146 | |
| Sam Kolton | a6792a3 | 2016-12-22 11:30:48 +0000 | [diff] [blame] | 147 | let Constraints = ps.Constraints; |
| 148 | let DisableEncoding = ps.DisableEncoding; |
| 149 | |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 150 | // copy relevant pseudo op flags |
| 151 | let SubtargetPredicate = ps.SubtargetPredicate; |
| 152 | let AsmMatchConverter = ps.AsmMatchConverter; |
| 153 | let AsmVariantName = ps.AsmVariantName; |
| 154 | let Constraints = ps.Constraints; |
| 155 | let DisableEncoding = ps.DisableEncoding; |
| 156 | let TSFlags = ps.TSFlags; |
| Dmitry Preobrazhensky | 03880f8 | 2017-03-03 14:31:06 +0000 | [diff] [blame] | 157 | let UseNamedOperandTable = ps.UseNamedOperandTable; |
| 158 | let Uses = ps.Uses; |
| Stanislav Mekhanoshin | f630047 | 2018-01-15 17:55:35 +0000 | [diff] [blame] | 159 | let Defs = ps.Defs; |
| Sam Kolton | 4685b70a | 2017-07-18 14:23:26 +0000 | [diff] [blame] | 160 | |
| 161 | VOPProfile Pfl = ps.Pfl; |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 162 | } |
| 163 | |
| Matt Arsenault | 9be7b0d | 2017-02-27 18:49:11 +0000 | [diff] [blame] | 164 | // XXX - Is there any reason to distingusih this from regular VOP3 |
| 165 | // here? |
| Nicolai Haehnle | 4f850ea | 2018-03-26 13:56:53 +0000 | [diff] [blame] | 166 | class VOP3P_Real<VOP_Pseudo ps, int EncodingFamily> : |
| Matt Arsenault | 9be7b0d | 2017-02-27 18:49:11 +0000 | [diff] [blame] | 167 | VOP3_Real<ps, EncodingFamily>; |
| 168 | |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 169 | class VOP3a<VOPProfile P> : Enc64 { |
| Dmitry Preobrazhensky | abf2839 | 2017-07-21 13:54:11 +0000 | [diff] [blame] | 170 | bits<4> src0_modifiers; |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 171 | bits<9> src0; |
| Dmitry Preobrazhensky | abf2839 | 2017-07-21 13:54:11 +0000 | [diff] [blame] | 172 | bits<3> src1_modifiers; |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 173 | bits<9> src1; |
| Dmitry Preobrazhensky | abf2839 | 2017-07-21 13:54:11 +0000 | [diff] [blame] | 174 | bits<3> src2_modifiers; |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 175 | bits<9> src2; |
| 176 | bits<1> clamp; |
| 177 | bits<2> omod; |
| 178 | |
| 179 | let Inst{8} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); |
| 180 | let Inst{9} = !if(P.HasSrc1Mods, src1_modifiers{1}, 0); |
| 181 | let Inst{10} = !if(P.HasSrc2Mods, src2_modifiers{1}, 0); |
| 182 | |
| 183 | let Inst{31-26} = 0x34; //encoding |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 184 | let Inst{40-32} = !if(P.HasSrc0, src0, 0); |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 185 | let Inst{49-41} = !if(P.HasSrc1, src1, 0); |
| 186 | let Inst{58-50} = !if(P.HasSrc2, src2, 0); |
| 187 | let Inst{60-59} = !if(P.HasOMod, omod, 0); |
| 188 | let Inst{61} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); |
| 189 | let Inst{62} = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); |
| 190 | let Inst{63} = !if(P.HasSrc2Mods, src2_modifiers{0}, 0); |
| 191 | } |
| 192 | |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 193 | class VOP3a_si <bits<9> op, VOPProfile P> : VOP3a<P> { |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 194 | let Inst{25-17} = op; |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 195 | let Inst{11} = !if(P.HasClamp, clamp{0}, 0); |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 196 | } |
| 197 | |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 198 | class VOP3a_vi <bits<10> op, VOPProfile P> : VOP3a<P> { |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 199 | let Inst{25-16} = op; |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 200 | let Inst{15} = !if(P.HasClamp, clamp{0}, 0); |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 201 | } |
| 202 | |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 203 | class VOP3e_si <bits<9> op, VOPProfile P> : VOP3a_si <op, P> { |
| Valery Pykhtin | e330cfa | 2016-09-20 10:41:16 +0000 | [diff] [blame] | 204 | bits<8> vdst; |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 205 | let Inst{7-0} = !if(P.EmitDst, vdst{7-0}, 0); |
| Valery Pykhtin | e330cfa | 2016-09-20 10:41:16 +0000 | [diff] [blame] | 206 | } |
| 207 | |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 208 | class VOP3e_vi <bits<10> op, VOPProfile P> : VOP3a_vi <op, P> { |
| Valery Pykhtin | e330cfa | 2016-09-20 10:41:16 +0000 | [diff] [blame] | 209 | bits<8> vdst; |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 210 | let Inst{7-0} = !if(P.EmitDst, vdst{7-0}, 0); |
| Valery Pykhtin | e330cfa | 2016-09-20 10:41:16 +0000 | [diff] [blame] | 211 | } |
| 212 | |
| Dmitry Preobrazhensky | abf2839 | 2017-07-21 13:54:11 +0000 | [diff] [blame] | 213 | class VOP3OpSel_gfx9 <bits<10> op, VOPProfile P> : VOP3e_vi <op, P> { |
| 214 | let Inst{11} = !if(P.HasSrc0, src0_modifiers{2}, 0); |
| 215 | let Inst{12} = !if(P.HasSrc1, src1_modifiers{2}, 0); |
| 216 | let Inst{13} = !if(P.HasSrc2, src2_modifiers{2}, 0); |
| 217 | let Inst{14} = !if(P.HasDst, src0_modifiers{3}, 0); |
| 218 | } |
| 219 | |
| Dmitry Preobrazhensky | 50805a0 | 2017-08-07 13:14:12 +0000 | [diff] [blame] | 220 | // NB: For V_INTERP* opcodes, src0 is encoded as src1 and vice versa |
| 221 | class VOP3Interp_vi <bits<10> op, VOPProfile P> : VOP3e_vi <op, P> { |
| 222 | bits<2> attrchan; |
| 223 | bits<6> attr; |
| 224 | bits<1> high; |
| 225 | |
| 226 | let Inst{8} = 0; // No modifiers for src0 |
| 227 | let Inst{61} = 0; |
| 228 | |
| 229 | let Inst{9} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); |
| 230 | let Inst{62} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); |
| 231 | |
| 232 | let Inst{37-32} = attr; |
| 233 | let Inst{39-38} = attrchan; |
| 234 | let Inst{40} = !if(P.HasHigh, high, 0); |
| 235 | |
| 236 | let Inst{49-41} = src0; |
| 237 | } |
| 238 | |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 239 | class VOP3be <VOPProfile P> : Enc64 { |
| Valery Pykhtin | e330cfa | 2016-09-20 10:41:16 +0000 | [diff] [blame] | 240 | bits<8> vdst; |
| 241 | bits<2> src0_modifiers; |
| 242 | bits<9> src0; |
| 243 | bits<2> src1_modifiers; |
| 244 | bits<9> src1; |
| 245 | bits<2> src2_modifiers; |
| 246 | bits<9> src2; |
| 247 | bits<7> sdst; |
| 248 | bits<2> omod; |
| 249 | |
| 250 | let Inst{7-0} = vdst; |
| 251 | let Inst{14-8} = sdst; |
| 252 | let Inst{31-26} = 0x34; //encoding |
| 253 | let Inst{40-32} = !if(P.HasSrc0, src0, 0); |
| 254 | let Inst{49-41} = !if(P.HasSrc1, src1, 0); |
| 255 | let Inst{58-50} = !if(P.HasSrc2, src2, 0); |
| 256 | let Inst{60-59} = !if(P.HasOMod, omod, 0); |
| 257 | let Inst{61} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); |
| 258 | let Inst{62} = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); |
| 259 | let Inst{63} = !if(P.HasSrc2Mods, src2_modifiers{0}, 0); |
| 260 | } |
| 261 | |
| Matt Arsenault | 9be7b0d | 2017-02-27 18:49:11 +0000 | [diff] [blame] | 262 | class VOP3Pe <bits<10> op, VOPProfile P> : Enc64 { |
| 263 | bits<8> vdst; |
| 264 | // neg, neg_hi, op_sel put in srcN_modifiers |
| 265 | bits<4> src0_modifiers; |
| 266 | bits<9> src0; |
| 267 | bits<4> src1_modifiers; |
| 268 | bits<9> src1; |
| 269 | bits<4> src2_modifiers; |
| 270 | bits<9> src2; |
| 271 | bits<1> clamp; |
| 272 | |
| 273 | let Inst{7-0} = vdst; |
| 274 | let Inst{8} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); // neg_hi src0 |
| 275 | let Inst{9} = !if(P.HasSrc1Mods, src1_modifiers{1}, 0); // neg_hi src1 |
| 276 | let Inst{10} = !if(P.HasSrc2Mods, src2_modifiers{1}, 0); // neg_hi src2 |
| 277 | |
| Dmitry Preobrazhensky | 851a3d9 | 2017-06-21 16:00:54 +0000 | [diff] [blame] | 278 | let Inst{11} = !if(!and(P.HasSrc0, P.HasOpSel), src0_modifiers{2}, 0); // op_sel(0) |
| 279 | let Inst{12} = !if(!and(P.HasSrc1, P.HasOpSel), src1_modifiers{2}, 0); // op_sel(1) |
| 280 | let Inst{13} = !if(!and(P.HasSrc2, P.HasOpSel), src2_modifiers{2}, 0); // op_sel(2) |
| Matt Arsenault | 9be7b0d | 2017-02-27 18:49:11 +0000 | [diff] [blame] | 281 | |
| Dmitry Preobrazhensky | 851a3d9 | 2017-06-21 16:00:54 +0000 | [diff] [blame] | 282 | let Inst{14} = !if(!and(P.HasSrc2, P.HasOpSel), src2_modifiers{3}, 0); // op_sel_hi(2) |
| Matt Arsenault | 9be7b0d | 2017-02-27 18:49:11 +0000 | [diff] [blame] | 283 | |
| 284 | let Inst{15} = !if(P.HasClamp, clamp{0}, 0); |
| 285 | |
| 286 | let Inst{25-16} = op; |
| 287 | let Inst{31-26} = 0x34; //encoding |
| 288 | let Inst{40-32} = !if(P.HasSrc0, src0, 0); |
| 289 | let Inst{49-41} = !if(P.HasSrc1, src1, 0); |
| 290 | let Inst{58-50} = !if(P.HasSrc2, src2, 0); |
| Dmitry Preobrazhensky | 851a3d9 | 2017-06-21 16:00:54 +0000 | [diff] [blame] | 291 | let Inst{59} = !if(!and(P.HasSrc0, P.HasOpSel), src0_modifiers{3}, 0); // op_sel_hi(0) |
| 292 | let Inst{60} = !if(!and(P.HasSrc1, P.HasOpSel), src1_modifiers{3}, 0); // op_sel_hi(1) |
| Matt Arsenault | 9be7b0d | 2017-02-27 18:49:11 +0000 | [diff] [blame] | 293 | let Inst{61} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); // neg (lo) |
| 294 | let Inst{62} = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); // neg (lo) |
| 295 | let Inst{63} = !if(P.HasSrc2Mods, src2_modifiers{0}, 0); // neg (lo) |
| 296 | } |
| 297 | |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 298 | class VOP3be_si <bits<9> op, VOPProfile P> : VOP3be<P> { |
| Valery Pykhtin | e330cfa | 2016-09-20 10:41:16 +0000 | [diff] [blame] | 299 | let Inst{25-17} = op; |
| 300 | } |
| 301 | |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 302 | class VOP3be_vi <bits<10> op, VOPProfile P> : VOP3be<P> { |
| Valery Pykhtin | e330cfa | 2016-09-20 10:41:16 +0000 | [diff] [blame] | 303 | bits<1> clamp; |
| 304 | let Inst{25-16} = op; |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 305 | let Inst{15} = !if(P.HasClamp, clamp{0}, 0); |
| Valery Pykhtin | e330cfa | 2016-09-20 10:41:16 +0000 | [diff] [blame] | 306 | } |
| 307 | |
| Sam Kolton | a568e3d | 2016-12-22 12:57:41 +0000 | [diff] [blame] | 308 | def SDWA { |
| 309 | // sdwa_sel |
| 310 | int BYTE_0 = 0; |
| 311 | int BYTE_1 = 1; |
| 312 | int BYTE_2 = 2; |
| 313 | int BYTE_3 = 3; |
| 314 | int WORD_0 = 4; |
| 315 | int WORD_1 = 5; |
| 316 | int DWORD = 6; |
| 317 | |
| 318 | // dst_unused |
| 319 | int UNUSED_PAD = 0; |
| 320 | int UNUSED_SEXT = 1; |
| 321 | int UNUSED_PRESERVE = 2; |
| 322 | } |
| 323 | |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 324 | class VOP_SDWAe<VOPProfile P> : Enc64 { |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 325 | bits<8> src0; |
| 326 | bits<3> src0_sel; |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 327 | bits<2> src0_modifiers; // float: {abs,neg}, int {sext} |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 328 | bits<3> src1_sel; |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 329 | bits<2> src1_modifiers; |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 330 | bits<3> dst_sel; |
| 331 | bits<2> dst_unused; |
| 332 | bits<1> clamp; |
| 333 | |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 334 | let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0); |
| Dmitry Preobrazhensky | 9c1a6e7 | 2018-03-16 15:40:27 +0000 | [diff] [blame] | 335 | let Inst{42-40} = !if(P.EmitDst, dst_sel{2-0}, 0); |
| 336 | let Inst{44-43} = !if(P.EmitDst, dst_unused{1-0}, 0); |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 337 | let Inst{45} = !if(P.HasSDWAClamp, clamp{0}, 0); |
| Dmitry Preobrazhensky | 9c1a6e7 | 2018-03-16 15:40:27 +0000 | [diff] [blame] | 338 | let Inst{50-48} = !if(P.HasSrc0, src0_sel{2-0}, 0); |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 339 | let Inst{51} = !if(P.HasSrc0IntMods, src0_modifiers{0}, 0); |
| Sam Kolton | f7659d71 | 2017-05-23 10:08:55 +0000 | [diff] [blame] | 340 | let Inst{53-52} = !if(P.HasSrc0FloatMods, src0_modifiers{1-0}, 0); |
| Dmitry Preobrazhensky | 9c1a6e7 | 2018-03-16 15:40:27 +0000 | [diff] [blame] | 341 | let Inst{58-56} = !if(P.HasSrc1, src1_sel{2-0}, 0); |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 342 | let Inst{59} = !if(P.HasSrc1IntMods, src1_modifiers{0}, 0); |
| Sam Kolton | f7659d71 | 2017-05-23 10:08:55 +0000 | [diff] [blame] | 343 | let Inst{61-60} = !if(P.HasSrc1FloatMods, src1_modifiers{1-0}, 0); |
| 344 | } |
| 345 | |
| Sam Kolton | 549c89d | 2017-06-21 08:53:38 +0000 | [diff] [blame] | 346 | // GFX9 adds two features to SDWA: |
| 347 | // 1. Add 3 fields to the SDWA microcode word: S0, S1 and OMOD. |
| 348 | // a. S0 and S1 indicate that source 0 and 1 respectively are SGPRs rather |
| 349 | // than VGPRs (at most 1 can be an SGPR); |
| 350 | // b. OMOD is the standard output modifier (result *2, *4, /2) |
| 351 | // 2. Add a new version of the SDWA microcode word for VOPC: SDWAB. This |
| 352 | // replaces OMOD and the dest fields with SD and SDST (SGPR destination) |
| 353 | // field. |
| 354 | // a. When SD=1, the SDST is used as the destination for the compare result; |
| 355 | // b. When SD=0, VCC is used. |
| 356 | // |
| 357 | // In GFX9, V_MAC_F16, V_MAC_F32 opcodes cannot be used with SDWA |
| 358 | |
| Sam Kolton | f7659d71 | 2017-05-23 10:08:55 +0000 | [diff] [blame] | 359 | // gfx9 SDWA basic encoding |
| 360 | class VOP_SDWA9e<VOPProfile P> : Enc64 { |
| 361 | bits<9> src0; // {src0_sgpr{0}, src0{7-0}} |
| 362 | bits<3> src0_sel; |
| 363 | bits<2> src0_modifiers; // float: {abs,neg}, int {sext} |
| 364 | bits<3> src1_sel; |
| 365 | bits<2> src1_modifiers; |
| 366 | bits<1> src1_sgpr; |
| 367 | |
| 368 | let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0); |
| Dmitry Preobrazhensky | 9c1a6e7 | 2018-03-16 15:40:27 +0000 | [diff] [blame] | 369 | let Inst{50-48} = !if(P.HasSrc0, src0_sel{2-0}, 0); |
| Sam Kolton | f7659d71 | 2017-05-23 10:08:55 +0000 | [diff] [blame] | 370 | let Inst{51} = !if(P.HasSrc0IntMods, src0_modifiers{0}, 0); |
| 371 | let Inst{53-52} = !if(P.HasSrc0FloatMods, src0_modifiers{1-0}, 0); |
| 372 | let Inst{55} = !if(P.HasSrc0, src0{8}, 0); |
| Dmitry Preobrazhensky | 9c1a6e7 | 2018-03-16 15:40:27 +0000 | [diff] [blame] | 373 | let Inst{58-56} = !if(P.HasSrc1, src1_sel{2-0}, 0); |
| Sam Kolton | f7659d71 | 2017-05-23 10:08:55 +0000 | [diff] [blame] | 374 | let Inst{59} = !if(P.HasSrc1IntMods, src1_modifiers{0}, 0); |
| 375 | let Inst{61-60} = !if(P.HasSrc1FloatMods, src1_modifiers{1-0}, 0); |
| 376 | let Inst{63} = 0; // src1_sgpr - should be specified in subclass |
| 377 | } |
| 378 | |
| 379 | // gfx9 SDWA-A |
| 380 | class VOP_SDWA9Ae<VOPProfile P> : VOP_SDWA9e<P> { |
| 381 | bits<3> dst_sel; |
| 382 | bits<2> dst_unused; |
| 383 | bits<1> clamp; |
| 384 | bits<2> omod; |
| 385 | |
| Dmitry Preobrazhensky | 9c1a6e7 | 2018-03-16 15:40:27 +0000 | [diff] [blame] | 386 | let Inst{42-40} = !if(P.EmitDst, dst_sel{2-0}, 0); |
| 387 | let Inst{44-43} = !if(P.EmitDst, dst_unused{1-0}, 0); |
| Sam Kolton | f7659d71 | 2017-05-23 10:08:55 +0000 | [diff] [blame] | 388 | let Inst{45} = !if(P.HasSDWAClamp, clamp{0}, 0); |
| 389 | let Inst{47-46} = !if(P.HasSDWAOMod, omod{1-0}, 0); |
| 390 | } |
| 391 | |
| 392 | // gfx9 SDWA-B |
| 393 | class VOP_SDWA9Be<VOPProfile P> : VOP_SDWA9e<P> { |
| 394 | bits<8> sdst; // {vcc_sdst{0}, sdst{6-0}} |
| 395 | |
| 396 | let Inst{46-40} = !if(P.EmitDst, sdst{6-0}, 0); |
| 397 | let Inst{47} = !if(P.EmitDst, sdst{7}, 0); |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 398 | } |
| 399 | |
| Sam Kolton | a568e3d | 2016-12-22 12:57:41 +0000 | [diff] [blame] | 400 | class VOP_SDWA_Pseudo <string opName, VOPProfile P, list<dag> pattern=[]> : |
| 401 | InstSI <P.OutsSDWA, P.InsSDWA, "", pattern>, |
| 402 | VOP <opName>, |
| 403 | SIMCInstr <opName#"_sdwa", SIEncodingFamily.NONE>, |
| 404 | MnemonicAlias <opName#"_sdwa", opName> { |
| Matt Arsenault | b4493e9 | 2017-02-10 02:42:31 +0000 | [diff] [blame] | 405 | |
| Sam Kolton | a568e3d | 2016-12-22 12:57:41 +0000 | [diff] [blame] | 406 | let isPseudo = 1; |
| 407 | let isCodeGenOnly = 1; |
| 408 | let UseNamedOperandTable = 1; |
| 409 | |
| 410 | string Mnemonic = opName; |
| 411 | string AsmOperands = P.AsmSDWA; |
| Sam Kolton | 549c89d | 2017-06-21 08:53:38 +0000 | [diff] [blame] | 412 | string AsmOperands9 = P.AsmSDWA9; |
| Sam Kolton | a568e3d | 2016-12-22 12:57:41 +0000 | [diff] [blame] | 413 | |
| 414 | let Size = 8; |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 415 | let mayLoad = 0; |
| 416 | let mayStore = 0; |
| Matt Arsenault | b4493e9 | 2017-02-10 02:42:31 +0000 | [diff] [blame] | 417 | let hasSideEffects = 0; |
| Sam Kolton | a568e3d | 2016-12-22 12:57:41 +0000 | [diff] [blame] | 418 | |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 419 | let VALU = 1; |
| 420 | let SDWA = 1; |
| Sam Kolton | a568e3d | 2016-12-22 12:57:41 +0000 | [diff] [blame] | 421 | let Uses = [EXEC]; |
| Matt Arsenault | b4493e9 | 2017-02-10 02:42:31 +0000 | [diff] [blame] | 422 | |
| Konstantin Zhuravlyov | 5f1b818 | 2018-09-27 20:49:00 +0000 | [diff] [blame^] | 423 | let SubtargetPredicate = !if(P.HasExtSDWA, HasSDWA, DisableInst); |
| 424 | let AssemblerPredicate = !if(P.HasExtSDWA, HasSDWA, DisableInst); |
| 425 | let AsmVariantName = !if(P.HasExtSDWA, AMDGPUAsmVariants.SDWA, |
| 426 | AMDGPUAsmVariants.Disable); |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 427 | let DecoderNamespace = "SDWA"; |
| Sam Kolton | a568e3d | 2016-12-22 12:57:41 +0000 | [diff] [blame] | 428 | |
| 429 | VOPProfile Pfl = P; |
| 430 | } |
| 431 | |
| 432 | class VOP_SDWA_Real <VOP_SDWA_Pseudo ps> : |
| 433 | InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands, []>, |
| Sam Kolton | 549c89d | 2017-06-21 08:53:38 +0000 | [diff] [blame] | 434 | SIMCInstr <ps.PseudoInstr, SIEncodingFamily.SDWA> { |
| Sam Kolton | a568e3d | 2016-12-22 12:57:41 +0000 | [diff] [blame] | 435 | |
| 436 | let isPseudo = 0; |
| 437 | let isCodeGenOnly = 0; |
| 438 | |
| 439 | let Defs = ps.Defs; |
| 440 | let Uses = ps.Uses; |
| 441 | let SchedRW = ps.SchedRW; |
| 442 | let hasSideEffects = ps.hasSideEffects; |
| 443 | |
| 444 | let Constraints = ps.Constraints; |
| 445 | let DisableEncoding = ps.DisableEncoding; |
| 446 | |
| 447 | // Copy relevant pseudo op flags |
| 448 | let SubtargetPredicate = ps.SubtargetPredicate; |
| 449 | let AssemblerPredicate = ps.AssemblerPredicate; |
| 450 | let AsmMatchConverter = ps.AsmMatchConverter; |
| 451 | let AsmVariantName = ps.AsmVariantName; |
| 452 | let UseNamedOperandTable = ps.UseNamedOperandTable; |
| 453 | let DecoderNamespace = ps.DecoderNamespace; |
| 454 | let Constraints = ps.Constraints; |
| 455 | let DisableEncoding = ps.DisableEncoding; |
| 456 | let TSFlags = ps.TSFlags; |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 457 | } |
| 458 | |
| Sam Kolton | 549c89d | 2017-06-21 08:53:38 +0000 | [diff] [blame] | 459 | class VOP_SDWA9_Real <VOP_SDWA_Pseudo ps> : |
| 460 | InstSI <ps.OutOperandList, ps.InOperandList, ps.Mnemonic # ps.AsmOperands9, []>, |
| 461 | SIMCInstr <ps.PseudoInstr, SIEncodingFamily.SDWA9> { |
| Sam Kolton | f7659d71 | 2017-05-23 10:08:55 +0000 | [diff] [blame] | 462 | |
| 463 | let isPseudo = 0; |
| 464 | let isCodeGenOnly = 0; |
| 465 | |
| 466 | let Defs = ps.Defs; |
| 467 | let Uses = ps.Uses; |
| 468 | let SchedRW = ps.SchedRW; |
| 469 | let hasSideEffects = ps.hasSideEffects; |
| 470 | |
| 471 | let Constraints = ps.Constraints; |
| 472 | let DisableEncoding = ps.DisableEncoding; |
| 473 | |
| Konstantin Zhuravlyov | 5f1b818 | 2018-09-27 20:49:00 +0000 | [diff] [blame^] | 474 | let SubtargetPredicate = !if(ps.Pfl.HasExtSDWA9, HasSDWA9, DisableInst); |
| 475 | let AssemblerPredicate = !if(ps.Pfl.HasExtSDWA9, HasSDWA9, DisableInst); |
| 476 | let AsmVariantName = !if(ps.Pfl.HasExtSDWA9, AMDGPUAsmVariants.SDWA9, |
| 477 | AMDGPUAsmVariants.Disable); |
| Sam Kolton | 549c89d | 2017-06-21 08:53:38 +0000 | [diff] [blame] | 478 | let DecoderNamespace = "SDWA9"; |
| 479 | |
| Sam Kolton | f7659d71 | 2017-05-23 10:08:55 +0000 | [diff] [blame] | 480 | // Copy relevant pseudo op flags |
| Sam Kolton | f7659d71 | 2017-05-23 10:08:55 +0000 | [diff] [blame] | 481 | let AsmMatchConverter = ps.AsmMatchConverter; |
| Sam Kolton | f7659d71 | 2017-05-23 10:08:55 +0000 | [diff] [blame] | 482 | let UseNamedOperandTable = ps.UseNamedOperandTable; |
| Sam Kolton | f7659d71 | 2017-05-23 10:08:55 +0000 | [diff] [blame] | 483 | let Constraints = ps.Constraints; |
| 484 | let DisableEncoding = ps.DisableEncoding; |
| 485 | let TSFlags = ps.TSFlags; |
| 486 | } |
| 487 | |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 488 | class VOP_DPPe<VOPProfile P> : Enc64 { |
| 489 | bits<2> src0_modifiers; |
| 490 | bits<8> src0; |
| 491 | bits<2> src1_modifiers; |
| 492 | bits<9> dpp_ctrl; |
| 493 | bits<1> bound_ctrl; |
| 494 | bits<4> bank_mask; |
| 495 | bits<4> row_mask; |
| 496 | |
| 497 | let Inst{39-32} = !if(P.HasSrc0, src0{7-0}, 0); |
| 498 | let Inst{48-40} = dpp_ctrl; |
| 499 | let Inst{51} = bound_ctrl; |
| 500 | let Inst{52} = !if(P.HasSrc0Mods, src0_modifiers{0}, 0); // src0_neg |
| 501 | let Inst{53} = !if(P.HasSrc0Mods, src0_modifiers{1}, 0); // src0_abs |
| 502 | let Inst{54} = !if(P.HasSrc1Mods, src1_modifiers{0}, 0); // src1_neg |
| 503 | let Inst{55} = !if(P.HasSrc1Mods, src1_modifiers{1}, 0); // src1_abs |
| 504 | let Inst{59-56} = bank_mask; |
| 505 | let Inst{63-60} = row_mask; |
| 506 | } |
| 507 | |
| 508 | class VOP_DPP <string OpName, VOPProfile P> : |
| 509 | InstSI <P.OutsDPP, P.InsDPP, OpName#P.AsmDPP, []>, |
| 510 | VOP_DPPe<P> { |
| 511 | |
| 512 | let mayLoad = 0; |
| 513 | let mayStore = 0; |
| 514 | let hasSideEffects = 0; |
| 515 | let UseNamedOperandTable = 1; |
| 516 | |
| 517 | let VALU = 1; |
| 518 | let DPP = 1; |
| 519 | let Size = 8; |
| 520 | |
| 521 | let AsmMatchConverter = !if(!eq(P.HasModifiers,1), "cvtDPP", ""); |
| Sam Kolton | 07dbde2 | 2017-01-20 10:01:25 +0000 | [diff] [blame] | 522 | let SubtargetPredicate = HasDPP; |
| Konstantin Zhuravlyov | 5f1b818 | 2018-09-27 20:49:00 +0000 | [diff] [blame^] | 523 | let AssemblerPredicate = !if(P.HasExtDPP, HasDPP, DisableInst); |
| 524 | let AsmVariantName = !if(P.HasExtDPP, AMDGPUAsmVariants.DPP, |
| 525 | AMDGPUAsmVariants.Disable); |
| Connor Abbott | 79f3ade | 2017-08-07 19:10:56 +0000 | [diff] [blame] | 526 | let Constraints = !if(P.NumSrcArgs, "$old = $vdst", ""); |
| 527 | let DisableEncoding = !if(P.NumSrcArgs, "$old", ""); |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 528 | let DecoderNamespace = "DPP"; |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 529 | } |
| 530 | |
| Alexander Timofeev | 36617f01 | 2018-09-21 10:31:22 +0000 | [diff] [blame] | 531 | class getNumNodeArgs<SDPatternOperator Op> { |
| 532 | SDNode N = !cast<SDNode>(Op); |
| 533 | SDTypeProfile TP = N.TypeProfile; |
| 534 | int ret = TP.NumOperands; |
| 535 | } |
| 536 | |
| 537 | |
| 538 | class getDivergentFrag<SDPatternOperator Op> { |
| 539 | |
| 540 | int NumSrcArgs = getNumNodeArgs<Op>.ret; |
| 541 | PatFrag ret = PatFrag < |
| 542 | !if(!eq(NumSrcArgs, 1), |
| 543 | (ops node:$src0), |
| 544 | !if(!eq(NumSrcArgs, 2), |
| 545 | (ops node:$src0, node:$src1), |
| 546 | (ops node:$src0, node:$src1, node:$src2))), |
| 547 | !if(!eq(NumSrcArgs, 1), |
| 548 | (Op $src0), |
| 549 | !if(!eq(NumSrcArgs, 2), |
| 550 | (Op $src0, $src1), |
| 551 | (Op $src0, $src1, $src2))), |
| 552 | [{ return N->isDivergent(); }] |
| 553 | >; |
| 554 | } |
| 555 | |
| 556 | class VOPPatGen<SDPatternOperator Op, VOPProfile P> { |
| 557 | |
| 558 | PatFrag Operator = getDivergentFrag < Op >.ret; |
| 559 | |
| 560 | dag Ins = !foreach(tmp, P.Ins32, !subst(ins, Operator, |
| 561 | !subst(P.Src0RC32, P.Src0VT, |
| 562 | !subst(P.Src1RC32, P.Src1VT, tmp)))); |
| 563 | |
| 564 | |
| 565 | dag Outs = !foreach(tmp, P.Outs32, !subst(outs, set, |
| 566 | !subst(P.DstRC, P.DstVT, tmp))); |
| 567 | |
| 568 | list<dag> ret = [!con(Outs, (set Ins))]; |
| 569 | } |
| 570 | |
| 571 | class VOPPatOrNull<SDPatternOperator Op, VOPProfile P> { |
| 572 | list<dag> ret = !if(!ne(P.NeedPatGen,PatGenMode.NoPattern), VOPPatGen<Op, P>.ret, []); |
| 573 | } |
| 574 | |
| Valery Pykhtin | 2828b9b | 2016-09-19 14:39:49 +0000 | [diff] [blame] | 575 | include "VOPCInstructions.td" |
| Valery Pykhtin | 355103f | 2016-09-23 09:08:07 +0000 | [diff] [blame] | 576 | include "VOP1Instructions.td" |
| 577 | include "VOP2Instructions.td" |
| Valery Pykhtin | e330cfa | 2016-09-20 10:41:16 +0000 | [diff] [blame] | 578 | include "VOP3Instructions.td" |
| Matt Arsenault | 9be7b0d | 2017-02-27 18:49:11 +0000 | [diff] [blame] | 579 | include "VOP3PInstructions.td" |