sys_arm.s raw

   1  // SPDX-License-Identifier: Apache-2.0
   2  // SPDX-FileCopyrightText: 2026 The Ebitengine Authors
   3  
   4  //go:build linux
   5  
   6  #include "textflag.h"
   7  #include "go_asm.h"
   8  #include "funcdata.h"
   9  
  10  #define STACK_SIZE 128
  11  #define PTR_ADDRESS (STACK_SIZE - 4)
  12  
  13  // syscall15X calls a function in libc on behalf of the syscall package.
  14  // syscall15X takes a pointer to a struct like:
  15  // struct {
  16  //	fn    uintptr
  17  //	a1    uintptr
  18  //  ...
  19  //	a32   uintptr
  20  //	f1    uintptr
  21  //	...
  22  //	f16   uintptr
  23  //	arm64_r8 uintptr
  24  // }
  25  // syscall15X must be called on the g0 stack with the
  26  // C calling convention (use libcCall).
  27  GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $4
  28  DATA ·syscall15XABI0(SB)/4, $syscall15X(SB)
  29  TEXT syscall15X(SB), NOSPLIT|NOFRAME, $0-0
  30  	// Called via C calling convention: R0 = pointer to syscall15Args
  31  	// NOT via Go calling convention
  32  	// Save link register and callee-saved registers first
  33  	MOVW.W    R14, -4(R13)                         // save LR (decrement and store)
  34  	MOVM.DB.W [R4, R5, R6, R7, R8, R9, R11], (R13) // save callee-saved regs
  35  
  36  	MOVW R0, R8
  37  	SUB  $STACK_SIZE, R13
  38  	MOVW R8, PTR_ADDRESS(R13)
  39  
  40  	// Load function pointer first (before anything can corrupt R8)
  41  	MOVW syscall15Args_fn(R8), R5
  42  	MOVW R5, (PTR_ADDRESS-4)(R13) // save fn at offset 56
  43  
  44  	// Load floating point arguments
  45  	// Each float64 spans 2 uintptr slots (8 bytes) on ARM32, so we skip by 2
  46  	MOVD syscall15Args_f1(R8), F0  // f1+f2 -> D0
  47  	MOVD syscall15Args_f3(R8), F1  // f3+f4 -> D1
  48  	MOVD syscall15Args_f5(R8), F2  // f5+f6 -> D2
  49  	MOVD syscall15Args_f7(R8), F3  // f7+f8 -> D3
  50  	MOVD syscall15Args_f9(R8), F4  // f9+f10 -> D4
  51  	MOVD syscall15Args_f11(R8), F5 // f11+f12 -> D5
  52  	MOVD syscall15Args_f13(R8), F6 // f13+f14 -> D6
  53  	MOVD syscall15Args_f15(R8), F7 // f15+f16 -> D7
  54  
  55  	// Load integer arguments into registers (R0-R3 for ARM EABI)
  56  	MOVW syscall15Args_a1(R8), R0 // a1
  57  	MOVW syscall15Args_a2(R8), R1 // a2
  58  	MOVW syscall15Args_a3(R8), R2 // a3
  59  	MOVW syscall15Args_a4(R8), R3 // a4
  60  
  61  	// push a5-a32 onto stack
  62  	MOVW syscall15Args_a5(R8), R4
  63  	MOVW R4, 0(R13)
  64  	MOVW syscall15Args_a6(R8), R4
  65  	MOVW R4, 4(R13)
  66  	MOVW syscall15Args_a7(R8), R4
  67  	MOVW R4, 8(R13)
  68  	MOVW syscall15Args_a8(R8), R4
  69  	MOVW R4, 12(R13)
  70  	MOVW syscall15Args_a9(R8), R4
  71  	MOVW R4, 16(R13)
  72  	MOVW syscall15Args_a10(R8), R4
  73  	MOVW R4, 20(R13)
  74  	MOVW syscall15Args_a11(R8), R4
  75  	MOVW R4, 24(R13)
  76  	MOVW syscall15Args_a12(R8), R4
  77  	MOVW R4, 28(R13)
  78  	MOVW syscall15Args_a13(R8), R4
  79  	MOVW R4, 32(R13)
  80  	MOVW syscall15Args_a14(R8), R4
  81  	MOVW R4, 36(R13)
  82  	MOVW syscall15Args_a15(R8), R4
  83  	MOVW R4, 40(R13)
  84  	MOVW syscall15Args_a16(R8), R4
  85  	MOVW R4, 44(R13)
  86  	MOVW syscall15Args_a17(R8), R4
  87  	MOVW R4, 48(R13)
  88  	MOVW syscall15Args_a18(R8), R4
  89  	MOVW R4, 52(R13)
  90  	MOVW syscall15Args_a19(R8), R4
  91  	MOVW R4, 56(R13)
  92  	MOVW syscall15Args_a20(R8), R4
  93  	MOVW R4, 60(R13)
  94  	MOVW syscall15Args_a21(R8), R4
  95  	MOVW R4, 64(R13)
  96  	MOVW syscall15Args_a22(R8), R4
  97  	MOVW R4, 68(R13)
  98  	MOVW syscall15Args_a23(R8), R4
  99  	MOVW R4, 72(R13)
 100  	MOVW syscall15Args_a24(R8), R4
 101  	MOVW R4, 76(R13)
 102  	MOVW syscall15Args_a25(R8), R4
 103  	MOVW R4, 80(R13)
 104  	MOVW syscall15Args_a26(R8), R4
 105  	MOVW R4, 84(R13)
 106  	MOVW syscall15Args_a27(R8), R4
 107  	MOVW R4, 88(R13)
 108  	MOVW syscall15Args_a28(R8), R4
 109  	MOVW R4, 92(R13)
 110  	MOVW syscall15Args_a29(R8), R4
 111  	MOVW R4, 96(R13)
 112  	MOVW syscall15Args_a30(R8), R4
 113  	MOVW R4, 100(R13)
 114  	MOVW syscall15Args_a31(R8), R4
 115  	MOVW R4, 104(R13)
 116  	MOVW syscall15Args_a32(R8), R4
 117  	MOVW R4, 108(R13)
 118  
 119  	// Load saved function pointer and call
 120  	MOVW (PTR_ADDRESS-4)(R13), R4
 121  
 122  	// Use BLX for Thumb interworking - Go assembler doesn't support BLX Rn
 123  	// BLX R4 = 0xE12FFF34 (ARM encoding, always condition)
 124  	WORD $0xE12FFF34 // blx r4
 125  
 126  	// pop structure pointer
 127  	MOVW PTR_ADDRESS(R13), R8
 128  	ADD  $STACK_SIZE, R13
 129  
 130  	// save R0, R1
 131  	MOVW R0, syscall15Args_a1(R8)
 132  	MOVW R1, syscall15Args_a2(R8)
 133  
 134  	// save f0-f3 (each float64 spans 2 uintptr slots on ARM32)
 135  	MOVD F0, syscall15Args_f1(R8)
 136  	MOVD F1, syscall15Args_f3(R8)
 137  	MOVD F2, syscall15Args_f5(R8)
 138  	MOVD F3, syscall15Args_f7(R8)
 139  
 140  	// Restore callee-saved registers and return
 141  	MOVM.IA.W (R13), [R4, R5, R6, R7, R8, R9, R11]
 142  	MOVW.P    4(R13), R15                          // pop LR into PC (return)
 143