From e6330d71b51efd53b26a7e2922162f0dcaae6ba5 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Timur=20Krist=C3=B3f?= Date: Thu, 26 Sep 2019 17:50:06 +0200 Subject: [PATCH] aco: Fix GFX9 FLAT, SCRATCH, GLOBAL instructions, add GFX10 support. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Timur Kristóf Reviewed-by: Daniel Schürmann --- src/amd/compiler/README | 4 ++++ src/amd/compiler/aco_assembler.cpp | 31 ++++++++++++++++++++++-------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/amd/compiler/README b/src/amd/compiler/README index 254c5028524..01b8339c547 100644 --- a/src/amd/compiler/README +++ b/src/amd/compiler/README @@ -82,6 +82,10 @@ work. What works is adding `0x180`, which LLVM also does. The NV bit was removed in RDNA, but some parts of the doc still mention it. +RDNA ISA doc 13.8.1 says that SADDR should be set to 0x7f when ADDR is used, but +9.3.1 says it should be set to NULL. We assume 9.3.1 is correct and set it to +SGPR_NULL. + ## Legacy instructions Some instructions have a `_LEGACY` variant which implements "DX9 rules", in which diff --git a/src/amd/compiler/aco_assembler.cpp b/src/amd/compiler/aco_assembler.cpp index 42826b213d8..39bf9eca21c 100644 --- a/src/amd/compiler/aco_assembler.cpp +++ b/src/amd/compiler/aco_assembler.cpp @@ -373,26 +373,41 @@ void emit_instruction(asm_context& ctx, std::vector& out, Instruction* FLAT_instruction *flat = static_cast(instr); uint32_t encoding = (0b110111 << 26); encoding |= opcode << 18; - encoding |= flat->offset & 0x1fff; + if (ctx.chip_class <= GFX9) { + assert(flat->offset <= 0x1fff); + encoding |= flat->offset & 0x1fff; + } else { + assert(flat->offset <= 0x0fff); + encoding |= flat->offset & 0x0fff; + } if (instr->format == Format::SCRATCH) encoding |= 1 << 14; else if (instr->format == Format::GLOBAL) encoding |= 2 << 14; encoding |= flat->lds ? 1 << 13 : 0; - encoding |= flat->glc ? 1 << 13 : 0; - encoding |= flat->slc ? 1 << 13 : 0; + encoding |= flat->glc ? 1 << 16 : 0; + encoding |= flat->slc ? 1 << 17 : 0; + if (ctx.chip_class >= GFX10) { + assert(!flat->nv); + encoding |= flat->dlc ? 1 << 12 : 0; + } else { + assert(!flat->dlc); + } out.push_back(encoding); - encoding = (0xFF & instr->operands[0].physReg().reg); + encoding = (0xFF & instr->operands[0].physReg()); if (!instr->definitions.empty()) - encoding |= (0xFF & instr->definitions[0].physReg().reg) << 24; + encoding |= (0xFF & instr->definitions[0].physReg()) << 24; else - encoding |= (0xFF & instr->operands[2].physReg().reg) << 8; + encoding |= (0xFF & instr->operands[2].physReg()) << 8; if (!instr->operands[1].isUndefined()) { - assert(instr->operands[1].physReg() != 0x7f); + assert(ctx.chip_class >= GFX10 || instr->operands[1].physReg() != 0x7F); assert(instr->format != Format::FLAT); encoding |= instr->operands[1].physReg() << 16; } else if (instr->format != Format::FLAT) { - encoding |= 0x7F << 16; + if (ctx.chip_class <= GFX9) + encoding |= 0x7F << 16; + else + encoding |= sgpr_null << 16; } encoding |= flat->nv ? 1 << 23 : 0; out.push_back(encoding); -- 2.30.2