#define iassert(cond) do { \
if (!(cond)) { \
- assert(cond); \
+ debug_assert(cond); \
return -1; \
} } while (0)
+#define iassert_type(reg, full) do { \
+ if ((full)) { \
+ iassert(!((reg)->flags & IR3_REG_HALF)); \
+ } else { \
+ iassert((reg)->flags & IR3_REG_HALF); \
+ } } while (0);
+
static uint32_t reg(struct ir3_register *reg, struct ir3_info *info,
uint32_t repeat, uint32_t valid_flags)
{
return 0;
}
-static uint32_t type_flags(type_t type)
-{
- return (type_size(type) == 32) ? 0 : IR3_REG_HALF;
-}
-
static int emit_cat1(struct ir3_instruction *instr, void *ptr,
struct ir3_info *info)
{
instr_cat1_t *cat1 = ptr;
iassert(instr->regs_count == 2);
- iassert(!((dst->flags ^ type_flags(instr->cat1.dst_type)) & IR3_REG_HALF));
- iassert((src->flags & IR3_REG_IMMED) ||
- !((src->flags ^ type_flags(instr->cat1.src_type)) & IR3_REG_HALF));
+ iassert_type(dst, type_size(instr->cat1.dst_type) == 32);
+ if (!(src->flags & IR3_REG_IMMED))
+ iassert_type(src, type_size(instr->cat1.src_type) == 32);
if (src->flags & IR3_REG_IMMED) {
cat1->iim_val = src->iim_val;
struct ir3_register *src3 = instr->regs[3];
instr_cat5_t *cat5 = ptr;
- iassert(!((dst->flags ^ type_flags(instr->cat5.type)) & IR3_REG_HALF));
+ iassert_type(dst, type_size(instr->cat5.type) == 32)
assume(src1 || !src2);
assume(src2 || !src3);
{
struct ir3_register *dst, *src1, *src2;
instr_cat6_t *cat6 = ptr;
+ bool type_full = type_size(instr->cat6.type) == 32;
cat6->type = instr->cat6.type;
cat6->opc = instr->opc;
cat6->g = !!(instr->flags & IR3_INSTR_G);
cat6->opc_cat = 6;
+ switch (instr->opc) {
+ case OPC_RESINFO:
+ case OPC_RESFMT:
+ iassert_type(instr->regs[0], type_full); /* dst */
+ iassert_type(instr->regs[1], type_full); /* src1 */
+ break;
+ case OPC_L2G:
+ case OPC_G2L:
+ iassert_type(instr->regs[0], true); /* dst */
+ iassert_type(instr->regs[1], true); /* src1 */
+ break;
+ case OPC_STG:
+ case OPC_STL:
+ case OPC_STP:
+ case OPC_STI:
+ case OPC_STLW:
+ case OPC_STIB:
+ /* no dst, so regs[0] is dummy */
+ iassert_type(instr->regs[1], true); /* dst */
+ iassert_type(instr->regs[2], type_full); /* src1 */
+ iassert_type(instr->regs[3], true); /* src2 */
+ break;
+ default:
+ iassert_type(instr->regs[0], type_full); /* dst */
+ iassert_type(instr->regs[1], true); /* src1 */
+ if (instr->regs_count > 2)
+ iassert_type(instr->regs[2], true); /* src1 */
+ break;
+ }
+
/* the "dst" for a store instruction is (from the perspective
* of data flow in the shader, ie. register use/def, etc) in
* fact a register that is read by the instruction, rather
cat6->src_off = false;
- cat6b->src1 = reg(src1, info, instr->repeat, IR3_REG_IMMED);
+ cat6b->src1 = reg(src1, info, instr->repeat, IR3_REG_IMMED | IR3_REG_HALF);
cat6b->src1_im = !!(src1->flags & IR3_REG_IMMED);
if (src2) {
cat6b->src2 = reg(src2, info, instr->repeat, IR3_REG_IMMED);
/* ************************************************************************* */
/* instruction helpers */
+/* creates SSA src of correct type (ie. half vs full precision) */
+static inline struct ir3_register * __ssa_src(struct ir3_instruction *instr,
+ struct ir3_instruction *src, unsigned flags)
+{
+ struct ir3_register *reg;
+ if (src->regs[0]->flags & IR3_REG_HALF)
+ flags |= IR3_REG_HALF;
+ reg = ir3_reg_create(instr, 0, IR3_REG_SSA | flags);
+ reg->instr = src;
+ return reg;
+}
+
static inline struct ir3_instruction *
ir3_MOV(struct ir3_block *block, struct ir3_instruction *src, type_t type)
{
struct ir3_instruction *instr = ir3_instr_create(block, OPC_MOV);
ir3_reg_create(instr, 0, 0); /* dst */
if (src->regs[0]->flags & IR3_REG_ARRAY) {
- struct ir3_register *src_reg =
- ir3_reg_create(instr, 0, IR3_REG_ARRAY);
+ struct ir3_register *src_reg = __ssa_src(instr, src, IR3_REG_ARRAY);
src_reg->array = src->regs[0]->array;
- src_reg->instr = src;
} else {
- ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = src;
+ __ssa_src(instr, src, 0);
}
debug_assert(!(src->regs[0]->flags & IR3_REG_RELATIV));
instr->cat1.src_type = type;
{
struct ir3_instruction *instr = ir3_instr_create(block, OPC_MOV);
ir3_reg_create(instr, 0, 0); /* dst */
- ir3_reg_create(instr, 0, IR3_REG_SSA)->instr = src;
+ __ssa_src(instr, src, 0);
instr->cat1.src_type = src_type;
instr->cat1.dst_type = dst_type;
debug_assert(!(src->regs[0]->flags & IR3_REG_ARRAY));
struct ir3_instruction *instr = \
ir3_instr_create(block, OPC_##name); \
ir3_reg_create(instr, 0, 0); /* dst */ \
- ir3_reg_create(instr, 0, IR3_REG_SSA | aflags)->instr = a; \
+ __ssa_src(instr, a, aflags); \
return instr; \
}
struct ir3_instruction *instr = \
ir3_instr_create(block, OPC_##name); \
ir3_reg_create(instr, 0, 0); /* dst */ \
- ir3_reg_create(instr, 0, IR3_REG_SSA | aflags)->instr = a; \
- ir3_reg_create(instr, 0, IR3_REG_SSA | bflags)->instr = b; \
+ __ssa_src(instr, a, aflags); \
+ __ssa_src(instr, b, bflags); \
return instr; \
}
struct ir3_instruction *instr = \
ir3_instr_create(block, OPC_##name); \
ir3_reg_create(instr, 0, 0); /* dst */ \
- ir3_reg_create(instr, 0, IR3_REG_SSA | aflags)->instr = a; \
- ir3_reg_create(instr, 0, IR3_REG_SSA | bflags)->instr = b; \
- ir3_reg_create(instr, 0, IR3_REG_SSA | cflags)->instr = c; \
+ __ssa_src(instr, a, aflags); \
+ __ssa_src(instr, b, bflags); \
+ __ssa_src(instr, c, cflags); \
return instr; \
}
struct ir3_instruction *instr = \
ir3_instr_create2(block, OPC_##name, 5); \
ir3_reg_create(instr, 0, 0); /* dst */ \
- ir3_reg_create(instr, 0, IR3_REG_SSA | aflags)->instr = a; \
- ir3_reg_create(instr, 0, IR3_REG_SSA | bflags)->instr = b; \
- ir3_reg_create(instr, 0, IR3_REG_SSA | cflags)->instr = c; \
- ir3_reg_create(instr, 0, IR3_REG_SSA | dflags)->instr = d; \
+ __ssa_src(instr, a, aflags); \
+ __ssa_src(instr, b, bflags); \
+ __ssa_src(instr, c, cflags); \
+ __ssa_src(instr, d, dflags); \
return instr; \
}
struct ir3_instruction *instr = \
ir3_instr_create2(block, OPC_##name, 5); \
ir3_reg_create(instr, 0, 0); /* dst */ \
- ir3_reg_create(instr, 0, IR3_REG_SSA | aflags)->instr = a; \
- ir3_reg_create(instr, 0, IR3_REG_SSA | bflags)->instr = b; \
- ir3_reg_create(instr, 0, IR3_REG_SSA | cflags)->instr = c; \
- ir3_reg_create(instr, 0, IR3_REG_SSA | dflags)->instr = d; \
+ __ssa_src(instr, a, aflags); \
+ __ssa_src(instr, b, bflags); \
+ __ssa_src(instr, c, cflags); \
+ __ssa_src(instr, d, dflags); \
instr->flags |= IR3_INSTR_##f; \
return instr; \
}