github.com/jwijenbergh/purego@v0.0.0-20240126093400-70ff3a61df13/sys_unix_arm64.s (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // SPDX-FileCopyrightText: 2023 The Ebitengine Authors
     3  
     4  //go:build darwin || freebsd || linux
     5  
     6  #include "textflag.h"
     7  #include "go_asm.h"
     8  #include "funcdata.h"
     9  #include "abi_arm64.h"
    10  
    11  TEXT callbackasm1(SB), NOSPLIT|NOFRAME, $0
    12  	NO_LOCAL_POINTERS
    13  
    14  	// On entry, the trampoline in zcallback_darwin_arm64.s left
    15  	// the callback index in R12 (which is volatile in the C ABI).
    16  
    17  	// Save callback register arguments R0-R7 and F0-F7.
    18  	// We do this at the top of the frame so they're contiguous with stack arguments.
    19  	SUB   $(16*8), RSP, R14
    20  	FSTPD (F0, F1), (0*8)(R14)
    21  	FSTPD (F2, F3), (2*8)(R14)
    22  	FSTPD (F4, F5), (4*8)(R14)
    23  	FSTPD (F6, F7), (6*8)(R14)
    24  	STP   (R0, R1), (8*8)(R14)
    25  	STP   (R2, R3), (10*8)(R14)
    26  	STP   (R4, R5), (12*8)(R14)
    27  	STP   (R6, R7), (14*8)(R14)
    28  
    29  	// Adjust SP by frame size.
    30  	SUB $(26*8), RSP
    31  
    32  	// It is important to save R27 because the go assembler
    33  	// uses it for move instructions for a variable.
    34  	// This line:
    35  	// MOVD ·callbackWrap_call(SB), R0
    36  	// Creates the instructions:
    37  	// ADRP 14335(PC), R27
    38  	// MOVD 388(27), R0
    39  	// R27 is a callee saved register so we are responsible
    40  	// for ensuring its value doesn't change. So save it and
    41  	// restore it at the end of this function.
    42  	// R30 is the link register. crosscall2 doesn't save it
    43  	// so it's saved here.
    44  	STP (R27, R30), 0(RSP)
    45  
    46  	// Create a struct callbackArgs on our stack.
    47  	MOVD $(callbackArgs__size)(RSP), R13
    48  	MOVD R12, callbackArgs_index(R13)    // callback index
    49  	MOVD R14, callbackArgs_args(R13)     // address of args vector
    50  	MOVD ZR, callbackArgs_result(R13)    // result
    51  
    52  	// Move parameters into registers
    53  	// Get the ABIInternal function pointer
    54  	// without <ABIInternal> by using a closure.
    55  	MOVD ·callbackWrap_call(SB), R0
    56  	MOVD (R0), R0                   // fn unsafe.Pointer
    57  	MOVD R13, R1                    // frame (&callbackArgs{...})
    58  	MOVD $0, R3                     // ctxt uintptr
    59  
    60  	BL crosscall2(SB)
    61  
    62  	// Get callback result.
    63  	MOVD $(callbackArgs__size)(RSP), R13
    64  	MOVD callbackArgs_result(R13), R0
    65  
    66  	// Restore LR and R27
    67  	LDP 0(RSP), (R27, R30)
    68  	ADD $(26*8), RSP
    69  
    70  	RET