vendor raymenu dependencies
This commit is contained in:
+99
@@ -0,0 +1,99 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Macros for transitioning from the host ABI to Go ABI0.
|
||||
//
|
||||
// These save the frame pointer, so in general, functions that use
|
||||
// these should have zero frame size to suppress the automatic frame
|
||||
// pointer, though it's harmless to not do this.
|
||||
|
||||
#ifdef GOOS_windows
|
||||
|
||||
// REGS_HOST_TO_ABI0_STACK is the stack bytes used by
|
||||
// PUSH_REGS_HOST_TO_ABI0.
|
||||
#define REGS_HOST_TO_ABI0_STACK (28*8 + 8)
|
||||
|
||||
// PUSH_REGS_HOST_TO_ABI0 prepares for transitioning from
|
||||
// the host ABI to Go ABI0 code. It saves all registers that are
|
||||
// callee-save in the host ABI and caller-save in Go ABI0 and prepares
|
||||
// for entry to Go.
|
||||
//
|
||||
// Save DI SI BP BX R12 R13 R14 R15 X6-X15 registers and the DF flag.
|
||||
// Clear the DF flag for the Go ABI.
|
||||
// MXCSR matches the Go ABI, so we don't have to set that,
|
||||
// and Go doesn't modify it, so we don't have to save it.
|
||||
#define PUSH_REGS_HOST_TO_ABI0() \
|
||||
PUSHFQ \
|
||||
CLD \
|
||||
ADJSP $(REGS_HOST_TO_ABI0_STACK - 8) \
|
||||
MOVQ DI, (0*0)(SP) \
|
||||
MOVQ SI, (1*8)(SP) \
|
||||
MOVQ BP, (2*8)(SP) \
|
||||
MOVQ BX, (3*8)(SP) \
|
||||
MOVQ R12, (4*8)(SP) \
|
||||
MOVQ R13, (5*8)(SP) \
|
||||
MOVQ R14, (6*8)(SP) \
|
||||
MOVQ R15, (7*8)(SP) \
|
||||
MOVUPS X6, (8*8)(SP) \
|
||||
MOVUPS X7, (10*8)(SP) \
|
||||
MOVUPS X8, (12*8)(SP) \
|
||||
MOVUPS X9, (14*8)(SP) \
|
||||
MOVUPS X10, (16*8)(SP) \
|
||||
MOVUPS X11, (18*8)(SP) \
|
||||
MOVUPS X12, (20*8)(SP) \
|
||||
MOVUPS X13, (22*8)(SP) \
|
||||
MOVUPS X14, (24*8)(SP) \
|
||||
MOVUPS X15, (26*8)(SP)
|
||||
|
||||
#define POP_REGS_HOST_TO_ABI0() \
|
||||
MOVQ (0*0)(SP), DI \
|
||||
MOVQ (1*8)(SP), SI \
|
||||
MOVQ (2*8)(SP), BP \
|
||||
MOVQ (3*8)(SP), BX \
|
||||
MOVQ (4*8)(SP), R12 \
|
||||
MOVQ (5*8)(SP), R13 \
|
||||
MOVQ (6*8)(SP), R14 \
|
||||
MOVQ (7*8)(SP), R15 \
|
||||
MOVUPS (8*8)(SP), X6 \
|
||||
MOVUPS (10*8)(SP), X7 \
|
||||
MOVUPS (12*8)(SP), X8 \
|
||||
MOVUPS (14*8)(SP), X9 \
|
||||
MOVUPS (16*8)(SP), X10 \
|
||||
MOVUPS (18*8)(SP), X11 \
|
||||
MOVUPS (20*8)(SP), X12 \
|
||||
MOVUPS (22*8)(SP), X13 \
|
||||
MOVUPS (24*8)(SP), X14 \
|
||||
MOVUPS (26*8)(SP), X15 \
|
||||
ADJSP $-(REGS_HOST_TO_ABI0_STACK - 8) \
|
||||
POPFQ
|
||||
|
||||
#else
|
||||
// SysV ABI
|
||||
|
||||
#define REGS_HOST_TO_ABI0_STACK (6*8)
|
||||
|
||||
// SysV MXCSR matches the Go ABI, so we don't have to set that,
|
||||
// and Go doesn't modify it, so we don't have to save it.
|
||||
// Both SysV and Go require DF to be cleared, so that's already clear.
|
||||
// The SysV and Go frame pointer conventions are compatible.
|
||||
#define PUSH_REGS_HOST_TO_ABI0() \
|
||||
ADJSP $(REGS_HOST_TO_ABI0_STACK) \
|
||||
MOVQ BP, (5*8)(SP) \
|
||||
LEAQ (5*8)(SP), BP \
|
||||
MOVQ BX, (0*8)(SP) \
|
||||
MOVQ R12, (1*8)(SP) \
|
||||
MOVQ R13, (2*8)(SP) \
|
||||
MOVQ R14, (3*8)(SP) \
|
||||
MOVQ R15, (4*8)(SP)
|
||||
|
||||
#define POP_REGS_HOST_TO_ABI0() \
|
||||
MOVQ (0*8)(SP), BX \
|
||||
MOVQ (1*8)(SP), R12 \
|
||||
MOVQ (2*8)(SP), R13 \
|
||||
MOVQ (3*8)(SP), R14 \
|
||||
MOVQ (4*8)(SP), R15 \
|
||||
MOVQ (5*8)(SP), BP \
|
||||
ADJSP $-(REGS_HOST_TO_ABI0_STACK)
|
||||
|
||||
#endif
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Macros for transitioning from the host ABI to Go ABI0.
|
||||
//
|
||||
// These macros save and restore the callee-saved registers
|
||||
// from the stack, but they don't adjust stack pointer, so
|
||||
// the user should prepare stack space in advance.
|
||||
// SAVE_R19_TO_R28(offset) saves R19 ~ R28 to the stack space
|
||||
// of ((offset)+0*8)(RSP) ~ ((offset)+9*8)(RSP).
|
||||
//
|
||||
// SAVE_F8_TO_F15(offset) saves F8 ~ F15 to the stack space
|
||||
// of ((offset)+0*8)(RSP) ~ ((offset)+7*8)(RSP).
|
||||
//
|
||||
// R29 is not saved because Go will save and restore it.
|
||||
|
||||
#define SAVE_R19_TO_R28(offset) \
|
||||
STP (R19, R20), ((offset)+0*8)(RSP) \
|
||||
STP (R21, R22), ((offset)+2*8)(RSP) \
|
||||
STP (R23, R24), ((offset)+4*8)(RSP) \
|
||||
STP (R25, R26), ((offset)+6*8)(RSP) \
|
||||
STP (R27, g), ((offset)+8*8)(RSP)
|
||||
#define RESTORE_R19_TO_R28(offset) \
|
||||
LDP ((offset)+0*8)(RSP), (R19, R20) \
|
||||
LDP ((offset)+2*8)(RSP), (R21, R22) \
|
||||
LDP ((offset)+4*8)(RSP), (R23, R24) \
|
||||
LDP ((offset)+6*8)(RSP), (R25, R26) \
|
||||
LDP ((offset)+8*8)(RSP), (R27, g) /* R28 */
|
||||
#define SAVE_F8_TO_F15(offset) \
|
||||
FSTPD (F8, F9), ((offset)+0*8)(RSP) \
|
||||
FSTPD (F10, F11), ((offset)+2*8)(RSP) \
|
||||
FSTPD (F12, F13), ((offset)+4*8)(RSP) \
|
||||
FSTPD (F14, F15), ((offset)+6*8)(RSP)
|
||||
#define RESTORE_F8_TO_F15(offset) \
|
||||
FLDPD ((offset)+0*8)(RSP), (F8, F9) \
|
||||
FLDPD ((offset)+2*8)(RSP), (F10, F11) \
|
||||
FLDPD ((offset)+4*8)(RSP), (F12, F13) \
|
||||
FLDPD ((offset)+6*8)(RSP), (F14, F15)
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Macros for transitioning from the host ABI to Go ABI0.
|
||||
//
|
||||
// These macros save and restore the callee-saved registers
|
||||
// from the stack, but they don't adjust stack pointer, so
|
||||
// the user should prepare stack space in advance.
|
||||
// SAVE_R22_TO_R31(offset) saves R22 ~ R31 to the stack space
|
||||
// of ((offset)+0*8)(R3) ~ ((offset)+9*8)(R3).
|
||||
//
|
||||
// SAVE_F24_TO_F31(offset) saves F24 ~ F31 to the stack space
|
||||
// of ((offset)+0*8)(R3) ~ ((offset)+7*8)(R3).
|
||||
//
|
||||
// Note: g is R22
|
||||
|
||||
#define SAVE_R22_TO_R31(offset) \
|
||||
MOVV g, ((offset)+(0*8))(R3) \
|
||||
MOVV R23, ((offset)+(1*8))(R3) \
|
||||
MOVV R24, ((offset)+(2*8))(R3) \
|
||||
MOVV R25, ((offset)+(3*8))(R3) \
|
||||
MOVV R26, ((offset)+(4*8))(R3) \
|
||||
MOVV R27, ((offset)+(5*8))(R3) \
|
||||
MOVV R28, ((offset)+(6*8))(R3) \
|
||||
MOVV R29, ((offset)+(7*8))(R3) \
|
||||
MOVV R30, ((offset)+(8*8))(R3) \
|
||||
MOVV R31, ((offset)+(9*8))(R3)
|
||||
|
||||
#define SAVE_F24_TO_F31(offset) \
|
||||
MOVD F24, ((offset)+(0*8))(R3) \
|
||||
MOVD F25, ((offset)+(1*8))(R3) \
|
||||
MOVD F26, ((offset)+(2*8))(R3) \
|
||||
MOVD F27, ((offset)+(3*8))(R3) \
|
||||
MOVD F28, ((offset)+(4*8))(R3) \
|
||||
MOVD F29, ((offset)+(5*8))(R3) \
|
||||
MOVD F30, ((offset)+(6*8))(R3) \
|
||||
MOVD F31, ((offset)+(7*8))(R3)
|
||||
|
||||
#define RESTORE_R22_TO_R31(offset) \
|
||||
MOVV ((offset)+(0*8))(R3), g \
|
||||
MOVV ((offset)+(1*8))(R3), R23 \
|
||||
MOVV ((offset)+(2*8))(R3), R24 \
|
||||
MOVV ((offset)+(3*8))(R3), R25 \
|
||||
MOVV ((offset)+(4*8))(R3), R26 \
|
||||
MOVV ((offset)+(5*8))(R3), R27 \
|
||||
MOVV ((offset)+(6*8))(R3), R28 \
|
||||
MOVV ((offset)+(7*8))(R3), R29 \
|
||||
MOVV ((offset)+(8*8))(R3), R30 \
|
||||
MOVV ((offset)+(9*8))(R3), R31
|
||||
|
||||
#define RESTORE_F24_TO_F31(offset) \
|
||||
MOVD ((offset)+(0*8))(R3), F24 \
|
||||
MOVD ((offset)+(1*8))(R3), F25 \
|
||||
MOVD ((offset)+(2*8))(R3), F26 \
|
||||
MOVD ((offset)+(3*8))(R3), F27 \
|
||||
MOVD ((offset)+(4*8))(R3), F28 \
|
||||
MOVD ((offset)+(5*8))(R3), F29 \
|
||||
MOVD ((offset)+(6*8))(R3), F30 \
|
||||
MOVD ((offset)+(7*8))(R3), F31
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
// Copyright 2023 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Macros for transitioning from the host ABI to Go ABI
|
||||
//
|
||||
// On PPC64/ELFv2 targets, the following registers are callee
|
||||
// saved when called from C. They must be preserved before
|
||||
// calling into Go which does not preserve any of them.
|
||||
//
|
||||
// R14-R31
|
||||
// CR2-4
|
||||
// VR20-31
|
||||
// F14-F31
|
||||
//
|
||||
// xcoff(aix) and ELFv1 are similar, but may only require a
|
||||
// subset of these.
|
||||
//
|
||||
// These macros assume a 16 byte aligned stack pointer. This
|
||||
// is required by ELFv1, ELFv2, and AIX PPC64.
|
||||
|
||||
#define SAVE_GPR_SIZE (18*8)
|
||||
#define SAVE_GPR(offset) \
|
||||
MOVD R14, (offset+8*0)(R1) \
|
||||
MOVD R15, (offset+8*1)(R1) \
|
||||
MOVD R16, (offset+8*2)(R1) \
|
||||
MOVD R17, (offset+8*3)(R1) \
|
||||
MOVD R18, (offset+8*4)(R1) \
|
||||
MOVD R19, (offset+8*5)(R1) \
|
||||
MOVD R20, (offset+8*6)(R1) \
|
||||
MOVD R21, (offset+8*7)(R1) \
|
||||
MOVD R22, (offset+8*8)(R1) \
|
||||
MOVD R23, (offset+8*9)(R1) \
|
||||
MOVD R24, (offset+8*10)(R1) \
|
||||
MOVD R25, (offset+8*11)(R1) \
|
||||
MOVD R26, (offset+8*12)(R1) \
|
||||
MOVD R27, (offset+8*13)(R1) \
|
||||
MOVD R28, (offset+8*14)(R1) \
|
||||
MOVD R29, (offset+8*15)(R1) \
|
||||
MOVD g, (offset+8*16)(R1) \
|
||||
MOVD R31, (offset+8*17)(R1)
|
||||
|
||||
#define RESTORE_GPR(offset) \
|
||||
MOVD (offset+8*0)(R1), R14 \
|
||||
MOVD (offset+8*1)(R1), R15 \
|
||||
MOVD (offset+8*2)(R1), R16 \
|
||||
MOVD (offset+8*3)(R1), R17 \
|
||||
MOVD (offset+8*4)(R1), R18 \
|
||||
MOVD (offset+8*5)(R1), R19 \
|
||||
MOVD (offset+8*6)(R1), R20 \
|
||||
MOVD (offset+8*7)(R1), R21 \
|
||||
MOVD (offset+8*8)(R1), R22 \
|
||||
MOVD (offset+8*9)(R1), R23 \
|
||||
MOVD (offset+8*10)(R1), R24 \
|
||||
MOVD (offset+8*11)(R1), R25 \
|
||||
MOVD (offset+8*12)(R1), R26 \
|
||||
MOVD (offset+8*13)(R1), R27 \
|
||||
MOVD (offset+8*14)(R1), R28 \
|
||||
MOVD (offset+8*15)(R1), R29 \
|
||||
MOVD (offset+8*16)(R1), g \
|
||||
MOVD (offset+8*17)(R1), R31
|
||||
|
||||
#define SAVE_FPR_SIZE (18*8)
|
||||
#define SAVE_FPR(offset) \
|
||||
FMOVD F14, (offset+8*0)(R1) \
|
||||
FMOVD F15, (offset+8*1)(R1) \
|
||||
FMOVD F16, (offset+8*2)(R1) \
|
||||
FMOVD F17, (offset+8*3)(R1) \
|
||||
FMOVD F18, (offset+8*4)(R1) \
|
||||
FMOVD F19, (offset+8*5)(R1) \
|
||||
FMOVD F20, (offset+8*6)(R1) \
|
||||
FMOVD F21, (offset+8*7)(R1) \
|
||||
FMOVD F22, (offset+8*8)(R1) \
|
||||
FMOVD F23, (offset+8*9)(R1) \
|
||||
FMOVD F24, (offset+8*10)(R1) \
|
||||
FMOVD F25, (offset+8*11)(R1) \
|
||||
FMOVD F26, (offset+8*12)(R1) \
|
||||
FMOVD F27, (offset+8*13)(R1) \
|
||||
FMOVD F28, (offset+8*14)(R1) \
|
||||
FMOVD F29, (offset+8*15)(R1) \
|
||||
FMOVD F30, (offset+8*16)(R1) \
|
||||
FMOVD F31, (offset+8*17)(R1)
|
||||
|
||||
#define RESTORE_FPR(offset) \
|
||||
FMOVD (offset+8*0)(R1), F14 \
|
||||
FMOVD (offset+8*1)(R1), F15 \
|
||||
FMOVD (offset+8*2)(R1), F16 \
|
||||
FMOVD (offset+8*3)(R1), F17 \
|
||||
FMOVD (offset+8*4)(R1), F18 \
|
||||
FMOVD (offset+8*5)(R1), F19 \
|
||||
FMOVD (offset+8*6)(R1), F20 \
|
||||
FMOVD (offset+8*7)(R1), F21 \
|
||||
FMOVD (offset+8*8)(R1), F22 \
|
||||
FMOVD (offset+8*9)(R1), F23 \
|
||||
FMOVD (offset+8*10)(R1), F24 \
|
||||
FMOVD (offset+8*11)(R1), F25 \
|
||||
FMOVD (offset+8*12)(R1), F26 \
|
||||
FMOVD (offset+8*13)(R1), F27 \
|
||||
FMOVD (offset+8*14)(R1), F28 \
|
||||
FMOVD (offset+8*15)(R1), F29 \
|
||||
FMOVD (offset+8*16)(R1), F30 \
|
||||
FMOVD (offset+8*17)(R1), F31
|
||||
|
||||
// Save and restore VR20-31 (aka VSR56-63). These
|
||||
// macros must point to a 16B aligned offset.
|
||||
#define SAVE_VR_SIZE (12*16)
|
||||
#define SAVE_VR(offset, rtmp) \
|
||||
MOVD $(offset+16*0), rtmp \
|
||||
STVX V20, (rtmp)(R1) \
|
||||
MOVD $(offset+16*1), rtmp \
|
||||
STVX V21, (rtmp)(R1) \
|
||||
MOVD $(offset+16*2), rtmp \
|
||||
STVX V22, (rtmp)(R1) \
|
||||
MOVD $(offset+16*3), rtmp \
|
||||
STVX V23, (rtmp)(R1) \
|
||||
MOVD $(offset+16*4), rtmp \
|
||||
STVX V24, (rtmp)(R1) \
|
||||
MOVD $(offset+16*5), rtmp \
|
||||
STVX V25, (rtmp)(R1) \
|
||||
MOVD $(offset+16*6), rtmp \
|
||||
STVX V26, (rtmp)(R1) \
|
||||
MOVD $(offset+16*7), rtmp \
|
||||
STVX V27, (rtmp)(R1) \
|
||||
MOVD $(offset+16*8), rtmp \
|
||||
STVX V28, (rtmp)(R1) \
|
||||
MOVD $(offset+16*9), rtmp \
|
||||
STVX V29, (rtmp)(R1) \
|
||||
MOVD $(offset+16*10), rtmp \
|
||||
STVX V30, (rtmp)(R1) \
|
||||
MOVD $(offset+16*11), rtmp \
|
||||
STVX V31, (rtmp)(R1)
|
||||
|
||||
#define RESTORE_VR(offset, rtmp) \
|
||||
MOVD $(offset+16*0), rtmp \
|
||||
LVX (rtmp)(R1), V20 \
|
||||
MOVD $(offset+16*1), rtmp \
|
||||
LVX (rtmp)(R1), V21 \
|
||||
MOVD $(offset+16*2), rtmp \
|
||||
LVX (rtmp)(R1), V22 \
|
||||
MOVD $(offset+16*3), rtmp \
|
||||
LVX (rtmp)(R1), V23 \
|
||||
MOVD $(offset+16*4), rtmp \
|
||||
LVX (rtmp)(R1), V24 \
|
||||
MOVD $(offset+16*5), rtmp \
|
||||
LVX (rtmp)(R1), V25 \
|
||||
MOVD $(offset+16*6), rtmp \
|
||||
LVX (rtmp)(R1), V26 \
|
||||
MOVD $(offset+16*7), rtmp \
|
||||
LVX (rtmp)(R1), V27 \
|
||||
MOVD $(offset+16*8), rtmp \
|
||||
LVX (rtmp)(R1), V28 \
|
||||
MOVD $(offset+16*9), rtmp \
|
||||
LVX (rtmp)(R1), V29 \
|
||||
MOVD $(offset+16*10), rtmp \
|
||||
LVX (rtmp)(R1), V30 \
|
||||
MOVD $(offset+16*11), rtmp \
|
||||
LVX (rtmp)(R1), V31
|
||||
|
||||
// LR and CR are saved in the caller's frame. The callee must
|
||||
// make space for all other callee-save registers.
|
||||
#define SAVE_ALL_REG_SIZE (SAVE_GPR_SIZE+SAVE_FPR_SIZE+SAVE_VR_SIZE)
|
||||
|
||||
// Stack a frame and save all callee-save registers following the
|
||||
// host OS's ABI. Fortunately, this is identical for AIX, ELFv1, and
|
||||
// ELFv2. All host ABIs require the stack pointer to maintain 16 byte
|
||||
// alignment, and save the callee-save registers in the same places.
|
||||
//
|
||||
// To restate, R1 is assumed to be aligned when this macro is used.
|
||||
// This assumes the caller's frame is compliant with the host ABI.
|
||||
// CR and LR are saved into the caller's frame per the host ABI.
|
||||
// R0 is initialized to $0 as expected by Go.
|
||||
#define STACK_AND_SAVE_HOST_TO_GO_ABI(extra) \
|
||||
MOVD LR, R0 \
|
||||
MOVD R0, 16(R1) \
|
||||
MOVW CR, R0 \
|
||||
MOVD R0, 8(R1) \
|
||||
MOVDU R1, -(extra)-FIXED_FRAME-SAVE_ALL_REG_SIZE(R1) \
|
||||
SAVE_GPR(extra+FIXED_FRAME) \
|
||||
SAVE_FPR(extra+FIXED_FRAME+SAVE_GPR_SIZE) \
|
||||
SAVE_VR(extra+FIXED_FRAME+SAVE_GPR_SIZE+SAVE_FPR_SIZE, R0) \
|
||||
MOVD $0, R0
|
||||
|
||||
// This unstacks the frame, restoring all callee-save registers
|
||||
// as saved by STACK_AND_SAVE_HOST_TO_GO_ABI.
|
||||
//
|
||||
// R0 is not guaranteed to contain $0 after this macro.
|
||||
#define UNSTACK_AND_RESTORE_GO_TO_HOST_ABI(extra) \
|
||||
RESTORE_GPR(extra+FIXED_FRAME) \
|
||||
RESTORE_FPR(extra+FIXED_FRAME+SAVE_GPR_SIZE) \
|
||||
RESTORE_VR(extra+FIXED_FRAME+SAVE_GPR_SIZE+SAVE_FPR_SIZE, R0) \
|
||||
ADD $(extra+FIXED_FRAME+SAVE_ALL_REG_SIZE), R1 \
|
||||
MOVD 16(R1), R0 \
|
||||
MOVD R0, LR \
|
||||
MOVD 8(R1), R0 \
|
||||
MOVW R0, CR
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// Called by C code generated by cmd/cgo.
|
||||
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
|
||||
// Saves C callee-saved registers and calls cgocallback with three arguments.
|
||||
// fn is the PC of a func(a unsafe.Pointer) function.
|
||||
TEXT crosscall2(SB), NOSPLIT, $28-16
|
||||
MOVL BP, 24(SP)
|
||||
MOVL BX, 20(SP)
|
||||
MOVL SI, 16(SP)
|
||||
MOVL DI, 12(SP)
|
||||
|
||||
MOVL ctxt+12(FP), AX
|
||||
MOVL AX, 8(SP)
|
||||
MOVL a+4(FP), AX
|
||||
MOVL AX, 4(SP)
|
||||
MOVL fn+0(FP), AX
|
||||
MOVL AX, 0(SP)
|
||||
CALL runtime·cgocallback(SB)
|
||||
|
||||
MOVL 12(SP), DI
|
||||
MOVL 16(SP), SI
|
||||
MOVL 20(SP), BX
|
||||
MOVL 24(SP), BP
|
||||
RET
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
#include "abi_amd64.h"
|
||||
|
||||
// Called by C code generated by cmd/cgo.
|
||||
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
|
||||
// Saves C callee-saved registers and calls cgocallback with three arguments.
|
||||
// fn is the PC of a func(a unsafe.Pointer) function.
|
||||
// This signature is known to SWIG, so we can't change it.
|
||||
TEXT crosscall2(SB), NOSPLIT, $0-0
|
||||
PUSH_REGS_HOST_TO_ABI0()
|
||||
|
||||
// Make room for arguments to cgocallback.
|
||||
ADJSP $0x18
|
||||
|
||||
#ifndef GOOS_windows
|
||||
MOVQ DI, 0x0(SP) // fn
|
||||
MOVQ SI, 0x8(SP) // arg
|
||||
|
||||
// Skip n in DX.
|
||||
MOVQ CX, 0x10(SP) // ctxt
|
||||
|
||||
#else
|
||||
MOVQ CX, 0x0(SP) // fn
|
||||
MOVQ DX, 0x8(SP) // arg
|
||||
|
||||
// Skip n in R8.
|
||||
MOVQ R9, 0x10(SP) // ctxt
|
||||
|
||||
#endif
|
||||
|
||||
CALL runtime·cgocallback(SB)
|
||||
|
||||
ADJSP $-0x18
|
||||
POP_REGS_HOST_TO_ABI0()
|
||||
RET
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// Called by C code generated by cmd/cgo.
|
||||
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
|
||||
// Saves C callee-saved registers and calls cgocallback with three arguments.
|
||||
// fn is the PC of a func(a unsafe.Pointer) function.
|
||||
TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0
|
||||
SUB $(8*9), R13 // Reserve space for the floating point registers.
|
||||
|
||||
// The C arguments arrive in R0, R1, R2, and R3. We want to
|
||||
// pass R0, R1, and R3 to Go, so we push those on the stack.
|
||||
// Also, save C callee-save registers R4-R12.
|
||||
MOVM.WP [R0, R1, R3, R4, R5, R6, R7, R8, R9, g, R11, R12], (R13)
|
||||
|
||||
// Finally, save the link register R14. This also puts the
|
||||
// arguments we pushed for cgocallback where they need to be,
|
||||
// starting at 4(R13).
|
||||
MOVW.W R14, -4(R13)
|
||||
|
||||
// Save VFP callee-saved registers D8-D15 (same as S16-S31).
|
||||
// Note: We always save these since we target hard-float ABI.
|
||||
MOVD F8, (13*4+8*1)(R13)
|
||||
MOVD F9, (13*4+8*2)(R13)
|
||||
MOVD F10, (13*4+8*3)(R13)
|
||||
MOVD F11, (13*4+8*4)(R13)
|
||||
MOVD F12, (13*4+8*5)(R13)
|
||||
MOVD F13, (13*4+8*6)(R13)
|
||||
MOVD F14, (13*4+8*7)(R13)
|
||||
MOVD F15, (13*4+8*8)(R13)
|
||||
|
||||
BL runtime·load_g(SB)
|
||||
|
||||
// We set up the arguments to cgocallback when saving registers above.
|
||||
BL runtime·cgocallback(SB)
|
||||
|
||||
MOVD (13*4+8*1)(R13), F8
|
||||
MOVD (13*4+8*2)(R13), F9
|
||||
MOVD (13*4+8*3)(R13), F10
|
||||
MOVD (13*4+8*4)(R13), F11
|
||||
MOVD (13*4+8*5)(R13), F12
|
||||
MOVD (13*4+8*6)(R13), F13
|
||||
MOVD (13*4+8*7)(R13), F14
|
||||
MOVD (13*4+8*8)(R13), F15
|
||||
|
||||
MOVW.P 4(R13), R14
|
||||
MOVM.IAW (R13), [R0, R1, R3, R4, R5, R6, R7, R8, R9, g, R11, R12]
|
||||
ADD $(8*9), R13
|
||||
MOVW R14, R15
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
#include "abi_arm64.h"
|
||||
|
||||
// Called by C code generated by cmd/cgo.
|
||||
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
|
||||
// Saves C callee-saved registers and calls cgocallback with three arguments.
|
||||
// fn is the PC of a func(a unsafe.Pointer) function.
|
||||
TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0
|
||||
/*
|
||||
* We still need to save all callee save register as before, and then
|
||||
* push 3 args for fn (R0, R1, R3), skipping R2.
|
||||
* Also note that at procedure entry in gc world, 8(RSP) will be the
|
||||
* first arg.
|
||||
*/
|
||||
SUB $(8*24), RSP
|
||||
STP (R0, R1), (8*1)(RSP)
|
||||
MOVD R3, (8*3)(RSP)
|
||||
|
||||
SAVE_R19_TO_R28(8*4)
|
||||
SAVE_F8_TO_F15(8*14)
|
||||
STP (R29, R30), (8*22)(RSP)
|
||||
|
||||
// Initialize Go ABI environment
|
||||
BL runtime·load_g(SB)
|
||||
BL runtime·cgocallback(SB)
|
||||
|
||||
RESTORE_R19_TO_R28(8*4)
|
||||
RESTORE_F8_TO_F15(8*14)
|
||||
LDP (8*22)(RSP), (R29, R30)
|
||||
|
||||
ADD $(8*24), RSP
|
||||
RET
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
// Copyright 2022 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
#include "abi_loong64.h"
|
||||
|
||||
// Called by C code generated by cmd/cgo.
|
||||
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
|
||||
// Saves C callee-saved registers and calls cgocallback with three arguments.
|
||||
// fn is the PC of a func(a unsafe.Pointer) function.
|
||||
TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0
|
||||
/*
|
||||
* We still need to save all callee save register as before, and then
|
||||
* push 3 args for fn (R4, R5, R7), skipping R6.
|
||||
* Also note that at procedure entry in gc world, 8(R29) will be the
|
||||
* first arg.
|
||||
*/
|
||||
|
||||
ADDV $(-23*8), R3
|
||||
MOVV R4, (1*8)(R3) // fn unsafe.Pointer
|
||||
MOVV R5, (2*8)(R3) // a unsafe.Pointer
|
||||
MOVV R7, (3*8)(R3) // ctxt uintptr
|
||||
|
||||
SAVE_R22_TO_R31((4*8))
|
||||
SAVE_F24_TO_F31((14*8))
|
||||
MOVV R1, (22*8)(R3)
|
||||
|
||||
// Initialize Go ABI environment
|
||||
JAL runtime·load_g(SB)
|
||||
|
||||
JAL runtime·cgocallback(SB)
|
||||
|
||||
RESTORE_R22_TO_R31((4*8))
|
||||
RESTORE_F24_TO_F31((14*8))
|
||||
MOVV (22*8)(R3), R1
|
||||
|
||||
ADDV $(23*8), R3
|
||||
|
||||
RET
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
#include "abi_ppc64x.h"
|
||||
|
||||
// Called by C code generated by cmd/cgo.
|
||||
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
|
||||
// Saves C callee-saved registers and calls cgocallback with three arguments.
|
||||
// fn is the PC of a func(a unsafe.Pointer) function.
|
||||
//
|
||||
// This is a simplified version that only saves GPR and FPR registers,
|
||||
// not vector registers. This keeps the stack frame smaller to avoid
|
||||
// exceeding the nosplit stack limit.
|
||||
//
|
||||
// On PPC64LE ELFv2, callee-save registers are:
|
||||
// R14-R31 (18 GPRs = 144 bytes)
|
||||
// F14-F31 (18 FPRs = 144 bytes)
|
||||
// CR2-CR4 (saved in CR field)
|
||||
//
|
||||
// Stack layout (must be 16-byte aligned):
|
||||
// 32 (FIXED_FRAME) + 24 (args) + 144 (GPR) + 144 (FPR) = 344
|
||||
// Rounded to 352 for 16-byte alignment.
|
||||
|
||||
#define FIXED_FRAME 32
|
||||
#define SAVE_SIZE 352
|
||||
#define GPR_OFFSET (FIXED_FRAME+24)
|
||||
#define FPR_OFFSET (GPR_OFFSET+SAVE_GPR_SIZE)
|
||||
|
||||
TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0
|
||||
// Save LR and CR in caller's frame per ELFv2 ABI
|
||||
MOVD LR, R0
|
||||
MOVD R0, 16(R1)
|
||||
MOVW CR, R0
|
||||
MOVD R0, 8(R1)
|
||||
|
||||
// Allocate our stack frame
|
||||
MOVDU R1, -SAVE_SIZE(R1)
|
||||
|
||||
// Save TOC (R2) in case needed
|
||||
MOVD R2, 24(R1)
|
||||
|
||||
// Save callee-save GPRs
|
||||
SAVE_GPR(GPR_OFFSET)
|
||||
|
||||
// Save callee-save FPRs
|
||||
SAVE_FPR(FPR_OFFSET)
|
||||
|
||||
// Initialize R0 to 0 as expected by Go
|
||||
MOVD $0, R0
|
||||
|
||||
// Load the current g.
|
||||
BL runtime·load_g(SB)
|
||||
|
||||
// Set up arguments for cgocallback
|
||||
MOVD R3, FIXED_FRAME+0(R1) // fn unsafe.Pointer
|
||||
MOVD R4, FIXED_FRAME+8(R1) // a unsafe.Pointer
|
||||
|
||||
// Skip R5 = n uint32
|
||||
MOVD R6, FIXED_FRAME+16(R1) // ctxt uintptr
|
||||
BL runtime·cgocallback(SB)
|
||||
|
||||
// Restore callee-save FPRs
|
||||
RESTORE_FPR(FPR_OFFSET)
|
||||
|
||||
// Restore callee-save GPRs
|
||||
RESTORE_GPR(GPR_OFFSET)
|
||||
|
||||
// Restore TOC
|
||||
MOVD 24(R1), R2
|
||||
|
||||
// Deallocate stack frame
|
||||
ADD $SAVE_SIZE, R1
|
||||
|
||||
// Restore LR and CR from caller's frame
|
||||
MOVD 16(R1), R0
|
||||
MOVD R0, LR
|
||||
MOVD 8(R1), R0
|
||||
MOVW R0, CR
|
||||
|
||||
RET
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
// Copyright 2020 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// Called by C code generated by cmd/cgo.
|
||||
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
|
||||
// Saves C callee-saved registers and calls cgocallback with three arguments.
|
||||
// fn is the PC of a func(a unsafe.Pointer) function.
|
||||
TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0
|
||||
/*
|
||||
* Push arguments for fn (X10, X11, X13), along with all callee-save
|
||||
* registers. Note that at procedure entry the first argument is at
|
||||
* 8(X2).
|
||||
*/
|
||||
ADD $(-8*29), X2
|
||||
MOV X10, (8*1)(X2) // fn unsafe.Pointer
|
||||
MOV X11, (8*2)(X2) // a unsafe.Pointer
|
||||
MOV X13, (8*3)(X2) // ctxt uintptr
|
||||
MOV X8, (8*4)(X2)
|
||||
MOV X9, (8*5)(X2)
|
||||
MOV X18, (8*6)(X2)
|
||||
MOV X19, (8*7)(X2)
|
||||
MOV X20, (8*8)(X2)
|
||||
MOV X21, (8*9)(X2)
|
||||
MOV X22, (8*10)(X2)
|
||||
MOV X23, (8*11)(X2)
|
||||
MOV X24, (8*12)(X2)
|
||||
MOV X25, (8*13)(X2)
|
||||
MOV X26, (8*14)(X2)
|
||||
MOV g, (8*15)(X2)
|
||||
MOV X1, (8*16)(X2)
|
||||
MOVD F8, (8*17)(X2)
|
||||
MOVD F9, (8*18)(X2)
|
||||
MOVD F18, (8*19)(X2)
|
||||
MOVD F19, (8*20)(X2)
|
||||
MOVD F20, (8*21)(X2)
|
||||
MOVD F21, (8*22)(X2)
|
||||
MOVD F22, (8*23)(X2)
|
||||
MOVD F23, (8*24)(X2)
|
||||
MOVD F24, (8*25)(X2)
|
||||
MOVD F25, (8*26)(X2)
|
||||
MOVD F26, (8*27)(X2)
|
||||
MOVD F27, (8*28)(X2)
|
||||
|
||||
// Initialize Go ABI environment
|
||||
CALL runtime·load_g(SB)
|
||||
CALL runtime·cgocallback(SB)
|
||||
|
||||
MOV (8*4)(X2), X8
|
||||
MOV (8*5)(X2), X9
|
||||
MOV (8*6)(X2), X18
|
||||
MOV (8*7)(X2), X19
|
||||
MOV (8*8)(X2), X20
|
||||
MOV (8*9)(X2), X21
|
||||
MOV (8*10)(X2), X22
|
||||
MOV (8*11)(X2), X23
|
||||
MOV (8*12)(X2), X24
|
||||
MOV (8*13)(X2), X25
|
||||
MOV (8*14)(X2), X26
|
||||
MOV (8*15)(X2), g
|
||||
MOV (8*16)(X2), X1
|
||||
MOVD (8*17)(X2), F8
|
||||
MOVD (8*18)(X2), F9
|
||||
MOVD (8*19)(X2), F18
|
||||
MOVD (8*20)(X2), F19
|
||||
MOVD (8*21)(X2), F20
|
||||
MOVD (8*22)(X2), F21
|
||||
MOVD (8*23)(X2), F22
|
||||
MOVD (8*24)(X2), F23
|
||||
MOVD (8*25)(X2), F24
|
||||
MOVD (8*26)(X2), F25
|
||||
MOVD (8*27)(X2), F26
|
||||
MOVD (8*28)(X2), F27
|
||||
ADD $(8*29), X2
|
||||
|
||||
RET
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
// Copyright 2016 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// Called by C code generated by cmd/cgo.
|
||||
// func crosscall2(fn, a unsafe.Pointer, n int32, ctxt uintptr)
|
||||
// Saves C callee-saved registers and calls cgocallback with three arguments.
|
||||
// fn is the PC of a func(a unsafe.Pointer) function.
|
||||
TEXT crosscall2(SB), NOSPLIT|NOFRAME, $0
|
||||
// Start with standard C stack frame layout and linkage.
|
||||
|
||||
// Save R6-R15 in the register save area of the calling function.
|
||||
STMG R6, R15, 48(R15)
|
||||
|
||||
// Allocate 96 bytes on the stack.
|
||||
MOVD $-96(R15), R15
|
||||
|
||||
// Save F8-F15 in our stack frame.
|
||||
FMOVD F8, 32(R15)
|
||||
FMOVD F9, 40(R15)
|
||||
FMOVD F10, 48(R15)
|
||||
FMOVD F11, 56(R15)
|
||||
FMOVD F12, 64(R15)
|
||||
FMOVD F13, 72(R15)
|
||||
FMOVD F14, 80(R15)
|
||||
FMOVD F15, 88(R15)
|
||||
|
||||
// Initialize Go ABI environment.
|
||||
BL runtime·load_g(SB)
|
||||
|
||||
MOVD R2, 8(R15) // fn unsafe.Pointer
|
||||
MOVD R3, 16(R15) // a unsafe.Pointer
|
||||
|
||||
// Skip R4 = n uint32
|
||||
MOVD R5, 24(R15) // ctxt uintptr
|
||||
BL runtime·cgocallback(SB)
|
||||
|
||||
FMOVD 32(R15), F8
|
||||
FMOVD 40(R15), F9
|
||||
FMOVD 48(R15), F10
|
||||
FMOVD 56(R15), F11
|
||||
FMOVD 64(R15), F12
|
||||
FMOVD 72(R15), F13
|
||||
FMOVD 80(R15), F14
|
||||
FMOVD 88(R15), F15
|
||||
|
||||
// De-allocate stack frame.
|
||||
MOVD $96(R15), R15
|
||||
|
||||
// Restore R6-R15.
|
||||
LMG 48(R15), R6, R15
|
||||
|
||||
RET
|
||||
+93
@@ -0,0 +1,93 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
package fakecgo
|
||||
|
||||
import (
|
||||
_ "unsafe"
|
||||
)
|
||||
|
||||
// TODO: decide if we need _runtime_cgo_panic_internal
|
||||
|
||||
//go:linkname x_cgo_init_trampoline x_cgo_init_trampoline
|
||||
//go:linkname _cgo_init _cgo_init
|
||||
var x_cgo_init_trampoline byte
|
||||
var _cgo_init = &x_cgo_init_trampoline
|
||||
|
||||
// Creates a new system thread without updating any Go state.
|
||||
//
|
||||
// This method is invoked during shared library loading to create a new OS
|
||||
// thread to perform the runtime initialization. This method is similar to
|
||||
// _cgo_sys_thread_start except that it doesn't update any Go state.
|
||||
|
||||
//go:linkname x_cgo_thread_start_trampoline x_cgo_thread_start_trampoline
|
||||
//go:linkname _cgo_thread_start _cgo_thread_start
|
||||
var x_cgo_thread_start_trampoline byte
|
||||
var _cgo_thread_start = &x_cgo_thread_start_trampoline
|
||||
|
||||
// Notifies that the runtime has been initialized.
|
||||
//
|
||||
// We currently block at every CGO entry point (via _cgo_wait_runtime_init_done)
|
||||
// to ensure that the runtime has been initialized before the CGO call is
|
||||
// executed. This is necessary for shared libraries where we kickoff runtime
|
||||
// initialization in a separate thread and return without waiting for this
|
||||
// thread to complete the init.
|
||||
|
||||
//go:linkname x_cgo_notify_runtime_init_done_trampoline x_cgo_notify_runtime_init_done_trampoline
|
||||
//go:linkname _cgo_notify_runtime_init_done _cgo_notify_runtime_init_done
|
||||
var x_cgo_notify_runtime_init_done_trampoline byte
|
||||
var _cgo_notify_runtime_init_done = &x_cgo_notify_runtime_init_done_trampoline
|
||||
|
||||
// Indicates whether a dummy thread key has been created or not.
|
||||
//
|
||||
// When calling go exported function from C, we register a destructor
|
||||
// callback, for a dummy thread key, by using pthread_key_create.
|
||||
|
||||
//go:linkname _cgo_pthread_key_created _cgo_pthread_key_created
|
||||
var x_cgo_pthread_key_created uintptr
|
||||
var _cgo_pthread_key_created = &x_cgo_pthread_key_created
|
||||
|
||||
// Set the x_crosscall2_ptr C function pointer variable point to crosscall2.
|
||||
// It's for the runtime package to call at init time.
|
||||
func set_crosscall2() {
|
||||
// nothing needs to be done here for fakecgo
|
||||
// because it's possible to just call cgocallback directly
|
||||
}
|
||||
|
||||
//go:linkname _set_crosscall2 runtime.set_crosscall2
|
||||
var _set_crosscall2 = set_crosscall2
|
||||
|
||||
// Store the g into the thread-specific value.
|
||||
// So that pthread_key_destructor will dropm when the thread is exiting.
|
||||
|
||||
//go:linkname x_cgo_bindm_trampoline x_cgo_bindm_trampoline
|
||||
//go:linkname _cgo_bindm _cgo_bindm
|
||||
var x_cgo_bindm_trampoline byte
|
||||
var _cgo_bindm = &x_cgo_bindm_trampoline
|
||||
|
||||
// TODO: decide if we need x_cgo_set_context_function
|
||||
// TODO: decide if we need _cgo_yield
|
||||
|
||||
var (
|
||||
// In Go 1.20 the race detector was rewritten to pure Go
|
||||
// on darwin. This means that when CGO_ENABLED=0 is set
|
||||
// fakecgo is built with race detector code. This is not
|
||||
// good since this code is pretending to be C. The go:norace
|
||||
// pragma is not enough, since it only applies to the native
|
||||
// ABIInternal function. The ABIO wrapper (which is necessary,
|
||||
// since all references to text symbols from assembly will use it)
|
||||
// does not inherit the go:norace pragma, so it will still be
|
||||
// instrumented by the race detector.
|
||||
//
|
||||
// To circumvent this issue, using closure calls in the
|
||||
// assembly, which forces the compiler to use the ABIInternal
|
||||
// native implementation (which has go:norace) instead.
|
||||
threadentry_call = threadentry
|
||||
x_cgo_init_call = x_cgo_init
|
||||
x_cgo_setenv_call = x_cgo_setenv
|
||||
x_cgo_unsetenv_call = x_cgo_unsetenv
|
||||
x_cgo_thread_start_call = x_cgo_thread_start
|
||||
)
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
// Package fakecgo implements the Cgo runtime (runtime/cgo) entirely in Go.
|
||||
// This allows code that calls into C to function properly when CGO_ENABLED=0.
|
||||
//
|
||||
// # Goals
|
||||
//
|
||||
// fakecgo attempts to replicate the same naming structure as in the runtime.
|
||||
// For example, functions that have the prefix "gcc_*" are named "go_*".
|
||||
// This makes it easier to port other GOOSs and GOARCHs as well as to keep
|
||||
// it in sync with runtime/cgo.
|
||||
//
|
||||
// # Support
|
||||
//
|
||||
// Currently, fakecgo only supports macOS on amd64 & arm64. It also cannot
|
||||
// be used with -buildmode=c-archive because that requires special initialization
|
||||
// that fakecgo does not implement at the moment.
|
||||
//
|
||||
// # Usage
|
||||
//
|
||||
// Using fakecgo is easy just import _ "github.com/ebitengine/purego" and then
|
||||
// set the environment variable CGO_ENABLED=0.
|
||||
// The recommended usage for fakecgo is to prefer using runtime/cgo if possible
|
||||
// but if cross-compiling or fast build times are important fakecgo is available.
|
||||
// Purego will pick which ever Cgo runtime is available and prefer the one that
|
||||
// comes with Go (runtime/cgo).
|
||||
package fakecgo
|
||||
|
||||
//go:generate go run gen.go
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2025 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
package fakecgo
|
||||
|
||||
import _ "unsafe"
|
||||
|
||||
// setg_trampoline calls setg with the G provided
|
||||
func setg_trampoline(setg uintptr, G uintptr)
|
||||
|
||||
// call5 takes fn the C function and 5 arguments and calls the function with those arguments
|
||||
func call5(fn, a1, a2, a3, a4, a5 uintptr) uintptr
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build freebsd && !cgo
|
||||
|
||||
package fakecgo
|
||||
|
||||
import _ "unsafe" // for go:linkname
|
||||
|
||||
// Supply environ and __progname, because we don't
|
||||
// link against the standard FreeBSD crt0.o and the
|
||||
// libc dynamic library needs them.
|
||||
|
||||
// Note: when building with cross-compiling or CGO_ENABLED=0, add
|
||||
// the following argument to `go` so that these symbols are defined by
|
||||
// making fakecgo the Cgo.
|
||||
// -gcflags="github.com/ebitengine/purego/internal/fakecgo=-std"
|
||||
|
||||
//go:linkname _environ environ
|
||||
//go:linkname _progname __progname
|
||||
|
||||
//go:cgo_export_dynamic environ
|
||||
//go:cgo_export_dynamic __progname
|
||||
|
||||
var _environ uintptr
|
||||
var _progname uintptr
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
package fakecgo
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func _cgo_sys_thread_start(ts *ThreadStart) {
|
||||
var attr pthread_attr_t
|
||||
var ign, oset sigset_t
|
||||
var p pthread_t
|
||||
var size size_t
|
||||
var err int
|
||||
|
||||
sigfillset(&ign)
|
||||
pthread_sigmask(SIG_SETMASK, &ign, &oset)
|
||||
|
||||
size = pthread_get_stacksize_np(pthread_self())
|
||||
pthread_attr_init(&attr)
|
||||
pthread_attr_setstacksize(&attr, size)
|
||||
// Leave stacklo=0 and set stackhi=size; mstart will do the rest.
|
||||
ts.g.stackhi = uintptr(size)
|
||||
|
||||
err = _cgo_try_pthread_create(&p, &attr, unsafe.Pointer(threadentry_trampolineABI0), ts)
|
||||
|
||||
pthread_sigmask(SIG_SETMASK, &oset, nil)
|
||||
|
||||
if err != 0 {
|
||||
print("fakecgo: pthread_create failed: ")
|
||||
println(err)
|
||||
abort()
|
||||
}
|
||||
}
|
||||
|
||||
// threadentry_trampolineABI0 maps the C ABI to Go ABI then calls the Go function
|
||||
//
|
||||
//go:linkname x_threadentry_trampoline threadentry_trampoline
|
||||
var x_threadentry_trampoline byte
|
||||
var threadentry_trampolineABI0 = &x_threadentry_trampoline
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func threadentry(v unsafe.Pointer) unsafe.Pointer {
|
||||
ts := *(*ThreadStart)(v)
|
||||
free(v)
|
||||
|
||||
// TODO: support ios
|
||||
//#if TARGET_OS_IPHONE
|
||||
// darwin_arm_init_thread_exception_port();
|
||||
//#endif
|
||||
setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g)))
|
||||
|
||||
// faking funcs in go is a bit a... involved - but the following works :)
|
||||
fn := uintptr(unsafe.Pointer(&ts.fn))
|
||||
(*(*func())(unsafe.Pointer(&fn)))()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// here we will store a pointer to the provided setg func
|
||||
var setg_func uintptr
|
||||
|
||||
// x_cgo_init(G *g, void (*setg)(void*)) (runtime/cgo/gcc_linux_amd64.c)
|
||||
// This get's called during startup, adjusts stacklo, and provides a pointer to setg_gcc for us
|
||||
// Additionally, if we set _cgo_init to non-null, go won't do it's own TLS setup
|
||||
// This function can't be go:systemstack since go is not in a state where the systemcheck would work.
|
||||
//
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func x_cgo_init(g *G, setg uintptr) {
|
||||
var size size_t
|
||||
|
||||
setg_func = setg
|
||||
size = pthread_get_stacksize_np(pthread_self())
|
||||
g.stacklo = uintptr(unsafe.Add(unsafe.Pointer(&size), -size+4096))
|
||||
|
||||
//TODO: support ios
|
||||
//#if TARGET_OS_IPHONE
|
||||
// darwin_arm_init_mach_exception_handler();
|
||||
// darwin_arm_init_thread_exception_port();
|
||||
// init_working_dir();
|
||||
//#endif
|
||||
}
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
package fakecgo
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//go:nosplit
|
||||
func _cgo_sys_thread_start(ts *ThreadStart) {
|
||||
var attr pthread_attr_t
|
||||
var ign, oset sigset_t
|
||||
var p pthread_t
|
||||
var size size_t
|
||||
var err int
|
||||
|
||||
// fprintf(stderr, "runtime/cgo: _cgo_sys_thread_start: fn=%p, g=%p\n", ts->fn, ts->g); // debug
|
||||
sigfillset(&ign)
|
||||
pthread_sigmask(SIG_SETMASK, &ign, &oset)
|
||||
|
||||
pthread_attr_init(&attr)
|
||||
pthread_attr_getstacksize(&attr, &size)
|
||||
// Leave stacklo=0 and set stackhi=size; mstart will do the rest.
|
||||
ts.g.stackhi = uintptr(size)
|
||||
|
||||
err = _cgo_try_pthread_create(&p, &attr, unsafe.Pointer(threadentry_trampolineABI0), ts)
|
||||
|
||||
pthread_sigmask(SIG_SETMASK, &oset, nil)
|
||||
|
||||
if err != 0 {
|
||||
print("fakecgo: pthread_create failed: ")
|
||||
println(err)
|
||||
abort()
|
||||
}
|
||||
}
|
||||
|
||||
// threadentry_trampolineABI0 maps the C ABI to Go ABI then calls the Go function
|
||||
//
|
||||
//go:linkname x_threadentry_trampoline threadentry_trampoline
|
||||
var x_threadentry_trampoline byte
|
||||
var threadentry_trampolineABI0 = &x_threadentry_trampoline
|
||||
|
||||
//go:nosplit
|
||||
func threadentry(v unsafe.Pointer) unsafe.Pointer {
|
||||
ts := *(*ThreadStart)(v)
|
||||
free(v)
|
||||
|
||||
setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g)))
|
||||
|
||||
// faking funcs in go is a bit a... involved - but the following works :)
|
||||
fn := uintptr(unsafe.Pointer(&ts.fn))
|
||||
(*(*func())(unsafe.Pointer(&fn)))()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// here we will store a pointer to the provided setg func
|
||||
var setg_func uintptr
|
||||
|
||||
// x_cgo_init(G *g, void (*setg)(void*)) (runtime/cgo/gcc_linux_amd64.c)
|
||||
// This get's called during startup, adjusts stacklo, and provides a pointer to setg_gcc for us
|
||||
// Additionally, if we set _cgo_init to non-null, go won't do it's own TLS setup
|
||||
// This function can't be go:systemstack since go is not in a state where the systemcheck would work.
|
||||
//
|
||||
//go:nosplit
|
||||
func x_cgo_init(g *G, setg uintptr) {
|
||||
var size size_t
|
||||
var attr *pthread_attr_t
|
||||
|
||||
/* The memory sanitizer distributed with versions of clang
|
||||
before 3.8 has a bug: if you call mmap before malloc, mmap
|
||||
may return an address that is later overwritten by the msan
|
||||
library. Avoid this problem by forcing a call to malloc
|
||||
here, before we ever call malloc.
|
||||
|
||||
This is only required for the memory sanitizer, so it's
|
||||
unfortunate that we always run it. It should be possible
|
||||
to remove this when we no longer care about versions of
|
||||
clang before 3.8. The test for this is
|
||||
misc/cgo/testsanitizers.
|
||||
|
||||
GCC works hard to eliminate a seemingly unnecessary call to
|
||||
malloc, so we actually use the memory we allocate. */
|
||||
|
||||
setg_func = setg
|
||||
attr = (*pthread_attr_t)(malloc(unsafe.Sizeof(*attr)))
|
||||
if attr == nil {
|
||||
println("fakecgo: malloc failed")
|
||||
abort()
|
||||
}
|
||||
pthread_attr_init(attr)
|
||||
pthread_attr_getstacksize(attr, &size)
|
||||
// runtime/cgo uses __builtin_frame_address(0) instead of `uintptr(unsafe.Pointer(&size))`
|
||||
// but this should be OK since we are taking the address of the first variable in this function.
|
||||
g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096
|
||||
pthread_attr_destroy(attr)
|
||||
free(unsafe.Pointer(attr))
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
package fakecgo
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
pthread_g pthread_key_t
|
||||
|
||||
runtime_init_cond = PTHREAD_COND_INITIALIZER
|
||||
runtime_init_mu = PTHREAD_MUTEX_INITIALIZER
|
||||
runtime_init_done int
|
||||
)
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func x_cgo_notify_runtime_init_done() {
|
||||
pthread_mutex_lock(&runtime_init_mu)
|
||||
runtime_init_done = 1
|
||||
pthread_cond_broadcast(&runtime_init_cond)
|
||||
pthread_mutex_unlock(&runtime_init_mu)
|
||||
}
|
||||
|
||||
// Store the g into a thread-specific value associated with the pthread key pthread_g.
|
||||
// And pthread_key_destructor will dropm when the thread is exiting.
|
||||
//
|
||||
//go:norace
|
||||
func x_cgo_bindm(g unsafe.Pointer) {
|
||||
// We assume this will always succeed, otherwise, there might be extra M leaking,
|
||||
// when a C thread exits after a cgo call.
|
||||
// We only invoke this function once per thread in runtime.needAndBindM,
|
||||
// and the next calls just reuse the bound m.
|
||||
pthread_setspecific(pthread_g, g)
|
||||
}
|
||||
|
||||
// _cgo_try_pthread_create retries pthread_create if it fails with
|
||||
// EAGAIN.
|
||||
//
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func _cgo_try_pthread_create(thread *pthread_t, attr *pthread_attr_t, pfn unsafe.Pointer, arg *ThreadStart) int {
|
||||
var ts syscall.Timespec
|
||||
// tries needs to be the same type as syscall.Timespec.Nsec
|
||||
// but the fields are int32 on 32bit and int64 on 64bit.
|
||||
// tries is assigned to syscall.Timespec.Nsec in order to match its type.
|
||||
tries := ts.Nsec
|
||||
var err int
|
||||
|
||||
for tries = 0; tries < 20; tries++ {
|
||||
// inlined this call because it ran out of stack when inlining was disabled
|
||||
err = int(call5(pthread_createABI0, uintptr(unsafe.Pointer(thread)), uintptr(unsafe.Pointer(attr)), uintptr(pfn), uintptr(unsafe.Pointer(arg)), 0))
|
||||
if err == 0 {
|
||||
// inlined this call because it ran out of stack when inlining was disabled
|
||||
call5(pthread_detachABI0, uintptr(*thread), 0, 0, 0, 0)
|
||||
return 0
|
||||
}
|
||||
if err != int(syscall.EAGAIN) {
|
||||
return err
|
||||
}
|
||||
ts.Sec = 0
|
||||
ts.Nsec = (tries + 1) * 1000 * 1000 // Milliseconds.
|
||||
// inlined this call because it ran out of stack when inlining was disabled
|
||||
call5(nanosleepABI0, uintptr(unsafe.Pointer(&ts)), 0, 0, 0, 0)
|
||||
}
|
||||
return int(syscall.EAGAIN)
|
||||
}
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
package fakecgo
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//go:nosplit
|
||||
func _cgo_sys_thread_start(ts *ThreadStart) {
|
||||
var attr pthread_attr_t
|
||||
var ign, oset sigset_t
|
||||
var p pthread_t
|
||||
var size size_t
|
||||
var err int
|
||||
|
||||
//fprintf(stderr, "runtime/cgo: _cgo_sys_thread_start: fn=%p, g=%p\n", ts->fn, ts->g); // debug
|
||||
sigfillset(&ign)
|
||||
pthread_sigmask(SIG_SETMASK, &ign, &oset)
|
||||
|
||||
pthread_attr_init(&attr)
|
||||
pthread_attr_getstacksize(&attr, &size)
|
||||
// Leave stacklo=0 and set stackhi=size; mstart will do the rest.
|
||||
ts.g.stackhi = uintptr(size)
|
||||
|
||||
err = _cgo_try_pthread_create(&p, &attr, unsafe.Pointer(threadentry_trampolineABI0), ts)
|
||||
|
||||
pthread_sigmask(SIG_SETMASK, &oset, nil)
|
||||
|
||||
if err != 0 {
|
||||
print("fakecgo: pthread_create failed: ")
|
||||
println(err)
|
||||
abort()
|
||||
}
|
||||
}
|
||||
|
||||
// threadentry_trampolineABI0 maps the C ABI to Go ABI then calls the Go function
|
||||
//
|
||||
//go:linkname x_threadentry_trampoline threadentry_trampoline
|
||||
var x_threadentry_trampoline byte
|
||||
var threadentry_trampolineABI0 = &x_threadentry_trampoline
|
||||
|
||||
//go:nosplit
|
||||
func threadentry(v unsafe.Pointer) unsafe.Pointer {
|
||||
ts := *(*ThreadStart)(v)
|
||||
free(v)
|
||||
|
||||
setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g)))
|
||||
|
||||
// faking funcs in go is a bit a... involved - but the following works :)
|
||||
fn := uintptr(unsafe.Pointer(&ts.fn))
|
||||
(*(*func())(unsafe.Pointer(&fn)))()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// here we will store a pointer to the provided setg func
|
||||
var setg_func uintptr
|
||||
|
||||
// x_cgo_init(G *g, void (*setg)(void*)) (runtime/cgo/gcc_linux_amd64.c)
|
||||
// This get's called during startup, adjusts stacklo, and provides a pointer to setg_gcc for us
|
||||
// Additionally, if we set _cgo_init to non-null, go won't do it's own TLS setup
|
||||
// This function can't be go:systemstack since go is not in a state where the systemcheck would work.
|
||||
//
|
||||
//go:nosplit
|
||||
func x_cgo_init(g *G, setg uintptr) {
|
||||
var size size_t
|
||||
var attr *pthread_attr_t
|
||||
|
||||
/* The memory sanitizer distributed with versions of clang
|
||||
before 3.8 has a bug: if you call mmap before malloc, mmap
|
||||
may return an address that is later overwritten by the msan
|
||||
library. Avoid this problem by forcing a call to malloc
|
||||
here, before we ever call malloc.
|
||||
|
||||
This is only required for the memory sanitizer, so it's
|
||||
unfortunate that we always run it. It should be possible
|
||||
to remove this when we no longer care about versions of
|
||||
clang before 3.8. The test for this is
|
||||
misc/cgo/testsanitizers.
|
||||
|
||||
GCC works hard to eliminate a seemingly unnecessary call to
|
||||
malloc, so we actually use the memory we allocate. */
|
||||
|
||||
setg_func = setg
|
||||
attr = (*pthread_attr_t)(malloc(unsafe.Sizeof(*attr)))
|
||||
if attr == nil {
|
||||
println("fakecgo: malloc failed")
|
||||
abort()
|
||||
}
|
||||
pthread_attr_init(attr)
|
||||
pthread_attr_getstacksize(attr, &size)
|
||||
// runtime/cgo uses __builtin_frame_address(0) instead of `uintptr(unsafe.Pointer(&size))`
|
||||
// but this should be OK since we are taking the address of the first variable in this function.
|
||||
g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096
|
||||
pthread_attr_destroy(attr)
|
||||
free(unsafe.Pointer(attr))
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !cgo && (amd64 || arm64)
|
||||
|
||||
package fakecgo
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//go:nosplit
|
||||
func _cgo_sys_thread_start(ts *ThreadStart) {
|
||||
var attr pthread_attr_t
|
||||
var ign, oset sigset_t
|
||||
var p pthread_t
|
||||
var size size_t
|
||||
var err int
|
||||
|
||||
// fprintf(stderr, "runtime/cgo: _cgo_sys_thread_start: fn=%p, g=%p\n", ts->fn, ts->g); // debug
|
||||
sigfillset(&ign)
|
||||
pthread_sigmask(SIG_SETMASK, &ign, &oset)
|
||||
|
||||
pthread_attr_init(&attr)
|
||||
pthread_attr_getstacksize(&attr, &size)
|
||||
// Leave stacklo=0 and set stackhi=size; mstart will do the rest.
|
||||
ts.g.stackhi = uintptr(size)
|
||||
|
||||
err = _cgo_try_pthread_create(&p, &attr, unsafe.Pointer(threadentry_trampolineABI0), ts)
|
||||
|
||||
pthread_sigmask(SIG_SETMASK, &oset, nil)
|
||||
|
||||
if err != 0 {
|
||||
print("fakecgo: pthread_create failed: ")
|
||||
println(err)
|
||||
abort()
|
||||
}
|
||||
}
|
||||
|
||||
// threadentry_trampolineABI0 maps the C ABI to Go ABI then calls the Go function
|
||||
//
|
||||
//go:linkname x_threadentry_trampoline threadentry_trampoline
|
||||
var x_threadentry_trampoline byte
|
||||
var threadentry_trampolineABI0 = &x_threadentry_trampoline
|
||||
|
||||
//go:nosplit
|
||||
func threadentry(v unsafe.Pointer) unsafe.Pointer {
|
||||
var ss stack_t
|
||||
ts := *(*ThreadStart)(v)
|
||||
free(v)
|
||||
|
||||
// On NetBSD, a new thread inherits the signal stack of the
|
||||
// creating thread. That confuses minit, so we remove that
|
||||
// signal stack here before calling the regular mstart. It's
|
||||
// a bit baroque to remove a signal stack here only to add one
|
||||
// in minit, but it's a simple change that keeps NetBSD
|
||||
// working like other OS's. At this point all signals are
|
||||
// blocked, so there is no race.
|
||||
ss.ss_flags = SS_DISABLE
|
||||
sigaltstack(&ss, nil)
|
||||
|
||||
setg_trampoline(setg_func, uintptr(unsafe.Pointer(ts.g)))
|
||||
|
||||
// faking funcs in go is a bit a... involved - but the following works :)
|
||||
fn := uintptr(unsafe.Pointer(&ts.fn))
|
||||
(*(*func())(unsafe.Pointer(&fn)))()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// here we will store a pointer to the provided setg func
|
||||
var setg_func uintptr
|
||||
|
||||
//go:nosplit
|
||||
func x_cgo_init(g *G, setg uintptr) {
|
||||
var size size_t
|
||||
var attr *pthread_attr_t
|
||||
|
||||
/* The memory sanitizer distributed with versions of clang
|
||||
before 3.8 has a bug: if you call mmap before malloc, mmap
|
||||
may return an address that is later overwritten by the msan
|
||||
library. Avoid this problem by forcing a call to malloc
|
||||
here, before we ever call malloc.
|
||||
|
||||
This is only required for the memory sanitizer, so it's
|
||||
unfortunate that we always run it. It should be possible
|
||||
to remove this when we no longer care about versions of
|
||||
clang before 3.8. The test for this is
|
||||
misc/cgo/testsanitizers.
|
||||
|
||||
GCC works hard to eliminate a seemingly unnecessary call to
|
||||
malloc, so we actually use the memory we allocate. */
|
||||
|
||||
setg_func = setg
|
||||
attr = (*pthread_attr_t)(malloc(unsafe.Sizeof(*attr)))
|
||||
if attr == nil {
|
||||
println("fakecgo: malloc failed")
|
||||
abort()
|
||||
}
|
||||
pthread_attr_init(attr)
|
||||
pthread_attr_getstacksize(attr, &size)
|
||||
// runtime/cgo uses __builtin_frame_address(0) instead of `uintptr(unsafe.Pointer(&size))`
|
||||
// but this should be OK since we are taking the address of the first variable in this function.
|
||||
g.stacklo = uintptr(unsafe.Pointer(&size)) - uintptr(size) + 4096
|
||||
pthread_attr_destroy(attr)
|
||||
free(unsafe.Pointer(attr))
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
package fakecgo
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func x_cgo_setenv(arg *[2]*byte) {
|
||||
setenv(arg[0], arg[1], 1)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func x_cgo_unsetenv(arg *[1]*byte) {
|
||||
unsetenv(arg[0])
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
package fakecgo
|
||||
|
||||
import "unsafe"
|
||||
|
||||
// _cgo_thread_start is split into three parts in cgo since only one part is system dependent (keep it here for easier handling)
|
||||
|
||||
// _cgo_thread_start(ThreadStart *arg) (runtime/cgo/gcc_util.c)
|
||||
// This get's called instead of the go code for creating new threads
|
||||
// -> pthread_* stuff is used, so threads are setup correctly for C
|
||||
// If this is missing, TLS is only setup correctly on thread 1!
|
||||
// This function should be go:systemstack instead of go:nosplit (but that requires runtime)
|
||||
//
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func x_cgo_thread_start(arg *ThreadStart) {
|
||||
var ts *ThreadStart
|
||||
// Make our own copy that can persist after we return.
|
||||
// _cgo_tsan_acquire();
|
||||
ts = (*ThreadStart)(malloc(unsafe.Sizeof(*ts)))
|
||||
// _cgo_tsan_release();
|
||||
if ts == nil {
|
||||
println("fakecgo: out of memory in thread_start")
|
||||
abort()
|
||||
}
|
||||
// *ts = *arg would cause a writebarrier so copy using slices
|
||||
const ptrSize = unsafe.Sizeof(uintptr(0))
|
||||
s1 := unsafe.Slice((*uintptr)(unsafe.Pointer(ts)), unsafe.Sizeof(*ts)/ptrSize)
|
||||
s2 := unsafe.Slice((*uintptr)(unsafe.Pointer(arg)), unsafe.Sizeof(*arg)/ptrSize)
|
||||
for i := range s2 {
|
||||
s1[i] = s2[i]
|
||||
}
|
||||
_cgo_sys_thread_start(ts) // OS-dependent half
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
// The runtime package contains an uninitialized definition
|
||||
// for runtime·iscgo. Override it to tell the runtime we're here.
|
||||
// There are various function pointers that should be set too,
|
||||
// but those depend on dynamic linker magic to get initialized
|
||||
// correctly, and sometimes they break. This variable is a
|
||||
// backup: it depends only on old C style static linking rules.
|
||||
|
||||
package fakecgo
|
||||
|
||||
import _ "unsafe" // for go:linkname
|
||||
|
||||
//go:linkname _iscgo runtime.iscgo
|
||||
var _iscgo bool = true
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
package fakecgo
|
||||
|
||||
type (
|
||||
size_t uintptr
|
||||
// Sources:
|
||||
// Darwin (32 bytes) - https://github.com/apple/darwin-xnu/blob/2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32/bsd/sys/_types.h#L74
|
||||
// FreeBSD (32 bytes) - https://github.com/DoctorWkt/xv6-freebsd/blob/d2a294c2a984baed27676068b15ed9a29b06ab6f/include/signal.h#L98C9-L98C21
|
||||
// Linux (128 bytes) - https://github.com/torvalds/linux/blob/ab75170520d4964f3acf8bb1f91d34cbc650688e/arch/x86/include/asm/signal.h#L25
|
||||
sigset_t [128]byte
|
||||
pthread_attr_t [64]byte
|
||||
pthread_t int
|
||||
pthread_key_t uint64
|
||||
)
|
||||
|
||||
// for pthread_sigmask:
|
||||
|
||||
type sighow int32
|
||||
|
||||
const (
|
||||
SIG_BLOCK sighow = 0
|
||||
SIG_UNBLOCK sighow = 1
|
||||
SIG_SETMASK sighow = 2
|
||||
)
|
||||
|
||||
type G struct {
|
||||
stacklo uintptr
|
||||
stackhi uintptr
|
||||
}
|
||||
|
||||
type ThreadStart struct {
|
||||
g *G
|
||||
tls *uintptr
|
||||
fn uintptr
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
package fakecgo
|
||||
|
||||
type (
|
||||
pthread_mutex_t struct {
|
||||
sig int64
|
||||
opaque [56]byte
|
||||
}
|
||||
pthread_cond_t struct {
|
||||
sig int64
|
||||
opaque [40]byte
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
PTHREAD_COND_INITIALIZER = pthread_cond_t{sig: 0x3CB0B1BB}
|
||||
PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t{sig: 0x32AAABA7}
|
||||
)
|
||||
|
||||
type stack_t struct {
|
||||
/* not implemented */
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
package fakecgo
|
||||
|
||||
type (
|
||||
pthread_cond_t uintptr
|
||||
pthread_mutex_t uintptr
|
||||
)
|
||||
|
||||
var (
|
||||
PTHREAD_COND_INITIALIZER = pthread_cond_t(0)
|
||||
PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t(0)
|
||||
)
|
||||
|
||||
type stack_t struct {
|
||||
/* not implemented */
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
package fakecgo
|
||||
|
||||
type (
|
||||
pthread_cond_t [48]byte
|
||||
pthread_mutex_t [48]byte
|
||||
)
|
||||
|
||||
var (
|
||||
PTHREAD_COND_INITIALIZER = pthread_cond_t{}
|
||||
PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t{}
|
||||
)
|
||||
|
||||
type stack_t struct {
|
||||
/* not implemented */
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2025 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
package fakecgo
|
||||
|
||||
type (
|
||||
pthread_cond_t uintptr
|
||||
pthread_mutex_t uintptr
|
||||
)
|
||||
|
||||
var (
|
||||
PTHREAD_COND_INITIALIZER = pthread_cond_t(0)
|
||||
PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t(0)
|
||||
)
|
||||
|
||||
// Source: https://github.com/NetBSD/src/blob/613e27c65223fd2283b6ed679da1197e12f50e27/sys/compat/linux/arch/m68k/linux_signal.h#L133
|
||||
type stack_t struct {
|
||||
ss_sp uintptr
|
||||
ss_flags int32
|
||||
ss_size uintptr
|
||||
}
|
||||
|
||||
// Source: https://github.com/NetBSD/src/blob/613e27c65223fd2283b6ed679da1197e12f50e27/sys/sys/signal.h#L261
|
||||
const SS_DISABLE = 0x004
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build netbsd
|
||||
|
||||
package fakecgo
|
||||
|
||||
import _ "unsafe" // for go:linkname
|
||||
|
||||
// Supply environ and __progname, because we don't
|
||||
// link against the standard NetBSD crt0.o and the
|
||||
// libc dynamic library needs them.
|
||||
|
||||
//go:linkname _environ environ
|
||||
//go:linkname _progname __progname
|
||||
//go:linkname ___ps_strings __ps_strings
|
||||
|
||||
var (
|
||||
_environ uintptr
|
||||
_progname uintptr
|
||||
___ps_strings uintptr
|
||||
)
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
package fakecgo
|
||||
|
||||
import _ "unsafe" // for go:linkname
|
||||
|
||||
//go:linkname x_cgo_setenv_trampoline x_cgo_setenv_trampoline
|
||||
//go:linkname _cgo_setenv runtime._cgo_setenv
|
||||
var x_cgo_setenv_trampoline byte
|
||||
var _cgo_setenv = &x_cgo_setenv_trampoline
|
||||
|
||||
//go:linkname x_cgo_unsetenv_trampoline x_cgo_unsetenv_trampoline
|
||||
//go:linkname _cgo_unsetenv runtime._cgo_unsetenv
|
||||
var x_cgo_unsetenv_trampoline byte
|
||||
var _cgo_unsetenv = &x_cgo_unsetenv_trampoline
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (freebsd || linux)
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
|
||||
// These trampolines map the gcc ABI to Go ABI0 and then call into the Go equivalent functions.
|
||||
// On i386, both GCC and Go use stack-based calling conventions.
|
||||
//
|
||||
// When C calls a function, the stack looks like:
|
||||
// 0(SP) = return address
|
||||
// 4(SP) = arg1
|
||||
// 8(SP) = arg2
|
||||
// ...
|
||||
//
|
||||
// When we declare a Go function with frame size $N-0, Go's prologue
|
||||
// effectively does SUB $N, SP, so the C arguments shift up by N bytes:
|
||||
// N+0(SP) = return address
|
||||
// N+4(SP) = arg1
|
||||
// N+8(SP) = arg2
|
||||
//
|
||||
// Go ABI0 on 386 expects arguments starting at 0(FP) which equals N+4(SP)
|
||||
// after the prologue (where N is the local frame size).
|
||||
|
||||
TEXT x_cgo_init_trampoline(SB), NOSPLIT, $8-0
|
||||
// C args at 12(SP) and 16(SP) after frame setup (8 bytes local + 4 bytes ret addr)
|
||||
// Go function expects args at 0(SP) and 4(SP) in local frame
|
||||
MOVL 12(SP), AX // first C arg
|
||||
MOVL 16(SP), BX // second C arg
|
||||
MOVL AX, 0(SP) // Go arg 1
|
||||
MOVL BX, 4(SP) // Go arg 2
|
||||
MOVL ·x_cgo_init_call(SB), CX
|
||||
MOVL (CX), CX
|
||||
CALL CX
|
||||
RET
|
||||
|
||||
TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT, $4-0
|
||||
// C args at 8(SP) after frame setup (4 bytes local + 4 bytes ret addr)
|
||||
MOVL 8(SP), AX // first C arg
|
||||
MOVL AX, 0(SP) // Go arg 1
|
||||
MOVL ·x_cgo_thread_start_call(SB), CX
|
||||
MOVL (CX), CX
|
||||
CALL CX
|
||||
RET
|
||||
|
||||
TEXT x_cgo_setenv_trampoline(SB), NOSPLIT, $4-0
|
||||
MOVL 8(SP), AX // first C arg
|
||||
MOVL AX, 0(SP) // Go arg 1
|
||||
MOVL ·x_cgo_setenv_call(SB), CX
|
||||
MOVL (CX), CX
|
||||
CALL CX
|
||||
RET
|
||||
|
||||
TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT, $4-0
|
||||
MOVL 8(SP), AX // first C arg
|
||||
MOVL AX, 0(SP) // Go arg 1
|
||||
MOVL ·x_cgo_unsetenv_call(SB), CX
|
||||
MOVL (CX), CX
|
||||
CALL CX
|
||||
RET
|
||||
|
||||
TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT, $0-0
|
||||
CALL ·x_cgo_notify_runtime_init_done(SB)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_bindm_trampoline(SB), NOSPLIT, $0
|
||||
CALL ·x_cgo_bindm(SB)
|
||||
RET
|
||||
|
||||
// func setg_trampoline(setg uintptr, g uintptr)
|
||||
// This is called from Go, so args are at normal FP positions
|
||||
TEXT ·setg_trampoline(SB), NOSPLIT, $4-8
|
||||
MOVL g+4(FP), AX
|
||||
MOVL setg+0(FP), BX
|
||||
|
||||
// setg expects g in 0(SP)
|
||||
MOVL AX, 0(SP)
|
||||
CALL BX
|
||||
RET
|
||||
|
||||
TEXT threadentry_trampoline(SB), NOSPLIT, $4-0
|
||||
MOVL 8(SP), AX // first C arg
|
||||
MOVL AX, 0(SP) // Go arg 1
|
||||
MOVL ·threadentry_call(SB), CX
|
||||
MOVL (CX), CX
|
||||
CALL CX
|
||||
RET
|
||||
|
||||
TEXT ·call5(SB), NOSPLIT, $20-28
|
||||
MOVL fn+0(FP), AX
|
||||
MOVL a1+4(FP), BX
|
||||
MOVL a2+8(FP), CX
|
||||
MOVL a3+12(FP), DX
|
||||
MOVL a4+16(FP), SI
|
||||
MOVL a5+20(FP), DI
|
||||
|
||||
// Place arguments on local stack frame for C calling convention
|
||||
MOVL BX, 0(SP) // a1
|
||||
MOVL CX, 4(SP) // a2
|
||||
MOVL DX, 8(SP) // a3
|
||||
MOVL SI, 12(SP) // a4
|
||||
MOVL DI, 16(SP) // a5
|
||||
CALL AX
|
||||
MOVL AX, r1+24(FP)
|
||||
RET
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (darwin || linux || freebsd)
|
||||
|
||||
/*
|
||||
trampoline for emulating required C functions for cgo in go (see cgo.go)
|
||||
(we convert cdecl calling convention to go and vice-versa)
|
||||
|
||||
C Calling convention cdecl used here (we only need integer args):
|
||||
1. arg: DI
|
||||
2. arg: SI
|
||||
3. arg: DX
|
||||
4. arg: CX
|
||||
5. arg: R8
|
||||
6. arg: R9
|
||||
We don't need floats with these functions -> AX=0
|
||||
return value will be in AX
|
||||
temporary register is R11
|
||||
*/
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
#include "abi_amd64.h"
|
||||
|
||||
// these trampolines map the gcc ABI to Go ABI and then calls into the Go equivalent functions.
|
||||
|
||||
TEXT x_cgo_init_trampoline(SB), NOSPLIT, $16
|
||||
MOVQ DI, AX
|
||||
MOVQ SI, BX
|
||||
MOVQ ·x_cgo_init_call(SB), R11
|
||||
MOVQ (R11), R11
|
||||
CALL R11
|
||||
RET
|
||||
|
||||
TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT, $8
|
||||
MOVQ DI, AX
|
||||
MOVQ ·x_cgo_thread_start_call(SB), R11
|
||||
MOVQ (R11), R11
|
||||
CALL R11
|
||||
RET
|
||||
|
||||
TEXT x_cgo_setenv_trampoline(SB), NOSPLIT, $8
|
||||
MOVQ DI, AX
|
||||
MOVQ ·x_cgo_setenv_call(SB), R11
|
||||
MOVQ (R11), R11
|
||||
CALL R11
|
||||
RET
|
||||
|
||||
TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT, $8
|
||||
MOVQ DI, AX
|
||||
MOVQ ·x_cgo_unsetenv_call(SB), R11
|
||||
MOVQ (R11), R11
|
||||
CALL R11
|
||||
RET
|
||||
|
||||
TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT, $0
|
||||
JMP ·x_cgo_notify_runtime_init_done(SB)
|
||||
|
||||
TEXT x_cgo_bindm_trampoline(SB), NOSPLIT, $0
|
||||
JMP ·x_cgo_bindm(SB)
|
||||
|
||||
// func setg_trampoline(setg uintptr, g uintptr)
|
||||
TEXT ·setg_trampoline(SB), NOSPLIT, $0-16
|
||||
MOVQ G+8(FP), DI
|
||||
MOVQ setg+0(FP), R11
|
||||
XORL AX, AX
|
||||
CALL R11
|
||||
RET
|
||||
|
||||
TEXT threadentry_trampoline(SB), NOSPLIT, $0
|
||||
// See crosscall2.
|
||||
PUSH_REGS_HOST_TO_ABI0()
|
||||
|
||||
// X15 is designated by Go as a fixed zero register.
|
||||
// Calling directly into ABIInternal, ensure it is zero.
|
||||
PXOR X15, X15
|
||||
|
||||
MOVQ DI, AX
|
||||
MOVQ ·threadentry_call(SB), R11
|
||||
MOVQ (R11), R11
|
||||
CALL R11
|
||||
|
||||
POP_REGS_HOST_TO_ABI0()
|
||||
RET
|
||||
|
||||
TEXT ·call5(SB), NOSPLIT, $0-56
|
||||
MOVQ fn+0(FP), R11
|
||||
MOVQ a1+8(FP), DI
|
||||
MOVQ a2+16(FP), SI
|
||||
MOVQ a3+24(FP), DX
|
||||
MOVQ a4+32(FP), CX
|
||||
MOVQ a5+40(FP), R8
|
||||
|
||||
XORL AX, AX // no floats
|
||||
|
||||
PUSHQ BP // save BP
|
||||
MOVQ SP, BP // save SP inside BP bc BP is callee-saved
|
||||
SUBQ $16, SP // allocate space for alignment
|
||||
ANDQ $-16, SP // align on 16 bytes for SSE
|
||||
|
||||
CALL R11
|
||||
|
||||
MOVQ BP, SP // get SP back
|
||||
POPQ BP // restore BP
|
||||
|
||||
MOVQ AX, ret+48(FP)
|
||||
RET
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (freebsd || linux)
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
|
||||
// These trampolines map the gcc ABI to Go ABI0 and then call into the Go equivalent functions.
|
||||
// On ARM32, Go ABI0 uses stack-based calling convention.
|
||||
// Arguments are placed on the stack starting at 4(SP) after the prologue.
|
||||
|
||||
TEXT x_cgo_init_trampoline(SB), NOSPLIT, $8-0
|
||||
MOVW R0, 4(R13)
|
||||
MOVW R1, 8(R13)
|
||||
MOVW ·x_cgo_init_call(SB), R12
|
||||
MOVW (R12), R12
|
||||
CALL (R12)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT, $8-0
|
||||
MOVW R0, 4(R13)
|
||||
MOVW ·x_cgo_thread_start_call(SB), R12
|
||||
MOVW (R12), R12
|
||||
CALL (R12)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_setenv_trampoline(SB), NOSPLIT, $8-0
|
||||
MOVW R0, 4(R13)
|
||||
MOVW ·x_cgo_setenv_call(SB), R12
|
||||
MOVW (R12), R12
|
||||
CALL (R12)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT, $8-0
|
||||
MOVW R0, 4(R13)
|
||||
MOVW ·x_cgo_unsetenv_call(SB), R12
|
||||
MOVW (R12), R12
|
||||
CALL (R12)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT, $0-0
|
||||
CALL ·x_cgo_notify_runtime_init_done(SB)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_bindm_trampoline(SB), NOSPLIT, $0
|
||||
CALL ·x_cgo_bindm(SB)
|
||||
RET
|
||||
|
||||
// func setg_trampoline(setg uintptr, g uintptr)
|
||||
TEXT ·setg_trampoline(SB), NOSPLIT, $0-8
|
||||
MOVW G+4(FP), R0
|
||||
MOVW setg+0(FP), R12
|
||||
BL (R12)
|
||||
RET
|
||||
|
||||
TEXT threadentry_trampoline(SB), NOSPLIT, $8-0
|
||||
// See crosscall2.
|
||||
MOVW R0, 4(R13)
|
||||
MOVW ·threadentry_call(SB), R12
|
||||
MOVW (R12), R12
|
||||
CALL (R12)
|
||||
RET
|
||||
|
||||
TEXT ·call5(SB), NOSPLIT, $8-28
|
||||
MOVW fn+0(FP), R12
|
||||
MOVW a1+4(FP), R0
|
||||
MOVW a2+8(FP), R1
|
||||
MOVW a3+12(FP), R2
|
||||
MOVW a4+16(FP), R3
|
||||
MOVW a5+20(FP), R4
|
||||
|
||||
// Store 5th arg below SP (in local frame area)
|
||||
MOVW R4, arg5-8(SP)
|
||||
|
||||
// Align SP to 8 bytes for call (required by ARM AAPCS)
|
||||
SUB $8, R13
|
||||
CALL (R12)
|
||||
ADD $8, R13
|
||||
MOVW R0, r1+24(FP)
|
||||
RET
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux)
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
#include "abi_arm64.h"
|
||||
|
||||
// These trampolines map the gcc ABI to Go ABIInternal and then calls into the Go equivalent functions.
|
||||
// Note that C arguments are passed in R0-R7, which matches Go ABIInternal for the first eight arguments.
|
||||
// R9 is used as a temporary register.
|
||||
|
||||
TEXT x_cgo_init_trampoline(SB), NOSPLIT, $0-0
|
||||
MOVD ·x_cgo_init_call(SB), R9
|
||||
MOVD (R9), R9
|
||||
CALL R9
|
||||
RET
|
||||
|
||||
TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT, $0-0
|
||||
MOVD ·x_cgo_thread_start_call(SB), R9
|
||||
MOVD (R9), R9
|
||||
CALL R9
|
||||
RET
|
||||
|
||||
TEXT x_cgo_setenv_trampoline(SB), NOSPLIT, $0-0
|
||||
MOVD ·x_cgo_setenv_call(SB), R9
|
||||
MOVD (R9), R9
|
||||
CALL R9
|
||||
RET
|
||||
|
||||
TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT, $0-0
|
||||
MOVD ·x_cgo_unsetenv_call(SB), R9
|
||||
MOVD (R9), R9
|
||||
CALL R9
|
||||
RET
|
||||
|
||||
TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT, $0-0
|
||||
CALL ·x_cgo_notify_runtime_init_done(SB)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_bindm_trampoline(SB), NOSPLIT, $0
|
||||
CALL ·x_cgo_bindm(SB)
|
||||
RET
|
||||
|
||||
// func setg_trampoline(setg uintptr, g uintptr)
|
||||
TEXT ·setg_trampoline(SB), NOSPLIT, $0-16
|
||||
MOVD G+8(FP), R0
|
||||
MOVD setg+0(FP), R9
|
||||
CALL R9
|
||||
RET
|
||||
|
||||
TEXT threadentry_trampoline(SB), NOSPLIT, $0-0
|
||||
// See crosscall2.
|
||||
SUB $(8*24), RSP
|
||||
STP (R0, R1), (8*1)(RSP)
|
||||
MOVD R3, (8*3)(RSP)
|
||||
|
||||
SAVE_R19_TO_R28(8*4)
|
||||
SAVE_F8_TO_F15(8*14)
|
||||
STP (R29, R30), (8*22)(RSP)
|
||||
|
||||
MOVD ·threadentry_call(SB), R9
|
||||
MOVD (R9), R9
|
||||
CALL R9
|
||||
MOVD $0, R0 // TODO: get the return value from threadentry
|
||||
|
||||
RESTORE_R19_TO_R28(8*4)
|
||||
RESTORE_F8_TO_F15(8*14)
|
||||
LDP (8*22)(RSP), (R29, R30)
|
||||
|
||||
ADD $(8*24), RSP
|
||||
RET
|
||||
|
||||
TEXT ·call5(SB), NOSPLIT, $0-0
|
||||
MOVD fn+0(FP), R9
|
||||
MOVD a1+8(FP), R0
|
||||
MOVD a2+16(FP), R1
|
||||
MOVD a3+24(FP), R2
|
||||
MOVD a4+32(FP), R3
|
||||
MOVD a5+40(FP), R4
|
||||
CALL R9
|
||||
MOVD R0, ret+48(FP)
|
||||
RET
|
||||
Generated
Vendored
+88
@@ -0,0 +1,88 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2025 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && linux
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
#include "abi_loong64.h"
|
||||
|
||||
// these trampolines map the gcc ABI to Go ABI and then calls into the Go equivalent functions.
|
||||
// R23 is used as temporary register.
|
||||
|
||||
TEXT x_cgo_init_trampoline(SB), NOSPLIT, $16
|
||||
MOVV R4, 8(R3)
|
||||
MOVV R5, 16(R3)
|
||||
MOVV ·x_cgo_init_call(SB), R23
|
||||
MOVV (R23), R23
|
||||
CALL (R23)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT, $8
|
||||
MOVV R4, 8(R3)
|
||||
MOVV ·x_cgo_thread_start_call(SB), R23
|
||||
MOVV (R23), R23
|
||||
CALL (R23)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_setenv_trampoline(SB), NOSPLIT, $8
|
||||
MOVV R4, 8(R3)
|
||||
MOVV ·x_cgo_setenv_call(SB), R23
|
||||
MOVV (R23), R23
|
||||
CALL (R23)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT, $8
|
||||
MOVV R4, 8(R3)
|
||||
MOVV ·x_cgo_unsetenv_call(SB), R23
|
||||
MOVV (R23), R23
|
||||
CALL (R23)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT, $0
|
||||
CALL ·x_cgo_notify_runtime_init_done(SB)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_bindm_trampoline(SB), NOSPLIT, $0
|
||||
CALL ·x_cgo_bindm(SB)
|
||||
RET
|
||||
|
||||
// func setg_trampoline(setg uintptr, g uintptr)
|
||||
TEXT ·setg_trampoline(SB), NOSPLIT, $0
|
||||
MOVV G+8(FP), R4
|
||||
MOVV setg+0(FP), R23
|
||||
CALL (R23)
|
||||
RET
|
||||
|
||||
TEXT threadentry_trampoline(SB), NOSPLIT, $0
|
||||
// See crosscall2.
|
||||
ADDV $(-23*8), R3
|
||||
MOVV R4, (1*8)(R3) // fn unsafe.Pointer
|
||||
MOVV R5, (2*8)(R3) // a unsafe.Pointer
|
||||
MOVV R7, (3*8)(R3) // ctxt uintptr
|
||||
|
||||
SAVE_R22_TO_R31((4*8))
|
||||
SAVE_F24_TO_F31((14*8))
|
||||
MOVV R1, (22*8)(R3)
|
||||
|
||||
MOVV ·threadentry_call(SB), R23
|
||||
MOVV (R23), R23
|
||||
CALL (R23)
|
||||
|
||||
RESTORE_R22_TO_R31((4*8))
|
||||
RESTORE_F24_TO_F31((14*8))
|
||||
MOVV (22*8)(R3), R1
|
||||
|
||||
ADDV $(23*8), R3
|
||||
RET
|
||||
|
||||
TEXT ·call5(SB), NOSPLIT, $0-0
|
||||
MOVV fn+0(FP), R23
|
||||
MOVV a1+8(FP), R4
|
||||
MOVV a2+16(FP), R5
|
||||
MOVV a3+24(FP), R6
|
||||
MOVV a4+32(FP), R7
|
||||
MOVV a5+40(FP), R8
|
||||
CALL (R23)
|
||||
MOVV R4, ret+48(FP)
|
||||
RET
|
||||
Generated
Vendored
+227
@@ -0,0 +1,227 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && linux
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
|
||||
// These trampolines map the C ABI to Go ABI and call into the Go equivalent functions.
|
||||
//
|
||||
// PPC64LE ELFv2 ABI stack frame layout:
|
||||
// 0(R1) = backchain (pointer to caller's frame)
|
||||
// 8(R1) = CR save area
|
||||
// 16(R1) = LR save area
|
||||
// 24(R1) = reserved
|
||||
// 32(R1) = parameter save area (minimum 64 bytes for 8 args)
|
||||
//
|
||||
// Two patterns are used depending on call direction:
|
||||
//
|
||||
// C→Go trampolines: The C caller already provides a 32-byte linkage area.
|
||||
// Save LR/CR into caller's frame at 16(R1)/8(R1) BEFORE allocating,
|
||||
// then use MOVDU to allocate and set backchain atomically.
|
||||
//
|
||||
// Go→C trampolines: Go callers don't provide ELFv2 linkage area.
|
||||
// Allocate frame first with MOVDU, then save LR/CR into OUR frame.
|
||||
|
||||
TEXT x_cgo_init_trampoline(SB), NOSPLIT|NOFRAME, $0-0
|
||||
MOVD LR, 16(R1)
|
||||
MOVW CR, R0
|
||||
MOVD R0, 8(R1)
|
||||
|
||||
MOVDU R1, -32(R1)
|
||||
|
||||
// R3, R4 already have the arguments
|
||||
MOVD ·x_cgo_init_call(SB), R12
|
||||
MOVD (R12), R12
|
||||
MOVD R12, CTR
|
||||
CALL CTR
|
||||
|
||||
ADD $32, R1
|
||||
|
||||
MOVD 16(R1), LR
|
||||
MOVD 8(R1), R0
|
||||
MOVW R0, CR
|
||||
RET
|
||||
|
||||
TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT|NOFRAME, $0-0
|
||||
MOVD LR, 16(R1)
|
||||
MOVW CR, R0
|
||||
MOVD R0, 8(R1)
|
||||
|
||||
MOVDU R1, -32(R1)
|
||||
|
||||
MOVD ·x_cgo_thread_start_call(SB), R12
|
||||
MOVD (R12), R12
|
||||
MOVD R12, CTR
|
||||
CALL CTR
|
||||
|
||||
ADD $32, R1
|
||||
|
||||
MOVD 16(R1), LR
|
||||
MOVD 8(R1), R0
|
||||
MOVW R0, CR
|
||||
RET
|
||||
|
||||
// void (*_cgo_setenv)(char**)
|
||||
// C arg: R3 = pointer to env
|
||||
// This is C→Go: caller is C ABI.
|
||||
TEXT x_cgo_setenv_trampoline(SB), NOSPLIT|NOFRAME, $0-0
|
||||
MOVD LR, 16(R1)
|
||||
MOVW CR, R0
|
||||
MOVD R0, 8(R1)
|
||||
|
||||
MOVDU R1, -32(R1)
|
||||
|
||||
MOVD ·x_cgo_setenv_call(SB), R12
|
||||
MOVD (R12), R12
|
||||
MOVD R12, CTR
|
||||
CALL CTR
|
||||
|
||||
ADD $32, R1
|
||||
|
||||
MOVD 16(R1), LR
|
||||
MOVD 8(R1), R0
|
||||
MOVW R0, CR
|
||||
RET
|
||||
|
||||
TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT|NOFRAME, $0-0
|
||||
MOVD LR, 16(R1)
|
||||
MOVW CR, R0
|
||||
MOVD R0, 8(R1)
|
||||
|
||||
MOVDU R1, -32(R1)
|
||||
|
||||
MOVD ·x_cgo_unsetenv_call(SB), R12
|
||||
MOVD (R12), R12
|
||||
MOVD R12, CTR
|
||||
CALL CTR
|
||||
|
||||
ADD $32, R1
|
||||
|
||||
MOVD 16(R1), LR
|
||||
MOVD 8(R1), R0
|
||||
MOVW R0, CR
|
||||
RET
|
||||
|
||||
TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT|NOFRAME, $0-0
|
||||
MOVD LR, 16(R1)
|
||||
MOVW CR, R0
|
||||
MOVD R0, 8(R1)
|
||||
|
||||
MOVDU R1, -32(R1)
|
||||
|
||||
CALL ·x_cgo_notify_runtime_init_done(SB)
|
||||
|
||||
ADD $32, R1
|
||||
|
||||
MOVD 16(R1), LR
|
||||
MOVD 8(R1), R0
|
||||
MOVW R0, CR
|
||||
RET
|
||||
|
||||
TEXT x_cgo_bindm_trampoline(SB), NOSPLIT|NOFRAME, $0-0
|
||||
MOVD LR, 16(R1)
|
||||
MOVW CR, R0
|
||||
MOVD R0, 8(R1)
|
||||
|
||||
MOVDU R1, -32(R1)
|
||||
|
||||
CALL ·x_cgo_bindm(SB)
|
||||
|
||||
ADD $32, R1
|
||||
|
||||
MOVD 16(R1), LR
|
||||
MOVD 8(R1), R0
|
||||
MOVW R0, CR
|
||||
RET
|
||||
|
||||
TEXT ·setg_trampoline(SB), NOSPLIT|NOFRAME, $0-16
|
||||
// Save LR, CR, and R31 to non-volatile registers (C ABI preserves R14-R31)
|
||||
MOVD LR, R20
|
||||
MOVW CR, R21
|
||||
MOVD R31, R22 // save R31 because load_g clobbers it
|
||||
|
||||
// Load arguments from Go stack
|
||||
MOVD 32(R1), R12 // setg function pointer
|
||||
MOVD 40(R1), R3 // g pointer → first C arg
|
||||
|
||||
// Allocate ELFv2 frame for the C callee (32 bytes minimum)
|
||||
MOVDU R1, -32(R1)
|
||||
|
||||
// Call setg_gcc which stores g to TLS
|
||||
MOVD R12, CTR
|
||||
CALL CTR
|
||||
|
||||
// setg_gcc stored g to TLS but restored old g in R30.
|
||||
// Call load_g to reload g from TLS into R30.
|
||||
// Note: load_g clobbers R31
|
||||
CALL runtime·load_g(SB)
|
||||
|
||||
// Deallocate frame
|
||||
ADD $32, R1
|
||||
|
||||
// Clear R0 before returning to Go code.
|
||||
// Go uses R0 as a constant 0 for things like "std r0,X(r1)" to zero stack locations.
|
||||
// C/assembly functions may leave garbage in R0.
|
||||
XOR R0, R0, R0
|
||||
|
||||
// Restore LR, CR, and R31 from non-volatile registers
|
||||
MOVD R22, R31 // restore R31
|
||||
MOVD R20, LR
|
||||
MOVW R21, CR
|
||||
RET
|
||||
|
||||
TEXT threadentry_trampoline(SB), NOSPLIT|NOFRAME, $0-0
|
||||
MOVD LR, 16(R1)
|
||||
MOVW CR, R0
|
||||
MOVD R0, 8(R1)
|
||||
|
||||
MOVDU R1, -32(R1)
|
||||
|
||||
MOVD ·threadentry_call(SB), R12
|
||||
MOVD (R12), R12
|
||||
MOVD R12, CTR
|
||||
CALL CTR
|
||||
|
||||
ADD $32, R1
|
||||
|
||||
MOVD 16(R1), LR
|
||||
MOVD 8(R1), R0
|
||||
MOVW R0, CR
|
||||
RET
|
||||
|
||||
TEXT ·call5(SB), NOSPLIT|NOFRAME, $0-56
|
||||
MOVD LR, R20
|
||||
MOVW CR, R21
|
||||
|
||||
// Load arguments from Go stack into C argument registers
|
||||
// Go placed args at 32(R1), 40(R1), etc.
|
||||
MOVD 32(R1), R12 // fn
|
||||
MOVD 40(R1), R3 // a1 → first C arg
|
||||
MOVD 48(R1), R4 // a2 → second C arg
|
||||
MOVD 56(R1), R5 // a3 → third C arg
|
||||
MOVD 64(R1), R6 // a4 → fourth C arg
|
||||
MOVD 72(R1), R7 // a5 → fifth C arg
|
||||
|
||||
MOVDU R1, -32(R1)
|
||||
|
||||
MOVD R12, CTR
|
||||
CALL CTR
|
||||
|
||||
// Store return value
|
||||
// After MOVDU -32, original 80(R1) is now at 80+32=112(R1)
|
||||
MOVD R3, (80+32)(R1)
|
||||
|
||||
// Deallocate frame
|
||||
ADD $32, R1
|
||||
|
||||
// Clear R0 before returning to Go code.
|
||||
// Go uses R0 as a constant 0 register for things like "std r0,X(r1)"
|
||||
// to zero stack locations. C functions may leave garbage in R0.
|
||||
XOR R0, R0, R0
|
||||
|
||||
// Restore LR/CR from non-volatile registers
|
||||
MOVD R20, LR
|
||||
MOVW R21, CR
|
||||
RET
|
||||
Generated
Vendored
+72
@@ -0,0 +1,72 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2026 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && linux
|
||||
|
||||
#include "textflag.h"
|
||||
#include "go_asm.h"
|
||||
|
||||
// these trampolines map the gcc ABI to Go ABI and then calls into the Go equivalent functions.
|
||||
// X5 is used as temporary register.
|
||||
|
||||
TEXT x_cgo_init_trampoline(SB), NOSPLIT, $16
|
||||
MOV X10, 8(SP)
|
||||
MOV X11, 16(SP)
|
||||
MOV ·x_cgo_init_call(SB), X5
|
||||
MOV (X5), X5
|
||||
CALL X5
|
||||
RET
|
||||
|
||||
TEXT x_cgo_thread_start_trampoline(SB), NOSPLIT, $8
|
||||
MOV X10, 8(SP)
|
||||
MOV ·x_cgo_thread_start_call(SB), X5
|
||||
MOV (X5), X5
|
||||
CALL X5
|
||||
RET
|
||||
|
||||
TEXT x_cgo_setenv_trampoline(SB), NOSPLIT, $8
|
||||
MOV X10, 8(SP)
|
||||
MOV ·x_cgo_setenv_call(SB), X5
|
||||
MOV (X5), X5
|
||||
CALL X5
|
||||
RET
|
||||
|
||||
TEXT x_cgo_unsetenv_trampoline(SB), NOSPLIT, $8
|
||||
MOV X10, 8(SP)
|
||||
MOV ·x_cgo_unsetenv_call(SB), X5
|
||||
MOV (X5), X5
|
||||
CALL X5
|
||||
RET
|
||||
|
||||
TEXT x_cgo_notify_runtime_init_done_trampoline(SB), NOSPLIT, $0
|
||||
CALL ·x_cgo_notify_runtime_init_done(SB)
|
||||
RET
|
||||
|
||||
TEXT x_cgo_bindm_trampoline(SB), NOSPLIT, $0
|
||||
CALL ·x_cgo_bindm(SB)
|
||||
RET
|
||||
|
||||
// func setg_trampoline(setg uintptr, g uintptr)
|
||||
TEXT ·setg_trampoline(SB), NOSPLIT, $0
|
||||
MOV gp+8(FP), X10
|
||||
MOV setg+0(FP), X5
|
||||
CALL X5
|
||||
RET
|
||||
|
||||
TEXT threadentry_trampoline(SB), NOSPLIT, $16
|
||||
MOV X10, 8(SP)
|
||||
MOV ·threadentry_call(SB), X5
|
||||
MOV (X5), X5
|
||||
CALL X5
|
||||
RET
|
||||
|
||||
TEXT ·call5(SB), NOSPLIT, $0-48
|
||||
MOV fn+0(FP), X5
|
||||
MOV a1+8(FP), X10
|
||||
MOV a2+16(FP), X11
|
||||
MOV a3+24(FP), X12
|
||||
MOV a4+32(FP), X13
|
||||
MOV a5+40(FP), X14
|
||||
CALL X5
|
||||
MOV X10, ret+48(FP)
|
||||
RET
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
// Code generated by 'go generate' with gen.go. DO NOT EDIT.
|
||||
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
package fakecgo
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func malloc(size uintptr) unsafe.Pointer {
|
||||
ret := call5(mallocABI0, uintptr(size), 0, 0, 0, 0)
|
||||
// this indirection is to avoid go vet complaining about possible misuse of unsafe.Pointer
|
||||
return *(*unsafe.Pointer)(unsafe.Pointer(&ret))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func free(ptr unsafe.Pointer) {
|
||||
call5(freeABI0, uintptr(ptr), 0, 0, 0, 0)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func setenv(name *byte, value *byte, overwrite int32) int32 {
|
||||
return int32(call5(setenvABI0, uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(value)), uintptr(overwrite), 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func unsetenv(name *byte) int32 {
|
||||
return int32(call5(unsetenvABI0, uintptr(unsafe.Pointer(name)), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func sigfillset(set *sigset_t) int32 {
|
||||
return int32(call5(sigfillsetABI0, uintptr(unsafe.Pointer(set)), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func nanosleep(ts *syscall.Timespec, rem *syscall.Timespec) int32 {
|
||||
return int32(call5(nanosleepABI0, uintptr(unsafe.Pointer(ts)), uintptr(unsafe.Pointer(rem)), 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func abort() {
|
||||
call5(abortABI0, 0, 0, 0, 0, 0)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_attr_init(attr *pthread_attr_t) int32 {
|
||||
return int32(call5(pthread_attr_initABI0, uintptr(unsafe.Pointer(attr)), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_create(thread *pthread_t, attr *pthread_attr_t, start unsafe.Pointer, arg unsafe.Pointer) int32 {
|
||||
return int32(call5(pthread_createABI0, uintptr(unsafe.Pointer(thread)), uintptr(unsafe.Pointer(attr)), uintptr(start), uintptr(arg), 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_detach(thread pthread_t) int32 {
|
||||
return int32(call5(pthread_detachABI0, uintptr(thread), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_sigmask(how sighow, ign *sigset_t, oset *sigset_t) int32 {
|
||||
return int32(call5(pthread_sigmaskABI0, uintptr(how), uintptr(unsafe.Pointer(ign)), uintptr(unsafe.Pointer(oset)), 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_mutex_lock(mutex *pthread_mutex_t) int32 {
|
||||
return int32(call5(pthread_mutex_lockABI0, uintptr(unsafe.Pointer(mutex)), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_mutex_unlock(mutex *pthread_mutex_t) int32 {
|
||||
return int32(call5(pthread_mutex_unlockABI0, uintptr(unsafe.Pointer(mutex)), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_cond_broadcast(cond *pthread_cond_t) int32 {
|
||||
return int32(call5(pthread_cond_broadcastABI0, uintptr(unsafe.Pointer(cond)), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_setspecific(key pthread_key_t, value unsafe.Pointer) int32 {
|
||||
return int32(call5(pthread_setspecificABI0, uintptr(key), uintptr(value), 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:linkname _malloc _malloc
|
||||
var _malloc uint8
|
||||
var mallocABI0 = uintptr(unsafe.Pointer(&_malloc))
|
||||
|
||||
//go:linkname _free _free
|
||||
var _free uint8
|
||||
var freeABI0 = uintptr(unsafe.Pointer(&_free))
|
||||
|
||||
//go:linkname _setenv _setenv
|
||||
var _setenv uint8
|
||||
var setenvABI0 = uintptr(unsafe.Pointer(&_setenv))
|
||||
|
||||
//go:linkname _unsetenv _unsetenv
|
||||
var _unsetenv uint8
|
||||
var unsetenvABI0 = uintptr(unsafe.Pointer(&_unsetenv))
|
||||
|
||||
//go:linkname _sigfillset _sigfillset
|
||||
var _sigfillset uint8
|
||||
var sigfillsetABI0 = uintptr(unsafe.Pointer(&_sigfillset))
|
||||
|
||||
//go:linkname _nanosleep _nanosleep
|
||||
var _nanosleep uint8
|
||||
var nanosleepABI0 = uintptr(unsafe.Pointer(&_nanosleep))
|
||||
|
||||
//go:linkname _abort _abort
|
||||
var _abort uint8
|
||||
var abortABI0 = uintptr(unsafe.Pointer(&_abort))
|
||||
|
||||
//go:linkname _pthread_attr_init _pthread_attr_init
|
||||
var _pthread_attr_init uint8
|
||||
var pthread_attr_initABI0 = uintptr(unsafe.Pointer(&_pthread_attr_init))
|
||||
|
||||
//go:linkname _pthread_create _pthread_create
|
||||
var _pthread_create uint8
|
||||
var pthread_createABI0 = uintptr(unsafe.Pointer(&_pthread_create))
|
||||
|
||||
//go:linkname _pthread_detach _pthread_detach
|
||||
var _pthread_detach uint8
|
||||
var pthread_detachABI0 = uintptr(unsafe.Pointer(&_pthread_detach))
|
||||
|
||||
//go:linkname _pthread_sigmask _pthread_sigmask
|
||||
var _pthread_sigmask uint8
|
||||
var pthread_sigmaskABI0 = uintptr(unsafe.Pointer(&_pthread_sigmask))
|
||||
|
||||
//go:linkname _pthread_mutex_lock _pthread_mutex_lock
|
||||
var _pthread_mutex_lock uint8
|
||||
var pthread_mutex_lockABI0 = uintptr(unsafe.Pointer(&_pthread_mutex_lock))
|
||||
|
||||
//go:linkname _pthread_mutex_unlock _pthread_mutex_unlock
|
||||
var _pthread_mutex_unlock uint8
|
||||
var pthread_mutex_unlockABI0 = uintptr(unsafe.Pointer(&_pthread_mutex_unlock))
|
||||
|
||||
//go:linkname _pthread_cond_broadcast _pthread_cond_broadcast
|
||||
var _pthread_cond_broadcast uint8
|
||||
var pthread_cond_broadcastABI0 = uintptr(unsafe.Pointer(&_pthread_cond_broadcast))
|
||||
|
||||
//go:linkname _pthread_setspecific _pthread_setspecific
|
||||
var _pthread_setspecific uint8
|
||||
var pthread_setspecificABI0 = uintptr(unsafe.Pointer(&_pthread_setspecific))
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
// Code generated by 'go generate' with gen.go. DO NOT EDIT.
|
||||
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
package fakecgo
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//go:cgo_import_dynamic purego_malloc malloc "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_free free "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_setenv setenv "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_unsetenv unsetenv "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_sigfillset sigfillset "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_nanosleep nanosleep "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_abort abort "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_init pthread_attr_init "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_create pthread_create "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_detach pthread_detach "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_sigmask pthread_sigmask "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_mutex_lock pthread_mutex_lock "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_mutex_unlock pthread_mutex_unlock "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_cond_broadcast pthread_cond_broadcast "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_setspecific pthread_setspecific "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_self pthread_self "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_get_stacksize_np pthread_get_stacksize_np "/usr/lib/libSystem.B.dylib"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_setstacksize pthread_attr_setstacksize "/usr/lib/libSystem.B.dylib"
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_self() pthread_t {
|
||||
return pthread_t(call5(pthread_selfABI0, 0, 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_get_stacksize_np(thread pthread_t) size_t {
|
||||
return size_t(call5(pthread_get_stacksize_npABI0, uintptr(thread), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_attr_setstacksize(attr *pthread_attr_t, size size_t) int32 {
|
||||
return int32(call5(pthread_attr_setstacksizeABI0, uintptr(unsafe.Pointer(attr)), uintptr(size), 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:linkname _pthread_self _pthread_self
|
||||
var _pthread_self uint8
|
||||
var pthread_selfABI0 = uintptr(unsafe.Pointer(&_pthread_self))
|
||||
|
||||
//go:linkname _pthread_get_stacksize_np _pthread_get_stacksize_np
|
||||
var _pthread_get_stacksize_np uint8
|
||||
var pthread_get_stacksize_npABI0 = uintptr(unsafe.Pointer(&_pthread_get_stacksize_np))
|
||||
|
||||
//go:linkname _pthread_attr_setstacksize _pthread_attr_setstacksize
|
||||
var _pthread_attr_setstacksize uint8
|
||||
var pthread_attr_setstacksizeABI0 = uintptr(unsafe.Pointer(&_pthread_attr_setstacksize))
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
// Code generated by 'go generate' with gen.go. DO NOT EDIT.
|
||||
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
package fakecgo
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//go:cgo_import_dynamic purego_malloc malloc "libc.so.7"
|
||||
//go:cgo_import_dynamic purego_free free "libc.so.7"
|
||||
//go:cgo_import_dynamic purego_setenv setenv "libc.so.7"
|
||||
//go:cgo_import_dynamic purego_unsetenv unsetenv "libc.so.7"
|
||||
//go:cgo_import_dynamic purego_sigfillset sigfillset "libc.so.7"
|
||||
//go:cgo_import_dynamic purego_nanosleep nanosleep "libc.so.7"
|
||||
//go:cgo_import_dynamic purego_abort abort "libc.so.7"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_init pthread_attr_init "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_create pthread_create "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_detach pthread_detach "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_sigmask pthread_sigmask "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_mutex_lock pthread_mutex_lock "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_mutex_unlock pthread_mutex_unlock "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_cond_broadcast pthread_cond_broadcast "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_setspecific pthread_setspecific "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_getstacksize pthread_attr_getstacksize "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_destroy pthread_attr_destroy "libpthread.so"
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_attr_getstacksize(attr *pthread_attr_t, stacksize *size_t) int32 {
|
||||
return int32(call5(pthread_attr_getstacksizeABI0, uintptr(unsafe.Pointer(attr)), uintptr(unsafe.Pointer(stacksize)), 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_attr_destroy(attr *pthread_attr_t) int32 {
|
||||
return int32(call5(pthread_attr_destroyABI0, uintptr(unsafe.Pointer(attr)), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:linkname _pthread_attr_getstacksize _pthread_attr_getstacksize
|
||||
var _pthread_attr_getstacksize uint8
|
||||
var pthread_attr_getstacksizeABI0 = uintptr(unsafe.Pointer(&_pthread_attr_getstacksize))
|
||||
|
||||
//go:linkname _pthread_attr_destroy _pthread_attr_destroy
|
||||
var _pthread_attr_destroy uint8
|
||||
var pthread_attr_destroyABI0 = uintptr(unsafe.Pointer(&_pthread_attr_destroy))
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
// Code generated by 'go generate' with gen.go. DO NOT EDIT.
|
||||
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
package fakecgo
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//go:cgo_import_dynamic purego_malloc malloc "libc.so.6"
|
||||
//go:cgo_import_dynamic purego_free free "libc.so.6"
|
||||
//go:cgo_import_dynamic purego_setenv setenv "libc.so.6"
|
||||
//go:cgo_import_dynamic purego_unsetenv unsetenv "libc.so.6"
|
||||
//go:cgo_import_dynamic purego_sigfillset sigfillset "libc.so.6"
|
||||
//go:cgo_import_dynamic purego_nanosleep nanosleep "libc.so.6"
|
||||
//go:cgo_import_dynamic purego_abort abort "libc.so.6"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_init pthread_attr_init "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_create pthread_create "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_detach pthread_detach "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_sigmask pthread_sigmask "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_mutex_lock pthread_mutex_lock "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_mutex_unlock pthread_mutex_unlock "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_cond_broadcast pthread_cond_broadcast "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_setspecific pthread_setspecific "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_getstacksize pthread_attr_getstacksize "libpthread.so.0"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_destroy pthread_attr_destroy "libpthread.so.0"
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_attr_getstacksize(attr *pthread_attr_t, stacksize *size_t) int32 {
|
||||
return int32(call5(pthread_attr_getstacksizeABI0, uintptr(unsafe.Pointer(attr)), uintptr(unsafe.Pointer(stacksize)), 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_attr_destroy(attr *pthread_attr_t) int32 {
|
||||
return int32(call5(pthread_attr_destroyABI0, uintptr(unsafe.Pointer(attr)), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:linkname _pthread_attr_getstacksize _pthread_attr_getstacksize
|
||||
var _pthread_attr_getstacksize uint8
|
||||
var pthread_attr_getstacksizeABI0 = uintptr(unsafe.Pointer(&_pthread_attr_getstacksize))
|
||||
|
||||
//go:linkname _pthread_attr_destroy _pthread_attr_destroy
|
||||
var _pthread_attr_destroy uint8
|
||||
var pthread_attr_destroyABI0 = uintptr(unsafe.Pointer(&_pthread_attr_destroy))
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
// Code generated by 'go generate' with gen.go. DO NOT EDIT.
|
||||
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
package fakecgo
|
||||
|
||||
import "unsafe"
|
||||
|
||||
//go:cgo_import_dynamic purego_malloc malloc "libc.so"
|
||||
//go:cgo_import_dynamic purego_free free "libc.so"
|
||||
//go:cgo_import_dynamic purego_setenv setenv "libc.so"
|
||||
//go:cgo_import_dynamic purego_unsetenv unsetenv "libc.so"
|
||||
//go:cgo_import_dynamic purego_sigfillset sigfillset "libc.so"
|
||||
//go:cgo_import_dynamic purego_nanosleep nanosleep "libc.so"
|
||||
//go:cgo_import_dynamic purego_abort abort "libc.so"
|
||||
//go:cgo_import_dynamic purego_sigaltstack sigaltstack "libc.so"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_init pthread_attr_init "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_create pthread_create "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_detach pthread_detach "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_sigmask pthread_sigmask "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_mutex_lock pthread_mutex_lock "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_mutex_unlock pthread_mutex_unlock "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_cond_broadcast pthread_cond_broadcast "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_setspecific pthread_setspecific "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_getstacksize pthread_attr_getstacksize "libpthread.so"
|
||||
//go:cgo_import_dynamic purego_pthread_attr_destroy pthread_attr_destroy "libpthread.so"
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func sigaltstack(ss *stack_t, old_ss *stack_t) int32 {
|
||||
return int32(call5(sigaltstackABI0, uintptr(unsafe.Pointer(ss)), uintptr(unsafe.Pointer(old_ss)), 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_attr_getstacksize(attr *pthread_attr_t, stacksize *size_t) int32 {
|
||||
return int32(call5(pthread_attr_getstacksizeABI0, uintptr(unsafe.Pointer(attr)), uintptr(unsafe.Pointer(stacksize)), 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
//go:norace
|
||||
func pthread_attr_destroy(attr *pthread_attr_t) int32 {
|
||||
return int32(call5(pthread_attr_destroyABI0, uintptr(unsafe.Pointer(attr)), 0, 0, 0, 0))
|
||||
}
|
||||
|
||||
//go:linkname _sigaltstack _sigaltstack
|
||||
var _sigaltstack uint8
|
||||
var sigaltstackABI0 = uintptr(unsafe.Pointer(&_sigaltstack))
|
||||
|
||||
//go:linkname _pthread_attr_getstacksize _pthread_attr_getstacksize
|
||||
var _pthread_attr_getstacksize uint8
|
||||
var pthread_attr_getstacksizeABI0 = uintptr(unsafe.Pointer(&_pthread_attr_getstacksize))
|
||||
|
||||
//go:linkname _pthread_attr_destroy _pthread_attr_destroy
|
||||
var _pthread_attr_destroy uint8
|
||||
var pthread_attr_destroyABI0 = uintptr(unsafe.Pointer(&_pthread_attr_destroy))
|
||||
Generated
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
// Code generated by 'go generate' with gen.go. DO NOT EDIT.
|
||||
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// these stubs are here because it is not possible to go:linkname directly the C functions
|
||||
|
||||
TEXT _pthread_self(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_self(SB)
|
||||
|
||||
TEXT _pthread_get_stacksize_np(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_get_stacksize_np(SB)
|
||||
|
||||
TEXT _pthread_attr_setstacksize(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_setstacksize(SB)
|
||||
Generated
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
// Code generated by 'go generate' with gen.go. DO NOT EDIT.
|
||||
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// these stubs are here because it is not possible to go:linkname directly the C functions
|
||||
|
||||
TEXT _pthread_attr_getstacksize(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_getstacksize(SB)
|
||||
|
||||
TEXT _pthread_attr_destroy(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_destroy(SB)
|
||||
Generated
Vendored
+16
@@ -0,0 +1,16 @@
|
||||
// Code generated by 'go generate' with gen.go. DO NOT EDIT.
|
||||
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// these stubs are here because it is not possible to go:linkname directly the C functions
|
||||
|
||||
TEXT _pthread_attr_getstacksize(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_getstacksize(SB)
|
||||
|
||||
TEXT _pthread_attr_destroy(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_destroy(SB)
|
||||
Generated
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
// Code generated by 'go generate' with gen.go. DO NOT EDIT.
|
||||
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// these stubs are here because it is not possible to go:linkname directly the C functions
|
||||
|
||||
TEXT _sigaltstack(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_sigaltstack(SB)
|
||||
|
||||
TEXT _pthread_attr_getstacksize(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_getstacksize(SB)
|
||||
|
||||
TEXT _pthread_attr_destroy(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_destroy(SB)
|
||||
Generated
Vendored
+55
@@ -0,0 +1,55 @@
|
||||
// Code generated by 'go generate' with gen.go. DO NOT EDIT.
|
||||
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// SPDX-FileCopyrightText: 2022 The Ebitengine Authors
|
||||
|
||||
//go:build !cgo && (darwin || freebsd || linux || netbsd)
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// these stubs are here because it is not possible to go:linkname directly the C functions
|
||||
|
||||
TEXT _malloc(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_malloc(SB)
|
||||
|
||||
TEXT _free(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_free(SB)
|
||||
|
||||
TEXT _setenv(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_setenv(SB)
|
||||
|
||||
TEXT _unsetenv(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_unsetenv(SB)
|
||||
|
||||
TEXT _sigfillset(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_sigfillset(SB)
|
||||
|
||||
TEXT _nanosleep(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_nanosleep(SB)
|
||||
|
||||
TEXT _abort(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_abort(SB)
|
||||
|
||||
TEXT _pthread_attr_init(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_attr_init(SB)
|
||||
|
||||
TEXT _pthread_create(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_create(SB)
|
||||
|
||||
TEXT _pthread_detach(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_detach(SB)
|
||||
|
||||
TEXT _pthread_sigmask(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_sigmask(SB)
|
||||
|
||||
TEXT _pthread_mutex_lock(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_mutex_lock(SB)
|
||||
|
||||
TEXT _pthread_mutex_unlock(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_mutex_unlock(SB)
|
||||
|
||||
TEXT _pthread_cond_broadcast(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_cond_broadcast(SB)
|
||||
|
||||
TEXT _pthread_setspecific(SB), NOSPLIT|NOFRAME, $0-0
|
||||
JMP purego_pthread_setspecific(SB)
|
||||
Reference in New Issue
Block a user