aco: Initial GFX7 Support
Reviewed-by: Rhys Perry <pendingchaos02@gmail.com>
This commit is contained in:
parent
3177346bfc
commit
0d42e4d7a0
4 changed files with 95 additions and 72 deletions
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue