drc: handle invalidate on clear() calls and reset
[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         ldr     r0, [fp, #pcaddr-dynarec_local]
591         bl      get_addr_ht
592         ldr     r1, [fp, #next_interupt-dynarec_local]
593         ldr     r10, [fp, #cycle-dynarec_local]
594         str     r1, [fp, #last_count-dynarec_local]
595         sub     r10, r10, r1
596         add     r10, r10, #2
597         mov     pc, r0
598         .size   do_interrupt, .-do_interrupt
599         .align  2
600         .global fp_exception
601         .type   fp_exception, %function
602 fp_exception:
603         mov     r2, #0x10000000
604 .E7:
605         ldr     r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
606         mov     r3, #0x80000000
607         str     r0, [fp, #reg_cop0+56-dynarec_local] /* EPC */
608         orr     r1, #2
609         add     r2, r2, #0x2c
610         str     r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
611         str     r2, [fp, #reg_cop0+52-dynarec_local] /* Cause */
612         add     r0, r3, #0x80
613         bl      get_addr_ht
614         mov     pc, r0
615         .size   fp_exception, .-fp_exception
616         .align  2
617         .global fp_exception_ds
618         .type   fp_exception_ds, %function
619 fp_exception_ds:
620         mov     r2, #0x90000000 /* Set high bit if delay slot */
621         b       .E7
622         .size   fp_exception_ds, .-fp_exception_ds
623
624         .align  2
625         .global jump_syscall
626         .type   jump_syscall, %function
627 jump_syscall:
628         ldr     r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
629         mov     r3, #0x80000000
630         str     r0, [fp, #reg_cop0+56-dynarec_local] /* EPC */
631         orr     r1, #2
632         mov     r2, #0x20
633         str     r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
634         str     r2, [fp, #reg_cop0+52-dynarec_local] /* Cause */
635         add     r0, r3, #0x80
636         bl      get_addr_ht
637         mov     pc, r0
638         .size   jump_syscall, .-jump_syscall
639         .align  2
640
641         .align  2
642         .global jump_syscall_hle
643         .type   jump_syscall_hle, %function
644 jump_syscall_hle:
645         str     r0, [fp, #pcaddr-dynarec_local] /* PC must be set to EPC for psxException */
646         ldr     r2, [fp, #last_count-dynarec_local]
647         mov     r1, #0    /* in delay slot */
648         add     r2, r2, r10
649         mov     r0, #0x20 /* cause */
650         str     r2, [fp, #cycle-dynarec_local] /* PCSX cycle counter */
651         bl      psxException
652
653         /* note: psxException might do recorsive recompiler call from it's HLE code,
654          * so be ready for this */
655 pcsx_return:
656         ldr     r1, [fp, #next_interupt-dynarec_local]
657         ldr     r10, [fp, #cycle-dynarec_local]
658         ldr     r0, [fp, #pcaddr-dynarec_local]
659         sub     r10, r10, r1
660         str     r1, [fp, #last_count-dynarec_local]
661         bl      get_addr_ht
662         mov     pc, r0
663         .size   jump_syscall_hle, .-jump_syscall_hle
664
665         .align  2
666         .global jump_hlecall
667         .type   jump_hlecall, %function
668 jump_hlecall:
669         ldr     r2, [fp, #last_count-dynarec_local]
670         str     r0, [fp, #pcaddr-dynarec_local]
671         add     r2, r2, r10
672         str     r2, [fp, #cycle-dynarec_local] /* PCSX cycle counter */
673         adr     lr, pcsx_return
674         bx      r1
675         .size   jump_hlecall, .-jump_hlecall
676
677 new_dyna_leave:
678         .align  2
679         .global new_dyna_leave
680         .type   new_dyna_leave, %function
681         ldr     r0, [fp, #last_count-dynarec_local]
682         add     r12, fp, #28
683         add     r10, r0, r10
684         str     r10, [fp, #cycle-dynarec_local]
685         ldmfd   sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, pc}
686         .size   new_dyna_leave, .-new_dyna_leave
687
688         /* these are used to call memhandlers */
689         .align  2
690         .global indirect_jump_indexed
691         .type   indirect_jump_indexed, %function
692 indirect_jump_indexed:
693         ldr     r0, [r0, r1, lsl #2]
694         .global indirect_jump
695         .type   indirect_jump, %function
696 indirect_jump:
697         ldr     r12, [fp, #last_count-dynarec_local]
698         add     r2, r2, r12 
699         str     r2, [fp, #cycle-dynarec_local]
700         mov     pc, r0
701         .size   indirect_jump, .-indirect_jump
702         .size   indirect_jump_indexed, .-indirect_jump_indexed
703
704         .align  2
705         .global jump_eret
706         .type   jump_eret, %function
707 jump_eret:
708         ldr     r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
709         ldr     r0, [fp, #last_count-dynarec_local]
710         bic     r1, r1, #2
711         add     r10, r0, r10
712         str     r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
713         str     r10, [fp, #cycle-dynarec_local]
714         bl      check_interupt
715         ldr     r1, [fp, #next_interupt-dynarec_local]
716         ldr     r0, [fp, #reg_cop0+56-dynarec_local] /* EPC */
717         str     r1, [fp, #last_count-dynarec_local]
718         subs    r10, r10, r1
719         bpl     .E11
720 .E8:
721         bl      get_addr
722         mov     pc, r0
723 .E11:
724         str     r0, [fp, #pcaddr-dynarec_local]
725         bl      cc_interrupt
726         ldr     r0, [fp, #pcaddr-dynarec_local]
727         b       .E8
728         .size   jump_eret, .-jump_eret
729
730         .align  2
731         .global new_dyna_start
732         .type   new_dyna_start, %function
733 new_dyna_start:
734         /* ip is stored to conform EABI alignment */
735         stmfd   sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr}
736 .if HAVE_ARMV7
737         movw    fp, #:lower16:dynarec_local
738         movt    fp, #:upper16:dynarec_local
739 .else
740         ldr     fp, .dlptr
741 .endif
742         ldr     r0, [fp, #pcaddr-dynarec_local]
743         bl      get_addr_ht
744         ldr     r1, [fp, #next_interupt-dynarec_local]
745         ldr     r10, [fp, #cycle-dynarec_local]
746         str     r1, [fp, #last_count-dynarec_local]
747         sub     r10, r10, r1
748         mov     pc, r0
749 .dlptr:
750         .word   dynarec_local
751         .size   new_dyna_start, .-new_dyna_start
752
753         .align  2
754         .global write_rdram_new
755         .type   write_rdram_new, %function
756 write_rdram_new:
757         ldr     r2, [fp, #address-dynarec_local]
758         ldr     r0, [fp, #word-dynarec_local]
759         str     r0, [r2]
760         b       .E12
761         .size   write_rdram_new, .-write_rdram_new
762         .align  2
763         .global write_rdramb_new
764         .type   write_rdramb_new, %function
765 write_rdramb_new:
766         ldr     r2, [fp, #address-dynarec_local]
767         ldrb    r0, [fp, #byte-dynarec_local]
768         eor     r2, r2, #3
769         strb    r0, [r2]
770         b       .E12
771         .size   write_rdramb_new, .-write_rdramb_new
772         .align  2
773         .global write_rdramh_new
774         .type   write_rdramh_new, %function
775 write_rdramh_new:
776         ldr     r2, [fp, #address-dynarec_local]
777         ldrh    r0, [fp, #hword-dynarec_local]
778         eor     r2, r2, #2
779         strh    r0, [r2]
780         b       .E12
781         .size   write_rdramh_new, .-write_rdramh_new
782
783         .align  2
784         .global do_invalidate
785         .type   do_invalidate, %function
786 do_invalidate:
787         ldr     r2, [fp, #address-dynarec_local]
788 .E12:
789         ldr     r1, [fp, #invc_ptr-dynarec_local]
790         lsr     r0, r2, #12
791         ldrb    r2, [r1, r0]
792         tst     r2, r2
793         beq     invalidate_block
794         mov     pc, lr
795         .size   do_invalidate, .-do_invalidate
796
797         .align  2
798         .global read_nomem_new
799         .type   read_nomem_new, %function
800 /*read_nomem_new:*/
801 read_nomemb_new:
802 read_nomemh_new:
803 read_nomemd_new:
804         /* should never happen */
805         b       read_nomem_new
806 /*
807         ldr     r2, [fp, #address-dynarec_local]
808         add     r12, fp, #memory_map-dynarec_local
809         lsr     r0, r2, #12
810         ldr     r12, [r12, r0, lsl #2]
811         mov     r1, #8
812         tst     r12, r12
813         bmi     tlb_exception
814         ldr     r0, [r2, r12, lsl #2]
815         str     r0, [fp, #readmem_dword-dynarec_local]
816         mov     pc, lr
817 */
818         .size   read_nomem_new, .-read_nomem_new
819 /*
820         .align  2
821         .global read_nomemb_new
822         .type   read_nomemb_new, %function
823 write_nomem_new:
824         str     r3, [fp, #24]
825         str     lr, [fp, #28]
826         bl      do_invalidate
827         ldr     r2, [fp, #address-dynarec_local]
828         add     r12, fp, #memory_map-dynarec_local
829         ldr     lr, [fp, #28]
830         lsr     r0, r2, #12
831         ldr     r3, [fp, #24]
832         ldr     r12, [r12, r0, lsl #2]
833         mov     r1, #0xc
834         tst     r12, #0x40000000
835         bne     tlb_exception
836         ldr     r0, [fp, #word-dynarec_local]
837         str     r0, [r2, r12, lsl #2]
838         mov     pc, lr
839         .size   write_nomem_new, .-write_nomem_new
840
841         .align  2
842         .global write_nomemb_new
843         .type   write_nomemb_new, %function
844 write_nomemb_new:
845         str     r3, [fp, #24]
846         str     lr, [fp, #28]
847         bl      do_invalidate
848         ldr     r2, [fp, #address-dynarec_local]
849         add     r12, fp, #memory_map-dynarec_local
850         ldr     lr, [fp, #28]
851         lsr     r0, r2, #12
852         ldr     r3, [fp, #24]
853         ldr     r12, [r12, r0, lsl #2]
854         mov     r1, #0xc
855         tst     r12, #0x40000000
856         bne     tlb_exception
857         eor     r2, r2, #3
858         ldrb    r0, [fp, #byte-dynarec_local]
859         strb    r0, [r2, r12, lsl #2]
860         mov     pc, lr
861         .size   write_nomemb_new, .-write_nomemb_new
862
863         .align  2
864         .global write_nomemh_new
865         .type   write_nomemh_new, %function
866 write_nomemh_new:
867         str     r3, [fp, #24]
868         str     lr, [fp, #28]
869         bl      do_invalidate
870         ldr     r2, [fp, #address-dynarec_local]
871         add     r12, fp, #memory_map-dynarec_local
872         ldr     lr, [fp, #28]
873         lsr     r0, r2, #12
874         ldr     r3, [fp, #24]
875         ldr     r12, [r12, r0, lsl #2]
876         mov     r1, #0xc
877         lsls    r12, #2
878         bcs     tlb_exception
879         eor     r2, r2, #2
880         ldrh    r0, [fp, #hword-dynarec_local]
881         strh    r0, [r2, r12]
882         mov     pc, lr
883         .size   write_nomemh_new, .-write_nomemh_new
884 */
885         .align  2
886         .global breakpoint
887         .type   breakpoint, %function
888 breakpoint:
889         /* Set breakpoint here for debugging */
890         mov     pc, lr
891         .size   breakpoint, .-breakpoint
892         .section        .note.GNU-stack,"",%progbits