X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Famd%2Fcompiler%2Faco_print_asm.cpp;h=d4b0e0edbcf3e6acb2776e35846988bf8798bd7f;hb=f302ef3853bfcc4dc68205c40f1e7390aff799ab;hp=743824888d6b9c4faa55f9ddd3903fbc1877e0f4;hpb=23319add93bb22744ba48e9026dcc40ecd30628c;p=mesa.git diff --git a/src/amd/compiler/aco_print_asm.cpp b/src/amd/compiler/aco_print_asm.cpp index 743824888d6..d4b0e0edbcf 100644 --- a/src/amd/compiler/aco_print_asm.cpp +++ b/src/amd/compiler/aco_print_asm.cpp @@ -5,12 +5,97 @@ #include "ac_llvm_util.h" #include +#if LLVM_VERSION_MAJOR >= 11 +#include +#endif 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& binary, + std::ostream& out) +{ + char path[] = "/tmp/fileXXXXXX"; + char line[2048], command[128]; + const char *gpu_type; + 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; + } + + /* Determine the GPU type for CLRXdisasm. Use the family for GFX6 chips + * because it doesn't allow to use gfx600 directly. + */ + switch (program->chip_class) { + case GFX6: + switch (program->family) { + case CHIP_TAHITI: + gpu_type = "tahiti"; + break; + case CHIP_PITCAIRN: + gpu_type = "pitcairn"; + break; + case CHIP_VERDE: + gpu_type = "capeverde"; + break; + case CHIP_OLAND: + gpu_type = "oland"; + break; + case CHIP_HAINAN: + gpu_type = "hainan"; + break; + default: + unreachable("Invalid GFX6 family!"); + } + break; + case GFX7: + gpu_type = "gfx700"; + break; + default: + unreachable("Invalid chip class!"); + } + + sprintf(command, "clrxdisasm --gpuType=%s -r %s", gpu_type, path); + + p = popen(command, "r"); + if (p) { + if (!fgets(line, sizeof(line), p)) { + out << "clrxdisasm not found\n"; + pclose(p); + goto fail; + } + + do { + out << line; + } while (fgets(line, sizeof(line), p)); + + pclose(p); + } + +fail: + close(fd); + unlink(path); +} + void print_asm(Program *program, std::vector& binary, unsigned exec_size, std::ostream& out) { + if (program->chip_class <= GFX7) { + print_asm_gfx6_gfx7(program, binary, out); + return; + } + std::vector referenced_blocks(program->blocks.size()); referenced_blocks[0] = true; for (Block& block : program->blocks) { @@ -18,7 +103,11 @@ void print_asm(Program *program, std::vector& binary, referenced_blocks[succ] = true; } + #if LLVM_VERSION_MAJOR >= 11 + std::vector symbols; + #else std::vector> symbols; + #endif std::vector> block_names; block_names.reserve(program->blocks.size()); for (Block& block : program->blocks) { @@ -53,7 +142,7 @@ void print_asm(Program *program, std::vector& binary, /* mask out src2 on v_writelane_b32 */ if (((program->chip_class == GFX8 || program->chip_class == GFX9) && (binary[pos] & 0xffff8000) == 0xd28a0000) || - (program->chip_class == GFX10 && (binary[pos] & 0xffff8000) == 0xd7610000)) { + (program->chip_class >= GFX10 && (binary[pos] & 0xffff8000) == 0xd7610000)) { binary[pos+1] = binary[pos+1] & 0xF803FFFF; } @@ -63,8 +152,16 @@ void print_asm(Program *program, std::vector& binary, size_t new_pos; const int align_width = 60; - if (!l && program->chip_class == GFX9 && ((binary[pos] & 0xffff8000) == 0xd1348000)) { /* not actually an invalid instruction */ - out << std::left << std::setw(align_width) << std::setfill(' ') << "\tv_add_u32_e64 + clamp"; + if (!l && + ((program->chip_class >= GFX9 && (binary[pos] & 0xffff8000) == 0xd1348000) || /* v_add_u32_e64 + clamp */ + (program->chip_class >= GFX10 && (binary[pos] & 0xffff8000) == 0xd7038000) || /* v_add_u16_e64 + clamp */ + (program->chip_class <= GFX9 && (binary[pos] & 0xffff8000) == 0xd1268000)) /* v_add_u16_e64 + clamp */) { + out << std::left << std::setw(align_width) << std::setfill(' ') << "\tinteger addition + clamp"; + bool has_literal = program->chip_class >= GFX10 && + (((binary[pos+1] & 0x1ff) == 0xff) || (((binary[pos+1] >> 9) & 0x1ff) == 0xff)); + new_pos = pos + 2 + has_literal; + } else if (program->chip_class >= GFX10 && l == 4 && ((binary[pos] & 0xfe0001ff) == 0x020000f9)) { + out << std::left << std::setw(align_width) << std::setfill(' ') << "\tv_cndmask_b32 + sdwa"; new_pos = pos + 2; } else if (!l) { out << std::left << std::setw(align_width) << std::setfill(' ') << "(invalid instruction)";