diff options
author | Sagar Ghuge <[email protected]> | 2018-12-10 16:12:07 -0800 |
---|---|---|
committer | Matt Turner <[email protected]> | 2019-05-07 14:33:38 -0700 |
commit | 70308a5a8a801a960bb9f45fb597f80b77c51014 (patch) | |
tree | 567aad915f6c9bbd77c2571be21425a6aab4bb90 /src/intel/tools | |
parent | a232aa5c50226a744dfbcd46057f84d5d82e5c82 (diff) |
intel/tools: New i965 instruction assembler tool
Tool is inspired from igt's assembler tool. Thanks to Matt Turner, who
mentored me through out this project.
v2: Fix memory leaks and naming convention (Caio)
v3: Fix meson changes (Dylan Baker)
v4: Fix usage options (Matt Turner)
Signed-off-by: Sagar Ghuge <[email protected]>
Reviewed-by: Dylan Baker <[email protected]>
Reviewed-by: Matt Turner <[email protected]>
Closes: https://gitlab.freedesktop.org/mesa/mesa/merge_requests/141
Diffstat (limited to 'src/intel/tools')
-rw-r--r-- | src/intel/tools/i965_asm.c | 255 | ||||
-rw-r--r-- | src/intel/tools/i965_asm.h | 77 | ||||
-rw-r--r-- | src/intel/tools/i965_gram.y | 2278 | ||||
-rw-r--r-- | src/intel/tools/i965_lex.l | 404 | ||||
-rw-r--r-- | src/intel/tools/meson.build | 26 |
5 files changed, 3040 insertions, 0 deletions
diff --git a/src/intel/tools/i965_asm.c b/src/intel/tools/i965_asm.c new file mode 100644 index 00000000000..667f43da0d7 --- /dev/null +++ b/src/intel/tools/i965_asm.c @@ -0,0 +1,255 @@ +/* + * Copyright © 2018 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#include <stdio.h> +#include <getopt.h> +#include "i965_asm.h" + +extern FILE *yyin; +struct brw_codegen *p; +static int c_literal_output = 0; +char *input_filename; +int errors; + +static void +print_help(const char *progname, FILE *file) +{ + fprintf(file, + "Usage: %s [OPTION] inputfile\n" + "Assemble i965 instructions from input file.\n\n" + " -h, --help display this help and exit\n" + " -l, --c-literal C literal\n" + " -o, --output specify output file\n" + " --compact print compacted instructions\n" + " -g, --gen=platform assemble instructions for given \n" + " platform (3 letter platform name)\n" + "Example:\n" + " i965_asm -g kbl input.asm -o output\n", + progname); +} + +static void +print_instruction(FILE *output, bool compact, const brw_inst *instruction) +{ + int byte_limit; + + byte_limit = (compact == true) ? 8 : 16; + + if (c_literal_output) { + fprintf(output, "\t0x%02x,", ((unsigned char *)instruction)[0]); + + for (unsigned i = 1; i < byte_limit; i++) + fprintf(output, " 0x%02x,", ((unsigned char *)instruction)[i]); + } else { + fprintf(output, "%02x", ((unsigned char *)instruction)[0]); + + for (unsigned i = 1; i < byte_limit; i++) + fprintf(output, " %02x", ((unsigned char *)instruction)[i]); + } + fprintf(output, "\n"); +} + +static struct gen_device_info * +i965_disasm_init(uint16_t pci_id) +{ + struct gen_device_info *devinfo; + + devinfo = malloc(sizeof *devinfo); + if (devinfo == NULL) + return NULL; + + if (!gen_get_device_info(pci_id, devinfo)) { + fprintf(stderr, "can't find device information: pci_id=0x%x\n", + pci_id); + return NULL; + } + + brw_init_compaction_tables(devinfo); + + return devinfo; +} + +int main(int argc, char **argv) +{ + char *output_file = NULL; + char c; + FILE *output = stdout; + bool help = false, compact = false; + void *store; + uint64_t pci_id = 0; + int offset, err; + int start_offset = 0; + struct disasm_info *disasm_info; + struct gen_device_info *devinfo; + int result = EXIT_FAILURE; + + const struct option i965_asm_opts[] = { + { "help", no_argument, (int *) &help, true }, + { "c-literal", no_argument, NULL, 'c' }, + { "gen", required_argument, NULL, 'g' }, + { "output", required_argument, NULL, 'o' }, + { "compact", no_argument, (int *) &compact, true }, + { NULL, 0, NULL, 0 } + }; + + while ((c = getopt_long(argc, argv, ":g:o:lh", i965_asm_opts, NULL)) != -1) { + switch (c) { + case 'g': { + const int id = gen_device_name_to_pci_device_id(optarg); + if (id < 0) { + fprintf(stderr, "can't parse gen: '%s', expected 3 letter " + "platform name\n", optarg); + goto end; + } else { + pci_id = id; + } + break; + } + case 'h': + help = true; + print_help(argv[0], stderr); + goto end; + case 'l': + c_literal_output = 1; + break; + case 'o': + output_file = strdup(optarg); + break; + case 0: + break; + case ':': + fprintf(stderr, "%s: option `-%c' requires an argument\n", + argv[0], optopt); + goto end; + case '?': + default: + fprintf(stderr, "%s: option `-%c' is invalid: ignored\n", + argv[0], optopt); + goto end; + } + } + + if (help || !pci_id) { + print_help(argv[0], stderr); + goto end; + } + + if (!argv[optind]) { + fprintf(stderr, "Please specify input file\n"); + goto end; + } + + input_filename = strdup(argv[optind]); + yyin = fopen(input_filename, "r"); + if (!yyin) { + fprintf(stderr, "Unable to read input file : %s\n", + input_filename); + goto end; + } + + if (output_file) { + output = fopen(output_file, "w"); + if (!output) { + fprintf(stderr, "Couldn't open output file\n"); + goto end; + } + } + + devinfo = i965_disasm_init(pci_id); + if (!devinfo) { + fprintf(stderr, "Unable to allocate memory for " + "gen_device_info struct instance.\n"); + goto end; + } + + p = rzalloc(NULL, struct brw_codegen); + brw_init_codegen(devinfo, p, p); + p->automatic_exec_sizes = false; + + err = yyparse(); + if (err || errors) + goto end; + + store = p->store; + + disasm_info = disasm_initialize(p->devinfo, NULL); + if (!disasm_info) { + fprintf(stderr, "Unable to initialize disasm_info struct instance\n"); + goto end; + } + + if (c_literal_output) + fprintf(output, "static const char gen_eu_bytes[] = {\n"); + + brw_validate_instructions(p->devinfo, p->store, 0, + p->next_insn_offset, disasm_info); + + int nr_insn = (p->next_insn_offset - start_offset) / 16; + + if (compact) + brw_compact_instructions(p, start_offset, disasm_info); + + ralloc_free(disasm_info); + + for (int i = 0; i < nr_insn; i++) { + const brw_inst *insn = store + offset; + bool compacted = false; + + if (compact && brw_inst_cmpt_control(p->devinfo, insn)) { + offset += 8; + compacted = true; + } else { + offset += 16; + } + + print_instruction(output, compacted, insn); + } + + if (c_literal_output) + fprintf(output, "}"); + + result = EXIT_SUCCESS; + goto end; + +end: + if (input_filename) + free(input_filename); + + if (output_file) + free(output_file); + + if (yyin) + fclose(yyin); + + if (output) + fclose(output); + + if (p) + ralloc_free(p); + + if (devinfo) + free(devinfo); + + exit(result); +} diff --git a/src/intel/tools/i965_asm.h b/src/intel/tools/i965_asm.h new file mode 100644 index 00000000000..7027f4e5fb4 --- /dev/null +++ b/src/intel/tools/i965_asm.h @@ -0,0 +1,77 @@ +/* + * Copyright © 2018 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#ifndef __I965_ASM_H__ +#define __I965_ASM_H__ + +#include <inttypes.h> +#include <stdbool.h> +#include <assert.h> + +#include "compiler/brw_reg.h" +#include "compiler/brw_reg_type.h" +#include "compiler/brw_eu_defines.h" +#include "compiler/brw_inst.h" +#include "compiler/brw_eu.h" +#include "dev/gen_device_info.h" + +void yyerror (char *); +int yyparse(void); +int yylex(void); +char *lex_text(void); + +extern struct brw_codegen *p; +extern int errors; +extern char *input_filename; + +struct condition { + unsigned cond_modifier:4; + unsigned flag_reg_nr:1; + unsigned flag_subreg_nr:1; +}; + +struct predicate { + unsigned pred_control:4; + unsigned pred_inv:1; + unsigned flag_reg_nr:1; + unsigned flag_subreg_nr:1; +}; + +struct options { + unsigned access_mode:1; + unsigned compression_control:2; + unsigned thread_control:2; + unsigned no_dd_check:1; // Dependency control + unsigned no_dd_clear:1; // Dependency control + unsigned mask_control:1; + unsigned debug_control:1; + unsigned acc_wr_control:1; + unsigned end_of_thread:1; + unsigned compaction:1; + unsigned qtr_ctrl:2; + unsigned nib_ctrl:1; + unsigned is_compr:1; +}; + +#endif /* __I965_ASM_H__ */ diff --git a/src/intel/tools/i965_gram.y b/src/intel/tools/i965_gram.y new file mode 100644 index 00000000000..bbe7ce53f6b --- /dev/null +++ b/src/intel/tools/i965_gram.y @@ -0,0 +1,2278 @@ +%{ +/* + * Copyright © 2018 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <strings.h> +#include "i965_asm.h" + +#define YYLTYPE YYLTYPE +typedef struct YYLTYPE +{ + int first_line; + int first_column; + int last_line; + int last_column; +} YYLTYPE; + +enum message_level { + WARN, + ERROR, +}; + +int yydebug = 1; + +static void +message(enum message_level level, YYLTYPE *location, + const char *fmt, ...) +{ + static const char *level_str[] = { "warning", "error" }; + va_list args; + + if (location) + fprintf(stderr, "%s:%d:%d: %s: ", input_filename, + location->first_line, + location->first_column, level_str[level]); + else + fprintf(stderr, "%s:%s: ", input_filename, level_str[level]); + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); +} + +#define warn(flag, l, fmt, ...) \ + do { \ + if (warning_flags & WARN_ ## flag) \ + message(WARN, l, fmt, ## __VA_ARGS__); \ + } while (0) + +#define error(l, fmt, ...) \ + do { \ + message(ERROR, l, fmt, ## __VA_ARGS__); \ + } while (0) + +static bool +isPowerofTwo(unsigned int x) +{ + return x && (!(x & (x - 1))); +} + +static struct brw_reg +set_direct_src_operand(struct brw_reg *reg, int type) +{ + return brw_reg(reg->file, + reg->nr, + reg->subnr, + 0, // negate + 0, // abs + type, + 0, // vstride + 0, // width + 0, // hstride + BRW_SWIZZLE_NOOP, + WRITEMASK_XYZW); +} + +static void +i965_asm_unary_instruction(int opcode, struct brw_codegen *p, + struct brw_reg dest, struct brw_reg src0) +{ + switch (opcode) { + case BRW_OPCODE_BFREV: + brw_BFREV(p, dest, src0); + break; + case BRW_OPCODE_CBIT: + brw_CBIT(p, dest, src0); + break; + case BRW_OPCODE_F32TO16: + brw_F32TO16(p, dest, src0); + break; + case BRW_OPCODE_F16TO32: + brw_F16TO32(p, dest, src0); + break; + case BRW_OPCODE_MOV: + brw_MOV(p, dest, src0); + break; + case BRW_OPCODE_FBL: + brw_FBL(p, dest, src0); + break; + case BRW_OPCODE_FRC: + brw_FRC(p, dest, src0); + break; + case BRW_OPCODE_FBH: + brw_FBH(p, dest, src0); + break; + case BRW_OPCODE_NOT: + brw_NOT(p, dest, src0); + break; + case BRW_OPCODE_RNDE: + brw_RNDE(p, dest, src0); + break; + case BRW_OPCODE_RNDZ: + brw_RNDZ(p, dest, src0); + break; + case BRW_OPCODE_RNDD: + brw_RNDD(p, dest, src0); + break; + case BRW_OPCODE_LZD: + brw_LZD(p, dest, src0); + break; + case BRW_OPCODE_DIM: + brw_DIM(p, dest, src0); + break; + case BRW_OPCODE_RNDU: + fprintf(stderr, "Opcode BRW_OPCODE_RNDU unhandled\n"); + break; + default: + fprintf(stderr, "Unsupported unary opcode\n"); + } +} + +static void +i965_asm_binary_instruction(int opcode, + struct brw_codegen *p, + struct brw_reg dest, + struct brw_reg src0, + struct brw_reg src1) +{ + switch (opcode) { + case BRW_OPCODE_ADDC: + brw_ADDC(p, dest, src0, src1); + break; + case BRW_OPCODE_BFI1: + brw_BFI1(p, dest, src0, src1); + break; + case BRW_OPCODE_DP2: + brw_DP2(p, dest, src0, src1); + break; + case BRW_OPCODE_DP3: + brw_DP3(p, dest, src0, src1); + break; + case BRW_OPCODE_DP4: + brw_DP4(p, dest, src0, src1); + break; + case BRW_OPCODE_DPH: + brw_DPH(p, dest, src0, src1); + break; + case BRW_OPCODE_LINE: + brw_LINE(p, dest, src0, src1); + break; + case BRW_OPCODE_MAC: + brw_MAC(p, dest, src0, src1); + break; + case BRW_OPCODE_MACH: + brw_MACH(p, dest, src0, src1); + break; + case BRW_OPCODE_PLN: + brw_PLN(p, dest, src0, src1); + break; + case BRW_OPCODE_SAD2: + fprintf(stderr, "Opcode BRW_OPCODE_SAD2 unhandled\n"); + break; + case BRW_OPCODE_SADA2: + fprintf(stderr, "Opcode BRW_OPCODE_SADA2 unhandled\n"); + break; + case BRW_OPCODE_SUBB: + brw_SUBB(p, dest, src0, src1); + break; + case BRW_OPCODE_ADD: + brw_ADD(p, dest, src0, src1); + break; + case BRW_OPCODE_CMP: + /* Third parameter is conditional modifier + * which gets updated later + */ + brw_CMP(p, dest, 0, src0, src1); + break; + case BRW_OPCODE_AND: + brw_AND(p, dest, src0, src1); + break; + case BRW_OPCODE_ASR: + brw_ASR(p, dest, src0, src1); + break; + case BRW_OPCODE_AVG: + brw_AVG(p, dest, src0, src1); + break; + case BRW_OPCODE_OR: + brw_OR(p, dest, src0, src1); + break; + case BRW_OPCODE_SEL: + brw_SEL(p, dest, src0, src1); + break; + case BRW_OPCODE_SHL: + brw_SHL(p, dest, src0, src1); + break; + case BRW_OPCODE_SHR: + brw_SHR(p, dest, src0, src1); + break; + case BRW_OPCODE_XOR: + brw_XOR(p, dest, src0, src1); + break; + case BRW_OPCODE_MUL: + brw_MUL(p, dest, src0, src1); + break; + default: + fprintf(stderr, "Unsupported binary opcode\n"); + } +} + +static void +i965_asm_ternary_instruction(int opcode, + struct brw_codegen *p, + struct brw_reg dest, + struct brw_reg src0, + struct brw_reg src1, + struct brw_reg src2) +{ + switch (opcode) { + case BRW_OPCODE_MAD: + brw_MAD(p, dest, src0, src1, src2); + break; + case BRW_OPCODE_CSEL: + brw_CSEL(p, dest, src0, src1, src2); + break; + case BRW_OPCODE_LRP: + brw_LRP(p, dest, src0, src1, src2); + break; + case BRW_OPCODE_BFE: + brw_BFE(p, dest, src0, src1, src2); + break; + case BRW_OPCODE_BFI2: + brw_BFI2(p, dest, src0, src1, src2); + break; + default: + fprintf(stderr, "Unsupported ternary opcode\n"); + } +} + +static void +i965_asm_set_instruction_options(struct brw_codegen *p, + struct options options) +{ + brw_inst_set_access_mode(p->devinfo, brw_last_inst, + options.access_mode); + brw_inst_set_mask_control(p->devinfo, brw_last_inst, + options.mask_control); + brw_inst_set_thread_control(p->devinfo, brw_last_inst, + options.thread_control); + brw_inst_set_no_dd_check(p->devinfo, brw_last_inst, + options.no_dd_check); + brw_inst_set_no_dd_clear(p->devinfo, brw_last_inst, + options.no_dd_clear); + brw_inst_set_debug_control(p->devinfo, brw_last_inst, + options.debug_control); + if (p->devinfo->gen >= 6) + brw_inst_set_acc_wr_control(p->devinfo, brw_last_inst, + options.acc_wr_control); + brw_inst_set_cmpt_control(p->devinfo, brw_last_inst, + options.compaction); +} + +static void +i965_asm_set_dst_nr(struct brw_codegen *p, + struct brw_reg *reg, + struct options options) +{ + if (p->devinfo->gen <= 6) { + if (reg->file == BRW_MESSAGE_REGISTER_FILE && + options.qtr_ctrl == BRW_COMPRESSION_COMPRESSED && + !options.is_compr) + reg->nr |= BRW_MRF_COMPR4; + } +} + +%} + +%locations + +%start ROOT + +%union { + double number; + int integer; + unsigned long long int llint; + struct brw_reg reg; + struct brw_codegen *program; + struct predicate predicate; + struct condition condition; + struct options options; + brw_inst *instruction; +} + +%token ABS +%token COLON +%token COMMA +%token DOT +%token LANGLE RANGLE +%token LCURLY RCURLY +%token LPAREN RPAREN +%token LSQUARE RSQUARE +%token PLUS MINUS +%token SEMICOLON + +/* datatypes */ +%token <integer> TYPE_B TYPE_UB +%token <integer> TYPE_W TYPE_UW +%token <integer> TYPE_D TYPE_UD +%token <integer> TYPE_Q TYPE_UQ +%token <integer> TYPE_V TYPE_UV +%token <integer> TYPE_F TYPE_HF +%token <integer> TYPE_DF TYPE_NF +%token <integer> TYPE_VF + +/* opcodes */ +%token <integer> ADD ADD3 ADDC AND ASR AVG +%token <integer> BFE BFI1 BFI2 BFB BFREV BRC BRD BREAK +%token <integer> CALL CALLA CASE CBIT CMP CMPN CONT CSEL +%token <integer> DIM DO DPAS DPASW DP2 DP3 DP4 DP4A DPH +%token <integer> ELSE ENDIF F16TO32 F32TO16 FBH FBL FORK FRC +%token <integer> GOTO +%token <integer> HALT +%token <integer> IF IFF ILLEGAL +%token <integer> JMPI JOIN +%token <integer> LINE LRP LZD +%token <integer> MAC MACH MAD MADM MOV MOVI MUL MREST MSAVE +%token <integer> NENOP NOP NOT +%token <integer> OR +%token <integer> PLN POP PUSH +%token <integer> RET RNDD RNDE RNDU RNDZ ROL ROR +%token <integer> SAD2 SADA2 SEL SEND SENDC SENDS SENDSC SHL SHR SMOV SUBB SYNC +%token <integer> WAIT WHILE +%token <integer> XOR + +/* extended math functions */ +%token <integer> COS EXP FDIV INV INVM INTDIV INTDIVMOD INTMOD LOG POW RSQ +%token <integer> RSQRTM SIN SINCOS SQRT + +/* shared functions for send */ +%token CONST CRE DATA DP_DATA_1 GATEWAY MATH PIXEL_INTERP READ RENDER SAMPLER +%token THREAD_SPAWNER URB VME WRITE DP_SAMPLER + +/* Conditional modifiers */ +%token <integer> EQUAL GREATER GREATER_EQUAL LESS LESS_EQUAL NOT_EQUAL +%token <integer> NOT_ZERO OVERFLOW UNORDERED ZERO + +/* register Access Modes */ +%token ALIGN1 ALIGN16 + +/* accumulator write control */ +%token ACCWREN + +/* compaction control */ +%token CMPTCTRL + +/* compression control */ +%token COMPR COMPR4 SECHALF + +/* mask control (WeCtrl) */ +%token WECTRL + +/* debug control */ +%token BREAKPOINT + +/* dependency control */ +%token NODDCLR NODDCHK + +/* end of thread */ +%token EOT + +/* mask control */ +%token MASK_DISABLE; + +/* predicate control */ +%token <integer> ANYV ALLV ANY2H ALL2H ANY4H ALL4H ANY8H ALL8H ANY16H ALL16H +%token <integer> ANY32H ALL32H + +/* round instructions */ +%token <integer> ROUND_INCREMENT + +/* staturation */ +%token SATURATE + +/* thread control */ +%token ATOMIC SWITCH + +/* quater control */ +%token QTR_2Q QTR_3Q QTR_4Q QTR_2H QTR_2N QTR_3N QTR_4N QTR_5N +%token QTR_6N QTR_7N QTR_8N + +/* channels */ +%token <integer> X Y Z W + +/* reg files */ +%token GENREGFILE MSGREGFILE + +/* vertical stride in register region */ +%token VxH + +/* register type */ +%token <integer> GENREG MSGREG ADDRREG ACCREG FLAGREG NOTIFYREG STATEREG +%token <integer> CONTROLREG IPREG PERFORMANCEREG THREADREG CHANNELENABLEREG +%token <integer> MASKREG + +%token <integer> INTEGER +%token <llint> LONG +%token NULL_TOKEN + +%precedence SUBREGNUM +%left PLUS MINUS +%precedence DOT +%precedence EMPTYEXECSIZE +%precedence LPAREN + +%type <integer> execsize simple_int exp +%type <llint> exp2 + +/* predicate control */ +%type <integer> predctrl predstate +%type <predicate> predicate + +/* conditional modifier */ +%type <condition> cond_mod +%type <integer> condModifiers + +/* instruction options */ +%type <options> instoptions instoption_list +%type <integer> instoption + +/* writemask */ +%type <integer> writemask_x writemask_y writemask_z writemask_w +%type <reg> writemask + +/* dst operand */ +%type <reg> dst dstoperand dstoperandex dstoperandex_typed dstreg dsttype +%type <reg> dstoperandex_ud_typed +%type <integer> dstregion + +%type <integer> saturate relativelocation rellocation +%type <reg> relativelocation2 + +/* src operand */ +%type <reg> directsrcoperand directsrcaccoperand indirectsrcoperand srcacc +%type <reg> srcarcoperandex srcaccimm srcarcoperandex_typed srctype srcimm +%type <reg> srcarcoperandex_ud_typed srcimmtype indirectgenreg indirectregion +%type <reg> immreg src reg32 payload directgenreg_list addrparam region +%type <reg> region_wh swizzle directgenreg directmsgreg indirectmsgreg + +/* registers */ +%type <reg> accreg addrreg channelenablereg controlreg flagreg ipreg +%type <reg> notifyreg nullreg performancereg threadcontrolreg statereg maskreg +%type <integer> subregnum + +/* immediate values */ +%type <llint> immval + +/* instruction opcodes */ +%type <integer> unaryopcodes binaryopcodes binaryaccopcodes ternaryopcodes +%type <integer> sendop +%type <instruction> sendopcode + +%type <integer> negate abs chansel math_function sharedfunction + +%code { + +static void +add_instruction_option(struct options *options, int option) +{ + switch (option) { + case ALIGN1: + options->access_mode = BRW_ALIGN_1; + break; + case ALIGN16: + options->access_mode = BRW_ALIGN_16; + break; + case SECHALF: + options->qtr_ctrl |= BRW_COMPRESSION_2NDHALF; + break; + case COMPR: + options->qtr_ctrl |= BRW_COMPRESSION_COMPRESSED; + options->is_compr = true; + break; + case COMPR4: + options->qtr_ctrl |= BRW_COMPRESSION_COMPRESSED; + break; + case SWITCH: + options->thread_control |= BRW_THREAD_SWITCH; + break; + case ATOMIC: + options->thread_control |= BRW_THREAD_ATOMIC; + break; + case NODDCHK: + options->no_dd_check = true; + break; + case NODDCLR: + options->no_dd_clear = BRW_DEPENDENCY_NOTCLEARED; + break; + case MASK_DISABLE: + options->mask_control |= BRW_MASK_DISABLE; + break; + case BREAKPOINT: + options->debug_control = BRW_DEBUG_BREAKPOINT; + break; + case WECTRL: + options->mask_control |= BRW_WE_ALL; + break; + case CMPTCTRL: + options->compaction = true; + break; + case ACCWREN: + options->acc_wr_control = true; + break; + case EOT: + options->end_of_thread = true; + break; + /* TODO : Figure out how to set instruction group and get rid of + * code below + */ + case QTR_2Q: + options->qtr_ctrl = BRW_COMPRESSION_2NDHALF; + break; + case QTR_3Q: + options->qtr_ctrl = BRW_COMPRESSION_COMPRESSED; + break; + case QTR_4Q: + options->qtr_ctrl = 3; + break; + case QTR_2H: + options->qtr_ctrl = BRW_COMPRESSION_COMPRESSED; + break; + case QTR_2N: + options->qtr_ctrl = BRW_COMPRESSION_NONE; + options->nib_ctrl = true; + break; + case QTR_3N: + options->qtr_ctrl = BRW_COMPRESSION_2NDHALF; + break; + case QTR_4N: + options->qtr_ctrl = BRW_COMPRESSION_2NDHALF; + options->nib_ctrl = true; + break; + case QTR_5N: + options->qtr_ctrl = BRW_COMPRESSION_COMPRESSED; + break; + case QTR_6N: + options->qtr_ctrl = BRW_COMPRESSION_COMPRESSED; + options->nib_ctrl = true; + break; + case QTR_7N: + options->qtr_ctrl = 3; + break; + case QTR_8N: + options->qtr_ctrl = 3; + options->nib_ctrl = true; + break; + } +} +} +%% + +ROOT: + instrseq + ; + +instrseq: + instrseq instruction SEMICOLON + | instrseq relocatableinstruction SEMICOLON + | instruction SEMICOLON + | relocatableinstruction SEMICOLON + ; + +/* Instruction Group */ +instruction: + unaryinstruction + | binaryinstruction + | binaryaccinstruction + | mathinstruction + | nopinstruction + | syncinstruction + | ternaryinstruction + | sendinstruction + ; + +relocatableinstruction: + jumpinstruction + | branchinstruction + | breakinstruction + | loopinstruction + ; + +/* Unary instruction */ +unaryinstruction: + predicate unaryopcodes saturate cond_mod execsize dst srcaccimm instoptions + { + i965_asm_set_dst_nr(p, &$6, $8); + brw_set_default_access_mode(p, $8.access_mode); + i965_asm_unary_instruction($2, p, $6, $7); + brw_pop_insn_state(p); + i965_asm_set_instruction_options(p, $8); + brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, + $4.cond_modifier); + + if (p->devinfo->gen >= 7) { + if ($2 != BRW_OPCODE_DIM) { + brw_inst_set_flag_reg_nr(p->devinfo, + brw_last_inst, + $4.flag_reg_nr); + brw_inst_set_flag_subreg_nr(p->devinfo, + brw_last_inst, + $4.flag_subreg_nr); + } + } + + if ($7.file != BRW_IMMEDIATE_VALUE) { + brw_inst_set_src0_vstride(p->devinfo, brw_last_inst, + $7.vstride); + } + brw_inst_set_saturate(p->devinfo, brw_last_inst, $3); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $5); + // TODO: set instruction group instead of qtr and nib ctrl + brw_inst_set_qtr_control(p->devinfo, brw_last_inst, + $8.qtr_ctrl); + + if (p->devinfo->gen >= 7) + brw_inst_set_nib_control(p->devinfo, brw_last_inst, + $8.nib_ctrl); + } + ; + +unaryopcodes: + BFREV + | CBIT + | DIM + | F16TO32 + | F32TO16 + | FBH + | FBL + | FRC + | LZD + | MOV + | NOT + | RNDD + | RNDE + | RNDU + | RNDZ + ; + +/* Binary instruction */ +binaryinstruction: + predicate binaryopcodes saturate cond_mod execsize dst srcimm srcimm instoptions + { + i965_asm_set_dst_nr(p, &$6, $9); + brw_set_default_access_mode(p, $9.access_mode); + i965_asm_binary_instruction($2, p, $6, $7, $8); + i965_asm_set_instruction_options(p, $9); + brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, + $4.cond_modifier); + + if (p->devinfo->gen >= 7) { + brw_inst_set_flag_reg_nr(p->devinfo, brw_last_inst, + $4.flag_reg_nr); + brw_inst_set_flag_subreg_nr(p->devinfo, brw_last_inst, + $4.flag_subreg_nr); + } + + brw_inst_set_saturate(p->devinfo, brw_last_inst, $3); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $5); + // TODO: set instruction group instead of qtr and nib ctrl + brw_inst_set_qtr_control(p->devinfo, brw_last_inst, + $9.qtr_ctrl); + + if (p->devinfo->gen >= 7) + brw_inst_set_nib_control(p->devinfo, brw_last_inst, + $9.nib_ctrl); + + brw_pop_insn_state(p); + } + ; + +binaryopcodes: + ADDC + | BFI1 + | DP2 + | DP3 + | DP4 + | DPH + | LINE + | MAC + | MACH + | MUL + | PLN + | SAD2 + | SADA2 + | SUBB + ; + +/* Binary acc instruction */ +binaryaccinstruction: + predicate binaryaccopcodes saturate cond_mod execsize dst srcacc srcimm instoptions + { + i965_asm_set_dst_nr(p, &$6, $9); + brw_set_default_access_mode(p, $9.access_mode); + i965_asm_binary_instruction($2, p, $6, $7, $8); + brw_pop_insn_state(p); + i965_asm_set_instruction_options(p, $9); + brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, + $4.cond_modifier); + + if (p->devinfo->gen >= 7) { + if (!brw_inst_flag_reg_nr(p->devinfo, brw_last_inst)) { + brw_inst_set_flag_reg_nr(p->devinfo, + brw_last_inst, + $4.flag_reg_nr); + brw_inst_set_flag_subreg_nr(p->devinfo, + brw_last_inst, + $4.flag_subreg_nr); + } + } + + brw_inst_set_saturate(p->devinfo, brw_last_inst, $3); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $5); + // TODO: set instruction group instead of qtr and nib ctrl + brw_inst_set_qtr_control(p->devinfo, brw_last_inst, + $9.qtr_ctrl); + + if (p->devinfo->gen >= 7) + brw_inst_set_nib_control(p->devinfo, brw_last_inst, + $9.nib_ctrl); + + } + ; + +binaryaccopcodes: + ADD + | AND + | ASR + | AVG + | CMP + | CMPN + | OR + | SEL + | SHL + | SHR + | XOR + ; + +/* Math instruction */ +mathinstruction: + predicate MATH saturate math_function execsize dst src srcimm instoptions + { + brw_set_default_access_mode(p, $9.access_mode); + gen6_math(p, $6, $4, $7, $8); + i965_asm_set_instruction_options(p, $9); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $5); + brw_inst_set_saturate(p->devinfo, brw_last_inst, $3); + // TODO: set instruction group instead + brw_inst_set_qtr_control(p->devinfo, brw_last_inst, + $9.qtr_ctrl); + + if (p->devinfo->gen >= 7) + brw_inst_set_nib_control(p->devinfo, brw_last_inst, + $9.nib_ctrl); + + brw_pop_insn_state(p); + } + ; + +math_function: + COS + | EXP + | FDIV + | INV + | INVM + | INTDIV + | INTDIVMOD + | INTMOD + | LOG + | POW + | RSQ + | RSQRTM + | SIN + | SQRT + | SINCOS + ; + +/* NOP instruction */ +nopinstruction: + NOP + { + brw_NOP(p); + } + ; + +/* Ternary operand instruction */ +ternaryinstruction: + predicate ternaryopcodes saturate cond_mod execsize dst src src src instoptions + { + brw_set_default_access_mode(p, $10.access_mode); + i965_asm_ternary_instruction($2, p, $6, $7, $8, $9); + brw_pop_insn_state(p); + i965_asm_set_instruction_options(p, $10); + brw_inst_set_cond_modifier(p->devinfo, brw_last_inst, + $4.cond_modifier); + + if (p->devinfo->gen >= 7) { + brw_inst_set_3src_a16_flag_reg_nr(p->devinfo, brw_last_inst, + $4.flag_reg_nr); + brw_inst_set_3src_a16_flag_subreg_nr(p->devinfo, brw_last_inst, + $4.flag_subreg_nr); + } + + brw_inst_set_saturate(p->devinfo, brw_last_inst, $3); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $5); + // TODO: set instruction group instead of qtr and nib ctrl + brw_inst_set_qtr_control(p->devinfo, brw_last_inst, + $10.qtr_ctrl); + + if (p->devinfo->gen >= 7) + brw_inst_set_nib_control(p->devinfo, brw_last_inst, + $10.nib_ctrl); + } + ; + +ternaryopcodes: + CSEL + | BFE + | BFI2 + | LRP + | MAD + ; + +/* Sync instruction */ +syncinstruction: + WAIT execsize src instoptions + { + brw_next_insn(p, $1); + i965_asm_set_instruction_options(p, $4); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $2); + brw_set_default_access_mode(p, $4.access_mode); + struct brw_reg src = brw_notification_reg(); + brw_set_dest(p, brw_last_inst, src); + brw_set_src0(p, brw_last_inst, src); + brw_set_src1(p, brw_last_inst, brw_null_reg()); + brw_inst_set_mask_control(p->devinfo, brw_last_inst, BRW_MASK_DISABLE); + } + ; + +/* Send instruction */ +sendinstruction: + predicate sendopcode execsize dst payload exp2 sharedfunction instoptions + { + i965_asm_set_instruction_options(p, $8); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); + brw_set_dest(p, brw_last_inst, $4); + brw_set_src0(p, brw_last_inst, $5); + brw_inst_set_bits(brw_last_inst, 127, 96, $6); + brw_inst_set_src1_file_type(p->devinfo, brw_last_inst, + BRW_IMMEDIATE_VALUE, + BRW_REGISTER_TYPE_UD); + brw_inst_set_sfid(p->devinfo, brw_last_inst, $7); + brw_inst_set_eot(p->devinfo, brw_last_inst, $8.end_of_thread); + // TODO: set instruction group instead of qtr and nib ctrl + brw_inst_set_qtr_control(p->devinfo, brw_last_inst, + $8.qtr_ctrl); + + if (p->devinfo->gen >= 7) + brw_inst_set_nib_control(p->devinfo, brw_last_inst, + $8.nib_ctrl); + + brw_pop_insn_state(p); + } + | predicate sendopcode execsize exp dst payload exp2 sharedfunction instoptions + { + i965_asm_set_instruction_options(p, $9); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); + brw_inst_set_base_mrf(p->devinfo, brw_last_inst, $4); + brw_set_dest(p, brw_last_inst, $5); + brw_set_src0(p, brw_last_inst, $6); + brw_inst_set_bits(brw_last_inst, 127, 96, $7); + brw_inst_set_src1_file_type(p->devinfo, brw_last_inst, + BRW_IMMEDIATE_VALUE, + BRW_REGISTER_TYPE_UD); + brw_inst_set_sfid(p->devinfo, brw_last_inst, $8); + brw_inst_set_eot(p->devinfo, brw_last_inst, $9.end_of_thread); + // TODO: set instruction group instead of qtr and nib ctrl + brw_inst_set_qtr_control(p->devinfo, brw_last_inst, + $9.qtr_ctrl); + + if (p->devinfo->gen >= 7) + brw_inst_set_nib_control(p->devinfo, brw_last_inst, + $9.nib_ctrl); + + brw_pop_insn_state(p); + } + | predicate sendopcode execsize dst payload payload exp2 sharedfunction instoptions + { + i965_asm_set_instruction_options(p, $9); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); + brw_set_dest(p, brw_last_inst, $4); + brw_set_src0(p, brw_last_inst, $5); + brw_inst_set_bits(brw_last_inst, 127, 96, $7); + brw_inst_set_sfid(p->devinfo, brw_last_inst, $8); + brw_inst_set_eot(p->devinfo, brw_last_inst, $9.end_of_thread); + // TODO: set instruction group instead of qtr and nib ctrl + brw_inst_set_qtr_control(p->devinfo, brw_last_inst, + $9.qtr_ctrl); + + if (p->devinfo->gen >= 7) + brw_inst_set_nib_control(p->devinfo, brw_last_inst, + $9.nib_ctrl); + + brw_pop_insn_state(p); + } + | predicate SENDS execsize dst payload payload exp2 exp2 sharedfunction instoptions + { + brw_next_insn(p, $2); + i965_asm_set_instruction_options(p, $10); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); + brw_set_dest(p, brw_last_inst, $4); + brw_set_src0(p, brw_last_inst, $5); + brw_set_src1(p, brw_last_inst, $6); + + if (brw_inst_send_sel_reg32_ex_desc(p->devinfo, brw_last_inst)) { + brw_inst_set_send_ex_desc_ia_subreg_nr(p->devinfo, brw_last_inst, $5.subnr); + } else { + brw_inst_set_send_ex_desc(p->devinfo, brw_last_inst, $8); + } + + brw_inst_set_bits(brw_last_inst, 127, 96, $7); + brw_inst_set_sfid(p->devinfo, brw_last_inst, $9); + brw_inst_set_eot(p->devinfo, brw_last_inst, $10.end_of_thread); + // TODO: set instruction group instead of qtr and nib ctrl + brw_inst_set_qtr_control(p->devinfo, brw_last_inst, + $10.qtr_ctrl); + + if (p->devinfo->gen >= 7) + brw_inst_set_nib_control(p->devinfo, brw_last_inst, + $10.nib_ctrl); + + brw_pop_insn_state(p); + } + | predicate SENDS execsize dst payload payload src exp2 sharedfunction instoptions + { + brw_next_insn(p, $2); + i965_asm_set_instruction_options(p, $10); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); + brw_set_dest(p, brw_last_inst, $4); + brw_set_src0(p, brw_last_inst, $5); + brw_set_src1(p, brw_last_inst, $6); + + brw_inst_set_send_sel_reg32_desc(p->devinfo, brw_last_inst, 1); + brw_inst_set_send_ex_desc(p->devinfo, brw_last_inst, $8); + + brw_inst_set_sfid(p->devinfo, brw_last_inst, $9); + brw_inst_set_eot(p->devinfo, brw_last_inst, $10.end_of_thread); + // TODO: set instruction group instead of qtr and nib ctrl + brw_inst_set_qtr_control(p->devinfo, brw_last_inst, + $10.qtr_ctrl); + + if (p->devinfo->gen >= 7) + brw_inst_set_nib_control(p->devinfo, brw_last_inst, + $10.nib_ctrl); + + brw_pop_insn_state(p); + } + ; + +sendop: + SEND + | SENDC + ; + +sendopcode: + sendop { $$ = brw_next_insn(p, $1); } + ; + +sharedfunction: + NULL_TOKEN { $$ = BRW_SFID_NULL; } + | MATH { $$ = BRW_SFID_MATH; } + | GATEWAY { $$ = BRW_SFID_MESSAGE_GATEWAY; } + | READ { $$ = BRW_SFID_DATAPORT_READ; } + | WRITE { $$ = BRW_SFID_DATAPORT_WRITE; } + | URB { $$ = BRW_SFID_URB; } + | THREAD_SPAWNER { $$ = BRW_SFID_THREAD_SPAWNER; } + | VME { $$ = BRW_SFID_VME; } + | RENDER { $$ = GEN6_SFID_DATAPORT_RENDER_CACHE; } + | CONST { $$ = GEN6_SFID_DATAPORT_CONSTANT_CACHE; } + | DATA { $$ = GEN7_SFID_DATAPORT_DATA_CACHE; } + | PIXEL_INTERP { $$ = GEN7_SFID_PIXEL_INTERPOLATOR; } + | DP_DATA_1 { $$ = HSW_SFID_DATAPORT_DATA_CACHE_1; } + | CRE { $$ = HSW_SFID_CRE; } + | SAMPLER { $$ = BRW_SFID_SAMPLER; } + | DP_SAMPLER { $$ = GEN6_SFID_DATAPORT_SAMPLER_CACHE; } + ; + +exp2: + LONG { $$ = $1; } + | MINUS LONG { $$ = -$2; } + ; + +/* Jump instruction */ +jumpinstruction: + predicate JMPI execsize relativelocation2 instoptions + { + brw_next_insn(p, $2); + i965_asm_set_instruction_options(p, $5); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); + brw_set_dest(p, brw_last_inst, brw_ip_reg()); + brw_set_src0(p, brw_last_inst, brw_ip_reg()); + brw_set_src1(p, brw_last_inst, $4); + brw_inst_set_pred_control(p->devinfo, brw_last_inst, + brw_inst_pred_control(p->devinfo, + brw_last_inst)); + brw_pop_insn_state(p); + } + ; + +/* branch instruction */ +branchinstruction: + predicate ENDIF execsize relativelocation instoptions + { + brw_next_insn(p, $2); + i965_asm_set_instruction_options(p, $5); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); + + if (p->devinfo->gen < 6) { + brw_set_dest(p, brw_last_inst, retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src0(p, brw_last_inst, retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src1(p, brw_last_inst, brw_imm_d(0x0)); + brw_inst_set_gen4_pop_count(p->devinfo, brw_last_inst, + $4); + } else if (p->devinfo->gen == 6) { + brw_set_dest(p, brw_last_inst, brw_imm_w(0x0)); + brw_inst_set_gen6_jump_count(p->devinfo, brw_last_inst, + $4); + brw_set_src0(p, brw_last_inst, retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src1(p, brw_last_inst, retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + } else if (p->devinfo->gen == 7) { + brw_set_dest(p, brw_last_inst, retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src0(p, brw_last_inst, retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src1(p, brw_last_inst, brw_imm_w(0x0)); + brw_inst_set_jip(p->devinfo, brw_last_inst, $4); + } else { + brw_set_src0(p, brw_last_inst, brw_imm_d($4)); + } + + if (p->devinfo->gen < 6) + brw_inst_set_thread_control(p->devinfo, brw_last_inst, + BRW_THREAD_SWITCH); + brw_pop_insn_state(p); + } + | ELSE execsize relativelocation rellocation instoptions + { + brw_next_insn(p, $1); + i965_asm_set_instruction_options(p, $5); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $2); + + if (p->devinfo->gen < 6) { + brw_set_dest(p, brw_last_inst, brw_ip_reg()); + brw_set_src0(p, brw_last_inst, brw_ip_reg()); + brw_set_src1(p, brw_last_inst, brw_imm_d(0x0)); + brw_inst_set_gen4_jump_count(p->devinfo, brw_last_inst, + $3); + brw_inst_set_gen4_pop_count(p->devinfo, brw_last_inst, + $4); + } else if (p->devinfo->gen == 6) { + brw_set_dest(p, brw_last_inst, brw_imm_w(0x0)); + brw_inst_set_gen6_jump_count(p->devinfo, brw_last_inst, + $3); + brw_set_src0(p, brw_last_inst, retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src1(p, brw_last_inst, retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + } else if (p->devinfo->gen == 7) { + brw_set_dest(p, brw_last_inst, retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src0(p, brw_last_inst, retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src1(p, brw_last_inst, brw_imm_w($3)); + brw_inst_set_jip(p->devinfo, brw_last_inst, $3); + brw_inst_set_uip(p->devinfo, brw_last_inst, $4); + } else { + brw_set_dest(p, brw_last_inst, retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src0(p, brw_last_inst, brw_imm_d($3)); + brw_inst_set_jip(p->devinfo, brw_last_inst, $3); + brw_inst_set_uip(p->devinfo, brw_last_inst, $4); + } + + if (!p->single_program_flow && p->devinfo->gen < 6) + brw_inst_set_thread_control(p->devinfo, brw_last_inst, + BRW_THREAD_SWITCH); + } + | predicate IF execsize relativelocation rellocation instoptions + { + brw_next_insn(p, $2); + i965_asm_set_instruction_options(p, $6); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); + + if (p->devinfo->gen < 6) { + brw_set_dest(p, brw_last_inst, brw_ip_reg()); + brw_set_src0(p, brw_last_inst, brw_ip_reg()); + brw_set_src1(p, brw_last_inst, brw_imm_d(0x0)); + brw_inst_set_gen4_jump_count(p->devinfo, brw_last_inst, + $4); + brw_inst_set_gen4_pop_count(p->devinfo, brw_last_inst, + $5); + } else if (p->devinfo->gen == 6) { + brw_set_dest(p, brw_last_inst, brw_imm_w(0x0)); + brw_inst_set_gen6_jump_count(p->devinfo, brw_last_inst, + $4); + brw_set_src0(p, brw_last_inst, + vec1(retype(brw_null_reg(), + BRW_REGISTER_TYPE_D))); + brw_set_src1(p, brw_last_inst, + vec1(retype(brw_null_reg(), + BRW_REGISTER_TYPE_D))); + } else if (p->devinfo->gen == 7) { + brw_set_dest(p, brw_last_inst, + vec1(retype(brw_null_reg(), + BRW_REGISTER_TYPE_D))); + brw_set_src0(p, brw_last_inst, + vec1(retype(brw_null_reg(), + BRW_REGISTER_TYPE_D))); + brw_set_src1(p, brw_last_inst, brw_imm_w($4)); + brw_inst_set_jip(p->devinfo, brw_last_inst, $4); + brw_inst_set_uip(p->devinfo, brw_last_inst, $5); + } else { + brw_set_dest(p, brw_last_inst, + vec1(retype(brw_null_reg(), + BRW_REGISTER_TYPE_D))); + brw_set_src0(p, brw_last_inst, brw_imm_d($4)); + brw_inst_set_jip(p->devinfo, brw_last_inst, $4); + brw_inst_set_uip(p->devinfo, brw_last_inst, $5); + } + + if (!p->single_program_flow && p->devinfo->gen < 6) + brw_inst_set_thread_control(p->devinfo, brw_last_inst, + BRW_THREAD_SWITCH); + + brw_pop_insn_state(p); + } + | predicate IFF execsize relativelocation instoptions + { + brw_next_insn(p, $2); + i965_asm_set_instruction_options(p, $5); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); + + if (p->devinfo->gen < 6) { + brw_set_dest(p, brw_last_inst, brw_ip_reg()); + brw_set_src0(p, brw_last_inst, brw_ip_reg()); + brw_inst_set_gen4_jump_count(p->devinfo, brw_last_inst, + $4); + brw_set_src1(p, brw_last_inst, brw_imm_d($4)); + } else if (p->devinfo->gen == 6) { + brw_set_dest(p, brw_last_inst, brw_imm_w($4)); + brw_inst_set_gen6_jump_count(p->devinfo, brw_last_inst, + $4); + brw_set_src0(p, brw_last_inst, + vec1(retype(brw_null_reg(), + BRW_REGISTER_TYPE_D))); + brw_set_src1(p, brw_last_inst, + vec1(retype(brw_null_reg(), + BRW_REGISTER_TYPE_D))); + } else if (p->devinfo->gen == 7) { + brw_set_dest(p, brw_last_inst, + vec1(retype(brw_null_reg(), + BRW_REGISTER_TYPE_D))); + brw_set_src0(p, brw_last_inst, + vec1(retype(brw_null_reg(), + BRW_REGISTER_TYPE_D))); + brw_set_src1(p, brw_last_inst, brw_imm_w($4)); + brw_inst_set_jip(p->devinfo, brw_last_inst, $4); + } else { + brw_set_dest(p, brw_last_inst, + vec1(retype(brw_null_reg(), + BRW_REGISTER_TYPE_D))); + brw_set_src0(p, brw_last_inst, brw_imm_d($4)); + brw_inst_set_jip(p->devinfo, brw_last_inst, $4); + } + + if (!p->single_program_flow && p->devinfo->gen < 6) + brw_inst_set_thread_control(p->devinfo, brw_last_inst, + BRW_THREAD_SWITCH); + + brw_pop_insn_state(p); + } + ; + +/* break instruction */ +breakinstruction: + predicate BREAK execsize relativelocation relativelocation instoptions + { + brw_next_insn(p, $2); + i965_asm_set_instruction_options(p, $6); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); + + if (p->devinfo->gen >= 8) { + brw_set_dest(p, brw_last_inst, retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src0(p, brw_last_inst, brw_imm_d($4)); + brw_inst_set_uip(p->devinfo, brw_last_inst, $5); + } else if (p->devinfo->gen >= 6) { + brw_set_dest(p, brw_last_inst, retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src0(p, brw_last_inst, retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src1(p, brw_last_inst, brw_imm_d(0x0)); + brw_inst_set_jip(p->devinfo, brw_last_inst, $4); + brw_inst_set_uip(p->devinfo, brw_last_inst, $5); + } else { + brw_set_dest(p, brw_last_inst, brw_ip_reg()); + brw_set_src0(p, brw_last_inst, brw_ip_reg()); + brw_set_src1(p, brw_last_inst, brw_imm_d(0x0)); + brw_inst_set_gen4_jump_count(p->devinfo, brw_last_inst, + $4); + brw_inst_set_gen4_pop_count(p->devinfo, brw_last_inst, + $5); + } + + brw_pop_insn_state(p); + } + | predicate HALT execsize relativelocation relativelocation instoptions + { + brw_next_insn(p, $2); + i965_asm_set_instruction_options(p, $6); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); + brw_set_dest(p, brw_last_inst, retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + + if (p->devinfo->gen >= 8) { + brw_set_src0(p, brw_last_inst, brw_imm_d($4)); + brw_inst_set_uip(p->devinfo, brw_last_inst, $5); + } else { + brw_set_src0(p, brw_last_inst, retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src1(p, brw_last_inst, brw_imm_d($5)); + } + + brw_inst_set_jip(p->devinfo, brw_last_inst, $4); + brw_inst_set_uip(p->devinfo, brw_last_inst, $5); + brw_pop_insn_state(p); + } + | predicate CONT execsize relativelocation relativelocation instoptions + { + brw_next_insn(p, $2); + i965_asm_set_instruction_options(p, $6); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); + brw_set_dest(p, brw_last_inst, brw_ip_reg()); + + if (p->devinfo->gen >= 8) { + brw_set_src0(p, brw_last_inst, brw_imm_d(0x0)); + brw_inst_set_jip(p->devinfo, brw_last_inst, $4); + brw_inst_set_uip(p->devinfo, brw_last_inst, $5); + } else { + brw_set_src0(p, brw_last_inst, brw_ip_reg()); + brw_set_src1(p, brw_last_inst, brw_imm_d(0x0)); + if (p->devinfo->gen >= 6) { + brw_inst_set_jip(p->devinfo, brw_last_inst, $4); + brw_inst_set_uip(p->devinfo, brw_last_inst, $5); + } else { + brw_inst_set_gen4_jump_count(p->devinfo, brw_last_inst, + $4); + brw_inst_set_gen4_pop_count(p->devinfo, brw_last_inst, + $5); + } + } + + brw_pop_insn_state(p); + } + ; + +/* loop instruction */ +loopinstruction: + predicate WHILE execsize relativelocation instoptions + { + brw_next_insn(p, $2); + i965_asm_set_instruction_options(p, $5); + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $3); + + if (p->devinfo->gen >= 6) { + if (p->devinfo->gen >= 8) { + brw_set_dest(p, brw_last_inst, + retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src0(p, brw_last_inst, brw_imm_d($4)); + } else if (p->devinfo->gen == 7) { + brw_set_dest(p, brw_last_inst, + retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src0(p, brw_last_inst, + retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src1(p, brw_last_inst, + brw_imm_w(0x0)); + brw_inst_set_jip(p->devinfo, brw_last_inst, + $4); + } else { + brw_set_dest(p, brw_last_inst, brw_imm_w(0x0)); + brw_inst_set_gen6_jump_count(p->devinfo, + brw_last_inst, + $4); + brw_set_src0(p, brw_last_inst, + retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + brw_set_src1(p, brw_last_inst, + retype(brw_null_reg(), + BRW_REGISTER_TYPE_D)); + } + } else { + brw_set_dest(p, brw_last_inst, brw_ip_reg()); + brw_set_src0(p, brw_last_inst, brw_ip_reg()); + brw_set_src1(p, brw_last_inst, brw_imm_d(0x0)); + brw_inst_set_gen4_jump_count(p->devinfo, brw_last_inst, + $4); + brw_inst_set_gen4_pop_count(p->devinfo, brw_last_inst, + 0); + } + brw_pop_insn_state(p); + } + | DO execsize instoptions + { + brw_next_insn(p, $1); + if (p->devinfo->gen < 6) { + brw_inst_set_exec_size(p->devinfo, brw_last_inst, $2); + i965_asm_set_instruction_options(p, $3); + brw_set_dest(p, brw_last_inst, brw_null_reg()); + brw_set_src0(p, brw_last_inst, brw_null_reg()); + brw_set_src1(p, brw_last_inst, brw_null_reg()); + + brw_inst_set_qtr_control(p->devinfo, brw_last_inst, BRW_COMPRESSION_NONE); + } + } + ; + +/* Relative location */ +relativelocation2: + immreg + | reg32 + ; + +simple_int: + INTEGER { $$ = $1; } + | MINUS INTEGER { $$ = -$2; } + | LONG { $$ = $1; } + | MINUS LONG { $$ = -$2; } + ; + +rellocation: + relativelocation + | %empty { $$ = 0; } + ; + +relativelocation: + simple_int + { + $$ = $1; + } + ; + +/* Destination register */ +dst: + dstoperand + | dstoperandex + ; + +dstoperand: + dstreg dstregion writemask dsttype + { + $$ = $1; + + if ($2 == -1) { + $$.hstride = BRW_HORIZONTAL_STRIDE_1; + $$.vstride = BRW_VERTICAL_STRIDE_1; + $$.width = BRW_WIDTH_1; + } else { + $$.hstride = $2; + } + $$.type = $4.type; + $$.writemask = $3.writemask; + $$.swizzle = BRW_SWIZZLE_NOOP; + $$.subnr = $$.subnr * brw_reg_type_to_size($4.type); + } + ; + +dstoperandex: + dstoperandex_typed dstregion writemask dsttype + { + $$ = $1; + $$.hstride = $2; + $$.type = $4.type; + $$.writemask = $3.writemask; + $$.subnr = $$.subnr * brw_reg_type_to_size($4.type); + } + | dstoperandex_ud_typed + { + $$ = $1; + $$.hstride = 1; + $$.type = BRW_REGISTER_TYPE_UD; + } + /* BSpec says "When the conditional modifier is present, updates + * to the selected flag register also occur. In this case, the + * register region fields of the ‘null’ operand are valid." + */ + | nullreg dstregion writemask dsttype + { + $$ = $1; + if ($2 == -1) { + $$.hstride = BRW_HORIZONTAL_STRIDE_1; + $$.vstride = BRW_VERTICAL_STRIDE_1; + $$.width = BRW_WIDTH_1; + } else { + $$.hstride = $2; + } + $$.writemask = $3.writemask; + $$.type = $4.type; + } + | threadcontrolreg + { + $$ = $1; + $$.hstride = 1; + $$.type = BRW_REGISTER_TYPE_UW; + } + ; + +dstoperandex_ud_typed: + controlreg + | ipreg + | channelenablereg + | performancereg + ; + +dstoperandex_typed: + accreg + | flagreg + | addrreg + | maskreg + | statereg + ; + +dstreg: + directgenreg + { + $$ = $1; + $$.address_mode = BRW_ADDRESS_DIRECT; + } + | indirectgenreg + { + $$ = $1; + $$.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER; + } + | directmsgreg + { + $$ = $1; + $$.address_mode = BRW_ADDRESS_DIRECT; + } + | indirectmsgreg + { + $$ = $1; + $$.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER; + } + ; + +/* Source register */ +srcaccimm: + srcacc + | immreg + ; + +immreg: + immval srcimmtype + { + uint32_t u32; + uint64_t u64; + switch ($2.type) { + case BRW_REGISTER_TYPE_UD: + u32 = $1; + $$ = brw_imm_ud(u32); + break; + case BRW_REGISTER_TYPE_D: + $$ = brw_imm_d($1); + break; + case BRW_REGISTER_TYPE_UW: + u32 = $1 | ($1 << 16); + $$ = brw_imm_uw(u32); + break; + case BRW_REGISTER_TYPE_W: + u32 = $1; + $$ = brw_imm_w(u32); + break; + case BRW_REGISTER_TYPE_F: + $$ = brw_imm_reg(BRW_REGISTER_TYPE_F); + $$.u64 = $1; + $$.ud = $1; + break; + case BRW_REGISTER_TYPE_V: + $$ = brw_imm_v($1); + break; + case BRW_REGISTER_TYPE_UV: + $$ = brw_imm_uv($1); + break; + case BRW_REGISTER_TYPE_VF: + $$ = brw_imm_reg(BRW_REGISTER_TYPE_VF); + $$.d = $1; + break; + case BRW_REGISTER_TYPE_Q: + u64 = $1; + $$ = brw_imm_q(u64); + break; + case BRW_REGISTER_TYPE_UQ: + u64 = $1; + $$ = brw_imm_uq(u64); + break; + case BRW_REGISTER_TYPE_DF: + $$ = brw_imm_reg(BRW_REGISTER_TYPE_DF); + $$.d64 = $1; + break; + default: + error(&@2, "Unkown immdediate type %s\n", + brw_reg_type_to_letters($2.type)); + } + } + ; + +reg32: + directgenreg region srctype + { + $$ = set_direct_src_operand(&$1, $3.type); + $$ = stride($$, $2.vstride, $2.width, $2.hstride); + } + ; + +payload: + directsrcoperand + ; + +src: + directsrcoperand + | indirectsrcoperand + ; + +srcacc: + directsrcaccoperand + | indirectsrcoperand + ; + +srcimm: + directsrcoperand + | indirectsrcoperand + | immreg + ; + +directsrcaccoperand: + directsrcoperand + | accreg region srctype + { + $$ = set_direct_src_operand(&$1, $3.type); + $$.vstride = $2.vstride; + $$.width = $2.width; + $$.hstride = $2.hstride; + } + ; + +srcarcoperandex: + srcarcoperandex_typed region srctype + { + $$ = brw_reg($1.file, + $1.nr, + $1.subnr, + 0, + 0, + $3.type, + $2.vstride, + $2.width, + $2.hstride, + BRW_SWIZZLE_NOOP, + WRITEMASK_XYZW); + } + | srcarcoperandex_ud_typed + { + $$ = set_direct_src_operand(&$1, BRW_REGISTER_TYPE_UD); + } + | nullreg region srctype + { + $$ = set_direct_src_operand(&$1, $3.type); + $$.vstride = $2.vstride; + $$.width = $2.width; + $$.hstride = $2.hstride; + } + | threadcontrolreg + { + $$ = set_direct_src_operand(&$1, BRW_REGISTER_TYPE_UW); + } + ; + +srcarcoperandex_ud_typed: + controlreg + | statereg + | ipreg + | channelenablereg + ; + +srcarcoperandex_typed: + flagreg + | maskreg + ; + +indirectsrcoperand: + negate abs indirectgenreg indirectregion swizzle srctype + { + $$ = brw_reg($3.file, + 0, + $3.subnr, + $1, // negate + $2, // abs + $6.type, + $4.vstride, + $4.width, + $4.hstride, + $5.swizzle, + WRITEMASK_X); + + $$.address_mode = BRW_ADDRESS_REGISTER_INDIRECT_REGISTER; + // brw_reg set indirect_offset to 0 so set it to valid value + $$.indirect_offset = $3.indirect_offset; + } + ; + +directgenreg_list: + directgenreg + | directmsgreg + | notifyreg + | addrreg + | performancereg + ; + +directsrcoperand: + negate abs directgenreg_list region swizzle srctype + { + $$ = brw_reg($3.file, + $3.nr, + $3.subnr, + $1, + $2, + $6.type, + $4.vstride, + $4.width, + $4.hstride, + $5.swizzle, + WRITEMASK_X); + } + | srcarcoperandex + ; + +/* Address register */ +addrparam: + addrreg exp + { + memset(&$$, '\0', sizeof($$)); + $$.subnr = $1.subnr; + $$.indirect_offset = $2; + } + | addrreg + ; + +/* Register files and register numbers */ +exp: + INTEGER { $$ = $1; } + | LONG { $$ = $1; } + ; + +subregnum: + DOT exp { $$ = $2; } + | %empty %prec SUBREGNUM { $$ = 0; } + ; + +directgenreg: + GENREG subregnum + { + memset(&$$, '\0', sizeof($$)); + $$.file = BRW_GENERAL_REGISTER_FILE; + $$.nr = $1; + $$.subnr = $2; + } + ; + +indirectgenreg: + GENREGFILE LSQUARE addrparam RSQUARE + { + memset(&$$, '\0', sizeof($$)); + $$.file = BRW_GENERAL_REGISTER_FILE; + $$.subnr = $3.subnr; + $$.indirect_offset = $3.indirect_offset; + } + ; + +directmsgreg: + MSGREG subregnum + { + $$ = brw_message_reg($1); + $$.subnr = $2; + } + ; + +indirectmsgreg: + MSGREGFILE LSQUARE addrparam RSQUARE + { + memset(&$$, '\0', sizeof($$)); + $$.file = BRW_MESSAGE_REGISTER_FILE; + $$.subnr = $3.subnr; + $$.indirect_offset = $3.indirect_offset; + } + ; + +addrreg: + ADDRREG subregnum + { + if ($1 != 0) + error(&@1, "Address register number %d" + "out of range\n", $1); + + int subnr = (p->devinfo->gen >= 8) ? 16 : 8; + + if ($2 > subnr) + error(&@2, "Address sub resgister number %d" + "out of range\n", $2); + + $$ = brw_address_reg($2); + } + ; + +accreg: + ACCREG subregnum + { + int nr_reg; + if (p->devinfo->gen < 8) + nr_reg = 2; + else + nr_reg = 10; + + if ($1 > nr_reg) + error(&@1, "Accumulator register number %d" + " out of range\n", $1); + + memset(&$$, '\0', sizeof($$)); + $$.file = BRW_ARCHITECTURE_REGISTER_FILE; + $$.nr = BRW_ARF_ACCUMULATOR; + $$.subnr = $2; + } + ; + +flagreg: + FLAGREG subregnum + { + // SNB = 1 flag reg and IVB+ = 2 flag reg + int nr_reg = (p->devinfo->gen >= 7) ? 2 : 1; + int subnr = nr_reg; + + if ($1 > nr_reg) + error(&@1, "Flag register number %d" + " out of range \n", $1); + if ($2 > subnr) + error(&@2, "Flag subregister number %d" + " out of range\n", $2); + + $$.file = BRW_ARCHITECTURE_REGISTER_FILE; + $$.nr = BRW_ARF_FLAG | $1; + $$.subnr = $2; + } + ; + +maskreg: + MASKREG subregnum + { + if ($1 > 0) + error(&@1, "Mask register number %d" + " out of range\n", $1); + + $$ = brw_mask_reg($2); + } + ; + +notifyreg: + NOTIFYREG subregnum + { + if ($1 > 0) + error(&@1, "Notification register number %d" + " out of range\n", $1); + + int subnr = (p->devinfo->gen >= 11) ? 2 : 3; + if ($2 > subnr) + error(&@2, "Notification sub register number %d" + " out of range\n", $2); + + $$ = brw_notification_reg(); + $$.subnr = $2; + } + ; + +statereg: + STATEREG subregnum + { + if ($1 > 2) + error(&@1, "State register number %d" + " out of range\n", $1); + + if ($2 > 4) + error(&@2, "State sub register number %d" + " out of range\n", $2); + + $$ = brw_sr0_reg($2); + $$.nr = $1; + } + ; + +controlreg: + CONTROLREG subregnum + { + if ($1 > 0) + error(&@1, "Control register number %d" + " out of range\n", $1); + + if ($2 > 4) + error(&@2, "control sub register number %d" + " out of range\n", $2); + + $$ = brw_cr0_reg($2); + $$.nr = $1; + } + ; + +ipreg: + IPREG srctype { $$ = brw_ip_reg(); } + ; + +nullreg: + NULL_TOKEN { $$ = brw_null_reg(); } + ; + +threadcontrolreg: + THREADREG subregnum + { + if ($1 > 0) + error(&@1, "Thread control register number %d" + " out of range\n", $1); + + if ($2 > 7) + error(&@2, "Thread control sub register number %d" + " out of range\n", $2); + + $$ = brw_tdr_reg(); + $$.subnr = $2; + } + ; + +performancereg: + PERFORMANCEREG subregnum + { + int subnr; + if (p->devinfo->gen >= 10) + subnr = 5; + else if (p->devinfo->gen <= 8) + subnr = 3; + else + subnr = 4; + + if ($2 > subnr) + error(&@2, "Performance sub register number %d" + " out of range\n", $2); + + $$.file = BRW_ARCHITECTURE_REGISTER_FILE; + $$.nr = BRW_ARF_TIMESTAMP; + } + ; + +channelenablereg: + CHANNELENABLEREG subregnum + { + if ($1 > 0) + error(&@1, "Channel enable register number %d" + " out of range\n", $1); + + $$ = brw_mask_reg($2); + } + ; + +/* Immediate values */ +immval: + exp2 + { + $$ = $1; + } + | LSQUARE exp2 COMMA exp2 COMMA exp2 COMMA exp2 RSQUARE + { + $$ = ($2 << 0) | ($4 << 8) | ($6 << 16) | ($8 << 24); + } + ; + +/* Regions */ +dstregion: + %empty { $$ = -1; } + | LANGLE exp RANGLE + { + if ($2 != 0 && ($2 > 4 || !isPowerofTwo($2))) + error(&@2, "Invalid Horizontal stride %d\n", $2); + + $$ = ffs($2); + } + ; + +indirectregion: + region + | region_wh + ; + +region: + %empty + { + $$ = stride($$, BRW_VERTICAL_STRIDE_1, BRW_WIDTH_2, BRW_HORIZONTAL_STRIDE_1); + } + | LANGLE exp RANGLE + { + if ($2 != 0 && ($2 > 32 || !isPowerofTwo($2))) + error(&@2, "Invalid VertStride %d\n", $2); + + $$ = stride($$, $2, BRW_WIDTH_1, 0); + } + | LANGLE exp COMMA exp COMMA exp RANGLE + { + + if ($2 != 0 && ($2 > 32 || !isPowerofTwo($2))) + error(&@2, "Invalid VertStride %d\n", $2); + + if ($4 > 16 || !isPowerofTwo($4)) + error(&@4, "Invalid width %d\n", $4); + + if ($6 != 0 && ($6 > 4 || !isPowerofTwo($6))) + error(&@6, "Invalid Horizontal stride in" + " region_wh %d\n", $6); + + $$ = stride($$, $2, $4, $6); + } + | LANGLE exp SEMICOLON exp COMMA exp RANGLE + { + if ($2 != 0 && ($2 > 32 || !isPowerofTwo($2))) + error(&@2, "Invalid VertStride %d\n", $2); + + if ($4 > 16 || !isPowerofTwo($4)) + error(&@4, "Invalid width %d\n", $4); + + if ($6 != 0 && ($6 > 4 || !isPowerofTwo($6))) + error(&@6, "Invalid Horizontal stride in" + " region_wh %d\n", $6); + + $$ = stride($$, $2, $4, $6); + } + | LANGLE VxH COMMA exp COMMA exp RANGLE + { + if ($4 > 16 || !isPowerofTwo($4)) + error(&@4, "Invalid width %d\n", $4); + + if ($6 != 0 && ($6 > 4 || !isPowerofTwo($6))) + error(&@6, "Invalid Horizontal stride in" + " region_wh %d\n", $6); + + $$ = brw_VxH_indirect(0, 0); + } + ; + +region_wh: + LANGLE exp COMMA exp RANGLE + { + if ($2 > 16 || !isPowerofTwo($2)) + error(&@2, "Invalid width %d\n", $2); + + if ($4 != 0 && ($4 > 4 || !isPowerofTwo($4))) + error(&@4, "Invalid Horizontal stride in" + " region_wh %d\n", $4); + + $$ = stride($$, BRW_VERTICAL_STRIDE_ONE_DIMENSIONAL, $2, $4); + } + ; + +srctype: + %empty { $$ = retype($$, BRW_REGISTER_TYPE_F); } + | TYPE_F { $$ = retype($$, BRW_REGISTER_TYPE_F); } + | TYPE_UD { $$ = retype($$, BRW_REGISTER_TYPE_UD); } + | TYPE_D { $$ = retype($$, BRW_REGISTER_TYPE_D); } + | TYPE_UW { $$ = retype($$, BRW_REGISTER_TYPE_UW); } + | TYPE_W { $$ = retype($$, BRW_REGISTER_TYPE_W); } + | TYPE_UB { $$ = retype($$, BRW_REGISTER_TYPE_UB); } + | TYPE_B { $$ = retype($$, BRW_REGISTER_TYPE_B); } + | TYPE_DF { $$ = retype($$, BRW_REGISTER_TYPE_DF); } + | TYPE_UQ { $$ = retype($$, BRW_REGISTER_TYPE_UQ); } + | TYPE_Q { $$ = retype($$, BRW_REGISTER_TYPE_Q); } + | TYPE_HF { $$ = retype($$, BRW_REGISTER_TYPE_HF); } + | TYPE_NF { $$ = retype($$, BRW_REGISTER_TYPE_NF); } + ; + +srcimmtype: + srctype { $$ = $1; } + | TYPE_V { $$ = retype($$, BRW_REGISTER_TYPE_V); } + | TYPE_VF { $$ = retype($$, BRW_REGISTER_TYPE_VF); } + | TYPE_UV { $$ = retype($$, BRW_REGISTER_TYPE_UV); } + ; + +dsttype: + srctype { $$ = $1; } + ; + +writemask: + %empty + { + $$= brw_set_writemask($$, WRITEMASK_XYZW); + } + | DOT writemask_x writemask_y writemask_z writemask_w + { + $$ = brw_set_writemask($$, $2 | $3 | $4 | $5); + } + ; + +writemask_x: + %empty { $$ = 0; } + | X { $$ = 1 << BRW_CHANNEL_X; } + ; + +writemask_y: + %empty { $$ = 0; } + | Y { $$ = 1 << BRW_CHANNEL_Y; } + ; + +writemask_z: + %empty { $$ = 0; } + | Z { $$ = 1 << BRW_CHANNEL_Z; } + ; + +writemask_w: + %empty { $$ = 0; } + | W { $$ = 1 << BRW_CHANNEL_W; } + ; + +swizzle: + %empty + { + $$.swizzle = BRW_SWIZZLE_NOOP; + } + | DOT chansel + { + $$.swizzle = BRW_SWIZZLE4($2, $2, $2, $2); + } + | DOT chansel chansel chansel chansel + { + $$.swizzle = BRW_SWIZZLE4($2, $3, $4, $5); + } + ; + +chansel: + X + | Y + | Z + | W + ; + +/* Instruction prediction and modifiers */ +predicate: + %empty + { + brw_push_insn_state(p); + brw_set_default_predicate_control(p, BRW_PREDICATE_NONE); + brw_set_default_flag_reg(p, 0, 0); + brw_set_default_predicate_inverse(p, false); + } + | LPAREN predstate flagreg predctrl RPAREN + { + brw_push_insn_state(p); + brw_set_default_predicate_inverse(p, $2); + brw_set_default_flag_reg(p, $3.nr, $3.subnr); + brw_set_default_predicate_control(p, $4); + } + ; + +predstate: + %empty { $$ = 0; } + | PLUS { $$ = 0; } + | MINUS { $$ = 1; } + ; + +predctrl: + %empty { $$ = BRW_PREDICATE_NORMAL; } + | DOT X { $$ = BRW_PREDICATE_ALIGN16_REPLICATE_X; } + | DOT Y { $$ = BRW_PREDICATE_ALIGN16_REPLICATE_Y; } + | DOT Z { $$ = BRW_PREDICATE_ALIGN16_REPLICATE_Z; } + | DOT W { $$ = BRW_PREDICATE_ALIGN16_REPLICATE_W; } + | ANYV + | ALLV + | ANY2H + | ALL2H + | ANY4H + | ALL4H + | ANY8H + | ALL8H + | ANY16H + | ALL16H + | ANY32H + | ALL32H + ; + +/* Source Modification */ +negate: + %empty { $$ = 0; } + | MINUS { $$ = 1; } + ; + +abs: + %empty { $$ = 0; } + | ABS { $$ = 1; } + ; + +/* Flag (Conditional) Modifier */ +cond_mod: + condModifiers + { + $$.cond_modifier = $1; + $$.flag_reg_nr = 0; + $$.flag_subreg_nr = 0; + } + | condModifiers DOT flagreg + { + $$.cond_modifier = $1; + $$.flag_reg_nr = $3.nr; + $$.flag_subreg_nr = $3.subnr; + } + ; + +condModifiers: + %empty { $$ = BRW_CONDITIONAL_NONE; } + | ZERO + | EQUAL + | NOT_ZERO + | NOT_EQUAL + | GREATER + | GREATER_EQUAL + | LESS + | LESS_EQUAL + | OVERFLOW + | ROUND_INCREMENT + | UNORDERED + ; + +saturate: + %empty { $$ = BRW_INSTRUCTION_NORMAL; } + | SATURATE { $$ = BRW_INSTRUCTION_SATURATE; } + ; + +/* Execution size */ +execsize: + %empty %prec EMPTYEXECSIZE + { + $$ = 0; + } + | LPAREN exp2 RPAREN + { + if ($2 > 32 || !isPowerofTwo($2)) + error(&@2, "Invalid execution size %d\n", $2); + + $$ = cvt($2) - 1; + } + ; + +/* Instruction options */ +instoptions: + %empty + { + memset(&$$, 0, sizeof($$)); + } + | LCURLY instoption_list RCURLY + { + memset(&$$, 0, sizeof($$)); + $$ = $2; + } + ; + +instoption_list: + instoption_list COMMA instoption + { + memset(&$$, 0, sizeof($$)); + $$ = $1; + add_instruction_option(&$$, $3); + } + | instoption_list instoption + { + memset(&$$, 0, sizeof($$)); + $$ = $1; + add_instruction_option(&$$, $2); + } + | %empty + { + memset(&$$, 0, sizeof($$)); + } + ; + +instoption: + ALIGN1 { $$ = ALIGN1;} + | ALIGN16 { $$ = ALIGN16; } + | ACCWREN { $$ = ACCWREN; } + | SECHALF { $$ = SECHALF; } + | COMPR { $$ = COMPR; } + | COMPR4 { $$ = COMPR4; } + | BREAKPOINT { $$ = BREAKPOINT; } + | NODDCLR { $$ = NODDCLR; } + | NODDCHK { $$ = NODDCHK; } + | MASK_DISABLE { $$ = MASK_DISABLE; } + | EOT { $$ = EOT; } + | SWITCH { $$ = SWITCH; } + | ATOMIC { $$ = ATOMIC; } + | CMPTCTRL { $$ = CMPTCTRL; } + | WECTRL { $$ = WECTRL; } + | QTR_2Q { $$ = QTR_2Q; } + | QTR_3Q { $$ = QTR_3Q; } + | QTR_4Q { $$ = QTR_4Q; } + | QTR_2H { $$ = QTR_2H; } + | QTR_2N { $$ = QTR_2N; } + | QTR_3N { $$ = QTR_3N; } + | QTR_4N { $$ = QTR_4N; } + | QTR_5N { $$ = QTR_5N; } + | QTR_6N { $$ = QTR_6N; } + | QTR_7N { $$ = QTR_7N; } + | QTR_8N { $$ = QTR_8N; } + ; + +%% + +extern int yylineno; + +void +yyerror(char *msg) +{ + fprintf(stderr, "%s: %d: %s at \"%s\"\n", + input_filename, yylineno, msg, lex_text()); + ++errors; +} diff --git a/src/intel/tools/i965_lex.l b/src/intel/tools/i965_lex.l new file mode 100644 index 00000000000..3aa2bd64083 --- /dev/null +++ b/src/intel/tools/i965_lex.l @@ -0,0 +1,404 @@ +%option yylineno +%option nounput +%{ +#include <string.h> +#include "i965_asm.h" +#include "i965_gram.tab.h" + +/* Locations */ +int yycolumn = 1; + +int saved_state = 0; +extern char *input_filename; + +#define YY_NO_INPUT +#define YY_USER_ACTION \ + yylloc.first_line = yylloc.last_line = yylineno; \ + yylloc.first_column = yycolumn; \ + yylloc.last_column = yycolumn + yyleng - 1; \ + yycolumn += yyleng; +%} + +%x BLOCK_COMMENT +%x FILENAME +%x CHANNEL +%x REG +%x DOTSEL +%% + + /* eat up single line comment */ +\/\/.*[\r\n] { yycolumn = 1; } + + /* eat up multiline comment */ +\/\* { saved_state = YYSTATE; BEGIN(BLOCK_COMMENT); } + +<BLOCK_COMMENT>\*\/ { BEGIN(saved_state); } + +<BLOCK_COMMENT>. { } +<BLOCK_COMMENT>[\r\n] { } + +<FILENAME>\"[^\"]+\" { + char *name = malloc(yyleng - 1); + memmove(name, yytext + 1, yyleng - 2); + name[yyleng-1] = '\0'; + input_filename = name; + } + + /* null register */ +null { BEGIN(REG); return NULL_TOKEN; } + + /* Opcodes */ +add { yylval.integer = BRW_OPCODE_ADD; return ADD; } +addc { yylval.integer = BRW_OPCODE_ADDC; return ADDC; } +and { yylval.integer = BRW_OPCODE_AND; return AND; } +asr { yylval.integer = BRW_OPCODE_ASR; return ASR; } +avg { yylval.integer = BRW_OPCODE_AVG; return AVG; } +bfe { yylval.integer = BRW_OPCODE_BFE; return BFE; } +bfi1 { yylval.integer = BRW_OPCODE_BFI1; return BFI1; } +bfi2 { yylval.integer = BRW_OPCODE_BFI2; return BFI2; } +bfrev { yylval.integer = BRW_OPCODE_BFREV; return BFREV; } +brc { yylval.integer = BRW_OPCODE_BRC; return BRC; } +brd { yylval.integer = BRW_OPCODE_BRD; return BRD; } +break { yylval.integer = BRW_OPCODE_BREAK; return BREAK; } +call { yylval.integer = BRW_OPCODE_CALL; return CALL; } +calla { yylval.integer = BRW_OPCODE_CALLA; return CALLA; } +case { yylval.integer = BRW_OPCODE_CASE; return CASE; } +cbit { yylval.integer = BRW_OPCODE_CBIT; return CBIT; } +cmp { yylval.integer = BRW_OPCODE_CMP; return CMP; } +cmpn { yylval.integer = BRW_OPCODE_CMPN; return CMPN; } +cont { yylval.integer = BRW_OPCODE_CONTINUE; return CONT; } +csel { yylval.integer = BRW_OPCODE_CSEL; return CSEL; } +dim { yylval.integer = BRW_OPCODE_DIM; return DIM; } +do { yylval.integer = BRW_OPCODE_DO; return DO; } +dp2 { yylval.integer = BRW_OPCODE_DP2; return DP2; } +dp3 { yylval.integer = BRW_OPCODE_DP3; return DP3; } +dp4 { yylval.integer = BRW_OPCODE_DP4; return DP4; } +dph { yylval.integer = BRW_OPCODE_DPH; return DPH; } +else { yylval.integer = BRW_OPCODE_ELSE; return ELSE; } +endif { yylval.integer = BRW_OPCODE_ENDIF; return ENDIF; } +f16to32 { yylval.integer = BRW_OPCODE_F16TO32; return F16TO32; } +f32to16 { yylval.integer = BRW_OPCODE_F32TO16; return F32TO16; } +fbh { yylval.integer = BRW_OPCODE_FBH; return FBH; } +fbl { yylval.integer = BRW_OPCODE_FBL; return FBL; } +fork { yylval.integer = BRW_OPCODE_FORK; return FORK; } +frc { yylval.integer = BRW_OPCODE_FRC; return FRC; } +goto { yylval.integer = BRW_OPCODE_GOTO; return GOTO; } +halt { yylval.integer = BRW_OPCODE_HALT; return HALT; } +if { yylval.integer = BRW_OPCODE_IF; return IF; } +iff { yylval.integer = BRW_OPCODE_IFF; return IFF; } +illegal { yylval.integer = BRW_OPCODE_ILLEGAL; return ILLEGAL; } +jmpi { yylval.integer = BRW_OPCODE_JMPI; return JMPI; } +line { yylval.integer = BRW_OPCODE_LINE; return LINE; } +lrp { yylval.integer = BRW_OPCODE_LRP; return LRP; } +lzd { yylval.integer = BRW_OPCODE_LZD; return LZD; } +mac { yylval.integer = BRW_OPCODE_MAC; return MAC; } +mach { yylval.integer = BRW_OPCODE_MACH; return MACH; } +mad { yylval.integer = BRW_OPCODE_MAD; return MAD; } +madm { yylval.integer = BRW_OPCODE_MADM; return MADM; } +mov { yylval.integer = BRW_OPCODE_MOV; return MOV; } +movi { yylval.integer = BRW_OPCODE_MOVI; return MOVI; } +mul { yylval.integer = BRW_OPCODE_MUL; return MUL; } +mrest { yylval.integer = BRW_OPCODE_MREST; return MREST; } +msave { yylval.integer = BRW_OPCODE_MSAVE; return MSAVE; } +nenop { yylval.integer = BRW_OPCODE_NENOP; return NENOP; } +nop { yylval.integer = BRW_OPCODE_NOP; return NOP; } +not { yylval.integer = BRW_OPCODE_NOT; return NOT; } +or { yylval.integer = BRW_OPCODE_OR; return OR; } +pln { yylval.integer = BRW_OPCODE_PLN; return PLN; } +pop { yylval.integer = BRW_OPCODE_POP; return POP; } +push { yylval.integer = BRW_OPCODE_PUSH; return PUSH; } +ret { yylval.integer = BRW_OPCODE_RET; return RET; } +rndd { yylval.integer = BRW_OPCODE_RNDD; return RNDD; } +rnde { yylval.integer = BRW_OPCODE_RNDE; return RNDE; } +rndu { yylval.integer = BRW_OPCODE_RNDU; return RNDU; } +rndz { yylval.integer = BRW_OPCODE_RNDZ; return RNDZ; } +sad2 { yylval.integer = BRW_OPCODE_SAD2; return SAD2; } +sada2 { yylval.integer = BRW_OPCODE_SADA2; return SADA2; } +sel { yylval.integer = BRW_OPCODE_SEL; return SEL; } +send { yylval.integer = BRW_OPCODE_SEND; return SEND; } +sendc { yylval.integer = BRW_OPCODE_SENDC; return SENDC; } +sends { yylval.integer = BRW_OPCODE_SENDS; return SENDS; } +sendsc { yylval.integer = BRW_OPCODE_SENDSC; return SENDSC; } +shl { yylval.integer = BRW_OPCODE_SHL; return SHL; } +shr { yylval.integer = BRW_OPCODE_SHR; return SHR; } +smov { yylval.integer = BRW_OPCODE_SMOV; return SMOV; } +subb { yylval.integer = BRW_OPCODE_SUBB; return SUBB; } +wait { yylval.integer = BRW_OPCODE_WAIT; return WAIT; } +while { yylval.integer = BRW_OPCODE_WHILE; return WHILE; } +xor { yylval.integer = BRW_OPCODE_XOR; return XOR; } + + /* extended math functions */ +cos { yylval.integer = BRW_MATH_FUNCTION_COS; return COS; } +exp { yylval.integer = BRW_MATH_FUNCTION_EXP; return EXP; } +fdiv { yylval.integer = BRW_MATH_FUNCTION_FDIV; return FDIV; } +inv { yylval.integer = BRW_MATH_FUNCTION_INV; return INV; } +invm { yylval.integer = GEN8_MATH_FUNCTION_INVM; return INVM; } +intdiv { + yylval.integer = BRW_MATH_FUNCTION_INT_DIV_QUOTIENT; + return INTDIV; + } +intdivmod { + yylval.integer = + BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER; + return INTDIVMOD; + } +intmod { + yylval.integer = BRW_MATH_FUNCTION_INT_DIV_REMAINDER; + return INTMOD; + } +log { yylval.integer = BRW_MATH_FUNCTION_LOG; return LOG; } +pow { yylval.integer = BRW_MATH_FUNCTION_POW; return POW; } +rsq { yylval.integer = BRW_MATH_FUNCTION_RSQ; return RSQ; } +rsqrtm { yylval.integer = GEN8_MATH_FUNCTION_RSQRTM; return RSQRTM; } +sin { yylval.integer = BRW_MATH_FUNCTION_SIN; return SIN; } +sqrt { yylval.integer = BRW_MATH_FUNCTION_SQRT; return SQRT; } +sincos { yylval.integer = BRW_MATH_FUNCTION_SINCOS; return SINCOS; } + + /* shared functions for send instruction */ +sampler { return SAMPLER; } +dp_sampler { return DP_SAMPLER; } +gateway { return GATEWAY; } +urb { return URB; } +thread_spawner { return THREAD_SPAWNER; } +render { return RENDER; } +const { return CONST; } +data { return DATA; } +cre { return CRE; } +math { return MATH; } +read { return READ; } +write { return WRITE; } +vme { return VME; } +"pixel interp" { return PIXEL_INTERP; } +"dp data 1" { return DP_DATA_1; } + +";" { return SEMICOLON; } +":" { return COLON; } +"(" { return LPAREN; } +")" { return RPAREN; } +"{" { return LCURLY; } +"}" { return RCURLY; } +"[" { return LSQUARE; } +"]" { return RSQUARE; } +"<" { return LANGLE; } +">" { return RANGLE; } +"," { return COMMA; } +"." { return DOT; } +"+" { return PLUS; } +"-" { return MINUS; } +"~" { return MINUS; } +"(abs)" { return ABS; } + + +"VxH" { return VxH; } +<REG>"<" { return LANGLE; } +<REG>[0-9][0-9]* { + yylval.integer = strtoul(yytext, NULL, 10); + return INTEGER; + } +<REG>">" { return RANGLE; } +<REG>"," { return COMMA; } +<REG>"." { BEGIN(DOTSEL); return DOT; } +<REG>";" { return SEMICOLON; } + +<DOTSEL>"x" { yylval.integer = BRW_CHANNEL_X; return X; } +<DOTSEL>"y" { yylval.integer = BRW_CHANNEL_Y; return Y; } +<DOTSEL>"z" { yylval.integer = BRW_CHANNEL_Z; return Z; } +<DOTSEL>"w" { yylval.integer = BRW_CHANNEL_W; return W; } +<DOTSEL>[0-9][0-9]* { + yylval.integer = strtoul(yytext, NULL, 10); + BEGIN(REG); + return INTEGER; + } +<DOTSEL>. { yyless(0); BEGIN(INITIAL); } +<REG>. { yyless(0); BEGIN(INITIAL); } + + /* Access mode */ +"align1" { return ALIGN1; } +"align16" { return ALIGN16; } + + /* Accumulator write control */ +AccWrEnable { return ACCWREN; } + + /* Mask control (formerly WECtrl/Write Enable Control) */ +"WE_all" { return WECTRL; } + + /* Compaction control */ +compacted { return CMPTCTRL; } + + /* Debug control */ +breakpoint { return BREAKPOINT; } + + /* Dependency control */ +NoDDClr { return NODDCLR; } +NoDDChk { return NODDCHK; } + + /* End of thread */ +EOT { return EOT; } + + /* Mask control */ +nomask { return MASK_DISABLE; } + + /* Channel */ +<CHANNEL>"x" { yylval.integer = BRW_CHANNEL_X; return X; } +<CHANNEL>"y" { yylval.integer = BRW_CHANNEL_Y; return Y; } +<CHANNEL>"z" { yylval.integer = BRW_CHANNEL_Z; return Z; } +<CHANNEL>"w" { yylval.integer = BRW_CHANNEL_W; return W; } +<CHANNEL>[0-9][0-9]* { + yylval.integer = strtoul(yytext, NULL, 10); + return INTEGER; + } +<CHANNEL>"." { return DOT; } +<CHANNEL>. { yyless(0); BEGIN(INITIAL); } + + + /* Predicate Control */ +<CHANNEL>".anyv" { yylval.integer = BRW_PREDICATE_ALIGN1_ANYV; return ANYV; } +<CHANNEL>".allv" { yylval.integer = BRW_PREDICATE_ALIGN1_ALLV; return ALLV; } +<CHANNEL>".any2h" { yylval.integer = BRW_PREDICATE_ALIGN1_ANY2H; return ANY2H; } +<CHANNEL>".all2h" { yylval.integer = BRW_PREDICATE_ALIGN1_ALL2H; return ALL2H; } +<CHANNEL>".any4h" { yylval.integer = BRW_PREDICATE_ALIGN16_ANY4H; return ANY4H; } +<CHANNEL>".all4h" { yylval.integer = BRW_PREDICATE_ALIGN16_ALL4H; return ALL4H; } +<CHANNEL>".any8h" { yylval.integer = BRW_PREDICATE_ALIGN1_ANY8H; return ANY8H; } +<CHANNEL>".all8h" { yylval.integer = BRW_PREDICATE_ALIGN1_ALL8H; return ALL8H; } +<CHANNEL>".any16h" { yylval.integer = BRW_PREDICATE_ALIGN1_ANY16H; return ANY16H; } +<CHANNEL>".all16h" { yylval.integer = BRW_PREDICATE_ALIGN1_ALL16H; return ALL16H; } +<CHANNEL>".any32h" { yylval.integer = BRW_PREDICATE_ALIGN1_ANY32H; return ANY32H; } +<CHANNEL>".all32h" { yylval.integer = BRW_PREDICATE_ALIGN1_ALL32H; return ALL32H; } + + /* Saturation */ +".sat" { return SATURATE; } + + /* Thread control */ +atomic { return ATOMIC; } +switch { return SWITCH; } + + /* compression control */ +compr { return COMPR; } +compr4 { return COMPR4; } +sechalf { return SECHALF; } + + /* Quarter Control */ +1[HNQ] { } +"2Q" { return QTR_2Q; } +"3Q" { return QTR_3Q; } +"4Q" { return QTR_4Q; } +"2H" { return QTR_2H; } +"2N" { return QTR_2N; } +"3N" { return QTR_3N; } +"4N" { return QTR_4N; } +"5N" { return QTR_5N; } +"6N" { return QTR_6N; } +"7N" { return QTR_7N; } +"8N" { return QTR_8N; } + + /* data types */ +:?B { return TYPE_B; } +:?D { return TYPE_D; } +:?DF { return TYPE_DF; } +:?F { return TYPE_F; } +:?HF { return TYPE_HF; } +:?NF { return TYPE_NF; } +:?Q { return TYPE_Q; } +:?UB { return TYPE_UB; } +:?UD { return TYPE_UD; } +:?UW { return TYPE_UW; } +:?UQ { return TYPE_UQ; } +:?UV { return TYPE_UV; } +:?V { return TYPE_V; } +:?VF { return TYPE_VF; } +:?W { return TYPE_W; } + + /* Address registers */ +"a0" { yylval.integer = atoi(yytext + 1); BEGIN(REG); return ADDRREG; } + + /* accumulator registers */ +"acc"[0-9]+ { yylval.integer = atoi(yytext + 3); return ACCREG; } + + /* channel enable registers */ +"ce0" { return CHANNELENABLEREG; } + + /* control registers */ +"cr0" { return CONTROLREG; } + + /* flag registers */ +"f"[0|1] { BEGIN(CHANNEL); yylval.integer = atoi(yytext + 1); return FLAGREG; } + + /* message control registers */ +"m" { return MSGREGFILE; } +m[0-9]+ { yylval.integer = atoi(yytext + 1); BEGIN(REG); return MSGREG; } + + /* state register */ +sr[0-9]+ { yylval.integer = atoi(yytext + 2); return STATEREG; } + + /* notification registers */ +"n"[0-2]+ { yylval.integer = atoi(yytext + 1); BEGIN(REG); return NOTIFYREG; } + + /* IP register */ +"ip" { return IPREG; } + + /* Thread control register */ +"tdr0" { return THREADREG; } + + /* performance register */ +"tm0" { BEGIN(REG); return PERFORMANCEREG; } + +[gr][0-9]+ { + yylval.integer = atoi(yytext + 1); + BEGIN(REG); return GENREG; + } +[gr] { return GENREGFILE; } +"mask"[0-9]+ { yylval.integer = atoi(yytext + 4); return MASKREG; } + + /* Conditional modifiers */ +".e" { yylval.integer = BRW_CONDITIONAL_Z; return EQUAL; } +".g" { yylval.integer = BRW_CONDITIONAL_G; return GREATER; } +".ge" { yylval.integer = BRW_CONDITIONAL_GE; return GREATER_EQUAL; } +".l" { yylval.integer = BRW_CONDITIONAL_L; return LESS; } +".le" { yylval.integer = BRW_CONDITIONAL_LE; return LESS_EQUAL; } +".ne" { yylval.integer = BRW_CONDITIONAL_NZ; return NOT_EQUAL; } +".nz" { yylval.integer = BRW_CONDITIONAL_NZ; return NOT_ZERO; } +".o" { yylval.integer = BRW_CONDITIONAL_O; return OVERFLOW; } +".r" { yylval.integer = BRW_CONDITIONAL_R; return ROUND_INCREMENT; } +".u" { yylval.integer = BRW_CONDITIONAL_U; return UNORDERED; } +".z" { yylval.integer = BRW_CONDITIONAL_Z; return ZERO; } + + /* Eat up JIP and UIP token, their values will be parsed + * in numeric section + */ +"JIP: " { } +"UIP: " { } +"Jump: " { } +"Pop: " { } +[ \t]+ { } +"MsgDesc:"[^{]* { } + +"0x"[0-9a-f][0-9a-f]* { + yylval.llint = strtoull(yytext + 2, NULL, 16); + return LONG; + } +[0-9][0-9]* { + yylval.llint = strtoll(yytext, NULL, 10); + return LONG; + } + +\n { yycolumn = 1; } + +. { + fprintf(stderr, "%s: %d: %s: at \"%s\"\n", + input_filename, yylineno, + "unexpected token", lex_text()); + } +%% + +char * +lex_text(void) +{ + return yytext; +} + +#ifndef yywrap +int yywrap() +{ + return -1; +} +#endif diff --git a/src/intel/tools/meson.build b/src/intel/tools/meson.build index 1c061e251ea..472e5b301b1 100644 --- a/src/intel/tools/meson.build +++ b/src/intel/tools/meson.build @@ -127,3 +127,29 @@ if with_tools.contains('intel-ui') install : true ) endif + +i965_gram_tab = custom_target( + 'i965_gram.tab.[ch]', + input : 'i965_gram.y', + output : ['i965_gram.tab.c', 'i965_gram.tab.h'], + command : [ + prog_bison, '@INPUT@', '--defines=@OUTPUT1@', + '--output=@OUTPUT0@' + ] +) + +i965_lex_yy_c = custom_target( + 'i965_lex.yy.c', + input : 'i965_lex.l', + output : 'i965_lex.yy.c', + command : [prog_flex, '-o', '@OUTPUT@', '@INPUT@'] +) + +i965_asm = executable( + 'i965_asm', + ['i965_asm.c', i965_gram_tab[0], i965_gram_tab[1], i965_lex_yy_c], + include_directories : [inc_common, inc_intel], + link_with : [libintel_common, libintel_compiler, libintel_dev, libmesa_util], + c_args : [c_vis_args, no_override_init_args], + install : true +) |