some drc integration work
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / linkage_arm.s
... / ...
CommitLineData
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
32rdram = 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
66dynarec_local:
67 .space dynarec_local_end-dynarec_local /*0x400630*/
68next_interupt = dynarec_local + 64
69 .type next_interupt, %object
70 .size next_interupt, 4
71cycle_count = next_interupt + 4
72 .type cycle_count, %object
73 .size cycle_count, 4
74last_count = cycle_count + 4
75 .type last_count, %object
76 .size last_count, 4
77pending_exception = last_count + 4
78 .type pending_exception, %object
79 .size pending_exception, 4
80pcaddr = pending_exception + 4
81 .type pcaddr, %object
82 .size pcaddr, 4
83stop = pcaddr + 4
84 .type stop, %object
85 .size stop, 4
86invc_ptr = stop + 4
87 .type invc_ptr, %object
88 .size invc_ptr, 4
89address = invc_ptr + 4
90 .type address, %object
91 .size address, 4
92readmem_dword = address + 4
93readmem_word = readmem_dword
94 .type readmem_dword, %object
95 .size readmem_dword, 8
96dword = readmem_dword + 8
97 .type dword, %object
98 .size dword, 8
99word = dword + 8
100 .type word, %object
101 .size word, 4
102hword = word + 4
103 .type hword, %object
104 .size hword, 2
105byte = hword + 2
106 .type byte, %object
107 .size byte, 1 /* 1 byte free */
108FCR0 = hword + 4
109 .type FCR0, %object
110 .size FCR0, 4
111FCR31 = FCR0 + 4
112 .type FCR31, %object
113 .size FCR31, 4
114reg = FCR31 + 4
115
116/* psxRegs */
117psxRegs = reg
118 .type reg, %object
119 .size reg, 128
120 .size psxRegs, psxRegs_end-psxRegs
121hi = reg + 128
122 .type hi, %object
123 .size hi, 4
124lo = hi + 4
125 .type lo, %object
126 .size lo, 4
127reg_cop0 = lo + 4
128 .type reg_cop0, %object
129 .size reg_cop0, 128
130reg_cop2d = reg_cop0 + 128
131 .type reg_cop2d, %object
132 .size reg_cop2d, 128
133reg_cop2c = reg_cop2d + 128
134 .type reg_cop2c, %object
135 .size reg_cop2c, 128
136PC = reg_cop2c + 128
137 .type PC, %object
138 .size PC, 4
139code = PC + 4
140 .type code, %object
141 .size code, 4
142cycle = code + 4
143 .type cycle, %object
144 .size cycle, 4
145interrupt = cycle + 4
146 .type interrupt, %object
147 .size interrupt, 4
148intCycle = interrupt + 4
149 .type intCycle, %object
150 .size intCycle, 128
151psxRegs_end = intCycle + 128
152
153align0 = psxRegs_end /* just for alignment */
154 .type align0, %object
155 .size align0, 4
156branch_target = align0 + 4
157 .type branch_target, %object
158 .size branch_target, 4
159mini_ht = branch_target + 4
160 .type mini_ht, %object
161 .size mini_ht, 256
162restore_candidate = mini_ht + 256
163 .type restore_candidate, %object
164 .size restore_candidate, 512
165memory_map = restore_candidate + 512
166 .type memory_map, %object
167 .size memory_map, 4194304
168dynarec_local_end = memory_map + 4194304
169
170 .text
171 .align 2
172 .global dyna_linker
173 .type dyna_linker, %function
174dyna_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
264exec_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
291dyna_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
392jump_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
398jump_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
405jump_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
412jump_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
419jump_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
426jump_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
433jump_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
440jump_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
447jump_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
454jump_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
461jump_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
468jump_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
474jump_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
492verify_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
497verify_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
524verify_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
561cc_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
611do_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
624fp_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
641fp_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
648jump_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
663indirect_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
669indirect_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
678jump_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
722new_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
738write_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
747write_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
757write_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
767write_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
779do_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:*/
793read_nomemb_new:
794read_nomemh_new:
795read_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
814write_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
834write_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
855write_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
876write_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
900tlb_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
952breakpoint:
953 /* Set breakpoint here for debugging */
954 mov pc, lr
955 .size breakpoint, .-breakpoint
956 .section .note.GNU-stack,"",%progbits