intel/device: rename gen_get_device_info
[mesa.git] / src / intel / tools / i965_asm.c
1 /*
2 * Copyright © 2018 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *
23 */
24
25 #include <stdio.h>
26 #include <getopt.h>
27 #include "i965_asm.h"
28
29 extern FILE *yyin;
30 struct brw_codegen *p;
31 static int c_literal_output = 0;
32 char *input_filename = NULL;
33 int errors;
34
35 static void
36 print_help(const char *progname, FILE *file)
37 {
38 fprintf(file,
39 "Usage: %s [OPTION] inputfile\n"
40 "Assemble i965 instructions from input file.\n\n"
41 " -h, --help display this help and exit\n"
42 " -l, --c-literal C literal\n"
43 " -o, --output specify output file\n"
44 " --compact print compacted instructions\n"
45 " -g, --gen=platform assemble instructions for given \n"
46 " platform (3 letter platform name)\n"
47 "Example:\n"
48 " i965_asm -g kbl input.asm -o output\n",
49 progname);
50 }
51
52 static void
53 print_instruction(FILE *output, bool compact, const brw_inst *instruction)
54 {
55 int byte_limit;
56
57 byte_limit = (compact == true) ? 8 : 16;
58
59 if (c_literal_output) {
60 fprintf(output, "\t0x%02x,", ((unsigned char *)instruction)[0]);
61
62 for (unsigned i = 1; i < byte_limit; i++)
63 fprintf(output, " 0x%02x,", ((unsigned char *)instruction)[i]);
64 } else {
65 fprintf(output, "%02x", ((unsigned char *)instruction)[0]);
66
67 for (unsigned i = 1; i < byte_limit; i++)
68 fprintf(output, " %02x", ((unsigned char *)instruction)[i]);
69 }
70 fprintf(output, "\n");
71 }
72
73 static struct gen_device_info *
74 i965_disasm_init(uint16_t pci_id)
75 {
76 struct gen_device_info *devinfo;
77
78 devinfo = malloc(sizeof *devinfo);
79 if (devinfo == NULL)
80 return NULL;
81
82 if (!gen_get_device_info_from_pci_id(pci_id, devinfo)) {
83 fprintf(stderr, "can't find device information: pci_id=0x%x\n",
84 pci_id);
85 free(devinfo);
86 return NULL;
87 }
88
89 brw_init_compaction_tables(devinfo);
90
91 return devinfo;
92 }
93
94 int main(int argc, char **argv)
95 {
96 char *output_file = NULL;
97 char c;
98 FILE *output = stdout;
99 bool help = false, compact = false;
100 void *store;
101 uint64_t pci_id = 0;
102 int offset = 0, err;
103 int start_offset = 0;
104 struct disasm_info *disasm_info;
105 struct gen_device_info *devinfo = NULL;
106 int result = EXIT_FAILURE;
107
108 const struct option i965_asm_opts[] = {
109 { "help", no_argument, (int *) &help, true },
110 { "c-literal", no_argument, NULL, 'c' },
111 { "gen", required_argument, NULL, 'g' },
112 { "output", required_argument, NULL, 'o' },
113 { "compact", no_argument, (int *) &compact, true },
114 { NULL, 0, NULL, 0 }
115 };
116
117 while ((c = getopt_long(argc, argv, ":g:o:lh", i965_asm_opts, NULL)) != -1) {
118 switch (c) {
119 case 'g': {
120 const int id = gen_device_name_to_pci_device_id(optarg);
121 if (id < 0) {
122 fprintf(stderr, "can't parse gen: '%s', expected 3 letter "
123 "platform name\n", optarg);
124 goto end;
125 } else {
126 pci_id = id;
127 }
128 break;
129 }
130 case 'h':
131 help = true;
132 print_help(argv[0], stderr);
133 goto end;
134 case 'l':
135 c_literal_output = 1;
136 break;
137 case 'o':
138 output_file = strdup(optarg);
139 break;
140 case 0:
141 break;
142 case ':':
143 fprintf(stderr, "%s: option `-%c' requires an argument\n",
144 argv[0], optopt);
145 goto end;
146 case '?':
147 default:
148 fprintf(stderr, "%s: option `-%c' is invalid: ignored\n",
149 argv[0], optopt);
150 goto end;
151 }
152 }
153
154 if (help || !pci_id) {
155 print_help(argv[0], stderr);
156 goto end;
157 }
158
159 if (!argv[optind]) {
160 fprintf(stderr, "Please specify input file\n");
161 goto end;
162 }
163
164 input_filename = strdup(argv[optind]);
165 yyin = fopen(input_filename, "r");
166 if (!yyin) {
167 fprintf(stderr, "Unable to read input file : %s\n",
168 input_filename);
169 goto end;
170 }
171
172 if (output_file) {
173 output = fopen(output_file, "w");
174 if (!output) {
175 fprintf(stderr, "Couldn't open output file\n");
176 goto end;
177 }
178 }
179
180 devinfo = i965_disasm_init(pci_id);
181 if (!devinfo) {
182 fprintf(stderr, "Unable to allocate memory for "
183 "gen_device_info struct instance.\n");
184 goto end;
185 }
186
187 p = rzalloc(NULL, struct brw_codegen);
188 brw_init_codegen(devinfo, p, p);
189 p->automatic_exec_sizes = false;
190
191 err = yyparse();
192 if (err || errors)
193 goto end;
194
195 store = p->store;
196
197 disasm_info = disasm_initialize(p->devinfo, NULL);
198 if (!disasm_info) {
199 fprintf(stderr, "Unable to initialize disasm_info struct instance\n");
200 goto end;
201 }
202
203 if (c_literal_output)
204 fprintf(output, "static const char gen_eu_bytes[] = {\n");
205
206 brw_validate_instructions(p->devinfo, p->store, 0,
207 p->next_insn_offset, disasm_info);
208
209 const int nr_insn = (p->next_insn_offset - start_offset) / 16;
210
211 if (compact)
212 brw_compact_instructions(p, start_offset, disasm_info);
213
214 for (int i = 0; i < nr_insn; i++) {
215 const brw_inst *insn = store + offset;
216 bool compacted = false;
217
218 if (compact && brw_inst_cmpt_control(p->devinfo, insn)) {
219 offset += 8;
220 compacted = true;
221 } else {
222 offset += 16;
223 }
224
225 print_instruction(output, compacted, insn);
226 }
227
228 ralloc_free(disasm_info);
229
230 if (c_literal_output)
231 fprintf(output, "}");
232
233 result = EXIT_SUCCESS;
234 goto end;
235
236 end:
237 free(input_filename);
238 free(output_file);
239
240 if (yyin)
241 fclose(yyin);
242
243 if (output)
244 fclose(output);
245
246 if (p)
247 ralloc_free(p);
248
249 if (devinfo)
250 free(devinfo);
251
252 exit(result);
253 }