Win32: Add coroutine for mswin on arm64
This commit is contained in:
parent
e4a4dea2c0
commit
c25dd4ee47
Notes:
git
2024-12-17 11:56:49 +00:00
81
coroutine/arm64/Context.asm
Normal file
81
coroutine/arm64/Context.asm
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
TTL coroutine/arm64/Context.asm
|
||||||
|
|
||||||
|
AREA |.drectve|, DRECTVE
|
||||||
|
|
||||||
|
EXPORT |coroutine_transfer|
|
||||||
|
|
||||||
|
AREA |.text$mn|, CODE, ARM64
|
||||||
|
|
||||||
|
;; Add more space for certain TEB values on each stack
|
||||||
|
TEB_OFFSET EQU 0x20
|
||||||
|
|
||||||
|
;; Incomplete implementation
|
||||||
|
coroutine_transfer PROC
|
||||||
|
; Make space on the stack for caller registers
|
||||||
|
sub sp, sp, 0xa0 + TEB_OFFSET
|
||||||
|
|
||||||
|
; Save caller registers
|
||||||
|
stp d8, d9, [sp, 0x00 + TEB_OFFSET]
|
||||||
|
stp d10, d11, [sp, 0x10 + TEB_OFFSET]
|
||||||
|
stp d12, d13, [sp, 0x20 + TEB_OFFSET]
|
||||||
|
stp d14, d15, [sp, 0x30 + TEB_OFFSET]
|
||||||
|
stp x19, x20, [sp, 0x40 + TEB_OFFSET]
|
||||||
|
stp x21, x22, [sp, 0x50 + TEB_OFFSET]
|
||||||
|
stp x23, x24, [sp, 0x60 + TEB_OFFSET]
|
||||||
|
stp x25, x26, [sp, 0x70 + TEB_OFFSET]
|
||||||
|
stp x27, x28, [sp, 0x80 + TEB_OFFSET]
|
||||||
|
stp x29, x30, [sp, 0x90 + TEB_OFFSET]
|
||||||
|
|
||||||
|
;; Save certain values from Thread Environment Block (TEB) x18
|
||||||
|
;; points to the TEB on Windows
|
||||||
|
;; Read TeStackBase and TeStackLimit at ksarm64.h from TEB
|
||||||
|
ldp x5, x6, [x18, #0x08]
|
||||||
|
;; Save them
|
||||||
|
stp x5, x6, [sp, #0x00]
|
||||||
|
;; Read TeDeallocationStack at ksarm64.h from TEB
|
||||||
|
ldr x5, [x18, #0x1478]
|
||||||
|
;; Read TeFiberData at ksarm64.h from TEB
|
||||||
|
ldr x6, [x18, #0x20]
|
||||||
|
;; Save current fiber data and deallocation stack
|
||||||
|
stp x5, x6, [sp, #0x10]
|
||||||
|
|
||||||
|
; Save stack pointer to x0 (first argument)
|
||||||
|
mov x2, sp
|
||||||
|
str x2, [x0, 0]
|
||||||
|
|
||||||
|
; Load stack pointer from x1 (second argument)
|
||||||
|
ldr x3, [x1, 0]
|
||||||
|
mov sp, x3
|
||||||
|
|
||||||
|
;; Restore stack base and limit
|
||||||
|
ldp x5, x6, [sp, #0x00]
|
||||||
|
;; Write TeStackBase and TeStackLimit at ksarm64.h to TEB
|
||||||
|
stp x5, x6, [x18, #0x08]
|
||||||
|
;; Restore fiber data and deallocation stack
|
||||||
|
ldp x5, x6, [sp, #0x10]
|
||||||
|
;; Write TeDeallocationStack at ksarm64.h to TEB
|
||||||
|
str x5, [x18, #0x1478]
|
||||||
|
;; Write TeFiberData at ksarm64.h to TEB
|
||||||
|
str x6, [x18, #0x20]
|
||||||
|
|
||||||
|
; Restore caller registers
|
||||||
|
ldp d8, d9, [sp, 0x00 + TEB_OFFSET]
|
||||||
|
ldp d10, d11, [sp, 0x10 + TEB_OFFSET]
|
||||||
|
ldp d12, d13, [sp, 0x20 + TEB_OFFSET]
|
||||||
|
ldp d14, d15, [sp, 0x30 + TEB_OFFSET]
|
||||||
|
ldp x19, x20, [sp, 0x40 + TEB_OFFSET]
|
||||||
|
ldp x21, x22, [sp, 0x50 + TEB_OFFSET]
|
||||||
|
ldp x23, x24, [sp, 0x60 + TEB_OFFSET]
|
||||||
|
ldp x25, x26, [sp, 0x70 + TEB_OFFSET]
|
||||||
|
ldp x27, x28, [sp, 0x80 + TEB_OFFSET]
|
||||||
|
ldp x29, x30, [sp, 0x90 + TEB_OFFSET]
|
||||||
|
|
||||||
|
; Pop stack frame
|
||||||
|
add sp, sp, 0xa0 + TEB_OFFSET
|
||||||
|
|
||||||
|
; Jump to return address (in x30)
|
||||||
|
ret
|
||||||
|
|
||||||
|
endp
|
||||||
|
|
||||||
|
end
|
@ -15,7 +15,13 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#if defined __GNUC__
|
||||||
#define COROUTINE __attribute__((noreturn)) void
|
#define COROUTINE __attribute__((noreturn)) void
|
||||||
|
#define COROUTINE_DECL COROUTINE
|
||||||
|
#elif defined _MSC_VER
|
||||||
|
#define COROUTINE __declspec(noreturn) void
|
||||||
|
#define COROUTINE_DECL void
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#define TEB_OFFSET 0x20
|
#define TEB_OFFSET 0x20
|
||||||
@ -50,7 +56,7 @@ struct coroutine_context
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef COROUTINE(* coroutine_start)(struct coroutine_context *from, struct coroutine_context *self);
|
typedef COROUTINE_DECL(* coroutine_start)(struct coroutine_context *from, struct coroutine_context *self);
|
||||||
|
|
||||||
static inline void coroutine_initialize_main(struct coroutine_context * context) {
|
static inline void coroutine_initialize_main(struct coroutine_context * context) {
|
||||||
context->stack_pointer = NULL;
|
context->stack_pointer = NULL;
|
||||||
|
@ -336,6 +336,8 @@ COROUTINE_SRC = $(COROUTINE_OBJ:.obj=.asm)
|
|||||||
COROUTINE_OBJ = coroutine/win32/Context.obj
|
COROUTINE_OBJ = coroutine/win32/Context.obj
|
||||||
COROUTINE_SRC = $(COROUTINE_OBJ:.obj=.asm)
|
COROUTINE_SRC = $(COROUTINE_OBJ:.obj=.asm)
|
||||||
!elseif "$(ARCH)" == "arm64"
|
!elseif "$(ARCH)" == "arm64"
|
||||||
|
COROUTINE_OBJ = coroutine/arm64/Context.obj
|
||||||
|
COROUTINE_SRC = $(COROUTINE_OBJ:.obj=.asm)
|
||||||
!else
|
!else
|
||||||
!error copy coroutine has been replaced with pthread implementation at 42130a64f02294dc8025af3a51bda518c67ab33d
|
!error copy coroutine has been replaced with pthread implementation at 42130a64f02294dc8025af3a51bda518c67ab33d
|
||||||
!endif
|
!endif
|
||||||
@ -1329,6 +1331,9 @@ $(ruby_pc): $(RBCONFIG)
|
|||||||
{$(srcdir)/coroutine/win64}.asm{coroutine/win64}.obj:
|
{$(srcdir)/coroutine/win64}.asm{coroutine/win64}.obj:
|
||||||
$(ECHO) assembling $(<:\=/)
|
$(ECHO) assembling $(<:\=/)
|
||||||
$(Q) $(AS) $(ASFLAGS) $(XCFLAGS) $(CPPFLAGS) $(COUTFLAG)$@ -c $(<:\=/)
|
$(Q) $(AS) $(ASFLAGS) $(XCFLAGS) $(CPPFLAGS) $(COUTFLAG)$@ -c $(<:\=/)
|
||||||
|
{$(srcdir)/coroutine/arm64}.asm{coroutine/arm64}.obj:
|
||||||
|
$(ECHO) assembling $(<:\=/)
|
||||||
|
$(Q) $(AS) $(ASFLAGS) -o $@ $(<:\=/)
|
||||||
|
|
||||||
{$(srcdir)/prism}.c.obj:
|
{$(srcdir)/prism}.c.obj:
|
||||||
$(ECHO) compiling $(<:\=/)
|
$(ECHO) compiling $(<:\=/)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user