menu: add interpreter option
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / linkage_arm.s
CommitLineData
57871462 1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
7e605697 2 * linkage_arm.s for PCSX *
57871462 3 * Copyright (C) 2009-2010 Ari64 *
576bbd8f 4 * Copyright (C) 2010-2011 GraÅžvydas "notaz" Ignotas *
57871462 5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 * This program is distributed in the hope that it will be useful, *
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
14 * GNU General Public License for more details. *
15 * *
16 * You should have received a copy of the GNU General Public License *
17 * along with this program; if not, write to the *
18 * Free Software Foundation, Inc., *
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
20 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
b021ee75 21
22.equiv HAVE_ARMV7, 1
23
24.if HAVE_ARMV7
25 .cpu cortex-a8
26 .fpu vfp
27.else
57871462 28 .cpu arm9tdmi
29 .fpu softvfp
b021ee75 30.endif
57871462 31 .global rdram
32rdram = 0x80000000
33 .global dynarec_local
34 .global reg
35 .global hi
36 .global lo
57871462 37 .global reg_cop0
b9b61529 38 .global reg_cop2d
39 .global reg_cop2c
57871462 40 .global FCR0
41 .global FCR31
57871462 42 .global next_interupt
43 .global cycle_count
44 .global last_count
45 .global pending_exception
46 .global pcaddr
47 .global stop
48 .global invc_ptr
49 .global address
50 .global readmem_dword
f95a77f7 51 .global readmem_word
57871462 52 .global dword
53 .global word
54 .global hword
55 .global byte
56 .global branch_target
57 .global PC
57871462 58 .global mini_ht
59 .global restore_candidate
60 .global memory_map
f95a77f7 61 /* psx */
62 .global psxRegs
7e605697 63 .global nd_pcsx_io
64 .global psxH_ptr
f95a77f7 65
57871462 66 .bss
67 .align 4
68 .type dynarec_local, %object
f95a77f7 69 .size dynarec_local, dynarec_local_end-dynarec_local
57871462 70dynarec_local:
f95a77f7 71 .space dynarec_local_end-dynarec_local /*0x400630*/
57871462 72next_interupt = dynarec_local + 64
73 .type next_interupt, %object
74 .size next_interupt, 4
75cycle_count = next_interupt + 4
76 .type cycle_count, %object
77 .size cycle_count, 4
78last_count = cycle_count + 4
79 .type last_count, %object
80 .size last_count, 4
81pending_exception = last_count + 4
82 .type pending_exception, %object
83 .size pending_exception, 4
7139f3c8 84stop = pending_exception + 4
57871462 85 .type stop, %object
86 .size stop, 4
87invc_ptr = stop + 4
88 .type invc_ptr, %object
89 .size invc_ptr, 4
90address = invc_ptr + 4
91 .type address, %object
92 .size address, 4
93readmem_dword = address + 4
f95a77f7 94readmem_word = readmem_dword
57871462 95 .type readmem_dword, %object
96 .size readmem_dword, 8
97dword = readmem_dword + 8
98 .type dword, %object
99 .size dword, 8
100word = dword + 8
101 .type word, %object
102 .size word, 4
103hword = word + 4
104 .type hword, %object
105 .size hword, 2
106byte = hword + 2
107 .type byte, %object
108 .size byte, 1 /* 1 byte free */
109FCR0 = hword + 4
110 .type FCR0, %object
111 .size FCR0, 4
112FCR31 = FCR0 + 4
113 .type FCR31, %object
114 .size FCR31, 4
7e605697 115psxRegs = FCR31 + 4
f95a77f7 116
117/* psxRegs */
7e605697 118 .type psxRegs, %object
119 .size psxRegs, psxRegs_end-psxRegs
120reg = psxRegs
57871462 121 .type reg, %object
f95a77f7 122 .size reg, 128
7139f3c8 123lo = reg + 128
57871462 124 .type lo, %object
f95a77f7 125 .size lo, 4
7139f3c8 126hi = lo + 4
127 .type hi, %object
128 .size hi, 4
129reg_cop0 = hi + 4
57871462 130 .type reg_cop0, %object
131 .size reg_cop0, 128
f95a77f7 132reg_cop2d = reg_cop0 + 128
133 .type reg_cop2d, %object
134 .size reg_cop2d, 128
135reg_cop2c = reg_cop2d + 128
136 .type reg_cop2c, %object
137 .size reg_cop2c, 128
138PC = reg_cop2c + 128
7139f3c8 139pcaddr = PC
57871462 140 .type PC, %object
141 .size PC, 4
f95a77f7 142code = PC + 4
143 .type code, %object
144 .size code, 4
145cycle = code + 4
146 .type cycle, %object
147 .size cycle, 4
148interrupt = cycle + 4
149 .type interrupt, %object
150 .size interrupt, 4
151intCycle = interrupt + 4
152 .type intCycle, %object
52082bc1 153 .size intCycle, 256
154psxRegs_end = intCycle + 256
f95a77f7 155
7e605697 156/* nd_pcsx_io */
157nd_pcsx_io = psxRegs_end
158 .type nd_pcsx_io, %object
159 .size nd_pcsx_io, nd_pcsx_io_end-nd_pcsx_io
160tab_read8 = nd_pcsx_io
161 .type tab_read8, %object
162 .size tab_read8, 4
163tab_read16 = tab_read8 + 4
164 .type tab_read16, %object
165 .size tab_read16, 4
166tab_read32 = tab_read16 + 4
167 .type tab_read32, %object
168 .size tab_read32, 4
169tab_write8 = tab_read32 + 4
170 .type tab_write8, %object
171 .size tab_write8, 4
172tab_write16 = tab_write8 + 4
173 .type tab_write16, %object
174 .size tab_write16, 4
175tab_write32 = tab_write16 + 4
176 .type tab_write32, %object
177 .size tab_write32, 4
178spu_readf = tab_write32 + 4
179 .type spu_readf, %object
180 .size spu_readf, 4
181spu_writef = spu_readf + 4
182 .type spu_writef, %object
183 .size spu_writef, 4
184nd_pcsx_io_end = spu_writef + 4
185
186psxH_ptr = nd_pcsx_io_end
187 .type psxH_ptr, %object
188 .size psxH_ptr, 4
189align0 = psxH_ptr + 4 /* just for alignment */
f95a77f7 190 .type align0, %object
7e605697 191 .size align0, 4
192branch_target = align0 + 4
f95a77f7 193 .type branch_target, %object
194 .size branch_target, 4
195mini_ht = branch_target + 4
57871462 196 .type mini_ht, %object
197 .size mini_ht, 256
198restore_candidate = mini_ht + 256
199 .type restore_candidate, %object
200 .size restore_candidate, 512
201memory_map = restore_candidate + 512
202 .type memory_map, %object
203 .size memory_map, 4194304
f95a77f7 204dynarec_local_end = memory_map + 4194304
57871462 205
206 .text
207 .align 2
208 .global dyna_linker
209 .type dyna_linker, %function
210dyna_linker:
211 /* r0 = virtual target address */
212 /* r1 = instruction to patch */
57871462 213 mov r12, r0
57871462 214 mov r6, #4096
57871462 215 mov r2, #0x80000
216 ldr r3, .jiptr
57871462 217 sub r6, r6, #1
57871462 218 ldr r7, [r1]
219 eor r2, r2, r12, lsr #12
220 and r6, r6, r12, lsr #12
221 cmp r2, #2048
222 add r12, r7, #2
223 orrcs r2, r6, #2048
224 ldr r5, [r3, r2, lsl #2]
225 lsl r12, r12, #8
226 /* jump_in lookup */
227.A1:
228 movs r4, r5
229 beq .A3
230 ldr r3, [r5]
231 ldr r5, [r4, #12]
232 teq r3, r0
233 bne .A1
234 ldr r3, [r4, #4]
235 ldr r4, [r4, #8]
236 tst r3, r3
237 bne .A1
238.A2:
239 mov r5, r1
240 add r1, r1, r12, asr #6
241 teq r1, r4
242 moveq pc, r4 /* Stale i-cache */
243 bl add_link
244 sub r2, r4, r5
245 and r1, r7, #0xff000000
246 lsl r2, r2, #6
247 sub r1, r1, #2
248 add r1, r1, r2, lsr #8
249 str r1, [r5]
250 mov pc, r4
251.A3:
252 /* hash_table lookup */
253 cmp r2, #2048
254 ldr r3, .jdptr
255 eor r4, r0, r0, lsl #16
256 lslcc r2, r0, #9
257 ldr r6, .htptr
258 lsr r4, r4, #12
259 lsrcc r2, r2, #21
260 bic r4, r4, #15
261 ldr r5, [r3, r2, lsl #2]
262 ldr r7, [r6, r4]!
263 teq r7, r0
264 ldreq pc, [r6, #4]
265 ldr r7, [r6, #8]
266 teq r7, r0
267 ldreq pc, [r6, #12]
268 /* jump_dirty lookup */
269.A6:
270 movs r4, r5
271 beq .A8
272 ldr r3, [r5]
273 ldr r5, [r4, #12]
274 teq r3, r0
275 bne .A6
276.A7:
277 ldr r1, [r4, #8]
278 /* hash_table insert */
279 ldr r2, [r6]
280 ldr r3, [r6, #4]
281 str r0, [r6]
282 str r1, [r6, #4]
283 str r2, [r6, #8]
284 str r3, [r6, #12]
285 mov pc, r1
286.A8:
287 mov r4, r0
288 mov r5, r1
289 bl new_recompile_block
290 tst r0, r0
291 mov r0, r4
292 mov r1, r5
293 beq dyna_linker
294 /* pagefault */
295 mov r1, r0
296 mov r2, #8
297 .size dyna_linker, .-dyna_linker
298 .global exec_pagefault
299 .type exec_pagefault, %function
300exec_pagefault:
301 /* r0 = instruction pointer */
302 /* r1 = fault address */
303 /* r2 = cause */
304 ldr r3, [fp, #reg_cop0+48-dynarec_local] /* Status */
305 mvn r6, #0xF000000F
306 ldr r4, [fp, #reg_cop0+16-dynarec_local] /* Context */
307 bic r6, r6, #0x0F800000
308 str r0, [fp, #reg_cop0+56-dynarec_local] /* EPC */
309 orr r3, r3, #2
310 str r1, [fp, #reg_cop0+32-dynarec_local] /* BadVAddr */
311 bic r4, r4, r6
312 str r3, [fp, #reg_cop0+48-dynarec_local] /* Status */
313 and r5, r6, r1, lsr #9
314 str r2, [fp, #reg_cop0+52-dynarec_local] /* Cause */
315 and r1, r1, r6, lsl #9
316 str r1, [fp, #reg_cop0+40-dynarec_local] /* EntryHi */
317 orr r4, r4, r5
318 str r4, [fp, #reg_cop0+16-dynarec_local] /* Context */
319 mov r0, #0x80000000
320 bl get_addr_ht
321 mov pc, r0
322 .size exec_pagefault, .-exec_pagefault
7139f3c8 323
57871462 324/* Special dynamic linker for the case where a page fault
325 may occur in a branch delay slot */
326 .global dyna_linker_ds
327 .type dyna_linker_ds, %function
328dyna_linker_ds:
329 /* r0 = virtual target address */
330 /* r1 = instruction to patch */
57871462 331 mov r12, r0
57871462 332 mov r6, #4096
57871462 333 mov r2, #0x80000
334 ldr r3, .jiptr
57871462 335 sub r6, r6, #1
57871462 336 ldr r7, [r1]
337 eor r2, r2, r12, lsr #12
338 and r6, r6, r12, lsr #12
339 cmp r2, #2048
340 add r12, r7, #2
341 orrcs r2, r6, #2048
342 ldr r5, [r3, r2, lsl #2]
343 lsl r12, r12, #8
344 /* jump_in lookup */
345.B1:
346 movs r4, r5
347 beq .B3
348 ldr r3, [r5]
349 ldr r5, [r4, #12]
350 teq r3, r0
351 bne .B1
352 ldr r3, [r4, #4]
353 ldr r4, [r4, #8]
354 tst r3, r3
355 bne .B1
356.B2:
357 mov r5, r1
358 add r1, r1, r12, asr #6
359 teq r1, r4
360 moveq pc, r4 /* Stale i-cache */
361 bl add_link
362 sub r2, r4, r5
363 and r1, r7, #0xff000000
364 lsl r2, r2, #6
365 sub r1, r1, #2
366 add r1, r1, r2, lsr #8
367 str r1, [r5]
368 mov pc, r4
369.B3:
370 /* hash_table lookup */
371 cmp r2, #2048
372 ldr r3, .jdptr
373 eor r4, r0, r0, lsl #16
374 lslcc r2, r0, #9
375 ldr r6, .htptr
376 lsr r4, r4, #12
377 lsrcc r2, r2, #21
378 bic r4, r4, #15
379 ldr r5, [r3, r2, lsl #2]
380 ldr r7, [r6, r4]!
381 teq r7, r0
382 ldreq pc, [r6, #4]
383 ldr r7, [r6, #8]
384 teq r7, r0
385 ldreq pc, [r6, #12]
386 /* jump_dirty lookup */
387.B6:
388 movs r4, r5
389 beq .B8
390 ldr r3, [r5]
391 ldr r5, [r4, #12]
392 teq r3, r0
393 bne .B6
394.B7:
395 ldr r1, [r4, #8]
396 /* hash_table insert */
397 ldr r2, [r6]
398 ldr r3, [r6, #4]
399 str r0, [r6]
400 str r1, [r6, #4]
401 str r2, [r6, #8]
402 str r3, [r6, #12]
403 mov pc, r1
404.B8:
405 mov r4, r0
406 bic r0, r0, #7
407 mov r5, r1
408 orr r0, r0, #1
409 bl new_recompile_block
410 tst r0, r0
411 mov r0, r4
412 mov r1, r5
413 beq dyna_linker_ds
414 /* pagefault */
415 bic r1, r0, #7
416 mov r2, #0x80000008 /* High bit set indicates pagefault in delay slot */
417 sub r0, r1, #4
418 b exec_pagefault
419 .size dyna_linker_ds, .-dyna_linker_ds
420.jiptr:
421 .word jump_in
422.jdptr:
423 .word jump_dirty
57871462 424.htptr:
425 .word hash_table
7139f3c8 426
57871462 427 .align 2
428 .global jump_vaddr_r0
429 .type jump_vaddr_r0, %function
430jump_vaddr_r0:
431 eor r2, r0, r0, lsl #16
432 b jump_vaddr
433 .size jump_vaddr_r0, .-jump_vaddr_r0
434 .global jump_vaddr_r1
435 .type jump_vaddr_r1, %function
436jump_vaddr_r1:
437 eor r2, r1, r1, lsl #16
438 mov r0, r1
439 b jump_vaddr
440 .size jump_vaddr_r1, .-jump_vaddr_r1
441 .global jump_vaddr_r2
442 .type jump_vaddr_r2, %function
443jump_vaddr_r2:
444 mov r0, r2
445 eor r2, r2, r2, lsl #16
446 b jump_vaddr
447 .size jump_vaddr_r2, .-jump_vaddr_r2
448 .global jump_vaddr_r3
449 .type jump_vaddr_r3, %function
450jump_vaddr_r3:
451 eor r2, r3, r3, lsl #16
452 mov r0, r3
453 b jump_vaddr
454 .size jump_vaddr_r3, .-jump_vaddr_r3
455 .global jump_vaddr_r4
456 .type jump_vaddr_r4, %function
457jump_vaddr_r4:
458 eor r2, r4, r4, lsl #16
459 mov r0, r4
460 b jump_vaddr
461 .size jump_vaddr_r4, .-jump_vaddr_r4
462 .global jump_vaddr_r5
463 .type jump_vaddr_r5, %function
464jump_vaddr_r5:
465 eor r2, r5, r5, lsl #16
466 mov r0, r5
467 b jump_vaddr
468 .size jump_vaddr_r5, .-jump_vaddr_r5
469 .global jump_vaddr_r6
470 .type jump_vaddr_r6, %function
471jump_vaddr_r6:
472 eor r2, r6, r6, lsl #16
473 mov r0, r6
474 b jump_vaddr
475 .size jump_vaddr_r6, .-jump_vaddr_r6
476 .global jump_vaddr_r8
477 .type jump_vaddr_r8, %function
478jump_vaddr_r8:
479 eor r2, r8, r8, lsl #16
480 mov r0, r8
481 b jump_vaddr
482 .size jump_vaddr_r8, .-jump_vaddr_r8
483 .global jump_vaddr_r9
484 .type jump_vaddr_r9, %function
485jump_vaddr_r9:
486 eor r2, r9, r9, lsl #16
487 mov r0, r9
488 b jump_vaddr
489 .size jump_vaddr_r9, .-jump_vaddr_r9
490 .global jump_vaddr_r10
491 .type jump_vaddr_r10, %function
492jump_vaddr_r10:
493 eor r2, r10, r10, lsl #16
494 mov r0, r10
495 b jump_vaddr
496 .size jump_vaddr_r10, .-jump_vaddr_r10
497 .global jump_vaddr_r12
498 .type jump_vaddr_r12, %function
499jump_vaddr_r12:
500 eor r2, r12, r12, lsl #16
501 mov r0, r12
502 b jump_vaddr
503 .size jump_vaddr_r12, .-jump_vaddr_r12
504 .global jump_vaddr_r7
505 .type jump_vaddr_r7, %function
506jump_vaddr_r7:
507 eor r2, r7, r7, lsl #16
508 add r0, r7, #0
509 .size jump_vaddr_r7, .-jump_vaddr_r7
510 .global jump_vaddr
511 .type jump_vaddr, %function
512jump_vaddr:
513 ldr r1, .htptr
514 mvn r3, #15
515 and r2, r3, r2, lsr #12
516 ldr r2, [r1, r2]!
517 teq r2, r0
518 ldreq pc, [r1, #4]
519 ldr r2, [r1, #8]
520 teq r2, r0
521 ldreq pc, [r1, #12]
522 str r10, [fp, #cycle_count-dynarec_local]
523 bl get_addr
524 ldr r10, [fp, #cycle_count-dynarec_local]
525 mov pc, r0
526 .size jump_vaddr, .-jump_vaddr
7139f3c8 527
57871462 528 .align 2
529 .global verify_code_ds
530 .type verify_code_ds, %function
531verify_code_ds:
532 str r8, [fp, #branch_target-dynarec_local]
533 .size verify_code_ds, .-verify_code_ds
534 .global verify_code_vm
535 .type verify_code_vm, %function
536verify_code_vm:
57871462 537 .global verify_code
538 .type verify_code, %function
539verify_code:
540 /* r1 = source */
541 /* r2 = target */
542 /* r3 = length */
543 tst r3, #4
544 mov r4, #0
545 add r3, r1, r3
546 mov r5, #0
547 ldrne r4, [r1], #4
548 mov r12, #0
549 ldrne r5, [r2], #4
550 teq r1, r3
551 beq .D3
552.D2:
553 ldr r7, [r1], #4
554 eor r9, r4, r5
555 ldr r8, [r2], #4
556 orrs r9, r9, r12
557 bne .D4
558 ldr r4, [r1], #4
559 eor r12, r7, r8
560 ldr r5, [r2], #4
561 cmp r1, r3
562 bcc .D2
563 teq r7, r8
564.D3:
565 teqeq r4, r5
566.D4:
567 ldr r8, [fp, #branch_target-dynarec_local]
568 moveq pc, lr
569.D5:
570 bl get_addr
571 mov pc, r0
572 .size verify_code, .-verify_code
7139f3c8 573 .size verify_code_vm, .-verify_code_vm
574
57871462 575 .align 2
576 .global cc_interrupt
577 .type cc_interrupt, %function
578cc_interrupt:
579 ldr r0, [fp, #last_count-dynarec_local]
580 mov r1, #0
581 mov r2, #0x1fc
582 add r10, r0, r10
583 str r1, [fp, #pending_exception-dynarec_local]
584 and r2, r2, r10, lsr #17
585 add r3, fp, #restore_candidate-dynarec_local
822b27d1 586 str r10, [fp, #cycle-dynarec_local] /* PCSX cycles */
587@@ str r10, [fp, #reg_cop0+36-dynarec_local] /* Count */
57871462 588 ldr r4, [r2, r3]
589 mov r10, lr
590 tst r4, r4
591 bne .E4
592.E1:
593 bl gen_interupt
594 mov lr, r10
822b27d1 595 ldr r10, [fp, #cycle-dynarec_local]
57871462 596 ldr r0, [fp, #next_interupt-dynarec_local]
597 ldr r1, [fp, #pending_exception-dynarec_local]
598 ldr r2, [fp, #stop-dynarec_local]
599 str r0, [fp, #last_count-dynarec_local]
600 sub r10, r10, r0
601 tst r2, r2
b021ee75 602 ldmnefd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, pc}
57871462 603 tst r1, r1
604 moveq pc, lr
605.E2:
606 ldr r0, [fp, #pcaddr-dynarec_local]
607 bl get_addr_ht
608 mov pc, r0
57871462 609.E4:
610 /* Move 'dirty' blocks to the 'clean' list */
611 lsl r5, r2, #3
612 str r1, [r2, r3]
613.E5:
614 lsrs r4, r4, #1
615 mov r0, r5
616 add r5, r5, #1
617 blcs clean_blocks
618 tst r5, #31
619 bne .E5
620 b .E1
57871462 621 .size cc_interrupt, .-cc_interrupt
7139f3c8 622
57871462 623 .align 2
624 .global do_interrupt
625 .type do_interrupt, %function
626do_interrupt:
28bc5688 627 /* FIXME: cycles already calculated, not needed? */
57871462 628 ldr r0, [fp, #pcaddr-dynarec_local]
629 bl get_addr_ht
630 ldr r1, [fp, #next_interupt-dynarec_local]
822b27d1 631 ldr r10, [fp, #cycle-dynarec_local]
57871462 632 str r1, [fp, #last_count-dynarec_local]
633 sub r10, r10, r1
634 add r10, r10, #2
635 mov pc, r0
636 .size do_interrupt, .-do_interrupt
637 .align 2
638 .global fp_exception
639 .type fp_exception, %function
640fp_exception:
641 mov r2, #0x10000000
642.E7:
643 ldr r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
644 mov r3, #0x80000000
645 str r0, [fp, #reg_cop0+56-dynarec_local] /* EPC */
646 orr r1, #2
647 add r2, r2, #0x2c
648 str r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
649 str r2, [fp, #reg_cop0+52-dynarec_local] /* Cause */
7139f3c8 650 add r0, r3, #0x80
57871462 651 bl get_addr_ht
652 mov pc, r0
653 .size fp_exception, .-fp_exception
654 .align 2
655 .global fp_exception_ds
656 .type fp_exception_ds, %function
657fp_exception_ds:
658 mov r2, #0x90000000 /* Set high bit if delay slot */
659 b .E7
660 .size fp_exception_ds, .-fp_exception_ds
7139f3c8 661
57871462 662 .align 2
663 .global jump_syscall
664 .type jump_syscall, %function
665jump_syscall:
666 ldr r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
667 mov r3, #0x80000000
668 str r0, [fp, #reg_cop0+56-dynarec_local] /* EPC */
669 orr r1, #2
670 mov r2, #0x20
671 str r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
672 str r2, [fp, #reg_cop0+52-dynarec_local] /* Cause */
7139f3c8 673 add r0, r3, #0x80
57871462 674 bl get_addr_ht
675 mov pc, r0
676 .size jump_syscall, .-jump_syscall
7139f3c8 677 .align 2
678
679 .align 2
680 .global jump_syscall_hle
681 .type jump_syscall_hle, %function
682jump_syscall_hle:
683 str r0, [fp, #pcaddr-dynarec_local] /* PC must be set to EPC for psxException */
684 ldr r2, [fp, #last_count-dynarec_local]
685 mov r1, #0 /* in delay slot */
686 add r2, r2, r10
687 mov r0, #0x20 /* cause */
688 str r2, [fp, #cycle-dynarec_local] /* PCSX cycle counter */
7139f3c8 689 bl psxException
690
691 /* note: psxException might do recorsive recompiler call from it's HLE code,
692 * so be ready for this */
822b27d1 693pcsx_return:
694 ldr r1, [fp, #next_interupt-dynarec_local]
695 ldr r10, [fp, #cycle-dynarec_local]
7139f3c8 696 ldr r0, [fp, #pcaddr-dynarec_local]
822b27d1 697 sub r10, r10, r1
698 str r1, [fp, #last_count-dynarec_local]
7139f3c8 699 bl get_addr_ht
700 mov pc, r0
701 .size jump_syscall_hle, .-jump_syscall_hle
702
703 .align 2
704 .global jump_hlecall
705 .type jump_hlecall, %function
706jump_hlecall:
707 ldr r2, [fp, #last_count-dynarec_local]
708 str r0, [fp, #pcaddr-dynarec_local]
7139f3c8 709 add r2, r2, r10
7139f3c8 710 str r2, [fp, #cycle-dynarec_local] /* PCSX cycle counter */
822b27d1 711 adr lr, pcsx_return
67ba0fb4 712 bx r1
7139f3c8 713 .size jump_hlecall, .-jump_hlecall
714
715new_dyna_leave:
716 .align 2
717 .global new_dyna_leave
718 .type new_dyna_leave, %function
719 ldr r0, [fp, #last_count-dynarec_local]
720 add r12, fp, #28
721 add r10, r0, r10
822b27d1 722 str r10, [fp, #cycle-dynarec_local]
b021ee75 723 ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, pc}
7139f3c8 724 .size new_dyna_leave, .-new_dyna_leave
725
822b27d1 726 /* these are used to call memhandlers */
57871462 727 .align 2
728 .global indirect_jump_indexed
729 .type indirect_jump_indexed, %function
730indirect_jump_indexed:
731 ldr r0, [r0, r1, lsl #2]
57871462 732 .global indirect_jump
733 .type indirect_jump, %function
734indirect_jump:
735 ldr r12, [fp, #last_count-dynarec_local]
736 add r2, r2, r12
822b27d1 737 str r2, [fp, #cycle-dynarec_local]
57871462 738 mov pc, r0
739 .size indirect_jump, .-indirect_jump
7139f3c8 740 .size indirect_jump_indexed, .-indirect_jump_indexed
741
57871462 742 .align 2
743 .global new_dyna_start
744 .type new_dyna_start, %function
745new_dyna_start:
b021ee75 746 /* ip is stored to conform EABI alignment */
747 stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr}
748.if HAVE_ARMV7
749 movw fp, #:lower16:dynarec_local
750 movt fp, #:upper16:dynarec_local
751.else
752 ldr fp, .dlptr
753.endif
7139f3c8 754 ldr r0, [fp, #pcaddr-dynarec_local]
7139f3c8 755 bl get_addr_ht
756 ldr r1, [fp, #next_interupt-dynarec_local]
822b27d1 757 ldr r10, [fp, #cycle-dynarec_local]
7139f3c8 758 str r1, [fp, #last_count-dynarec_local]
759 sub r10, r10, r1
760 mov pc, r0
57871462 761.dlptr:
b021ee75 762 .word dynarec_local
57871462 763 .size new_dyna_start, .-new_dyna_start
7139f3c8 764
7e605697 765/* --------------------------------------- */
7139f3c8 766
7e605697 767.align 2
768.global ari_read_ram8
769.global ari_read_ram16
770.global ari_read_ram32
771.global ari_read_ram_mirror8
772.global ari_read_ram_mirror16
773.global ari_read_ram_mirror32
774.global ari_write_ram8
775.global ari_write_ram16
776.global ari_write_ram32
777.global ari_write_ram_mirror8
778.global ari_write_ram_mirror16
779.global ari_write_ram_mirror32
a06c1d6e 780.global ari_read_bios8
781.global ari_read_bios16
782.global ari_read_bios32
7e605697 783.global ari_read_io8
784.global ari_read_io16
785.global ari_read_io32
786.global ari_write_io8
787.global ari_write_io16
788.global ari_write_io32
7139f3c8 789
7e605697 790.macro ari_read_ram bic_const op
791 ldr r0, [fp, #address-dynarec_local]
792.if \bic_const
793 bic r0, r0, #\bic_const
794.endif
795 \op r0, [r0]
57871462 796 str r0, [fp, #readmem_dword-dynarec_local]
797 mov pc, lr
7e605697 798.endm
799
800ari_read_ram8:
801 ari_read_ram 0, ldrb
802
803ari_read_ram16:
804 ari_read_ram 1, ldrh
805
806ari_read_ram32:
807 ari_read_ram 3, ldr
808
809.macro ari_read_ram_mirror mvn_const, op
810 ldr r0, [fp, #address-dynarec_local]
811 mvn r1, #\mvn_const
812 and r0, r1, lsr #11
813 orr r0, r0, #1<<31
814 \op r0, [r0]
815 str r0, [fp, #readmem_dword-dynarec_local]
57871462 816 mov pc, lr
7e605697 817.endm
7139f3c8 818
7e605697 819ari_read_ram_mirror8:
820 ari_read_ram_mirror 0, ldrb
821
822ari_read_ram_mirror16:
823 ari_read_ram_mirror (1<<11), ldrh
824
825ari_read_ram_mirror32:
826 ari_read_ram_mirror (3<<11), ldr
827
828/* invalidation is already taken care of by the caller */
829.macro ari_write_ram bic_const var op
830 ldr r0, [fp, #address-dynarec_local]
831 ldr r1, [fp, #\var-dynarec_local]
832.if \bic_const
833 bic r0, r0, #\bic_const
834.endif
835 \op r1, [r0]
57871462 836 mov pc, lr
7e605697 837.endm
7139f3c8 838
7e605697 839ari_write_ram8:
840 ari_write_ram 0, byte, strb
841
842ari_write_ram16:
843 ari_write_ram 1, hword, strh
844
845ari_write_ram32:
846 ari_write_ram 3, word, str
847
848.macro ari_write_ram_mirror mvn_const var op
849 ldr r0, [fp, #address-dynarec_local]
850 mvn r3, #\mvn_const
851 ldr r1, [fp, #\var-dynarec_local]
852 and r0, r3, lsr #11
853 ldr r2, [fp, #invc_ptr-dynarec_local]
854 orr r0, r0, #1<<31
855 ldrb r2, [r2, r0, lsr #12]
856 \op r1, [r0]
857 tst r2, r2
858 movne pc, lr
859 lsr r0, r0, #12
860 b invalidate_block
861.endm
862
863ari_write_ram_mirror8:
864 ari_write_ram_mirror 0, byte, strb
865
866ari_write_ram_mirror16:
867 ari_write_ram_mirror (1<<11), hword, strh
868
869ari_write_ram_mirror32:
870 ari_write_ram_mirror (3<<11), word, str
871
872
a06c1d6e 873.macro ari_read_bios_mirror bic_const op
874 ldr r0, [fp, #address-dynarec_local]
875 orr r0, r0, #0x80000000
876 bic r0, r0, #(0x20000000|\bic_const) @ map to 0x9fc...
877 \op r0, [r0]
878 str r0, [fp, #readmem_dword-dynarec_local]
879 mov pc, lr
880.endm
881
882ari_read_bios8:
883 ari_read_bios_mirror 0, ldrb
884
885ari_read_bios16:
886 ari_read_bios_mirror 1, ldrh
887
888ari_read_bios32:
889 ari_read_bios_mirror 3, ldr
890
891
7e605697 892@ for testing
893.macro ari_read_io_old tab_shift
894 str lr, [sp, #-8]! @ EABI alignment..
895.if \tab_shift == 0
896 bl psxHwRead32
897.endif
898.if \tab_shift == 1
899 bl psxHwRead16
900.endif
901.if \tab_shift == 2
902 bl psxHwRead8
903.endif
904 str r0, [fp, #readmem_dword-dynarec_local]
905 ldr pc, [sp], #8
906.endm
907
908.macro ari_read_io readop mem_tab tab_shift
909 ldr r0, [fp, #address-dynarec_local]
910 ldr r1, [fp, #psxH_ptr-dynarec_local]
911.if \tab_shift == 0
912 bic r0, r0, #3
913.endif
914.if \tab_shift == 1
915 bic r0, r0, #1
916.endif
917 bic r2, r0, #0x1f800000
918 ldr r12,[fp, #\mem_tab-dynarec_local]
919 subs r3, r2, #0x1000
920 blo 2f
921@ ari_read_io_old \tab_shift
922 cmp r3, #0x880
923 bhs 1f
924 ldr r12,[r12, r3, lsl #\tab_shift]
925 tst r12,r12
926 beq 2f
9270:
928 str lr, [sp, #-8]! @ EABI alignment..
929 blx r12
930 str r0, [fp, #readmem_dword-dynarec_local]
931 ldr pc, [sp], #8
932
9331:
934.if \tab_shift == 1 @ read16
935 cmp r2, #0x1c00
936 blo 2f
937 cmp r2, #0x1e00
938 bhs 2f
939 ldr r12,[fp, #spu_readf-dynarec_local]
940 b 0b
941.endif
9422:
943 @ no handler, just read psxH
944 \readop r0, [r1, r2]
945 str r0, [fp, #readmem_dword-dynarec_local]
57871462 946 mov pc, lr
7e605697 947.endm
948
949ari_read_io8:
950 ari_read_io ldrb, tab_read8, 2
951
952ari_read_io16:
953 ari_read_io ldrh, tab_read16, 1
954
955ari_read_io32:
956 ari_read_io ldr, tab_read32, 0
957
958.macro ari_write_io_old tab_shift
959.if \tab_shift == 0
960 b psxHwWrite32
961.endif
962.if \tab_shift == 1
963 b psxHwWrite16
964.endif
965.if \tab_shift == 2
966 b psxHwWrite8
967.endif
968.endm
969
970.macro ari_write_io opvl opst var mem_tab tab_shift
971 ldr r0, [fp, #address-dynarec_local]
972 \opvl r1, [fp, #\var-dynarec_local]
973.if \tab_shift == 0
974 bic r0, r0, #3
975.endif
976.if \tab_shift == 1
977 bic r0, r0, #1
978.endif
979 bic r2, r0, #0x1f800000
980 ldr r12,[fp, #\mem_tab-dynarec_local]
981 subs r3, r2, #0x1000
982 blo 0f
983@ ari_write_io_old \tab_shift
984 cmp r3, #0x880
985 bhs 1f
986 ldr r12,[r12, r3, lsl #\tab_shift]
987 mov r0, r1
988 tst r12,r12
989 bxne r12
9900:
991 ldr r3, [fp, #psxH_ptr-dynarec_local]
992 \opst r1, [r2, r3]
57871462 993 mov pc, lr
7e605697 9941:
995.if \tab_shift == 1 @ write16
996 cmp r2, #0x1c00
997 blo 0b
998 cmp r2, #0x1e00
999 ldrlo pc, [fp, #spu_writef-dynarec_local]
1000 nop
1001.endif
1002 b 0b
1003.endm
1004
1005ari_write_io8:
80e38194 1006 @ PCSX always writes to psxH, so do we for consistency
1007 ldr r0, [fp, #address-dynarec_local]
1008 ldr r3, [fp, #psxH_ptr-dynarec_local]
1009 ldrb r1, [fp, #byte-dynarec_local]
1010 bic r2, r0, #0x1f800000
1011 ldr r12,[fp, #tab_write8-dynarec_local]
1012 strb r1, [r2, r3]
1013 subs r3, r2, #0x1000
1014 movlo pc, lr
1015@ ari_write_io_old 2
1016 cmp r3, #0x880
1017 movhs pc, lr
1018 ldr r12,[r12, r3, lsl #2]
1019 mov r0, r1
1020 tst r12,r12
1021 bxne r12
1022 mov pc, lr
7e605697 1023
1024ari_write_io16:
1025 ari_write_io ldrh, strh, hword, tab_write16, 1
1026
1027ari_write_io32:
1028 ari_write_io ldr, str, word, tab_write32, 0
1029
1030@ vim:filetype=armasm