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 55 TEXT runtimeopen(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 62 TEXT runtimepread(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 69 TEXT runtimepwrite(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 76 TEXT runtimeseek(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 90 TEXT runtimeclosefd(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) 97 TEXT runtimeexits(SB),NOSPLIT,$0-4 98 MOVW $SYS_EXITS, R0 99 SWI 0 100 RET 101 102 //func brk_(addr unsafe.Pointer) int32 103 TEXT runtimebrk_(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 110 TEXT runtimesleep(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 117 TEXT runtimeplan9_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 124 TEXT runtimeplan9_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 131 TEXT runtimensec(SB),NOSPLIT,$-4-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 // time.now() (sec int64, nsec int32) 142 TEXT timenow(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 182 TEXT runtimenotify(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 189 TEXT runtimenoted(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 196 TEXT runtimeplan9_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 203 TEXT runtimerfork(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) 210 TEXT runtimetstart_plan9(SB),NOSPLIT,$0-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 runtimemstart(SB) 228 229 MOVW $0x1234, R0 230 MOVW R0, 0(R0) // not reached 231 RET 232 233 //func sigtramp(ureg, note unsafe.Pointer) 234 TEXT runtimesigtramp(SB),NOSPLIT,$0-8 235 // check that g and m exist 236 CMP $0, g 237 BEQ 4(PC) 238 MOVW g_m(g), R0 239 CMP $0, R0 240 BNE 2(PC) 241 BL runtimebadsignal2(SB) // will exit 242 243 // save args 244 MOVW ureg+0(FP), R1 245 MOVW note+4(FP), R2 246 247 // change stack 248 MOVW m_gsignal(R0), R3 249 MOVW (g_stack+stack_hi)(R3), R13 250 251 // make room for args, retval and g 252 SUB $24, R13 253 254 // save g 255 MOVW g, R3 256 MOVW R3, 20(R13) 257 258 // g = m->gsignal 259 MOVW m_gsignal(R0), g 260 261 // load args and call sighandler 262 ADD $4,R13,R5 263 MOVM.IA [R1-R3], (R5) 264 BL runtimesighandler(SB) 265 MOVW 16(R13), R0 // retval 266 267 // restore g 268 MOVW 20(R13), g 269 270 // call noted(R0) 271 MOVW R0, 4(R13) 272 BL runtimenoted(SB) 273 RET 274 275 //func sigpanictramp() 276 TEXT runtimesigpanictramp(SB),NOSPLIT,$0-0 277 MOVW.W R0, -4(R13) 278 B runtimesigpanic(SB) 279 280 //func setfpmasks() 281 // Only used by the 64-bit runtime. 282 TEXT runtimesetfpmasks(SB),NOSPLIT,$0 283 RET 284 285 #define ERRMAX 128 /* from os_plan9.h */ 286 287 // func errstr() string 288 // Only used by package syscall. 289 // Grab error string due to a syscall made 290 // in entersyscall mode, without going 291 // through the allocator (issue 4994). 292 // See ../syscall/asm_plan9_arm.s:/Syscall/ 293 TEXT runtimeerrstr(SB),NOSPLIT,$0-8 294 MOVW g_m(g), R0 295 MOVW (m_mOS+mOS_errstr)(R0), R1 296 MOVW R1, ret_base+0(FP) 297 MOVW $ERRMAX, R2 298 MOVW R2, ret_len+4(FP) 299 MOVW $SYS_ERRSTR, R0 300 SWI 0 301 MOVW R1, R2 302 MOVBU 0(R2), R0 303 CMP $0, R0 304 BEQ 3(PC) 305 ADD $1, R2 306 B -4(PC) 307 SUB R1, R2 308 MOVW R2, ret_len+4(FP) 309 RET 310 311 TEXT publicationBarrier(SB),NOSPLIT,$-4-0 312 B runtimearmPublicationBarrier(SB) 313 314 // never called (cgo not supported) 315 TEXT runtimeread_tls_fallback(SB),NOSPLIT,$-4 316 MOVW $0, R0 317 MOVW R0, (R0) 318 RET 319