1;
2; stack switching code for MASM on x641
3; Kristjan Valur Jonsson, sept 2005
4;
5
6
7;prototypes for our calls
8slp_save_state_asm PROTO
9slp_restore_state_asm PROTO
10
11
12pushxmm MACRO reg
13    sub rsp, 16
14    .allocstack 16
15    movaps [rsp], reg ; faster than movups, but we must be aligned
16    ; .savexmm128 reg, offset  (don't know what offset is, no documentation)
17ENDM
18popxmm MACRO reg
19    movaps reg, [rsp] ; faster than movups, but we must be aligned
20    add rsp, 16
21ENDM
22
23pushreg MACRO reg
24    push reg
25    .pushreg reg
26ENDM
27popreg MACRO reg
28    pop reg
29ENDM
30
31
32.code
33slp_switch PROC FRAME
34    ;realign stack to 16 bytes after return address push, makes the following faster
35    sub rsp,8
36    .allocstack 8
37
38    pushxmm xmm15
39    pushxmm xmm14
40    pushxmm xmm13
41    pushxmm xmm12
42    pushxmm xmm11
43    pushxmm xmm10
44    pushxmm xmm9
45    pushxmm xmm8
46    pushxmm xmm7
47    pushxmm xmm6
48
49    pushreg r15
50    pushreg r14
51    pushreg r13
52    pushreg r12
53
54    pushreg rbp
55    pushreg rbx
56    pushreg rdi
57    pushreg rsi
58
59    sub rsp, 10h ;allocate the singlefunction argument (must be multiple of 16)
60    .allocstack 10h
61.endprolog
62
63    lea rcx, [rsp+10h] ;load stack base that we are saving
64    call slp_save_state_asm ;pass stackpointer, return offset in eax
65    cmp rax, 1
66    je EXIT1
67    cmp rax, -1
68    je EXIT2
69    ;actual stack switch:
70    add rsp, rax
71    call slp_restore_state_asm
72    xor rax, rax ;return 0
73
74EXIT:
75
76    add rsp, 10h
77    popreg rsi
78    popreg rdi
79    popreg rbx
80    popreg rbp
81
82    popreg r12
83    popreg r13
84    popreg r14
85    popreg r15
86
87    popxmm xmm6
88    popxmm xmm7
89    popxmm xmm8
90    popxmm xmm9
91    popxmm xmm10
92    popxmm xmm11
93    popxmm xmm12
94    popxmm xmm13
95    popxmm xmm14
96    popxmm xmm15
97
98    add rsp, 8
99    ret
100
101EXIT1:
102    mov rax, 1
103    jmp EXIT
104
105EXIT2:
106    sar rax, 1
107    jmp EXIT
108
109slp_switch ENDP
110
111END