webassembly.pp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964
  1. {
  2. This file is part of the Free Pascal run time library.
  3. Copyright (c) 2022 by Nikolay Nikolov
  4. This unit contains some WebAssembly-specific routines
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. {$IFNDEF FPC_DOTTEDUNITS}
  12. unit WebAssembly;
  13. {$ENDIF FPC_DOTTEDUNITS}
  14. {$mode objfpc}
  15. interface
  16. const
  17. { Special values for the TimeoutNanoseconds parameter of AtomicWait }
  18. awtInfiniteTimeout = -1;
  19. { AtomicWait result values }
  20. awrOk = 0; { woken by another agent in the cluster }
  21. awrNotEqual = 1; { the loaded value did not match the expected value }
  22. awrTimedOut = 2; { not woken before timeout expired }
  23. procedure AtomicFence; inline;
  24. function AtomicLoad(constref Mem: Int8): Int8; inline;
  25. function AtomicLoad(constref Mem: UInt8): UInt8; inline;
  26. function AtomicLoad(constref Mem: Int16): Int16; inline;
  27. function AtomicLoad(constref Mem: UInt16): UInt16; inline;
  28. function AtomicLoad(constref Mem: Int32): Int32; inline;
  29. function AtomicLoad(constref Mem: UInt32): UInt32; inline;
  30. function AtomicLoad(constref Mem: Int64): Int64; inline;
  31. function AtomicLoad(constref Mem: UInt64): UInt64; inline;
  32. procedure AtomicStore(out Mem: Int8; Data: Int8); inline;
  33. procedure AtomicStore(out Mem: UInt8; Data: UInt8); inline;
  34. procedure AtomicStore(out Mem: Int16; Data: Int16); inline;
  35. procedure AtomicStore(out Mem: UInt16; Data: UInt16); inline;
  36. procedure AtomicStore(out Mem: Int32; Data: Int32); inline;
  37. procedure AtomicStore(out Mem: UInt32; Data: UInt32); inline;
  38. procedure AtomicStore(out Mem: Int64; Data: Int64); inline;
  39. procedure AtomicStore(out Mem: UInt64; Data: UInt64); inline;
  40. function AtomicAdd(var Mem: Int8; Data: Int8): Int8; inline;
  41. function AtomicAdd(var Mem: UInt8; Data: UInt8): UInt8; inline;
  42. function AtomicAdd(var Mem: Int16; Data: Int16): Int16; inline;
  43. function AtomicAdd(var Mem: UInt16; Data: UInt16): UInt16; inline;
  44. function AtomicAdd(var Mem: Int32; Data: Int32): Int32; inline;
  45. function AtomicAdd(var Mem: UInt32; Data: UInt32): UInt32; inline;
  46. function AtomicAdd(var Mem: Int64; Data: Int64): Int64; inline;
  47. function AtomicAdd(var Mem: UInt64; Data: UInt64): UInt64; inline;
  48. function AtomicSub(var Mem: Int8; Data: Int8): Int8; inline;
  49. function AtomicSub(var Mem: UInt8; Data: UInt8): UInt8; inline;
  50. function AtomicSub(var Mem: Int16; Data: Int16): Int16; inline;
  51. function AtomicSub(var Mem: UInt16; Data: UInt16): UInt16; inline;
  52. function AtomicSub(var Mem: Int32; Data: Int32): Int32; inline;
  53. function AtomicSub(var Mem: UInt32; Data: UInt32): UInt32; inline;
  54. function AtomicSub(var Mem: Int64; Data: Int64): Int64; inline;
  55. function AtomicSub(var Mem: UInt64; Data: UInt64): UInt64; inline;
  56. function AtomicAnd(var Mem: Int8; Data: Int8): Int8; inline;
  57. function AtomicAnd(var Mem: UInt8; Data: UInt8): UInt8; inline;
  58. function AtomicAnd(var Mem: Int16; Data: Int16): Int16; inline;
  59. function AtomicAnd(var Mem: UInt16; Data: UInt16): UInt16; inline;
  60. function AtomicAnd(var Mem: Int32; Data: Int32): Int32; inline;
  61. function AtomicAnd(var Mem: UInt32; Data: UInt32): UInt32; inline;
  62. function AtomicAnd(var Mem: Int64; Data: Int64): Int64; inline;
  63. function AtomicAnd(var Mem: UInt64; Data: UInt64): UInt64; inline;
  64. function AtomicOr(var Mem: Int8; Data: Int8): Int8; inline;
  65. function AtomicOr(var Mem: UInt8; Data: UInt8): UInt8; inline;
  66. function AtomicOr(var Mem: Int16; Data: Int16): Int16; inline;
  67. function AtomicOr(var Mem: UInt16; Data: UInt16): UInt16; inline;
  68. function AtomicOr(var Mem: Int32; Data: Int32): Int32; inline;
  69. function AtomicOr(var Mem: UInt32; Data: UInt32): UInt32; inline;
  70. function AtomicOr(var Mem: Int64; Data: Int64): Int64; inline;
  71. function AtomicOr(var Mem: UInt64; Data: UInt64): UInt64; inline;
  72. function AtomicXor(var Mem: Int8; Data: Int8): Int8; inline;
  73. function AtomicXor(var Mem: UInt8; Data: UInt8): UInt8; inline;
  74. function AtomicXor(var Mem: Int16; Data: Int16): Int16; inline;
  75. function AtomicXor(var Mem: UInt16; Data: UInt16): UInt16; inline;
  76. function AtomicXor(var Mem: Int32; Data: Int32): Int32; inline;
  77. function AtomicXor(var Mem: UInt32; Data: UInt32): UInt32; inline;
  78. function AtomicXor(var Mem: Int64; Data: Int64): Int64; inline;
  79. function AtomicXor(var Mem: UInt64; Data: UInt64): UInt64; inline;
  80. function AtomicExchange(var Mem: Int8; Data: Int8): Int8; inline;
  81. function AtomicExchange(var Mem: UInt8; Data: UInt8): UInt8; inline;
  82. function AtomicExchange(var Mem: Int16; Data: Int16): Int16; inline;
  83. function AtomicExchange(var Mem: UInt16; Data: UInt16): UInt16; inline;
  84. function AtomicExchange(var Mem: Int32; Data: Int32): Int32; inline;
  85. function AtomicExchange(var Mem: UInt32; Data: UInt32): UInt32; inline;
  86. function AtomicExchange(var Mem: Int64; Data: Int64): Int64; inline;
  87. function AtomicExchange(var Mem: UInt64; Data: UInt64): UInt64; inline;
  88. function AtomicCompareExchange(var Mem: Int8; Compare, Data: Int8): Int8; inline;
  89. function AtomicCompareExchange(var Mem: UInt8; Compare, Data: UInt8): UInt8; inline;
  90. function AtomicCompareExchange(var Mem: Int16; Compare, Data: Int16): Int16; inline;
  91. function AtomicCompareExchange(var Mem: UInt16; Compare, Data: UInt16): UInt16; inline;
  92. function AtomicCompareExchange(var Mem: Int32; Compare, Data: Int32): Int32; inline;
  93. function AtomicCompareExchange(var Mem: UInt32; Compare, Data: UInt32): UInt32; inline;
  94. function AtomicCompareExchange(var Mem: Int64; Compare, Data: Int64): Int64; inline;
  95. function AtomicCompareExchange(var Mem: UInt64; Compare, Data: UInt64): UInt64; inline;
  96. function AtomicWait(constref Mem: Int32; Compare: Int32; TimeoutNanoseconds: Int64): Int32; inline;
  97. function AtomicWait(constref Mem: UInt32; Compare: UInt32; TimeoutNanoseconds: Int64): Int32; inline;
  98. function AtomicWait(constref Mem: Int64; Compare: Int64; TimeoutNanoseconds: Int64): Int32; inline;
  99. function AtomicWait(constref Mem: UInt64; Compare: UInt64; TimeoutNanoseconds: Int64): Int32; inline;
  100. function AtomicNotify(constref Mem: Int32; Count: UInt32): UInt32; inline;
  101. function AtomicNotify(constref Mem: UInt32; Count: UInt32): UInt32; inline;
  102. function AtomicNotify(constref Mem: Int64; Count: UInt32): UInt32; inline;
  103. function AtomicNotify(constref Mem: UInt64; Count: UInt32): UInt32; inline;
  104. implementation
  105. {$I cpuh.inc}
  106. procedure AtomicFence; inline;
  107. begin
  108. {$ifdef FPC_WASM_THREADS}
  109. fpc_wasm32_atomic_fence;
  110. {$endif FPC_WASM_THREADS}
  111. end;
  112. function AtomicLoad(constref Mem: Int8): Int8; inline;
  113. begin
  114. {$ifdef FPC_WASM_THREADS}
  115. AtomicLoad:=Int8(fpc_wasm32_i32_atomic_load8_u(@Mem));
  116. {$else FPC_WASM_THREADS}
  117. AtomicLoad:=Mem;
  118. {$endif FPC_WASM_THREADS}
  119. end;
  120. function AtomicLoad(constref Mem: UInt8): UInt8; inline;
  121. begin
  122. {$ifdef FPC_WASM_THREADS}
  123. AtomicLoad:=UInt8(fpc_wasm32_i32_atomic_load8_u(@Mem));
  124. {$else FPC_WASM_THREADS}
  125. AtomicLoad:=Mem;
  126. {$endif FPC_WASM_THREADS}
  127. end;
  128. function AtomicLoad(constref Mem: Int16): Int16; inline;
  129. begin
  130. {$ifdef FPC_WASM_THREADS}
  131. AtomicLoad:=Int16(fpc_wasm32_i32_atomic_load16_u(@Mem));
  132. {$else FPC_WASM_THREADS}
  133. AtomicLoad:=Mem;
  134. {$endif FPC_WASM_THREADS}
  135. end;
  136. function AtomicLoad(constref Mem: UInt16): UInt16; inline;
  137. begin
  138. {$ifdef FPC_WASM_THREADS}
  139. AtomicLoad:=UInt16(fpc_wasm32_i32_atomic_load16_u(@Mem));
  140. {$else FPC_WASM_THREADS}
  141. AtomicLoad:=Mem;
  142. {$endif FPC_WASM_THREADS}
  143. end;
  144. function AtomicLoad(constref Mem: Int32): Int32; inline;
  145. begin
  146. {$ifdef FPC_WASM_THREADS}
  147. AtomicLoad:=Int32(fpc_wasm32_i32_atomic_load(@Mem));
  148. {$else FPC_WASM_THREADS}
  149. AtomicLoad:=Mem;
  150. {$endif FPC_WASM_THREADS}
  151. end;
  152. function AtomicLoad(constref Mem: UInt32): UInt32; inline;
  153. begin
  154. {$ifdef FPC_WASM_THREADS}
  155. AtomicLoad:=UInt32(fpc_wasm32_i32_atomic_load(@Mem));
  156. {$else FPC_WASM_THREADS}
  157. AtomicLoad:=Mem;
  158. {$endif FPC_WASM_THREADS}
  159. end;
  160. function AtomicLoad(constref Mem: Int64): Int64; inline;
  161. begin
  162. {$ifdef FPC_WASM_THREADS}
  163. AtomicLoad:=Int64(fpc_wasm32_i64_atomic_load(@Mem));
  164. {$else FPC_WASM_THREADS}
  165. AtomicLoad:=Mem;
  166. {$endif FPC_WASM_THREADS}
  167. end;
  168. function AtomicLoad(constref Mem: UInt64): UInt64; inline;
  169. begin
  170. {$ifdef FPC_WASM_THREADS}
  171. AtomicLoad:=UInt64(fpc_wasm32_i64_atomic_load(@Mem));
  172. {$else FPC_WASM_THREADS}
  173. AtomicLoad:=Mem;
  174. {$endif FPC_WASM_THREADS}
  175. end;
  176. procedure AtomicStore(out Mem: Int8; Data: Int8); inline;
  177. begin
  178. {$ifdef FPC_WASM_THREADS}
  179. fpc_wasm32_i32_atomic_store8(@Mem,Byte(Data));
  180. {$else FPC_WASM_THREADS}
  181. Mem:=Data;
  182. {$endif FPC_WASM_THREADS}
  183. end;
  184. procedure AtomicStore(out Mem: UInt8; Data: UInt8); inline;
  185. begin
  186. {$ifdef FPC_WASM_THREADS}
  187. fpc_wasm32_i32_atomic_store8(@Mem,Data);
  188. {$else FPC_WASM_THREADS}
  189. Mem:=Data;
  190. {$endif FPC_WASM_THREADS}
  191. end;
  192. procedure AtomicStore(out Mem: Int16; Data: Int16); inline;
  193. begin
  194. {$ifdef FPC_WASM_THREADS}
  195. fpc_wasm32_i32_atomic_store16(@Mem,Word(Data));
  196. {$else FPC_WASM_THREADS}
  197. Mem:=Data;
  198. {$endif FPC_WASM_THREADS}
  199. end;
  200. procedure AtomicStore(out Mem: UInt16; Data: UInt16); inline;
  201. begin
  202. {$ifdef FPC_WASM_THREADS}
  203. fpc_wasm32_i32_atomic_store16(@Mem,Data);
  204. {$else FPC_WASM_THREADS}
  205. Mem:=Data;
  206. {$endif FPC_WASM_THREADS}
  207. end;
  208. procedure AtomicStore(out Mem: Int32; Data: Int32); inline;
  209. begin
  210. {$ifdef FPC_WASM_THREADS}
  211. fpc_wasm32_i32_atomic_store(@Mem,LongWord(Data));
  212. {$else FPC_WASM_THREADS}
  213. Mem:=Data;
  214. {$endif FPC_WASM_THREADS}
  215. end;
  216. procedure AtomicStore(out Mem: UInt32; Data: UInt32); inline;
  217. begin
  218. {$ifdef FPC_WASM_THREADS}
  219. fpc_wasm32_i32_atomic_store(@Mem,Data);
  220. {$else FPC_WASM_THREADS}
  221. Mem:=Data;
  222. {$endif FPC_WASM_THREADS}
  223. end;
  224. procedure AtomicStore(out Mem: Int64; Data: Int64); inline;
  225. begin
  226. {$ifdef FPC_WASM_THREADS}
  227. fpc_wasm32_i64_atomic_store(@Mem,QWord(Data));
  228. {$else FPC_WASM_THREADS}
  229. Mem:=Data;
  230. {$endif FPC_WASM_THREADS}
  231. end;
  232. procedure AtomicStore(out Mem: UInt64; Data: UInt64); inline;
  233. begin
  234. {$ifdef FPC_WASM_THREADS}
  235. fpc_wasm32_i64_atomic_store(@Mem,Data);
  236. {$else FPC_WASM_THREADS}
  237. Mem:=Data;
  238. {$endif FPC_WASM_THREADS}
  239. end;
  240. function AtomicAdd(var Mem: Int8; Data: Int8): Int8; inline;
  241. begin
  242. {$ifdef FPC_WASM_THREADS}
  243. AtomicAdd:=Int8(fpc_wasm32_i32_atomic_rmw8_add_u(@Mem,Byte(Data)));
  244. {$else FPC_WASM_THREADS}
  245. {$push}{$Q-,R-}
  246. AtomicAdd:=Mem;
  247. Inc(Mem,Data);
  248. {$pop}
  249. {$endif FPC_WASM_THREADS}
  250. end;
  251. function AtomicAdd(var Mem: UInt8; Data: UInt8): UInt8; inline;
  252. begin
  253. {$ifdef FPC_WASM_THREADS}
  254. AtomicAdd:=UInt8(fpc_wasm32_i32_atomic_rmw8_add_u(@Mem,Data));
  255. {$else FPC_WASM_THREADS}
  256. {$push}{$Q-,R-}
  257. AtomicAdd:=Mem;
  258. Inc(Mem,Data);
  259. {$pop}
  260. {$endif FPC_WASM_THREADS}
  261. end;
  262. function AtomicAdd(var Mem: Int16; Data: Int16): Int16; inline;
  263. begin
  264. {$ifdef FPC_WASM_THREADS}
  265. AtomicAdd:=Int16(fpc_wasm32_i32_atomic_rmw16_add_u(@Mem,Word(Data)));
  266. {$else FPC_WASM_THREADS}
  267. {$push}{$Q-,R-}
  268. AtomicAdd:=Mem;
  269. Inc(Mem,Data);
  270. {$pop}
  271. {$endif FPC_WASM_THREADS}
  272. end;
  273. function AtomicAdd(var Mem: UInt16; Data: UInt16): UInt16; inline;
  274. begin
  275. {$ifdef FPC_WASM_THREADS}
  276. AtomicAdd:=UInt16(fpc_wasm32_i32_atomic_rmw16_add_u(@Mem,Data));
  277. {$else FPC_WASM_THREADS}
  278. {$push}{$Q-,R-}
  279. AtomicAdd:=Mem;
  280. Inc(Mem,Data);
  281. {$pop}
  282. {$endif FPC_WASM_THREADS}
  283. end;
  284. function AtomicAdd(var Mem: Int32; Data: Int32): Int32; inline;
  285. begin
  286. {$ifdef FPC_WASM_THREADS}
  287. AtomicAdd:=Int32(fpc_wasm32_i32_atomic_rmw_add(@Mem,LongWord(Data)));
  288. {$else FPC_WASM_THREADS}
  289. {$push}{$Q-,R-}
  290. AtomicAdd:=Mem;
  291. Inc(Mem,Data);
  292. {$pop}
  293. {$endif FPC_WASM_THREADS}
  294. end;
  295. function AtomicAdd(var Mem: UInt32; Data: UInt32): UInt32; inline;
  296. begin
  297. {$ifdef FPC_WASM_THREADS}
  298. AtomicAdd:=fpc_wasm32_i32_atomic_rmw_add(@Mem,Data);
  299. {$else FPC_WASM_THREADS}
  300. {$push}{$Q-,R-}
  301. AtomicAdd:=Mem;
  302. Inc(Mem,Data);
  303. {$pop}
  304. {$endif FPC_WASM_THREADS}
  305. end;
  306. function AtomicAdd(var Mem: Int64; Data: Int64): Int64; inline;
  307. begin
  308. {$ifdef FPC_WASM_THREADS}
  309. AtomicAdd:=Int64(fpc_wasm32_i64_atomic_rmw_add(@Mem,QWord(Data)));
  310. {$else FPC_WASM_THREADS}
  311. {$push}{$Q-,R-}
  312. AtomicAdd:=Mem;
  313. Inc(Mem,Data);
  314. {$pop}
  315. {$endif FPC_WASM_THREADS}
  316. end;
  317. function AtomicAdd(var Mem: UInt64; Data: UInt64): UInt64; inline;
  318. begin
  319. {$ifdef FPC_WASM_THREADS}
  320. AtomicAdd:=fpc_wasm32_i64_atomic_rmw_add(@Mem,Data);
  321. {$else FPC_WASM_THREADS}
  322. {$push}{$Q-,R-}
  323. AtomicAdd:=Mem;
  324. Inc(Mem,Data);
  325. {$pop}
  326. {$endif FPC_WASM_THREADS}
  327. end;
  328. function AtomicSub(var Mem: Int8; Data: Int8): Int8; inline;
  329. begin
  330. {$ifdef FPC_WASM_THREADS}
  331. AtomicSub:=Int8(fpc_wasm32_i32_atomic_rmw8_sub_u(@Mem,Byte(Data)));
  332. {$else FPC_WASM_THREADS}
  333. {$push}{$Q-,R-}
  334. AtomicSub:=Mem;
  335. Dec(Mem,Data);
  336. {$pop}
  337. {$endif FPC_WASM_THREADS}
  338. end;
  339. function AtomicSub(var Mem: UInt8; Data: UInt8): UInt8; inline;
  340. begin
  341. {$ifdef FPC_WASM_THREADS}
  342. AtomicSub:=UInt8(fpc_wasm32_i32_atomic_rmw8_sub_u(@Mem,Data));
  343. {$else FPC_WASM_THREADS}
  344. {$push}{$Q-,R-}
  345. AtomicSub:=Mem;
  346. Dec(Mem,Data);
  347. {$pop}
  348. {$endif FPC_WASM_THREADS}
  349. end;
  350. function AtomicSub(var Mem: Int16; Data: Int16): Int16; inline;
  351. begin
  352. {$ifdef FPC_WASM_THREADS}
  353. AtomicSub:=Int16(fpc_wasm32_i32_atomic_rmw16_sub_u(@Mem,Word(Data)));
  354. {$else FPC_WASM_THREADS}
  355. {$push}{$Q-,R-}
  356. AtomicSub:=Mem;
  357. Dec(Mem,Data);
  358. {$pop}
  359. {$endif FPC_WASM_THREADS}
  360. end;
  361. function AtomicSub(var Mem: UInt16; Data: UInt16): UInt16; inline;
  362. begin
  363. {$ifdef FPC_WASM_THREADS}
  364. AtomicSub:=UInt16(fpc_wasm32_i32_atomic_rmw16_sub_u(@Mem,Data));
  365. {$else FPC_WASM_THREADS}
  366. {$push}{$Q-,R-}
  367. AtomicSub:=Mem;
  368. Dec(Mem,Data);
  369. {$pop}
  370. {$endif FPC_WASM_THREADS}
  371. end;
  372. function AtomicSub(var Mem: Int32; Data: Int32): Int32; inline;
  373. begin
  374. {$ifdef FPC_WASM_THREADS}
  375. AtomicSub:=Int32(fpc_wasm32_i32_atomic_rmw_sub(@Mem,LongWord(Data)));
  376. {$else FPC_WASM_THREADS}
  377. {$push}{$Q-,R-}
  378. AtomicSub:=Mem;
  379. Dec(Mem,Data);
  380. {$pop}
  381. {$endif FPC_WASM_THREADS}
  382. end;
  383. function AtomicSub(var Mem: UInt32; Data: UInt32): UInt32; inline;
  384. begin
  385. {$ifdef FPC_WASM_THREADS}
  386. AtomicSub:=fpc_wasm32_i32_atomic_rmw_sub(@Mem,Data);
  387. {$else FPC_WASM_THREADS}
  388. {$push}{$Q-,R-}
  389. AtomicSub:=Mem;
  390. Dec(Mem,Data);
  391. {$pop}
  392. {$endif FPC_WASM_THREADS}
  393. end;
  394. function AtomicSub(var Mem: Int64; Data: Int64): Int64; inline;
  395. begin
  396. {$ifdef FPC_WASM_THREADS}
  397. AtomicSub:=Int64(fpc_wasm32_i64_atomic_rmw_sub(@Mem,QWord(Data)));
  398. {$else FPC_WASM_THREADS}
  399. {$push}{$Q-,R-}
  400. AtomicSub:=Mem;
  401. Dec(Mem,Data);
  402. {$pop}
  403. {$endif FPC_WASM_THREADS}
  404. end;
  405. function AtomicSub(var Mem: UInt64; Data: UInt64): UInt64; inline;
  406. begin
  407. {$ifdef FPC_WASM_THREADS}
  408. AtomicSub:=fpc_wasm32_i64_atomic_rmw_sub(@Mem,Data);
  409. {$else FPC_WASM_THREADS}
  410. {$push}{$Q-,R-}
  411. AtomicSub:=Mem;
  412. Dec(Mem,Data);
  413. {$pop}
  414. {$endif FPC_WASM_THREADS}
  415. end;
  416. function AtomicAnd(var Mem: Int8; Data: Int8): Int8; inline;
  417. begin
  418. {$ifdef FPC_WASM_THREADS}
  419. AtomicAnd:=Int8(fpc_wasm32_i32_atomic_rmw8_and_u(@Mem,Byte(Data)));
  420. {$else FPC_WASM_THREADS}
  421. AtomicAnd:=Mem;
  422. Mem:=Mem and Data;
  423. {$endif FPC_WASM_THREADS}
  424. end;
  425. function AtomicAnd(var Mem: UInt8; Data: UInt8): UInt8; inline;
  426. begin
  427. {$ifdef FPC_WASM_THREADS}
  428. AtomicAnd:=UInt8(fpc_wasm32_i32_atomic_rmw8_and_u(@Mem,Data));
  429. {$else FPC_WASM_THREADS}
  430. AtomicAnd:=Mem;
  431. Mem:=Mem and Data;
  432. {$endif FPC_WASM_THREADS}
  433. end;
  434. function AtomicAnd(var Mem: Int16; Data: Int16): Int16; inline;
  435. begin
  436. {$ifdef FPC_WASM_THREADS}
  437. AtomicAnd:=Int16(fpc_wasm32_i32_atomic_rmw16_and_u(@Mem,Word(Data)));
  438. {$else FPC_WASM_THREADS}
  439. AtomicAnd:=Mem;
  440. Mem:=Mem and Data;
  441. {$endif FPC_WASM_THREADS}
  442. end;
  443. function AtomicAnd(var Mem: UInt16; Data: UInt16): UInt16; inline;
  444. begin
  445. {$ifdef FPC_WASM_THREADS}
  446. AtomicAnd:=UInt16(fpc_wasm32_i32_atomic_rmw16_and_u(@Mem,Data));
  447. {$else FPC_WASM_THREADS}
  448. AtomicAnd:=Mem;
  449. Mem:=Mem and Data;
  450. {$endif FPC_WASM_THREADS}
  451. end;
  452. function AtomicAnd(var Mem: Int32; Data: Int32): Int32; inline;
  453. begin
  454. {$ifdef FPC_WASM_THREADS}
  455. AtomicAnd:=Int32(fpc_wasm32_i32_atomic_rmw_and(@Mem,LongWord(Data)));
  456. {$else FPC_WASM_THREADS}
  457. AtomicAnd:=Mem;
  458. Mem:=Mem and Data;
  459. {$endif FPC_WASM_THREADS}
  460. end;
  461. function AtomicAnd(var Mem: UInt32; Data: UInt32): UInt32; inline;
  462. begin
  463. {$ifdef FPC_WASM_THREADS}
  464. AtomicAnd:=fpc_wasm32_i32_atomic_rmw_and(@Mem,Data);
  465. {$else FPC_WASM_THREADS}
  466. AtomicAnd:=Mem;
  467. Mem:=Mem and Data;
  468. {$endif FPC_WASM_THREADS}
  469. end;
  470. function AtomicAnd(var Mem: Int64; Data: Int64): Int64; inline;
  471. begin
  472. {$ifdef FPC_WASM_THREADS}
  473. AtomicAnd:=Int64(fpc_wasm32_i64_atomic_rmw_and(@Mem,QWord(Data)));
  474. {$else FPC_WASM_THREADS}
  475. AtomicAnd:=Mem;
  476. Mem:=Mem and Data;
  477. {$endif FPC_WASM_THREADS}
  478. end;
  479. function AtomicAnd(var Mem: UInt64; Data: UInt64): UInt64; inline;
  480. begin
  481. {$ifdef FPC_WASM_THREADS}
  482. AtomicAnd:=fpc_wasm32_i64_atomic_rmw_and(@Mem,Data);
  483. {$else FPC_WASM_THREADS}
  484. AtomicAnd:=Mem;
  485. Mem:=Mem and Data;
  486. {$endif FPC_WASM_THREADS}
  487. end;
  488. function AtomicOr(var Mem: Int8; Data: Int8): Int8; inline;
  489. begin
  490. {$ifdef FPC_WASM_THREADS}
  491. AtomicOr:=Int8(fpc_wasm32_i32_atomic_rmw8_or_u(@Mem,Byte(Data)));
  492. {$else FPC_WASM_THREADS}
  493. AtomicOr:=Mem;
  494. Mem:=Mem or Data;
  495. {$endif FPC_WASM_THREADS}
  496. end;
  497. function AtomicOr(var Mem: UInt8; Data: UInt8): UInt8; inline;
  498. begin
  499. {$ifdef FPC_WASM_THREADS}
  500. AtomicOr:=UInt8(fpc_wasm32_i32_atomic_rmw8_or_u(@Mem,Data));
  501. {$else FPC_WASM_THREADS}
  502. AtomicOr:=Mem;
  503. Mem:=Mem or Data;
  504. {$endif FPC_WASM_THREADS}
  505. end;
  506. function AtomicOr(var Mem: Int16; Data: Int16): Int16; inline;
  507. begin
  508. {$ifdef FPC_WASM_THREADS}
  509. AtomicOr:=Int16(fpc_wasm32_i32_atomic_rmw16_or_u(@Mem,Word(Data)));
  510. {$else FPC_WASM_THREADS}
  511. AtomicOr:=Mem;
  512. Mem:=Mem or Data;
  513. {$endif FPC_WASM_THREADS}
  514. end;
  515. function AtomicOr(var Mem: UInt16; Data: UInt16): UInt16; inline;
  516. begin
  517. {$ifdef FPC_WASM_THREADS}
  518. AtomicOr:=UInt16(fpc_wasm32_i32_atomic_rmw16_or_u(@Mem,Data));
  519. {$else FPC_WASM_THREADS}
  520. AtomicOr:=Mem;
  521. Mem:=Mem or Data;
  522. {$endif FPC_WASM_THREADS}
  523. end;
  524. function AtomicOr(var Mem: Int32; Data: Int32): Int32; inline;
  525. begin
  526. {$ifdef FPC_WASM_THREADS}
  527. AtomicOr:=Int32(fpc_wasm32_i32_atomic_rmw_or(@Mem,LongWord(Data)));
  528. {$else FPC_WASM_THREADS}
  529. AtomicOr:=Mem;
  530. Mem:=Mem or Data;
  531. {$endif FPC_WASM_THREADS}
  532. end;
  533. function AtomicOr(var Mem: UInt32; Data: UInt32): UInt32; inline;
  534. begin
  535. {$ifdef FPC_WASM_THREADS}
  536. AtomicOr:=fpc_wasm32_i32_atomic_rmw_or(@Mem,Data);
  537. {$else FPC_WASM_THREADS}
  538. AtomicOr:=Mem;
  539. Mem:=Mem or Data;
  540. {$endif FPC_WASM_THREADS}
  541. end;
  542. function AtomicOr(var Mem: Int64; Data: Int64): Int64; inline;
  543. begin
  544. {$ifdef FPC_WASM_THREADS}
  545. AtomicOr:=Int64(fpc_wasm32_i64_atomic_rmw_or(@Mem,QWord(Data)));
  546. {$else FPC_WASM_THREADS}
  547. AtomicOr:=Mem;
  548. Mem:=Mem or Data;
  549. {$endif FPC_WASM_THREADS}
  550. end;
  551. function AtomicOr(var Mem: UInt64; Data: UInt64): UInt64; inline;
  552. begin
  553. {$ifdef FPC_WASM_THREADS}
  554. AtomicOr:=fpc_wasm32_i64_atomic_rmw_or(@Mem,Data);
  555. {$else FPC_WASM_THREADS}
  556. AtomicOr:=Mem;
  557. Mem:=Mem or Data;
  558. {$endif FPC_WASM_THREADS}
  559. end;
  560. function AtomicXor(var Mem: Int8; Data: Int8): Int8; inline;
  561. begin
  562. {$ifdef FPC_WASM_THREADS}
  563. AtomicXor:=Int8(fpc_wasm32_i32_atomic_rmw8_xor_u(@Mem,Byte(Data)));
  564. {$else FPC_WASM_THREADS}
  565. AtomicXor:=Mem;
  566. Mem:=Mem xor Data;
  567. {$endif FPC_WASM_THREADS}
  568. end;
  569. function AtomicXor(var Mem: UInt8; Data: UInt8): UInt8; inline;
  570. begin
  571. {$ifdef FPC_WASM_THREADS}
  572. AtomicXor:=UInt8(fpc_wasm32_i32_atomic_rmw8_xor_u(@Mem,Data));
  573. {$else FPC_WASM_THREADS}
  574. AtomicXor:=Mem;
  575. Mem:=Mem xor Data;
  576. {$endif FPC_WASM_THREADS}
  577. end;
  578. function AtomicXor(var Mem: Int16; Data: Int16): Int16; inline;
  579. begin
  580. {$ifdef FPC_WASM_THREADS}
  581. AtomicXor:=Int16(fpc_wasm32_i32_atomic_rmw16_xor_u(@Mem,Word(Data)));
  582. {$else FPC_WASM_THREADS}
  583. AtomicXor:=Mem;
  584. Mem:=Mem xor Data;
  585. {$endif FPC_WASM_THREADS}
  586. end;
  587. function AtomicXor(var Mem: UInt16; Data: UInt16): UInt16; inline;
  588. begin
  589. {$ifdef FPC_WASM_THREADS}
  590. AtomicXor:=UInt16(fpc_wasm32_i32_atomic_rmw16_xor_u(@Mem,Data));
  591. {$else FPC_WASM_THREADS}
  592. AtomicXor:=Mem;
  593. Mem:=Mem xor Data;
  594. {$endif FPC_WASM_THREADS}
  595. end;
  596. function AtomicXor(var Mem: Int32; Data: Int32): Int32; inline;
  597. begin
  598. {$ifdef FPC_WASM_THREADS}
  599. AtomicXor:=Int32(fpc_wasm32_i32_atomic_rmw_xor(@Mem,LongWord(Data)));
  600. {$else FPC_WASM_THREADS}
  601. AtomicXor:=Mem;
  602. Mem:=Mem xor Data;
  603. {$endif FPC_WASM_THREADS}
  604. end;
  605. function AtomicXor(var Mem: UInt32; Data: UInt32): UInt32; inline;
  606. begin
  607. {$ifdef FPC_WASM_THREADS}
  608. AtomicXor:=fpc_wasm32_i32_atomic_rmw_xor(@Mem,Data);
  609. {$else FPC_WASM_THREADS}
  610. AtomicXor:=Mem;
  611. Mem:=Mem xor Data;
  612. {$endif FPC_WASM_THREADS}
  613. end;
  614. function AtomicXor(var Mem: Int64; Data: Int64): Int64; inline;
  615. begin
  616. {$ifdef FPC_WASM_THREADS}
  617. AtomicXor:=Int64(fpc_wasm32_i64_atomic_rmw_xor(@Mem,QWord(Data)));
  618. {$else FPC_WASM_THREADS}
  619. AtomicXor:=Mem;
  620. Mem:=Mem xor Data;
  621. {$endif FPC_WASM_THREADS}
  622. end;
  623. function AtomicXor(var Mem: UInt64; Data: UInt64): UInt64; inline;
  624. begin
  625. {$ifdef FPC_WASM_THREADS}
  626. AtomicXor:=fpc_wasm32_i64_atomic_rmw_xor(@Mem,Data);
  627. {$else FPC_WASM_THREADS}
  628. AtomicXor:=Mem;
  629. Mem:=Mem xor Data;
  630. {$endif FPC_WASM_THREADS}
  631. end;
  632. function AtomicExchange(var Mem: Int8; Data: Int8): Int8; inline;
  633. begin
  634. {$ifdef FPC_WASM_THREADS}
  635. AtomicExchange:=Int8(fpc_wasm32_i32_atomic_rmw8_xchg_u(@Mem,Byte(Data)));
  636. {$else FPC_WASM_THREADS}
  637. AtomicExchange:=Mem;
  638. Mem:=Data;
  639. {$endif FPC_WASM_THREADS}
  640. end;
  641. function AtomicExchange(var Mem: UInt8; Data: UInt8): UInt8; inline;
  642. begin
  643. {$ifdef FPC_WASM_THREADS}
  644. AtomicExchange:=UInt8(fpc_wasm32_i32_atomic_rmw8_xchg_u(@Mem,Data));
  645. {$else FPC_WASM_THREADS}
  646. AtomicExchange:=Mem;
  647. Mem:=Data;
  648. {$endif FPC_WASM_THREADS}
  649. end;
  650. function AtomicExchange(var Mem: Int16; Data: Int16): Int16; inline;
  651. begin
  652. {$ifdef FPC_WASM_THREADS}
  653. AtomicExchange:=Int16(fpc_wasm32_i32_atomic_rmw16_xchg_u(@Mem,Word(Data)));
  654. {$else FPC_WASM_THREADS}
  655. AtomicExchange:=Mem;
  656. Mem:=Data;
  657. {$endif FPC_WASM_THREADS}
  658. end;
  659. function AtomicExchange(var Mem: UInt16; Data: UInt16): UInt16; inline;
  660. begin
  661. {$ifdef FPC_WASM_THREADS}
  662. AtomicExchange:=UInt16(fpc_wasm32_i32_atomic_rmw16_xchg_u(@Mem,Data));
  663. {$else FPC_WASM_THREADS}
  664. AtomicExchange:=Mem;
  665. Mem:=Data;
  666. {$endif FPC_WASM_THREADS}
  667. end;
  668. function AtomicExchange(var Mem: Int32; Data: Int32): Int32; inline;
  669. begin
  670. {$ifdef FPC_WASM_THREADS}
  671. AtomicExchange:=Int32(fpc_wasm32_i32_atomic_rmw_xchg(@Mem,LongWord(Data)));
  672. {$else FPC_WASM_THREADS}
  673. AtomicExchange:=Mem;
  674. Mem:=Data;
  675. {$endif FPC_WASM_THREADS}
  676. end;
  677. function AtomicExchange(var Mem: UInt32; Data: UInt32): UInt32; inline;
  678. begin
  679. {$ifdef FPC_WASM_THREADS}
  680. AtomicExchange:=fpc_wasm32_i32_atomic_rmw_xchg(@Mem,Data);
  681. {$else FPC_WASM_THREADS}
  682. AtomicExchange:=Mem;
  683. Mem:=Data;
  684. {$endif FPC_WASM_THREADS}
  685. end;
  686. function AtomicExchange(var Mem: Int64; Data: Int64): Int64; inline;
  687. begin
  688. {$ifdef FPC_WASM_THREADS}
  689. AtomicExchange:=Int64(fpc_wasm32_i64_atomic_rmw_xchg(@Mem,QWord(Data)));
  690. {$else FPC_WASM_THREADS}
  691. AtomicExchange:=Mem;
  692. Mem:=Data;
  693. {$endif FPC_WASM_THREADS}
  694. end;
  695. function AtomicExchange(var Mem: UInt64; Data: UInt64): UInt64; inline;
  696. begin
  697. {$ifdef FPC_WASM_THREADS}
  698. AtomicExchange:=fpc_wasm32_i64_atomic_rmw_xchg(@Mem,Data);
  699. {$else FPC_WASM_THREADS}
  700. AtomicExchange:=Mem;
  701. Mem:=Data;
  702. {$endif FPC_WASM_THREADS}
  703. end;
  704. function AtomicCompareExchange(var Mem: Int8; Compare, Data: Int8): Int8; inline;
  705. begin
  706. {$ifdef FPC_WASM_THREADS}
  707. AtomicCompareExchange:=Int8(fpc_wasm32_i32_atomic_rmw8_cmpxchg_u(@Mem,Byte(Compare),Byte(Data)));
  708. {$else FPC_WASM_THREADS}
  709. AtomicCompareExchange:=Mem;
  710. if Mem=Compare then
  711. Mem:=Data;
  712. {$endif FPC_WASM_THREADS}
  713. end;
  714. function AtomicCompareExchange(var Mem: UInt8; Compare, Data: UInt8): UInt8; inline;
  715. begin
  716. {$ifdef FPC_WASM_THREADS}
  717. AtomicCompareExchange:=UInt8(fpc_wasm32_i32_atomic_rmw8_cmpxchg_u(@Mem,Compare,Data));
  718. {$else FPC_WASM_THREADS}
  719. AtomicCompareExchange:=Mem;
  720. if Mem=Compare then
  721. Mem:=Data;
  722. {$endif FPC_WASM_THREADS}
  723. end;
  724. function AtomicCompareExchange(var Mem: Int16; Compare, Data: Int16): Int16; inline;
  725. begin
  726. {$ifdef FPC_WASM_THREADS}
  727. AtomicCompareExchange:=Int16(fpc_wasm32_i32_atomic_rmw16_cmpxchg_u(@Mem,Word(Compare),Word(Data)));
  728. {$else FPC_WASM_THREADS}
  729. AtomicCompareExchange:=Mem;
  730. if Mem=Compare then
  731. Mem:=Data;
  732. {$endif FPC_WASM_THREADS}
  733. end;
  734. function AtomicCompareExchange(var Mem: UInt16; Compare, Data: UInt16): UInt16; inline;
  735. begin
  736. {$ifdef FPC_WASM_THREADS}
  737. AtomicCompareExchange:=UInt16(fpc_wasm32_i32_atomic_rmw16_cmpxchg_u(@Mem,Compare,Data));
  738. {$else FPC_WASM_THREADS}
  739. AtomicCompareExchange:=Mem;
  740. if Mem=Compare then
  741. Mem:=Data;
  742. {$endif FPC_WASM_THREADS}
  743. end;
  744. function AtomicCompareExchange(var Mem: Int32; Compare, Data: Int32): Int32; inline;
  745. begin
  746. {$ifdef FPC_WASM_THREADS}
  747. AtomicCompareExchange:=Int32(fpc_wasm32_i32_atomic_rmw_cmpxchg_u(@Mem,LongWord(Compare),LongWord(Data)));
  748. {$else FPC_WASM_THREADS}
  749. AtomicCompareExchange:=Mem;
  750. if Mem=Compare then
  751. Mem:=Data;
  752. {$endif FPC_WASM_THREADS}
  753. end;
  754. function AtomicCompareExchange(var Mem: UInt32; Compare, Data: UInt32): UInt32; inline;
  755. begin
  756. {$ifdef FPC_WASM_THREADS}
  757. AtomicCompareExchange:=fpc_wasm32_i32_atomic_rmw_cmpxchg_u(@Mem,Compare,Data);
  758. {$else FPC_WASM_THREADS}
  759. AtomicCompareExchange:=Mem;
  760. if Mem=Compare then
  761. Mem:=Data;
  762. {$endif FPC_WASM_THREADS}
  763. end;
  764. function AtomicCompareExchange(var Mem: Int64; Compare, Data: Int64): Int64; inline;
  765. begin
  766. {$ifdef FPC_WASM_THREADS}
  767. AtomicCompareExchange:=Int64(fpc_wasm32_i64_atomic_rmw_cmpxchg_u(@Mem,QWord(Compare),QWord(Data)));
  768. {$else FPC_WASM_THREADS}
  769. AtomicCompareExchange:=Mem;
  770. if Mem=Compare then
  771. Mem:=Data;
  772. {$endif FPC_WASM_THREADS}
  773. end;
  774. function AtomicCompareExchange(var Mem: UInt64; Compare, Data: UInt64): UInt64; inline;
  775. begin
  776. {$ifdef FPC_WASM_THREADS}
  777. AtomicCompareExchange:=fpc_wasm32_i64_atomic_rmw_cmpxchg_u(@Mem,Compare,Data);
  778. {$else FPC_WASM_THREADS}
  779. AtomicCompareExchange:=Mem;
  780. if Mem=Compare then
  781. Mem:=Data;
  782. {$endif FPC_WASM_THREADS}
  783. end;
  784. function AtomicWait(constref Mem: Int32; Compare: Int32; TimeoutNanoseconds: Int64): Int32; inline;
  785. begin
  786. {$ifdef FPC_WASM_THREADS}
  787. AtomicWait:=fpc_wasm32_memory_atomic_wait32(@Mem,LongWord(Compare),TimeoutNanoseconds);
  788. {$else FPC_WASM_THREADS}
  789. if Mem<>Compare then
  790. AtomicWait:=awrNotEqual
  791. else
  792. AtomicWait:=awrTimedOut;
  793. {$endif FPC_WASM_THREADS}
  794. end;
  795. function AtomicWait(constref Mem: UInt32; Compare: UInt32; TimeoutNanoseconds: Int64): Int32; inline;
  796. begin
  797. {$ifdef FPC_WASM_THREADS}
  798. AtomicWait:=fpc_wasm32_memory_atomic_wait32(@Mem,Compare,TimeoutNanoseconds);
  799. {$else FPC_WASM_THREADS}
  800. if Mem<>Compare then
  801. AtomicWait:=awrNotEqual
  802. else
  803. AtomicWait:=awrTimedOut;
  804. {$endif FPC_WASM_THREADS}
  805. end;
  806. function AtomicWait(constref Mem: Int64; Compare: Int64; TimeoutNanoseconds: Int64): Int32; inline;
  807. begin
  808. {$ifdef FPC_WASM_THREADS}
  809. AtomicWait:=fpc_wasm32_memory_atomic_wait64(@Mem,QWord(Compare),TimeoutNanoseconds);
  810. {$else FPC_WASM_THREADS}
  811. if Mem<>Compare then
  812. AtomicWait:=awrNotEqual
  813. else
  814. AtomicWait:=awrTimedOut;
  815. {$endif FPC_WASM_THREADS}
  816. end;
  817. function AtomicWait(constref Mem: UInt64; Compare: UInt64; TimeoutNanoseconds: Int64): Int32; inline;
  818. begin
  819. {$ifdef FPC_WASM_THREADS}
  820. AtomicWait:=fpc_wasm32_memory_atomic_wait64(@Mem,Compare,TimeoutNanoseconds);
  821. {$else FPC_WASM_THREADS}
  822. if Mem<>Compare then
  823. AtomicWait:=awrNotEqual
  824. else
  825. AtomicWait:=awrTimedOut;
  826. {$endif FPC_WASM_THREADS}
  827. end;
  828. function AtomicNotify(constref Mem: Int32; Count: UInt32): UInt32; inline;
  829. begin
  830. {$ifdef FPC_WASM_THREADS}
  831. AtomicNotify:=fpc_wasm32_memory_atomic_notify(@Mem,Count);
  832. {$else FPC_WASM_THREADS}
  833. AtomicNotify:=0;
  834. {$endif FPC_WASM_THREADS}
  835. end;
  836. function AtomicNotify(constref Mem: UInt32; Count: UInt32): UInt32; inline;
  837. begin
  838. {$ifdef FPC_WASM_THREADS}
  839. AtomicNotify:=fpc_wasm32_memory_atomic_notify(@Mem,Count);
  840. {$else FPC_WASM_THREADS}
  841. AtomicNotify:=0;
  842. {$endif FPC_WASM_THREADS}
  843. end;
  844. function AtomicNotify(constref Mem: Int64; Count: UInt32): UInt32; inline;
  845. begin
  846. {$ifdef FPC_WASM_THREADS}
  847. AtomicNotify:=fpc_wasm32_memory_atomic_notify(@Mem,Count);
  848. {$else FPC_WASM_THREADS}
  849. AtomicNotify:=0;
  850. {$endif FPC_WASM_THREADS}
  851. end;
  852. function AtomicNotify(constref Mem: UInt64; Count: UInt32): UInt32; inline;
  853. begin
  854. {$ifdef FPC_WASM_THREADS}
  855. AtomicNotify:=fpc_wasm32_memory_atomic_notify(@Mem,Count);
  856. {$else FPC_WASM_THREADS}
  857. AtomicNotify:=0;
  858. {$endif FPC_WASM_THREADS}
  859. end;
  860. end.