xtensa.inc 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2003 by the Free Pascal development team.
  4. Processor dependent implementation for the system unit for
  5. Xtensa
  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. {$define FPC_SYSTEM_HAS_SYSRESETFPU}
  13. Procedure SysResetFPU;{$ifdef SYSTEMINLINE}inline;{$endif}
  14. begin
  15. end;
  16. {$define FPC_SYSTEM_HAS_SYSINITFPU}
  17. Procedure SysInitFPU;{$ifdef SYSTEMINLINE}inline;{$endif}
  18. begin
  19. end;
  20. procedure fpc_cpuinit;
  21. begin
  22. { don't let libraries influence the FPU cw set by the host program }
  23. if not IsLibrary then
  24. SysInitFPU;
  25. end;
  26. {$ifdef fpc_abi_windowed}
  27. const
  28. // Minimum call8 calls to force register spilling to stack for caller of forceSpilledRegs
  29. spillcount = 6;
  30. procedure forceSpilledRegs(n: uint32); assembler; public name 'forcespilledregs';
  31. label
  32. done, fin;
  33. asm
  34. beqz a2, done
  35. addi a10, a2, -1
  36. call8 forcespilledregs
  37. done:
  38. bnez a2, fin
  39. movi a15, 0
  40. fin:
  41. end;
  42. procedure fixCodeAddress(var addr: pointer);
  43. begin
  44. // Check if valid code address
  45. if ptruint(addr) and $C0000000 >= $40000000 then
  46. begin
  47. // Replace windowed call prefix
  48. addr:=codepointer((ptruint(addr)and$00FFFFFF) or $40000000);
  49. // Rewind to call instruction address
  50. dec(addr,3);
  51. end
  52. else
  53. addr:=nil;
  54. end;
  55. {$endif fpc_abi_windowed}
  56. {$IFNDEF INTERNAL_BACKTRACE}
  57. {$define FPC_SYSTEM_HAS_GET_FRAME}
  58. function get_frame:pointer;assembler;
  59. label
  60. done;
  61. asm
  62. {$ifdef fpc_abi_windowed}
  63. // Force registers to spill onto stack
  64. movi a10, spillcount
  65. call8 forcespilledregs
  66. // now get frame pointer of caller
  67. addi a2, a1, -12
  68. l32i a2, a2, 0
  69. done:
  70. {$else}
  71. mov a2, a1
  72. {$endif}
  73. end;
  74. {$ENDIF not INTERNAL_BACKTRACE}
  75. {$define FPC_SYSTEM_HAS_GET_CALLER_ADDR}
  76. function get_caller_addr(framebp:pointer;addr:pointer=nil):pointer;
  77. begin
  78. {$ifdef fpc_abi_windowed}
  79. forceSpilledRegs(spillcount);
  80. if (ptruint(framebp)>$3ff00000)and(ptruint(framebp)<$40000000) then
  81. begin
  82. get_caller_addr:=pointer((framebp-16)^);
  83. fixCodeAddress(get_caller_addr);
  84. end
  85. else
  86. get_caller_addr:=nil;
  87. {$else}
  88. get_caller_addr:=nil;
  89. {$endif}
  90. end;
  91. {$define FPC_SYSTEM_HAS_GET_CALLER_FRAME}
  92. function get_caller_frame(framebp:pointer;addr:pointer=nil):pointer;
  93. begin
  94. {$ifdef fpc_abi_windowed}
  95. if (ptruint(framebp)>$3ff00000)and(ptruint(framebp)<$40000000) then
  96. begin
  97. forceSpilledRegs(spillcount);
  98. get_caller_frame:=pointer((framebp-12)^);
  99. end
  100. else
  101. get_caller_frame:=nil;
  102. {$else}
  103. get_caller_frame:=nil;
  104. {$endif}
  105. end;
  106. {$ifdef fpc_abi_windowed}
  107. {$define FPC_SYSTEM_HAS_GET_CALLER_STACKINFO}
  108. procedure get_caller_stackinfo(var framebp : pointer; var addr : codepointer);
  109. begin
  110. if (ptruint(framebp)>$3ff00000)and(ptruint(framebp)<$40000000) then
  111. begin
  112. forceSpilledRegs(spillcount);
  113. addr:=codepointer((framebp-16)^);
  114. framebp := pointer((framebp-12)^);
  115. fixCodeAddress(addr);
  116. end
  117. else
  118. begin
  119. addr:=nil;
  120. framebp:=nil;
  121. end;
  122. end;
  123. {$endif fpc_abi_windowed}
  124. {$define FPC_SYSTEM_HAS_SPTR}
  125. Function Sptr : pointer;assembler;
  126. asm
  127. mov a2,a1
  128. end;
  129. {$define FPC_SYSTEM_HAS_STACKTOP}
  130. // Interim fix for now, set to large address
  131. // TODO: provide more realistic value, possibly by inspecting stack pointer
  132. // when main or task is started
  133. function StackTop: pointer;
  134. begin
  135. StackTop:=pointer($3fffffff);
  136. end;
  137. function InterLockedDecrement (var Target: longint) : longint;
  138. var
  139. temp_sreg : byte;
  140. begin
  141. Result:=Target-1;
  142. Target:=Result;
  143. end;
  144. function InterLockedIncrement (var Target: longint) : longint;
  145. var
  146. temp_sreg : byte;
  147. begin
  148. Result:=Target+1;
  149. Target:=Result;
  150. end;
  151. function InterLockedExchange (var Target: longint;Source : longint) : longint;
  152. var
  153. temp_sreg : byte;
  154. begin
  155. Result:=Target;
  156. Target:=Source;
  157. end;
  158. function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint;
  159. var
  160. temp_sreg : byte;
  161. begin
  162. Result:=Target;
  163. if Result=Comperand then
  164. Target:=NewValue;
  165. end;
  166. function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint;
  167. var
  168. temp_sreg : byte;
  169. begin
  170. Result:=Target;
  171. Target:=Result+Source;
  172. end;
  173. function InterLockedDecrement (var Target: smallint) : smallint;
  174. var
  175. temp_sreg : byte;
  176. begin
  177. Result:=Target-1;
  178. Target:=Result;
  179. end;
  180. function InterLockedIncrement (var Target: smallint) : smallint;
  181. var
  182. temp_sreg : byte;
  183. begin
  184. Result:=Target+1;
  185. Target:=Result;
  186. end;
  187. function InterLockedExchange (var Target: smallint;Source : smallint) : smallint;
  188. var
  189. temp_sreg : byte;
  190. begin
  191. Result:=Target;
  192. Target:=Source;
  193. end;
  194. function InterlockedCompareExchange(var Target: smallint; NewValue: smallint; Comperand: smallint): smallint;
  195. var
  196. temp_sreg : byte;
  197. begin
  198. Result:=Target;
  199. if Result=Comperand then
  200. Target:=NewValue;
  201. end;
  202. function InterLockedExchangeAdd (var Target: smallint;Source : smallint) : smallint;
  203. var
  204. temp_sreg : byte;
  205. begin
  206. Result:=Target;
  207. Target:=Result+Source;
  208. end;