agx_foreach_instr_global_safe(ctx, ins) {
/* Lower away RA pseudo-instructions */
+ agx_builder b = agx_init_builder(ctx, agx_after_instr(ins));
+
if (ins->op == AGX_OPCODE_P_COMBINE) {
unsigned base = agx_index_to_reg(ssa_to_reg, ins->dest[0]);
unsigned width = agx_size_align_16(ins->dest[0].size);
};
}
- /* Lower away the copies pseudo-instruction */
- agx_builder b = agx_init_builder(ctx, agx_after_instr(ins));
agx_emit_parallel_copies(&b, copies, n);
+ agx_remove_instruction(ins);
continue;
} else if (ins->op == AGX_OPCODE_P_EXTRACT) {
/* Uses the destination size */
unsigned right = agx_index_to_reg(ssa_to_reg, ins->src[0]) + (size * ins->imm);
if (left != right) {
- agx_builder b = agx_init_builder(ctx, agx_after_instr(ins));
agx_mov_to(&b, agx_register(left, ins->dest[0].size),
agx_register(right, ins->src[0].size));
}
agx_remove_instruction(ins);
continue;
+ } else if (ins->op == AGX_OPCODE_P_SPLIT) {
+ unsigned base = agx_index_to_reg(ssa_to_reg, ins->src[0]);
+ unsigned width = agx_size_align_16(ins->src[0].size);
+
+ struct agx_copy copies[4];
+ unsigned n = 0;
+
+ /* Move the sources */
+ for (unsigned i = 0; i < 4; ++i) {
+ if (agx_is_null(ins->dest[i])) continue;
+ assert(ins->dest[i].size == ins->src[0].size);
+
+ copies[n++] = (struct agx_copy) {
+ .dest = agx_index_to_reg(ssa_to_reg, ins->dest[i]),
+ .src = base + (i * width),
+ .size = ins->dest[i].size
+ };
+ }
+
+ /* Lower away */
+ agx_builder b = agx_init_builder(ctx, agx_after_instr(ins));
+ agx_emit_parallel_copies(&b, copies, n);
+ agx_remove_instruction(ins);
+ continue;
}
agx_foreach_src(ins, s) {