1 //===-- SIInstrInfo.td - SI Instruction Infos -------------*- tablegen -*--===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
9 def isCI : Predicate<"Subtarget->getGeneration() "
10 ">= SISubtarget::SEA_ISLANDS">;
11 def isCIOnly : Predicate<"Subtarget->getGeneration() =="
12 "SISubtarget::SEA_ISLANDS">,
13 AssemblerPredicate <"FeatureSeaIslands">;
15 def DisableInst : Predicate <"false">, AssemblerPredicate<"FeatureDisable">;
17 // Execpt for the NONE field, this must be kept in sync with the
18 // SIEncodingFamily enum in AMDGPUInstrInfo.cpp
19 def SIEncodingFamily {
25 //===----------------------------------------------------------------------===//
27 //===----------------------------------------------------------------------===//
29 def SIload_constant : SDNode<"AMDGPUISD::LOAD_CONSTANT",
30 SDTypeProfile<1, 2, [SDTCisVT<0, f32>, SDTCisVT<1, v4i32>, SDTCisVT<2, i32>]>,
31 [SDNPMayLoad, SDNPMemOperand]
34 def SIatomic_inc : SDNode<"AMDGPUISD::ATOMIC_INC", SDTAtomic2,
35 [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain]
38 def SIatomic_dec : SDNode<"AMDGPUISD::ATOMIC_DEC", SDTAtomic2,
39 [SDNPMayLoad, SDNPMayStore, SDNPMemOperand, SDNPHasChain]
42 def SItbuffer_store : SDNode<"AMDGPUISD::TBUFFER_STORE_FORMAT",
44 [SDTCisVT<0, v4i32>, // rsrc(SGPR)
45 SDTCisVT<1, iAny>, // vdata(VGPR)
46 SDTCisVT<2, i32>, // num_channels(imm)
47 SDTCisVT<3, i32>, // vaddr(VGPR)
48 SDTCisVT<4, i32>, // soffset(SGPR)
49 SDTCisVT<5, i32>, // inst_offset(imm)
50 SDTCisVT<6, i32>, // dfmt(imm)
51 SDTCisVT<7, i32>, // nfmt(imm)
52 SDTCisVT<8, i32>, // offen(imm)
53 SDTCisVT<9, i32>, // idxen(imm)
54 SDTCisVT<10, i32>, // glc(imm)
55 SDTCisVT<11, i32>, // slc(imm)
56 SDTCisVT<12, i32> // tfe(imm)
58 [SDNPMayStore, SDNPMemOperand, SDNPHasChain]
61 def SDTBufferLoad : SDTypeProfile<1, 5,
63 SDTCisVT<1, v4i32>, // rsrc
64 SDTCisVT<2, i32>, // vindex
65 SDTCisVT<3, i32>, // offset
66 SDTCisVT<4, i1>, // glc
67 SDTCisVT<5, i1>]>; // slc
69 def SIbuffer_load : SDNode <"AMDGPUISD::BUFFER_LOAD", SDTBufferLoad,
70 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>;
71 def SIbuffer_load_format : SDNode <"AMDGPUISD::BUFFER_LOAD_FORMAT", SDTBufferLoad,
72 [SDNPMemOperand, SDNPHasChain, SDNPMayLoad]>;
74 class SDSample<string opcode> : SDNode <opcode,
75 SDTypeProfile<1, 4, [SDTCisVT<0, v4f32>, SDTCisVT<2, v8i32>,
76 SDTCisVT<3, v4i32>, SDTCisVT<4, i32>]>
79 def SIsample : SDSample<"AMDGPUISD::SAMPLE">;
80 def SIsampleb : SDSample<"AMDGPUISD::SAMPLEB">;
81 def SIsampled : SDSample<"AMDGPUISD::SAMPLED">;
82 def SIsamplel : SDSample<"AMDGPUISD::SAMPLEL">;
84 def SIpc_add_rel_offset : SDNode<"AMDGPUISD::PC_ADD_REL_OFFSET",
85 SDTypeProfile<1, 2, [SDTCisVT<0, iPTR>, SDTCisSameAs<0,1>, SDTCisSameAs<0,2>]>
88 //===----------------------------------------------------------------------===//
89 // PatFrags for global memory operations
90 //===----------------------------------------------------------------------===//
92 defm atomic_inc_global : global_binary_atomic_op<SIatomic_inc>;
93 defm atomic_dec_global : global_binary_atomic_op<SIatomic_dec>;
95 //===----------------------------------------------------------------------===//
96 // SDNodes and PatFrag for local loads and stores to enable s_mov_b32 m0, -1
97 // to be glued to the memory instructions.
98 //===----------------------------------------------------------------------===//
100 def SIld_local : SDNode <"ISD::LOAD", SDTLoad,
101 [SDNPHasChain, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
104 def si_ld_local : PatFrag <(ops node:$ptr), (SIld_local node:$ptr), [{
105 return cast<LoadSDNode>(N)->getAddressSpace() == AMDGPUASI.LOCAL_ADDRESS;
108 def si_load_local : PatFrag <(ops node:$ptr), (si_ld_local node:$ptr), [{
109 return cast<LoadSDNode>(N)->getAddressingMode() == ISD::UNINDEXED &&
110 cast<LoadSDNode>(N)->getExtensionType() == ISD::NON_EXTLOAD;
113 def si_load_local_align8 : Aligned8Bytes <
114 (ops node:$ptr), (si_load_local node:$ptr)
117 def si_sextload_local : PatFrag <(ops node:$ptr), (si_ld_local node:$ptr), [{
118 return cast<LoadSDNode>(N)->getExtensionType() == ISD::SEXTLOAD;
120 def si_az_extload_local : AZExtLoadBase <si_ld_local>;
122 multiclass SIExtLoadLocal <PatFrag ld_node> {
124 def _i8 : PatFrag <(ops node:$ptr), (ld_node node:$ptr),
125 [{return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8;}]
128 def _i16 : PatFrag <(ops node:$ptr), (ld_node node:$ptr),
129 [{return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16;}]
133 defm si_sextload_local : SIExtLoadLocal <si_sextload_local>;
134 defm si_az_extload_local : SIExtLoadLocal <si_az_extload_local>;
136 def SIst_local : SDNode <"ISD::STORE", SDTStore,
137 [SDNPHasChain, SDNPMayStore, SDNPMemOperand, SDNPInGlue]
140 def si_st_local : PatFrag <
141 (ops node:$val, node:$ptr), (SIst_local node:$val, node:$ptr), [{
142 return cast<StoreSDNode>(N)->getAddressSpace() == AMDGPUASI.LOCAL_ADDRESS;
145 def si_store_local : PatFrag <
146 (ops node:$val, node:$ptr), (si_st_local node:$val, node:$ptr), [{
147 return cast<StoreSDNode>(N)->getAddressingMode() == ISD::UNINDEXED &&
148 !cast<StoreSDNode>(N)->isTruncatingStore();
151 def si_store_local_align8 : Aligned8Bytes <
152 (ops node:$val, node:$ptr), (si_store_local node:$val, node:$ptr)
155 def si_truncstore_local : PatFrag <
156 (ops node:$val, node:$ptr), (si_st_local node:$val, node:$ptr), [{
157 return cast<StoreSDNode>(N)->isTruncatingStore();
160 def si_truncstore_local_i8 : PatFrag <
161 (ops node:$val, node:$ptr), (si_truncstore_local node:$val, node:$ptr), [{
162 return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i8;
165 def si_truncstore_local_i16 : PatFrag <
166 (ops node:$val, node:$ptr), (si_truncstore_local node:$val, node:$ptr), [{
167 return cast<StoreSDNode>(N)->getMemoryVT() == MVT::i16;
170 def si_setcc_uniform : PatFrag <
171 (ops node:$lhs, node:$rhs, node:$cond),
172 (setcc node:$lhs, node:$rhs, node:$cond), [{
173 for (SDNode *Use : N->uses()) {
174 if (Use->isMachineOpcode() || Use->getOpcode() != ISD::CopyToReg)
177 unsigned Reg = cast<RegisterSDNode>(Use->getOperand(1))->getReg();
178 if (Reg != AMDGPU::SCC)
184 def si_uniform_br : PatFrag <
185 (ops node:$cond, node:$bb), (brcond node:$cond, node:$bb), [{
186 return isUniformBr(N);
189 def si_uniform_br_scc : PatFrag <
190 (ops node:$cond, node:$bb), (si_uniform_br node:$cond, node:$bb), [{
191 return isCBranchSCC(N);
194 def lshr_rev : PatFrag <
195 (ops node:$src1, node:$src0),
199 def ashr_rev : PatFrag <
200 (ops node:$src1, node:$src0),
204 def lshl_rev : PatFrag <
205 (ops node:$src1, node:$src0),
209 multiclass SIAtomicM0Glue2 <string op_name, bit is_amdgpu = 0> {
212 !if(is_amdgpu, "AMDGPUISD", "ISD")#"::ATOMIC_"#op_name, SDTAtomic2,
213 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
216 def _local : local_binary_atomic_op <!cast<SDNode>(NAME#"_glue")>;
219 defm si_atomic_load_add : SIAtomicM0Glue2 <"LOAD_ADD">;
220 defm si_atomic_load_sub : SIAtomicM0Glue2 <"LOAD_SUB">;
221 defm si_atomic_inc : SIAtomicM0Glue2 <"INC", 1>;
222 defm si_atomic_dec : SIAtomicM0Glue2 <"DEC", 1>;
223 defm si_atomic_load_and : SIAtomicM0Glue2 <"LOAD_AND">;
224 defm si_atomic_load_min : SIAtomicM0Glue2 <"LOAD_MIN">;
225 defm si_atomic_load_max : SIAtomicM0Glue2 <"LOAD_MAX">;
226 defm si_atomic_load_or : SIAtomicM0Glue2 <"LOAD_OR">;
227 defm si_atomic_load_xor : SIAtomicM0Glue2 <"LOAD_XOR">;
228 defm si_atomic_load_umin : SIAtomicM0Glue2 <"LOAD_UMIN">;
229 defm si_atomic_load_umax : SIAtomicM0Glue2 <"LOAD_UMAX">;
230 defm si_atomic_swap : SIAtomicM0Glue2 <"SWAP">;
232 def si_atomic_cmp_swap_glue : SDNode <"ISD::ATOMIC_CMP_SWAP", SDTAtomic3,
233 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand, SDNPInGlue]
236 defm si_atomic_cmp_swap : AtomicCmpSwapLocal <si_atomic_cmp_swap_glue>;
238 def as_i1imm : SDNodeXForm<imm, [{
239 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i1);
242 def as_i8imm : SDNodeXForm<imm, [{
243 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i8);
246 def as_i16imm : SDNodeXForm<imm, [{
247 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i16);
250 def as_i32imm: SDNodeXForm<imm, [{
251 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i32);
254 def as_i64imm: SDNodeXForm<imm, [{
255 return CurDAG->getTargetConstant(N->getSExtValue(), SDLoc(N), MVT::i64);
258 // Copied from the AArch64 backend:
259 def bitcast_fpimm_to_i32 : SDNodeXForm<fpimm, [{
260 return CurDAG->getTargetConstant(
261 N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i32);
264 def frameindex_to_targetframeindex : SDNodeXForm<frameindex, [{
265 auto FI = cast<FrameIndexSDNode>(N);
266 return CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32);
269 // Copied from the AArch64 backend:
270 def bitcast_fpimm_to_i64 : SDNodeXForm<fpimm, [{
271 return CurDAG->getTargetConstant(
272 N->getValueAPF().bitcastToAPInt().getZExtValue(), SDLoc(N), MVT::i64);
275 def SIMM16bit : PatLeaf <(imm),
276 [{return isInt<16>(N->getSExtValue());}]
279 class InlineImm <ValueType vt> : PatLeaf <(vt imm), [{
280 return isInlineImmediate(N);
283 class InlineFPImm <ValueType vt> : PatLeaf <(vt fpimm), [{
284 return isInlineImmediate(N);
287 class VGPRImm <dag frag> : PatLeaf<frag, [{
288 if (Subtarget->getGeneration() < SISubtarget::SOUTHERN_ISLANDS) {
291 const SIRegisterInfo *SIRI =
292 static_cast<const SIRegisterInfo *>(Subtarget->getRegisterInfo());
294 for (SDNode::use_iterator U = N->use_begin(), E = SDNode::use_end();
295 Limit < 10 && U != E; ++U, ++Limit) {
296 const TargetRegisterClass *RC = getOperandRegClass(*U, U.getOperandNo());
298 // If the register class is unknown, it could be an unknown
299 // register class that needs to be an SGPR, e.g. an inline asm
301 if (!RC || SIRI->isSGPRClass(RC))
308 def NegateImm : SDNodeXForm<imm, [{
309 return CurDAG->getConstant(-N->getSExtValue(), SDLoc(N), MVT::i32);
312 // TODO: When FP inline imm values work?
313 def NegSubInlineConst32 : ImmLeaf<i32, [{
314 return Imm < -16 && Imm >= -64;
317 def NegSubInlineConst16 : ImmLeaf<i16, [{
318 return Imm < -16 && Imm >= -64;
321 //===----------------------------------------------------------------------===//
323 //===----------------------------------------------------------------------===//
325 def SoppBrTarget : AsmOperandClass {
326 let Name = "SoppBrTarget";
327 let ParserMethod = "parseSOppBrTarget";
330 def sopp_brtarget : Operand<OtherVT> {
331 let EncoderMethod = "getSOPPBrEncoding";
332 let DecoderMethod = "decodeSoppBrTarget";
333 let OperandType = "OPERAND_PCREL";
334 let ParserMatchClass = SoppBrTarget;
337 def si_ga : Operand<iPTR>;
339 def InterpSlotMatchClass : AsmOperandClass {
340 let Name = "InterpSlot";
341 let PredicateMethod = "isInterpSlot";
342 let ParserMethod = "parseInterpSlot";
343 let RenderMethod = "addImmOperands";
346 def InterpSlot : Operand<i32> {
347 let PrintMethod = "printInterpSlot";
348 let ParserMatchClass = InterpSlotMatchClass;
349 let OperandType = "OPERAND_IMMEDIATE";
352 def AttrMatchClass : AsmOperandClass {
354 let PredicateMethod = "isInterpAttr";
355 let ParserMethod = "parseInterpAttr";
356 let RenderMethod = "addImmOperands";
359 // It appears to be necessary to create a separate operand for this to
360 // be able to parse attr<num> with no space.
361 def Attr : Operand<i32> {
362 let PrintMethod = "printInterpAttr";
363 let ParserMatchClass = AttrMatchClass;
364 let OperandType = "OPERAND_IMMEDIATE";
367 def AttrChanMatchClass : AsmOperandClass {
368 let Name = "AttrChan";
369 let PredicateMethod = "isAttrChan";
370 let RenderMethod = "addImmOperands";
373 def AttrChan : Operand<i32> {
374 let PrintMethod = "printInterpAttrChan";
375 let ParserMatchClass = AttrChanMatchClass;
376 let OperandType = "OPERAND_IMMEDIATE";
379 def SendMsgMatchClass : AsmOperandClass {
380 let Name = "SendMsg";
381 let PredicateMethod = "isSendMsg";
382 let ParserMethod = "parseSendMsgOp";
383 let RenderMethod = "addImmOperands";
386 def ExpTgtMatchClass : AsmOperandClass {
388 let PredicateMethod = "isExpTgt";
389 let ParserMethod = "parseExpTgt";
390 let RenderMethod = "printExpTgt";
393 def SendMsgImm : Operand<i32> {
394 let PrintMethod = "printSendMsg";
395 let ParserMatchClass = SendMsgMatchClass;
398 def SWaitMatchClass : AsmOperandClass {
399 let Name = "SWaitCnt";
400 let RenderMethod = "addImmOperands";
401 let ParserMethod = "parseSWaitCntOps";
404 def VReg32OrOffClass : AsmOperandClass {
405 let Name = "VReg32OrOff";
406 let ParserMethod = "parseVReg32OrOff";
409 def WAIT_FLAG : Operand <i32> {
410 let ParserMatchClass = SWaitMatchClass;
411 let PrintMethod = "printWaitFlag";
414 include "SIInstrFormats.td"
415 include "VIInstrFormats.td"
417 // ===----------------------------------------------------------------------===//
418 // ExpSrc* Special cases for exp src operands which are printed as
419 // "off" depending on en operand.
420 // ===----------------------------------------------------------------------===//
422 def ExpSrc0 : RegisterOperand<VGPR_32> {
423 let PrintMethod = "printExpSrc0";
424 let ParserMatchClass = VReg32OrOffClass;
427 def ExpSrc1 : RegisterOperand<VGPR_32> {
428 let PrintMethod = "printExpSrc1";
429 let ParserMatchClass = VReg32OrOffClass;
432 def ExpSrc2 : RegisterOperand<VGPR_32> {
433 let PrintMethod = "printExpSrc2";
434 let ParserMatchClass = VReg32OrOffClass;
437 def ExpSrc3 : RegisterOperand<VGPR_32> {
438 let PrintMethod = "printExpSrc3";
439 let ParserMatchClass = VReg32OrOffClass;
442 class SDWA9Src : RegisterOperand<VS_32> {
443 let OperandNamespace = "AMDGPU";
444 let OperandType = "OPERAND_SDWA9_SRC";
445 let EncoderMethod = "getSDWA9SrcEncoding";
448 def SDWA9Src32 : SDWA9Src {
449 let DecoderMethod = "decodeSDWA9Src32";
452 def SDWA9Src16 : SDWA9Src {
453 let DecoderMethod = "decodeSDWA9Src16";
456 def SDWA9VopcDst : VOPDstOperand<SReg_64> {
457 let OperandNamespace = "AMDGPU";
458 let OperandType = "OPERAND_SDWA9_VOPC_DST";
459 let EncoderMethod = "getSDWA9VopcDstEncoding";
460 let DecoderMethod = "decodeSDWA9VopcDst";
463 class NamedMatchClass<string CName, bit Optional = 1> : AsmOperandClass {
464 let Name = "Imm"#CName;
465 let PredicateMethod = "is"#CName;
466 let ParserMethod = !if(Optional, "parseOptionalOperand", "parse"#CName);
467 let RenderMethod = "addImmOperands";
468 let IsOptional = Optional;
469 let DefaultMethod = !if(Optional, "default"#CName, ?);
472 class NamedOperandBit<string Name, AsmOperandClass MatchClass> : Operand<i1> {
473 let PrintMethod = "print"#Name;
474 let ParserMatchClass = MatchClass;
477 class NamedOperandU8<string Name, AsmOperandClass MatchClass> : Operand<i8> {
478 let PrintMethod = "print"#Name;
479 let ParserMatchClass = MatchClass;
482 class NamedOperandU16<string Name, AsmOperandClass MatchClass> : Operand<i16> {
483 let PrintMethod = "print"#Name;
484 let ParserMatchClass = MatchClass;
487 class NamedOperandU32<string Name, AsmOperandClass MatchClass> : Operand<i32> {
488 let PrintMethod = "print"#Name;
489 let ParserMatchClass = MatchClass;
492 class NamedOperandU32Default0<string Name, AsmOperandClass MatchClass> :
493 OperandWithDefaultOps<i32, (ops (i32 0))> {
494 let PrintMethod = "print"#Name;
495 let ParserMatchClass = MatchClass;
498 let OperandType = "OPERAND_IMMEDIATE" in {
500 def offen : NamedOperandBit<"Offen", NamedMatchClass<"Offen">>;
501 def idxen : NamedOperandBit<"Idxen", NamedMatchClass<"Idxen">>;
502 def addr64 : NamedOperandBit<"Addr64", NamedMatchClass<"Addr64">>;
504 def offset : NamedOperandU16<"Offset", NamedMatchClass<"Offset">>;
505 def offset0 : NamedOperandU8<"Offset0", NamedMatchClass<"Offset0">>;
506 def offset1 : NamedOperandU8<"Offset1", NamedMatchClass<"Offset1">>;
508 def gds : NamedOperandBit<"GDS", NamedMatchClass<"GDS">>;
510 def omod : NamedOperandU32<"OModSI", NamedMatchClass<"OModSI">>;
511 def clampmod : NamedOperandBit<"ClampSI", NamedMatchClass<"ClampSI">>;
513 def GLC : NamedOperandBit<"GLC", NamedMatchClass<"GLC">>;
514 def slc : NamedOperandBit<"SLC", NamedMatchClass<"SLC">>;
515 def tfe : NamedOperandBit<"TFE", NamedMatchClass<"TFE">>;
516 def unorm : NamedOperandBit<"UNorm", NamedMatchClass<"UNorm">>;
517 def da : NamedOperandBit<"DA", NamedMatchClass<"DA">>;
518 def r128 : NamedOperandBit<"R128", NamedMatchClass<"R128">>;
519 def lwe : NamedOperandBit<"LWE", NamedMatchClass<"LWE">>;
520 def exp_compr : NamedOperandBit<"ExpCompr", NamedMatchClass<"ExpCompr">>;
521 def exp_vm : NamedOperandBit<"ExpVM", NamedMatchClass<"ExpVM">>;
523 def dmask : NamedOperandU16<"DMask", NamedMatchClass<"DMask">>;
525 def dpp_ctrl : NamedOperandU32<"DPPCtrl", NamedMatchClass<"DPPCtrl", 0>>;
526 def row_mask : NamedOperandU32<"RowMask", NamedMatchClass<"RowMask">>;
527 def bank_mask : NamedOperandU32<"BankMask", NamedMatchClass<"BankMask">>;
528 def bound_ctrl : NamedOperandBit<"BoundCtrl", NamedMatchClass<"BoundCtrl">>;
530 def dst_sel : NamedOperandU32<"SDWADstSel", NamedMatchClass<"SDWADstSel">>;
531 def src0_sel : NamedOperandU32<"SDWASrc0Sel", NamedMatchClass<"SDWASrc0Sel">>;
532 def src1_sel : NamedOperandU32<"SDWASrc1Sel", NamedMatchClass<"SDWASrc1Sel">>;
533 def dst_unused : NamedOperandU32<"SDWADstUnused", NamedMatchClass<"SDWADstUnused">>;
535 def op_sel : NamedOperandU32Default0<"OpSel", NamedMatchClass<"OpSel">>;
536 def op_sel_hi : NamedOperandU32Default0<"OpSelHi", NamedMatchClass<"OpSelHi">>;
537 def neg_lo : NamedOperandU32Default0<"NegLo", NamedMatchClass<"NegLo">>;
538 def neg_hi : NamedOperandU32Default0<"NegHi", NamedMatchClass<"NegHi">>;
540 def hwreg : NamedOperandU16<"Hwreg", NamedMatchClass<"Hwreg", 0>>;
542 def exp_tgt : NamedOperandU8<"ExpTgt", NamedMatchClass<"ExpTgt", 0>> {
546 } // End OperandType = "OPERAND_IMMEDIATE"
548 class KImmMatchClass<int size> : AsmOperandClass {
549 let Name = "KImmFP"#size;
550 let PredicateMethod = "isKImmFP"#size;
551 let ParserMethod = "parseImm";
552 let RenderMethod = "addKImmFP"#size#"Operands";
555 class kimmOperand<ValueType vt> : Operand<vt> {
556 let OperandNamespace = "AMDGPU";
557 let OperandType = "OPERAND_KIMM"#vt.Size;
558 let PrintMethod = "printU"#vt.Size#"ImmOperand";
559 let ParserMatchClass = !cast<AsmOperandClass>("KImmFP"#vt.Size#"MatchClass");
562 // 32-bit VALU immediate operand that uses the constant bus.
563 def KImmFP32MatchClass : KImmMatchClass<32>;
564 def f32kimm : kimmOperand<i32>;
566 // 32-bit VALU immediate operand with a 16-bit value that uses the
568 def KImmFP16MatchClass : KImmMatchClass<16>;
569 def f16kimm : kimmOperand<i16>;
572 def VOPDstS64 : VOPDstOperand <SReg_64>;
574 class FPInputModsMatchClass <int opSize> : AsmOperandClass {
575 let Name = "RegOrImmWithFP"#opSize#"InputMods";
576 let ParserMethod = "parseRegOrImmWithFPInputMods";
577 let PredicateMethod = "isRegOrImmWithFP"#opSize#"InputMods";
580 def FP16InputModsMatchClass : FPInputModsMatchClass<16>;
581 def FP32InputModsMatchClass : FPInputModsMatchClass<32>;
582 def FP64InputModsMatchClass : FPInputModsMatchClass<64>;
584 class InputMods <AsmOperandClass matchClass> : Operand <i32> {
585 let OperandNamespace = "AMDGPU";
586 let OperandType = "OPERAND_INPUT_MODS";
587 let ParserMatchClass = matchClass;
590 class FPInputMods <FPInputModsMatchClass matchClass> : InputMods <matchClass> {
591 let PrintMethod = "printOperandAndFPInputMods";
594 def FP16InputMods : FPInputMods<FP16InputModsMatchClass>;
595 def FP32InputMods : FPInputMods<FP32InputModsMatchClass>;
596 def FP64InputMods : FPInputMods<FP64InputModsMatchClass>;
598 class IntInputModsMatchClass <int opSize> : AsmOperandClass {
599 let Name = "RegOrImmWithInt"#opSize#"InputMods";
600 let ParserMethod = "parseRegOrImmWithIntInputMods";
601 let PredicateMethod = "isRegOrImmWithInt"#opSize#"InputMods";
603 def Int32InputModsMatchClass : IntInputModsMatchClass<32>;
604 def Int64InputModsMatchClass : IntInputModsMatchClass<64>;
606 class IntInputMods <IntInputModsMatchClass matchClass> : InputMods <matchClass> {
607 let PrintMethod = "printOperandAndIntInputMods";
609 def Int32InputMods : IntInputMods<Int32InputModsMatchClass>;
610 def Int64InputMods : IntInputMods<Int64InputModsMatchClass>;
612 def FPRegInputModsMatchClass : AsmOperandClass {
613 let Name = "RegWithFPInputMods";
614 let ParserMethod = "parseRegWithFPInputMods";
615 let PredicateMethod = "isRegKind";
618 def FPRegInputMods : InputMods <FPRegInputModsMatchClass> {
619 let PrintMethod = "printOperandAndFPInputMods";
622 def FPVRegInputModsMatchClass : AsmOperandClass {
623 let Name = "VRegWithFPInputMods";
624 let ParserMethod = "parseRegWithFPInputMods";
625 let PredicateMethod = "isVReg";
628 def FPVRegInputMods : InputMods <FPVRegInputModsMatchClass> {
629 let PrintMethod = "printOperandAndFPInputMods";
633 def IntRegInputModsMatchClass : AsmOperandClass {
634 let Name = "RegWithIntInputMods";
635 let ParserMethod = "parseRegWithIntInputMods";
636 let PredicateMethod = "isRegKind";
639 def IntRegInputMods : InputMods <IntRegInputModsMatchClass> {
640 let PrintMethod = "printOperandAndIntInputMods";
643 def IntVRegInputModsMatchClass : AsmOperandClass {
644 let Name = "VRegWithIntInputMods";
645 let ParserMethod = "parseRegWithIntInputMods";
646 let PredicateMethod = "isVReg";
649 def IntVRegInputMods : InputMods <IntVRegInputModsMatchClass> {
650 let PrintMethod = "printOperandAndIntInputMods";
653 class PackedFPInputModsMatchClass <int opSize> : AsmOperandClass {
654 let Name = "PackedFP"#opSize#"InputMods";
655 let ParserMethod = "parseRegOrImm";
656 let PredicateMethod = "isRegOrImm";
657 // let PredicateMethod = "isPackedFP"#opSize#"InputMods";
660 class PackedIntInputModsMatchClass <int opSize> : AsmOperandClass {
661 let Name = "PackedInt"#opSize#"InputMods";
662 let ParserMethod = "parseRegOrImm";
663 let PredicateMethod = "isRegOrImm";
664 // let PredicateMethod = "isPackedInt"#opSize#"InputMods";
667 def PackedF16InputModsMatchClass : PackedFPInputModsMatchClass<16>;
668 def PackedI16InputModsMatchClass : PackedIntInputModsMatchClass<16>;
670 class PackedFPInputMods <PackedFPInputModsMatchClass matchClass> : InputMods <matchClass> {
671 // let PrintMethod = "printPackedFPInputMods";
674 class PackedIntInputMods <PackedIntInputModsMatchClass matchClass> : InputMods <matchClass> {
675 //let PrintMethod = "printPackedIntInputMods";
678 def PackedF16InputMods : PackedFPInputMods<PackedF16InputModsMatchClass>;
679 def PackedI16InputMods : PackedIntInputMods<PackedI16InputModsMatchClass>;
681 //===----------------------------------------------------------------------===//
683 //===----------------------------------------------------------------------===//
685 def DS1Addr1Offset : ComplexPattern<i32, 2, "SelectDS1Addr1Offset">;
686 def DS64Bit4ByteAligned : ComplexPattern<i32, 3, "SelectDS64Bit4ByteAligned">;
688 def MOVRELOffset : ComplexPattern<i32, 2, "SelectMOVRELOffset">;
690 def VOP3Mods0 : ComplexPattern<untyped, 4, "SelectVOP3Mods0">;
691 def VOP3Mods0Clamp : ComplexPattern<untyped, 3, "SelectVOP3Mods0Clamp">;
692 def VOP3Mods0Clamp0OMod : ComplexPattern<untyped, 4, "SelectVOP3Mods0Clamp0OMod">;
693 def VOP3Mods : ComplexPattern<untyped, 2, "SelectVOP3Mods">;
694 def VOP3NoMods : ComplexPattern<untyped, 1, "SelectVOP3NoMods">;
695 // VOP3Mods, but the input source is known to never be NaN.
696 def VOP3Mods_nnan : ComplexPattern<fAny, 2, "SelectVOP3Mods_NNaN">;
698 def VOP3OMods : ComplexPattern<untyped, 3, "SelectVOP3OMods">;
700 def VOP3PMods : ComplexPattern<untyped, 2, "SelectVOP3PMods">;
701 def VOP3PMods0 : ComplexPattern<untyped, 3, "SelectVOP3PMods0">;
704 //===----------------------------------------------------------------------===//
705 // SI assembler operands
706 //===----------------------------------------------------------------------===//
714 // This should be kept in sync with SISrcMods enum
737 int LLVM_DEBUG_TRAP = 3;
740 //===----------------------------------------------------------------------===//
742 // SI Instruction multiclass helpers.
744 // Instructions with _32 take 32-bit operands.
745 // Instructions with _64 take 64-bit operands.
747 // VOP_* instructions can use either a 32-bit or 64-bit encoding. The 32-bit
748 // encoding is the standard encoding, but instruction that make use of
749 // any of the instruction modifiers must use the 64-bit encoding.
751 // Instructions with _e32 use the 32-bit encoding.
752 // Instructions with _e64 use the 64-bit encoding.
754 //===----------------------------------------------------------------------===//
756 class SIMCInstr <string pseudo, int subtarget> {
757 string PseudoInstr = pseudo;
758 int Subtarget = subtarget;
761 //===----------------------------------------------------------------------===//
763 //===----------------------------------------------------------------------===//
765 class EXP_Helper<bit done, SDPatternOperator node = null_frag> : EXPCommon<
768 ExpSrc0:$src0, ExpSrc1:$src1, ExpSrc2:$src2, ExpSrc3:$src3,
769 exp_vm:$vm, exp_compr:$compr, i8imm:$en),
770 "exp$tgt $src0, $src1, $src2, $src3"#!if(done, " done", "")#"$compr$vm",
771 [(node (i8 timm:$tgt), (i8 timm:$en),
772 f32:$src0, f32:$src1, f32:$src2, f32:$src3,
773 (i1 timm:$compr), (i1 timm:$vm))]> {
774 let AsmMatchConverter = "cvtExp";
777 // Split EXP instruction into EXP and EXP_DONE so we can set
778 // mayLoad for done=1.
779 multiclass EXP_m<bit done, SDPatternOperator node> {
780 let mayLoad = done in {
781 let isPseudo = 1, isCodeGenOnly = 1 in {
782 def "" : EXP_Helper<done, node>,
783 SIMCInstr <"exp"#!if(done, "_done", ""), SIEncodingFamily.NONE>;
787 def _si : EXP_Helper<done>,
788 SIMCInstr <"exp"#!if(done, "_done", ""), SIEncodingFamily.SI>,
790 let AssemblerPredicates = [isSICI];
791 let DecoderNamespace = "SICI";
792 let DisableDecoder = DisableSIDecoder;
795 def _vi : EXP_Helper<done>,
796 SIMCInstr <"exp"#!if(done, "_done", ""), SIEncodingFamily.VI>,
798 let AssemblerPredicates = [isVI];
799 let DecoderNamespace = "VI";
800 let DisableDecoder = DisableVIDecoder;
806 //===----------------------------------------------------------------------===//
807 // Vector ALU classes
808 //===----------------------------------------------------------------------===//
810 class getNumSrcArgs<ValueType Src0, ValueType Src1, ValueType Src2> {
812 !if (!eq(Src0.Value, untyped.Value), 0,
813 !if (!eq(Src1.Value, untyped.Value), 1, // VOP1
814 !if (!eq(Src2.Value, untyped.Value), 2, // VOP2
818 // Returns the register class to use for the destination of VOP[123C]
819 // instructions for the given VT.
820 class getVALUDstForVT<ValueType VT> {
821 RegisterOperand ret = !if(!eq(VT.Size, 32), VOPDstOperand<VGPR_32>,
822 !if(!eq(VT.Size, 128), VOPDstOperand<VReg_128>,
823 !if(!eq(VT.Size, 64), VOPDstOperand<VReg_64>,
824 !if(!eq(VT.Size, 16), VOPDstOperand<VGPR_32>,
825 VOPDstOperand<SReg_64>)))); // else VT == i1
828 // Returns the register class to use for the destination of VOP[12C]
829 // instructions with GFX9 SDWA extension
830 class getSDWA9DstForVT<ValueType VT> {
831 RegisterOperand ret = !if(!eq(VT.Size, 1),
832 SDWA9VopcDst, // VOPC
833 VOPDstOperand<VGPR_32>); // VOP1/2 32-bit dst
836 // Returns the register class to use for source 0 of VOP[12C]
837 // instructions for the given VT.
838 class getVOPSrc0ForVT<ValueType VT> {
839 bit isFP = !if(!eq(VT.Value, f16.Value), 1,
840 !if(!eq(VT.Value, v2f16.Value), 1,
841 !if(!eq(VT.Value, f32.Value), 1,
842 !if(!eq(VT.Value, f64.Value), 1,
845 RegisterOperand ret =
847 !if(!eq(VT.Size, 64),
849 !if(!eq(VT.Value, f16.Value),
851 !if(!eq(VT.Value, v2f16.Value),
857 !if(!eq(VT.Size, 64),
859 !if(!eq(VT.Value, i16.Value),
861 !if(!eq(VT.Value, v2i16.Value),
870 // Returns the vreg register class to use for source operand given VT
871 class getVregSrcForVT<ValueType VT> {
872 RegisterClass ret = !if(!eq(VT.Size, 128), VReg_128,
873 !if(!eq(VT.Size, 64), VReg_64, VGPR_32));
876 class getSDWA9SrcForVT <ValueType VT> {
877 RegisterOperand ret = !if(!eq(VT.Size, 16), SDWA9Src16, SDWA9Src32);
880 // Returns the register class to use for sources of VOP3 instructions for the
882 class getVOP3SrcForVT<ValueType VT> {
883 bit isFP = !if(!eq(VT.Value, f16.Value), 1,
884 !if(!eq(VT.Value, v2f16.Value), 1,
885 !if(!eq(VT.Value, f32.Value), 1,
886 !if(!eq(VT.Value, f64.Value), 1,
888 RegisterOperand ret =
889 !if(!eq(VT.Size, 128),
891 !if(!eq(VT.Size, 64),
895 !if(!eq(VT.Value, i1.Value),
898 !if(!eq(VT.Value, f16.Value),
900 !if(!eq(VT.Value, v2f16.Value),
905 !if(!eq(VT.Value, i16.Value),
907 !if(!eq(VT.Value, v2i16.Value),
918 // Returns 1 if the source arguments have modifiers, 0 if they do not.
919 // XXX - do f16 instructions?
920 class isFloatType<ValueType SrcVT> {
922 !if(!eq(SrcVT.Value, f16.Value), 1,
923 !if(!eq(SrcVT.Value, f32.Value), 1,
924 !if(!eq(SrcVT.Value, f64.Value), 1,
925 !if(!eq(SrcVT.Value, v2f16.Value), 1,
929 class isIntType<ValueType SrcVT> {
931 !if(!eq(SrcVT.Value, i16.Value), 1,
932 !if(!eq(SrcVT.Value, i32.Value), 1,
933 !if(!eq(SrcVT.Value, i64.Value), 1,
937 class isPackedType<ValueType SrcVT> {
939 !if(!eq(SrcVT.Value, v2i16.Value), 1,
940 !if(!eq(SrcVT.Value, v2f16.Value), 1, 0)
944 // Float or packed int
945 class isModifierType<ValueType SrcVT> {
947 !if(!eq(SrcVT.Value, f16.Value), 1,
948 !if(!eq(SrcVT.Value, f32.Value), 1,
949 !if(!eq(SrcVT.Value, f64.Value), 1,
950 !if(!eq(SrcVT.Value, v2f16.Value), 1,
951 !if(!eq(SrcVT.Value, v2i16.Value), 1,
955 // Return type of input modifiers operand for specified input operand
956 class getSrcMod <ValueType VT> {
957 bit isFP = !if(!eq(VT.Value, f16.Value), 1,
958 !if(!eq(VT.Value, f32.Value), 1,
959 !if(!eq(VT.Value, f64.Value), 1,
961 bit isPacked = isPackedType<VT>.ret;
962 Operand ret = !if(!eq(VT.Size, 64),
963 !if(isFP, FP64InputMods, Int64InputMods),
965 !if(!eq(VT.Value, f16.Value),
973 // Return type of input modifiers operand specified input operand for SDWA/DPP
974 class getSrcModExt <ValueType VT> {
975 bit isFP = !if(!eq(VT.Value, f16.Value), 1,
976 !if(!eq(VT.Value, f32.Value), 1,
977 !if(!eq(VT.Value, f64.Value), 1,
979 Operand ret = !if(isFP, FPVRegInputMods, IntVRegInputMods);
982 // Return type of input modifiers operand specified input operand for SDWA 9
983 class getSrcModSDWA9 <ValueType VT> {
984 bit isFP = !if(!eq(VT.Value, f16.Value), 1,
985 !if(!eq(VT.Value, f32.Value), 1,
986 !if(!eq(VT.Value, f64.Value), 1,
988 Operand ret = !if(isFP, FPRegInputMods, IntRegInputMods);
991 // Returns the input arguments for VOP[12C] instructions for the given SrcVT.
992 class getIns32 <RegisterOperand Src0RC, RegisterClass Src1RC, int NumSrcArgs> {
993 dag ret = !if(!eq(NumSrcArgs, 1), (ins Src0RC:$src0), // VOP1
994 !if(!eq(NumSrcArgs, 2), (ins Src0RC:$src0, Src1RC:$src1), // VOP2
998 // Returns the input arguments for VOP3 instructions for the given SrcVT.
999 class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC,
1000 RegisterOperand Src2RC, int NumSrcArgs,
1001 bit HasModifiers, bit HasOMod,
1002 Operand Src0Mod, Operand Src1Mod, Operand Src2Mod> {
1005 !if (!eq(NumSrcArgs, 0),
1006 // VOP1 without input operands (V_NOP, V_CLREXCP)
1009 !if (!eq(NumSrcArgs, 1),
1010 !if (!eq(HasModifiers, 1),
1011 // VOP1 with modifiers
1012 (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1013 clampmod:$clamp, omod:$omod)
1015 // VOP1 without modifiers
1018 !if (!eq(NumSrcArgs, 2),
1019 !if (!eq(HasModifiers, 1),
1020 // VOP 2 with modifiers
1021 !if( !eq(HasOMod, 1),
1022 (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1023 Src1Mod:$src1_modifiers, Src1RC:$src1,
1024 clampmod:$clamp, omod:$omod),
1025 (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1026 Src1Mod:$src1_modifiers, Src1RC:$src1,
1029 // VOP2 without modifiers
1030 (ins Src0RC:$src0, Src1RC:$src1)
1032 /* NumSrcArgs == 3 */,
1033 !if (!eq(HasModifiers, 1),
1034 // VOP3 with modifiers
1035 !if (!eq(HasOMod, 1),
1036 (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1037 Src1Mod:$src1_modifiers, Src1RC:$src1,
1038 Src2Mod:$src2_modifiers, Src2RC:$src2,
1039 clampmod:$clamp, omod:$omod),
1040 (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1041 Src1Mod:$src1_modifiers, Src1RC:$src1,
1042 Src2Mod:$src2_modifiers, Src2RC:$src2,
1045 // VOP3 without modifiers
1046 (ins Src0RC:$src0, Src1RC:$src1, Src2RC:$src2)
1050 /// XXX - src1 may only allow VGPRs?
1052 // The modifiers (except clamp) are dummy operands for the benefit of
1053 // printing and parsing. They defer their values to looking at the
1054 // srcN_modifiers for what to print.
1055 class getInsVOP3P <RegisterOperand Src0RC, RegisterOperand Src1RC,
1056 RegisterOperand Src2RC, int NumSrcArgs,
1058 Operand Src0Mod, Operand Src1Mod, Operand Src2Mod> {
1059 dag ret = !if (!eq(NumSrcArgs, 2),
1061 (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1062 Src1Mod:$src1_modifiers, Src1RC:$src1,
1064 op_sel:$op_sel, op_sel_hi:$op_sel_hi,
1065 neg_lo:$neg_lo, neg_hi:$neg_hi),
1066 (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1067 Src1Mod:$src1_modifiers, Src1RC:$src1,
1068 op_sel:$op_sel, op_sel_hi:$op_sel_hi,
1069 neg_lo:$neg_lo, neg_hi:$neg_hi)),
1070 // else NumSrcArgs == 3
1072 (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1073 Src1Mod:$src1_modifiers, Src1RC:$src1,
1074 Src2Mod:$src2_modifiers, Src2RC:$src2,
1076 op_sel:$op_sel, op_sel_hi:$op_sel_hi,
1077 neg_lo:$neg_lo, neg_hi:$neg_hi),
1078 (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1079 Src1Mod:$src1_modifiers, Src1RC:$src1,
1080 Src2Mod:$src2_modifiers, Src2RC:$src2,
1081 op_sel:$op_sel, op_sel_hi:$op_sel_hi,
1082 neg_lo:$neg_lo, neg_hi:$neg_hi))
1086 class getInsDPP <RegisterClass Src0RC, RegisterClass Src1RC, int NumSrcArgs,
1087 bit HasModifiers, Operand Src0Mod, Operand Src1Mod> {
1089 dag ret = !if (!eq(NumSrcArgs, 0),
1090 // VOP1 without input operands (V_NOP)
1091 (ins dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
1092 bank_mask:$bank_mask, bound_ctrl:$bound_ctrl),
1093 !if (!eq(NumSrcArgs, 1),
1094 !if (!eq(HasModifiers, 1),
1095 // VOP1_DPP with modifiers
1096 (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1097 dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
1098 bank_mask:$bank_mask, bound_ctrl:$bound_ctrl)
1100 // VOP1_DPP without modifiers
1101 (ins Src0RC:$src0, dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
1102 bank_mask:$bank_mask, bound_ctrl:$bound_ctrl)
1104 /* NumSrcArgs == 2 */,
1105 !if (!eq(HasModifiers, 1),
1106 // VOP2_DPP with modifiers
1107 (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1108 Src1Mod:$src1_modifiers, Src1RC:$src1,
1109 dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
1110 bank_mask:$bank_mask, bound_ctrl:$bound_ctrl)
1112 // VOP2_DPP without modifiers
1113 (ins Src0RC:$src0, Src1RC:$src1, dpp_ctrl:$dpp_ctrl,
1114 row_mask:$row_mask, bank_mask:$bank_mask,
1115 bound_ctrl:$bound_ctrl)
1119 class getInsSDWA <RegisterClass Src0RC, RegisterClass Src1RC, int NumSrcArgs,
1120 bit HasFloatModifiers, Operand Src0Mod, Operand Src1Mod,
1123 dag ret = !if(!eq(NumSrcArgs, 0),
1124 // VOP1 without input operands (V_NOP)
1126 !if(!eq(NumSrcArgs, 1),
1128 (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1129 clampmod:$clamp, dst_sel:$dst_sel, dst_unused:$dst_unused,
1130 src0_sel:$src0_sel),
1131 !if(!eq(NumSrcArgs, 2),
1132 !if(!eq(DstVT.Size, 1),
1133 // VOPC_SDWA with modifiers
1134 (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1135 Src1Mod:$src1_modifiers, Src1RC:$src1,
1136 clampmod:$clamp, src0_sel:$src0_sel, src1_sel:$src1_sel),
1137 // VOP2_SDWA with modifiers
1138 (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1139 Src1Mod:$src1_modifiers, Src1RC:$src1,
1140 clampmod:$clamp, dst_sel:$dst_sel, dst_unused:$dst_unused,
1141 src0_sel:$src0_sel, src1_sel:$src1_sel)),
1142 (ins)/* endif */)));
1145 // Ins for GFX9 SDWA
1146 class getInsSDWA9 <RegisterOperand Src0RC, RegisterOperand Src1RC, int NumSrcArgs,
1147 bit HasSDWAOMod, Operand Src0Mod, Operand Src1Mod,
1150 dag ret = !if(!eq(NumSrcArgs, 0),
1151 // VOP1 without input operands (V_NOP)
1153 !if(!eq(NumSrcArgs, 1),
1155 !if(!eq(HasSDWAOMod, 0),
1156 // VOP1_SDWA9 without omod
1157 (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1159 dst_sel:$dst_sel, dst_unused:$dst_unused,
1160 src0_sel:$src0_sel),
1161 // VOP1_SDWA9 with omod
1162 (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1163 clampmod:$clamp, omod:$omod,
1164 dst_sel:$dst_sel, dst_unused:$dst_unused,
1165 src0_sel:$src0_sel)),
1166 !if(!eq(NumSrcArgs, 2),
1167 !if(!eq(DstVT.Size, 1),
1169 (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1170 Src1Mod:$src1_modifiers, Src1RC:$src1,
1171 src0_sel:$src0_sel, src1_sel:$src1_sel),
1173 !if(!eq(HasSDWAOMod, 0),
1174 // VOP2_SDWA9 without omod
1175 (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1176 Src1Mod:$src1_modifiers, Src1RC:$src1,
1178 dst_sel:$dst_sel, dst_unused:$dst_unused,
1179 src0_sel:$src0_sel, src1_sel:$src1_sel),
1180 // VOP1_SDWA9 with omod
1181 (ins Src0Mod:$src0_modifiers, Src0RC:$src0,
1182 Src1Mod:$src1_modifiers, Src1RC:$src1,
1183 clampmod:$clamp, omod:$omod,
1184 dst_sel:$dst_sel, dst_unused:$dst_unused,
1185 src0_sel:$src0_sel, src1_sel:$src1_sel))),
1186 (ins)/* endif */)));
1189 // Outs for DPP and SDWA
1190 class getOutsExt <bit HasDst, ValueType DstVT, RegisterOperand DstRCExt> {
1191 dag ret = !if(HasDst,
1192 !if(!eq(DstVT.Size, 1),
1193 (outs), // no dst for VOPC, we use "vcc"-token as dst in SDWA VOPC instructions
1194 (outs DstRCExt:$vdst)),
1198 // Outs for GFX9 SDWA
1199 class getOutsSDWA9 <bit HasDst, ValueType DstVT, RegisterOperand DstRCSDWA9> {
1200 dag ret = !if(HasDst,
1201 !if(!eq(DstVT.Size, 1),
1202 (outs DstRCSDWA9:$sdst),
1203 (outs DstRCSDWA9:$vdst)),
1207 // Returns the assembly string for the inputs and outputs of a VOP[12C]
1208 // instruction. This does not add the _e32 suffix, so it can be reused
1210 class getAsm32 <bit HasDst, int NumSrcArgs, ValueType DstVT = i32> {
1211 string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC
1212 string src0 = ", $src0";
1213 string src1 = ", $src1";
1214 string src2 = ", $src2";
1215 string ret = !if(HasDst, dst, "") #
1216 !if(!eq(NumSrcArgs, 1), src0, "") #
1217 !if(!eq(NumSrcArgs, 2), src0#src1, "") #
1218 !if(!eq(NumSrcArgs, 3), src0#src1#src2, "");
1221 // Returns the assembly string for the inputs and outputs of a VOP3
1223 class getAsm64 <bit HasDst, int NumSrcArgs, bit HasModifiers,
1224 bit HasOMod, ValueType DstVT = i32> {
1225 string dst = !if(!eq(DstVT.Size, 1), "$sdst", "$vdst"); // use $sdst for VOPC
1226 string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
1227 string src1 = !if(!eq(NumSrcArgs, 1), "",
1228 !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
1229 " $src1_modifiers,"));
1230 string src2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", "");
1232 !if(!eq(HasModifiers, 0),
1233 getAsm32<HasDst, NumSrcArgs, DstVT>.ret,
1234 dst#", "#src0#src1#src2#"$clamp"#!if(HasOMod, "$omod", ""));
1237 // Returns the assembly string for the inputs and outputs of a VOP3P
1239 class getAsmVOP3P <bit HasDst, int NumSrcArgs, bit HasModifiers,
1240 bit HasClamp, ValueType DstVT = i32> {
1241 string dst = " $vdst";
1242 string src0 = !if(!eq(NumSrcArgs, 1), "$src0", "$src0,");
1243 string src1 = !if(!eq(NumSrcArgs, 1), "",
1244 !if(!eq(NumSrcArgs, 2), " $src1",
1246 string src2 = !if(!eq(NumSrcArgs, 3), " $src2", "");
1248 string mods = !if(HasModifiers, "$neg_lo$neg_hi", "");
1249 string clamp = !if(HasClamp, "$clamp", "");
1251 // Each modifier is printed as an array of bits for each operand, so
1252 // all operands are printed as part of src0_modifiers.
1253 string ret = dst#", "#src0#src1#src2#"$op_sel$op_sel_hi"#mods#clamp;
1256 class getAsmDPP <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> {
1257 string dst = !if(HasDst,
1258 !if(!eq(DstVT.Size, 1),
1261 ""); // use $sdst for VOPC
1262 string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
1263 string src1 = !if(!eq(NumSrcArgs, 1), "",
1264 !if(!eq(NumSrcArgs, 2), " $src1_modifiers",
1265 " $src1_modifiers,"));
1266 string args = !if(!eq(HasModifiers, 0),
1267 getAsm32<0, NumSrcArgs, DstVT>.ret,
1269 string ret = dst#args#" $dpp_ctrl$row_mask$bank_mask$bound_ctrl";
1272 class getAsmSDWA <bit HasDst, int NumSrcArgs, ValueType DstVT = i32> {
1273 string dst = !if(HasDst,
1274 !if(!eq(DstVT.Size, 1),
1275 " vcc", // use vcc token as dst for VOPC instructioins
1278 string src0 = "$src0_modifiers";
1279 string src1 = "$src1_modifiers";
1280 string args = !if(!eq(NumSrcArgs, 0),
1282 !if(!eq(NumSrcArgs, 1),
1284 ", "#src0#", "#src1#"$clamp"
1287 string sdwa = !if(!eq(NumSrcArgs, 0),
1289 !if(!eq(NumSrcArgs, 1),
1290 " $dst_sel $dst_unused $src0_sel",
1291 !if(!eq(DstVT.Size, 1),
1292 " $src0_sel $src1_sel", // No dst_sel and dst_unused for VOPC
1293 " $dst_sel $dst_unused $src0_sel $src1_sel"
1297 string ret = dst#args#sdwa;
1300 class getAsmSDWA9 <bit HasDst, bit HasOMod, int NumSrcArgs,
1301 ValueType DstVT = i32> {
1302 string dst = !if(HasDst,
1303 !if(!eq(DstVT.Size, 1),
1307 string src0 = "$src0_modifiers";
1308 string src1 = "$src1_modifiers";
1309 string out_mods = !if(!eq(HasOMod, 0), "$clamp", "$clamp$omod");
1310 string args = !if(!eq(NumSrcArgs, 0), "",
1311 !if(!eq(NumSrcArgs, 1),
1316 string sdwa = !if(!eq(NumSrcArgs, 0), "",
1317 !if(!eq(NumSrcArgs, 1),
1318 out_mods#" $dst_sel $dst_unused $src0_sel",
1319 !if(!eq(DstVT.Size, 1),
1320 " $src0_sel $src1_sel", // No dst_sel, dst_unused and output modifiers for VOPC
1321 out_mods#" $dst_sel $dst_unused $src0_sel $src1_sel"
1325 string ret = dst#args#sdwa;
1329 // Function that checks if instruction supports DPP and SDWA
1330 class getHasExt <int NumSrcArgs, ValueType DstVT = i32, ValueType Src0VT = i32,
1331 ValueType Src1VT = i32> {
1332 bit ret = !if(!eq(NumSrcArgs, 3),
1333 0, // NumSrcArgs == 3 - No DPP or SDWA for VOP3
1334 !if(!eq(DstVT.Size, 64),
1335 0, // 64-bit dst - No DPP or SDWA for 64-bit operands
1336 !if(!eq(Src0VT.Size, 64),
1338 !if(!eq(Src0VT.Size, 64),
1347 class BitOr<bit a, bit b> {
1348 bit ret = !if(a, 1, !if(b, 1, 0));
1351 class BitAnd<bit a, bit b> {
1352 bit ret = !if(a, !if(b, 1, 0), 0);
1355 class VOPProfile <list<ValueType> _ArgVT> {
1357 field list<ValueType> ArgVT = _ArgVT;
1359 field ValueType DstVT = ArgVT[0];
1360 field ValueType Src0VT = ArgVT[1];
1361 field ValueType Src1VT = ArgVT[2];
1362 field ValueType Src2VT = ArgVT[3];
1363 field RegisterOperand DstRC = getVALUDstForVT<DstVT>.ret;
1364 field RegisterOperand DstRCDPP = getVALUDstForVT<DstVT>.ret;
1365 field RegisterOperand DstRCSDWA = getVALUDstForVT<DstVT>.ret;
1366 field RegisterOperand DstRCSDWA9 = getSDWA9DstForVT<DstVT>.ret;
1367 field RegisterOperand Src0RC32 = getVOPSrc0ForVT<Src0VT>.ret;
1368 field RegisterClass Src1RC32 = getVregSrcForVT<Src1VT>.ret;
1369 field RegisterOperand Src0RC64 = getVOP3SrcForVT<Src0VT>.ret;
1370 field RegisterOperand Src1RC64 = getVOP3SrcForVT<Src1VT>.ret;
1371 field RegisterOperand Src2RC64 = getVOP3SrcForVT<Src2VT>.ret;
1372 field RegisterClass Src0DPP = getVregSrcForVT<Src0VT>.ret;
1373 field RegisterClass Src1DPP = getVregSrcForVT<Src1VT>.ret;
1374 field RegisterClass Src0SDWA = getVregSrcForVT<Src0VT>.ret;
1375 field RegisterClass Src1SDWA = getVregSrcForVT<Src1VT>.ret;
1376 field RegisterOperand Src0SDWA9 = getSDWA9SrcForVT<Src0VT>.ret;
1377 field RegisterOperand Src1SDWA9 = getSDWA9SrcForVT<Src0VT>.ret;
1378 field Operand Src0Mod = getSrcMod<Src0VT>.ret;
1379 field Operand Src1Mod = getSrcMod<Src1VT>.ret;
1380 field Operand Src2Mod = getSrcMod<Src2VT>.ret;
1381 field Operand Src0ModDPP = getSrcModExt<Src0VT>.ret;
1382 field Operand Src1ModDPP = getSrcModExt<Src1VT>.ret;
1383 field Operand Src0ModSDWA = getSrcModExt<Src0VT>.ret;
1384 field Operand Src1ModSDWA = getSrcModExt<Src1VT>.ret;
1385 field Operand Src0ModSDWA9 = getSrcModSDWA9<Src0VT>.ret;
1386 field Operand Src1ModSDWA9 = getSrcModSDWA9<Src1VT>.ret;
1389 field bit HasDst = !if(!eq(DstVT.Value, untyped.Value), 0, 1);
1390 field bit HasDst32 = HasDst;
1391 field bit EmitDst = HasDst; // force dst encoding, see v_movreld_b32 special case
1392 field int NumSrcArgs = getNumSrcArgs<Src0VT, Src1VT, Src2VT>.ret;
1393 field bit HasSrc0 = !if(!eq(Src0VT.Value, untyped.Value), 0, 1);
1394 field bit HasSrc1 = !if(!eq(Src1VT.Value, untyped.Value), 0, 1);
1395 field bit HasSrc2 = !if(!eq(Src2VT.Value, untyped.Value), 0, 1);
1397 // TODO: Modifiers logic is somewhat adhoc here, to be refined later
1398 field bit HasModifiers = isModifierType<Src0VT>.ret;
1400 field bit HasSrc0FloatMods = isFloatType<Src0VT>.ret;
1401 field bit HasSrc1FloatMods = isFloatType<Src1VT>.ret;
1402 field bit HasSrc2FloatMods = isFloatType<Src2VT>.ret;
1404 field bit HasSrc0IntMods = isIntType<Src0VT>.ret;
1405 field bit HasSrc1IntMods = isIntType<Src1VT>.ret;
1406 field bit HasSrc2IntMods = isIntType<Src2VT>.ret;
1408 field bit HasSrc0Mods = HasModifiers;
1409 field bit HasSrc1Mods = !if(HasModifiers, BitOr<HasSrc1FloatMods, HasSrc1IntMods>.ret, 0);
1410 field bit HasSrc2Mods = !if(HasModifiers, BitOr<HasSrc2FloatMods, HasSrc2IntMods>.ret, 0);
1412 field bit HasClamp = HasModifiers;
1413 field bit HasSDWAClamp = EmitDst;
1414 field bit HasFPClamp = BitAnd<isFloatType<DstVT>.ret, HasClamp>.ret;
1416 field bit IsPacked = isPackedType<Src0VT>.ret;
1417 field bit HasOpSel = IsPacked;
1418 field bit HasOMod = !if(HasOpSel, 0, HasModifiers);
1419 field bit HasSDWAOMod = isFloatType<DstVT>.ret;
1421 field bit HasExt = getHasExt<NumSrcArgs, DstVT, Src0VT, Src1VT>.ret;
1422 field bit HasSDWA9 = HasExt;
1424 field Operand Src0PackedMod = !if(HasSrc0FloatMods, PackedF16InputMods, PackedI16InputMods);
1425 field Operand Src1PackedMod = !if(HasSrc1FloatMods, PackedF16InputMods, PackedI16InputMods);
1426 field Operand Src2PackedMod = !if(HasSrc2FloatMods, PackedF16InputMods, PackedI16InputMods);
1428 field dag Outs = !if(HasDst,(outs DstRC:$vdst),(outs));
1430 // VOP3b instructions are a special case with a second explicit
1431 // output. This is manually overridden for them.
1432 field dag Outs32 = Outs;
1433 field dag Outs64 = Outs;
1434 field dag OutsDPP = getOutsExt<HasDst, DstVT, DstRCDPP>.ret;
1435 field dag OutsSDWA = getOutsExt<HasDst, DstVT, DstRCSDWA>.ret;
1436 field dag OutsSDWA9 = getOutsSDWA9<HasDst, DstVT, DstRCSDWA9>.ret;
1438 field dag Ins32 = getIns32<Src0RC32, Src1RC32, NumSrcArgs>.ret;
1439 field dag Ins64 = getIns64<Src0RC64, Src1RC64, Src2RC64, NumSrcArgs,
1440 HasModifiers, HasOMod, Src0Mod, Src1Mod,
1442 field dag InsVOP3P = getInsVOP3P<Src0RC64, Src1RC64, Src2RC64,
1443 NumSrcArgs, HasClamp,
1444 Src0PackedMod, Src1PackedMod, Src2PackedMod>.ret;
1446 field dag InsDPP = getInsDPP<Src0DPP, Src1DPP, NumSrcArgs,
1447 HasModifiers, Src0ModDPP, Src1ModDPP>.ret;
1448 field dag InsSDWA = getInsSDWA<Src0SDWA, Src1SDWA, NumSrcArgs,
1449 HasModifiers, Src0ModSDWA, Src1ModSDWA,
1451 field dag InsSDWA9 = getInsSDWA9<Src0SDWA9, Src1SDWA9, NumSrcArgs,
1452 HasSDWAOMod, Src0ModSDWA9, Src1ModSDWA9,
1455 field string Asm32 = getAsm32<HasDst, NumSrcArgs, DstVT>.ret;
1456 field string Asm64 = getAsm64<HasDst, NumSrcArgs, HasModifiers, HasOMod, DstVT>.ret;
1457 field string AsmVOP3P = getAsmVOP3P<HasDst, NumSrcArgs, HasModifiers, HasClamp, DstVT>.ret;
1458 field string AsmDPP = getAsmDPP<HasDst, NumSrcArgs, HasModifiers, DstVT>.ret;
1459 field string AsmSDWA = getAsmSDWA<HasDst, NumSrcArgs, DstVT>.ret;
1460 field string AsmSDWA9 = getAsmSDWA9<HasDst, HasSDWAOMod, NumSrcArgs, DstVT>.ret;
1463 class VOP_NO_EXT <VOPProfile p> : VOPProfile <p.ArgVT> {
1468 def VOP_F16_F16 : VOPProfile <[f16, f16, untyped, untyped]>;
1469 def VOP_F16_I16 : VOPProfile <[f16, i16, untyped, untyped]>;
1470 def VOP_I16_F16 : VOPProfile <[i16, f16, untyped, untyped]>;
1472 def VOP_F16_F16_F16 : VOPProfile <[f16, f16, f16, untyped]>;
1473 def VOP_F16_F16_I16 : VOPProfile <[f16, f16, i16, untyped]>;
1474 def VOP_F16_F16_I32 : VOPProfile <[f16, f16, i32, untyped]>;
1475 def VOP_I16_I16_I16 : VOPProfile <[i16, i16, i16, untyped]>;
1477 def VOP_I16_I16_I16_I16 : VOPProfile <[i16, i16, i16, i16, untyped]>;
1478 def VOP_F16_F16_F16_F16 : VOPProfile <[f16, f16, f16, f16, untyped]>;
1480 def VOP_V2F16_V2F16_V2F16 : VOPProfile <[v2f16, v2f16, v2f16, untyped]>;
1481 def VOP_V2I16_V2I16_V2I16 : VOPProfile <[v2i16, v2i16, v2i16, untyped]>;
1482 def VOP_B32_F16_F16 : VOPProfile <[i32, f16, f16, untyped]>;
1484 def VOP_V2F16_V2F16_V2F16_V2F16 : VOPProfile <[v2f16, v2f16, v2f16, v2f16]>;
1485 def VOP_V2I16_V2I16_V2I16_V2I16 : VOPProfile <[v2i16, v2i16, v2i16, v2i16]>;
1487 def VOP_NONE : VOPProfile <[untyped, untyped, untyped, untyped]>;
1489 def VOP_F32_F32 : VOPProfile <[f32, f32, untyped, untyped]>;
1490 def VOP_F32_F64 : VOPProfile <[f32, f64, untyped, untyped]>;
1491 def VOP_F32_I32 : VOPProfile <[f32, i32, untyped, untyped]>;
1492 def VOP_F64_F32 : VOPProfile <[f64, f32, untyped, untyped]>;
1493 def VOP_F64_F64 : VOPProfile <[f64, f64, untyped, untyped]>;
1494 def VOP_F64_I32 : VOPProfile <[f64, i32, untyped, untyped]>;
1495 def VOP_I32_F32 : VOPProfile <[i32, f32, untyped, untyped]>;
1496 def VOP_I32_F64 : VOPProfile <[i32, f64, untyped, untyped]>;
1497 def VOP_I32_I32 : VOPProfile <[i32, i32, untyped, untyped]>;
1498 def VOP_F16_F32 : VOPProfile <[f16, f32, untyped, untyped]>;
1499 def VOP_F32_F16 : VOPProfile <[f32, f16, untyped, untyped]>;
1501 def VOP_F32_F32_F16 : VOPProfile <[f32, f32, f16, untyped]>;
1502 def VOP_F32_F32_F32 : VOPProfile <[f32, f32, f32, untyped]>;
1503 def VOP_F32_F32_I32 : VOPProfile <[f32, f32, i32, untyped]>;
1504 def VOP_F64_F64_F64 : VOPProfile <[f64, f64, f64, untyped]>;
1505 def VOP_F64_F64_I32 : VOPProfile <[f64, f64, i32, untyped]>;
1506 def VOP_I32_F32_F32 : VOPProfile <[i32, f32, f32, untyped]>;
1507 def VOP_I32_F32_I32 : VOPProfile <[i32, f32, i32, untyped]>;
1508 def VOP_I32_I32_I32 : VOPProfile <[i32, i32, i32, untyped]>;
1509 def VOP_V2F16_F32_F32 : VOPProfile <[v2f16, f32, f32, untyped]>;
1511 def VOP_I64_I64_I32 : VOPProfile <[i64, i64, i32, untyped]>;
1512 def VOP_I64_I32_I64 : VOPProfile <[i64, i32, i64, untyped]>;
1513 def VOP_I64_I64_I64 : VOPProfile <[i64, i64, i64, untyped]>;
1515 def VOP_F16_F32_F16_F32 : VOPProfile <[f16, f32, f16, f32]>;
1516 def VOP_F32_F32_F16_F16 : VOPProfile <[f32, f32, f16, f16]>;
1517 def VOP_F32_F32_F32_F32 : VOPProfile <[f32, f32, f32, f32]>;
1518 def VOP_F64_F64_F64_F64 : VOPProfile <[f64, f64, f64, f64]>;
1519 def VOP_I32_I32_I32_I32 : VOPProfile <[i32, i32, i32, i32]>;
1520 def VOP_I64_I32_I32_I64 : VOPProfile <[i64, i32, i32, i64]>;
1521 def VOP_I32_F32_I32_I32 : VOPProfile <[i32, f32, i32, i32]>;
1522 def VOP_I64_I64_I32_I64 : VOPProfile <[i64, i64, i32, i64]>;
1523 def VOP_V4I32_I64_I32_V4I32 : VOPProfile <[v4i32, i64, i32, v4i32]>;
1525 class Commutable_REV <string revOp, bit isOrig> {
1526 string RevOp = revOp;
1527 bit IsOrig = isOrig;
1530 class AtomicNoRet <string noRetOp, bit isRet> {
1531 string NoRetOp = noRetOp;
1535 //===----------------------------------------------------------------------===//
1536 // Interpolation opcodes
1537 //===----------------------------------------------------------------------===//
1539 class VINTRP_Pseudo <string opName, dag outs, dag ins, list<dag> pattern> :
1540 VINTRPCommon <outs, ins, "", pattern>,
1541 SIMCInstr<opName, SIEncodingFamily.NONE> {
1543 let isCodeGenOnly = 1;
1546 class VINTRP_Real_si <bits <2> op, string opName, dag outs, dag ins,
1548 VINTRPCommon <outs, ins, asm, []>,
1550 SIMCInstr<opName, SIEncodingFamily.SI> {
1551 let AssemblerPredicate = SIAssemblerPredicate;
1552 let DecoderNamespace = "SICI";
1553 let DisableDecoder = DisableSIDecoder;
1556 class VINTRP_Real_vi <bits <2> op, string opName, dag outs, dag ins,
1558 VINTRPCommon <outs, ins, asm, []>,
1560 SIMCInstr<opName, SIEncodingFamily.VI> {
1561 let AssemblerPredicate = VIAssemblerPredicate;
1562 let DecoderNamespace = "VI";
1563 let DisableDecoder = DisableVIDecoder;
1566 multiclass VINTRP_m <bits <2> op, dag outs, dag ins, string asm,
1567 list<dag> pattern = []> {
1568 def "" : VINTRP_Pseudo <NAME, outs, ins, pattern>;
1570 def _si : VINTRP_Real_si <op, NAME, outs, ins, asm>;
1572 def _vi : VINTRP_Real_vi <op, NAME, outs, ins, asm>;
1575 //===----------------------------------------------------------------------===//
1576 // Vector instruction mappings
1577 //===----------------------------------------------------------------------===//
1579 // Maps an opcode in e32 form to its e64 equivalent
1580 def getVOPe64 : InstrMapping {
1581 let FilterClass = "VOP";
1582 let RowFields = ["OpName"];
1583 let ColFields = ["Size", "VOP3"];
1584 let KeyCol = ["4", "0"];
1585 let ValueCols = [["8", "1"]];
1588 // Maps an opcode in e64 form to its e32 equivalent
1589 def getVOPe32 : InstrMapping {
1590 let FilterClass = "VOP";
1591 let RowFields = ["OpName"];
1592 let ColFields = ["Size", "VOP3"];
1593 let KeyCol = ["8", "1"];
1594 let ValueCols = [["4", "0"]];
1597 // Maps ordinary instructions to their SDWA counterparts
1598 def getSDWAOp : InstrMapping {
1599 let FilterClass = "VOP";
1600 let RowFields = ["OpName"];
1601 let ColFields = ["AsmVariantName"];
1602 let KeyCol = ["Default"];
1603 let ValueCols = [["SDWA"]];
1606 // Maps ordinary instructions to their SDWA GFX9 counterparts
1607 def getSDWA9Op : InstrMapping {
1608 let FilterClass = "VOP";
1609 let RowFields = ["OpName"];
1610 let ColFields = ["AsmVariantName"];
1611 let KeyCol = ["Default"];
1612 let ValueCols = [["SDWA9"]];
1615 def getMaskedMIMGOp : InstrMapping {
1616 let FilterClass = "MIMG_Mask";
1617 let RowFields = ["Op"];
1618 let ColFields = ["Channels"];
1620 let ValueCols = [["1"], ["2"], ["3"] ];
1623 // Maps an commuted opcode to its original version
1624 def getCommuteOrig : InstrMapping {
1625 let FilterClass = "Commutable_REV";
1626 let RowFields = ["RevOp"];
1627 let ColFields = ["IsOrig"];
1629 let ValueCols = [["1"]];
1632 // Maps an original opcode to its commuted version
1633 def getCommuteRev : InstrMapping {
1634 let FilterClass = "Commutable_REV";
1635 let RowFields = ["RevOp"];
1636 let ColFields = ["IsOrig"];
1638 let ValueCols = [["0"]];
1641 def getMCOpcodeGen : InstrMapping {
1642 let FilterClass = "SIMCInstr";
1643 let RowFields = ["PseudoInstr"];
1644 let ColFields = ["Subtarget"];
1645 let KeyCol = [!cast<string>(SIEncodingFamily.NONE)];
1646 let ValueCols = [[!cast<string>(SIEncodingFamily.SI)],
1647 [!cast<string>(SIEncodingFamily.VI)]];
1650 // Get equivalent SOPK instruction.
1651 def getSOPKOp : InstrMapping {
1652 let FilterClass = "SOPKInstTable";
1653 let RowFields = ["BaseCmpOp"];
1654 let ColFields = ["IsSOPK"];
1656 let ValueCols = [["1"]];
1659 def getAddr64Inst : InstrMapping {
1660 let FilterClass = "MUBUFAddr64Table";
1661 let RowFields = ["OpName"];
1662 let ColFields = ["IsAddr64"];
1664 let ValueCols = [["1"]];
1667 // Maps an atomic opcode to its version with a return value.
1668 def getAtomicRetOp : InstrMapping {
1669 let FilterClass = "AtomicNoRet";
1670 let RowFields = ["NoRetOp"];
1671 let ColFields = ["IsRet"];
1673 let ValueCols = [["1"]];
1676 // Maps an atomic opcode to its returnless version.
1677 def getAtomicNoRetOp : InstrMapping {
1678 let FilterClass = "AtomicNoRet";
1679 let RowFields = ["NoRetOp"];
1680 let ColFields = ["IsRet"];
1682 let ValueCols = [["0"]];
1685 include "SIInstructions.td"
1686 include "CIInstructions.td"
1688 include "DSInstructions.td"
1689 include "MIMGInstructions.td"