github.com/4ad/go@v0.0.0-20161219182952-69a12818b605/src/runtime/sys_solaris_sparc64.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 // System calls and other sys.stuff for SPARC64, Solaris. 6 // 7 8 #include "go_asm.h" 9 #include "go_tls.h" 10 #include "textflag.h" 11 #include "asm_sparc64.h" 12 13 // void libc_miniterrno(void *(*___errno)(void)); 14 // 15 // Set the TLS errno pointer in M. 16 // 17 // Called using runtime·asmcgocall from os_solaris.c:/minit. 18 // NOT USING GO CALLING CONVENTION. 19 TEXT runtime·miniterrno(SB),NOSPLIT|REGWIN,$0 20 // asmcgocall will put first argument into I0. 21 CALL I0 // SysV ABI so returns in O0 22 CALL runtime·load_g(SB) 23 MOVD g_m(g), I3 24 MOVD O0, (m_mOS+mOS_perrno)(I3) 25 RET 26 27 // int64 runtime·nanotime1(void); 28 // 29 // clock_gettime(3c) wrapper because Timespec is too large for 30 // runtime·nanotime stack. 31 // 32 // Called using runtime·sysvicall6 from os_solaris.c:/nanotime. 33 // NOT USING GO CALLING CONVENTION. 34 TEXT runtime·nanotime1(SB),NOSPLIT|REGWIN,$64 35 MOVW $3, O0 // CLOCK_REALTIME from <sys/time_impl.h> 36 MOVD $tv-16(SP), O1 37 MOVD $libc_clock_gettime(SB), I3 38 CALL I3 39 MOVD tv_sec-16(SP), I3 // tv_sec from struct timespec 40 MOVD $1000000000, I1 41 MULD I1, I3 // multiply into nanoseconds 42 MOVD tv_nsec-8(SP), I5 // tv_nsec, offset should be stable. 43 ADD I5, I3, I0 44 RET 45 46 // pipe(3c) wrapper that returns fds in AX, DX. 47 // NOT USING GO CALLING CONVENTION. 48 TEXT runtime·pipe1(SB),NOSPLIT|REGWIN,$16 49 MOVD $FIXED_FRAME(BSP), O0 50 MOVD $libc_pipe(SB), I3 51 CALL I3 52 MOVW (FIXED_FRAME+0)(BSP), I0 53 MOVW (FIXED_FRAME+4)(BSP), I1 54 RET 55 56 // Call a library function with SysV calling conventions. 57 // The called function can take a maximum of 6 INTEGER class arguments, 58 // see 59 // SYSTEM V APPLICATION BINARY INTERFACE 60 // SPARC Version 9 Processor Supplement 61 // section 3.2.2. 62 // 63 // Called by runtime·asmcgocall or runtime·cgocall. 64 // NOT USING GO CALLING CONVENTION. 65 TEXT runtime·asmsysvicall6(SB),NOSPLIT|REGWIN,$0 66 // asmcgocall will put first argument into I0. 67 MOVD I0, L6 68 MOVD libcall_fn(I0), I3 69 MOVD libcall_args(I0), L1 70 MOVD libcall_n(I0), L2 71 72 CMP ZR, g 73 BED skiperrno1 74 MOVD g_m(g), I5 75 MOVD (m_mOS+mOS_perrno)(I5), I1 76 CMP I1, ZR 77 BED skiperrno1 78 MOVW ZR, (I1) 79 80 skiperrno1: 81 CMP L1, ZR 82 BED skipargs 83 // Load 6 args into correspondent registers. 84 MOVD 0(L1), O0 85 MOVD 8(L1), O1 86 MOVD 16(L1), O2 87 MOVD 24(L1), O3 88 MOVD 32(L1), O4 89 MOVD 40(L1), O5 90 skipargs: 91 92 MOVD g, L1 93 // Call SysV function 94 CALL I3 95 MOVD L1, g 96 97 // Return result 98 MOVD O0, libcall_r1(L6) 99 MOVD O1, libcall_r2(L6) 100 MOVD O0, I0 101 MOVD O1, I1 102 103 CMP g, ZR 104 BED skiperrno2 105 MOVD g_m(g), I5 106 MOVD (m_mOS+mOS_perrno)(I5), I4 107 CMP I4, ZR 108 BED skiperrno2 109 MOVW (I4), I4 110 MOVD I4, libcall_err(L6) 111 112 skiperrno2: 113 RET 114 115 // uint32 tstart_sysvicall(M *newm); 116 TEXT runtime·tstart_sysvicall(SB),NOSPLIT|REGWIN,$0 117 // I0 contains first arg newm 118 MOVD m_g0(I0), g // g 119 MOVD I0, g_m(g) 120 121 CALL runtime·save_g(SB) 122 123 // Layout new m scheduler stack on os stack. 124 MOVD BSP, I3 125 MOVD I3, (g_stack+stack_hi)(g) 126 SUB $(0x100000), I3 // stack size 127 MOVD I3, (g_stack+stack_lo)(g) 128 ADD $const__StackGuard, I3 129 MOVD I3, g_stackguard0(g) 130 MOVD I3, g_stackguard1(g) 131 132 // initialize essential registers 133 CALL runtime·reginit(SB) 134 135 CALL runtime·stackcheck(SB) 136 CALL runtime·mstart(SB) 137 138 MOVW ZR, ret+8(FP) 139 RET 140 141 #define SIGTRAMP_FRAME 144 142 143 // Careful, this is called by __sighndlr, a libc function. 144 // We must preserve registers as per SPARC64 ABI. 145 TEXT runtime·sigtramp(SB),NOSPLIT|REGWIN,$SIGTRAMP_FRAME 146 MOVD g, L1 147 CALL runtime·load_g(SB) 148 CMP g, ZR 149 BNED allgood 150 MOVD L1, g 151 MOVD I0, (8*0+FIXED_FRAME)(BSP) 152 MOVD ZR, (8*1+FIXED_FRAME)(BSP) 153 MOVD $runtime·badsignal(SB), L1 154 CALL (L1) 155 JMP exit 156 157 allgood: 158 // initialize essential registers (just in case) 159 CALL runtime·reginit(SB) 160 161 // save g 162 MOVD g, (-8-0*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP) 163 164 // Save m->libcall and m->scratch. We need to do this because we 165 // might get interrupted by a signal in runtime·asmcgocall. 166 167 // save m->libcall 168 MOVD g_m(g), L1 169 MOVD $m_libcall(L1), L2 170 MOVD libcall_fn(L2), L3 171 MOVD L3, (-8-1*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP) 172 MOVD libcall_args(L2), L3 173 MOVD L3, (-8-2*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP) 174 MOVD libcall_n(L2), L3 175 MOVD L3, (-8-3*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP) 176 MOVD libcall_r1(L2), L3 177 MOVD L3, (-8-4*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP) 178 MOVD libcall_r2(L2), L3 179 MOVD L3, (-8-5*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP) 180 181 // save m->scratch 182 MOVD $(m_mOS+mOS_scratch)(L1), L2 183 MOVD 0(L2), L3 184 MOVD L3, (-8-6*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP) 185 MOVD 8(L2), L3 186 MOVD L3, (-8-7*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP) 187 MOVD 16(L2), L3 188 MOVD L3, (-8-8*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP) 189 MOVD 24(L2), L3 190 MOVD L3, (-8-9*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP) 191 MOVD 32(L2), L3 192 MOVD L3, (-8-10*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP) 193 MOVD 40(L2), L3 194 MOVD L3, (-8-11*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP) 195 196 // save errno, it might be EINTR; stuff we do here might reset it. 197 MOVD (m_mOS+mOS_perrno)(L1), L2 198 MOVW 0(L2), L2 199 MOVD L2, (-8-12*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP) 200 201 // prepare call 202 MOVW I0, (8*0+FIXED_FRAME)(BSP) 203 MOVD I1, (8*1+FIXED_FRAME)(BSP) 204 MOVD I2, (8*2+FIXED_FRAME)(BSP) 205 MOVD g, (8*3+FIXED_FRAME)(BSP) 206 207 // g = m->gsignal 208 MOVD m_gsignal(L1), g 209 CALL runtime·save_g(SB) 210 211 // TODO(shawn): If current SP is not in gsignal.stack, then assume 212 // non-Go code caused a signal and adjust gsignal.stack? 213 MOVD (g_stack+stack_lo)(g), L2 214 MOVD BSP, TMP 215 CMP L2, TMP 216 BGED checkhi 217 CALL runtime·abort(SB) 218 219 checkhi: 220 MOVD (g_stack+stack_hi)(g), L2 221 MOVD BSP, TMP 222 CMP L2, TMP 223 BLD handler 224 CALL runtime·abort(SB) 225 226 handler: 227 CALL runtime·sighandler(SB) 228 229 MOVD g_m(g), L1 230 // restore libcall 231 MOVD $m_libcall(L1), L2 232 MOVD (-8-1*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3 233 MOVD L3, libcall_fn(L2) 234 MOVD (-8-2*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3 235 MOVD L3, libcall_args(L2) 236 MOVD (-8-3*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3 237 MOVD L3, libcall_n(L2) 238 MOVD (-8-4*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3 239 MOVD L3, libcall_r1(L2) 240 MOVD (-8-5*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3 241 MOVD L3, libcall_r2(L2) 242 243 // restore scratch 244 MOVD $(m_mOS+mOS_scratch)(L1), L2 245 MOVD (-8-6*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3 246 MOVD L3, 0(L2) 247 MOVD (-8-7*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3 248 MOVD L3, 8(L2) 249 MOVD (-8-8*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3 250 MOVD L3, 16(L2) 251 MOVD (-8-9*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3 252 MOVD L3, 24(L2) 253 MOVD (-8-10*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3 254 MOVD L3, 32(L2) 255 MOVD (-8-11*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3 256 MOVD L3, 40(L2) 257 258 // restore errno 259 MOVD (m_mOS+mOS_perrno)(L1), L2 260 MOVD (-8-12*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), L3 261 MOVW L3, 0(L2) 262 263 // restore g 264 MOVD (-8-0*8+SIGTRAMP_FRAME+FIXED_FRAME)(BSP), g 265 CALL runtime·save_g(SB) 266 267 exit: 268 // kernel will restore registers 269 RET 270 271 272 // Runs on OS stack, called from runtime·usleep1_go. 273 TEXT runtime·usleep2(SB),NOSPLIT|REGWIN,$0 274 MOVW us+0(FP), O0 275 MOVD $libc_usleep(SB), I3 276 CALL I3 277 RET 278 279 // Runs on OS stack, called from runtime·osyield. 280 TEXT runtime·osyield1(SB),NOSPLIT|REGWIN,$0 281 MOVD $libc_sched_yield(SB), I3 282 CALL I3 283 RET