frontend: update libpicofe, fix missed callbacks
[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
c57af5e6 27#ifdef __MACH__
28#define dynarec_local ESYM(dynarec_local)
555d3b51 29#define ndrc_patch_link ESYM(ndrc_patch_link)
c57af5e6 30#define ndrc_get_addr_ht ESYM(ndrc_get_addr_ht)
f49a4c48 31#define ndrc_get_addr_ht_param ESYM(ndrc_get_addr_ht_param)
c57af5e6 32#define gen_interupt ESYM(gen_interupt)
c57af5e6 33#define psxException ESYM(psxException)
34#define execI ESYM(execI)
35#endif
36
39b71d9a 37#if (LO_mem_wtab & 7)
38#error misligned pointers
39#endif
40
be516ebe 41.bss
42 .align 4
43 .global dynarec_local
c57af5e6 44 EOBJECT(dynarec_local)
45 ESIZE(dynarec_local, LO_dynarec_local_size)
be516ebe 46dynarec_local:
47 .space LO_dynarec_local_size
48
49#define DRC_VAR_(name, vname, size_) \
c57af5e6 50 vname = dynarec_local + LO_##name ASM_SEPARATOR \
51 .globl vname; \
52 EOBJECT(vname); \
53 ESIZE(vname, LO_dynarec_local_size)
be516ebe 54
55#define DRC_VAR(name, size_) \
56 DRC_VAR_(name, ESYM(name), size_)
57
c87406ff 58#DRC_VAR(next_interupt, 4)
be516ebe 59DRC_VAR(cycle_count, 4)
60DRC_VAR(last_count, 4)
c87406ff 61#DRC_VAR(stop, 4)
be516ebe 62DRC_VAR(address, 4)
7f94b097 63DRC_VAR(hack_addr, 4)
be516ebe 64DRC_VAR(psxRegs, LO_psxRegs_end - LO_psxRegs)
65
66/* psxRegs */
0b1633d7 67#DRC_VAR(lo, 4)
68#DRC_VAR(hi, 4)
be516ebe 69DRC_VAR(reg_cop2d, 128)
70DRC_VAR(reg_cop2c, 128)
be516ebe 71#DRC_VAR(code, 4)
72#DRC_VAR(cycle, 4)
73#DRC_VAR(interrupt, 4)
74#DRC_VAR(intCycle, 256)
75
76DRC_VAR(rcnts, 7*4*4)
be516ebe 77DRC_VAR(inv_code_start, 4)
78DRC_VAR(inv_code_end, 4)
687b4580 79DRC_VAR(mem_rtab, 8)
80DRC_VAR(mem_wtab, 8)
81DRC_VAR(psxH_ptr, 8)
82DRC_VAR(invc_ptr, 8)
83DRC_VAR(zeromem_ptr, 8)
22346d41 84DRC_VAR(scratch_buf_ptr, 8)
37387d8b 85DRC_VAR(ram_offset, 8)
22346d41 86DRC_VAR(hash_table_ptr, 8)
be516ebe 87DRC_VAR(mini_ht, 256)
be516ebe 88
89
90 .text
91 .align 2
92
be516ebe 93FUNCTION(dyna_linker):
555d3b51 94 /* w0 = virtual target address */
95 /* x1 = instruction to patch */
96#if 1
97 mov w19, w0
98 mov x20, x1
99 /* must not compile - that might expire the caller block */
100 ldr x0, [rFP, #LO_hash_table_ptr]
101 mov w1, w19
102 mov w2, #0 /* ndrc_compile_mode=ndrc_cm_no_compile */
103 bl ndrc_get_addr_ht_param
104 cbz x0, 0f
105
106 ldr w2, [x20]
107 mov x3, x0
108 sbfiz x2, x2, 2, 26
109 add x2, x2, x20
110 mov x1, x20
111 mov w0, w19
112 mov x19, x3
113 bl ndrc_patch_link
114 br x19
1150:
116 mov w0, w19
117#endif
ea5c2d78 118 ldr x1, [rFP, #LO_hash_table_ptr]
104df9d3 119 bl ndrc_get_addr_ht
4bdc30ab 120 br x0
c57af5e6 121 ESIZE(dyna_linker, .-dyna_linker)
be516ebe 122
be516ebe 123 .align 2
124FUNCTION(cc_interrupt):
d1e4ebd9 125 ldr w0, [rFP, #LO_last_count]
e7172b26 126 ldr w22, [rFP, #LO_pcaddr]
d1e4ebd9 127 add rCC, w0, rCC
d1e4ebd9 128 str rCC, [rFP, #LO_cycle] /* PCSX cycles */
d1e4ebd9 129 mov x21, lr
d1e4ebd9 1301:
de6dbc52 131 add x0, rFP, #LO_reg_cop0 /* CP0 */
d1e4ebd9 132 bl gen_interupt
133 mov lr, x21
134 ldr rCC, [rFP, #LO_cycle]
e7172b26 135 ldr w0, [rFP, #LO_pcaddr]
136 ldr w1, [rFP, #LO_next_interupt]
bb17f8f4 137 ldrb w2, [rFP, #LO_stop]
e7172b26 138 str w1, [rFP, #LO_last_count]
139 sub rCC, rCC, w1
d1e4ebd9 140 cbnz w2, new_dyna_leave
e7172b26 141 cmp w0, w22
142 bne 2f
d1e4ebd9 143 ret
1442:
ea5c2d78 145 ldr x1, [rFP, #LO_hash_table_ptr]
104df9d3 146 bl ndrc_get_addr_ht
d1e4ebd9 147 br x0
c57af5e6 148 ESIZE(cc_interrupt, .-cc_interrupt)
be516ebe 149
be516ebe 150 .align 2
277718fa 151FUNCTION(jump_addrerror_ds): /* R3000E_AdEL / R3000E_AdES in w0 */
152 str w1, [rFP, #(LO_psxRegs + (34+8)*4)] /* BadVaddr */
153 mov w1, #1
154 b call_psxException
155FUNCTION(jump_addrerror):
156 str w1, [rFP, #(LO_psxRegs + (34+8)*4)] /* BadVaddr */
157 mov w1, #0
158 b call_psxException
a5cd72d0 159FUNCTION(jump_overflow_ds):
160 mov w0, #(12<<2) /* R3000E_Ov */
161 mov w1, #1
162 b call_psxException
163FUNCTION(jump_overflow):
164 mov w0, #(12<<2)
165 mov w1, #0
166 b call_psxException
d1150cd6 167FUNCTION(jump_break_ds):
a5cd72d0 168 mov w0, #(9<<2) /* R3000E_Bp */
d1150cd6 169 mov w1, #1
170 b call_psxException
171FUNCTION(jump_break):
a5cd72d0 172 mov w0, #(9<<2)
d1150cd6 173 mov w1, #0
174 b call_psxException
175FUNCTION(jump_syscall_ds):
a5cd72d0 176 mov w0, #(8<<2) /* R3000E_Syscall */
bc7c5acb 177 mov w1, #2
d1150cd6 178 b call_psxException
be516ebe 179FUNCTION(jump_syscall):
a5cd72d0 180 mov w0, #(8<<2)
d1150cd6 181 mov w1, #0
182
183call_psxException:
184 ldr w3, [rFP, #LO_last_count]
185 str w2, [rFP, #LO_pcaddr]
186 add rCC, w3, rCC
6d75addf 187 str rCC, [rFP, #LO_cycle] /* PCSX cycles */
de6dbc52 188 add x2, rFP, #LO_reg_cop0 /* CP0 */
d1150cd6 189 bl psxException
be516ebe 190
be516ebe 191 /* note: psxException might do recursive recompiler call from it's HLE code,
192 * so be ready for this */
3968e69e 193FUNCTION(jump_to_new_pc):
bb17f8f4 194 ldrb w2, [rFP, #LO_stop]
81dbbf4c 195 ldr w1, [rFP, #LO_next_interupt]
196 ldr rCC, [rFP, #LO_cycle]
197 ldr w0, [rFP, #LO_pcaddr]
3968e69e 198 sub rCC, rCC, w1
81dbbf4c 199 str w1, [rFP, #LO_last_count]
dc4fa8bc 200 cbnz w2, new_dyna_leave
ea5c2d78 201 ldr x1, [rFP, #LO_hash_table_ptr]
104df9d3 202 bl ndrc_get_addr_ht
be516ebe 203 br x0
c57af5e6 204 ESIZE(jump_to_new_pc, .-jump_to_new_pc)
be516ebe 205
687b4580 206 /* stack must be aligned by 16, and include space for save_regs() use */
be516ebe 207 .align 2
0b1633d7 208FUNCTION(new_dyna_start_at):
209 stp x29, x30, [sp, #-SSP_ALL]!
210 mov rFP, x0
211 b new_dyna_start_at_e
212
be516ebe 213FUNCTION(new_dyna_start):
687b4580 214 stp x29, x30, [sp, #-SSP_ALL]!
0b1633d7 215 mov rFP, x0
216 ldr w0, [rFP, #LO_pcaddr]
ea5c2d78 217 ldr x1, [rFP, #LO_hash_table_ptr]
0b1633d7 218 bl ndrc_get_addr_ht
ea5c2d78 219 mov x1, x0
0b1633d7 220new_dyna_start_at_e:
221 ldr w3, [rFP, #LO_next_interupt]
222 ldr w2, [rFP, #LO_cycle]
be516ebe 223 stp x19, x20, [sp, #16*1]
224 stp x21, x22, [sp, #16*2]
225 stp x23, x24, [sp, #16*3]
226 stp x25, x26, [sp, #16*4]
227 stp x27, x28, [sp, #16*5]
0b1633d7 228 str w3, [rFP, #LO_last_count]
229 sub rCC, w2, w3
230 br x1
c57af5e6 231 ESIZE(new_dyna_start, .-new_dyna_start)
be516ebe 232
233 .align 2
234FUNCTION(new_dyna_leave):
235 ldr w0, [rFP, #LO_last_count]
236 add rCC, rCC, w0
237 str rCC, [rFP, #LO_cycle]
238 ldp x19, x20, [sp, #16*1]
239 ldp x21, x22, [sp, #16*2]
240 ldp x23, x24, [sp, #16*3]
241 ldp x25, x26, [sp, #16*4]
242 ldp x27, x28, [sp, #16*5]
687b4580 243 ldp x29, x30, [sp], #SSP_ALL
be516ebe 244 ret
c57af5e6 245 ESIZE(new_dyna_leave, .-new_dyna_leave)
be516ebe 246
247/* --------------------------------------- */
248
249.align 2
250
d1e4ebd9 251.macro memhandler_pre
eb38e4a2 252 /* w0 = addr/data, x1 = rhandler, w2 = cycles, x3 = whandler */
d1e4ebd9 253 ldr w4, [rFP, #LO_last_count]
254 add w4, w4, w2
255 str w4, [rFP, #LO_cycle]
256.endm
257
258.macro memhandler_post
7da5c7ad 259 /* w2 = cycles_out, x3 = tmp */
260 ldr w3, [rFP, #LO_next_interupt]
9b9af0d1 261 ldr w2, [rFP, #LO_cycle] // memhandlers can modify cc, like dma
7da5c7ad 262 str w3, [rFP, #LO_last_count]
263 sub w2, w2, w3
d1e4ebd9 264.endm
265
266FUNCTION(do_memhandler_pre):
267 memhandler_pre
268 ret
269
270FUNCTION(do_memhandler_post):
271 memhandler_post
272 ret
273
274.macro pcsx_read_mem readop tab_shift
275 /* w0 = address, x1 = handler_tab, w2 = cycles */
d1e4ebd9 276 ubfm w4, w0, #\tab_shift, #11
277 ldr x3, [x1, w4, uxtw #3]
278 adds x3, x3, x3
279 bcs 0f
280 \readop w0, [x3, w4, uxtw #\tab_shift]
281 ret
2820:
3968e69e 283 stp xzr, x30, [sp, #-16]!
d1e4ebd9 284 memhandler_pre
285 blr x3
286.endm
287
be516ebe 288FUNCTION(jump_handler_read8):
3968e69e 289 add x1, x1, #0x1000/4*8 + 0x1000/2*8 /* shift to r8 part */
d1e4ebd9 290 pcsx_read_mem ldrb, 0
7da5c7ad 291 ldp xzr, x30, [sp], #16
292 ret
be516ebe 293
294FUNCTION(jump_handler_read16):
3968e69e 295 add x1, x1, #0x1000/4*8 /* shift to r16 part */
d1e4ebd9 296 pcsx_read_mem ldrh, 1
7da5c7ad 297 ldp xzr, x30, [sp], #16
298 ret
be516ebe 299
300FUNCTION(jump_handler_read32):
d1e4ebd9 301 pcsx_read_mem ldr, 2
7da5c7ad 302 /* memhandler_post */
d1e4ebd9 303 ldp xzr, x30, [sp], #16
304 ret
305
306.macro pcsx_write_mem wrtop movop tab_shift
307 /* w0 = address, w1 = data, w2 = cycles, x3 = handler_tab */
d1e4ebd9 308 ubfm w4, w0, #\tab_shift, #11
309 ldr x3, [x3, w4, uxtw #3]
d1e4ebd9 310 adds x3, x3, x3
d1e4ebd9 311 bcs 0f
d1e4ebd9 312 \wrtop w1, [x3, w4, uxtw #\tab_shift]
313 ret
3140:
3968e69e 315 stp xzr, x30, [sp, #-16]!
316 str w0, [rFP, #LO_address] /* some handlers still need it... */
d1e4ebd9 317 \movop w0, w1
318 memhandler_pre
319 blr x3
320.endm
be516ebe 321
322FUNCTION(jump_handler_write8):
3968e69e 323 add x3, x3, #0x1000/4*8 + 0x1000/2*8 /* shift to r8 part */
c57af5e6 324 pcsx_write_mem strb, uxtb, 0
d1e4ebd9 325 b handler_write_end
be516ebe 326
327FUNCTION(jump_handler_write16):
3968e69e 328 add x3, x3, #0x1000/4*8 /* shift to r16 part */
c57af5e6 329 pcsx_write_mem strh, uxth, 1
d1e4ebd9 330 b handler_write_end
be516ebe 331
332FUNCTION(jump_handler_write32):
c57af5e6 333 pcsx_write_mem str, mov, 2
be516ebe 334
d1e4ebd9 335handler_write_end:
336 memhandler_post
337 ldp xzr, x30, [sp], #16
338 ret
be516ebe 339
340FUNCTION(jump_handle_swl):
3968e69e 341 /* w0 = address, w1 = data, w2 = cycles */
81dbbf4c 342 ldr x3, [rFP, #LO_mem_wtab]
48ce2528 343 orr w4, wzr, w0, lsr #12
3968e69e 344 ldr x3, [x3, w4, uxtw #3]
345 adds x3, x3, x3
de6dbc52 346 bcs jump_handle_swx_interp
3968e69e 347 add x3, x0, x3
348 mov w0, w2
349 tbz x3, #1, 10f // & 2
350 tbz x3, #0, 2f // & 1
3513:
352 stur w1, [x3, #-3]
353 ret
3542:
355 lsr w2, w1, #8
356 lsr w1, w1, #24
357 sturh w2, [x3, #-2]
358 strb w1, [x3]
359 ret
36010:
361 tbz x3, #0, 0f // & 1
3621:
363 lsr w1, w1, #16
364 sturh w1, [x3, #-1]
365 ret
3660:
367 lsr w2, w1, #24
368 strb w2, [x3]
369 ret
be516ebe 370
371FUNCTION(jump_handle_swr):
3968e69e 372 /* w0 = address, w1 = data, w2 = cycles */
81dbbf4c 373 ldr x3, [rFP, #LO_mem_wtab]
48ce2528 374 orr w4, wzr, w0, lsr #12
3968e69e 375 ldr x3, [x3, w4, uxtw #3]
376 adds x3, x3, x3
de6dbc52 377 bcs jump_handle_swx_interp
3968e69e 378 add x3, x0, x3
379 mov w0, w2
380 tbz x3, #1, 10f // & 2
381 tbz x3, #0, 2f // & 1
3823:
383 strb w1, [x3]
384 ret
3852:
386 strh w1, [x3]
387 ret
38810:
389 tbz x3, #0, 0f // & 1
3901:
391 lsr w2, w1, #8
392 strb w1, [x3]
393 sturh w2, [x3, #1]
394 ret
3950:
396 str w1, [x3]
397 ret
de6dbc52 398
399jump_handle_swx_interp: /* almost never happens */
400 ldr w3, [rFP, #LO_last_count]
401 add x0, rFP, #LO_psxRegs
402 add w2, w3, w2
403 str w2, [rFP, #LO_cycle] /* PCSX cycles */
404 bl execI
405 b jump_to_new_pc
be516ebe 406
33a1eda1 407#ifdef DRC_DBG
408#undef do_insn_cmp
409FUNCTION(do_insn_cmp_arm64):
410 stp x2, x3, [sp, #(SSP_CALLEE_REGS + 2*8)]
411 stp x4, x5, [sp, #(SSP_CALLEE_REGS + 4*8)]
412 stp x6, x7, [sp, #(SSP_CALLEE_REGS + 6*8)]
413 stp x8, x9, [sp, #(SSP_CALLEE_REGS + 8*8)]
414 stp x10, x11, [sp, #(SSP_CALLEE_REGS + 10*8)]
415 stp x12, x13, [sp, #(SSP_CALLEE_REGS + 12*8)]
416 stp x14, x15, [sp, #(SSP_CALLEE_REGS + 14*8)]
417 stp x16, x17, [sp, #(SSP_CALLEE_REGS + 16*8)]
418 stp x18, x30, [sp, #(SSP_CALLEE_REGS + 18*8)]
419 bl do_insn_cmp
420 ldp x2, x3, [sp, #(SSP_CALLEE_REGS + 2*8)]
421 ldp x4, x5, [sp, #(SSP_CALLEE_REGS + 4*8)]
422 ldp x6, x7, [sp, #(SSP_CALLEE_REGS + 6*8)]
423 ldp x8, x9, [sp, #(SSP_CALLEE_REGS + 8*8)]
424 ldp x10, x11, [sp, #(SSP_CALLEE_REGS + 10*8)]
425 ldp x12, x13, [sp, #(SSP_CALLEE_REGS + 12*8)]
426 ldp x14, x15, [sp, #(SSP_CALLEE_REGS + 14*8)]
427 ldp x16, x17, [sp, #(SSP_CALLEE_REGS + 16*8)]
428 ldp x18, x30, [sp, #(SSP_CALLEE_REGS + 18*8)]
429 ret
430#endif