if(itype[i]==LOADLR) {
hsn[FTEMP]=0;
}
- // Also 64-bit SDL/SDR
- if(opcode[i]==0x2c||opcode[i]==0x2d) {
+ // Also SWL/SWR/SDL/SDR
+ if(opcode[i]==0x2a||opcode[i]==0x2e||opcode[i]==0x2c||opcode[i]==0x2d) {
hsn[FTEMP]=0;
}
// Don't remove the TLB registers either
// Dereference the pointers and remove if it matches
void ll_kill_pointers(struct ll_entry *head,int addr,int shift)
{
+ u_int old_host_addr=0;
while(head) {
int ptr=get_pointer(head->addr);
inv_debug("EXP: Lookup pointer to %x at %x (%x)\n",(int)ptr,(int)head->addr,head->vaddr);
if(((ptr>>shift)==(addr>>shift)) ||
(((ptr-MAX_OUTPUT_BLOCK_SIZE)>>shift)==(addr>>shift)))
{
- inv_debug("EXP: Kill pointer at %x (%x)\n",(int)head->addr,head->vaddr);
- kill_pointer(head->addr);
+ printf("EXP: Kill pointer at %x (%x)\n",(int)head->addr,head->vaddr);
+ u_int host_addr=(u_int)kill_pointer(head->addr);
+
+ if((host_addr>>12)!=(old_host_addr>>12)) {
+ #ifdef __arm__
+ __clear_cache((void *)(old_host_addr&~0xfff),(void *)(old_host_addr|0xfff));
+ #endif
+ old_host_addr=host_addr;
+ }
}
head=head->next;
}
+ #ifdef __arm__
+ if (old_host_addr)
+ __clear_cache((void *)(old_host_addr&~0xfff),(void *)(old_host_addr|0xfff));
+ #endif
}
// This is called when we write to a compiled block (see do_invstub)
-int invalidate_page(u_int page)
+void invalidate_page(u_int page)
{
- int modified=0;
struct ll_entry *head;
struct ll_entry *next;
+ u_int old_host_addr=0;
head=jump_in[page];
jump_in[page]=0;
while(head!=NULL) {
jump_out[page]=0;
while(head!=NULL) {
inv_debug("INVALIDATE: kill pointer to %x (%x)\n",head->vaddr,(int)head->addr);
- kill_pointer(head->addr);
- modified=1;
+ u_int host_addr=(u_int)kill_pointer(head->addr);
+
+ if((host_addr>>12)!=(old_host_addr>>12)) {
+ #ifdef __arm__
+ __clear_cache((void *)(old_host_addr&~0xfff),(void *)(old_host_addr|0xfff));
+ #endif
+ old_host_addr=host_addr;
+ }
next=head->next;
free(head);
head=next;
}
- return modified;
+ #ifdef __arm__
+ if (old_host_addr)
+ __clear_cache((void *)(old_host_addr&~0xfff),(void *)(old_host_addr|0xfff));
+ #endif
}
void invalidate_block(u_int block)
{
- int modified;
u_int page=get_page(block<<12);
u_int vpage=get_vpage(block<<12);
inv_debug("INVALIDATE: %x (%d)\n",block<<12,page);
head=head->next;
}
//printf("first=%d last=%d\n",first,last);
- modified=invalidate_page(page);
+ invalidate_page(page);
assert(first+5>page); // NB: this assumes MAXBLOCK<=4096 (4 pages)
assert(last<page+5);
// Invalidate the adjacent pages if a block crosses a 4K boundary
}
else if(block>=0x80000&&block<0x80800) memory_map[block]=((u_int)rdram-0x80000000)>>2;
#endif
- #ifdef __arm__
- if(modified)
- __clear_cache((void *)BASE_ADDR,(void *)BASE_ADDR+(1<<TARGET_SIZE_2));
- #endif
+
#ifdef USE_MINI_HT
memset(mini_ht,-1,sizeof(mini_ht));
#endif
// On CPUs without 32-bit immediates we need a pointer to invalid_code
else alloc_reg(current,i,INVCP);
#endif
- if(opcode[i]==0x2c||opcode[i]==0x2d) { // 64-bit SDL/SDR
+ if(opcode[i]==0x2a||opcode[i]==0x2e||opcode[i]==0x2c||opcode[i]==0x2d) { // SWL/SWL/SDL/SDR
alloc_reg(current,i,FTEMP);
}
// We need a temporary register for address generation
int s,th,tl,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]);
memtarget=((signed int)(constmap[i][s]+offset))<(signed int)0x80800000;
if(using_tlb&&((signed int)(constmap[i][s]+offset))>=(signed int)0xC0000000) memtarget=1;
}
- if(offset||s<0||c) addr=tl;
- else addr=s;
//printf("load_assemble: c=%d\n",c);
//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) {
+ // could be FIFO, must perform the read
+ assem_debug("(forced read)\n");
+ tl=get_reg(i_regs->regmap,-1);
+ assert(tl>=0);
+ }
+ }
+ if(offset||s<0||c) addr=tl;
+ else addr=s;
+#endif
if(tl>=0) {
//assert(tl>=0);
//assert(rt1[i]);
int case1,case2,case3;
int done0,done1,done2;
int memtarget,c=0;
+ int agr=AGEN1+(i&1);
u_int hr,reglist=0;
th=get_reg(i_regs->regmap,rs2[i]|64);
tl=get_reg(i_regs->regmap,rs2[i]);
s=get_reg(i_regs->regmap,rs1[i]);
- temp=get_reg(i_regs->regmap,-1);
+ temp=get_reg(i_regs->regmap,agr);
+ if(temp<0) temp=get_reg(i_regs->regmap,-1);
offset=imm[i];
if(s>=0) {
c=(i_regs->isconst>>s)&1;
set_jump_target(done0,(int)out);
}
if(!c||!memtarget)
- add_stub(STORELR_STUB,jaddr,(int)out,0,(int)i_regs,rs2[i],ccadj[i],reglist);
+ add_stub(STORELR_STUB,jaddr,(int)out,i,(int)i_regs,temp,ccadj[i],reglist);
}
if(!using_tlb) {
emit_addimm_no_flags((u_int)0x80000000-(u_int)rdram,temp);
#ifdef PCSX
if (Config.HLE && start == 0x80001000) {
// 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);
- emit_jmp((int)new_dyna_leave); // enough??
+ emit_jmp((int)new_dyna_leave);
+#ifdef __arm__
+ __clear_cache((void *)beginning,out);
+#endif
return 0;
}
else if ((u_int)addr < 0x00200000) {
break;
case 3:
// Clear jump_out
- #ifdef __arm__
- if((expirep&2047)==0)
- __clear_cache((void *)BASE_ADDR,(void *)BASE_ADDR+(1<<TARGET_SIZE_2));
- #endif
ll_remove_matching_addrs(jump_out+(expirep&2047),base,shift);
ll_remove_matching_addrs(jump_out+2048+(expirep&2047),base,shift);
break;