1//===-- VOPDInstructions.td - Vector Instruction Definitions --------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8 9//===----------------------------------------------------------------------===// 10// Encodings 11//===----------------------------------------------------------------------===// 12 13class VOPDe<bits<4> opX, bits<5> opY> : Enc64 { 14 bits<9> src0X; 15 bits<8> vsrc1X; 16 bits<8> vdstX; 17 bits<9> src0Y; 18 bits<8> vsrc1Y; 19 bits<8> vdstY; 20 21 let Inst{8-0} = src0X; 22 let Inst{16-9} = vsrc1X; 23 let Inst{21-17} = opY; 24 let Inst{25-22} = opX; 25 let Inst{31-26} = 0x32; // encoding 26 let Inst{40-32} = src0Y; 27 let Inst{48-41} = vsrc1Y; 28 let Inst{55-49} = vdstY{7-1}; 29 let Inst{63-56} = vdstX; 30} 31 32class VOPD_MADKe<bits<4> opX, bits<5> opY> : Enc96 { 33 bits<9> src0X; 34 bits<8> vsrc1X; 35 bits<8> vdstX; 36 bits<9> src0Y; 37 bits<8> vsrc1Y; 38 bits<8> vdstY; 39 bits<32> imm; 40 41 let Inst{8-0} = src0X; 42 let Inst{16-9} = vsrc1X; 43 let Inst{21-17} = opY; 44 let Inst{25-22} = opX; 45 let Inst{31-26} = 0x32; // encoding 46 let Inst{40-32} = src0Y; 47 let Inst{48-41} = vsrc1Y; 48 let Inst{55-49} = vdstY{7-1}; 49 let Inst{63-56} = vdstX; 50 let Inst{95-64} = imm; 51} 52 53//===----------------------------------------------------------------------===// 54// VOPD classes 55//===----------------------------------------------------------------------===// 56 57class VOPD_Base<dag outs, dag ins, string asm, VOP_Pseudo VDX, VOP_Pseudo VDY, 58 VOPD_Component XasVC, VOPD_Component YasVC> 59 : VOPAnyCommon<outs, ins, asm, []>, 60 VOP<NAME>, 61 SIMCInstr<NAME, SIEncodingFamily.GFX11> { 62 // Fields for table indexing 63 Instruction Opcode = !cast<Instruction>(NAME); 64 bits<5> OpX = XasVC.VOPDOp; 65 bits<5> OpY = YasVC.VOPDOp; 66 67 let VALU = 1; 68 69 let DecoderNamespace = "GFX11"; 70 let AssemblerPredicate = isGFX11Plus; 71 let WaveSizePredicate = isWave32; 72 let isCodeGenOnly = 0; 73 let SubtargetPredicate = isGFX11Plus; 74 let AsmMatchConverter = "cvtVOPD"; 75 let Size = 8; 76 let ReadsModeReg = !or(VDX.ReadsModeReg, VDY.ReadsModeReg); 77 let mayRaiseFPException = ReadsModeReg; 78 79 let Uses = RegListUnion<VDX.Uses, VDY.Uses>.ret; 80 let Defs = RegListUnion<VDX.Defs, VDY.Defs>.ret; 81 let SchedRW = !listconcat(VDX.SchedRW, VDY.SchedRW); 82} 83 84class VOPD<dag outs, dag ins, string asm, VOP_Pseudo VDX, VOP_Pseudo VDY, 85 VOPD_Component XasVC, VOPD_Component YasVC> 86 : VOPD_Base<outs, ins, asm, VDX, VDY, XasVC, YasVC>, 87 VOPDe<XasVC.VOPDOp{3-0}, YasVC.VOPDOp> { 88 let Inst{16-9} = !if (!eq(VDX.Mnemonic, "v_mov_b32"), 0x0, vsrc1X); 89 let Inst{48-41} = !if (!eq(VDY.Mnemonic, "v_mov_b32"), 0x0, vsrc1Y); 90} 91 92class VOPD_MADK<dag outs, dag ins, string asm, VOP_Pseudo VDX, VOP_Pseudo VDY, 93 VOPD_Component XasVC, VOPD_Component YasVC> 94 : VOPD_Base<outs, ins, asm, VDX, VDY, XasVC, YasVC>, 95 VOPD_MADKe<XasVC.VOPDOp{3-0}, YasVC.VOPDOp> { 96 let Inst{16-9} = !if (!eq(VDX.Mnemonic, "v_mov_b32"), 0x0, vsrc1X); 97 let Inst{48-41} = !if (!eq(VDY.Mnemonic, "v_mov_b32"), 0x0, vsrc1Y); 98 let Size = 12; 99} 100 101// V_DUAL_DOT2ACC_F32_BF16 is a legal instruction, but V_DOT2ACC_F32_BF16 is 102// not. Since we generate the DUAL form by converting from the normal form we 103// will never generate it. 104defvar VOPDYPseudos = [ 105 "V_FMAC_F32_e32", "V_FMAAK_F32", "V_FMAMK_F32", "V_MUL_F32_e32", 106 "V_ADD_F32_e32", "V_SUB_F32_e32", "V_SUBREV_F32_e32", "V_MUL_LEGACY_F32_e32", 107 "V_MOV_B32_e32", "V_CNDMASK_B32_e32", "V_MAX_F32_e32", "V_MIN_F32_e32", 108 "V_DOT2C_F32_F16_e32", "V_ADD_U32_e32", "V_LSHLREV_B32_e32", "V_AND_B32_e32" 109]; 110defvar VOPDXPseudos = VOPDYPseudos[0...VOPDX_Max_Index]; 111 112def VOPDDstYOperand : RegisterOperand<VGPR_32, "printRegularOperand"> { 113 let DecoderMethod = "decodeOperandVOPDDstY"; 114} 115 116foreach x = VOPDXPseudos in { 117 foreach y = VOPDYPseudos in { 118 defvar xInst = !cast<VOP_Pseudo>(x); 119 defvar yInst = !cast<VOP_Pseudo>(y); 120 defvar XasVC = !cast<VOPD_Component>(x); 121 defvar YasVC = !cast<VOPD_Component>(y); 122 defvar isMADK = !or(!eq(x, "V_FMAAK_F32"), !eq(x, "V_FMAMK_F32"), 123 !eq(y, "V_FMAAK_F32"), !eq(y, "V_FMAMK_F32")); 124 // If X or Y is MADK (have a mandatory immediate), all src operands which 125 // may contain an optional literal must use the VSrc_*_Deferred operand 126 // type. Optional literal operands in MADK VOPD components always use this 127 // operand form. If Both X and Y are MADK, the mandatory literal of X 128 // additionally must use an alternate operand format which defers to the 129 // 'real' Y literal 130 defvar isOpXMADK = !or(!eq(x, "V_FMAAK_F32"), !eq(x, "V_FMAMK_F32")); 131 defvar isOpYMADK = !or(!eq(y, "V_FMAAK_F32"), !eq(y, "V_FMAMK_F32")); 132 defvar OpName = "V_DUAL_" # !substr(x,2) # "_X_" # !substr(y,2); 133 defvar outs = (outs VGPRSrc_32:$vdstX, VOPDDstYOperand:$vdstY); 134 if !or(isOpXMADK, isOpYMADK) then { 135 if !and(isOpXMADK, isOpYMADK) then { 136 defvar X_MADK_Pfl = !cast<VOP_MADK_Base>(xInst.Pfl); 137 defvar ins = !con(xInst.Pfl.InsVOPDXDeferred, yInst.Pfl.InsVOPDY); 138 defvar asm = XasVC.VOPDName #" "# X_MADK_Pfl.AsmVOPDXDeferred #" :: "# YasVC.VOPDName #" "# yInst.Pfl.AsmVOPDY; 139 def OpName : VOPD_MADK<outs, ins, asm, xInst, yInst, XasVC, YasVC>; 140 } else { 141 defvar asm = XasVC.VOPDName #" "# xInst.Pfl.AsmVOPDX #" :: "# YasVC.VOPDName #" "# yInst.Pfl.AsmVOPDY; 142 if isOpXMADK then { 143 assert !not(isOpYMADK), "Expected only OpX as MADK"; 144 defvar ins = !con(xInst.Pfl.InsVOPDX, yInst.Pfl.InsVOPDYDeferred); 145 def OpName : VOPD_MADK<outs, ins, asm, xInst, yInst, XasVC, YasVC>; 146 } else { 147 assert !not(isOpXMADK), "Expected only OpY as MADK"; 148 defvar ins = !con(xInst.Pfl.InsVOPDXDeferred, yInst.Pfl.InsVOPDY); 149 def OpName : VOPD_MADK<outs, ins, asm, xInst, yInst, XasVC, YasVC>; 150 } 151 } 152 } else { 153 defvar ins = !con(xInst.Pfl.InsVOPDX, yInst.Pfl.InsVOPDY); 154 defvar asm = XasVC.VOPDName #" "# xInst.Pfl.AsmVOPDX #" :: "# YasVC.VOPDName #" "# yInst.Pfl.AsmVOPDY; 155 def OpName : VOPD<outs, ins, asm, xInst, yInst, XasVC, YasVC>; 156 } 157 } 158} 159 160