{
#ifdef FORCE32
return get_addr(vaddr);
-#endif
+#else
//printf("TRACE: count=%d next=%d (get_addr_32 %x,flags %x)\n",Count,next_interupt,vaddr,flags);
int *ht_bin=hash_table[((vaddr>>16)^vaddr)&0xFFFF];
if(ht_bin[0]==vaddr) return (void *)ht_bin[1];
Context=(Context&0xFF80000F)|((BadVAddr>>9)&0x007FFFF0);
EntryHi=BadVAddr&0xFFFFE000;
return get_addr_ht(0x80000000);
+#endif
}
void clear_all_regs(signed char regmap[])
//if(c) printf("load_assemble: const=%x\n",(int)constmap[i][s]+offset);
// FIXME: Even if the load is a NOP, we should check for pagefaults...
#ifdef PCSX
- if(tl<0) {
- if(!c||(((u_int)constmap[i][s]+offset)>>16)==0x1f80) {
+ if(tl<0&&(!c||(((u_int)constmap[i][s]+offset)>>16)==0x1f80)
+ ||rt1[i]==0) {
// could be FIFO, must perform the read
+ // ||dummy read
assem_debug("(forced read)\n");
tl=get_reg(i_regs->regmap,-1);
assert(tl>=0);
- }
}
+#endif
if(offset||s<0||c) addr=tl;
else addr=s;
-#endif
if(tl>=0) {
//assert(tl>=0);
//assert(rt1[i]);
int s,tl;
int ar;
int offset;
- int c=0;
+ int memtarget=0,c=0;
int jaddr,jaddr2=0,jaddr3,type;
int agr=AGEN1+(i&1);
u_int hr,reglist=0;
} else { // LWC2
ar=tl;
}
+ if(s>=0) c=(i_regs->wasconst>>s)&1;
+ memtarget=c&&(((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE);
if (!offset&&!c&&s>=0) ar=s;
assert(ar>=0);
if (opcode[i]==0x3a) { // SWC2
cop2_get_dreg(copr,tl,HOST_TEMPREG);
+ type=STOREW_STUB;
}
- if(s>=0) c=(i_regs->wasconst>>s)&1;
- if(!c) {
- emit_cmpimm(offset||c||s<0?ar:s,RAM_SIZE);
- jaddr2=(int)out;
- emit_jno(0);
- }
- else if(((signed int)(constmap[i][s]+offset))>=(signed int)0x80000000+RAM_SIZE) {
- jaddr2=(int)out;
- emit_jmp(0); // inline_readstub/inline_writestub? Very rare case
- }
- if (opcode[i]==0x32) { // LWC2
- #ifdef HOST_IMM_ADDR32
- if(c) emit_readword_tlb(constmap[i][s]+offset,-1,tl);
- else
- #endif
- emit_readword_indexed(0,ar,tl);
+ else
type=LOADW_STUB;
+
+ if(c&&!memtarget) {
+ jaddr2=(int)out;
+ emit_jmp(0); // inline_readstub/inline_writestub?
}
- if (opcode[i]==0x3a) { // SWC2
-#ifdef DESTRUCTIVE_SHIFT
- if(!offset&&!c&&s>=0) emit_mov(s,ar);
-#endif
- emit_writeword_indexed(tl,0,ar);
- type=STOREW_STUB;
+ else {
+ if(!c) {
+ emit_cmpimm(offset||c||s<0?ar:s,RAM_SIZE);
+ jaddr2=(int)out;
+ emit_jno(0);
+ }
+ if (opcode[i]==0x32) { // LWC2
+ #ifdef HOST_IMM_ADDR32
+ if(c) emit_readword_tlb(constmap[i][s]+offset,-1,tl);
+ else
+ #endif
+ emit_readword_indexed(0,ar,tl);
+ }
+ if (opcode[i]==0x3a) { // SWC2
+ #ifdef DESTRUCTIVE_SHIFT
+ if(!offset&&!c&&s>=0) emit_mov(s,ar);
+ #endif
+ emit_writeword_indexed(tl,0,ar);
+ }
}
if(jaddr2)
add_stub(type,jaddr2,(int)out,i,ar,(int)i_regs,ccadj[i],reglist);
{
//if(opcode2[i]==0x10||opcode2[i]==0x12) { // MFHI/MFLO
//if(opcode2[i]==0x11||opcode2[i]==0x13) { // MTHI/MTLO
- assert(rt1[i]>0);
+ //assert(rt1[i]>0);
if(rt1[i]) {
signed char sh,sl,th,tl;
th=get_reg(i_regs->regmap,rt1[i]|64);
if(itype[i]==C1LS||itype[i]==C2LS) {
if ((opcode[i]&0x3b)==0x31||(opcode[i]&0x3b)==0x32) // LWC1/LDC1/LWC2/LDC2
ra=get_reg(i_regs->regmap,FTEMP);
- else { // SWC1/SDC1
+ else { // SWC1/SDC1/SWC2/SDC2
ra=get_reg(i_regs->regmap,agr);
if(ra<0) ra=get_reg(i_regs->regmap,-1);
}
#endif
//if(opcode2[i]>=0x10) return; // FIXME (BxxZAL)
- assert(opcode2[i]<0x10||rs1[i]==0); // FIXME (BxxZAL)
+ //assert(opcode2[i]<0x10||rs1[i]==0); // FIXME (BxxZAL)
if(ooo)
if(rs1[i]&&(rs1[i]==rt1[i+1]||rs1[i]==rt2[i+1]))
// First test branch condition, then execute delay slot, then branch
ooo=0;
}
- // TODO: Conditional branches w/link must execute in-order so that
- // condition test and write to r31 occur before cycle count test
+ assert(opcode2[i]<0x10||ooo); // FIXME (BxxZALL)
if(ooo) {
s1l=get_reg(branch_regs[i].regmap,rs1[i]);
if(!only32)
{
assert(s1h>=0);
- if(opcode2[i]==0) // BLTZ
+ if((opcode2[i]&0xf)==0) // BLTZ/BLTZAL
{
emit_test(s1h,s1h);
if(invert){
emit_js(0);
}
}
- if(opcode2[i]==1) // BGEZ
+ if((opcode2[i]&0xf)==1) // BGEZ/BLTZAL
{
emit_test(s1h,s1h);
if(invert){
else
{
assert(s1l>=0);
- if(opcode2[i]==0) // BLTZ
+ if((opcode2[i]&0xf)==0) // BLTZ/BLTZAL
{
emit_test(s1l,s1l);
if(invert){
emit_js(0);
}
}
- if(opcode2[i]==1) // BGEZ
+ if((opcode2[i]&0xf)==1) // BGEZ/BLTZAL
{
emit_test(s1l,s1l);
if(invert){
case FJUMP:
printf (" %x: %s %8x\n",start+i*4,insn[i],ba[i]);break;
case RJUMP:
- if (rt1[i]!=31)
+ if (opcode[i]==0x9&&rt1[i]!=31)
printf (" %x: %s r%d,r%d\n",start+i*4,insn[i],rt1[i],rs1[i]);
else
printf (" %x: %s r%d\n",start+i*4,insn[i],rs1[i]);
start = (u_int)addr&~3;
//assert(((u_int)addr&1)==0);
#ifdef PCSX
- if (Config.HLE && start == 0x80001000) {
+ if (Config.HLE && start == 0x80001000) // hlecall
+ {
// XXX: is this enough? Maybe check hleSoftCall?
u_int beginning=(u_int)out;
u_int page=get_page(start);
- ll_add(jump_in+page,start,out);
invalid_code[start>>12]=0;
emit_movimm(start,0);
emit_writeword(0,(int)&pcaddr);
#ifdef __arm__
__clear_cache((void *)beginning,out);
#endif
+ ll_add(jump_in+page,start,(void *)beginning);
return 0;
}
- else if ((u_int)addr < 0x00200000) {
+ else if ((u_int)addr < 0x00200000 ||
+ (0xa0000000 <= addr && addr < 0xa0200000)) {
// used for BIOS calls mostly?
- source = (u_int *)((u_int)rdram+start-0);
- pagelimit = 0x00200000;
+ source = (u_int *)((u_int)rdram+(start&0x1fffff));
+ pagelimit = (addr&0xa0000000)|0x00200000;
+ }
+ else if (!Config.HLE && (
+/* (0x9fc00000 <= addr && addr < 0x9fc80000) ||*/
+ (0xbfc00000 <= addr && addr < 0xbfc80000))) {
+ // BIOS
+ source = (u_int *)((u_int)psxR+(start&0x7ffff));
+ pagelimit = (addr&0xfff00000)|0x80000;
}
else
#endif
else {
assem_debug("Compile at unmapped memory address: %x \n", (int)addr);
//assem_debug("start: %x next: %x\n",memory_map[start>>12],memory_map[(start+4096)>>12]);
- return 1; // Caller will invoke exception handler
+ return -1; // Caller will invoke exception handler
}
//printf("source= %x\n",(int)source);
}
case 0x02: strcpy(insn[i],"TLBWI"); type=COP0; break;
case 0x06: strcpy(insn[i],"TLBWR"); type=COP0; break;
case 0x08: strcpy(insn[i],"TLBP"); type=COP0; break;
+#ifdef PCSX
+ case 0x10: strcpy(insn[i],"RFE"); type=COP0; break;
+#else
case 0x18: strcpy(insn[i],"ERET"); type=COP0; break;
+#endif
}
}
break;
if (rt1[i]==31) {
alloc_reg(¤t,i,31);
dirty_reg(¤t,31);
- assert(rs1[i+1]!=31&&rs2[i+1]!=31);
+ //assert(rs1[i+1]!=31&&rs2[i+1]!=31);
+ assert(rt1[i+1]!=rt1[i]);
#ifdef REG_PREFETCH
alloc_reg(¤t,i,PTEMP);
#endif
if (rt1[i]!=0) {
alloc_reg(¤t,i,rt1[i]);
dirty_reg(¤t,rt1[i]);
- assert(rs1[i+1]!=31&&rs2[i+1]!=31);
+ //assert(rs1[i+1]!=31&&rs2[i+1]!=31);
+ assert(rt1[i+1]!=rt1[i]);
#ifdef REG_PREFETCH
alloc_reg(¤t,i,PTEMP);
#endif
ds=1;
pagespan_ds();
}
+ u_int instr_addr0_override=0;
+
+#ifdef PCSX
+ if (start == 0x80030000) {
+ // nasty hack for fastbios thing
+ instr_addr0_override=(u_int)out;
+ emit_movimm(start,0);
+ emit_readword((int)&pcaddr,1);
+ emit_writeword(0,(int)&pcaddr);
+ emit_cmp(0,1);
+ emit_jne((int)new_dyna_leave);
+ }
+#endif
for(i=0;i<slen;i++)
{
//if(ds) printf("ds: ");
}
}
+ if (instr_addr0_override)
+ instr_addr[0] = instr_addr0_override;
+
/* Pass 9 - Linker */
for(i=0;i<linkcount;i++)
{