riscv.inc 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2008 by the Free Pascal development team.
  4. Processor dependent implementation for the system unit for
  5. RiscV which is common to all RiscV types
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {****************************************************************************
  13. fpu exception related stuff
  14. ****************************************************************************}
  15. {$ifdef FPUFD}
  16. const
  17. fpu_nx = 1 shl 0;
  18. fpu_uf = 1 shl 1;
  19. fpu_of = 1 shl 2;
  20. fpu_dz = 1 shl 3;
  21. fpu_nv = 1 shl 4;
  22. function getfflags: sizeuint; nostackframe; assembler;
  23. asm
  24. frflags a0
  25. end;
  26. procedure setfflags(flags : sizeuint);
  27. begin
  28. DefaultFPUControlWord.cw:=flags;
  29. asm
  30. {$ifdef cpuriscv32}
  31. lw a0, flags
  32. {$else}
  33. ld a0, flags
  34. {$endif}
  35. fsflags a0
  36. end;
  37. end;
  38. function getrm: dword; nostackframe; assembler;
  39. asm
  40. frrm a0
  41. end;
  42. procedure setrm(val: dword);
  43. begin
  44. DefaultFPUControlWord.cw:=val;
  45. asm
  46. lw a0, val
  47. fsrm a0
  48. end;
  49. end;
  50. function GetNativeFPUControlWord: TNativeFPUControlWord; {$if defined(SYSTEMINLINE)}inline;{$endif}
  51. begin
  52. result.cw:=getfflags;
  53. result.rndmode:=getrm;
  54. end;
  55. procedure SetNativeFPUControlWord(const cw: TNativeFPUControlWord); {$if defined(SYSTEMINLINE)}inline;{$endif}
  56. begin
  57. setfflags(cw.cw);
  58. setrm(cw.rndmode);
  59. end;
  60. procedure RaisePendingExceptions;
  61. var
  62. fflags : sizeuint;
  63. f: TFPUException;
  64. begin
  65. fflags:=getfflags;
  66. if (fflags and fpu_dz) <> 0 then
  67. float_raise(exZeroDivide);
  68. if (fflags and fpu_of) <> 0 then
  69. float_raise(exOverflow);
  70. if (fflags and fpu_uf) <> 0 then
  71. float_raise(exUnderflow);
  72. if (fflags and fpu_nv) <> 0 then
  73. float_raise(exInvalidOp);
  74. if (fflags and fpu_nx) <> 0 then
  75. float_raise(exPrecision);
  76. { now the soft float exceptions }
  77. for f in softfloat_exception_flags do
  78. float_raise(f);
  79. end;
  80. procedure fpc_throwfpuexception;[public,alias:'FPC_THROWFPUEXCEPTION'];
  81. var
  82. fflags : sizeuint;
  83. begin
  84. fflags:=getfflags;
  85. { check, if the exception is masked }
  86. if ((fflags and fpu_dz) <> 0) and (exZeroDivide in softfloat_exception_mask) then
  87. fflags:=fflags and not(fpu_dz);
  88. if ((fflags and fpu_of) <> 0) and (exOverflow in softfloat_exception_mask) then
  89. fflags:=fflags and not(fpu_of);
  90. if ((fflags and fpu_uf) <> 0) and (exUnderflow in softfloat_exception_mask) then
  91. fflags:=fflags and not(fpu_uf);
  92. if ((fflags and fpu_nv) <> 0) and (exInvalidOp in softfloat_exception_mask) then
  93. fflags:=fflags and not(fpu_nv);
  94. if ((fflags and fpu_nx) <> 0) and (exPrecision in softfloat_exception_mask) then
  95. fflags:=fflags and not(fpu_nx);
  96. setfflags(fflags);
  97. if fflags<>0 then
  98. RaisePendingExceptions;
  99. end;
  100. {$endif FPUFD}
  101. {$define FPC_SYSTEM_HAS_SYSINITFPU}
  102. procedure SysInitFPU;
  103. {$ifdef FPUFD}
  104. var
  105. cw: TNativeFPUControlWord;
  106. {$endif}
  107. begin
  108. softfloat_exception_flags:=[];
  109. softfloat_exception_mask:=[exPrecision,exUnderflow];
  110. {$ifdef FPUFD}
  111. cw:=GetNativeFPUControlWord;
  112. { riscv does not support triggering exceptions when FPU exceptions happen;
  113. it merely records which exceptions have happened until now -> clear }
  114. cw.cw:=0;
  115. { round to nearest }
  116. cw.rndmode:=0;
  117. SetNativeFPUControlWord(cw);
  118. {$endif}
  119. end;
  120. {$define FPC_SYSTEM_HAS_SYSRESETFPU}
  121. Procedure SysResetFPU;
  122. {$ifdef FPUFD}
  123. var
  124. cw: TNativeFPUControlWord;
  125. {$endif}
  126. begin
  127. softfloat_exception_flags:=[];
  128. {$ifdef FPUFD}
  129. { clear all "exception happened" flags we care about}
  130. cw:=GetNativeFPUControlWord;
  131. cw.cw:=0;
  132. SetNativeFPUControlWord(cw);
  133. {$endif FPUFD}
  134. end;
  135. {$define FPC_SYSTEM_HAS_MEM_BARRIER}
  136. procedure ReadBarrier; assembler; nostackframe;
  137. asm
  138. fence ir, ir
  139. end;
  140. procedure ReadDependencyBarrier;
  141. begin
  142. end;
  143. procedure ReadWriteBarrier; assembler; nostackframe;
  144. asm
  145. fence iorw, iorw
  146. end;
  147. procedure WriteBarrier; assembler; nostackframe;
  148. asm
  149. fence ow, ow
  150. end;