forked from OSchip/llvm-project
AMDGPU: Add instruction definitions for VGPR indexing
VI added a second method of indexing into VGPRs besides using v_movrel* llvm-svn: 284027
This commit is contained in:
parent
0fd6e9608e
commit
cc88ce36ed
|
@ -168,6 +168,18 @@ def Feature16BitInsts : SubtargetFeature<"16-bit-insts",
|
|||
"Has i16/f16 instructions"
|
||||
>;
|
||||
|
||||
def FeatureMovrel : SubtargetFeature<"movrel",
|
||||
"HasMovrel",
|
||||
"true",
|
||||
"Has v_movrel*_b32 instructions"
|
||||
>;
|
||||
|
||||
def FeatureVGPRIndexMode : SubtargetFeature<"vgpr-index-mode",
|
||||
"HasVGPRIndexMode",
|
||||
"true",
|
||||
"Has VGPR mode register indexing"
|
||||
>;
|
||||
|
||||
//===------------------------------------------------------------===//
|
||||
// Subtarget Features (options and debugging)
|
||||
//===------------------------------------------------------------===//
|
||||
|
@ -295,20 +307,20 @@ def FeatureNorthernIslands : SubtargetFeatureGeneration<"NORTHERN_ISLANDS",
|
|||
def FeatureSouthernIslands : SubtargetFeatureGeneration<"SOUTHERN_ISLANDS",
|
||||
[FeatureFP64, FeatureLocalMemorySize32768,
|
||||
FeatureWavefrontSize64, FeatureGCN, FeatureGCN1Encoding,
|
||||
FeatureLDSBankCount32]
|
||||
FeatureLDSBankCount32, FeatureMovrel]
|
||||
>;
|
||||
|
||||
def FeatureSeaIslands : SubtargetFeatureGeneration<"SEA_ISLANDS",
|
||||
[FeatureFP64, FeatureLocalMemorySize65536,
|
||||
FeatureWavefrontSize64, FeatureGCN, FeatureFlatAddressSpace,
|
||||
FeatureGCN1Encoding, FeatureCIInsts]
|
||||
FeatureGCN1Encoding, FeatureCIInsts, FeatureMovrel]
|
||||
>;
|
||||
|
||||
def FeatureVolcanicIslands : SubtargetFeatureGeneration<"VOLCANIC_ISLANDS",
|
||||
[FeatureFP64, FeatureLocalMemorySize65536,
|
||||
FeatureWavefrontSize64, FeatureFlatAddressSpace, FeatureGCN,
|
||||
FeatureGCN3Encoding, FeatureCIInsts, Feature16BitInsts,
|
||||
FeatureSMemRealTime
|
||||
FeatureSMemRealTime, FeatureVGPRIndexMode, FeatureMovrel
|
||||
]
|
||||
>;
|
||||
|
||||
|
|
|
@ -107,6 +107,8 @@ AMDGPUSubtarget::AMDGPUSubtarget(const Triple &TT, StringRef GPU, StringRef FS,
|
|||
SGPRInitBug(false),
|
||||
HasSMemRealTime(false),
|
||||
Has16BitInsts(false),
|
||||
HasMovrel(false),
|
||||
HasVGPRIndexMode(false),
|
||||
FlatAddressSpace(false),
|
||||
|
||||
R600ALUInst(false),
|
||||
|
|
|
@ -99,6 +99,8 @@ protected:
|
|||
bool SGPRInitBug;
|
||||
bool HasSMemRealTime;
|
||||
bool Has16BitInsts;
|
||||
bool HasMovrel;
|
||||
bool HasVGPRIndexMode;
|
||||
bool FlatAddressSpace;
|
||||
bool R600ALUInst;
|
||||
bool CaymanISA;
|
||||
|
@ -501,6 +503,14 @@ public:
|
|||
return Has16BitInsts;
|
||||
}
|
||||
|
||||
bool hasMovrel() const {
|
||||
return HasMovrel;
|
||||
}
|
||||
|
||||
bool hasVGPRIndexMode() const {
|
||||
return HasVGPRIndexMode;
|
||||
}
|
||||
|
||||
bool hasScalarCompareEq64() const {
|
||||
return getGeneration() >= VOLCANIC_ISLANDS;
|
||||
}
|
||||
|
|
|
@ -344,6 +344,7 @@ public:
|
|||
bool isSMRDOffset() const;
|
||||
bool isSMRDLiteralOffset() const;
|
||||
bool isDPPCtrl() const;
|
||||
bool isGPRIdxMode() const;
|
||||
|
||||
StringRef getExpressionAsToken() const {
|
||||
assert(isExpr());
|
||||
|
@ -2744,6 +2745,10 @@ bool AMDGPUOperand::isDPPCtrl() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool AMDGPUOperand::isGPRIdxMode() const {
|
||||
return isImm() && isUInt<4>(getImm());
|
||||
}
|
||||
|
||||
AMDGPUAsmParser::OperandMatchResultTy
|
||||
AMDGPUAsmParser::parseDPPCtrl(OperandVector &Operands) {
|
||||
SMLoc S = Parser.getTok().getLoc();
|
||||
|
|
|
@ -34,6 +34,7 @@ void AMDGPUInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
|
|||
}
|
||||
|
||||
void AMDGPUInstPrinter::printU4ImmOperand(const MCInst *MI, unsigned OpNo,
|
||||
const MCSubtargetInfo &STI,
|
||||
raw_ostream &O) {
|
||||
O << formatHex(MI->getOperand(OpNo).getImm() & 0xf);
|
||||
}
|
||||
|
@ -510,14 +511,14 @@ void AMDGPUInstPrinter::printRowMask(const MCInst *MI, unsigned OpNo,
|
|||
const MCSubtargetInfo &STI,
|
||||
raw_ostream &O) {
|
||||
O << " row_mask:";
|
||||
printU4ImmOperand(MI, OpNo, O);
|
||||
printU4ImmOperand(MI, OpNo, STI, O);
|
||||
}
|
||||
|
||||
void AMDGPUInstPrinter::printBankMask(const MCInst *MI, unsigned OpNo,
|
||||
const MCSubtargetInfo &STI,
|
||||
raw_ostream &O) {
|
||||
O << " bank_mask:";
|
||||
printU4ImmOperand(MI, OpNo, O);
|
||||
printU4ImmOperand(MI, OpNo, STI, O);
|
||||
}
|
||||
|
||||
void AMDGPUInstPrinter::printBoundCtrl(const MCInst *MI, unsigned OpNo,
|
||||
|
@ -598,6 +599,28 @@ void AMDGPUInstPrinter::printInterpSlot(const MCInst *MI, unsigned OpNo,
|
|||
}
|
||||
}
|
||||
|
||||
void AMDGPUInstPrinter::printVGPRIndexMode(const MCInst *MI, unsigned OpNo,
|
||||
const MCSubtargetInfo &STI,
|
||||
raw_ostream &O) {
|
||||
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";
|
||||
}
|
||||
|
||||
void AMDGPUInstPrinter::printMemOperand(const MCInst *MI, unsigned OpNo,
|
||||
const MCSubtargetInfo &STI,
|
||||
raw_ostream &O) {
|
||||
|
|
|
@ -34,7 +34,8 @@ public:
|
|||
const MCRegisterInfo &MRI);
|
||||
|
||||
private:
|
||||
void printU4ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printU4ImmOperand(const MCInst *MI, unsigned OpNo,
|
||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||
void printU8ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printU16ImmOperand(const MCInst *MI, unsigned OpNo,
|
||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||
|
@ -107,6 +108,8 @@ private:
|
|||
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||
void printInterpSlot(const MCInst *MI, unsigned OpNo,
|
||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||
void printVGPRIndexMode(const MCInst *MI, unsigned OpNo,
|
||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||
void printMemOperand(const MCInst *MI, unsigned OpNo,
|
||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||
static void printIfSet(const MCInst *MI, unsigned OpNo, raw_ostream &O,
|
||||
|
|
|
@ -110,6 +110,15 @@ namespace SIOutMods {
|
|||
};
|
||||
}
|
||||
|
||||
namespace VGPRIndexMode {
|
||||
enum {
|
||||
SRC0_ENABLE = 1 << 0,
|
||||
SRC1_ENABLE = 1 << 1,
|
||||
SRC2_ENABLE = 1 << 2,
|
||||
DST_ENABLE = 1 << 3
|
||||
};
|
||||
}
|
||||
|
||||
namespace AMDGPUAsmVariants {
|
||||
enum {
|
||||
DEFAULT = 0,
|
||||
|
|
|
@ -20,6 +20,10 @@ def isSI : Predicate<"Subtarget->getGeneration() "
|
|||
|
||||
def has16BankLDS : Predicate<"Subtarget->getLDSBankCount() == 16">;
|
||||
def has32BankLDS : Predicate<"Subtarget->getLDSBankCount() == 32">;
|
||||
def HasVGPRIndexMode : Predicate<"Subtarget->hasVGPRIndexMode()">,
|
||||
AssemblerPredicate<"FeatureVGPRIndexMode">;
|
||||
def HasMovrel : Predicate<"Subtarget->hasMovrel()">,
|
||||
AssemblerPredicate<"FeatureMovrel">;
|
||||
|
||||
include "VOPInstructions.td"
|
||||
include "SOPInstructions.td"
|
||||
|
|
|
@ -7,6 +7,18 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
def GPRIdxModeMatchClass : AsmOperandClass {
|
||||
let Name = "GPRIdxMode";
|
||||
let PredicateMethod = "isGPRIdxMode";
|
||||
let RenderMethod = "addImmOperands";
|
||||
}
|
||||
|
||||
def GPRIdxMode : Operand<i32> {
|
||||
let PrintMethod = "printVGPRIndexMode";
|
||||
let ParserMatchClass = GPRIdxModeMatchClass;
|
||||
let OperandType = "OPERAND_IMMEDIATE";
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// SOP1 Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -63,6 +75,13 @@ class SOP1_32 <string opName, list<dag> pattern=[]> : SOP1_Pseudo <
|
|||
"$sdst, $src0", pattern
|
||||
>;
|
||||
|
||||
// 32-bit input, no output.
|
||||
class SOP1_0_32 <string opName, list<dag> pattern = []> : SOP1_Pseudo <
|
||||
opName, (outs), (ins SSrc_b32:$src0),
|
||||
"$src0", pattern> {
|
||||
let has_sdst = 0;
|
||||
}
|
||||
|
||||
class SOP1_64 <string opName, list<dag> pattern=[]> : SOP1_Pseudo <
|
||||
opName, (outs SReg_64:$sdst), (ins SSrc_b64:$src0),
|
||||
"$sdst, $src0", pattern
|
||||
|
@ -198,6 +217,12 @@ def S_ABS_I32 : SOP1_32 <"s_abs_i32">;
|
|||
} // End Defs = [SCC]
|
||||
def S_MOV_FED_B32 : SOP1_32 <"s_mov_fed_b32">;
|
||||
|
||||
let SubtargetPredicate = HasVGPRIndexMode in {
|
||||
def S_SET_GPR_IDX_IDX : SOP1_0_32<"s_set_gpr_idx_idx"> {
|
||||
let Uses = [M0];
|
||||
let Defs = [M0];
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// SOP2 Instructions
|
||||
|
@ -597,7 +622,8 @@ class SOPCe <bits<7> op> : Enc32 {
|
|||
let Inst{31-23} = 0x17e;
|
||||
}
|
||||
|
||||
class SOPC <bits<7> op, dag outs, dag ins, string asm, list<dag> pattern> :
|
||||
class SOPC <bits<7> op, dag outs, dag ins, string asm,
|
||||
list<dag> pattern = []> :
|
||||
InstSI<outs, ins, asm, pattern>, SOPCe <op> {
|
||||
let mayLoad = 0;
|
||||
let mayStore = 0;
|
||||
|
@ -670,6 +696,17 @@ def S_CMP_EQ_U64 : SOPC_CMP_64 <0x12, "s_cmp_eq_u64", COND_EQ>;
|
|||
def S_CMP_LG_U64 : SOPC_CMP_64 <0x13, "s_cmp_lg_u64", COND_NE>;
|
||||
}
|
||||
|
||||
let SubtargetPredicate = HasVGPRIndexMode in {
|
||||
def S_SET_GPR_IDX_ON : SOPC <0x11,
|
||||
(outs),
|
||||
(ins SSrc_b32:$src0, GPRIdxMode:$src1),
|
||||
"s_set_gpr_idx_on $src0,$src1"> {
|
||||
let Defs = [M0]; // No scc def
|
||||
let Uses = [M0]; // Other bits of m0 unmodified.
|
||||
let hasSideEffects = 1; // Sets mode.gpr_idx_en
|
||||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// SOPP Instructions
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -809,8 +846,20 @@ def S_DECPERFLEVEL : SOPP <0x00000015, (ins i32imm:$simm16), "s_decperflevel $si
|
|||
def S_TTRACEDATA : SOPP <0x00000016, (ins), "s_ttracedata"> {
|
||||
let simm16 = 0;
|
||||
}
|
||||
|
||||
let SubtargetPredicate = HasVGPRIndexMode in {
|
||||
def S_SET_GPR_IDX_OFF : SOPP<0x1c, (ins), "s_set_gpr_idx_off"> {
|
||||
let simm16 = 0;
|
||||
}
|
||||
}
|
||||
} // End hasSideEffects
|
||||
|
||||
let SubtargetPredicate = HasVGPRIndexMode in {
|
||||
def S_SET_GPR_IDX_MODE : SOPP<0x1d, (ins GPRIdxMode:$simm16),
|
||||
"s_set_gpr_idx_mode$simm16"> {
|
||||
let Defs = [M0];
|
||||
}
|
||||
}
|
||||
|
||||
let Predicates = [isGCN] in {
|
||||
|
||||
|
@ -1071,6 +1120,7 @@ def S_CBRANCH_JOIN_vi : SOP1_Real_vi <0x2e, S_CBRANCH_JOIN>;
|
|||
def S_MOV_REGRD_B32_vi : SOP1_Real_vi <0x2f, S_MOV_REGRD_B32>;
|
||||
def S_ABS_I32_vi : SOP1_Real_vi <0x30, S_ABS_I32>;
|
||||
def S_MOV_FED_B32_vi : SOP1_Real_vi <0x31, S_MOV_FED_B32>;
|
||||
def S_SET_GPR_IDX_IDX_vi : SOP1_Real_vi <0x32, S_SET_GPR_IDX_IDX>;
|
||||
|
||||
def S_ADD_U32_vi : SOP2_Real_vi <0x00, S_ADD_U32>;
|
||||
def S_ADD_I32_vi : SOP2_Real_vi <0x02, S_ADD_I32>;
|
||||
|
|
|
@ -229,7 +229,7 @@ def VOP_MOVRELD : VOPProfile<[untyped, i32, untyped, untyped]> {
|
|||
let EmitDst = 1; // force vdst emission
|
||||
}
|
||||
|
||||
let Uses = [M0, EXEC] in {
|
||||
let SubtargetPredicate = HasMovrel, Uses = [M0, EXEC] in {
|
||||
// v_movreld_b32 is a special case because the destination output
|
||||
// register is really a source. It isn't actually read (but may be
|
||||
// written), and is only to provide the base register to start
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// RUN: llvm-mc -arch=amdgcn -show-encoding %s | FileCheck --check-prefix=GCN --check-prefix=SICI %s
|
||||
// RUN: llvm-mc -arch=amdgcn -mcpu=SI -show-encoding %s | FileCheck --check-prefix=GCN --check-prefix=SICI %s
|
||||
// RUN: not llvm-mc -arch=amdgcn -show-encoding %s | FileCheck --check-prefix=GCN --check-prefix=SICI %s
|
||||
// RUN: not llvm-mc -arch=amdgcn -show-encoding %s 2>&1 | FileCheck --check-prefix=NOSICI %s
|
||||
// RUN: not llvm-mc -arch=amdgcn -mcpu=fiji -show-encoding %s 2>&1 | FileCheck --check-prefix=GCN --check-prefix=VI %s
|
||||
// RUN: not llvm-mc -arch=amdgcn -mcpu=fiji -show-encoding %s 2>&1 | FileCheck --check-prefix=NOVI %s
|
||||
|
||||
|
@ -242,3 +242,7 @@ s_abs_i32 s1, s2
|
|||
|
||||
s_mov_fed_b32 s1, s2
|
||||
// SICI: s_mov_fed_b32 s1, s2 ; encoding: [0x02,0x35,0x81,0xbe]
|
||||
|
||||
s_set_gpr_idx_idx s0
|
||||
// VI: s_set_gpr_idx_idx s0 ; encoding: [0x00,0x32,0x80,0xbe]
|
||||
// NOSICI: error: instruction not supported on this GPU
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
// RUN: not llvm-mc -arch=amdgcn -mcpu=tonga %s 2>&1 | FileCheck -check-prefix=GCN -check-prefix=VI %s
|
||||
|
||||
s_set_gpr_idx_on s0, s1
|
||||
// GCN: error: invalid operand for instruction
|
||||
|
||||
s_set_gpr_idx_on s0, 16
|
||||
// GCN: error: invalid operand for instruction
|
||||
|
||||
s_set_gpr_idx_on s0, -1
|
||||
// GCN: error: invalid operand for instruction
|
|
@ -64,3 +64,19 @@ s_cmp_eq_u64 s[0:1], s[2:3]
|
|||
s_cmp_lg_u64 s[0:1], s[2:3]
|
||||
// VI: s_cmp_lg_u64 s[0:1], s[2:3] ; encoding: [0x00,0x02,0x13,0xbf]
|
||||
// NOSICI: error: instruction not supported on this GPU
|
||||
|
||||
s_set_gpr_idx_on s0, 0
|
||||
// VI: s_set_gpr_idx_on s0, 0 ; encoding: [0x00,0x00,0x11,0xbf]
|
||||
// NOSICI: error: instruction not supported on this GPU
|
||||
|
||||
s_set_gpr_idx_on s0, 1
|
||||
// VI: s_set_gpr_idx_on s0, src0 ; encoding: [0x00,0x01,0x11,0xbf]
|
||||
// NOSICI: error: instruction not supported on this GPU
|
||||
|
||||
s_set_gpr_idx_on s0, 3
|
||||
// VI: s_set_gpr_idx_on s0, src0 src1 ; encoding: [0x00,0x03,0x11,0xbf]
|
||||
// NOSICI: error: instruction not supported on this GPU
|
||||
|
||||
s_set_gpr_idx_on s0, 15
|
||||
// VI: s_set_gpr_idx_on s0, dst src0 src1 src2 ; encoding: [0x00,0x0f,0x11,0xbf]
|
||||
// NOSICI: error: instruction not supported on this GPU
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// RUN: llvm-mc -arch=amdgcn -show-encoding %s | FileCheck --check-prefix=GCN --check-prefix=SICI %s
|
||||
// RUN: llvm-mc -arch=amdgcn -mcpu=SI -show-encoding %s | FileCheck --check-prefix=GCN --check-prefix=SICI %s
|
||||
// RUN: not llvm-mc -arch=amdgcn -show-encoding %s | FileCheck --check-prefix=GCN --check-prefix=SICI %s
|
||||
// RUN: not llvm-mc -arch=amdgcn -show-encoding %s 2>&1 | FileCheck %s --check-prefix=NOSICI
|
||||
// RUN: llvm-mc -arch=amdgcn -mcpu=fiji -show-encoding %s | FileCheck --check-prefix=GCN --check-prefix=VI %s
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -176,3 +176,15 @@ s_decperflevel 6
|
|||
|
||||
s_ttracedata
|
||||
// GCN: s_ttracedata ; encoding: [0x00,0x00,0x96,0xbf]
|
||||
|
||||
s_set_gpr_idx_off
|
||||
// VI: s_set_gpr_idx_off ; encoding: [0x00,0x00,0x9c,0xbf]
|
||||
// NOSICI: error: instruction not supported on this GPU
|
||||
|
||||
s_set_gpr_idx_mode 0
|
||||
// VI: s_set_gpr_idx_mode 0 ; encoding: [0x00,0x00,0x9d,0xbf]
|
||||
// NOSICI: error: instruction not supported on this GPU
|
||||
|
||||
s_set_gpr_idx_mode 15
|
||||
// VI: s_set_gpr_idx_mode dst src0 src1 src2 ; encoding: [0x0f,0x00,0x9d,0xbf]
|
||||
// NOSICI: error: instruction not supported on this GPU
|
||||
|
|
Loading…
Reference in New Issue