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