#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 mchecksum()
{
- //if(!tracedebug) return 0;
int i;
int sum=0;
for(i=0;i<2097152;i++) {
printf("\n");
}
-void enabletrace()
-{
- tracedebug=1;
-}
-
-void memdebug(int i)
-{
- //printf("TRACE: count=%d next=%d (checksum %x) lo=%8x%8x\n",Count,next_interupt,mchecksum(),(int)(reg[LOREG]>>32),(int)reg[LOREG]);
- //printf("TRACE: count=%d next=%d (rchecksum %x)\n",Count,next_interupt,rchecksum());
- //rlist();
- //if(tracedebug) {
- //if(Count>=-2084597794) {
- if((signed int)Count>=-2084597794&&(signed int)Count<0) {
- //if(0) {
- printf("TRACE: count=%d next=%d (checksum %x)\n",Count,next_interupt,mchecksum());
- //printf("TRACE: count=%d next=%d (checksum %x) Status=%x\n",Count,next_interupt,mchecksum(),Status);
- //printf("TRACE: count=%d next=%d (checksum %x) hi=%8x%8x\n",Count,next_interupt,mchecksum(),(int)(reg[HIREG]>>32),(int)reg[HIREG]);
- rlist();
- #ifdef __i386__
- printf("TRACE: %x\n",(&i)[-1]);
- #endif
- #ifdef __arm__
- int j;
- printf("TRACE: %x \n",(&j)[10]);
- printf("TRACE: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n",(&j)[1],(&j)[2],(&j)[3],(&j)[4],(&j)[5],(&j)[6],(&j)[7],(&j)[8],(&j)[9],(&j)[10],(&j)[11],(&j)[12],(&j)[13],(&j)[14],(&j)[15],(&j)[16],(&j)[17],(&j)[18],(&j)[19],(&j)[20]);
- #endif
- //fflush(stdout);
- }
- //printf("TRACE: %x\n",(&i)[-1]);
-}
-
void alu_assemble(int i,struct regstat *i_regs)
{
if(opcode2[i]>=0x20&&opcode2[i]<=0x23) { // ADD/ADDU/SUB/SUBU
{
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);
}
}
- //emit_storereg(rt1[i],tl); // DEBUG
- //if(opcode[i]==0x23)
- //if(opcode[i]==0x24)
- //if(opcode[i]==0x23||opcode[i]==0x24)
- /*if(opcode[i]==0x21||opcode[i]==0x23||opcode[i]==0x24)
- {
- //emit_pusha();
- save_regs(0x100f);
- emit_readword((int)&last_count,ECX);
- #ifdef __i386__
- if(get_reg(i_regs->regmap,CCREG)<0)
- emit_loadreg(CCREG,HOST_CCREG);
- emit_add(HOST_CCREG,ECX,HOST_CCREG);
- emit_addimm(HOST_CCREG,2*ccadj[i],HOST_CCREG);
- emit_writeword(HOST_CCREG,(int)&Count);
- #endif
- #ifdef __arm__
- if(get_reg(i_regs->regmap,CCREG)<0)
- emit_loadreg(CCREG,0);
- else
- emit_mov(HOST_CCREG,0);
- emit_add(0,ECX,0);
- emit_addimm(0,2*ccadj[i],0);
- emit_writeword(0,(int)&Count);
- #endif
- emit_call((int)memdebug);
- //emit_popa();
- restore_regs(0x100f);
- }*/
}
#ifndef loadlr_assemble
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)
- //if(opcode[i]==0x2B || opcode[i]==0x28)
- //if(opcode[i]==0x2B || opcode[i]==0x29)
- //if(opcode[i]==0x2B)
- /*if(opcode[i]==0x2B || opcode[i]==0x28 || opcode[i]==0x29 || opcode[i]==0x3F)
- {
- #ifdef __i386__
- emit_pusha();
- #endif
- #ifdef __arm__
- save_regs(0x100f);
- #endif
- emit_readword((int)&last_count,ECX);
- #ifdef __i386__
- if(get_reg(i_regs->regmap,CCREG)<0)
- emit_loadreg(CCREG,HOST_CCREG);
- emit_add(HOST_CCREG,ECX,HOST_CCREG);
- emit_addimm(HOST_CCREG,2*ccadj[i],HOST_CCREG);
- emit_writeword(HOST_CCREG,(int)&Count);
- #endif
- #ifdef __arm__
- if(get_reg(i_regs->regmap,CCREG)<0)
- emit_loadreg(CCREG,0);
- else
- emit_mov(HOST_CCREG,0);
- emit_add(0,ECX,0);
- emit_addimm(0,2*ccadj[i],0);
- emit_writeword(0,(int)&Count);
- #endif
- emit_call((int)memdebug);
- #ifdef __i386__
- emit_popa();
- #endif
- #ifdef __arm__
- restore_regs(0x100f);
- #endif
- }*/
}
void storelr_assemble(int i,struct regstat *i_regs)
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
}
- /*
- emit_pusha();
- //save_regs(0x100f);
- emit_readword((int)&last_count,ECX);
- if(get_reg(i_regs->regmap,CCREG)<0)
- emit_loadreg(CCREG,HOST_CCREG);
- emit_add(HOST_CCREG,ECX,HOST_CCREG);
- emit_addimm(HOST_CCREG,2*ccadj[i],HOST_CCREG);
- emit_writeword(HOST_CCREG,(int)&Count);
- emit_call((int)memdebug);
- emit_popa();
- //restore_regs(0x100f);
- */
}
void c1ls_assemble(int i,struct regstat *i_regs)
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
-
- /* This works but uses a lot of memory...
- emit_readword((int)&last_count,ECX);
- emit_add(HOST_CCREG,ECX,EAX);
- emit_writeword(EAX,(int)&Count);
- emit_call((int)gen_interupt);
- emit_readword((int)&Count,HOST_CCREG);
- emit_readword((int)&next_interupt,EAX);
- emit_readword((int)&pending_exception,EBX);
- emit_writeword(EAX,(int)&last_count);
- emit_sub(HOST_CCREG,EAX,HOST_CCREG);
- 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);
- load_all_regs(branch_regs[i].regmap);
- emit_jmp(stubs[n][2]); // 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.
- // This code is executed infrequently and takes up a lot of space
- // so smaller is better.
- emit_storereg(CCREG,HOST_CCREG);
- emit_pushreg(EAX);
- emit_call((int)get_addr_ht);
- emit_loadreg(CCREG,HOST_CCREG);
- emit_addimm(ESP,4,ESP);
- emit_jmpreg(EAX);*/
+ emit_jmp(stubs[n].retaddr);
}
static void add_to_linker(int addr,int target,int ext)
//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);
else
#endif
{
- //if(rs!=EAX) emit_mov(rs,EAX);
- //emit_jmp((int)jump_vaddr_eax);
emit_jmp(jump_vaddr_reg[rs]);
}
- /* Check hash table
- temp=!rs;
- emit_mov(rs,temp);
- emit_shrimm(rs,16,rs);
- emit_xor(temp,rs,rs);
- emit_movzwl_reg(rs,rs);
- emit_shlimm(rs,4,rs);
- emit_cmpmem_indexed((int)hash_table,rs,temp);
- emit_jne((int)out+14);
- emit_readword_indexed((int)hash_table+4,rs,rs);
- emit_jmpreg(rs);
- emit_cmpmem_indexed((int)hash_table+8,rs,temp);
- emit_addimm_no_flags(8,rs);
- emit_jeq((int)out-17);
- // No hit on hash table, call compiler
- emit_pushreg(temp);
-//DEBUG >
-#ifdef DEBUG_CYCLE_COUNT
- emit_readword((int)&last_count,ECX);
- emit_add(HOST_CCREG,ECX,HOST_CCREG);
- emit_readword((int)&next_interupt,ECX);
- emit_writeword(HOST_CCREG,(int)&Count);
- emit_sub(HOST_CCREG,ECX,HOST_CCREG);
- emit_writeword(ECX,(int)&last_count);
-#endif
-//DEBUG <
- emit_storereg(CCREG,HOST_CCREG);
- emit_call((int)get_addr);
- emit_loadreg(CCREG,HOST_CCREG);
- emit_addimm(ESP,4,ESP);
- emit_jmpreg(EAX);*/
#ifdef CORTEX_A8_BRANCH_PREDICTION_HACK
if(rt1[i]!=31&&i<slen-2&&(((u_int)out)&7)) emit_mov(13,13);
#endif
}
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;
u_int state_rflags = 0;
int i;
- assem_debug("NOTCOMPILED: addr = %x -> %x\n", (int)addr, (int)out);
- //printf("NOTCOMPILED: addr = %x -> %x\n", (int)addr, (int)out);
+ assem_debug("NOTCOMPILED: addr = %x -> %p\n", addr, out);
//printf("TRACE: count=%d next=%d (compile %x)\n",Count,next_interupt,addr);
//if(debug)
//printf("TRACE: count=%d next=%d (checksum %x)\n",Count,next_interupt,mchecksum());
//printf("fpu mapping=%x enabled=%x\n",(Status & 0x04000000)>>26,(Status & 0x20000000)>>29);
- /*if(Count>=312978186) {
- rlist();
- }*/
- //rlist();
// this is just for speculation
for (i = 1; i < 32; i++) {
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: