intel/tools: New i965 instruction assembler tool
authorSagar Ghuge <sagar.ghuge@intel.com>
Tue, 11 Dec 2018 00:12:07 +0000 (16:12 -0800)
committerMatt Turner <mattst88@gmail.com>
Tue, 7 May 2019 21:33:38 +0000 (14:33 -0700)
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 <sagar.ghuge@intel.com>
Reviewed-by: Dylan Baker <dylan@pnwbakers.com>
Reviewed-by: Matt Turner <mattst88@gmail.com>
Closes: https://gitlab.freedesktop.org/mesa/mesa/merge_requests/141
src/intel/tools/i965_asm.c [new file with mode: 0644]
src/intel/tools/i965_asm.h [new file with mode: 0644]
src/intel/tools/i965_gram.y [new file with mode: 0644]
src/intel/tools/i965_lex.l [new file with mode: 0644]
src/intel/tools/meson.build

diff --git a/src/intel/tools/i965_asm.c b/src/intel/tools/i965_asm.c
new file mode 100644 (file)
index 0000000..667f43d
--- /dev/null
@@ -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 (file)
index 0000000..7027f4e
--- /dev/null
@@ -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 (file)
index 0000000..bbe7ce5
--- /dev/null
@@ -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 (file)
index 0000000..3aa2bd6
--- /dev/null
@@ -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
index 1c061e251eaf2c07092c202d3c418100d9b5e3c4..472e5b301b16ac6efb24fbb01a581654ed35c258 100644 (file)
@@ -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
+)