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 reg);
- fs_reg(enum register_file file, int nr);
- fs_reg(enum register_file file, int nr, enum brw_reg_type type);
+ 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;
*/
int subreg_offset;
- fs_reg *reladdr;
-
/** Register region horizontal stride */
uint8_t stride;
};
static inline fs_reg
byte_offset(fs_reg reg, unsigned delta)
{
+ reg.subreg_offset += delta;
+
switch (reg.file) {
case BAD_FILE:
break;
case VGRF:
case ATTR:
- reg.reg_offset += delta / 32;
+ reg.reg_offset += reg.subreg_offset / 32;
break;
case MRF:
reg.nr += delta / 32;
break;
+ case UNIFORM:
+ reg.reg_offset += reg.subreg_offset / 4;
+ reg.subreg_offset %= 4;
+ return reg;
case ARF:
case FIXED_GRF:
case IMM:
- case UNIFORM:
+ default:
assert(delta == 0);
}
- reg.subreg_offset += delta % 32;
+ reg.subreg_offset %= 32;
return reg;
}
return reg;
}
+/**
+ * Get the scalar channel of \p reg given by \p idx and replicate it to all
+ * channels of the result.
+ */
static inline fs_reg
component(fs_reg reg, unsigned idx)
{
- assert(reg.subreg_offset == 0);
- reg.subreg_offset = idx * type_sz(reg.type);
+ reg = horiz_offset(reg, idx);
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));
+ return (reg.stride == 0 || reg.is_null());
}
/**
return reg;
}
+/**
+ * Reinterpret each channel of register \p reg as a vector of values of the
+ * given smaller type and take the i-th subcomponent from each.
+ */
+static inline fs_reg
+subscript(fs_reg reg, brw_reg_type type, unsigned i)
+{
+ assert((i + 1) * type_sz(type) <= type_sz(reg.type));
+
+ if (reg.file == ARF || reg.file == FIXED_GRF) {
+ /* The stride is encoded inconsistently for fixed GRF and ARF registers
+ * as the log2 of the actual vertical and horizontal strides.
+ */
+ const int delta = _mesa_logbase2(type_sz(reg.type)) -
+ _mesa_logbase2(type_sz(type));
+ reg.hstride += (reg.hstride ? delta : 0);
+ reg.vstride += (reg.vstride ? delta : 0);
+
+ } else if (reg.file == IMM) {
+ assert(reg.type == type);
+
+ } else {
+ reg.stride *= type_sz(reg.type) / type_sz(type);
+ }
+
+ return byte_offset(retype(reg, type), i * type_sz(type));
+}
+
static const fs_reg reg_undef;
class fs_inst : public backend_instruction {
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;