aboutsummaryrefslogtreecommitdiff
path: root/libpcsxcore/new_dynarec
diff options
context:
space:
mode:
authornotaz2011-02-16 21:31:19 +0200
committernotaz2011-02-17 00:48:38 +0200
commitdd3a91a17c7b45c56cde69ff39ea35185f476898 (patch)
tree3806aa27d160d766342b53bb6c0a8d453e4ac6b2 /libpcsxcore/new_dynarec
parent535d208a8473e9255919b1e5bfe0b5aa88f6992a (diff)
downloadpcsx_rearmed-dd3a91a17c7b45c56cde69ff39ea35185f476898.tar.gz
pcsx_rearmed-dd3a91a17c7b45c56cde69ff39ea35185f476898.tar.bz2
pcsx_rearmed-dd3a91a17c7b45c56cde69ff39ea35185f476898.zip
drc: merge Ari64's patch: 07_clear_cache
Diffstat (limited to 'libpcsxcore/new_dynarec')
-rw-r--r--libpcsxcore/new_dynarec/assem_arm.c34
-rw-r--r--libpcsxcore/new_dynarec/new_dynarec.c39
2 files changed, 49 insertions, 24 deletions
diff --git a/libpcsxcore/new_dynarec/assem_arm.c b/libpcsxcore/new_dynarec/assem_arm.c
index ed89bb0..0153bfc 100644
--- a/libpcsxcore/new_dynarec/assem_arm.c
+++ b/libpcsxcore/new_dynarec/assem_arm.c
@@ -68,6 +68,8 @@ const u_int jump_vaddr_reg[16] = {
#include "fpu.h"
+unsigned int needs_clear_cache[1<<(TARGET_SIZE_2-17)];
+
/* Linker */
void set_jump_target(int addr,u_int target)
@@ -4784,6 +4786,38 @@ void wb_invalidate_arm(signed char pre[],signed char entry[],uint64_t dirty,uint
#define wb_invalidate wb_invalidate_arm
*/
+// Clearing the cache is rather slow on ARM Linux, so mark the areas
+// that need to be cleared, and then only clear these areas once.
+void do_clear_cache()
+{
+ int i,j;
+ for (i=0;i<(1<<(TARGET_SIZE_2-17));i++)
+ {
+ u_int bitmap=needs_clear_cache[i];
+ if(bitmap) {
+ u_int start,end;
+ for(j=0;j<32;j++)
+ {
+ if(bitmap&(1<<j)) {
+ start=BASE_ADDR+i*131072+j*4096;
+ end=start+4095;
+ j++;
+ while(j<32) {
+ if(bitmap&(1<<j)) {
+ end+=4096;
+ j++;
+ }else{
+ __clear_cache((void *)start,(void *)end);
+ break;
+ }
+ }
+ }
+ }
+ needs_clear_cache[i]=0;
+ }
+ }
+}
+
// CPU-architecture-specific initialization
void arch_init() {
#ifndef DISABLE_COP1
diff --git a/libpcsxcore/new_dynarec/new_dynarec.c b/libpcsxcore/new_dynarec/new_dynarec.c
index 28a0245..fb6ace4 100644
--- a/libpcsxcore/new_dynarec/new_dynarec.c
+++ b/libpcsxcore/new_dynarec/new_dynarec.c
@@ -1086,7 +1086,6 @@ void ll_clear(struct ll_entry **head)
// 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);
@@ -1095,20 +1094,12 @@ void ll_kill_pointers(struct ll_entry *head,int addr,int shift)
{
inv_debug("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;
- }
+ #ifdef __arm__
+ needs_clear_cache[(host_addr-(u_int)BASE_ADDR)>>17]|=1<<(((host_addr-(u_int)BASE_ADDR)>>12)&31);
+ #endif
}
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)
@@ -1116,7 +1107,6 @@ void invalidate_page(u_int page)
{
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) {
@@ -1131,21 +1121,13 @@ void invalidate_page(u_int page)
while(head!=NULL) {
inv_debug("INVALIDATE: kill pointer to %x (%x)\n",head->vaddr,(int)head->addr);
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;
- }
+ #ifdef __arm__
+ needs_clear_cache[(host_addr-(u_int)BASE_ADDR)>>17]|=1<<(((host_addr-(u_int)BASE_ADDR)>>12)&31);
+ #endif
next=head->next;
free(head);
head=next;
}
- #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)
{
@@ -1192,6 +1174,9 @@ void invalidate_block(u_int block)
for(first=page+1;first<last;first++) {
invalidate_page(first);
}
+ #ifdef __arm__
+ do_clear_cache();
+ #endif
// Don't trap writes
invalid_code[block]=1;
@@ -1216,6 +1201,8 @@ void invalidate_addr(u_int addr)
{
invalidate_block(addr>>12);
}
+// This is called when loading a save state.
+// Anything could have changed, so invalidate everything.
void invalidate_all_pages()
{
u_int page,n;
@@ -11041,6 +11028,10 @@ int new_recompile_block(int addr)
break;
case 3:
// Clear jump_out
+ #ifdef __arm__
+ if((expirep&2047)==0)
+ do_clear_cache();
+ #endif
ll_remove_matching_addrs(jump_out+(expirep&2047),base,shift);
ll_remove_matching_addrs(jump_out+2048+(expirep&2047),base,shift);
break;