aboutsummaryrefslogtreecommitdiff
path: root/libpcsxcore/new_dynarec
diff options
context:
space:
mode:
authornotaz2011-09-20 00:01:39 +0300
committernotaz2011-09-20 00:01:39 +0300
commit76f71c2748608a51e1f9a49273eb3ff58e715700 (patch)
treea3bd4185a1745ac6e6d3e354be512f55377e3e15 /libpcsxcore/new_dynarec
parenteba830cd5dc35bc900ea60d8c06ee582178280a4 (diff)
downloadpcsx_rearmed-76f71c2748608a51e1f9a49273eb3ff58e715700.tar.gz
pcsx_rearmed-76f71c2748608a51e1f9a49273eb3ff58e715700.tar.bz2
pcsx_rearmed-76f71c2748608a51e1f9a49273eb3ff58e715700.zip
drc: make sure dyna_linker is really called from stub
in very rare cases add_link() would end up being called with jump to another block and not stub, which would later cause kill_pointer() to crash while cleaning jump_out. I'm guessing wrong pointer was being picked from jump_in by dyna_linker, failing to detect stale cache, and hoping this will fix it.
Diffstat (limited to 'libpcsxcore/new_dynarec')
-rw-r--r--libpcsxcore/new_dynarec/linkage_arm.s134
-rw-r--r--libpcsxcore/new_dynarec/new_dynarec.c2
2 files changed, 39 insertions, 97 deletions
diff --git a/libpcsxcore/new_dynarec/linkage_arm.s b/libpcsxcore/new_dynarec/linkage_arm.s
index b22d491..ac4929f 100644
--- a/libpcsxcore/new_dynarec/linkage_arm.s
+++ b/libpcsxcore/new_dynarec/linkage_arm.s
@@ -212,11 +212,7 @@ dynarec_local_end = memory_map + 4194304
.endif
.endm
- .text
- .align 2
- .global dyna_linker
- .type dyna_linker, %function
-dyna_linker:
+.macro dyna_linker_main
/* r0 = virtual target address */
/* r1 = instruction to patch */
ldr r3, .jiptr
@@ -234,32 +230,39 @@ dyna_linker:
orrcs r2, r6, #2048
ldr r5, [r3, r2, lsl #2]
lsl r12, r12, #8
+ add r6, r1, r12, asr #6
+ mov r8, #0
/* jump_in lookup */
-.A1:
+1:
movs r4, r5
- beq .A3
+ beq 2f
ldr r3, [r5]
ldr r5, [r4, #12]
teq r3, r0
- bne .A1
+ bne 1b
ldr r3, [r4, #4]
ldr r4, [r4, #8]
tst r3, r3
- bne .A1
-.A2:
- mov r5, r1
- add r1, r1, r12, asr #6
- teq r1, r4
+ bne 1b
+ teq r4, r6
moveq pc, r4 /* Stale i-cache */
+ mov r8, r4
+ b 1b /* jump_in may have dupes, continue search */
+2:
+ tst r8, r8
+ beq 3f /* r0 not in jump_in */
+
+ mov r5, r1
+ mov r1, r6
bl add_link
- sub r2, r4, r5
+ sub r2, r8, r5
and r1, r7, #0xff000000
lsl r2, r2, #6
sub r1, r1, #2
add r1, r1, r2, lsr #8
str r1, [r5]
- mov pc, r4
-.A3:
+ mov pc, r8
+3:
/* hash_table lookup */
cmp r2, #2048
ldr r3, .jdptr
@@ -277,14 +280,14 @@ dyna_linker:
teq r7, r0
ldreq pc, [r6, #12]
/* jump_dirty lookup */
-.A6:
+6:
movs r4, r5
- beq .A8
+ beq 8f
ldr r3, [r5]
ldr r5, [r4, #12]
teq r3, r0
- bne .A6
-.A7:
+ bne 6b
+7:
ldr r1, [r4, #8]
/* hash_table insert */
ldr r2, [r6]
@@ -294,7 +297,18 @@ dyna_linker:
str r2, [r6, #8]
str r3, [r6, #12]
mov pc, r1
-.A8:
+8:
+.endm
+
+ .text
+ .align 2
+ .global dyna_linker
+ .type dyna_linker, %function
+dyna_linker:
+ /* r0 = virtual target address */
+ /* r1 = instruction to patch */
+ dyna_linker_main
+
mov r4, r0
mov r5, r1
bl new_recompile_block
@@ -339,82 +353,8 @@ exec_pagefault:
dyna_linker_ds:
/* r0 = virtual target address */
/* r1 = instruction to patch */
- ldr r3, .jiptr
- /* get_page */
- lsr r2, r0, #12
- mov r6, #4096
- bic r2, r2, #0xe0000
- sub r6, r6, #1
- cmp r2, #0x1000
- ldr r7, [r1]
- biclt r2, #0x0e00
- and r6, r6, r2
- cmp r2, #2048
- add r12, r7, #2
- orrcs r2, r6, #2048
- ldr r5, [r3, r2, lsl #2]
- lsl r12, r12, #8
- /* jump_in lookup */
-.B1:
- movs r4, r5
- beq .B3
- ldr r3, [r5]
- ldr r5, [r4, #12]
- teq r3, r0
- bne .B1
- ldr r3, [r4, #4]
- ldr r4, [r4, #8]
- tst r3, r3
- bne .B1
-.B2:
- mov r5, r1
- add r1, r1, r12, asr #6
- teq r1, r4
- moveq pc, r4 /* Stale i-cache */
- bl add_link
- sub r2, r4, r5
- and r1, r7, #0xff000000
- lsl r2, r2, #6
- sub r1, r1, #2
- add r1, r1, r2, lsr #8
- str r1, [r5]
- mov pc, r4
-.B3:
- /* hash_table lookup */
- cmp r2, #2048
- ldr r3, .jdptr
- eor r4, r0, r0, lsl #16
- lslcc r2, r0, #9
- ldr r6, .htptr
- lsr r4, r4, #12
- lsrcc r2, r2, #21
- bic r4, r4, #15
- ldr r5, [r3, r2, lsl #2]
- ldr r7, [r6, r4]!
- teq r7, r0
- ldreq pc, [r6, #4]
- ldr r7, [r6, #8]
- teq r7, r0
- ldreq pc, [r6, #12]
- /* jump_dirty lookup */
-.B6:
- movs r4, r5
- beq .B8
- ldr r3, [r5]
- ldr r5, [r4, #12]
- teq r3, r0
- bne .B6
-.B7:
- ldr r1, [r4, #8]
- /* hash_table insert */
- ldr r2, [r6]
- ldr r3, [r6, #4]
- str r0, [r6]
- str r1, [r6, #4]
- str r2, [r6, #8]
- str r3, [r6, #12]
- mov pc, r1
-.B8:
+ dyna_linker_main
+
mov r4, r0
bic r0, r0, #7
mov r5, r1
diff --git a/libpcsxcore/new_dynarec/new_dynarec.c b/libpcsxcore/new_dynarec/new_dynarec.c
index a177d88..74451c7 100644
--- a/libpcsxcore/new_dynarec/new_dynarec.c
+++ b/libpcsxcore/new_dynarec/new_dynarec.c
@@ -1240,6 +1240,8 @@ void add_link(u_int vaddr,void *src)
{
u_int page=get_page(vaddr);
inv_debug("add_link: %x -> %x (%d)\n",(int)src,vaddr,page);
+ int *ptr=(int *)(src+4);
+ assert((*ptr&0x0fff0000)==0x059f0000);
ll_add(jump_out+page,vaddr,src);
//int ptr=get_pointer(src);
//inv_debug("add_link: Pointer is to %x\n",(int)ptr);