aco: print assembly with CLRXdisasm for GFX6-GFX7 if found on the system
authorSamuel Pitoiset <samuel.pitoiset@gmail.com>
Fri, 17 Jan 2020 08:49:44 +0000 (09:49 +0100)
committerMarge Bot <eric+marge@anholt.net>
Fri, 17 Jan 2020 17:41:32 +0000 (17:41 +0000)
LLVM only supports GFX8+. Using CLRXdisasm works most of the time,
so it's useful to add support for it.

Original patch by Daniel Schürmann.

Signed-off-by: Samuel Pitoiset <samuel.pitoiset@gmail.com>
Reviewed-by: Daniel Schürmann <daniel@schuermann.dev>
Tested-by: Marge Bot <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3439>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/merge_requests/3439>

src/amd/compiler/aco_print_asm.cpp

index 4b0ce26994be5d4d703a78f6b61f22a7f3c0ed1e..74115e10cd342fecd395bc821e200f8d1d3f9c52 100644 (file)
@@ -8,13 +8,51 @@
 
 namespace aco {
 
+/* LLVM disassembler only supports GFX8+, try to disassemble with CLRXdisasm
+ * for GFX6-GFX7 if found on the system, this is better than nothing.
+*/
+void print_asm_gfx6_gfx7(Program *program, std::vector<uint32_t>& binary,
+                         std::ostream& out)
+{
+   char path[] = "/tmp/fileXXXXXX";
+   char line[2048], command[128];
+   FILE *p;
+   int fd;
+
+   /* Dump the binary into a temporary file. */
+   fd = mkstemp(path);
+   if (fd < 0)
+      return;
+
+   for (uint32_t w : binary)
+   {
+      if (write(fd, &w, sizeof(w)) == -1)
+         goto fail;
+   }
+
+   sprintf(command, "clrxdisasm --gpuType=%s -r %s",
+           program->chip_class == GFX6 ? "gfx600" : "gfx700", path);
+
+   p = popen(command, "r");
+   if (p) {
+      while (fgets(line, sizeof(line), p))
+         out << line;
+      pclose(p);
+   }
+
+fail:
+   close(fd);
+   unlink(path);
+}
+
 void print_asm(Program *program, std::vector<uint32_t>& binary,
                unsigned exec_size, std::ostream& out)
 {
    if (program->chip_class <= GFX7) {
-      out << "Disassembly for this GPU currently not supported." << std::endl;
+      print_asm_gfx6_gfx7(program, binary, out);
       return;
    }
+
    std::vector<bool> referenced_blocks(program->blocks.size());
    referenced_blocks[0] = true;
    for (Block& block : program->blocks) {