drc: sync gte with interpreter
[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:
627 ldr r0, [fp, #pcaddr-dynarec_local]
628 bl get_addr_ht
57871462 629 add r10, r10, #2
630 mov pc, r0
631 .size do_interrupt, .-do_interrupt
fca1aef2 632
57871462 633 .align 2
634 .global fp_exception
635 .type fp_exception, %function
636fp_exception:
637 mov r2, #0x10000000
638.E7:
639 ldr r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
640 mov r3, #0x80000000
641 str r0, [fp, #reg_cop0+56-dynarec_local] /* EPC */
642 orr r1, #2
643 add r2, r2, #0x2c
644 str r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
645 str r2, [fp, #reg_cop0+52-dynarec_local] /* Cause */
7139f3c8 646 add r0, r3, #0x80
57871462 647 bl get_addr_ht
648 mov pc, r0
649 .size fp_exception, .-fp_exception
650 .align 2
651 .global fp_exception_ds
652 .type fp_exception_ds, %function
653fp_exception_ds:
654 mov r2, #0x90000000 /* Set high bit if delay slot */
655 b .E7
656 .size fp_exception_ds, .-fp_exception_ds
7139f3c8 657
57871462 658 .align 2
659 .global jump_syscall
660 .type jump_syscall, %function
661jump_syscall:
662 ldr r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
663 mov r3, #0x80000000
664 str r0, [fp, #reg_cop0+56-dynarec_local] /* EPC */
665 orr r1, #2
666 mov r2, #0x20
667 str r1, [fp, #reg_cop0+48-dynarec_local] /* Status */
668 str r2, [fp, #reg_cop0+52-dynarec_local] /* Cause */
7139f3c8 669 add r0, r3, #0x80
57871462 670 bl get_addr_ht
671 mov pc, r0
672 .size jump_syscall, .-jump_syscall
7139f3c8 673 .align 2
674
675 .align 2
676 .global jump_syscall_hle
677 .type jump_syscall_hle, %function
678jump_syscall_hle:
679 str r0, [fp, #pcaddr-dynarec_local] /* PC must be set to EPC for psxException */
680 ldr r2, [fp, #last_count-dynarec_local]
681 mov r1, #0 /* in delay slot */
682 add r2, r2, r10
683 mov r0, #0x20 /* cause */
684 str r2, [fp, #cycle-dynarec_local] /* PCSX cycle counter */
7139f3c8 685 bl psxException
686
687 /* note: psxException might do recorsive recompiler call from it's HLE code,
688 * so be ready for this */
822b27d1 689pcsx_return:
690 ldr r1, [fp, #next_interupt-dynarec_local]
691 ldr r10, [fp, #cycle-dynarec_local]
7139f3c8 692 ldr r0, [fp, #pcaddr-dynarec_local]
822b27d1 693 sub r10, r10, r1
694 str r1, [fp, #last_count-dynarec_local]
7139f3c8 695 bl get_addr_ht
696 mov pc, r0
697 .size jump_syscall_hle, .-jump_syscall_hle
698
699 .align 2
700 .global jump_hlecall
701 .type jump_hlecall, %function
702jump_hlecall:
703 ldr r2, [fp, #last_count-dynarec_local]
704 str r0, [fp, #pcaddr-dynarec_local]
7139f3c8 705 add r2, r2, r10
822b27d1 706 adr lr, pcsx_return
0d16cda2 707 str r2, [fp, #cycle-dynarec_local] /* PCSX cycle counter */
67ba0fb4 708 bx r1
7139f3c8 709 .size jump_hlecall, .-jump_hlecall
710
0d16cda2 711 .align 2
712 .global jump_intcall
713 .type jump_intcall, %function
714jump_intcall:
715 ldr r2, [fp, #last_count-dynarec_local]
716 str r0, [fp, #pcaddr-dynarec_local]
717 add r2, r2, r10
718 adr lr, pcsx_return
719 str r2, [fp, #cycle-dynarec_local] /* PCSX cycle counter */
720 b execI
721 .size jump_hlecall, .-jump_hlecall
722
7139f3c8 723new_dyna_leave:
724 .align 2
725 .global new_dyna_leave
726 .type new_dyna_leave, %function
727 ldr r0, [fp, #last_count-dynarec_local]
728 add r12, fp, #28
729 add r10, r0, r10
822b27d1 730 str r10, [fp, #cycle-dynarec_local]
b021ee75 731 ldmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, pc}
7139f3c8 732 .size new_dyna_leave, .-new_dyna_leave
733
822b27d1 734 /* these are used to call memhandlers */
57871462 735 .align 2
736 .global indirect_jump_indexed
737 .type indirect_jump_indexed, %function
738indirect_jump_indexed:
739 ldr r0, [r0, r1, lsl #2]
57871462 740 .global indirect_jump
741 .type indirect_jump, %function
742indirect_jump:
743 ldr r12, [fp, #last_count-dynarec_local]
744 add r2, r2, r12
822b27d1 745 str r2, [fp, #cycle-dynarec_local]
57871462 746 mov pc, r0
747 .size indirect_jump, .-indirect_jump
7139f3c8 748 .size indirect_jump_indexed, .-indirect_jump_indexed
749
57871462 750 .align 2
751 .global new_dyna_start
752 .type new_dyna_start, %function
753new_dyna_start:
b021ee75 754 /* ip is stored to conform EABI alignment */
755 stmfd sp!, {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr}
756.if HAVE_ARMV7
757 movw fp, #:lower16:dynarec_local
758 movt fp, #:upper16:dynarec_local
759.else
760 ldr fp, .dlptr
761.endif
7139f3c8 762 ldr r0, [fp, #pcaddr-dynarec_local]
7139f3c8 763 bl get_addr_ht
764 ldr r1, [fp, #next_interupt-dynarec_local]
822b27d1 765 ldr r10, [fp, #cycle-dynarec_local]
7139f3c8 766 str r1, [fp, #last_count-dynarec_local]
767 sub r10, r10, r1
768 mov pc, r0
57871462 769.dlptr:
b021ee75 770 .word dynarec_local
57871462 771 .size new_dyna_start, .-new_dyna_start
7139f3c8 772
7e605697 773/* --------------------------------------- */
7139f3c8 774
7e605697 775.align 2
776.global ari_read_ram8
777.global ari_read_ram16
778.global ari_read_ram32
779.global ari_read_ram_mirror8
780.global ari_read_ram_mirror16
781.global ari_read_ram_mirror32
782.global ari_write_ram8
783.global ari_write_ram16
784.global ari_write_ram32
785.global ari_write_ram_mirror8
786.global ari_write_ram_mirror16
787.global ari_write_ram_mirror32
a06c1d6e 788.global ari_read_bios8
789.global ari_read_bios16
790.global ari_read_bios32
7e605697 791.global ari_read_io8
792.global ari_read_io16
793.global ari_read_io32
794.global ari_write_io8
795.global ari_write_io16
796.global ari_write_io32
7139f3c8 797
7e605697 798.macro ari_read_ram bic_const op
799 ldr r0, [fp, #address-dynarec_local]
800.if \bic_const
801 bic r0, r0, #\bic_const
802.endif
803 \op r0, [r0]
57871462 804 str r0, [fp, #readmem_dword-dynarec_local]
805 mov pc, lr
7e605697 806.endm
807
808ari_read_ram8:
809 ari_read_ram 0, ldrb
810
811ari_read_ram16:
812 ari_read_ram 1, ldrh
813
814ari_read_ram32:
815 ari_read_ram 3, ldr
816
817.macro ari_read_ram_mirror mvn_const, op
818 ldr r0, [fp, #address-dynarec_local]
819 mvn r1, #\mvn_const
820 and r0, r1, lsr #11
821 orr r0, r0, #1<<31
822 \op r0, [r0]
823 str r0, [fp, #readmem_dword-dynarec_local]
57871462 824 mov pc, lr
7e605697 825.endm
7139f3c8 826
7e605697 827ari_read_ram_mirror8:
828 ari_read_ram_mirror 0, ldrb
829
830ari_read_ram_mirror16:
831 ari_read_ram_mirror (1<<11), ldrh
832
833ari_read_ram_mirror32:
834 ari_read_ram_mirror (3<<11), ldr
835
836/* invalidation is already taken care of by the caller */
0d16cda2 837.macro ari_write_ram bic_const var pf
7e605697 838 ldr r0, [fp, #address-dynarec_local]
0d16cda2 839 ldr\pf r1, [fp, #\var-dynarec_local]
7e605697 840.if \bic_const
841 bic r0, r0, #\bic_const
842.endif
0d16cda2 843 str\pf r1, [r0]
57871462 844 mov pc, lr
7e605697 845.endm
7139f3c8 846
7e605697 847ari_write_ram8:
0d16cda2 848 ari_write_ram 0, byte, b
7e605697 849
850ari_write_ram16:
0d16cda2 851 ari_write_ram 1, hword, h
7e605697 852
853ari_write_ram32:
0d16cda2 854 ari_write_ram 3, word,
7e605697 855
0d16cda2 856.macro ari_write_ram_mirror mvn_const var pf
7e605697 857 ldr r0, [fp, #address-dynarec_local]
858 mvn r3, #\mvn_const
0d16cda2 859 ldr\pf r1, [fp, #\var-dynarec_local]
7e605697 860 and r0, r3, lsr #11
861 ldr r2, [fp, #invc_ptr-dynarec_local]
862 orr r0, r0, #1<<31
863 ldrb r2, [r2, r0, lsr #12]
0d16cda2 864 str\pf r1, [r0]
7e605697 865 tst r2, r2
866 movne pc, lr
867 lsr r0, r0, #12
868 b invalidate_block
869.endm
870
871ari_write_ram_mirror8:
0d16cda2 872 ari_write_ram_mirror 0, byte, b
7e605697 873
874ari_write_ram_mirror16:
0d16cda2 875 ari_write_ram_mirror (1<<11), hword, h
7e605697 876
877ari_write_ram_mirror32:
0d16cda2 878 ari_write_ram_mirror (3<<11), word,
7e605697 879
880
a06c1d6e 881.macro ari_read_bios_mirror bic_const op
882 ldr r0, [fp, #address-dynarec_local]
883 orr r0, r0, #0x80000000
884 bic r0, r0, #(0x20000000|\bic_const) @ map to 0x9fc...
885 \op r0, [r0]
886 str r0, [fp, #readmem_dword-dynarec_local]
887 mov pc, lr
888.endm
889
890ari_read_bios8:
891 ari_read_bios_mirror 0, ldrb
892
893ari_read_bios16:
894 ari_read_bios_mirror 1, ldrh
895
896ari_read_bios32:
897 ari_read_bios_mirror 3, ldr
898
899
7e605697 900@ for testing
901.macro ari_read_io_old tab_shift
902 str lr, [sp, #-8]! @ EABI alignment..
903.if \tab_shift == 0
904 bl psxHwRead32
905.endif
906.if \tab_shift == 1
907 bl psxHwRead16
908.endif
909.if \tab_shift == 2
910 bl psxHwRead8
911.endif
912 str r0, [fp, #readmem_dword-dynarec_local]
913 ldr pc, [sp], #8
914.endm
915
916.macro ari_read_io readop mem_tab tab_shift
917 ldr r0, [fp, #address-dynarec_local]
918 ldr r1, [fp, #psxH_ptr-dynarec_local]
919.if \tab_shift == 0
920 bic r0, r0, #3
921.endif
922.if \tab_shift == 1
923 bic r0, r0, #1
924.endif
925 bic r2, r0, #0x1f800000
926 ldr r12,[fp, #\mem_tab-dynarec_local]
927 subs r3, r2, #0x1000
928 blo 2f
929@ ari_read_io_old \tab_shift
930 cmp r3, #0x880
931 bhs 1f
932 ldr r12,[r12, r3, lsl #\tab_shift]
933 tst r12,r12
934 beq 2f
9350:
936 str lr, [sp, #-8]! @ EABI alignment..
937 blx r12
938 str r0, [fp, #readmem_dword-dynarec_local]
939 ldr pc, [sp], #8
940
9411:
942.if \tab_shift == 1 @ read16
943 cmp r2, #0x1c00
944 blo 2f
945 cmp r2, #0x1e00
946 bhs 2f
947 ldr r12,[fp, #spu_readf-dynarec_local]
948 b 0b
949.endif
9502:
951 @ no handler, just read psxH
952 \readop r0, [r1, r2]
953 str r0, [fp, #readmem_dword-dynarec_local]
57871462 954 mov pc, lr
7e605697 955.endm
956
957ari_read_io8:
958 ari_read_io ldrb, tab_read8, 2
959
960ari_read_io16:
961 ari_read_io ldrh, tab_read16, 1
962
963ari_read_io32:
964 ari_read_io ldr, tab_read32, 0
965
966.macro ari_write_io_old tab_shift
967.if \tab_shift == 0
968 b psxHwWrite32
969.endif
970.if \tab_shift == 1
971 b psxHwWrite16
972.endif
973.if \tab_shift == 2
974 b psxHwWrite8
975.endif
976.endm
977
0d16cda2 978.macro ari_write_io pf var mem_tab tab_shift
7e605697 979 ldr r0, [fp, #address-dynarec_local]
0d16cda2 980 ldr\pf r1, [fp, #\var-dynarec_local]
7e605697 981.if \tab_shift == 0
982 bic r0, r0, #3
983.endif
984.if \tab_shift == 1
985 bic r0, r0, #1
986.endif
987 bic r2, r0, #0x1f800000
988 ldr r12,[fp, #\mem_tab-dynarec_local]
989 subs r3, r2, #0x1000
990 blo 0f
991@ ari_write_io_old \tab_shift
992 cmp r3, #0x880
993 bhs 1f
994 ldr r12,[r12, r3, lsl #\tab_shift]
995 mov r0, r1
996 tst r12,r12
997 bxne r12
9980:
999 ldr r3, [fp, #psxH_ptr-dynarec_local]
0d16cda2 1000 str\pf r1, [r2, r3]
57871462 1001 mov pc, lr
7e605697 10021:
1003.if \tab_shift == 1 @ write16
1004 cmp r2, #0x1c00
1005 blo 0b
1006 cmp r2, #0x1e00
1007 ldrlo pc, [fp, #spu_writef-dynarec_local]
1008 nop
1009.endif
1010 b 0b
1011.endm
1012
1013ari_write_io8:
80e38194 1014 @ PCSX always writes to psxH, so do we for consistency
1015 ldr r0, [fp, #address-dynarec_local]
1016 ldr r3, [fp, #psxH_ptr-dynarec_local]
1017 ldrb r1, [fp, #byte-dynarec_local]
1018 bic r2, r0, #0x1f800000
1019 ldr r12,[fp, #tab_write8-dynarec_local]
1020 strb r1, [r2, r3]
1021 subs r3, r2, #0x1000
1022 movlo pc, lr
1023@ ari_write_io_old 2
1024 cmp r3, #0x880
1025 movhs pc, lr
1026 ldr r12,[r12, r3, lsl #2]
1027 mov r0, r1
1028 tst r12,r12
1029 bxne r12
1030 mov pc, lr
7e605697 1031
1032ari_write_io16:
0d16cda2 1033 ari_write_io h, hword, tab_write16, 1
7e605697 1034
1035ari_write_io32:
0d16cda2 1036 ari_write_io , word, tab_write32, 0
7e605697 1037
1038@ vim:filetype=armasm