detached 3a10209

sys_unix_s390x.s RawHistoryFolder

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// S390X ELF ABI callbackasm1 implementation
11// On entry, R0 contains the callback index (set by callbackasm)
12// NOTE: We use R0 instead of R11 because R11 is callee-saved on S390X.
13//
14// S390X stack frame layout:
15//   0(R15)   - back chain
16//  48(R15)   - register save area (R6-R15)
17// 160(R15)  - parameter area
18//
19// S390X uses R2-R6 for integer arguments (5 registers) and F0,F2,F4,F6 for floats (4 registers).
20//
21// Our frame layout (total 200 bytes, 8-byte aligned). To stay under the
22// 800-byte nosplit limit on Go 1.27 the callbackArgs struct is stored in the
23// caller's free linkage slot (old_R15+16..48) instead of our own frame:
24//  0(R15)    - back chain
25// 48(R15)   - saved R6-R15 (done by STMG)
26// 128(R15)  - args array start
27//
28// Args array layout:
29// - floats F0,F2,F4,F6 (32 bytes)
30// - ints R2-R6 (40 bytes)
31// Total args array: 72 bytes, ends at 200
32//
33// callbackArgs struct lives at old_R15+16 (32 bytes: index, args, result, stackArgs)
34// Stack args in caller's frame start at old_R15+160
35
36#define FRAME_SIZE     200
37#define ARGS_ARRAY     128
38#define CB_ARGS        (FRAME_SIZE+16)
39#define FLOAT_OFF      0
40#define INT_OFF        32
41
42TEXT callbackasm1(SB), NOSPLIT|NOFRAME, $0
43	NO_LOCAL_POINTERS
44
45	// On entry, the trampoline in zcallback_s390x.s left
46	// the callback index in R0 (NOT R11, since R11 is callee-saved).
47	// R6 contains the 5th integer argument.
48
49	// Save R6-R15 in caller's frame (per S390X ABI) BEFORE allocating our frame
50	// STMG stores R6's current value (the 5th arg) at 48(R15)
51	STMG R6, R15, 48(R15)
52
53	// Save current stack pointer (will be back chain)
54	MOVD R15, R1
55
56	// Allocate our stack frame
57	SUB  $FRAME_SIZE, R15
58	MOVD R1, 0(R15)       // back chain
59
60	// Save R0 (callback index) immediately - it's volatile
61	MOVD R0, (CB_ARGS+0)(R15)
62
63	// Save callback arguments to args array.
64	// Layout: floats first (F0,F2,F4,F6), then ints (R2-R6)
65	FMOVD F0, (ARGS_ARRAY+FLOAT_OFF+0*8)(R15)
66	FMOVD F2, (ARGS_ARRAY+FLOAT_OFF+1*8)(R15)
67	FMOVD F4, (ARGS_ARRAY+FLOAT_OFF+2*8)(R15)
68	FMOVD F6, (ARGS_ARRAY+FLOAT_OFF+3*8)(R15)
69
70	MOVD R2, (ARGS_ARRAY+INT_OFF+0*8)(R15)
71	MOVD R3, (ARGS_ARRAY+INT_OFF+1*8)(R15)
72	MOVD R4, (ARGS_ARRAY+INT_OFF+2*8)(R15)
73	MOVD R5, (ARGS_ARRAY+INT_OFF+3*8)(R15)
74
75	// R6 (5th int arg) was saved at 48(old_R15) by STMG
76	// old_R15 = current R15 + FRAME_SIZE
77	MOVD (48+FRAME_SIZE)(R15), R1
78	MOVD R1, (ARGS_ARRAY+INT_OFF+4*8)(R15)
79
80	// Finish setting up callbackArgs struct at CB_ARGS(R15)
81	// struct { index uintptr; args unsafe.Pointer; result uintptr; stackArgs unsafe.Pointer }
82	// Note: index was already saved earlier
83	ADD  $ARGS_ARRAY, R15, R1
84	MOVD R1, (CB_ARGS+8)(R15)  // args = address of register args
85	MOVD $0, (CB_ARGS+16)(R15) // result = 0
86
87	// stackArgs points to caller's stack arguments at old_R15+160 = R15+FRAME_SIZE+160
88	ADD  $(FRAME_SIZE+160), R15, R1
89	MOVD R1, (CB_ARGS+24)(R15)      // stackArgs = &caller_stack_args
90
91	// Call crosscall2 with arguments in registers:
92	// R2 = fn (from callbackWrap_call closure)
93	// R3 = frame (address of callbackArgs)
94	// R5 = ctxt (0)
95	MOVD ·callbackWrap_call(SB), R2
96	MOVD (R2), R2                   // dereference closure to get fn
97	ADD  $CB_ARGS, R15, R3          // frame = &callbackArgs
98	MOVD $0, R5                     // ctxt = 0
99
100	BL crosscall2(SB)
101
102	// Get callback result into R2
103	MOVD (CB_ARGS+16)(R15), R2
104
105	// Deallocate frame
106	ADD $FRAME_SIZE, R15
107
108	// Restore R6-R15 from caller's frame
109	LMG 48(R15), R6, R15
110
111	RET

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 102

↑↓ moveenter openesc close