1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * linkage_arm.s for PCSX *
3 * Copyright (C) 2009-2011 Ari64 *
4 * Copyright (C) 2021 notaz *
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. *
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. *
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 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
22 #include "arm_features.h"
23 #include "new_dynarec_config.h"
24 #include "assem_arm64.h"
25 #include "linkage_offsets.h"
30 .type dynarec_local, %object
31 .size dynarec_local, LO_dynarec_local_size
33 .space LO_dynarec_local_size
35 #define DRC_VAR_(name, vname, size_) \
36 vname = dynarec_local + LO_##name; \
38 .type vname, %object; \
41 #define DRC_VAR(name, size_) \
42 DRC_VAR_(name, ESYM(name), size_)
44 DRC_VAR(next_interupt, 4)
45 DRC_VAR(cycle_count, 4)
46 DRC_VAR(last_count, 4)
47 DRC_VAR(pending_exception, 4)
51 DRC_VAR(psxRegs, LO_psxRegs_end - LO_psxRegs)
57 DRC_VAR(reg_cop0, 128)
58 DRC_VAR(reg_cop2d, 128)
59 DRC_VAR(reg_cop2c, 128)
63 #DRC_VAR(interrupt, 4)
64 #DRC_VAR(intCycle, 256)
70 DRC_VAR(zeromem_ptr, 4)
71 DRC_VAR(inv_code_start, 4)
72 DRC_VAR(inv_code_end, 4)
73 DRC_VAR(branch_target, 4)
74 DRC_VAR(scratch_buf_ptr, 4)
75 #DRC_VAR(align0, 12) /* unused/alignment */
77 DRC_VAR(restore_candidate, 512)
83 /* r0 = virtual target address */
84 /* r1 = instruction to patch */
85 .macro dyna_linker_main
86 /* XXX: should be able to do better than this... */
92 FUNCTION(dyna_linker):
93 /* r0 = virtual target address */
94 /* r1 = instruction to patch */
96 .size dyna_linker, .-dyna_linker
98 FUNCTION(exec_pagefault):
99 /* r0 = instruction pointer */
100 /* r1 = fault address */
103 .size exec_pagefault, .-exec_pagefault
105 /* Special dynamic linker for the case where a page fault
106 may occur in a branch delay slot */
107 FUNCTION(dyna_linker_ds):
108 /* r0 = virtual target address */
109 /* r1 = instruction to patch */
111 .size dyna_linker_ds, .-dyna_linker_ds
115 FUNCTION(jump_vaddr):
117 .size jump_vaddr, .-jump_vaddr
121 FUNCTION(verify_code_ds):
123 FUNCTION(verify_code_vm):
124 FUNCTION(verify_code):
129 .size verify_code, .-verify_code
130 .size verify_code_vm, .-verify_code_vm
133 FUNCTION(cc_interrupt):
135 .size cc_interrupt, .-cc_interrupt
138 FUNCTION(do_interrupt):
140 .size do_interrupt, .-do_interrupt
143 FUNCTION(fp_exception):
146 ldr w1, [fp, #LO_reg_cop0+48] /* Status */
148 str w0, [fp, #LO_reg_cop0+56] /* EPC */
151 str w1, [fp, #LO_reg_cop0+48] /* Status */
152 str w2, [fp, #LO_reg_cop0+52] /* Cause */
156 .size fp_exception, .-fp_exception
158 FUNCTION(fp_exception_ds):
159 mov w2, #0x90000000 /* Set high bit if delay slot */
161 .size fp_exception_ds, .-fp_exception_ds
164 FUNCTION(jump_syscall):
165 ldr w1, [fp, #LO_reg_cop0+48] /* Status */
167 str w0, [fp, #LO_reg_cop0+56] /* EPC */
170 str w1, [fp, #LO_reg_cop0+48] /* Status */
171 str w2, [fp, #LO_reg_cop0+52] /* Cause */
175 .size jump_syscall, .-jump_syscall
179 FUNCTION(jump_syscall_hle):
182 /* note: psxException might do recursive recompiler call from it's HLE code,
183 * so be ready for this */
186 ldr w1, [fp, #LO_next_interupt]
187 ldr w10, [fp, #LO_cycle]
188 ldr w0, [fp, #LO_pcaddr]
190 str w1, [fp, #LO_last_count]
193 .size jump_syscall_hle, .-jump_syscall_hle
196 FUNCTION(jump_hlecall):
198 .size jump_hlecall, .-jump_hlecall
201 FUNCTION(jump_intcall):
203 .size jump_intcall, .-jump_intcall
206 FUNCTION(new_dyna_start):
207 stp x29, x30, [sp, #-96]! // must be aligned by 16
208 ldr w1, [x0, #LO_next_interupt]
209 ldr w2, [x0, #LO_cycle]
210 stp x19, x20, [sp, #16*1]
211 stp x21, x22, [sp, #16*2]
212 stp x23, x24, [sp, #16*3]
213 stp x25, x26, [sp, #16*4]
214 stp x27, x28, [sp, #16*5]
216 ldr w0, [rFP, #LO_pcaddr]
217 str w1, [rFP, #LO_last_count]
221 .size new_dyna_start, .-new_dyna_start
224 FUNCTION(new_dyna_leave):
225 ldr w0, [rFP, #LO_last_count]
227 str rCC, [rFP, #LO_cycle]
228 ldp x19, x20, [sp, #16*1]
229 ldp x21, x22, [sp, #16*2]
230 ldp x23, x24, [sp, #16*3]
231 ldp x25, x26, [sp, #16*4]
232 ldp x27, x28, [sp, #16*5]
233 ldp x29, x30, [sp], #96
235 .size new_dyna_leave, .-new_dyna_leave
237 /* --------------------------------------- */
241 FUNCTION(jump_handler_read8):
244 FUNCTION(jump_handler_read16):
247 FUNCTION(jump_handler_read32):
250 FUNCTION(jump_handler_write8):
253 FUNCTION(jump_handler_write16):
256 FUNCTION(jump_handler_write32):
259 FUNCTION(jump_handler_write_h):
262 FUNCTION(jump_handle_swl):
265 FUNCTION(jump_handle_swr):