/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* Mupen64plus - assem_arm.c *
- * Copyright (C) 2009-2010 Ari64 *
+ * Copyright (C) 2009-2011 Ari64 *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
0,
0};
+void invalidate_addr_r0();
+void invalidate_addr_r1();
+void invalidate_addr_r2();
+void invalidate_addr_r3();
+void invalidate_addr_r4();
+void invalidate_addr_r5();
+void invalidate_addr_r6();
+void invalidate_addr_r7();
+void invalidate_addr_r8();
+void invalidate_addr_r9();
+void invalidate_addr_r10();
+void invalidate_addr_r12();
+
+const u_int invalidate_addr_reg[16] = {
+ (int)invalidate_addr_r0,
+ (int)invalidate_addr_r1,
+ (int)invalidate_addr_r2,
+ (int)invalidate_addr_r3,
+ (int)invalidate_addr_r4,
+ (int)invalidate_addr_r5,
+ (int)invalidate_addr_r6,
+ (int)invalidate_addr_r7,
+ (int)invalidate_addr_r8,
+ (int)invalidate_addr_r9,
+ (int)invalidate_addr_r10,
+ 0,
+ (int)invalidate_addr_r12,
+ 0,
+ 0,
+ 0};
+
#include "fpu.h"
unsigned int needs_clear_cache[1<<(TARGET_SIZE_2-17)];
}
u_int genimm(u_int imm,u_int *encoded)
{
- if(imm==0) {*encoded=0;return 1;}
+ *encoded=0;
+ if(imm==0) return 1;
int i=32;
while(i>0)
{
#ifdef FORCE32
if(r&64) {
printf("64bit load in 32bit mode!\n");
- exit(1);
+ assert(0);
+ return;
}
#endif
if((r&63)==0)
#ifdef FORCE32
if(r&64) {
printf("64bit store in 32bit mode!\n");
- exit(1);
+ assert(0);
+ return;
}
#endif
int addr=((int)reg)+((r&63)<<REG_SHIFT)+((r&64)>>4);
output_w32(0xe0800620|rd_rn_rm(rt,rs1,rs2));
}
+void emit_callne(int a)
+{
+ assem_debug("blne %x\n",a);
+ u_int offset=genjmp(a);
+ output_w32(0x1b000000|offset);
+}
+
// Used to preload hash table entries
void emit_prefetch(void *addr)
{
emit_extjump2(addr, target, (int)dyna_linker_ds);
}
+#ifdef PCSX
+#include "pcsxmem_inline.c"
+#endif
+
do_readstub(int n)
{
assem_debug("do_readstub %x\n",start+stubs[n][3]*4);
emit_writeword(rs,(int)&address);
//emit_pusha();
save_regs(reglist);
+#ifndef PCSX
ds=i_regs!=®s[i];
int real_rs=(itype[i]==LOADLR)?-1:get_reg(i_regmap,rs1[i]);
u_int cmask=ds?-1:(0x100f|~i_regs->wasconst);
if(!ds) load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty&~(1<<addr)&(real_rs<0?-1:~(1<<real_rs))&0x100f,i);
wb_dirtys(i_regs->regmap_entry,i_regs->was32,i_regs->wasdirty&cmask&~(1<<addr)&(real_rs<0?-1:~(1<<real_rs)));
if(!ds) wb_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty&~(1<<addr)&(real_rs<0?-1:~(1<<real_rs))&~0x100f,i);
+#endif
emit_shrimm(rs,16,1);
int cc=get_reg(i_regmap,CCREG);
if(cc<0) {
}
emit_movimm(ftable,0);
emit_addimm(cc<0?2:cc,2*stubs[n][6]+2,2);
+#ifndef PCSX
emit_movimm(start+stubs[n][3]*4+(((regs[i].was32>>rs1[i])&1)<<1)+ds,3);
+#endif
//emit_readword((int)&last_count,temp);
//emit_add(cc,temp,cc);
//emit_writeword(cc,(int)&Count);
emit_call((int)&indirect_jump_indexed);
//emit_callreg(rs);
//emit_readword_dualindexedx4(rs,HOST_TEMPREG,15);
+#ifndef PCSX
// We really shouldn't need to update the count here,
// but not doing so causes random crashes...
emit_readword((int)&Count,HOST_TEMPREG);
if(cc<0) {
emit_storereg(CCREG,HOST_TEMPREG);
}
+#endif
//emit_popa();
restore_regs(reglist);
//if((cc=get_reg(regmap,CCREG))>=0) {
ftable=(int)readmemd;
#endif
assert(ftable!=0);
+#ifdef PCSX
+ if(pcsx_direct_read(type,addr,target?rs:-1,rt))
+ return;
+#endif
if(target==0)
emit_movimm(addr,rs);
emit_writeword(rs,(int)&address);
emit_movimm(((u_int *)ftable)[addr>>16],0);
//emit_readword((int)&last_count,12);
emit_addimm(cc<0?2:cc,CLOCK_DIVIDER*(adj+1),2);
+#ifndef PCSX
if((signed int)addr>=(signed int)0xC0000000) {
// Pagefault address
int ds=regmap!=regs[i].regmap;
emit_movimm(start+i*4+(((regs[i].was32>>rs1[i])&1)<<1)+ds,3);
}
+#endif
//emit_add(12,2,2);
//emit_writeword(2,(int)&Count);
//emit_call(((u_int *)ftable)[addr>>16]);
emit_call((int)&indirect_jump);
+#ifndef PCSX
// We really shouldn't need to update the count here,
// but not doing so causes random crashes...
emit_readword((int)&Count,HOST_TEMPREG);
if(cc<0) {
emit_storereg(CCREG,HOST_TEMPREG);
}
+#endif
//emit_popa();
restore_regs(reglist);
if(rt>=0) {
}
//emit_pusha();
save_regs(reglist);
+#ifndef PCSX
ds=i_regs!=®s[i];
int real_rs=get_reg(i_regmap,rs1[i]);
u_int cmask=ds?-1:(0x100f|~i_regs->wasconst);
if(!ds) load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty&~(1<<addr)&(real_rs<0?-1:~(1<<real_rs))&0x100f,i);
wb_dirtys(i_regs->regmap_entry,i_regs->was32,i_regs->wasdirty&cmask&~(1<<addr)&(real_rs<0?-1:~(1<<real_rs)));
if(!ds) wb_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty&~(1<<addr)&(real_rs<0?-1:~(1<<real_rs))&~0x100f,i);
+#endif
emit_shrimm(rs,16,1);
int cc=get_reg(i_regmap,CCREG);
if(cc<0) {
}
emit_movimm(ftable,0);
emit_addimm(cc<0?2:cc,2*stubs[n][6]+2,2);
+#ifndef PCSX
emit_movimm(start+stubs[n][3]*4+(((regs[i].was32>>rs1[i])&1)<<1)+ds,3);
+#endif
//emit_readword((int)&last_count,temp);
//emit_addimm(cc,2*stubs[n][5]+2,cc);
//emit_add(cc,temp,cc);
int rt=get_reg(regmap,target);
assert(rs>=0);
assert(rt>=0);
+#ifdef PCSX
+ if(pcsx_direct_write(type,addr,rs,rt,regmap))
+ return;
+#endif
int ftable=0;
if(type==STOREB_STUB)
ftable=(int)writememb;
emit_movimm(((u_int *)ftable)[addr>>16],0);
//emit_readword((int)&last_count,12);
emit_addimm(cc<0?2:cc,CLOCK_DIVIDER*(adj+1),2);
+#ifndef PCSX
if((signed int)addr>=(signed int)0xC0000000) {
// Pagefault address
int ds=regmap!=regs[i].regmap;
emit_movimm(start+i*4+(((regs[i].was32>>rs1[i])&1)<<1)+ds,3);
}
+#endif
//emit_add(12,2,2);
//emit_writeword(2,(int)&Count);
//emit_call(((u_int *)ftable)[addr>>16]);
emit_writeword(temp2,(int)&address);
save_regs(reglist);
+#ifndef PCSX
ds=i_regs!=®s[i];
real_rs=get_reg(i_regmap,rs1[i]);
u_int cmask=ds?-1:(0x100f|~i_regs->wasconst);
if(!ds) load_all_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty&~(1<<addr)&(real_rs<0?-1:~(1<<real_rs))&0x100f,i);
wb_dirtys(i_regs->regmap_entry,i_regs->was32,i_regs->wasdirty&cmask&~(1<<addr)&(real_rs<0?-1:~(1<<real_rs)));
if(!ds) wb_consts(regs[i].regmap_entry,regs[i].was32,regs[i].wasdirty&~(1<<addr)&(real_rs<0?-1:~(1<<real_rs))&~0x100f,i);
+#endif
emit_shrimm(addr,16,1);
int cc=get_reg(i_regmap,CCREG);
if(cc<0) {
}
emit_movimm((u_int)readmem,0);
emit_addimm(cc<0?2:cc,2*stubs[n][6]+2,2);
- emit_movimm(start+stubs[n][3]*4+(((regs[i].was32>>rs1[i])&1)<<1)+ds,3); // XXX: can be rm'd?
+#ifndef PCSX
+ // pagefault address
+ emit_movimm(start+stubs[n][3]*4+(((regs[i].was32>>rs1[i])&1)<<1)+ds,3);
+#endif
emit_call((int)&indirect_jump_indexed);
restore_regs(reglist);
int s,th,tl,temp,temp2,addr,map=-1;
int offset;
int jaddr=0;
- int memtarget,c=0;
+ int memtarget=0,c=0;
u_int hr,reglist=0;
th=get_reg(i_regs->regmap,rt1[i]|64);
tl=get_reg(i_regs->regmap,rt1[i]);
else addr=s;
if(s>=0) {
c=(i_regs->wasconst>>s)&1;
- memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
- if(using_tlb&&((signed int)(constmap[i][s]+offset))>=(signed int)0xC0000000) memtarget=1;
+ if(c) {
+ memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80000000+RAM_SIZE;
+ if(using_tlb&&((signed int)(constmap[i][s]+offset))>=(signed int)0xC0000000) memtarget=1;
+ }
}
if(!using_tlb) {
if(!c) {
if (gte_handlers[c2op]!=NULL) {
int cc=get_reg(i_regs->regmap,CCREG);
- emit_movimm(source[i],temp); // opcode
+ emit_movimm(source[i],1); // opcode
if (cc>=0&>e_cycletab[c2op])
- emit_addimm(cc,gte_cycletab[c2op]/2,cc); // XXX: cound just adjust ccadj?
- emit_writeword(temp,(int)&psxRegs.code);
+ emit_addimm(cc,gte_cycletab[c2op]/2,cc); // XXX: could just adjust ccadj?
+ emit_addimm(FP,(int)&psxRegs.CP2D.r[0]-(int)&dynarec_local,0); // cop2 regs
+ emit_writeword(1,(int)&psxRegs.code);
emit_call((int)gte_handlers[c2op]);
}