1// Copyright 2015 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 "go_tls.h" 7#include "textflag.h" 8 9// from ../syscall/zsysnum_plan9.go 10 11#define SYS_SYSR1 0 12#define SYS_BIND 2 13#define SYS_CHDIR 3 14#define SYS_CLOSE 4 15#define SYS_DUP 5 16#define SYS_ALARM 6 17#define SYS_EXEC 7 18#define SYS_EXITS 8 19#define SYS_FAUTH 10 20#define SYS_SEGBRK 12 21#define SYS_OPEN 14 22#define SYS_OSEEK 16 23#define SYS_SLEEP 17 24#define SYS_RFORK 19 25#define SYS_PIPE 21 26#define SYS_CREATE 22 27#define SYS_FD2PATH 23 28#define SYS_BRK_ 24 29#define SYS_REMOVE 25 30#define SYS_NOTIFY 28 31#define SYS_NOTED 29 32#define SYS_SEGATTACH 30 33#define SYS_SEGDETACH 31 34#define SYS_SEGFREE 32 35#define SYS_SEGFLUSH 33 36#define SYS_RENDEZVOUS 34 37#define SYS_UNMOUNT 35 38#define SYS_SEMACQUIRE 37 39#define SYS_SEMRELEASE 38 40#define SYS_SEEK 39 41#define SYS_FVERSION 40 42#define SYS_ERRSTR 41 43#define SYS_STAT 42 44#define SYS_FSTAT 43 45#define SYS_WSTAT 44 46#define SYS_FWSTAT 45 47#define SYS_MOUNT 46 48#define SYS_AWAIT 47 49#define SYS_PREAD 50 50#define SYS_PWRITE 51 51#define SYS_TSEMACQUIRE 52 52#define SYS_NSEC 53 53 54//func open(name *byte, mode, perm int32) int32 55TEXT runtime·open(SB),NOSPLIT,$0-16 56 MOVW $SYS_OPEN, R0 57 SWI $0 58 MOVW R0, ret+12(FP) 59 RET 60 61//func pread(fd int32, buf unsafe.Pointer, nbytes int32, offset int64) int32 62TEXT runtime·pread(SB),NOSPLIT,$0-24 63 MOVW $SYS_PREAD, R0 64 SWI $0 65 MOVW R0, ret+20(FP) 66 RET 67 68//func pwrite(fd int32, buf unsafe.Pointer, nbytes int32, offset int64) int32 69TEXT runtime·pwrite(SB),NOSPLIT,$0-24 70 MOVW $SYS_PWRITE, R0 71 SWI $0 72 MOVW R0, ret+20(FP) 73 RET 74 75//func seek(fd int32, offset int64, whence int32) int64 76TEXT runtime·seek(SB),NOSPLIT,$0-24 77 MOVW $ret_lo+16(FP), R0 78 MOVW 0(R13), R1 79 MOVW R0, 0(R13) 80 MOVW.W R1, -4(R13) 81 MOVW $SYS_SEEK, R0 82 SWI $0 83 MOVW.W R1, 4(R13) 84 CMP $-1, R0 85 MOVW.EQ R0, ret_lo+16(FP) 86 MOVW.EQ R0, ret_hi+20(FP) 87 RET 88 89//func closefd(fd int32) int32 90TEXT runtime·closefd(SB),NOSPLIT,$0-8 91 MOVW $SYS_CLOSE, R0 92 SWI $0 93 MOVW R0, ret+4(FP) 94 RET 95 96//func exits(msg *byte) 97TEXT runtime·exits(SB),NOSPLIT,$0-4 98 MOVW $SYS_EXITS, R0 99 SWI $0 100 RET 101 102//func brk_(addr unsafe.Pointer) int32 103TEXT runtime·brk_(SB),NOSPLIT,$0-8 104 MOVW $SYS_BRK_, R0 105 SWI $0 106 MOVW R0, ret+4(FP) 107 RET 108 109//func sleep(ms int32) int32 110TEXT runtime·sleep(SB),NOSPLIT,$0-8 111 MOVW $SYS_SLEEP, R0 112 SWI $0 113 MOVW R0, ret+4(FP) 114 RET 115 116//func plan9_semacquire(addr *uint32, block int32) int32 117TEXT runtime·plan9_semacquire(SB),NOSPLIT,$0-12 118 MOVW $SYS_SEMACQUIRE, R0 119 SWI $0 120 MOVW R0, ret+8(FP) 121 RET 122 123//func plan9_tsemacquire(addr *uint32, ms int32) int32 124TEXT runtime·plan9_tsemacquire(SB),NOSPLIT,$0-12 125 MOVW $SYS_TSEMACQUIRE, R0 126 SWI $0 127 MOVW R0, ret+8(FP) 128 RET 129 130//func nsec(*int64) int64 131TEXT runtime·nsec(SB),NOSPLIT|NOFRAME,$0-12 132 MOVW $SYS_NSEC, R0 133 SWI $0 134 MOVW arg+0(FP), R1 135 MOVW 0(R1), R0 136 MOVW R0, ret_lo+4(FP) 137 MOVW 4(R1), R0 138 MOVW R0, ret_hi+8(FP) 139 RET 140 141// func walltime() (sec int64, nsec int32) 142TEXT runtime·walltime(SB),NOSPLIT,$12-12 143 // use nsec system call to get current time in nanoseconds 144 MOVW $sysnsec_lo-8(SP), R0 // destination addr 145 MOVW R0,res-12(SP) 146 MOVW $SYS_NSEC, R0 147 SWI $0 148 MOVW sysnsec_lo-8(SP), R1 // R1:R2 = nsec 149 MOVW sysnsec_hi-4(SP), R2 150 151 // multiply nanoseconds by reciprocal of 10**9 (scaled by 2**61) 152 // to get seconds (96 bit scaled result) 153 MOVW $0x89705f41, R3 // 2**61 * 10**-9 154 MULLU R1,R3,(R6,R5) // R5:R6:R7 = R1:R2 * R3 155 MOVW $0,R7 156 MULALU R2,R3,(R7,R6) 157 158 // unscale by discarding low 32 bits, shifting the rest by 29 159 MOVW R6>>29,R6 // R6:R7 = (R5:R6:R7 >> 61) 160 ORR R7<<3,R6 161 MOVW R7>>29,R7 162 163 // subtract (10**9 * sec) from nsec to get nanosecond remainder 164 MOVW $1000000000, R5 // 10**9 165 MULLU R6,R5,(R9,R8) // R8:R9 = R6:R7 * R5 166 MULA R7,R5,R9,R9 167 SUB.S R8,R1 // R1:R2 -= R8:R9 168 SBC R9,R2 169 170 // because reciprocal was a truncated repeating fraction, quotient 171 // may be slightly too small -- adjust to make remainder < 10**9 172 CMP R5,R1 // if remainder > 10**9 173 SUB.HS R5,R1 // remainder -= 10**9 174 ADD.HS $1,R6 // sec += 1 175 176 MOVW R6,sec_lo+0(FP) 177 MOVW R7,sec_hi+4(FP) 178 MOVW R1,nsec+8(FP) 179 RET 180 181//func notify(fn unsafe.Pointer) int32 182TEXT runtime·notify(SB),NOSPLIT,$0-8 183 MOVW $SYS_NOTIFY, R0 184 SWI $0 185 MOVW R0, ret+4(FP) 186 RET 187 188//func noted(mode int32) int32 189TEXT runtime·noted(SB),NOSPLIT,$0-8 190 MOVW $SYS_NOTED, R0 191 SWI $0 192 MOVW R0, ret+4(FP) 193 RET 194 195//func plan9_semrelease(addr *uint32, count int32) int32 196TEXT runtime·plan9_semrelease(SB),NOSPLIT,$0-12 197 MOVW $SYS_SEMRELEASE, R0 198 SWI $0 199 MOVW R0, ret+8(FP) 200 RET 201 202//func rfork(flags int32) int32 203TEXT runtime·rfork(SB),NOSPLIT,$0-8 204 MOVW $SYS_RFORK, R0 205 SWI $0 206 MOVW R0, ret+4(FP) 207 RET 208 209//func tstart_plan9(newm *m) 210TEXT runtime·tstart_plan9(SB),NOSPLIT,$4-4 211 MOVW newm+0(FP), R1 212 MOVW m_g0(R1), g 213 214 // Layout new m scheduler stack on os stack. 215 MOVW R13, R0 216 MOVW R0, g_stack+stack_hi(g) 217 SUB $(64*1024), R0 218 MOVW R0, (g_stack+stack_lo)(g) 219 MOVW R0, g_stackguard0(g) 220 MOVW R0, g_stackguard1(g) 221 222 // Initialize procid from TOS struct. 223 MOVW _tos(SB), R0 224 MOVW 48(R0), R0 225 MOVW R0, m_procid(R1) // save pid as m->procid 226 227 BL runtime·mstart(SB) 228 229 // Exit the thread. 230 MOVW $0, R0 231 MOVW R0, 4(R13) 232 CALL runtime·exits(SB) 233 JMP 0(PC) 234 235//func sigtramp(ureg, note unsafe.Pointer) 236TEXT runtime·sigtramp(SB),NOSPLIT,$0-8 237 // check that g and m exist 238 CMP $0, g 239 BEQ 4(PC) 240 MOVW g_m(g), R0 241 CMP $0, R0 242 BNE 2(PC) 243 BL runtime·badsignal2(SB) // will exit 244 245 // save args 246 MOVW ureg+0(FP), R1 247 MOVW note+4(FP), R2 248 249 // change stack 250 MOVW m_gsignal(R0), R3 251 MOVW (g_stack+stack_hi)(R3), R13 252 253 // make room for args, retval and g 254 SUB $24, R13 255 256 // save g 257 MOVW g, R3 258 MOVW R3, 20(R13) 259 260 // g = m->gsignal 261 MOVW m_gsignal(R0), g 262 263 // load args and call sighandler 264 ADD $4,R13,R5 265 MOVM.IA [R1-R3], (R5) 266 BL runtime·sighandler(SB) 267 MOVW 16(R13), R0 // retval 268 269 // restore g 270 MOVW 20(R13), g 271 272 // call noted(R0) 273 MOVW R0, 4(R13) 274 BL runtime·noted(SB) 275 RET 276 277//func sigpanictramp() 278TEXT runtime·sigpanictramp(SB),NOSPLIT,$0-0 279 MOVW.W R0, -4(R13) 280 B runtime·sigpanic(SB) 281 282//func setfpmasks() 283// Only used by the 64-bit runtime. 284TEXT runtime·setfpmasks(SB),NOSPLIT,$0 285 RET 286 287#define ERRMAX 128 /* from os_plan9.h */ 288 289// func errstr() string 290// Only used by package syscall. 291// Grab error string due to a syscall made 292// in entersyscall mode, without going 293// through the allocator (issue 4994). 294// See ../syscall/asm_plan9_arm.s:/·Syscall/ 295TEXT runtime·errstr(SB),NOSPLIT,$0-8 296 MOVW g_m(g), R0 297 MOVW (m_mOS+mOS_errstr)(R0), R1 298 MOVW R1, ret_base+0(FP) 299 MOVW $ERRMAX, R2 300 MOVW R2, ret_len+4(FP) 301 MOVW $SYS_ERRSTR, R0 302 SWI $0 303 MOVW R1, R2 304 MOVBU 0(R2), R0 305 CMP $0, R0 306 BEQ 3(PC) 307 ADD $1, R2 308 B -4(PC) 309 SUB R1, R2 310 MOVW R2, ret_len+4(FP) 311 RET 312 313TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0 314 B runtime·armPublicationBarrier(SB) 315 316// never called (cgo not supported) 317TEXT runtime·read_tls_fallback(SB),NOSPLIT|NOFRAME,$0 318 MOVW $0, R0 319 MOVW R0, (R0) 320 RET 321