#include "util/bitscan.h"
#include "util/list.h"
+#include "util/set.h"
#include "util/u_debug.h"
#include "instr-a3xx.h"
int off; /* component/offset */
} fo;
struct {
- struct ir3_block *block;
- } inout;
+ /* for sysvals, identifies the sysval type. Mostly so we can
+ * identify the special cases where a sysval should not be DCE'd
+ * (currently, just pre-fs texture fetch)
+ */
+ gl_system_value sysval;
+ } input;
};
/* transient values used during various algorithms: */
};
/* used for per-pass extra instruction data.
+ *
+ * TODO we should remove the per-pass data like this and 'use_count'
+ * and do something similar to what RA does w/ ir3_ra_instr_data..
+ * ie. use the ir3_count_instructions pass, and then use instr->ip
+ * to index into a table of pass-private data.
*/
void *data;
struct ir3_instruction *condition;
struct ir3_block *successors[2];
- unsigned predecessors_count;
- struct ir3_block **predecessors;
+ struct set *predecessors; /* set of ir3_block */
uint16_t start_ip, end_ip;
return instr->opc == OPC_NOP;
}
+static inline bool is_same_type_reg(struct ir3_register *reg1,
+ struct ir3_register *reg2)
+{
+ unsigned type_reg1 = (reg1->flags & (IR3_REG_HIGH | IR3_REG_HALF));
+ unsigned type_reg2 = (reg2->flags & (IR3_REG_HIGH | IR3_REG_HALF));
+
+ if (type_reg1 ^ type_reg2)
+ return false;
+ else
+ return true;
+}
+
/* Is it a non-transformative (ie. not type changing) mov? This can
* also include absneg.s/absneg.f, which for the most part can be
* treated as a mov (single src argument).
case OPC_ABSNEG_S:
if (instr->flags & IR3_INSTR_SAT)
return false;
+ /* If the type of dest reg and src reg are different,
+ * it shouldn't be considered as same type mov */
+ if (!is_same_type_reg(instr->regs[0], instr->regs[1]))
+ return false;
break;
default:
return false;
}
}
+static inline bool ir3_cat2_float(opc_t opc)
+{
+ switch (opc) {
+ case OPC_ADD_F:
+ case OPC_MIN_F:
+ case OPC_MAX_F:
+ case OPC_MUL_F:
+ case OPC_SIGN_F:
+ case OPC_CMPS_F:
+ case OPC_ABSNEG_F:
+ case OPC_CMPV_F:
+ case OPC_FLOOR_F:
+ case OPC_CEIL_F:
+ case OPC_RNDNE_F:
+ case OPC_RNDAZ_F:
+ case OPC_TRUNC_F:
+ return true;
+
+ default:
+ return false;
+ }
+}
+
+static inline bool ir3_cat3_float(opc_t opc)
+{
+ switch (opc) {
+ case OPC_MAD_F16:
+ case OPC_MAD_F32:
+ case OPC_SEL_F16:
+ case OPC_SEL_F32:
+ return true;
+ default:
+ return false;
+ }
+}
/* map cat2 instruction to valid abs/neg flags: */
static inline unsigned ir3_cat2_absneg(opc_t opc)
void ir3_print_instr(struct ir3_instruction *instr);
/* depth calculation: */
+struct ir3_shader_variant;
int ir3_delayslots(struct ir3_instruction *assigner,
struct ir3_instruction *consumer, unsigned n);
void ir3_insert_by_depth(struct ir3_instruction *instr, struct list_head *list);
-void ir3_depth(struct ir3 *ir);
+void ir3_depth(struct ir3 *ir, struct ir3_shader_variant *so);
/* copy-propagate: */
-struct ir3_shader_variant;
void ir3_cp(struct ir3 *ir, struct ir3_shader_variant *so);
/* group neighbors and insert mov's to resolve conflicts: */
/* register assignment: */
struct ir3_ra_reg_set * ir3_ra_alloc_reg_set(struct ir3_compiler *compiler);
-int ir3_ra(struct ir3 *ir3, gl_shader_stage type,
- bool frag_coord, bool frag_face);
+int ir3_ra(struct ir3_shader_variant *v, struct ir3_instruction **precolor, unsigned nprecolor);
/* legalize: */
void ir3_legalize(struct ir3 *ir, bool *has_ssbo, bool *need_pixlod, int *max_bary);
}
static inline struct ir3_instruction *
-create_uniform(struct ir3_block *block, unsigned n)
+create_uniform_typed(struct ir3_block *block, unsigned n, type_t type)
{
struct ir3_instruction *mov;
+ unsigned flags = (type_size(type) < 32) ? IR3_REG_HALF : 0;
mov = ir3_instr_create(block, OPC_MOV);
- /* TODO get types right? */
- mov->cat1.src_type = TYPE_F32;
- mov->cat1.dst_type = TYPE_F32;
- ir3_reg_create(mov, 0, 0);
- ir3_reg_create(mov, n, IR3_REG_CONST);
+ mov->cat1.src_type = type;
+ mov->cat1.dst_type = type;
+ ir3_reg_create(mov, 0, flags);
+ ir3_reg_create(mov, n, IR3_REG_CONST | flags);
return mov;
}
+static inline struct ir3_instruction *
+create_uniform(struct ir3_block *block, unsigned n)
+{
+ return create_uniform_typed(block, n, TYPE_F32);
+}
+
static inline struct ir3_instruction *
create_uniform_indirect(struct ir3_block *block, int n,
struct ir3_instruction *address)
INSTR0(JUMP)
INSTR1(KILL)
INSTR0(END)
+INSTR0(CHSH)
+INSTR0(CHMASK)
/* cat2 instructions, most 2 src but some 1 src: */
INSTR2(ADD_F)
/* cat6 instructions: */
INSTR2(LDLV)
-INSTR2(LDG)
-INSTR2(LDL)
+INSTR3(LDG)
+INSTR3(LDL)
+INSTR3(LDLW)
INSTR3(STG)
INSTR3(STL)
+INSTR3(STLW)
INSTR1(RESINFO)
INSTR1(RESFMT)
INSTR2(ATOMIC_ADD)