summaryrefslogtreecommitdiff
path: root/libcpu/risc-v/vector/rvv-1.0/rvv_context.h
blob: fd66166d2d054be457205a48a10f2fd0e051285f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
 * Copyright (c) 2006-2024, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2022-10-10     RT-Thread    the first version,
 *                             compatible to riscv-v-spec-1.0
 */
#ifndef __RVV_CONTEXT_1_0_H__
#define __RVV_CONTEXT_1_0_H__

#ifdef __ASSEMBLY__
#include "vector_encoding.h"

/* common64 uses the older REGBYTES/STORE/LOAD assembler ABI. */
#ifndef SZREG
#define SZREG       REGBYTES
#endif
#ifndef REG_S
#define REG_S       STORE
#endif
#ifndef REG_L
#define REG_L       LOAD
#endif

/* The unified common supplies these through csr.h. */
#ifndef CSR_VSTART
#define CSR_VSTART  0x008
#endif
#ifndef CSR_VCSR
#define CSR_VCSR    0x00f
#endif
#ifndef CSR_VL
#define CSR_VL      0xc20
#endif
#ifndef CSR_VTYPE
#define CSR_VTYPE   0xc21
#endif
#ifndef CSR_VLENB
#define CSR_VLENB   0xc22
#endif
#endif

#if defined(ARCH_VECTOR_VLEN_128)
    #define CTX_VECTOR_VLEN 128
#elif defined(ARCH_VECTOR_VLEN_256)
    #define CTX_VECTOR_VLEN 256
#elif defined(ARCH_VECTOR_VLEN_512)
    #define CTX_VECTOR_VLEN 512
#elif defined(ARCH_VECTOR_VLEN_1024)
    #define CTX_VECTOR_VLEN 1024
#elif defined(ARCH_VECTOR_VLEN_2048)
    #define CTX_VECTOR_VLEN 2048
#elif defined(ARCH_VECTOR_VLEN_4096)
    #define CTX_VECTOR_VLEN 4096
#else
#error "No RISC-V vector length configured"
#endif /* VLEN */

/* Number of XLEN-sized stack slots occupied by vector CSRs and registers. */
#define CTX_VECTOR_REG_NR  ((CTX_VECTOR_VLEN * 32 / __riscv_xlen) + 4)

#ifdef __ASSEMBLY__

/* The following macros contain assembler, not C. */
/* clang-format off */

/**
 * ==================================
 * VECTOR EXTENSION
 * ==================================
 */

#define VEC_FRAME_VSTART    (0 * SZREG)
#define VEC_FRAME_VTYPE     (1 * SZREG)
#define VEC_FRAME_VL        (2 * SZREG)
#define VEC_FRAME_VCSR      (3 * SZREG)
#define VEC_FRAME_V0        (4 * SZREG)

.macro GET_VEC_FRAME_LEN, xreg
    csrr    \xreg, CSR_VLENB
    slli    \xreg, \xreg, 5
    addi    \xreg, \xreg, 4 * SZREG
.endm

/**
 * @brief save vector extension hardware state
 *
 * @param dst register storing bottom of storage block
 *
 */
.macro SAVE_VECTOR, dst
    mv      t1, \dst

    csrr    t0, CSR_VSTART
    REG_S   t0, VEC_FRAME_VSTART(t1)
    csrr    t0, CSR_VTYPE
    REG_S   t0, VEC_FRAME_VTYPE(t1)
    csrr    t0, CSR_VL
    REG_S   t0, VEC_FRAME_VL(t1)
    csrr    t0, CSR_VCSR
    REG_S   t0, VEC_FRAME_VCSR(t1)

    addi    t1, t1, VEC_FRAME_V0

    /*
     * config vector setting,
     * t2 is updated to length of a vector group in bytes
     */
    VEC_INSN_VSETVLI_T2_X0_E8_M8

    VEC_INSN_VSE8_V0_T1
    add     t1, t1, t2
    VEC_INSN_VSE8_V8_T1
    add     t1, t1, t2
    VEC_INSN_VSE8_V16_T1
    add     t1, t1, t2
    VEC_INSN_VSE8_V24_T1
.endm

/**
 * @brief restore vector extension hardware states
 *
 * @param dst register storing bottom of storage block
 *
 */
.macro RESTORE_VECTOR, dst
    /* Restore vector registers first since it will modify vector states */
    mv      t0, \dst
    addi    t1, t0, VEC_FRAME_V0

    VEC_INSN_VSETVLI_T2_X0_E8_M8

    VEC_INSN_VLE8_V0_T1
    add     t1, t1, t2
    VEC_INSN_VLE8_V8_T1
    add     t1, t1, t2
    VEC_INSN_VLE8_V16_T1
    add     t1, t1, t2
    VEC_INSN_VLE8_V24_T1

    mv      t1, t0

    REG_L   t0, VEC_FRAME_VCSR(t1)
    csrw    CSR_VCSR, t0

    REG_L   t0, VEC_FRAME_VTYPE(t1)
    REG_L   t3, VEC_FRAME_VL(t1)
    VEC_INSN_VSETVL_X0_T3_T0

    /* vsetvl resets vstart, so restore the restart index last. */
    REG_L   t0, VEC_FRAME_VSTART(t1)
    csrw    CSR_VSTART, t0
.endm

/* clang-format on */
#endif /* __ASSEMBLY__ */

#endif /* __RVV_CONTEXT_H__ */