diff options
author | Anup Patel <anup.patel@wdc.com> | 2019-01-03 08:07:43 +0300 |
---|---|---|
committer | Atish Patra <atishp04@gmail.com> | 2019-01-04 01:21:08 +0300 |
commit | 4d1eccc41d96413fae25cea5f941f7860429340b (patch) | |
tree | ce8e984f098ba2447a36af4c78d13089eb7e3f7b /include/sbi/riscv_fp.h | |
parent | 9829a86e8dcd98b62eb3095eb86131cb2dbd5330 (diff) | |
download | opensbi-4d1eccc41d96413fae25cea5f941f7860429340b.tar.xz |
include: Add hard FP access macros and defines
This patch adds hardware floating-point (hard FP) access
macros and defines.
Signed-off-by: Anup Patel <anup.patel@wdc.com>
Diffstat (limited to 'include/sbi/riscv_fp.h')
-rw-r--r-- | include/sbi/riscv_fp.h | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/include/sbi/riscv_fp.h b/include/sbi/riscv_fp.h new file mode 100644 index 0000000..0deb8e4 --- /dev/null +++ b/include/sbi/riscv_fp.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2019 Western Digital Corporation or its affiliates. + * + * Authors: + * Anup Patel <anup.patel@wdc.com> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#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(fcsr) +#define SET_FCSR(value) csr_write(fcsr, (value)) +#define GET_FRM() csr_read(frm) +#define SET_FRM(value) csr_write(frm, (value)) +#define GET_FFLAGS() csr_read(fflags) +#define SET_FFLAGS(value) csr_write(fflags, (value)) + +#define SET_FS_DIRTY() ((void) 0) + +#else +#error "Floating point emulation not supported.\n" +#endif + +#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 |