mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-31 17:42:40 +00:00
AMDGPU/SI: Add 64-bit versions of v_nop and v_clrexcp
Summary: The assembly printing of these is still missing the encoding size suffix, but this will be fixed in a later commit. Reviewers: arsenm Subscribers: arsenm, llvm-commits Differential Revision: http://reviews.llvm.org/D13436 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249424 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
42c0741b0d
commit
63c550368d
@ -347,6 +347,11 @@ private:
|
||||
bool ParseSectionDirectiveHSAText();
|
||||
|
||||
public:
|
||||
public:
|
||||
enum AMDGPUMatchResultTy {
|
||||
Match_PreferE32 = FIRST_TARGET_MATCH_RESULT_TY
|
||||
};
|
||||
|
||||
AMDGPUAsmParser(MCSubtargetInfo &STI, MCAsmParser &_Parser,
|
||||
const MCInstrInfo &MII,
|
||||
const MCTargetOptions &Options)
|
||||
@ -556,6 +561,11 @@ unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
|
||||
(getForcedEncodingSize() == 64 && !(TSFlags & SIInstrFlags::VOP3)))
|
||||
return Match_InvalidOperand;
|
||||
|
||||
if ((TSFlags & SIInstrFlags::VOP3) &&
|
||||
(TSFlags & SIInstrFlags::VOPAsmPrefer32Bit) &&
|
||||
getForcedEncodingSize() != 64)
|
||||
return Match_PreferE32;
|
||||
|
||||
return Match_Success;
|
||||
}
|
||||
|
||||
@ -614,6 +624,9 @@ bool AMDGPUAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
|
||||
}
|
||||
return Error(ErrorLoc, "invalid operand for instruction");
|
||||
}
|
||||
case Match_PreferE32:
|
||||
return Error(IDLoc, "internal error: instruction without _e64 suffix "
|
||||
"should be encoded as e32");
|
||||
}
|
||||
llvm_unreachable("Implement any new match types added!");
|
||||
}
|
||||
@ -1701,8 +1714,12 @@ AMDGPUAsmParser::parseVOP3OptionalOps(OperandVector &Operands) {
|
||||
}
|
||||
|
||||
void AMDGPUAsmParser::cvtVOP3(MCInst &Inst, const OperandVector &Operands) {
|
||||
((AMDGPUOperand &)*Operands[1]).addRegOperands(Inst, 1);
|
||||
unsigned i = 2;
|
||||
|
||||
unsigned i = 1;
|
||||
const MCInstrDesc &Desc = MII.get(Inst.getOpcode());
|
||||
if (Desc.getNumDefs() > 0) {
|
||||
((AMDGPUOperand &)*Operands[i++]).addRegOperands(Inst, 1);
|
||||
}
|
||||
|
||||
std::map<enum AMDGPUOperand::ImmTy, unsigned> OptionalIdx;
|
||||
|
||||
|
@ -37,7 +37,8 @@ enum {
|
||||
MIMG = 1 << 18,
|
||||
FLAT = 1 << 19,
|
||||
WQM = 1 << 20,
|
||||
VGPRSpill = 1 << 21
|
||||
VGPRSpill = 1 << 21,
|
||||
VOPAsmPrefer32Bit = 1 << 22
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,10 @@ class InstSI <dag outs, dag ins, string asm, list<dag> pattern> :
|
||||
field bits<1> WQM = 0;
|
||||
field bits<1> VGPRSpill = 0;
|
||||
|
||||
// This bit tells the assembler to use the 32-bit encoding in case it
|
||||
// is unable to infer the encoding from the operands.
|
||||
field bits<1> VOPAsmPrefer32Bit = 0;
|
||||
|
||||
// These need to be kept in sync with the enum in SIInstrFlags.
|
||||
let TSFlags{0} = VM_CNT;
|
||||
let TSFlags{1} = EXP_CNT;
|
||||
@ -68,6 +72,7 @@ class InstSI <dag outs, dag ins, string asm, list<dag> pattern> :
|
||||
let TSFlags{19} = FLAT;
|
||||
let TSFlags{20} = WQM;
|
||||
let TSFlags{21} = VGPRSpill;
|
||||
let TSFlags{22} = VOPAsmPrefer32Bit;
|
||||
|
||||
let SchedRW = [Write32Bit];
|
||||
}
|
||||
|
@ -989,11 +989,12 @@ def InputModsNoDefault : Operand <i32> {
|
||||
let ParserMatchClass = InputModsMatchClass;
|
||||
}
|
||||
|
||||
class getNumSrcArgs<ValueType Src1, ValueType Src2> {
|
||||
class getNumSrcArgs<ValueType Src0, ValueType Src1, ValueType Src2> {
|
||||
int ret =
|
||||
!if (!eq(Src1.Value, untyped.Value), 1, // VOP1
|
||||
!if (!eq(Src0.Value, untyped.Value), 0,
|
||||
!if (!eq(Src1.Value, untyped.Value), 1, // VOP1
|
||||
!if (!eq(Src2.Value, untyped.Value), 2, // VOP2
|
||||
3)); // VOP3
|
||||
3))); // VOP3
|
||||
}
|
||||
|
||||
// Returns the register class to use for the destination of VOP[123C]
|
||||
@ -1085,17 +1086,20 @@ class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC,
|
||||
// Returns the assembly string for the inputs and outputs of a VOP[12C]
|
||||
// instruction. This does not add the _e32 suffix, so it can be reused
|
||||
// by getAsm64.
|
||||
class getAsm32 <int NumSrcArgs> {
|
||||
class getAsm32 <bit HasDst, int NumSrcArgs> {
|
||||
string dst = "$dst";
|
||||
string src0 = ", $src0";
|
||||
string src1 = ", $src1";
|
||||
string src2 = ", $src2";
|
||||
string ret = "$dst, $src0"#
|
||||
!if(!eq(NumSrcArgs, 1), "", src1)#
|
||||
!if(!eq(NumSrcArgs, 3), src2, "");
|
||||
string ret = !if(HasDst, dst, "") #
|
||||
!if(!eq(NumSrcArgs, 1), src0, "") #
|
||||
!if(!eq(NumSrcArgs, 2), src0#src1, "") #
|
||||
!if(!eq(NumSrcArgs, 3), src0#src1#src2, "");
|
||||
}
|
||||
|
||||
// Returns the assembly string for the inputs and outputs of a VOP3
|
||||
// instruction.
|
||||
class getAsm64 <int NumSrcArgs, bit HasModifiers> {
|
||||
class getAsm64 <bit HasDst, int NumSrcArgs, bit HasModifiers> {
|
||||
string src0 = !if(!eq(NumSrcArgs, 1), "$src0_modifiers", "$src0_modifiers,");
|
||||
string src1 = !if(!eq(NumSrcArgs, 1), "",
|
||||
!if(!eq(NumSrcArgs, 2), " $src1_modifiers",
|
||||
@ -1103,7 +1107,7 @@ class getAsm64 <int NumSrcArgs, bit HasModifiers> {
|
||||
string src2 = !if(!eq(NumSrcArgs, 3), " $src2_modifiers", "");
|
||||
string ret =
|
||||
!if(!eq(HasModifiers, 0),
|
||||
getAsm32<NumSrcArgs>.ret,
|
||||
getAsm32<HasDst, NumSrcArgs>.ret,
|
||||
"$dst, "#src0#src1#src2#"$clamp"#"$omod");
|
||||
}
|
||||
|
||||
@ -1122,11 +1126,12 @@ class VOPProfile <list<ValueType> _ArgVT> {
|
||||
field RegisterOperand Src1RC64 = getVOP3SrcForVT<Src1VT>.ret;
|
||||
field RegisterOperand Src2RC64 = getVOP3SrcForVT<Src2VT>.ret;
|
||||
|
||||
field bit HasDst32 = !if(!eq(DstVT, untyped), 0, 1);
|
||||
field int NumSrcArgs = getNumSrcArgs<Src1VT, Src2VT>.ret;
|
||||
field bit HasDst = !if(!eq(DstVT.Value, untyped.Value), 0, 1);
|
||||
field bit HasDst32 = HasDst;
|
||||
field int NumSrcArgs = getNumSrcArgs<Src0VT, Src1VT, Src2VT>.ret;
|
||||
field bit HasModifiers = hasModifiers<Src0VT>.ret;
|
||||
|
||||
field dag Outs = (outs DstRC:$dst);
|
||||
field dag Outs = !if(HasDst,(outs DstRC:$dst),(outs));
|
||||
|
||||
// VOP3b instructions are a special case with a second explicit
|
||||
// output. This is manually overridden for them.
|
||||
@ -1137,8 +1142,8 @@ class VOPProfile <list<ValueType> _ArgVT> {
|
||||
field dag Ins64 = getIns64<Src0RC64, Src1RC64, Src2RC64, NumSrcArgs,
|
||||
HasModifiers>.ret;
|
||||
|
||||
field string Asm32 = getAsm32<NumSrcArgs>.ret;
|
||||
field string Asm64 = getAsm64<NumSrcArgs, HasModifiers>.ret;
|
||||
field string Asm32 = getAsm32<HasDst, NumSrcArgs>.ret;
|
||||
field string Asm64 = getAsm64<HasDst, NumSrcArgs, HasModifiers>.ret;
|
||||
}
|
||||
|
||||
// FIXME: I think these F16/I16 profiles will need to use f16/i16 types in order
|
||||
@ -1151,6 +1156,8 @@ def VOP_F16_F16_F16 : VOPProfile <[f16, f16, f16, untyped]>;
|
||||
def VOP_F16_F16_I16 : VOPProfile <[f16, f16, i32, untyped]>;
|
||||
def VOP_I16_I16_I16 : VOPProfile <[i32, i32, i32, untyped]>;
|
||||
|
||||
def VOP_NONE : VOPProfile <[untyped, untyped, untyped, untyped]>;
|
||||
|
||||
def VOP_F32_F32 : VOPProfile <[f32, f32, untyped, untyped]>;
|
||||
def VOP_F32_F64 : VOPProfile <[f32, f64, untyped, untyped]>;
|
||||
def VOP_F32_I32 : VOPProfile <[f32, i32, untyped, untyped]>;
|
||||
@ -1246,8 +1253,8 @@ def VOP_MAC : VOPProfile <[f32, f32, f32, f32]> {
|
||||
let Ins32 = (ins Src0RC32:$src0, Src1RC32:$src1, VGPR_32:$src2);
|
||||
let Ins64 = getIns64<Src0RC64, Src1RC64, RegisterOperand<VGPR_32>, 3,
|
||||
HasModifiers>.ret;
|
||||
let Asm32 = getAsm32<2>.ret;
|
||||
let Asm64 = getAsm64<2, HasModifiers>.ret;
|
||||
let Asm32 = getAsm32<1, 2>.ret;
|
||||
let Asm64 = getAsm64<1, 2, HasModifiers>.ret;
|
||||
}
|
||||
def VOP_F64_F64_F64_F64 : VOPProfile <[f64, f64, f64, f64]>;
|
||||
def VOP_I32_I32_I32_I32 : VOPProfile <[i32, i32, i32, i32]>;
|
||||
@ -1424,6 +1431,9 @@ class VOP3_Pseudo <dag outs, dag ins, list<dag> pattern, string opName> :
|
||||
MnemonicAlias<opName#"_e64", opName> {
|
||||
let isPseudo = 1;
|
||||
let isCodeGenOnly = 1;
|
||||
|
||||
field bit vdst;
|
||||
field bit src0;
|
||||
}
|
||||
|
||||
class VOP3_Real_si <bits<9> op, dag outs, dag ins, string asm, string opName> :
|
||||
|
@ -1156,8 +1156,8 @@ defm IMAGE_SAMPLE_C_CD_CL_O : MIMG_Sampler <0x0000006f, "image_sample_c_cd_cl_o"
|
||||
// VOP1 Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
let vdst = 0, src0 = 0 in {
|
||||
defm V_NOP : VOP1_m <vop1<0x0>, (outs), (ins), "v_nop", [], "v_nop">;
|
||||
let vdst = 0, src0 = 0, VOPAsmPrefer32Bit = 1 in {
|
||||
defm V_NOP : VOP1Inst <vop1<0x0>, "v_nop", VOP_NONE>;
|
||||
}
|
||||
|
||||
let isMoveImm = 1, isReMaterializable = 1, isAsCheapAsAMove = 1 in {
|
||||
@ -1332,10 +1332,8 @@ defm V_FREXP_EXP_I32_F32 : VOP1Inst <vop1<0x3f, 0x33>, "v_frexp_exp_i32_f32",
|
||||
defm V_FREXP_MANT_F32 : VOP1Inst <vop1<0x40, 0x34>, "v_frexp_mant_f32",
|
||||
VOP_F32_F32
|
||||
>;
|
||||
let vdst = 0, src0 = 0 in {
|
||||
defm V_CLREXCP : VOP1_m <vop1<0x41,0x35>, (outs), (ins), "v_clrexcp", [],
|
||||
"v_clrexcp"
|
||||
>;
|
||||
let vdst = 0, src0 = 0, VOPAsmPrefer32Bit = 1 in {
|
||||
defm V_CLREXCP : VOP1Inst <vop1<0x41,0x35>, "v_clrexcp", VOP_NONE>;
|
||||
}
|
||||
defm V_MOVRELD_B32 : VOP1Inst <vop1<0x42, 0x36>, "v_movreld_b32", VOP_I32_I32>;
|
||||
defm V_MOVRELS_B32 : VOP1Inst <vop1<0x43, 0x37>, "v_movrels_b32", VOP_I32_I32>;
|
||||
|
@ -8,6 +8,25 @@
|
||||
// RUN: not llvm-mc -arch=amdgcn -mcpu=bonaire -show-encoding %s 2>&1 | FileCheck %s --check-prefix=NOSICI
|
||||
// RUN: not llvm-mc -arch=amdgcn -mcpu=tonga -show-encoding %s 2>&1 | FileCheck %s -check-prefix=NOVI
|
||||
|
||||
// Force 32-bit encoding
|
||||
|
||||
// GCN: v_mov_b32_e32 v1, v2 ; encoding: [0x02,0x03,0x02,0x7e]
|
||||
v_mov_b32_e32 v1, v2
|
||||
|
||||
// Force 32-bit encoding for special instructions
|
||||
// FIXME: We should be printing _e32 suffixes for these:
|
||||
|
||||
// GCN: v_nop ; encoding: [0x00,0x00,0x00,0x7e]
|
||||
v_nop_e32
|
||||
|
||||
// SICI: v_clrexcp ; encoding: [0x00,0x82,0x00,0x7e]
|
||||
// VI: v_clrexcp ; encoding: [0x00,0x6a,0x00,0x7e]
|
||||
v_clrexcp_e32
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
// GCN: v_nop ; encoding: [0x00,0x00,0x00,0x7e]
|
||||
v_nop
|
||||
|
14
test/MC/AMDGPU/vop3-vop1-nosrc.s
Normal file
14
test/MC/AMDGPU/vop3-vop1-nosrc.s
Normal file
@ -0,0 +1,14 @@
|
||||
// RUN: llvm-mc -arch=amdgcn -mcpu=SI -show-encoding %s | FileCheck %s --check-prefix=SICI
|
||||
// RUN: llvm-mc -arch=amdgcn -mcpu=tonga -show-encoding %s | FileCheck %s --check-prefix=VI
|
||||
// XFAIL: *
|
||||
|
||||
// FIXME: We should be printing _e64 suffixes for these.
|
||||
// FIXME: When this is fixed delete this file and fix test case in vop3.s
|
||||
|
||||
v_nop_e64
|
||||
// SICI: v_nop_e64 ; encoding: [0x00,0x00,0x00,0xd3,0x00,0x00,0x00,0x00]
|
||||
// VI: v_nop_e64 ; encoding: [0x00,0x00,0x40,0xd1,0x00,0x00,0x00,0x00]
|
||||
|
||||
v_clrexcp_e64
|
||||
// SICI: v_clrexcp_e64 ; encoding: [0x00,0x00,0x82,0xd3,0x00,0x00,0x00,0x00]
|
||||
// VI: v_clrexcp_e64 ; encoding: [0x00,0x00,0x75,0xd1,0x00,0x00,0x00,0x00]
|
@ -118,6 +118,23 @@ v_cmp_f_i64 s[2:3], v[4:5], v[6:7]
|
||||
// VOP1 Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Test forced e64 encoding with e32 operands
|
||||
|
||||
v_mov_b32_e64 v1, v2
|
||||
// SICI: v_mov_b32_e64 v1, v2 ; encoding: [0x01,0x00,0x02,0xd3,0x02,0x01,0x00,0x00]
|
||||
// VI: v_mov_b32_e64 v1, v2 ; encoding: [0x01,0x00,0x41,0xd1,0x02,0x01,0x00,0x00]
|
||||
|
||||
// Force e64 encoding for special instructions.
|
||||
// FIXME, we should be printing the _e64 suffix for v_nop and v_clrexcp.
|
||||
|
||||
v_nop_e64
|
||||
// SICI: v_nop ; encoding: [0x00,0x00,0x00,0xd3,0x00,0x00,0x00,0x00]
|
||||
// VI: v_nop ; encoding: [0x00,0x00,0x40,0xd1,0x00,0x00,0x00,0x00]
|
||||
|
||||
v_clrexcp_e64
|
||||
// SICI: v_clrexcp ; encoding: [0x00,0x00,0x82,0xd3,0x00,0x00,0x00,0x00]
|
||||
// VI: v_clrexcp ; encoding: [0x00,0x00,0x75,0xd1,0x00,0x00,0x00,0x00]
|
||||
|
||||
//
|
||||
// Modifier tests:
|
||||
//
|
||||
|
Loading…
x
Reference in New Issue
Block a user