1*d83cc019SAndroid Build Coastguard Worker /* -*- c-basic-offset: 8 -*- */
2*d83cc019SAndroid Build Coastguard Worker /*
3*d83cc019SAndroid Build Coastguard Worker * Copyright © 2006 Intel Corporation
4*d83cc019SAndroid Build Coastguard Worker *
5*d83cc019SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
6*d83cc019SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
7*d83cc019SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
8*d83cc019SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9*d83cc019SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
10*d83cc019SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
11*d83cc019SAndroid Build Coastguard Worker *
12*d83cc019SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
13*d83cc019SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
14*d83cc019SAndroid Build Coastguard Worker * Software.
15*d83cc019SAndroid Build Coastguard Worker *
16*d83cc019SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*d83cc019SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*d83cc019SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19*d83cc019SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20*d83cc019SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21*d83cc019SAndroid Build Coastguard Worker * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22*d83cc019SAndroid Build Coastguard Worker * SOFTWARE.
23*d83cc019SAndroid Build Coastguard Worker *
24*d83cc019SAndroid Build Coastguard Worker * Authors:
25*d83cc019SAndroid Build Coastguard Worker * Eric Anholt <[email protected]>
26*d83cc019SAndroid Build Coastguard Worker *
27*d83cc019SAndroid Build Coastguard Worker */
28*d83cc019SAndroid Build Coastguard Worker
29*d83cc019SAndroid Build Coastguard Worker #include <stdio.h>
30*d83cc019SAndroid Build Coastguard Worker #include <stdlib.h>
31*d83cc019SAndroid Build Coastguard Worker #include <string.h>
32*d83cc019SAndroid Build Coastguard Worker #include <getopt.h>
33*d83cc019SAndroid Build Coastguard Worker #include <unistd.h>
34*d83cc019SAndroid Build Coastguard Worker #include <assert.h>
35*d83cc019SAndroid Build Coastguard Worker
36*d83cc019SAndroid Build Coastguard Worker #include "ralloc.h"
37*d83cc019SAndroid Build Coastguard Worker #include "gen4asm.h"
38*d83cc019SAndroid Build Coastguard Worker #include "brw_eu.h"
39*d83cc019SAndroid Build Coastguard Worker
40*d83cc019SAndroid Build Coastguard Worker extern FILE *yyin;
41*d83cc019SAndroid Build Coastguard Worker extern void set_branch_two_offsets(struct brw_program_instruction *insn, int jip_offset, int uip_offset);
42*d83cc019SAndroid Build Coastguard Worker extern void set_branch_one_offset(struct brw_program_instruction *insn, int jip_offset);
43*d83cc019SAndroid Build Coastguard Worker
44*d83cc019SAndroid Build Coastguard Worker long int gen_level = 40;
45*d83cc019SAndroid Build Coastguard Worker int advanced_flag = 0; /* 0: in unit of byte, 1: in unit of data element size */
46*d83cc019SAndroid Build Coastguard Worker unsigned int warning_flags = WARN_ALWAYS;
47*d83cc019SAndroid Build Coastguard Worker int need_export = 0;
48*d83cc019SAndroid Build Coastguard Worker char *input_filename = "<stdin>";
49*d83cc019SAndroid Build Coastguard Worker int errors;
50*d83cc019SAndroid Build Coastguard Worker
51*d83cc019SAndroid Build Coastguard Worker struct brw_context genasm_brw_context;
52*d83cc019SAndroid Build Coastguard Worker struct brw_compile genasm_compile;
53*d83cc019SAndroid Build Coastguard Worker
54*d83cc019SAndroid Build Coastguard Worker struct brw_program compiled_program;
55*d83cc019SAndroid Build Coastguard Worker struct program_defaults program_defaults = {.register_type = BRW_REGISTER_TYPE_F};
56*d83cc019SAndroid Build Coastguard Worker
57*d83cc019SAndroid Build Coastguard Worker /* 0: default output style, 1: nice C-style output */
58*d83cc019SAndroid Build Coastguard Worker static int binary_like_output = 0;
59*d83cc019SAndroid Build Coastguard Worker static char *export_filename = NULL;
60*d83cc019SAndroid Build Coastguard Worker static const char binary_prepend[] = "static const char gen_eu_bytes[] = {\n";
61*d83cc019SAndroid Build Coastguard Worker
62*d83cc019SAndroid Build Coastguard Worker #define HASH_SIZE 37
63*d83cc019SAndroid Build Coastguard Worker
64*d83cc019SAndroid Build Coastguard Worker struct hash_item {
65*d83cc019SAndroid Build Coastguard Worker char *key;
66*d83cc019SAndroid Build Coastguard Worker void *value;
67*d83cc019SAndroid Build Coastguard Worker struct hash_item *next;
68*d83cc019SAndroid Build Coastguard Worker };
69*d83cc019SAndroid Build Coastguard Worker
70*d83cc019SAndroid Build Coastguard Worker typedef struct hash_item *hash_table[HASH_SIZE];
71*d83cc019SAndroid Build Coastguard Worker
72*d83cc019SAndroid Build Coastguard Worker static hash_table declared_register_table;
73*d83cc019SAndroid Build Coastguard Worker
74*d83cc019SAndroid Build Coastguard Worker struct label_item {
75*d83cc019SAndroid Build Coastguard Worker char *name;
76*d83cc019SAndroid Build Coastguard Worker int addr;
77*d83cc019SAndroid Build Coastguard Worker struct label_item *next;
78*d83cc019SAndroid Build Coastguard Worker };
79*d83cc019SAndroid Build Coastguard Worker static struct label_item *label_table;
80*d83cc019SAndroid Build Coastguard Worker
81*d83cc019SAndroid Build Coastguard Worker static const struct option longopts[] = {
82*d83cc019SAndroid Build Coastguard Worker {"advanced", no_argument, 0, 'a'},
83*d83cc019SAndroid Build Coastguard Worker {"binary", no_argument, 0, 'b'},
84*d83cc019SAndroid Build Coastguard Worker {"export", required_argument, 0, 'e'},
85*d83cc019SAndroid Build Coastguard Worker {"input_list", required_argument, 0, 'l'},
86*d83cc019SAndroid Build Coastguard Worker {"output", required_argument, 0, 'o'},
87*d83cc019SAndroid Build Coastguard Worker {"gen", required_argument, 0, 'g'},
88*d83cc019SAndroid Build Coastguard Worker { NULL, 0, NULL, 0 }
89*d83cc019SAndroid Build Coastguard Worker };
90*d83cc019SAndroid Build Coastguard Worker
usage(void)91*d83cc019SAndroid Build Coastguard Worker static void usage(void)
92*d83cc019SAndroid Build Coastguard Worker {
93*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "usage: intel-gen4asm [options] inputfile\n");
94*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "OPTIONS:\n");
95*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "\t-a, --advanced Set advanced flag\n");
96*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "\t-b, --binary C style binary output\n");
97*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "\t-e, --export {exportfile} Export label file\n");
98*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "\t-l, --input_list {entrytablefile} Input entry_table_list file\n");
99*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "\t-o, --output {outputfile} Specify output file\n");
100*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "\t-g, --gen <4|5|6|7|8|9> Specify GPU generation\n");
101*d83cc019SAndroid Build Coastguard Worker }
102*d83cc019SAndroid Build Coastguard Worker
hash(char * key)103*d83cc019SAndroid Build Coastguard Worker static int hash(char *key)
104*d83cc019SAndroid Build Coastguard Worker {
105*d83cc019SAndroid Build Coastguard Worker unsigned ret = 0;
106*d83cc019SAndroid Build Coastguard Worker while(*key)
107*d83cc019SAndroid Build Coastguard Worker ret = (ret << 1) + (*key++);
108*d83cc019SAndroid Build Coastguard Worker return ret % HASH_SIZE;
109*d83cc019SAndroid Build Coastguard Worker }
110*d83cc019SAndroid Build Coastguard Worker
find_hash_item(hash_table t,char * key)111*d83cc019SAndroid Build Coastguard Worker static void *find_hash_item(hash_table t, char *key)
112*d83cc019SAndroid Build Coastguard Worker {
113*d83cc019SAndroid Build Coastguard Worker struct hash_item *p;
114*d83cc019SAndroid Build Coastguard Worker for(p = t[hash(key)]; p; p = p->next)
115*d83cc019SAndroid Build Coastguard Worker if(strcasecmp(p->key, key) == 0)
116*d83cc019SAndroid Build Coastguard Worker return p->value;
117*d83cc019SAndroid Build Coastguard Worker return NULL;
118*d83cc019SAndroid Build Coastguard Worker }
119*d83cc019SAndroid Build Coastguard Worker
insert_hash_item(hash_table t,char * key,void * v)120*d83cc019SAndroid Build Coastguard Worker static void insert_hash_item(hash_table t, char *key, void *v)
121*d83cc019SAndroid Build Coastguard Worker {
122*d83cc019SAndroid Build Coastguard Worker int index = hash(key);
123*d83cc019SAndroid Build Coastguard Worker struct hash_item *p = malloc(sizeof(*p));
124*d83cc019SAndroid Build Coastguard Worker p->key = key;
125*d83cc019SAndroid Build Coastguard Worker p->value = v;
126*d83cc019SAndroid Build Coastguard Worker p->next = t[index];
127*d83cc019SAndroid Build Coastguard Worker t[index] = p;
128*d83cc019SAndroid Build Coastguard Worker }
129*d83cc019SAndroid Build Coastguard Worker
free_hash_table(hash_table t)130*d83cc019SAndroid Build Coastguard Worker static void free_hash_table(hash_table t)
131*d83cc019SAndroid Build Coastguard Worker {
132*d83cc019SAndroid Build Coastguard Worker struct hash_item *p, *next;
133*d83cc019SAndroid Build Coastguard Worker int i;
134*d83cc019SAndroid Build Coastguard Worker for (i = 0; i < HASH_SIZE; i++) {
135*d83cc019SAndroid Build Coastguard Worker p = t[i];
136*d83cc019SAndroid Build Coastguard Worker while(p) {
137*d83cc019SAndroid Build Coastguard Worker next = p->next;
138*d83cc019SAndroid Build Coastguard Worker free(p->key);
139*d83cc019SAndroid Build Coastguard Worker free(p->value);
140*d83cc019SAndroid Build Coastguard Worker free(p);
141*d83cc019SAndroid Build Coastguard Worker p = next;
142*d83cc019SAndroid Build Coastguard Worker }
143*d83cc019SAndroid Build Coastguard Worker }
144*d83cc019SAndroid Build Coastguard Worker }
145*d83cc019SAndroid Build Coastguard Worker
find_register(char * name)146*d83cc019SAndroid Build Coastguard Worker struct declared_register *find_register(char *name)
147*d83cc019SAndroid Build Coastguard Worker {
148*d83cc019SAndroid Build Coastguard Worker return find_hash_item(declared_register_table, name);
149*d83cc019SAndroid Build Coastguard Worker }
150*d83cc019SAndroid Build Coastguard Worker
insert_register(struct declared_register * reg)151*d83cc019SAndroid Build Coastguard Worker void insert_register(struct declared_register *reg)
152*d83cc019SAndroid Build Coastguard Worker {
153*d83cc019SAndroid Build Coastguard Worker insert_hash_item(declared_register_table, reg->name, reg);
154*d83cc019SAndroid Build Coastguard Worker }
155*d83cc019SAndroid Build Coastguard Worker
add_label(struct brw_program_instruction * i)156*d83cc019SAndroid Build Coastguard Worker static void add_label(struct brw_program_instruction *i)
157*d83cc019SAndroid Build Coastguard Worker {
158*d83cc019SAndroid Build Coastguard Worker struct label_item **p = &label_table;
159*d83cc019SAndroid Build Coastguard Worker
160*d83cc019SAndroid Build Coastguard Worker assert(is_label(i));
161*d83cc019SAndroid Build Coastguard Worker
162*d83cc019SAndroid Build Coastguard Worker while(*p)
163*d83cc019SAndroid Build Coastguard Worker p = &((*p)->next);
164*d83cc019SAndroid Build Coastguard Worker *p = calloc(1, sizeof(**p));
165*d83cc019SAndroid Build Coastguard Worker (*p)->name = label_name(i);
166*d83cc019SAndroid Build Coastguard Worker (*p)->addr = i->inst_offset;
167*d83cc019SAndroid Build Coastguard Worker }
168*d83cc019SAndroid Build Coastguard Worker
169*d83cc019SAndroid Build Coastguard Worker /* Some assembly code have duplicated labels.
170*d83cc019SAndroid Build Coastguard Worker Start from start_addr. Search as a loop. Return the first label found. */
label_to_addr(char * name,int start_addr)171*d83cc019SAndroid Build Coastguard Worker static int label_to_addr(char *name, int start_addr)
172*d83cc019SAndroid Build Coastguard Worker {
173*d83cc019SAndroid Build Coastguard Worker /* return the first label just after start_addr, or the first label from the head */
174*d83cc019SAndroid Build Coastguard Worker struct label_item *p;
175*d83cc019SAndroid Build Coastguard Worker int r = -1;
176*d83cc019SAndroid Build Coastguard Worker for(p = label_table; p; p = p->next) {
177*d83cc019SAndroid Build Coastguard Worker if(strcmp(p->name, name) == 0) {
178*d83cc019SAndroid Build Coastguard Worker if(p->addr >= start_addr) // the first label just after start_addr
179*d83cc019SAndroid Build Coastguard Worker return p->addr;
180*d83cc019SAndroid Build Coastguard Worker else if(r == -1) // the first label from the head
181*d83cc019SAndroid Build Coastguard Worker r = p->addr;
182*d83cc019SAndroid Build Coastguard Worker }
183*d83cc019SAndroid Build Coastguard Worker }
184*d83cc019SAndroid Build Coastguard Worker if(r == -1) {
185*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "Can't find label %s\n", name);
186*d83cc019SAndroid Build Coastguard Worker exit(1);
187*d83cc019SAndroid Build Coastguard Worker }
188*d83cc019SAndroid Build Coastguard Worker return r;
189*d83cc019SAndroid Build Coastguard Worker }
190*d83cc019SAndroid Build Coastguard Worker
free_label_table(struct label_item * p)191*d83cc019SAndroid Build Coastguard Worker static void free_label_table(struct label_item *p)
192*d83cc019SAndroid Build Coastguard Worker {
193*d83cc019SAndroid Build Coastguard Worker if(p) {
194*d83cc019SAndroid Build Coastguard Worker free_label_table(p->next);
195*d83cc019SAndroid Build Coastguard Worker free(p);
196*d83cc019SAndroid Build Coastguard Worker }
197*d83cc019SAndroid Build Coastguard Worker }
198*d83cc019SAndroid Build Coastguard Worker
199*d83cc019SAndroid Build Coastguard Worker struct entry_point_item {
200*d83cc019SAndroid Build Coastguard Worker char *str;
201*d83cc019SAndroid Build Coastguard Worker struct entry_point_item *next;
202*d83cc019SAndroid Build Coastguard Worker } *entry_point_table;
203*d83cc019SAndroid Build Coastguard Worker
read_entry_file(char * fn)204*d83cc019SAndroid Build Coastguard Worker static int read_entry_file(char *fn)
205*d83cc019SAndroid Build Coastguard Worker {
206*d83cc019SAndroid Build Coastguard Worker FILE *entry_table_file;
207*d83cc019SAndroid Build Coastguard Worker char buf[2048];
208*d83cc019SAndroid Build Coastguard Worker struct entry_point_item **p = &entry_point_table;
209*d83cc019SAndroid Build Coastguard Worker if (!fn)
210*d83cc019SAndroid Build Coastguard Worker return 0;
211*d83cc019SAndroid Build Coastguard Worker if ((entry_table_file = fopen(fn, "r")) == NULL)
212*d83cc019SAndroid Build Coastguard Worker return -1;
213*d83cc019SAndroid Build Coastguard Worker while (fgets(buf, sizeof(buf)-1, entry_table_file) != NULL) {
214*d83cc019SAndroid Build Coastguard Worker // drop the final char '\n'
215*d83cc019SAndroid Build Coastguard Worker if(buf[strlen(buf)-1] == '\n')
216*d83cc019SAndroid Build Coastguard Worker buf[strlen(buf)-1] = 0;
217*d83cc019SAndroid Build Coastguard Worker *p = calloc(1, sizeof(struct entry_point_item));
218*d83cc019SAndroid Build Coastguard Worker (*p)->str = strdup(buf);
219*d83cc019SAndroid Build Coastguard Worker p = &((*p)->next);
220*d83cc019SAndroid Build Coastguard Worker }
221*d83cc019SAndroid Build Coastguard Worker fclose(entry_table_file);
222*d83cc019SAndroid Build Coastguard Worker return 0;
223*d83cc019SAndroid Build Coastguard Worker }
224*d83cc019SAndroid Build Coastguard Worker
is_entry_point(struct brw_program_instruction * i)225*d83cc019SAndroid Build Coastguard Worker static int is_entry_point(struct brw_program_instruction *i)
226*d83cc019SAndroid Build Coastguard Worker {
227*d83cc019SAndroid Build Coastguard Worker struct entry_point_item *p;
228*d83cc019SAndroid Build Coastguard Worker
229*d83cc019SAndroid Build Coastguard Worker assert(i->type == GEN4ASM_INSTRUCTION_LABEL);
230*d83cc019SAndroid Build Coastguard Worker
231*d83cc019SAndroid Build Coastguard Worker for (p = entry_point_table; p; p = p->next) {
232*d83cc019SAndroid Build Coastguard Worker if (strcmp(p->str, i->insn.label.name) == 0)
233*d83cc019SAndroid Build Coastguard Worker return 1;
234*d83cc019SAndroid Build Coastguard Worker }
235*d83cc019SAndroid Build Coastguard Worker return 0;
236*d83cc019SAndroid Build Coastguard Worker }
237*d83cc019SAndroid Build Coastguard Worker
free_entry_point_table(struct entry_point_item * p)238*d83cc019SAndroid Build Coastguard Worker static void free_entry_point_table(struct entry_point_item *p) {
239*d83cc019SAndroid Build Coastguard Worker if (p) {
240*d83cc019SAndroid Build Coastguard Worker free_entry_point_table(p->next);
241*d83cc019SAndroid Build Coastguard Worker free(p->str);
242*d83cc019SAndroid Build Coastguard Worker free(p);
243*d83cc019SAndroid Build Coastguard Worker }
244*d83cc019SAndroid Build Coastguard Worker }
245*d83cc019SAndroid Build Coastguard Worker
246*d83cc019SAndroid Build Coastguard Worker static void
print_instruction(FILE * output,struct brw_instruction * instruction)247*d83cc019SAndroid Build Coastguard Worker print_instruction(FILE *output, struct brw_instruction *instruction)
248*d83cc019SAndroid Build Coastguard Worker {
249*d83cc019SAndroid Build Coastguard Worker if (binary_like_output) {
250*d83cc019SAndroid Build Coastguard Worker fprintf(output, "\t0x%02x, 0x%02x, 0x%02x, 0x%02x, "
251*d83cc019SAndroid Build Coastguard Worker "0x%02x, 0x%02x, 0x%02x, 0x%02x,\n"
252*d83cc019SAndroid Build Coastguard Worker "\t0x%02x, 0x%02x, 0x%02x, 0x%02x, "
253*d83cc019SAndroid Build Coastguard Worker "0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
254*d83cc019SAndroid Build Coastguard Worker ((unsigned char *)instruction)[0],
255*d83cc019SAndroid Build Coastguard Worker ((unsigned char *)instruction)[1],
256*d83cc019SAndroid Build Coastguard Worker ((unsigned char *)instruction)[2],
257*d83cc019SAndroid Build Coastguard Worker ((unsigned char *)instruction)[3],
258*d83cc019SAndroid Build Coastguard Worker ((unsigned char *)instruction)[4],
259*d83cc019SAndroid Build Coastguard Worker ((unsigned char *)instruction)[5],
260*d83cc019SAndroid Build Coastguard Worker ((unsigned char *)instruction)[6],
261*d83cc019SAndroid Build Coastguard Worker ((unsigned char *)instruction)[7],
262*d83cc019SAndroid Build Coastguard Worker ((unsigned char *)instruction)[8],
263*d83cc019SAndroid Build Coastguard Worker ((unsigned char *)instruction)[9],
264*d83cc019SAndroid Build Coastguard Worker ((unsigned char *)instruction)[10],
265*d83cc019SAndroid Build Coastguard Worker ((unsigned char *)instruction)[11],
266*d83cc019SAndroid Build Coastguard Worker ((unsigned char *)instruction)[12],
267*d83cc019SAndroid Build Coastguard Worker ((unsigned char *)instruction)[13],
268*d83cc019SAndroid Build Coastguard Worker ((unsigned char *)instruction)[14],
269*d83cc019SAndroid Build Coastguard Worker ((unsigned char *)instruction)[15]);
270*d83cc019SAndroid Build Coastguard Worker } else {
271*d83cc019SAndroid Build Coastguard Worker fprintf(output, " { 0x%08x, 0x%08x, 0x%08x, 0x%08x },\n",
272*d83cc019SAndroid Build Coastguard Worker ((int *)instruction)[0],
273*d83cc019SAndroid Build Coastguard Worker ((int *)instruction)[1],
274*d83cc019SAndroid Build Coastguard Worker ((int *)instruction)[2],
275*d83cc019SAndroid Build Coastguard Worker ((int *)instruction)[3]);
276*d83cc019SAndroid Build Coastguard Worker }
277*d83cc019SAndroid Build Coastguard Worker }
main(int argc,char ** argv)278*d83cc019SAndroid Build Coastguard Worker int main(int argc, char **argv)
279*d83cc019SAndroid Build Coastguard Worker {
280*d83cc019SAndroid Build Coastguard Worker char *output_file = NULL;
281*d83cc019SAndroid Build Coastguard Worker char *entry_table_file = NULL;
282*d83cc019SAndroid Build Coastguard Worker FILE *output = stdout;
283*d83cc019SAndroid Build Coastguard Worker FILE *export_file;
284*d83cc019SAndroid Build Coastguard Worker struct brw_program_instruction *entry, *entry1, *tmp_entry;
285*d83cc019SAndroid Build Coastguard Worker int err, inst_offset;
286*d83cc019SAndroid Build Coastguard Worker char o;
287*d83cc019SAndroid Build Coastguard Worker void *mem_ctx;
288*d83cc019SAndroid Build Coastguard Worker
289*d83cc019SAndroid Build Coastguard Worker while ((o = getopt_long(argc, argv, "e:l:o:g:abW", longopts, NULL)) != -1) {
290*d83cc019SAndroid Build Coastguard Worker switch (o) {
291*d83cc019SAndroid Build Coastguard Worker case 'o':
292*d83cc019SAndroid Build Coastguard Worker if (strcmp(optarg, "-") != 0)
293*d83cc019SAndroid Build Coastguard Worker output_file = optarg;
294*d83cc019SAndroid Build Coastguard Worker
295*d83cc019SAndroid Build Coastguard Worker break;
296*d83cc019SAndroid Build Coastguard Worker
297*d83cc019SAndroid Build Coastguard Worker case 'g': {
298*d83cc019SAndroid Build Coastguard Worker char *dec_ptr, *end_ptr;
299*d83cc019SAndroid Build Coastguard Worker unsigned long decimal;
300*d83cc019SAndroid Build Coastguard Worker
301*d83cc019SAndroid Build Coastguard Worker gen_level = strtol(optarg, &dec_ptr, 10) * 10;
302*d83cc019SAndroid Build Coastguard Worker
303*d83cc019SAndroid Build Coastguard Worker if (*dec_ptr == '.') {
304*d83cc019SAndroid Build Coastguard Worker decimal = strtoul(++dec_ptr, &end_ptr, 10);
305*d83cc019SAndroid Build Coastguard Worker if (end_ptr != dec_ptr && *end_ptr == '\0') {
306*d83cc019SAndroid Build Coastguard Worker if (decimal > 10) {
307*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "Invalid Gen X decimal version\n");
308*d83cc019SAndroid Build Coastguard Worker exit(1);
309*d83cc019SAndroid Build Coastguard Worker }
310*d83cc019SAndroid Build Coastguard Worker gen_level += decimal;
311*d83cc019SAndroid Build Coastguard Worker }
312*d83cc019SAndroid Build Coastguard Worker }
313*d83cc019SAndroid Build Coastguard Worker
314*d83cc019SAndroid Build Coastguard Worker if (gen_level < 40 || gen_level > 90) {
315*d83cc019SAndroid Build Coastguard Worker usage();
316*d83cc019SAndroid Build Coastguard Worker exit(1);
317*d83cc019SAndroid Build Coastguard Worker }
318*d83cc019SAndroid Build Coastguard Worker
319*d83cc019SAndroid Build Coastguard Worker break;
320*d83cc019SAndroid Build Coastguard Worker }
321*d83cc019SAndroid Build Coastguard Worker
322*d83cc019SAndroid Build Coastguard Worker case 'a':
323*d83cc019SAndroid Build Coastguard Worker advanced_flag = 1;
324*d83cc019SAndroid Build Coastguard Worker break;
325*d83cc019SAndroid Build Coastguard Worker case 'b':
326*d83cc019SAndroid Build Coastguard Worker binary_like_output = 1;
327*d83cc019SAndroid Build Coastguard Worker break;
328*d83cc019SAndroid Build Coastguard Worker
329*d83cc019SAndroid Build Coastguard Worker case 'e':
330*d83cc019SAndroid Build Coastguard Worker need_export = 1;
331*d83cc019SAndroid Build Coastguard Worker if (strcmp(optarg, "-") != 0)
332*d83cc019SAndroid Build Coastguard Worker export_filename = optarg;
333*d83cc019SAndroid Build Coastguard Worker break;
334*d83cc019SAndroid Build Coastguard Worker
335*d83cc019SAndroid Build Coastguard Worker case 'l':
336*d83cc019SAndroid Build Coastguard Worker if (strcmp(optarg, "-") != 0)
337*d83cc019SAndroid Build Coastguard Worker entry_table_file = optarg;
338*d83cc019SAndroid Build Coastguard Worker break;
339*d83cc019SAndroid Build Coastguard Worker
340*d83cc019SAndroid Build Coastguard Worker case 'W':
341*d83cc019SAndroid Build Coastguard Worker warning_flags |= WARN_ALL;
342*d83cc019SAndroid Build Coastguard Worker break;
343*d83cc019SAndroid Build Coastguard Worker
344*d83cc019SAndroid Build Coastguard Worker default:
345*d83cc019SAndroid Build Coastguard Worker usage();
346*d83cc019SAndroid Build Coastguard Worker exit(1);
347*d83cc019SAndroid Build Coastguard Worker }
348*d83cc019SAndroid Build Coastguard Worker }
349*d83cc019SAndroid Build Coastguard Worker argc -= optind;
350*d83cc019SAndroid Build Coastguard Worker argv += optind;
351*d83cc019SAndroid Build Coastguard Worker if (argc != 1) {
352*d83cc019SAndroid Build Coastguard Worker usage();
353*d83cc019SAndroid Build Coastguard Worker exit(1);
354*d83cc019SAndroid Build Coastguard Worker }
355*d83cc019SAndroid Build Coastguard Worker
356*d83cc019SAndroid Build Coastguard Worker if (strcmp(argv[0], "-") != 0) {
357*d83cc019SAndroid Build Coastguard Worker input_filename = argv[0];
358*d83cc019SAndroid Build Coastguard Worker yyin = fopen(input_filename, "r");
359*d83cc019SAndroid Build Coastguard Worker if (yyin == NULL) {
360*d83cc019SAndroid Build Coastguard Worker perror("Couldn't open input file");
361*d83cc019SAndroid Build Coastguard Worker exit(1);
362*d83cc019SAndroid Build Coastguard Worker }
363*d83cc019SAndroid Build Coastguard Worker }
364*d83cc019SAndroid Build Coastguard Worker
365*d83cc019SAndroid Build Coastguard Worker brw_init_context(&genasm_brw_context, gen_level);
366*d83cc019SAndroid Build Coastguard Worker mem_ctx = ralloc_context(NULL);
367*d83cc019SAndroid Build Coastguard Worker brw_init_compile(&genasm_brw_context, &genasm_compile, mem_ctx);
368*d83cc019SAndroid Build Coastguard Worker
369*d83cc019SAndroid Build Coastguard Worker err = yyparse();
370*d83cc019SAndroid Build Coastguard Worker
371*d83cc019SAndroid Build Coastguard Worker if (strcmp(argv[0], "-"))
372*d83cc019SAndroid Build Coastguard Worker fclose(yyin);
373*d83cc019SAndroid Build Coastguard Worker
374*d83cc019SAndroid Build Coastguard Worker yylex_destroy();
375*d83cc019SAndroid Build Coastguard Worker
376*d83cc019SAndroid Build Coastguard Worker if (err || errors)
377*d83cc019SAndroid Build Coastguard Worker exit (1);
378*d83cc019SAndroid Build Coastguard Worker
379*d83cc019SAndroid Build Coastguard Worker if (output_file) {
380*d83cc019SAndroid Build Coastguard Worker output = fopen(output_file, "w");
381*d83cc019SAndroid Build Coastguard Worker if (output == NULL) {
382*d83cc019SAndroid Build Coastguard Worker perror("Couldn't open output file");
383*d83cc019SAndroid Build Coastguard Worker exit(1);
384*d83cc019SAndroid Build Coastguard Worker }
385*d83cc019SAndroid Build Coastguard Worker
386*d83cc019SAndroid Build Coastguard Worker }
387*d83cc019SAndroid Build Coastguard Worker
388*d83cc019SAndroid Build Coastguard Worker if (read_entry_file(entry_table_file)) {
389*d83cc019SAndroid Build Coastguard Worker fprintf(stderr, "Read entry file error\n");
390*d83cc019SAndroid Build Coastguard Worker exit(1);
391*d83cc019SAndroid Build Coastguard Worker }
392*d83cc019SAndroid Build Coastguard Worker inst_offset = 0 ;
393*d83cc019SAndroid Build Coastguard Worker for (entry = compiled_program.first;
394*d83cc019SAndroid Build Coastguard Worker entry != NULL; entry = entry->next) {
395*d83cc019SAndroid Build Coastguard Worker entry->inst_offset = inst_offset;
396*d83cc019SAndroid Build Coastguard Worker entry1 = entry->next;
397*d83cc019SAndroid Build Coastguard Worker if (entry1 && is_label(entry1) && is_entry_point(entry1)) {
398*d83cc019SAndroid Build Coastguard Worker // insert NOP instructions until (inst_offset+1) % 4 == 0
399*d83cc019SAndroid Build Coastguard Worker while (((inst_offset+1) % 4) != 0) {
400*d83cc019SAndroid Build Coastguard Worker tmp_entry = calloc(sizeof(*tmp_entry), 1);
401*d83cc019SAndroid Build Coastguard Worker tmp_entry->insn.gen.header.opcode = BRW_OPCODE_NOP;
402*d83cc019SAndroid Build Coastguard Worker entry->next = tmp_entry;
403*d83cc019SAndroid Build Coastguard Worker tmp_entry->next = entry1;
404*d83cc019SAndroid Build Coastguard Worker entry = tmp_entry;
405*d83cc019SAndroid Build Coastguard Worker tmp_entry->inst_offset = ++inst_offset;
406*d83cc019SAndroid Build Coastguard Worker }
407*d83cc019SAndroid Build Coastguard Worker }
408*d83cc019SAndroid Build Coastguard Worker if (!is_label(entry))
409*d83cc019SAndroid Build Coastguard Worker inst_offset++;
410*d83cc019SAndroid Build Coastguard Worker }
411*d83cc019SAndroid Build Coastguard Worker
412*d83cc019SAndroid Build Coastguard Worker for (entry = compiled_program.first; entry; entry = entry->next)
413*d83cc019SAndroid Build Coastguard Worker if (is_label(entry))
414*d83cc019SAndroid Build Coastguard Worker add_label(entry);
415*d83cc019SAndroid Build Coastguard Worker
416*d83cc019SAndroid Build Coastguard Worker if (need_export) {
417*d83cc019SAndroid Build Coastguard Worker if (export_filename) {
418*d83cc019SAndroid Build Coastguard Worker export_file = fopen(export_filename, "w");
419*d83cc019SAndroid Build Coastguard Worker } else {
420*d83cc019SAndroid Build Coastguard Worker export_file = fopen("export.inc", "w");
421*d83cc019SAndroid Build Coastguard Worker }
422*d83cc019SAndroid Build Coastguard Worker for (entry = compiled_program.first;
423*d83cc019SAndroid Build Coastguard Worker entry != NULL; entry = entry->next) {
424*d83cc019SAndroid Build Coastguard Worker if (is_label(entry))
425*d83cc019SAndroid Build Coastguard Worker fprintf(export_file, "#define %s_IP %d\n",
426*d83cc019SAndroid Build Coastguard Worker label_name(entry), (IS_GENx(5) ? 2 : 1)*(entry->inst_offset));
427*d83cc019SAndroid Build Coastguard Worker }
428*d83cc019SAndroid Build Coastguard Worker fclose(export_file);
429*d83cc019SAndroid Build Coastguard Worker }
430*d83cc019SAndroid Build Coastguard Worker
431*d83cc019SAndroid Build Coastguard Worker for (entry = compiled_program.first; entry; entry = entry->next) {
432*d83cc019SAndroid Build Coastguard Worker struct relocation *reloc = &entry->reloc;
433*d83cc019SAndroid Build Coastguard Worker
434*d83cc019SAndroid Build Coastguard Worker if (!is_relocatable(entry))
435*d83cc019SAndroid Build Coastguard Worker continue;
436*d83cc019SAndroid Build Coastguard Worker
437*d83cc019SAndroid Build Coastguard Worker if (reloc->first_reloc_target)
438*d83cc019SAndroid Build Coastguard Worker reloc->first_reloc_offset = label_to_addr(reloc->first_reloc_target, entry->inst_offset) - entry->inst_offset;
439*d83cc019SAndroid Build Coastguard Worker
440*d83cc019SAndroid Build Coastguard Worker if (reloc->second_reloc_target)
441*d83cc019SAndroid Build Coastguard Worker reloc->second_reloc_offset = label_to_addr(reloc->second_reloc_target, entry->inst_offset) - entry->inst_offset;
442*d83cc019SAndroid Build Coastguard Worker
443*d83cc019SAndroid Build Coastguard Worker if (reloc->second_reloc_offset) { // this is a branch instruction with two offset arguments
444*d83cc019SAndroid Build Coastguard Worker set_branch_two_offsets(entry, reloc->first_reloc_offset, reloc->second_reloc_offset);
445*d83cc019SAndroid Build Coastguard Worker } else if (reloc->first_reloc_offset) {
446*d83cc019SAndroid Build Coastguard Worker set_branch_one_offset(entry, reloc->first_reloc_offset);
447*d83cc019SAndroid Build Coastguard Worker }
448*d83cc019SAndroid Build Coastguard Worker }
449*d83cc019SAndroid Build Coastguard Worker
450*d83cc019SAndroid Build Coastguard Worker if (binary_like_output)
451*d83cc019SAndroid Build Coastguard Worker fprintf(output, "%s", binary_prepend);
452*d83cc019SAndroid Build Coastguard Worker
453*d83cc019SAndroid Build Coastguard Worker for (entry = compiled_program.first;
454*d83cc019SAndroid Build Coastguard Worker entry != NULL;
455*d83cc019SAndroid Build Coastguard Worker entry = entry1) {
456*d83cc019SAndroid Build Coastguard Worker entry1 = entry->next;
457*d83cc019SAndroid Build Coastguard Worker if (!is_label(entry))
458*d83cc019SAndroid Build Coastguard Worker print_instruction(output, &entry->insn.gen);
459*d83cc019SAndroid Build Coastguard Worker else
460*d83cc019SAndroid Build Coastguard Worker free(entry->insn.label.name);
461*d83cc019SAndroid Build Coastguard Worker free(entry);
462*d83cc019SAndroid Build Coastguard Worker }
463*d83cc019SAndroid Build Coastguard Worker if (binary_like_output)
464*d83cc019SAndroid Build Coastguard Worker fprintf(output, "};");
465*d83cc019SAndroid Build Coastguard Worker
466*d83cc019SAndroid Build Coastguard Worker free_entry_point_table(entry_point_table);
467*d83cc019SAndroid Build Coastguard Worker free_hash_table(declared_register_table);
468*d83cc019SAndroid Build Coastguard Worker free_label_table(label_table);
469*d83cc019SAndroid Build Coastguard Worker
470*d83cc019SAndroid Build Coastguard Worker fflush (output);
471*d83cc019SAndroid Build Coastguard Worker if (ferror (output)) {
472*d83cc019SAndroid Build Coastguard Worker perror ("Could not flush output file");
473*d83cc019SAndroid Build Coastguard Worker if (output_file)
474*d83cc019SAndroid Build Coastguard Worker unlink (output_file);
475*d83cc019SAndroid Build Coastguard Worker err = 1;
476*d83cc019SAndroid Build Coastguard Worker }
477*d83cc019SAndroid Build Coastguard Worker return err;
478*d83cc019SAndroid Build Coastguard Worker }
479