fpu.rs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  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 fx: [u64; 32],
  7. pub fcc: u64,
  8. pub fcsr: u64,
  9. }
  10. impl RawFpuState for FpuState {
  11. fn new() -> Self {
  12. unsafe { core::mem::zeroed() }
  13. }
  14. /// Save reg -> mem
  15. fn save(&mut self) {
  16. unsafe {
  17. asm!(
  18. "fst.d $f0, {base}, 0 * 8",
  19. "fst.d $f1, {base}, 1 * 8",
  20. "fst.d $f2, {base}, 2 * 8",
  21. "fst.d $f3, {base}, 3 * 8",
  22. "fst.d $f4, {base}, 4 * 8",
  23. "fst.d $f5, {base}, 5 * 8",
  24. "fst.d $f6, {base}, 6 * 8",
  25. "fst.d $f7, {base}, 7 * 8",
  26. "fst.d $f8, {base}, 8 * 8",
  27. "fst.d $f9, {base}, 9 * 8",
  28. "fst.d $f10, {base}, 10 * 8",
  29. "fst.d $f11, {base}, 11 * 8",
  30. "fst.d $f12, {base}, 12 * 8",
  31. "fst.d $f13, {base}, 13 * 8",
  32. "fst.d $f14, {base}, 14 * 8",
  33. "fst.d $f15, {base}, 15 * 8",
  34. "fst.d $f16, {base}, 16 * 8",
  35. "fst.d $f17, {base}, 17 * 8",
  36. "fst.d $f18, {base}, 18 * 8",
  37. "fst.d $f19, {base}, 19 * 8",
  38. "fst.d $f20, {base}, 20 * 8",
  39. "fst.d $f21, {base}, 21 * 8",
  40. "fst.d $f22, {base}, 22 * 8",
  41. "fst.d $f23, {base}, 23 * 8",
  42. "fst.d $f24, {base}, 24 * 8",
  43. "fst.d $f25, {base}, 25 * 8",
  44. "fst.d $f26, {base}, 26 * 8",
  45. "fst.d $f27, {base}, 27 * 8",
  46. "fst.d $f28, {base}, 28 * 8",
  47. "fst.d $f29, {base}, 29 * 8",
  48. "fst.d $f30, {base}, 30 * 8",
  49. "fst.d $f31, {base}, 31 * 8",
  50. "",
  51. "movcf2gr {tmp}, $fcc0",
  52. "move {fcc}, {tmp}",
  53. "movcf2gr {tmp}, $fcc1",
  54. "bstrins.d {fcc}, {tmp}, 15, 8",
  55. "movcf2gr {tmp}, $fcc2",
  56. "bstrins.d {fcc}, {tmp}, 23, 16",
  57. "movcf2gr {tmp}, $fcc3",
  58. "bstrins.d {fcc}, {tmp}, 31, 24",
  59. "movcf2gr {tmp}, $fcc4",
  60. "bstrins.d {fcc}, {tmp}, 39, 32",
  61. "movcf2gr {tmp}, $fcc5",
  62. "bstrins.d {fcc}, {tmp}, 47, 40",
  63. "movcf2gr {tmp}, $fcc6",
  64. "bstrins.d {fcc}, {tmp}, 55, 48",
  65. "movcf2gr {tmp}, $fcc7",
  66. "bstrins.d {fcc}, {tmp}, 63, 56",
  67. "",
  68. "movfcsr2gr {fcsr}, $fcsr0",
  69. base = in(reg) &raw mut self.fx,
  70. tmp = out(reg) _,
  71. fcc = out(reg) self.fcc,
  72. fcsr = out(reg) self.fcsr,
  73. options(nostack, preserves_flags));
  74. }
  75. }
  76. fn restore(&mut self) {
  77. unsafe {
  78. asm!(
  79. "fld.d $f0, {base}, 0 * 8",
  80. "fld.d $f1, {base}, 1 * 8",
  81. "fld.d $f2, {base}, 2 * 8",
  82. "fld.d $f3, {base}, 3 * 8",
  83. "fld.d $f4, {base}, 4 * 8",
  84. "fld.d $f5, {base}, 5 * 8",
  85. "fld.d $f6, {base}, 6 * 8",
  86. "fld.d $f7, {base}, 7 * 8",
  87. "fld.d $f8, {base}, 8 * 8",
  88. "fld.d $f9, {base}, 9 * 8",
  89. "fld.d $f10, {base}, 10 * 8",
  90. "fld.d $f11, {base}, 11 * 8",
  91. "fld.d $f12, {base}, 12 * 8",
  92. "fld.d $f13, {base}, 13 * 8",
  93. "fld.d $f14, {base}, 14 * 8",
  94. "fld.d $f15, {base}, 15 * 8",
  95. "fld.d $f16, {base}, 16 * 8",
  96. "fld.d $f17, {base}, 17 * 8",
  97. "fld.d $f18, {base}, 18 * 8",
  98. "fld.d $f19, {base}, 19 * 8",
  99. "fld.d $f20, {base}, 20 * 8",
  100. "fld.d $f21, {base}, 21 * 8",
  101. "fld.d $f22, {base}, 22 * 8",
  102. "fld.d $f23, {base}, 23 * 8",
  103. "fld.d $f24, {base}, 24 * 8",
  104. "fld.d $f25, {base}, 25 * 8",
  105. "fld.d $f26, {base}, 26 * 8",
  106. "fld.d $f27, {base}, 27 * 8",
  107. "fld.d $f28, {base}, 28 * 8",
  108. "fld.d $f29, {base}, 29 * 8",
  109. "fld.d $f30, {base}, 30 * 8",
  110. "fld.d $f31, {base}, 31 * 8",
  111. "",
  112. "bstrpick.d {tmp}, {fcc}, 7, 0",
  113. "movgr2cf $fcc0, {tmp}",
  114. "bstrpick.d {tmp}, {fcc}, 15, 8",
  115. "movgr2cf $fcc1, {tmp}",
  116. "bstrpick.d {tmp}, {fcc}, 23, 16",
  117. "movgr2cf $fcc2, {tmp}",
  118. "bstrpick.d {tmp}, {fcc}, 31, 24",
  119. "movgr2cf $fcc3, {tmp}",
  120. "bstrpick.d {tmp}, {fcc}, 39, 32",
  121. "movgr2cf $fcc4, {tmp}",
  122. "bstrpick.d {tmp}, {fcc}, 47, 40",
  123. "movgr2cf $fcc5, {tmp}",
  124. "bstrpick.d {tmp}, {fcc}, 55, 48",
  125. "movgr2cf $fcc6, {tmp}",
  126. "bstrpick.d {tmp}, {fcc}, 63, 56",
  127. "movgr2cf $fcc7, {tmp}",
  128. "",
  129. "movgr2fcsr $fcsr0, {fcsr}",
  130. base = in(reg) &raw mut self.fx,
  131. fcc = in(reg) self.fcc,
  132. fcsr = in(reg) self.fcsr,
  133. tmp = out(reg) _,
  134. options(nostack, preserves_flags));
  135. }
  136. }
  137. }