Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit c261b6e

Browse files
committed
core.thread: Add support for AArch64
1 parent 9402a93 commit c261b6e

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

src/core/thread.d

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3539,6 +3539,15 @@ private
35393539
version = AsmExternal;
35403540
}
35413541
}
3542+
else version( AArch64 )
3543+
{
3544+
version( Posix )
3545+
{
3546+
version = AsmAArch64_Posix;
3547+
version = AsmExternal;
3548+
version = AlignFiberStackTo16Byte;
3549+
}
3550+
}
35423551
else version( ARM )
35433552
{
35443553
version( Posix )
@@ -4870,6 +4879,29 @@ private:
48704879
pstack -= ABOVE;
48714880
*cast(size_t*)(pstack - SZ_RA) = cast(size_t)&fiber_entryPoint;
48724881
}
4882+
else version( AsmAArch64_Posix )
4883+
{
4884+
// Like others, FP registers and return address (lr) are kept
4885+
// below the saved stack top (tstack) to hide from GC scanning.
4886+
// fiber_switchContext expects newp sp to look like this:
4887+
// 19: x19
4888+
// ...
4889+
// 9: x29 (fp) <-- newp tstack
4890+
// 8: x30 (lr) [&fiber_entryPoint]
4891+
// 7: d8
4892+
// ...
4893+
// 0: d15
4894+
4895+
version( StackGrowsDown ) {}
4896+
else
4897+
static assert(false, "Only full descending stacks supported on AArch64");
4898+
4899+
// Only need to set return address (lr). Everything else is fine
4900+
// zero initialized.
4901+
pstack -= size_t.sizeof * 11; // skip past x19-x29
4902+
push(cast(size_t) &fiber_entryPoint);
4903+
pstack += size_t.sizeof; // adjust sp (newp) above lr
4904+
}
48734905
else version( AsmARM_Posix )
48744906
{
48754907
/* We keep the FP registers and the return address below

src/core/threadasm.S

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,4 +449,59 @@ fiber_switchContext:
449449
// return by writing lr into pc
450450
mov pc, r1
451451
.fnend
452+
453+
#elif defined(__aarch64__)
454+
/************************************************************************************
455+
* AArch64 (arm64) ASM BITS
456+
************************************************************************************/
457+
/**
458+
* preserve/restore AAPCS64 registers
459+
* x19-x28 5.1.1 64-bit callee saved
460+
* x29 fp, or possibly callee saved reg - depends on platform choice 5.2.3)
461+
* x30 lr
462+
* d8-d15 5.1.2 says callee only must save bottom 64-bits (the "d" regs)
463+
*
464+
* saved regs on stack will look like:
465+
* 19: x19
466+
* 18: x20
467+
* ...
468+
* 10: x28
469+
* 9: x29 (fp) <-- oldp / *newp save stack top
470+
* 8: x30 (lr)
471+
* 7: d8
472+
* ...
473+
* 0: d15 <-- sp
474+
*/
475+
.text
476+
.global CSYM(fiber_switchContext)
477+
.p2align 2
478+
CSYM(fiber_switchContext):
479+
stp d15, d14, [sp, #-20*8]!
480+
stp d13, d12, [sp, #2*8]
481+
stp d11, d10, [sp, #4*8]
482+
stp d9, d8, [sp, #6*8]
483+
stp x30, x29, [sp, #8*8] // lr, fp
484+
stp x28, x27, [sp, #10*8]
485+
stp x26, x25, [sp, #12*8]
486+
stp x24, x23, [sp, #14*8]
487+
stp x22, x21, [sp, #16*8]
488+
stp x20, x19, [sp, #18*8]
489+
490+
// oldp is set above saved lr (x30) to hide it and float regs
491+
// from GC
492+
add x19, sp, #9*8
493+
str x19, [x0] // *oldp tstack
494+
sub sp, x1, #9*8 // switch to newp sp
495+
496+
ldp x20, x19, [sp, #18*8]
497+
ldp x22, x21, [sp, #16*8]
498+
ldp x24, x23, [sp, #14*8]
499+
ldp x26, x25, [sp, #12*8]
500+
ldp x28, x27, [sp, #10*8]
501+
ldp x30, x29, [sp, #8*8] // lr, fp
502+
ldp d9, d8, [sp, #6*8]
503+
ldp d11, d10, [sp, #4*8]
504+
ldp d13, d12, [sp, #2*8]
505+
ldp d15, d14, [sp], #20*8
506+
ret
452507
#endif

0 commit comments

Comments
 (0)