| // Copyright 2025 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| #include "go_asm.h" |
| #include "textflag.h" |
| |
| // Offsets into Thread Environment Block (pointer in R18) |
| #define TEB_error 0x68 |
| |
| TEXT ·StdCall<ABIInternal>(SB),NOSPLIT,$0 |
| B ·asmstdcall(SB) |
| |
| TEXT ·asmstdcall(SB),NOSPLIT,$16 |
| STP (R19, R20), 16(RSP) // save old R19, R20 |
| MOVD R0, R19 // save fn pointer |
| MOVD RSP, R20 // save stack pointer |
| |
| // SetLastError(0) |
| MOVD $0, TEB_error(R18_PLATFORM) |
| MOVD StdCallInfo_Args(R19), R12 |
| |
| // Do we have more than 8 arguments? |
| MOVD StdCallInfo_N(R19), R0 |
| CMP $0, R0; BEQ _0args |
| CMP $1, R0; BEQ _1args |
| CMP $2, R0; BEQ _2args |
| CMP $3, R0; BEQ _3args |
| CMP $4, R0; BEQ _4args |
| CMP $5, R0; BEQ _5args |
| CMP $6, R0; BEQ _6args |
| CMP $7, R0; BEQ _7args |
| CMP $8, R0; BEQ _8args |
| |
| // Reserve stack space for remaining args |
| SUB $8, R0, R2 |
| ADD $1, R2, R3 // make even number of words for stack alignment |
| AND $~1, R3 |
| LSL $3, R3 |
| SUB R3, RSP |
| |
| // R4: size of stack arguments (n-8)*8 |
| // R5: &args[8] |
| // R6: loop counter, from 0 to (n-8)*8 |
| // R7: scratch |
| // R8: copy of RSP - (R2)(RSP) assembles as (R2)(ZR) |
| SUB $8, R0, R4 |
| LSL $3, R4 |
| ADD $(8*8), R12, R5 |
| MOVD $0, R6 |
| MOVD RSP, R8 |
| stackargs: |
| MOVD (R6)(R5), R7 |
| MOVD R7, (R6)(R8) |
| ADD $8, R6 |
| CMP R6, R4 |
| BNE stackargs |
| |
| _8args: |
| MOVD (7*8)(R12), R7 |
| _7args: |
| MOVD (6*8)(R12), R6 |
| _6args: |
| MOVD (5*8)(R12), R5 |
| _5args: |
| MOVD (4*8)(R12), R4 |
| _4args: |
| MOVD (3*8)(R12), R3 |
| _3args: |
| MOVD (2*8)(R12), R2 |
| _2args: |
| MOVD (1*8)(R12), R1 |
| _1args: |
| MOVD (0*8)(R12), R0 |
| _0args: |
| |
| MOVD StdCallInfo_Fn(R19), R12 |
| BL (R12) |
| |
| MOVD R20, RSP // free stack space |
| MOVD R0, StdCallInfo_R1(R19) // save return value |
| // TODO(rsc) floating point like amd64 in StdCallInfo_R2? |
| |
| // GetLastError |
| MOVD TEB_error(R18_PLATFORM), R0 |
| MOVD R0, StdCallInfo_Err(R19) |
| |
| // Restore callee-saved registers. |
| LDP 16(RSP), (R19, R20) |
| RET |