mirror of git://gcc.gnu.org/git/gcc.git
87 lines
2.4 KiB
C
87 lines
2.4 KiB
C
// 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 "runtime.h"
|
|
#include "go-panic.h"
|
|
|
|
#ifdef __s390x__
|
|
# define S390_GO_USE_64_BIT_ABI 1
|
|
# define S390_GO_S390X_ARGS , double f4, double f6
|
|
# define S390_GO_S390X_FIELDS double f4; double f6;
|
|
extern void S390xMakeFuncStubGo(void *, void *)
|
|
asm ("reflect.S390xMakeFuncStubGo");
|
|
# define S390_GO_MakeFuncStubGo(r, c) S390xMakeFuncStubGo((r), (c))
|
|
#else
|
|
# define S390_GO_USE_64_BIT_ABI 0
|
|
# define S390_GO_S390X_ARGS
|
|
# define S390_GO_S390X_FIELDS
|
|
extern void S390MakeFuncStubGo(void *, void *)
|
|
asm ("reflect.S390MakeFuncStubGo");
|
|
# define S390_GO_MakeFuncStubGo(r, c) S390MakeFuncStubGo((r), (c))
|
|
/* Needed to make the unused 64 bit abi conditional code compile. */
|
|
# define f4 f0
|
|
# define f6 f2
|
|
#endif
|
|
|
|
/* Structure to store all registers used for parameter passing. */
|
|
typedef struct
|
|
{
|
|
long r2;
|
|
long r3;
|
|
long r4;
|
|
long r5;
|
|
long r6;
|
|
/* Pointer to non-register arguments on the stack. */
|
|
long stack_args;
|
|
double f0;
|
|
double f2;
|
|
S390_GO_S390X_FIELDS
|
|
} s390Regs;
|
|
|
|
void
|
|
makeFuncStub(long r2, long r3, long r4, long r5, long r6,
|
|
unsigned long stack_args, double f0, double f2
|
|
S390_GO_S390X_ARGS)
|
|
asm ("reflect.makeFuncStub");
|
|
|
|
void
|
|
makeFuncStub(long r2, long r3, long r4, long r5, long r6,
|
|
unsigned long stack_args, double f0, double f2
|
|
S390_GO_S390X_ARGS)
|
|
{
|
|
s390Regs regs;
|
|
void *closure;
|
|
|
|
/* Store the registers in a structure that is passed on to the Go stub
|
|
function. */
|
|
regs.r2 = r2;
|
|
regs.r3 = r3;
|
|
regs.r4 = r4;
|
|
regs.r5 = r5;
|
|
regs.r6 = r6;
|
|
regs.stack_args = (long)&stack_args;
|
|
regs.f0 = f0;
|
|
regs.f2 = f2;
|
|
if (S390_GO_USE_64_BIT_ABI) {
|
|
regs.f4 = f4;
|
|
regs.f6 = f6;
|
|
}
|
|
/* For MakeFunc functions that call recover. */
|
|
__go_makefunc_can_recover(__builtin_return_address(0));
|
|
/* Call the Go stub function. */
|
|
closure = __go_get_closure();
|
|
S390_GO_MakeFuncStubGo(®s, closure);
|
|
/* MakeFunc functions can no longer call recover. */
|
|
__go_makefunc_returning();
|
|
/* Restore all possible return registers. */
|
|
if (S390_GO_USE_64_BIT_ABI) {
|
|
asm volatile ("lg\t%%r2,0(%0)" : : "a" (®s.r2) : "r2" );
|
|
asm volatile ("ld\t%%f0,0(%0)" : : "a" (®s.f0) : "f0" );
|
|
} else {
|
|
asm volatile ("l\t%%r2,0(%0)" : : "a" (®s.r2) : "r2" );
|
|
asm volatile ("l\t%%r3,0(%0)" : : "a" (®s.r3) : "r3" );
|
|
asm volatile ("ld\t%%f0,0(%0)" : : "a" (®s.f0) : "f0" );
|
|
}
|
|
}
|