sh4: move Sh4RegType & GetRegPtr into sh4/dyna

rec-arm: use getRegOffset/reg_nofs instead of GetRegPtr
This commit is contained in:
Flyinghead 2024-11-06 20:46:32 +01:00
parent 897e06b887
commit 7eec648690
5 changed files with 189 additions and 247 deletions

View File

@ -5,22 +5,6 @@
#include "hw/sh4/sh4_mmr.h"
#include "ngen.h"
#include "hw/sh4/sh4_core.h"
#define SHIL_MODE 1
#include "shil_canonical.h"
#define SHIL_MODE 4
#include "shil_canonical.h"
//#define SHIL_MODE 2
//#include "shil_canonical.h"
#if FEAT_SHREC != DYNAREC_NONE
#define SHIL_MODE 3
#include "shil_canonical.h"
#endif
#include "ssa.h"
void AnalyseBlock(RuntimeBlockInfo* blk)
@ -29,6 +13,48 @@ void AnalyseBlock(RuntimeBlockInfo* blk)
optim.Optimize();
}
u32 getRegOffset(Sh4RegType reg)
{
if (reg >= reg_r0 && reg <= reg_r15)
return offsetof(Sh4Context, r[reg - reg_r0]);
if (reg >= reg_r0_Bank && reg <= reg_r7_Bank)
return offsetof(Sh4Context, r_bank[reg - reg_r0_Bank]);
if (reg >= reg_fr_0 && reg <= reg_fr_15)
return offsetof(Sh4Context, xffr[reg - reg_fr_0 + 16]);
if (reg >= reg_xf_0 && reg <= reg_xf_15)
return offsetof(Sh4Context, xffr[reg - reg_xf_0]);
switch (reg)
{
case reg_gbr: return offsetof(Sh4Context, gbr);
case reg_vbr: return offsetof(Sh4Context, vbr);
case reg_ssr: return offsetof(Sh4Context, ssr);
case reg_spc: return offsetof(Sh4Context, spc);
case reg_sgr: return offsetof(Sh4Context, sgr);
case reg_dbr: return offsetof(Sh4Context, dbr);
case reg_mach: return offsetof(Sh4Context, mac.h);
case reg_macl: return offsetof(Sh4Context, mac.l);
case reg_pr: return offsetof(Sh4Context, pr);
case reg_fpul: return offsetof(Sh4Context, fpul);
case reg_nextpc: return offsetof(Sh4Context, pc);
case reg_sr_status: return offsetof(Sh4Context, sr.status);
case reg_sr_T: return offsetof(Sh4Context, sr.T);
case reg_old_fpscr: return offsetof(Sh4Context, old_fpscr.full);
case reg_fpscr: return offsetof(Sh4Context, fpscr.full);
case reg_pc_dyn: return offsetof(Sh4Context, jdyn);
case reg_temp: return offsetof(Sh4Context, temp_reg);
// TODO case reg_sq_buffer: return offsetof(Sh4Context, sq_buffer);
default:
ERROR_LOG(SH4, "Unknown register ID %d", reg);
die("Invalid reg");
return 0;
}
}
u32* GetRegPtr(u32 reg)
{
return (u32 *)((u8 *)&p_sh4rcb->cntx + getRegOffset((Sh4RegType)reg));
}
std::string name_reg(Sh4RegType reg)
{
std::stringstream ss;
@ -119,6 +145,22 @@ static std::string dissasm_param(const shil_param& prm, bool comma)
return ss.str();
}
#include "hw/sh4/sh4_core.h"
#define SHIL_MODE 1
#include "shil_canonical.h"
#define SHIL_MODE 4
#include "shil_canonical.h"
//#define SHIL_MODE 2
//#include "shil_canonical.h"
#if FEAT_SHREC != DYNAREC_NONE
#define SHIL_MODE 3
#include "shil_canonical.h"
#endif
std::string shil_opcode::dissasm() const
{
std::stringstream ss;

View File

@ -5,6 +5,131 @@ struct shil_opcode;
typedef void shil_chfp(shil_opcode* op);
extern shil_chfp* shil_chf[];
enum Sh4RegType
{
//GPRs
reg_r0,
reg_r1,
reg_r2,
reg_r3,
reg_r4,
reg_r5,
reg_r6,
reg_r7,
reg_r8,
reg_r9,
reg_r10,
reg_r11,
reg_r12,
reg_r13,
reg_r14,
reg_r15,
//FPU, bank 0
reg_fr_0,
reg_fr_1,
reg_fr_2,
reg_fr_3,
reg_fr_4,
reg_fr_5,
reg_fr_6,
reg_fr_7,
reg_fr_8,
reg_fr_9,
reg_fr_10,
reg_fr_11,
reg_fr_12,
reg_fr_13,
reg_fr_14,
reg_fr_15,
//FPU, bank 1
reg_xf_0,
reg_xf_1,
reg_xf_2,
reg_xf_3,
reg_xf_4,
reg_xf_5,
reg_xf_6,
reg_xf_7,
reg_xf_8,
reg_xf_9,
reg_xf_10,
reg_xf_11,
reg_xf_12,
reg_xf_13,
reg_xf_14,
reg_xf_15,
//GPR Interrupt bank
reg_r0_Bank,
reg_r1_Bank,
reg_r2_Bank,
reg_r3_Bank,
reg_r4_Bank,
reg_r5_Bank,
reg_r6_Bank,
reg_r7_Bank,
//Misc regs
reg_gbr,
reg_ssr,
reg_spc,
reg_sgr,
reg_dbr,
reg_vbr,
reg_mach,
reg_macl,
reg_pr,
reg_fpul,
reg_nextpc,
reg_sr_status, //Only the status bits
reg_sr_T, //Only T
reg_old_fpscr,
reg_fpscr,
reg_pc_dyn, //Write only, for dynarec only (dynamic block exit address)
reg_temp,
sh4_reg_count,
/*
These are virtual registers, used by the dynarec decoder
*/
regv_dr_0,
regv_dr_2,
regv_dr_4,
regv_dr_6,
regv_dr_8,
regv_dr_10,
regv_dr_12,
regv_dr_14,
regv_xd_0,
regv_xd_2,
regv_xd_4,
regv_xd_6,
regv_xd_8,
regv_xd_10,
regv_xd_12,
regv_xd_14,
regv_fv_0,
regv_fv_4,
regv_fv_8,
regv_fv_12,
regv_xmtrx,
regv_fmtrx,
//reg_sq_buffer,
NoReg=-1
};
u32 getRegOffset(Sh4RegType reg);
u32* GetRegPtr(u32 reg);
enum shil_param_type
{
FMT_NULL,
@ -27,7 +152,6 @@ enum shil_param_type
param types: r32, r64
*/
#define SHIL_MODE 0
#include "shil_canonical.h"
@ -108,7 +232,7 @@ struct shil_param
bool is_imm_s8() const { return is_imm() && (int8_t)_imm == (int32_t)_imm; }
u32* reg_ptr() const { verify(is_reg()); return GetRegPtr(_reg); }
s32 reg_nofs() const { verify(is_reg()); return (s32)((u8*)GetRegPtr(_reg) - (u8*)GetRegPtr(reg_xf_0)-sizeof(Sh4cntx)); }
s32 reg_nofs() const { verify(is_reg()); return (int)getRegOffset(_reg) - sizeof(Sh4Context); }
u32 reg_aofs() const { return -reg_nofs(); }
u32 imm_value() const { verify(is_imm()); return _imm; }

View File

@ -161,105 +161,3 @@ void setDefaultRoundingMode()
fpscr.RM = savedRM;
fpscr.DN = savedDN;
}
static u32* Sh4_int_GetRegisterPtr(Sh4RegType reg)
{
if ((reg>=reg_r0) && (reg<=reg_r15))
{
return &r[reg-reg_r0];
}
else if ((reg>=reg_r0_Bank) && (reg<=reg_r7_Bank))
{
return &r_bank[reg-reg_r0_Bank];
}
else if ((reg>=reg_fr_0) && (reg<=reg_fr_15))
{
return &fr_hex[reg-reg_fr_0];
}
else if ((reg>=reg_xf_0) && (reg<=reg_xf_15))
{
return &xf_hex[reg-reg_xf_0];
}
else
{
switch(reg)
{
case reg_gbr :
return &gbr;
break;
case reg_vbr :
return &vbr;
break;
case reg_ssr :
return &ssr;
break;
case reg_spc :
return &spc;
break;
case reg_sgr :
return &sgr;
break;
case reg_dbr :
return &dbr;
break;
case reg_mach :
return &mac.h;
break;
case reg_macl :
return &mac.l;
break;
case reg_pr :
return &pr;
break;
case reg_fpul :
return &fpul;
break;
case reg_nextpc :
return &next_pc;
break;
case reg_sr_status :
return &sr.status;
break;
case reg_sr_T :
return &sr.T;
break;
case reg_old_fpscr :
return &old_fpscr.full;
break;
case reg_fpscr :
return &fpscr.full;
break;
case reg_pc_dyn:
return &Sh4cntx.jdyn;
case reg_temp:
return &Sh4cntx.temp_reg;
default:
ERROR_LOG(SH4, "Unknown register ID %d", reg);
die("Invalid reg");
return 0;
break;
}
}
}
u32* GetRegPtr(u32 reg)
{
return Sh4_int_GetRegisterPtr((Sh4RegType)reg);
}

View File

@ -3,126 +3,6 @@
#include "stdclass.h"
#include <cassert>
enum Sh4RegType
{
//GPRs
reg_r0,
reg_r1,
reg_r2,
reg_r3,
reg_r4,
reg_r5,
reg_r6,
reg_r7,
reg_r8,
reg_r9,
reg_r10,
reg_r11,
reg_r12,
reg_r13,
reg_r14,
reg_r15,
//FPU, bank 0
reg_fr_0,
reg_fr_1,
reg_fr_2,
reg_fr_3,
reg_fr_4,
reg_fr_5,
reg_fr_6,
reg_fr_7,
reg_fr_8,
reg_fr_9,
reg_fr_10,
reg_fr_11,
reg_fr_12,
reg_fr_13,
reg_fr_14,
reg_fr_15,
//FPU, bank 1
reg_xf_0,
reg_xf_1,
reg_xf_2,
reg_xf_3,
reg_xf_4,
reg_xf_5,
reg_xf_6,
reg_xf_7,
reg_xf_8,
reg_xf_9,
reg_xf_10,
reg_xf_11,
reg_xf_12,
reg_xf_13,
reg_xf_14,
reg_xf_15,
//GPR Interrupt bank
reg_r0_Bank,
reg_r1_Bank,
reg_r2_Bank,
reg_r3_Bank,
reg_r4_Bank,
reg_r5_Bank,
reg_r6_Bank,
reg_r7_Bank,
//Misc regs
reg_gbr,
reg_ssr,
reg_spc,
reg_sgr,
reg_dbr,
reg_vbr,
reg_mach,
reg_macl,
reg_pr,
reg_fpul,
reg_nextpc,
reg_sr_status, //Only the status bits
reg_sr_T, //Only T
reg_old_fpscr,
reg_fpscr,
reg_pc_dyn, //Write only, for dynarec only (dynamic block exit address)
reg_temp,
sh4_reg_count,
/*
These are virtual registers, used by the dynarec decoder
*/
regv_dr_0,
regv_dr_2,
regv_dr_4,
regv_dr_6,
regv_dr_8,
regv_dr_10,
regv_dr_12,
regv_dr_14,
regv_xd_0,
regv_xd_2,
regv_xd_4,
regv_xd_6,
regv_xd_8,
regv_xd_10,
regv_xd_12,
regv_xd_14,
regv_fv_0,
regv_fv_4,
regv_fv_8,
regv_fv_12,
regv_xmtrx,
regv_fmtrx,
NoReg=-1
};
// SR (status register)
union sr_status_t
@ -366,8 +246,6 @@ extern Sh4RCB* p_sh4rcb;
void Get_Sh4Interpreter(sh4_if* cpu);
void Get_Sh4Recompiler(sh4_if* cpu);
u32* GetRegPtr(u32 reg);
enum Sh4ExceptionCode : u16
{
Sh4Ex_PowerOnReset = 0,

View File

@ -170,14 +170,14 @@ public:
void loadSh4Reg(Register Rt, u32 Sh4_Reg)
{
const int shRegOffs = (u8*)GetRegPtr(Sh4_Reg) - (u8*)&p_sh4rcb->cntx - sizeof(Sh4cntx);
const int shRegOffs = getRegOffset((Sh4RegType)Sh4_Reg) - sizeof(Sh4Context);
Ldr(Rt, MemOperand(r8, shRegOffs));
}
void storeSh4Reg(Register Rt, u32 Sh4_Reg)
{
const int shRegOffs = (u8*)GetRegPtr(Sh4_Reg) - (u8*)&p_sh4rcb->cntx - sizeof(Sh4cntx);
const int shRegOffs = getRegOffset((Sh4RegType)Sh4_Reg) - sizeof(Sh4Context);
Str(Rt, MemOperand(r8, shRegOffs));
}
@ -393,13 +393,13 @@ void arm_reg_alloc::Writeback(u32 reg, int nreg)
void arm_reg_alloc::Preload_FPU(u32 reg, int nreg)
{
const s32 shRegOffs = (u8*)GetRegPtr(reg) - (u8*)&p_sh4rcb->cntx - sizeof(Sh4cntx);
const s32 shRegOffs = getRegOffset((Sh4RegType)reg) - sizeof(Sh4Context);
ass.Vldr(SRegister(nreg), MemOperand(r8, shRegOffs));
}
void arm_reg_alloc::Writeback_FPU(u32 reg, int nreg)
{
const s32 shRegOffs = (u8*)GetRegPtr(reg) - (u8*)&p_sh4rcb->cntx - sizeof(Sh4cntx);
const s32 shRegOffs = getRegOffset((Sh4RegType)reg) - sizeof(Sh4Context);
ass.Vstr(SRegister(nreg), MemOperand(r8, shRegOffs));
}
@ -649,7 +649,7 @@ void Arm32Assembler::canonCall(const shil_opcode *op, void *function)
if (ccParam.type == CPT_ptr && prm.count() == 2 && reg.IsAllocf(prm) && (op->rd._reg == prm._reg || op->rd2._reg == prm._reg))
{
// fsca rd param is a pointer to a 64-bit reg so reload the regs if allocated
const int shRegOffs = (u8*)GetRegPtr(prm._reg) - (u8*)&p_sh4rcb->cntx - sizeof(Sh4cntx);
const int shRegOffs = prm.reg_nofs();
Vldr(reg.mapFReg(prm, 0), MemOperand(r8, shRegOffs));
Vldr(reg.mapFReg(prm, 1), MemOperand(r8, shRegOffs + 4));
}