sys_unix_arm64.s raw

   1  // SPDX-License-Identifier: Apache-2.0
   2  // SPDX-FileCopyrightText: 2023 The Ebitengine Authors
   3  
   4  //go:build darwin || freebsd || linux || netbsd
   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
  71