diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp --- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp +++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUInstPrinter.cpp @@ -362,22 +362,30 @@ } void AMDGPUInstPrinter::printVOPDst(const MCInst *MI, unsigned OpNo, - const MCSubtargetInfo &STI, raw_ostream &O) { + const MCSubtargetInfo &STI, + raw_ostream &O) { + auto Opcode = MI->getOpcode(); + auto Flags = MII.get(Opcode).TSFlags; + if (OpNo == 0) { - if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::VOP3) - O << "_e64 "; - else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::DPP) - O << "_dpp "; - else if (MII.get(MI->getOpcode()).TSFlags & SIInstrFlags::SDWA) - O << "_sdwa "; - else - O << "_e32 "; + if (Flags & SIInstrFlags::VOP3) { + if (!getVOP3IsSingle(Opcode)) + O << "_e64"; + } else if (Flags & SIInstrFlags::DPP) { + O << "_dpp"; + } else if (Flags & SIInstrFlags::SDWA) { + O << "_sdwa"; + } else if (((Flags & SIInstrFlags::VOP1) && !getVOP1IsSingle(Opcode)) || + ((Flags & SIInstrFlags::VOP2) && !getVOP2IsSingle(Opcode))) { + O << "_e32"; + } + O << " "; } printOperand(MI, OpNo, STI, O); // Print default vcc/vcc_lo operand. - switch (MI->getOpcode()) { + switch (Opcode) { default: break; case AMDGPU::V_ADD_CO_CI_U32_e32_gfx10: diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.td b/llvm/lib/Target/AMDGPU/SIInstrInfo.td --- a/llvm/lib/Target/AMDGPU/SIInstrInfo.td +++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.td @@ -1860,7 +1860,7 @@ // instruction. class getAsmVOP3P { - string dst = " $vdst"; + string dst = "$vdst"; string src0 = !if(!eq(NumSrcArgs, 1), "$src0", "$src0,"); string src1 = !if(!eq(NumSrcArgs, 1), "", !if(!eq(NumSrcArgs, 2), " $src1", @@ -1881,7 +1881,7 @@ bit Src0HasMods, bit Src1HasMods, bit Src2HasMods> { - string dst = " $vdst"; + string dst = "$vdst"; string isrc0 = !if(!eq(NumSrcArgs, 1), "$src0", "$src0,"); string isrc1 = !if(!eq(NumSrcArgs, 1), "", @@ -2147,6 +2147,7 @@ field bit IsMAI = 0; field bit IsDOT = 0; + field bit IsSingle = 0; field Operand Src0PackedMod = !if(HasSrc0FloatMods, PackedF16InputMods, PackedI16InputMods); field Operand Src1PackedMod = !if(HasSrc1FloatMods, PackedF16InputMods, PackedI16InputMods); diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h +++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.h @@ -397,6 +397,15 @@ LLVM_READONLY bool getSMEMIsBuffer(unsigned Opc); +LLVM_READONLY +bool getVOP1IsSingle(unsigned Opc); + +LLVM_READONLY +bool getVOP2IsSingle(unsigned Opc); + +LLVM_READONLY +bool getVOP3IsSingle(unsigned Opc); + LLVM_READONLY const GcnBufferFormatInfo *getGcnBufferFormatInfo(uint8_t BitsPerComp, uint8_t NumComponents, diff --git a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp --- a/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp +++ b/llvm/lib/Target/AMDGPU/Utils/AMDGPUBaseInfo.cpp @@ -178,12 +178,23 @@ bool IsBuffer; }; +struct VOPInfo { + uint16_t Opcode; + bool IsSingle; +}; + #define GET_MTBUFInfoTable_DECL #define GET_MTBUFInfoTable_IMPL #define GET_MUBUFInfoTable_DECL #define GET_MUBUFInfoTable_IMPL #define GET_SMInfoTable_DECL #define GET_SMInfoTable_IMPL +#define GET_VOP1InfoTable_DECL +#define GET_VOP1InfoTable_IMPL +#define GET_VOP2InfoTable_DECL +#define GET_VOP2InfoTable_IMPL +#define GET_VOP3InfoTable_DECL +#define GET_VOP3InfoTable_IMPL #include "AMDGPUGenSearchableTables.inc" int getMTBUFBaseOpcode(unsigned Opc) { @@ -251,6 +262,21 @@ return Info ? Info->IsBuffer : false; } +bool getVOP1IsSingle(unsigned Opc) { + const VOPInfo *Info = getVOP1OpcodeHelper(Opc); + return Info ? Info->IsSingle : false; +} + +bool getVOP2IsSingle(unsigned Opc) { + const VOPInfo *Info = getVOP2OpcodeHelper(Opc); + return Info ? Info->IsSingle : false; +} + +bool getVOP3IsSingle(unsigned Opc) { + const VOPInfo *Info = getVOP3OpcodeHelper(Opc); + return Info ? Info->IsSingle : false; +} + // Wrapper for Tablegen'd function. enum Subtarget is not defined in any // header files, so we need to wrap it in a function that takes unsigned // instead. diff --git a/llvm/lib/Target/AMDGPU/VOP1Instructions.td b/llvm/lib/Target/AMDGPU/VOP1Instructions.td --- a/llvm/lib/Target/AMDGPU/VOP1Instructions.td +++ b/llvm/lib/Target/AMDGPU/VOP1Instructions.td @@ -60,6 +60,7 @@ } class VOP1_Real : + VOP_Real , InstSI , SIMCInstr { diff --git a/llvm/lib/Target/AMDGPU/VOP2Instructions.td b/llvm/lib/Target/AMDGPU/VOP2Instructions.td --- a/llvm/lib/Target/AMDGPU/VOP2Instructions.td +++ b/llvm/lib/Target/AMDGPU/VOP2Instructions.td @@ -81,6 +81,7 @@ } class VOP2_Real : + VOP_Real , InstSI , SIMCInstr { @@ -268,10 +269,9 @@ (ins VCSrc_f32:$src0, VGPR_32:$src1, ImmOpType:$imm), (ins VCSrc_f16:$src0, VGPR_32:$src1, ImmOpType:$imm)); field bit HasExt = 0; + let IsSingle = 1; - // Hack to stop printing _e64 - let DstRC = RegisterOperand; - field string Asm32 = " $vdst, $src0, $src1, $imm"; + field string Asm32 = "$vdst, $src0, $src1, $imm"; } def VOP_MADAK_F16 : VOP_MADAK ; @@ -281,10 +281,9 @@ field Operand ImmOpType = !if(!eq(vt.Size, 32), f32kimm, f16kimm); field dag Ins32 = (ins VCSrc_f32:$src0, ImmOpType:$imm, VGPR_32:$src1); field bit HasExt = 0; + let IsSingle = 1; - // Hack to stop printing _e64 - let DstRC = RegisterOperand; - field string Asm32 = " $vdst, $src0, $imm, $src1"; + field string Asm32 = "$vdst, $src0, $imm, $src1"; } def VOP_MADMK_F16 : VOP_MADMK ; @@ -1406,10 +1405,7 @@ def _e64_vi : VOP3_Real(NAME#"_e64"), SIEncodingFamily.VI>, VOP3e_vi (NAME#"_e64").Pfl> { - // Hack to stop printing _e64 - VOP3_Pseudo ps = !cast(NAME#"_e64"); - let OutOperandList = (outs VGPR_32:$vdst); - let AsmString = ps.Mnemonic # " " # ps.AsmOperands; + let IsSingle = 1; } } diff --git a/llvm/lib/Target/AMDGPU/VOP3Instructions.td b/llvm/lib/Target/AMDGPU/VOP3Instructions.td --- a/llvm/lib/Target/AMDGPU/VOP3Instructions.td +++ b/llvm/lib/Target/AMDGPU/VOP3Instructions.td @@ -184,47 +184,24 @@ let IsPacked = !if(Features.IsPacked, 1, P.IsPacked); let HasModifiers = !if(Features.IsMAI, 0, !or(Features.IsPacked, P.HasModifiers)); - - // FIXME: Hack to stop printing _e64 - let Outs64 = (outs DstRC.RegClass:$vdst); - let Asm64 = - " " # !if(Features.HasOpSel, - getAsmVOP3OpSel.ret, - !if(Features.HasClamp, - getAsm64.ret, - P.Asm64)); - let NeedPatGen = P.NeedPatGen; + let IsSingle = 1; } class VOP3b_Profile : VOPProfile<[vt, vt, vt, vt]> { let Outs64 = (outs DstRC:$vdst, VOPDstS64orS32:$sdst); - let Asm64 = " $vdst, $sdst, $src0_modifiers, $src1_modifiers, $src2_modifiers$clamp$omod"; -} - -def VOP3b_F32_I1_F32_F32_F32 : VOP3b_Profile { - // FIXME: Hack to stop printing _e64 - let DstRC = RegisterOperand; + let Asm64 = "$vdst, $sdst, $src0_modifiers, $src1_modifiers, $src2_modifiers$clamp$omod"; + let IsSingle = 1; } -def VOP3b_F64_I1_F64_F64_F64 : VOP3b_Profile { - // FIXME: Hack to stop printing _e64 - let DstRC = RegisterOperand; -} +def VOP3b_F32_I1_F32_F32_F32 : VOP3b_Profile; +def VOP3b_F64_I1_F64_F64_F64 : VOP3b_Profile; def VOP3b_I64_I1_I32_I32_I64 : VOPProfile<[i64, i32, i32, i64]> { let HasClamp = 1; - - // FIXME: Hack to stop printing _e64 - let DstRC = RegisterOperand; + let IsSingle = 1; let Outs64 = (outs DstRC:$vdst, VOPDstS64orS32:$sdst); - let Asm64 = " $vdst, $sdst, $src0, $src1, $src2$clamp"; + let Asm64 = "$vdst, $sdst, $src0, $src1, $src2$clamp"; } //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/AMDGPU/VOP3PInstructions.td b/llvm/lib/Target/AMDGPU/VOP3PInstructions.td --- a/llvm/lib/Target/AMDGPU/VOP3PInstructions.td +++ b/llvm/lib/Target/AMDGPU/VOP3PInstructions.td @@ -44,7 +44,7 @@ let Constraints = !if(UseTiedOutput, "$vdst = $vdst_in", ""); let DisableEncoding = !if(UseTiedOutput, "$vdst_in", ""); let AsmOperands = - " $vdst, $src0_modifiers, $src1_modifiers, $src2_modifiers$op_sel$op_sel_hi$clamp"; + "$vdst, $src0_modifiers, $src1_modifiers, $src2_modifiers$op_sel$op_sel_hi$clamp"; } let isCommutable = 1 in { @@ -377,7 +377,7 @@ let HasIntClamp = 0; let HasOMod = 0; let HasModifiers = 0; - let Asm64 = " $vdst, $src0, $src1, $src2$cbsz$abid$blgp"; + let Asm64 = "$vdst, $src0, $src1, $src2$cbsz$abid$blgp"; let Ins64 = (ins Src0RC64:$src0, Src1RC64:$src1, Src2RC64:$src2, cbsz:$cbsz, abid:$abid, blgp:$blgp); } diff --git a/llvm/lib/Target/AMDGPU/VOPInstructions.td b/llvm/lib/Target/AMDGPU/VOPInstructions.td --- a/llvm/lib/Target/AMDGPU/VOPInstructions.td +++ b/llvm/lib/Target/AMDGPU/VOPInstructions.td @@ -140,7 +140,13 @@ let VOP3P = 1; } +class VOP_Real { + Instruction Opcode = !cast(NAME); + bit IsSingle = ps.Pfl.IsSingle; +} + class VOP3_Real : + VOP_Real , InstSI , SIMCInstr { @@ -797,3 +803,17 @@ include "VOP2Instructions.td" include "VOP3Instructions.td" include "VOP3PInstructions.td" + + +class VOPInfoTable : GenericTable { + let FilterClass = Format # "_Real"; + let CppTypeName = "VOPInfo"; + let Fields = ["Opcode", "IsSingle"]; + + let PrimaryKey = ["Opcode"]; + let PrimaryKeyName = "get" # Format # "OpcodeHelper"; +} + +def VOP1InfoTable : VOPInfoTable<"VOP1">; +def VOP2InfoTable : VOPInfoTable<"VOP2">; +def VOP3InfoTable : VOPInfoTable<"VOP3">;