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

committed by
Marge Bot

parent
7386342a19
commit
81f86a559c
@@ -34,34 +34,99 @@
|
||||
*/
|
||||
|
||||
static inline void rogue_set_io_sel(rogue_instr_group_io_sel *map,
|
||||
enum rogue_alu alu,
|
||||
enum rogue_io io,
|
||||
rogue_ref *ref,
|
||||
bool is_dst)
|
||||
{
|
||||
/* Hookup feedthrough outputs to W0 using IS4. */
|
||||
if (is_dst && rogue_io_is_ft(io)) {
|
||||
*(rogue_instr_group_io_sel_ref(map, ROGUE_IO_IS4)) = rogue_ref_io(io);
|
||||
io = ROGUE_IO_W0;
|
||||
/* Skip unassigned I/Os. */
|
||||
if (rogue_ref_is_io_none(ref))
|
||||
return;
|
||||
|
||||
/* Early skip I/Os that have already been assigned (e.g. for grouping). */
|
||||
if (rogue_ref_is_io(ref) && rogue_ref_get_io(ref) == io)
|
||||
return;
|
||||
|
||||
/* Leave source feedthroughs in place. */
|
||||
if (!is_dst && rogue_io_is_ft(io))
|
||||
return;
|
||||
|
||||
if (alu == ROGUE_ALU_MAIN) {
|
||||
/* Hookup feedthrough outputs to W0 using IS4. */
|
||||
if (is_dst && rogue_io_is_ft(io)) {
|
||||
if (io == ROGUE_IO_FTE) {
|
||||
*(rogue_instr_group_io_sel_ref(map, ROGUE_IO_IS5)) =
|
||||
rogue_ref_io(io);
|
||||
io = ROGUE_IO_W1;
|
||||
} else {
|
||||
*(rogue_instr_group_io_sel_ref(map, ROGUE_IO_IS4)) =
|
||||
rogue_ref_io(io);
|
||||
io = ROGUE_IO_W0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Pack source */
|
||||
if (!is_dst && io == ROGUE_IO_IS3) {
|
||||
enum rogue_io src = ROGUE_IO_S0;
|
||||
*(rogue_instr_group_io_sel_ref(map, ROGUE_IO_IS0)) = rogue_ref_io(src);
|
||||
*(rogue_instr_group_io_sel_ref(map, ROGUE_IO_IS3)) =
|
||||
rogue_ref_io(ROGUE_IO_FTE);
|
||||
io = src;
|
||||
}
|
||||
|
||||
/* Movc sources. */
|
||||
if (!is_dst && rogue_io_is_dst(io)) {
|
||||
enum rogue_io dst_ft =
|
||||
(io == ROGUE_IO_W0 ? ROGUE_IO_IS4 : ROGUE_IO_IS5);
|
||||
enum rogue_io src = ROGUE_IO_S0;
|
||||
*(rogue_instr_group_io_sel_ref(map, dst_ft)) =
|
||||
rogue_ref_io(ROGUE_IO_FTE);
|
||||
*(rogue_instr_group_io_sel_ref(map, ROGUE_IO_IS0)) = rogue_ref_io(src);
|
||||
io = src;
|
||||
}
|
||||
|
||||
/* ADD64 fourth source */
|
||||
if (!is_dst && io == ROGUE_IO_IS0) {
|
||||
enum rogue_io src = ROGUE_IO_S3;
|
||||
*(rogue_instr_group_io_sel_ref(map, io)) = rogue_ref_io(src);
|
||||
io = src;
|
||||
}
|
||||
|
||||
/* Test source(s). */
|
||||
/* TODO: tidy up. */
|
||||
if (!is_dst && io == ROGUE_IO_IS1) {
|
||||
enum rogue_io src = ROGUE_IO_S0;
|
||||
enum rogue_io ft = ROGUE_IO_FT0;
|
||||
|
||||
/* Already set up. */
|
||||
if (io != ft)
|
||||
*(rogue_instr_group_io_sel_ref(map, io)) = rogue_ref_io(ft);
|
||||
|
||||
io = src;
|
||||
}
|
||||
|
||||
if (!is_dst && io == ROGUE_IO_IS2) {
|
||||
enum rogue_io src = ROGUE_IO_S3;
|
||||
enum rogue_io ft = ROGUE_IO_FTE;
|
||||
|
||||
*(rogue_instr_group_io_sel_ref(map, ROGUE_IO_IS0)) =
|
||||
rogue_ref_io(ROGUE_IO_S3);
|
||||
|
||||
/* Already set up. */
|
||||
if (io != ft)
|
||||
*(rogue_instr_group_io_sel_ref(map, io)) = rogue_ref_io(ft);
|
||||
|
||||
io = src;
|
||||
}
|
||||
} else if (alu == ROGUE_ALU_BITWISE) {
|
||||
/* TODO: This is temporary because we just have BYP0, do it properly. */
|
||||
if (is_dst)
|
||||
io = ROGUE_IO_W0;
|
||||
}
|
||||
|
||||
/* Pack source */
|
||||
if (!is_dst && io == ROGUE_IO_IS3) {
|
||||
enum rogue_io src = ROGUE_IO_S0;
|
||||
*(rogue_instr_group_io_sel_ref(map, ROGUE_IO_IS0)) = rogue_ref_io(src);
|
||||
*(rogue_instr_group_io_sel_ref(map, ROGUE_IO_IS3)) =
|
||||
rogue_ref_io(ROGUE_IO_FTE);
|
||||
io = src;
|
||||
}
|
||||
|
||||
if (!is_dst && rogue_io_is_dst(io)) {
|
||||
enum rogue_io dst_ft = (io == ROGUE_IO_W0 ? ROGUE_IO_IS4 : ROGUE_IO_IS5);
|
||||
enum rogue_io src = ROGUE_IO_S0;
|
||||
*(rogue_instr_group_io_sel_ref(map, dst_ft)) = rogue_ref_io(ROGUE_IO_FTE);
|
||||
*(rogue_instr_group_io_sel_ref(map, ROGUE_IO_IS0)) = rogue_ref_io(src);
|
||||
io = src;
|
||||
}
|
||||
|
||||
*(rogue_instr_group_io_sel_ref(map, io)) = *ref;
|
||||
/* Set if not already set. */
|
||||
if (rogue_ref_is_null(rogue_instr_group_io_sel_ref(map, io)))
|
||||
*(rogue_instr_group_io_sel_ref(map, io)) = *ref;
|
||||
}
|
||||
|
||||
/* TODO NEXT: Abort if anything in sel map is already set. */
|
||||
@@ -77,6 +142,7 @@ static void rogue_lower_alu_io(rogue_alu_instr *alu, rogue_instr_group *group)
|
||||
continue;
|
||||
|
||||
rogue_set_io_sel(&group->io_sel,
|
||||
group->header.alu,
|
||||
info->phase_io[phase].dst[u],
|
||||
&alu->dst[u].ref,
|
||||
true);
|
||||
@@ -88,6 +154,7 @@ static void rogue_lower_alu_io(rogue_alu_instr *alu, rogue_instr_group *group)
|
||||
continue;
|
||||
|
||||
rogue_set_io_sel(&group->io_sel,
|
||||
group->header.alu,
|
||||
info->phase_io[phase].src[u],
|
||||
&alu->src[u].ref,
|
||||
false);
|
||||
@@ -105,6 +172,7 @@ static void rogue_lower_backend_io(rogue_backend_instr *backend,
|
||||
continue;
|
||||
|
||||
rogue_set_io_sel(&group->io_sel,
|
||||
group->header.alu,
|
||||
info->phase_io.dst[u],
|
||||
&backend->dst[u].ref,
|
||||
true);
|
||||
@@ -116,6 +184,7 @@ static void rogue_lower_backend_io(rogue_backend_instr *backend,
|
||||
continue;
|
||||
|
||||
rogue_set_io_sel(&group->io_sel,
|
||||
group->header.alu,
|
||||
info->phase_io.src[u],
|
||||
&backend->src[u].ref,
|
||||
false);
|
||||
@@ -437,6 +506,18 @@ static void rogue_calc_alu_instrs_size(rogue_instr_group *group,
|
||||
group->size.instrs[phase] = 2;
|
||||
break;
|
||||
|
||||
case ROGUE_ALU_OP_ADD64:
|
||||
group->size.instrs[phase] = 1;
|
||||
|
||||
if (rogue_ref_is_io_p0(&alu->src[4].ref) ||
|
||||
rogue_alu_src_mod_is_set(alu, 0, SM(ABS)) ||
|
||||
rogue_alu_src_mod_is_set(alu, 0, SM(NEG)) ||
|
||||
rogue_alu_src_mod_is_set(alu, 1, SM(ABS)) ||
|
||||
rogue_alu_src_mod_is_set(alu, 1, SM(NEG)) ||
|
||||
rogue_alu_src_mod_is_set(alu, 2, SM(ABS)))
|
||||
group->size.instrs[phase] = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
unreachable("Unsupported alu op.");
|
||||
}
|
||||
|
@@ -793,6 +793,20 @@ static inline enum rogue_io rogue_ref_get_io(const rogue_ref *ref)
|
||||
return ref->io;
|
||||
}
|
||||
|
||||
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_none(const rogue_ref *ref)
|
||||
{
|
||||
/* Special case - never assert. */
|
||||
if (!rogue_ref_is_io(ref))
|
||||
return false;
|
||||
|
||||
return rogue_ref_get_io(ref) == ROGUE_IO_NONE;
|
||||
}
|
||||
|
||||
static inline unsigned rogue_ref_get_drc_index(const rogue_ref *ref)
|
||||
{
|
||||
assert(rogue_ref_is_drc(ref));
|
||||
@@ -927,6 +941,8 @@ enum rogue_alu_op {
|
||||
ROGUE_ALU_OP_FMUL,
|
||||
ROGUE_ALU_OP_FMAD,
|
||||
|
||||
ROGUE_ALU_OP_ADD64,
|
||||
|
||||
ROGUE_ALU_OP_TST,
|
||||
|
||||
ROGUE_ALU_OP_PCK_U8888,
|
||||
@@ -942,8 +958,6 @@ enum rogue_alu_op {
|
||||
ROGUE_ALU_OP_FMAX,
|
||||
ROGUE_ALU_OP_FMIN,
|
||||
|
||||
ROGUE_ALU_OP_SEL,
|
||||
|
||||
ROGUE_ALU_OP_COUNT,
|
||||
};
|
||||
|
||||
@@ -1075,9 +1089,9 @@ static inline bool rogue_ctrl_op_has_dsts(enum rogue_ctrl_op op)
|
||||
return info->has_dsts;
|
||||
}
|
||||
|
||||
/* ALU instructions have at most 3 sources. */
|
||||
#define ROGUE_ALU_OP_MAX_SRCS 3
|
||||
#define ROGUE_ALU_OP_MAX_DSTS 2
|
||||
/* ALU instructions have at most 5 sources. */
|
||||
#define ROGUE_ALU_OP_MAX_SRCS 5
|
||||
#define ROGUE_ALU_OP_MAX_DSTS 3
|
||||
|
||||
typedef struct rogue_alu_io_info {
|
||||
enum rogue_io dst[ROGUE_ALU_OP_MAX_DSTS];
|
||||
|
@@ -49,6 +49,10 @@
|
||||
#define ROGUE_BUILDER_DEFINE_ALU22(...)
|
||||
#endif /* ROGUE_BUILDER_DEFINE_ALU22 */
|
||||
|
||||
#ifndef ROGUE_BUILDER_DEFINE_ALU35
|
||||
#define ROGUE_BUILDER_DEFINE_ALU35(...)
|
||||
#endif /* ROGUE_BUILDER_DEFINE_ALU35 */
|
||||
|
||||
ROGUE_BUILDER_DEFINE_ALU11(MOV)
|
||||
ROGUE_BUILDER_DEFINE_ALU11(MBYP)
|
||||
|
||||
@@ -65,10 +69,12 @@ ROGUE_BUILDER_DEFINE_ALU12(FMAX)
|
||||
ROGUE_BUILDER_DEFINE_ALU12(FMIN)
|
||||
|
||||
ROGUE_BUILDER_DEFINE_ALU13(FMAD)
|
||||
ROGUE_BUILDER_DEFINE_ALU13(SEL)
|
||||
|
||||
ROGUE_BUILDER_DEFINE_ALU22(TST)
|
||||
|
||||
ROGUE_BUILDER_DEFINE_ALU35(ADD64)
|
||||
|
||||
#undef ROGUE_BUILDER_DEFINE_ALU35
|
||||
#undef ROGUE_BUILDER_DEFINE_ALU22
|
||||
#undef ROGUE_BUILDER_DEFINE_ALU13
|
||||
#undef ROGUE_BUILDER_DEFINE_ALU12
|
||||
|
@@ -115,6 +115,22 @@ 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_alu35(rogue_builder *b,
|
||||
enum rogue_alu_op op,
|
||||
rogue_ref dst0,
|
||||
rogue_ref dst1,
|
||||
rogue_ref dst2,
|
||||
rogue_ref src0,
|
||||
rogue_ref src1,
|
||||
rogue_ref src2,
|
||||
rogue_ref src3,
|
||||
rogue_ref src4)
|
||||
{
|
||||
rogue_ref dsts[] = { dst0, dst1, dst2 };
|
||||
rogue_ref srcs[] = { src0, src1, src2, src3, src4 };
|
||||
return rogue_build_alu(b, op, 3, dsts, 5, srcs);
|
||||
}
|
||||
|
||||
/* TODO: Static inline in rogue.h? */
|
||||
#define ROGUE_BUILDER_DEFINE_ALU11(op) \
|
||||
PUBLIC \
|
||||
@@ -165,6 +181,32 @@ static inline rogue_alu_instr *rogue_build_alu22(rogue_builder *b,
|
||||
return rogue_build_alu22(b, ROGUE_ALU_OP_##op, dst0, dst1, src0, src1); \
|
||||
}
|
||||
|
||||
#define ROGUE_BUILDER_DEFINE_ALU35(op) \
|
||||
PUBLIC \
|
||||
rogue_alu_instr *rogue_##op(rogue_builder *b, \
|
||||
rogue_ref dst0, \
|
||||
rogue_ref dst1, \
|
||||
rogue_ref dst2, \
|
||||
rogue_ref src0, \
|
||||
rogue_ref src1, \
|
||||
rogue_ref src2, \
|
||||
rogue_ref src3, \
|
||||
rogue_ref src4) \
|
||||
{ \
|
||||
assert(rogue_alu_op_infos[ROGUE_ALU_OP_##op].num_dsts == 3); \
|
||||
assert(rogue_alu_op_infos[ROGUE_ALU_OP_##op].num_srcs == 5); \
|
||||
return rogue_build_alu35(b, \
|
||||
ROGUE_ALU_OP_##op, \
|
||||
dst0, \
|
||||
dst1, \
|
||||
dst2, \
|
||||
src0, \
|
||||
src1, \
|
||||
src2, \
|
||||
src3, \
|
||||
src4); \
|
||||
}
|
||||
|
||||
#include "rogue_alu_instrs.def"
|
||||
|
||||
static inline rogue_backend_instr *rogue_build_backend(rogue_builder *b,
|
||||
|
@@ -116,6 +116,17 @@ static inline rogue_block *rogue_push_block(rogue_builder *b)
|
||||
rogue_ref src0, \
|
||||
rogue_ref src1);
|
||||
|
||||
#define ROGUE_BUILDER_DEFINE_ALU35(op) \
|
||||
rogue_alu_instr *rogue_##op(rogue_builder *b, \
|
||||
rogue_ref dst0, \
|
||||
rogue_ref dst1, \
|
||||
rogue_ref dst2, \
|
||||
rogue_ref src0, \
|
||||
rogue_ref src1, \
|
||||
rogue_ref src2, \
|
||||
rogue_ref src3, \
|
||||
rogue_ref src4);
|
||||
|
||||
#include "rogue_alu_instrs.def"
|
||||
|
||||
/* Backend instructions. */
|
||||
|
@@ -255,6 +255,31 @@ static void rogue_encode_alu_instr(const rogue_alu_instr *alu,
|
||||
instr_encoding->alu.sngl.pck.pck.format = PCK_FMT_U8888;
|
||||
break;
|
||||
|
||||
case ROGUE_ALU_OP_ADD64:
|
||||
instr_encoding->alu.op = ALUOP_INT32_64;
|
||||
|
||||
instr_encoding->alu.int32_64.int32_64_op = INT32_64_OP_ADD64_NMX;
|
||||
instr_encoding->alu.int32_64.s2neg =
|
||||
rogue_alu_src_mod_is_set(alu, 2, SM(NEG));
|
||||
instr_encoding->alu.int32_64.s = 0;
|
||||
|
||||
if (instr_size == 2) {
|
||||
instr_encoding->alu.int32_64.ext = 1;
|
||||
instr_encoding->alu.int32_64.s2abs =
|
||||
rogue_alu_src_mod_is_set(alu, 2, SM(ABS));
|
||||
instr_encoding->alu.int32_64.s1abs =
|
||||
rogue_alu_src_mod_is_set(alu, 1, SM(ABS));
|
||||
instr_encoding->alu.int32_64.s0abs =
|
||||
rogue_alu_src_mod_is_set(alu, 0, SM(ABS));
|
||||
instr_encoding->alu.int32_64.s0neg =
|
||||
rogue_alu_src_mod_is_set(alu, 0, SM(NEG));
|
||||
instr_encoding->alu.int32_64.s1neg =
|
||||
rogue_alu_src_mod_is_set(alu, 1, SM(NEG));
|
||||
instr_encoding->alu.int32_64.cin =
|
||||
rogue_ref_is_io_p0(&alu->src[4].ref);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
unreachable("Unsupported alu op.");
|
||||
}
|
||||
|
@@ -376,6 +376,24 @@ const rogue_alu_op_info rogue_alu_op_infos[ROGUE_ALU_OP_COUNT] = {
|
||||
},
|
||||
/* TODO: Implement */
|
||||
[ROGUE_ALU_OP_TST] = { .str = "tst", .num_dsts = 2, .num_srcs = 2, },
|
||||
[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), },
|
||||
.supported_src_mods = {
|
||||
[0] = SM(ABS) | SM(NEG),
|
||||
[1] = SM(ABS) | SM(NEG),
|
||||
[2] = SM(ABS) | SM(NEG),
|
||||
[3] = SM(ABS) | SM(NEG),
|
||||
},
|
||||
.supported_dst_types = { [0] = T(REG) | T(REGARRAY), [1] = T(REG) | T(REGARRAY) | T(IO), [2] = T(IO) },
|
||||
.supported_src_types = {
|
||||
[0] = T(REG) | T(REGARRAY),
|
||||
[1] = T(REG) | T(REGARRAY),
|
||||
[2] = T(REG) | T(REGARRAY),
|
||||
[3] = T(REG) | T(REGARRAY)| T(IO),
|
||||
[4] = T(IO),
|
||||
},
|
||||
},
|
||||
[ROGUE_ALU_OP_PCK_U8888] = { .str = "pck.u8888", .num_dsts = 1, .num_srcs = 1,
|
||||
.supported_phases = P(2_PCK),
|
||||
.phase_io[PH(2_PCK)] = { .dst[0] = IO(FT2), .src[0] = IO(IS3), },
|
||||
@@ -399,7 +417,6 @@ const rogue_alu_op_info rogue_alu_op_infos[ROGUE_ALU_OP_COUNT] = {
|
||||
|
||||
[ROGUE_ALU_OP_FMAX] = { .str = "fmax", .num_dsts = 1, .num_srcs = 2, }, /* TODO */
|
||||
[ROGUE_ALU_OP_FMIN] = { .str = "fmin", .num_dsts = 1, .num_srcs = 2, }, /* TODO */
|
||||
[ROGUE_ALU_OP_SEL] = { .str = "sel", .num_dsts = 1, .num_srcs = 3, }, /* TODO */
|
||||
};
|
||||
#undef B
|
||||
#undef T
|
||||
|
@@ -636,6 +636,38 @@ typedef struct rogue_alu_mov_encoding {
|
||||
static_assert(sizeof(rogue_alu_mov_encoding) == 2,
|
||||
"sizeof(rogue_alu_mov_encoding) != 2");
|
||||
|
||||
typedef struct rogue_alu_int32_64_encoding {
|
||||
/* Byte 0 */
|
||||
struct {
|
||||
unsigned int32_64_op : 2;
|
||||
unsigned s2neg : 1;
|
||||
unsigned s : 1;
|
||||
unsigned ext : 1;
|
||||
unsigned : 3;
|
||||
} PACKED;
|
||||
|
||||
/* Byte 1 */
|
||||
struct {
|
||||
unsigned s2abs : 1;
|
||||
unsigned s1abs : 1;
|
||||
unsigned s0abs : 1;
|
||||
unsigned : 1;
|
||||
unsigned s0neg : 1;
|
||||
unsigned s1neg : 1;
|
||||
unsigned cin : 1;
|
||||
unsigned : 1;
|
||||
} PACKED;
|
||||
} PACKED rogue_alu_int32_64_encoding;
|
||||
static_assert(sizeof(rogue_alu_int32_64_encoding) == 2,
|
||||
"sizeof(rogue_alu_int32_64_encoding) != 2");
|
||||
|
||||
enum int32_64_op {
|
||||
INT32_64_OP_ADD6432 = 0b00,
|
||||
/* No multiply or extension, only valid when s=0. */
|
||||
INT32_64_OP_ADD64_NMX = 0b01,
|
||||
INT32_64_OP_MADD32 = 0b10,
|
||||
INT32_64_OP_MADD64 = 0b11,
|
||||
};
|
||||
typedef struct rogue_alu_instr_encoding {
|
||||
union {
|
||||
/* Byte 0 */
|
||||
@@ -651,6 +683,7 @@ typedef struct rogue_alu_instr_encoding {
|
||||
rogue_alu_fmad_encoding fmad;
|
||||
rogue_alu_tst_encoding tst;
|
||||
rogue_alu_mov_encoding mov;
|
||||
rogue_alu_int32_64_encoding int32_64;
|
||||
} PACKED;
|
||||
} PACKED rogue_alu_instr_encoding;
|
||||
static_assert(sizeof(rogue_alu_instr_encoding) == 2,
|
||||
|
Reference in New Issue
Block a user