fpu.rs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. use core::arch::asm;
  2. use eonix_hal_traits::fpu::RawFpuState;
  3. #[repr(C)]
  4. #[derive(Debug, Clone, Copy, Default)]
  5. pub struct FpuState {
  6. pub f: [u64; 32],
  7. pub fcsr: u32,
  8. }
  9. impl RawFpuState for FpuState {
  10. fn new() -> Self {
  11. unsafe { core::mem::zeroed() }
  12. }
  13. /// Save reg -> mem
  14. fn save(&mut self) {
  15. unsafe {
  16. let base_ptr: *mut u64 = self.f.as_mut_ptr();
  17. let fcsr_ptr: *mut u32 = &mut self.fcsr;
  18. let mut _fcsr_val: u32 = 0;
  19. asm!(
  20. "fsd f0, (0 * 8)({base})",
  21. "fsd f1, (1 * 8)({base})",
  22. "fsd f2, (2 * 8)({base})",
  23. "fsd f3, (3 * 8)({base})",
  24. "fsd f4, (4 * 8)({base})",
  25. "fsd f5, (5 * 8)({base})",
  26. "fsd f6, (6 * 8)({base})",
  27. "fsd f7, (7 * 8)({base})",
  28. "fsd f8, (8 * 8)({base})",
  29. "fsd f9, (9 * 8)({base})",
  30. "fsd f10, (10 * 8)({base})",
  31. "fsd f11, (11 * 8)({base})",
  32. "fsd f12, (12 * 8)({base})",
  33. "fsd f13, (13 * 8)({base})",
  34. "fsd f14, (14 * 8)({base})",
  35. "fsd f15, (15 * 8)({base})",
  36. "fsd f16, (16 * 8)({base})",
  37. "fsd f17, (17 * 8)({base})",
  38. "fsd f18, (18 * 8)({base})",
  39. "fsd f19, (19 * 8)({base})",
  40. "fsd f20, (20 * 8)({base})",
  41. "fsd f21, (21 * 8)({base})",
  42. "fsd f22, (22 * 8)({base})",
  43. "fsd f23, (23 * 8)({base})",
  44. "fsd f24, (24 * 8)({base})",
  45. "fsd f25, (25 * 8)({base})",
  46. "fsd f26, (26 * 8)({base})",
  47. "fsd f27, (27 * 8)({base})",
  48. "fsd f28, (28 * 8)({base})",
  49. "fsd f29, (29 * 8)({base})",
  50. "fsd f30, (30 * 8)({base})",
  51. "fsd f31, (31 * 8)({base})",
  52. "csrr {fcsr_val}, fcsr", // Read fcsr into fcsr_val (which is in a general-purpose register)
  53. "sw {fcsr_val}, 0({fcsr_ptr})",
  54. base = in(reg) base_ptr,
  55. fcsr_val = out(reg) _fcsr_val,
  56. fcsr_ptr = in(reg) fcsr_ptr,
  57. options(nostack, nomem, preserves_flags));
  58. }
  59. }
  60. fn restore(&mut self) {
  61. let base_ptr: *const u64 = self.f.as_ptr();
  62. let fcsr_ptr: *const u32 = &self.fcsr;
  63. let mut _fcsr_val: u64;
  64. unsafe {
  65. asm!(
  66. "fld f0, (0 * 8)({base})",
  67. "fld f1, (1 * 8)({base})",
  68. "fld f2, (2 * 8)({base})",
  69. "fld f3, (3 * 8)({base})",
  70. "fld f4, (4 * 8)({base})",
  71. "fld f5, (5 * 8)({base})",
  72. "fld f6, (6 * 8)({base})",
  73. "fld f7, (7 * 8)({base})",
  74. "fld f8, (8 * 8)({base})",
  75. "fld f9, (9 * 8)({base})",
  76. "fld f10, (10 * 8)({base})",
  77. "fld f11, (11 * 8)({base})",
  78. "fld f12, (12 * 8)({base})",
  79. "fld f13, (13 * 8)({base})",
  80. "fld f14, (14 * 8)({base})",
  81. "fld f15, (15 * 8)({base})",
  82. "fld f16, (16 * 8)({base})",
  83. "fld f17, (17 * 8)({base})",
  84. "fld f18, (18 * 8)({base})",
  85. "fld f19, (19 * 8)({base})",
  86. "fld f20, (20 * 8)({base})",
  87. "fld f21, (21 * 8)({base})",
  88. "fld f22, (22 * 8)({base})",
  89. "fld f23, (23 * 8)({base})",
  90. "fld f24, (24 * 8)({base})",
  91. "fld f25, (25 * 8)({base})",
  92. "fld f26, (26 * 8)({base})",
  93. "fld f27, (27 * 8)({base})",
  94. "fld f28, (28 * 8)({base})",
  95. "fld f29, (29 * 8)({base})",
  96. "fld f30, (30 * 8)({base})",
  97. "fld f31, (31 * 8)({base})",
  98. "lw {fcsr_val}, 0({fcsr_ptr})", // Load from memory (fcsr_ptr)
  99. "csrw fcsr, {fcsr_val}",
  100. base = in(reg) base_ptr,
  101. fcsr_val = out(reg) _fcsr_val,
  102. fcsr_ptr = in(reg) fcsr_ptr,
  103. options(nostack, preserves_flags));
  104. }
  105. }
  106. }