//===-- restore.S - restore up to 12 callee-save registers ----------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // Multiple entry points depending on number of registers to restore // //===----------------------------------------------------------------------===// // All of the entry points are in the same section since we rely on many of // them falling through into each other and don't want the linker to // accidentally split them up, garbage collect, or reorder them. // // The entry points are grouped up into 2s for rv64 and 4s for rv32 since this // is the minimum grouping which will maintain the required 16-byte stack // alignment. .text #if __riscv_xlen == 32 .globl __riscv_restore_12 .type __riscv_restore_12,@function __riscv_restore_12: lw s11, 12(sp) addi sp, sp, 16 // fallthrough into __riscv_restore_11/10/9/8 .globl __riscv_restore_11 .type __riscv_restore_11,@function .globl __riscv_restore_10 .type __riscv_restore_10,@function .globl __riscv_restore_9 .type __riscv_restore_9,@function .globl __riscv_restore_8 .type __riscv_restore_8,@function __riscv_restore_11: __riscv_restore_10: __riscv_restore_9: __riscv_restore_8: lw s10, 0(sp) lw s9, 4(sp) lw s8, 8(sp) lw s7, 12(sp) addi sp, sp, 16 // fallthrough into __riscv_restore_7/6/5/4 .globl __riscv_restore_7 .type __riscv_restore_7,@function .globl __riscv_restore_6 .type __riscv_restore_6,@function .globl __riscv_restore_5 .type __riscv_restore_5,@function .globl __riscv_restore_4 .type __riscv_restore_4,@function __riscv_restore_7: __riscv_restore_6: __riscv_restore_5: __riscv_restore_4: lw s6, 0(sp) lw s5, 4(sp) lw s4, 8(sp) lw s3, 12(sp) addi sp, sp, 16 // fallthrough into __riscv_restore_3/2/1/0 .globl __riscv_restore_3 .type __riscv_restore_3,@function .globl __riscv_restore_2 .type __riscv_restore_2,@function .globl __riscv_restore_1 .type __riscv_restore_1,@function .globl __riscv_restore_0 .type __riscv_restore_0,@function __riscv_restore_3: __riscv_restore_2: __riscv_restore_1: __riscv_restore_0: lw s2, 0(sp) lw s1, 4(sp) lw s0, 8(sp) lw ra, 12(sp) addi sp, sp, 16 ret #elif __riscv_xlen == 64 .globl __riscv_restore_12 .type __riscv_restore_12,@function __riscv_restore_12: ld s11, 8(sp) addi sp, sp, 16 // fallthrough into __riscv_restore_11/10/9/8 .globl __riscv_restore_11 .type __riscv_restore_11,@function .globl __riscv_restore_10 .type __riscv_restore_10,@function __riscv_restore_11: __riscv_restore_10: ld s10, 0(sp) ld s9, 8(sp) addi sp, sp, 16 // fallthrough into __riscv_restore_9/8 .globl __riscv_restore_9 .type __riscv_restore_9,@function .globl __riscv_restore_8 .type __riscv_restore_8,@function __riscv_restore_9: __riscv_restore_8: ld s8, 0(sp) ld s7, 8(sp) addi sp, sp, 16 // fallthrough into __riscv_restore_7/6 .globl __riscv_restore_7 .type __riscv_restore_7,@function .globl __riscv_restore_6 .type __riscv_restore_6,@function __riscv_restore_7: __riscv_restore_6: ld s6, 0(sp) ld s5, 8(sp) addi sp, sp, 16 // fallthrough into __riscv_restore_5/4 .globl __riscv_restore_5 .type __riscv_restore_5,@function .globl __riscv_restore_4 .type __riscv_restore_4,@function __riscv_restore_5: __riscv_restore_4: ld s4, 0(sp) ld s3, 8(sp) addi sp, sp, 16 // fallthrough into __riscv_restore_3/2 .globl __riscv_restore_3 .type __riscv_restore_3,@function .globl __riscv_restore_2 .type __riscv_restore_2,@function .globl __riscv_restore_1 .type __riscv_restore_1,@function .globl __riscv_restore_0 .type __riscv_restore_0,@function __riscv_restore_3: __riscv_restore_2: ld s2, 0(sp) ld s1, 8(sp) addi sp, sp, 16 // fallthrough into __riscv_restore_1/0 __riscv_restore_1: __riscv_restore_0: ld s0, 0(sp) ld ra, 8(sp) addi sp, sp, 16 ret #else # error "xlen must be 32 or 64 for save-restore implementation #endif