freedreno/ir3: delay test support for vectorish instructions
Signed-off-by: Rob Clark <robdclark@chromium.org> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5280>
This commit is contained in:
@@ -125,7 +125,7 @@ test('ir3_disasm',
|
|||||||
test('ir3_delay_test',
|
test('ir3_delay_test',
|
||||||
executable(
|
executable(
|
||||||
'ir3_delay_test',
|
'ir3_delay_test',
|
||||||
'tests/delay.c',
|
['tests/delay.c', ir3_parser],
|
||||||
link_with: libfreedreno_ir3,
|
link_with: libfreedreno_ir3,
|
||||||
dependencies: [idep_mesautil, idep_nir_headers],
|
dependencies: [idep_mesautil, idep_nir_headers],
|
||||||
include_directories: [inc_freedreno, inc_include, inc_src, inc_mesa, inc_gallium],
|
include_directories: [inc_freedreno, inc_include, inc_src, inc_mesa, inc_gallium],
|
||||||
|
@@ -57,6 +57,32 @@ static const struct test {
|
|||||||
mov.f32f32 r0.z, c0.z
|
mov.f32f32 r0.z, c0.z
|
||||||
mad.f32 r0.x, r0.x, r0.y, r0.z
|
mad.f32 r0.x, r0.x, r0.y, r0.z
|
||||||
),
|
),
|
||||||
|
TEST(2,
|
||||||
|
mov.f32f32 r0.x, c0.x
|
||||||
|
mov.f32f32 r0.y, c0.y
|
||||||
|
(rpt1)add.f r0.x, (r)r0.x, (r)c0.x
|
||||||
|
),
|
||||||
|
TEST(2,
|
||||||
|
(rpt1)mov.f32f32 r0.x, c0.x
|
||||||
|
(rpt1)add.f r0.x, (r)r0.x, (r)c0.x
|
||||||
|
),
|
||||||
|
TEST(3,
|
||||||
|
mov.f32f32 r0.y, c0.y
|
||||||
|
mov.f32f32 r0.x, c0.x
|
||||||
|
(rpt1)add.f r0.x, (r)r0.x, (r)c0.x
|
||||||
|
),
|
||||||
|
TEST(1,
|
||||||
|
(rpt2)mov.f32f32 r0.x, (r)c0.x
|
||||||
|
add.f r0.x, r0.x, c0.x
|
||||||
|
),
|
||||||
|
TEST(2,
|
||||||
|
(rpt2)mov.f32f32 r0.x, (r)c0.x
|
||||||
|
add.f r0.x, r0.x, r0.y
|
||||||
|
),
|
||||||
|
TEST(1,
|
||||||
|
(rpt2)mov.f32f32 r0.x, (r)c0.x
|
||||||
|
(rpt2)add.f r0.x, (r)r0.x, c0.x
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct ir3 *
|
static struct ir3 *
|
||||||
@@ -104,7 +130,7 @@ regs_to_ssa(struct ir3 *ir)
|
|||||||
struct ir3_block *block =
|
struct ir3_block *block =
|
||||||
list_first_entry(&ir->block_list, struct ir3_block, node);
|
list_first_entry(&ir->block_list, struct ir3_block, node);
|
||||||
|
|
||||||
foreach_instr (instr, &block->instr_list) {
|
foreach_instr_safe (instr, &block->instr_list) {
|
||||||
foreach_src (reg, instr) {
|
foreach_src (reg, instr) {
|
||||||
if (reg->flags & (IR3_REG_CONST | IR3_REG_IMMED))
|
if (reg->flags & (IR3_REG_CONST | IR3_REG_IMMED))
|
||||||
continue;
|
continue;
|
||||||
@@ -114,11 +140,42 @@ regs_to_ssa(struct ir3 *ir)
|
|||||||
if (!src)
|
if (!src)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (reg->flags & IR3_REG_R) {
|
||||||
|
unsigned nsrc = 1 + instr->repeat;
|
||||||
|
unsigned flags = src->regs[0]->flags & IR3_REG_HALF;
|
||||||
|
struct ir3_instruction *collect =
|
||||||
|
ir3_instr_create2(block, OPC_META_COLLECT, 1 + nsrc);
|
||||||
|
__ssa_dst(collect)->flags |= flags;
|
||||||
|
for (unsigned i = 0; i < nsrc; i++)
|
||||||
|
__ssa_src(collect, regfile[regn(reg) + i], flags);
|
||||||
|
|
||||||
|
ir3_instr_move_before(collect, instr);
|
||||||
|
|
||||||
|
src = collect;
|
||||||
|
}
|
||||||
|
|
||||||
reg->instr = src;
|
reg->instr = src;
|
||||||
reg->flags |= IR3_REG_SSA;
|
reg->flags |= IR3_REG_SSA;
|
||||||
}
|
}
|
||||||
|
|
||||||
regfile[regn(instr->regs[0])] = instr;
|
if (instr->repeat) {
|
||||||
|
unsigned ndst = 1 + instr->repeat;
|
||||||
|
unsigned flags = instr->regs[0]->flags & IR3_REG_HALF;
|
||||||
|
|
||||||
|
for (unsigned i = 0; i < ndst; i++) {
|
||||||
|
struct ir3_instruction *split =
|
||||||
|
ir3_instr_create(block, OPC_META_SPLIT);
|
||||||
|
__ssa_dst(split)->flags |= flags;
|
||||||
|
__ssa_src(split, instr, flags);
|
||||||
|
split->split.off = i;
|
||||||
|
|
||||||
|
ir3_instr_move_after(split, instr);
|
||||||
|
|
||||||
|
regfile[regn(instr->regs[0]) + i] = split;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
regfile[regn(instr->regs[0])] = instr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,8 +200,14 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
struct ir3_block *block =
|
struct ir3_block *block =
|
||||||
list_first_entry(&ir->block_list, struct ir3_block, node);
|
list_first_entry(&ir->block_list, struct ir3_block, node);
|
||||||
struct ir3_instruction *last =
|
struct ir3_instruction *last = NULL;
|
||||||
list_last_entry(&block->instr_list, struct ir3_instruction, node);
|
|
||||||
|
foreach_instr_rev (instr, &block->instr_list) {
|
||||||
|
if (is_meta(instr))
|
||||||
|
continue;
|
||||||
|
last = instr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* The delay calc is expecting the instr to not yet be added to the
|
/* The delay calc is expecting the instr to not yet be added to the
|
||||||
* block, so remove it from the block so that it doesn't get counted
|
* block, so remove it from the block so that it doesn't get counted
|
||||||
|
Reference in New Issue
Block a user