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

135 lines
3.7 KiB
C
Raw Normal View History

2013-12-19 17:10:14 +00:00
/*
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
2013-12-19 17:10:14 +00:00
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 (10*1024*1024)
2013-12-19 17:10:14 +00:00
// When NO_RWX is enabled there's two address-spaces, one executable and
// one writtable. The emitter and most of the code in rec-* will work with
// the RW pointer. However the fpcb table and other pointers during execution
// (ie. exceptions) are RX pointers. These two macros convert between them by
// sub/add the pointer offset. CodeCache will point to the RW pointer for simplicity.
#ifdef FEAT_NO_RWX_PAGES
extern uintptr_t cc_rx_offset;
#define CC_RW2RX(ptr) (void*)(((uintptr_t)ptr) + cc_rx_offset)
#define CC_RX2RW(ptr) (void*)(((uintptr_t)ptr) - cc_rx_offset)
#else
#define CC_RW2RX(ptr) (ptr)
#define CC_RX2RW(ptr) (ptr)
#endif
2013-12-19 17:10:14 +00:00
//alternative emit ptr, set to 0 to use the main buffer
extern u32* emit_ptr;
extern u8* CodeCache;
#ifdef __cplusplus
extern "C" {
#endif
2013-12-19 17:10:14 +00:00
void emit_Write32(u32 data);
void emit_Skip(u32 sz);
u32 emit_FreeSpace();
void* emit_GetCCPtr();
void emit_SetBaseAddr();
//Called from ngen_FailedToFindBlock
2015-05-08 16:59:20 +00:00
DynarecCodeEntryPtr DYNACALL rdv_FailedToFindBlock(u32 pc);
2013-12-19 17:10:14 +00:00
//Called when a block check failed, and the block needs to be invalidated
2015-05-08 16:59:20 +00:00
DynarecCodeEntryPtr DYNACALL rdv_BlockCheckFail(u32 pc);
2013-12-19 17:10:14 +00:00
//Called to compile code @pc
2015-05-08 16:59:20 +00:00
DynarecCodeEntryPtr rdv_CompilePC();
2013-12-19 17:10:14 +00:00
//Returns 0 if there is no code @pc, code ptr otherwise
2015-05-08 16:59:20 +00:00
DynarecCodeEntryPtr rdv_FindCode();
2013-12-19 17:10:14 +00:00
//Finds or compiles code @pc
2015-05-08 16:59:20 +00:00
DynarecCodeEntryPtr rdv_FindOrCompile();
2013-12-19 17:10:14 +00:00
//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);
2015-07-13 21:56:42 +00:00
u32 DYNACALL rdv_DoInterrupts_pc(u32 pc);
2013-12-19 17:10:14 +00:00
//Stuff to be implemented per dynarec core
void ngen_init();
//Called to compile a block
2019-03-30 05:33:52 +00:00
void ngen_Compile(RuntimeBlockInfo* block, SmcCheckEnum smc_checks, bool reset, bool staging,bool optimise);
2013-12-19 17:10:14 +00:00
//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
2015-07-13 21:56:42 +00:00
void ngen_mainloop(void* cntx);
2013-12-19 17:10:14 +00:00
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();
#ifdef __cplusplus
2013-12-19 17:10:14 +00:00
}
#endif