127 lines
3.3 KiB
C
127 lines
3.3 KiB
C
/*
|
|
Header file for native generator interface
|
|
Needs some cleanup
|
|
|
|
|
|
SH4 -> Code gen -> Ram
|
|
|
|
Ram -> link/relocate -> Staging buffer
|
|
Ram -> link/relocate -> Steady-state buffer
|
|
|
|
Staging : scratch, relatively small, circular code buffer
|
|
Steady state : 'final' code buffer. When blocks reach a steady-state, they get copied here
|
|
|
|
When the Staging buffer is full, a reset is done on the dynarec.
|
|
If the stating buffer is full, but re-locating everything will free enough space, it will be relocated (GC'd)
|
|
|
|
If the stating buffer is full, then blocks in it are put into "hibernation"
|
|
|
|
Block can be
|
|
in Ram, only ('hibernated')
|
|
in Ram + steady state buffer
|
|
in Ram + staging buffer
|
|
|
|
Changes required on the ngen/dynarecs for this to work
|
|
|
|
- Support relocation
|
|
- Support re-linking
|
|
- Support hibernated blocks, or block removal
|
|
|
|
Changes on BM
|
|
|
|
- Block graph
|
|
- Block removal
|
|
- Relocation driving logic
|
|
|
|
|
|
This will enable
|
|
|
|
- Extensive block specialisation (Further mem opts, other things that might gain)
|
|
- Possibility of superblock chains
|
|
*/
|
|
|
|
#pragma once
|
|
#include "rec_config.h"
|
|
#include "decoder.h"
|
|
#include "blockmanager.h"
|
|
|
|
|
|
#define CODE_SIZE (4*1024*1024)
|
|
|
|
|
|
//alternative emit ptr, set to 0 to use the main buffer
|
|
extern u32* emit_ptr;
|
|
extern u8* CodeCache;
|
|
|
|
#if HOST_OS==OS_LINUX || HOST_OS==OS_DARWIN
|
|
extern "C" {
|
|
#endif
|
|
|
|
void emit_Write32(u32 data);
|
|
void emit_Skip(u32 sz);
|
|
u32 emit_FreeSpace();
|
|
void* emit_GetCCPtr();
|
|
void emit_SetBaseAddr();
|
|
|
|
//Called from ngen_FailedToFindBlock
|
|
DynarecCodeEntryPtr DYNACALL rdv_FailedToFindBlock(u32 pc);
|
|
//Called when a block check failed, and the block needs to be invalidated
|
|
DynarecCodeEntryPtr DYNACALL rdv_BlockCheckFail(u32 pc);
|
|
//Called to compile code @pc
|
|
DynarecCodeEntryPtr rdv_CompilePC();
|
|
//Returns 0 if there is no code @pc, code ptr otherwise
|
|
DynarecCodeEntryPtr rdv_FindCode();
|
|
//Finds or compiles code @pc
|
|
DynarecCodeEntryPtr rdv_FindOrCompile();
|
|
|
|
//code -> pointer to code of block, dpc -> if dynamic block, pc. if cond, 0 for next, 1 for branch
|
|
void* DYNACALL rdv_LinkBlock(u8* code,u32 dpc);
|
|
|
|
u32 DYNACALL rdv_DoInterrupts(void* block_cpde);
|
|
|
|
//Stuff to be implemented per dynarec core
|
|
|
|
void ngen_init();
|
|
|
|
//Called to compile a block
|
|
void ngen_Compile(RuntimeBlockInfo* block,bool force_checks, bool reset, bool staging,bool optimise);
|
|
|
|
//Called when blocks are reseted
|
|
void ngen_ResetBlocks();
|
|
//Value to be returned when the block manager failed to find a block,
|
|
//should call rdv_FailedToFindBlock and then jump to the return value
|
|
extern void (*ngen_FailedToFindBlock)();
|
|
//the dynarec mainloop
|
|
extern "C" void ngen_mainloop(void* cntx);
|
|
//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
|
|
};
|
|
|
|
void ngen_GetFeatures(ngen_features* dst);
|
|
|
|
//Canonical callback interface
|
|
enum CanonicalParamType
|
|
{
|
|
CPT_u32,
|
|
CPT_u32rv,
|
|
CPT_u64rvL,
|
|
CPT_u64rvH,
|
|
CPT_f32,
|
|
CPT_f32rv,
|
|
CPT_ptr,
|
|
};
|
|
|
|
void ngen_CC_Start(shil_opcode* op);
|
|
void ngen_CC_Param(shil_opcode* op,shil_param* par,CanonicalParamType tp);
|
|
void ngen_CC_Call(shil_opcode* op,void* function);
|
|
void ngen_CC_Finish(shil_opcode* op);
|
|
|
|
RuntimeBlockInfo* ngen_AllocateBlock();
|
|
|
|
#if HOST_OS==OS_LINUX || HOST_OS==OS_DARWIN
|
|
}
|
|
#endif
|