f1b0f8cfdfa6755d23488564edffae414fd12720
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / linkage_arm.s
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  *   Mupen64plus - linkage_arm.s                                           *
3  *   Copyright (C) 2009-2010 Ari64                                         *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.          *
19  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
20         .cpu arm9tdmi
21         .fpu softvfp
22         .eabi_attribute 20, 1
23         .eabi_attribute 21, 1
24         .eabi_attribute 23, 3
25         .eabi_attribute 24, 1
26         .eabi_attribute 25, 1
27         .eabi_attribute 26, 2
28         .eabi_attribute 30, 6
29         .eabi_attribute 18, 4
30         .file   "linkage_arm.s"
31         .global rdram
32 rdram = 0x80000000
33         .global dynarec_local
34         .global reg
35         .global hi
36         .global lo
37         .global reg_cop0
38         .global FCR0
39         .global FCR31
40         .global next_interupt
41         .global cycle_count
42         .global last_count
43         .global pending_exception
44         .global pcaddr
45         .global stop
46         .global invc_ptr
47         .global address
48         .global readmem_dword
49         .global readmem_word
50         .global dword
51         .global word
52         .global hword
53         .global byte
54         .global branch_target
55         .global PC
56         .global mini_ht
57         .global restore_candidate
58         .global memory_map
59         /* psx */
60         .global psxRegs
61
62         .bss
63         .align  4
64         .type   dynarec_local, %object
65         .size   dynarec_local, dynarec_local_end-dynarec_local
66 dynarec_local:
67         .space  dynarec_local_end-dynarec_local /*0x400630*/
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 readmem_word = readmem_dword
94         .type   readmem_dword, %object
95         .size   readmem_dword, 8
96 dword = readmem_dword + 8
97         .type   dword, %object
98         .size   dword, 8
99 word = dword + 8
100         .type   word, %object
101         .size   word, 4
102 hword = word + 4
103         .type   hword, %object
104         .size   hword, 2
105 byte = hword + 2
106         .type   byte, %object
107         .size   byte, 1 /* 1 byte free */
108 FCR0 = hword + 4
109         .type   FCR0, %object
110         .size   FCR0, 4
111 FCR31 = FCR0 + 4
112         .type   FCR31, %object
113         .size   FCR31, 4
114 reg = FCR31 + 4
115
116 /* psxRegs */
117 psxRegs = reg
118         .type   reg, %object
119         .size   reg, 128
120         .size   psxRegs, psxRegs_end-psxRegs
121 hi = reg + 128
122         .type   hi, %object
123         .size   hi, 4
124 lo = hi + 4
125         .type   lo, %object
126         .size   lo, 4
127 reg_cop0 = lo + 4
128         .type   reg_cop0, %object
129         .size   reg_cop0, 128
130 reg_cop2d = reg_cop0 + 128
131         .type   reg_cop2d, %object
132         .size   reg_cop2d, 128
133 reg_cop2c = reg_cop2d + 128
134         .type   reg_cop2c, %object
135         .size   reg_cop2c, 128
136 PC = reg_cop2c + 128
137         .type   PC, %object
138         .size   PC, 4
139 code = PC + 4
140         .type   code, %object
141         .size   code, 4
142 cycle = code + 4
143         .type   cycle, %object
144         .size   cycle, 4
145 interrupt = cycle + 4
146         .type   interrupt, %object
147         .size   interrupt, 4
148 intCycle = interrupt + 4
149         .type   intCycle, %object
150         .size   intCycle, 128
151 psxRegs_end = intCycle + 128
152
153 align0 = psxRegs_end /* just for alignment */
154         .type   align0, %object
155         .size   align0, 4
156 branch_target = align0 + 4
157         .type   branch_target, %object
158         .size   branch_target, 4
159 mini_ht = branch_target + 4
160         .type   mini_ht, %object
161         .size   mini_ht, 256
162 restore_candidate = mini_ht + 256
163         .type   restore_candidate, %object
164         .size   restore_candidate, 512
165 memory_map = restore_candidate + 512
166         .type   memory_map, %object
167         .size   memory_map, 4194304
168 dynarec_local_end = memory_map + 4194304
169
170         .text
171         .align  2
172         .global dyna_linker
173         .type   dyna_linker, %function
174 dyna_linker:
175         /* r0 = virtual target address */
176         /* r1 = instruction to patch */
177         mov     r12, r0
178         mov     r6, #4096
179         mov     r2, #0x80000
180         ldr     r3, .jiptr
181         sub     r6, r6, #1
182         ldr     r7, [r1]
183         eor     r2, r2, r12, lsr #12
184         and     r6, r6, r12, lsr #12
185         cmp     r2, #2048
186         add     r12, r7, #2
187         orrcs   r2, r6, #2048
188         ldr     r5, [r3, r2, lsl #2]
189         lsl     r12, r12, #8
190         /* jump_in lookup */
191 .A1:
192         movs    r4, r5
193         beq     .A3
194         ldr     r3, [r5]
195         ldr     r5, [r4, #12]
196         teq     r3, r0
197         bne     .A1
198         ldr     r3, [r4, #4]
199         ldr     r4, [r4, #8]
200         tst     r3, r3
201         bne     .A1
202 .A2:
203         mov     r5, r1
204         add     r1, r1, r12, asr #6
205         teq     r1, r4
206         moveq   pc, r4 /* Stale i-cache */
207         bl      add_link
208         sub     r2, r4, r5
209         and     r1, r7, #0xff000000
210         lsl     r2, r2, #6
211         sub     r1, r1, #2
212         add     r1, r1, r2, lsr #8
213         str     r1, [r5]
214         mov     pc, r4
215 .A3:
216         /* hash_table lookup */
217         cmp     r2, #2048
218         ldr     r3, .jdptr
219         eor     r4, r0, r0, lsl #16
220         lslcc   r2, r0, #9
221         ldr     r6, .htptr
222         lsr     r4, r4, #12
223         lsrcc   r2, r2, #21
224         bic     r4, r4, #15
225         ldr     r5, [r3, r2, lsl #2]
226         ldr     r7, [r6, r4]!
227         teq     r7, r0
228         ldreq   pc, [r6, #4]
229         ldr     r7, [r6, #8]
230         teq     r7, r0
231         ldreq   pc, [r6, #12]
232         /* jump_dirty lookup */
233 .A6:
234         movs    r4, r5
235         beq     .A8
236         ldr     r3, [r5]
237         ldr     r5, [r4, #12]
238         teq     r3, r0
239         bne     .A6
240 .A7:
241         ldr     r1, [r4, #8]
242         /* hash_table insert */
243         ldr     r2, [r6]
244         ldr     r3, [r6, #4]
245         str     r0, [r6]
246         str     r1, [r6, #4]
247         str     r2, [r6, #8]
248         str     r3, [r6, #12]
249         mov     pc, r1
250 .A8:
251         mov     r4, r0
252         mov     r5, r1
253         bl      new_recompile_block
254         tst     r0, r0
255         mov     r0, r4
256         mov     r1, r5
257         beq     dyna_linker
258         /* pagefault */
259         mov     r1, r0
260         mov     r2, #8
261         .size   dyna_linker, .-dyna_linker
262         .global exec_pagefault
263         .type   exec_pagefault, %function
264 exec_pagefault:
265         /* r0 = instruction pointer */
266         /* r1 = fault address */
267         /* r2 = cause */
268         ldr     r3, [fp, #reg_cop0+48-dynarec_local] /* Status */
269         mvn     r6, #0xF000000F
270         ldr     r4, [fp, #reg_cop0+16-dynarec_local] /* Context */
271         bic     r6, r6, #0x0F800000
272         str     r0, [fp, #reg_cop0+56-dynarec_local] /* EPC */
273         orr     r3, r3, #2
274         str     r1, [fp, #reg_cop0+32-dynarec_local] /* BadVAddr */
275         bic     r4, r4, r6
276         str     r3, [fp, #reg_cop0+48-dynarec_local] /* Status */
277         and     r5, r6, r1, lsr #9
278         str     r2, [fp, #reg_cop0+52-dynarec_local] /* Cause */
279         and     r1, r1, r6, lsl #9
280         str     r1, [fp, #reg_cop0+40-dynarec_local] /* EntryHi */
281         orr     r4, r4, r5
282         str     r4, [fp, #reg_cop0+16-dynarec_local] /* Context */
283         mov     r0, #0x80000000
284         bl      get_addr_ht
285         mov     pc, r0
286         .size   exec_pagefault, .-exec_pagefault
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         .align  2
390         .global jump_vaddr_r0
391         .type   jump_vaddr_r0, %function
392 jump_vaddr_r0:
393         eor     r2, r0, r0, lsl #16
394         b       jump_vaddr
395         .size   jump_vaddr_r0, .-jump_vaddr_r0
396         .global jump_vaddr_r1
397         .type   jump_vaddr_r1, %function
398 jump_vaddr_r1:
399         eor     r2, r1, r1, lsl #16
400         mov     r0, r1
401         b       jump_vaddr
402         .size   jump_vaddr_r1, .-jump_vaddr_r1
403         .global jump_vaddr_r2
404         .type   jump_vaddr_r2, %function
405 jump_vaddr_r2:
406         mov     r0, r2
407         eor     r2, r2, r2, lsl #16
408         b       jump_vaddr
409         .size   jump_vaddr_r2, .-jump_vaddr_r2
410         .global jump_vaddr_r3
411         .type   jump_vaddr_r3, %function
412 jump_vaddr_r3:
413         eor     r2, r3, r3, lsl #16
414         mov     r0, r3
415         b       jump_vaddr
416         .size   jump_vaddr_r3, .-jump_vaddr_r3
417         .global jump_vaddr_r4
418         .type   jump_vaddr_r4, %function
419 jump_vaddr_r4:
420         eor     r2, r4, r4, lsl #16
421         mov     r0, r4
422         b       jump_vaddr
423         .size   jump_vaddr_r4, .-jump_vaddr_r4
424         .global jump_vaddr_r5
425         .type   jump_vaddr_r5, %function
426 jump_vaddr_r5:
427         eor     r2, r5, r5, lsl #16
428         mov     r0, r5
429         b       jump_vaddr
430         .size   jump_vaddr_r5, .-jump_vaddr_r5
431         .global jump_vaddr_r6
432         .type   jump_vaddr_r6, %function
433 jump_vaddr_r6:
434         eor     r2, r6, r6, lsl #16
435         mov     r0, r6
436         b       jump_vaddr
437         .size   jump_vaddr_r6, .-jump_vaddr_r6
438         .global jump_vaddr_r8
439         .type   jump_vaddr_r8, %function
440 jump_vaddr_r8:
441         eor     r2, r8, r8, lsl #16
442         mov     r0, r8
443         b       jump_vaddr
444         .size   jump_vaddr_r8, .-jump_vaddr_r8
445         .global jump_vaddr_r9
446         .type   jump_vaddr_r9, %function
447 jump_vaddr_r9:
448         eor     r2, r9, r9, lsl #16
449         mov     r0, r9
450         b       jump_vaddr
451         .size   jump_vaddr_r9, .-jump_vaddr_r9
452         .global jump_vaddr_r10
453         .type   jump_vaddr_r10, %function
454 jump_vaddr_r10:
455         eor     r2, r10, r10, lsl #16
456         mov     r0, r10
457         b       jump_vaddr
458         .size   jump_vaddr_r10, .-jump_vaddr_r10
459         .global jump_vaddr_r12
460         .type   jump_vaddr_r12, %function
461 jump_vaddr_r12:
462         eor     r2, r12, r12, lsl #16
463         mov     r0, r12
464         b       jump_vaddr
465         .size   jump_vaddr_r12, .-jump_vaddr_r12
466         .global jump_vaddr_r7
467         .type   jump_vaddr_r7, %function
468 jump_vaddr_r7:
469         eor     r2, r7, r7, lsl #16
470         add     r0, r7, #0
471         .size   jump_vaddr_r7, .-jump_vaddr_r7
472         .global jump_vaddr
473         .type   jump_vaddr, %function
474 jump_vaddr:
475         ldr     r1, .htptr
476         mvn     r3, #15
477         and     r2, r3, r2, lsr #12
478         ldr     r2, [r1, r2]!
479         teq     r2, r0
480         ldreq   pc, [r1, #4]
481         ldr     r2, [r1, #8]
482         teq     r2, r0
483         ldreq   pc, [r1, #12]
484         str     r10, [fp, #cycle_count-dynarec_local]
485         bl      get_addr
486         ldr     r10, [fp, #cycle_count-dynarec_local]
487         mov     pc, r0
488         .size   jump_vaddr, .-jump_vaddr
489         .align  2
490         .global verify_code_ds
491         .type   verify_code_ds, %function
492 verify_code_ds:
493         str     r8, [fp, #branch_target-dynarec_local]
494         .size   verify_code_ds, .-verify_code_ds
495         .global verify_code_vm
496         .type   verify_code_vm, %function
497 verify_code_vm:
498         /* r0 = instruction pointer (virtual address) */
499         /* r1 = source (virtual address) */
500         /* r2 = target */
501         /* r3 = length */
502         cmp     r1, #0xC0000000
503         blt     verify_code
504         add     r12, fp, #memory_map-dynarec_local
505         lsr     r4, r1, #12
506         add     r5, r1, r3
507         sub     r5, #1
508         ldr     r6, [r12, r4, lsl #2]
509         lsr     r5, r5, #12
510         movs    r7, r6
511         bmi     .D5
512         add     r1, r1, r6, lsl #2
513         lsl     r6, r6, #2
514 .D1:
515         add     r4, r4, #1
516         teq     r6, r7, lsl #2
517         bne     .D5
518         ldr     r7, [r12, r4, lsl #2]
519         cmp     r4, r5
520         bls     .D1
521         .size   verify_code_vm, .-verify_code_vm
522         .global verify_code
523         .type   verify_code, %function
524 verify_code:
525         /* r1 = source */
526         /* r2 = target */
527         /* r3 = length */
528         tst     r3, #4
529         mov     r4, #0
530         add     r3, r1, r3
531         mov     r5, #0
532         ldrne   r4, [r1], #4
533         mov     r12, #0
534         ldrne   r5, [r2], #4
535         teq     r1, r3
536         beq     .D3
537 .D2:
538         ldr     r7, [r1], #4
539         eor     r9, r4, r5
540         ldr     r8, [r2], #4
541         orrs    r9, r9, r12
542         bne     .D4
543         ldr     r4, [r1], #4
544         eor     r12, r7, r8
545         ldr     r5, [r2], #4
546         cmp     r1, r3
547         bcc     .D2
548         teq     r7, r8
549 .D3:
550         teqeq   r4, r5
551 .D4:
552         ldr     r8, [fp, #branch_target-dynarec_local]
553         moveq   pc, lr
554 .D5:
555         bl      get_addr
556         mov     pc, r0
557         .size   verify_code, .-verify_code
558         .align  2
559         .global cc_interrupt
560         .type   cc_interrupt, %function
561 cc_interrupt:
562         ldr     r0, [fp, #last_count-dynarec_local]
563         mov     r1, #0
564         mov     r2, #0x1fc
565         add     r10, r0, r10
566         str     r1, [fp, #pending_exception-dynarec_local]
567         and     r2, r2, r10, lsr #17
568         add     r3, fp, #restore_candidate-dynarec_local
569         str     r10, [fp, #reg_cop0+36-dynarec_local] /* Count */
570         ldr     r4, [r2, r3]
571         mov     r10, lr
572         tst     r4, r4
573         bne     .E4
574 .E1:
575         bl      gen_interupt
576         mov     lr, r10
577         ldr     r10, [fp, #reg_cop0+36-dynarec_local] /* Count */
578         ldr     r0, [fp, #next_interupt-dynarec_local]
579         ldr     r1, [fp, #pending_exception-dynarec_local]
580         ldr     r2, [fp, #stop-dynarec_local]
581         str     r0, [fp, #last_count-dynarec_local]
582         sub     r10, r10, r0
583         tst     r2, r2
584         bne     .E3
585         tst     r1, r1
586         moveq   pc, lr
587 .E2:
588         ldr     r0, [fp, #pcaddr-dynarec_local]
589         bl      get_addr_ht
590         mov     pc, r0
591 .E3:
592         add     r12, fp, #28
593         ldmia   r12, {r4, r5, r6, r7, r8, r9, sl, fp, pc}
594 .E4:
595         /* Move 'dirty' blocks to the 'clean' list */
596         lsl     r5, r2, #3
597         str     r1, [r2, r3]
598 .E5:
599         lsrs    r4, r4, #1
600         mov     r0, r5
601         add     r5, r5, #1
602         blcs    clean_blocks
603         tst     r5, #31
604         bne     .E5
605         b       .E1
606
607         .size   cc_interrupt, .-cc_interrupt
608         .align  2
609         .global do_interrupt
610         .type   do_interrupt, %function
611 do_interrupt:
612         ldr     r0, [fp, #pcaddr-dynarec_local]
613         bl      get_addr_ht
614         ldr     r1, [fp, #next_interupt-dynarec_local]
615         ldr     r10, [fp, #reg_cop0+36-dynarec_local] /* Count */
616         str     r1, [fp, #last_count-dynarec_local]
617         sub     r10, r10, r1
618         add     r10, r10, #2
619         mov     pc, r0
620         .size   do_interrupt, .-do_interrupt
621         .align  2
622         .global fp_exception
623         .type   fp_exception, %function
624 fp_exception:
625         mov     r2, #0x10000000
626 .E7:
627         ldr     r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
628         mov     r3, #0x80000000
629         str     r0, [fp, #reg_cop0+56-dynarec_local] /* EPC */
630         orr     r1, #2
631         add     r2, r2, #0x2c
632         str     r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
633         str     r2, [fp, #reg_cop0+52-dynarec_local] /* Cause */
634         add     r0, r3, #0x180
635         bl      get_addr_ht
636         mov     pc, r0
637         .size   fp_exception, .-fp_exception
638         .align  2
639         .global fp_exception_ds
640         .type   fp_exception_ds, %function
641 fp_exception_ds:
642         mov     r2, #0x90000000 /* Set high bit if delay slot */
643         b       .E7
644         .size   fp_exception_ds, .-fp_exception_ds
645         .align  2
646         .global jump_syscall
647         .type   jump_syscall, %function
648 jump_syscall:
649         ldr     r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
650         mov     r3, #0x80000000
651         str     r0, [fp, #reg_cop0+56-dynarec_local] /* EPC */
652         orr     r1, #2
653         mov     r2, #0x20
654         str     r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
655         str     r2, [fp, #reg_cop0+52-dynarec_local] /* Cause */
656         add     r0, r3, #0x180
657         bl      get_addr_ht
658         mov     pc, r0
659         .size   jump_syscall, .-jump_syscall
660         .align  2
661         .global indirect_jump_indexed
662         .type   indirect_jump_indexed, %function
663 indirect_jump_indexed:
664         ldr     r0, [r0, r1, lsl #2]
665         .size   indirect_jump_indexed, .-indirect_jump_indexed
666         .align  2
667         .global indirect_jump
668         .type   indirect_jump, %function
669 indirect_jump:
670         ldr     r12, [fp, #last_count-dynarec_local]
671         add     r2, r2, r12 
672         str     r2, [fp, #reg_cop0+36-dynarec_local] /* Count */
673         mov     pc, r0
674         .size   indirect_jump, .-indirect_jump
675         .align  2
676         .global jump_eret
677         .type   jump_eret, %function
678 jump_eret:
679         ldr     r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
680         ldr     r0, [fp, #last_count-dynarec_local]
681         bic     r1, r1, #2
682         add     r10, r0, r10
683         str     r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
684         str     r10, [fp, #reg_cop0+36-dynarec_local] /* Count */
685         bl      check_interupt
686         ldr     r1, [fp, #next_interupt-dynarec_local]
687         ldr     r0, [fp, #reg_cop0+56-dynarec_local] /* EPC */
688         str     r1, [fp, #last_count-dynarec_local]
689         subs    r10, r10, r1
690         bpl     .E11
691 .E8:
692         add     r6, fp, #reg+256-dynarec_local
693         mov     r5, #248
694         mov     r1, #0
695 .E9:
696         ldr     r2, [r6, #-8]!
697         ldr     r3, [r6, #4]
698         eor     r3, r3, r2, asr #31
699         subs    r3, r3, #1
700         adc     r1, r1, r1
701         subs    r5, r5, #8
702         bne     .E9
703         ldr     r2, [fp, #hi-dynarec_local]
704         ldr     r3, [fp, #hi+4-dynarec_local]
705         eors    r3, r3, r2, asr #31
706         ldr     r2, [fp, #lo-dynarec_local]
707         ldreq   r3, [fp, #lo+4-dynarec_local]
708         eoreq   r3, r3, r2, asr #31
709         subs    r3, r3, #1
710         adc     r1, r1, r1
711         bl      get_addr_32
712         mov     pc, r0
713 .E11:
714         str     r0, [fp, #pcaddr-dynarec_local]
715         bl      cc_interrupt
716         ldr     r0, [fp, #pcaddr-dynarec_local]
717         b       .E8
718         .size   jump_eret, .-jump_eret
719         .align  2
720         .global new_dyna_start
721         .type   new_dyna_start, %function
722 new_dyna_start:
723         ldr     r12, .dlptr
724         stmia   r12, {r4, r5, r6, r7, r8, r9, sl, fp, lr}
725         sub     fp, r12, #28
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, #0x2000000
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 read_nomemb_new:
794 read_nomemh_new:
795 read_nomemd_new:
796         /* should never happen */
797         b       read_nomem_new
798 /*
799         ldr     r2, [fp, #address-dynarec_local]
800         add     r12, fp, #memory_map-dynarec_local
801         lsr     r0, r2, #12
802         ldr     r12, [r12, r0, lsl #2]
803         mov     r1, #8
804         tst     r12, r12
805         bmi     tlb_exception
806         ldr     r0, [r2, r12, lsl #2]
807         str     r0, [fp, #readmem_dword-dynarec_local]
808         mov     pc, lr
809 */
810         .size   read_nomem_new, .-read_nomem_new
811         .align  2
812         .global read_nomemb_new
813         .type   read_nomemb_new, %function
814 write_nomem_new:
815         str     r3, [fp, #24]
816         str     lr, [fp, #28]
817         bl      do_invalidate
818         ldr     r2, [fp, #address-dynarec_local]
819         add     r12, fp, #memory_map-dynarec_local
820         ldr     lr, [fp, #28]
821         lsr     r0, r2, #12
822         ldr     r3, [fp, #24]
823         ldr     r12, [r12, r0, lsl #2]
824         mov     r1, #0xc
825         tst     r12, #0x40000000
826         bne     tlb_exception
827         ldr     r0, [fp, #word-dynarec_local]
828         str     r0, [r2, r12, lsl #2]
829         mov     pc, lr
830         .size   write_nomem_new, .-write_nomem_new
831         .align  2
832         .global write_nomemb_new
833         .type   write_nomemb_new, %function
834 write_nomemb_new:
835         str     r3, [fp, #24]
836         str     lr, [fp, #28]
837         bl      do_invalidate
838         ldr     r2, [fp, #address-dynarec_local]
839         add     r12, fp, #memory_map-dynarec_local
840         ldr     lr, [fp, #28]
841         lsr     r0, r2, #12
842         ldr     r3, [fp, #24]
843         ldr     r12, [r12, r0, lsl #2]
844         mov     r1, #0xc
845         tst     r12, #0x40000000
846         bne     tlb_exception
847         eor     r2, r2, #3
848         ldrb    r0, [fp, #byte-dynarec_local]
849         strb    r0, [r2, r12, lsl #2]
850         mov     pc, lr
851         .size   write_nomemb_new, .-write_nomemb_new
852         .align  2
853         .global write_nomemh_new
854         .type   write_nomemh_new, %function
855 write_nomemh_new:
856         str     r3, [fp, #24]
857         str     lr, [fp, #28]
858         bl      do_invalidate
859         ldr     r2, [fp, #address-dynarec_local]
860         add     r12, fp, #memory_map-dynarec_local
861         ldr     lr, [fp, #28]
862         lsr     r0, r2, #12
863         ldr     r3, [fp, #24]
864         ldr     r12, [r12, r0, lsl #2]
865         mov     r1, #0xc
866         lsls    r12, #2
867         bcs     tlb_exception
868         eor     r2, r2, #2
869         ldrh    r0, [fp, #hword-dynarec_local]
870         strh    r0, [r2, r12]
871         mov     pc, lr
872         .size   write_nomemh_new, .-write_nomemh_new
873         .align  2
874         .global write_nomemd_new
875         .type   write_nomemd_new, %function
876 write_nomemd_new:
877         str     r3, [fp, #24]
878         str     lr, [fp, #28]
879         bl      do_invalidate
880         ldr     r2, [fp, #address-dynarec_local]
881         add     r12, fp, #memory_map-dynarec_local
882         ldr     lr, [fp, #28]
883         lsr     r0, r2, #12
884         ldr     r3, [fp, #24]
885         ldr     r12, [r12, r0, lsl #2]
886         mov     r1, #0xc
887         lsls    r12, #2
888         bcs     tlb_exception
889         add     r3, r2, #4
890         ldr     r0, [fp, #dword+4-dynarec_local]
891         ldr     r1, [fp, #dword-dynarec_local]
892 /*      strd    r0, [r2, r12]*/
893         str     r0, [r2, r12]
894         str     r1, [r3, r12]
895         mov     pc, lr
896         .size   write_nomemd_new, .-write_nomemd_new
897         .align  2
898         .global tlb_exception
899         .type   tlb_exception, %function
900 tlb_exception:
901         /* r1 = cause */
902         /* r2 = address */
903         /* r3 = instr addr/flags */
904         ldr     r4, [fp, #reg_cop0+48-dynarec_local] /* Status */
905         add     r5, fp, #memory_map-dynarec_local
906         lsr     r6, r3, #12
907         orr     r1, r1, r3, lsl #31
908         orr     r4, r4, #2
909         ldr     r7, [r5, r6, lsl #2]
910         bic     r8, r3, #3
911         str     r4, [fp, #reg_cop0+48-dynarec_local] /* Status */
912         mov     r6, #0x6000000
913         str     r1, [fp, #reg_cop0+52-dynarec_local] /* Cause */
914         orr     r6, r6, #0x22
915         ldr     r0, [r8, r7, lsl #2]
916         add     r4, r8, r1, asr #29
917         add     r5, fp, #reg-dynarec_local
918         str     r4, [fp, #reg_cop0+56-dynarec_local] /* EPC */
919         mov     r7, #0xf8
920         ldr     r8, [fp, #reg_cop0+16-dynarec_local] /* Context */
921         lsl     r1, r0, #16
922         lsr     r4, r0, #26
923         and     r7, r7, r0, lsr #18
924         mvn     r9, #0xF000000F
925         sub     r2, r2, r1, asr #16
926         bic     r9, r9, #0x0F800000
927         rors    r6, r6, r4
928         mov     r0, #0x80000000
929         ldrcs   r2, [r5, r7]
930         bic     r8, r8, r9
931         tst     r3, #2
932         str     r2, [r5, r7]
933         add     r4, r2, r1, asr #16
934         add     r6, fp, #reg+4-dynarec_local
935         asr     r3, r2, #31
936         str     r4, [fp, #reg_cop0+32-dynarec_local] /* BadVAddr */
937         add     r0, r0, #0x180
938         and     r4, r9, r4, lsr #9
939         strne   r3, [r6, r7]
940         orr     r8, r8, r4
941         str     r8, [fp, #reg_cop0+16-dynarec_local] /* Context */
942         bl      get_addr_ht
943         ldr     r1, [fp, #next_interupt-dynarec_local]
944         ldr     r10, [fp, #reg_cop0+36-dynarec_local] /* Count */
945         str     r1, [fp, #last_count-dynarec_local]
946         sub     r10, r10, r1
947         mov     pc, r0  
948         .size   tlb_exception, .-tlb_exception
949         .align  2
950         .global breakpoint
951         .type   breakpoint, %function
952 breakpoint:
953         /* Set breakpoint here for debugging */
954         mov     pc, lr
955         .size   breakpoint, .-breakpoint
956         .section        .note.GNU-stack,"",%progbits