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