// 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" ); } }