github.com/primecitizens/pcz/std@v0.2.1/core/reflect/call_s390x.s (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright 2023 The Prime Citizens
     3  //
     4  // Copyright 2018 The Go Authors. All rights reserved.
     5  // Use of this source code is governed by a BSD-style
     6  // license that can be found in the LICENSE file.
     7  
     8  //go:build pcz && s390x
     9  
    10  #include "textflag.h"
    11  #include "funcdata.h" // for NO_LOCAL_POINTERS
    12  
    13  // reflectcall: call a function with the given argument list
    14  // func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
    15  // we don't have variable-sized frames, so we use a small number
    16  // of constant-sized-frame functions to encode a few bits of size in the pc.
    17  // Caution: ugly multiline assembly macros in your future!
    18  
    19  #define DISPATCH(NAME,MAXSIZE)		\
    20  	MOVD $MAXSIZE, R4;		\
    21  	CMP R3, R4;		\
    22  	BGT 3(PC);			\
    23  	MOVD $NAME(SB), R5;	\
    24  	BR (R5)
    25  // Note: can't just "BR NAME(SB)" - bad inlining results.
    26  
    27  TEXT ·Call(SB), NOSPLIT, $-8-48
    28  	MOVWZ frameSize+32(FP), R3
    29  	DISPATCH(·call16, 16)
    30  	DISPATCH(·call32, 32)
    31  	DISPATCH(·call64, 64)
    32  	DISPATCH(·call128, 128)
    33  	DISPATCH(·call256, 256)
    34  	DISPATCH(·call512, 512)
    35  	DISPATCH(·call1024, 1024)
    36  	DISPATCH(·call2048, 2048)
    37  	DISPATCH(·call4096, 4096)
    38  	DISPATCH(·call8192, 8192)
    39  	DISPATCH(·call16384, 16384)
    40  	DISPATCH(·call32768, 32768)
    41  	DISPATCH(·call65536, 65536)
    42  	DISPATCH(·call131072, 131072)
    43  	DISPATCH(·call262144, 262144)
    44  	DISPATCH(·call524288, 524288)
    45  	DISPATCH(·call1048576, 1048576)
    46  	DISPATCH(·call2097152, 2097152)
    47  	DISPATCH(·call4194304, 4194304)
    48  	DISPATCH(·call8388608, 8388608)
    49  	DISPATCH(·call16777216, 16777216)
    50  	DISPATCH(·call33554432, 33554432)
    51  	DISPATCH(·call67108864, 67108864)
    52  	DISPATCH(·call134217728, 134217728)
    53  	DISPATCH(·call268435456, 268435456)
    54  	DISPATCH(·call536870912, 536870912)
    55  	DISPATCH(·call1073741824, 1073741824)
    56  	MOVD $·badreflectcall(SB), R5
    57  	BR (R5)
    58  
    59  #define CALLFN(NAME,MAXSIZE)			\
    60  TEXT NAME(SB), WRAPPER, $MAXSIZE-48;		\
    61  	NO_LOCAL_POINTERS;			\
    62  	/* copy arguments to stack */		\
    63  	MOVD stackArgs+16(FP), R4;			\
    64  	MOVWZ stackArgsSize+24(FP), R5;		\
    65  	MOVD $stack-MAXSIZE(SP), R6;		\
    66  loopArgs: /* copy 256 bytes at a time */	\
    67  	CMP R5, $256;			\
    68  	BLT tailArgs;			\
    69  	SUB $256, R5;			\
    70  	MVC $256, 0(R4), 0(R6);		\
    71  	MOVD $256(R4), R4;			\
    72  	MOVD $256(R6), R6;			\
    73  	BR loopArgs;			\
    74  tailArgs: /* copy remaining bytes */		\
    75  	CMP R5, $0;				\
    76  	BEQ callFunction;			\
    77  	SUB $1, R5;				\
    78  	EXRL $callfnMVC<>(SB), R5;		\
    79  callFunction:					\
    80  	MOVD f+8(FP), R12;			\
    81  	MOVD (R12), R8;			\
    82  	PCDATA  $PCDATA_StackMapIndex, $0;	\
    83  	BL (R8);				\
    84  	/* copy return values back */		\
    85  	MOVD stackArgsType+0(FP), R7;		\
    86  	MOVD stackArgs+16(FP), R6;			\
    87  	MOVWZ stackArgsSize+24(FP), R5;			\
    88  	MOVD $stack-MAXSIZE(SP), R4;		\
    89  	MOVWZ stackRetOffset+28(FP), R1;		\
    90  	ADD R1, R4;				\
    91  	ADD R1, R6;				\
    92  	SUB R1, R5;				\
    93  	BL callRet<>(SB);			\
    94  	RET
    95  
    96  // callRet copies return values back at the end of call*. This is a
    97  // separate function so it can allocate stack space for the arguments
    98  // to reflectcallmove. It does not follow the Go ABI; it expects its
    99  // arguments in registers.
   100  TEXT callRet<>(SB), NOSPLIT, $40-0
   101  	MOVD R7, 8(R15)
   102  	MOVD R6, 16(R15)
   103  	MOVD R4, 24(R15)
   104  	MOVD R5, 32(R15)
   105  	MOVD $0, 40(R15)
   106  	BL ·reflectcallmove(SB)
   107  	RET
   108  
   109  CALLFN(·call16, 16)
   110  CALLFN(·call32, 32)
   111  CALLFN(·call64, 64)
   112  CALLFN(·call128, 128)
   113  CALLFN(·call256, 256)
   114  CALLFN(·call512, 512)
   115  CALLFN(·call1024, 1024)
   116  CALLFN(·call2048, 2048)
   117  CALLFN(·call4096, 4096)
   118  CALLFN(·call8192, 8192)
   119  CALLFN(·call16384, 16384)
   120  CALLFN(·call32768, 32768)
   121  CALLFN(·call65536, 65536)
   122  CALLFN(·call131072, 131072)
   123  CALLFN(·call262144, 262144)
   124  CALLFN(·call524288, 524288)
   125  CALLFN(·call1048576, 1048576)
   126  CALLFN(·call2097152, 2097152)
   127  CALLFN(·call4194304, 4194304)
   128  CALLFN(·call8388608, 8388608)
   129  CALLFN(·call16777216, 16777216)
   130  CALLFN(·call33554432, 33554432)
   131  CALLFN(·call67108864, 67108864)
   132  CALLFN(·call134217728, 134217728)
   133  CALLFN(·call268435456, 268435456)
   134  CALLFN(·call536870912, 536870912)
   135  CALLFN(·call1073741824, 1073741824)
   136  
   137  // Not a function: target for EXRL (execute relative long) instruction.
   138  TEXT callfnMVC<>(SB),NOSPLIT|NOFRAME,$0-0
   139  	MVC $1, 0(R4), 0(R6)