pvr: Add support for MOVC
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
c38c119617
commit
8719f7cb8d
@@ -552,6 +552,25 @@ static void rogue_calc_alu_instrs_size(rogue_instr_group *group,
|
||||
}
|
||||
break;
|
||||
|
||||
case ROGUE_ALU_OP_MOVC: {
|
||||
group->size.instrs[phase] = 1;
|
||||
|
||||
bool e0 = rogue_alu_dst_mod_is_set(alu, 0, DM(E0));
|
||||
bool e1 = rogue_alu_dst_mod_is_set(alu, 0, DM(E1));
|
||||
bool e2 = rogue_alu_dst_mod_is_set(alu, 0, DM(E2));
|
||||
bool e3 = rogue_alu_dst_mod_is_set(alu, 0, DM(E3));
|
||||
bool eq = (e0 == e1) && (e0 == e2) && (e0 == e3);
|
||||
|
||||
if ((!rogue_phase_occupied(ROGUE_INSTR_PHASE_2_TST,
|
||||
group->header.phases) &&
|
||||
!rogue_phase_occupied(ROGUE_INSTR_PHASE_2_PCK,
|
||||
group->header.phases)) ||
|
||||
!rogue_ref_is_io_ftt(&alu->src[0].ref) || !eq) {
|
||||
group->size.instrs[phase] = 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ROGUE_ALU_OP_PCK_U8888:
|
||||
group->size.instrs[phase] = 2;
|
||||
break;
|
||||
|
@@ -887,6 +887,11 @@ static inline bool rogue_ref_is_io_p0(const rogue_ref *ref)
|
||||
return rogue_ref_get_io(ref) == ROGUE_IO_P0;
|
||||
}
|
||||
|
||||
static inline bool rogue_ref_is_io_ftt(const rogue_ref *ref)
|
||||
{
|
||||
return rogue_ref_get_io(ref) == ROGUE_IO_FTT;
|
||||
}
|
||||
|
||||
static inline bool rogue_ref_is_io_none(const rogue_ref *ref)
|
||||
{
|
||||
/* Special case - never assert. */
|
||||
@@ -1038,12 +1043,14 @@ enum rogue_alu_op {
|
||||
ROGUE_ALU_OP_ADD64,
|
||||
|
||||
ROGUE_ALU_OP_TST,
|
||||
ROGUE_ALU_OP_MOVC,
|
||||
|
||||
ROGUE_ALU_OP_PCK_U8888,
|
||||
|
||||
/* Pseudo-instructions. */
|
||||
ROGUE_ALU_OP_PSEUDO,
|
||||
ROGUE_ALU_OP_MOV = ROGUE_ALU_OP_PSEUDO,
|
||||
ROGUE_ALU_OP_CMOV, /** Conditional move. */
|
||||
|
||||
ROGUE_ALU_OP_FABS,
|
||||
ROGUE_ALU_OP_FNEG,
|
||||
|
@@ -49,6 +49,10 @@
|
||||
#define ROGUE_BUILDER_DEFINE_ALU22(...)
|
||||
#endif /* ROGUE_BUILDER_DEFINE_ALU22 */
|
||||
|
||||
#ifndef ROGUE_BUILDER_DEFINE_ALU23
|
||||
#define ROGUE_BUILDER_DEFINE_ALU23(...)
|
||||
#endif /* ROGUE_BUILDER_DEFINE_ALU23 */
|
||||
|
||||
#ifndef ROGUE_BUILDER_DEFINE_ALU35
|
||||
#define ROGUE_BUILDER_DEFINE_ALU35(...)
|
||||
#endif /* ROGUE_BUILDER_DEFINE_ALU35 */
|
||||
@@ -69,12 +73,16 @@ ROGUE_BUILDER_DEFINE_ALU12(FMAX)
|
||||
ROGUE_BUILDER_DEFINE_ALU12(FMIN)
|
||||
|
||||
ROGUE_BUILDER_DEFINE_ALU13(FMAD)
|
||||
ROGUE_BUILDER_DEFINE_ALU13(CMOV)
|
||||
|
||||
ROGUE_BUILDER_DEFINE_ALU22(TST)
|
||||
|
||||
ROGUE_BUILDER_DEFINE_ALU23(MOVC)
|
||||
|
||||
ROGUE_BUILDER_DEFINE_ALU35(ADD64)
|
||||
|
||||
#undef ROGUE_BUILDER_DEFINE_ALU35
|
||||
#undef ROGUE_BUILDER_DEFINE_ALU23
|
||||
#undef ROGUE_BUILDER_DEFINE_ALU22
|
||||
#undef ROGUE_BUILDER_DEFINE_ALU13
|
||||
#undef ROGUE_BUILDER_DEFINE_ALU12
|
||||
|
@@ -115,6 +115,19 @@ static inline rogue_alu_instr *rogue_build_alu22(rogue_builder *b,
|
||||
return rogue_build_alu(b, op, 2, dsts, 2, srcs);
|
||||
}
|
||||
|
||||
static inline rogue_alu_instr *rogue_build_alu23(rogue_builder *b,
|
||||
enum rogue_alu_op op,
|
||||
rogue_ref dst0,
|
||||
rogue_ref dst1,
|
||||
rogue_ref src0,
|
||||
rogue_ref src1,
|
||||
rogue_ref src2)
|
||||
{
|
||||
rogue_ref dsts[] = { dst0, dst1 };
|
||||
rogue_ref srcs[] = { src0, src1, src2 };
|
||||
return rogue_build_alu(b, op, 2, dsts, 3, srcs);
|
||||
}
|
||||
|
||||
static inline rogue_alu_instr *rogue_build_alu35(rogue_builder *b,
|
||||
enum rogue_alu_op op,
|
||||
rogue_ref dst0,
|
||||
@@ -181,6 +194,26 @@ static inline rogue_alu_instr *rogue_build_alu35(rogue_builder *b,
|
||||
return rogue_build_alu22(b, ROGUE_ALU_OP_##op, dst0, dst1, src0, src1); \
|
||||
}
|
||||
|
||||
#define ROGUE_BUILDER_DEFINE_ALU23(op) \
|
||||
PUBLIC \
|
||||
rogue_alu_instr *rogue_##op(rogue_builder *b, \
|
||||
rogue_ref dst0, \
|
||||
rogue_ref dst1, \
|
||||
rogue_ref src0, \
|
||||
rogue_ref src1, \
|
||||
rogue_ref src2) \
|
||||
{ \
|
||||
assert(rogue_alu_op_infos[ROGUE_ALU_OP_##op].num_dsts == 2); \
|
||||
assert(rogue_alu_op_infos[ROGUE_ALU_OP_##op].num_srcs == 3); \
|
||||
return rogue_build_alu23(b, \
|
||||
ROGUE_ALU_OP_##op, \
|
||||
dst0, \
|
||||
dst1, \
|
||||
src0, \
|
||||
src1, \
|
||||
src2); \
|
||||
}
|
||||
|
||||
#define ROGUE_BUILDER_DEFINE_ALU35(op) \
|
||||
PUBLIC \
|
||||
rogue_alu_instr *rogue_##op(rogue_builder *b, \
|
||||
|
@@ -116,6 +116,14 @@ static inline rogue_block *rogue_push_block(rogue_builder *b)
|
||||
rogue_ref src0, \
|
||||
rogue_ref src1);
|
||||
|
||||
#define ROGUE_BUILDER_DEFINE_ALU23(op) \
|
||||
rogue_alu_instr *rogue_##op(rogue_builder *b, \
|
||||
rogue_ref dst0, \
|
||||
rogue_ref dst1, \
|
||||
rogue_ref src0, \
|
||||
rogue_ref src1, \
|
||||
rogue_ref src2);
|
||||
|
||||
#define ROGUE_BUILDER_DEFINE_ALU35(op) \
|
||||
rogue_alu_instr *rogue_##op(rogue_builder *b, \
|
||||
rogue_ref dst0, \
|
||||
|
@@ -348,6 +348,74 @@ static void rogue_encode_alu_instr(const rogue_alu_instr *alu,
|
||||
break;
|
||||
}
|
||||
|
||||
case ROGUE_ALU_OP_MOVC: {
|
||||
instr_encoding->alu.op = ALUOP_MOVC;
|
||||
|
||||
bool e0 = rogue_alu_dst_mod_is_set(alu, 0, DM(E0));
|
||||
bool e1 = rogue_alu_dst_mod_is_set(alu, 0, DM(E1));
|
||||
bool e2 = rogue_alu_dst_mod_is_set(alu, 0, DM(E2));
|
||||
bool e3 = rogue_alu_dst_mod_is_set(alu, 0, DM(E3));
|
||||
bool e_none = !e0 && !e1 && !e2 && !e3;
|
||||
|
||||
switch (rogue_ref_get_io(&alu->src[1].ref)) {
|
||||
case ROGUE_IO_FT0:
|
||||
instr_encoding->alu.movc.movw0 = MOVW_FT0;
|
||||
break;
|
||||
case ROGUE_IO_FT1:
|
||||
instr_encoding->alu.movc.movw0 = MOVW_FT1;
|
||||
break;
|
||||
case ROGUE_IO_FT2:
|
||||
instr_encoding->alu.movc.movw0 = MOVW_FT2;
|
||||
break;
|
||||
case ROGUE_IO_FTE:
|
||||
instr_encoding->alu.movc.movw0 = MOVW_FTE;
|
||||
break;
|
||||
default:
|
||||
unreachable("Invalid source.");
|
||||
}
|
||||
|
||||
switch (rogue_ref_get_io(&alu->src[2].ref)) {
|
||||
case ROGUE_IO_FT0:
|
||||
instr_encoding->alu.movc.movw1 = MOVW_FT0;
|
||||
break;
|
||||
case ROGUE_IO_FT1:
|
||||
instr_encoding->alu.movc.movw1 = MOVW_FT1;
|
||||
break;
|
||||
case ROGUE_IO_FT2:
|
||||
instr_encoding->alu.movc.movw1 = MOVW_FT2;
|
||||
break;
|
||||
case ROGUE_IO_FTE:
|
||||
instr_encoding->alu.movc.movw1 = MOVW_FTE;
|
||||
break;
|
||||
default:
|
||||
unreachable("Invalid source.");
|
||||
}
|
||||
|
||||
if (instr_size == 2) {
|
||||
instr_encoding->alu.movc.ext = 1;
|
||||
instr_encoding->alu.movc.p2end =
|
||||
!rogue_phase_occupied(ROGUE_INSTR_PHASE_2_TST,
|
||||
alu->instr.group->header.phases) &&
|
||||
!rogue_phase_occupied(ROGUE_INSTR_PHASE_2_PCK,
|
||||
alu->instr.group->header.phases);
|
||||
instr_encoding->alu.movc.aw = !rogue_ref_is_io_ftt(&alu->src[0].ref);
|
||||
|
||||
if (e_none) {
|
||||
instr_encoding->alu.movc.maskw0 = MASKW0_EALL;
|
||||
} else {
|
||||
if (e0)
|
||||
instr_encoding->alu.movc.maskw0 |= MASKW0_E0;
|
||||
if (e1)
|
||||
instr_encoding->alu.movc.maskw0 |= MASKW0_E1;
|
||||
if (e2)
|
||||
instr_encoding->alu.movc.maskw0 |= MASKW0_E2;
|
||||
if (e3)
|
||||
instr_encoding->alu.movc.maskw0 |= MASKW0_E3;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case ROGUE_ALU_OP_PCK_U8888:
|
||||
instr_encoding->alu.op = ALUOP_SNGL;
|
||||
instr_encoding->alu.sngl.snglop = SNGLOP_PCK;
|
||||
|
@@ -635,6 +635,19 @@ const rogue_alu_op_info rogue_alu_op_infos[ROGUE_ALU_OP_COUNT] = {
|
||||
[1] = T(REG) | T(IO),
|
||||
},
|
||||
},
|
||||
[ROGUE_ALU_OP_MOVC] = { .str = "movc", .num_dsts = 2, .num_srcs = 3,
|
||||
.supported_phases = P(2_MOV),
|
||||
.phase_io[PH(2_MOV)] = { .dst[0] = IO(W0), .dst[1] = IO(W1), .src[1] = IO(FT0), .src[2] = IO(FTE), }, /* TODO: SRC ONES ARE TEMPORARY, SHOULD BE MADE TO MATCH THE TST ONES INSTEAD? */
|
||||
.supported_dst_mods = {
|
||||
[0] = DM(E0) | DM(E1) | DM(E2) | DM(E3),
|
||||
},
|
||||
.supported_dst_types = { [0] = T(REG), [1] = T(REG) | T(IO), },
|
||||
.supported_src_types = {
|
||||
[0] = T(IO),
|
||||
[1] = T(REG) | T(IO),
|
||||
[2] = 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), },
|
||||
@@ -663,13 +676,20 @@ const rogue_alu_op_info rogue_alu_op_infos[ROGUE_ALU_OP_COUNT] = {
|
||||
},
|
||||
.src_repeat_mask = B(0),
|
||||
},
|
||||
/* This mov is "fake" since it can be lowered to a MBYP, make a new instruction for real mov (call it MOVD?). */
|
||||
[ROGUE_ALU_OP_MOV] = { .str = "mov", .num_dsts = 1, .num_srcs = 1,
|
||||
.supported_dst_types = { [0] = T(REG) | T(REGARRAY), },
|
||||
.supported_src_types = {
|
||||
[0] = T(REG) | T(IMM),
|
||||
},
|
||||
},
|
||||
[ROGUE_ALU_OP_CMOV] = { .str = "cmov", .num_dsts = 1, .num_srcs = 3,
|
||||
.supported_dst_types = { [0] = T(REG), },
|
||||
.supported_src_types = {
|
||||
[0] = T(IO),
|
||||
[1] = T(REG),
|
||||
[2] = T(REG),
|
||||
},
|
||||
},
|
||||
[ROGUE_ALU_OP_FABS] = { .str = "fabs", .num_dsts = 1, .num_srcs = 1, },
|
||||
[ROGUE_ALU_OP_FNEG] = { .str = "fneg", .num_dsts = 1, .num_srcs = 1, },
|
||||
[ROGUE_ALU_OP_FNABS] = { .str = "fnabs", .num_dsts = 1, .num_srcs = 1, },
|
||||
|
@@ -633,7 +633,7 @@ enum tstelem {
|
||||
TST_E3 = 0b11,
|
||||
};
|
||||
|
||||
typedef struct rogue_alu_mov_encoding {
|
||||
typedef struct rogue_alu_movc_encoding {
|
||||
/* Byte 0 */
|
||||
struct {
|
||||
unsigned movw0 : 2;
|
||||
@@ -649,9 +649,24 @@ typedef struct rogue_alu_mov_encoding {
|
||||
unsigned maskw0 : 4;
|
||||
unsigned : 2;
|
||||
} PACKED;
|
||||
} PACKED rogue_alu_mov_encoding;
|
||||
static_assert(sizeof(rogue_alu_mov_encoding) == 2,
|
||||
"sizeof(rogue_alu_mov_encoding) != 2");
|
||||
} PACKED rogue_alu_movc_encoding;
|
||||
static_assert(sizeof(rogue_alu_movc_encoding) == 2,
|
||||
"sizeof(rogue_alu_movc_encoding) != 2");
|
||||
|
||||
enum movw {
|
||||
MOVW_FT0 = 0b00,
|
||||
MOVW_FT1 = 0b01,
|
||||
MOVW_FT2 = 0b10,
|
||||
MOVW_FTE = 0b11,
|
||||
};
|
||||
|
||||
enum maskw0 {
|
||||
MASKW0_E0 = 0b0001,
|
||||
MASKW0_E1 = 0b0010,
|
||||
MASKW0_E2 = 0b0100,
|
||||
MASKW0_E3 = 0b1000,
|
||||
MASKW0_EALL = 0b1111,
|
||||
};
|
||||
|
||||
typedef struct rogue_alu_int32_64_encoding {
|
||||
/* Byte 0 */
|
||||
@@ -699,7 +714,7 @@ typedef struct rogue_alu_instr_encoding {
|
||||
rogue_alu_fdual_encoding fmul;
|
||||
rogue_alu_fmad_encoding fmad;
|
||||
rogue_alu_tst_encoding tst;
|
||||
rogue_alu_mov_encoding mov;
|
||||
rogue_alu_movc_encoding movc;
|
||||
rogue_alu_int32_64_encoding int32_64;
|
||||
} PACKED;
|
||||
} PACKED rogue_alu_instr_encoding;
|
||||
@@ -712,7 +727,7 @@ enum aluop {
|
||||
ALUOP_SNGL = 0b100, /** Phase 0, 1, 2. */
|
||||
ALUOP_INT8_16 = 0b101, /** Phase 0. */
|
||||
ALUOP_FMAD = 0b110, /** Phase 0, 1. */
|
||||
ALUOP_MOV = 0b110, /** Phase 2. */
|
||||
ALUOP_MOVC = 0b110, /** Phase 2. */
|
||||
ALUOP_INT32_64 = 0b111, /** Phase 0. */
|
||||
ALUOP_TST = 0b111, /** Phase 2. */
|
||||
};
|
||||
|
Reference in New Issue
Block a user