forked from OSchip/llvm-project
[AMDGPU][MC] Refactored exp tgt handling
Summary: - Separated tgt encoding from parsing; - Separated tgt decoding from printing; - Improved errors handling; - Disabled leading zeroes in index. The following code is no longer accepted: exp pos00 v3, v2, v1, v0 Reviewers: arsenm, rampitec, foad Differential Revision: https://reviews.llvm.org/D95216
This commit is contained in:
parent
25f80e16d1
commit
745064e36b
|
@ -32,7 +32,7 @@ static bool isExport(const SUnit &SU) {
|
|||
|
||||
static bool isPositionExport(const SIInstrInfo *TII, SUnit *SU) {
|
||||
const MachineInstr *MI = SU->getInstr();
|
||||
int Imm = TII->getNamedOperand(*MI, AMDGPU::OpName::tgt)->getImm();
|
||||
unsigned Imm = TII->getNamedOperand(*MI, AMDGPU::OpName::tgt)->getImm();
|
||||
return Imm >= AMDGPU::Exp::ET_POS0 && Imm <= AMDGPU::Exp::ET_POS_LAST;
|
||||
}
|
||||
|
||||
|
|
|
@ -1355,7 +1355,6 @@ private:
|
|||
const OperandInfoTy &Offset,
|
||||
const OperandInfoTy &Width);
|
||||
|
||||
OperandMatchResultTy parseExpTgtImpl(StringRef Str, uint8_t &Val);
|
||||
SMLoc getFlatOffsetLoc(const OperandVector &Operands) const;
|
||||
SMLoc getSMEMOffsetLoc(const OperandVector &Operands) const;
|
||||
|
||||
|
@ -5884,76 +5883,24 @@ OperandMatchResultTy AMDGPUAsmParser::parseInterpAttr(OperandVector &Operands) {
|
|||
// exp
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
OperandMatchResultTy AMDGPUAsmParser::parseExpTgtImpl(StringRef Str,
|
||||
uint8_t &Val) {
|
||||
if (Str == "null") {
|
||||
Val = Exp::ET_NULL;
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
if (Str.startswith("mrt")) {
|
||||
Str = Str.drop_front(3);
|
||||
if (Str == "z") { // == mrtz
|
||||
Val = Exp::ET_MRTZ;
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
if (Str.getAsInteger(10, Val))
|
||||
return MatchOperand_ParseFail;
|
||||
|
||||
if (Val > Exp::ET_MRT7)
|
||||
return MatchOperand_ParseFail;
|
||||
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
if (Str.startswith("pos")) {
|
||||
Str = Str.drop_front(3);
|
||||
if (Str.getAsInteger(10, Val))
|
||||
return MatchOperand_ParseFail;
|
||||
|
||||
if (Val > (isGFX10Plus() ? 4 : 3))
|
||||
return MatchOperand_ParseFail;
|
||||
|
||||
Val += Exp::ET_POS0;
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
if (isGFX10Plus() && Str == "prim") {
|
||||
Val = Exp::ET_PRIM;
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
if (Str.startswith("param")) {
|
||||
Str = Str.drop_front(5);
|
||||
if (Str.getAsInteger(10, Val))
|
||||
return MatchOperand_ParseFail;
|
||||
|
||||
if (Val >= 32)
|
||||
return MatchOperand_ParseFail;
|
||||
|
||||
Val += Exp::ET_PARAM0;
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
|
||||
OperandMatchResultTy AMDGPUAsmParser::parseExpTgt(OperandVector &Operands) {
|
||||
using namespace llvm::AMDGPU::Exp;
|
||||
|
||||
StringRef Str;
|
||||
SMLoc S = getLoc();
|
||||
|
||||
if (!parseId(Str))
|
||||
return MatchOperand_NoMatch;
|
||||
|
||||
uint8_t Val;
|
||||
auto Res = parseExpTgtImpl(Str, Val);
|
||||
if (Res != MatchOperand_Success) {
|
||||
Error(S, "invalid exp target");
|
||||
return Res;
|
||||
unsigned Id = getTgtId(Str);
|
||||
if (Id == ET_INVALID || !isSupportedTgtId(Id, getSTI())) {
|
||||
Error(S, (Id == ET_INVALID) ?
|
||||
"invalid exp target" :
|
||||
"exp target is not supported on this GPU");
|
||||
return MatchOperand_ParseFail;
|
||||
}
|
||||
|
||||
Operands.push_back(AMDGPUOperand::CreateImm(this, Val, S,
|
||||
Operands.push_back(AMDGPUOperand::CreateImm(this, Id, S,
|
||||
AMDGPUOperand::ImmTyExpTgt));
|
||||
return MatchOperand_Success;
|
||||
}
|
||||
|
|
|
@ -1004,25 +1004,19 @@ void AMDGPUInstPrinter::printExpSrc3(const MCInst *MI, unsigned OpNo,
|
|||
void AMDGPUInstPrinter::printExpTgt(const MCInst *MI, unsigned OpNo,
|
||||
const MCSubtargetInfo &STI,
|
||||
raw_ostream &O) {
|
||||
// This is really a 6 bit field.
|
||||
uint32_t Tgt = MI->getOperand(OpNo).getImm() & ((1 << 6) - 1);
|
||||
using namespace llvm::AMDGPU::Exp;
|
||||
|
||||
if (Tgt <= Exp::ET_MRT7)
|
||||
O << " mrt" << Tgt - Exp::ET_MRT0;
|
||||
else if (Tgt == Exp::ET_MRTZ)
|
||||
O << " mrtz";
|
||||
else if (Tgt == Exp::ET_NULL)
|
||||
O << " null";
|
||||
else if (Tgt >= Exp::ET_POS0 &&
|
||||
Tgt <= uint32_t(isGFX10Plus(STI) ? Exp::ET_POS4 : Exp::ET_POS3))
|
||||
O << " pos" << Tgt - Exp::ET_POS0;
|
||||
else if (isGFX10Plus(STI) && Tgt == Exp::ET_PRIM)
|
||||
O << " prim";
|
||||
else if (Tgt >= Exp::ET_PARAM0 && Tgt <= Exp::ET_PARAM31)
|
||||
O << " param" << Tgt - Exp::ET_PARAM0;
|
||||
else {
|
||||
// Reserved values 10, 11
|
||||
O << " invalid_target_" << Tgt;
|
||||
// This is really a 6 bit field.
|
||||
unsigned Id = MI->getOperand(OpNo).getImm() & ((1 << 6) - 1);
|
||||
|
||||
int Index;
|
||||
StringRef TgtName;
|
||||
if (getTgtName(Id, TgtName, Index) && isSupportedTgtId(Id, STI)) {
|
||||
O << ' ' << TgtName;
|
||||
if (Index >= 0)
|
||||
O << Index;
|
||||
} else {
|
||||
O << " invalid_target_" << Id;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -692,7 +692,7 @@ enum DppFiMode {
|
|||
|
||||
namespace Exp {
|
||||
|
||||
enum Target {
|
||||
enum Target : unsigned {
|
||||
ET_MRT0 = 0,
|
||||
ET_MRT7 = 7,
|
||||
ET_MRTZ = 8,
|
||||
|
@ -704,6 +704,15 @@ enum Target {
|
|||
ET_PRIM = 20, // GFX10+
|
||||
ET_PARAM0 = 32,
|
||||
ET_PARAM31 = 63,
|
||||
|
||||
ET_NULL_MAX_IDX = 0,
|
||||
ET_MRTZ_MAX_IDX = 0,
|
||||
ET_PRIM_MAX_IDX = 0,
|
||||
ET_MRT_MAX_IDX = 7,
|
||||
ET_POS_MAX_IDX = 4,
|
||||
ET_PARAM_MAX_IDX = 31,
|
||||
|
||||
ET_INVALID = 255,
|
||||
};
|
||||
|
||||
} // namespace Exp
|
||||
|
|
|
@ -1298,7 +1298,7 @@ void SIInsertWaitcnts::updateEventWaitcntAfter(MachineInstr &Inst,
|
|||
ScoreBrackets->applyWaitcnt(AMDGPU::Waitcnt());
|
||||
}
|
||||
} else if (SIInstrInfo::isEXP(Inst)) {
|
||||
int Imm = TII->getNamedOperand(Inst, AMDGPU::OpName::tgt)->getImm();
|
||||
unsigned Imm = TII->getNamedOperand(Inst, AMDGPU::OpName::tgt)->getImm();
|
||||
if (Imm >= AMDGPU::Exp::ET_PARAM0 && Imm <= AMDGPU::Exp::ET_PARAM31)
|
||||
ScoreBrackets->updateByEvent(TII, TRI, MRI, EXP_PARAM_ACCESS, Inst);
|
||||
else if (Imm >= AMDGPU::Exp::ET_POS0 && Imm <= AMDGPU::Exp::ET_POS_LAST)
|
||||
|
|
|
@ -788,6 +788,67 @@ void decodeHwreg(unsigned Val, unsigned &Id, unsigned &Offset, unsigned &Width)
|
|||
|
||||
} // namespace Hwreg
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// exp tgt
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
namespace Exp {
|
||||
|
||||
struct ExpTgt {
|
||||
StringLiteral Name;
|
||||
unsigned Tgt;
|
||||
unsigned MaxIndex;
|
||||
};
|
||||
|
||||
static constexpr ExpTgt ExpTgtInfo[] = {
|
||||
{{"null"}, ET_NULL, ET_NULL_MAX_IDX},
|
||||
{{"mrtz"}, ET_MRTZ, ET_MRTZ_MAX_IDX},
|
||||
{{"prim"}, ET_PRIM, ET_PRIM_MAX_IDX},
|
||||
{{"mrt"}, ET_MRT0, ET_MRT_MAX_IDX},
|
||||
{{"pos"}, ET_POS0, ET_POS_MAX_IDX},
|
||||
{{"param"}, ET_PARAM0, ET_PARAM_MAX_IDX},
|
||||
};
|
||||
|
||||
bool getTgtName(unsigned Id, StringRef &Name, int &Index) {
|
||||
for (const ExpTgt &Val : ExpTgtInfo) {
|
||||
if (Val.Tgt <= Id && Id <= Val.Tgt + Val.MaxIndex) {
|
||||
Index = (Val.MaxIndex == 0) ? -1 : (Id - Val.Tgt);
|
||||
Name = Val.Name;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned getTgtId(const StringRef Name) {
|
||||
|
||||
for (const ExpTgt &Val : ExpTgtInfo) {
|
||||
if (Val.MaxIndex == 0 && Name == Val.Name)
|
||||
return Val.Tgt;
|
||||
|
||||
if (Val.MaxIndex > 0 && Name.startswith(Val.Name)) {
|
||||
StringRef Suffix = Name.drop_front(Val.Name.size());
|
||||
|
||||
unsigned Id;
|
||||
if (Suffix.getAsInteger(10, Id) || Id > Val.MaxIndex)
|
||||
return ET_INVALID;
|
||||
|
||||
// Disable leading zeroes
|
||||
if (Suffix.size() > 1 && Suffix[0] == '0')
|
||||
return ET_INVALID;
|
||||
|
||||
return Val.Tgt + Id;
|
||||
}
|
||||
}
|
||||
return ET_INVALID;
|
||||
}
|
||||
|
||||
bool isSupportedTgtId(unsigned Id, const MCSubtargetInfo &STI) {
|
||||
return (Id != ET_POS4 && Id != ET_PRIM) || isGFX10Plus(STI);
|
||||
}
|
||||
|
||||
} // namespace Exp
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// MTBUF Format
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -486,6 +486,18 @@ void decodeHwreg(unsigned Val, unsigned &Id, unsigned &Offset, unsigned &Width);
|
|||
|
||||
} // namespace Hwreg
|
||||
|
||||
namespace Exp {
|
||||
|
||||
bool getTgtName(unsigned Id, StringRef &Name, int &Index);
|
||||
|
||||
LLVM_READONLY
|
||||
unsigned getTgtId(const StringRef Name);
|
||||
|
||||
LLVM_READNONE
|
||||
bool isSupportedTgtId(unsigned Id, const MCSubtargetInfo &STI);
|
||||
|
||||
} // namespace Exp
|
||||
|
||||
namespace MTBUFFormat {
|
||||
|
||||
LLVM_READNONE
|
||||
|
|
|
@ -5,6 +5,9 @@ exp mrt8 v3, v2, v1, v0
|
|||
// GCN: :5: error: invalid exp target
|
||||
|
||||
exp pos4 v3, v2, v1, v0
|
||||
// GCN: :5: error: exp target is not supported on this GPU
|
||||
|
||||
exp pos5 v3, v2, v1, v0
|
||||
// GCN: :5: error: invalid exp target
|
||||
|
||||
exp param32 v3, v2, v1, v0
|
||||
|
|
|
@ -3,13 +3,13 @@
|
|||
// RUN: llvm-mc -arch=amdgcn -mcpu=gfx1010 -show-encoding %s | FileCheck -check-prefix=GFX10 %s
|
||||
|
||||
exp prim v1, off, off, off
|
||||
// SIVI: :5: error: invalid exp target
|
||||
// SIVI: :5: error: exp target is not supported on this GPU
|
||||
// GFX10: exp prim v1, off, off, off ; encoding: [0x41,0x01,0x00,0xf8,0x01,0x00,0x00,0x00]
|
||||
|
||||
exp prim v2, v3, off, off
|
||||
// SIVI: :5: error: invalid exp target
|
||||
// SIVI: :5: error: exp target is not supported on this GPU
|
||||
// GFX10: exp prim v2, v3, off, off ; encoding: [0x43,0x01,0x00,0xf8,0x02,0x03,0x00,0x00]
|
||||
|
||||
exp pos4 v4, v3, v2, v1
|
||||
// SIVI: error: invalid exp target
|
||||
// SIVI: error: exp target is not supported on this GPU
|
||||
// GFX10: exp pos4 v4, v3, v2, v1 ; encoding: [0x0f,0x01,0x00,0xf8,0x04,0x03,0x02,0x01]
|
||||
|
|
|
@ -665,6 +665,11 @@ exp invalid_target_10 v3, v2, v1, v0
|
|||
// CHECK-NEXT:{{^}}exp invalid_target_10 v3, v2, v1, v0
|
||||
// CHECK-NEXT:{{^}} ^
|
||||
|
||||
exp pos00 v3, v2, v1, v0
|
||||
// CHECK: error: invalid exp target
|
||||
// CHECK-NEXT:{{^}}exp pos00 v3, v2, v1, v0
|
||||
// CHECK-NEXT:{{^}} ^
|
||||
|
||||
//==============================================================================
|
||||
// invalid immediate: only 16-bit values are legal
|
||||
|
||||
|
|
|
@ -24,6 +24,14 @@ s_set_gpr_idx_on s0, gpr_idx(SRC0,DST,SRC1,DST)
|
|||
// CHECK-NEXT:{{^}}s_set_gpr_idx_on s0, gpr_idx(SRC0,DST,SRC1,DST)
|
||||
// CHECK-NEXT:{{^}} ^
|
||||
|
||||
//==============================================================================
|
||||
// exp target is not supported on this GPU
|
||||
|
||||
exp pos4 v4, v3, v2, v1
|
||||
// CHECK: error: exp target is not supported on this GPU
|
||||
// CHECK-NEXT:{{^}}exp pos4 v4, v3, v2, v1
|
||||
// CHECK-NEXT:{{^}} ^
|
||||
|
||||
//==============================================================================
|
||||
// expected a 12-bit unsigned offset
|
||||
|
||||
|
|
Loading…
Reference in New Issue