sys_ppc64le.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  // PPC64LE ELFv2 ABI:
  11  // - Integer args: R3-R10 (8 registers)
  12  // - Float args: F1-F8 (8 registers)
  13  // - Return: R3 (integer), F1 (float)
  14  // - Stack pointer: R1
  15  // - Link register: LR (special)
  16  // - TOC pointer: R2 (must preserve)
  17  
  18  // Stack layout for ELFv2 ABI (aligned to 16 bytes):
  19  // From callee's perspective when we call BL (CTR):
  20  //  0(R1)  - back chain (our old R1)
  21  //  8(R1)  - CR save word (optional)
  22  // 16(R1)  - LR save (optional, we save it)
  23  // 24(R1)  - Reserved (compilers)
  24  // 32(R1)  - Parameter save area start (8 * 8 = 64 bytes for R3-R10)
  25  // 96(R1)  - First stack arg (a9) - this is where callee looks
  26  // 104(R1) - Second stack arg (a10)
  27  // 112-152 - Stack args a11-a15 (5 * 8 = 40 bytes)
  28  // 160(R1) - TOC save (we put it here, outside param save area)
  29  // 168(R1) - saved args pointer
  30  // 176(R1) - padding for 16-byte alignment
  31  // Total: 176 bytes
  32  
  33  #define STACK_SIZE 176
  34  #define LR_SAVE    16
  35  #define TOC_SAVE   160
  36  #define ARGP_SAVE  168
  37  
  38  GLOBL ·syscall15XABI0(SB), NOPTR|RODATA, $8
  39  DATA ·syscall15XABI0(SB)/8, $syscall15X(SB)
  40  
  41  TEXT syscall15X(SB), NOSPLIT, $0
  42  	// Prologue: create stack frame
  43  	// R3 contains the args pointer on entry
  44  	MOVD R1, R12          // save old SP
  45  	SUB  $STACK_SIZE, R1  // allocate stack frame
  46  	MOVD R12, 0(R1)       // save back chain
  47  	MOVD LR, R12
  48  	MOVD R12, LR_SAVE(R1) // save LR
  49  	MOVD R2, TOC_SAVE(R1) // save TOC
  50  
  51  	// Save args pointer (in R3)
  52  	MOVD R3, ARGP_SAVE(R1)
  53  
  54  	// R11 := args pointer (syscall15Args*)
  55  	MOVD R3, R11
  56  
  57  	// Load float args into F1-F8
  58  	FMOVD syscall15Args_f1(R11), F1
  59  	FMOVD syscall15Args_f2(R11), F2
  60  	FMOVD syscall15Args_f3(R11), F3
  61  	FMOVD syscall15Args_f4(R11), F4
  62  	FMOVD syscall15Args_f5(R11), F5
  63  	FMOVD syscall15Args_f6(R11), F6
  64  	FMOVD syscall15Args_f7(R11), F7
  65  	FMOVD syscall15Args_f8(R11), F8
  66  
  67  	// Load integer args into R3-R10
  68  	MOVD syscall15Args_a1(R11), R3
  69  	MOVD syscall15Args_a2(R11), R4
  70  	MOVD syscall15Args_a3(R11), R5
  71  	MOVD syscall15Args_a4(R11), R6
  72  	MOVD syscall15Args_a5(R11), R7
  73  	MOVD syscall15Args_a6(R11), R8
  74  	MOVD syscall15Args_a7(R11), R9
  75  	MOVD syscall15Args_a8(R11), R10
  76  
  77  	// Spill a9-a15 onto the stack (stack parameters start at 96(R1))
  78  	// Per ELFv2: parameter save area is 32-95, stack args start at 96
  79  	MOVD ARGP_SAVE(R1), R11          // reload args pointer
  80  	MOVD syscall15Args_a9(R11), R12
  81  	MOVD R12, 96(R1)                 // a9 at 96(R1)
  82  	MOVD syscall15Args_a10(R11), R12
  83  	MOVD R12, 104(R1)                // a10 at 104(R1)
  84  	MOVD syscall15Args_a11(R11), R12
  85  	MOVD R12, 112(R1)                // a11 at 112(R1)
  86  	MOVD syscall15Args_a12(R11), R12
  87  	MOVD R12, 120(R1)                // a12 at 120(R1)
  88  	MOVD syscall15Args_a13(R11), R12
  89  	MOVD R12, 128(R1)                // a13 at 128(R1)
  90  	MOVD syscall15Args_a14(R11), R12
  91  	MOVD R12, 136(R1)                // a14 at 136(R1)
  92  	MOVD syscall15Args_a15(R11), R12
  93  	MOVD R12, 144(R1)                // a15 at 144(R1)
  94  
  95  	// Call function: load fn and call
  96  	MOVD syscall15Args_fn(R11), R12
  97  	MOVD R12, CTR
  98  	BL   (CTR)
  99  
 100  	// Restore TOC after call
 101  	MOVD TOC_SAVE(R1), R2
 102  
 103  	// Restore args pointer for storing results
 104  	MOVD ARGP_SAVE(R1), R11
 105  
 106  	// Store integer results back (R3, R4)
 107  	MOVD R3, syscall15Args_a1(R11)
 108  	MOVD R4, syscall15Args_a2(R11)
 109  
 110  	// Store float return values (F1-F4)
 111  	FMOVD F1, syscall15Args_f1(R11)
 112  	FMOVD F2, syscall15Args_f2(R11)
 113  	FMOVD F3, syscall15Args_f3(R11)
 114  	FMOVD F4, syscall15Args_f4(R11)
 115  
 116  	// Epilogue: restore and return
 117  	MOVD LR_SAVE(R1), R12
 118  	MOVD R12, LR
 119  	ADD  $STACK_SIZE, R1
 120  	RET
 121