github.com/primecitizens/pcz/std@v0.2.1/core/reflect/call_riscv64.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 && riscv64
     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 X25.
    14  TEXT ·spillArgs(SB),NOSPLIT,$0-0
    15  	MOV X10, (0*8)(X25)
    16  	MOV X11, (1*8)(X25)
    17  	MOV X12, (2*8)(X25)
    18  	MOV X13, (3*8)(X25)
    19  	MOV X14, (4*8)(X25)
    20  	MOV X15, (5*8)(X25)
    21  	MOV X16, (6*8)(X25)
    22  	MOV X17, (7*8)(X25)
    23  	MOV X8,  (8*8)(X25)
    24  	MOV X9,  (9*8)(X25)
    25  	MOV X18, (10*8)(X25)
    26  	MOV X19, (11*8)(X25)
    27  	MOV X20, (12*8)(X25)
    28  	MOV X21, (13*8)(X25)
    29  	MOV X22, (14*8)(X25)
    30  	MOV X23, (15*8)(X25)
    31  	MOVD F10, (16*8)(X25)
    32  	MOVD F11, (17*8)(X25)
    33  	MOVD F12, (18*8)(X25)
    34  	MOVD F13, (19*8)(X25)
    35  	MOVD F14, (20*8)(X25)
    36  	MOVD F15, (21*8)(X25)
    37  	MOVD F16, (22*8)(X25)
    38  	MOVD F17, (23*8)(X25)
    39  	MOVD F8,  (24*8)(X25)
    40  	MOVD F9,  (25*8)(X25)
    41  	MOVD F18, (26*8)(X25)
    42  	MOVD F19, (27*8)(X25)
    43  	MOVD F20, (28*8)(X25)
    44  	MOVD F21, (29*8)(X25)
    45  	MOVD F22, (30*8)(X25)
    46  	MOVD F23, (31*8)(X25)
    47  	RET
    48  
    49  // unspillArgs loads args into registers from a *internal/abi.RegArgs in X25.
    50  TEXT ·unspillArgs(SB),NOSPLIT,$0-0
    51  	MOV (0*8)(X25), X10
    52  	MOV (1*8)(X25), X11
    53  	MOV (2*8)(X25), X12
    54  	MOV (3*8)(X25), X13
    55  	MOV (4*8)(X25), X14
    56  	MOV (5*8)(X25), X15
    57  	MOV (6*8)(X25), X16
    58  	MOV (7*8)(X25), X17
    59  	MOV (8*8)(X25), X8
    60  	MOV (9*8)(X25), X9
    61  	MOV (10*8)(X25), X18
    62  	MOV (11*8)(X25), X19
    63  	MOV (12*8)(X25), X20
    64  	MOV (13*8)(X25), X21
    65  	MOV (14*8)(X25), X22
    66  	MOV (15*8)(X25), X23
    67  	MOVD (16*8)(X25), F10
    68  	MOVD (17*8)(X25), F11
    69  	MOVD (18*8)(X25), F12
    70  	MOVD (19*8)(X25), F13
    71  	MOVD (20*8)(X25), F14
    72  	MOVD (21*8)(X25), F15
    73  	MOVD (22*8)(X25), F16
    74  	MOVD (23*8)(X25), F17
    75  	MOVD (24*8)(X25), F8
    76  	MOVD (25*8)(X25), F9
    77  	MOVD (26*8)(X25), F18
    78  	MOVD (27*8)(X25), F19
    79  	MOVD (28*8)(X25), F20
    80  	MOVD (29*8)(X25), F21
    81  	MOVD (30*8)(X25), F22
    82  	MOVD (31*8)(X25), F23
    83  	RET
    84  
    85  // reflectcall: call a function with the given argument list
    86  // func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
    87  // we don't have variable-sized frames, so we use a small number
    88  // of constant-sized-frame functions to encode a few bits of size in the pc.
    89  // Caution: ugly multiline assembly macros in your future!
    90  
    91  #define DISPATCH(NAME,MAXSIZE)	\
    92  	MOV $MAXSIZE, T1 \
    93  	BLTU T1, T0, 3(PC)	\
    94  	MOV $NAME(SB), T2;	\
    95  	JALR ZERO, T2
    96  // Note: can't just "BR NAME(SB)" - bad inlining results.
    97  
    98  // func call(stackArgsType *_type, fn, stackArgs unsafe.Pointer, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
    99  TEXT ·Call(SB), NOSPLIT|NOFRAME, $0-48
   100  	MOVWU frameSize+32(FP), T0
   101  	DISPATCH(·call16, 16)
   102  	DISPATCH(·call32, 32)
   103  	DISPATCH(·call64, 64)
   104  	DISPATCH(·call128, 128)
   105  	DISPATCH(·call256, 256)
   106  	DISPATCH(·call512, 512)
   107  	DISPATCH(·call1024, 1024)
   108  	DISPATCH(·call2048, 2048)
   109  	DISPATCH(·call4096, 4096)
   110  	DISPATCH(·call8192, 8192)
   111  	DISPATCH(·call16384, 16384)
   112  	DISPATCH(·call32768, 32768)
   113  	DISPATCH(·call65536, 65536)
   114  	DISPATCH(·call131072, 131072)
   115  	DISPATCH(·call262144, 262144)
   116  	DISPATCH(·call524288, 524288)
   117  	DISPATCH(·call1048576, 1048576)
   118  	DISPATCH(·call2097152, 2097152)
   119  	DISPATCH(·call4194304, 4194304)
   120  	DISPATCH(·call8388608, 8388608)
   121  	DISPATCH(·call16777216, 16777216)
   122  	DISPATCH(·call33554432, 33554432)
   123  	DISPATCH(·call67108864, 67108864)
   124  	DISPATCH(·call134217728, 134217728)
   125  	DISPATCH(·call268435456, 268435456)
   126  	DISPATCH(·call536870912, 536870912)
   127  	DISPATCH(·call1073741824, 1073741824)
   128  	MOV $·badreflectcall(SB), T2
   129  	JALR ZERO, T2
   130  
   131  #define CALLFN(NAME,MAXSIZE)			\
   132  TEXT NAME(SB), WRAPPER, $MAXSIZE-48;		\
   133  	NO_LOCAL_POINTERS;			\
   134  	/* copy arguments to stack */		\
   135  	MOV stackArgs+16(FP), A1;			\
   136  	MOVWU stackArgsSize+24(FP), A2;		\
   137  	MOV X2, A3;				\
   138  	ADD $8, A3;				\
   139  	ADD A3, A2;				\
   140  	BEQ A3, A2, 6(PC);			\
   141  	MOVBU (A1), A4;			\
   142  	ADD $1, A1;				\
   143  	MOVB A4, (A3);			\
   144  	ADD $1, A3;				\
   145  	JMP -5(PC);				\
   146  	/* set up argument registers */		\
   147  	MOV regArgs+40(FP), X25;		\
   148  	CALL ·unspillArgs(SB);		\
   149  	/* call function */			\
   150  	MOV f+8(FP), CTXT;			\
   151  	MOV (CTXT), X25;			\
   152  	PCDATA  $PCDATA_StackMapIndex, $0;	\
   153  	JALR RA, X25;				\
   154  	/* copy return values back */		\
   155  	MOV regArgs+40(FP), X25;		\
   156  	CALL ·spillArgs(SB);		\
   157  	MOV stackArgsType+0(FP), A5;		\
   158  	MOV stackArgs+16(FP), A1;			\
   159  	MOVWU stackArgsSize+24(FP), A2;			\
   160  	MOVWU stackRetOffset+28(FP), A4;		\
   161  	ADD $8, X2, A3;			\
   162  	ADD A4, A3; 			\
   163  	ADD A4, A1;				\
   164  	SUB A4, A2;				\
   165  	CALL callRet<>(SB);			\
   166  	RET
   167  
   168  // callRet copies return values back at the end of call*. This is a
   169  // separate function so it can allocate stack space for the arguments
   170  // to reflectcallmove. It does not follow the Go ABI; it expects its
   171  // arguments in registers.
   172  TEXT callRet<>(SB), NOSPLIT, $40-0
   173  	NO_LOCAL_POINTERS
   174  	MOV A5, 8(X2)
   175  	MOV A1, 16(X2)
   176  	MOV A3, 24(X2)
   177  	MOV A2, 32(X2)
   178  	MOV X25, 40(X2)
   179  	CALL ·reflectcallmove(SB)
   180  	RET
   181  
   182  CALLFN(·call16, 16)
   183  CALLFN(·call32, 32)
   184  CALLFN(·call64, 64)
   185  CALLFN(·call128, 128)
   186  CALLFN(·call256, 256)
   187  CALLFN(·call512, 512)
   188  CALLFN(·call1024, 1024)
   189  CALLFN(·call2048, 2048)
   190  CALLFN(·call4096, 4096)
   191  CALLFN(·call8192, 8192)
   192  CALLFN(·call16384, 16384)
   193  CALLFN(·call32768, 32768)
   194  CALLFN(·call65536, 65536)
   195  CALLFN(·call131072, 131072)
   196  CALLFN(·call262144, 262144)
   197  CALLFN(·call524288, 524288)
   198  CALLFN(·call1048576, 1048576)
   199  CALLFN(·call2097152, 2097152)
   200  CALLFN(·call4194304, 4194304)
   201  CALLFN(·call8388608, 8388608)
   202  CALLFN(·call16777216, 16777216)
   203  CALLFN(·call33554432, 33554432)
   204  CALLFN(·call67108864, 67108864)
   205  CALLFN(·call134217728, 134217728)
   206  CALLFN(·call268435456, 268435456)
   207  CALLFN(·call536870912, 536870912)
   208  CALLFN(·call1073741824, 1073741824)