github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/internal/task/task_stack_arm.S (about)

     1  //go:build tinygo
     2  
     3  // Only generate .debug_frame, don't generate .eh_frame.
     4  .cfi_sections .debug_frame
     5  
     6  .section .text.tinygo_startTask
     7  .global  tinygo_startTask
     8  .type    tinygo_startTask, %function
     9  tinygo_startTask:
    10      .cfi_startproc
    11      // Small assembly stub for starting a goroutine. This is already run on the
    12      // new stack, with the callee-saved registers already loaded.
    13      // Most importantly, r4 contains the pc of the to-be-started function and r5
    14      // contains the only argument it is given. Multiple arguments are packed
    15      // into one by storing them in a new allocation.
    16  
    17      // Indicate to the unwinder that there is nothing to unwind, this is the
    18      // root frame. It avoids the following (bogus) error message in GDB:
    19      //     Backtrace stopped: previous frame identical to this frame (corrupt stack?)
    20      .cfi_undefined lr
    21  
    22      // Set the first argument of the goroutine start wrapper, which contains all
    23      // the arguments.
    24      mov   r0, r5
    25  
    26      // Branch to the "goroutine start" function. By using blx instead of bx,
    27      // we'll return here instead of tail calling.
    28      blx   r4
    29  
    30      // After return, exit this goroutine. This is a tail call.
    31      bl    tinygo_pause
    32      .cfi_endproc
    33  .size tinygo_startTask, .-tinygo_startTask
    34  
    35  .global tinygo_swapTask
    36  .type tinygo_swapTask, %function
    37  tinygo_swapTask:
    38      // This function gets the following parameters:
    39      // r0 = newStack uintptr
    40      // r1 = oldStack *uintptr
    41  
    42      // Save all callee-saved registers:
    43      push {r4-r11, lr}
    44  
    45      // Save the current stack pointer in oldStack.
    46      str sp, [r1]
    47  
    48      // Switch to the new stack pointer.
    49      mov sp, r0
    50  
    51      // Load state from new task and branch to the previous position in the
    52      // program.
    53      pop {r4-r11, pc}