#ifndef BRW_INST_H
#define BRW_INST_H
+#include <assert.h>
#include <stdint.h>
-#include "brw_context.h"
+#include "brw_eu_defines.h"
+#include "common/gen_device_info.h"
#ifdef __cplusplus
extern "C" {
#define FC(name, high, low, assertions) \
static inline void \
-brw_inst_set_##name(const struct brw_device_info *devinfo, \
+brw_inst_set_##name(const struct gen_device_info *devinfo, \
brw_inst *inst, uint64_t v) \
{ \
assert(assertions); \
brw_inst_set_bits(inst, high, low, v); \
} \
static inline uint64_t \
-brw_inst_##name(const struct brw_device_info *devinfo, \
+brw_inst_##name(const struct gen_device_info *devinfo, \
const brw_inst *inst) \
{ \
assert(assertions); \
*/
#define FF(name, hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, hi7, lo7, hi8, lo8)\
static inline void \
-brw_inst_set_##name(const struct brw_device_info *devinfo, \
+brw_inst_set_##name(const struct gen_device_info *devinfo, \
brw_inst *inst, uint64_t value) \
{ \
BOUNDS(hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, hi7, lo7, hi8, lo8) \
brw_inst_set_bits(inst, high, low, value); \
} \
static inline uint64_t \
-brw_inst_##name(const struct brw_device_info *devinfo, const brw_inst *inst) \
+brw_inst_##name(const struct gen_device_info *devinfo, const brw_inst *inst) \
{ \
BOUNDS(hi4, lo4, hi45, lo45, hi5, lo5, hi6, lo6, hi7, lo7, hi8, lo8) \
return brw_inst_bits(inst, high, low); \
F(debug_control, 30, 30)
F(cmpt_control, 29, 29)
FC(branch_control, 28, 28, devinfo->gen >= 8)
-F(acc_wr_control, 28, 28)
+FC(acc_wr_control, 28, 28, devinfo->gen >= 6)
+FC(mask_control_ex, 28, 28, devinfo->is_g4x || devinfo->gen == 5)
F(cond_modifier, 27, 24)
FC(math_function, 27, 24, devinfo->gen >= 6)
F(exec_size, 23, 21)
* @{
*/
static inline void
-brw_inst_set_uip(const struct brw_device_info *devinfo,
+brw_inst_set_uip(const struct gen_device_info *devinfo,
brw_inst *inst, int32_t value)
{
assert(devinfo->gen >= 6);
}
static inline int32_t
-brw_inst_uip(const struct brw_device_info *devinfo, const brw_inst *inst)
+brw_inst_uip(const struct gen_device_info *devinfo, const brw_inst *inst)
{
assert(devinfo->gen >= 6);
}
static inline void
-brw_inst_set_jip(const struct brw_device_info *devinfo,
+brw_inst_set_jip(const struct gen_device_info *devinfo,
brw_inst *inst, int32_t value)
{
assert(devinfo->gen >= 6);
if (devinfo->gen >= 8) {
brw_inst_set_bits(inst, 127, 96, (uint32_t)value);
} else {
- assert(value <= (1 << 16) - 1);
- assert(value > -(1 << 16));
+ assert(value <= (1 << 15) - 1);
+ assert(value >= -(1 << 15));
brw_inst_set_bits(inst, 111, 96, (uint16_t)value);
}
}
static inline int32_t
-brw_inst_jip(const struct brw_device_info *devinfo, const brw_inst *inst)
+brw_inst_jip(const struct gen_device_info *devinfo, const brw_inst *inst)
{
assert(devinfo->gen >= 6);
/** Like FC, but using int16_t to handle negative jump targets. */
#define FJ(name, high, low, assertions) \
static inline void \
-brw_inst_set_##name(const struct brw_device_info *devinfo, brw_inst *inst, int16_t v) \
+brw_inst_set_##name(const struct gen_device_info *devinfo, brw_inst *inst, int16_t v) \
{ \
assert(assertions); \
(void) devinfo; \
brw_inst_set_bits(inst, high, low, (uint16_t) v); \
} \
static inline int16_t \
-brw_inst_##name(const struct brw_device_info *devinfo, const brw_inst *inst) \
+brw_inst_##name(const struct gen_device_info *devinfo, const brw_inst *inst) \
{ \
assert(assertions); \
(void) devinfo; \
/* 4-6: */ -1, -1, -1, -1, -1, -1, -1, -1,
/* 7: */ MD(16), MD(16),
/* 8: */ MD(17), MD(17))
+FC(urb_channel_mask_present, MD(15), MD(15), devinfo->gen >= 8)
FC(urb_complete, MD(15), MD(15), devinfo->gen < 8)
FC(urb_used, MD(14), MD(14), devinfo->gen < 7)
FC(urb_allocate, MD(13), MD(13), devinfo->gen < 7)
* @{
*/
static inline int
-brw_inst_imm_d(const struct brw_device_info *devinfo, const brw_inst *insn)
+brw_inst_imm_d(const struct gen_device_info *devinfo, const brw_inst *insn)
{
(void) devinfo;
return brw_inst_bits(insn, 127, 96);
}
static inline unsigned
-brw_inst_imm_ud(const struct brw_device_info *devinfo, const brw_inst *insn)
+brw_inst_imm_ud(const struct gen_device_info *devinfo, const brw_inst *insn)
{
(void) devinfo;
return brw_inst_bits(insn, 127, 96);
}
static inline float
-brw_inst_imm_f(const struct brw_device_info *devinfo, const brw_inst *insn)
+brw_inst_imm_f(const struct gen_device_info *devinfo, const brw_inst *insn)
{
- fi_type ft;
+ union {
+ float f;
+ uint32_t u;
+ } ft;
(void) devinfo;
ft.u = brw_inst_bits(insn, 127, 96);
return ft.f;
}
+static inline double
+brw_inst_imm_df(const struct gen_device_info *devinfo, const brw_inst *insn)
+{
+ union {
+ double d;
+ uint64_t u;
+ } dt;
+ (void) devinfo;
+ dt.u = brw_inst_bits(insn, 127, 64);
+ return dt.d;
+}
+
static inline void
-brw_inst_set_imm_d(const struct brw_device_info *devinfo,
+brw_inst_set_imm_d(const struct gen_device_info *devinfo,
brw_inst *insn, int value)
{
(void) devinfo;
}
static inline void
-brw_inst_set_imm_ud(const struct brw_device_info *devinfo,
+brw_inst_set_imm_ud(const struct gen_device_info *devinfo,
brw_inst *insn, unsigned value)
{
(void) devinfo;
}
static inline void
-brw_inst_set_imm_f(const struct brw_device_info *devinfo,
+brw_inst_set_imm_f(const struct gen_device_info *devinfo,
brw_inst *insn, float value)
{
- fi_type ft;
+ union {
+ float f;
+ uint32_t u;
+ } ft;
(void) devinfo;
ft.f = value;
brw_inst_set_bits(insn, 127, 96, ft.u);
}
+static inline void
+brw_inst_set_imm_df(const struct gen_device_info *devinfo,
+ brw_inst *insn, double value)
+{
+ union {
+ double d;
+ uint64_t u;
+ } dt;
+ (void) devinfo;
+ dt.d = value;
+ brw_inst_set_bits(insn, 127, 64, dt.u);
+}
+
+static inline void
+brw_inst_set_imm_uq(const struct gen_device_info *devinfo,
+ brw_inst *insn, uint64_t value)
+{
+ (void) devinfo;
+ brw_inst_set_bits(insn, 127, 64, value);
+}
+
/** @} */
/* The AddrImm fields are split into two discontiguous sections on Gen8+ */
#define BRW_IA1_ADDR_IMM(reg, g4_high, g4_low, g8_nine, g8_high, g8_low) \
static inline void \
-brw_inst_set_##reg##_ia1_addr_imm(const struct brw_device_info *devinfo, \
+brw_inst_set_##reg##_ia1_addr_imm(const struct gen_device_info *devinfo, \
brw_inst *inst, \
unsigned value) \
{ \
} \
} \
static inline unsigned \
-brw_inst_##reg##_ia1_addr_imm(const struct brw_device_info *devinfo, \
+brw_inst_##reg##_ia1_addr_imm(const struct gen_device_info *devinfo, \
const brw_inst *inst) \
{ \
if (devinfo->gen >= 8) { \
#define BRW_IA16_ADDR_IMM(reg, g4_high, g4_low, g8_nine, g8_high, g8_low) \
static inline void \
-brw_inst_set_##reg##_ia16_addr_imm(const struct brw_device_info *devinfo, \
+brw_inst_set_##reg##_ia16_addr_imm(const struct gen_device_info *devinfo, \
brw_inst *inst, unsigned value) \
{ \
assert((value & ~0x3ff) == 0); \
} \
} \
static inline unsigned \
-brw_inst_##reg##_ia16_addr_imm(const struct brw_device_info *devinfo, \
+brw_inst_##reg##_ia16_addr_imm(const struct gen_device_info *devinfo, \
const brw_inst *inst) \
{ \
if (devinfo->gen >= 8) { \
high %= 64;
low %= 64;
- const uint64_t mask = (((1ull << (high - low + 1)) - 1) << low);
+ const uint64_t mask = (~0ull >> (64 - (high - low + 1)));
- return (inst->data[word] & mask) >> low;
+ return (inst->data[word] >> low) & mask;
}
/**
high %= 64;
low %= 64;
- const uint64_t mask = (((1ull << (high - low + 1)) - 1) << low);
+ const uint64_t mask = (~0ull >> (64 - (high - low + 1))) << low;
/* Make sure the supplied value actually fits in the given bitfield. */
assert((value & (mask >> low)) == value);
- inst->data[word] = (inst->data[word] & ~mask) | ((value << low) & mask);
+ inst->data[word] = (inst->data[word] & ~mask) | (value << low);
}
#undef BRW_IA16_ADDR_IMM
* Bits indices range from 0..63.
*/
static inline unsigned
-brw_compact_inst_bits(brw_compact_inst *inst, unsigned high, unsigned low)
+brw_compact_inst_bits(const brw_compact_inst *inst, unsigned high, unsigned low)
{
- const uint64_t mask = (((1ull << (high - low + 1)) - 1) << low);
+ const uint64_t mask = (1ull << (high - low + 1)) - 1;
- return (inst->data & mask) >> low;
+ return (inst->data >> low) & mask;
}
/**
brw_compact_inst_set_bits(brw_compact_inst *inst, unsigned high, unsigned low,
uint64_t value)
{
- const uint64_t mask = (((1ull << (high - low + 1)) - 1) << low);
+ const uint64_t mask = ((1ull << (high - low + 1)) - 1) << low;
/* Make sure the supplied value actually fits in the given bitfield. */
assert((value & (mask >> low)) == value);
- inst->data = (inst->data & ~mask) | ((value << low) & mask);
+ inst->data = (inst->data & ~mask) | (value << low);
}
-#define F(name, high, low) \
-static inline void \
-brw_compact_inst_set_##name(brw_compact_inst *inst, unsigned v) \
-{ \
- brw_compact_inst_set_bits(inst, high, low, v); \
-} \
- \
-static inline unsigned \
-brw_compact_inst_##name(brw_compact_inst *inst) \
-{ \
- return brw_compact_inst_bits(inst, high, low); \
+#define FC(name, high, low, assertions) \
+static inline void \
+brw_compact_inst_set_##name(const struct gen_device_info *devinfo, \
+ brw_compact_inst *inst, unsigned v) \
+{ \
+ assert(assertions); \
+ (void) devinfo; \
+ brw_compact_inst_set_bits(inst, high, low, v); \
+} \
+static inline unsigned \
+brw_compact_inst_##name(const struct gen_device_info *devinfo, \
+ const brw_compact_inst *inst) \
+{ \
+ assert(assertions); \
+ (void) devinfo; \
+ return brw_compact_inst_bits(inst, high, low); \
}
-F(src1_reg_nr, 63, 56)
-F(src0_reg_nr, 55, 48)
-F(dst_reg_nr, 47, 40)
-F(src1_index, 39, 35)
-F(src0_index, 34, 30)
-F(cmpt_control, 29, 29) /* Same location as brw_inst */
-F(flag_subreg_nr, 28, 28) /* <= Gen6 only */
-F(cond_modifier, 27, 24) /* Same location as brw_inst */
-F(acc_wr_control, 23, 23)
-F(subreg_index, 22, 18)
-F(datatype_index, 17, 13)
-F(control_index, 12, 8)
-F(debug_control, 7, 7)
-F(opcode, 6, 0) /* Same location as brw_inst */
+/* A simple macro for fields which stay in the same place on all generations. */
+#define F(name, high, low) FC(name, high, low, true)
+
+F(src1_reg_nr, 63, 56)
+F(src0_reg_nr, 55, 48)
+F(dst_reg_nr, 47, 40)
+F(src1_index, 39, 35)
+F(src0_index, 34, 30)
+F(cmpt_control, 29, 29) /* Same location as brw_inst */
+FC(flag_subreg_nr, 28, 28, devinfo->gen <= 6)
+F(cond_modifier, 27, 24) /* Same location as brw_inst */
+FC(acc_wr_control, 23, 23, devinfo->gen >= 6)
+FC(mask_control_ex, 23, 23, devinfo->is_g4x || devinfo->gen == 5)
+F(subreg_index, 22, 18)
+F(datatype_index, 17, 13)
+F(control_index, 12, 8)
+F(debug_control, 7, 7)
+F(opcode, 6, 0) /* Same location as brw_inst */
/**
* (Gen8+) Compacted three-source instructions:
* @{
*/
-F(3src_src2_reg_nr, 63, 57)
-F(3src_src1_reg_nr, 56, 50)
-F(3src_src0_reg_nr, 49, 43)
-F(3src_src2_subreg_nr, 42, 40)
-F(3src_src1_subreg_nr, 39, 37)
-F(3src_src0_subreg_nr, 36, 34)
-F(3src_src2_rep_ctrl, 33, 33)
-F(3src_src1_rep_ctrl, 32, 32)
-F(3src_saturate, 31, 31)
-F(3src_debug_control, 30, 30)
-F(3src_cmpt_control, 29, 29)
-F(3src_src0_rep_ctrl, 28, 28)
+FC(3src_src2_reg_nr, 63, 57, devinfo->gen >= 8)
+FC(3src_src1_reg_nr, 56, 50, devinfo->gen >= 8)
+FC(3src_src0_reg_nr, 49, 43, devinfo->gen >= 8)
+FC(3src_src2_subreg_nr, 42, 40, devinfo->gen >= 8)
+FC(3src_src1_subreg_nr, 39, 37, devinfo->gen >= 8)
+FC(3src_src0_subreg_nr, 36, 34, devinfo->gen >= 8)
+FC(3src_src2_rep_ctrl, 33, 33, devinfo->gen >= 8)
+FC(3src_src1_rep_ctrl, 32, 32, devinfo->gen >= 8)
+FC(3src_saturate, 31, 31, devinfo->gen >= 8)
+FC(3src_debug_control, 30, 30, devinfo->gen >= 8)
+FC(3src_cmpt_control, 29, 29, devinfo->gen >= 8)
+FC(3src_src0_rep_ctrl, 28, 28, devinfo->gen >= 8)
/* Reserved */
-F(3src_dst_reg_nr, 18, 12)
-F(3src_source_index, 11, 10)
-F(3src_control_index, 9, 8)
+FC(3src_dst_reg_nr, 18, 12, devinfo->gen >= 8)
+FC(3src_source_index, 11, 10, devinfo->gen >= 8)
+FC(3src_control_index, 9, 8, devinfo->gen >= 8)
/* Bit 7 is Reserved (for future Opcode expansion) */
-F(3src_opcode, 6, 0)
+FC(3src_opcode, 6, 0, devinfo->gen >= 8)
/** @} */
#undef F