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