Skip to content

Commit

Permalink
[AMDGPU][MC][GFX8+] Added syntactic sugar for 'vgpr index' operand of…
Browse files Browse the repository at this point in the history
… instructions s_set_gpr_idx_on and s_set_gpr_idx_mode

See bug 39331: https://bugs.llvm.org/show_bug.cgi?id=39331

Reviewers: artem.tamazov, arsenm

Differential Revision: https://reviews.llvm.org/D58288

llvm-svn: 354969
  • Loading branch information
dpreobra committed Feb 27, 2019
1 parent 3fc81c2 commit ef92035
Show file tree
Hide file tree
Showing 15 changed files with 260 additions and 69 deletions.
91 changes: 87 additions & 4 deletions llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp
Expand Up @@ -173,6 +173,7 @@ class AMDGPUOperand : public MCParsedAsmOperand {
ImmTyNegLo,
ImmTyNegHi,
ImmTySwizzle,
ImmTyGprIdxMode,
ImmTyHigh
};

Expand Down Expand Up @@ -694,6 +695,7 @@ class AMDGPUOperand : public MCParsedAsmOperand {
case ImmTyNegLo: OS << "NegLo"; break;
case ImmTyNegHi: OS << "NegHi"; break;
case ImmTySwizzle: OS << "Swizzle"; break;
case ImmTyGprIdxMode: OS << "GprIdxMode"; break;
case ImmTyHigh: OS << "High"; break;
}
}
Expand Down Expand Up @@ -1129,6 +1131,9 @@ class AMDGPUAsmParser : public MCTargetAsmParser {
bool parseSwizzleSwap(int64_t &Imm);
bool parseSwizzleReverse(int64_t &Imm);

OperandMatchResultTy parseGPRIdxMode(OperandVector &Operands);
int64_t parseGPRIdxMacro();

void cvtMubuf(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, false, false); }
void cvtMubufAtomic(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, true, false); }
void cvtMubufAtomicReturn(MCInst &Inst, const OperandVector &Operands) { cvtMubufImpl(Inst, Operands, true, true); }
Expand Down Expand Up @@ -4648,6 +4653,88 @@ AMDGPUOperand::isSwizzle() const {
return isImmTy(ImmTySwizzle);
}

//===----------------------------------------------------------------------===//
// VGPR Index Mode
//===----------------------------------------------------------------------===//

int64_t AMDGPUAsmParser::parseGPRIdxMacro() {

using namespace llvm::AMDGPU::VGPRIndexMode;

if (trySkipToken(AsmToken::RParen)) {
return OFF;
}

int64_t Imm = 0;

while (true) {
unsigned Mode = 0;
SMLoc S = Parser.getTok().getLoc();

for (unsigned ModeId = ID_MIN; ModeId <= ID_MAX; ++ModeId) {
if (trySkipId(IdSymbolic[ModeId])) {
Mode = 1 << ModeId;
break;
}
}

if (Mode == 0) {
Error(S, (Imm == 0)?
"expected a VGPR index mode or a closing parenthesis" :
"expected a VGPR index mode");
break;
}

if (Imm & Mode) {
Error(S, "duplicate VGPR index mode");
break;
}
Imm |= Mode;

if (trySkipToken(AsmToken::RParen))
break;
if (!skipToken(AsmToken::Comma,
"expected a comma or a closing parenthesis"))
break;
}

return Imm;
}

OperandMatchResultTy
AMDGPUAsmParser::parseGPRIdxMode(OperandVector &Operands) {

int64_t Imm = 0;
SMLoc S = Parser.getTok().getLoc();

if (getLexer().getKind() == AsmToken::Identifier &&
Parser.getTok().getString() == "gpr_idx" &&
getLexer().peekTok().is(AsmToken::LParen)) {

Parser.Lex();
Parser.Lex();

// If parse failed, trigger an error but do not return error code
// to avoid excessive error messages.
Imm = parseGPRIdxMacro();

} else {
if (getParser().parseAbsoluteExpression(Imm))
return MatchOperand_NoMatch;
if (Imm < 0 || !isUInt<4>(Imm)) {
Error(S, "invalid immediate: only 4-bit values are legal");
}
}

Operands.push_back(
AMDGPUOperand::CreateImm(this, Imm, S, AMDGPUOperand::ImmTyGprIdxMode));
return MatchOperand_Success;
}

bool AMDGPUOperand::isGPRIdxMode() const {
return isImmTy(ImmTyGprIdxMode);
}

//===----------------------------------------------------------------------===//
// sopp branch targets
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -5289,10 +5376,6 @@ bool AMDGPUOperand::isDPPCtrl() const {
return false;
}

bool AMDGPUOperand::isGPRIdxMode() const {
return isImm() && isUInt<4>(getImm());
}

bool AMDGPUOperand::isS16Imm() const {
return isImm() && (isInt<16>(getImm()) || isUInt<16>(getImm()));
}
Expand Down
31 changes: 16 additions & 15 deletions llvm/lib/Target/AMDGPU/InstPrinter/AMDGPUInstPrinter.cpp
Expand Up @@ -934,23 +934,24 @@ void AMDGPUInstPrinter::printInterpAttrChan(const MCInst *MI, unsigned OpNum,
void AMDGPUInstPrinter::printVGPRIndexMode(const MCInst *MI, unsigned OpNo,
const MCSubtargetInfo &STI,
raw_ostream &O) {
using namespace llvm::AMDGPU::VGPRIndexMode;
unsigned Val = MI->getOperand(OpNo).getImm();
if (Val == 0) {
O << " 0";
return;
}

if (Val & VGPRIndexMode::DST_ENABLE)
O << " dst";

if (Val & VGPRIndexMode::SRC0_ENABLE)
O << " src0";

if (Val & VGPRIndexMode::SRC1_ENABLE)
O << " src1";

if (Val & VGPRIndexMode::SRC2_ENABLE)
O << " src2";
if ((Val & ~ENABLE_MASK) != 0) {
O << " " << formatHex(static_cast<uint64_t>(Val));
} else {
O << " gpr_idx(";
bool NeedComma = false;
for (unsigned ModeId = ID_MIN; ModeId <= ID_MAX; ++ModeId) {
if (Val & (1 << ModeId)) {
if (NeedComma)
O << ',';
O << IdSymbolic[ModeId];
NeedComma = true;
}
}
O << ')';
}
}

void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
Expand Down
30 changes: 23 additions & 7 deletions llvm/lib/Target/AMDGPU/SIDefines.h
Expand Up @@ -180,14 +180,30 @@ namespace SIOutMods {
};
}

namespace AMDGPU {
namespace VGPRIndexMode {
enum {
SRC0_ENABLE = 1 << 0,
SRC1_ENABLE = 1 << 1,
SRC2_ENABLE = 1 << 2,
DST_ENABLE = 1 << 3
};
}

enum Id { // id of symbolic names
ID_SRC0 = 0,
ID_SRC1,
ID_SRC2,
ID_DST,

ID_MIN = ID_SRC0,
ID_MAX = ID_DST
};

enum EncBits {
OFF = 0,
SRC0_ENABLE = 1 << ID_SRC0,
SRC1_ENABLE = 1 << ID_SRC1,
SRC2_ENABLE = 1 << ID_SRC2,
DST_ENABLE = 1 << ID_DST,
ENABLE_MASK = SRC0_ENABLE | SRC1_ENABLE | SRC2_ENABLE | DST_ENABLE
};

} // namespace VGPRIndexMode
} // namespace AMDGPU

namespace AMDGPUAsmVariants {
enum {
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/AMDGPU/SIISelLowering.cpp
Expand Up @@ -2911,7 +2911,7 @@ static MachineBasicBlock::iterator emitLoadM0FromVGPRLoop(
.addImm(Offset);
}
unsigned IdxMode = IsIndirectSrc ?
VGPRIndexMode::SRC0_ENABLE : VGPRIndexMode::DST_ENABLE;
AMDGPU::VGPRIndexMode::SRC0_ENABLE : AMDGPU::VGPRIndexMode::DST_ENABLE;
MachineInstr *SetOn =
BuildMI(LoopBB, I, DL, TII->get(AMDGPU::S_SET_GPR_IDX_ON))
.addReg(IdxReg, RegState::Kill)
Expand Down Expand Up @@ -3042,7 +3042,7 @@ static bool setM0ToIndexFromSGPR(const SIInstrInfo *TII,

if (UseGPRIdxMode) {
unsigned IdxMode = IsIndirectSrc ?
VGPRIndexMode::SRC0_ENABLE : VGPRIndexMode::DST_ENABLE;
AMDGPU::VGPRIndexMode::SRC0_ENABLE : AMDGPU::VGPRIndexMode::DST_ENABLE;
if (Offset == 0) {
MachineInstr *SetOn =
BuildMI(*MBB, I, DL, TII->get(AMDGPU::S_SET_GPR_IDX_ON))
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/AMDGPU/SOPInstructions.td
Expand Up @@ -9,6 +9,7 @@
def GPRIdxModeMatchClass : AsmOperandClass {
let Name = "GPRIdxMode";
let PredicateMethod = "isGPRIdxMode";
let ParserMethod = "parseGPRIdxMode";
let RenderMethod = "addImmOperands";
}

Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.cpp
Expand Up @@ -85,5 +85,18 @@ const char* const IdSymbolic[] = {
};

} // namespace Swizzle

namespace VGPRIndexMode {

// This must be in sync with llvm::AMDGPU::VGPRIndexMode::Id enum members, see SIDefines.h.
const char* const IdSymbolic[] = {
"SRC0",
"SRC1",
"SRC2",
"DST",
};

} // namespace VGPRIndexMode

} // namespace AMDGPU
} // namespace llvm
7 changes: 7 additions & 0 deletions llvm/lib/Target/AMDGPU/Utils/AMDGPUAsmUtils.h
Expand Up @@ -30,6 +30,13 @@ namespace Swizzle { // Symbolic names for the swizzle(...) syntax.
extern const char* const IdSymbolic[];

} // namespace Swizzle

namespace VGPRIndexMode { // Symbolic names for the gpr_idx(...) syntax.

extern const char* const IdSymbolic[];

} // namespace VGPRIndexMode

} // namespace AMDGPU
} // namespace llvm

Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/AMDGPU/indirect-addressing-si-gfx9.ll
Expand Up @@ -24,7 +24,7 @@
; MOVREL: s_mov_b32 m0, [[READLANE]]
; MOVREL-NEXT: v_movreld_b32_e32 v[[VEC_ELT0]], [[INS0]]

; IDXMODE: s_set_gpr_idx_on [[READLANE]], dst
; IDXMODE: s_set_gpr_idx_on [[READLANE]], gpr_idx(DST)
; IDXMODE-NEXT: v_mov_b32_e32 v[[VEC_ELT0]], [[INS0]]
; IDXMODE: s_set_gpr_idx_off

Expand All @@ -44,7 +44,7 @@
; MOVREL: s_mov_b32 m0, [[READLANE]]
; MOVREL-NEXT: v_movreld_b32_e32 v{{[0-9]+}}, 63

; IDXMODE: s_set_gpr_idx_on [[READLANE]], dst
; IDXMODE: s_set_gpr_idx_on [[READLANE]], gpr_idx(DST)
; IDXMODE-NEXT: v_mov_b32_e32 v{{[0-9]+}}, 63
; IDXMODE: s_set_gpr_idx_off

Expand Down
4 changes: 2 additions & 2 deletions llvm/test/CodeGen/AMDGPU/indirect-addressing-si-pregfx9.ll
Expand Up @@ -27,7 +27,7 @@
; MOVREL: s_mov_b32 m0, [[READLANE]]
; MOVREL-NEXT: v_movreld_b32_e32 v[[VEC_ELT0]], [[INS0]]

; IDXMODE: s_set_gpr_idx_on [[READLANE]], dst
; IDXMODE: s_set_gpr_idx_on [[READLANE]], gpr_idx(DST)
; IDXMODE-NEXT: v_mov_b32_e32 v[[VEC_ELT0]], [[INS0]]
; IDXMODE: s_set_gpr_idx_off

Expand All @@ -47,7 +47,7 @@
; MOVREL: s_mov_b32 m0, [[READLANE]]
; MOVREL-NEXT: v_movreld_b32_e32 v{{[0-9]+}}, 63

; IDXMODE: s_set_gpr_idx_on [[READLANE]], dst
; IDXMODE: s_set_gpr_idx_on [[READLANE]], gpr_idx(DST)
; IDXMODE-NEXT: v_mov_b32_e32 v{{[0-9]+}}, 63
; IDXMODE: s_set_gpr_idx_off

Expand Down

0 comments on commit ef92035

Please sign in to comment.