@@ -146,6 +146,11 @@ private
146
146
version = AsmExternal;
147
147
version = AlignFiberStackTo16Byte;
148
148
}
149
+ else version (Windows )
150
+ {
151
+ version = AsmAArch64_Windows;
152
+ version = AlignFiberStackTo16Byte;
153
+ }
149
154
}
150
155
else version (ARM )
151
156
{
@@ -355,6 +360,63 @@ private
355
360
" ~{xmm6},~{xmm7},~{xmm8},~{xmm9},~{xmm10},~{xmm11},~{xmm12},~{xmm13},~{xmm14},~{xmm15}"
356
361
);
357
362
}
363
+ else version (AsmAArch64_Windows)
364
+ {
365
+ pragma (LDC_never_inline);
366
+ asm pure nothrow @nogc
367
+ {
368
+ ` // save current stack state (similar to posix version in threadasm.S)
369
+ stp x19, x20, [sp, #-16]!
370
+ stp x21, x22, [sp, #-16]!
371
+ stp x23, x24, [sp, #-16]!
372
+ stp x25, x26, [sp, #-16]!
373
+ stp x27, x28, [sp, #-16]!
374
+ stp fp, lr, [sp, #-16]!
375
+ mov x19, sp // no need to scan FP registers, so snapshot sp here
376
+
377
+ stp d8, d9, [sp, #-16]!
378
+ stp d10, d11, [sp, #-16]!
379
+ stp d12, d13, [sp, #-16]!
380
+ stp d14, d15, [sp, #-16]!
381
+
382
+ ldr x20, [x18, #8] // read stack range from TEB
383
+ ldr x21, [x18, #16]
384
+ stp x20, x21, [sp, #-16]!
385
+
386
+ ldr x20, [x18, #0x1478] // read Deallocation Stack
387
+ ldr w21, [x18, #0x1748] // read GuaranteedStackBytes
388
+ stp x20, x21, [sp, #-16]!
389
+
390
+ // store oldp
391
+ str x19, [x0]
392
+ // load newp to begin context switch
393
+ sub x1, x1, #6*16
394
+ mov sp, x1
395
+
396
+ ldp x20, x21, [sp], #16 // restore Deallocation/GuaranteedStackBytes
397
+ str x20, [x18, #0x1478]
398
+ str w21, [x18, #0x1748] // word only
399
+
400
+ ldp x20, x21, [sp], #16 // restore stack range
401
+ str x20, [x18, #8]
402
+ str x21, [x18, #16]
403
+
404
+ // load saved state from new stack
405
+ ldp d14, d15, [sp], #16
406
+ ldp d12, d13, [sp], #16
407
+ ldp d10, d11, [sp], #16
408
+ ldp d8, d9, [sp], #16
409
+
410
+ ldp fp, lr, [sp], #16
411
+ ldp x27, x28, [sp], #16
412
+ ldp x25, x26, [sp], #16
413
+ ldp x23, x24, [sp], #16
414
+ ldp x21, x22, [sp], #16
415
+ ldp x19, x20, [sp], #16
416
+
417
+ ret` ;
418
+ }
419
+ }
358
420
else
359
421
static assert (false );
360
422
}
@@ -1616,6 +1678,41 @@ private:
1616
1678
push( cast (size_t ) m_ctxt.bstack + m_size ); // GS:[16]
1617
1679
}
1618
1680
}
1681
+ else version (AsmAArch64_Windows)
1682
+ {
1683
+ version (StackGrowsDown) {} else static assert ( false );
1684
+
1685
+ push( 0x00000000_00000000 ); // another stack frame is needed
1686
+ push( 0x00000000_00000000 ); // to catch exceptions in fiber_entryPoint
1687
+ auto nextfp = pstack;
1688
+
1689
+ push( 0x00000000_00000000 ); // X20
1690
+ push( 0x00000000_00000000 ); // X19
1691
+ push( 0x00000000_00000000 ); // X22
1692
+ push( 0x00000000_00000000 ); // X21
1693
+ push( 0x00000000_00000000 ); // X24
1694
+ push( 0x00000000_00000000 ); // X23
1695
+ push( 0x00000000_00000000 ); // X26
1696
+ push( 0x00000000_00000000 ); // X25
1697
+ push( 0x00000000_00000000 ); // X28
1698
+ push( 0x00000000_00000000 ); // X27
1699
+ push( cast (size_t ) &fiber_entryPoint ); // X30 (lr)
1700
+ push( cast (size_t ) nextfp ); // X29 (fp)
1701
+ push( 0x00000000_00000000 ); // V9 (low)
1702
+ push( 0x00000000_00000000 ); // V8 (low)
1703
+ push( 0x00000000_00000000 ); // V11 (low)
1704
+ push( 0x00000000_00000000 ); // V10 (low)
1705
+ push( 0x00000000_00000000 ); // V13 (low)
1706
+ push( 0x00000000_00000000 ); // V12 (low)
1707
+ push( 0x00000000_00000000 ); // V15 (low)
1708
+ push( 0x00000000_00000000 ); // V14 (low)
1709
+ push( cast (size_t ) m_ctxt.bstack - m_size ); // StackLimit x18[16] (X18 is TEB)
1710
+ push( cast (size_t ) m_ctxt.bstack ); // StackBase x18[8]
1711
+ push( 0x00000000_00000000 ); // GuaranteedStackBytes
1712
+ push( cast (size_t ) m_ctxt.bstack - m_size ); // DeallocationStack
1713
+
1714
+ pstack += size_t .sizeof * 12 ; // exclude V8 and TEB-entries from scanning by the GC
1715
+ }
1619
1716
else version (AsmX86_Posix)
1620
1717
{
1621
1718
push( 0x00000000 ); // Return address of fiber_entryPoint call
0 commit comments