aco: Initial GFX7 Support

Reviewed-by: Rhys Perry <pendingchaos02@gmail.com>
This commit is contained in:
Daniel Schürmann 2019-11-04 18:02:47 +01:00
parent 3177346bfc
commit 0d42e4d7a0
4 changed files with 95 additions and 72 deletions

View file

@ -17,7 +17,9 @@ struct asm_context {
// TODO: keep track of branch instructions referring blocks
// and, when emitting the block, correct the offset in instr
asm_context(Program* program) : program(program), chip_class(program->chip_class) {
if (chip_class <= GFX9)
if (chip_class <= GFX7)
opcode = &instr_info.opcode_gfx7[0];
else if (chip_class <= GFX9)
opcode = &instr_info.opcode_gfx9[0];
else if (chip_class == GFX10)
opcode = &instr_info.opcode_gfx10[0];
@ -145,9 +147,26 @@ void emit_instruction(asm_context& ctx, std::vector<uint32_t>& out, Instruction*
SMEM_instruction* smem = static_cast<SMEM_instruction*>(instr);
bool soe = instr->operands.size() >= (!instr->definitions.empty() ? 3 : 4);
bool is_load = !instr->definitions.empty();
uint32_t encoding = 0;
if (ctx.chip_class <= GFX7) {
encoding = (0b11000 << 27);
encoding |= opcode << 22;
encoding |= instr->definitions.size() ? instr->definitions[0].physReg() << 15 : 0;
encoding |= instr->operands.size() ? (instr->operands[0].physReg() >> 1) << 9 : 0;
if (!instr->operands[1].isConstant() || instr->operands[1].constantValue() >= 1024) {
encoding |= instr->operands[1].physReg().reg;
} else {
encoding |= instr->operands[1].constantValue() >> 2;
encoding |= 1 << 8;
}
out.push_back(encoding);
/* SMRD instructions can take a literal on GFX6 & GFX7 */
if (instr->operands[1].isConstant() && instr->operands[1].constantValue() >= 1024)
out.push_back(instr->operands[1].constantValue() >> 2);
return;
}
if (ctx.chip_class <= GFX9) {
encoding = (0b110000 << 26);
assert(!smem->dlc); /* Device-level coherent is not supported on GFX9 and lower */
@ -291,7 +310,7 @@ void emit_instruction(asm_context& ctx, std::vector<uint32_t>& out, Instruction*
encoding |= (mubuf->glc ? 1 : 0) << 14;
encoding |= (mubuf->idxen ? 1 : 0) << 13;
encoding |= (mubuf->offen ? 1 : 0) << 12;
if (ctx.chip_class <= GFX9) {
if (ctx.chip_class == GFX8 || ctx.chip_class == GFX9) {
assert(!mubuf->dlc); /* Device-level coherent is not supported on GFX9 and lower */
encoding |= (mubuf->slc ? 1 : 0) << 17;
} else if (ctx.chip_class >= GFX10) {
@ -326,7 +345,7 @@ void emit_instruction(asm_context& ctx, std::vector<uint32_t>& out, Instruction*
encoding |= 0x0FFF & mtbuf->offset;
encoding |= (img_format << 19); /* Handles both the GFX10 FORMAT and the old NFMT+DFMT */
if (ctx.chip_class <= GFX9) {
if (ctx.chip_class == GFX8 || ctx.chip_class == GFX9) {
encoding |= opcode << 15;
} else {
encoding |= (opcode & 0x07) << 16; /* 3 LSBs of 4-bit OPCODE */
@ -444,9 +463,9 @@ void emit_instruction(asm_context& ctx, std::vector<uint32_t>& out, Instruction*
case Format::EXP: {
Export_instruction* exp = static_cast<Export_instruction*>(instr);
uint32_t encoding;
if (ctx.chip_class <= GFX9) {
if (ctx.chip_class == GFX8 || ctx.chip_class == GFX9) {
encoding = (0b110001 << 26);
} else if (ctx.chip_class >= GFX10) {
} else {
encoding = (0b111110 << 26);
}
@ -473,12 +492,10 @@ void emit_instruction(asm_context& ctx, std::vector<uint32_t>& out, Instruction*
if ((uint16_t) instr->format & (uint16_t) Format::VOP2) {
opcode = opcode + 0x100;
} else if ((uint16_t) instr->format & (uint16_t) Format::VOP1) {
if (ctx.chip_class <= GFX9) {
if (ctx.chip_class == GFX8 || ctx.chip_class == GFX9)
opcode = opcode + 0x140;
} else {
/* RDNA ISA doc says this is 0x140, but that doesn't work */
else
opcode = opcode + 0x180;
}
} else if ((uint16_t) instr->format & (uint16_t) Format::VOPC) {
opcode = opcode + 0x0;
} else if ((uint16_t) instr->format & (uint16_t) Format::VINTRP) {
@ -492,8 +509,13 @@ void emit_instruction(asm_context& ctx, std::vector<uint32_t>& out, Instruction*
encoding = (0b110101 << 26);
}
encoding |= opcode << 16;
encoding |= (vop3->clamp ? 1 : 0) << 15;
if (ctx.chip_class <= GFX7) {
encoding |= opcode << 17;
encoding |= (vop3->clamp ? 1 : 0) << 11;
} else {
encoding |= opcode << 16;
encoding |= (vop3->clamp ? 1 : 0) << 15;
}
for (unsigned i = 0; i < 3; i++)
encoding |= vop3->abs[i] << (8+i);
for (unsigned i = 0; i < 4; i++)
@ -515,6 +537,7 @@ void emit_instruction(asm_context& ctx, std::vector<uint32_t>& out, Instruction*
out.push_back(encoding);
} else if (instr->isDPP()){
assert(ctx.chip_class >= GFX8);
/* first emit the instruction without the DPP operand */
Operand dpp_op = instr->operands[0];
instr->operands[0] = Operand(PhysReg{250}, v1);