webassembly.pp 27 KB

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