github.com/primecitizens/pcz/std@v0.2.1/core/reflect/call_amd64.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 && amd64 9 10 #include "textflag.h" 11 #include "funcdata.h" // for NO_LOCAL_POINTERS 12 13 // spillArgs stores return values from registers to a *core/abi.RegArgs in R12. 14 TEXT ·spillArgs(SB),NOSPLIT,$0-0 15 MOVQ AX, 0(R12) 16 MOVQ BX, 8(R12) 17 MOVQ CX, 16(R12) 18 MOVQ DI, 24(R12) 19 MOVQ SI, 32(R12) 20 MOVQ R8, 40(R12) 21 MOVQ R9, 48(R12) 22 MOVQ R10, 56(R12) 23 MOVQ R11, 64(R12) 24 MOVQ X0, 72(R12) 25 MOVQ X1, 80(R12) 26 MOVQ X2, 88(R12) 27 MOVQ X3, 96(R12) 28 MOVQ X4, 104(R12) 29 MOVQ X5, 112(R12) 30 MOVQ X6, 120(R12) 31 MOVQ X7, 128(R12) 32 MOVQ X8, 136(R12) 33 MOVQ X9, 144(R12) 34 MOVQ X10, 152(R12) 35 MOVQ X11, 160(R12) 36 MOVQ X12, 168(R12) 37 MOVQ X13, 176(R12) 38 MOVQ X14, 184(R12) 39 RET 40 41 // unspillArgs loads args into registers from a *core/abi.RegArgs in R12. 42 TEXT ·unspillArgs(SB),NOSPLIT,$0-0 43 MOVQ 0(R12), AX 44 MOVQ 8(R12), BX 45 MOVQ 16(R12), CX 46 MOVQ 24(R12), DI 47 MOVQ 32(R12), SI 48 MOVQ 40(R12), R8 49 MOVQ 48(R12), R9 50 MOVQ 56(R12), R10 51 MOVQ 64(R12), R11 52 MOVQ 72(R12), X0 53 MOVQ 80(R12), X1 54 MOVQ 88(R12), X2 55 MOVQ 96(R12), X3 56 MOVQ 104(R12), X4 57 MOVQ 112(R12), X5 58 MOVQ 120(R12), X6 59 MOVQ 128(R12), X7 60 MOVQ 136(R12), X8 61 MOVQ 144(R12), X9 62 MOVQ 152(R12), X10 63 MOVQ 160(R12), X11 64 MOVQ 168(R12), X12 65 MOVQ 176(R12), X13 66 MOVQ 184(R12), X14 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 CMPQ CX, $MAXSIZE; \ 77 JA 3(PC); \ 78 MOVQ $NAME(SB), AX; \ 79 JMP AX 80 // Note: can't just "JMP NAME(SB)" - bad inlining results. 81 82 TEXT ·Call(SB), NOSPLIT, $0-48 83 MOVLQZX frameSize+32(FP), CX 84 DISPATCH(·call16, 16) 85 DISPATCH(·call32, 32) 86 DISPATCH(·call64, 64) 87 DISPATCH(·call128, 128) 88 DISPATCH(·call256, 256) 89 DISPATCH(·call512, 512) 90 DISPATCH(·call1024, 1024) 91 DISPATCH(·call2048, 2048) 92 DISPATCH(·call4096, 4096) 93 DISPATCH(·call8192, 8192) 94 DISPATCH(·call16384, 16384) 95 DISPATCH(·call32768, 32768) 96 DISPATCH(·call65536, 65536) 97 DISPATCH(·call131072, 131072) 98 DISPATCH(·call262144, 262144) 99 DISPATCH(·call524288, 524288) 100 DISPATCH(·call1048576, 1048576) 101 DISPATCH(·call2097152, 2097152) 102 DISPATCH(·call4194304, 4194304) 103 DISPATCH(·call8388608, 8388608) 104 DISPATCH(·call16777216, 16777216) 105 DISPATCH(·call33554432, 33554432) 106 DISPATCH(·call67108864, 67108864) 107 DISPATCH(·call134217728, 134217728) 108 DISPATCH(·call268435456, 268435456) 109 DISPATCH(·call536870912, 536870912) 110 DISPATCH(·call1073741824, 1073741824) 111 MOVQ $·badreflectcall(SB), AX 112 JMP AX 113 114 #define CALLFN(NAME,MAXSIZE) \ 115 TEXT NAME(SB), WRAPPER, $MAXSIZE-48; \ 116 NO_LOCAL_POINTERS; \ 117 /* copy arguments to stack */ \ 118 MOVQ stackArgs+16(FP), SI; \ 119 MOVLQZX stackArgsSize+24(FP), CX; \ 120 MOVQ SP, DI; \ 121 REP;MOVSB; \ 122 /* set up argument registers */ \ 123 MOVQ regArgs+40(FP), R12; \ 124 CALL ·unspillArgs(SB); \ 125 /* call function */ \ 126 MOVQ f+8(FP), DX; \ 127 PCDATA $PCDATA_StackMapIndex, $0; \ 128 MOVQ (DX), R12; \ 129 CALL R12; \ 130 /* copy register return values back */ \ 131 MOVQ regArgs+40(FP), R12; \ 132 CALL ·spillArgs(SB); \ 133 MOVLQZX stackArgsSize+24(FP), CX; \ 134 MOVLQZX stackRetOffset+28(FP), BX; \ 135 MOVQ stackArgs+16(FP), DI; \ 136 MOVQ stackArgsType+0(FP), DX; \ 137 MOVQ SP, SI; \ 138 ADDQ BX, DI; \ 139 ADDQ BX, SI; \ 140 SUBQ BX, CX; \ 141 CALL callRet<>(SB); \ 142 RET 143 144 // callRet copies return values back at the end of call*. This is a 145 // separate function so it can allocate stack space for the arguments 146 // to reflectcallmove. It does not follow the Go ABI; it expects its 147 // arguments in registers. 148 TEXT callRet<>(SB), NOSPLIT, $40-0 149 NO_LOCAL_POINTERS 150 MOVQ DX, 0(SP) 151 MOVQ DI, 8(SP) 152 MOVQ SI, 16(SP) 153 MOVQ CX, 24(SP) 154 MOVQ R12, 32(SP) 155 CALL ·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)