1 #ifndef __DISASM_H
2 #define __DISASM_H
3 
4 #include <stdio.h>
5 #include <stdint.h>
6 #include <inttypes.h>
7 #include <assert.h>
8 #include <stdbool.h>
9 #include <stdlib.h>
10 #include <string.h>
11 
12 #define BIT(b) (1ull << (b))
13 #define MASK(count) ((1ull << (count)) - 1)
14 #define SEXT(b, count) ((b ^ BIT(count - 1)) - BIT(count - 1))
15 #define UNUSED __attribute__((unused))
16 
17 #define VA_SRC_UNIFORM_TYPE 0x2
18 #define VA_SRC_IMM_TYPE 0x3
19 
20 static inline void
va_print_dest(FILE *fp, uint8_t dest, bool can_mask)21 va_print_dest(FILE *fp, uint8_t dest, bool can_mask)
22 {
23    unsigned mask = (dest >> 6);
24    unsigned value = (dest & 0x3F);
25    fprintf(fp, "r%u", value);
26 
27    /* Should write at least one component */
28    //	assert(mask != 0);
29    //	assert(mask == 0x3 || can_mask);
30 
31    if (mask != 0x3)
32       fprintf(fp, ".h%u", (mask == 1) ? 0 : 1);
33 }
34 
35 void va_disasm_instr(FILE *fp, uint64_t instr);
36 
37 static inline void
disassemble_valhall(FILE *fp, const uint64_t *code, unsigned size, bool verbose)38 disassemble_valhall(FILE *fp, const uint64_t *code, unsigned size, bool verbose)
39 {
40    assert((size & 7) == 0);
41 
42    /* Segment into 8-byte instructions */
43    for (unsigned i = 0; i < (size / 8); ++i) {
44       uint64_t instr = code[i];
45 
46       if (instr == 0) {
47          fprintf(fp, "\n");
48          return;
49       }
50 
51       if (verbose) {
52          /* Print byte pattern */
53          for (unsigned j = 0; j < 8; ++j)
54             fprintf(fp, "%02x ", (uint8_t) (instr >> (j * 8)));
55 
56          fprintf(fp, "   ");
57       } else {
58          /* Print whitespace */
59          fprintf(fp, "   ");
60       }
61 
62       va_disasm_instr(fp, instr);
63       fprintf(fp, "\n");
64 
65       /* Detect branches */
66       uint64_t opcode = (instr >> 48) & MASK(9);
67       bool branchz = (opcode == 0x1F);
68       bool branchzi = (opcode == 0x2F);
69 
70       /* Separate blocks visually by inserting whitespace after branches */
71       if (branchz || branchzi)
72          fprintf(fp, "\n");
73    }
74 
75    fprintf(fp, "\n");
76 }
77 
78 #endif
79