aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2020-06-12 14:56:42 -0700
committerMarge Bot <[email protected]>2020-06-16 20:56:15 +0000
commit5f1f8f7b172166c95b51473e3af3d72777c21dfc (patch)
tree7c1f55afd72abe068a5652df5db62584d7ba5024 /src
parent92d6eb4dd539f48355ebfe5408f6a18c5a4c3efd (diff)
freedreno/ir3: delay test support for vectorish instructions
Signed-off-by: Rob Clark <[email protected]> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/5280>
Diffstat (limited to 'src')
-rw-r--r--src/freedreno/ir3/meson.build2
-rw-r--r--src/freedreno/ir3/tests/delay.c71
2 files changed, 68 insertions, 5 deletions
diff --git a/src/freedreno/ir3/meson.build b/src/freedreno/ir3/meson.build
index 39531e99827..846eccfc443 100644
--- a/src/freedreno/ir3/meson.build
+++ b/src/freedreno/ir3/meson.build
@@ -125,7 +125,7 @@ test('ir3_disasm',
test('ir3_delay_test',
executable(
'ir3_delay_test',
- 'tests/delay.c',
+ ['tests/delay.c', ir3_parser],
link_with: libfreedreno_ir3,
dependencies: [idep_mesautil, idep_nir_headers],
include_directories: [inc_freedreno, inc_include, inc_src, inc_mesa, inc_gallium],
diff --git a/src/freedreno/ir3/tests/delay.c b/src/freedreno/ir3/tests/delay.c
index 562bdf474d6..0bfdceabab8 100644
--- a/src/freedreno/ir3/tests/delay.c
+++ b/src/freedreno/ir3/tests/delay.c
@@ -57,6 +57,32 @@ static const struct test {
mov.f32f32 r0.z, c0.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 *
@@ -104,7 +130,7 @@ regs_to_ssa(struct ir3 *ir)
struct ir3_block *block =
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) {
if (reg->flags & (IR3_REG_CONST | IR3_REG_IMMED))
continue;
@@ -114,11 +140,42 @@ regs_to_ssa(struct ir3 *ir)
if (!src)
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->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 =
list_first_entry(&ir->block_list, struct ir3_block, node);
- struct ir3_instruction *last =
- list_last_entry(&block->instr_list, struct ir3_instruction, node);
+ struct ir3_instruction *last = NULL;
+
+ 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
* block, so remove it from the block so that it doesn't get counted