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

     1  //go:build tinygo
     2  
     3  .section .text.tinygo_startTask
     4  .global  tinygo_startTask
     5  .type    tinygo_startTask, %function
     6  tinygo_startTask:
     7      // Small assembly stub for starting a goroutine. This is already run on the
     8      // new stack, with the callee-saved registers already loaded.
     9      // Most importantly, s0 contains the pc of the to-be-started function and s1
    10      // contains the only argument it is given. Multiple arguments are packed
    11      // into one by storing them in a new allocation.
    12  
    13      // Set the first argument of the goroutine start wrapper, which contains all
    14      // the arguments.
    15      mv    a0, s1
    16  
    17      // Branch to the "goroutine start" function. Use jalr to write the return
    18      // address to ra so we'll return here after the goroutine exits.
    19      jalr  s0
    20  
    21      // After return, exit this goroutine. This is a tail call.
    22      tail  tinygo_pause
    23  
    24  .section .text.tinygo_swapTask
    25  .global  tinygo_swapTask
    26  .type    tinygo_swapTask, %function
    27  tinygo_swapTask:
    28      // This function gets the following parameters:
    29      //   a0 = newStack uintptr
    30      //   a1 = oldStack *uintptr
    31  
    32      // Push all callee-saved registers.
    33      addi sp, sp, -52
    34      sw ra,  48(sp)
    35      sw s11, 44(sp)
    36      sw s10, 40(sp)
    37      sw s9,  36(sp)
    38      sw s8,  32(sp)
    39      sw s7,  28(sp)
    40      sw s6,  24(sp)
    41      sw s5,  20(sp)
    42      sw s4,  16(sp)
    43      sw s3,  12(sp)
    44      sw s2,   8(sp)
    45      sw s1,   4(sp)
    46      sw s0,    (sp)
    47  
    48      // Save the current stack pointer in oldStack.
    49      sw sp,  0(a1)
    50  
    51      // Switch to the new stack pointer.
    52      mv sp,  a0
    53  
    54      // Pop all saved registers from this new stack.
    55      lw ra,  48(sp)
    56      lw s11, 44(sp)
    57      lw s10, 40(sp)
    58      lw s9,  36(sp)
    59      lw s8,  32(sp)
    60      lw s7,  28(sp)
    61      lw s6,  24(sp)
    62      lw s5,  20(sp)
    63      lw s4,  16(sp)
    64      lw s3,  12(sp)
    65      lw s2,   8(sp)
    66      lw s1,   4(sp)
    67      lw s0,    (sp)
    68      addi sp, sp, 52
    69  
    70      // Return into the task.
    71      ret