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)