freedreno/afuc: Use SQE registers for call stack
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26691>
This commit is contained in:
@@ -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,
|
||||
|
@@ -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;
|
||||
|
@@ -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 }
|
||||
|
||||
|
Reference in New Issue
Block a user