diff --git a/src/imagination/rogue/passes/rogue_schedule_instr_groups.c b/src/imagination/rogue/passes/rogue_schedule_instr_groups.c index bbf3c74afd2..0ed103671a0 100644 --- a/src/imagination/rogue/passes/rogue_schedule_instr_groups.c +++ b/src/imagination/rogue/passes/rogue_schedule_instr_groups.c @@ -537,6 +537,21 @@ static void rogue_calc_alu_instrs_size(rogue_instr_group *group, } break; + case ROGUE_ALU_OP_TST: + group->size.instrs[phase] = 1; + + if (rogue_alu_op_mod_is_set(alu, OM(L)) || + rogue_alu_op_mod_is_set(alu, OM(LE)) || + !rogue_alu_op_mod_is_set(alu, OM(F32)) || + rogue_alu_src_mod_is_set(alu, 0, SM(E1)) || + rogue_alu_src_mod_is_set(alu, 0, SM(E2)) || + rogue_alu_src_mod_is_set(alu, 0, SM(E3)) || + !rogue_phase_occupied(ROGUE_INSTR_PHASE_2_PCK, + group->header.phases)) { + group->size.instrs[phase] = 2; + } + break; + case ROGUE_ALU_OP_PCK_U8888: group->size.instrs[phase] = 2; break; diff --git a/src/imagination/rogue/rogue.h b/src/imagination/rogue/rogue.h index 4acb2ae3033..5b5ce650876 100644 --- a/src/imagination/rogue/rogue.h +++ b/src/imagination/rogue/rogue.h @@ -398,6 +398,8 @@ enum rogue_exec_cond { ROGUE_EXEC_COND_COUNT, }; +extern const char *rogue_exec_cond_str[ROGUE_EXEC_COND_COUNT]; + /** Rogue instruction type. */ enum rogue_instr_type { ROGUE_INSTR_TYPE_INVALID = 0, @@ -436,6 +438,7 @@ typedef struct rogue_instr_group rogue_instr_group; typedef struct rogue_instr { enum rogue_instr_type type; /** Instruction type. */ + enum rogue_exec_cond exec_cond; unsigned repeat; bool end; @@ -479,6 +482,12 @@ typedef struct rogue_instr { rogue_foreach_block_safe_rev (_block, (shader)) \ rogue_foreach_instr_in_block_safe_rev ((instr), _block) +static inline void rogue_set_instr_exec_cond(rogue_instr *instr, + enum rogue_exec_cond exec_cond) +{ + instr->exec_cond = exec_cond; +} + static inline void rogue_set_instr_repeat(rogue_instr *instr, unsigned repeat) { instr->repeat = repeat; @@ -552,6 +561,9 @@ enum rogue_io { ROGUE_IO_FT4, ROGUE_IO_FT5, + /* Test output feedthrough. */ + ROGUE_IO_FTT, + /* Predicate register. */ ROGUE_IO_P0, @@ -1045,6 +1057,25 @@ enum rogue_alu_op_mod { ROGUE_ALU_OP_MOD_SCALE, /* Scale to [0, 1]. */ ROGUE_ALU_OP_MOD_ROUNDZERO, /* Round to zero. */ + ROGUE_ALU_OP_MOD_Z, /** Test == 0. */ + ROGUE_ALU_OP_MOD_GZ, /** Test > 0. */ + ROGUE_ALU_OP_MOD_GEZ, /** Test >= 0. */ + ROGUE_ALU_OP_MOD_C, /** Test integer carry-out. */ + ROGUE_ALU_OP_MOD_E, /** Test a == b. */ + ROGUE_ALU_OP_MOD_G, /** Test a > b. */ + ROGUE_ALU_OP_MOD_GE, /** Test a >= b. */ + ROGUE_ALU_OP_MOD_NE, /** Test a != b. */ + ROGUE_ALU_OP_MOD_L, /** Test a < b. */ + ROGUE_ALU_OP_MOD_LE, /** Test a <= b. */ + + ROGUE_ALU_OP_MOD_F32, + ROGUE_ALU_OP_MOD_U16, + ROGUE_ALU_OP_MOD_S16, + ROGUE_ALU_OP_MOD_U8, + ROGUE_ALU_OP_MOD_S8, + ROGUE_ALU_OP_MOD_U32, + ROGUE_ALU_OP_MOD_S32, + ROGUE_ALU_OP_MOD_COUNT, }; @@ -1085,6 +1116,11 @@ enum rogue_alu_src_mod { ROGUE_ALU_SRC_MOD_ABS, ROGUE_ALU_SRC_MOD_NEG, + ROGUE_ALU_SRC_MOD_E0, + ROGUE_ALU_SRC_MOD_E1, + ROGUE_ALU_SRC_MOD_E2, + ROGUE_ALU_SRC_MOD_E3, + ROGUE_ALU_SRC_MOD_COUNT, }; @@ -1210,55 +1246,12 @@ typedef struct rogue_alu_op_info { extern const rogue_alu_op_info rogue_alu_op_infos[ROGUE_ALU_OP_COUNT]; -enum rogue_comp_test { - ROGUE_COMP_TEST_NONE = 0, - - /* 0-source */ - /* ROGUE_COMP_TEST_IC, */ /* Integer carry-out, for INT64 pipeline only. */ - - /* 1-source */ - /* ROGUE_COMP_TEST_Z, */ - /* ROGUE_COMP_TEST_GZ, */ - /* ROGUE_COMP_TEST_GEZ, */ - - /* 2-source */ - ROGUE_COMP_TEST_EQ, - ROGUE_COMP_TEST_GT, - ROGUE_COMP_TEST_GE, - ROGUE_COMP_TEST_NE, - ROGUE_COMP_TEST_LT, - ROGUE_COMP_TEST_LE, - - ROGUE_COMP_TEST_COUNT, -}; - -extern const char *const rogue_comp_test_str[ROGUE_COMP_TEST_COUNT]; - -enum rogue_comp_type { - ROGUE_COMP_TYPE_NONE = 0, - - ROGUE_COMP_TYPE_F32, - ROGUE_COMP_TYPE_U16, - ROGUE_COMP_TYPE_S16, - ROGUE_COMP_TYPE_U8, - ROGUE_COMP_TYPE_S8, - ROGUE_COMP_TYPE_U32, - ROGUE_COMP_TYPE_S32, - - ROGUE_COMP_TYPE_COUNT, -}; - -extern const char *const rogue_comp_type_str[ROGUE_COMP_TYPE_COUNT]; - /** Rogue ALU instruction. */ typedef struct rogue_alu_instr { rogue_instr instr; enum rogue_alu_op op; - enum rogue_comp_test comp_test; - enum rogue_comp_type comp_type; - uint64_t mod; rogue_instr_dst dst[ROGUE_ALU_OP_MAX_DSTS]; @@ -1308,23 +1301,6 @@ static inline bool rogue_alu_src_mod_is_set(const rogue_alu_instr *alu, return !!(alu->src[src_index].mod & BITFIELD64_BIT(mod)); } -static inline void rogue_set_alu_comp(rogue_alu_instr *alu, - enum rogue_comp_test test, - enum rogue_comp_type comp_type) -{ - if (alu->op != ROGUE_ALU_OP_TST) - unreachable("Can't set comparisons on non-test instructions."); - - alu->comp_test = test; - alu->comp_type = comp_type; -} - -static inline bool rogue_alu_comp_is_none(const rogue_alu_instr *alu) -{ - return (alu->comp_test == ROGUE_COMP_TEST_NONE) && - (alu->comp_type == ROGUE_COMP_TYPE_NONE); -} - /** * \brief Allocates and initializes a new ALU instruction. * @@ -2634,6 +2610,12 @@ rogue_get_supported_phase(uint64_t supported_phases, uint64_t occupied_phases) return ROGUE_INSTR_PHASE_INVALID; } +static inline bool rogue_phase_occupied(enum rogue_instr_phase phase, + uint64_t occupied_phases) +{ + return !!(BITFIELD_BIT(phase) & occupied_phases); +} + static inline bool rogue_can_replace_reg_use(rogue_reg_use *use, const rogue_reg *new_reg) { diff --git a/src/imagination/rogue/rogue_encode.c b/src/imagination/rogue/rogue_encode.c index 438e14c51f9..c88839304be 100644 --- a/src/imagination/rogue/rogue_encode.c +++ b/src/imagination/rogue/rogue_encode.c @@ -254,6 +254,73 @@ static void rogue_encode_alu_instr(const rogue_alu_instr *alu, } break; + case ROGUE_ALU_OP_TST: { + instr_encoding->alu.op = ALUOP_TST; + instr_encoding->alu.tst.pwen = rogue_ref_is_io_p0(&alu->dst[1].ref); + + rogue_tstop tstop = { 0 }; + if (rogue_alu_op_mod_is_set(alu, OM(Z))) + tstop._ = TSTOP_Z; + else if (rogue_alu_op_mod_is_set(alu, OM(GZ))) + tstop._ = TSTOP_GZ; + else if (rogue_alu_op_mod_is_set(alu, OM(GEZ))) + tstop._ = TSTOP_GEZ; + else if (rogue_alu_op_mod_is_set(alu, OM(C))) + tstop._ = TSTOP_C; + else if (rogue_alu_op_mod_is_set(alu, OM(E))) + tstop._ = TSTOP_E; + else if (rogue_alu_op_mod_is_set(alu, OM(G))) + tstop._ = TSTOP_G; + else if (rogue_alu_op_mod_is_set(alu, OM(GE))) + tstop._ = TSTOP_GE; + else if (rogue_alu_op_mod_is_set(alu, OM(NE))) + tstop._ = TSTOP_NE; + else if (rogue_alu_op_mod_is_set(alu, OM(L))) + tstop._ = TSTOP_L; + else if (rogue_alu_op_mod_is_set(alu, OM(LE))) + tstop._ = TSTOP_LE; + else + unreachable("Invalid comparison test."); + + instr_encoding->alu.tst.tstop_2_0 = tstop._2_0; + + if (instr_size == 2) { + instr_encoding->alu.tst.ext = 1; + instr_encoding->alu.tst.tstop_3 = tstop._3; + + if (rogue_alu_src_mod_is_set(alu, 0, SM(E0))) + instr_encoding->alu.tst.elem = TST_E0; + else if (rogue_alu_src_mod_is_set(alu, 0, SM(E1))) + instr_encoding->alu.tst.elem = TST_E1; + else if (rogue_alu_src_mod_is_set(alu, 0, SM(E2))) + instr_encoding->alu.tst.elem = TST_E2; + else if (rogue_alu_src_mod_is_set(alu, 0, SM(E3))) + instr_encoding->alu.tst.elem = TST_E3; + + instr_encoding->alu.tst.p2end = + !rogue_phase_occupied(ROGUE_INSTR_PHASE_2_PCK, + alu->instr.group->header.phases); + + if (rogue_alu_op_mod_is_set(alu, OM(F32))) + instr_encoding->alu.tst.type = TSTTYPE_F32; + else if (rogue_alu_op_mod_is_set(alu, OM(U16))) + instr_encoding->alu.tst.type = TSTTYPE_U16; + else if (rogue_alu_op_mod_is_set(alu, OM(S16))) + instr_encoding->alu.tst.type = TSTTYPE_S16; + else if (rogue_alu_op_mod_is_set(alu, OM(U8))) + instr_encoding->alu.tst.type = TSTTYPE_U8; + else if (rogue_alu_op_mod_is_set(alu, OM(S8))) + instr_encoding->alu.tst.type = TSTTYPE_S8; + else if (rogue_alu_op_mod_is_set(alu, OM(U32))) + instr_encoding->alu.tst.type = TSTTYPE_U32; + else if (rogue_alu_op_mod_is_set(alu, OM(S32))) + instr_encoding->alu.tst.type = TSTTYPE_S32; + else + unreachable("Invalid comparison type."); + } + break; + } + case ROGUE_ALU_OP_PCK_U8888: instr_encoding->alu.op = ALUOP_SNGL; instr_encoding->alu.sngl.snglop = SNGLOP_PCK; diff --git a/src/imagination/rogue/rogue_info.c b/src/imagination/rogue/rogue_info.c index 8b40b708f98..afe049c7fbb 100644 --- a/src/imagination/rogue/rogue_info.c +++ b/src/imagination/rogue/rogue_info.c @@ -197,24 +197,49 @@ const rogue_reg_src_info rogue_reg_upper_src_infos[ROGUE_REG_SRC_VARIANTS] = { }, }; +#define OM(op_mod) BITFIELD64_BIT(ROGUE_ALU_OP_MOD_##op_mod) const rogue_alu_op_mod_info rogue_alu_op_mod_infos[ROGUE_ALU_OP_MOD_COUNT] = { - [ROGUE_ALU_OP_MOD_LP] = { .str = "lp", }, - [ROGUE_ALU_OP_MOD_SAT] = { .str = "sat", }, - [ROGUE_ALU_OP_MOD_SCALE] = { .str = "scale", }, - [ROGUE_ALU_OP_MOD_ROUNDZERO] = { .str = "roundzero", }, + [ROGUE_ALU_OP_MOD_LP] = { .str = "lp", }, + [ROGUE_ALU_OP_MOD_SAT] = { .str = "sat", }, + [ROGUE_ALU_OP_MOD_SCALE] = { .str = "scale", }, + [ROGUE_ALU_OP_MOD_ROUNDZERO] = { .str = "roundzero", }, + + [ROGUE_ALU_OP_MOD_Z] = { .str = "z", .exclude = OM(GZ) | OM(GEZ) | OM(C) | OM(E) | OM(G) | OM(GE) | OM(NE) | OM(L) | OM(LE) }, + [ROGUE_ALU_OP_MOD_GZ] = { .str = "gz", .exclude = OM(Z) | OM(GEZ) | OM(C) | OM(E) | OM(G) | OM(GE) | OM(NE) | OM(L) | OM(LE) }, + [ROGUE_ALU_OP_MOD_GEZ] = { .str = "gez", .exclude = OM(Z) | OM(GZ) | OM(C) | OM(E) | OM(G) | OM(GE) | OM(NE) | OM(L) | OM(LE) }, + [ROGUE_ALU_OP_MOD_C] = { .str = "c", .exclude = OM(Z) | OM(GZ) | OM(GEZ) | OM(E) | OM(G) | OM(GE) | OM(NE) | OM(L) | OM(LE) }, + [ROGUE_ALU_OP_MOD_E] = { .str = "e", .exclude = OM(Z) | OM(GZ) | OM(GEZ) | OM(C) | OM(G) | OM(GE) | OM(NE) | OM(L) | OM(LE) }, + [ROGUE_ALU_OP_MOD_G] = { .str = "g", .exclude = OM(Z) | OM(GZ) | OM(GEZ) | OM(C) | OM(E) | OM(GE) | OM(NE) | OM(L) | OM(LE) }, + [ROGUE_ALU_OP_MOD_GE] = { .str = "ge", .exclude = OM(Z) | OM(GZ) | OM(GEZ) | OM(C) | OM(E) | OM(G) | OM(NE) | OM(L) | OM(LE) }, + [ROGUE_ALU_OP_MOD_NE] = { .str = "ne", .exclude = OM(Z) | OM(GZ) | OM(GEZ) | OM(C) | OM(E) | OM(G) | OM(GE) | OM(L) | OM(LE) }, + [ROGUE_ALU_OP_MOD_L] = { .str = "l", .exclude = OM(Z) | OM(GZ) | OM(GEZ) | OM(C) | OM(E) | OM(G) | OM(GE) | OM(NE) | OM(LE) }, + [ROGUE_ALU_OP_MOD_LE] = { .str = "le", .exclude = OM(Z) | OM(GZ) | OM(GEZ) | OM(C) | OM(E) | OM(G) | OM(GE) | OM(NE) | OM(L) }, + + [ROGUE_ALU_OP_MOD_F32] = { .str = "f32", .exclude = OM(U16) | OM(S16) | OM(U8) | OM(S8) | OM(U32) | OM(S32) }, + [ROGUE_ALU_OP_MOD_U16] = { .str = "u16", .exclude = OM(F32) | OM(S16) | OM(U8) | OM(S8) | OM(U32) | OM(S32) }, + [ROGUE_ALU_OP_MOD_S16] = { .str = "s16", .exclude = OM(F32) | OM(U16) | OM(U8) | OM(S8) | OM(U32) | OM(S32) }, + [ROGUE_ALU_OP_MOD_U8] = { .str = "u8", .exclude = OM(F32) | OM(U16) | OM(S16) | OM(S8) | OM(U32) | OM(S32) }, + [ROGUE_ALU_OP_MOD_S8] = { .str = "s8", .exclude = OM(F32) | OM(U16) | OM(S16) | OM(U8) | OM(U32) | OM(S32) }, + [ROGUE_ALU_OP_MOD_U32] = { .str = "u32", .exclude = OM(F32) | OM(U16) | OM(S16) | OM(U8) | OM(S8) | OM(S32) }, + [ROGUE_ALU_OP_MOD_S32] = { .str = "s32", .exclude = OM(F32) | OM(U16) | OM(S16) | OM(U8) | OM(S8) | OM(U32) }, }; +#undef OM const rogue_alu_dst_mod_info rogue_alu_dst_mod_infos[ROGUE_ALU_DST_MOD_COUNT] = { - [ROGUE_ALU_DST_MOD_E0] = { .str = "e0", }, - [ROGUE_ALU_DST_MOD_E1] = { .str = "e1", }, - [ROGUE_ALU_DST_MOD_E2] = { .str = "e2", }, - [ROGUE_ALU_DST_MOD_E3] = { .str = "e3", }, + [ROGUE_ALU_DST_MOD_E0] = { .str = "e0", }, + [ROGUE_ALU_DST_MOD_E1] = { .str = "e1", }, + [ROGUE_ALU_DST_MOD_E2] = { .str = "e2", }, + [ROGUE_ALU_DST_MOD_E3] = { .str = "e3", }, }; const rogue_alu_src_mod_info rogue_alu_src_mod_infos[ROGUE_ALU_SRC_MOD_COUNT] = { - [ROGUE_ALU_SRC_MOD_FLR] = { .str = "flr", }, - [ROGUE_ALU_SRC_MOD_ABS] = { .str = "abs", }, - [ROGUE_ALU_SRC_MOD_NEG] = { .str = "neg", }, + [ROGUE_ALU_SRC_MOD_FLR] = { .str = "flr", }, + [ROGUE_ALU_SRC_MOD_ABS] = { .str = "abs", }, + [ROGUE_ALU_SRC_MOD_NEG] = { .str = "neg", }, + [ROGUE_ALU_SRC_MOD_E0] = { .str = "e0", }, + [ROGUE_ALU_SRC_MOD_E1] = { .str = "e1", }, + [ROGUE_ALU_SRC_MOD_E2] = { .str = "e2", }, + [ROGUE_ALU_SRC_MOD_E3] = { .str = "e3", }, }; #define OM(op_mod) BITFIELD64_BIT(ROGUE_CTRL_OP_MOD_##op_mod) @@ -506,30 +531,31 @@ const rogue_bitwise_op_info rogue_bitwise_op_infos[ROGUE_BITWISE_OP_COUNT] = { #undef P const rogue_io_info rogue_io_infos[ROGUE_IO_COUNT] = { - [ROGUE_IO_INVALID] = { .str = "!INVALID!", }, - [ROGUE_IO_S0] = { .str = "s0", }, - [ROGUE_IO_S1] = { .str = "s1", }, - [ROGUE_IO_S2] = { .str = "s2", }, - [ROGUE_IO_S3] = { .str = "s3", }, - [ROGUE_IO_S4] = { .str = "s4", }, - [ROGUE_IO_S5] = { .str = "s5", }, - [ROGUE_IO_W0] = { .str = "w0", }, - [ROGUE_IO_W1] = { .str = "w1", }, - [ROGUE_IO_IS0] = { .str = "is0", }, - [ROGUE_IO_IS1] = { .str = "is1", }, - [ROGUE_IO_IS2] = { .str = "is2", }, - [ROGUE_IO_IS3] = { .str = "is3", }, - [ROGUE_IO_IS4] = { .str = "is4/w0", }, - [ROGUE_IO_IS5] = { .str = "is5/w1", }, - [ROGUE_IO_FT0] = { .str = "ft0", }, - [ROGUE_IO_FT1] = { .str = "ft1", }, - [ROGUE_IO_FT2] = { .str = "ft2", }, - [ROGUE_IO_FTE] = { .str = "fte", }, - [ROGUE_IO_FT3] = { .str = "ft3", }, - [ROGUE_IO_FT4] = { .str = "ft4", }, - [ROGUE_IO_FT5] = { .str = "ft5", }, - [ROGUE_IO_P0] = { .str = "p0", }, - [ROGUE_IO_NONE] = { .str = "_", }, + [ROGUE_IO_INVALID] = { .str = "!INVALID!", }, + [ROGUE_IO_S0] = { .str = "s0", }, + [ROGUE_IO_S1] = { .str = "s1", }, + [ROGUE_IO_S2] = { .str = "s2", }, + [ROGUE_IO_S3] = { .str = "s3", }, + [ROGUE_IO_S4] = { .str = "s4", }, + [ROGUE_IO_S5] = { .str = "s5", }, + [ROGUE_IO_W0] = { .str = "w0", }, + [ROGUE_IO_W1] = { .str = "w1", }, + [ROGUE_IO_IS0] = { .str = "is0", }, + [ROGUE_IO_IS1] = { .str = "is1", }, + [ROGUE_IO_IS2] = { .str = "is2", }, + [ROGUE_IO_IS3] = { .str = "is3", }, + [ROGUE_IO_IS4] = { .str = "is4/w0", }, + [ROGUE_IO_IS5] = { .str = "is5/w1", }, + [ROGUE_IO_FT0] = { .str = "ft0", }, + [ROGUE_IO_FT1] = { .str = "ft1", }, + [ROGUE_IO_FT2] = { .str = "ft2", }, + [ROGUE_IO_FTE] = { .str = "fte", }, + [ROGUE_IO_FT3] = { .str = "ft3", }, + [ROGUE_IO_FT4] = { .str = "ft4", }, + [ROGUE_IO_FT5] = { .str = "ft5", }, + [ROGUE_IO_FTT] = { .str = "ftt", }, + [ROGUE_IO_P0] = { .str = "p0", }, + [ROGUE_IO_NONE] = { .str = "_", }, }; #define SM(src_mod) BITFIELD64_BIT(ROGUE_ALU_SRC_MOD_##src_mod) @@ -592,8 +618,23 @@ const rogue_alu_op_info rogue_alu_op_infos[ROGUE_ALU_OP_COUNT] = { [2] = T(REG), }, }, - /* TODO: Implement */ - [ROGUE_ALU_OP_TST] = { .str = "tst", .num_dsts = 2, .num_srcs = 2, }, + /* TODO NEXT!: Validate - can/must only select element if non-32-bit type, element has to be same for both args if both args present, 16-bit must be 0 or 1, 32-bit must be 0-3 (can't have no element set) + * Also validate number of sources provided/nulled out based on test op */ + [ROGUE_ALU_OP_TST] = { .str = "tst", .num_dsts = 2, .num_srcs = 2, + .supported_phases = P(2_TST), + .phase_io[PH(2_TST)] = { .src[0] = IO(IS1), .src[1] = IO(IS2), }, + .supported_op_mods = OM(Z) | OM(GZ) | OM(GEZ) | OM(C) | OM(E) | OM(G) | OM(GE) | OM(NE) | OM(L) | OM(LE) | + OM(F32) | OM(U16) | OM(S16) | OM(U8) | OM(S8) | OM(U32) | OM(S32), + .supported_src_mods = { + [0] = SM(E0) | SM(E1) | SM(E2) | SM(E3), + [1] = SM(E0) | SM(E1) | SM(E2) | SM(E3), + }, + .supported_dst_types = { [0] = T(IO), [1] = T(IO), }, /* FTT and either P0 or NONE */ + .supported_src_types = { + [0] = T(REG) | T(IO), + [1] = T(REG) | T(IO), + }, + }, [ROGUE_ALU_OP_ADD64] = { .str = "add64", .num_dsts = 3, .num_srcs = 5, .supported_phases = P(0), .phase_io[PH(0)] = { .dst[0] = IO(FT0), .dst[1] = IO(FTE), .src[0] = IO(S0), .src[1] = IO(S1), .src[2] = IO(S2), .src[3] = IO(IS0), }, @@ -645,18 +686,12 @@ const rogue_alu_op_info rogue_alu_op_infos[ROGUE_ALU_OP_COUNT] = { #undef DM #undef SM -const char *const rogue_comp_test_str[ROGUE_COMP_TEST_COUNT] = { - [ROGUE_COMP_TEST_NONE] = "!INVALID!", [ROGUE_COMP_TEST_EQ] = "eq", - [ROGUE_COMP_TEST_GT] = "gt", [ROGUE_COMP_TEST_GE] = "ge", - [ROGUE_COMP_TEST_NE] = "ne", [ROGUE_COMP_TEST_LT] = "lt", - [ROGUE_COMP_TEST_LE] = "le", -}; - -const char *const rogue_comp_type_str[ROGUE_COMP_TYPE_COUNT] = { - [ROGUE_COMP_TYPE_NONE] = "!INVALID!", [ROGUE_COMP_TYPE_F32] = "f32", - [ROGUE_COMP_TYPE_U16] = "u16", [ROGUE_COMP_TYPE_S16] = "s16", - [ROGUE_COMP_TYPE_U8] = "u8", [ROGUE_COMP_TYPE_S8] = "s8", - [ROGUE_COMP_TYPE_U32] = "u32", [ROGUE_COMP_TYPE_S32] = "s32", +const char *rogue_exec_cond_str[ROGUE_EXEC_COND_COUNT] = { + [ROGUE_EXEC_COND_INVALID] = "!INVALID!", + [ROGUE_EXEC_COND_PE_TRUE] = "if(pe)", + [ROGUE_EXEC_COND_P0_TRUE] = "if(p0)", + [ROGUE_EXEC_COND_PE_ANY] = "any(pe)", + [ROGUE_EXEC_COND_P0_FALSE] = "if(!p0)", }; const char *rogue_instr_type_str[ROGUE_INSTR_TYPE_COUNT] = { diff --git a/src/imagination/rogue/rogue_isa.h b/src/imagination/rogue/rogue_isa.h index 7634ba46eef..88bfaeffe68 100644 --- a/src/imagination/rogue/rogue_isa.h +++ b/src/imagination/rogue/rogue_isa.h @@ -607,15 +607,32 @@ enum tstop { TSTOP_Z = 0b0000, TSTOP_GZ = 0b0001, TSTOP_GEZ = 0b0010, - TSTOP_IC = 0b0011, - TSTOP_EQ = 0b0100, - TSTOP_GT = 0b0101, + TSTOP_C = 0b0011, + TSTOP_E = 0b0100, + TSTOP_G = 0b0101, TSTOP_GE = 0b0110, TSTOP_NE = 0b0111, - TSTOP_LT = 0b1000, + TSTOP_L = 0b1000, TSTOP_LE = 0b1001, }; +enum tsttype { + TSTTYPE_F32 = 0b000, + TSTTYPE_U16 = 0b001, + TSTTYPE_S16 = 0b010, + TSTTYPE_U8 = 0b011, + TSTTYPE_S8 = 0b100, + TSTTYPE_U32 = 0b101, + TSTTYPE_S32 = 0b110, +}; + +enum tstelem { + TST_E0 = 0b00, + TST_E1 = 0b01, + TST_E2 = 0b10, + TST_E3 = 0b11, +}; + typedef struct rogue_alu_mov_encoding { /* Byte 0 */ struct { diff --git a/src/imagination/rogue/rogue_print.c b/src/imagination/rogue/rogue_print.c index 44acd23c1b6..7748385f343 100644 --- a/src/imagination/rogue/rogue_print.c +++ b/src/imagination/rogue/rogue_print.c @@ -252,11 +252,6 @@ static inline void rogue_print_alu_instr(FILE *fp, const rogue_alu_instr *alu) fprintf(fp, "%s", info->str); - if (alu->op == ROGUE_ALU_OP_TST) { - fprintf(fp, "%s", rogue_comp_test_str[alu->comp_test]); - fprintf(fp, ".%s", rogue_comp_type_str[alu->comp_type]); - } - rogue_print_alu_mods(fp, alu); for (unsigned i = 0; i < info->num_dsts; ++i) { @@ -422,6 +417,9 @@ static inline void rogue_print_bitwise_instr(FILE *fp, PUBLIC void rogue_print_instr(FILE *fp, const rogue_instr *instr) { + if (instr->exec_cond > ROGUE_EXEC_COND_PE_TRUE) + fprintf(fp, "%s ", rogue_exec_cond_str[instr->exec_cond]); + if (instr->repeat > 1) fprintf(fp, "(rpt%u) ", instr->repeat); @@ -585,6 +583,9 @@ static inline void rogue_print_instr_group(FILE *fp, fprintf(fp, "%u", group->index); fputs(": ", fp); + if (group->header.exec_cond > ROGUE_EXEC_COND_PE_TRUE) + fprintf(fp, "%s ", rogue_exec_cond_str[group->header.exec_cond]); + if (group->header.repeat > 1) fprintf(fp, "(rpt%u) ", group->header.repeat); diff --git a/src/imagination/rogue/rogue_validate.c b/src/imagination/rogue/rogue_validate.c index e8f9d7b4caa..7d34c854513 100644 --- a/src/imagination/rogue/rogue_validate.c +++ b/src/imagination/rogue/rogue_validate.c @@ -249,12 +249,6 @@ static void validate_alu_instr(rogue_validation_state *state, const rogue_alu_op_info *info = &rogue_alu_op_infos[alu->op]; - if (!rogue_alu_comp_is_none(alu) && alu->op != ROGUE_ALU_OP_TST) - validate_log(state, "ALU comparison set for non-test op."); - - if (rogue_alu_comp_is_none(alu) && alu->op == ROGUE_ALU_OP_TST) - validate_log(state, "ALU comparison not set for test op."); - /* Check if instruction modifiers are valid. */ if (!rogue_mods_supported(alu->mod, info->supported_op_mods)) validate_log(state, "Unsupported ALU op modifiers.");