mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-12-11 05:24:16 +00:00
[AMDGPU] AsmParser: Support for sext() modifier in SDWA. Some code cleaning in AMDGPUOperand.
Summary: sext() modifier is supported in SDWA instructions only for integer operands. Spec is unclear should integer operands support abs and neg modifiers with sext - for now they are not supported. Renamed InputModsWithNoDefault to FloatInputMods. Added SextInputMods for operands that support sext() modifier. Added AMDGPUOperand::Modifier struct to handle register and immediate modifiers. Code cleaning in AMDGPUOperand class: organize method in groups (render-, predicate-methods...). Reviewers: vpykhtin, artem.tamazov, tstellarAMD Subscribers: arsenm, kzhuravl Differential Revision: http://reviews.llvm.org/D20968 llvm-svn: 272384
This commit is contained in:
parent
9a6ac0909a
commit
4f6d8a41f5
@ -64,6 +64,43 @@ public:
|
||||
|
||||
typedef std::unique_ptr<AMDGPUOperand> Ptr;
|
||||
|
||||
struct Modifiers {
|
||||
bool Abs;
|
||||
bool Neg;
|
||||
bool Sext;
|
||||
|
||||
bool hasFPModifiers() const { return Abs || Neg; }
|
||||
bool hasIntModifiers() const { return Sext; }
|
||||
bool hasModifiers() const { return hasFPModifiers() || hasIntModifiers(); }
|
||||
|
||||
int64_t getFPModifiersOperand() const {
|
||||
int64_t Operand = 0;
|
||||
Operand |= Abs ? SISrcMods::ABS : 0;
|
||||
Operand |= Neg ? SISrcMods::NEG : 0;
|
||||
return Operand;
|
||||
}
|
||||
|
||||
int64_t getIntModifiersOperand() const {
|
||||
int64_t Operand = 0;
|
||||
Operand |= Sext ? SISrcMods::SEXT : 0;
|
||||
return Operand;
|
||||
}
|
||||
|
||||
int64_t getModifiersOperand() const {
|
||||
assert(!(hasFPModifiers() && hasIntModifiers())
|
||||
&& "fp and int modifiers should not be used simultaneously");
|
||||
if (hasFPModifiers()) {
|
||||
return getFPModifiersOperand();
|
||||
} else if (hasIntModifiers()) {
|
||||
return getIntModifiersOperand();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
friend raw_ostream &operator <<(raw_ostream &OS, AMDGPUOperand::Modifiers Mods);
|
||||
};
|
||||
|
||||
enum ImmTy {
|
||||
ImmTyNone,
|
||||
ImmTyGDS,
|
||||
@ -104,12 +141,12 @@ public:
|
||||
bool IsFPImm;
|
||||
ImmTy Type;
|
||||
int64_t Val;
|
||||
int Modifiers;
|
||||
Modifiers Mods;
|
||||
};
|
||||
|
||||
struct RegOp {
|
||||
unsigned RegNo;
|
||||
int Modifiers;
|
||||
Modifiers Mods;
|
||||
const MCRegisterInfo *TRI;
|
||||
const MCSubtargetInfo *STI;
|
||||
bool IsForcedVOP3;
|
||||
@ -122,65 +159,6 @@ public:
|
||||
const MCExpr *Expr;
|
||||
};
|
||||
|
||||
void addImmOperands(MCInst &Inst, unsigned N, bool ApplyModifiers = true) const {
|
||||
if (Imm.Type == ImmTyNone && ApplyModifiers && Imm.Modifiers != 0) {
|
||||
// Apply modifiers to immediate value
|
||||
int64_t Val = Imm.Val;
|
||||
bool Negate = Imm.Modifiers & 0x1;
|
||||
bool Abs = Imm.Modifiers & 0x2;
|
||||
if (Imm.IsFPImm) {
|
||||
APFloat F(BitsToFloat(Val));
|
||||
if (Abs) {
|
||||
F.clearSign();
|
||||
}
|
||||
if (Negate) {
|
||||
F.changeSign();
|
||||
}
|
||||
Val = F.bitcastToAPInt().getZExtValue();
|
||||
} else {
|
||||
Val = Abs ? std::abs(Val) : Val;
|
||||
Val = Negate ? -Val : Val;
|
||||
}
|
||||
Inst.addOperand(MCOperand::createImm(Val));
|
||||
} else {
|
||||
Inst.addOperand(MCOperand::createImm(getImm()));
|
||||
}
|
||||
}
|
||||
|
||||
StringRef getToken() const {
|
||||
return StringRef(Tok.Data, Tok.Length);
|
||||
}
|
||||
|
||||
void addRegOperands(MCInst &Inst, unsigned N) const {
|
||||
Inst.addOperand(MCOperand::createReg(AMDGPU::getMCReg(getReg(), *Reg.STI)));
|
||||
}
|
||||
|
||||
void addRegOrImmOperands(MCInst &Inst, unsigned N) const {
|
||||
if (isRegKind())
|
||||
addRegOperands(Inst, N);
|
||||
else
|
||||
addImmOperands(Inst, N);
|
||||
}
|
||||
|
||||
void addRegOrImmWithInputModsOperands(MCInst &Inst, unsigned N) const {
|
||||
if (isRegKind()) {
|
||||
Inst.addOperand(MCOperand::createImm(Reg.Modifiers));
|
||||
addRegOperands(Inst, N);
|
||||
} else {
|
||||
Inst.addOperand(MCOperand::createImm(Imm.Modifiers));
|
||||
addImmOperands(Inst, N, false);
|
||||
}
|
||||
}
|
||||
|
||||
void addSoppBrTargetOperands(MCInst &Inst, unsigned N) const {
|
||||
if (isImm())
|
||||
addImmOperands(Inst, N);
|
||||
else {
|
||||
assert(isExpr());
|
||||
Inst.addOperand(MCOperand::createExpr(Expr));
|
||||
}
|
||||
}
|
||||
|
||||
bool isToken() const override {
|
||||
return Kind == Token;
|
||||
}
|
||||
@ -190,9 +168,10 @@ public:
|
||||
}
|
||||
|
||||
bool isInlinableImm() const {
|
||||
if (!isImm() || Imm.Type != AMDGPUOperand::ImmTyNone /* Only plain
|
||||
immediates are inlinable (e.g. "clamp" attribute is not) */ )
|
||||
if (!isImmTy(ImmTyNone)) {
|
||||
// Only plain immediates are inlinable (e.g. "clamp" attribute is not)
|
||||
return false;
|
||||
}
|
||||
// TODO: We should avoid using host float here. It would be better to
|
||||
// check the float bit values which is what a few other places do.
|
||||
// We've had bot failures before due to weird NaN support on mips hosts.
|
||||
@ -203,56 +182,33 @@ public:
|
||||
F == 2.0 || F == -2.0 || F == 4.0 || F == -4.0);
|
||||
}
|
||||
|
||||
int64_t getImm() const {
|
||||
return Imm.Val;
|
||||
}
|
||||
|
||||
enum ImmTy getImmTy() const {
|
||||
assert(isImm());
|
||||
return Imm.Type;
|
||||
}
|
||||
|
||||
bool isRegKind() const {
|
||||
return Kind == Register;
|
||||
}
|
||||
|
||||
bool isReg() const override {
|
||||
return Kind == Register && Reg.Modifiers == 0;
|
||||
return isRegKind() && !Reg.Mods.hasModifiers();
|
||||
}
|
||||
|
||||
bool isRegOrImmWithInputMods() const {
|
||||
return Kind == Register || isInlinableImm();
|
||||
return isRegKind() || isInlinableImm();
|
||||
}
|
||||
|
||||
bool isImmTy(ImmTy ImmT) const {
|
||||
return isImm() && Imm.Type == ImmT;
|
||||
}
|
||||
|
||||
bool isClampSI() const {
|
||||
return isImmTy(ImmTyClampSI);
|
||||
}
|
||||
|
||||
bool isOModSI() const {
|
||||
return isImmTy(ImmTyOModSI);
|
||||
}
|
||||
|
||||
|
||||
bool isImmModifier() const {
|
||||
return Kind == Immediate && Imm.Type != ImmTyNone;
|
||||
return isImm() && Imm.Type != ImmTyNone;
|
||||
}
|
||||
|
||||
bool isDMask() const {
|
||||
return isImmTy(ImmTyDMask);
|
||||
}
|
||||
|
||||
|
||||
bool isClampSI() const { return isImmTy(ImmTyClampSI); }
|
||||
bool isOModSI() const { return isImmTy(ImmTyOModSI); }
|
||||
bool isDMask() const { return isImmTy(ImmTyDMask); }
|
||||
bool isUNorm() const { return isImmTy(ImmTyUNorm); }
|
||||
bool isDA() const { return isImmTy(ImmTyDA); }
|
||||
bool isR128() const { return isImmTy(ImmTyUNorm); }
|
||||
bool isLWE() const { return isImmTy(ImmTyLWE); }
|
||||
|
||||
bool isMod() const {
|
||||
return isClampSI() || isOModSI();
|
||||
}
|
||||
|
||||
bool isOffen() const { return isImmTy(ImmTyOffen); }
|
||||
bool isIdxen() const { return isImmTy(ImmTyIdxen); }
|
||||
bool isAddr64() const { return isImmTy(ImmTyAddr64); }
|
||||
@ -263,50 +219,16 @@ public:
|
||||
bool isGLC() const { return isImmTy(ImmTyGLC); }
|
||||
bool isSLC() const { return isImmTy(ImmTySLC); }
|
||||
bool isTFE() const { return isImmTy(ImmTyTFE); }
|
||||
|
||||
bool isBankMask() const {
|
||||
return isImmTy(ImmTyDppBankMask);
|
||||
}
|
||||
|
||||
bool isRowMask() const {
|
||||
return isImmTy(ImmTyDppRowMask);
|
||||
}
|
||||
|
||||
bool isBoundCtrl() const {
|
||||
return isImmTy(ImmTyDppBoundCtrl);
|
||||
}
|
||||
|
||||
bool isSDWADstSel() const {
|
||||
return isImmTy(ImmTySdwaDstSel);
|
||||
}
|
||||
|
||||
bool isSDWASrc0Sel() const {
|
||||
return isImmTy(ImmTySdwaSrc0Sel);
|
||||
}
|
||||
|
||||
bool isSDWASrc1Sel() const {
|
||||
return isImmTy(ImmTySdwaSrc1Sel);
|
||||
}
|
||||
|
||||
bool isSDWADstUnused() const {
|
||||
return isImmTy(ImmTySdwaDstUnused);
|
||||
}
|
||||
|
||||
void setModifiers(unsigned Mods) {
|
||||
assert(isReg() || (isImm() && Imm.Modifiers == 0));
|
||||
if (isReg())
|
||||
Reg.Modifiers = Mods;
|
||||
else
|
||||
Imm.Modifiers = Mods;
|
||||
}
|
||||
|
||||
bool hasModifiers() const {
|
||||
assert(isRegKind() || isImm());
|
||||
return isRegKind() ? Reg.Modifiers != 0 : Imm.Modifiers != 0;
|
||||
}
|
||||
|
||||
unsigned getReg() const override {
|
||||
return Reg.RegNo;
|
||||
bool isBankMask() const { return isImmTy(ImmTyDppBankMask); }
|
||||
bool isRowMask() const { return isImmTy(ImmTyDppRowMask); }
|
||||
bool isBoundCtrl() const { return isImmTy(ImmTyDppBoundCtrl); }
|
||||
bool isSDWADstSel() const { return isImmTy(ImmTySdwaDstSel); }
|
||||
bool isSDWASrc0Sel() const { return isImmTy(ImmTySdwaSrc0Sel); }
|
||||
bool isSDWASrc1Sel() const { return isImmTy(ImmTySdwaSrc1Sel); }
|
||||
bool isSDWADstUnused() const { return isImmTy(ImmTySdwaDstUnused); }
|
||||
|
||||
bool isMod() const {
|
||||
return isClampSI() || isOModSI();
|
||||
}
|
||||
|
||||
bool isRegOrImm() const {
|
||||
@ -368,6 +290,32 @@ public:
|
||||
return isExpr() || isImm();
|
||||
}
|
||||
|
||||
bool isSWaitCnt() const;
|
||||
bool isHwreg() const;
|
||||
bool isSendMsg() const;
|
||||
bool isMubufOffset() const;
|
||||
bool isSMRDOffset() const;
|
||||
bool isSMRDLiteralOffset() const;
|
||||
bool isDPPCtrl() const;
|
||||
|
||||
StringRef getToken() const {
|
||||
return StringRef(Tok.Data, Tok.Length);
|
||||
}
|
||||
|
||||
int64_t getImm() const {
|
||||
assert(isImm());
|
||||
return Imm.Val;
|
||||
}
|
||||
|
||||
enum ImmTy getImmTy() const {
|
||||
assert(isImm());
|
||||
return Imm.Type;
|
||||
}
|
||||
|
||||
unsigned getReg() const override {
|
||||
return Reg.RegNo;
|
||||
}
|
||||
|
||||
SMLoc getStartLoc() const override {
|
||||
return StartLoc;
|
||||
}
|
||||
@ -376,6 +324,91 @@ public:
|
||||
return EndLoc;
|
||||
}
|
||||
|
||||
Modifiers getModifiers() const {
|
||||
assert(isRegKind() || isImmTy(ImmTyNone));
|
||||
return isRegKind() ? Reg.Mods : Imm.Mods;
|
||||
}
|
||||
|
||||
void setModifiers(Modifiers Mods) {
|
||||
assert(isRegKind() || isImmTy(ImmTyNone));
|
||||
if (isRegKind())
|
||||
Reg.Mods = Mods;
|
||||
else
|
||||
Imm.Mods = Mods;
|
||||
}
|
||||
|
||||
bool hasModifiers() const {
|
||||
return getModifiers().hasModifiers();
|
||||
}
|
||||
|
||||
bool hasFPModifiers() const {
|
||||
return getModifiers().hasFPModifiers();
|
||||
}
|
||||
|
||||
bool hasIntModifiers() const {
|
||||
return getModifiers().hasIntModifiers();
|
||||
}
|
||||
|
||||
void addImmOperands(MCInst &Inst, unsigned N, bool ApplyModifiers = true) const {
|
||||
if (isImmTy(ImmTyNone) && ApplyModifiers && Imm.Mods.hasFPModifiers()) {
|
||||
// Apply modifiers to immediate value
|
||||
int64_t Val = Imm.Val;
|
||||
bool Negate = Imm.Mods.Neg; // Only negate can get here
|
||||
if (Imm.IsFPImm) {
|
||||
APFloat F(BitsToFloat(Val));
|
||||
if (Negate) {
|
||||
F.changeSign();
|
||||
}
|
||||
Val = F.bitcastToAPInt().getZExtValue();
|
||||
} else {
|
||||
Val = Negate ? -Val : Val;
|
||||
}
|
||||
Inst.addOperand(MCOperand::createImm(Val));
|
||||
} else {
|
||||
Inst.addOperand(MCOperand::createImm(getImm()));
|
||||
}
|
||||
}
|
||||
|
||||
void addRegOperands(MCInst &Inst, unsigned N) const {
|
||||
Inst.addOperand(MCOperand::createReg(AMDGPU::getMCReg(getReg(), *Reg.STI)));
|
||||
}
|
||||
|
||||
void addRegOrImmOperands(MCInst &Inst, unsigned N) const {
|
||||
if (isRegKind())
|
||||
addRegOperands(Inst, N);
|
||||
else
|
||||
addImmOperands(Inst, N);
|
||||
}
|
||||
|
||||
void addRegOrImmWithInputModsOperands(MCInst &Inst, unsigned N) const {
|
||||
Modifiers Mods = getModifiers();
|
||||
Inst.addOperand(MCOperand::createImm(Mods.getModifiersOperand()));
|
||||
if (isRegKind()) {
|
||||
addRegOperands(Inst, N);
|
||||
} else {
|
||||
addImmOperands(Inst, N, false);
|
||||
}
|
||||
}
|
||||
|
||||
void addRegOrImmWithFPInputModsOperands(MCInst &Inst, unsigned N) const {
|
||||
assert(!hasIntModifiers());
|
||||
addRegOrImmWithInputModsOperands(Inst, N);
|
||||
}
|
||||
|
||||
void addRegOrImmWithIntInputModsOperands(MCInst &Inst, unsigned N) const {
|
||||
assert(!hasFPModifiers());
|
||||
addRegOrImmWithInputModsOperands(Inst, N);
|
||||
}
|
||||
|
||||
void addSoppBrTargetOperands(MCInst &Inst, unsigned N) const {
|
||||
if (isImm())
|
||||
addImmOperands(Inst, N);
|
||||
else {
|
||||
assert(isExpr());
|
||||
Inst.addOperand(MCOperand::createExpr(Expr));
|
||||
}
|
||||
}
|
||||
|
||||
void printImmTy(raw_ostream& OS, ImmTy Type) const {
|
||||
switch (Type) {
|
||||
case ImmTyNone: OS << "None"; break;
|
||||
@ -412,14 +445,14 @@ public:
|
||||
void print(raw_ostream &OS) const override {
|
||||
switch (Kind) {
|
||||
case Register:
|
||||
OS << "<register " << getReg() << " mods: " << Reg.Modifiers << '>';
|
||||
OS << "<register " << getReg() << " mods: " << Reg.Mods << '>';
|
||||
break;
|
||||
case Immediate:
|
||||
OS << '<' << getImm();
|
||||
if (getImmTy() != ImmTyNone) {
|
||||
OS << " type: "; printImmTy(OS, getImmTy());
|
||||
}
|
||||
OS << " mods: " << Imm.Modifiers << '>';
|
||||
OS << " mods: " << Imm.Mods << '>';
|
||||
break;
|
||||
case Token:
|
||||
OS << '\'' << getToken() << '\'';
|
||||
@ -437,7 +470,7 @@ public:
|
||||
Op->Imm.Val = Val;
|
||||
Op->Imm.IsFPImm = IsFPImm;
|
||||
Op->Imm.Type = Type;
|
||||
Op->Imm.Modifiers = 0;
|
||||
Op->Imm.Mods = {false, false, false};
|
||||
Op->StartLoc = Loc;
|
||||
Op->EndLoc = Loc;
|
||||
return Op;
|
||||
@ -462,7 +495,7 @@ public:
|
||||
Op->Reg.RegNo = RegNo;
|
||||
Op->Reg.TRI = TRI;
|
||||
Op->Reg.STI = STI;
|
||||
Op->Reg.Modifiers = 0;
|
||||
Op->Reg.Mods = {false, false, false};
|
||||
Op->Reg.IsForcedVOP3 = ForceVOP3;
|
||||
Op->StartLoc = S;
|
||||
Op->EndLoc = E;
|
||||
@ -476,16 +509,13 @@ public:
|
||||
Op->EndLoc = S;
|
||||
return Op;
|
||||
}
|
||||
|
||||
bool isSWaitCnt() const;
|
||||
bool isHwreg() const;
|
||||
bool isSendMsg() const;
|
||||
bool isMubufOffset() const;
|
||||
bool isSMRDOffset() const;
|
||||
bool isSMRDLiteralOffset() const;
|
||||
bool isDPPCtrl() const;
|
||||
};
|
||||
|
||||
raw_ostream &operator <<(raw_ostream &OS, AMDGPUOperand::Modifiers Mods) {
|
||||
OS << "abs:" << Mods.Abs << " neg: " << Mods.Neg << " sext:" << Mods.Sext;
|
||||
return OS;
|
||||
}
|
||||
|
||||
class AMDGPUAsmParser : public MCTargetAsmParser {
|
||||
const MCInstrInfo &MII;
|
||||
MCAsmParser &Parser;
|
||||
@ -598,7 +628,8 @@ public:
|
||||
|
||||
OperandMatchResultTy parseImm(OperandVector &Operands);
|
||||
OperandMatchResultTy parseRegOrImm(OperandVector &Operands);
|
||||
OperandMatchResultTy parseRegOrImmWithInputMods(OperandVector &Operands);
|
||||
OperandMatchResultTy parseRegOrImmWithFPInputMods(OperandVector &Operands);
|
||||
OperandMatchResultTy parseRegOrImmWithIntInputMods(OperandVector &Operands);
|
||||
|
||||
void cvtDSOffset01(MCInst &Inst, const OperandVector &Operands);
|
||||
void cvtDS(MCInst &Inst, const OperandVector &Operands);
|
||||
@ -665,12 +696,9 @@ public:
|
||||
AMDGPUOperand::Ptr defaultSDWASrc0Sel() const;
|
||||
AMDGPUOperand::Ptr defaultSDWASrc1Sel() const;
|
||||
AMDGPUOperand::Ptr defaultSDWADstUnused() const;
|
||||
void cvtSdwaVop1_mod(MCInst &Inst, const OperandVector &Operands);
|
||||
void cvtSdwaVop1_nomod(MCInst &Inst, const OperandVector &Operands);
|
||||
void cvtSdwaVop2_mod(MCInst &Inst, const OperandVector &Operands);
|
||||
void cvtSdwaVop2_nomod(MCInst &Inst, const OperandVector &Operands);
|
||||
void cvtSDWA(MCInst &Inst, const OperandVector &Operands, bool HasMods,
|
||||
bool IsVOP1);
|
||||
void cvtSdwaVOP1(MCInst &Inst, const OperandVector &Operands);
|
||||
void cvtSdwaVOP2(MCInst &Inst, const OperandVector &Operands);
|
||||
void cvtSDWA(MCInst &Inst, const OperandVector &Operands, bool IsVOP1);
|
||||
};
|
||||
|
||||
struct OptionalOperand {
|
||||
@ -969,7 +997,7 @@ AMDGPUAsmParser::parseRegOrImm(OperandVector &Operands) {
|
||||
}
|
||||
|
||||
AMDGPUAsmParser::OperandMatchResultTy
|
||||
AMDGPUAsmParser::parseRegOrImmWithInputMods(OperandVector &Operands) {
|
||||
AMDGPUAsmParser::parseRegOrImmWithFPInputMods(OperandVector &Operands) {
|
||||
// XXX: During parsing we can't determine if minus sign means
|
||||
// negate-modifier or negative immediate value.
|
||||
// By default we suppose it is modifier.
|
||||
@ -1004,9 +1032,9 @@ AMDGPUAsmParser::parseRegOrImmWithInputMods(OperandVector &Operands) {
|
||||
return Res;
|
||||
}
|
||||
|
||||
unsigned Modifiers = 0;
|
||||
AMDGPUOperand::Modifiers Mods = {false, false, false};
|
||||
if (Negate) {
|
||||
Modifiers |= 0x1;
|
||||
Mods.Neg = true;
|
||||
}
|
||||
if (Abs) {
|
||||
if (getLexer().getKind() != AsmToken::Pipe) {
|
||||
@ -1014,7 +1042,7 @@ AMDGPUAsmParser::parseRegOrImmWithInputMods(OperandVector &Operands) {
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
Parser.Lex();
|
||||
Modifiers |= 0x2;
|
||||
Mods.Abs = true;
|
||||
}
|
||||
if (Abs2) {
|
||||
if (getLexer().isNot(AsmToken::RParen)) {
|
||||
@ -1022,16 +1050,56 @@ AMDGPUAsmParser::parseRegOrImmWithInputMods(OperandVector &Operands) {
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
Parser.Lex();
|
||||
Modifiers |= 0x2;
|
||||
Mods.Abs = true;
|
||||
}
|
||||
|
||||
if (Modifiers) {
|
||||
if (Mods.hasFPModifiers()) {
|
||||
AMDGPUOperand &Op = static_cast<AMDGPUOperand &>(*Operands.back());
|
||||
Op.setModifiers(Modifiers);
|
||||
Op.setModifiers(Mods);
|
||||
}
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
AMDGPUAsmParser::OperandMatchResultTy
|
||||
AMDGPUAsmParser::parseRegOrImmWithIntInputMods(OperandVector &Operands) {
|
||||
bool Sext = false;
|
||||
|
||||
if (getLexer().getKind() == AsmToken::Identifier && Parser.getTok().getString() == "sext") {
|
||||
Parser.Lex();
|
||||
Sext = true;
|
||||
if (getLexer().isNot(AsmToken::LParen)) {
|
||||
Error(Parser.getTok().getLoc(), "expected left paren after sext");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
Parser.Lex();
|
||||
}
|
||||
|
||||
auto Res = parseRegOrImm(Operands);
|
||||
if (Res != MatchOperand_Success) {
|
||||
return Res;
|
||||
}
|
||||
|
||||
AMDGPUOperand &Op = static_cast<AMDGPUOperand &>(*Operands.back());
|
||||
if (Op.isImm() && Op.Imm.IsFPImm) {
|
||||
Error(Parser.getTok().getLoc(), "floating point operands not allowed with sext() modifier");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
|
||||
AMDGPUOperand::Modifiers Mods = {false, false, false};
|
||||
if (Sext) {
|
||||
if (getLexer().isNot(AsmToken::RParen)) {
|
||||
Error(Parser.getTok().getLoc(), "expected closing parentheses");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
Parser.Lex();
|
||||
Mods.Sext = true;
|
||||
}
|
||||
|
||||
if (Mods.hasIntModifiers()) {
|
||||
Op.setModifiers(Mods);
|
||||
}
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
unsigned AMDGPUAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
|
||||
|
||||
@ -2338,7 +2406,8 @@ void AMDGPUAsmParser::cvtVOP3(MCInst &Inst, const OperandVector &Operands) {
|
||||
for (unsigned E = Operands.size(); I != E; ++I) {
|
||||
AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
|
||||
if (Op.isRegOrImmWithInputMods()) {
|
||||
Op.addRegOrImmWithInputModsOperands(Inst, 2);
|
||||
// only fp modifiers allowed in VOP3
|
||||
Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
|
||||
} else if (Op.isImm()) {
|
||||
OptionalIdx[Op.getImmTy()] = I;
|
||||
} else {
|
||||
@ -2511,8 +2580,8 @@ void AMDGPUAsmParser::cvtDPP(MCInst &Inst, const OperandVector &Operands) {
|
||||
AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
|
||||
// Add the register arguments
|
||||
if (Op.isRegOrImmWithInputMods()) {
|
||||
// We convert only instructions with modifiers
|
||||
Op.addRegOrImmWithInputModsOperands(Inst, 2);
|
||||
// Only float modifiers supported in DPP
|
||||
Op.addRegOrImmWithFPInputModsOperands(Inst, 2);
|
||||
} else if (Op.isDPPCtrl()) {
|
||||
Op.addImmOperands(Inst, 1);
|
||||
} else if (Op.isImm()) {
|
||||
@ -2612,24 +2681,16 @@ AMDGPUOperand::Ptr AMDGPUAsmParser::defaultSDWADstUnused() const {
|
||||
return AMDGPUOperand::CreateImm(0, SMLoc(), AMDGPUOperand::ImmTySdwaDstUnused);
|
||||
}
|
||||
|
||||
void AMDGPUAsmParser::cvtSdwaVop1_mod(MCInst &Inst, const OperandVector &Operands) {
|
||||
cvtSDWA(Inst, Operands, true, true);
|
||||
void AMDGPUAsmParser::cvtSdwaVOP1(MCInst &Inst, const OperandVector &Operands) {
|
||||
cvtSDWA(Inst, Operands, true);
|
||||
}
|
||||
|
||||
void AMDGPUAsmParser::cvtSdwaVop1_nomod(MCInst &Inst, const OperandVector &Operands) {
|
||||
cvtSDWA(Inst, Operands, false, true);
|
||||
}
|
||||
|
||||
void AMDGPUAsmParser::cvtSdwaVop2_mod(MCInst &Inst, const OperandVector &Operands) {
|
||||
cvtSDWA(Inst, Operands, true, false);
|
||||
}
|
||||
|
||||
void AMDGPUAsmParser::cvtSdwaVop2_nomod(MCInst &Inst, const OperandVector &Operands) {
|
||||
cvtSDWA(Inst, Operands, false, false);
|
||||
void AMDGPUAsmParser::cvtSdwaVOP2(MCInst &Inst, const OperandVector &Operands) {
|
||||
cvtSDWA(Inst, Operands, false);
|
||||
}
|
||||
|
||||
void AMDGPUAsmParser::cvtSDWA(MCInst &Inst, const OperandVector &Operands,
|
||||
bool HasMods, bool IsVOP1) {
|
||||
bool IsVOP1) {
|
||||
OptionalImmIndexMap OptionalIdx;
|
||||
|
||||
unsigned I = 1;
|
||||
@ -2641,10 +2702,8 @@ void AMDGPUAsmParser::cvtSDWA(MCInst &Inst, const OperandVector &Operands,
|
||||
for (unsigned E = Operands.size(); I != E; ++I) {
|
||||
AMDGPUOperand &Op = ((AMDGPUOperand &)*Operands[I]);
|
||||
// Add the register arguments
|
||||
if (!HasMods && Op.isReg()) {
|
||||
Op.addRegOperands(Inst, 1);
|
||||
} else if (HasMods && Op.isRegOrImmWithInputMods()) {
|
||||
Op.addRegOrImmWithInputModsOperands(Inst, 2);
|
||||
if (Op.isRegOrImmWithInputMods()) {
|
||||
Op.addRegOrImmWithInputModsOperands(Inst, 2);
|
||||
} else if (Op.isImm()) {
|
||||
// Handle optional arguments
|
||||
OptionalIdx[Op.getImmTy()] = I;
|
||||
@ -2653,9 +2712,8 @@ void AMDGPUAsmParser::cvtSDWA(MCInst &Inst, const OperandVector &Operands,
|
||||
}
|
||||
}
|
||||
|
||||
if (HasMods) {
|
||||
addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyClampSI, 0);
|
||||
}
|
||||
addOptionalImmOperand(Inst, Operands, OptionalIdx, AMDGPUOperand::ImmTyClampSI, 0);
|
||||
|
||||
if (Inst.getOpcode() == AMDGPU::V_NOP_sdwa) {
|
||||
// V_NOP_sdwa has no optional sdwa arguments
|
||||
return;
|
||||
|
@ -423,8 +423,9 @@ void AMDGPUInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
|
||||
}
|
||||
}
|
||||
|
||||
void AMDGPUInstPrinter::printOperandAndMods(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) {
|
||||
void AMDGPUInstPrinter::printOperandAndFPInputMods(const MCInst *MI,
|
||||
unsigned OpNo,
|
||||
raw_ostream &O) {
|
||||
unsigned InputModifiers = MI->getOperand(OpNo).getImm();
|
||||
if (InputModifiers & SISrcMods::NEG)
|
||||
O << '-';
|
||||
@ -435,6 +436,17 @@ void AMDGPUInstPrinter::printOperandAndMods(const MCInst *MI, unsigned OpNo,
|
||||
O << '|';
|
||||
}
|
||||
|
||||
void AMDGPUInstPrinter::printOperandAndIntInputMods(const MCInst *MI,
|
||||
unsigned OpNo,
|
||||
raw_ostream &O) {
|
||||
unsigned InputModifiers = MI->getOperand(OpNo).getImm();
|
||||
if (InputModifiers & SISrcMods::SEXT)
|
||||
O << "sext(";
|
||||
printOperand(MI, OpNo + 1, O);
|
||||
if (InputModifiers & SISrcMods::SEXT)
|
||||
O << ')';
|
||||
}
|
||||
|
||||
|
||||
void AMDGPUInstPrinter::printDPPCtrl(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) {
|
||||
|
@ -64,7 +64,8 @@ private:
|
||||
void printImmediate32(uint32_t I, raw_ostream &O);
|
||||
void printImmediate64(uint64_t I, raw_ostream &O);
|
||||
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printOperandAndMods(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printOperandAndFPInputMods(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printOperandAndIntInputMods(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printDPPCtrl(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printRowMask(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printBankMask(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
|
@ -79,10 +79,13 @@ namespace SIInstrFlags {
|
||||
};
|
||||
}
|
||||
|
||||
// Input operand modifiers bit-masks
|
||||
// NEG and SEXT share same bit-mask because they can't be set simultaneously.
|
||||
namespace SISrcMods {
|
||||
enum {
|
||||
NEG = 1 << 0,
|
||||
ABS = 1 << 1
|
||||
NEG = 1 << 0, // Floating-point negate modifier
|
||||
ABS = 1 << 1, // Floating-point absolute modifier
|
||||
SEXT = 1 << 0 // Integer sign-extend modifier
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -560,6 +560,28 @@ def hwreg : NamedOperandU16<"Hwreg", NamedMatchClass<"Hwreg", 0>>;
|
||||
|
||||
def VOPDstS64 : VOPDstOperand <SReg_64>;
|
||||
|
||||
def FPInputModsMatchClass : AsmOperandClass {
|
||||
let Name = "RegOrImmWithFPInputMods";
|
||||
let ParserMethod = "parseRegOrImmWithFPInputMods";
|
||||
let PredicateMethod = "isRegOrImmWithInputMods";
|
||||
}
|
||||
|
||||
def FPInputMods : Operand <i32> {
|
||||
let PrintMethod = "printOperandAndFPInputMods";
|
||||
let ParserMatchClass = FPInputModsMatchClass;
|
||||
}
|
||||
|
||||
def IntInputModsMatchClass : AsmOperandClass {
|
||||
let Name = "RegOrImmWithIntInputMods";
|
||||
let ParserMethod = "parseRegOrImmWithIntInputMods";
|
||||
let PredicateMethod = "isRegOrImmWithInputMods";
|
||||
}
|
||||
|
||||
def IntInputMods: Operand <i32> {
|
||||
let PrintMethod = "printOperandAndIntInputMods";
|
||||
let ParserMatchClass = IntInputModsMatchClass;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Complex patterns
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -1093,21 +1115,6 @@ multiclass SMRD_Helper <smrd op, string opName, RegisterClass baseClass,
|
||||
// Vector ALU classes
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// This must always be right before the operand being input modified.
|
||||
def InputMods : OperandWithDefaultOps <i32, (ops (i32 0))> {
|
||||
let PrintMethod = "printOperandAndMods";
|
||||
}
|
||||
|
||||
def InputModsMatchClass : AsmOperandClass {
|
||||
let Name = "RegOrImmWithInputMods";
|
||||
let ParserMethod = "parseRegOrImmWithInputMods";
|
||||
}
|
||||
|
||||
def InputModsNoDefault : Operand <i32> {
|
||||
let PrintMethod = "printOperandAndMods";
|
||||
let ParserMatchClass = InputModsMatchClass;
|
||||
}
|
||||
|
||||
class getNumSrcArgs<ValueType Src0, ValueType Src1, ValueType Src2> {
|
||||
int ret =
|
||||
!if (!eq(Src0.Value, untyped.Value), 0,
|
||||
@ -1179,7 +1186,7 @@ class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC,
|
||||
!if (!eq(NumSrcArgs, 1),
|
||||
!if (!eq(HasModifiers, 1),
|
||||
// VOP1 with modifiers
|
||||
(ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
|
||||
(ins FPInputMods:$src0_modifiers, Src0RC:$src0,
|
||||
clampmod:$clamp, omod:$omod)
|
||||
/* else */,
|
||||
// VOP1 without modifiers
|
||||
@ -1188,8 +1195,8 @@ class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC,
|
||||
!if (!eq(NumSrcArgs, 2),
|
||||
!if (!eq(HasModifiers, 1),
|
||||
// VOP 2 with modifiers
|
||||
(ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
|
||||
InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
|
||||
(ins FPInputMods:$src0_modifiers, Src0RC:$src0,
|
||||
FPInputMods:$src1_modifiers, Src1RC:$src1,
|
||||
clampmod:$clamp, omod:$omod)
|
||||
/* else */,
|
||||
// VOP2 without modifiers
|
||||
@ -1198,9 +1205,9 @@ class getIns64 <RegisterOperand Src0RC, RegisterOperand Src1RC,
|
||||
/* NumSrcArgs == 3 */,
|
||||
!if (!eq(HasModifiers, 1),
|
||||
// VOP3 with modifiers
|
||||
(ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
|
||||
InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
|
||||
InputModsNoDefault:$src2_modifiers, Src2RC:$src2,
|
||||
(ins FPInputMods:$src0_modifiers, Src0RC:$src0,
|
||||
FPInputMods:$src1_modifiers, Src1RC:$src1,
|
||||
FPInputMods:$src2_modifiers, Src2RC:$src2,
|
||||
clampmod:$clamp, omod:$omod)
|
||||
/* else */,
|
||||
// VOP3 without modifiers
|
||||
@ -1218,7 +1225,7 @@ class getInsDPP <RegisterClass Src0RC, RegisterClass Src1RC, int NumSrcArgs,
|
||||
!if (!eq(NumSrcArgs, 1),
|
||||
!if (!eq(HasModifiers, 1),
|
||||
// VOP1_DPP with modifiers
|
||||
(ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
|
||||
(ins FPInputMods:$src0_modifiers, Src0RC:$src0,
|
||||
dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
|
||||
bank_mask:$bank_mask, bound_ctrl:$bound_ctrl)
|
||||
/* else */,
|
||||
@ -1229,10 +1236,10 @@ class getInsDPP <RegisterClass Src0RC, RegisterClass Src1RC, int NumSrcArgs,
|
||||
/* NumSrcArgs == 2 */,
|
||||
!if (!eq(HasModifiers, 1),
|
||||
// VOP2_DPP with modifiers
|
||||
(ins InputModsNoDefault:$src0_modifiers, Src0RC:$src0,
|
||||
InputModsNoDefault:$src1_modifiers, Src1RC:$src1,
|
||||
dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
|
||||
bank_mask:$bank_mask, bound_ctrl:$bound_ctrl)
|
||||
(ins FPInputMods:$src0_modifiers, Src0RC:$src0,
|
||||
FPInputMods:$src1_modifiers, Src1RC:$src1,
|
||||
dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
|
||||
bank_mask:$bank_mask, bound_ctrl:$bound_ctrl)
|
||||
/* else */,
|
||||
// VOP2_DPP without modifiers
|
||||
(ins Src0RC:$src0, Src1RC:$src1, dpp_ctrl:$dpp_ctrl,
|
||||
@ -1242,34 +1249,35 @@ class getInsDPP <RegisterClass Src0RC, RegisterClass Src1RC, int NumSrcArgs,
|
||||
}
|
||||
|
||||
class getInsSDWA <RegisterClass Src0RC, RegisterClass Src1RC, int NumSrcArgs,
|
||||
bit HasModifiers> {
|
||||
bit HasFloatModifiers> {
|
||||
|
||||
dag ret = !if (!eq(NumSrcArgs, 0),
|
||||
// VOP1 without input operands (V_NOP)
|
||||
(ins),
|
||||
!if (!eq(NumSrcArgs, 1),
|
||||
!if (!eq(HasModifiers, 1),
|
||||
// VOP1_SDWA with modifiers
|
||||
(ins InputModsNoDefault:$src0_fmodifiers, Src0RC:$src0,
|
||||
!if (HasFloatModifiers,
|
||||
// VOP1_SDWA with float modifiers
|
||||
(ins FPInputMods:$src0_fmodifiers, Src0RC:$src0,
|
||||
clampmod:$clamp, dst_sel:$dst_sel, dst_unused:$dst_unused,
|
||||
src0_sel:$src0_sel)
|
||||
/* else */,
|
||||
// VOP1_SDWA without modifiers
|
||||
// FIXME: sext() modifier is not supported yet
|
||||
(ins Src0RC:$src0, dst_sel:$dst_sel, dst_unused:$dst_unused,
|
||||
// VOP1_SDWA with sext modifier
|
||||
(ins IntInputMods:$src0_imodifiers, Src0RC:$src0,
|
||||
clampmod:$clamp, dst_sel:$dst_sel, dst_unused:$dst_unused,
|
||||
src0_sel:$src0_sel)
|
||||
/* endif */)
|
||||
/* NumSrcArgs == 2 */,
|
||||
!if (!eq(HasModifiers, 1),
|
||||
// VOP2_SDWA with modifiers
|
||||
(ins InputModsNoDefault:$src0_fmodifiers, Src0RC:$src0,
|
||||
InputModsNoDefault:$src1_fmodifiers, Src1RC:$src1,
|
||||
!if (HasFloatModifiers,
|
||||
// VOP2_SDWA with float modifiers
|
||||
(ins FPInputMods:$src0_fmodifiers, Src0RC:$src0,
|
||||
FPInputMods:$src1_fmodifiers, Src1RC:$src1,
|
||||
clampmod:$clamp, dst_sel:$dst_sel, dst_unused:$dst_unused,
|
||||
src0_sel:$src0_sel, src1_sel:$src1_sel)
|
||||
/* else */,
|
||||
// VOP2_DPP without modifiers
|
||||
(ins Src0RC:$src0, Src1RC:$src1,
|
||||
dst_sel:$dst_sel, dst_unused:$dst_unused,
|
||||
// VOP2_DPP with sext modifier
|
||||
(ins IntInputMods:$src0_imodifiers, Src0RC:$src0,
|
||||
IntInputMods:$src1_imodifiers, Src1RC:$src1,
|
||||
clampmod:$clamp, dst_sel:$dst_sel, dst_unused:$dst_unused,
|
||||
src0_sel:$src0_sel, src1_sel:$src1_sel)
|
||||
/* endif */)));
|
||||
}
|
||||
@ -1328,19 +1336,22 @@ class getAsmDPP <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT =
|
||||
string ret = dst#args#" $dpp_ctrl$row_mask$bank_mask$bound_ctrl";
|
||||
}
|
||||
|
||||
class getAsmSDWA <bit HasDst, int NumSrcArgs, bit HasModifiers, ValueType DstVT = i32> {
|
||||
string dst = !if(HasDst,
|
||||
class getAsmSDWA <bit HasDst, int NumSrcArgs, bit HasFloatModifiers,
|
||||
ValueType DstVT = i32> {
|
||||
string dst = !if(HasDst,
|
||||
!if(!eq(DstVT.Size, 1),
|
||||
"$sdst",
|
||||
"$sdst", // use $sdst for VOPC
|
||||
"$vdst"),
|
||||
""); // use $sdst for VOPC
|
||||
string src0 = !if(!eq(NumSrcArgs, 1), "$src0_fmodifiers", "$src0_fmodifiers,");
|
||||
string src1 = !if(!eq(NumSrcArgs, 1), "",
|
||||
!if(!eq(NumSrcArgs, 2), " $src1_fmodifiers",
|
||||
" $src1_fmodifiers,"));
|
||||
string args = !if(!eq(HasModifiers, 0),
|
||||
getAsm32<0, NumSrcArgs, DstVT>.ret,
|
||||
", "#src0#src1#"$clamp");
|
||||
"");
|
||||
string src0 = !if(HasFloatModifiers, "$src0_fmodifiers", "$src0_imodifiers");
|
||||
string src1 = !if(HasFloatModifiers, "$src1_fmodifiers", "$src1_imodifiers");
|
||||
string args = !if(!eq(NumSrcArgs, 0),
|
||||
"",
|
||||
!if(!eq(NumSrcArgs, 1),
|
||||
", "#src0#"$clamp",
|
||||
", "#src0#", "#src1#"$clamp"
|
||||
)
|
||||
);
|
||||
string sdwa = !if(!eq(NumSrcArgs, 0),
|
||||
"",
|
||||
!if(!eq(NumSrcArgs, 1),
|
||||
@ -1518,7 +1529,7 @@ class VOPC_Profile<ValueType vt0, ValueType vt1 = vt0> : VOPProfile <[i1, vt0, v
|
||||
}
|
||||
|
||||
class VOPC_Class_Profile<ValueType vt> : VOPC_Profile<vt, i32> {
|
||||
let Ins64 = (ins InputModsNoDefault:$src0_modifiers, Src0RC64:$src0, Src1RC64:$src1);
|
||||
let Ins64 = (ins FPInputMods:$src0_modifiers, Src0RC64:$src0, Src1RC64:$src1);
|
||||
let Asm64 = "$sdst, $src0_modifiers, $src1";
|
||||
}
|
||||
|
||||
@ -1549,13 +1560,13 @@ 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 InsDPP = (ins InputModsNoDefault:$src0_modifiers, Src0RC32:$src0,
|
||||
InputModsNoDefault:$src1_modifiers, Src1RC32:$src1,
|
||||
let InsDPP = (ins FPInputMods:$src0_modifiers, Src0RC32:$src0,
|
||||
FPInputMods:$src1_modifiers, Src1RC32:$src1,
|
||||
VGPR_32:$src2, // stub argument
|
||||
dpp_ctrl:$dpp_ctrl, row_mask:$row_mask,
|
||||
bank_mask:$bank_mask, bound_ctrl:$bound_ctrl);
|
||||
let InsSDWA = (ins InputModsNoDefault:$src0_fmodifiers, Src0RC32:$src0,
|
||||
InputModsNoDefault:$src1_fmodifiers, Src1RC32:$src1,
|
||||
let InsSDWA = (ins FPInputMods:$src0_fmodifiers, Src0RC32:$src0,
|
||||
FPInputMods:$src1_fmodifiers, Src1RC32:$src1,
|
||||
VGPR_32:$src2, // stub argument
|
||||
clampmod:$clamp, dst_sel:$dst_sel, dst_unused:$dst_unused,
|
||||
src0_sel:$src0_sel, src1_sel:$src1_sel);
|
||||
@ -1682,25 +1693,31 @@ class VOP1_DPP <vop1 op, string opName, VOPProfile p> :
|
||||
class SDWADisableFields <VOPProfile p> {
|
||||
bits<8> src0 = !if(!eq(p.NumSrcArgs, 0), 0, ?);
|
||||
bits<3> src0_sel = !if(!eq(p.NumSrcArgs, 0), 6, ?);
|
||||
bits<2> src0_fmodifiers = !if(p.HasModifiers, ?, 0);
|
||||
bits<1> src0_imodifiers = 0; // FIXME: always 0 untill sext modifier is supported
|
||||
bits<2> src0_fmodifiers = !if(!eq(p.NumSrcArgs, 0),
|
||||
0,
|
||||
!if(p.HasModifiers, ?, 0));
|
||||
bits<1> src0_imodifiers = !if(!eq(p.NumSrcArgs, 0),
|
||||
0,
|
||||
!if(p.HasModifiers, 0, ?));
|
||||
bits<3> src1_sel = !if(!eq(p.NumSrcArgs, 0), 6,
|
||||
!if(!eq(p.NumSrcArgs, 1), 6,
|
||||
?));
|
||||
bits<2> src1_fmodifiers = !if(!eq(p.NumSrcArgs, 0), 0,
|
||||
!if(!eq(p.NumSrcArgs, 1), 0,
|
||||
!if(p.HasModifiers, ?, 0)));
|
||||
bits<1> src1_imodifiers = 0;
|
||||
bits<1> src1_imodifiers = !if(!eq(p.NumSrcArgs, 0), 0,
|
||||
!if(!eq(p.NumSrcArgs, 1), 0,
|
||||
!if(p.HasModifiers, 0, ?)));
|
||||
bits<3> dst_sel = !if(p.HasDst, ?, 6);
|
||||
bits<2> dst_unused = !if(p.HasDst, ?, 2);
|
||||
bits<1> clamp = !if(p.HasModifiers, ?, 0);
|
||||
bits<1> clamp = !if(!eq(p.NumSrcArgs, 0), 0, ?);
|
||||
}
|
||||
|
||||
class VOP1_SDWA <vop1 op, string opName, VOPProfile p> :
|
||||
VOP1_SDWAe <op.VI>,
|
||||
VOP_SDWA <p.OutsSDWA, p.InsSDWA, opName#p.AsmSDWA, [], p.HasModifiers>,
|
||||
SDWADisableFields <p> {
|
||||
let AsmMatchConverter = !if(!eq(p.HasModifiers,1), "cvtSdwaVop1_mod", "cvtSdwaVop1_nomod");
|
||||
let AsmMatchConverter = "cvtSdwaVOP1";
|
||||
let AssemblerPredicates = !if(p.HasExt, [isVI], [DisableInst]);
|
||||
let DecoderNamespace = "SDWA";
|
||||
let DisableDecoder = DisableVIDecoder;
|
||||
@ -1774,7 +1791,7 @@ class VOP2_SDWA <vop2 op, string opName, VOPProfile p> :
|
||||
VOP2_SDWAe <op.VI>,
|
||||
VOP_SDWA <p.OutsSDWA, p.InsSDWA, opName#p.AsmSDWA, [], p.HasModifiers>,
|
||||
SDWADisableFields <p> {
|
||||
let AsmMatchConverter = !if(!eq(p.HasModifiers,1), "cvtSdwaVop2_mod", "cvtSdwaVop2_nomod");
|
||||
let AsmMatchConverter = "cvtSdwaVOP2";
|
||||
let AssemblerPredicates = !if(p.HasExt, [isVI], [DisableInst]);
|
||||
let DecoderNamespace = "SDWA";
|
||||
let DisableDecoder = DisableVIDecoder;
|
||||
@ -2397,9 +2414,9 @@ multiclass VOP3_VCC_Inst <vop3 op, string opName,
|
||||
SDPatternOperator node = null_frag> : VOP3_Helper <
|
||||
op, opName,
|
||||
(outs P.DstRC.RegClass:$vdst),
|
||||
(ins InputModsNoDefault:$src0_modifiers, P.Src0RC64:$src0,
|
||||
InputModsNoDefault:$src1_modifiers, P.Src1RC64:$src1,
|
||||
InputModsNoDefault:$src2_modifiers, P.Src2RC64:$src2,
|
||||
(ins FPInputMods:$src0_modifiers, P.Src0RC64:$src0,
|
||||
FPInputMods:$src1_modifiers, P.Src1RC64:$src1,
|
||||
FPInputMods:$src2_modifiers, P.Src2RC64:$src2,
|
||||
clampmod:$clamp,
|
||||
omod:$omod),
|
||||
"$vdst, $src0_modifiers, $src1_modifiers, $src2_modifiers"#"$clamp"#"$omod",
|
||||
|
@ -45,8 +45,8 @@ v_min_u32 v1, v1, v1 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:BYTE_0 src1_se
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
// NOSICI: error:
|
||||
// VI: v_cvt_u32_f32_sdwa v0, v0 dst_sel:DWORD dst_unused:UNUSED_PRESERVE src0_sel:DWORD ; encoding: [0xf9,0x0e,0x00,0x7e,0x00,0x16,0x06,0x06]
|
||||
v_cvt_u32_f32 v0, v0 dst_sel:DWORD
|
||||
// VI: v_cvt_u32_f32_sdwa v0, v0 clamp dst_sel:DWORD dst_unused:UNUSED_PRESERVE src0_sel:DWORD ; encoding: [0xf9,0x0e,0x00,0x7e,0x00,0x36,0x06,0x06]
|
||||
v_cvt_u32_f32 v0, v0 clamp dst_sel:DWORD
|
||||
|
||||
// NOSICI: error:
|
||||
// VI: v_fract_f32_sdwa v0, v0 clamp dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD ; encoding: [0xf9,0x36,0x00,0x7e,0x00,0x26,0x06,0x06]
|
||||
@ -57,8 +57,8 @@ v_fract_f32 v0, v0 clamp dst_sel:DWORD dst_unused:UNUSED_PAD
|
||||
v_sin_f32 v0, v0 dst_unused:UNUSED_PAD src0_sel:WORD_1
|
||||
|
||||
// NOSICI: error:
|
||||
// VI: v_mov_b32_sdwa v1, v0 dst_sel:DWORD dst_unused:UNUSED_PRESERVE src0_sel:WORD_1 ; encoding: [0xf9,0x02,0x02,0x7e,0x00,0x16,0x05,0x06]
|
||||
v_mov_b32 v1, v0 src0_sel:WORD_1
|
||||
// VI: v_mov_b32_sdwa v1, v0 clamp dst_sel:DWORD dst_unused:UNUSED_PRESERVE src0_sel:WORD_1 ; encoding: [0xf9,0x02,0x02,0x7e,0x00,0x36,0x05,0x06]
|
||||
v_mov_b32 v1, v0 clamp src0_sel:WORD_1
|
||||
|
||||
// NOSICI: error:
|
||||
// VI: v_trunc_f32_sdwa v1, v0 clamp dst_sel:DWORD dst_unused:UNUSED_PRESERVE src0_sel:WORD_1 ; encoding: [0xf9,0x38,0x02,0x7e,0x00,0x36,0x05,0x06]
|
||||
@ -81,8 +81,8 @@ v_min_f32 v0, v0, v0 clamp dst_sel:DWORD src1_sel:BYTE_2
|
||||
v_and_b32 v0, v0, v0 dst_unused:UNUSED_PAD src1_sel:BYTE_2
|
||||
|
||||
// NOSICI: error:
|
||||
// VI: v_mul_i32_i24_sdwa v1, v2, v3 dst_sel:DWORD dst_unused:UNUSED_PRESERVE src0_sel:DWORD src1_sel:DWORD ; encoding: [0xf9,0x06,0x02,0x0c,0x02,0x16,0x06,0x06]
|
||||
v_mul_i32_i24_sdwa v1, v2, v3
|
||||
// VI: v_mul_i32_i24_sdwa v1, v2, v3 clamp dst_sel:DWORD dst_unused:UNUSED_PRESERVE src0_sel:DWORD src1_sel:DWORD ; encoding: [0xf9,0x06,0x02,0x0c,0x02,0x36,0x06,0x06]
|
||||
v_mul_i32_i24_sdwa v1, v2, v3 clamp
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Check modifiers
|
||||
@ -104,6 +104,14 @@ v_add_f32 v0, -|v0|, -v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 src
|
||||
// VI: v_min_f32_sdwa v0, |v0|, -v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:BYTE_2 ; encoding: [0xf9,0x00,0x00,0x14,0x00,0x06,0x25,0x12]
|
||||
v_min_f32 v0, abs(v0), -v0 dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:WORD_1 src1_sel:BYTE_2
|
||||
|
||||
// NOSICI: error:
|
||||
// VI: v_mov_b32_sdwa v1, sext(v0) dst_sel:DWORD dst_unused:UNUSED_PRESERVE src0_sel:DWORD ; encoding: [0xf9,0x02,0x02,0x7e,0x00,0x16,0x0e,0x06]
|
||||
v_mov_b32_sdwa v1, sext(v0)
|
||||
|
||||
// NOSICI: error:
|
||||
// VI: v_and_b32_sdwa v0, sext(v0), sext(v0) dst_sel:DWORD dst_unused:UNUSED_PAD src0_sel:DWORD src1_sel:BYTE_2 ; encoding: [0xf9,0x00,0x00,0x26,0x00,0x06,0x0e,0x0a]
|
||||
v_and_b32 v0, sext(v0), sext(v0) dst_unused:UNUSED_PAD src1_sel:BYTE_2
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Check VOP1 opcodes
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
Loading…
Reference in New Issue
Block a user