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