mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-05 03:36:43 +00:00
AMDGPU: Start adding global_* instructions
llvm-svn: 305838
This commit is contained in:
parent
88f603bd96
commit
8ecc22a003
@ -644,7 +644,11 @@ def isCIVI : Predicate <
|
||||
"Subtarget->getGeneration() >= AMDGPUSubtarget::SEA_ISLANDS">,
|
||||
AssemblerPredicate<"FeatureCIInsts">;
|
||||
|
||||
def HasFlatAddressSpace : Predicate<"Subtarget->hasFlatAddressSpace()">;
|
||||
def HasFlatAddressSpace : Predicate<"Subtarget->hasFlatAddressSpace()">,
|
||||
AssemblerPredicate<"FeatureFlatAddressSpace">;
|
||||
|
||||
def HasFlatGlobalInsts : Predicate<"Subtarget->hasFlatGlobalInsts()">,
|
||||
AssemblerPredicate<"FeatureFlatGlobalInsts">;
|
||||
|
||||
def Has16BitInsts : Predicate<"Subtarget->has16BitInsts()">,
|
||||
AssemblerPredicate<"Feature16BitInsts">;
|
||||
|
@ -1042,6 +1042,7 @@ public:
|
||||
AMDGPUOperand::Ptr defaultSMRDOffset20() const;
|
||||
AMDGPUOperand::Ptr defaultSMRDLiteralOffset() const;
|
||||
AMDGPUOperand::Ptr defaultOffsetU12() const;
|
||||
AMDGPUOperand::Ptr defaultOffsetS13() const;
|
||||
|
||||
OperandMatchResultTy parseOModOperand(OperandVector &Operands);
|
||||
|
||||
@ -2554,11 +2555,21 @@ AMDGPUAsmParser::parseIntWithPrefix(const char *Prefix, int64_t &Int) {
|
||||
return MatchOperand_ParseFail;
|
||||
|
||||
Parser.Lex();
|
||||
|
||||
bool IsMinus = false;
|
||||
if (getLexer().getKind() == AsmToken::Minus) {
|
||||
Parser.Lex();
|
||||
IsMinus = true;
|
||||
}
|
||||
|
||||
if (getLexer().isNot(AsmToken::Integer))
|
||||
return MatchOperand_ParseFail;
|
||||
|
||||
if (getParser().parseAbsoluteExpression(Int))
|
||||
return MatchOperand_ParseFail;
|
||||
|
||||
if (IsMinus)
|
||||
Int = -Int;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -3870,6 +3881,10 @@ AMDGPUOperand::Ptr AMDGPUAsmParser::defaultOffsetU12() const {
|
||||
return AMDGPUOperand::CreateImm(this, 0, SMLoc(), AMDGPUOperand::ImmTyOffset);
|
||||
}
|
||||
|
||||
AMDGPUOperand::Ptr AMDGPUAsmParser::defaultOffsetS13() const {
|
||||
return AMDGPUOperand::CreateImm(this, 0, SMLoc(), AMDGPUOperand::ImmTyOffset);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// vop3
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -31,8 +31,6 @@ class FLAT_Pseudo<string opName, dag outs, dag ins,
|
||||
let VM_CNT = 1;
|
||||
let LGKM_CNT = 1;
|
||||
|
||||
let Uses = [EXEC, FLAT_SCR]; // M0
|
||||
|
||||
let UseNamedOperandTable = 1;
|
||||
let hasSideEffects = 0;
|
||||
let SchedRW = [WriteVMEM];
|
||||
@ -40,10 +38,16 @@ class FLAT_Pseudo<string opName, dag outs, dag ins,
|
||||
string Mnemonic = opName;
|
||||
string AsmOperands = asmOps;
|
||||
|
||||
bits<1> is_flat_global = 0;
|
||||
bits<1> is_flat_scratch = 0;
|
||||
|
||||
bits<1> has_vdst = 1;
|
||||
bits<1> has_data = 1;
|
||||
bits<1> has_glc = 1;
|
||||
bits<1> glcValue = 0;
|
||||
|
||||
// TODO: M0 if it could possibly access LDS (before gfx9? only)?
|
||||
let Uses = !if(is_flat_global, [EXEC], [EXEC, FLAT_SCR]);
|
||||
}
|
||||
|
||||
class FLAT_Real <bits<7> op, FLAT_Pseudo ps> :
|
||||
@ -68,7 +72,10 @@ class FLAT_Real <bits<7> op, FLAT_Pseudo ps> :
|
||||
|
||||
// Only valid on gfx9
|
||||
bits<1> lds = 0; // XXX - What does this actually do?
|
||||
bits<2> seg; // Segment, 00=flat, 01=scratch, 10=global, 11=reserved
|
||||
|
||||
// Segment, 00=flat, 01=scratch, 10=global, 11=reserved
|
||||
bits<2> seg = !if(ps.is_flat_global, 0b10,
|
||||
!if(ps.is_flat_scratch, 0b01, 0));
|
||||
|
||||
// Signed offset. Highest bit ignored for flat and treated as 12-bit
|
||||
// unsigned for flat acceses.
|
||||
@ -81,7 +88,7 @@ class FLAT_Real <bits<7> op, FLAT_Pseudo ps> :
|
||||
// Only valid on GFX9+
|
||||
let Inst{12-0} = offset;
|
||||
let Inst{13} = lds;
|
||||
let Inst{15-14} = 0;
|
||||
let Inst{15-14} = seg;
|
||||
|
||||
let Inst{16} = !if(ps.has_glc, glc, ps.glcValue);
|
||||
let Inst{17} = slc;
|
||||
@ -106,6 +113,16 @@ class FLAT_Load_Pseudo <string opName, RegisterClass regClass,
|
||||
let mayLoad = 1;
|
||||
}
|
||||
|
||||
class FLAT_Global_Load_Pseudo<string opName, RegisterClass regClass> :
|
||||
FLAT_Load_Pseudo<opName, regClass, 1> {
|
||||
let is_flat_global = 1;
|
||||
}
|
||||
|
||||
class FLAT_Scratch_Load_Pseudo<string opName, RegisterClass regClass> :
|
||||
FLAT_Load_Pseudo<opName, regClass, 1> {
|
||||
let is_flat_scratch = 1;
|
||||
}
|
||||
|
||||
class FLAT_Store_Pseudo <string opName, RegisterClass vdataClass,
|
||||
bit HasSignedOffset = 0> : FLAT_Pseudo<
|
||||
opName,
|
||||
@ -119,6 +136,16 @@ class FLAT_Store_Pseudo <string opName, RegisterClass vdataClass,
|
||||
let has_vdst = 0;
|
||||
}
|
||||
|
||||
class FLAT_Global_Store_Pseudo<string opName, RegisterClass regClass> :
|
||||
FLAT_Store_Pseudo<opName, regClass, 1> {
|
||||
let is_flat_global = 1;
|
||||
}
|
||||
|
||||
class FLAT_Scratch_Store_Pseudo<string opName, RegisterClass regClass> :
|
||||
FLAT_Store_Pseudo<opName, regClass, 1> {
|
||||
let is_flat_scratch = 1;
|
||||
}
|
||||
|
||||
multiclass FLAT_Atomic_Pseudo<
|
||||
string opName,
|
||||
RegisterClass vdst_rc,
|
||||
@ -306,6 +333,26 @@ defm FLAT_ATOMIC_FMAX_X2 : FLAT_Atomic_Pseudo <"flat_atomic_fmax_x2",
|
||||
|
||||
} // End SubtargetPredicate = isCI
|
||||
|
||||
let SubtargetPredicate = HasFlatGlobalInsts in {
|
||||
def GLOBAL_LOAD_UBYTE : FLAT_Global_Load_Pseudo <"global_load_ubyte", VGPR_32>;
|
||||
def GLOBAL_LOAD_SBYTE : FLAT_Global_Load_Pseudo <"global_load_sbyte", VGPR_32>;
|
||||
def GLOBAL_LOAD_USHORT : FLAT_Global_Load_Pseudo <"global_load_ushort", VGPR_32>;
|
||||
def GLOBAL_LOAD_SSHORT : FLAT_Global_Load_Pseudo <"global_load_sshort", VGPR_32>;
|
||||
def GLOBAL_LOAD_DWORD : FLAT_Global_Load_Pseudo <"global_load_dword", VGPR_32>;
|
||||
def GLOBAL_LOAD_DWORDX2 : FLAT_Global_Load_Pseudo <"global_load_dwordx2", VReg_64>;
|
||||
def GLOBAL_LOAD_DWORDX3 : FLAT_Global_Load_Pseudo <"global_load_dwordx3", VReg_96>;
|
||||
def GLOBAL_LOAD_DWORDX4 : FLAT_Global_Load_Pseudo <"global_load_dwordx4", VReg_128>;
|
||||
|
||||
def GLOBAL_STORE_BYTE : FLAT_Global_Store_Pseudo <"global_store_byte", VGPR_32>;
|
||||
def GLOBAL_STORE_SHORT : FLAT_Global_Store_Pseudo <"global_store_short", VGPR_32>;
|
||||
def GLOBAL_STORE_DWORD : FLAT_Global_Store_Pseudo <"global_store_dword", VGPR_32>;
|
||||
def GLOBAL_STORE_DWORDX2 : FLAT_Global_Store_Pseudo <"global_store_dwordx2", VReg_64>;
|
||||
def GLOBAL_STORE_DWORDX3 : FLAT_Global_Store_Pseudo <"global_store_dwordx3", VReg_96>;
|
||||
def GLOBAL_STORE_DWORDX4 : FLAT_Global_Store_Pseudo <"global_store_dwordx4", VReg_128>;
|
||||
|
||||
} // End SubtargetPredicate = HasFlatGlobalInsts
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Flat Patterns
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -557,3 +604,18 @@ defm FLAT_ATOMIC_XOR_X2 : FLAT_Real_Atomics_vi <0x6a, FLAT_ATOMIC_XOR_X2>;
|
||||
defm FLAT_ATOMIC_INC_X2 : FLAT_Real_Atomics_vi <0x6b, FLAT_ATOMIC_INC_X2>;
|
||||
defm FLAT_ATOMIC_DEC_X2 : FLAT_Real_Atomics_vi <0x6c, FLAT_ATOMIC_DEC_X2>;
|
||||
|
||||
def GLOBAL_LOAD_UBYTE_vi : FLAT_Real_vi <0x10, GLOBAL_LOAD_UBYTE>;
|
||||
def GLOBAL_LOAD_SBYTE_vi : FLAT_Real_vi <0x11, GLOBAL_LOAD_SBYTE>;
|
||||
def GLOBAL_LOAD_USHORT_vi : FLAT_Real_vi <0x12, GLOBAL_LOAD_USHORT>;
|
||||
def GLOBAL_LOAD_SSHORT_vi : FLAT_Real_vi <0x13, GLOBAL_LOAD_SSHORT>;
|
||||
def GLOBAL_LOAD_DWORD_vi : FLAT_Real_vi <0x14, GLOBAL_LOAD_DWORD>;
|
||||
def GLOBAL_LOAD_DWORDX2_vi : FLAT_Real_vi <0x15, GLOBAL_LOAD_DWORDX2>;
|
||||
def GLOBAL_LOAD_DWORDX4_vi : FLAT_Real_vi <0x17, GLOBAL_LOAD_DWORDX4>;
|
||||
def GLOBAL_LOAD_DWORDX3_vi : FLAT_Real_vi <0x16, GLOBAL_LOAD_DWORDX3>;
|
||||
|
||||
def GLOBAL_STORE_BYTE_vi : FLAT_Real_vi <0x18, GLOBAL_STORE_BYTE>;
|
||||
def GLOBAL_STORE_SHORT_vi : FLAT_Real_vi <0x1a, GLOBAL_STORE_SHORT>;
|
||||
def GLOBAL_STORE_DWORD_vi : FLAT_Real_vi <0x1c, GLOBAL_STORE_DWORD>;
|
||||
def GLOBAL_STORE_DWORDX2_vi : FLAT_Real_vi <0x1d, GLOBAL_STORE_DWORDX2>;
|
||||
def GLOBAL_STORE_DWORDX4_vi : FLAT_Real_vi <0x1f, GLOBAL_STORE_DWORDX4>;
|
||||
def GLOBAL_STORE_DWORDX3_vi : FLAT_Real_vi <0x1e, GLOBAL_STORE_DWORDX3>;
|
||||
|
@ -72,6 +72,11 @@ void AMDGPUInstPrinter::printU16ImmDecOperand(const MCInst *MI, unsigned OpNo,
|
||||
O << formatDec(MI->getOperand(OpNo).getImm() & 0xffff);
|
||||
}
|
||||
|
||||
void AMDGPUInstPrinter::printS16ImmDecOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) {
|
||||
O << formatDec(static_cast<int16_t>(MI->getOperand(OpNo).getImm()));
|
||||
}
|
||||
|
||||
void AMDGPUInstPrinter::printU32ImmOperand(const MCInst *MI, unsigned OpNo,
|
||||
const MCSubtargetInfo &STI,
|
||||
raw_ostream &O) {
|
||||
@ -118,6 +123,16 @@ void AMDGPUInstPrinter::printOffset(const MCInst *MI, unsigned OpNo,
|
||||
}
|
||||
}
|
||||
|
||||
void AMDGPUInstPrinter::printOffsetS13(const MCInst *MI, unsigned OpNo,
|
||||
const MCSubtargetInfo &STI,
|
||||
raw_ostream &O) {
|
||||
uint16_t Imm = MI->getOperand(OpNo).getImm();
|
||||
if (Imm != 0) {
|
||||
O << ((OpNo == 0)? "offset:" : " offset:");
|
||||
printS16ImmDecOperand(MI, OpNo, O);
|
||||
}
|
||||
}
|
||||
|
||||
void AMDGPUInstPrinter::printOffset0(const MCInst *MI, unsigned OpNo,
|
||||
const MCSubtargetInfo &STI,
|
||||
raw_ostream &O) {
|
||||
|
@ -42,6 +42,7 @@ private:
|
||||
void printU4ImmDecOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printU8ImmDecOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printU16ImmDecOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printS16ImmDecOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printU32ImmOperand(const MCInst *MI, unsigned OpNo,
|
||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||
void printNamedBit(const MCInst *MI, unsigned OpNo, raw_ostream &O,
|
||||
@ -52,6 +53,9 @@ private:
|
||||
void printMBUFOffset(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printOffset(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
|
||||
raw_ostream &O);
|
||||
void printOffsetS13(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
|
||||
raw_ostream &O);
|
||||
|
||||
void printOffset0(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
|
||||
raw_ostream &O);
|
||||
void printOffset1(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
|
||||
|
@ -525,7 +525,7 @@ def idxen : NamedOperandBit<"Idxen", NamedMatchClass<"Idxen">>;
|
||||
def addr64 : NamedOperandBit<"Addr64", NamedMatchClass<"Addr64">>;
|
||||
|
||||
def offset_u12 : NamedOperandU12<"Offset", NamedMatchClass<"OffsetU12">>;
|
||||
def offset_s13 : NamedOperandS13<"Offset", NamedMatchClass<"OffsetS13">>;
|
||||
def offset_s13 : NamedOperandS13<"OffsetS13", NamedMatchClass<"OffsetS13">>;
|
||||
def offset : NamedOperandU16<"Offset", NamedMatchClass<"Offset">>;
|
||||
def offset0 : NamedOperandU8<"Offset0", NamedMatchClass<"Offset0">>;
|
||||
def offset1 : NamedOperandU8<"Offset1", NamedMatchClass<"Offset1">>;
|
||||
|
87
test/MC/AMDGPU/flat-global.s
Normal file
87
test/MC/AMDGPU/flat-global.s
Normal file
@ -0,0 +1,87 @@
|
||||
// RUN: not llvm-mc -arch=amdgcn -mcpu=gfx900 -show-encoding %s | FileCheck -check-prefix=GFX9 -check-prefix=GCN %s
|
||||
// RUN: not llvm-mc -arch=amdgcn -mcpu=gfx900 -show-encoding 2>&1 %s | FileCheck -check-prefix=GFX9-ERR -check-prefix=GCNERR %s
|
||||
// RUN: not llvm-mc -arch=amdgcn -mcpu=tonga -show-encoding 2>&1 %s | FileCheck -check-prefix=VI-ERR -check-prefix=GCNERR %s
|
||||
|
||||
global_load_ubyte v1, v[3:4]
|
||||
// GFX9: global_load_ubyte v1, v[3:4] ; encoding: [0x00,0x80,0x40,0xdc,0x03,0x00,0x00,0x01]
|
||||
// VI-ERR: instruction not supported on this GPU
|
||||
|
||||
global_load_sbyte v1, v[3:4]
|
||||
// GFX9: global_load_sbyte v1, v[3:4] ; encoding: [0x00,0x80,0x44,0xdc,0x03,0x00,0x00,0x01]
|
||||
// VI-ERR: instruction not supported on this GPU
|
||||
|
||||
global_load_ushort v1, v[3:4]
|
||||
// GFX9: global_load_ushort v1, v[3:4] ; encoding: [0x00,0x80,0x48,0xdc,0x03,0x00,0x00,0x01]
|
||||
// VI-ERR: instruction not supported on this GPU
|
||||
|
||||
global_load_sshort v1, v[3:4]
|
||||
// GFX9: global_load_sshort v1, v[3:4] ; encoding: [0x00,0x80,0x4c,0xdc,0x03,0x00,0x00,0x01]
|
||||
// VI-ERR: instruction not supported on this GPU
|
||||
|
||||
global_load_dword v1, v[3:4]
|
||||
// GFX9: global_load_dword v1, v[3:4] ; encoding: [0x00,0x80,0x50,0xdc,0x03,0x00,0x00,0x01]
|
||||
// VI-ERR: instruction not supported on this GPU
|
||||
|
||||
global_load_dwordx2 v[1:2], v[3:4]
|
||||
// GFX9: global_load_dwordx2 v[1:2], v[3:4] ; encoding: [0x00,0x80,0x54,0xdc,0x03,0x00,0x00,0x01]
|
||||
// VI-ERR: instruction not supported on this GPU
|
||||
|
||||
global_load_dwordx3 v[1:3], v[3:4]
|
||||
// GFX9: global_load_dwordx3 v[1:3], v[3:4] ; encoding: [0x00,0x80,0x58,0xdc,0x03,0x00,0x00,0x01]
|
||||
// VI-ERR: instruction not supported on this GPU
|
||||
|
||||
global_load_dwordx4 v[1:4], v[3:4]
|
||||
// GFX9: global_load_dwordx4 v[1:4], v[3:4] ; encoding: [0x00,0x80,0x5c,0xdc,0x03,0x00,0x00,0x01]
|
||||
// VI-ERR: instruction not supported on this GPU
|
||||
// FIXME: VI error should be instruction nto supported
|
||||
global_load_dword v1, v[3:4] offset:0
|
||||
// GFX9: global_load_dword v1, v[3:4] ; encoding: [0x00,0x80,0x50,0xdc,0x03,0x00,0x00,0x01]
|
||||
// VI-ERR: :36: error: not a valid operand.
|
||||
|
||||
global_load_dword v1, v[3:4] offset:4095
|
||||
// GFX9: global_load_dword v1, v[3:4] offset:4095 ; encoding: [0xff,0x8f,0x50,0xdc,0x03,0x00,0x00,0x01]
|
||||
// VI-ERR: :36: error: not a valid operand.
|
||||
|
||||
global_load_dword v1, v[3:4] offset:-1
|
||||
// GFX9: global_load_dword v1, v[3:4] offset:-1 ; encoding: [0xff,0x9f,0x50,0xdc,0x03,0x00,0x00,0x01]
|
||||
// VI-ERR: :36: error: not a valid operand.
|
||||
|
||||
global_load_dword v1, v[3:4] offset:-4096
|
||||
// GFX9: global_load_dword v1, v[3:4] offset:-4096 ; encoding: [0x00,0x90,0x50,0xdc,0x03,0x00,0x00,0x01]
|
||||
// VI-ERR: :36: error: not a valid operand.
|
||||
|
||||
global_load_dword v1, v[3:4] offset:4096
|
||||
// GFX9-ERR: :30: error: invalid operand for instruction
|
||||
// VI-ERR: :36: error: not a valid operand.
|
||||
|
||||
global_load_dword v1, v[3:4] offset:-4097
|
||||
// GFX9-ERR: :30: error: invalid operand for instruction
|
||||
// VI-ERR: :36: error: not a valid operand.
|
||||
|
||||
global_store_byte v[3:4], v1
|
||||
// GFX9: global_store_byte v[3:4], v1 ; encoding: [0x00,0x80,0x60,0xdc,0x03,0x01,0x00,0x00]
|
||||
// VI-ERR: instruction not supported on this GPU
|
||||
|
||||
global_store_short v[3:4], v1
|
||||
// GFX9: global_store_short v[3:4], v1 ; encoding: [0x00,0x80,0x68,0xdc,0x03,0x01,0x00,0x00]
|
||||
// VI-ERR: instruction not supported on this GPU
|
||||
|
||||
global_store_dword v[3:4], v1
|
||||
// GFX9: global_store_dword v[3:4], v1 ; encoding: [0x00,0x80,0x70,0xdc,0x03,0x01,0x00,0x00]
|
||||
// VI-ERR: instruction not supported on this GPU
|
||||
|
||||
global_store_dwordx2 v[3:4], v[1:2]
|
||||
// GFX9: global_store_dwordx2 v[3:4], v[1:2] ; encoding: [0x00,0x80,0x74,0xdc,0x03,0x01,0x00,0x00]
|
||||
// VI-ERR: instruction not supported on this GPU
|
||||
|
||||
global_store_dwordx3 v[3:4], v[1:3]
|
||||
// GFX9: global_store_dwordx3 v[3:4], v[1:3] ; encoding: [0x00,0x80,0x78,0xdc,0x03,0x01,0x00,0x00]
|
||||
// VI-ERR: instruction not supported on this GPU
|
||||
|
||||
global_store_dwordx4 v[3:4], v[1:4]
|
||||
// GFX9: global_store_dwordx4 v[3:4], v[1:4] ; encoding: [0x00,0x80,0x7c,0xdc,0x03,0x01,0x00,0x00]
|
||||
// VI-ERR: instruction not supported on this GPU
|
||||
|
||||
global_store_dword v[3:4], v1 offset:12
|
||||
// GFX9: global_store_dword v[3:4], v1 offset:12 ; encoding: [0x0c,0x80,0x70,0xdc,0x03,0x01,0x00,0x00]
|
||||
// VI-ERR: :37: error: not a valid operand
|
Loading…
x
Reference in New Issue
Block a user