void init();
fs_reg();
- explicit fs_reg(float f);
- explicit fs_reg(int32_t i);
- explicit fs_reg(uint32_t u);
- explicit fs_reg(uint8_t vf[4]);
- explicit fs_reg(uint8_t vf0, uint8_t vf1, uint8_t vf2, uint8_t vf3);
- fs_reg(struct brw_reg fixed_hw_reg);
- fs_reg(enum register_file file, int reg);
- fs_reg(enum register_file file, int reg, enum brw_reg_type type);
- fs_reg(enum register_file file, int reg, enum brw_reg_type type, uint8_t width);
+ fs_reg(struct ::brw_reg reg);
+ fs_reg(enum brw_reg_file file, int nr);
+ fs_reg(enum brw_reg_file file, int nr, enum brw_reg_type type);
bool equals(const fs_reg &r) const;
bool is_contiguous() const;
+ /**
+ * Return the size in bytes of a single logical component of the
+ * register assuming the given execution width.
+ */
+ unsigned component_size(unsigned width) const;
+
/** Smear a channel of the reg to all channels. */
fs_reg &set_smear(unsigned subreg);
fs_reg *reladdr;
- /**
- * The register width. This indicates how many hardware values are
- * represented by each virtual value. Valid values are 1, 8, or 16.
- * For immediate values, this is 1. Most of the rest of the time, it
- * will be equal to the dispatch width.
- */
- uint8_t width;
-
- /**
- * Returns the effective register width when used as a source in the
- * given instruction. Registers such as uniforms and immediates
- * effectively take on the width of the instruction in which they are
- * used.
- */
- uint8_t effective_width;
-
/** Register region horizontal stride */
uint8_t stride;
};
static inline fs_reg
negate(fs_reg reg)
{
- assert(reg.file != HW_REG && reg.file != IMM);
+ assert(reg.file != IMM);
reg.negate = !reg.negate;
return reg;
}
static inline fs_reg
retype(fs_reg reg, enum brw_reg_type type)
{
- reg.fixed_hw_reg.type = reg.type = type;
+ reg.type = type;
return reg;
}
switch (reg.file) {
case BAD_FILE:
break;
- case GRF:
+ case VGRF:
case ATTR:
reg.reg_offset += delta / 32;
break;
case MRF:
- reg.reg += delta / 32;
+ reg.nr += delta / 32;
break;
- default:
+ case ARF:
+ case FIXED_GRF:
+ case IMM:
+ case UNIFORM:
assert(delta == 0);
}
reg.subreg_offset += delta % 32;
* horizontal offset should be a harmless no-op.
*/
break;
- case GRF:
+ case VGRF:
case MRF:
case ATTR:
return byte_offset(reg, delta * reg.stride * type_sz(reg.type));
- default:
- assert(delta == 0);
- }
- return reg;
-}
-
-static inline fs_reg
-offset(fs_reg reg, unsigned delta)
-{
- assert(reg.stride > 0);
- switch (reg.file) {
- case BAD_FILE:
- break;
- case GRF:
- case MRF:
- case ATTR:
- return byte_offset(reg, delta * reg.width * reg.stride * type_sz(reg.type));
- case UNIFORM:
- reg.reg_offset += delta;
- break;
- default:
+ case ARF:
+ case FIXED_GRF:
assert(delta == 0);
}
return reg;
component(fs_reg reg, unsigned idx)
{
assert(reg.subreg_offset == 0);
- assert(idx < reg.width);
reg.subreg_offset = idx * type_sz(reg.type);
- reg.width = 1;
+ reg.stride = 0;
return reg;
}
+static inline bool
+is_uniform(const fs_reg ®)
+{
+ return (reg.stride == 0 || reg.is_null()) &&
+ (!reg.reladdr || is_uniform(*reg.reladdr));
+}
+
/**
* Get either of the 8-component halves of a 16-component register.
*
{
assert(idx < 2);
- if (reg.file == UNIFORM)
+ switch (reg.file) {
+ case BAD_FILE:
+ case UNIFORM:
+ case IMM:
return reg;
- assert(idx == 0 || (reg.file != HW_REG && reg.file != IMM));
- assert(reg.width == 16);
- reg.width = 8;
- return horiz_offset(reg, 8 * idx);
+ case VGRF:
+ case MRF:
+ return horiz_offset(reg, 8 * idx);
+
+ case ARF:
+ case FIXED_GRF:
+ case ATTR:
+ unreachable("Cannot take half of this register type");
+ }
+ return reg;
}
static const fs_reg reg_undef;
fs_inst();
fs_inst(enum opcode opcode, uint8_t exec_size);
- fs_inst(enum opcode opcode, const fs_reg &dst);
+ fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst);
fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst,
const fs_reg &src0);
- fs_inst(enum opcode opcode, const fs_reg &dst, const fs_reg &src0);
fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst,
const fs_reg &src0, const fs_reg &src1);
- fs_inst(enum opcode opcode, const fs_reg &dst, const fs_reg &src0,
- const fs_reg &src1);
fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst,
const fs_reg &src0, const fs_reg &src1, const fs_reg &src2);
- fs_inst(enum opcode opcode, const fs_reg &dst, const fs_reg &src0,
- const fs_reg &src1, const fs_reg &src2);
- fs_inst(enum opcode opcode, const fs_reg &dst, const fs_reg src[],
- unsigned sources);
fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst,
const fs_reg src[], unsigned sources);
fs_inst(const fs_inst &that);
bool overwrites_reg(const fs_reg ®) const;
bool is_send_from_grf() const;
bool is_partial_write() const;
+ bool is_copy_payload(const brw::simple_allocator &grf_alloc) const;
+ unsigned components_read(unsigned i) const;
int regs_read(int arg) const;
bool can_do_source_mods(const struct brw_device_info *devinfo);
+ bool can_change_types() const;
bool has_side_effects() const;
+ bool has_source_and_destination_hazard() const;
bool reads_flag() const;
bool writes_flag() const;
uint8_t exec_size;
bool eot:1;
- bool force_uncompressed:1;
bool force_sechalf:1;
bool pi_noperspective:1; /**< Pixel interpolator noperspective flag */
};
+/**
+ * Set second-half quarter control on \p inst.
+ */
+static inline fs_inst *
+set_sechalf(fs_inst *inst)
+{
+ inst->force_sechalf = true;
+ return inst;
+}
+
+/**
+ * Make the execution of \p inst dependent on the evaluation of a possibly
+ * inverted predicate.
+ */
+static inline fs_inst *
+set_predicate_inv(enum brw_predicate pred, bool inverse,
+ fs_inst *inst)
+{
+ inst->predicate = pred;
+ inst->predicate_inverse = inverse;
+ return inst;
+}
+
+/**
+ * Make the execution of \p inst dependent on the evaluation of a predicate.
+ */
+static inline fs_inst *
+set_predicate(enum brw_predicate pred, fs_inst *inst)
+{
+ return set_predicate_inv(pred, false, inst);
+}
+
+/**
+ * Write the result of evaluating the condition given by \p mod to a flag
+ * register.
+ */
+static inline fs_inst *
+set_condmod(enum brw_conditional_mod mod, fs_inst *inst)
+{
+ inst->conditional_mod = mod;
+ return inst;
+}
+
+/**
+ * Clamp the result of \p inst to the saturation range of its destination
+ * datatype.
+ */
+static inline fs_inst *
+set_saturate(bool saturate, fs_inst *inst)
+{
+ inst->saturate = saturate;
+ return inst;
+}
+
#endif