+.macro memhandler_pre
+ /* w0 = adddr/data, x1 = rhandler, w2 = cycles, x3 = whandler */
+ ldr w4, [rFP, #LO_last_count]
+ add w4, w4, w2
+ str w4, [rFP, #LO_cycle]
+.endm
+
+.macro memhandler_post
+ ldr w0, [rFP, #LO_next_interupt]
+ ldr w2, [rFP, #LO_cycle] // memhandlers can modify cc, like dma
+ str w0, [rFP, #LO_last_count]
+ sub w0, w2, w0
+.endm
+
+FUNCTION(do_memhandler_pre):
+ memhandler_pre
+ ret
+
+FUNCTION(do_memhandler_post):
+ memhandler_post
+ ret
+
+.macro pcsx_read_mem readop tab_shift
+ /* w0 = address, x1 = handler_tab, w2 = cycles */
+ ubfm w4, w0, #\tab_shift, #11
+ ldr x3, [x1, w4, uxtw #3]
+ adds x3, x3, x3
+ bcs 0f
+ \readop w0, [x3, w4, uxtw #\tab_shift]
+ ret
+0:
+ stp xzr, x30, [sp, #-16]!
+ memhandler_pre
+ blr x3
+.endm
+