aco: Fix GFX9 FLAT, SCRATCH, GLOBAL instructions, add GFX10 support.
authorTimur Kristóf <timur.kristof@gmail.com>
Thu, 26 Sep 2019 15:50:06 +0000 (17:50 +0200)
committerTimur Kristóf <timur.kristof@gmail.com>
Thu, 10 Oct 2019 07:57:53 +0000 (09:57 +0200)
Signed-off-by: Timur Kristóf <timur.kristof@gmail.com>
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
src/amd/compiler/README
src/amd/compiler/aco_assembler.cpp

index 254c50285246d47564e301de4cc27b96fd36ce3f..01b8339c547e3582bbb71f6222efe63ec6e49f5c 100644 (file)
@@ -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
index 42826b213d8c8247ac0c8d6b4616e579e381b5ce..39bf9eca21c7bee7422f2377a5ba1f94439d3dbf 100644 (file)
@@ -373,26 +373,41 @@ void emit_instruction(asm_context& ctx, std::vector<uint32_t>& out, Instruction*
       FLAT_instruction *flat = static_cast<FLAT_instruction*>(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);