m68kamiga.inc 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2015-2016 by Karoly Balogh,
  4. member of the Free Pascal development team.
  5. Amiga specific m68k functions
  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. { The Amiga hardware doesn't support the m68k CPU's atomic operations
  13. like TAS, CAS, CAS2 and so on. Therefore we must "emulate" them from
  14. software. The easiest way is the Forbid()/Permit() OS call pair around
  15. the ops themselves. It of course won't be hardware-atomic, but should
  16. be safe for multithreading. (KB) }
  17. {$DEFINE FPC_SYSTEM_HAS_INTERLOCKEDFUNCS}
  18. {$ifdef VER3_2}
  19. function InterLockedDecrement (var Target: longint) : longint;
  20. {$else VER3_2}
  21. {$define FPC_SYSTEM_HAS_ATOMIC_DEC_32}
  22. function fpc_atomic_dec_32 (var Target: longint) : longint;
  23. {$endif VER3_2}
  24. begin
  25. Forbid;
  26. Dec(Target);
  27. Result := Target;
  28. Permit;
  29. end;
  30. {$ifdef VER3_2}
  31. function InterLockedIncrement (var Target: longint) : longint;
  32. {$else VER3_2}
  33. {$define FPC_SYSTEM_HAS_ATOMIC_INC_32}
  34. function fpc_atomic_inc_32 (var Target: longint) : longint;
  35. {$endif VER3_2}
  36. begin
  37. Forbid;
  38. Inc(Target);
  39. Result := Target;
  40. Permit;
  41. end;
  42. {$ifdef VER3_2}
  43. function InterLockedExchange (var Target: longint;Source : longint) : longint;
  44. {$else VER3_2}
  45. {$define FPC_SYSTEM_HAS_ATOMIC_XCHG_32}
  46. function fpc_atomic_xchg_32 (var Target: longint;Source : longint) : longint;
  47. {$endif VER3_2}
  48. begin
  49. Forbid;
  50. Result := Target;
  51. Target := Source;
  52. Permit;
  53. end;
  54. {$ifdef VER3_2}
  55. function InterLockedExchangeAdd (var Target: longint;Source : longint) : longint;
  56. {$else VER3_2}
  57. {$define FPC_SYSTEM_HAS_ATOMIC_ADD_32}
  58. function fpc_atomic_add_32 (var Target: longint;Value : longint) : longint;
  59. {$endif VER3_2}
  60. begin
  61. Forbid;
  62. Result := Target;
  63. Target := Target + {$ifdef VER3_2}Source{$else}Value{$endif};
  64. Permit;
  65. end;
  66. {$ifdef VER3_2}
  67. function InterlockedCompareExchange(var Target: longint; NewValue: longint; Comperand: longint): longint;
  68. {$else VER3_2}
  69. {$define FPC_SYSTEM_HAS_ATOMIC_CMP_XCHG_32}
  70. function fpc_atomic_cmp_xchg_32 (var Target: longint; NewValue: longint; Comparand: longint) : longint; [public,alias:'FPC_ATOMIC_CMP_XCHG_32'];
  71. {$endif VER3_2}
  72. begin
  73. Forbid;
  74. Result := Target;
  75. if Target = {$ifdef VER3_2}Comperand{$else}Comparand{$endif} then
  76. Target := NewValue;
  77. Permit;
  78. end;
  79. { AmigaOS tells us what CPU we run on, so just use that }
  80. {$DEFINE FPC_SYSTEM_HAS_TEST68K}
  81. procedure Test68k(var CPU: byte; var FPU: byte);
  82. var
  83. flags: DWord;
  84. begin
  85. flags:=PExecBase(AOS_ExecBase)^.AttnFlags;
  86. CPU:=0;
  87. if (flags and AFF_68010) > 0 then CPU:=1;
  88. if (flags and AFF_68020) > 0 then CPU:=2;
  89. if (flags and AFF_68030) > 0 then CPU:=3;
  90. if (flags and AFF_68040) > 0 then CPU:=4;
  91. if (flags and AFF_68060) > 0 then CPU:=6;
  92. FPU:=0;
  93. if (flags and AFF_68881) > 0 then FPU:=1;
  94. if (flags and AFF_68882) > 0 then FPU:=2;
  95. if (flags and AFF_FPU40) > 0 then FPU:=CPU; // 040 or 060 with FPU
  96. end;