mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 11:13:28 +01:00
AMDGPU: Assembler support for vintrp instructions
llvm-svn: 289866
This commit is contained in:
parent
765604b11b
commit
496e9bc65d
@ -155,6 +155,9 @@ public:
|
||||
ImmTyHwreg,
|
||||
ImmTyOff,
|
||||
ImmTySendMsg,
|
||||
ImmTyInterpSlot,
|
||||
ImmTyInterpAttr,
|
||||
ImmTyAttrChan
|
||||
};
|
||||
|
||||
struct TokOp {
|
||||
@ -279,6 +282,9 @@ public:
|
||||
bool isSDWASrc0Sel() const { return isImmTy(ImmTySdwaSrc0Sel); }
|
||||
bool isSDWASrc1Sel() const { return isImmTy(ImmTySdwaSrc1Sel); }
|
||||
bool isSDWADstUnused() const { return isImmTy(ImmTySdwaDstUnused); }
|
||||
bool isInterpSlot() const { return isImmTy(ImmTyInterpSlot); }
|
||||
bool isInterpAttr() const { return isImmTy(ImmTyInterpAttr); }
|
||||
bool isAttrChan() const { return isImmTy(ImmTyAttrChan); }
|
||||
|
||||
bool isMod() const {
|
||||
return isClampSI() || isOModSI();
|
||||
@ -568,6 +574,9 @@ public:
|
||||
case ImmTyExpVM: OS << "ExpVM"; break;
|
||||
case ImmTyHwreg: OS << "Hwreg"; break;
|
||||
case ImmTySendMsg: OS << "SendMsg"; break;
|
||||
case ImmTyInterpSlot: OS << "InterpSlot"; break;
|
||||
case ImmTyInterpAttr: OS << "InterpAttr"; break;
|
||||
case ImmTyAttrChan: OS << "AttrChan"; break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -823,6 +832,8 @@ public:
|
||||
|
||||
OperandMatchResultTy parseExpTgt(OperandVector &Operands);
|
||||
OperandMatchResultTy parseSendMsgOp(OperandVector &Operands);
|
||||
OperandMatchResultTy parseInterpSlot(OperandVector &Operands);
|
||||
OperandMatchResultTy parseInterpAttr(OperandVector &Operands);
|
||||
OperandMatchResultTy parseSOppBrTarget(OperandVector &Operands);
|
||||
|
||||
void cvtMubuf(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, false, false); }
|
||||
@ -2487,6 +2498,67 @@ bool AMDGPUAsmParser::parseSendMsgConstruct(OperandInfoTy &Msg, OperandInfoTy &O
|
||||
return false;
|
||||
}
|
||||
|
||||
OperandMatchResultTy AMDGPUAsmParser::parseInterpSlot(OperandVector &Operands) {
|
||||
if (getLexer().getKind() != AsmToken::Identifier)
|
||||
return MatchOperand_NoMatch;
|
||||
|
||||
StringRef Str = Parser.getTok().getString();
|
||||
int Slot = StringSwitch<int>(Str)
|
||||
.Case("p10", 0)
|
||||
.Case("p20", 1)
|
||||
.Case("p0", 2)
|
||||
.Default(-1);
|
||||
|
||||
SMLoc S = Parser.getTok().getLoc();
|
||||
if (Slot == -1)
|
||||
return MatchOperand_ParseFail;
|
||||
|
||||
Parser.Lex();
|
||||
Operands.push_back(AMDGPUOperand::CreateImm(this, Slot, S,
|
||||
AMDGPUOperand::ImmTyInterpSlot));
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
OperandMatchResultTy AMDGPUAsmParser::parseInterpAttr(OperandVector &Operands) {
|
||||
if (getLexer().getKind() != AsmToken::Identifier)
|
||||
return MatchOperand_NoMatch;
|
||||
|
||||
StringRef Str = Parser.getTok().getString();
|
||||
if (!Str.startswith("attr"))
|
||||
return MatchOperand_NoMatch;
|
||||
|
||||
StringRef Chan = Str.take_back(2);
|
||||
int AttrChan = StringSwitch<int>(Chan)
|
||||
.Case(".x", 0)
|
||||
.Case(".y", 1)
|
||||
.Case(".z", 2)
|
||||
.Case(".w", 3)
|
||||
.Default(-1);
|
||||
if (AttrChan == -1)
|
||||
return MatchOperand_ParseFail;
|
||||
|
||||
Str = Str.drop_back(2).drop_front(4);
|
||||
|
||||
uint8_t Attr;
|
||||
if (Str.getAsInteger(10, Attr))
|
||||
return MatchOperand_ParseFail;
|
||||
|
||||
SMLoc S = Parser.getTok().getLoc();
|
||||
Parser.Lex();
|
||||
if (Attr > 63) {
|
||||
Error(S, "out of bounds attr");
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
SMLoc SChan = SMLoc::getFromPointer(Chan.data());
|
||||
|
||||
Operands.push_back(AMDGPUOperand::CreateImm(this, Attr, S,
|
||||
AMDGPUOperand::ImmTyInterpAttr));
|
||||
Operands.push_back(AMDGPUOperand::CreateImm(this, AttrChan, SChan,
|
||||
AMDGPUOperand::ImmTyAttrChan));
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
void AMDGPUAsmParser::errorExpTgt() {
|
||||
Error(Parser.getTok().getLoc(), "invalid exp target");
|
||||
}
|
||||
@ -3423,6 +3495,12 @@ unsigned AMDGPUAsmParser::validateTargetOperandClass(MCParsedAsmOperand &Op,
|
||||
return Operand.isSoppBrTarget() ? Match_Success : Match_InvalidOperand;
|
||||
case MCK_VReg32OrOff:
|
||||
return Operand.isVReg32OrOff() ? Match_Success : Match_InvalidOperand;
|
||||
case MCK_InterpSlot:
|
||||
return Operand.isInterpSlot() ? Match_Success : Match_InvalidOperand;
|
||||
case MCK_Attr:
|
||||
return Operand.isInterpAttr() ? Match_Success : Match_InvalidOperand;
|
||||
case MCK_AttrChan:
|
||||
return Operand.isAttrChan() ? Match_Success : Match_InvalidOperand;
|
||||
default:
|
||||
return Match_InvalidOperand;
|
||||
}
|
||||
|
@ -304,19 +304,43 @@ def sopp_brtarget : Operand<OtherVT> {
|
||||
|
||||
def si_ga : Operand<iPTR>;
|
||||
|
||||
def InterpSlotMatchClass : AsmOperandClass {
|
||||
let Name = "InterpSlot";
|
||||
let PredicateMethod = "isInterpSlot";
|
||||
let ParserMethod = "parseInterpSlot";
|
||||
let RenderMethod = "addImmOperands";
|
||||
}
|
||||
|
||||
def InterpSlot : Operand<i32> {
|
||||
let PrintMethod = "printInterpSlot";
|
||||
let ParserMatchClass = InterpSlotMatchClass;
|
||||
let OperandType = "OPERAND_IMMEDIATE";
|
||||
}
|
||||
|
||||
def AttrMatchClass : AsmOperandClass {
|
||||
let Name = "Attr";
|
||||
let PredicateMethod = "isInterpAttr";
|
||||
let ParserMethod = "parseInterpAttr";
|
||||
let RenderMethod = "addImmOperands";
|
||||
}
|
||||
|
||||
// It appears to be necessary to create a separate operand for this to
|
||||
// be able to parse attr<num> with no space.
|
||||
def Attr : Operand<i32> {
|
||||
let PrintMethod = "printInterpAttr";
|
||||
let ParserMatchClass = AttrMatchClass;
|
||||
let OperandType = "OPERAND_IMMEDIATE";
|
||||
}
|
||||
|
||||
def AttrChanMatchClass : AsmOperandClass {
|
||||
let Name = "AttrChan";
|
||||
let PredicateMethod = "isAttrChan";
|
||||
let RenderMethod = "addImmOperands";
|
||||
}
|
||||
|
||||
def AttrChan : Operand<i32> {
|
||||
let PrintMethod = "printInterpAttrChan";
|
||||
let ParserMatchClass = AttrChanMatchClass;
|
||||
let OperandType = "OPERAND_IMMEDIATE";
|
||||
}
|
||||
|
||||
|
@ -51,8 +51,8 @@ let Uses = [M0, EXEC] in {
|
||||
multiclass V_INTERP_P1_F32_m : VINTRP_m <
|
||||
0x00000000,
|
||||
(outs VGPR_32:$vdst),
|
||||
(ins VGPR_32:$vsrc, i32imm:$attr, AttrChan:$attrchan),
|
||||
"v_interp_p1_f32 $vdst, $vsrc, attr${attr}$attrchan",
|
||||
(ins VGPR_32:$vsrc, Attr:$attr, AttrChan:$attrchan),
|
||||
"v_interp_p1_f32 $vdst, $vsrc, $attr$attrchan",
|
||||
[(set f32:$vdst, (AMDGPUinterp_p1 f32:$vsrc, (i32 imm:$attrchan),
|
||||
(i32 imm:$attr)))]
|
||||
>;
|
||||
@ -74,8 +74,8 @@ let DisableEncoding = "$src0", Constraints = "$src0 = $vdst" in {
|
||||
defm V_INTERP_P2_F32 : VINTRP_m <
|
||||
0x00000001,
|
||||
(outs VGPR_32:$vdst),
|
||||
(ins VGPR_32:$src0, VGPR_32:$vsrc, i32imm:$attr, AttrChan:$attrchan),
|
||||
"v_interp_p2_f32 $vdst, $vsrc, attr${attr}$attrchan",
|
||||
(ins VGPR_32:$src0, VGPR_32:$vsrc, Attr:$attr, AttrChan:$attrchan),
|
||||
"v_interp_p2_f32 $vdst, $vsrc, $attr$attrchan",
|
||||
[(set f32:$vdst, (AMDGPUinterp_p2 f32:$src0, f32:$vsrc, (i32 imm:$attrchan),
|
||||
(i32 imm:$attr)))]>;
|
||||
|
||||
@ -84,8 +84,8 @@ defm V_INTERP_P2_F32 : VINTRP_m <
|
||||
defm V_INTERP_MOV_F32 : VINTRP_m <
|
||||
0x00000002,
|
||||
(outs VGPR_32:$vdst),
|
||||
(ins InterpSlot:$vsrc, i32imm:$attr, AttrChan:$attrchan),
|
||||
"v_interp_mov_f32 $vdst, $vsrc, attr${attr}$attrchan",
|
||||
(ins InterpSlot:$vsrc, Attr:$attr, AttrChan:$attrchan),
|
||||
"v_interp_mov_f32 $vdst, $vsrc, $attr$attrchan",
|
||||
[(set f32:$vdst, (AMDGPUinterp_mov (i32 imm:$vsrc), (i32 imm:$attrchan),
|
||||
(i32 imm:$attr)))]>;
|
||||
|
||||
|
45
test/MC/AMDGPU/vintrp-err.s
Normal file
45
test/MC/AMDGPU/vintrp-err.s
Normal file
@ -0,0 +1,45 @@
|
||||
// RUN: not llvm-mc -arch=amdgcn -show-encoding %s 2>&1 | FileCheck -check-prefix=GCN -check-prefix=SI %s
|
||||
// RUN: not llvm-mc -arch=amdgcn -mcpu=tonga -show-encoding %s 2>&1 | FileCheck -check-prefix=GCN -check-prefix=VI %s
|
||||
|
||||
v_interp_p1_f32 v0, v1, attr64.w
|
||||
// GCN: :25: error: out of bounds attr
|
||||
|
||||
v_interp_p1_f32 v0, v1, attr64.x
|
||||
// GCN: :25: error: out of bounds attr
|
||||
|
||||
v_interp_p2_f32 v9, v1, attr64.x
|
||||
// GCN: :25: error: out of bounds attr
|
||||
|
||||
v_interp_p2_f32 v0, v1, attr64.x
|
||||
// GCN: :25: error: out of bounds attr
|
||||
|
||||
v_interp_p2_f32 v0, v1, attr0.q
|
||||
// GCN: :25: error: failed parsing operand.
|
||||
|
||||
v_interp_p2_f32 v0, v1, attr0.
|
||||
// GCN: :25: error: failed parsing operand.
|
||||
|
||||
v_interp_p2_f32 v0, v1, attr
|
||||
// GCN: :25: error: failed parsing operand.
|
||||
|
||||
// XXX - Why does this one parse?
|
||||
v_interp_p2_f32 v0, v1, att
|
||||
// GCN: :25: error: invalid operand for instruction
|
||||
|
||||
v_interp_p2_f32 v0, v1, attrq
|
||||
// GCN: :25: error: failed parsing operand.
|
||||
|
||||
v_interp_mov_f32 v11, invalid_param_3, attr0.y
|
||||
// GCN: :23: error: failed parsing operand.
|
||||
|
||||
v_interp_mov_f32 v12, invalid_param_10, attr0.x
|
||||
// GCN: :23: error: failed parsing operand.
|
||||
|
||||
v_interp_mov_f32 v3, invalid_param_3, attr0.x
|
||||
// GCN: :22: error: failed parsing operand.
|
||||
|
||||
v_interp_mov_f32 v8, invalid_param_8, attr0.x
|
||||
// GCN: :22: error: failed parsing operand.
|
||||
|
||||
v_interp_mov_f32 v8, foo, attr0.x
|
||||
// GCN: :22: error: failed parsing operand.
|
105
test/MC/AMDGPU/vintrp.s
Normal file
105
test/MC/AMDGPU/vintrp.s
Normal file
@ -0,0 +1,105 @@
|
||||
// RUN: llvm-mc -arch=amdgcn -show-encoding %s | FileCheck -check-prefix=GCN -check-prefix=SI %s
|
||||
// RUN: llvm-mc -arch=amdgcn -mcpu=tonga -show-encoding %s | FileCheck -check-prefix=GCN -check-prefix=VI %s
|
||||
|
||||
v_interp_p1_f32 v1, v0, attr0.x
|
||||
// SI: v_interp_p1_f32 v1, v0, attr0.x ; encoding: [0x00,0x00,0x04,0xc8]
|
||||
// VI: v_interp_p1_f32 v1, v0, attr0.x ; encoding: [0x00,0x00,0x04,0xd4]
|
||||
|
||||
v_interp_p1_f32 v2, v0, attr0.y
|
||||
// SI: v_interp_p1_f32 v2, v0, attr0.y ; encoding: [0x00,0x01,0x08,0xc8]
|
||||
// VI: v_interp_p1_f32 v2, v0, attr0.y ; encoding: [0x00,0x01,0x08,0xd4]
|
||||
|
||||
v_interp_p1_f32 v3, v0, attr0.z
|
||||
// SI: v_interp_p1_f32 v3, v0, attr0.z ; encoding: [0x00,0x02,0x0c,0xc8]
|
||||
// VI: v_interp_p1_f32 v3, v0, attr0.z ; encoding: [0x00,0x02,0x0c,0xd4]
|
||||
|
||||
v_interp_p1_f32 v4, v0, attr0.w
|
||||
// SI: v_interp_p1_f32 v4, v0, attr0.w ; encoding: [0x00,0x03,0x10,0xc8]
|
||||
// VI: v_interp_p1_f32 v4, v0, attr0.w ; encoding: [0x00,0x03,0x10,0xd4]
|
||||
|
||||
v_interp_p1_f32 v5, v0, attr0.x
|
||||
// SI: v_interp_p1_f32 v5, v0, attr0.x ; encoding: [0x00,0x00,0x14,0xc8]
|
||||
// VI: v_interp_p1_f32 v5, v0, attr0.x ; encoding: [0x00,0x00,0x14,0xd4]
|
||||
|
||||
v_interp_p1_f32 v6, v0, attr1.x
|
||||
// SI: v_interp_p1_f32 v6, v0, attr1.x ; encoding: [0x00,0x04,0x18,0xc8]
|
||||
// VI: v_interp_p1_f32 v6, v0, attr1.x ; encoding: [0x00,0x04,0x18,0xd4]
|
||||
|
||||
v_interp_p1_f32 v7, v0, attr2.y
|
||||
// SI: v_interp_p1_f32 v7, v0, attr2.y ; encoding: [0x00,0x09,0x1c,0xc8]
|
||||
// VI: v_interp_p1_f32 v7, v0, attr2.y ; encoding: [0x00,0x09,0x1c,0xd4]
|
||||
|
||||
v_interp_p1_f32 v8, v0, attr3.z
|
||||
// SI: v_interp_p1_f32 v8, v0, attr3.z ; encoding: [0x00,0x0e,0x20,0xc8]
|
||||
// VI: v_interp_p1_f32 v8, v0, attr3.z ; encoding: [0x00,0x0e,0x20,0xd4]
|
||||
|
||||
v_interp_p1_f32 v9, v0, attr4.w
|
||||
// SI: v_interp_p1_f32 v9, v0, attr4.w ; encoding: [0x00,0x13,0x24,0xc8]
|
||||
// VI: v_interp_p1_f32 v9, v0, attr4.w ; encoding: [0x00,0x13,0x24,0xd4]
|
||||
|
||||
v_interp_p1_f32 v10, v0, attr63.w
|
||||
// SI: v_interp_p1_f32 v10, v0, attr63.w ; encoding: [0x00,0xff,0x28,0xc8]
|
||||
// VI: v_interp_p1_f32 v10, v0, attr63.w ; encoding: [0x00,0xff,0x28,0xd4]
|
||||
|
||||
|
||||
v_interp_p2_f32 v2, v1, attr0.x
|
||||
// SI: v_interp_p2_f32 v2, v1, attr0.x ; encoding: [0x01,0x00,0x09,0xc8]
|
||||
// VI: v_interp_p2_f32 v2, v1, attr0.x ; encoding: [0x01,0x00,0x09,0xd4]
|
||||
|
||||
v_interp_p2_f32 v3, v1, attr0.y
|
||||
// SI: v_interp_p2_f32 v3, v1, attr0.y ; encoding: [0x01,0x01,0x0d,0xc8]
|
||||
// VI: v_interp_p2_f32 v3, v1, attr0.y ; encoding: [0x01,0x01,0x0d,0xd4]
|
||||
|
||||
v_interp_p2_f32 v4, v1, attr0.z
|
||||
// SI: v_interp_p2_f32 v4, v1, attr0.z ; encoding: [0x01,0x02,0x11,0xc8]
|
||||
// VI: v_interp_p2_f32 v4, v1, attr0.z ; encoding: [0x01,0x02,0x11,0xd4]
|
||||
|
||||
v_interp_p2_f32 v5, v1, attr0.w
|
||||
// SI: v_interp_p2_f32 v5, v1, attr0.w ; encoding: [0x01,0x03,0x15,0xc8]
|
||||
// VI: v_interp_p2_f32 v5, v1, attr0.w ; encoding: [0x01,0x03,0x15,0xd4]
|
||||
|
||||
v_interp_p2_f32 v6, v1, attr0.x
|
||||
// SI: v_interp_p2_f32 v6, v1, attr0.x ; encoding: [0x01,0x00,0x19,0xc8]
|
||||
// VI: v_interp_p2_f32 v6, v1, attr0.x ; encoding: [0x01,0x00,0x19,0xd4]
|
||||
|
||||
v_interp_p2_f32 v7, v1, attr1.x
|
||||
// SI: v_interp_p2_f32 v7, v1, attr1.x ; encoding: [0x01,0x04,0x1d,0xc8]
|
||||
// VI: v_interp_p2_f32 v7, v1, attr1.x ; encoding: [0x01,0x04,0x1d,0xd4]
|
||||
|
||||
v_interp_p2_f32 v8, v1, attr63.x
|
||||
// SI: v_interp_p2_f32 v8, v1, attr63.x ; encoding: [0x01,0xfc,0x21,0xc8]
|
||||
// VI: v_interp_p2_f32 v8, v1, attr63.x ; encoding: [0x01,0xfc,0x21,0xd4]
|
||||
|
||||
|
||||
v_interp_mov_f32 v0, p10, attr0.x
|
||||
// SI: v_interp_mov_f32 v0, p10, attr0.x ; encoding: [0x00,0x00,0x02,0xc8]
|
||||
// VI: v_interp_mov_f32 v0, p10, attr0.x ; encoding: [0x00,0x00,0x02,0xd4]
|
||||
|
||||
v_interp_mov_f32 v1, p20, attr0.x
|
||||
// SI: v_interp_mov_f32 v1, p20, attr0.x ; encoding: [0x01,0x00,0x06,0xc8]
|
||||
// VI: v_interp_mov_f32 v1, p20, attr0.x ; encoding: [0x01,0x00,0x06,0xd4]
|
||||
|
||||
v_interp_mov_f32 v2, p0, attr0.x
|
||||
// SI: v_interp_mov_f32 v2, p0, attr0.x ; encoding: [0x02,0x00,0x0a,0xc8]
|
||||
// VI: v_interp_mov_f32 v2, p0, attr0.x ; encoding: [0x02,0x00,0x0a,0xd4]
|
||||
|
||||
v_interp_mov_f32 v4, p10, attr0.y
|
||||
// SI: v_interp_mov_f32 v4, p10, attr0.y ; encoding: [0x00,0x01,0x12,0xc8]
|
||||
// VI: v_interp_mov_f32 v4, p10, attr0.y ; encoding: [0x00,0x01,0x12,0xd4]
|
||||
|
||||
v_interp_mov_f32 v5, p10, attr0.z
|
||||
// SI: v_interp_mov_f32 v5, p10, attr0.z ; encoding: [0x00,0x02,0x16,0xc8]
|
||||
// VI: v_interp_mov_f32 v5, p10, attr0.z ; encoding: [0x00,0x02,0x16,0xd4]
|
||||
|
||||
v_interp_mov_f32 v6, p10, attr0.w
|
||||
// SI: v_interp_mov_f32 v6, p10, attr0.w ; encoding: [0x00,0x03,0x1a,0xc8]
|
||||
// VI: v_interp_mov_f32 v6, p10, attr0.w ; encoding: [0x00,0x03,0x1a,0xd4]
|
||||
|
||||
v_interp_mov_f32 v7, p10, attr0.x
|
||||
// SI: v_interp_mov_f32 v7, p10, attr0.x ; encoding: [0x00,0x00,0x1e,0xc8]
|
||||
// VI: v_interp_mov_f32 v7, p10, attr0.x ; encoding: [0x00,0x00,0x1e,0xd4]
|
||||
|
||||
v_interp_mov_f32 v9, p10, attr63.y
|
||||
// SI: v_interp_mov_f32 v9, p10, attr63.y ; encoding: [0x00,0xfd,0x26,0xc8]
|
||||
// VI: v_interp_mov_f32 v9, p10, attr63.y ; encoding: [0x00,0xfd,0x26,0xd4]
|
||||
|
Loading…
Reference in New Issue
Block a user