liyujie
2025-08-28 d9927380ed7c8366f762049be9f3fee225860833
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
 
// time.now() (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