freedreno/afuc: Use SQE registers for call stack

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26691>
This commit is contained in:
Connor Abbott
2023-12-14 17:14:44 +01:00
committed by Marge Bot
parent da3cf26564
commit 579227e028
3 changed files with 19 additions and 10 deletions

View File

@@ -352,6 +352,12 @@ const struct emu_reg_accessor emu_control_accessor = {
.set = emu_set_control_reg,
};
const struct emu_reg_accessor emu_sqe_accessor = {
.get_offset = afuc_sqe_reg,
.get = emu_get_sqe_reg,
.set = emu_set_sqe_reg,
};
const struct emu_reg_accessor emu_pipe_accessor = {
.get_offset = afuc_pipe_reg,
.get = emu_get_pipe_reg,

View File

@@ -42,6 +42,9 @@
#define rotl32(x,r) (((x) << (r)) | ((x) >> (32 - (r))))
#define rotl64(x,r) (((x) << (r)) | ((x) >> (64 - (r))))
EMU_SQE_REG(SP);
EMU_SQE_REG(STACK0);
/**
* AFUC emulator. Currently only supports a6xx
*
@@ -317,20 +320,24 @@ emu_instr(struct emu *emu, struct afuc_instr *instr)
break;
}
case OPC_RET: {
assert(emu->call_stack_idx > 0);
unsigned sp = emu_get_reg32(emu, &SP);
assert(sp > 0);
/* counter-part to 'call' instruction, also has a delay slot: */
emu->branch_target = emu->call_stack[--emu->call_stack_idx];
emu->branch_target = emu_get_sqe_reg(emu, emu_reg_offset(&STACK0) + sp - 1);
emu_set_reg32(emu, &SP, sp - 1);
break;
}
case OPC_CALL: {
assert(emu->call_stack_idx < ARRAY_SIZE(emu->call_stack));
unsigned sp = emu_get_reg32(emu, &SP);
assert(sp + emu_reg_offset(&STACK0) < ARRAY_SIZE(emu->sqe_regs.val));
/* call looks to have same delay-slot behavior as branch/etc, so
* presumably the return PC is two instructions later:
*/
emu->call_stack[emu->call_stack_idx++] = emu->gpr_regs.pc + 2;
emu_set_sqe_reg(emu, emu_reg_offset(&STACK0) + sp, emu->gpr_regs.pc + 2);
emu_set_reg32(emu, &SP, sp + 1);
emu->branch_target = instr->literal;
break;

View File

@@ -198,12 +198,6 @@ struct emu {
*/
uint32_t carry;
/* call-stack of saved PCs.. I expect this to be a fixed size, but not
* sure what the actual size is
*/
uint32_t call_stack[5];
int call_stack_idx;
/* packet table (aka jmptable) has offsets for pm4 packet handlers: */
uint32_t jmptbl[0x80];
@@ -282,10 +276,12 @@ struct emu_reg {
};
extern const struct emu_reg_accessor emu_control_accessor;
extern const struct emu_reg_accessor emu_sqe_accessor;
extern const struct emu_reg_accessor emu_pipe_accessor;
extern const struct emu_reg_accessor emu_gpu_accessor;
#define EMU_CONTROL_REG(name) static struct emu_reg name = { #name, &emu_control_accessor, ~0 }
#define EMU_SQE_REG(name) static struct emu_reg name = { #name, &emu_sqe_accessor, ~0 }
#define EMU_PIPE_REG(name) static struct emu_reg name = { #name, &emu_pipe_accessor, ~0 }
#define EMU_GPU_REG(name) static struct emu_reg name = { #name, &emu_gpu_accessor, ~0 }