-
Notifications
You must be signed in to change notification settings - Fork 116
Expand file tree
/
Copy pathsys_ppc64le.s
More file actions
120 lines (102 loc) · 3.48 KB
/
Copy pathsys_ppc64le.s
File metadata and controls
120 lines (102 loc) · 3.48 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
//go:build linux
#include "textflag.h"
#include "go_asm.h"
#include "funcdata.h"
// PPC64LE ELFv2 ABI:
// - Integer args: R3-R10 (8 registers)
// - Float args: F1-F8 (8 registers)
// - Return: R3 (integer), F1 (float)
// - Stack pointer: R1
// - Link register: LR (special)
// - TOC pointer: R2 (must preserve)
// Stack layout for ELFv2 ABI (aligned to 16 bytes):
// From callee's perspective when we call BL (CTR):
// 0(R1) - back chain (our old R1)
// 8(R1) - CR save word (optional)
// 16(R1) - LR save (optional, we save it)
// 24(R1) - Reserved (compilers)
// 32(R1) - Parameter save area start (8 * 8 = 64 bytes for R3-R10)
// 96(R1) - First stack arg (a9) - this is where callee looks
// 104(R1) - Second stack arg (a10)
// 112-152 - Stack args a11-a15 (5 * 8 = 40 bytes)
// 160(R1) - TOC save (we put it here, outside param save area)
// 168(R1) - saved args pointer
// 176(R1) - padding for 16-byte alignment
// Total: 176 bytes
#define STACK_SIZE 176
#define LR_SAVE 16
#define TOC_SAVE 160
#define ARGP_SAVE 168
GLOBL ·syscallXABI0(SB), NOPTR|RODATA, $8
DATA ·syscallXABI0(SB)/8, $syscallX(SB)
TEXT syscallX(SB), NOSPLIT, $0
// Prologue: create stack frame
// R3 contains the args pointer on entry
MOVD R1, R12 // save old SP
SUB $STACK_SIZE, R1 // allocate stack frame
MOVD R12, 0(R1) // save back chain
MOVD LR, R12
MOVD R12, LR_SAVE(R1) // save LR
MOVD R2, TOC_SAVE(R1) // save TOC
// Save args pointer (in R3)
MOVD R3, ARGP_SAVE(R1)
// R11 := args pointer (syscallArgs*)
MOVD R3, R11
// Load float args into F1-F8
FMOVD syscallArgs_f1(R11), F1
FMOVD syscallArgs_f2(R11), F2
FMOVD syscallArgs_f3(R11), F3
FMOVD syscallArgs_f4(R11), F4
FMOVD syscallArgs_f5(R11), F5
FMOVD syscallArgs_f6(R11), F6
FMOVD syscallArgs_f7(R11), F7
FMOVD syscallArgs_f8(R11), F8
// Load integer args into R3-R10
MOVD syscallArgs_a1(R11), R3
MOVD syscallArgs_a2(R11), R4
MOVD syscallArgs_a3(R11), R5
MOVD syscallArgs_a4(R11), R6
MOVD syscallArgs_a5(R11), R7
MOVD syscallArgs_a6(R11), R8
MOVD syscallArgs_a7(R11), R9
MOVD syscallArgs_a8(R11), R10
// Spill a9-a15 onto the stack (stack parameters start at 96(R1))
// Per ELFv2: parameter save area is 32-95, stack args start at 96
MOVD ARGP_SAVE(R1), R11 // reload args pointer
MOVD syscallArgs_a9(R11), R12
MOVD R12, 96(R1) // a9 at 96(R1)
MOVD syscallArgs_a10(R11), R12
MOVD R12, 104(R1) // a10 at 104(R1)
MOVD syscallArgs_a11(R11), R12
MOVD R12, 112(R1) // a11 at 112(R1)
MOVD syscallArgs_a12(R11), R12
MOVD R12, 120(R1) // a12 at 120(R1)
MOVD syscallArgs_a13(R11), R12
MOVD R12, 128(R1) // a13 at 128(R1)
MOVD syscallArgs_a14(R11), R12
MOVD R12, 136(R1) // a14 at 136(R1)
MOVD syscallArgs_a15(R11), R12
MOVD R12, 144(R1) // a15 at 144(R1)
// Call function: load fn and call
MOVD syscallArgs_fn(R11), R12
MOVD R12, CTR
BL (CTR)
// Restore TOC after call
MOVD TOC_SAVE(R1), R2
// Restore args pointer for storing results
MOVD ARGP_SAVE(R1), R11
// Store integer results back (R3, R4)
MOVD R3, syscallArgs_a1(R11)
MOVD R4, syscallArgs_a2(R11)
// Store float return values (F1-F4)
FMOVD F1, syscallArgs_f1(R11)
FMOVD F2, syscallArgs_f2(R11)
FMOVD F3, syscallArgs_f3(R11)
FMOVD F4, syscallArgs_f4(R11)
// Epilogue: restore and return
MOVD LR_SAVE(R1), R12
MOVD R12, LR
ADD $STACK_SIZE, R1
RET