pvr: Add basic support for manual instruction grouping
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
b642e77cdd
commit
c38c119617
@@ -840,6 +840,8 @@ bool rogue_schedule_instr_groups(rogue_shader *shader, bool multi_instr_groups)
|
||||
|
||||
rogue_lower_regs(shader);
|
||||
|
||||
rogue_instr_group *group;
|
||||
bool grouping = false;
|
||||
unsigned g = 0;
|
||||
rogue_foreach_block (block, shader) {
|
||||
struct list_head instr_groups;
|
||||
@@ -865,12 +867,20 @@ bool rogue_schedule_instr_groups(rogue_shader *shader, bool multi_instr_groups)
|
||||
unreachable("Unsupported instruction type.");
|
||||
}
|
||||
|
||||
rogue_instr_group *group = rogue_instr_group_create(block, group_alu);
|
||||
group->index = g++;
|
||||
if (!grouping) {
|
||||
group = rogue_instr_group_create(block, group_alu);
|
||||
group->index = g++;
|
||||
}
|
||||
|
||||
assert(group_alu == group->header.alu);
|
||||
rogue_move_instr_to_group(instr, group);
|
||||
rogue_finalise_instr_group(group);
|
||||
list_addtail(&group->link, &instr_groups);
|
||||
|
||||
grouping = instr->group_next;
|
||||
|
||||
if (!grouping) {
|
||||
rogue_finalise_instr_group(group);
|
||||
list_addtail(&group->link, &instr_groups);
|
||||
}
|
||||
}
|
||||
|
||||
list_replace(&instr_groups, &block->instrs);
|
||||
|
@@ -450,10 +450,17 @@ typedef struct rogue_instr {
|
||||
|
||||
rogue_block *block; /** Basic block containing this instruction. */
|
||||
|
||||
bool group_next; /** Group next instruction with this one. */
|
||||
unsigned index; /** Instruction index. */
|
||||
char *comment; /** Comment string. */
|
||||
} rogue_instr;
|
||||
|
||||
static inline void rogue_set_instr_group_next(rogue_instr *instr,
|
||||
bool group_next)
|
||||
{
|
||||
instr->group_next = group_next;
|
||||
}
|
||||
|
||||
#define rogue_foreach_instr_in_block(instr, block) \
|
||||
list_for_each_entry (rogue_instr, instr, &(block)->instrs, link)
|
||||
|
||||
|
@@ -70,6 +70,52 @@ static unsigned rogue_calc_da(const rogue_instr_group *group)
|
||||
return da;
|
||||
}
|
||||
|
||||
#define P(type) BITFIELD64_BIT(ROGUE_INSTR_PHASE_##type)
|
||||
static enum oporg rogue_calc_oporg(uint64_t alu_phases)
|
||||
{
|
||||
bool P0 = !!(alu_phases & P(0));
|
||||
bool P1 = !!(alu_phases & P(1));
|
||||
bool P2 = !!(alu_phases & (P(2_PCK) | P(2_TST) | P(2_MOV)));
|
||||
bool PBE = !!(alu_phases & P(BACKEND));
|
||||
|
||||
if (P0 && P1 && P2 && PBE)
|
||||
return OPORG_P0_P1_P2_BE;
|
||||
else if (P0 && !P1 && P2 && PBE)
|
||||
return OPORG_P0_P2_BE;
|
||||
else if (P0 && P1 && P2 && !PBE)
|
||||
return OPORG_P0_P1_P2;
|
||||
else if (P0 && !P1 && P2 && !PBE)
|
||||
return OPORG_P0_P2;
|
||||
else if (P0 && P1 && !P2 && !PBE)
|
||||
return OPORG_P0_P1;
|
||||
else if (!P0 && !P1 && !P2 && PBE)
|
||||
return OPORG_BE;
|
||||
else if (!P0 && !P1 && P2 && !PBE)
|
||||
return OPORG_P2;
|
||||
else if (P0 && !P1 && !P2 && !PBE)
|
||||
return OPORG_P0;
|
||||
|
||||
unreachable("Invalid ALU phase combination.");
|
||||
}
|
||||
|
||||
static enum opcnt rogue_calc_opcnt(uint64_t bitwise_phases)
|
||||
{
|
||||
enum opcnt opcnt = 0;
|
||||
|
||||
if (bitwise_phases & P(0_BITMASK) || bitwise_phases & P(0_SHIFT1) ||
|
||||
bitwise_phases & P(0_COUNT)) {
|
||||
opcnt |= OPCNT_P0;
|
||||
}
|
||||
|
||||
if (bitwise_phases & P(1_LOGICAL))
|
||||
opcnt |= OPCNT_P1;
|
||||
|
||||
if (bitwise_phases & P(2_SHIFT2) || bitwise_phases & P(2_TEST))
|
||||
opcnt |= OPCNT_P2;
|
||||
|
||||
return opcnt;
|
||||
}
|
||||
|
||||
static void rogue_encode_instr_group_header(rogue_instr_group *group,
|
||||
struct util_dynarray *binary)
|
||||
{
|
||||
@@ -116,31 +162,12 @@ static void rogue_encode_instr_group_header(rogue_instr_group *group,
|
||||
switch (group->header.alu) {
|
||||
case ROGUE_ALU_MAIN:
|
||||
h.alutype = ALUTYPE_MAIN;
|
||||
/* TODO: Support multiple phase instructions. */
|
||||
#define P(type) BITFIELD64_BIT(ROGUE_INSTR_PHASE_##type)
|
||||
if (group->header.phases & P(0))
|
||||
h.oporg = OPORG_P0;
|
||||
if (group->header.phases & P(2_PCK) || group->header.phases & P(2_TST) ||
|
||||
group->header.phases & P(2_MOV))
|
||||
h.oporg = OPORG_P2;
|
||||
if (group->header.phases & P(BACKEND))
|
||||
h.oporg = OPORG_BE;
|
||||
#undef P
|
||||
h.oporg = rogue_calc_oporg(group->header.phases);
|
||||
break;
|
||||
|
||||
case ROGUE_ALU_BITWISE:
|
||||
h.alutype = ALUTYPE_BITWISE;
|
||||
#define P(type) BITFIELD64_BIT(ROGUE_INSTR_PHASE_##type)
|
||||
if (group->header.phases & P(0_BITMASK) ||
|
||||
group->header.phases & P(0_SHIFT1) ||
|
||||
group->header.phases & P(0_COUNT))
|
||||
h.oporg |= OPCNT_P0;
|
||||
if (group->header.phases & P(1_LOGICAL))
|
||||
h.oporg |= OPCNT_P1;
|
||||
if (group->header.phases & P(2_SHIFT2) ||
|
||||
group->header.phases & P(2_TEST))
|
||||
h.oporg |= OPCNT_P2;
|
||||
#undef P
|
||||
h.opcnt = rogue_calc_opcnt(group->header.phases);
|
||||
break;
|
||||
|
||||
case ROGUE_ALU_CONTROL:
|
||||
@@ -180,13 +207,13 @@ static void rogue_encode_instr_group_header(rogue_instr_group *group,
|
||||
|
||||
if (group->header.alu != ROGUE_ALU_CONTROL) {
|
||||
h.end = group->header.end;
|
||||
/* h.crel = ; */ /* Unused for now */
|
||||
/* h.atom = ; */ /* Unused for now */
|
||||
h.rpt = group->header.repeat - 1;
|
||||
}
|
||||
|
||||
util_dynarray_append_mem(binary, group->size.header, &h);
|
||||
}
|
||||
#undef P
|
||||
|
||||
typedef union rogue_instr_encoding {
|
||||
rogue_alu_instr_encoding alu;
|
||||
|
@@ -574,7 +574,7 @@ const rogue_alu_op_info rogue_alu_op_infos[ROGUE_ALU_OP_COUNT] = {
|
||||
.supported_src_mods = {
|
||||
[0] = SM(ABS) | SM(NEG),
|
||||
},
|
||||
.supported_dst_types = { [0] = T(REG) | T(REGARRAY), },
|
||||
.supported_dst_types = { [0] = T(REG) | T(REGARRAY) | T(IO), },
|
||||
.supported_src_types = {
|
||||
[0] = T(REG),
|
||||
},
|
||||
|
@@ -1346,7 +1346,7 @@ typedef struct rogue_instr_group_header_encoding {
|
||||
unsigned ccext : 1;
|
||||
unsigned rpt : 2;
|
||||
unsigned atom : 1;
|
||||
unsigned crel : 1;
|
||||
unsigned : 1;
|
||||
unsigned alutype : 2;
|
||||
unsigned end : 1;
|
||||
} PACKED;
|
||||
|
@@ -592,7 +592,7 @@ static inline void rogue_print_instr_group(FILE *fp,
|
||||
fputs("{ ", fp);
|
||||
|
||||
CYAN(fp);
|
||||
fprintf(fp, "%s ", rogue_alu_str[group->header.alu]);
|
||||
fprintf(fp, "%s", rogue_alu_str[group->header.alu]);
|
||||
RESET(fp);
|
||||
|
||||
/* Print each instruction. */
|
||||
@@ -600,6 +600,7 @@ static inline void rogue_print_instr_group(FILE *fp,
|
||||
const rogue_instr *instr = group->instrs[p];
|
||||
assert(instr);
|
||||
|
||||
fputs(" ", fp);
|
||||
rogue_print_instr_phase(fp, group->header.alu, p);
|
||||
fputs(": ", fp);
|
||||
rogue_print_instr(fp, instr);
|
||||
|
Reference in New Issue
Block a user