ImmTyHwreg,
ImmTyOff,
ImmTySendMsg,
+ ImmTyInterpSlot,
+ ImmTyInterpAttr,
+ ImmTyAttrChan
};
struct TokOp {
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();
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;
}
}
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); }
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");
}
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;
}
--- /dev/null
+// 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.
--- /dev/null
+// 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]
+