1//===-- restore.S - restore up to 12 callee-save registers ----------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// Multiple entry points depending on number of registers to restore 10// 11//===----------------------------------------------------------------------===// 12 13// All of the entry points are in the same section since we rely on many of 14// them falling through into each other and don't want the linker to 15// accidentally split them up, garbage collect, or reorder them. 16// 17// The entry points are grouped up into 2s for rv64 and 4s for rv32 since this 18// is the minimum grouping which will maintain the required 16-byte stack 19// alignment. 20 21 .text 22 23#if __riscv_xlen == 32 24 25#ifndef __riscv_32e 26 27 .globl __riscv_restore_12 28 .type __riscv_restore_12,@function 29__riscv_restore_12: 30 lw s11, 12(sp) 31 addi sp, sp, 16 32 // fallthrough into __riscv_restore_11/10/9/8 33 34 .globl __riscv_restore_11 35 .type __riscv_restore_11,@function 36 .globl __riscv_restore_10 37 .type __riscv_restore_10,@function 38 .globl __riscv_restore_9 39 .type __riscv_restore_9,@function 40 .globl __riscv_restore_8 41 .type __riscv_restore_8,@function 42__riscv_restore_11: 43__riscv_restore_10: 44__riscv_restore_9: 45__riscv_restore_8: 46 lw s10, 0(sp) 47 lw s9, 4(sp) 48 lw s8, 8(sp) 49 lw s7, 12(sp) 50 addi sp, sp, 16 51 // fallthrough into __riscv_restore_7/6/5/4 52 53 .globl __riscv_restore_7 54 .type __riscv_restore_7,@function 55 .globl __riscv_restore_6 56 .type __riscv_restore_6,@function 57 .globl __riscv_restore_5 58 .type __riscv_restore_5,@function 59 .globl __riscv_restore_4 60 .type __riscv_restore_4,@function 61__riscv_restore_7: 62__riscv_restore_6: 63__riscv_restore_5: 64__riscv_restore_4: 65 lw s6, 0(sp) 66 lw s5, 4(sp) 67 lw s4, 8(sp) 68 lw s3, 12(sp) 69 addi sp, sp, 16 70 // fallthrough into __riscv_restore_3/2/1/0 71 72 .globl __riscv_restore_3 73 .type __riscv_restore_3,@function 74 .globl __riscv_restore_2 75 .type __riscv_restore_2,@function 76 .globl __riscv_restore_1 77 .type __riscv_restore_1,@function 78 .globl __riscv_restore_0 79 .type __riscv_restore_0,@function 80__riscv_restore_3: 81__riscv_restore_2: 82__riscv_restore_1: 83__riscv_restore_0: 84 lw s2, 0(sp) 85 lw s1, 4(sp) 86 lw s0, 8(sp) 87 lw ra, 12(sp) 88 addi sp, sp, 16 89 ret 90 91#else 92 93 .globl __riscv_restore_2 94 .type __riscv_restore_2,@function 95 .globl __riscv_restore_1 96 .type __riscv_restore_1,@function 97 .globl __riscv_restore_0 98 .type __riscv_restore_0,@function 99__riscv_restore_2: 100__riscv_restore_1: 101__riscv_restore_0: 102 lw s1, 0(sp) 103 lw s0, 4(sp) 104 lw ra, 8(sp) 105 addi sp, sp, 12 106 ret 107 108#endif 109 110#elif __riscv_xlen == 64 111 112#ifndef __riscv_64e 113 114 .globl __riscv_restore_12 115 .type __riscv_restore_12,@function 116__riscv_restore_12: 117 ld s11, 8(sp) 118 addi sp, sp, 16 119 // fallthrough into __riscv_restore_11/10 120 121 .globl __riscv_restore_11 122 .type __riscv_restore_11,@function 123 .globl __riscv_restore_10 124 .type __riscv_restore_10,@function 125__riscv_restore_11: 126__riscv_restore_10: 127 ld s10, 0(sp) 128 ld s9, 8(sp) 129 addi sp, sp, 16 130 // fallthrough into __riscv_restore_9/8 131 132 .globl __riscv_restore_9 133 .type __riscv_restore_9,@function 134 .globl __riscv_restore_8 135 .type __riscv_restore_8,@function 136__riscv_restore_9: 137__riscv_restore_8: 138 ld s8, 0(sp) 139 ld s7, 8(sp) 140 addi sp, sp, 16 141 // fallthrough into __riscv_restore_7/6 142 143 .globl __riscv_restore_7 144 .type __riscv_restore_7,@function 145 .globl __riscv_restore_6 146 .type __riscv_restore_6,@function 147__riscv_restore_7: 148__riscv_restore_6: 149 ld s6, 0(sp) 150 ld s5, 8(sp) 151 addi sp, sp, 16 152 // fallthrough into __riscv_restore_5/4 153 154 .globl __riscv_restore_5 155 .type __riscv_restore_5,@function 156 .globl __riscv_restore_4 157 .type __riscv_restore_4,@function 158__riscv_restore_5: 159__riscv_restore_4: 160 ld s4, 0(sp) 161 ld s3, 8(sp) 162 addi sp, sp, 16 163 // fallthrough into __riscv_restore_3/2 164 165 .globl __riscv_restore_3 166 .type __riscv_restore_3,@function 167 .globl __riscv_restore_2 168 .type __riscv_restore_2,@function 169__riscv_restore_3: 170__riscv_restore_2: 171 ld s2, 0(sp) 172 ld s1, 8(sp) 173 addi sp, sp, 16 174 // fallthrough into __riscv_restore_1/0 175 176 .globl __riscv_restore_1 177 .type __riscv_restore_1,@function 178 .globl __riscv_restore_0 179 .type __riscv_restore_0,@function 180__riscv_restore_1: 181__riscv_restore_0: 182 ld s0, 0(sp) 183 ld ra, 8(sp) 184 addi sp, sp, 16 185 ret 186 187#else 188 189 .globl __riscv_restore_2 190 .type __riscv_restore_2,@function 191 .globl __riscv_restore_1 192 .type __riscv_restore_1,@function 193 .globl __riscv_restore_0 194 .type __riscv_restore_0,@function 195__riscv_restore_2: 196__riscv_restore_1: 197__riscv_restore_0: 198 ld s1, 0(sp) 199 ld s0, 8(sp) 200 ld ra, 16(sp) 201 addi sp, sp, 24 202 ret 203 204#endif 205 206#else 207# error "xlen must be 32 or 64 for save-restore implementation 208#endif 209