type_t type;
int src_offset;
int dst_offset;
- int iim_val;
+ int iim_val; /* for ldgb/stgb, # of components */
} cat6;
/* for meta-instructions, just used to hold extra data
* before instruction scheduling, etc
return num;
}
+/*
+ * Stupid/simple growable array implementation:
+ */
+#define DECLARE_ARRAY(type, name) \
+ unsigned name ## _count, name ## _sz; \
+ type * name;
+
+#define array_insert(ctx, arr, val) do { \
+ if (arr ## _count == arr ## _sz) { \
+ arr ## _sz = MAX2(2 * arr ## _sz, 16); \
+ arr = reralloc_size(ctx, arr, arr ## _sz * sizeof(arr[0])); \
+ } \
+ arr[arr ##_count++] = val; \
+ } while (0)
+
struct ir3 {
struct ir3_compiler *compiler;
* threads in a group are killed before the last bary.f gets
* a chance to signal end of input (ei).
*/
- unsigned baryfs_count, baryfs_sz;
- struct ir3_instruction **baryfs;
+ DECLARE_ARRAY(struct ir3_instruction *, baryfs);
/* Track all indirect instructions (read and write). To avoid
* deadlock scenario where an address register gets scheduled,
* convenient list of instructions that reference some address
* register simplifies this.
*/
- unsigned indirects_count, indirects_sz;
- struct ir3_instruction **indirects;
+ DECLARE_ARRAY(struct ir3_instruction *, indirects);
+
/* and same for instructions that consume predicate register: */
- unsigned predicates_count, predicates_sz;
- struct ir3_instruction **predicates;
+ DECLARE_ARRAY(struct ir3_instruction *, predicates);
/* Track texture sample instructions which need texture state
* patched in (for astc-srgb workaround):
*/
- unsigned astc_srgb_count, astc_srgb_sz;
- struct ir3_instruction **astc_srgb;
+ DECLARE_ARRAY(struct ir3_instruction *, astc_srgb);
/* List of blocks: */
struct list_head block_list;
struct list_head array_list;
};
-typedef struct nir_variable nir_variable;
+typedef struct nir_register nir_register;
struct ir3_array {
struct list_head node;
unsigned length;
unsigned id;
- nir_variable *var;
+ nir_register *r;
/* We track the last write and last access (read or write) to
* setup dependencies on instructions that read or write the
/* Track instructions which do not write a register but other-
* wise must not be discarded (such as kill, stg, etc)
*/
- unsigned keeps_count, keeps_sz;
- struct ir3_instruction **keeps;
+ DECLARE_ARRAY(struct ir3_instruction *, keeps);
/* used for per-pass extra block data. Mainly used right
* now in RA step to track livein/liveout.
*/
switch (instr->opc) {
case OPC_STG:
+ case OPC_STGB:
case OPC_STP:
case OPC_STL:
case OPC_STLW:
{
switch (instr->opc) {
case OPC_LDG:
+ case OPC_LDGB:
case OPC_LDL:
case OPC_LDP:
case OPC_L2G:
}
}
-#define array_insert(ctx, arr, val) do { \
- if (arr ## _count == arr ## _sz) { \
- arr ## _sz = MAX2(2 * arr ## _sz, 16); \
- arr = reralloc_size(ctx, arr, arr ## _sz * sizeof(arr[0])); \
- } \
- arr[arr ##_count++] = val; \
- } while (0)
-
/* iterator for an instructions's sources (reg), also returns src #: */
#define foreach_src_n(__srcreg, __n, __instr) \
if ((__instr)->regs_count) \
bool frag_coord, bool frag_face);
/* legalize: */
-void ir3_legalize(struct ir3 *ir, bool *has_samp, int *max_bary);
+void ir3_legalize(struct ir3 *ir, bool *has_samp, bool *has_ssbo, int *max_bary);
/* ************************************************************************* */
/* instruction helpers */
return instr; \
}
+#define INSTR4(name) \
+static inline struct ir3_instruction * \
+ir3_##name(struct ir3_block *block, \
+ struct ir3_instruction *a, unsigned aflags, \
+ struct ir3_instruction *b, unsigned bflags, \
+ struct ir3_instruction *c, unsigned cflags, \
+ struct ir3_instruction *d, unsigned dflags) \
+{ \
+ 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; \
+ return instr; \
+}
+
/* cat0 instructions: */
INSTR0(BR);
INSTR0(JUMP);
INSTR2(LDLV)
INSTR2(LDG)
INSTR3(STG)
+INSTR3(LDGB);
+INSTR4(STGB);
+INSTR4(ATOMIC_ADD);
+INSTR4(ATOMIC_SUB);
+INSTR4(ATOMIC_XCHG);
+INSTR4(ATOMIC_INC);
+INSTR4(ATOMIC_DEC);
+INSTR4(ATOMIC_CMPXCHG);
+INSTR4(ATOMIC_MIN);
+INSTR4(ATOMIC_MAX);
+INSTR4(ATOMIC_AND);
+INSTR4(ATOMIC_OR);
+INSTR4(ATOMIC_XOR);
/* ************************************************************************* */
/* split this out or find some helper to use.. like main/bitset.h.. */