pvr: Add support for TST
Signed-off-by: Simon Perretta <simon.perretta@imgtec.com> Acked-by: Frank Binns <frank.binns@imgtec.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/21474>
This commit is contained in:

committed by
Marge Bot

parent
de64dfe940
commit
b642e77cdd
@@ -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;
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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;
|
||||
|
@@ -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] = {
|
||||
|
@@ -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 {
|
||||
|
@@ -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);
|
||||
|
||||
|
@@ -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.");
|
||||
|
Reference in New Issue
Block a user