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