1 /*
2 * Copyright © 2008 Keith Packard
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that copyright
7 * notice and this permission notice appear in supporting documentation, and
8 * that the name of the copyright holders not be used in advertising or
9 * publicity pertaining to distribution of the software without specific,
10 * written prior permission. The copyright holders make no representations
11 * about the suitability of this software for any purpose. It is provided "as
12 * is" without express or implied warranty.
13 *
14 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
20 * OF THIS SOFTWARE.
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <getopt.h>
27 #include <unistd.h>
28
29 #include "gen4asm.h"
30 #include "brw_eu.h"
31 #include "gen8_instruction.h"
32
33 static const struct option longopts[] = {
34 { NULL, 0, NULL, 0 }
35 };
36
37 static struct brw_program *
read_program(FILE * input)38 read_program (FILE *input)
39 {
40 uint32_t inst[4];
41 struct brw_program *program;
42 struct brw_program_instruction *entry, **prev;
43 int c;
44 int n = 0;
45
46 program = malloc (sizeof (struct brw_program));
47 program->first = NULL;
48 prev = &program->first;
49 while ((c = getc (input)) != EOF) {
50 if (c == '0') {
51 if (fscanf (input, "x%x", &inst[n]) == 1) {
52 ++n;
53 if (n == 4) {
54 entry = malloc (sizeof (struct brw_program_instruction));
55 memcpy (&entry->insn, inst, 4 * sizeof (uint32_t));
56 entry->next = NULL;
57 *prev = entry;
58 prev = &entry->next;
59 n = 0;
60 }
61 }
62 }
63 }
64 return program;
65 }
66
67 static struct brw_program *
read_program_binary(FILE * input)68 read_program_binary (FILE *input)
69 {
70 uint32_t temp;
71 uint8_t inst[16];
72 struct brw_program *program;
73 struct brw_program_instruction *entry, **prev;
74 int c;
75 int n = 0;
76
77 program = malloc (sizeof (struct brw_program));
78 program->first = NULL;
79 prev = &program->first;
80 while ((c = getc (input)) != EOF) {
81 if (c == '0') {
82 if (fscanf (input, "x%2x", &temp) == 1) {
83 inst[n++] = (uint8_t)temp;
84 if (n == 16) {
85 entry = malloc (sizeof (struct brw_program_instruction));
86 memcpy (&entry->insn, inst, 16 * sizeof (uint8_t));
87 entry->next = NULL;
88 *prev = entry;
89 prev = &entry->next;
90 n = 0;
91 }
92 }
93 }
94 }
95 return program;
96 }
97
usage(void)98 static void usage(void)
99 {
100 fprintf(stderr, "usage: intel-gen4disasm [options] inputfile\n");
101 fprintf(stderr, "\t-b, --binary C style binary output\n");
102 fprintf(stderr, "\t-o, --output {outputfile} Specify output file\n");
103 fprintf(stderr, "\t-g, --gen <4|5|6|7|8|9> Specify GPU generation\n");
104 }
105
main(int argc,char ** argv)106 int main(int argc, char **argv)
107 {
108 struct brw_program *program;
109 FILE *input = stdin;
110 FILE *output = stdout;
111 char *input_filename = NULL;
112 char *output_file = NULL;
113 int byte_array_input = 0;
114 int o;
115 int gen = 4;
116 struct brw_program_instruction *inst;
117
118 while ((o = getopt_long(argc, argv, "o:bg:", longopts, NULL)) != -1) {
119 switch (o) {
120 case 'o':
121 if (strcmp(optarg, "-") != 0)
122 output_file = optarg;
123 break;
124 case 'b':
125 byte_array_input = 1;
126 break;
127 case 'g':
128 gen = strtol(optarg, NULL, 10);
129
130 if (gen < 4 || gen > 9) {
131 usage();
132 exit(1);
133 }
134
135 break;
136 default:
137 usage();
138 exit(1);
139 }
140 }
141 argc -= optind;
142 argv += optind;
143 if (argc != 1) {
144 usage();
145 exit(1);
146 }
147
148 if (strcmp(argv[0], "-") != 0) {
149 input_filename = argv[0];
150 input = fopen(input_filename, "r");
151 if (input == NULL) {
152 perror("Couldn't open input file");
153 exit(1);
154 }
155 }
156 if (byte_array_input)
157 program = read_program_binary (input);
158 else
159 program = read_program (input);
160 if (!program)
161 exit (1);
162 if (output_file) {
163 output = fopen (output_file, "w");
164 if (output == NULL) {
165 perror("Couldn't open output file");
166 exit(1);
167 }
168 }
169
170 for (inst = program->first; inst; inst = inst->next)
171 if (gen >= 8)
172 gen8_disassemble(output, &inst->insn.gen8, gen);
173 else
174 brw_disasm (output, &inst->insn.gen, gen);
175
176 exit (0);
177 }
178