mirror of
https://github.com/joncampbell123/dosbox-x.git
synced 2025-10-14 10:48:18 +08:00
Dynrec: Convert the rest of the processor support code using the same C++ template trick, hope for the best, should not break anything (let me know if it does!)
This commit is contained in:
@@ -822,8 +822,8 @@ static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) {
|
||||
}
|
||||
|
||||
// helper function for gen_call_function_raw and gen_call_function_setup
|
||||
static void gen_call_function_helper(void * func) {
|
||||
Bit8u *datapos;
|
||||
template <typename T> static void gen_call_function_helper(const T func) {
|
||||
Bit8u *datapos;
|
||||
|
||||
datapos = cache_reservedata();
|
||||
*(Bit32u*)datapos=(Bit32u)func;
|
||||
@@ -848,7 +848,7 @@ static void gen_call_function_helper(void * func) {
|
||||
}
|
||||
|
||||
// generate a call to a parameterless function
|
||||
static void INLINE gen_call_function_raw(void * func) {
|
||||
template <typename T> static void INLINE gen_call_function_raw(const T func) {
|
||||
cache_checkinstr(12);
|
||||
gen_call_function_helper(func);
|
||||
}
|
||||
@@ -856,7 +856,7 @@ static void INLINE gen_call_function_raw(void * func) {
|
||||
// generate a call to a function with paramcount parameters
|
||||
// note: the parameters are loaded in the architecture specific way
|
||||
// using the gen_load_param_ functions below
|
||||
static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) {
|
||||
template <typename T> template <typename T> static Bit32u INLINE gen_call_function_setup(const T func,Bitu paramcount,bool fastcall=false) {
|
||||
cache_checkinstr(12);
|
||||
Bit32u proc_addr = (Bit32u)cache.pos;
|
||||
gen_call_function_helper(func);
|
||||
|
@@ -822,43 +822,43 @@ static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) {
|
||||
}
|
||||
|
||||
// helper function for gen_call_function_raw and gen_call_function_setup
|
||||
static void gen_call_function_helper(void * func) {
|
||||
Bit8u *datapos;
|
||||
template <typename T> static void gen_call_function_helper(const T func) {
|
||||
Bit8u *datapos;
|
||||
|
||||
datapos = cache_reservedata();
|
||||
*(Bit32u*)datapos=(Bit32u)func;
|
||||
datapos = cache_reservedata();
|
||||
*(Bit32u*)datapos=(Bit32u)func;
|
||||
|
||||
if (((Bit32u)cache.pos & 0x03) == 0) {
|
||||
cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 4)) ); // ldr templo1, [pc, datapos]
|
||||
cache_addw( ADD_LO_PC_IMM(templo2, 4) ); // adr templo2, after_call (add templo2, pc, #4)
|
||||
cache_addw( MOV_HI_LO(HOST_lr, templo2) ); // mov lr, templo2
|
||||
cache_addw( BX(templo1) ); // bx templo1 --- switch to arm state
|
||||
} else {
|
||||
cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 2)) ); // ldr templo1, [pc, datapos]
|
||||
cache_addw( ADD_LO_PC_IMM(templo2, 4) ); // adr templo2, after_call (add templo2, pc, #4)
|
||||
cache_addw( MOV_HI_LO(HOST_lr, templo2) ); // mov lr, templo2
|
||||
cache_addw( BX(templo1) ); // bx templo1 --- switch to arm state
|
||||
cache_addw( NOP ); // nop
|
||||
}
|
||||
// after_call:
|
||||
if (((Bit32u)cache.pos & 0x03) == 0) {
|
||||
cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 4)) ); // ldr templo1, [pc, datapos]
|
||||
cache_addw( ADD_LO_PC_IMM(templo2, 4) ); // adr templo2, after_call (add templo2, pc, #4)
|
||||
cache_addw( MOV_HI_LO(HOST_lr, templo2) ); // mov lr, templo2
|
||||
cache_addw( BX(templo1) ); // bx templo1 --- switch to arm state
|
||||
} else {
|
||||
cache_addw( LDR_PC_IMM(templo1, datapos - (cache.pos + 2)) ); // ldr templo1, [pc, datapos]
|
||||
cache_addw( ADD_LO_PC_IMM(templo2, 4) ); // adr templo2, after_call (add templo2, pc, #4)
|
||||
cache_addw( MOV_HI_LO(HOST_lr, templo2) ); // mov lr, templo2
|
||||
cache_addw( BX(templo1) ); // bx templo1 --- switch to arm state
|
||||
cache_addw( NOP ); // nop
|
||||
}
|
||||
// after_call:
|
||||
|
||||
// switch from arm to thumb state
|
||||
cache_addd(0xe2800000 + (templo1 << 12) + (HOST_pc << 16) + (1)); // add templo1, pc, #1
|
||||
cache_addd(0xe12fff10 + (templo1)); // bx templo1
|
||||
// switch from arm to thumb state
|
||||
cache_addd(0xe2800000 + (templo1 << 12) + (HOST_pc << 16) + (1)); // add templo1, pc, #1
|
||||
cache_addd(0xe12fff10 + (templo1)); // bx templo1
|
||||
|
||||
// thumb state from now on
|
||||
// thumb state from now on
|
||||
}
|
||||
|
||||
// generate a call to a parameterless function
|
||||
static void INLINE gen_call_function_raw(void * func) {
|
||||
cache_checkinstr(18);
|
||||
gen_call_function_helper(func);
|
||||
template <typename T> static void INLINE gen_call_function_raw(const T func) {
|
||||
cache_checkinstr(18);
|
||||
gen_call_function_helper(func);
|
||||
}
|
||||
|
||||
// generate a call to a function with paramcount parameters
|
||||
// note: the parameters are loaded in the architecture specific way
|
||||
// using the gen_load_param_ functions below
|
||||
static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) {
|
||||
template <typename T> static Bit32u INLINE gen_call_function_setup(const T func,Bitu paramcount,bool fastcall=false) {
|
||||
cache_checkinstr(18);
|
||||
Bit32u proc_addr = (Bit32u)cache.pos;
|
||||
gen_call_function_helper(func);
|
||||
|
@@ -664,8 +664,8 @@ static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) {
|
||||
}
|
||||
|
||||
// generate a call to a parameterless function
|
||||
static void INLINE gen_call_function_raw(void * func) {
|
||||
if (((Bit32u)cache.pos & 0x03) == 0) {
|
||||
template <typename T> static void INLINE gen_call_function_raw(const T func) {
|
||||
if (((Bit32u)cache.pos & 0x03) == 0) {
|
||||
cache_addw( LDR_PC_IMM(templo1, 4) ); // ldr templo1, [pc, #4]
|
||||
cache_addw( ADD_LO_PC_IMM(templo2, 8) ); // adr templo2, after_call (add templo2, pc, #8)
|
||||
cache_addw( MOV_HI_LO(HOST_lr, templo2) ); // mov lr, templo2
|
||||
@@ -690,7 +690,7 @@ static void INLINE gen_call_function_raw(void * func) {
|
||||
// generate a call to a function with paramcount parameters
|
||||
// note: the parameters are loaded in the architecture specific way
|
||||
// using the gen_load_param_ functions below
|
||||
static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) {
|
||||
template <typename T> static Bit32u INLINE gen_call_function_setup(const T func,Bitu paramcount,bool fastcall=false) {
|
||||
Bit32u proc_addr = (Bit32u)cache.pos;
|
||||
gen_call_function_raw(func);
|
||||
return proc_addr;
|
||||
|
@@ -757,19 +757,19 @@ static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) {
|
||||
}
|
||||
|
||||
// generate a call to a parameterless function
|
||||
static void INLINE gen_call_function_raw(void * func) {
|
||||
cache_addd( MOVZ64(temp1, ((Bit64u)func) & 0xffff, 0) ); // movz dest_reg, #(func & 0xffff)
|
||||
cache_addd( MOVK64(temp1, (((Bit64u)func) >> 16) & 0xffff, 16) ); // movk dest_reg, #((func >> 16) & 0xffff), lsl #16
|
||||
cache_addd( MOVK64(temp1, (((Bit64u)func) >> 32) & 0xffff, 32) ); // movk dest_reg, #((func >> 32) & 0xffff), lsl #32
|
||||
cache_addd( MOVK64(temp1, (((Bit64u)func) >> 48) & 0xffff, 48) ); // movk dest_reg, #((func >> 48) & 0xffff), lsl #48
|
||||
cache_addd( BLR_REG(temp1) ); // blr temp1
|
||||
template <typename T> static void INLINE gen_call_function_raw(const T func) {
|
||||
cache_addd( MOVZ64(temp1, ((Bit64u)func) & 0xffff, 0) ); // movz dest_reg, #(func & 0xffff)
|
||||
cache_addd( MOVK64(temp1, (((Bit64u)func) >> 16) & 0xffff, 16) ); // movk dest_reg, #((func >> 16) & 0xffff), lsl #16
|
||||
cache_addd( MOVK64(temp1, (((Bit64u)func) >> 32) & 0xffff, 32) ); // movk dest_reg, #((func >> 32) & 0xffff), lsl #32
|
||||
cache_addd( MOVK64(temp1, (((Bit64u)func) >> 48) & 0xffff, 48) ); // movk dest_reg, #((func >> 48) & 0xffff), lsl #48
|
||||
cache_addd( BLR_REG(temp1) ); // blr temp1
|
||||
}
|
||||
|
||||
// generate a call to a function with paramcount parameters
|
||||
// note: the parameters are loaded in the architecture specific way
|
||||
// using the gen_load_param_ functions below
|
||||
static DRC_PTR_SIZE_IM INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) {
|
||||
DRC_PTR_SIZE_IM proc_addr = (DRC_PTR_SIZE_IM)cache.pos;
|
||||
template <typename T> static DRC_PTR_SIZE_IM INLINE gen_call_function_setup(const T func,Bitu paramcount,bool fastcall=false) {
|
||||
DRC_PTR_SIZE_IM proc_addr = (DRC_PTR_SIZE_IM)cache.pos;
|
||||
gen_call_function_raw(func);
|
||||
return proc_addr;
|
||||
}
|
||||
|
@@ -386,20 +386,20 @@ static INLINE void gen_lea(HostReg dest_reg,Bitu scale,Bits imm) {
|
||||
#define DELAY cache_addd(0) // nop
|
||||
|
||||
// generate a call to a parameterless function
|
||||
static void INLINE gen_call_function_raw(void * func) {
|
||||
template <typename T> static void INLINE gen_call_function_raw(const T func) {
|
||||
#if C_DEBUG
|
||||
if ((cache.pos ^ func) & 0xf0000000) LOG_MSG("jump overflow\n");
|
||||
if ((cache.pos ^ func) & 0xf0000000) LOG_MSG("jump overflow\n");
|
||||
#endif
|
||||
temp1_valid = false;
|
||||
cache_addd(0x0c000000+(((Bit32u)func>>2)&0x3ffffff)); // jal func
|
||||
DELAY;
|
||||
temp1_valid = false;
|
||||
cache_addd(0x0c000000+(((Bit32u)func>>2)&0x3ffffff)); // jal func
|
||||
DELAY;
|
||||
}
|
||||
|
||||
// generate a call to a function with paramcount parameters
|
||||
// note: the parameters are loaded in the architecture specific way
|
||||
// using the gen_load_param_ functions below
|
||||
static Bit32u INLINE gen_call_function_setup(void * func,Bitu paramcount,bool fastcall=false) {
|
||||
Bit32u proc_addr = (Bit32u)cache.pos;
|
||||
template <typename T> static Bit32u INLINE gen_call_function_setup(const T func,Bitu paramcount,bool fastcall=false) {
|
||||
Bit32u proc_addr = (Bit32u)cache.pos;
|
||||
gen_call_function_raw(func);
|
||||
return proc_addr;
|
||||
}
|
||||
|
Reference in New Issue
Block a user