summaryrefslogtreecommitdiffstats
path: root/src/runtime/sys_plan9_arm.s
blob: 53430857437793c2877c9f7cecf1d97c573dc09c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "go_asm.h"
#include "go_tls.h"
#include "textflag.h"

// from ../syscall/zsysnum_plan9.go

#define SYS_SYSR1       0
#define SYS_BIND        2
#define SYS_CHDIR       3
#define SYS_CLOSE       4
#define SYS_DUP         5
#define SYS_ALARM       6
#define SYS_EXEC        7
#define SYS_EXITS       8
#define SYS_FAUTH       10
#define SYS_SEGBRK      12
#define SYS_OPEN        14
#define SYS_OSEEK       16
#define SYS_SLEEP       17
#define SYS_RFORK       19
#define SYS_PIPE        21
#define SYS_CREATE      22
#define SYS_FD2PATH     23
#define SYS_BRK_        24
#define SYS_REMOVE      25
#define SYS_NOTIFY      28
#define SYS_NOTED       29
#define SYS_SEGATTACH   30
#define SYS_SEGDETACH   31
#define SYS_SEGFREE     32
#define SYS_SEGFLUSH    33
#define SYS_RENDEZVOUS  34
#define SYS_UNMOUNT     35
#define SYS_SEMACQUIRE  37
#define SYS_SEMRELEASE  38
#define SYS_SEEK        39
#define SYS_FVERSION    40
#define SYS_ERRSTR      41
#define SYS_STAT        42
#define SYS_FSTAT       43
#define SYS_WSTAT       44
#define SYS_FWSTAT      45
#define SYS_MOUNT       46
#define SYS_AWAIT       47
#define SYS_PREAD       50
#define SYS_PWRITE      51
#define SYS_TSEMACQUIRE 52
#define SYS_NSEC        53

//func open(name *byte, mode, perm int32) int32
TEXT runtime·open(SB),NOSPLIT,$0-16
	MOVW    $SYS_OPEN, R0
	SWI	$0
	MOVW	R0, ret+12(FP)
	RET

//func pread(fd int32, buf unsafe.Pointer, nbytes int32, offset int64) int32
TEXT runtime·pread(SB),NOSPLIT,$0-24
	MOVW    $SYS_PREAD, R0
	SWI	$0
	MOVW	R0, ret+20(FP)
	RET

//func pwrite(fd int32, buf unsafe.Pointer, nbytes int32, offset int64) int32
TEXT runtime·pwrite(SB),NOSPLIT,$0-24
	MOVW    $SYS_PWRITE, R0
	SWI	$0
	MOVW	R0, ret+20(FP)
	RET

//func seek(fd int32, offset int64, whence int32) int64
TEXT runtime·seek(SB),NOSPLIT,$0-24
	MOVW	$ret_lo+16(FP), R0
	MOVW	0(R13), R1
	MOVW	R0, 0(R13)
	MOVW.W	R1, -4(R13)
	MOVW	$SYS_SEEK, R0
	SWI	$0
	MOVW.W	R1, 4(R13)
	CMP	$-1, R0
	MOVW.EQ	R0, ret_lo+16(FP)
	MOVW.EQ	R0, ret_hi+20(FP)
	RET

//func closefd(fd int32) int32
TEXT runtime·closefd(SB),NOSPLIT,$0-8
	MOVW	$SYS_CLOSE, R0
	SWI	$0
	MOVW	R0, ret+4(FP)
	RET

//func exits(msg *byte)
TEXT runtime·exits(SB),NOSPLIT,$0-4
	MOVW    $SYS_EXITS, R0
	SWI	$0
	RET

//func brk_(addr unsafe.Pointer) int32
TEXT runtime·brk_(SB),NOSPLIT,$0-8
	MOVW    $SYS_BRK_, R0
	SWI	$0
	MOVW	R0, ret+4(FP)
	RET

//func sleep(ms int32) int32
TEXT runtime·sleep(SB),NOSPLIT,$0-8
	MOVW    $SYS_SLEEP, R0
	SWI	$0
	MOVW	R0, ret+4(FP)
	RET

//func plan9_semacquire(addr *uint32, block int32) int32
TEXT runtime·plan9_semacquire(SB),NOSPLIT,$0-12
	MOVW	$SYS_SEMACQUIRE, R0
	SWI	$0
	MOVW	R0, ret+8(FP)
	RET

//func plan9_tsemacquire(addr *uint32, ms int32) int32
TEXT runtime·plan9_tsemacquire(SB),NOSPLIT,$0-12
	MOVW	$SYS_TSEMACQUIRE, R0
	SWI	$0
	MOVW	R0, ret+8(FP)
	RET

//func nsec(*int64) int64
TEXT runtime·nsec(SB),NOSPLIT|NOFRAME,$0-12
	MOVW	$SYS_NSEC, R0
	SWI	$0
	MOVW	arg+0(FP), R1
	MOVW	0(R1), R0
	MOVW	R0, ret_lo+4(FP)
	MOVW	4(R1), R0
	MOVW	R0, ret_hi+8(FP)
	RET

// func walltime() (sec int64, nsec int32)
TEXT runtime·walltime(SB),NOSPLIT,$12-12
	// use nsec system call to get current time in nanoseconds
	MOVW	$sysnsec_lo-8(SP), R0	// destination addr
	MOVW	R0,res-12(SP)
	MOVW	$SYS_NSEC, R0
	SWI	$0
	MOVW	sysnsec_lo-8(SP), R1	// R1:R2 = nsec
	MOVW	sysnsec_hi-4(SP), R2

	// multiply nanoseconds by reciprocal of 10**9 (scaled by 2**61)
	// to get seconds (96 bit scaled result)
	MOVW	$0x89705f41, R3		// 2**61 * 10**-9
	MULLU	R1,R3,(R6,R5)		// R5:R6:R7 = R1:R2 * R3
	MOVW	$0,R7
	MULALU	R2,R3,(R7,R6)

	// unscale by discarding low 32 bits, shifting the rest by 29
	MOVW	R6>>29,R6		// R6:R7 = (R5:R6:R7 >> 61)
	ORR	R7<<3,R6
	MOVW	R7>>29,R7

	// subtract (10**9 * sec) from nsec to get nanosecond remainder
	MOVW	$1000000000, R5		// 10**9
	MULLU	R6,R5,(R9,R8)		// R8:R9 = R6:R7 * R5
	MULA	R7,R5,R9,R9
	SUB.S	R8,R1			// R1:R2 -= R8:R9
	SBC	R9,R2

	// because reciprocal was a truncated repeating fraction, quotient
	// may be slightly too small -- adjust to make remainder < 10**9
	CMP	R5,R1			// if remainder > 10**9
	SUB.HS	R5,R1			//    remainder -= 10**9
	ADD.HS	$1,R6			//    sec += 1

	MOVW	R6,sec_lo+0(FP)
	MOVW	R7,sec_hi+4(FP)
	MOVW	R1,nsec+8(FP)
	RET

//func notify(fn unsafe.Pointer) int32
TEXT runtime·notify(SB),NOSPLIT,$0-8
	MOVW	$SYS_NOTIFY, R0
	SWI	$0
	MOVW	R0, ret+4(FP)
	RET

//func noted(mode int32) int32
TEXT runtime·noted(SB),NOSPLIT,$0-8
	MOVW	$SYS_NOTED, R0
	SWI	$0
	MOVW	R0, ret+4(FP)
	RET

//func plan9_semrelease(addr *uint32, count int32) int32
TEXT runtime·plan9_semrelease(SB),NOSPLIT,$0-12
	MOVW	$SYS_SEMRELEASE, R0
	SWI	$0
	MOVW	R0, ret+8(FP)
	RET

//func rfork(flags int32) int32
TEXT runtime·rfork(SB),NOSPLIT,$0-8
	MOVW	$SYS_RFORK, R0
	SWI	$0
	MOVW	R0, ret+4(FP)
	RET

//func tstart_plan9(newm *m)
TEXT runtime·tstart_plan9(SB),NOSPLIT,$4-4
	MOVW	newm+0(FP), R1
	MOVW	m_g0(R1), g

	// Layout new m scheduler stack on os stack.
	MOVW	R13, R0
	MOVW	R0, g_stack+stack_hi(g)
	SUB	$(64*1024), R0
	MOVW	R0, (g_stack+stack_lo)(g)
	MOVW	R0, g_stackguard0(g)
	MOVW	R0, g_stackguard1(g)

	// Initialize procid from TOS struct.
	MOVW	_tos(SB), R0
	MOVW	48(R0), R0
	MOVW	R0, m_procid(R1)	// save pid as m->procid

	BL	runtime·mstart(SB)

	// Exit the thread.
	MOVW	$0, R0
	MOVW	R0, 4(R13)
	CALL	runtime·exits(SB)
	JMP	0(PC)

//func sigtramp(ureg, note unsafe.Pointer)
TEXT runtime·sigtramp(SB),NOSPLIT,$0-8
	// check that g and m exist
	CMP	$0, g
	BEQ	4(PC)
	MOVW	g_m(g), R0
	CMP 	$0, R0
	BNE	2(PC)
	BL	runtime·badsignal2(SB)	// will exit

	// save args
	MOVW	ureg+0(FP), R1
	MOVW	note+4(FP), R2

	// change stack
	MOVW	m_gsignal(R0), R3
	MOVW	(g_stack+stack_hi)(R3), R13

	// make room for args, retval and g
	SUB	$24, R13

	// save g
	MOVW	g, R3
	MOVW	R3, 20(R13)

	// g = m->gsignal
	MOVW	m_gsignal(R0), g

	// load args and call sighandler
	ADD	$4,R13,R5
	MOVM.IA	[R1-R3], (R5)
	BL	runtime·sighandler(SB)
	MOVW	16(R13), R0			// retval

	// restore g
	MOVW	20(R13), g

	// call noted(R0)
	MOVW	R0, 4(R13)
	BL	runtime·noted(SB)
	RET

//func sigpanictramp()
TEXT  runtime·sigpanictramp(SB),NOSPLIT,$0-0
	MOVW.W	R0, -4(R13)
	B	runtime·sigpanic(SB)

//func setfpmasks()
// Only used by the 64-bit runtime.
TEXT runtime·setfpmasks(SB),NOSPLIT,$0
	RET

#define ERRMAX 128	/* from os_plan9.h */

// func errstr() string
// Only used by package syscall.
// Grab error string due to a syscall made
// in entersyscall mode, without going
// through the allocator (issue 4994).
// See ../syscall/asm_plan9_arm.s:/·Syscall/
TEXT runtime·errstr(SB),NOSPLIT,$0-8
	MOVW	g_m(g), R0
	MOVW	(m_mOS+mOS_errstr)(R0), R1
	MOVW	R1, ret_base+0(FP)
	MOVW	$ERRMAX, R2
	MOVW	R2, ret_len+4(FP)
	MOVW    $SYS_ERRSTR, R0
	SWI	$0
	MOVW	R1, R2
	MOVBU	0(R2), R0
	CMP	$0, R0
	BEQ	3(PC)
	ADD	$1, R2
	B	-4(PC)
	SUB	R1, R2
	MOVW	R2, ret_len+4(FP)
	RET

TEXT ·publicationBarrier(SB),NOSPLIT|NOFRAME,$0-0
	B	runtime·armPublicationBarrier(SB)

// never called (cgo not supported)
TEXT runtime·read_tls_fallback(SB),NOSPLIT|NOFRAME,$0
	MOVW	$0, R0
	MOVW	R0, (R0)
	RET