flycast/core/hw/sh4/dyna/decoder.h

78 lines
2.0 KiB
C

#pragma once
#include "shil.h"
#include "../sh4_if.h"
#define mkbet(c,s,v) ((c<<3)|(s<<1)|v)
#define BET_GET_CLS(x) (x>>3)
enum BlockEndType
{
BET_CLS_Static=0,
BET_CLS_Dynamic=1,
BET_CLS_COND=2,
BET_SCL_Jump=0,
BET_SCL_Call=1,
BET_SCL_Ret=2,
BET_SCL_Intr=3,
BET_StaticJump=mkbet(BET_CLS_Static,BET_SCL_Jump,0), //BranchBlock is jump target
BET_StaticCall=mkbet(BET_CLS_Static,BET_SCL_Call,0), //BranchBlock is jump target, NextBlock is ret hint
BET_StaticIntr=mkbet(BET_CLS_Static,BET_SCL_Intr,0), //(pending inttr!=0) -> Intr else NextBlock
BET_DynamicJump=mkbet(BET_CLS_Dynamic,BET_SCL_Jump,0), //pc+2 is jump target
BET_DynamicCall=mkbet(BET_CLS_Dynamic,BET_SCL_Call,0), //pc+2 is jump target, NextBlock is ret hint
BET_DynamicRet=mkbet(BET_CLS_Dynamic,BET_SCL_Ret,0), //pr is jump target
BET_DynamicIntr=mkbet(BET_CLS_Dynamic,BET_SCL_Intr,0), //(pending inttr!=0) -> Intr else Dynamic
BET_Cond_0=mkbet(BET_CLS_COND,BET_SCL_Jump,0), //sr.T==0 -> BranchBlock else NextBlock
BET_Cond_1=mkbet(BET_CLS_COND,BET_SCL_Jump,1), //sr.T==1 -> BranchBlock else NextBlock
};
enum NextDecoderOperation
{
NDO_NextOp, //pc+=2
NDO_End, //End the block, Type = BlockEndType
NDO_Delayslot, //pc+=2, NextOp=DelayOp
NDO_Jump, //pc=JumpAddr,NextOp=JumpOp
};
//ngen features
struct ngen_features
{
bool OnlyDynamicEnds; //if set the block endings aren't handled natively and only Dynamic block end type is used
bool InterpreterFallback; //if set all the non-branch opcodes are handled with the ifb opcode
};
struct RuntimeBlockInfo;
bool dec_DecodeBlock(RuntimeBlockInfo* rbi,u32 max_cycles);
struct state_t
{
NextDecoderOperation NextOp;
NextDecoderOperation DelayOp;
NextDecoderOperation JumpOp;
u32 JumpAddr;
u32 NextAddr;
BlockEndType BlockType;
struct
{
bool FPR64; //64 bit FPU opcodes
bool FSZ64; //64 bit FPU moves
bool RoundToZero; //false -> Round to nearest.
u32 rpc;
bool is_delayslot;
} cpu;
ngen_features ngen;
struct
{
bool has_readm;
bool has_writem;
bool has_fpu;
} info;
} ;