/*
   Distributed under the Boost Software License, Version 1.0.
      (See accompanying file LICENSE_1_0.txt or copy at
          http://www.boost.org/LICENSE_1_0.txt)
*/
/*******************************************************
 *                                                     *
 *  -------------------------------------------------  *
 *  |  0  |  1  |  2  |  3  |  4  |  5  |  6  |  7  |  *
 *  -------------------------------------------------  *
 *  | 0x0 | 0x4 | 0x8 | 0xc | 0x10| 0x14| 0x18| 0x1c|  *
 *  -------------------------------------------------  *
 *  |    fs0    |    fs1    |    fs2    |    fs3    |  *
 *  -------------------------------------------------  *
 *  -------------------------------------------------  *
 *  |  8  |  9  |  10 |  11 |  12 |  13 |  14 |  15 |  *
 *  -------------------------------------------------  *
 *  | 0x20| 0x24| 0x28| 0x2c| 0x30| 0x34| 0x38| 0x3c|  *
 *  -------------------------------------------------  *
 *  |    fs4    |    fs5    |    fs6    |    fs7    |  *
 *  -------------------------------------------------  *
 *  -------------------------------------------------  *
 *  |  16 |  17 |  18 |  19 |  20 |  21 |  22 |  23 |  *
 *  -------------------------------------------------  *
 *  | 0x40| 0x44| 0x48| 0x4c| 0x50| 0x54| 0x58| 0x5c|  *
 *  -------------------------------------------------  *
 *  |    fs8    |    fs9    |    fs10   |    fs11   |  *
 *  -------------------------------------------------  *
 *  -------------------------------------------------  *
 *  |  24 |  25 |  26 |  27 |  28 |  29 |  30 |  31 |  *
 *  -------------------------------------------------  *
 *  | 0x60| 0x64| 0x68| 0x6c| 0x70| 0x74| 0x78| 0x7c|  *
 *  -------------------------------------------------  *
 *  |    s0     |    s1     |    s2     |    s3     |  *
 *  -------------------------------------------------  *
 *  -------------------------------------------------  *
 *  |  32 |  33 |  34 |  35 |  36 |  37 |  38 |  39 |  *
 *  -------------------------------------------------  *
 *  | 0x80| 0x84| 0x88| 0x8c| 0x90| 0x94| 0x98| 0x9c|  *
 *  -------------------------------------------------  *
 *  |    s4     |    s5     |    s6     |     s7    |  *
 *  -------------------------------------------------  *
 *  -------------------------------------------------  *
 *  |  40 |  41 |  42 | 43  |  44 | 45  |  46 | 47  |  *
 *  -------------------------------------------------  *
 *  | 0xa0| 0xa4| 0xa8| 0xac| 0xb0| 0xb4| 0xb8| 0xbc|  *
 *  -------------------------------------------------  *
 *  |     s8    |     s9    |    s10    |    s11    |  *
 *  -------------------------------------------------  *
 *  -------------------------------------------------  *
 *  |  48 |  49 |  50 | 51  |     |     |     |     |  *
 *  -------------------------------------------------  *
 *  | 0xc0| 0xc4| 0xc8| 0xcc|     |     |     |     |  *
 *  -------------------------------------------------  *
 *  |     ra    |     pc    |           |           |  *
 *  -------------------------------------------------  *
 *                                                     *
 *******************************************************/

.file "jump_riscv64_sysv_elf_gas.S"
.text
.align  1
.global jump_fcontext
.type   jump_fcontext, %function
jump_fcontext:
    # prepare stack for GP + FPU
    addi  sp, sp, -0xd0

    # save fs0 - fs11
    fsd  fs0, 0x00(sp)
    fsd  fs1, 0x08(sp)
    fsd  fs2, 0x10(sp)
    fsd  fs3, 0x18(sp)
    fsd  fs4, 0x20(sp)
    fsd  fs5, 0x28(sp)
    fsd  fs6, 0x30(sp)
    fsd  fs7, 0x38(sp)
    fsd  fs8, 0x40(sp)
    fsd  fs9, 0x48(sp)
    fsd  fs10, 0x50(sp)
    fsd  fs11, 0x58(sp)

    # save s0-s11, ra
    sd  s0, 0x60(sp)
    sd  s1, 0x68(sp)
    sd  s2, 0x70(sp)
    sd  s3, 0x78(sp)
    sd  s4, 0x80(sp)
    sd  s5, 0x88(sp)
    sd  s6, 0x90(sp)
    sd  s7, 0x98(sp)
    sd  s8, 0xa0(sp)
    sd  s9, 0xa8(sp)
    sd  s10, 0xb0(sp)
    sd  s11, 0xb8(sp)
    sd  ra, 0xc0(sp)

    # save RA as PC
    sd  ra, 0xc8(sp)

    # store SP (pointing to context-data) in A2
    mv  a2, sp

    # restore SP (pointing to context-data) from A0
    mv  sp, a0

    # load fs0 - fs11
    fld  fs0, 0x00(sp)
    fld  fs1, 0x08(sp)
    fld  fs2, 0x10(sp)
    fld  fs3, 0x18(sp)
    fld  fs4, 0x20(sp)
    fld  fs5, 0x28(sp)
    fld  fs6, 0x30(sp)
    fld  fs7, 0x38(sp)
    fld  fs8, 0x40(sp)
    fld  fs9, 0x48(sp)
    fld  fs10, 0x50(sp)
    fld  fs11, 0x58(sp)

    # load s0-s11,ra
    ld  s0, 0x60(sp)
    ld  s1, 0x68(sp)
    ld  s2, 0x70(sp)
    ld  s3, 0x78(sp)
    ld  s4, 0x80(sp)
    ld  s5, 0x88(sp)
    ld  s6, 0x90(sp)
    ld  s7, 0x98(sp)
    ld  s8, 0xa0(sp)
    ld  s9, 0xa8(sp)
    ld  s10, 0xb0(sp)
    ld  s11, 0xb8(sp)
    ld  ra, 0xc0(sp)

    # return transfer_t from jump
    # pass transfer_t as first arg in context function
    # a0 == FCTX, a1 == DATA
    mv a0, a2

    # load pc
    ld  a2, 0xc8(sp)

    # restore stack from GP + FPU
    addi  sp, sp, 0xd0

    jr a2
.size   jump_fcontext,.-jump_fcontext
# Mark that we don't need executable stack.
.section .note.GNU-stack,"",%progbits
