assembler/bdw: Add gen8_instruction from mesa
authorDamien Lespiau <damien.lespiau@intel.com>
Wed, 30 Jan 2013 17:19:57 +0000 (17:19 +0000)
committerBen Widawsky <benjamin.widawsky@intel.com>
Wed, 6 Nov 2013 17:34:35 +0000 (09:34 -0800)
Signed-off-by: Damien Lespiau <damien.lespiau@intel.com>
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
assembler/Makefile.am
assembler/brw_compat.h
assembler/gen8_instruction.c [new file with mode: 0644]
assembler/gen8_instruction.h [new file with mode: 0644]
assembler/main.c

index 95ba08d..b3c042a 100644 (file)
@@ -18,6 +18,8 @@ libbrw_la_SOURCES =           \
        brw_eu_util.c           \
        brw_reg.h               \
        brw_structs.h           \
+       gen8_instruction.h      \
+       gen8_instruction.c      \
        ralloc.c                \
        ralloc.h                \
        $(NULL)
index 4bf7f31..e909182 100644 (file)
@@ -60,6 +60,8 @@ extern "C" {
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
 #define Elements(x) ARRAY_SIZE(x)
 
+typedef union { float f; int i; unsigned u; } fi_type;
+
 #ifdef __cplusplus
 } /* end of extern "C" */
 #endif
diff --git a/assembler/gen8_instruction.c b/assembler/gen8_instruction.c
new file mode 100644 (file)
index 0000000..7fb1eac
--- /dev/null
@@ -0,0 +1,375 @@
+/*
+ * Copyright © 2012 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.
+ */
+
+/** @file gen8_instruction.cpp
+ *
+ * A representation of a Gen8+ EU instruction, with helper methods to get
+ * and set various fields.  This is the actual hardware format.
+ */
+
+#include "brw_defines.h"
+#include "gen8_instruction.h"
+
+void
+gen8_set_dst(struct gen8_instruction *inst, struct brw_reg reg)
+{
+   /* MRFs haven't existed since Gen7, so we better not be using them. */
+   if (reg.file == BRW_MESSAGE_REGISTER_FILE) {
+      reg.file = BRW_GENERAL_REGISTER_FILE;
+      reg.nr += GEN7_MRF_HACK_START;
+   }
+
+   assert(reg.file != BRW_MESSAGE_REGISTER_FILE);
+
+   if (reg.file == BRW_GENERAL_REGISTER_FILE)
+      assert(reg.nr < BRW_MAX_GRF);
+
+   gen8_set_dst_reg_file(inst, reg.file);
+   gen8_set_dst_reg_type(inst, reg.type);
+
+   assert(reg.address_mode == BRW_ADDRESS_DIRECT);
+
+   gen8_set_dst_da_reg_nr(inst, reg.nr);
+
+   if (gen8_access_mode(inst) == BRW_ALIGN_1) {
+      /* Set Dst.SubRegNum[4:0] */
+      gen8_set_dst_da1_subreg_nr(inst, reg.subnr);
+
+      /* Set Dst.HorzStride */
+      if (reg.hstride == BRW_HORIZONTAL_STRIDE_0)
+         reg.hstride = BRW_HORIZONTAL_STRIDE_1;
+      gen8_set_dst_da1_hstride(inst, reg.hstride);
+   } else {
+      /* Align16 SubRegNum only has a single bit (bit 4; bits 3:0 MBZ). */
+      assert(reg.subnr == 0 || reg.subnr == 16);
+      gen8_set_dst_da16_subreg_nr(inst, reg.subnr >> 4);
+      gen8_set_da16_writemask(inst, reg.dw1.bits.writemask);
+   }
+
+   /* Generators should set a default exec_size of either 8 (SIMD4x2 or SIMD8)
+    * or 16 (SIMD16), as that's normally correct.  However, when dealing with
+    * small registers, we automatically reduce it to match the register size.
+    */
+   if (reg.width < BRW_EXECUTE_8)
+      gen8_set_exec_size(inst, reg.width);
+}
+
+static void
+gen8_validate_reg(struct gen8_instruction *inst, struct brw_reg reg)
+{
+   int hstride_for_reg[] = {0, 1, 2, 4};
+   int vstride_for_reg[] = {0, 1, 2, 4, 8, 16, 32, 64, 128, 256};
+   int width_for_reg[] = {1, 2, 4, 8, 16};
+   int execsize_for_reg[] = {1, 2, 4, 8, 16};
+   int width, hstride, vstride, execsize;
+
+   if (reg.file == BRW_IMMEDIATE_VALUE) {
+      /* TODO: check immediate vectors */
+      return;
+   }
+
+   if (reg.file == BRW_ARCHITECTURE_REGISTER_FILE)
+      return;
+
+   assert(reg.hstride >= 0 && reg.hstride < Elements(hstride_for_reg));
+   hstride = hstride_for_reg[reg.hstride];
+
+   if (reg.vstride == 0xf) {
+      vstride = -1;
+   } else {
+      assert(reg.vstride >= 0 && reg.vstride < Elements(vstride_for_reg));
+      vstride = vstride_for_reg[reg.vstride];
+   }
+
+   assert(reg.width >= 0 && reg.width < Elements(width_for_reg));
+   width = width_for_reg[reg.width];
+
+   assert(gen8_exec_size(inst) >= 0 &&
+         gen8_exec_size(inst) < Elements(execsize_for_reg));
+   execsize = execsize_for_reg[gen8_exec_size(inst)];
+
+   /* Restrictions from 3.3.10: Register Region Restrictions. */
+   /* 3. */
+   assert(execsize >= width);
+
+   /* 4. */
+   if (execsize == width && hstride != 0) {
+      assert(vstride == -1 || vstride == width * hstride);
+   }
+
+   /* 5. */
+   if (execsize == width && hstride == 0) {
+      /* no restriction on vstride. */
+   }
+
+   /* 6. */
+   if (width == 1) {
+      assert(hstride == 0);
+   }
+
+   /* 7. */
+   if (execsize == 1 && width == 1) {
+      assert(hstride == 0);
+      assert(vstride == 0);
+   }
+
+   /* 8. */
+   if (vstride == 0 && hstride == 0) {
+      assert(width == 1);
+   }
+
+   /* 10. Check destination issues. */
+}
+
+void
+gen8_set_src0(struct gen8_instruction *inst, struct brw_reg reg)
+{
+   /* MRFs haven't existed since Gen7, so we better not be using them. */
+   if (reg.file == BRW_MESSAGE_REGISTER_FILE) {
+      reg.file = BRW_GENERAL_REGISTER_FILE;
+      reg.nr += GEN7_MRF_HACK_START;
+   }
+
+   if (reg.file == BRW_GENERAL_REGISTER_FILE)
+      assert(reg.nr < BRW_MAX_GRF);
+
+   gen8_validate_reg(inst, reg);
+
+   gen8_set_src0_reg_file(inst, reg.file);
+   gen8_set_src0_reg_type(inst, reg.type);
+   gen8_set_src0_abs(inst, reg.abs);
+   gen8_set_src0_negate(inst, reg.negate);
+
+   assert(reg.address_mode == BRW_ADDRESS_DIRECT);
+
+   if (reg.file == BRW_IMMEDIATE_VALUE) {
+      inst->data[3] = reg.dw1.ud;
+
+      /* Required to set some fields in src1 as well: */
+      gen8_set_src1_reg_file(inst, 0); /* arf */
+      gen8_set_src1_reg_type(inst, reg.type);
+   } else {
+      gen8_set_src0_da_reg_nr(inst, reg.nr);
+
+      if (gen8_access_mode(inst) == BRW_ALIGN_1) {
+         /* Set Src0.SubRegNum[4:0] */
+         gen8_set_src0_da1_subreg_nr(inst, reg.subnr);
+
+         if (reg.width == BRW_WIDTH_1 &&
+            gen8_exec_size(inst) == BRW_EXECUTE_1) {
+            gen8_set_src0_da1_hstride(inst, BRW_HORIZONTAL_STRIDE_0);
+            gen8_set_src0_vert_stride(inst, BRW_VERTICAL_STRIDE_0);
+         } else {
+            gen8_set_src0_da1_hstride(inst, reg.hstride);
+            gen8_set_src0_vert_stride(inst, reg.vstride);
+         }
+         gen8_set_src0_da1_width(inst, reg.width);
+
+      } else {
+         /* Align16 SubRegNum only has a single bit (bit 4; bits 3:0 MBZ). */
+         assert(reg.subnr == 0 || reg.subnr == 16);
+         gen8_set_src0_da16_subreg_nr(inst, reg.subnr >> 4);
+
+         gen8_set_src0_da16_swiz_x(inst,
+                                  BRW_GET_SWZ(reg.dw1.bits.swizzle,
+                                              BRW_CHANNEL_X));
+         gen8_set_src0_da16_swiz_y(inst,
+                                  BRW_GET_SWZ(reg.dw1.bits.swizzle,
+                                              BRW_CHANNEL_Y));
+         gen8_set_src0_da16_swiz_z(inst,
+                                  BRW_GET_SWZ(reg.dw1.bits.swizzle,
+                                              BRW_CHANNEL_Z));
+         gen8_set_src0_da16_swiz_w(inst,
+                                  BRW_GET_SWZ(reg.dw1.bits.swizzle,
+                                              BRW_CHANNEL_W));
+
+         /* This is an oddity of the fact that we're using the same
+          * descriptions for registers in both Align16 and Align1 modes.
+          */
+         if (reg.vstride == BRW_VERTICAL_STRIDE_8)
+            gen8_set_src0_vert_stride(inst, BRW_VERTICAL_STRIDE_4);
+         else
+            gen8_set_src0_vert_stride(inst, reg.vstride);
+      }
+   }
+}
+
+void
+gen8_set_src1(struct gen8_instruction *inst, struct brw_reg reg)
+{
+   /* MRFs haven't existed since Gen7, so we better not be using them. */
+   if (reg.file == BRW_MESSAGE_REGISTER_FILE) {
+      reg.file = BRW_GENERAL_REGISTER_FILE;
+      reg.nr += GEN7_MRF_HACK_START;
+   }
+
+   if (reg.file == BRW_GENERAL_REGISTER_FILE)
+      assert(reg.nr < BRW_MAX_GRF);
+
+   gen8_validate_reg(inst, reg);
+
+   gen8_set_src1_reg_file(inst, reg.file);
+   gen8_set_src1_reg_type(inst, reg.type);
+   gen8_set_src1_abs(inst, reg.abs);
+   gen8_set_src1_negate(inst, reg.negate);
+
+   /* Only src1 can be an immediate in two-argument instructions. */
+   assert(gen8_src0_reg_file(inst) != BRW_IMMEDIATE_VALUE);
+
+   assert(reg.address_mode == BRW_ADDRESS_DIRECT);
+
+   if (reg.file == BRW_IMMEDIATE_VALUE) {
+      inst->data[3] = reg.dw1.ud;
+   } else {
+      gen8_set_src1_da_reg_nr(inst, reg.nr);
+
+      if (gen8_access_mode(inst) == BRW_ALIGN_1) {
+         /* Set Src0.SubRegNum[4:0] */
+         gen8_set_src1_da1_subreg_nr(inst, reg.subnr);
+
+         if (reg.width == BRW_WIDTH_1 &&
+            gen8_exec_size(inst) == BRW_EXECUTE_1) {
+            gen8_set_src1_da1_hstride(inst, BRW_HORIZONTAL_STRIDE_0);
+            gen8_set_src1_vert_stride(inst, BRW_VERTICAL_STRIDE_0);
+         } else {
+            gen8_set_src1_da1_hstride(inst, reg.hstride);
+            gen8_set_src1_vert_stride(inst, reg.vstride);
+         }
+         gen8_set_src1_da1_width(inst, reg.width);
+      } else {
+         /* Align16 SubRegNum only has a single bit (bit 4; bits 3:0 MBZ). */
+         assert(reg.subnr == 0 || reg.subnr == 16);
+         gen8_set_src1_da16_subreg_nr(inst, reg.subnr >> 4);
+
+         gen8_set_src1_da16_swiz_x(inst,
+                                  BRW_GET_SWZ(reg.dw1.bits.swizzle,
+                                              BRW_CHANNEL_X));
+         gen8_set_src1_da16_swiz_y(inst,
+                                  BRW_GET_SWZ(reg.dw1.bits.swizzle,
+                                              BRW_CHANNEL_Y));
+         gen8_set_src1_da16_swiz_z(inst,
+                                  BRW_GET_SWZ(reg.dw1.bits.swizzle,
+                                              BRW_CHANNEL_Z));
+         gen8_set_src1_da16_swiz_w(inst,
+                                  BRW_GET_SWZ(reg.dw1.bits.swizzle,
+                                              BRW_CHANNEL_W));
+
+         /* This is an oddity of the fact that we're using the same
+          * descriptions for registers in both Align16 and Align1 modes.
+          */
+         if (reg.vstride == BRW_VERTICAL_STRIDE_8)
+            gen8_set_src1_vert_stride(inst, BRW_VERTICAL_STRIDE_4);
+         else
+            gen8_set_src1_vert_stride(inst, reg.vstride);
+      }
+   }
+}
+
+/**
+ * Set the Message Descriptor and Extended Message Descriptor fields
+ * for SEND messages.
+ *
+ * \note This zeroes out the Function Control bits, so it must be called
+ *       \b before filling out any message-specific data.  Callers can
+ *       choose not to fill in irrelevant bits; they will be zero.
+ */
+static void
+gen8_set_message_descriptor(struct gen8_instruction *inst,
+                           enum brw_message_target sfid,
+                           unsigned msg_length,
+                           unsigned response_length,
+                           bool header_present,
+                           bool end_of_thread)
+{
+   gen8_set_src1(inst, brw_imm_d(0));
+
+   gen8_set_sfid(inst, sfid);
+   gen8_set_mlen(inst, msg_length);
+   gen8_set_rlen(inst, response_length);
+   gen8_set_header_present(inst, header_present);
+   gen8_set_eot(inst, end_of_thread);
+}
+
+void
+gen8_set_urb_message(struct gen8_instruction *inst,
+                    unsigned opcode,
+                    unsigned msg_length,
+                    unsigned response_length,
+                    bool end_of_thread,
+                    unsigned offset,
+                    bool interleave)
+{
+   gen8_set_message_descriptor(inst, BRW_SFID_URB, msg_length, response_length,
+                              true, end_of_thread);
+   gen8_set_src0(inst, brw_vec8_grf(GEN7_MRF_HACK_START + 1, 0));
+   gen8_set_urb_opcode(inst, 0); /* URB_WRITE_HWORD */
+   gen8_set_urb_global_offset(inst, offset);
+   gen8_set_urb_interleave(inst, interleave);
+   /* per_slot_offset = 0 makes it ignore offsets in message header */
+   gen8_set_urb_per_slot_offset(inst, 0);
+}
+
+void
+gen8_set_sampler_message(struct gen8_instruction *inst,
+                        unsigned binding_table_index,
+                        unsigned sampler,
+                        unsigned msg_type,
+                        unsigned response_length,
+                        unsigned msg_length,
+                        bool header_present,
+                        unsigned simd_mode)
+{
+   gen8_set_message_descriptor(inst, BRW_SFID_SAMPLER, msg_length,
+                              response_length, header_present, false);
+
+   gen8_set_binding_table_index(inst, binding_table_index);
+   gen8_set_sampler(inst, sampler);
+   gen8_set_sampler_msg_type(inst, msg_type);
+   gen8_set_sampler_simd_mode(inst, simd_mode);
+}
+
+void
+gen8_set_dp_message(struct gen8_instruction *inst,
+                   enum brw_message_target sfid,
+                   unsigned binding_table_index,
+                   unsigned msg_type,
+                   unsigned msg_control,
+                   unsigned mlen,
+                   unsigned rlen,
+                   bool header_present,
+                   bool end_of_thread)
+{
+   /* Binding table index is from 0..255 */
+   assert((binding_table_index & 0xff) == binding_table_index);
+
+   /* Message Type is only 5 bits */
+   assert((msg_type & 0x1f) == msg_type);
+
+   /* Message Control is only 6 bits */
+   assert((msg_control & 0x3f) == msg_control);
+
+   gen8_set_message_descriptor(inst, sfid, mlen, rlen, header_present,
+                              end_of_thread);
+   gen8_set_function_control(inst,
+         binding_table_index | msg_type << 14 | msg_control << 8);
+}
diff --git a/assembler/gen8_instruction.h b/assembler/gen8_instruction.h
new file mode 100644 (file)
index 0000000..0533011
--- /dev/null
@@ -0,0 +1,300 @@
+/*
+ * Copyright © 2012 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.
+ */
+
+/** @file gen8_instruction.h
+ *
+ * A representation of a Gen8+ EU instruction, with helper methods to get
+ * and set various fields.  This is the actual hardware format.
+ */
+
+#ifndef GEN8_INSTRUCTION_H
+#define GEN8_INSTRUCTION_H
+
+#include <stdio.h>
+#include <stdint.h>
+
+#include "brw_compat.h"
+#include "brw_reg.h"
+
+struct gen8_instruction {
+   uint32_t data[4];
+};
+
+static inline unsigned gen8_bits(struct gen8_instruction *insn,
+                                unsigned high,
+                                unsigned low);
+static inline void gen8_set_bits(struct gen8_instruction *insn,
+                                unsigned high,
+                                unsigned low,
+                                unsigned value);
+
+#define F(name, high, low) \
+   static inline void gen8_set_##name(struct gen8_instruction *insn, unsigned v) \
+   { \
+      gen8_set_bits(insn, high, low, v); \
+   } \
+   static inline unsigned gen8_##name(struct gen8_instruction *insn) \
+   { \
+      return gen8_bits(insn, high, low); \
+   }
+
+/**
+* Direct addressing only:
+*  @{
+*/
+F(src1_da_reg_nr,      108, 101);
+F(src0_da_reg_nr,       76,  69);
+F(dst_da1_hstride,      62,  61);
+F(dst_da_reg_nr,        60,  53);
+F(dst_da16_subreg_nr,   52,  52);
+F(dst_da1_subreg_nr,    52,  48);
+F(da16_writemask,       51,  48); /* Dst.ChanEn */
+/** @} */
+
+F(src1_vert_stride,    120, 117)
+F(src1_da1_width,      116, 114)
+F(src1_da16_swiz_w,    115, 114)
+F(src1_da16_swiz_z,    113, 112)
+F(src1_da1_hstride,    113, 112)
+F(src1_address_mode,   111, 111)
+/** Src1.SrcMod @{ */
+F(src1_negate,         110, 110)
+F(src1_abs,            109, 109)
+/** @} */
+F(src1_da16_subreg_nr, 100, 100)
+F(src1_da1_subreg_nr,  100,  96)
+F(src1_da16_swiz_y,     99,  98)
+F(src1_da16_swiz_x,     97,  96)
+F(src1_reg_type,        94,  91)
+F(src1_reg_file,        90,  89)
+F(src0_vert_stride,     88,  85)
+F(src0_da1_width,       84,  82)
+F(src0_da16_swiz_w,     83,  82)
+F(src0_da16_swiz_z,     81,  80)
+F(src0_da1_hstride,     81,  80)
+F(src0_address_mode,    79,  79)
+/** Src0.SrcMod @{ */
+F(src0_negate,          78,  78)
+F(src0_abs,             77,  77)
+/** @} */
+F(src0_da16_subreg_nr,  68,  68)
+F(src0_da1_subreg_nr,   68,  64)
+F(src0_da16_swiz_y,     67,  66)
+F(src0_da16_swiz_x,     65,  64)
+F(dst_address_mode,     63,  63)
+F(src0_reg_type,        46,  43)
+F(src0_reg_file,        42,  41)
+F(dst_reg_type,         40,  37)
+F(dst_reg_file,         36,  35)
+F(mask_control,         34,  34)
+F(flag_reg_nr,          33,  33)
+F(flag_subreg_nr,       32,  32)
+F(saturate,             31,  31)
+F(branch_control,       30,  30)
+F(debug_control,        30,  30)
+F(cmpt_control,         29,  29)
+F(acc_wr_control,       28,  28)
+F(cond_modifier,        27,  24)
+F(exec_size,            23,  21)
+F(pred_inv,             20,  20)
+F(pred_control,         19,  16)
+F(thread_control,       15,  14)
+F(qtr_control,          13,  12)
+F(nib_control,          11,  11)
+F(dep_control,          10,   9)
+F(access_mode,           8,   8)
+/* Bit 7 is Reserve d (for future Opcode expansion) */
+F(opcode,                6,   0)
+
+/**
+* Three-source instructions:
+*  @{
+*/
+F(src2_3src_reg_nr,    125, 118)
+F(src2_3src_subreg_nr, 117, 115)
+F(src2_3src_swizzle,   114, 107)
+F(src2_3src_rep_ctrl,  106, 106)
+F(src1_3src_reg_nr,    104,  97)
+F(src1_3src_subreg_hi,  96,  96)
+F(src1_3src_subreg_lo,  95,  94)
+F(src1_3src_swizzle,    93,  86)
+F(src1_3src_rep_ctrl,   85,  85)
+F(src0_3src_reg_nr,     83,  76)
+F(src0_3src_subreg_nr,  75,  73)
+F(src0_3src_swizzle,    72,  65)
+F(src0_3src_rep_ctrl,   64,  64)
+F(dst_3src_reg_nr,      63,  56)
+F(dst_3src_subreg_nr,   55,  53)
+F(dst_3src_writemask,   52,  49)
+F(dst_3src_type,        48,  46)
+F(src_3src_type,        45,  43)
+F(src2_3src_negate,     42,  42)
+F(src2_3src_abs,        41,  41)
+F(src1_3src_negate,     40,  40)
+F(src1_3src_abs,        39,  39)
+F(src0_3src_negate,     38,  38)
+F(src0_3src_abs,        37,  37)
+/** @} */
+
+/**
+* Fields for SEND messages:
+*  @{
+*/
+F(eot,                 127, 127)
+F(mlen,                124, 121)
+F(rlen,                120, 116)
+F(header_present,      115, 115)
+F(function_control,    114,  96)
+F(sfid,                 27,  24)
+F(math_function,        27,  24)
+/** @} */
+
+/**
+* URB message function control bits:
+*  @{
+*/
+F(urb_per_slot_offset, 113, 113)
+F(urb_interleave,      111, 111)
+F(urb_global_offset,   110, 100)
+F(urb_opcode,           99,  96)
+/** @} */
+
+/**
+* Sampler message function control bits:
+*  @{
+*/
+F(sampler_simd_mode,   114, 113)
+F(sampler_msg_type,    112, 108)
+F(sampler,             107, 104)
+F(binding_table_index, 103,  96)
+/** @} */
+#undef F
+
+/**
+* Flow control instruction bits:
+*  @{
+*/
+static inline unsigned gen8_uip(struct gen8_instruction *insn)
+{
+   return insn->data[2];
+}
+static inline void gen8_set_uip(struct gen8_instruction *insn, unsigned uip)
+{
+   insn->data[2] = uip;
+}
+static inline unsigned gen8_jip(struct gen8_instruction *insn)
+{
+   return insn->data[3];
+}
+static inline void gen8_set_jip(struct gen8_instruction *insn, unsigned jip)
+{
+   insn->data[3] = jip;
+}
+/** @} */
+
+static inline int gen8_src1_imm_d(struct gen8_instruction *insn)
+{
+   return insn->data[3];
+}
+static inline unsigned gen8_src1_imm_ud(struct gen8_instruction *insn)
+{
+   return insn->data[3];
+}
+static inline float gen8_src1_imm_f(struct gen8_instruction *insn)
+{
+   fi_type ft;
+
+   ft.u = insn->data[3];
+   return ft.f;
+}
+
+void gen8_set_dst(struct gen8_instruction *insn, struct brw_reg reg);
+void gen8_set_src0(struct gen8_instruction *insn, struct brw_reg reg);
+void gen8_set_src1(struct gen8_instruction *insn, struct brw_reg reg);
+
+void gen8_set_urb_message(struct gen8_instruction *insn,
+                         unsigned opcode, unsigned mlen, unsigned rlen,
+                         bool eot, unsigned offset, bool interleave);
+
+void gen8_set_sampler_message(struct gen8_instruction *insn,
+                             unsigned binding_table_index, unsigned sampler,
+                             unsigned msg_type, unsigned rlen, unsigned mlen,
+                             bool header_present, unsigned simd_mode);
+
+void gen8_set_dp_message(struct gen8_instruction *insn,
+                        enum brw_message_target sfid,
+                        unsigned binding_table_index,
+                        unsigned msg_type,
+                        unsigned msg_control,
+                        unsigned msg_length,
+                        unsigned response_length,
+                        bool header_present,
+                        bool end_of_thread);
+
+/** Disassemble the instruction. */
+int gen8_disassemble(FILE *file, struct gen8_instruction *insn, int gen);
+
+
+/**
+ * Fetch a set of contiguous bits from the instruction.
+ *
+ * Bits indexes range from 0..127; fields may not cross 32-bit boundaries.
+ */
+static inline unsigned
+gen8_bits(struct gen8_instruction *insn, unsigned high, unsigned low)
+{
+   /* We assume the field doesn't cross 32-bit boundaries. */
+   const unsigned word = high / 32;
+   assert(word == low / 32);
+
+   high %= 32;
+   low %= 32;
+
+   const unsigned mask = (((1 << (high - low + 1)) - 1) << low);
+
+   return (insn->data[word] & mask) >> low;
+}
+
+/**
+ * Set bits in the instruction, with proper shifting and masking.
+ *
+ * Bits indexes range from 0..127; fields may not cross 32-bit boundaries.
+ */
+static inline void
+gen8_set_bits(struct gen8_instruction *insn,
+             unsigned high,
+             unsigned low,
+             unsigned value)
+{
+   const unsigned word = high / 32;
+   assert(word == low / 32);
+
+   high %= 32;
+   low %= 32;
+
+   const unsigned mask = (((1 << (high - low + 1)) - 1) << low);
+
+   insn->data[word] = (insn->data[word] & ~mask) | ((value << low) & mask);
+}
+
+#endif
index 05ca337..809977b 100644 (file)
@@ -105,7 +105,7 @@ static void usage(void)
        fprintf(stderr, "\t-e, --export {exportfile}            Export label file\n");
        fprintf(stderr, "\t-l, --input_list {entrytablefile}    Input entry_table_list file\n");
        fprintf(stderr, "\t-o, --output {outputfile}            Specify output file\n");
-       fprintf(stderr, "\t-g, --gen <4|5|6|7>                  Specify GPU generation\n");
+       fprintf(stderr, "\t-g, --gen <4|5|6|7|8>                Specify GPU generation\n");
 }
 
 static int hash(char *key)
@@ -319,7 +319,7 @@ int main(int argc, char **argv)
                                }
                        }
 
-                       if (gen_level < 40 || gen_level > 75) {
+                       if (gen_level < 40 || gen_level > 80) {
                                usage();
                                exit(1);
                        }