github.com/primecitizens/pcz/std@v0.2.1/core/reflect/call_arm64.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 && arm64
     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  	STP (R0, R1), (0*8)(R20)
    16  	STP (R2, R3), (2*8)(R20)
    17  	STP (R4, R5), (4*8)(R20)
    18  	STP (R6, R7), (6*8)(R20)
    19  	STP (R8, R9), (8*8)(R20)
    20  	STP (R10, R11), (10*8)(R20)
    21  	STP (R12, R13), (12*8)(R20)
    22  	STP (R14, R15), (14*8)(R20)
    23  	FSTPD (F0, F1), (16*8)(R20)
    24  	FSTPD (F2, F3), (18*8)(R20)
    25  	FSTPD (F4, F5), (20*8)(R20)
    26  	FSTPD (F6, F7), (22*8)(R20)
    27  	FSTPD (F8, F9), (24*8)(R20)
    28  	FSTPD (F10, F11), (26*8)(R20)
    29  	FSTPD (F12, F13), (28*8)(R20)
    30  	FSTPD (F14, F15), (30*8)(R20)
    31  	RET
    32  
    33  // unspillArgs loads args into registers from a *internal/abi.RegArgs in R20.
    34  TEXT ·unspillArgs(SB),NOSPLIT,$0-0
    35  	LDP (0*8)(R20), (R0, R1)
    36  	LDP (2*8)(R20), (R2, R3)
    37  	LDP (4*8)(R20), (R4, R5)
    38  	LDP (6*8)(R20), (R6, R7)
    39  	LDP (8*8)(R20), (R8, R9)
    40  	LDP (10*8)(R20), (R10, R11)
    41  	LDP (12*8)(R20), (R12, R13)
    42  	LDP (14*8)(R20), (R14, R15)
    43  	FLDPD (16*8)(R20), (F0, F1)
    44  	FLDPD (18*8)(R20), (F2, F3)
    45  	FLDPD (20*8)(R20), (F4, F5)
    46  	FLDPD (22*8)(R20), (F6, F7)
    47  	FLDPD (24*8)(R20), (F8, F9)
    48  	FLDPD (26*8)(R20), (F10, F11)
    49  	FLDPD (28*8)(R20), (F12, F13)
    50  	FLDPD (30*8)(R20), (F14, F15)
    51  	RET
    52  
    53  // reflectcall: call a function with the given argument list
    54  // func call(stackArgsType *_type, f *FuncVal, stackArgs *byte, stackArgsSize, stackRetOffset, frameSize uint32, regArgs *abi.RegArgs).
    55  // we don't have variable-sized frames, so we use a small number
    56  // of constant-sized-frame functions to encode a few bits of size in the pc.
    57  // Caution: ugly multiline assembly macros in your future!
    58  
    59  #define DISPATCH(NAME,MAXSIZE)		\
    60  	MOVD $MAXSIZE, R27;		\
    61  	CMP R27, R16;		\
    62  	BGT 3(PC);			\
    63  	MOVD $NAME(SB), R27;	\
    64  	B (R27)
    65  // Note: can't just "B NAME(SB)" - bad inlining results.
    66  
    67  TEXT ·Call(SB), NOSPLIT|NOFRAME, $0-48
    68  	MOVWU frameSize+32(FP), R16
    69  	DISPATCH(·call16, 16)
    70  	DISPATCH(·call32, 32)
    71  	DISPATCH(·call64, 64)
    72  	DISPATCH(·call128, 128)
    73  	DISPATCH(·call256, 256)
    74  	DISPATCH(·call512, 512)
    75  	DISPATCH(·call1024, 1024)
    76  	DISPATCH(·call2048, 2048)
    77  	DISPATCH(·call4096, 4096)
    78  	DISPATCH(·call8192, 8192)
    79  	DISPATCH(·call16384, 16384)
    80  	DISPATCH(·call32768, 32768)
    81  	DISPATCH(·call65536, 65536)
    82  	DISPATCH(·call131072, 131072)
    83  	DISPATCH(·call262144, 262144)
    84  	DISPATCH(·call524288, 524288)
    85  	DISPATCH(·call1048576, 1048576)
    86  	DISPATCH(·call2097152, 2097152)
    87  	DISPATCH(·call4194304, 4194304)
    88  	DISPATCH(·call8388608, 8388608)
    89  	DISPATCH(·call16777216, 16777216)
    90  	DISPATCH(·call33554432, 33554432)
    91  	DISPATCH(·call67108864, 67108864)
    92  	DISPATCH(·call134217728, 134217728)
    93  	DISPATCH(·call268435456, 268435456)
    94  	DISPATCH(·call536870912, 536870912)
    95  	DISPATCH(·call1073741824, 1073741824)
    96  	MOVD $·badreflectcall(SB), R0
    97  	B (R0)
    98  
    99  #define CALLFN(NAME,MAXSIZE)			\
   100  TEXT NAME(SB), WRAPPER, $MAXSIZE-48;		\
   101  	NO_LOCAL_POINTERS;			\
   102  	/* copy arguments to stack */		\
   103  	MOVD stackArgs+16(FP), R3;			\
   104  	MOVWU stackArgsSize+24(FP), R4;		\
   105  	ADD $8, RSP, R5;			\
   106  	BIC $0xf, R4, R6;			\
   107  	CBZ R6, 6(PC);			\
   108  	/* if R6=(argsize&~15) != 0 */		\
   109  	ADD R6, R5, R6;			\
   110  	/* copy 16 bytes a time */		\
   111  	LDP.P 16(R3), (R7, R8);		\
   112  	STP.P (R7, R8), 16(R5);		\
   113  	CMP R5, R6;				\
   114  	BNE -3(PC);				\
   115  	AND $0xf, R4, R6;			\
   116  	CBZ R6, 6(PC);			\
   117  	/* if R6=(argsize&15) != 0 */		\
   118  	ADD R6, R5, R6;			\
   119  	/* copy 1 byte a time for the rest */	\
   120  	MOVBU.P 1(R3), R7;			\
   121  	MOVBU.P R7, 1(R5);			\
   122  	CMP R5, R6;				\
   123  	BNE -3(PC);				\
   124  	/* set up argument registers */		\
   125  	MOVD regArgs+40(FP), R20;		\
   126  	CALL ·unspillArgs(SB);		\
   127  	/* call function */			\
   128  	MOVD f+8(FP), R26;			\
   129  	MOVD (R26), R20;			\
   130  	PCDATA $PCDATA_StackMapIndex, $0;	\
   131  	BL (R20);				\
   132  	/* copy return values back */		\
   133  	MOVD regArgs+40(FP), R20;		\
   134  	CALL ·spillArgs(SB);		\
   135  	MOVD stackArgsType+0(FP), R7;		\
   136  	MOVD stackArgs+16(FP), R3;			\
   137  	MOVWU stackArgsSize+24(FP), R4;			\
   138  	MOVWU stackRetOffset+28(FP), R6;		\
   139  	ADD $8, RSP, R5;			\
   140  	ADD R6, R5; 			\
   141  	ADD R6, R3;				\
   142  	SUB R6, R4;				\
   143  	BL callRet<>(SB);			\
   144  	RET
   145  
   146  // callRet copies return values back at the end of call*. This is a
   147  // separate function so it can allocate stack space for the arguments
   148  // to reflectcallmove. It does not follow the Go ABI; it expects its
   149  // arguments in registers.
   150  TEXT callRet<>(SB), NOSPLIT, $48-0
   151  	NO_LOCAL_POINTERS
   152  	STP (R7, R3), 8(RSP)
   153  	STP (R5, R4), 24(RSP)
   154  	MOVD R20, 40(RSP)
   155  	BL ·reflectcallmove(SB)
   156  	RET
   157  
   158  CALLFN(·call16, 16)
   159  CALLFN(·call32, 32)
   160  CALLFN(·call64, 64)
   161  CALLFN(·call128, 128)
   162  CALLFN(·call256, 256)
   163  CALLFN(·call512, 512)
   164  CALLFN(·call1024, 1024)
   165  CALLFN(·call2048, 2048)
   166  CALLFN(·call4096, 4096)
   167  CALLFN(·call8192, 8192)
   168  CALLFN(·call16384, 16384)
   169  CALLFN(·call32768, 32768)
   170  CALLFN(·call65536, 65536)
   171  CALLFN(·call131072, 131072)
   172  CALLFN(·call262144, 262144)
   173  CALLFN(·call524288, 524288)
   174  CALLFN(·call1048576, 1048576)
   175  CALLFN(·call2097152, 2097152)
   176  CALLFN(·call4194304, 4194304)
   177  CALLFN(·call8388608, 8388608)
   178  CALLFN(·call16777216, 16777216)
   179  CALLFN(·call33554432, 33554432)
   180  CALLFN(·call67108864, 67108864)
   181  CALLFN(·call134217728, 134217728)
   182  CALLFN(·call268435456, 268435456)
   183  CALLFN(·call536870912, 536870912)
   184  CALLFN(·call1073741824, 1073741824)