nulldc-360/nullDC/dc/sh4/sh4_if.h

332 lines
No EOL
5.9 KiB
C

#pragma once
#include "types.h"
#include "intc_types.h"
#define xstr(s) str(s)
#define str(s) #s
#include "../../emitter/emitter.h"
//sh4 exeption saved stack pointer :)
extern u32* sh4_exept_ssp;
//sh4 next opcode execute
extern u32* sh4_exept_next;
//sh4 exeption raised bool , set to true when an exeption was raised , and its not handled
extern bool sh4_exept_raised;
enum Sh4RegType
{
//GPR , bank 0
r0=0,
r1=1,
r2=2,
r3=3,
r4=4,
r5=5,
r6=6,
r7=7,
r8=8,
r9=9,
r10=10,
r11=11,
r12=12,
r13=13,
r14=14,
r15=15,
//GPR , bank 1
r0_Bank=16,
r1_Bank=17,
r2_Bank=18,
r3_Bank=19,
r4_Bank=20,
r5_Bank=21,
r6_Bank=22,
r7_Bank=23,
//Misc regs
reg_gbr=24,
reg_ssr=25,
reg_spc=26,
reg_sgr=27,
reg_dbr=28,
reg_vbr=29,
reg_mach=30,
reg_macl=31,
reg_pr=32,
reg_fpul=33,
reg_pc=34,
reg_sr=35,
reg_fpscr=36,
//FPU gpr , bank 0
fr_0=37,
fr_1=fr_0+1,
fr_2=fr_0+2,
fr_3=fr_0+3,
fr_4=fr_0+4,
fr_5=fr_0+5,
fr_6=fr_0+6,
fr_7=fr_0+7,
fr_8=fr_0+8,
fr_9=fr_0+9,
fr_10=fr_0+10,
fr_11=fr_0+11,
fr_12=fr_0+12,
fr_13=fr_0+13,
fr_14=fr_0+14,
fr_15=fr_0+15,
//FPU gpr , bank 1
xf_0=fr_15+1,
xf_1=xf_0+1,
xf_2=xf_0+2,
xf_3=xf_0+3,
xf_4=xf_0+4,
xf_5=xf_0+5,
xf_6=xf_0+6,
xf_7=xf_0+7,
xf_8=xf_0+8,
xf_9=xf_0+9,
xf_10=xf_0+10,
xf_11=xf_0+11,
xf_12=xf_0+12,
xf_13=xf_0+13,
xf_14=xf_0+14,
xf_15=xf_0+15,
//special regs , used _only_ on rec
reg_ftrv=xf_15+1,
reg_xmtrx=reg_ftrv+1,
//sr_T=xmtrx+1,
//sr_Q=sr_T+1,
//sr_S=sr_Q+1,
//sr_M=sr_S+1,
dr_0=reg_xmtrx+1,
dr_7=dr_0+7,
xd_0=dr_7+1,
xd_7=xd_0+7,
reg_pc_temp=xd_7+1,
reg_sr_T=reg_pc_temp+1,
sh4_reg_count,
NoReg=-1
};
extern u8 GetSingleFromDouble(u8 dbl);
#define STATUS_MASK 0x700083F2
struct __attribute__((packed)) StatusReg
{//
union
{
#ifndef XENON
struct
{
u32 T_h :1;//<<0
u32 S :1;//<<1
u32 rsvd0 :2;//<<2
u32 IMASK :4;//<<4
u32 Q :1;//<<8
u32 M :1;//<<9
u32 rsvd1 :5;//<<10
u32 FD :1;//<<15
u32 rsvd2 :12;//<<16
u32 BL :1;//<<28
u32 RB :1;//<<29
u32 MD :1;//<<20
u32 rsvd3 :1;//<<31
};
#else
struct
{
u32 rsvd3 :1;//<<31
u32 MD :1;//<<20
u32 RB :1;//<<29
u32 BL :1;//<<28
u32 rsvd2 :12;//<<16
u32 FD :1;//<<15
u32 rsvd1 :5;//<<10
u32 M :1;//<<9
u32 Q :1;//<<8
u32 IMASK :4;//<<4
u32 rsvd0 :2;//<<2
u32 S :1;//<<1
u32 T_h :1;//<<0
};
#endif
u32 m_full;
};
u32 T_;
INLINE u32 GetT()
{
GetFull(true);
return T_;
}
INLINE void SetT(u32 t)
{
SetFull((GetFull(true)&~1) | (t&1),true);
}
INLINE u32 GetFull(bool autoDR)
{
if (autoDR && settings.dynarec.Enable)
{
//gli interpeter T needs to be up to date
u32 Tloc=0;
asm volatile (
"li %[Tloc],0 \n"
"bc 4," xstr(CR_T_FLAG) ",1f \n"
"li %[Tloc],1 \n"
"1: \n"
:[Tloc] "+r" (Tloc)
);
T_=Tloc;
}
return (m_full&STATUS_MASK) | (T_&1);
}
INLINE void SetFull(u32 value,bool autoDR)
{
m_full=value & STATUS_MASK;
T_=value&1;
if (autoDR && settings.dynarec.Enable)
{
//gli dynarec T needs to be up to date
u32 Tloc=T_;
asm volatile (
"cmplwi %[Tloc],0 \n"
"crnor " xstr(CR_T_FLAG) ",2,2 \n"
::[Tloc] "r" (Tloc)
);
}
}
};
struct __attribute__((packed)) fpscr_type
{
union
{
u32 full;
#ifndef XENON
struct
{
u32 RM:2;
u32 finexact:1;
u32 funderflow:1;
u32 foverflow:1;
u32 fdivbyzero:1;
u32 finvalidop:1;
u32 einexact:1;
u32 eunderflow:1;
u32 eoverflow:1;
u32 edivbyzero:1;
u32 einvalidop:1;
u32 cinexact:1;
u32 cunderflow:1;
u32 coverflow:1;
u32 cdivbyzero:1;
u32 cinvalid:1;
u32 cfpuerr:1;
u32 DN:1;
u32 PR:1;
u32 SZ:1;
u32 FR:1;
u32 rsvd:10;
};
struct
{
u32 nil:2+1+1+1+1+4+8+1;
u32 PR_SZ:2;
u32 nil2:11;
};
#else
struct
{
u32 rsvd:10;
u32 FR:1;
u32 SZ:1;
u32 PR:1;
u32 DN:1;
u32 cfpuerr:1;
u32 cinvalid:1;
u32 cdivbyzero:1;
u32 coverflow:1;
u32 cunderflow:1;
u32 cinexact:1;
u32 einvalidop:1;
u32 edivbyzero:1;
u32 eoverflow:1;
u32 eunderflow:1;
u32 einexact:1;
u32 finvalidop:1;
u32 fdivbyzero:1;
u32 foverflow:1;
u32 funderflow:1;
u32 finexact:1;
u32 RM:2;
};
struct
{
u32 nil2:11;
u32 PR_SZ:2;
u32 nil:2+1+1+1+1+4+8+1;
};
#endif
};
};
typedef void RunFP();
typedef void StopFP();
typedef void StepFP();
typedef void SkipFP();
typedef void ResetFP(bool Manual);
typedef void InitFP();
typedef void TermFP();
typedef bool IsCpuRunningFP();
typedef u32 GetRegisterFP(Sh4RegType reg);
typedef void SetRegisterFP(Sh4RegType reg,u32 value);
typedef cResetEvent* GetArmResetEventFP();
typedef void __fastcall sh4_int_RaiseExeptionFP(u32 ExeptionCode,u32 VectorAddress);
//sh4 interface
struct sh4_if
{
RunFP* Run;
StopFP* Stop;
StepFP* Step;
SkipFP* Skip;
ResetFP* Reset;
InitFP* Init;
TermFP* Term;
TermFP* ResetCache;
IsCpuRunningFP* IsCpuRunning;
GetRegisterFP* GetRegister;
SetRegisterFP* SetRegister;
//Sh4RaiseInterruptFP* RaiseInterrupt;
sh4_int_RaiseExeptionFP* RaiseExeption;
};
//Get an interface to sh4 interpreter
sh4_if* Get_Sh4Interpreter();
//Get an interface to sh4 dynarec
sh4_if* Get_Sh4Recompiler();
//free it
void Release_Sh4If(sh4_if* cpu);
void DissasembleOpcode(u16 opcode,u32 pc,char* Dissasm);
#define BPT_OPCODE 0x8A00
bool IsReg64(Sh4RegType reg);