Left: | ||
Right: |
LEFT | RIGHT |
---|---|
(no file at all) | |
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 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
319 MOVW frame+4(FP), R0 | 319 MOVW frame+4(FP), R0 |
320 MOVW R0, 8(R13) | 320 MOVW R0, 8(R13) |
321 MOVW framesize+8(FP), R0 | 321 MOVW framesize+8(FP), R0 |
322 MOVW R0, 12(R13) | 322 MOVW R0, 12(R13) |
323 MOVW $runtime·cgocallback_gofunc(SB), R0 | 323 MOVW $runtime·cgocallback_gofunc(SB), R0 |
324 BL (R0) | 324 BL (R0) |
325 RET | 325 RET |
326 | 326 |
327 // cgocallback_gofunc(void (*fn)(void*), void *frame, uintptr framesize) | 327 // cgocallback_gofunc(void (*fn)(void*), void *frame, uintptr framesize) |
328 // See cgocall.c for more details. | 328 // See cgocall.c for more details. |
329 TEXT» runtime·cgocallback_gofunc(SB),7,$16 | 329 TEXT» runtime·cgocallback_gofunc(SB),7,$12 |
330 // Load m and g from thread-local storage. | 330 // Load m and g from thread-local storage. |
331 MOVW _cgo_load_gm(SB), R0 | 331 MOVW _cgo_load_gm(SB), R0 |
332 CMP $0, R0 | 332 CMP $0, R0 |
333 BL.NE (R0) | 333 BL.NE (R0) |
334 | 334 |
335 // If m is nil, Go did not create the current thread. | 335 // If m is nil, Go did not create the current thread. |
336 // Call needm to obtain one for temporary use. | 336 // Call needm to obtain one for temporary use. |
337 // In this case, we're running on the thread stack, so there's | 337 // In this case, we're running on the thread stack, so there's |
338 // lots of space, but the linker doesn't know. Hide the call from | 338 // lots of space, but the linker doesn't know. Hide the call from |
339 // the linker analysis by using an indirect call. | 339 // the linker analysis by using an indirect call. |
340 » MOVW» m, savedm-16(SP) | 340 » MOVW» m, savedm-12(SP) |
341 CMP $0, m | 341 CMP $0, m |
342 B.NE havem | 342 B.NE havem |
343 MOVW $runtime·needm(SB), R0 | 343 MOVW $runtime·needm(SB), R0 |
344 BL (R0) | 344 BL (R0) |
345 | 345 |
346 havem: | 346 havem: |
347 // Now there's a valid m, and we're running on its m->g0. | 347 // Now there's a valid m, and we're running on its m->g0. |
348 // Save current m->g0->sched.sp on stack and then set it to SP. | 348 // Save current m->g0->sched.sp on stack and then set it to SP. |
349 // Save current sp in m->g0->sched.sp in preparation for | 349 // Save current sp in m->g0->sched.sp in preparation for |
350 // switch back to m->curg stack. | 350 // switch back to m->curg stack. |
351 MOVW fn+0(FP), R0 | |
352 MOVW frame+4(FP), R1 | |
353 MOVW framesize+8(FP), R2 | |
354 | |
355 MOVW m_g0(m), R3 | 351 MOVW m_g0(m), R3 |
356 MOVW (g_sched+gobuf_sp)(R3), R4 | 352 MOVW (g_sched+gobuf_sp)(R3), R4 |
357 MOVW.W R4, -4(R13) | 353 MOVW.W R4, -4(R13) |
358 MOVW R13, (g_sched+gobuf_sp)(R3) | 354 MOVW R13, (g_sched+gobuf_sp)(R3) |
359 | 355 |
360 // Switch to m->curg stack and call runtime.cgocallbackg | 356 // Switch to m->curg stack and call runtime.cgocallbackg |
361 // with the three arguments. Because we are taking over | 357 // with the three arguments. Because we are taking over |
362 // the execution of m->curg but *not* resuming what had | 358 // the execution of m->curg but *not* resuming what had |
363 // been running, we need to save that information (m->curg->gobuf) | 359 // been running, we need to save that information (m->curg->gobuf) |
364 // so that we can restore it when we're done.· | 360 // so that we can restore it when we're done.· |
365 // We can restore m->curg->gobuf.sp easily, because calling | 361 // We can restore m->curg->gobuf.sp easily, because calling |
366 // runtime.cgocallbackg leaves SP unchanged upon return. | 362 // runtime.cgocallbackg leaves SP unchanged upon return. |
367 // To save m->curg->gobuf.pc, we push it onto the stack. | 363 // To save m->curg->gobuf.pc, we push it onto the stack. |
368 // This has the added benefit that it looks to the traceback | 364 // This has the added benefit that it looks to the traceback |
369 // routine like cgocallbackg is going to return to that | 365 // routine like cgocallbackg is going to return to that |
370 // PC (because we defined cgocallbackg to have | 366 // PC (because we defined cgocallbackg to have |
371 » // a frame size of 16, the same amount that we use below), | 367 » // a frame size of 12, the same amount that we use below), |
372 // so that the traceback will seamlessly trace back into | 368 // so that the traceback will seamlessly trace back into |
373 // the earlier calls. | 369 // the earlier calls. |
374 | 370 » MOVW» fn+4(FP), R0 |
rsc
2013/03/25 22:12:01
This is very confusing. Can you please move the in
cshapiro1
2013/03/25 22:21:04
The motivation here is to make the code read like
| |
375 » // Save current m->g0->sched.sp on stack and then set it to SP. | 371 » MOVW» frame+8(FP), R1 |
372 » MOVW» framesize+12(FP), R2 | |
373 | |
376 MOVW m_curg(m), g | 374 MOVW m_curg(m), g |
377 MOVW (g_sched+gobuf_sp)(g), R4 // prepare stack as R4 | 375 MOVW (g_sched+gobuf_sp)(g), R4 // prepare stack as R4 |
378 | 376 |
379 // Push gobuf.pc | 377 // Push gobuf.pc |
380 MOVW (g_sched+gobuf_pc)(g), R5 | 378 MOVW (g_sched+gobuf_pc)(g), R5 |
381 » SUB» $4, R4 | 379 » MOVW.W» R5, -16(R4) |
382 » MOVW» R5, 0(R4) | |
383 | 380 |
384 // Push arguments to cgocallbackg. | 381 // Push arguments to cgocallbackg. |
385 // Frame size here must match the frame size above | 382 // Frame size here must match the frame size above |
386 // to trick traceback routines into doing the right thing. | 383 // to trick traceback routines into doing the right thing. |
387 SUB $16, R4 | |
388 MOVW R0, 4(R4) | 384 MOVW R0, 4(R4) |
389 MOVW R1, 8(R4) | 385 MOVW R1, 8(R4) |
390 MOVW R2, 12(R4) | 386 MOVW R2, 12(R4) |
391 ········ | 387 ········ |
392 // Switch stack and make the call. | 388 // Switch stack and make the call. |
393 MOVW R4, R13 | 389 MOVW R4, R13 |
394 BL runtime·cgocallbackg(SB) | 390 BL runtime·cgocallbackg(SB) |
395 | 391 |
396 // Restore g->gobuf (== m->curg->gobuf) from saved values. | 392 // Restore g->gobuf (== m->curg->gobuf) from saved values. |
397 » MOVW» 16(R13), R5 | 393 » MOVW» 0(R13), R5 |
398 MOVW R5, (g_sched+gobuf_pc)(g) | 394 MOVW R5, (g_sched+gobuf_pc)(g) |
399 » ADD» $(16+4), R13 // SP clobbered! It is ok! | 395 » ADD» $(12+4), R13, R4 |
400 » MOVW» R13, (g_sched+gobuf_sp)(g) | 396 » MOVW» R4, (g_sched+gobuf_sp)(g) |
401 | 397 |
402 // Switch back to m->g0's stack and restore m->g0->sched.sp. | 398 // Switch back to m->g0's stack and restore m->g0->sched.sp. |
403 // (Unlike m->curg, the g0 goroutine never uses sched.pc, | 399 // (Unlike m->curg, the g0 goroutine never uses sched.pc, |
404 // so we do not have to restore it.) | 400 // so we do not have to restore it.) |
405 MOVW m_g0(m), g | 401 MOVW m_g0(m), g |
406 MOVW (g_sched+gobuf_sp)(g), R13 | 402 MOVW (g_sched+gobuf_sp)(g), R13 |
407 // POP R6 | 403 // POP R6 |
408 MOVW 0(R13), R6 | 404 MOVW 0(R13), R6 |
409 ADD $4, R13 | 405 ADD $4, R13 |
410 MOVW R6, (g_sched+gobuf_sp)(g) | 406 MOVW R6, (g_sched+gobuf_sp)(g) |
411 | 407 |
412 // If the m on entry was nil, we called needm above to borrow an m | 408 // If the m on entry was nil, we called needm above to borrow an m |
413 // for the duration of the call. Since the call is over, return it with dropm. | 409 // for the duration of the call. Since the call is over, return it with dropm. |
414 » MOVW» savedm-16(SP), R6 | 410 » MOVW» savedm-12(SP), R6 |
415 CMP $0, R6 | 411 CMP $0, R6 |
416 B.NE 3(PC) | 412 B.NE 3(PC) |
417 MOVW $runtime·dropm(SB), R0 | 413 MOVW $runtime·dropm(SB), R0 |
418 BL (R0) | 414 BL (R0) |
419 | 415 |
420 // Done! | 416 // Done! |
421 RET | 417 RET |
422 | 418 |
423 // void setmg(M*, G*); set m and g. for use by needm. | 419 // void setmg(M*, G*); set m and g. for use by needm. |
424 TEXT runtime·setmg(SB), 7, $-4 | 420 TEXT runtime·setmg(SB), 7, $-4 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
497 MOVW (R0), R1 | 493 MOVW (R0), R1 |
498 TEXT runtime·aeshash32(SB),7,$-4 | 494 TEXT runtime·aeshash32(SB),7,$-4 |
499 MOVW $0, R0 | 495 MOVW $0, R0 |
500 MOVW (R0), R1 | 496 MOVW (R0), R1 |
501 TEXT runtime·aeshash64(SB),7,$-4 | 497 TEXT runtime·aeshash64(SB),7,$-4 |
502 MOVW $0, R0 | 498 MOVW $0, R0 |
503 MOVW (R0), R1 | 499 MOVW (R0), R1 |
504 TEXT runtime·aeshashstr(SB),7,$-4 | 500 TEXT runtime·aeshashstr(SB),7,$-4 |
505 MOVW $0, R0 | 501 MOVW $0, R0 |
506 MOVW (R0), R1 | 502 MOVW (R0), R1 |
LEFT | RIGHT |