/* One of BRW_MASK_* */
unsigned mask_control:1;
+ /* Scheduling info for Gen12+ */
+ struct tgl_swsb swsb;
+
bool saturate:1;
/* One of BRW_ALIGN_* */
unsigned brw_get_default_exec_size(struct brw_codegen *p);
unsigned brw_get_default_group(struct brw_codegen *p);
unsigned brw_get_default_access_mode(struct brw_codegen *p);
+struct tgl_swsb brw_get_default_swsb(struct brw_codegen *p);
void brw_set_default_exec_size(struct brw_codegen *p, unsigned value);
void brw_set_default_mask_control( struct brw_codegen *p, unsigned value );
void brw_set_default_saturate( struct brw_codegen *p, bool enable );
brw_inst *inst, unsigned group);
void brw_set_default_group(struct brw_codegen *p, unsigned group);
void brw_set_default_compression_control(struct brw_codegen *p, enum brw_compression c);
-void brw_set_default_predicate_control( struct brw_codegen *p, unsigned pc );
+void brw_set_default_predicate_control(struct brw_codegen *p, enum brw_predicate pc);
void brw_set_default_predicate_inverse(struct brw_codegen *p, bool predicate_inverse);
void brw_set_default_flag_reg(struct brw_codegen *p, int reg, int subreg);
void brw_set_default_acc_write_control(struct brw_codegen *p, unsigned value);
+void brw_set_default_swsb(struct brw_codegen *p, struct tgl_swsb value);
void brw_init_codegen(const struct gen_device_info *, struct brw_codegen *p,
void *mem_ctx);
const void *assembly, int start, int end, FILE *out);
const unsigned *brw_get_program( struct brw_codegen *p, unsigned *sz );
+bool brw_try_override_assembly(struct brw_codegen *p, int start_offset,
+ const char *identifier);
+
brw_inst *brw_next_insn(struct brw_codegen *p, unsigned opcode);
void brw_set_dest(struct brw_codegen *p, brw_inst *insn, struct brw_reg dest);
void brw_set_src0(struct brw_codegen *p, brw_inst *insn, struct brw_reg reg);
struct brw_reg src1, \
struct brw_reg src2);
-#define ROUND(OP) \
-void brw_##OP(struct brw_codegen *p, struct brw_reg dest, struct brw_reg src0);
-
ALU1(MOV)
ALU2(SEL)
ALU1(NOT)
ALU2(SHL)
ALU1(DIM)
ALU2(ASR)
+ALU2(ROL)
+ALU2(ROR)
ALU3(CSEL)
ALU1(F32TO16)
ALU1(F16TO32)
ALU2(MUL)
ALU1(FRC)
ALU1(RNDD)
+ALU1(RNDE)
+ALU1(RNDU)
+ALU1(RNDZ)
ALU2(MAC)
ALU2(MACH)
ALU1(LZD)
ALU2(SUBB)
ALU2(MAC)
-ROUND(RNDZ)
-ROUND(RNDE)
-
#undef ALU1
#undef ALU2
#undef ALU3
-#undef ROUND
/* Helpers for SEND instruction:
}
static inline bool
-brw_message_desc_header_present(const struct gen_device_info *devinfo,
+brw_message_desc_header_present(ASSERTED const struct gen_device_info *devinfo,
uint32_t desc)
{
assert(devinfo->gen >= 5);
}
static inline unsigned
-brw_message_ex_desc(const struct gen_device_info *devinfo,
+brw_message_ex_desc(UNUSED const struct gen_device_info *devinfo,
unsigned ex_msg_length)
{
return SET_BITS(ex_msg_length, 9, 6);
}
static inline unsigned
-brw_message_ex_desc_ex_mlen(const struct gen_device_info *devinfo,
+brw_message_ex_desc_ex_mlen(UNUSED const struct gen_device_info *devinfo,
uint32_t ex_desc)
{
return GET_BITS(ex_desc, 9, 6);
}
+static inline uint32_t
+brw_urb_desc(const struct gen_device_info *devinfo,
+ unsigned msg_type,
+ bool per_slot_offset_present,
+ bool channel_mask_present,
+ unsigned global_offset)
+{
+ if (devinfo->gen >= 8) {
+ return (SET_BITS(per_slot_offset_present, 17, 17) |
+ SET_BITS(channel_mask_present, 15, 15) |
+ SET_BITS(global_offset, 14, 4) |
+ SET_BITS(msg_type, 3, 0));
+ } else if (devinfo->gen >= 7) {
+ assert(!channel_mask_present);
+ return (SET_BITS(per_slot_offset_present, 16, 16) |
+ SET_BITS(global_offset, 13, 3) |
+ SET_BITS(msg_type, 3, 0));
+ } else {
+ unreachable("unhandled URB write generation");
+ }
+}
+
+static inline uint32_t
+brw_urb_desc_msg_type(ASSERTED const struct gen_device_info *devinfo,
+ uint32_t desc)
+{
+ assert(devinfo->gen >= 7);
+ return GET_BITS(desc, 3, 0);
+}
+
/**
* Construct a message descriptor immediate with the specified sampler
* function controls.
}
static inline unsigned
-brw_sampler_desc_binding_table_index(const struct gen_device_info *devinfo,
+brw_sampler_desc_binding_table_index(UNUSED const struct gen_device_info *devinfo,
uint32_t desc)
{
return GET_BITS(desc, 7, 0);
}
static inline unsigned
-brw_sampler_desc_sampler(const struct gen_device_info *devinfo, uint32_t desc)
+brw_sampler_desc_sampler(UNUSED const struct gen_device_info *devinfo, uint32_t desc)
{
return GET_BITS(desc, 11, 8);
}
}
static inline unsigned
-brw_sampler_desc_return_format(const struct gen_device_info *devinfo,
+brw_sampler_desc_return_format(ASSERTED const struct gen_device_info *devinfo,
uint32_t desc)
{
assert(devinfo->gen == 4 && !devinfo->is_g4x);
}
static inline unsigned
-brw_dp_desc_binding_table_index(const struct gen_device_info *devinfo,
+brw_dp_desc_binding_table_index(UNUSED const struct gen_device_info *devinfo,
uint32_t desc)
{
return GET_BITS(desc, 7, 0);
return brw_dp_surface_desc(devinfo, msg_type, msg_control);
}
+static inline uint32_t
+brw_dp_dword_scattered_rw_desc(const struct gen_device_info *devinfo,
+ unsigned exec_size,
+ bool write)
+{
+ assert(exec_size == 8 || exec_size == 16);
+
+ unsigned msg_type;
+ if (write) {
+ if (devinfo->gen >= 6) {
+ msg_type = GEN6_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE;
+ } else {
+ msg_type = BRW_DATAPORT_WRITE_MESSAGE_DWORD_SCATTERED_WRITE;
+ }
+ } else {
+ if (devinfo->gen >= 7) {
+ msg_type = GEN7_DATAPORT_DC_DWORD_SCATTERED_READ;
+ } else if (devinfo->gen > 4 || devinfo->is_g4x) {
+ msg_type = G45_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ;
+ } else {
+ msg_type = BRW_DATAPORT_READ_MESSAGE_DWORD_SCATTERED_READ;
+ }
+ }
+
+ const unsigned msg_control =
+ SET_BITS(1, 1, 1) | /* Legacy SIMD Mode */
+ SET_BITS(exec_size == 16, 0, 0);
+
+ return brw_dp_surface_desc(devinfo, msg_type, msg_control);
+}
+
+static inline uint32_t
+brw_dp_a64_untyped_surface_rw_desc(const struct gen_device_info *devinfo,
+ unsigned exec_size, /**< 0 for SIMD4x2 */
+ unsigned num_channels,
+ bool write)
+{
+ assert(exec_size <= 8 || exec_size == 16);
+ assert(devinfo->gen >= 8);
+
+ unsigned msg_type =
+ write ? GEN8_DATAPORT_DC_PORT1_A64_UNTYPED_SURFACE_WRITE :
+ GEN8_DATAPORT_DC_PORT1_A64_UNTYPED_SURFACE_READ;
+
+ /* See also MDC_SM3 in the SKL PRM Vol 2d. */
+ const unsigned simd_mode = exec_size == 0 ? 0 : /* SIMD4x2 */
+ exec_size <= 8 ? 2 : 1;
+
+ const unsigned msg_control =
+ SET_BITS(brw_mdc_cmask(num_channels), 3, 0) |
+ SET_BITS(simd_mode, 5, 4);
+
+ return brw_dp_desc(devinfo, GEN8_BTI_STATELESS_NON_COHERENT,
+ msg_type, msg_control);
+}
+
+/**
+ * Calculate the data size (see MDC_A64_DS in the "Structures" volume of the
+ * Skylake PRM).
+ */
+static inline uint32_t
+brw_mdc_a64_ds(unsigned elems)
+{
+ switch (elems) {
+ case 1: return 0;
+ case 2: return 1;
+ case 4: return 2;
+ case 8: return 3;
+ default:
+ unreachable("Unsupported elmeent count for A64 scattered message");
+ }
+}
+
+static inline uint32_t
+brw_dp_a64_byte_scattered_rw_desc(const struct gen_device_info *devinfo,
+ unsigned exec_size, /**< 0 for SIMD4x2 */
+ unsigned bit_size,
+ bool write)
+{
+ assert(exec_size <= 8 || exec_size == 16);
+ assert(devinfo->gen >= 8);
+
+ unsigned msg_type =
+ write ? GEN8_DATAPORT_DC_PORT1_A64_SCATTERED_WRITE :
+ GEN9_DATAPORT_DC_PORT1_A64_SCATTERED_READ;
+
+ const unsigned msg_control =
+ SET_BITS(GEN8_A64_SCATTERED_SUBTYPE_BYTE, 1, 0) |
+ SET_BITS(brw_mdc_a64_ds(bit_size / 8), 3, 2) |
+ SET_BITS(exec_size == 16, 4, 4);
+
+ return brw_dp_desc(devinfo, GEN8_BTI_STATELESS_NON_COHERENT,
+ msg_type, msg_control);
+}
+
+static inline uint32_t
+brw_dp_a64_untyped_atomic_desc(const struct gen_device_info *devinfo,
+ ASSERTED unsigned exec_size, /**< 0 for SIMD4x2 */
+ unsigned bit_size,
+ unsigned atomic_op,
+ bool response_expected)
+{
+ assert(exec_size == 8);
+ assert(devinfo->gen >= 8);
+ assert(bit_size == 32 || bit_size == 64);
+
+ const unsigned msg_type = GEN8_DATAPORT_DC_PORT1_A64_UNTYPED_ATOMIC_OP;
+
+ const unsigned msg_control =
+ SET_BITS(atomic_op, 3, 0) |
+ SET_BITS(bit_size == 64, 4, 4) |
+ SET_BITS(response_expected, 5, 5);
+
+ return brw_dp_desc(devinfo, GEN8_BTI_STATELESS_NON_COHERENT,
+ msg_type, msg_control);
+}
+
+static inline uint32_t
+brw_dp_a64_untyped_atomic_float_desc(const struct gen_device_info *devinfo,
+ ASSERTED unsigned exec_size,
+ unsigned atomic_op,
+ bool response_expected)
+{
+ assert(exec_size == 8);
+ assert(devinfo->gen >= 9);
+
+ assert(exec_size > 0);
+ const unsigned msg_type = GEN9_DATAPORT_DC_PORT1_A64_UNTYPED_ATOMIC_FLOAT_OP;
+
+ const unsigned msg_control =
+ SET_BITS(atomic_op, 1, 0) |
+ SET_BITS(response_expected, 5, 5);
+
+ return brw_dp_desc(devinfo, GEN8_BTI_STATELESS_NON_COHERENT,
+ msg_type, msg_control);
+}
+
static inline uint32_t
brw_dp_typed_atomic_desc(const struct gen_device_info *devinfo,
unsigned exec_size,
struct brw_reg dst,
struct brw_reg payload,
struct brw_reg desc,
- unsigned desc_imm);
+ unsigned desc_imm,
+ bool eot);
void
brw_send_indirect_split_message(struct brw_codegen *p,
struct brw_reg desc,
unsigned desc_imm,
struct brw_reg ex_desc,
- unsigned ex_desc_imm);
+ unsigned ex_desc_imm,
+ bool eot);
void brw_ff_sync(struct brw_codegen *p,
struct brw_reg dest,
brw_inst *brw_BREAK(struct brw_codegen *p);
brw_inst *brw_CONT(struct brw_codegen *p);
-brw_inst *gen6_HALT(struct brw_codegen *p);
+brw_inst *brw_HALT(struct brw_codegen *p);
/* Forward jumps:
*/
void brw_WAIT(struct brw_codegen *p);
+void brw_SYNC(struct brw_codegen *p, enum tgl_sync_function func);
+
/* Special case: there is never a destination, execution size will be
* taken from src0:
*/
unsigned num_channels,
bool header_present);
-void
-brw_typed_atomic(struct brw_codegen *p,
- struct brw_reg dst,
- struct brw_reg payload,
- struct brw_reg surface,
- unsigned atomic_op,
- unsigned msg_length,
- bool response_expected,
- bool header_present);
-
-void
-brw_typed_surface_read(struct brw_codegen *p,
- struct brw_reg dst,
- struct brw_reg payload,
- struct brw_reg surface,
- unsigned msg_length,
- unsigned num_channels,
- bool header_present);
-
-void
-brw_typed_surface_write(struct brw_codegen *p,
- struct brw_reg payload,
- struct brw_reg surface,
- unsigned msg_length,
- unsigned num_channels,
- bool header_present);
-
void
brw_memory_fence(struct brw_codegen *p,
struct brw_reg dst,
- enum opcode send_op);
+ struct brw_reg src,
+ enum opcode send_op,
+ enum brw_message_target sfid,
+ bool commit_enable,
+ unsigned bti);
void
brw_pixel_interpolator_query(struct brw_codegen *p,
struct brw_reg idx);
void
-brw_rounding_mode(struct brw_codegen *p,
- enum brw_rnd_mode mode);
+brw_float_controls_mode(struct brw_codegen *p,
+ unsigned mode, unsigned mask);
/***********************************************************************
* brw_eu_util.c:
void brw_set_uip_jip(struct brw_codegen *p, int start_offset);
-enum brw_conditional_mod brw_negate_cmod(uint32_t cmod);
-enum brw_conditional_mod brw_swap_cmod(uint32_t cmod);
+enum brw_conditional_mod brw_negate_cmod(enum brw_conditional_mod cmod);
+enum brw_conditional_mod brw_swap_cmod(enum brw_conditional_mod cmod);
/* brw_eu_compact.c */
void brw_init_compaction_tables(const struct gen_device_info *devinfo);
brw_inst *orig, brw_inst *uncompacted);
/* brw_eu_validate.c */
+bool brw_validate_instruction(const struct gen_device_info *devinfo,
+ const brw_inst *inst, int offset,
+ struct disasm_info *disasm);
bool brw_validate_instructions(const struct gen_device_info *devinfo,
const void *assembly, int start_offset, int end_offset,
struct disasm_info *disasm);
}
struct opcode_desc {
- /* The union is an implementation detail used by brw_opcode_desc() to handle
- * opcodes that have been reused for different instructions across hardware
- * generations.
- *
- * The gens field acts as a tag. If it is non-zero, name points to a string
- * containing the instruction mnemonic. If it is zero, the table field is
- * valid and either points to a secondary opcode_desc table with 'size'
- * elements or is NULL and no such instruction exists for the opcode.
- */
- union {
- struct {
- char *name;
- int nsrc;
- };
- struct {
- const struct opcode_desc *table;
- unsigned size;
- };
- };
- int ndst;
- int gens;
+ unsigned ir;
+ unsigned hw;
+ const char *name;
+ int nsrc;
+ int ndst;
+ int gens;
};
const struct opcode_desc *
brw_opcode_desc(const struct gen_device_info *devinfo, enum opcode opcode);
+const struct opcode_desc *
+brw_opcode_desc_from_hw(const struct gen_device_info *devinfo, unsigned hw);
+
+static inline unsigned
+brw_opcode_encode(const struct gen_device_info *devinfo, enum opcode opcode)
+{
+ return brw_opcode_desc(devinfo, opcode)->hw;
+}
+
+static inline enum opcode
+brw_opcode_decode(const struct gen_device_info *devinfo, unsigned hw)
+{
+ const struct opcode_desc *desc = brw_opcode_desc_from_hw(devinfo, hw);
+ return desc ? (enum opcode)desc->ir : BRW_OPCODE_ILLEGAL;
+}
+
+static inline void
+brw_inst_set_opcode(const struct gen_device_info *devinfo,
+ brw_inst *inst, enum opcode opcode)
+{
+ brw_inst_set_hw_opcode(devinfo, inst, brw_opcode_encode(devinfo, opcode));
+}
+
+static inline enum opcode
+brw_inst_opcode(const struct gen_device_info *devinfo, const brw_inst *inst)
+{
+ return brw_opcode_decode(devinfo, brw_inst_hw_opcode(devinfo, inst));
+}
+
static inline bool
is_3src(const struct gen_device_info *devinfo, enum opcode opcode)
{