aeb8baa3b08da87de70f9cf865ee583af85ad8a7
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / linkage_arm.s
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  *   Mupen64plus - linkage_arm.s                                           *
3  *   Copyright (C) 2009-2010 Ari64                                         *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
19  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
20         .cpu arm9tdmi
21         .fpu softvfp
22         .eabi_attribute 20, 1
23         .eabi_attribute 21, 1
24         .eabi_attribute 23, 3
25         .eabi_attribute 24, 1
26         .eabi_attribute 25, 1
27         .eabi_attribute 26, 2
28         .eabi_attribute 30, 6
29         .eabi_attribute 18, 4
30         .file   "linkage_arm.s"
31         .global rdram
32 rdram = 0x80000000
33         .global dynarec_local
34         .global reg
35         .global hi
36         .global lo
37         .global reg_cop0
38         .global reg_cop2d
39         .global reg_cop2c
40         .global FCR0
41         .global FCR31
42         .global next_interupt
43         .global cycle_count
44         .global last_count
45         .global pending_exception
46         .global pcaddr
47         .global stop
48         .global invc_ptr
49         .global address
50         .global readmem_dword
51         .global readmem_word
52         .global dword
53         .global word
54         .global hword
55         .global byte
56         .global branch_target
57         .global PC
58         .global mini_ht
59         .global restore_candidate
60         .global memory_map
61         /* psx */
62         .global psxRegs
63         .global psxHLEt_addr
64
65         .bss
66         .align  4
67         .type   dynarec_local, %object
68         .size   dynarec_local, dynarec_local_end-dynarec_local
69 dynarec_local:
70         .space  dynarec_local_end-dynarec_local /*0x400630*/
71 next_interupt = dynarec_local + 64
72         .type   next_interupt, %object
73         .size   next_interupt, 4
74 cycle_count = next_interupt + 4
75         .type   cycle_count, %object
76         .size   cycle_count, 4
77 last_count = cycle_count + 4
78         .type   last_count, %object
79         .size   last_count, 4
80 pending_exception = last_count + 4
81         .type   pending_exception, %object
82         .size   pending_exception, 4
83 stop = pending_exception + 4
84         .type   stop, %object
85         .size   stop, 4
86 invc_ptr = stop + 4
87         .type   invc_ptr, %object
88         .size   invc_ptr, 4
89 address = invc_ptr + 4
90         .type   address, %object
91         .size   address, 4
92 readmem_dword = address + 4
93 readmem_word = readmem_dword
94         .type   readmem_dword, %object
95         .size   readmem_dword, 8
96 dword = readmem_dword + 8
97         .type   dword, %object
98         .size   dword, 8
99 word = dword + 8
100         .type   word, %object
101         .size   word, 4
102 hword = word + 4
103         .type   hword, %object
104         .size   hword, 2
105 byte = hword + 2
106         .type   byte, %object
107         .size   byte, 1 /* 1 byte free */
108 FCR0 = hword + 4
109         .type   FCR0, %object
110         .size   FCR0, 4
111 FCR31 = FCR0 + 4
112         .type   FCR31, %object
113         .size   FCR31, 4
114 reg = FCR31 + 4
115
116 /* psxRegs */
117 psxRegs = reg
118         .type   reg, %object
119         .size   reg, 128
120         .size   psxRegs, psxRegs_end-psxRegs
121 lo = reg + 128
122         .type   lo, %object
123         .size   lo, 4
124 hi = lo + 4
125         .type   hi, %object
126         .size   hi, 4
127 reg_cop0 = hi + 4
128         .type   reg_cop0, %object
129         .size   reg_cop0, 128
130 reg_cop2d = reg_cop0 + 128
131         .type   reg_cop2d, %object
132         .size   reg_cop2d, 128
133 reg_cop2c = reg_cop2d + 128
134         .type   reg_cop2c, %object
135         .size   reg_cop2c, 128
136 PC = reg_cop2c + 128
137 pcaddr = PC
138         .type   PC, %object
139         .size   PC, 4
140 code = PC + 4
141         .type   code, %object
142         .size   code, 4
143 cycle = code + 4
144         .type   cycle, %object
145         .size   cycle, 4
146 interrupt = cycle + 4
147         .type   interrupt, %object
148         .size   interrupt, 4
149 intCycle = interrupt + 4
150         .type   intCycle, %object
151         .size   intCycle, 128
152 psxRegs_end = intCycle + 128
153
154 psxHLEt_addr = psxRegs_end
155         .type   psxHLEt_addr, %object
156         .size   psxHLEt_addr, 4
157 align0 = psxHLEt_addr + 4 /* just for alignment */
158         .type   align0, %object
159         .size   align0, 4
160 branch_target = align0 + 4
161         .type   branch_target, %object
162         .size   branch_target, 4
163 mini_ht = branch_target + 4
164         .type   mini_ht, %object
165         .size   mini_ht, 256
166 restore_candidate = mini_ht + 256
167         .type   restore_candidate, %object
168         .size   restore_candidate, 512
169 memory_map = restore_candidate + 512
170         .type   memory_map, %object
171         .size   memory_map, 4194304
172 dynarec_local_end = memory_map + 4194304
173
174         .text
175         .align  2
176         .global dyna_linker
177         .type   dyna_linker, %function
178 dyna_linker:
179         /* r0 = virtual target address */
180         /* r1 = instruction to patch */
181         mov     r12, r0
182         mov     r6, #4096
183         mov     r2, #0x80000
184         ldr     r3, .jiptr
185         sub     r6, r6, #1
186         ldr     r7, [r1]
187         eor     r2, r2, r12, lsr #12
188         and     r6, r6, r12, lsr #12
189         cmp     r2, #2048
190         add     r12, r7, #2
191         orrcs   r2, r6, #2048
192         ldr     r5, [r3, r2, lsl #2]
193         lsl     r12, r12, #8
194         /* jump_in lookup */
195 .A1:
196         movs    r4, r5
197         beq     .A3
198         ldr     r3, [r5]
199         ldr     r5, [r4, #12]
200         teq     r3, r0
201         bne     .A1
202         ldr     r3, [r4, #4]
203         ldr     r4, [r4, #8]
204         tst     r3, r3
205         bne     .A1
206 .A2:
207         mov     r5, r1
208         add     r1, r1, r12, asr #6
209         teq     r1, r4
210         moveq   pc, r4 /* Stale i-cache */
211         bl      add_link
212         sub     r2, r4, r5
213         and     r1, r7, #0xff000000
214         lsl     r2, r2, #6
215         sub     r1, r1, #2
216         add     r1, r1, r2, lsr #8
217         str     r1, [r5]
218         mov     pc, r4
219 .A3:
220         /* hash_table lookup */
221         cmp     r2, #2048
222         ldr     r3, .jdptr
223         eor     r4, r0, r0, lsl #16
224         lslcc   r2, r0, #9
225         ldr     r6, .htptr
226         lsr     r4, r4, #12
227         lsrcc   r2, r2, #21
228         bic     r4, r4, #15
229         ldr     r5, [r3, r2, lsl #2]
230         ldr     r7, [r6, r4]!
231         teq     r7, r0
232         ldreq   pc, [r6, #4]
233         ldr     r7, [r6, #8]
234         teq     r7, r0
235         ldreq   pc, [r6, #12]
236         /* jump_dirty lookup */
237 .A6:
238         movs    r4, r5
239         beq     .A8
240         ldr     r3, [r5]
241         ldr     r5, [r4, #12]
242         teq     r3, r0
243         bne     .A6
244 .A7:
245         ldr     r1, [r4, #8]
246         /* hash_table insert */
247         ldr     r2, [r6]
248         ldr     r3, [r6, #4]
249         str     r0, [r6]
250         str     r1, [r6, #4]
251         str     r2, [r6, #8]
252         str     r3, [r6, #12]
253         mov     pc, r1
254 .A8:
255         mov     r4, r0
256         mov     r5, r1
257         bl      new_recompile_block
258         tst     r0, r0
259         mov     r0, r4
260         mov     r1, r5
261         beq     dyna_linker
262         /* pagefault */
263         mov     r1, r0
264         mov     r2, #8
265         .size   dyna_linker, .-dyna_linker
266         .global exec_pagefault
267         .type   exec_pagefault, %function
268 exec_pagefault:
269         /* r0 = instruction pointer */
270         /* r1 = fault address */
271         /* r2 = cause */
272         ldr     r3, [fp, #reg_cop0+48-dynarec_local] /* Status */
273         mvn     r6, #0xF000000F
274         ldr     r4, [fp, #reg_cop0+16-dynarec_local] /* Context */
275         bic     r6, r6, #0x0F800000
276         str     r0, [fp, #reg_cop0+56-dynarec_local] /* EPC */
277         orr     r3, r3, #2
278         str     r1, [fp, #reg_cop0+32-dynarec_local] /* BadVAddr */
279         bic     r4, r4, r6
280         str     r3, [fp, #reg_cop0+48-dynarec_local] /* Status */
281         and     r5, r6, r1, lsr #9
282         str     r2, [fp, #reg_cop0+52-dynarec_local] /* Cause */
283         and     r1, r1, r6, lsl #9
284         str     r1, [fp, #reg_cop0+40-dynarec_local] /* EntryHi */
285         orr     r4, r4, r5
286         str     r4, [fp, #reg_cop0+16-dynarec_local] /* Context */
287         mov     r0, #0x80000000
288         bl      get_addr_ht
289         mov     pc, r0
290         .size   exec_pagefault, .-exec_pagefault
291
292 /* Special dynamic linker for the case where a page fault
293    may occur in a branch delay slot */
294         .global dyna_linker_ds
295         .type   dyna_linker_ds, %function
296 dyna_linker_ds:
297         /* r0 = virtual target address */
298         /* r1 = instruction to patch */
299         mov     r12, r0
300         mov     r6, #4096
301         mov     r2, #0x80000
302         ldr     r3, .jiptr
303         sub     r6, r6, #1
304         ldr     r7, [r1]
305         eor     r2, r2, r12, lsr #12
306         and     r6, r6, r12, lsr #12
307         cmp     r2, #2048
308         add     r12, r7, #2
309         orrcs   r2, r6, #2048
310         ldr     r5, [r3, r2, lsl #2]
311         lsl     r12, r12, #8
312         /* jump_in lookup */
313 .B1:
314         movs    r4, r5
315         beq     .B3
316         ldr     r3, [r5]
317         ldr     r5, [r4, #12]
318         teq     r3, r0
319         bne     .B1
320         ldr     r3, [r4, #4]
321         ldr     r4, [r4, #8]
322         tst     r3, r3
323         bne     .B1
324 .B2:
325         mov     r5, r1
326         add     r1, r1, r12, asr #6
327         teq     r1, r4
328         moveq   pc, r4 /* Stale i-cache */
329         bl      add_link
330         sub     r2, r4, r5
331         and     r1, r7, #0xff000000
332         lsl     r2, r2, #6
333         sub     r1, r1, #2
334         add     r1, r1, r2, lsr #8
335         str     r1, [r5]
336         mov     pc, r4
337 .B3:
338         /* hash_table lookup */
339         cmp     r2, #2048
340         ldr     r3, .jdptr
341         eor     r4, r0, r0, lsl #16
342         lslcc   r2, r0, #9
343         ldr     r6, .htptr
344         lsr     r4, r4, #12
345         lsrcc   r2, r2, #21
346         bic     r4, r4, #15
347         ldr     r5, [r3, r2, lsl #2]
348         ldr     r7, [r6, r4]!
349         teq     r7, r0
350         ldreq   pc, [r6, #4]
351         ldr     r7, [r6, #8]
352         teq     r7, r0
353         ldreq   pc, [r6, #12]
354         /* jump_dirty lookup */
355 .B6:
356         movs    r4, r5
357         beq     .B8
358         ldr     r3, [r5]
359         ldr     r5, [r4, #12]
360         teq     r3, r0
361         bne     .B6
362 .B7:
363         ldr     r1, [r4, #8]
364         /* hash_table insert */
365         ldr     r2, [r6]
366         ldr     r3, [r6, #4]
367         str     r0, [r6]
368         str     r1, [r6, #4]
369         str     r2, [r6, #8]
370         str     r3, [r6, #12]
371         mov     pc, r1
372 .B8:
373         mov     r4, r0
374         bic     r0, r0, #7
375         mov     r5, r1
376         orr     r0, r0, #1
377         bl      new_recompile_block
378         tst     r0, r0
379         mov     r0, r4
380         mov     r1, r5
381         beq     dyna_linker_ds
382         /* pagefault */
383         bic     r1, r0, #7
384         mov     r2, #0x80000008 /* High bit set indicates pagefault in delay slot */
385         sub     r0, r1, #4
386         b       exec_pagefault
387         .size   dyna_linker_ds, .-dyna_linker_ds
388 .jiptr:
389         .word   jump_in
390 .jdptr:
391         .word   jump_dirty
392 .htptr:
393         .word   hash_table
394
395         .align  2
396         .global jump_vaddr_r0
397         .type   jump_vaddr_r0, %function
398 jump_vaddr_r0:
399         eor     r2, r0, r0, lsl #16
400         b       jump_vaddr
401         .size   jump_vaddr_r0, .-jump_vaddr_r0
402         .global jump_vaddr_r1
403         .type   jump_vaddr_r1, %function
404 jump_vaddr_r1:
405         eor     r2, r1, r1, lsl #16
406         mov     r0, r1
407         b       jump_vaddr
408         .size   jump_vaddr_r1, .-jump_vaddr_r1
409         .global jump_vaddr_r2
410         .type   jump_vaddr_r2, %function
411 jump_vaddr_r2:
412         mov     r0, r2
413         eor     r2, r2, r2, lsl #16
414         b       jump_vaddr
415         .size   jump_vaddr_r2, .-jump_vaddr_r2
416         .global jump_vaddr_r3
417         .type   jump_vaddr_r3, %function
418 jump_vaddr_r3:
419         eor     r2, r3, r3, lsl #16
420         mov     r0, r3
421         b       jump_vaddr
422         .size   jump_vaddr_r3, .-jump_vaddr_r3
423         .global jump_vaddr_r4
424         .type   jump_vaddr_r4, %function
425 jump_vaddr_r4:
426         eor     r2, r4, r4, lsl #16
427         mov     r0, r4
428         b       jump_vaddr
429         .size   jump_vaddr_r4, .-jump_vaddr_r4
430         .global jump_vaddr_r5
431         .type   jump_vaddr_r5, %function
432 jump_vaddr_r5:
433         eor     r2, r5, r5, lsl #16
434         mov     r0, r5
435         b       jump_vaddr
436         .size   jump_vaddr_r5, .-jump_vaddr_r5
437         .global jump_vaddr_r6
438         .type   jump_vaddr_r6, %function
439 jump_vaddr_r6:
440         eor     r2, r6, r6, lsl #16
441         mov     r0, r6
442         b       jump_vaddr
443         .size   jump_vaddr_r6, .-jump_vaddr_r6
444         .global jump_vaddr_r8
445         .type   jump_vaddr_r8, %function
446 jump_vaddr_r8:
447         eor     r2, r8, r8, lsl #16
448         mov     r0, r8
449         b       jump_vaddr
450         .size   jump_vaddr_r8, .-jump_vaddr_r8
451         .global jump_vaddr_r9
452         .type   jump_vaddr_r9, %function
453 jump_vaddr_r9:
454         eor     r2, r9, r9, lsl #16
455         mov     r0, r9
456         b       jump_vaddr
457         .size   jump_vaddr_r9, .-jump_vaddr_r9
458         .global jump_vaddr_r10
459         .type   jump_vaddr_r10, %function
460 jump_vaddr_r10:
461         eor     r2, r10, r10, lsl #16
462         mov     r0, r10
463         b       jump_vaddr
464         .size   jump_vaddr_r10, .-jump_vaddr_r10
465         .global jump_vaddr_r12
466         .type   jump_vaddr_r12, %function
467 jump_vaddr_r12:
468         eor     r2, r12, r12, lsl #16
469         mov     r0, r12
470         b       jump_vaddr
471         .size   jump_vaddr_r12, .-jump_vaddr_r12
472         .global jump_vaddr_r7
473         .type   jump_vaddr_r7, %function
474 jump_vaddr_r7:
475         eor     r2, r7, r7, lsl #16
476         add     r0, r7, #0
477         .size   jump_vaddr_r7, .-jump_vaddr_r7
478         .global jump_vaddr
479         .type   jump_vaddr, %function
480 jump_vaddr:
481         ldr     r1, .htptr
482         mvn     r3, #15
483         and     r2, r3, r2, lsr #12
484         ldr     r2, [r1, r2]!
485         teq     r2, r0
486         ldreq   pc, [r1, #4]
487         ldr     r2, [r1, #8]
488         teq     r2, r0
489         ldreq   pc, [r1, #12]
490         str     r10, [fp, #cycle_count-dynarec_local]
491         bl      get_addr
492         ldr     r10, [fp, #cycle_count-dynarec_local]
493         mov     pc, r0
494         .size   jump_vaddr, .-jump_vaddr
495
496         .align  2
497         .global verify_code_ds
498         .type   verify_code_ds, %function
499 verify_code_ds:
500         str     r8, [fp, #branch_target-dynarec_local]
501         .size   verify_code_ds, .-verify_code_ds
502         .global verify_code_vm
503         .type   verify_code_vm, %function
504 verify_code_vm:
505         .global verify_code
506         .type   verify_code, %function
507 verify_code:
508         /* r1 = source */
509         /* r2 = target */
510         /* r3 = length */
511         tst     r3, #4
512         mov     r4, #0
513         add     r3, r1, r3
514         mov     r5, #0
515         ldrne   r4, [r1], #4
516         mov     r12, #0
517         ldrne   r5, [r2], #4
518         teq     r1, r3
519         beq     .D3
520 .D2:
521         ldr     r7, [r1], #4
522         eor     r9, r4, r5
523         ldr     r8, [r2], #4
524         orrs    r9, r9, r12
525         bne     .D4
526         ldr     r4, [r1], #4
527         eor     r12, r7, r8
528         ldr     r5, [r2], #4
529         cmp     r1, r3
530         bcc     .D2
531         teq     r7, r8
532 .D3:
533         teqeq   r4, r5
534 .D4:
535         ldr     r8, [fp, #branch_target-dynarec_local]
536         moveq   pc, lr
537 .D5:
538         bl      get_addr
539         mov     pc, r0
540         .size   verify_code, .-verify_code
541         .size   verify_code_vm, .-verify_code_vm
542
543         .align  2
544         .global cc_interrupt
545         .type   cc_interrupt, %function
546 cc_interrupt:
547         ldr     r0, [fp, #last_count-dynarec_local]
548         mov     r1, #0
549         mov     r2, #0x1fc
550         add     r10, r0, r10
551         str     r1, [fp, #pending_exception-dynarec_local]
552         and     r2, r2, r10, lsr #17
553         add     r3, fp, #restore_candidate-dynarec_local
554         str     r10, [fp, #cycle-dynarec_local] /* PCSX cycles */
555 @@      str     r10, [fp, #reg_cop0+36-dynarec_local] /* Count */
556         ldr     r4, [r2, r3]
557         mov     r10, lr
558         tst     r4, r4
559         bne     .E4
560 .E1:
561         bl      gen_interupt
562         mov     lr, r10
563         ldr     r10, [fp, #cycle-dynarec_local]
564         ldr     r0, [fp, #next_interupt-dynarec_local]
565         ldr     r1, [fp, #pending_exception-dynarec_local]
566         ldr     r2, [fp, #stop-dynarec_local]
567         str     r0, [fp, #last_count-dynarec_local]
568         sub     r10, r10, r0
569         tst     r2, r2
570         bne     .E3
571         tst     r1, r1
572         moveq   pc, lr
573 .E2:
574         ldr     r0, [fp, #pcaddr-dynarec_local]
575         bl      get_addr_ht
576         mov     pc, r0
577 .E3:
578         add     r12, fp, #28
579         ldmia   r12, {r4, r5, r6, r7, r8, r9, sl, fp, pc}
580 .E4:
581         /* Move 'dirty' blocks to the 'clean' list */
582         lsl     r5, r2, #3
583         str     r1, [r2, r3]
584 .E5:
585         lsrs    r4, r4, #1
586         mov     r0, r5
587         add     r5, r5, #1
588         blcs    clean_blocks
589         tst     r5, #31
590         bne     .E5
591         b       .E1
592         .size   cc_interrupt, .-cc_interrupt
593
594         .align  2
595         .global do_interrupt
596         .type   do_interrupt, %function
597 do_interrupt:
598         ldr     r0, [fp, #pcaddr-dynarec_local]
599         bl      get_addr_ht
600         ldr     r1, [fp, #next_interupt-dynarec_local]
601         ldr     r10, [fp, #cycle-dynarec_local]
602         str     r1, [fp, #last_count-dynarec_local]
603         sub     r10, r10, r1
604         add     r10, r10, #2
605         mov     pc, r0
606         .size   do_interrupt, .-do_interrupt
607         .align  2
608         .global fp_exception
609         .type   fp_exception, %function
610 fp_exception:
611         mov     r2, #0x10000000
612 .E7:
613         ldr     r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
614         mov     r3, #0x80000000
615         str     r0, [fp, #reg_cop0+56-dynarec_local] /* EPC */
616         orr     r1, #2
617         add     r2, r2, #0x2c
618         str     r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
619         str     r2, [fp, #reg_cop0+52-dynarec_local] /* Cause */
620         add     r0, r3, #0x80
621         bl      get_addr_ht
622         mov     pc, r0
623         .size   fp_exception, .-fp_exception
624         .align  2
625         .global fp_exception_ds
626         .type   fp_exception_ds, %function
627 fp_exception_ds:
628         mov     r2, #0x90000000 /* Set high bit if delay slot */
629         b       .E7
630         .size   fp_exception_ds, .-fp_exception_ds
631
632         .align  2
633         .global jump_syscall
634         .type   jump_syscall, %function
635 jump_syscall:
636         ldr     r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
637         mov     r3, #0x80000000
638         str     r0, [fp, #reg_cop0+56-dynarec_local] /* EPC */
639         orr     r1, #2
640         mov     r2, #0x20
641         str     r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
642         str     r2, [fp, #reg_cop0+52-dynarec_local] /* Cause */
643         add     r0, r3, #0x80
644         bl      get_addr_ht
645         mov     pc, r0
646         .size   jump_syscall, .-jump_syscall
647         .align  2
648
649         .align  2
650         .global jump_syscall_hle
651         .type   jump_syscall_hle, %function
652 jump_syscall_hle:
653         str     r0, [fp, #pcaddr-dynarec_local] /* PC must be set to EPC for psxException */
654         ldr     r2, [fp, #last_count-dynarec_local]
655         mov     r1, #0    /* in delay slot */
656         add     r2, r2, r10
657         mov     r0, #0x20 /* cause */
658         str     r2, [fp, #cycle-dynarec_local] /* PCSX cycle counter */
659         bl      psxException
660
661         /* note: psxException might do recorsive recompiler call from it's HLE code,
662          * so be ready for this */
663 pcsx_return:
664         ldr     r1, [fp, #next_interupt-dynarec_local]
665         ldr     r10, [fp, #cycle-dynarec_local]
666         ldr     r0, [fp, #pcaddr-dynarec_local]
667         sub     r10, r10, r1
668         str     r1, [fp, #last_count-dynarec_local]
669         bl      get_addr_ht
670         mov     pc, r0
671         .size   jump_syscall_hle, .-jump_syscall_hle
672
673         .align  2
674         .global jump_hlecall
675         .type   jump_hlecall, %function
676 jump_hlecall:
677         ldr     r2, [fp, #last_count-dynarec_local]
678         str     r0, [fp, #pcaddr-dynarec_local]
679         and     r1, r1, #7
680         add     r2, r2, r10
681         ldr     r3, [fp, #psxHLEt_addr-dynarec_local] /* psxHLEt */
682         str     r2, [fp, #cycle-dynarec_local] /* PCSX cycle counter */
683         adr     lr, pcsx_return
684         ldr     pc, [r3, r1, lsl #2] @ FIXME
685         .size   jump_hlecall, .-jump_hlecall
686
687 new_dyna_leave:
688         .align  2
689         .global new_dyna_leave
690         .type   new_dyna_leave, %function
691         ldr     r0, [fp, #last_count-dynarec_local]
692         add     r12, fp, #28
693         add     r10, r0, r10
694         str     r10, [fp, #cycle-dynarec_local]
695         ldmia   r12, {r4, r5, r6, r7, r8, r9, sl, fp, pc}
696         .size   new_dyna_leave, .-new_dyna_leave
697
698         /* these are used to call memhandlers */
699         .align  2
700         .global indirect_jump_indexed
701         .type   indirect_jump_indexed, %function
702 indirect_jump_indexed:
703         ldr     r0, [r0, r1, lsl #2]
704         .global indirect_jump
705         .type   indirect_jump, %function
706 indirect_jump:
707         ldr     r12, [fp, #last_count-dynarec_local]
708         add     r2, r2, r12 
709         str     r2, [fp, #cycle-dynarec_local]
710         mov     pc, r0
711         .size   indirect_jump, .-indirect_jump
712         .size   indirect_jump_indexed, .-indirect_jump_indexed
713
714         .align  2
715         .global jump_eret
716         .type   jump_eret, %function
717 jump_eret:
718         ldr     r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
719         ldr     r0, [fp, #last_count-dynarec_local]
720         bic     r1, r1, #2
721         add     r10, r0, r10
722         str     r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
723         str     r10, [fp, #cycle-dynarec_local]
724         bl      check_interupt
725         ldr     r1, [fp, #next_interupt-dynarec_local]
726         ldr     r0, [fp, #reg_cop0+56-dynarec_local] /* EPC */
727         str     r1, [fp, #last_count-dynarec_local]
728         subs    r10, r10, r1
729         bpl     .E11
730 .E8:
731         bl      get_addr
732         mov     pc, r0
733 .E11:
734         str     r0, [fp, #pcaddr-dynarec_local]
735         bl      cc_interrupt
736         ldr     r0, [fp, #pcaddr-dynarec_local]
737         b       .E8
738         .size   jump_eret, .-jump_eret
739
740         .align  2
741         .global new_dyna_start
742         .type   new_dyna_start, %function
743 new_dyna_start:
744         ldr     r12, .dlptr
745         stmia   r12, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
746         sub     fp, r12, #28
747         ldr     r0, [fp, #pcaddr-dynarec_local]
748         /*bl    new_recompile_block*/
749         bl      get_addr_ht
750         ldr     r1, [fp, #next_interupt-dynarec_local]
751         ldr     r10, [fp, #cycle-dynarec_local]
752         str     r1, [fp, #last_count-dynarec_local]
753         sub     r10, r10, r1
754         mov     pc, r0
755 .dlptr:
756         .word   dynarec_local+28
757         .size   new_dyna_start, .-new_dyna_start
758
759         .align  2
760         .global write_rdram_new
761         .type   write_rdram_new, %function
762 write_rdram_new:
763         ldr     r2, [fp, #address-dynarec_local]
764         ldr     r0, [fp, #word-dynarec_local]
765         str     r0, [r2]
766         b       .E12
767         .size   write_rdram_new, .-write_rdram_new
768         .align  2
769         .global write_rdramb_new
770         .type   write_rdramb_new, %function
771 write_rdramb_new:
772         ldr     r2, [fp, #address-dynarec_local]
773         ldrb    r0, [fp, #byte-dynarec_local]
774         eor     r2, r2, #3
775         strb    r0, [r2]
776         b       .E12
777         .size   write_rdramb_new, .-write_rdramb_new
778         .align  2
779         .global write_rdramh_new
780         .type   write_rdramh_new, %function
781 write_rdramh_new:
782         ldr     r2, [fp, #address-dynarec_local]
783         ldrh    r0, [fp, #hword-dynarec_local]
784         eor     r2, r2, #2
785         strh    r0, [r2]
786         b       .E12
787         .size   write_rdramh_new, .-write_rdramh_new
788
789         .align  2
790         .global do_invalidate
791         .type   do_invalidate, %function
792 do_invalidate:
793         ldr     r2, [fp, #address-dynarec_local]
794 .E12:
795         ldr     r1, [fp, #invc_ptr-dynarec_local]
796         lsr     r0, r2, #12
797         ldrb    r2, [r1, r0]
798         tst     r2, r2
799         beq     invalidate_block
800         mov     pc, lr
801         .size   do_invalidate, .-do_invalidate
802
803         .align  2
804         .global read_nomem_new
805         .type   read_nomem_new, %function
806 /*read_nomem_new:*/
807 read_nomemb_new:
808 read_nomemh_new:
809 read_nomemd_new:
810         /* should never happen */
811         b       read_nomem_new
812 /*
813         ldr     r2, [fp, #address-dynarec_local]
814         add     r12, fp, #memory_map-dynarec_local
815         lsr     r0, r2, #12
816         ldr     r12, [r12, r0, lsl #2]
817         mov     r1, #8
818         tst     r12, r12
819         bmi     tlb_exception
820         ldr     r0, [r2, r12, lsl #2]
821         str     r0, [fp, #readmem_dword-dynarec_local]
822         mov     pc, lr
823 */
824         .size   read_nomem_new, .-read_nomem_new
825 /*
826         .align  2
827         .global read_nomemb_new
828         .type   read_nomemb_new, %function
829 write_nomem_new:
830         str     r3, [fp, #24]
831         str     lr, [fp, #28]
832         bl      do_invalidate
833         ldr     r2, [fp, #address-dynarec_local]
834         add     r12, fp, #memory_map-dynarec_local
835         ldr     lr, [fp, #28]
836         lsr     r0, r2, #12
837         ldr     r3, [fp, #24]
838         ldr     r12, [r12, r0, lsl #2]
839         mov     r1, #0xc
840         tst     r12, #0x40000000
841         bne     tlb_exception
842         ldr     r0, [fp, #word-dynarec_local]
843         str     r0, [r2, r12, lsl #2]
844         mov     pc, lr
845         .size   write_nomem_new, .-write_nomem_new
846
847         .align  2
848         .global write_nomemb_new
849         .type   write_nomemb_new, %function
850 write_nomemb_new:
851         str     r3, [fp, #24]
852         str     lr, [fp, #28]
853         bl      do_invalidate
854         ldr     r2, [fp, #address-dynarec_local]
855         add     r12, fp, #memory_map-dynarec_local
856         ldr     lr, [fp, #28]
857         lsr     r0, r2, #12
858         ldr     r3, [fp, #24]
859         ldr     r12, [r12, r0, lsl #2]
860         mov     r1, #0xc
861         tst     r12, #0x40000000
862         bne     tlb_exception
863         eor     r2, r2, #3
864         ldrb    r0, [fp, #byte-dynarec_local]
865         strb    r0, [r2, r12, lsl #2]
866         mov     pc, lr
867         .size   write_nomemb_new, .-write_nomemb_new
868
869         .align  2
870         .global write_nomemh_new
871         .type   write_nomemh_new, %function
872 write_nomemh_new:
873         str     r3, [fp, #24]
874         str     lr, [fp, #28]
875         bl      do_invalidate
876         ldr     r2, [fp, #address-dynarec_local]
877         add     r12, fp, #memory_map-dynarec_local
878         ldr     lr, [fp, #28]
879         lsr     r0, r2, #12
880         ldr     r3, [fp, #24]
881         ldr     r12, [r12, r0, lsl #2]
882         mov     r1, #0xc
883         lsls    r12, #2
884         bcs     tlb_exception
885         eor     r2, r2, #2
886         ldrh    r0, [fp, #hword-dynarec_local]
887         strh    r0, [r2, r12]
888         mov     pc, lr
889         .size   write_nomemh_new, .-write_nomemh_new
890 */
891         .align  2
892         .global breakpoint
893         .type   breakpoint, %function
894 breakpoint:
895         /* Set breakpoint here for debugging */
896         mov     pc, lr
897         .size   breakpoint, .-breakpoint
898         .section        .note.GNU-stack,"",%progbits