github.com/primecitizens/pcz/std@v0.2.1/core/reflect/call_ppc64x.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 && (ppc64 || ppc64le)
     9  
    10  #include "textflag.h"
    11  #include "funcdata.h" // for NO_LOCAL_POINTERS
    12  
    13  // spillArgs stores return values from registers to a *internal/abi.RegArgs in R20.
    14  TEXT ·spillArgs(SB),NOSPLIT,$0-0
    15  	MOVD R3, 0(R20)
    16  	MOVD R4, 8(R20)
    17  	MOVD R5, 16(R20)
    18  	MOVD R6, 24(R20)
    19  	MOVD R7, 32(R20)
    20  	MOVD R8, 40(R20)
    21  	MOVD R9, 48(R20)
    22  	MOVD R10, 56(R20)
    23  	MOVD R14, 64(R20)
    24  	MOVD R15, 72(R20)
    25  	MOVD R16, 80(R20)
    26  	MOVD R17, 88(R20)
    27  	FMOVD F1, 96(R20)
    28  	FMOVD F2, 104(R20)
    29  	FMOVD F3, 112(R20)
    30  	FMOVD F4, 120(R20)
    31  	FMOVD F5, 128(R20)
    32  	FMOVD F6, 136(R20)
    33  	FMOVD F7, 144(R20)
    34  	FMOVD F8, 152(R20)
    35  	FMOVD F9, 160(R20)
    36  	FMOVD F10, 168(R20)
    37  	FMOVD F11, 176(R20)
    38  	FMOVD F12, 184(R20)
    39  	RET
    40  
    41  // unspillArgs loads args into registers from a *internal/abi.RegArgs in R20.
    42  TEXT ·unspillArgs(SB),NOSPLIT,$0-0
    43  	MOVD 0(R20), R3
    44  	MOVD 8(R20), R4
    45  	MOVD 16(R20), R5
    46  	MOVD 24(R20), R6
    47  	MOVD 32(R20), R7
    48  	MOVD 40(R20), R8
    49  	MOVD 48(R20), R9
    50  	MOVD 56(R20), R10
    51  	MOVD 64(R20), R14
    52  	MOVD 72(R20), R15
    53  	MOVD 80(R20), R16
    54  	MOVD 88(R20), R17
    55  	FMOVD 96(R20), F1
    56  	FMOVD 104(R20), F2
    57  	FMOVD 112(R20), F3
    58  	FMOVD 120(R20), F4
    59  	FMOVD 128(R20), F5
    60  	FMOVD 136(R20), F6
    61  	FMOVD 144(R20), F7
    62  	FMOVD 152(R20), F8
    63  	FMOVD 160(R20), F9
    64  	FMOVD 168(R20), F10
    65  	FMOVD 176(R20), F11
    66  	FMOVD 184(R20), F12
    67  	RET
    68  
    69  // reflectcall: call a function with the given argument list
    70  // func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
    71  // we don't have variable-sized frames, so we use a small number
    72  // of constant-sized-frame functions to encode a few bits of size in the pc.
    73  // Caution: ugly multiline assembly macros in your future!
    74  
    75  #define DISPATCH(NAME,MAXSIZE)		\
    76  	MOVD $MAXSIZE, R31;		\
    77  	CMP R3, R31;		\
    78  	BGT 4(PC);			\
    79  	MOVD $NAME(SB), R12;		\
    80  	MOVD R12, CTR;		\
    81  	BR (CTR)
    82  // Note: can't just "BR NAME(SB)" - bad inlining results.
    83  
    84  TEXT ·Call(SB), NOSPLIT|NOFRAME, $0-48
    85  	MOVWZ frameSize+32(FP), R3
    86  	DISPATCH(·call16, 16)
    87  	DISPATCH(·call32, 32)
    88  	DISPATCH(·call64, 64)
    89  	DISPATCH(·call128, 128)
    90  	DISPATCH(·call256, 256)
    91  	DISPATCH(·call512, 512)
    92  	DISPATCH(·call1024, 1024)
    93  	DISPATCH(·call2048, 2048)
    94  	DISPATCH(·call4096, 4096)
    95  	DISPATCH(·call8192, 8192)
    96  	DISPATCH(·call16384, 16384)
    97  	DISPATCH(·call32768, 32768)
    98  	DISPATCH(·call65536, 65536)
    99  	DISPATCH(·call131072, 131072)
   100  	DISPATCH(·call262144, 262144)
   101  	DISPATCH(·call524288, 524288)
   102  	DISPATCH(·call1048576, 1048576)
   103  	DISPATCH(·call2097152, 2097152)
   104  	DISPATCH(·call4194304, 4194304)
   105  	DISPATCH(·call8388608, 8388608)
   106  	DISPATCH(·call16777216, 16777216)
   107  	DISPATCH(·call33554432, 33554432)
   108  	DISPATCH(·call67108864, 67108864)
   109  	DISPATCH(·call134217728, 134217728)
   110  	DISPATCH(·call268435456, 268435456)
   111  	DISPATCH(·call536870912, 536870912)
   112  	DISPATCH(·call1073741824, 1073741824)
   113  	MOVD $·badreflectcall(SB), R12
   114  	MOVD R12, CTR
   115  	BR (CTR)
   116  
   117  #define CALLFN(NAME,MAXSIZE)			\
   118  TEXT NAME(SB), WRAPPER, $MAXSIZE-48;		\
   119  	NO_LOCAL_POINTERS;			\
   120  	/* copy arguments to stack */		\
   121  	MOVD stackArgs+16(FP), R3;			\
   122  	MOVWZ stackArgsSize+24(FP), R4;			\
   123  	MOVD R1, R5;				\
   124  	CMP R4, $8;				\
   125  	BLT tailsetup;			\
   126  	/* copy 8 at a time if possible */	\
   127  	ADD $(FIXED_FRAME-8), R5;			\
   128  	SUB $8, R3;				\
   129  top: \
   130  	MOVDU 8(R3), R7;			\
   131  	MOVDU R7, 8(R5);			\
   132  	SUB $8, R4;				\
   133  	CMP R4, $8;				\
   134  	BGE top;				\
   135  	/* handle remaining bytes */	\
   136  	CMP $0, R4;			\
   137  	BEQ callfn;			\
   138  	ADD $7, R3;			\
   139  	ADD $7, R5;			\
   140  	BR tail;			\
   141  tailsetup: \
   142  	CMP $0, R4;			\
   143  	BEQ callfn;			\
   144  	ADD     $(FIXED_FRAME-1), R5;	\
   145  	SUB     $1, R3;			\
   146  tail: \
   147  	MOVBU 1(R3), R6;		\
   148  	MOVBU R6, 1(R5);		\
   149  	SUB $1, R4;			\
   150  	CMP $0, R4;			\
   151  	BGT tail;			\
   152  callfn: \
   153  	/* call function */			\
   154  	MOVD f+8(FP), R11;			\
   155  #ifdef GOOS_aix \
   156  	/* AIX won't trigger a SIGSEGV if R11 = nil */	\
   157  	/* So it manually triggers it */	\
   158  	CMP R0, R11 \
   159  	BNE 2(PC)				\
   160  	MOVD R0, 0(R0)			\
   161  #endif \
   162  	MOVD regArgs+40(FP), R20;    \
   163  	BL      ·unspillArgs(SB);        \
   164  	MOVD (R11), R12;			\
   165  	MOVD R12, CTR;			\
   166  	PCDATA  $PCDATA_StackMapIndex, $0;	\
   167  	BL (CTR);				\
   168  #ifndef GOOS_aix \
   169  	MOVD 24(R1), R2;			\
   170  #endif \
   171  	/* copy return values back */		\
   172  	MOVD regArgs+40(FP), R20;		\
   173  	BL ·spillArgs(SB);			\
   174  	MOVD stackArgsType+0(FP), R7;		\
   175  	MOVD stackArgs+16(FP), R3;			\
   176  	MOVWZ stackArgsSize+24(FP), R4;			\
   177  	MOVWZ stackRetOffset+28(FP), R6;		\
   178  	ADD $FIXED_FRAME, R1, R5;		\
   179  	ADD R6, R5; 			\
   180  	ADD R6, R3;				\
   181  	SUB R6, R4;				\
   182  	BL callRet<>(SB);			\
   183  	RET
   184  
   185  // callRet copies return values back at the end of call*. This is a
   186  // separate function so it can allocate stack space for the arguments
   187  // to reflectcallmove. It does not follow the Go ABI; it expects its
   188  // arguments in registers.
   189  TEXT callRet<>(SB), NOSPLIT, $40-0
   190  	NO_LOCAL_POINTERS
   191  	MOVD R7, FIXED_FRAME+0(R1)
   192  	MOVD R3, FIXED_FRAME+8(R1)
   193  	MOVD R5, FIXED_FRAME+16(R1)
   194  	MOVD R4, FIXED_FRAME+24(R1)
   195  	MOVD R20, FIXED_FRAME+32(R1)
   196  	BL ·reflectcallmove(SB)
   197  	RET
   198  
   199  CALLFN(·call16, 16)
   200  CALLFN(·call32, 32)
   201  CALLFN(·call64, 64)
   202  CALLFN(·call128, 128)
   203  CALLFN(·call256, 256)
   204  CALLFN(·call512, 512)
   205  CALLFN(·call1024, 1024)
   206  CALLFN(·call2048, 2048)
   207  CALLFN(·call4096, 4096)
   208  CALLFN(·call8192, 8192)
   209  CALLFN(·call16384, 16384)
   210  CALLFN(·call32768, 32768)
   211  CALLFN(·call65536, 65536)
   212  CALLFN(·call131072, 131072)
   213  CALLFN(·call262144, 262144)
   214  CALLFN(·call524288, 524288)
   215  CALLFN(·call1048576, 1048576)
   216  CALLFN(·call2097152, 2097152)
   217  CALLFN(·call4194304, 4194304)
   218  CALLFN(·call8388608, 8388608)
   219  CALLFN(·call16777216, 16777216)
   220  CALLFN(·call33554432, 33554432)
   221  CALLFN(·call67108864, 67108864)
   222  CALLFN(·call134217728, 134217728)
   223  CALLFN(·call268435456, 268435456)
   224  CALLFN(·call536870912, 536870912)
   225  CALLFN(·call1073741824, 1073741824)