1 // Copyright 2014 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 #include "syscall_nacl.h" 9 10 #define NACL_SYSCALL(code) \ 11 MOVW $(0x10000 + ((code)<<5)), R8; BL (R8) 12 13 TEXT runtimeexit(SB),NOSPLIT,$0 14 MOVW code+0(FP), R0 15 NACL_SYSCALL(SYS_exit) 16 RET 17 18 TEXT runtimeexit1(SB),NOSPLIT,$0 19 MOVW code+0(FP), R0 20 NACL_SYSCALL(SYS_thread_exit) 21 RET 22 23 TEXT runtimeopen(SB),NOSPLIT,$0 24 MOVW name+0(FP), R0 25 MOVW name+0(FP), R1 26 MOVW name+0(FP), R2 27 NACL_SYSCALL(SYS_open) 28 MOVW R0, ret+12(FP) 29 RET 30 31 TEXT runtimeclosefd(SB),NOSPLIT,$0 32 MOVW fd+0(FP), R0 33 NACL_SYSCALL(SYS_close) 34 MOVW R0, ret+4(FP) 35 RET 36 37 TEXT runtimeread(SB),NOSPLIT,$0 38 MOVW fd+0(FP), R0 39 MOVW p+4(FP), R1 40 MOVW n+8(FP), R2 41 NACL_SYSCALL(SYS_read) 42 MOVW R0, ret+12(FP) 43 RET 44 45 // func naclWrite(fd int, b []byte) int 46 TEXT syscallnaclWrite(SB),NOSPLIT,$0 47 MOVW arg1+0(FP), R0 48 MOVW arg2+4(FP), R1 49 MOVW arg3+8(FP), R2 50 NACL_SYSCALL(SYS_write) 51 MOVW R0, ret+16(FP) 52 RET 53 54 TEXT runtimewrite(SB),NOSPLIT,$0 55 MOVW fd+0(FP), R0 56 MOVW p+4(FP), R1 57 MOVW n+8(FP), R2 58 NACL_SYSCALL(SYS_write) 59 MOVW R0, ret+12(FP) 60 RET 61 62 TEXT runtimenacl_exception_stack(SB),NOSPLIT,$0 63 MOVW p+0(FP), R0 64 MOVW size+4(FP), R1 65 NACL_SYSCALL(SYS_exception_stack) 66 MOVW R0, ret+8(FP) 67 RET 68 69 TEXT runtimenacl_exception_handler(SB),NOSPLIT,$0 70 MOVW fn+0(FP), R0 71 MOVW arg+4(FP), R1 72 NACL_SYSCALL(SYS_exception_handler) 73 MOVW R0, ret+8(FP) 74 RET 75 76 TEXT runtimenacl_sem_create(SB),NOSPLIT,$0 77 MOVW flag+0(FP), R0 78 NACL_SYSCALL(SYS_sem_create) 79 MOVW R0, ret+4(FP) 80 RET 81 82 TEXT runtimenacl_sem_wait(SB),NOSPLIT,$0 83 MOVW sem+0(FP), R0 84 NACL_SYSCALL(SYS_sem_wait) 85 MOVW R0, ret+4(FP) 86 RET 87 88 TEXT runtimenacl_sem_post(SB),NOSPLIT,$0 89 MOVW sem+0(FP), R0 90 NACL_SYSCALL(SYS_sem_post) 91 MOVW R0, ret+4(FP) 92 RET 93 94 TEXT runtimenacl_mutex_create(SB),NOSPLIT,$0 95 MOVW flag+0(FP), R0 96 NACL_SYSCALL(SYS_mutex_create) 97 MOVW R0, ret+4(FP) 98 RET 99 100 TEXT runtimenacl_mutex_lock(SB),NOSPLIT,$0 101 MOVW mutex+0(FP), R0 102 NACL_SYSCALL(SYS_mutex_lock) 103 MOVW R0, ret+4(FP) 104 RET 105 106 TEXT runtimenacl_mutex_trylock(SB),NOSPLIT,$0 107 MOVW mutex+0(FP), R0 108 NACL_SYSCALL(SYS_mutex_trylock) 109 MOVW R0, ret+4(FP) 110 RET 111 112 TEXT runtimenacl_mutex_unlock(SB),NOSPLIT,$0 113 MOVW mutex+0(FP), R0 114 NACL_SYSCALL(SYS_mutex_unlock) 115 MOVW R0, ret+4(FP) 116 RET 117 118 TEXT runtimenacl_cond_create(SB),NOSPLIT,$0 119 MOVW flag+0(FP), R0 120 NACL_SYSCALL(SYS_cond_create) 121 MOVW R0, ret+4(FP) 122 RET 123 124 TEXT runtimenacl_cond_wait(SB),NOSPLIT,$0 125 MOVW cond+0(FP), R0 126 MOVW n+4(FP), R1 127 NACL_SYSCALL(SYS_cond_wait) 128 MOVW R0, ret+8(FP) 129 RET 130 131 TEXT runtimenacl_cond_signal(SB),NOSPLIT,$0 132 MOVW cond+0(FP), R0 133 NACL_SYSCALL(SYS_cond_signal) 134 MOVW R0, ret+4(FP) 135 RET 136 137 TEXT runtimenacl_cond_broadcast(SB),NOSPLIT,$0 138 MOVW cond+0(FP), R0 139 NACL_SYSCALL(SYS_cond_broadcast) 140 MOVW R0, ret+4(FP) 141 RET 142 143 TEXT runtimenacl_cond_timed_wait_abs(SB),NOSPLIT,$0 144 MOVW cond+0(FP), R0 145 MOVW lock+4(FP), R1 146 MOVW ts+8(FP), R2 147 NACL_SYSCALL(SYS_cond_timed_wait_abs) 148 MOVW R0, ret+12(FP) 149 RET 150 151 TEXT runtimenacl_thread_create(SB),NOSPLIT,$0 152 MOVW fn+0(FP), R0 153 MOVW stk+4(FP), R1 154 MOVW tls+8(FP), R2 155 MOVW xx+12(FP), R3 156 NACL_SYSCALL(SYS_thread_create) 157 MOVW R0, ret+16(FP) 158 RET 159 160 TEXT runtimemstart_nacl(SB),NOSPLIT,$0 161 MOVW 0(R9), R0 // TLS 162 MOVW -8(R0), R1 // g 163 MOVW -4(R0), R2 // m 164 MOVW R2, g_m(R1) 165 MOVW R1, g 166 B runtimemstart(SB) 167 168 TEXT runtimenacl_nanosleep(SB),NOSPLIT,$0 169 MOVW ts+0(FP), R0 170 MOVW extra+4(FP), R1 171 NACL_SYSCALL(SYS_nanosleep) 172 MOVW R0, ret+8(FP) 173 RET 174 175 TEXT runtimeosyield(SB),NOSPLIT,$0 176 NACL_SYSCALL(SYS_sched_yield) 177 RET 178 179 TEXT runtimemmap(SB),NOSPLIT,$8 180 MOVW addr+0(FP), R0 181 MOVW n+4(FP), R1 182 MOVW prot+8(FP), R2 183 MOVW flags+12(FP), R3 184 MOVW fd+16(FP), R4 185 // arg6:offset should be passed as a pointer (to int64) 186 MOVW off+20(FP), R5 187 MOVW R5, 4(R13) 188 MOVW $0, R6 189 MOVW R6, 8(R13) 190 MOVW $4(R13), R5 191 MOVM.DB.W [R4,R5], (R13) // arg5 and arg6 are passed on stack 192 NACL_SYSCALL(SYS_mmap) 193 MOVM.IA.W (R13), [R4, R5] 194 CMP $-4095, R0 195 RSB.HI $0, R0 196 MOVW R0, ret+24(FP) 197 RET 198 199 TEXT timenow(SB),NOSPLIT,$16 200 MOVW $0, R0 // real time clock 201 MOVW $4(R13), R1 202 NACL_SYSCALL(SYS_clock_gettime) 203 MOVW 4(R13), R0 // low 32-bit sec 204 MOVW 8(R13), R1 // high 32-bit sec 205 MOVW 12(R13), R2 // nsec 206 MOVW R0, sec+0(FP) 207 MOVW R1, sec+4(FP) 208 MOVW R2, sec+8(FP) 209 RET 210 211 TEXT syscallnow(SB),NOSPLIT,$0 212 B timenow(SB) 213 214 TEXT runtimenacl_clock_gettime(SB),NOSPLIT,$0 215 MOVW arg1+0(FP), R0 216 MOVW arg2+4(FP), R1 217 NACL_SYSCALL(SYS_clock_gettime) 218 MOVW R0, ret+8(FP) 219 RET 220 221 // int64 nanotime(void) so really 222 // void nanotime(int64 *nsec) 223 TEXT runtimenanotime(SB),NOSPLIT,$16 224 MOVW $0, R0 // real time clock 225 MOVW $4(R13), R1 226 NACL_SYSCALL(SYS_clock_gettime) 227 MOVW 4(R13), R0 // low 32-bit sec 228 MOVW 8(R13), R1 // high 32-bit sec (ignored for now) 229 MOVW 12(R13), R2 // nsec 230 MOVW $1000000000, R3 231 MULLU R0, R3, (R1, R0) 232 MOVW $0, R4 233 ADD.S R2, R0 234 ADC R4, R1 235 MOVW R0, ret_lo+0(FP) 236 MOVW R1, ret_hi+4(FP) 237 RET 238 239 TEXT runtimesigtramp(SB),NOSPLIT,$80 240 // load g from thread context 241 MOVW $ctxt+-4(FP), R0 242 MOVW (16*4+10*4)(R0), g 243 244 // check that g exists 245 CMP $0, g 246 BNE 4(PC) 247 MOVW $runtimebadsignal2(SB), R11 248 BL (R11) 249 RET 250 251 // save g 252 MOVW g, R3 253 MOVW g, 20(R13) 254 255 // g = m->gsignal 256 MOVW g_m(g), R8 257 MOVW m_gsignal(R8), g 258 259 // copy arguments for call to sighandler 260 MOVW $11, R0 261 MOVW R0, 4(R13) // signal 262 MOVW $0, R0 263 MOVW R0, 8(R13) // siginfo 264 MOVW $ctxt+-4(FP), R0 265 MOVW R0, 12(R13) // context 266 MOVW R3, 16(R13) // g 267 268 BL runtimesighandler(SB) 269 270 // restore g 271 MOVW 20(R13), g 272 273 // Enable exceptions again. 274 NACL_SYSCALL(SYS_exception_clear_flag) 275 276 // Restore registers as best we can. Impossible to do perfectly. 277 // See comment in sys_nacl_386.s for extended rationale. 278 MOVW $ctxt+-4(FP), R1 279 ADD $64, R1 280 MOVW (0*4)(R1), R0 281 MOVW (2*4)(R1), R2 282 MOVW (3*4)(R1), R3 283 MOVW (4*4)(R1), R4 284 MOVW (5*4)(R1), R5 285 MOVW (6*4)(R1), R6 286 MOVW (7*4)(R1), R7 287 MOVW (8*4)(R1), R8 288 // cannot write to R9 289 MOVW (10*4)(R1), g 290 MOVW (11*4)(R1), R11 291 MOVW (12*4)(R1), R12 292 MOVW (13*4)(R1), R13 293 MOVW (14*4)(R1), R14 294 MOVW (15*4)(R1), R1 295 B (R1) 296 297 nog: 298 MOVW $0, R0 299 RET 300 301 TEXT runtimenacl_sysinfo(SB),NOSPLIT,$16 302 RET 303 304 // func getRandomData([]byte) 305 TEXT runtimegetRandomData(SB),NOSPLIT,$0-12 306 MOVW arg_base+0(FP), R0 307 MOVW arg_len+4(FP), R1 308 NACL_SYSCALL(SYS_get_random_bytes) 309 RET 310 311 // Likewise, this is only valid for ARMv7+, but that's okay. 312 TEXT publicationBarrier(SB),NOSPLIT,$-4-0 313 B runtimearmPublicationBarrier(SB) 314 315 TEXT runtimeread_tls_fallback(SB),NOSPLIT,$-4 316 WORD $0xe7fedef0 // NACL_INSTR_ARM_ABORT_NOW (UDF #0xEDE0) 317