Home | History | Annotate | Download | only in runtime
      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 runtimewalltime(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,$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	runtimemstart(SB)
    228 
    229 	// Exit the thread.
    230 	MOVW	$0, R0
    231 	MOVW	R0, 4(R13)
    232 	CALL	runtimeexits(SB)
    233 	JMP	0(PC)
    234 
    235 //func sigtramp(ureg, note unsafe.Pointer)
    236 TEXT runtimesigtramp(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	runtimebadsignal2(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	runtimesighandler(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	runtimenoted(SB)
    275 	RET
    276 
    277 //func sigpanictramp()
    278 TEXT  runtimesigpanictramp(SB),NOSPLIT,$0-0
    279 	MOVW.W	R0, -4(R13)
    280 	B	runtimesigpanic(SB)
    281 
    282 //func setfpmasks()
    283 // Only used by the 64-bit runtime.
    284 TEXT runtimesetfpmasks(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/
    295 TEXT runtimeerrstr(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 
    313 TEXT publicationBarrier(SB),NOSPLIT,$-4-0
    314 	B	runtimearmPublicationBarrier(SB)
    315 
    316 // never called (cgo not supported)
    317 TEXT runtimeread_tls_fallback(SB),NOSPLIT,$-4
    318 	MOVW	$0, R0
    319 	MOVW	R0, (R0)
    320 	RET
    321