try to fix win32 build
[pcsx_rearmed.git] / libpcsxcore / new_dynarec / linkage_arm64.S
CommitLineData
be516ebe 1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2 * linkage_arm.s for PCSX *
3 * Copyright (C) 2009-2011 Ari64 *
4 * Copyright (C) 2021 notaz *
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 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
21
22#include "arm_features.h"
23#include "new_dynarec_config.h"
24#include "assem_arm64.h"
25#include "linkage_offsets.h"
26
39b71d9a 27#if (LO_mem_wtab & 7)
28#error misligned pointers
29#endif
30
be516ebe 31.bss
32 .align 4
33 .global dynarec_local
34 .type dynarec_local, %object
35 .size dynarec_local, LO_dynarec_local_size
36dynarec_local:
37 .space LO_dynarec_local_size
38
39#define DRC_VAR_(name, vname, size_) \
40 vname = dynarec_local + LO_##name; \
41 .global vname; \
42 .type vname, %object; \
43 .size vname, size_
44
45#define DRC_VAR(name, size_) \
46 DRC_VAR_(name, ESYM(name), size_)
47
48DRC_VAR(next_interupt, 4)
49DRC_VAR(cycle_count, 4)
50DRC_VAR(last_count, 4)
51DRC_VAR(pending_exception, 4)
52DRC_VAR(stop, 4)
687b4580 53DRC_VAR(branch_target, 4)
be516ebe 54DRC_VAR(address, 4)
7f94b097 55DRC_VAR(hack_addr, 4)
be516ebe 56DRC_VAR(psxRegs, LO_psxRegs_end - LO_psxRegs)
57
58/* psxRegs */
7c3a5182 59#DRC_VAR(reg, 128)
be516ebe 60DRC_VAR(lo, 4)
61DRC_VAR(hi, 4)
62DRC_VAR(reg_cop0, 128)
63DRC_VAR(reg_cop2d, 128)
64DRC_VAR(reg_cop2c, 128)
65DRC_VAR(pcaddr, 4)
66#DRC_VAR(code, 4)
67#DRC_VAR(cycle, 4)
68#DRC_VAR(interrupt, 4)
69#DRC_VAR(intCycle, 256)
70
71DRC_VAR(rcnts, 7*4*4)
be516ebe 72DRC_VAR(inv_code_start, 4)
73DRC_VAR(inv_code_end, 4)
687b4580 74DRC_VAR(mem_rtab, 8)
75DRC_VAR(mem_wtab, 8)
76DRC_VAR(psxH_ptr, 8)
77DRC_VAR(invc_ptr, 8)
78DRC_VAR(zeromem_ptr, 8)
79DRC_VAR(scratch_buf_ptr, 8)
37387d8b 80DRC_VAR(ram_offset, 8)
be516ebe 81DRC_VAR(mini_ht, 256)
be516ebe 82
83
84 .text
85 .align 2
86
be516ebe 87FUNCTION(dyna_linker):
88 /* r0 = virtual target address */
89 /* r1 = instruction to patch */
104df9d3 90 bl ndrc_get_addr_ht
4bdc30ab 91 br x0
be516ebe 92 .size dyna_linker, .-dyna_linker
93
be516ebe 94 .align 2
95FUNCTION(cc_interrupt):
d1e4ebd9 96 ldr w0, [rFP, #LO_last_count]
d1e4ebd9 97 add rCC, w0, rCC
98 str wzr, [rFP, #LO_pending_exception]
d1e4ebd9 99 str rCC, [rFP, #LO_cycle] /* PCSX cycles */
100# str rCC, [rFP, #LO_reg_cop0+36] /* Count */
d1e4ebd9 101 mov x21, lr
d1e4ebd9 1021:
6d75addf 103 add x0, rFP, #(LO_psxRegs + 34*4) /* CP0 */
d1e4ebd9 104 bl gen_interupt
105 mov lr, x21
106 ldr rCC, [rFP, #LO_cycle]
107 ldr w0, [rFP, #LO_next_interupt]
108 ldr w1, [rFP, #LO_pending_exception]
109 ldr w2, [rFP, #LO_stop]
110 str w0, [rFP, #LO_last_count]
111 sub rCC, rCC, w0
112 cbnz w2, new_dyna_leave
113 cbnz w1, 2f
114 ret
1152:
116 ldr w0, [rFP, #LO_pcaddr]
104df9d3 117 bl ndrc_get_addr_ht
d1e4ebd9 118 br x0
be516ebe 119 .size cc_interrupt, .-cc_interrupt
120
be516ebe 121 .align 2
122FUNCTION(fp_exception):
123 mov w2, #0x10000000
1240:
81dbbf4c 125 ldr w1, [rFP, #LO_reg_cop0+48] /* Status */
be516ebe 126 mov w3, #0x80000000
81dbbf4c 127 str w0, [rFP, #LO_reg_cop0+56] /* EPC */
be516ebe 128 orr w1, w1, #2
129 add w2, w2, #0x2c
81dbbf4c 130 str w1, [rFP, #LO_reg_cop0+48] /* Status */
131 str w2, [rFP, #LO_reg_cop0+52] /* Cause */
be516ebe 132 add w0, w3, #0x80
104df9d3 133 bl ndrc_get_addr_ht
be516ebe 134 br x0
135 .size fp_exception, .-fp_exception
136 .align 2
137FUNCTION(fp_exception_ds):
138 mov w2, #0x90000000 /* Set high bit if delay slot */
139 b 0b
140 .size fp_exception_ds, .-fp_exception_ds
141
142 .align 2
d1150cd6 143FUNCTION(jump_break_ds):
144 mov w0, #0x24
145 mov w1, #1
146 b call_psxException
147FUNCTION(jump_break):
148 mov w0, #0x24
149 mov w1, #0
150 b call_psxException
151FUNCTION(jump_syscall_ds):
152 mov w0, #0x20
bc7c5acb 153 mov w1, #2
d1150cd6 154 b call_psxException
be516ebe 155FUNCTION(jump_syscall):
d1150cd6 156 mov w0, #0x20
157 mov w1, #0
158
159call_psxException:
160 ldr w3, [rFP, #LO_last_count]
161 str w2, [rFP, #LO_pcaddr]
162 add rCC, w3, rCC
6d75addf 163 str rCC, [rFP, #LO_cycle] /* PCSX cycles */
164 add x2, rFP, #(LO_psxRegs + 34*4) /* CP0 */
d1150cd6 165 bl psxException
be516ebe 166
be516ebe 167 /* note: psxException might do recursive recompiler call from it's HLE code,
168 * so be ready for this */
3968e69e 169FUNCTION(jump_to_new_pc):
81dbbf4c 170 ldr w1, [rFP, #LO_next_interupt]
171 ldr rCC, [rFP, #LO_cycle]
172 ldr w0, [rFP, #LO_pcaddr]
3968e69e 173 sub rCC, rCC, w1
81dbbf4c 174 str w1, [rFP, #LO_last_count]
104df9d3 175 bl ndrc_get_addr_ht
be516ebe 176 br x0
3968e69e 177 .size jump_to_new_pc, .-jump_to_new_pc
be516ebe 178
687b4580 179 /* stack must be aligned by 16, and include space for save_regs() use */
be516ebe 180 .align 2
181FUNCTION(new_dyna_start):
687b4580 182 stp x29, x30, [sp, #-SSP_ALL]!
be516ebe 183 ldr w1, [x0, #LO_next_interupt]
184 ldr w2, [x0, #LO_cycle]
185 stp x19, x20, [sp, #16*1]
186 stp x21, x22, [sp, #16*2]
187 stp x23, x24, [sp, #16*3]
188 stp x25, x26, [sp, #16*4]
189 stp x27, x28, [sp, #16*5]
190 mov rFP, x0
191 ldr w0, [rFP, #LO_pcaddr]
192 str w1, [rFP, #LO_last_count]
193 sub rCC, w2, w1
104df9d3 194 bl ndrc_get_addr_ht
be516ebe 195 br x0
196 .size new_dyna_start, .-new_dyna_start
197
198 .align 2
199FUNCTION(new_dyna_leave):
200 ldr w0, [rFP, #LO_last_count]
201 add rCC, rCC, w0
202 str rCC, [rFP, #LO_cycle]
203 ldp x19, x20, [sp, #16*1]
204 ldp x21, x22, [sp, #16*2]
205 ldp x23, x24, [sp, #16*3]
206 ldp x25, x26, [sp, #16*4]
207 ldp x27, x28, [sp, #16*5]
687b4580 208 ldp x29, x30, [sp], #SSP_ALL
be516ebe 209 ret
210 .size new_dyna_leave, .-new_dyna_leave
211
212/* --------------------------------------- */
213
214.align 2
215
d1e4ebd9 216.macro memhandler_pre
217 /* w0 = adddr/data, x1 = rhandler, w2 = cycles, x3 = whandler */
218 ldr w4, [rFP, #LO_last_count]
219 add w4, w4, w2
220 str w4, [rFP, #LO_cycle]
221.endm
222
223.macro memhandler_post
9b9af0d1 224 ldr w0, [rFP, #LO_next_interupt]
225 ldr w2, [rFP, #LO_cycle] // memhandlers can modify cc, like dma
226 str w0, [rFP, #LO_last_count]
227 sub w0, w2, w0
d1e4ebd9 228.endm
229
230FUNCTION(do_memhandler_pre):
231 memhandler_pre
232 ret
233
234FUNCTION(do_memhandler_post):
235 memhandler_post
236 ret
237
238.macro pcsx_read_mem readop tab_shift
239 /* w0 = address, x1 = handler_tab, w2 = cycles */
d1e4ebd9 240 ubfm w4, w0, #\tab_shift, #11
241 ldr x3, [x1, w4, uxtw #3]
242 adds x3, x3, x3
243 bcs 0f
244 \readop w0, [x3, w4, uxtw #\tab_shift]
245 ret
2460:
3968e69e 247 stp xzr, x30, [sp, #-16]!
d1e4ebd9 248 memhandler_pre
249 blr x3
250.endm
251
be516ebe 252FUNCTION(jump_handler_read8):
3968e69e 253 add x1, x1, #0x1000/4*8 + 0x1000/2*8 /* shift to r8 part */
d1e4ebd9 254 pcsx_read_mem ldrb, 0
255 b handler_read_end
be516ebe 256
257FUNCTION(jump_handler_read16):
3968e69e 258 add x1, x1, #0x1000/4*8 /* shift to r16 part */
d1e4ebd9 259 pcsx_read_mem ldrh, 1
260 b handler_read_end
be516ebe 261
262FUNCTION(jump_handler_read32):
d1e4ebd9 263 pcsx_read_mem ldr, 2
264
265handler_read_end:
266 ldp xzr, x30, [sp], #16
267 ret
268
269.macro pcsx_write_mem wrtop movop tab_shift
270 /* w0 = address, w1 = data, w2 = cycles, x3 = handler_tab */
d1e4ebd9 271 ubfm w4, w0, #\tab_shift, #11
272 ldr x3, [x3, w4, uxtw #3]
d1e4ebd9 273 adds x3, x3, x3
d1e4ebd9 274 bcs 0f
275 mov w0, w2 /* cycle return */
276 \wrtop w1, [x3, w4, uxtw #\tab_shift]
277 ret
2780:
3968e69e 279 stp xzr, x30, [sp, #-16]!
280 str w0, [rFP, #LO_address] /* some handlers still need it... */
d1e4ebd9 281 \movop w0, w1
282 memhandler_pre
283 blr x3
284.endm
be516ebe 285
286FUNCTION(jump_handler_write8):
3968e69e 287 add x3, x3, #0x1000/4*8 + 0x1000/2*8 /* shift to r8 part */
d1e4ebd9 288 pcsx_write_mem strb uxtb 0
289 b handler_write_end
be516ebe 290
291FUNCTION(jump_handler_write16):
3968e69e 292 add x3, x3, #0x1000/4*8 /* shift to r16 part */
d1e4ebd9 293 pcsx_write_mem strh uxth 1
294 b handler_write_end
be516ebe 295
296FUNCTION(jump_handler_write32):
d1e4ebd9 297 pcsx_write_mem str mov 2
be516ebe 298
d1e4ebd9 299handler_write_end:
300 memhandler_post
301 ldp xzr, x30, [sp], #16
302 ret
be516ebe 303
304FUNCTION(jump_handle_swl):
3968e69e 305 /* w0 = address, w1 = data, w2 = cycles */
81dbbf4c 306 ldr x3, [rFP, #LO_mem_wtab]
48ce2528 307 orr w4, wzr, w0, lsr #12
3968e69e 308 ldr x3, [x3, w4, uxtw #3]
309 adds x3, x3, x3
310 bcs 4f
311 add x3, x0, x3
312 mov w0, w2
313 tbz x3, #1, 10f // & 2
314 tbz x3, #0, 2f // & 1
3153:
316 stur w1, [x3, #-3]
317 ret
3182:
319 lsr w2, w1, #8
320 lsr w1, w1, #24
321 sturh w2, [x3, #-2]
322 strb w1, [x3]
323 ret
32410:
325 tbz x3, #0, 0f // & 1
3261:
327 lsr w1, w1, #16
328 sturh w1, [x3, #-1]
329 ret
3300:
331 lsr w2, w1, #24
332 strb w2, [x3]
333 ret
3344:
335 mov w0, w2 // todo
be516ebe 336 bl abort
3968e69e 337 ret
be516ebe 338
339FUNCTION(jump_handle_swr):
3968e69e 340 /* w0 = address, w1 = data, w2 = cycles */
81dbbf4c 341 ldr x3, [rFP, #LO_mem_wtab]
48ce2528 342 orr w4, wzr, w0, lsr #12
3968e69e 343 ldr x3, [x3, w4, uxtw #3]
344 adds x3, x3, x3
345 bcs 4f
346 add x3, x0, x3
347 mov w0, w2
348 tbz x3, #1, 10f // & 2
349 tbz x3, #0, 2f // & 1
3503:
351 strb w1, [x3]
352 ret
3532:
354 strh w1, [x3]
355 ret
35610:
357 tbz x3, #0, 0f // & 1
3581:
359 lsr w2, w1, #8
360 strb w1, [x3]
361 sturh w2, [x3, #1]
362 ret
3630:
364 str w1, [x3]
365 ret
3664:
367 mov w0, w2 // todo
be516ebe 368 bl abort
3968e69e 369 ret
be516ebe 370
81dbbf4c 371FUNCTION(call_gteStall):
372 /* w0 = op_cycles, w1 = cycles */
373 ldr w2, [rFP, #LO_last_count]
374 str lr, [rFP, #LO_saved_lr]
375 add w1, w1, w2
376 str w1, [rFP, #LO_cycle]
377 add x1, rFP, #LO_psxRegs
378 bl gteCheckStallRaw
379 ldr lr, [rFP, #LO_saved_lr]
380 add rCC, rCC, w0
381 ret
382