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