riscv_fp.h 5.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. /*
  2. * SPDX-License-Identifier: BSD-2-Clause
  3. *
  4. * Copyright (c) 2019 Western Digital Corporation or its affiliates.
  5. *
  6. * Authors:
  7. * Anup Patel <anup.patel@wdc.com>
  8. */
  9. #ifndef __RISCV_FP_H__
  10. #define __RISCV_FP_H__
  11. #include <sbi/riscv_asm.h>
  12. #include <sbi/riscv_encoding.h>
  13. #include <sbi/sbi_types.h>
  14. #define GET_PRECISION(insn) (((insn) >> 25) & 3)
  15. #define GET_RM(insn) (((insn) >> 12) & 7)
  16. #define PRECISION_S 0
  17. #define PRECISION_D 1
  18. #ifdef __riscv_flen
  19. #define GET_F32_REG(insn, pos, regs) \
  20. ({ \
  21. register s32 value asm("a0") = \
  22. SHIFT_RIGHT(insn, (pos)-3) & 0xf8; \
  23. ulong tmp; \
  24. asm("1: auipc %0, %%pcrel_hi(get_f32_reg); add %0, %0, %1; jalr t0, %0, %%pcrel_lo(1b)" \
  25. : "=&r"(tmp), "+&r"(value)::"t0"); \
  26. value; \
  27. })
  28. #define SET_F32_REG(insn, pos, regs, val) \
  29. ({ \
  30. register u32 value asm("a0") = (val); \
  31. ulong offset = SHIFT_RIGHT(insn, (pos)-3) & 0xf8; \
  32. ulong tmp; \
  33. asm volatile( \
  34. "1: auipc %0, %%pcrel_hi(put_f32_reg); add %0, %0, %2; jalr t0, %0, %%pcrel_lo(1b)" \
  35. : "=&r"(tmp) \
  36. : "r"(value), "r"(offset) \
  37. : "t0"); \
  38. })
  39. #define init_fp_reg(i) SET_F32_REG((i) << 3, 3, 0, 0)
  40. #define GET_F64_REG(insn, pos, regs) \
  41. ({ \
  42. register ulong value asm("a0") = \
  43. SHIFT_RIGHT(insn, (pos)-3) & 0xf8; \
  44. ulong tmp; \
  45. asm("1: auipc %0, %%pcrel_hi(get_f64_reg); add %0, %0, %1; jalr t0, %0, %%pcrel_lo(1b)" \
  46. : "=&r"(tmp), "+&r"(value)::"t0"); \
  47. sizeof(ulong) == 4 ? *(int64_t *)value : (int64_t)value; \
  48. })
  49. #define SET_F64_REG(insn, pos, regs, val) \
  50. ({ \
  51. uint64_t __val = (val); \
  52. register ulong value asm("a0") = \
  53. sizeof(ulong) == 4 ? (ulong)&__val : (ulong)__val; \
  54. ulong offset = SHIFT_RIGHT(insn, (pos)-3) & 0xf8; \
  55. ulong tmp; \
  56. asm volatile( \
  57. "1: auipc %0, %%pcrel_hi(put_f64_reg); add %0, %0, %2; jalr t0, %0, %%pcrel_lo(1b)" \
  58. : "=&r"(tmp) \
  59. : "r"(value), "r"(offset) \
  60. : "t0"); \
  61. })
  62. #define GET_FCSR() csr_read(CSR_FCSR)
  63. #define SET_FCSR(value) csr_write(CSR_FCSR, (value))
  64. #define GET_FRM() csr_read(CSR_FRM)
  65. #define SET_FRM(value) csr_write(CSR_FRM, (value))
  66. #define GET_FFLAGS() csr_read(CSR_FFLAGS)
  67. #define SET_FFLAGS(value) csr_write(CSR_FFLAGS, (value))
  68. #define SET_FS_DIRTY() ((void)0)
  69. #define GET_F32_RS1(insn, regs) (GET_F32_REG(insn, 15, regs))
  70. #define GET_F32_RS2(insn, regs) (GET_F32_REG(insn, 20, regs))
  71. #define GET_F32_RS3(insn, regs) (GET_F32_REG(insn, 27, regs))
  72. #define GET_F64_RS1(insn, regs) (GET_F64_REG(insn, 15, regs))
  73. #define GET_F64_RS2(insn, regs) (GET_F64_REG(insn, 20, regs))
  74. #define GET_F64_RS3(insn, regs) (GET_F64_REG(insn, 27, regs))
  75. #define SET_F32_RD(insn, regs, val) \
  76. (SET_F32_REG(insn, 7, regs, val), SET_FS_DIRTY())
  77. #define SET_F64_RD(insn, regs, val) \
  78. (SET_F64_REG(insn, 7, regs, val), SET_FS_DIRTY())
  79. #define GET_F32_RS2C(insn, regs) (GET_F32_REG(insn, 2, regs))
  80. #define GET_F32_RS2S(insn, regs) (GET_F32_REG(RVC_RS2S(insn), 0, regs))
  81. #define GET_F64_RS2C(insn, regs) (GET_F64_REG(insn, 2, regs))
  82. #define GET_F64_RS2S(insn, regs) (GET_F64_REG(RVC_RS2S(insn), 0, regs))
  83. #endif
  84. #endif