1 // Copyright 2025 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 #include "go_asm.h"
6 #include "textflag.h"
7
8 TEXT ·StdCall<ABIInternal>(SB),NOSPLIT,$0
9 MOVQ AX, CX
10 JMP ·asmstdcall(SB)
11
12 TEXT ·asmstdcall(SB),NOSPLIT,$16
13 MOVQ SP, AX
14 ANDQ $~15, SP // alignment as per Windows requirement
15 MOVQ AX, 8(SP)
16 MOVQ CX, 0(SP) // asmcgocall will put first argument into CX.
17
18 MOVQ StdCallInfo_Fn(CX), AX
19 MOVQ StdCallInfo_Args(CX), SI
20 MOVQ StdCallInfo_N(CX), CX
21
22 // SetLastError(0).
23 MOVQ 0x30(GS), DI
24 MOVL $0, 0x68(DI)
25
26 MOVQ SP, R12 // save frame pointer in the callee-saved R12 register to restore it before return
27 SUBQ $32, SP // reserve shadow space (Windows x64 ABI)
28
29 // Fast version (n <= 4): no stack copy needed.
30 CMPL CX, $0; JE _0args
31 CMPL CX, $1; JE _1args
32 CMPL CX, $2; JE _2args
33 CMPL CX, $3; JE _3args
34 CMPL CX, $4; JE _4args
35
36 // Slow version (n > 4): grow stack for remaining args.
37 // Stack stays 16-byte aligned by rounding extra slots to even.
38 LEAQ -3(CX), R8
39 ANDQ $~1, R8
40 SHLQ $3, R8
41 SUBQ R8, SP
42
43 // Copy args to the stack.
44 MOVQ SP, DI
45 CLD
46 REP; MOVSQ
47 MOVQ SP, SI
48
49 // Load first 4 args into correspondent registers.
50 // Floating point arguments are passed in the XMM
51 // registers. Set them here in case any of the arguments
52 // are floating point values. For details see
53 // https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170
54 _4args:
55 MOVQ 24(SI), R9
56 MOVQ R9, X3
57 _3args:
58 MOVQ 16(SI), R8
59 MOVQ R8, X2
60 _2args:
61 MOVQ 8(SI), DX
62 MOVQ DX, X1
63 _1args:
64 MOVQ 0(SI), CX
65 MOVQ CX, X0
66 _0args:
67
68 // Call stdcall function.
69 CALL AX
70
71 MOVQ R12, SP // restore frame pointer
72
73 // Return result.
74 MOVQ 0(SP), CX
75 MOVQ 8(SP), SP
76 MOVQ AX, StdCallInfo_R1(CX)
77 // Floating point return values are returned in XMM0. Setting r2 to this
78 // value in case this call returned a floating point value. For details,
79 // see https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention
80 MOVQ X0, StdCallInfo_R2(CX)
81
82 // GetLastError().
83 MOVQ 0x30(GS), DI
84 MOVL 0x68(DI), AX
85
86 RET
87
View as plain text