1 /*
2 * Copyright © 2020 Google, Inc.
3 * SPDX-License-Identifier: MIT
4 */
5
6 #include <inttypes.h>
7 #include <stdbool.h>
8 #include <stdint.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <unistd.h>
12
13 #include "util/os_file.h"
14
15 #include "freedreno_dev_info.h"
16 #include "ir3-isa.h"
17
18 static void
disasm_instr_cb(void * d,unsigned n,void * instr)19 disasm_instr_cb(void *d, unsigned n, void *instr)
20 {
21 uint32_t *dwords = (uint32_t *)instr;
22 printf("%3d[%08x_%08x] ", n, dwords[1], dwords[0]);
23 }
24
25 static void
usage(const char * prog)26 usage(const char *prog)
27 {
28 fprintf(stderr,
29 "Usage: %s [-g GPU_ID | -c CHIP_ID] [-x HEX | FILE]\n"
30 " -g GPU_ID: specify GPU ID\n"
31 " -c CHIP_ID: specify GPU chip ID in hex\n"
32 " -x HEX: disassemble instruction encoded as HEX\n",
33 prog);
34 }
35
36 int
main(int argc,char ** argv)37 main(int argc, char **argv)
38 {
39 size_t sz;
40 void *raw = NULL;
41 uint64_t raw_hex;
42 const struct fd_dev_info *info = NULL;
43 int opt;
44
45 while ((opt = getopt(argc, argv, "g:c:x:")) != -1) {
46 switch (opt) {
47 case 'g':
48 info = fd_dev_info_raw_by_name(optarg);
49 if (!info) {
50 fprintf(stderr, "Unknown GPU name: %s\n", optarg);
51 usage(argv[0]);
52 return EXIT_FAILURE;
53 }
54 break;
55 case 'c': {
56 uint64_t chip_id;
57 if (sscanf(optarg, "%" PRIx64, &chip_id) != 1) {
58 fprintf(stderr, "Invalid chip ID: %s\n", optarg);
59 usage(argv[0]);
60 return EXIT_FAILURE;
61 }
62
63 struct fd_dev_id id = {.chip_id = chip_id};
64 info = fd_dev_info_raw(&id);
65 if (!info) {
66 fprintf(stderr, "Unknown chip ID: %s\n", optarg);
67 usage(argv[0]);
68 return EXIT_FAILURE;
69 }
70 break;
71 }
72 case 'x':
73 if (sscanf(optarg, "%" PRIx64, &raw_hex) != 1) {
74 fprintf(stderr, "Invalid hex number: %s\n", optarg);
75 usage(argv[0]);
76 return EXIT_FAILURE;
77 }
78
79 raw = &raw_hex;
80 sz = sizeof(raw_hex);
81 break;
82 default:
83 usage(argv[0]);
84 return EXIT_FAILURE;
85 }
86 }
87
88 if (!raw) {
89 if (optind >= argc) {
90 fprintf(stderr, "No file specified\n");
91 usage(argv[0]);
92 return EXIT_FAILURE;
93 }
94
95 raw = os_read_file(argv[optind], &sz);
96 }
97
98 unsigned chip = info ? info->chip : 7;
99
100 ir3_isa_disasm(raw, sz, stdout,
101 &(struct isa_decode_options){
102 .show_errors = true,
103 .branch_labels = true,
104 .pre_instr_cb = disasm_instr_cb,
105 .gpu_id = chip * 100,
106 });
107
108 return 0;
109 }
110