riscv.inc 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  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. stack frame related stuff
  14. ****************************************************************************}
  15. {$IFNDEF INTERNAL_BACKTRACE}
  16. {$define FPC_SYSTEM_HAS_GET_FRAME}
  17. function get_frame:pointer;assembler;nostackframe;
  18. asm
  19. addi a0, fp, 0
  20. end;
  21. {$ENDIF not INTERNAL_BACKTRACE}
  22. {$define FPC_SYSTEM_HAS_SPTR}
  23. Function Sptr : pointer;assembler;nostackframe;
  24. asm
  25. addi a0, sp, 0
  26. end;
  27. {****************************************************************************
  28. fpu exception related stuff
  29. ****************************************************************************}
  30. {$ifdef FPUFD}
  31. const
  32. fpu_nx = 1 shl 0;
  33. fpu_uf = 1 shl 1;
  34. fpu_of = 1 shl 2;
  35. fpu_dz = 1 shl 3;
  36. fpu_nv = 1 shl 4;
  37. function getfflags: sizeuint; nostackframe; assembler;
  38. asm
  39. frflags a0
  40. end;
  41. procedure setfflags(flags : sizeuint);
  42. begin
  43. DefaultFPUControlWord.cw:=flags;
  44. asm
  45. {$ifdef cpuriscv32}
  46. lw a0, flags
  47. {$else}
  48. ld a0, flags
  49. {$endif}
  50. fsflags a0
  51. end;
  52. end;
  53. function getrm: dword; nostackframe; assembler;
  54. asm
  55. frrm a0
  56. end;
  57. procedure setrm(val: dword);
  58. begin
  59. DefaultFPUControlWord.cw:=val;
  60. asm
  61. lw a0, val
  62. fsrm a0
  63. end;
  64. end;
  65. function GetNativeFPUControlWord: TNativeFPUControlWord; {$if defined(SYSTEMINLINE)}inline;{$endif}
  66. begin
  67. result.cw:=getfflags;
  68. result.rndmode:=getrm;
  69. end;
  70. procedure SetNativeFPUControlWord(const cw: TNativeFPUControlWord); {$if defined(SYSTEMINLINE)}inline;{$endif}
  71. begin
  72. setfflags(cw.cw);
  73. setrm(cw.rndmode);
  74. end;
  75. procedure RaisePendingExceptions;
  76. var
  77. fflags : sizeuint;
  78. f: TFPUException;
  79. begin
  80. fflags:=getfflags;
  81. if (fflags and fpu_dz) <> 0 then
  82. float_raise(exZeroDivide);
  83. if (fflags and fpu_of) <> 0 then
  84. float_raise(exOverflow);
  85. if (fflags and fpu_uf) <> 0 then
  86. float_raise(exUnderflow);
  87. if (fflags and fpu_nv) <> 0 then
  88. float_raise(exInvalidOp);
  89. if (fflags and fpu_nx) <> 0 then
  90. float_raise(exPrecision);
  91. { now the soft float exceptions }
  92. for f in softfloat_exception_flags do
  93. float_raise(f);
  94. end;
  95. procedure fpc_throwfpuexception;[public,alias:'FPC_THROWFPUEXCEPTION'];
  96. var
  97. fflags : sizeuint;
  98. begin
  99. fflags:=getfflags;
  100. { check, if the exception is masked }
  101. if ((fflags and fpu_dz) <> 0) and (exZeroDivide in softfloat_exception_mask) then
  102. fflags:=fflags and not(fpu_dz);
  103. if ((fflags and fpu_of) <> 0) and (exOverflow in softfloat_exception_mask) then
  104. fflags:=fflags and not(fpu_of);
  105. if ((fflags and fpu_uf) <> 0) and (exUnderflow in softfloat_exception_mask) then
  106. fflags:=fflags and not(fpu_uf);
  107. if ((fflags and fpu_nv) <> 0) and (exInvalidOp in softfloat_exception_mask) then
  108. fflags:=fflags and not(fpu_nv);
  109. if ((fflags and fpu_nx) <> 0) and (exPrecision in softfloat_exception_mask) then
  110. fflags:=fflags and not(fpu_nx);
  111. setfflags(fflags);
  112. if fflags<>0 then
  113. RaisePendingExceptions;
  114. end;
  115. {$endif FPUFD}
  116. {$define FPC_SYSTEM_HAS_SYSINITFPU}
  117. procedure SysInitFPU;
  118. {$ifdef FPUFD}
  119. var
  120. cw: TNativeFPUControlWord;
  121. {$endif}
  122. begin
  123. softfloat_exception_flags:=[];
  124. softfloat_exception_mask:=[exPrecision,exUnderflow];
  125. {$ifdef FPUFD}
  126. cw:=GetNativeFPUControlWord;
  127. { riscv does not support triggering exceptions when FPU exceptions happen;
  128. it merely records which exceptions have happened until now -> clear }
  129. cw.cw:=0;
  130. { round to nearest }
  131. cw.rndmode:=0;
  132. SetNativeFPUControlWord(cw);
  133. {$endif}
  134. end;
  135. {$define FPC_SYSTEM_HAS_SYSRESETFPU}
  136. Procedure SysResetFPU;
  137. {$ifdef FPUFD}
  138. var
  139. cw: TNativeFPUControlWord;
  140. {$endif}
  141. begin
  142. softfloat_exception_flags:=[];
  143. {$ifdef FPUFD}
  144. { clear all "exception happened" flags we care about}
  145. cw:=GetNativeFPUControlWord;
  146. cw.cw:=0;
  147. SetNativeFPUControlWord(cw);
  148. {$endif FPUFD}
  149. end;
  150. {$define FPC_SYSTEM_HAS_MEM_BARRIER}
  151. procedure ReadBarrier; assembler; nostackframe;
  152. asm
  153. fence ir, ir
  154. end;
  155. procedure ReadDependencyBarrier;
  156. begin
  157. end;
  158. procedure ReadWriteBarrier; assembler; nostackframe;
  159. asm
  160. fence iorw, iorw
  161. end;
  162. procedure WriteBarrier; assembler; nostackframe;
  163. asm
  164. fence ow, ow
  165. end;
  166. {****************************************************************************
  167. atomic operations
  168. ****************************************************************************}
  169. {$define FPC_SYSTEM_HAS_DECLOCKED_LONGINT}
  170. function declocked(var l: longint) : boolean; inline;
  171. begin
  172. Result:=InterLockedDecrement(l) = 0;
  173. end;
  174. {$define FPC_SYSTEM_HAS_INCLOCKED_LONGINT}
  175. procedure inclocked(var l: longint); inline;
  176. begin
  177. InterLockedIncrement(l);
  178. end;