github.com/mtsmfm/go/src@v0.0.0-20221020090648-44bdcb9f8fde/runtime/rt0_linux_ppc64le.s (about) 1 // Copyright 2016 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 #include "go_asm.h" 6 #include "textflag.h" 7 8 TEXT _rt0_ppc64le_linux(SB),NOSPLIT,$0 9 XOR R0, R0 // Make sure R0 is zero before _main 10 BR _main<>(SB) 11 12 TEXT _rt0_ppc64le_linux_lib(SB),NOSPLIT,$-8 13 // Start with standard C stack frame layout and linkage. 14 MOVD LR, R0 15 MOVD R0, 16(R1) // Save LR in caller's frame. 16 MOVW CR, R0 // Save CR in caller's frame 17 MOVD R0, 8(R1) 18 MOVDU R1, -320(R1) // Allocate frame. 19 20 // Preserve callee-save registers. 21 MOVD R14, 24(R1) 22 MOVD R15, 32(R1) 23 MOVD R16, 40(R1) 24 MOVD R17, 48(R1) 25 MOVD R18, 56(R1) 26 MOVD R19, 64(R1) 27 MOVD R20, 72(R1) 28 MOVD R21, 80(R1) 29 MOVD R22, 88(R1) 30 MOVD R23, 96(R1) 31 MOVD R24, 104(R1) 32 MOVD R25, 112(R1) 33 MOVD R26, 120(R1) 34 MOVD R27, 128(R1) 35 MOVD R28, 136(R1) 36 MOVD R29, 144(R1) 37 MOVD g, 152(R1) // R30 38 MOVD R31, 160(R1) 39 FMOVD F14, 168(R1) 40 FMOVD F15, 176(R1) 41 FMOVD F16, 184(R1) 42 FMOVD F17, 192(R1) 43 FMOVD F18, 200(R1) 44 FMOVD F19, 208(R1) 45 FMOVD F20, 216(R1) 46 FMOVD F21, 224(R1) 47 FMOVD F22, 232(R1) 48 FMOVD F23, 240(R1) 49 FMOVD F24, 248(R1) 50 FMOVD F25, 256(R1) 51 FMOVD F26, 264(R1) 52 FMOVD F27, 272(R1) 53 FMOVD F28, 280(R1) 54 FMOVD F29, 288(R1) 55 FMOVD F30, 296(R1) 56 FMOVD F31, 304(R1) 57 58 MOVD R3, _rt0_ppc64le_linux_lib_argc<>(SB) 59 MOVD R4, _rt0_ppc64le_linux_lib_argv<>(SB) 60 61 // Synchronous initialization. 62 MOVD $runtime·reginit(SB), R12 63 MOVD R12, CTR 64 BL (CTR) 65 MOVD $runtime·libpreinit(SB), R12 66 MOVD R12, CTR 67 BL (CTR) 68 69 // Create a new thread to do the runtime initialization and return. 70 MOVD _cgo_sys_thread_create(SB), R12 71 CMP $0, R12 72 BEQ nocgo 73 MOVD $_rt0_ppc64le_linux_lib_go(SB), R3 74 MOVD $0, R4 75 MOVD R12, CTR 76 BL (CTR) 77 BR done 78 79 nocgo: 80 MOVD $0x800000, R12 // stacksize = 8192KB 81 MOVD R12, 8(R1) 82 MOVD $_rt0_ppc64le_linux_lib_go(SB), R12 83 MOVD R12, 16(R1) 84 MOVD $runtime·newosproc0(SB),R12 85 MOVD R12, CTR 86 BL (CTR) 87 88 done: 89 // Restore saved registers. 90 MOVD 24(R1), R14 91 MOVD 32(R1), R15 92 MOVD 40(R1), R16 93 MOVD 48(R1), R17 94 MOVD 56(R1), R18 95 MOVD 64(R1), R19 96 MOVD 72(R1), R20 97 MOVD 80(R1), R21 98 MOVD 88(R1), R22 99 MOVD 96(R1), R23 100 MOVD 104(R1), R24 101 MOVD 112(R1), R25 102 MOVD 120(R1), R26 103 MOVD 128(R1), R27 104 MOVD 136(R1), R28 105 MOVD 144(R1), R29 106 MOVD 152(R1), g // R30 107 MOVD 160(R1), R31 108 FMOVD 168(R1), F14 109 FMOVD 176(R1), F15 110 FMOVD 184(R1), F16 111 FMOVD 192(R1), F17 112 FMOVD 200(R1), F18 113 FMOVD 208(R1), F19 114 FMOVD 216(R1), F20 115 FMOVD 224(R1), F21 116 FMOVD 232(R1), F22 117 FMOVD 240(R1), F23 118 FMOVD 248(R1), F24 119 FMOVD 256(R1), F25 120 FMOVD 264(R1), F26 121 FMOVD 272(R1), F27 122 FMOVD 280(R1), F28 123 FMOVD 288(R1), F29 124 FMOVD 296(R1), F30 125 FMOVD 304(R1), F31 126 127 ADD $320, R1 128 MOVD 8(R1), R0 129 MOVFL R0, $0xff 130 MOVD 16(R1), R0 131 MOVD R0, LR 132 RET 133 134 TEXT _rt0_ppc64le_linux_lib_go(SB),NOSPLIT,$0 135 MOVD _rt0_ppc64le_linux_lib_argc<>(SB), R3 136 MOVD _rt0_ppc64le_linux_lib_argv<>(SB), R4 137 MOVD $runtime·rt0_go(SB), R12 138 MOVD R12, CTR 139 BR (CTR) 140 141 DATA _rt0_ppc64le_linux_lib_argc<>(SB)/8, $0 142 GLOBL _rt0_ppc64le_linux_lib_argc<>(SB),NOPTR, $8 143 DATA _rt0_ppc64le_linux_lib_argv<>(SB)/8, $0 144 GLOBL _rt0_ppc64le_linux_lib_argv<>(SB),NOPTR, $8 145 146 TEXT _main<>(SB),NOSPLIT,$-8 147 // In a statically linked binary, the stack contains argc, 148 // argv as argc string pointers followed by a NULL, envv as a 149 // sequence of string pointers followed by a NULL, and auxv. 150 // The TLS pointer should be initialized to 0. 151 // 152 // In an ELFv2 compliant dynamically linked binary, R3 contains argc, 153 // R4 contains argv, R5 contains envp, R6 contains auxv, and R13 154 // contains the TLS pointer. 155 // 156 // When loading via glibc, the first doubleword on the stack points 157 // to NULL a value. (that is *(uintptr)(R1) == 0). This is used to 158 // differentiate static vs dynamicly linked binaries. 159 // 160 // If loading with the musl loader, it doesn't follow the ELFv2 ABI. It 161 // passes argc/argv similar to the linux kernel, R13 (TLS) is 162 // initialized, and R3/R4 are undefined. 163 MOVD (R1), R12 164 CMP R0, R12 165 BEQ tls_and_argcv_in_reg 166 167 // Arguments are passed via the stack (musl loader or a static binary) 168 MOVD 0(R1), R3 // argc 169 ADD $8, R1, R4 // argv 170 171 // Did the TLS pointer get set? If so, don't change it (e.g musl). 172 CMP R0, R13 173 BNE tls_and_argcv_in_reg 174 175 MOVD $runtime·m0+m_tls(SB), R13 // TLS 176 ADD $0x7000, R13 177 178 tls_and_argcv_in_reg: 179 BR main(SB) 180 181 TEXT main(SB),NOSPLIT,$-8 182 MOVD $runtime·rt0_go(SB), R12 183 MOVD R12, CTR 184 BR (CTR)