hc
2024-03-22 619f0f87159c5dbd2755b1b0a0eb35784be84e7a
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
/*
 * SPDX-License-Identifier: BSD-2-Clause
 *
 * Copyright (c) 2019 Western Digital Corporation or its affiliates.
 *
 * Authors:
 *   Anup Patel <anup.patel@wdc.com>
 */
 
#ifndef __RISCV_FP_H__
#define __RISCV_FP_H__
 
#include <sbi/riscv_asm.h>
#include <sbi/riscv_encoding.h>
#include <sbi/sbi_types.h>
 
#define GET_PRECISION(insn) (((insn) >> 25) & 3)
#define GET_RM(insn) (((insn) >> 12) & 7)
#define PRECISION_S 0
#define PRECISION_D 1
 
#ifdef __riscv_flen
 
#define GET_F32_REG(insn, pos, regs)                                                                    \
   ({                                                                                              \
       register s32 value asm("a0") =                                                          \
           SHIFT_RIGHT(insn, (pos)-3) & 0xf8;                                              \
       ulong tmp;                                                                              \
       asm("1: auipc %0, %%pcrel_hi(get_f32_reg); add %0, %0, %1; jalr t0, %0, %%pcrel_lo(1b)" \
           : "=&r"(tmp), "+&r"(value)::"t0");                                                  \
       value;                                                                                  \
   })
#define SET_F32_REG(insn, pos, regs, val)                                                                   \
   ({                                                                                                  \
       register u32 value asm("a0") = (val);                                                       \
       ulong offset = SHIFT_RIGHT(insn, (pos)-3) & 0xf8;                                           \
       ulong tmp;                                                                                  \
       asm volatile(                                                                               \
           "1: auipc %0, %%pcrel_hi(put_f32_reg); add %0, %0, %2; jalr t0, %0, %%pcrel_lo(1b)" \
           : "=&r"(tmp)                                                                        \
           : "r"(value), "r"(offset)                                                           \
           : "t0");                                                                            \
   })
#define init_fp_reg(i) SET_F32_REG((i) << 3, 3, 0, 0)
#define GET_F64_REG(insn, pos, regs)                                                                    \
   ({                                                                                              \
       register ulong value asm("a0") =                                                        \
           SHIFT_RIGHT(insn, (pos)-3) & 0xf8;                                              \
       ulong tmp;                                                                              \
       asm("1: auipc %0, %%pcrel_hi(get_f64_reg); add %0, %0, %1; jalr t0, %0, %%pcrel_lo(1b)" \
           : "=&r"(tmp), "+&r"(value)::"t0");                                                  \
       sizeof(ulong) == 4 ? *(int64_t *)value : (int64_t)value;                                \
   })
#define SET_F64_REG(insn, pos, regs, val)                                                                   \
   ({                                                                                                  \
       uint64_t __val = (val);                                                                     \
       register ulong value asm("a0") =                                                            \
           sizeof(ulong) == 4 ? (ulong)&__val : (ulong)__val;                                  \
       ulong offset = SHIFT_RIGHT(insn, (pos)-3) & 0xf8;                                           \
       ulong tmp;                                                                                  \
       asm volatile(                                                                               \
           "1: auipc %0, %%pcrel_hi(put_f64_reg); add %0, %0, %2; jalr t0, %0, %%pcrel_lo(1b)" \
           : "=&r"(tmp)                                                                        \
           : "r"(value), "r"(offset)                                                           \
           : "t0");                                                                            \
   })
#define GET_FCSR() csr_read(CSR_FCSR)
#define SET_FCSR(value) csr_write(CSR_FCSR, (value))
#define GET_FRM() csr_read(CSR_FRM)
#define SET_FRM(value) csr_write(CSR_FRM, (value))
#define GET_FFLAGS() csr_read(CSR_FFLAGS)
#define SET_FFLAGS(value) csr_write(CSR_FFLAGS, (value))
 
#define SET_FS_DIRTY() ((void)0)
 
#define GET_F32_RS1(insn, regs) (GET_F32_REG(insn, 15, regs))
#define GET_F32_RS2(insn, regs) (GET_F32_REG(insn, 20, regs))
#define GET_F32_RS3(insn, regs) (GET_F32_REG(insn, 27, regs))
#define GET_F64_RS1(insn, regs) (GET_F64_REG(insn, 15, regs))
#define GET_F64_RS2(insn, regs) (GET_F64_REG(insn, 20, regs))
#define GET_F64_RS3(insn, regs) (GET_F64_REG(insn, 27, regs))
#define SET_F32_RD(insn, regs, val) \
   (SET_F32_REG(insn, 7, regs, val), SET_FS_DIRTY())
#define SET_F64_RD(insn, regs, val) \
   (SET_F64_REG(insn, 7, regs, val), SET_FS_DIRTY())
 
#define GET_F32_RS2C(insn, regs) (GET_F32_REG(insn, 2, regs))
#define GET_F32_RS2S(insn, regs) (GET_F32_REG(RVC_RS2S(insn), 0, regs))
#define GET_F64_RS2C(insn, regs) (GET_F64_REG(insn, 2, regs))
#define GET_F64_RS2S(insn, regs) (GET_F64_REG(RVC_RS2S(insn), 0, regs))
 
#endif
 
#endif