107b7fadaSJoe Nash//===-- VOPDInstructions.td - Vector Instruction Definitions --------------===// 207b7fadaSJoe Nash// 307b7fadaSJoe Nash// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 407b7fadaSJoe Nash// See https://llvm.org/LICENSE.txt for license information. 507b7fadaSJoe Nash// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 607b7fadaSJoe Nash// 707b7fadaSJoe Nash//===----------------------------------------------------------------------===// 807b7fadaSJoe Nash 907b7fadaSJoe Nash//===----------------------------------------------------------------------===// 1007b7fadaSJoe Nash// Encodings 1107b7fadaSJoe Nash//===----------------------------------------------------------------------===// 1207b7fadaSJoe Nash 1307b7fadaSJoe Nashclass VOPDe<bits<4> opX, bits<5> opY> : Enc64 { 1407b7fadaSJoe Nash bits<9> src0X; 1507b7fadaSJoe Nash bits<8> vsrc1X; 1607b7fadaSJoe Nash bits<8> vdstX; 1707b7fadaSJoe Nash bits<9> src0Y; 1807b7fadaSJoe Nash bits<8> vsrc1Y; 1907b7fadaSJoe Nash bits<8> vdstY; 2007b7fadaSJoe Nash 2107b7fadaSJoe Nash let Inst{8-0} = src0X; 2207b7fadaSJoe Nash let Inst{16-9} = vsrc1X; 2307b7fadaSJoe Nash let Inst{21-17} = opY; 2407b7fadaSJoe Nash let Inst{25-22} = opX; 2507b7fadaSJoe Nash let Inst{31-26} = 0x32; // encoding 2607b7fadaSJoe Nash let Inst{40-32} = src0Y; 2707b7fadaSJoe Nash let Inst{48-41} = vsrc1Y; 2807b7fadaSJoe Nash let Inst{55-49} = vdstY{7-1}; 2907b7fadaSJoe Nash let Inst{63-56} = vdstX; 3007b7fadaSJoe Nash} 3107b7fadaSJoe Nash 3207b7fadaSJoe Nashclass VOPD_MADKe<bits<4> opX, bits<5> opY> : Enc96 { 3307b7fadaSJoe Nash bits<9> src0X; 3407b7fadaSJoe Nash bits<8> vsrc1X; 3507b7fadaSJoe Nash bits<8> vdstX; 3607b7fadaSJoe Nash bits<9> src0Y; 3707b7fadaSJoe Nash bits<8> vsrc1Y; 3807b7fadaSJoe Nash bits<8> vdstY; 3907b7fadaSJoe Nash bits<32> imm; 4007b7fadaSJoe Nash 4107b7fadaSJoe Nash let Inst{8-0} = src0X; 4207b7fadaSJoe Nash let Inst{16-9} = vsrc1X; 4307b7fadaSJoe Nash let Inst{21-17} = opY; 4407b7fadaSJoe Nash let Inst{25-22} = opX; 4507b7fadaSJoe Nash let Inst{31-26} = 0x32; // encoding 4607b7fadaSJoe Nash let Inst{40-32} = src0Y; 4707b7fadaSJoe Nash let Inst{48-41} = vsrc1Y; 4807b7fadaSJoe Nash let Inst{55-49} = vdstY{7-1}; 4907b7fadaSJoe Nash let Inst{63-56} = vdstX; 5007b7fadaSJoe Nash let Inst{95-64} = imm; 5107b7fadaSJoe Nash} 5207b7fadaSJoe Nash 5307b7fadaSJoe Nash//===----------------------------------------------------------------------===// 5407b7fadaSJoe Nash// VOPD classes 5507b7fadaSJoe Nash//===----------------------------------------------------------------------===// 5607b7fadaSJoe Nash 57a97028acSMariusz Sikora 58a97028acSMariusz Sikoraclass GFXGenD<GFXGen Gen, list<string> DXPseudos, list<string> DYPseudos, 59a97028acSMariusz Sikora Predicate subtargetPred = Gen.AssemblerPredicate> : 60a97028acSMariusz Sikora GFXGen<Gen.AssemblerPredicate, Gen.DecoderNamespace, Gen.Suffix, 61a97028acSMariusz Sikora Gen.Subtarget> { 62a97028acSMariusz Sikora list<string> VOPDXPseudos = DXPseudos; 63a97028acSMariusz Sikora list<string> VOPDYPseudos = DYPseudos; 64a97028acSMariusz Sikora Predicate SubtargetPredicate = subtargetPred; 65a97028acSMariusz Sikora} 66a97028acSMariusz Sikora 6707b7fadaSJoe Nashclass VOPD_Base<dag outs, dag ins, string asm, VOP_Pseudo VDX, VOP_Pseudo VDY, 68a97028acSMariusz Sikora VOPD_Component XasVC, VOPD_Component YasVC, GFXGenD Gen> 6907b7fadaSJoe Nash : VOPAnyCommon<outs, ins, asm, []>, 7007b7fadaSJoe Nash VOP<NAME>, 71a97028acSMariusz Sikora SIMCInstr<NAME, Gen.Subtarget> { 7207b7fadaSJoe Nash // Fields for table indexing 7307b7fadaSJoe Nash Instruction Opcode = !cast<Instruction>(NAME); 7407b7fadaSJoe Nash bits<5> OpX = XasVC.VOPDOp; 7507b7fadaSJoe Nash bits<5> OpY = YasVC.VOPDOp; 76a97028acSMariusz Sikora bits<4> SubTgt = Gen.Subtarget; 7707b7fadaSJoe Nash 7807b7fadaSJoe Nash let VALU = 1; 7907b7fadaSJoe Nash 80a97028acSMariusz Sikora let DecoderNamespace = Gen.DecoderNamespace; 81a97028acSMariusz Sikora let AssemblerPredicate = Gen.AssemblerPredicate; 8207b7fadaSJoe Nash let WaveSizePredicate = isWave32; 8307b7fadaSJoe Nash let isCodeGenOnly = 0; 84a97028acSMariusz Sikora let SubtargetPredicate = Gen.SubtargetPredicate; 8507b7fadaSJoe Nash let AsmMatchConverter = "cvtVOPD"; 8607b7fadaSJoe Nash let Size = 8; 8707b7fadaSJoe Nash let ReadsModeReg = !or(VDX.ReadsModeReg, VDY.ReadsModeReg); 8807b7fadaSJoe Nash let mayRaiseFPException = ReadsModeReg; 8907b7fadaSJoe Nash 90f9d6d46aSJay Foad // V_DUAL_FMAC and V_DUAL_DOT2ACC_F32_F16 and V_DUAL_DOT2ACC_F32_BF16 need a 91f9d6d46aSJay Foad // dummy src2 tied to dst for passes to track its uses. Its presence does not 92f9d6d46aSJay Foad // affect VOPD formation rules because the rules for src2 and dst are the 93f9d6d46aSJay Foad // same. src2X and src2Y should not be encoded. 94f9d6d46aSJay Foad bit hasSrc2AccX = !or(!eq(VDX.Mnemonic, "v_fmac_f32"), !eq(VDX.Mnemonic, "v_dot2c_f32_f16"), !eq(VDX.Mnemonic, "v_dot2c_f32_bf16")); 95f9d6d46aSJay Foad bit hasSrc2AccY = !or(!eq(VDY.Mnemonic, "v_fmac_f32"), !eq(VDY.Mnemonic, "v_dot2c_f32_f16"), !eq(VDY.Mnemonic, "v_dot2c_f32_bf16")); 9601b8140dSJoe Nash string ConstraintsX = !if(hasSrc2AccX, "$src2X = $vdstX", ""); 9701b8140dSJoe Nash string ConstraintsY = !if(hasSrc2AccY, "$src2Y = $vdstY", ""); 9801b8140dSJoe Nash let Constraints = 9901b8140dSJoe Nash ConstraintsX # !if(!and(hasSrc2AccX, hasSrc2AccY), ", ", "") # ConstraintsY; 10001b8140dSJoe Nash string DisableEncodingX = !if(hasSrc2AccX, "$src2X", ""); 10101b8140dSJoe Nash string DisableEncodingY = !if(hasSrc2AccY, "$src2Y", ""); 10201b8140dSJoe Nash let DisableEncoding = 10301b8140dSJoe Nash DisableEncodingX # !if(!and(hasSrc2AccX, hasSrc2AccY), ", ", "") # DisableEncodingY; 10401b8140dSJoe Nash 10507b7fadaSJoe Nash let Uses = RegListUnion<VDX.Uses, VDY.Uses>.ret; 10607b7fadaSJoe Nash let Defs = RegListUnion<VDX.Defs, VDY.Defs>.ret; 10707b7fadaSJoe Nash let SchedRW = !listconcat(VDX.SchedRW, VDY.SchedRW); 10807b7fadaSJoe Nash} 10907b7fadaSJoe Nash 11007b7fadaSJoe Nashclass VOPD<dag outs, dag ins, string asm, VOP_Pseudo VDX, VOP_Pseudo VDY, 111a97028acSMariusz Sikora VOPD_Component XasVC, VOPD_Component YasVC, GFXGenD Gen> 112a97028acSMariusz Sikora : VOPD_Base<outs, ins, asm, VDX, VDY, XasVC, YasVC, Gen>, 11307b7fadaSJoe Nash VOPDe<XasVC.VOPDOp{3-0}, YasVC.VOPDOp> { 11407b7fadaSJoe Nash let Inst{16-9} = !if (!eq(VDX.Mnemonic, "v_mov_b32"), 0x0, vsrc1X); 11507b7fadaSJoe Nash let Inst{48-41} = !if (!eq(VDY.Mnemonic, "v_mov_b32"), 0x0, vsrc1Y); 11607b7fadaSJoe Nash} 11707b7fadaSJoe Nash 11807b7fadaSJoe Nashclass VOPD_MADK<dag outs, dag ins, string asm, VOP_Pseudo VDX, VOP_Pseudo VDY, 119a97028acSMariusz Sikora VOPD_Component XasVC, VOPD_Component YasVC, GFXGenD Gen> 120a97028acSMariusz Sikora : VOPD_Base<outs, ins, asm, VDX, VDY, XasVC, YasVC, Gen>, 12107b7fadaSJoe Nash VOPD_MADKe<XasVC.VOPDOp{3-0}, YasVC.VOPDOp> { 12207b7fadaSJoe Nash let Inst{16-9} = !if (!eq(VDX.Mnemonic, "v_mov_b32"), 0x0, vsrc1X); 12307b7fadaSJoe Nash let Inst{48-41} = !if (!eq(VDY.Mnemonic, "v_mov_b32"), 0x0, vsrc1Y); 12407b7fadaSJoe Nash let Size = 12; 1256e86ab7eSMirko Brkusanin let FixedSize = 1; 12607b7fadaSJoe Nash} 12707b7fadaSJoe Nash 128a97028acSMariusz Sikoradefvar VOPDPseudosCommon = [ 12907b7fadaSJoe Nash "V_FMAC_F32_e32", "V_FMAAK_F32", "V_FMAMK_F32", "V_MUL_F32_e32", 13007b7fadaSJoe Nash "V_ADD_F32_e32", "V_SUB_F32_e32", "V_SUBREV_F32_e32", "V_MUL_LEGACY_F32_e32", 131*d1cf86feSJay Foad "V_MOV_B32_e32", "V_CNDMASK_B32_e32", "V_MAX_F32_e32", "V_MIN_F32_e32", 132*d1cf86feSJay Foad "V_DOT2C_F32_F16_e32", "V_DOT2C_F32_BF16_e32" 13307b7fadaSJoe Nash]; 134a97028acSMariusz Sikoradefvar VOPDYOnlyPseudosCommon = ["V_ADD_U32_e32", "V_LSHLREV_B32_e32", 135a97028acSMariusz Sikora "V_AND_B32_e32"]; 136a97028acSMariusz Sikora 137*d1cf86feSJay Foaddefvar VOPDXPseudosGFX11 = VOPDPseudosCommon; 138a97028acSMariusz Sikoradefvar VOPDXPseudosGFX12 = VOPDPseudosCommon; 139a97028acSMariusz Sikoradefvar VOPDYPseudosGFX11 = !listconcat(VOPDXPseudosGFX11, VOPDYOnlyPseudosCommon); 140a97028acSMariusz Sikoradefvar VOPDYPseudosGFX12 = !listconcat(VOPDXPseudosGFX12, VOPDYOnlyPseudosCommon); 141a97028acSMariusz Sikora 142a97028acSMariusz Sikoradef GFX11GenD : GFXGenD<GFX11Gen, VOPDXPseudosGFX11, VOPDYPseudosGFX11>; 143a97028acSMariusz Sikoradef GFX12GenD : GFXGenD<GFX12Gen, VOPDXPseudosGFX12, VOPDYPseudosGFX12>; 144a97028acSMariusz Sikora 14507b7fadaSJoe Nash 14607b7fadaSJoe Nashdef VOPDDstYOperand : RegisterOperand<VGPR_32, "printRegularOperand"> { 14707b7fadaSJoe Nash let DecoderMethod = "decodeOperandVOPDDstY"; 14807b7fadaSJoe Nash} 14907b7fadaSJoe Nash 150a97028acSMariusz Sikoraclass getRenamed<string VOPDName, GFXGen Gen> { 151a97028acSMariusz Sikora string ret = !if(!eq(Gen.Subtarget, GFX12Gen.Subtarget), 152a97028acSMariusz Sikora !if(!eq(VOPDName, "v_dual_max_f32"), 153a97028acSMariusz Sikora "v_dual_max_num_f32", 154a97028acSMariusz Sikora !if(!eq(VOPDName, "v_dual_min_f32"), 155a97028acSMariusz Sikora "v_dual_min_num_f32", 156a97028acSMariusz Sikora VOPDName)), 157a97028acSMariusz Sikora VOPDName); 158a97028acSMariusz Sikora} 159a97028acSMariusz Sikora 160a97028acSMariusz Sikoraforeach Gen = [GFX11GenD, GFX12GenD] in { 161a97028acSMariusz Sikora foreach x = Gen.VOPDXPseudos in { 162a97028acSMariusz Sikora foreach y = Gen.VOPDYPseudos in { 16307b7fadaSJoe Nash defvar xInst = !cast<VOP_Pseudo>(x); 16407b7fadaSJoe Nash defvar yInst = !cast<VOP_Pseudo>(y); 16507b7fadaSJoe Nash defvar XasVC = !cast<VOPD_Component>(x); 16607b7fadaSJoe Nash defvar YasVC = !cast<VOPD_Component>(y); 167a97028acSMariusz Sikora defvar xAsmName = getRenamed<XasVC.VOPDName, Gen>.ret; 168a97028acSMariusz Sikora defvar yAsmName = getRenamed<YasVC.VOPDName, Gen>.ret; 16907b7fadaSJoe Nash defvar isMADK = !or(!eq(x, "V_FMAAK_F32"), !eq(x, "V_FMAMK_F32"), 17007b7fadaSJoe Nash !eq(y, "V_FMAAK_F32"), !eq(y, "V_FMAMK_F32")); 17107b7fadaSJoe Nash // If X or Y is MADK (have a mandatory immediate), all src operands which 17207b7fadaSJoe Nash // may contain an optional literal must use the VSrc_*_Deferred operand 17307b7fadaSJoe Nash // type. Optional literal operands in MADK VOPD components always use this 17407b7fadaSJoe Nash // operand form. If Both X and Y are MADK, the mandatory literal of X 17507b7fadaSJoe Nash // additionally must use an alternate operand format which defers to the 17607b7fadaSJoe Nash // 'real' Y literal 17707b7fadaSJoe Nash defvar isOpXMADK = !or(!eq(x, "V_FMAAK_F32"), !eq(x, "V_FMAMK_F32")); 17807b7fadaSJoe Nash defvar isOpYMADK = !or(!eq(y, "V_FMAAK_F32"), !eq(y, "V_FMAMK_F32")); 179a97028acSMariusz Sikora defvar OpName = "V_DUAL_" # !substr(x,2) # "_X_" # !substr(y,2) # Gen.Suffix; 18007b7fadaSJoe Nash defvar outs = (outs VGPRSrc_32:$vdstX, VOPDDstYOperand:$vdstY); 18107b7fadaSJoe Nash if !or(isOpXMADK, isOpYMADK) then { 18207b7fadaSJoe Nash if !and(isOpXMADK, isOpYMADK) then { 18307b7fadaSJoe Nash defvar X_MADK_Pfl = !cast<VOP_MADK_Base>(xInst.Pfl); 18407b7fadaSJoe Nash defvar ins = !con(xInst.Pfl.InsVOPDXDeferred, yInst.Pfl.InsVOPDY); 185a97028acSMariusz Sikora defvar asm = xAsmName #" "# X_MADK_Pfl.AsmVOPDXDeferred #" :: "# yAsmName #" "# yInst.Pfl.AsmVOPDY; 186a97028acSMariusz Sikora def OpName : VOPD_MADK<outs, ins, asm, xInst, yInst, XasVC, YasVC, Gen>; 18707b7fadaSJoe Nash } else { 188a97028acSMariusz Sikora defvar asm = xAsmName #" "# xInst.Pfl.AsmVOPDX #" :: "# yAsmName #" "# yInst.Pfl.AsmVOPDY; 18907b7fadaSJoe Nash if isOpXMADK then { 19007b7fadaSJoe Nash assert !not(isOpYMADK), "Expected only OpX as MADK"; 19107b7fadaSJoe Nash defvar ins = !con(xInst.Pfl.InsVOPDX, yInst.Pfl.InsVOPDYDeferred); 192a97028acSMariusz Sikora def OpName : VOPD_MADK<outs, ins, asm, xInst, yInst, XasVC, YasVC, Gen>; 19307b7fadaSJoe Nash } else { 19407b7fadaSJoe Nash assert !not(isOpXMADK), "Expected only OpY as MADK"; 19507b7fadaSJoe Nash defvar ins = !con(xInst.Pfl.InsVOPDXDeferred, yInst.Pfl.InsVOPDY); 196a97028acSMariusz Sikora def OpName : VOPD_MADK<outs, ins, asm, xInst, yInst, XasVC, YasVC, Gen>; 19707b7fadaSJoe Nash } 19807b7fadaSJoe Nash } 19907b7fadaSJoe Nash } else { 20007b7fadaSJoe Nash defvar ins = !con(xInst.Pfl.InsVOPDX, yInst.Pfl.InsVOPDY); 201a97028acSMariusz Sikora defvar asm = xAsmName #" "# xInst.Pfl.AsmVOPDX #" :: "# yAsmName #" "# yInst.Pfl.AsmVOPDY; 202a97028acSMariusz Sikora def OpName : VOPD<outs, ins, asm, xInst, yInst, XasVC, YasVC, Gen>; 203a97028acSMariusz Sikora } 20407b7fadaSJoe Nash } 20507b7fadaSJoe Nash } 20607b7fadaSJoe Nash} 20707b7fadaSJoe Nash 208