OLD | NEW |
1 // Copyright 2009 The Go Authors. All rights reserved. | 1 // Copyright 2009 The Go Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style | 2 // Use of this source code is governed by a BSD-style |
3 // license that can be found in the LICENSE file. | 3 // license that can be found in the LICENSE file. |
4 | 4 |
5 #include "zasm_GOOS_GOARCH.h" | 5 #include "zasm_GOOS_GOARCH.h" |
6 | 6 |
7 // using frame size $-4 means do not save LR on stack. | 7 // using frame size $-4 means do not save LR on stack. |
8 TEXT _rt0_arm(SB),7,$-4 | 8 TEXT _rt0_arm(SB),7,$-4 |
9 MOVW $0xcafebabe, R12 | 9 MOVW $0xcafebabe, R12 |
10 | 10 |
(...skipping 13 matching lines...) Expand all Loading... |
24 | 24 |
25 // save m->g0 = g0 | 25 // save m->g0 = g0 |
26 MOVW g, m_g0(m) | 26 MOVW g, m_g0(m) |
27 | 27 |
28 // create istack out of the OS stack | 28 // create istack out of the OS stack |
29 MOVW $(-8192+104)(R13), R0 | 29 MOVW $(-8192+104)(R13), R0 |
30 MOVW R0, g_stackguard(g) // (w 104b guard) | 30 MOVW R0, g_stackguard(g) // (w 104b guard) |
31 MOVW R13, g_stackbase(g) | 31 MOVW R13, g_stackbase(g) |
32 BL runtime·emptyfunc(SB) // fault if stack check is wrong | 32 BL runtime·emptyfunc(SB) // fault if stack check is wrong |
33 | 33 |
| 34 // if there is an initcgo, call it. |
| 35 MOVW initcgo(SB), R2 |
| 36 CMP $0, R2 |
| 37 MOVW.NE g, R0 // first argument of initcgo is g |
| 38 BL.NE (R2) // will clobber R0-R3 |
| 39 |
34 BL runtime·check(SB) | 40 BL runtime·check(SB) |
35 | 41 |
36 // saved argc, argv | 42 // saved argc, argv |
37 MOVW 60(R13), R0 | 43 MOVW 60(R13), R0 |
38 MOVW R0, 4(R13) | 44 MOVW R0, 4(R13) |
39 MOVW 64(R13), R1 | 45 MOVW 64(R13), R1 |
40 MOVW R1, 8(R13) | 46 MOVW R1, 8(R13) |
41 BL runtime·args(SB) | 47 BL runtime·args(SB) |
42 BL runtime·osinit(SB) | 48 BL runtime·osinit(SB) |
43 BL runtime·schedinit(SB) | 49 BL runtime·schedinit(SB) |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 MOVW 0(FP), R0 // gobuf | 85 MOVW 0(FP), R0 // gobuf |
80 MOVW SP, gobuf_sp(R0) | 86 MOVW SP, gobuf_sp(R0) |
81 MOVW LR, gobuf_pc(R0) | 87 MOVW LR, gobuf_pc(R0) |
82 MOVW g, gobuf_g(R0) | 88 MOVW g, gobuf_g(R0) |
83 RET | 89 RET |
84 | 90 |
85 // void gogo(Gobuf*, uintptr) | 91 // void gogo(Gobuf*, uintptr) |
86 // restore state from Gobuf; longjmp | 92 // restore state from Gobuf; longjmp |
87 TEXT runtime·gogo(SB), 7, $-4 | 93 TEXT runtime·gogo(SB), 7, $-4 |
88 MOVW 0(FP), R1 // gobuf | 94 MOVW 0(FP), R1 // gobuf |
89 MOVW 4(FP), R0 // return 2nd arg | |
90 MOVW gobuf_g(R1), g | 95 MOVW gobuf_g(R1), g |
91 MOVW 0(g), R2 // make sure g != nil | 96 MOVW 0(g), R2 // make sure g != nil |
| 97 MOVW cgo_save_gm(SB), R2 |
| 98 CMP $0, R2 // if in Cgo, we have to save g and m |
| 99 BL.NE (R2) // this call will clobber R0 |
| 100 MOVW 4(FP), R0 // return 2nd arg |
92 MOVW gobuf_sp(R1), SP // restore SP | 101 MOVW gobuf_sp(R1), SP // restore SP |
93 MOVW gobuf_pc(R1), PC | 102 MOVW gobuf_pc(R1), PC |
94 | 103 |
95 // void gogocall(Gobuf*, void (*fn)(void)) | 104 // void gogocall(Gobuf*, void (*fn)(void)) |
96 // restore state from Gobuf but then call fn. | 105 // restore state from Gobuf but then call fn. |
97 // (call fn, returning to state in Gobuf) | 106 // (call fn, returning to state in Gobuf) |
98 // using frame size $-4 means do not save LR on stack. | 107 // using frame size $-4 means do not save LR on stack. |
99 TEXT runtime·gogocall(SB), 7, $-4 | 108 TEXT runtime·gogocall(SB), 7, $-4 |
100 » MOVW» 0(FP), R0» » // gobuf | 109 » MOVW» 0(FP), R3» » // gobuf |
101 MOVW 4(FP), R1 // fn | 110 MOVW 4(FP), R1 // fn |
102 MOVW 8(FP), R2 // fp offset | 111 MOVW 8(FP), R2 // fp offset |
103 » MOVW» gobuf_g(R0), g | 112 » MOVW» gobuf_g(R3), g |
104 » MOVW» 0(g), R3» » // make sure g != nil | 113 » MOVW» 0(g), R0» » // make sure g != nil |
105 » MOVW» gobuf_sp(R0), SP» // restore SP | 114 » MOVW» cgo_save_gm(SB), R0 |
106 » MOVW» gobuf_pc(R0), LR | 115 » CMP » $0, R0 // if in Cgo, we have to save g and m |
| 116 » BL.NE» (R0) // this call will clobber R0 |
| 117 » MOVW» gobuf_sp(R3), SP» // restore SP |
| 118 » MOVW» gobuf_pc(R3), LR |
107 MOVW R1, PC | 119 MOVW R1, PC |
108 | 120 |
109 // void mcall(void (*fn)(G*)) | 121 // void mcall(void (*fn)(G*)) |
110 // Switch to m->g0's stack, call fn(g). | 122 // Switch to m->g0's stack, call fn(g). |
111 // Fn must never return. It should gogo(&g->sched) | 123 // Fn must never return. It should gogo(&g->sched) |
112 // to keep running g. | 124 // to keep running g. |
113 TEXT runtime·mcall(SB), 7, $-4 | 125 TEXT runtime·mcall(SB), 7, $-4 |
114 MOVW fn+0(FP), R0 | 126 MOVW fn+0(FP), R0 |
115 | 127 |
116 // Save caller state in g->gobuf. | 128 // Save caller state in g->gobuf. |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 // 2. sub 4 bytes to get back to BL deferreturn | 229 // 2. sub 4 bytes to get back to BL deferreturn |
218 // 3. B to fn | 230 // 3. B to fn |
219 TEXT runtime·jmpdefer(SB), 7, $0 | 231 TEXT runtime·jmpdefer(SB), 7, $0 |
220 MOVW 0(SP), LR | 232 MOVW 0(SP), LR |
221 MOVW $-4(LR), LR // BL deferreturn | 233 MOVW $-4(LR), LR // BL deferreturn |
222 MOVW fn+0(FP), R0 | 234 MOVW fn+0(FP), R0 |
223 MOVW argp+4(FP), SP | 235 MOVW argp+4(FP), SP |
224 MOVW $-4(SP), SP // SP is 4 below argp, due to saved LR | 236 MOVW $-4(SP), SP // SP is 4 below argp, due to saved LR |
225 B (R0) | 237 B (R0) |
226 | 238 |
| 239 // Dummy function to use in saved gobuf.PC, |
| 240 // to match SP pointing at a return address. |
| 241 // The gobuf.PC is unused by the contortions here |
| 242 // but setting it to return will make the traceback code work. |
| 243 TEXT return<>(SB),7,$0 |
| 244 RET |
| 245 |
| 246 // asmcgocall(void(*fn)(void*), void *arg) |
| 247 // Call fn(arg) on the scheduler stack, |
| 248 // aligned appropriately for the gcc ABI. |
| 249 // See cgocall.c for more details. |
227 TEXT runtime·asmcgocall(SB),7,$0 | 250 TEXT runtime·asmcgocall(SB),7,$0 |
228 » B» runtime·cgounimpl(SB) | 251 » MOVW» fn+0(FP), R1 |
| 252 » MOVW» arg+4(FP), R0 |
| 253 » MOVW» R13, R2 |
| 254 » MOVW» g, R5 |
229 | 255 |
230 TEXT» runtime·cgocallback(SB),7,$0 | 256 » // Figure out if we need to switch to m->g0 stack. |
231 » B» runtime·cgounimpl(SB) | 257 » // We get called to create new OS threads too, and those |
| 258 » // come in on the m->g0 stack already. |
| 259 » MOVW» m_g0(m), R3 |
| 260 » CMP» R3, g |
| 261 » BEQ» 7(PC) |
| 262 » MOVW» R13, (g_sched + gobuf_sp)(g) |
| 263 » MOVW» $return<>(SB), R4 |
| 264 » MOVW» R4, (g_sched+gobuf_pc)(g) |
| 265 » MOVW» g, (g_sched+gobuf_g)(g) |
| 266 » MOVW» R3, g |
| 267 » MOVW» (g_sched+gobuf_sp)(g), R13 |
| 268 |
| 269 » // Now on a scheduling stack (a pthread-created stack). |
| 270 » SUB» $24, R13 |
| 271 » BIC» $0x7, R13» // alignment for gcc ABI |
| 272 » MOVW» R5, 20(R13) // save old g |
| 273 » MOVW» R2, 16(R13)» // save old SP |
| 274 » // R0 already contains the first argument |
| 275 » BL» (R1) |
| 276 |
| 277 » // Restore registers, g, stack pointer. |
| 278 » MOVW» 20(R13), g |
| 279 » MOVW» 16(R13), R13 |
| 280 » RET |
| 281 |
| 282 // cgocallback(void (*fn)(void*), void *frame, uintptr framesize) |
| 283 // See cgocall.c for more details. |
| 284 TEXT» runtime·cgocallback(SB),7,$16 |
| 285 » MOVW» fn+0(FP), R0 |
| 286 » MOVW» frame+4(FP), R1 |
| 287 » MOVW» framesize+8(FP), R2 |
| 288 |
| 289 » // Save current m->g0->sched.sp on stack and then set it to SP. |
| 290 » MOVW» m_g0(m), R3 |
| 291 » MOVW» (g_sched+gobuf_sp)(R3), R4 |
| 292 » MOVW.W» R4, -4(SP) |
| 293 » MOVW» R13, (g_sched+gobuf_sp)(R3) |
| 294 |
| 295 » // Switch to m->curg stack and call runtime.cgocallbackg |
| 296 » // with the three arguments. Because we are taking over |
| 297 » // the execution of m->curg but *not* resuming what had |
| 298 » // been running, we need to save that information (m->curg->gobuf) |
| 299 » // so that we can restore it when we're done.· |
| 300 » // We can restore m->curg->gobuf.sp easily, because calling |
| 301 » // runtime.cgocallbackg leaves SP unchanged upon return. |
| 302 » // To save m->curg->gobuf.pc, we push it onto the stack. |
| 303 » // This has the added benefit that it looks to the traceback |
| 304 » // routine like cgocallbackg is going to return to that |
| 305 » // PC (because we defined cgocallbackg to have |
| 306 » // a frame size of 16, the same amount that we use below), |
| 307 » // so that the traceback will seamlessly trace back into |
| 308 » // the earlier calls. |
| 309 » MOVW» m_curg(m), g |
| 310 » MOVW» (g_sched+gobuf_sp)(g), R4 // prepare stack as R4 |
| 311 |
| 312 » // Push gobuf.pc |
| 313 » MOVW» (g_sched+gobuf_pc)(g), R5 |
| 314 » SUB» $4, R4 |
| 315 » MOVW» R5, 0(R4) |
| 316 |
| 317 » // Push arguments to cgocallbackg. |
| 318 » // Frame size here must match the frame size above |
| 319 » // to trick traceback routines into doing the right thing. |
| 320 » SUB» $16, R4 |
| 321 » MOVW» R0, 4(R4) |
| 322 » MOVW» R1, 8(R4) |
| 323 » MOVW» R2, 12(R4) |
| 324 »······· |
| 325 » // Switch stack and make the call. |
| 326 » MOVW» R4, R13 |
| 327 » BL» runtime·cgocallbackg(SB) |
| 328 |
| 329 » // Restore g->gobuf (== m->curg->gobuf) from saved values. |
| 330 » MOVW» 16(R13), R5 |
| 331 » MOVW» R5, (g_sched+gobuf_pc)(g) |
| 332 » ADD» $(16+4), R13 // SP clobbered! It is ok! |
| 333 » MOVW» R13, (g_sched+gobuf_sp)(g) |
| 334 |
| 335 » // Switch back to m->g0's stack and restore m->g0->sched.sp. |
| 336 » // (Unlike m->curg, the g0 goroutine never uses sched.pc, |
| 337 » // so we do not have to restore it.) |
| 338 » MOVW» m_g0(m), g |
| 339 » MOVW» (g_sched+gobuf_sp)(g), R13 |
| 340 » // POP R6 |
| 341 » MOVW» 0(R13), R6 |
| 342 » ADD» $4, R13 |
| 343 » MOVW» R6, (g_sched+gobuf_sp)(g) |
| 344 |
| 345 » // Done! |
| 346 » RET |
232 | 347 |
233 TEXT runtime·memclr(SB),7,$20 | 348 TEXT runtime·memclr(SB),7,$20 |
234 MOVW 0(FP), R0 | 349 MOVW 0(FP), R0 |
235 MOVW $0, R1 // c = 0 | 350 MOVW $0, R1 // c = 0 |
236 MOVW R1, -16(SP) | 351 MOVW R1, -16(SP) |
237 MOVW 4(FP), R1 // n | 352 MOVW 4(FP), R1 // n |
238 MOVW R1, -12(SP) | 353 MOVW R1, -12(SP) |
239 MOVW m, -8(SP) // Save m and g | 354 MOVW m, -8(SP) // Save m and g |
240 MOVW g, -4(SP) | 355 MOVW g, -4(SP) |
241 BL runtime·memset(SB) | 356 BL runtime·memset(SB) |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 casfail: | 419 casfail: |
305 MOVW $0, R0 | 420 MOVW $0, R0 |
306 RET | 421 RET |
307 | 422 |
308 TEXT runtime·stackguard(SB),7,$0 | 423 TEXT runtime·stackguard(SB),7,$0 |
309 MOVW R13, R1 | 424 MOVW R13, R1 |
310 MOVW g_stackguard(g), R2 | 425 MOVW g_stackguard(g), R2 |
311 MOVW R1, sp+0(FP) | 426 MOVW R1, sp+0(FP) |
312 MOVW R2, limit+4(FP) | 427 MOVW R2, limit+4(FP) |
313 RET | 428 RET |
OLD | NEW |