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);
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;
};
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:
- assert(delta == 0);
- }
- return reg;
-}
-
static inline fs_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 GRF:
+ case MRF:
+ return horiz_offset(reg, 8 * idx);
+
+ case ATTR:
+ case HW_REG:
+ default:
+ unreachable("Cannot take half of this register type");
+ }
+ return reg;
}
static const fs_reg reg_undef;
fs_inst &operator=(const fs_inst &);
void init(enum opcode opcode, uint8_t exec_width, const fs_reg &dst,
- fs_reg *src, int sources);
+ const fs_reg *src, unsigned sources);
public:
DECLARE_RALLOC_CXX_OPERATORS(fs_inst)
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, fs_reg src[], int sources);
fs_inst(enum opcode opcode, uint8_t exec_size, const fs_reg &dst,
- fs_reg src[], int sources);
+ const fs_reg src[], unsigned sources);
fs_inst(const fs_inst &that);
+ ~fs_inst();
void resize_sources(uint8_t num_sources);
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(struct brw_context *brw);
+ bool can_do_source_mods(const struct brw_device_info *devinfo);
+ bool has_side_effects() const;
bool reads_flag() const;
bool writes_flag() const;
*/
uint8_t exec_size;
- /* Chooses which flag subregister (f0.0 or f0.1) is used for conditional
- * mod and predication.
- */
- uint8_t flag_subreg;
-
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