brw_pop_insn_state(p);
}
-/**
- * Change the register's data type from UD to W, doubling the strides in order
- * to compensate for halving the data type width.
- */
-static struct brw_reg
-ud_reg_to_w(struct brw_reg r)
-{
- assert(r.type == BRW_REGISTER_TYPE_UD);
- r.type = BRW_REGISTER_TYPE_W;
-
- /* The BRW_*_STRIDE enums are defined so that incrementing the field
- * doubles the real stride.
- */
- if (r.hstride != 0)
- ++r.hstride;
- if (r.vstride != 0)
- ++r.vstride;
-
- return r;
-}
-
void
fs_generator::generate_pack_half_2x16_split(fs_inst *inst,
struct brw_reg dst,
* (HorzStride) of 2. The 16-bit result is stored in the lower word of
* each destination channel and the upper word is not modified.
*/
- struct brw_reg dst_w = ud_reg_to_w(dst);
+ struct brw_reg dst_w = spread(retype(dst, BRW_REGISTER_TYPE_W), 2);
- /* Give each 32-bit channel of dst the form below , where "." means
+ /* Give each 32-bit channel of dst the form below, where "." means
* unchanged.
* 0x....hhhh
*/
* the source data type must be Word (W). The destination type must be
* F (Float).
*/
- struct brw_reg src_w = ud_reg_to_w(src);
+ struct brw_reg src_w = spread(retype(src, BRW_REGISTER_TYPE_W), 2);
/* Each channel of src has the form of unpackHalf2x16's input: 0xhhhhllll.
* For the Y case, we wish to access only the upper word; therefore
#include <stdbool.h>
#include "main/imports.h"
#include "main/compiler.h"
+#include "main/macros.h"
#include "program/prog_instruction.h"
#include "brw_defines.h"
return reg;
}
+/**
+ * Multiply the vertical and horizontal stride of a register by the given
+ * factor \a s.
+ */
+static inline struct brw_reg
+spread(struct brw_reg reg, unsigned s)
+{
+ if (s) {
+ assert(is_power_of_two(s));
+
+ if (reg.hstride)
+ reg.hstride += cvt(s) - 1;
+
+ if (reg.vstride)
+ reg.vstride += cvt(s) - 1;
+
+ return reg;
+ } else {
+ return stride(reg, 0, 1, 0);
+ }
+}
static inline struct brw_reg
vec16(struct brw_reg reg)