void jump_vaddr_r10();
void jump_vaddr_r12();
-const u_int jump_vaddr_reg[16] = {
- (int)jump_vaddr_r0,
- (int)jump_vaddr_r1,
- (int)jump_vaddr_r2,
- (int)jump_vaddr_r3,
- (int)jump_vaddr_r4,
- (int)jump_vaddr_r5,
- (int)jump_vaddr_r6,
- (int)jump_vaddr_r7,
- (int)jump_vaddr_r8,
- (int)jump_vaddr_r9,
- (int)jump_vaddr_r10,
+void * const jump_vaddr_reg[16] = {
+ jump_vaddr_r0,
+ jump_vaddr_r1,
+ jump_vaddr_r2,
+ jump_vaddr_r3,
+ jump_vaddr_r4,
+ jump_vaddr_r5,
+ jump_vaddr_r6,
+ jump_vaddr_r7,
+ jump_vaddr_r8,
+ jump_vaddr_r9,
+ jump_vaddr_r10,
0,
- (int)jump_vaddr_r12,
+ jump_vaddr_r12,
0,
0,
- 0};
+ 0
+};
void invalidate_addr_r0();
void invalidate_addr_r1();
output_w32(0xeb000000|offset);
}
-static void emit_jmp(int a)
+static void emit_jmp(const void *a_)
{
+ int a = (int)a_;
assem_debug("b %x (%x+%x)%s\n",a,(int)out,a-(int)out-8,func_name(a));
u_int offset=genjmp(a);
output_w32(0xea000000|offset);
output_w32(0x2a000000|offset);
}
-static void emit_jcc(int a)
+static void emit_jcc(void *a_)
{
+ int a = (int)a_;
assem_debug("bcc %x\n",a);
u_int offset=genjmp(a);
output_w32(0x3a000000|offset);
set_jump_target(jaddr, out);
}
-static void emit_extjump2(u_int addr, int target, int linker)
+static void emit_extjump2(u_int addr, int target, void *linker)
{
u_char *ptr=(u_char *)addr;
assert((ptr[3]&0x0e)==0xa);
static void emit_extjump(int addr, int target)
{
- emit_extjump2(addr, target, (int)dyna_linker);
+ emit_extjump2(addr, target, dyna_linker);
}
static void emit_extjump_ds(int addr, int target)
{
- emit_extjump2(addr, target, (int)dyna_linker_ds);
+ emit_extjump2(addr, target, dyna_linker_ds);
}
// put rt_val into rt, potentially making use of rs with value rs_val
}
}
-static void mov_loadtype_adj(int type,int rs,int rt)
+static void mov_loadtype_adj(enum stub_type type,int rs,int rt)
{
switch(type) {
case LOADB_STUB: emit_signextend8(rs,rt); break;
static void do_readstub(int n)
{
- assem_debug("do_readstub %x\n",start+stubs[n][3]*4);
+ assem_debug("do_readstub %x\n",start+stubs[n].a*4);
literal_pool(256);
- set_jump_target(stubs[n][1], out);
- int type=stubs[n][0];
- int i=stubs[n][3];
- int rs=stubs[n][4];
- struct regstat *i_regs=(struct regstat *)stubs[n][5];
- u_int reglist=stubs[n][7];
+ set_jump_target(stubs[n].addr, out);
+ enum stub_type type=stubs[n].type;
+ int i=stubs[n].a;
+ int rs=stubs[n].b;
+ struct regstat *i_regs=(struct regstat *)stubs[n].c;
+ u_int reglist=stubs[n].e;
signed char *i_regmap=i_regs->regmap;
int rt;
if(itype[i]==C1LS||itype[i]==C2LS||itype[i]==LOADLR) {
case LOADH_STUB: emit_ldrccsh_dualindexed(temp2,rs,rt); break;
case LOADHU_STUB: emit_ldrcch_dualindexed(temp2,rs,rt); break;
case LOADW_STUB: emit_ldrcc_dualindexed(temp2,rs,rt); break;
+ default: assert(0);
}
}
if(regs_saved) {
emit_jcc(0); // jump to reg restore
}
else
- emit_jcc(stubs[n][2]); // return address
+ emit_jcc(stubs[n].retaddr); // return address
if(!regs_saved)
save_regs(reglist);
int cc=get_reg(i_regmap,CCREG);
if(cc<0)
emit_loadreg(CCREG,2);
- emit_addimm(cc<0?2:cc,CLOCK_ADJUST((int)stubs[n][6]+1),2);
+ emit_addimm(cc<0?2:cc,CLOCK_ADJUST((int)stubs[n].d+1),2);
emit_call(handler);
if(itype[i]==C1LS||itype[i]==C2LS||(rt>=0&&rt1[i]!=0)) {
mov_loadtype_adj(type,0,rt);
if(restore_jump)
set_jump_target(restore_jump, out);
restore_regs(reglist);
- emit_jmp(stubs[n][2]); // return address
+ emit_jmp(stubs[n].retaddr); // return address
}
// return memhandler, or get directly accessable address and return 0
-static u_int get_direct_memhandler(void *table,u_int addr,int type,u_int *addr_host)
+static u_int get_direct_memhandler(void *table,u_int addr,enum stub_type type,u_int *addr_host)
{
u_int l1,l2=0;
l1=((u_int *)table)[addr>>12];
}
}
-static void inline_readstub(int type, int i, u_int addr, signed char regmap[], int target, int adj, u_int reglist)
+static void inline_readstub(enum stub_type type, int i, u_int addr, signed char regmap[], int target, int adj, u_int reglist)
{
int rs=get_reg(regmap,target);
int rt=get_reg(regmap,target);
static void do_writestub(int n)
{
- assem_debug("do_writestub %x\n",start+stubs[n][3]*4);
+ assem_debug("do_writestub %x\n",start+stubs[n].a*4);
literal_pool(256);
- set_jump_target(stubs[n][1], out);
- int type=stubs[n][0];
- int i=stubs[n][3];
- int rs=stubs[n][4];
- struct regstat *i_regs=(struct regstat *)stubs[n][5];
- u_int reglist=stubs[n][7];
+ set_jump_target(stubs[n].addr, out);
+ enum stub_type type=stubs[n].type;
+ int i=stubs[n].a;
+ int rs=stubs[n].b;
+ struct regstat *i_regs=(struct regstat *)stubs[n].c;
+ u_int reglist=stubs[n].e;
signed char *i_regmap=i_regs->regmap;
int rt,r;
if(itype[i]==C1LS||itype[i]==C2LS) {
}
assert(rs>=0);
assert(rt>=0);
- int rtmp,temp=-1,temp2=HOST_TEMPREG,regs_saved=0,ra;
+ int rtmp,temp=-1,temp2=HOST_TEMPREG,regs_saved=0;
void *restore_jump = NULL;
int reglist2=reglist|(1<<rs)|(1<<rt);
for(rtmp=0;rtmp<=12;rtmp++) {
emit_jcc(0); // jump to reg restore
}
else
- emit_jcc(stubs[n][2]); // return address (invcode check)
+ emit_jcc(stubs[n].retaddr); // return address (invcode check)
if(!regs_saved)
save_regs(reglist);
case STOREB_STUB: handler=(int)jump_handler_write8; break;
case STOREH_STUB: handler=(int)jump_handler_write16; break;
case STOREW_STUB: handler=(int)jump_handler_write32; break;
+ default: assert(0);
}
assert(handler!=0);
pass_args(rs,rt);
int cc=get_reg(i_regmap,CCREG);
if(cc<0)
emit_loadreg(CCREG,2);
- emit_addimm(cc<0?2:cc,CLOCK_ADJUST((int)stubs[n][6]+1),2);
+ emit_addimm(cc<0?2:cc,CLOCK_ADJUST((int)stubs[n].d+1),2);
// returns new cycle_count
emit_call(handler);
- emit_addimm(0,-CLOCK_ADJUST((int)stubs[n][6]+1),cc<0?2:cc);
+ emit_addimm(0,-CLOCK_ADJUST((int)stubs[n].d+1),cc<0?2:cc);
if(cc<0)
emit_storereg(CCREG,2);
if(restore_jump)
set_jump_target(restore_jump, out);
restore_regs(reglist);
- ra=stubs[n][2];
- emit_jmp(ra);
+ emit_jmp(stubs[n].retaddr);
}
-static void inline_writestub(int type, int i, u_int addr, signed char regmap[], int target, int adj, u_int reglist)
+static void inline_writestub(enum stub_type type, int i, u_int addr, signed char regmap[], int target, int adj, u_int reglist)
{
int rs=get_reg(regmap,-1);
int rt=get_reg(regmap,target);
static void do_unalignedwritestub(int n)
{
- assem_debug("do_unalignedwritestub %x\n",start+stubs[n][3]*4);
+ assem_debug("do_unalignedwritestub %x\n",start+stubs[n].a*4);
literal_pool(256);
- set_jump_target(stubs[n][1], out);
+ set_jump_target(stubs[n].addr, out);
- int i=stubs[n][3];
- struct regstat *i_regs=(struct regstat *)stubs[n][4];
- int addr=stubs[n][5];
- u_int reglist=stubs[n][7];
+ int i=stubs[n].a;
+ struct regstat *i_regs=(struct regstat *)stubs[n].c;
+ int addr=stubs[n].b;
+ u_int reglist=stubs[n].e;
signed char *i_regmap=i_regs->regmap;
int temp2=get_reg(i_regmap,FTEMP);
int rt;
int cc=get_reg(i_regmap,CCREG);
if(cc<0)
emit_loadreg(CCREG,2);
- emit_addimm(cc<0?2:cc,CLOCK_ADJUST((int)stubs[n][6]+1),2);
+ emit_addimm(cc<0?2:cc,CLOCK_ADJUST((int)stubs[n].d+1),2);
emit_call((int)(opcode[i]==0x2a?jump_handle_swl:jump_handle_swr));
- emit_addimm(0,-CLOCK_ADJUST((int)stubs[n][6]+1),cc<0?2:cc);
+ emit_addimm(0,-CLOCK_ADJUST((int)stubs[n].d+1),cc<0?2:cc);
if(cc<0)
emit_storereg(CCREG,2);
restore_regs(reglist);
- emit_jmp(stubs[n][2]); // return address
+ emit_jmp(stubs[n].retaddr); // return address
#else
emit_andimm(addr,0xfffffffc,temp2);
emit_writeword(temp2,(int)&address);
emit_loadreg(CCREG,2);
}
emit_movimm((u_int)readmem,0);
- emit_addimm(cc<0?2:cc,2*stubs[n][6]+2,2);
+ emit_addimm(cc<0?2:cc,2*stubs[n].d+2,2);
emit_call((int)&indirect_jump_indexed);
restore_regs(reglist);
emit_readword_dualindexedx4(0,1,15);
emit_readword((int)&Count,HOST_TEMPREG);
emit_readword((int)&next_interupt,2);
- emit_addimm(HOST_TEMPREG,-2*stubs[n][6]-2,HOST_TEMPREG);
+ emit_addimm(HOST_TEMPREG,-2*stubs[n].d-2,HOST_TEMPREG);
emit_writeword(2,(int)&last_count);
emit_sub(HOST_TEMPREG,2,cc<0?HOST_TEMPREG:cc);
if(cc<0) {
emit_storereg(CCREG,HOST_TEMPREG);
}
restore_regs(reglist);
- emit_jmp(stubs[n][2]); // return address
+ emit_jmp(stubs[n].retaddr); // return address
#endif
}
static void do_invstub(int n)
{
literal_pool(20);
- u_int reglist=stubs[n][3];
- set_jump_target(stubs[n][1], out);
+ u_int reglist=stubs[n].a;
+ set_jump_target(stubs[n].addr, out);
save_regs(reglist);
- if(stubs[n][4]!=0) emit_mov(stubs[n][4],0);
+ if(stubs[n].b!=0) emit_mov(stubs[n].b,0);
emit_call((int)&invalidate_addr);
restore_regs(reglist);
- emit_jmp(stubs[n][2]); // return address
+ emit_jmp(stubs[n].retaddr); // return address
}
void *do_dirty_stub(int i)
static void do_cop1stub(int n)
{
literal_pool(256);
- assem_debug("do_cop1stub %x\n",start+stubs[n][3]*4);
- set_jump_target(stubs[n][1], out);
- int i=stubs[n][3];
-// int rs=stubs[n][4];
- struct regstat *i_regs=(struct regstat *)stubs[n][5];
- int ds=stubs[n][6];
+ assem_debug("do_cop1stub %x\n",start+stubs[n].a*4);
+ set_jump_target(stubs[n].addr, out);
+ int i=stubs[n].a;
+// int rs=stubs[n].b;
+ struct regstat *i_regs=(struct regstat *)stubs[n].c;
+ int ds=stubs[n].d;
if(!ds) {
load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty,i);
//if(i_regs!=®s[i]) printf("oops: regs[i]=%x i_regs=%x",(int)®s[i],(int)i_regs);
if(regs[i].regmap_entry[HOST_CCREG]!=CCREG) emit_loadreg(CCREG,HOST_CCREG);
emit_movimm(start+(i-ds)*4,EAX); // Get PC
emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG); // CHECK: is this right? There should probably be an extra cycle...
- emit_jmp(ds?(int)fp_exception_ds:(int)fp_exception);
+ emit_jmp(ds?fp_exception_ds:fp_exception);
}
/* Special assem */
return MTYPE_8000;
}
-static int emit_fastpath_cmp_jump(int i,int addr,int *addr_reg_override)
+static void *emit_fastpath_cmp_jump(int i,int addr,int *addr_reg_override)
{
- int jaddr=0,type=0;
+ void *jaddr = NULL;
+ int type=0;
int mr=rs1[i];
if(((smrv_strong|smrv_weak)>>mr)&1) {
type=get_ptr_mem_type(smrv[mr]);
if (psxH == (void *)0x1f800000) {
emit_addimm(addr,-0x1f800000,HOST_TEMPREG);
emit_cmpimm(HOST_TEMPREG,0x1000);
- jaddr=(int)out;
+ jaddr=out;
emit_jc(0);
}
else {
if(type==0)
{
emit_cmpimm(addr,RAM_SIZE);
- jaddr=(int)out;
+ jaddr=out;
#ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
// Hint to branch predictor that the branch is unlikely to be taken
if(rs1[i]>=28)
{
int s,th,tl,temp,temp2,addr,map=-1;
int offset;
- int jaddr=0;
+ void *jaddr=0;
int memtarget=0,c=0;
int fastload_reg_override=0;
u_int hr,reglist=0;
if(fastload_reg_override) a=fastload_reg_override;
//emit_readword_indexed((int)rdram-0x80000000,temp2,temp2);
emit_readword_indexed_tlb(0,a,map,temp2);
- if(jaddr) add_stub(LOADW_STUB,jaddr,(int)out,i,temp2,(int)i_regs,ccadj[i],reglist);
+ if(jaddr) add_stub_r(LOADW_STUB,jaddr,out,i,temp2,i_regs,ccadj[i],reglist);
}
else
inline_readstub(LOADW_STUB,i,(constmap[i][s]+offset)&0xFFFFFFFC,i_regs->regmap,FTEMP,ccadj[i],reglist);
//if(th>=0) emit_readword_indexed((int)rdram-0x80000000,temp2,temp2h);
//emit_readword_indexed((int)rdram-0x7FFFFFFC,temp2,temp2);
emit_readdword_indexed_tlb(0,temp2,map,temp2h,temp2);
- if(jaddr) add_stub(LOADD_STUB,jaddr,(int)out,i,temp2,(int)i_regs,ccadj[i],reglist);
+ if(jaddr) add_stub_r(LOADD_STUB,jaddr,out,i,temp2,i_regs,ccadj[i],reglist);
}
else
inline_readstub(LOADD_STUB,i,(constmap[i][s]+offset)&0xFFFFFFF8,i_regs->regmap,FTEMP,ccadj[i],reglist);
{
// XXX: should just just do the exception instead
if(!cop1_usable) {
- int jaddr=(int)out;
+ void *jaddr=out;
emit_jmp(0);
- add_stub(FP_STUB,jaddr,(int)out,i,0,(int)i_regs,is_delayslot,0);
+ add_stub_r(FP_STUB,jaddr,out,i,0,i_regs,is_delayslot,0);
cop1_usable=1;
}
}
emit_subcs(remainder,HOST_TEMPREG,remainder);
emit_adcs(quotient,quotient,quotient);
emit_shrimm(HOST_TEMPREG,1,HOST_TEMPREG);
- emit_jcc((int)out-16); // -4
+ emit_jcc(out-16); // -4
emit_teq(d1,d2);
emit_negmi(quotient,quotient);
emit_test(d1,d1);
emit_subcs(remainder,d2,remainder);
emit_adcs(quotient,quotient,quotient);
emit_shrcc_imm(d2,1,d2);
- emit_jcc((int)out-16); // -4
+ emit_jcc(out-16); // -4
}
}
else // 64-bit
#include "../psxhle.h" //emulator interface
#include "emu_if.h" //emulator interface
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
+#endif
+
//#define DISASM
//#define assem_debug printf
//#define inv_debug printf
#define MAXBLOCK 4096
#define MAX_OUTPUT_BLOCK_SIZE 262144
+// stubs
+enum stub_type {
+ CC_STUB = 1,
+ FP_STUB = 2,
+ LOADB_STUB = 3,
+ LOADH_STUB = 4,
+ LOADW_STUB = 5,
+ LOADD_STUB = 6,
+ LOADBU_STUB = 7,
+ LOADHU_STUB = 8,
+ STOREB_STUB = 9,
+ STOREH_STUB = 10,
+ STOREW_STUB = 11,
+ STORED_STUB = 12,
+ STORELR_STUB = 13,
+ INVCODE_STUB = 14,
+};
+
struct regstat
{
signed char regmap_entry[HOST_REGS];
void *tcaddr[2];
};
+struct code_stub
+{
+ enum stub_type type;
+ void *addr;
+ void *retaddr;
+ u_int a;
+ uintptr_t b;
+ uintptr_t c;
+ u_int d;
+ u_int e;
+};
+
// used by asm:
u_char *out;
struct ht_entry hash_table[65536] __attribute__((aligned(16)));
static void *instr_addr[MAXBLOCK];
static u_int link_addr[MAXBLOCK][3];
static int linkcount;
- static u_int stubs[MAXBLOCK*3][8];
+ static struct code_stub stubs[MAXBLOCK*3];
static int stubcount;
static u_int literals[1024][2];
static int literalcount;
#define C2OP 29 // Coprocessor 2 operation
#define INTCALL 30// Call interpreter to handle rare corner cases
- /* stubs */
-#define CC_STUB 1
-#define FP_STUB 2
-#define LOADB_STUB 3
-#define LOADH_STUB 4
-#define LOADW_STUB 5
-#define LOADD_STUB 6
-#define LOADBU_STUB 7
-#define LOADHU_STUB 8
-#define STOREB_STUB 9
-#define STOREH_STUB 10
-#define STOREW_STUB 11
-#define STORED_STUB 12
-#define STORELR_STUB 13
-#define INVCODE_STUB 14
-
/* branch codes */
#define TAKEN 1
#define NOTTAKEN 2
static int verify_dirty(u_int *ptr);
static int get_final_value(int hr, int i, int *value);
-static void add_stub(int type,int addr,int retaddr,int a,int b,int c,int d,int e);
+static void add_stub(enum stub_type type, void *addr, void *retaddr,
+ u_int a, uintptr_t b, uintptr_t c, u_int d, u_int e);
+static void add_stub_r(enum stub_type type, void *addr, void *retaddr,
+ int i, int addr_reg, struct regstat *i_regs, int ccadj, u_int reglist);
static void add_to_linker(int addr,int target,int ext);
static int tracedebug=0;
{
struct ht_entry *ht_bin = hash_table_get(vaddr);
size_t i;
- for (i = 0; i < sizeof(ht_bin->vaddr)/sizeof(ht_bin->vaddr[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(ht_bin->vaddr); i++) {
if (ht_bin->vaddr[i] == vaddr)
if (doesnt_expire_soon((u_char *)ht_bin->tcaddr[i] - MAX_OUTPUT_BLOCK_SIZE))
if (isclean(ht_bin->tcaddr[i]))
//else ...
}
-static void add_stub(int type,int addr,int retaddr,int a,int b,int c,int d,int e)
+static void add_stub(enum stub_type type, void *addr, void *retaddr,
+ u_int a, uintptr_t b, uintptr_t c, u_int d, u_int e)
{
- stubs[stubcount][0]=type;
- stubs[stubcount][1]=addr;
- stubs[stubcount][2]=retaddr;
- stubs[stubcount][3]=a;
- stubs[stubcount][4]=b;
- stubs[stubcount][5]=c;
- stubs[stubcount][6]=d;
- stubs[stubcount][7]=e;
+ assert(a < ARRAY_SIZE(stubs));
+ stubs[stubcount].type = type;
+ stubs[stubcount].addr = addr;
+ stubs[stubcount].retaddr = retaddr;
+ stubs[stubcount].a = a;
+ stubs[stubcount].b = b;
+ stubs[stubcount].c = c;
+ stubs[stubcount].d = d;
+ stubs[stubcount].e = e;
stubcount++;
}
+static void add_stub_r(enum stub_type type, void *addr, void *retaddr,
+ int i, int addr_reg, struct regstat *i_regs, int ccadj, u_int reglist)
+{
+ add_stub(type, addr, retaddr, i, addr_reg, (uintptr_t)i_regs, ccadj, reglist);
+}
+
// Write out a single register
void wb_register(signed char r,signed char regmap[],uint64_t dirty,uint64_t is32)
{
{
int s,th,tl,addr,map=-1;
int offset;
- int jaddr=0;
+ void *jaddr=0;
int memtarget=0,c=0;
int fastload_reg_override=0;
u_int hr,reglist=0;
}
}
if(jaddr)
- add_stub(LOADB_STUB,jaddr,(int)out,i,addr,(int)i_regs,ccadj[i],reglist);
+ add_stub_r(LOADB_STUB,jaddr,out,i,addr,i_regs,ccadj[i],reglist);
}
else
inline_readstub(LOADB_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist);
}
}
if(jaddr)
- add_stub(LOADH_STUB,jaddr,(int)out,i,addr,(int)i_regs,ccadj[i],reglist);
+ add_stub_r(LOADH_STUB,jaddr,out,i,addr,i_regs,ccadj[i],reglist);
}
else
inline_readstub(LOADH_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist);
emit_readword_indexed_tlb(0,a,map,tl);
}
if(jaddr)
- add_stub(LOADW_STUB,jaddr,(int)out,i,addr,(int)i_regs,ccadj[i],reglist);
+ add_stub_r(LOADW_STUB,jaddr,out,i,addr,i_regs,ccadj[i],reglist);
}
else
inline_readstub(LOADW_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist);
}
}
if(jaddr)
- add_stub(LOADBU_STUB,jaddr,(int)out,i,addr,(int)i_regs,ccadj[i],reglist);
+ add_stub_r(LOADBU_STUB,jaddr,out,i,addr,i_regs,ccadj[i],reglist);
}
else
inline_readstub(LOADBU_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist);
}
}
if(jaddr)
- add_stub(LOADHU_STUB,jaddr,(int)out,i,addr,(int)i_regs,ccadj[i],reglist);
+ add_stub_r(LOADHU_STUB,jaddr,out,i,addr,i_regs,ccadj[i],reglist);
}
else
inline_readstub(LOADHU_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist);
emit_readword_indexed_tlb(0,a,map,tl);
}
if(jaddr)
- add_stub(LOADW_STUB,jaddr,(int)out,i,addr,(int)i_regs,ccadj[i],reglist);
+ add_stub_r(LOADW_STUB,jaddr,out,i,addr,i_regs,ccadj[i],reglist);
}
else {
inline_readstub(LOADW_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist);
emit_readdword_indexed_tlb(0,a,map,th,tl);
}
if(jaddr)
- add_stub(LOADD_STUB,jaddr,(int)out,i,addr,(int)i_regs,ccadj[i],reglist);
+ add_stub_r(LOADD_STUB,jaddr,out,i,addr,i_regs,ccadj[i],reglist);
}
else
inline_readstub(LOADD_STUB,i,constmap[i][s]+offset,i_regs->regmap,rt1[i],ccadj[i],reglist);
int s,th,tl,map=-1;
int addr,temp;
int offset;
- int jaddr=0,type;
+ void *jaddr=0;
+ enum stub_type type;
int memtarget=0,c=0;
int agr=AGEN1+(i&1);
int faststore_reg_override=0;
if(jaddr) {
// PCSX store handlers don't check invcode again
reglist|=1<<addr;
- add_stub(type,jaddr,(int)out,i,addr,(int)i_regs,ccadj[i],reglist);
+ add_stub_r(type,jaddr,out,i,addr,i_regs,ccadj[i],reglist);
jaddr=0;
}
if(!(i_regs->waswritten&(1<<rs1[i]))&&!(new_dynarec_hacks&NDHACK_NO_SMC_CHECK)) {
#if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT)
emit_callne(invalidate_addr_reg[addr]);
#else
- int jaddr2=(int)out;
+ void *jaddr2 = out;
emit_jne(0);
- add_stub(INVCODE_STUB,jaddr2,(int)out,reglist|(1<<HOST_CCREG),addr,0,0,0);
+ add_stub(INVCODE_STUB,jaddr2,out,reglist|(1<<HOST_CCREG),addr,0,0,0);
#endif
}
}
u_int addr_val=constmap[i][s]+offset;
if(jaddr) {
- add_stub(type,jaddr,(int)out,i,addr,(int)i_regs,ccadj[i],reglist);
+ add_stub_r(type,jaddr,out,i,addr,i_regs,ccadj[i],reglist);
} else if(c&&!memtarget) {
inline_writestub(type,i,addr_val,i_regs->regmap,rs2[i],ccadj[i],reglist);
}
wb_dirtys(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty);
emit_movimm(start+i*4+4,0);
emit_writeword(0,(int)&pcaddr);
- emit_jmp((int)do_interrupt);
+ emit_jmp(do_interrupt);
}
}
//if(opcode[i]==0x2B || opcode[i]==0x3F)
int temp;
int temp2=-1;
int offset;
- int jaddr=0;
+ void *jaddr=0;
void *case1, *case2, *case3;
void *done0, *done1, *done2;
int memtarget=0,c=0;
if(!c) {
emit_cmpimm(s<0||offset?temp:s,RAM_SIZE);
if(!offset&&s!=temp) emit_mov(s,temp);
- jaddr=(int)out;
+ jaddr=out;
emit_jno(0);
}
else
{
if(!memtarget||!rs1[i]) {
- jaddr=(int)out;
+ jaddr=out;
emit_jmp(0);
}
}
set_jump_target(done0, out);
}
if(!c||!memtarget)
- add_stub(STORELR_STUB,jaddr,(int)out,i,(int)i_regs,temp,ccadj[i],reglist);
+ add_stub_r(STORELR_STUB,jaddr,out,i,temp,i_regs,ccadj[i],reglist);
if(!(i_regs->waswritten&(1<<rs1[i]))&&!(new_dynarec_hacks&NDHACK_NO_SMC_CHECK)) {
#ifdef RAM_OFFSET
int map=get_reg(i_regs->regmap,ROREG);
#if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT)
emit_callne(invalidate_addr_reg[temp]);
#else
- int jaddr2=(int)out;
+ void *jaddr2 = out;
emit_jne(0);
- add_stub(INVCODE_STUB,jaddr2,(int)out,reglist|(1<<HOST_CCREG),temp,0,0,0);
+ add_stub(INVCODE_STUB,jaddr2,out,reglist|(1<<HOST_CCREG),temp,0,0,0);
#endif
}
/*
int ar;
int offset;
int memtarget=0,c=0;
- int jaddr2=0,type;
+ void *jaddr2=NULL;
+ enum stub_type type;
int agr=AGEN1+(i&1);
int fastio_reg_override=0;
u_int hr,reglist=0;
type=LOADW_STUB;
if(c&&!memtarget) {
- jaddr2=(int)out;
+ jaddr2=out;
emit_jmp(0); // inline_readstub/inline_writestub?
}
else {
}
}
if(jaddr2)
- add_stub(type,jaddr2,(int)out,i,ar,(int)i_regs,ccadj[i],reglist);
+ add_stub_r(type,jaddr2,out,i,ar,i_regs,ccadj[i],reglist);
if(opcode[i]==0x3a) // SWC2
if(!(i_regs->waswritten&(1<<rs1[i]))&&!(new_dynarec_hacks&NDHACK_NO_SMC_CHECK)) {
#if defined(HOST_IMM8)
#if defined(HAVE_CONDITIONAL_CALL) && !defined(DESTRUCTIVE_SHIFT)
emit_callne(invalidate_addr_reg[ar]);
#else
- int jaddr3=(int)out;
+ void *jaddr3 = out;
emit_jne(0);
- add_stub(INVCODE_STUB,jaddr3,(int)out,reglist|(1<<HOST_CCREG),ar,0,0,0);
+ add_stub(INVCODE_STUB,jaddr3,out,reglist|(1<<HOST_CCREG),ar,0,0,0);
#endif
}
if (opcode[i]==0x32) { // LWC2
(void)ccreg;
emit_movimm(start+i*4,EAX); // Get PC
emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG); // CHECK: is this right? There should probably be an extra cycle...
- emit_jmp((int)jump_syscall_hle); // XXX
+ emit_jmp(jump_syscall_hle); // XXX
}
void hlecall_assemble(int i,struct regstat *i_regs)
(void)ccreg;
emit_movimm(start+i*4+4,0); // Get PC
uint32_t hleCode = source[i] & 0x03ffffff;
- if (hleCode >= (sizeof(psxHLEt) / sizeof(psxHLEt[0])))
+ if (hleCode >= ARRAY_SIZE(psxHLEt))
emit_movimm((int)psxNULL,1);
else
emit_movimm((int)psxHLEt[hleCode],1);
emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG); // XXX
- emit_jmp((int)jump_hlecall);
+ emit_jmp(jump_hlecall);
}
void intcall_assemble(int i,struct regstat *i_regs)
(void)ccreg;
emit_movimm(start+i*4,0); // Get PC
emit_addimm(HOST_CCREG,CLOCK_ADJUST(ccadj[i]),HOST_CCREG);
- emit_jmp((int)jump_intcall);
+ emit_jmp(jump_intcall);
}
void ds_assemble(int i,struct regstat *i_regs)
void do_cc(int i,signed char i_regmap[],int *adj,int addr,int taken,int invert)
{
int count;
- int jaddr;
- int idle=0;
+ void *jaddr;
+ void *idle=NULL;
int t=0;
if(itype[i]==RJUMP)
{
if(taken==TAKEN && i==(ba[i]-start)>>2 && source[i+1]==0) {
// Idle loop
if(count&1) emit_addimm_and_set_flags(2*(count+2),HOST_CCREG);
- idle=(int)out;
+ idle=out;
//emit_subfrommem(&idlecount,HOST_CCREG); // Count idle cycles
emit_andimm(HOST_CCREG,3,HOST_CCREG);
- jaddr=(int)out;
+ jaddr=out;
emit_jmp(0);
}
else if(*adj==0||invert) {
cycles=CLOCK_ADJUST(*adj)+count+2-*adj;
}
emit_addimm_and_set_flags(cycles,HOST_CCREG);
- jaddr=(int)out;
+ jaddr=out;
emit_jns(0);
}
else
{
emit_cmpimm(HOST_CCREG,-CLOCK_ADJUST(count+2));
- jaddr=(int)out;
+ jaddr=out;
emit_jns(0);
}
- add_stub(CC_STUB,jaddr,idle?idle:(int)out,(*adj==0||invert||idle)?0:(count+2),i,addr,taken,0);
+ add_stub(CC_STUB,jaddr,idle?idle:out,(*adj==0||invert||idle)?0:(count+2),i,addr,taken,0);
}
-void do_ccstub(int n)
+static void do_ccstub(int n)
{
literal_pool(256);
- assem_debug("do_ccstub %x\n",start+stubs[n][4]*4);
- set_jump_target(stubs[n][1], out);
- int i=stubs[n][4];
- if(stubs[n][6]==NULLDS) {
+ assem_debug("do_ccstub %x\n",start+stubs[n].b*4);
+ set_jump_target(stubs[n].addr, out);
+ int i=stubs[n].b;
+ if(stubs[n].d==NULLDS) {
// Delay slot instruction is nullified ("likely" branch)
wb_dirtys(regs[i].regmap,regs[i].is32,regs[i].dirty);
}
- else if(stubs[n][6]!=TAKEN) {
+ else if(stubs[n].d!=TAKEN) {
wb_dirtys(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty);
}
else {
if(internal_branch(branch_regs[i].is32,ba[i]))
wb_needed_dirtys(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]);
}
- if(stubs[n][5]!=-1)
+ if(stubs[n].c!=-1)
{
// Save PC as return address
- emit_movimm(stubs[n][5],EAX);
+ emit_movimm(stubs[n].c,EAX);
emit_writeword(EAX,(int)&pcaddr);
}
else
}
// Update cycle count
assert(branch_regs[i].regmap[HOST_CCREG]==CCREG||branch_regs[i].regmap[HOST_CCREG]==-1);
- if(stubs[n][3]) emit_addimm(HOST_CCREG,CLOCK_ADJUST((int)stubs[n][3]),HOST_CCREG);
+ if(stubs[n].a) emit_addimm(HOST_CCREG,CLOCK_ADJUST((int)stubs[n].a),HOST_CCREG);
emit_call((int)cc_interrupt);
- if(stubs[n][3]) emit_addimm(HOST_CCREG,-CLOCK_ADJUST((int)stubs[n][3]),HOST_CCREG);
- if(stubs[n][6]==TAKEN) {
+ if(stubs[n].a) emit_addimm(HOST_CCREG,-CLOCK_ADJUST((int)stubs[n].a),HOST_CCREG);
+ if(stubs[n].d==TAKEN) {
if(internal_branch(branch_regs[i].is32,ba[i]))
load_needed_regs(branch_regs[i].regmap,regs[(ba[i]-start)>>2].regmap_entry);
else if(itype[i]==RJUMP) {
else
emit_loadreg(rs1[i],get_reg(branch_regs[i].regmap,rs1[i]));
}
- }else if(stubs[n][6]==NOTTAKEN) {
+ }else if(stubs[n].d==NOTTAKEN) {
if(i<slen-2) load_needed_regs(branch_regs[i].regmap,regmap_pre[i+2]);
else load_all_regs(branch_regs[i].regmap);
- }else if(stubs[n][6]==NULLDS) {
+ }else if(stubs[n].d==NULLDS) {
// Delay slot instruction is nullified ("likely" branch)
if(i<slen-2) load_needed_regs(regs[i].regmap,regmap_pre[i+2]);
else load_all_regs(regs[i].regmap);
}else{
load_all_regs(branch_regs[i].regmap);
}
- emit_jmp(stubs[n][2]); // return address
+ emit_jmp(stubs[n].retaddr);
/* This works but uses a lot of memory...
emit_readword((int)&last_count,ECX);
emit_test(EBX,EBX);
int jne_instr=(int)out;
emit_jne(0);
- if(stubs[n][3]) emit_addimm(HOST_CCREG,-2*stubs[n][3],HOST_CCREG);
+ if(stubs[n].a) emit_addimm(HOST_CCREG,-2*stubs[n].a,HOST_CCREG);
load_all_regs(branch_regs[i].regmap);
- emit_jmp(stubs[n][2]); // return address
+ emit_jmp(stubs[n].retaddr); // return address
set_jump_target(jne_instr,(int)out);
emit_readword((int)&pcaddr,EAX);
// Call get_addr_ht instead of doing the hash table here.
//if(adj) emit_addimm(cc,2*(ccadj[i]+2-adj),cc); // ??? - Shouldn't happen
//assert(adj==0);
emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),HOST_CCREG);
- add_stub(CC_STUB,(int)out,jump_vaddr_reg[rs],0,i,-1,TAKEN,0);
+ add_stub(CC_STUB,out,jump_vaddr_reg[rs],0,i,-1,TAKEN,0);
if(itype[i+1]==COP0&&(source[i+1]&0x3f)==0x10)
// special case for RFE
emit_jmp(0);
#endif
{
//if(rs!=EAX) emit_mov(rs,EAX);
- //emit_jmp((int)jump_vaddr_eax);
+ //emit_jmp(jump_vaddr_eax);
emit_jmp(jump_vaddr_reg[rs]);
}
/* Check hash table
}
else if(nop) {
emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),cc);
- int jaddr=(int)out;
+ void *jaddr=out;
emit_jns(0);
- add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,NOTTAKEN,0);
+ add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
}
else {
void *taken = NULL, *nottaken = NULL, *nottaken1 = NULL;
// Cycle count isn't in a register, temporarily load it then write it out
emit_loadreg(CCREG,HOST_CCREG);
emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),HOST_CCREG);
- int jaddr=(int)out;
+ void *jaddr=out;
emit_jns(0);
- add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,NOTTAKEN,0);
+ add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
emit_storereg(CCREG,HOST_CCREG);
}
else{
cc=get_reg(i_regmap,CCREG);
assert(cc==HOST_CCREG);
emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),cc);
- int jaddr=(int)out;
+ void *jaddr=out;
emit_jns(0);
- add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,likely[i]?NULLDS:NOTTAKEN,0);
+ add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,likely[i]?NULLDS:NOTTAKEN,0);
}
}
}
}
else if(nevertaken) {
emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),cc);
- int jaddr=(int)out;
+ void *jaddr=out;
emit_jns(0);
- add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,NOTTAKEN,0);
+ add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
}
else {
void *nottaken = NULL;
// Cycle count isn't in a register, temporarily load it then write it out
emit_loadreg(CCREG,HOST_CCREG);
emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),HOST_CCREG);
- int jaddr=(int)out;
+ void *jaddr=out;
emit_jns(0);
- add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,NOTTAKEN,0);
+ add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
emit_storereg(CCREG,HOST_CCREG);
}
else{
cc=get_reg(i_regmap,CCREG);
assert(cc==HOST_CCREG);
emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),cc);
- int jaddr=(int)out;
+ void *jaddr=out;
emit_jns(0);
- add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,likely[i]?NULLDS:NOTTAKEN,0);
+ add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,likely[i]?NULLDS:NOTTAKEN,0);
}
}
}
match=match_bt(branch_regs[i].regmap,branch_regs[i].is32,branch_regs[i].dirty,ba[i]);
assem_debug("fmatch=%d\n",match);
int fs,cs;
- int eaddr;
+ void *eaddr;
int invert=0;
int internal=internal_branch(branch_regs[i].is32,ba[i]);
if(i==(ba[i]-start)>>2) assem_debug("idle loop\n");
cs=get_reg(i_regmap,CSREG);
assert(cs>=0);
emit_testimm(cs,0x20000000);
- eaddr=(int)out;
+ eaddr=out;
emit_jeq(0);
- add_stub(FP_STUB,eaddr,(int)out,i,cs,(int)i_regs,0,0);
+ add_stub_r(FP_STUB,eaddr,out,i,cs,i_regs,0,0);
cop1_usable=1;
}
// Cycle count isn't in a register, temporarily load it then write it out
emit_loadreg(CCREG,HOST_CCREG);
emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),HOST_CCREG);
- int jaddr=(int)out;
+ void *jaddr=out;
emit_jns(0);
- add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,NOTTAKEN,0);
+ add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,NOTTAKEN,0);
emit_storereg(CCREG,HOST_CCREG);
}
else{
cc=get_reg(i_regmap,CCREG);
assert(cc==HOST_CCREG);
emit_addimm_and_set_flags(CLOCK_ADJUST(ccadj[i]+2),cc);
- int jaddr=(int)out;
+ void *jaddr=out;
emit_jns(0);
- add_stub(CC_STUB,jaddr,(int)out,0,i,start+i*4+8,likely[i]?NULLDS:NOTTAKEN,0);
+ add_stub(CC_STUB,jaddr,out,0,i,start+i*4+8,likely[i]?NULLDS:NOTTAKEN,0);
}
}
}
u_int addr;
o = 0;
- for (p = 0; p < sizeof(jump_in) / sizeof(jump_in[0]); p++) {
+ for (p = 0; p < ARRAY_SIZE(jump_in); p++) {
bcnt = 0;
for (head = jump_in[p]; head != NULL; head = head->next) {
tmp_blocks[bcnt].addr = head->vaddr;
invalid_code[start>>12]=0;
emit_movimm(start,0);
emit_writeword(0,(int)&pcaddr);
- emit_jmp((int)new_dyna_leave);
+ emit_jmp(new_dyna_leave);
literal_pool(0);
end_block(beginning);
ll_add_flags(jump_in+page,start,state_rflags,(void *)beginning);
// Stubs
for(i=0;i<stubcount;i++)
{
- switch(stubs[i][0])
+ switch(stubs[i].type)
{
case LOADB_STUB:
case LOADH_STUB: