nwasminl.pas 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090
  1. {
  2. Copyright (c) 1998-2002, 2021 by Florian Klaempfl and Nikolay Nikolov
  3. Generate WebAssembly inline nodes
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  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. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. ****************************************************************************
  16. }
  17. unit nwasminl;
  18. {$i fpcdefs.inc}
  19. interface
  20. uses
  21. node,ncginl,cpubase;
  22. type
  23. { twasminlinenode }
  24. twasminlinenode = class(tcginlinenode)
  25. private
  26. function first_abs_real:tnode;override;
  27. function first_int_real:tnode;override;
  28. function first_sqrt_real:tnode;override;
  29. function first_trunc_real:tnode;override;
  30. function first_round_real:tnode;override;
  31. function first_popcnt:tnode;override;
  32. procedure second_abs_real;override;
  33. procedure second_int_real;override;
  34. procedure second_sqrt_real;override;
  35. procedure second_trunc_real;override;
  36. procedure second_round_real;override;
  37. procedure second_high; override;
  38. procedure second_popcnt;override;
  39. procedure second_memory_size;
  40. procedure second_memory_grow;
  41. procedure second_memory_fill;
  42. procedure second_memory_copy;
  43. procedure second_unreachable;
  44. procedure second_throw_fpcexception;
  45. procedure second_atomic_fence;
  46. procedure second_atomic_load(op: TAsmOp);
  47. procedure second_atomic_store(op: TAsmOp);
  48. procedure second_atomic_rmw_x_y(op: TAsmOp);
  49. procedure second_atomic_rmw_x_y_z(op: TAsmOp);
  50. procedure second_tls_get(const SymStr: string);
  51. procedure second_set_base_pointer;
  52. protected
  53. function first_sqr_real: tnode; override;
  54. public
  55. function pass_typecheck_cpu: tnode; override;
  56. function first_cpu: tnode; override;
  57. procedure pass_generate_code_cpu; override;
  58. procedure second_length;override;
  59. procedure second_sqr_real; override;
  60. end;
  61. implementation
  62. uses
  63. procinfo,
  64. ninl,ncal,compinnr,
  65. aasmbase,aasmdata,aasmcpu,
  66. cgbase,cgutils,
  67. hlcgobj,hlcgcpu,
  68. defutil,pass_2,verbose,
  69. symtype,symdef,symcpu,
  70. tgobj,tgcpu;
  71. {*****************************************************************************
  72. twasminlinenode
  73. *****************************************************************************}
  74. function twasminlinenode.first_abs_real: tnode;
  75. begin
  76. expectloc:=LOC_FPUREGISTER;
  77. result:=nil;
  78. end;
  79. function twasminlinenode.first_int_real: tnode;
  80. begin
  81. expectloc:=LOC_FPUREGISTER;
  82. result:=nil;
  83. end;
  84. function twasminlinenode.first_sqrt_real: tnode;
  85. begin
  86. expectloc:=LOC_FPUREGISTER;
  87. result:=nil;
  88. end;
  89. function twasminlinenode.first_trunc_real: tnode;
  90. begin
  91. expectloc:=LOC_REGISTER;
  92. result:=nil;
  93. end;
  94. function twasminlinenode.first_round_real: tnode;
  95. begin
  96. expectloc:=LOC_REGISTER;
  97. result:=nil;
  98. end;
  99. function twasminlinenode.first_popcnt: tnode;
  100. begin
  101. expectloc:=LOC_REGISTER;
  102. result:=nil;
  103. end;
  104. procedure twasminlinenode.second_abs_real;
  105. begin
  106. secondpass(left);
  107. hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
  108. thlcgwasm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location);
  109. case left.location.size of
  110. OS_F32:
  111. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_f32_abs));
  112. OS_F64:
  113. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_f64_abs));
  114. else
  115. internalerror(2021092902);
  116. end;
  117. location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
  118. location.register:=hlcg.getregisterfordef(current_asmdata.CurrAsmList,resultdef);
  119. thlcgwasm(hlcg).a_load_stack_loc(current_asmdata.CurrAsmList,resultdef,location);
  120. end;
  121. procedure twasminlinenode.second_int_real;
  122. begin
  123. secondpass(left);
  124. hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
  125. thlcgwasm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location);
  126. case left.location.size of
  127. OS_F32:
  128. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_f32_trunc));
  129. OS_F64:
  130. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_f64_trunc));
  131. else
  132. internalerror(2021092903);
  133. end;
  134. location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
  135. location.register:=hlcg.getregisterfordef(current_asmdata.CurrAsmList,resultdef);
  136. thlcgwasm(hlcg).a_load_stack_loc(current_asmdata.CurrAsmList,resultdef,location);
  137. end;
  138. procedure twasminlinenode.second_sqrt_real;
  139. begin
  140. secondpass(left);
  141. hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
  142. thlcgwasm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location);
  143. case left.location.size of
  144. OS_F32:
  145. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_f32_sqrt));
  146. OS_F64:
  147. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_f64_sqrt));
  148. else
  149. internalerror(2021092901);
  150. end;
  151. location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
  152. location.register:=hlcg.getregisterfordef(current_asmdata.CurrAsmList,resultdef);
  153. thlcgwasm(hlcg).a_load_stack_loc(current_asmdata.CurrAsmList,resultdef,location);
  154. end;
  155. procedure twasminlinenode.second_trunc_real;
  156. begin
  157. secondpass(left);
  158. hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
  159. thlcgwasm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location);
  160. case left.location.size of
  161. OS_F32:
  162. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_i64_trunc_f32_s));
  163. OS_F64:
  164. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_i64_trunc_f64_s));
  165. else
  166. internalerror(2021092904);
  167. end;
  168. location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
  169. location.register:=hlcg.getregisterfordef(current_asmdata.CurrAsmList,resultdef);
  170. thlcgwasm(hlcg).a_load_stack_loc(current_asmdata.CurrAsmList,resultdef,location);
  171. end;
  172. procedure twasminlinenode.second_round_real;
  173. begin
  174. secondpass(left);
  175. hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
  176. thlcgwasm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location);
  177. case left.location.size of
  178. OS_F32:
  179. begin
  180. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_f32_nearest));
  181. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_i64_trunc_f32_s));
  182. end;
  183. OS_F64:
  184. begin
  185. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_f64_nearest));
  186. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_i64_trunc_f64_s));
  187. end
  188. else
  189. internalerror(2021092905);
  190. end;
  191. location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
  192. location.register:=hlcg.getregisterfordef(current_asmdata.CurrAsmList,resultdef);
  193. thlcgwasm(hlcg).a_load_stack_loc(current_asmdata.CurrAsmList,resultdef,location);
  194. end;
  195. procedure twasminlinenode.second_high;
  196. var
  197. hightype: TWasmBasicType;
  198. begin
  199. secondpass(left);
  200. if not(is_dynamic_array(left.resultdef)) then
  201. Internalerror(2019122801);
  202. { determine the WasmBasicType of the result }
  203. if is_64bit(resultdef) then
  204. hightype:=wbt_i64
  205. else
  206. hightype:=wbt_i32;
  207. { length in dynamic arrays is at offset -sizeof(pint) }
  208. thlcgwasm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location);
  209. { 64-bit pointer values need a <>0 comparison to produce a 32-bit int on the stack (0 or 1) for the 'if' instruction.
  210. 32-bit pointer values don't need it, because 'if' already expects and pops a 32-bit int and checks for <>0. }
  211. if is_64bit(left.resultdef) then
  212. begin
  213. thlcgwasm(hlcg).a_load_const_stack(current_asmdata.CurrAsmList,left.resultdef,0,R_INTREGISTER);
  214. thlcgwasm(hlcg).a_cmp_stack_stack(current_asmdata.CurrAsmList,left.resultdef,OC_NE);
  215. end;
  216. { if not nil }
  217. current_asmdata.CurrAsmList.Concat(taicpu.op_functype(a_if,TWasmFuncType.Create([],[hightype])));
  218. thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,1);
  219. { volatility of the dyn. array refers to the volatility of the
  220. string pointer, not of the string data }
  221. thlcgwasm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location);
  222. { length in dynamic arrays is at offset -ossinttype.size }
  223. thlcgwasm(hlcg).a_op_const_stack(current_asmdata.CurrAsmList,OP_SUB,left.resultdef,ossinttype.size);
  224. { load length }
  225. if ossinttype.size=8 then
  226. current_asmdata.CurrAsmList.Concat(taicpu.op_const(a_i64_load,0))
  227. else
  228. current_asmdata.CurrAsmList.Concat(taicpu.op_const(a_i32_load,0));
  229. { else }
  230. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_else));
  231. thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,1);
  232. { high=-1 }
  233. thlcgwasm(hlcg).a_load_const_stack(current_asmdata.CurrAsmList,resultdef,-1,R_INTREGISTER);
  234. { endif }
  235. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_end_if));
  236. location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
  237. {$if not defined(cpu64bitalu) and not defined(cpuhighleveltarget)}
  238. if location.size in [OS_64,OS_S64] then
  239. begin
  240. location.register64.reglo := cg.getintregister(current_asmdata.CurrAsmList,OS_32);
  241. location.register64.reghi := cg.getintregister(current_asmdata.CurrAsmList,OS_32);
  242. end
  243. else
  244. {$endif}
  245. location.register := hlcg.getintregister(current_asmdata.CurrAsmList,resultdef);
  246. thlcgwasm(hlcg).a_load_stack_loc(current_asmdata.CurrAsmList,resultdef,location);
  247. end;
  248. procedure twasminlinenode.second_popcnt;
  249. begin
  250. secondpass(left);
  251. hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
  252. thlcgwasm(hlcg).a_load_reg_stack(current_asmdata.CurrAsmList,left.resultdef,left.location.register);
  253. if is_64bit(left.resultdef) then
  254. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_i64_popcnt))
  255. else
  256. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_i32_popcnt));
  257. location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
  258. location.register:=hlcg.getregisterfordef(current_asmdata.CurrAsmList,resultdef);
  259. thlcgwasm(hlcg).a_load_stack_loc(current_asmdata.CurrAsmList,resultdef,location);
  260. end;
  261. procedure twasminlinenode.second_memory_size;
  262. begin
  263. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_memory_size));
  264. thlcgwasm(hlcg).incstack(current_asmdata.CurrAsmList,1);
  265. location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
  266. location.register:=hlcg.getregisterfordef(current_asmdata.CurrAsmList,resultdef);
  267. thlcgwasm(hlcg).a_load_stack_loc(current_asmdata.CurrAsmList,resultdef,location);
  268. end;
  269. procedure twasminlinenode.second_memory_grow;
  270. begin
  271. secondpass(left);
  272. hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
  273. thlcgwasm(hlcg).a_load_reg_stack(current_asmdata.CurrAsmList,left.resultdef,left.location.register);
  274. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_memory_grow));
  275. location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
  276. location.register:=hlcg.getregisterfordef(current_asmdata.CurrAsmList,resultdef);
  277. thlcgwasm(hlcg).a_load_stack_loc(current_asmdata.CurrAsmList,resultdef,location);
  278. end;
  279. procedure twasminlinenode.second_memory_fill;
  280. begin
  281. location_reset(location,LOC_VOID,OS_NO);
  282. secondpass(tcallparanode(tcallparanode(tcallparanode(left).right).right).left);
  283. hlcg.location_force_reg(current_asmdata.CurrAsmList,
  284. tcallparanode(tcallparanode(tcallparanode(left).right).right).left.location,
  285. tcallparanode(tcallparanode(tcallparanode(left).right).right).left.resultdef,
  286. tcallparanode(tcallparanode(tcallparanode(left).right).right).left.resultdef,false);
  287. thlcgwasm(hlcg).a_load_reg_stack(current_asmdata.CurrAsmList,
  288. tcallparanode(tcallparanode(tcallparanode(left).right).right).left.resultdef,
  289. tcallparanode(tcallparanode(tcallparanode(left).right).right).left.location.register);
  290. secondpass(tcallparanode(tcallparanode(left).right).left);
  291. hlcg.location_force_reg(current_asmdata.CurrAsmList,
  292. tcallparanode(tcallparanode(left).right).left.location,
  293. tcallparanode(tcallparanode(left).right).left.resultdef,
  294. tcallparanode(tcallparanode(left).right).left.resultdef,false);
  295. thlcgwasm(hlcg).a_load_reg_stack(current_asmdata.CurrAsmList,
  296. tcallparanode(tcallparanode(left).right).left.resultdef,
  297. tcallparanode(tcallparanode(left).right).left.location.register);
  298. secondpass(tcallparanode(left).left);
  299. hlcg.location_force_reg(current_asmdata.CurrAsmList,
  300. tcallparanode(left).left.location,
  301. tcallparanode(left).left.resultdef,
  302. tcallparanode(left).left.resultdef,false);
  303. thlcgwasm(hlcg).a_load_reg_stack(current_asmdata.CurrAsmList,
  304. tcallparanode(left).left.resultdef,
  305. tcallparanode(left).left.location.register);
  306. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_memory_fill));
  307. thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,3);
  308. end;
  309. procedure twasminlinenode.second_memory_copy;
  310. begin
  311. location_reset(location,LOC_VOID,OS_NO);
  312. secondpass(tcallparanode(tcallparanode(tcallparanode(left).right).right).left);
  313. hlcg.location_force_reg(current_asmdata.CurrAsmList,
  314. tcallparanode(tcallparanode(tcallparanode(left).right).right).left.location,
  315. tcallparanode(tcallparanode(tcallparanode(left).right).right).left.resultdef,
  316. tcallparanode(tcallparanode(tcallparanode(left).right).right).left.resultdef,false);
  317. thlcgwasm(hlcg).a_load_reg_stack(current_asmdata.CurrAsmList,
  318. tcallparanode(tcallparanode(tcallparanode(left).right).right).left.resultdef,
  319. tcallparanode(tcallparanode(tcallparanode(left).right).right).left.location.register);
  320. secondpass(tcallparanode(tcallparanode(left).right).left);
  321. hlcg.location_force_reg(current_asmdata.CurrAsmList,
  322. tcallparanode(tcallparanode(left).right).left.location,
  323. tcallparanode(tcallparanode(left).right).left.resultdef,
  324. tcallparanode(tcallparanode(left).right).left.resultdef,false);
  325. thlcgwasm(hlcg).a_load_reg_stack(current_asmdata.CurrAsmList,
  326. tcallparanode(tcallparanode(left).right).left.resultdef,
  327. tcallparanode(tcallparanode(left).right).left.location.register);
  328. secondpass(tcallparanode(left).left);
  329. hlcg.location_force_reg(current_asmdata.CurrAsmList,
  330. tcallparanode(left).left.location,
  331. tcallparanode(left).left.resultdef,
  332. tcallparanode(left).left.resultdef,false);
  333. thlcgwasm(hlcg).a_load_reg_stack(current_asmdata.CurrAsmList,
  334. tcallparanode(left).left.resultdef,
  335. tcallparanode(left).left.location.register);
  336. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_memory_copy));
  337. thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,3);
  338. end;
  339. procedure twasminlinenode.second_unreachable;
  340. begin
  341. location_reset(location,LOC_VOID,OS_NO);
  342. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_unreachable));
  343. end;
  344. procedure twasminlinenode.second_throw_fpcexception;
  345. begin
  346. location_reset(location,LOC_VOID,OS_NO);
  347. current_asmdata.CurrAsmList.Concat(taicpu.op_sym(a_throw,current_asmdata.WeakRefAsmSymbol(FPC_EXCEPTION_TAG_SYM,AT_WASM_EXCEPTION_TAG)));
  348. end;
  349. procedure twasminlinenode.second_atomic_fence;
  350. begin
  351. location_reset(location,LOC_VOID,OS_NO);
  352. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_atomic_fence));
  353. end;
  354. procedure twasminlinenode.second_atomic_load(op: TAsmOp);
  355. begin
  356. secondpass(left);
  357. hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
  358. thlcgwasm(hlcg).a_load_reg_stack(current_asmdata.CurrAsmList,left.resultdef,left.location.register);
  359. current_asmdata.CurrAsmList.Concat(taicpu.op_const(op,0));
  360. location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
  361. location.register:=hlcg.getregisterfordef(current_asmdata.CurrAsmList,resultdef);
  362. thlcgwasm(hlcg).a_load_stack_loc(current_asmdata.CurrAsmList,resultdef,location);
  363. end;
  364. procedure twasminlinenode.second_atomic_store(op: TAsmOp);
  365. begin
  366. location_reset(location,LOC_VOID,OS_NO);
  367. secondpass(tcallparanode(tcallparanode(left).right).left);
  368. hlcg.location_force_reg(current_asmdata.CurrAsmList,
  369. tcallparanode(tcallparanode(left).right).left.location,
  370. tcallparanode(tcallparanode(left).right).left.resultdef,
  371. tcallparanode(tcallparanode(left).right).left.resultdef,false);
  372. thlcgwasm(hlcg).a_load_reg_stack(current_asmdata.CurrAsmList,
  373. tcallparanode(tcallparanode(left).right).left.resultdef,
  374. tcallparanode(tcallparanode(left).right).left.location.register);
  375. secondpass(tcallparanode(left).left);
  376. hlcg.location_force_reg(current_asmdata.CurrAsmList,
  377. tcallparanode(left).left.location,
  378. tcallparanode(left).left.resultdef,
  379. tcallparanode(left).left.resultdef,false);
  380. thlcgwasm(hlcg).a_load_reg_stack(current_asmdata.CurrAsmList,
  381. tcallparanode(left).left.resultdef,
  382. tcallparanode(left).left.location.register);
  383. current_asmdata.CurrAsmList.Concat(taicpu.op_const(op,0));
  384. thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,2);
  385. end;
  386. procedure twasminlinenode.second_atomic_rmw_x_y(op: TAsmOp);
  387. begin
  388. secondpass(tcallparanode(tcallparanode(left).right).left);
  389. hlcg.location_force_reg(current_asmdata.CurrAsmList,
  390. tcallparanode(tcallparanode(left).right).left.location,
  391. tcallparanode(tcallparanode(left).right).left.resultdef,
  392. tcallparanode(tcallparanode(left).right).left.resultdef,false);
  393. thlcgwasm(hlcg).a_load_reg_stack(current_asmdata.CurrAsmList,
  394. tcallparanode(tcallparanode(left).right).left.resultdef,
  395. tcallparanode(tcallparanode(left).right).left.location.register);
  396. secondpass(tcallparanode(left).left);
  397. hlcg.location_force_reg(current_asmdata.CurrAsmList,
  398. tcallparanode(left).left.location,
  399. tcallparanode(left).left.resultdef,
  400. tcallparanode(left).left.resultdef,false);
  401. thlcgwasm(hlcg).a_load_reg_stack(current_asmdata.CurrAsmList,
  402. tcallparanode(left).left.resultdef,
  403. tcallparanode(left).left.location.register);
  404. current_asmdata.CurrAsmList.Concat(taicpu.op_const(op,0));
  405. thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,1);
  406. location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
  407. location.register:=hlcg.getregisterfordef(current_asmdata.CurrAsmList,resultdef);
  408. thlcgwasm(hlcg).a_load_stack_loc(current_asmdata.CurrAsmList,resultdef,location);
  409. end;
  410. procedure twasminlinenode.second_atomic_rmw_x_y_z(op: TAsmOp);
  411. begin
  412. secondpass(tcallparanode(tcallparanode(tcallparanode(left).right).right).left);
  413. hlcg.location_force_reg(current_asmdata.CurrAsmList,
  414. tcallparanode(tcallparanode(tcallparanode(left).right).right).left.location,
  415. tcallparanode(tcallparanode(tcallparanode(left).right).right).left.resultdef,
  416. tcallparanode(tcallparanode(tcallparanode(left).right).right).left.resultdef,false);
  417. thlcgwasm(hlcg).a_load_reg_stack(current_asmdata.CurrAsmList,
  418. tcallparanode(tcallparanode(tcallparanode(left).right).right).left.resultdef,
  419. tcallparanode(tcallparanode(tcallparanode(left).right).right).left.location.register);
  420. secondpass(tcallparanode(tcallparanode(left).right).left);
  421. hlcg.location_force_reg(current_asmdata.CurrAsmList,
  422. tcallparanode(tcallparanode(left).right).left.location,
  423. tcallparanode(tcallparanode(left).right).left.resultdef,
  424. tcallparanode(tcallparanode(left).right).left.resultdef,false);
  425. thlcgwasm(hlcg).a_load_reg_stack(current_asmdata.CurrAsmList,
  426. tcallparanode(tcallparanode(left).right).left.resultdef,
  427. tcallparanode(tcallparanode(left).right).left.location.register);
  428. secondpass(tcallparanode(left).left);
  429. hlcg.location_force_reg(current_asmdata.CurrAsmList,
  430. tcallparanode(left).left.location,
  431. tcallparanode(left).left.resultdef,
  432. tcallparanode(left).left.resultdef,false);
  433. thlcgwasm(hlcg).a_load_reg_stack(current_asmdata.CurrAsmList,
  434. tcallparanode(left).left.resultdef,
  435. tcallparanode(left).left.location.register);
  436. current_asmdata.CurrAsmList.Concat(taicpu.op_const(op,0));
  437. thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,2);
  438. location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
  439. location.register:=hlcg.getregisterfordef(current_asmdata.CurrAsmList,resultdef);
  440. thlcgwasm(hlcg).a_load_stack_loc(current_asmdata.CurrAsmList,resultdef,location);
  441. end;
  442. procedure twasminlinenode.second_tls_get(const SymStr: string);
  443. var
  444. sym: TWasmGlobalAsmSymbol;
  445. begin
  446. sym:=TWasmGlobalAsmSymbol(current_asmdata.RefAsmSymbolByClass(TWasmGlobalAsmSymbol,SymStr,AT_WASM_GLOBAL));
  447. sym.WasmGlobalType:=wbt_i32;
  448. current_asmdata.CurrAsmList.Concat(taicpu.op_sym(a_global_get,sym));
  449. thlcgwasm(hlcg).incstack(current_asmdata.CurrAsmList,1);
  450. location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
  451. location.register:=hlcg.getregisterfordef(current_asmdata.CurrAsmList,resultdef);
  452. thlcgwasm(hlcg).a_load_stack_loc(current_asmdata.CurrAsmList,resultdef,location);
  453. end;
  454. procedure twasminlinenode.second_set_base_pointer;
  455. var
  456. pd: tcpuprocdef;
  457. begin
  458. location_reset(location,LOC_VOID,OS_NO);
  459. secondpass(left);
  460. hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
  461. thlcgwasm(hlcg).a_load_reg_stack(current_asmdata.CurrAsmList,left.resultdef,left.location.register);
  462. pd:=tcpuprocdef(current_procinfo.procdef);
  463. if pd.base_pointer_ref.base<>NR_LOCAL_STACK_POINTER_REG then
  464. ttgwasm(tg).allocbasepointer(current_asmdata.CurrAsmList,pd.base_pointer_ref);
  465. current_asmdata.CurrAsmList.Concat(taicpu.op_ref(a_local_set,pd.base_pointer_ref));
  466. thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,1);
  467. end;
  468. function twasminlinenode.first_sqr_real: tnode;
  469. begin
  470. expectloc:=LOC_FPUREGISTER;
  471. first_sqr_real:=nil;
  472. end;
  473. function twasminlinenode.pass_typecheck_cpu: tnode;
  474. begin
  475. Result:=nil;
  476. case inlinenumber of
  477. in_wasm32_set_base_pointer:
  478. begin
  479. CheckParameters(1);
  480. resultdef:=voidtype;
  481. end;
  482. in_wasm32_memory_size:
  483. begin
  484. CheckParameters(0);
  485. resultdef:=u32inttype;
  486. end;
  487. in_wasm32_memory_grow:
  488. begin
  489. CheckParameters(1);
  490. resultdef:=u32inttype;
  491. end;
  492. in_wasm32_unreachable:
  493. begin
  494. CheckParameters(0);
  495. resultdef:=voidtype;
  496. end;
  497. in_wasm32_throw_fpcexception:
  498. begin
  499. CheckParameters(0);
  500. resultdef:=voidtype;
  501. end;
  502. in_wasm32_memory_fill:
  503. begin
  504. CheckParameters(3);
  505. resultdef:=voidtype;
  506. end;
  507. in_wasm32_memory_copy:
  508. begin
  509. CheckParameters(3);
  510. resultdef:=voidtype;
  511. end;
  512. in_wasm32_atomic_fence:
  513. begin
  514. CheckParameters(0);
  515. resultdef:=voidtype;
  516. end;
  517. in_wasm32_i32_atomic_rmw8_add_u,
  518. in_wasm32_i32_atomic_rmw16_add_u,
  519. in_wasm32_i32_atomic_rmw_add,
  520. in_wasm32_i32_atomic_rmw8_sub_u,
  521. in_wasm32_i32_atomic_rmw16_sub_u,
  522. in_wasm32_i32_atomic_rmw_sub,
  523. in_wasm32_i32_atomic_rmw8_and_u,
  524. in_wasm32_i32_atomic_rmw16_and_u,
  525. in_wasm32_i32_atomic_rmw_and,
  526. in_wasm32_i32_atomic_rmw8_or_u,
  527. in_wasm32_i32_atomic_rmw16_or_u,
  528. in_wasm32_i32_atomic_rmw_or,
  529. in_wasm32_i32_atomic_rmw8_xor_u,
  530. in_wasm32_i32_atomic_rmw16_xor_u,
  531. in_wasm32_i32_atomic_rmw_xor,
  532. in_wasm32_i32_atomic_rmw8_xchg_u,
  533. in_wasm32_i32_atomic_rmw16_xchg_u,
  534. in_wasm32_i32_atomic_rmw_xchg:
  535. begin
  536. CheckParameters(2);
  537. resultdef:=u32inttype;
  538. end;
  539. in_wasm32_i64_atomic_rmw8_add_u,
  540. in_wasm32_i64_atomic_rmw16_add_u,
  541. in_wasm32_i64_atomic_rmw32_add_u,
  542. in_wasm32_i64_atomic_rmw_add,
  543. in_wasm32_i64_atomic_rmw8_sub_u,
  544. in_wasm32_i64_atomic_rmw16_sub_u,
  545. in_wasm32_i64_atomic_rmw32_sub_u,
  546. in_wasm32_i64_atomic_rmw_sub,
  547. in_wasm32_i64_atomic_rmw8_and_u,
  548. in_wasm32_i64_atomic_rmw16_and_u,
  549. in_wasm32_i64_atomic_rmw32_and_u,
  550. in_wasm32_i64_atomic_rmw_and,
  551. in_wasm32_i64_atomic_rmw8_or_u,
  552. in_wasm32_i64_atomic_rmw16_or_u,
  553. in_wasm32_i64_atomic_rmw32_or_u,
  554. in_wasm32_i64_atomic_rmw_or,
  555. in_wasm32_i64_atomic_rmw8_xor_u,
  556. in_wasm32_i64_atomic_rmw16_xor_u,
  557. in_wasm32_i64_atomic_rmw32_xor_u,
  558. in_wasm32_i64_atomic_rmw_xor,
  559. in_wasm32_i64_atomic_rmw8_xchg_u,
  560. in_wasm32_i64_atomic_rmw16_xchg_u,
  561. in_wasm32_i64_atomic_rmw32_xchg_u,
  562. in_wasm32_i64_atomic_rmw_xchg:
  563. begin
  564. CheckParameters(2);
  565. resultdef:=u64inttype;
  566. end;
  567. in_wasm32_i32_atomic_rmw8_cmpxchg_u,
  568. in_wasm32_i32_atomic_rmw16_cmpxchg_u,
  569. in_wasm32_i32_atomic_rmw_cmpxchg:
  570. begin
  571. CheckParameters(3);
  572. resultdef:=u32inttype;
  573. end;
  574. in_wasm32_i64_atomic_rmw8_cmpxchg_u,
  575. in_wasm32_i64_atomic_rmw16_cmpxchg_u,
  576. in_wasm32_i64_atomic_rmw32_cmpxchg_u,
  577. in_wasm32_i64_atomic_rmw_cmpxchg:
  578. begin
  579. CheckParameters(3);
  580. resultdef:=u64inttype;
  581. end;
  582. in_wasm32_memory_atomic_wait32,
  583. in_wasm32_memory_atomic_wait64:
  584. begin
  585. CheckParameters(3);
  586. resultdef:=s32inttype;
  587. end;
  588. in_wasm32_memory_atomic_notify:
  589. begin
  590. CheckParameters(2);
  591. resultdef:=u32inttype;
  592. end;
  593. in_i32_atomic_load8_u,
  594. in_i32_atomic_load16_u,
  595. in_i32_atomic_load:
  596. begin
  597. CheckParameters(1);
  598. resultdef:=u32inttype;
  599. end;
  600. in_i64_atomic_load8_u,
  601. in_i64_atomic_load16_u,
  602. in_i64_atomic_load32_u,
  603. in_i64_atomic_load:
  604. begin
  605. CheckParameters(1);
  606. resultdef:=u64inttype;
  607. end;
  608. in_i32_atomic_store8,
  609. in_i32_atomic_store16,
  610. in_i32_atomic_store,
  611. in_i64_atomic_store8,
  612. in_i64_atomic_store16,
  613. in_i64_atomic_store32,
  614. in_i64_atomic_store:
  615. begin
  616. CheckParameters(2);
  617. resultdef:=voidtype;
  618. end;
  619. in_wasm32_tls_size,
  620. in_wasm32_tls_align:
  621. begin
  622. CheckParameters(0);
  623. resultdef:=u32inttype;
  624. end;
  625. in_wasm32_tls_base:
  626. begin
  627. CheckParameters(0);
  628. resultdef:=voidpointertype;
  629. end;
  630. else
  631. Result:=inherited pass_typecheck_cpu;
  632. end;
  633. end;
  634. function twasminlinenode.first_cpu: tnode;
  635. begin
  636. Result:=nil;
  637. case inlinenumber of
  638. in_wasm32_memory_size,
  639. in_wasm32_memory_grow:
  640. expectloc:=LOC_REGISTER;
  641. in_wasm32_set_base_pointer,
  642. in_wasm32_memory_fill,
  643. in_wasm32_memory_copy,
  644. in_wasm32_unreachable,
  645. in_wasm32_throw_fpcexception,
  646. in_wasm32_atomic_fence,
  647. in_i32_atomic_store8,
  648. in_i32_atomic_store16,
  649. in_i32_atomic_store,
  650. in_i64_atomic_store8,
  651. in_i64_atomic_store16,
  652. in_i64_atomic_store32,
  653. in_i64_atomic_store:
  654. expectloc:=LOC_VOID;
  655. in_wasm32_i32_atomic_rmw8_add_u,
  656. in_wasm32_i32_atomic_rmw16_add_u,
  657. in_wasm32_i32_atomic_rmw_add,
  658. in_wasm32_i64_atomic_rmw8_add_u,
  659. in_wasm32_i64_atomic_rmw16_add_u,
  660. in_wasm32_i64_atomic_rmw32_add_u,
  661. in_wasm32_i64_atomic_rmw_add,
  662. in_wasm32_i32_atomic_rmw8_sub_u,
  663. in_wasm32_i32_atomic_rmw16_sub_u,
  664. in_wasm32_i32_atomic_rmw_sub,
  665. in_wasm32_i64_atomic_rmw8_sub_u,
  666. in_wasm32_i64_atomic_rmw16_sub_u,
  667. in_wasm32_i64_atomic_rmw32_sub_u,
  668. in_wasm32_i64_atomic_rmw_sub,
  669. in_wasm32_i32_atomic_rmw8_and_u,
  670. in_wasm32_i32_atomic_rmw16_and_u,
  671. in_wasm32_i32_atomic_rmw_and,
  672. in_wasm32_i64_atomic_rmw8_and_u,
  673. in_wasm32_i64_atomic_rmw16_and_u,
  674. in_wasm32_i64_atomic_rmw32_and_u,
  675. in_wasm32_i64_atomic_rmw_and,
  676. in_wasm32_i32_atomic_rmw8_or_u,
  677. in_wasm32_i32_atomic_rmw16_or_u,
  678. in_wasm32_i32_atomic_rmw_or,
  679. in_wasm32_i64_atomic_rmw8_or_u,
  680. in_wasm32_i64_atomic_rmw16_or_u,
  681. in_wasm32_i64_atomic_rmw32_or_u,
  682. in_wasm32_i64_atomic_rmw_or,
  683. in_wasm32_i32_atomic_rmw8_xor_u,
  684. in_wasm32_i32_atomic_rmw16_xor_u,
  685. in_wasm32_i32_atomic_rmw_xor,
  686. in_wasm32_i64_atomic_rmw8_xor_u,
  687. in_wasm32_i64_atomic_rmw16_xor_u,
  688. in_wasm32_i64_atomic_rmw32_xor_u,
  689. in_wasm32_i64_atomic_rmw_xor,
  690. in_wasm32_i32_atomic_rmw8_xchg_u,
  691. in_wasm32_i32_atomic_rmw16_xchg_u,
  692. in_wasm32_i32_atomic_rmw_xchg,
  693. in_wasm32_i64_atomic_rmw8_xchg_u,
  694. in_wasm32_i64_atomic_rmw16_xchg_u,
  695. in_wasm32_i64_atomic_rmw32_xchg_u,
  696. in_wasm32_i64_atomic_rmw_xchg,
  697. in_wasm32_i32_atomic_rmw8_cmpxchg_u,
  698. in_wasm32_i32_atomic_rmw16_cmpxchg_u,
  699. in_wasm32_i32_atomic_rmw_cmpxchg,
  700. in_wasm32_i64_atomic_rmw8_cmpxchg_u,
  701. in_wasm32_i64_atomic_rmw16_cmpxchg_u,
  702. in_wasm32_i64_atomic_rmw32_cmpxchg_u,
  703. in_wasm32_i64_atomic_rmw_cmpxchg,
  704. in_wasm32_memory_atomic_wait32,
  705. in_wasm32_memory_atomic_wait64,
  706. in_wasm32_memory_atomic_notify,
  707. in_i32_atomic_load8_u,
  708. in_i32_atomic_load16_u,
  709. in_i32_atomic_load,
  710. in_i64_atomic_load8_u,
  711. in_i64_atomic_load16_u,
  712. in_i64_atomic_load32_u,
  713. in_i64_atomic_load,
  714. in_wasm32_tls_size,
  715. in_wasm32_tls_align,
  716. in_wasm32_tls_base:
  717. expectloc:=LOC_REGISTER;
  718. else
  719. Result:=inherited first_cpu;
  720. end;
  721. end;
  722. procedure twasminlinenode.pass_generate_code_cpu;
  723. begin
  724. case inlinenumber of
  725. in_wasm32_memory_size:
  726. second_memory_size;
  727. in_wasm32_memory_grow:
  728. second_memory_grow;
  729. in_wasm32_memory_fill:
  730. second_memory_fill;
  731. in_wasm32_memory_copy:
  732. second_memory_copy;
  733. in_wasm32_unreachable:
  734. second_unreachable;
  735. in_wasm32_throw_fpcexception:
  736. second_throw_fpcexception;
  737. in_wasm32_atomic_fence:
  738. second_atomic_fence;
  739. in_wasm32_i32_atomic_rmw8_add_u:
  740. second_atomic_rmw_x_y(a_i32_atomic_rmw8_add_u);
  741. in_wasm32_i32_atomic_rmw16_add_u:
  742. second_atomic_rmw_x_y(a_i32_atomic_rmw16_add_u);
  743. in_wasm32_i32_atomic_rmw_add:
  744. second_atomic_rmw_x_y(a_i32_atomic_rmw_add);
  745. in_wasm32_i64_atomic_rmw8_add_u:
  746. second_atomic_rmw_x_y(a_i64_atomic_rmw8_add_u);
  747. in_wasm32_i64_atomic_rmw16_add_u:
  748. second_atomic_rmw_x_y(a_i64_atomic_rmw16_add_u);
  749. in_wasm32_i64_atomic_rmw32_add_u:
  750. second_atomic_rmw_x_y(a_i64_atomic_rmw32_add_u);
  751. in_wasm32_i64_atomic_rmw_add:
  752. second_atomic_rmw_x_y(a_i64_atomic_rmw_add);
  753. in_wasm32_i32_atomic_rmw8_sub_u:
  754. second_atomic_rmw_x_y(a_i32_atomic_rmw8_sub_u);
  755. in_wasm32_i32_atomic_rmw16_sub_u:
  756. second_atomic_rmw_x_y(a_i32_atomic_rmw16_sub_u);
  757. in_wasm32_i32_atomic_rmw_sub:
  758. second_atomic_rmw_x_y(a_i32_atomic_rmw_sub);
  759. in_wasm32_i64_atomic_rmw8_sub_u:
  760. second_atomic_rmw_x_y(a_i64_atomic_rmw8_sub_u);
  761. in_wasm32_i64_atomic_rmw16_sub_u:
  762. second_atomic_rmw_x_y(a_i64_atomic_rmw16_sub_u);
  763. in_wasm32_i64_atomic_rmw32_sub_u:
  764. second_atomic_rmw_x_y(a_i64_atomic_rmw32_sub_u);
  765. in_wasm32_i64_atomic_rmw_sub:
  766. second_atomic_rmw_x_y(a_i64_atomic_rmw_sub);
  767. in_wasm32_i32_atomic_rmw8_and_u:
  768. second_atomic_rmw_x_y(a_i32_atomic_rmw8_and_u);
  769. in_wasm32_i32_atomic_rmw16_and_u:
  770. second_atomic_rmw_x_y(a_i32_atomic_rmw16_and_u);
  771. in_wasm32_i32_atomic_rmw_and:
  772. second_atomic_rmw_x_y(a_i32_atomic_rmw_and);
  773. in_wasm32_i64_atomic_rmw8_and_u:
  774. second_atomic_rmw_x_y(a_i64_atomic_rmw8_and_u);
  775. in_wasm32_i64_atomic_rmw16_and_u:
  776. second_atomic_rmw_x_y(a_i64_atomic_rmw16_and_u);
  777. in_wasm32_i64_atomic_rmw32_and_u:
  778. second_atomic_rmw_x_y(a_i64_atomic_rmw32_and_u);
  779. in_wasm32_i64_atomic_rmw_and:
  780. second_atomic_rmw_x_y(a_i64_atomic_rmw_and);
  781. in_wasm32_i32_atomic_rmw8_or_u:
  782. second_atomic_rmw_x_y(a_i32_atomic_rmw8_or_u);
  783. in_wasm32_i32_atomic_rmw16_or_u:
  784. second_atomic_rmw_x_y(a_i32_atomic_rmw16_or_u);
  785. in_wasm32_i32_atomic_rmw_or:
  786. second_atomic_rmw_x_y(a_i32_atomic_rmw_or);
  787. in_wasm32_i64_atomic_rmw8_or_u:
  788. second_atomic_rmw_x_y(a_i64_atomic_rmw8_or_u);
  789. in_wasm32_i64_atomic_rmw16_or_u:
  790. second_atomic_rmw_x_y(a_i64_atomic_rmw16_or_u);
  791. in_wasm32_i64_atomic_rmw32_or_u:
  792. second_atomic_rmw_x_y(a_i64_atomic_rmw32_or_u);
  793. in_wasm32_i64_atomic_rmw_or:
  794. second_atomic_rmw_x_y(a_i64_atomic_rmw_or);
  795. in_wasm32_i32_atomic_rmw8_xor_u:
  796. second_atomic_rmw_x_y(a_i32_atomic_rmw8_xor_u);
  797. in_wasm32_i32_atomic_rmw16_xor_u:
  798. second_atomic_rmw_x_y(a_i32_atomic_rmw16_xor_u);
  799. in_wasm32_i32_atomic_rmw_xor:
  800. second_atomic_rmw_x_y(a_i32_atomic_rmw_xor);
  801. in_wasm32_i64_atomic_rmw8_xor_u:
  802. second_atomic_rmw_x_y(a_i64_atomic_rmw8_xor_u);
  803. in_wasm32_i64_atomic_rmw16_xor_u:
  804. second_atomic_rmw_x_y(a_i64_atomic_rmw16_xor_u);
  805. in_wasm32_i64_atomic_rmw32_xor_u:
  806. second_atomic_rmw_x_y(a_i64_atomic_rmw32_xor_u);
  807. in_wasm32_i64_atomic_rmw_xor:
  808. second_atomic_rmw_x_y(a_i64_atomic_rmw_xor);
  809. in_wasm32_i32_atomic_rmw8_xchg_u:
  810. second_atomic_rmw_x_y(a_i32_atomic_rmw8_xchg_u);
  811. in_wasm32_i32_atomic_rmw16_xchg_u:
  812. second_atomic_rmw_x_y(a_i32_atomic_rmw16_xchg_u);
  813. in_wasm32_i32_atomic_rmw_xchg:
  814. second_atomic_rmw_x_y(a_i32_atomic_rmw_xchg);
  815. in_wasm32_i64_atomic_rmw8_xchg_u:
  816. second_atomic_rmw_x_y(a_i64_atomic_rmw8_xchg_u);
  817. in_wasm32_i64_atomic_rmw16_xchg_u:
  818. second_atomic_rmw_x_y(a_i64_atomic_rmw16_xchg_u);
  819. in_wasm32_i64_atomic_rmw32_xchg_u:
  820. second_atomic_rmw_x_y(a_i64_atomic_rmw32_xchg_u);
  821. in_wasm32_i64_atomic_rmw_xchg:
  822. second_atomic_rmw_x_y(a_i64_atomic_rmw_xchg);
  823. in_wasm32_i32_atomic_rmw8_cmpxchg_u:
  824. second_atomic_rmw_x_y_z(a_i32_atomic_rmw8_cmpxchg_u);
  825. in_wasm32_i32_atomic_rmw16_cmpxchg_u:
  826. second_atomic_rmw_x_y_z(a_i32_atomic_rmw16_cmpxchg_u);
  827. in_wasm32_i32_atomic_rmw_cmpxchg:
  828. second_atomic_rmw_x_y_z(a_i32_atomic_rmw_cmpxchg);
  829. in_wasm32_i64_atomic_rmw8_cmpxchg_u:
  830. second_atomic_rmw_x_y_z(a_i64_atomic_rmw8_cmpxchg_u);
  831. in_wasm32_i64_atomic_rmw16_cmpxchg_u:
  832. second_atomic_rmw_x_y_z(a_i64_atomic_rmw16_cmpxchg_u);
  833. in_wasm32_i64_atomic_rmw32_cmpxchg_u:
  834. second_atomic_rmw_x_y_z(a_i64_atomic_rmw32_cmpxchg_u);
  835. in_wasm32_i64_atomic_rmw_cmpxchg:
  836. second_atomic_rmw_x_y_z(a_i64_atomic_rmw_cmpxchg);
  837. in_wasm32_memory_atomic_wait32:
  838. second_atomic_rmw_x_y_z(a_memory_atomic_wait32);
  839. in_wasm32_memory_atomic_wait64:
  840. second_atomic_rmw_x_y_z(a_memory_atomic_wait64);
  841. in_wasm32_memory_atomic_notify:
  842. second_atomic_rmw_x_y(a_memory_atomic_notify);
  843. in_i32_atomic_load8_u:
  844. second_atomic_load(a_i32_atomic_load8_u);
  845. in_i32_atomic_load16_u:
  846. second_atomic_load(a_i32_atomic_load16_u);
  847. in_i32_atomic_load:
  848. second_atomic_load(a_i32_atomic_load);
  849. in_i64_atomic_load8_u:
  850. second_atomic_load(a_i64_atomic_load8_u);
  851. in_i64_atomic_load16_u:
  852. second_atomic_load(a_i64_atomic_load16_u);
  853. in_i64_atomic_load32_u:
  854. second_atomic_load(a_i64_atomic_load32_u);
  855. in_i64_atomic_load:
  856. second_atomic_load(a_i64_atomic_load);
  857. in_i32_atomic_store8:
  858. second_atomic_store(a_i32_atomic_store8);
  859. in_i32_atomic_store16:
  860. second_atomic_store(a_i32_atomic_store16);
  861. in_i32_atomic_store:
  862. second_atomic_store(a_i32_atomic_store);
  863. in_i64_atomic_store8:
  864. second_atomic_store(a_i64_atomic_store8);
  865. in_i64_atomic_store16:
  866. second_atomic_store(a_i64_atomic_store16);
  867. in_i64_atomic_store32:
  868. second_atomic_store(a_i64_atomic_store32);
  869. in_i64_atomic_store:
  870. second_atomic_store(a_i64_atomic_store);
  871. in_wasm32_tls_size:
  872. second_tls_get(TLS_SIZE_SYM);
  873. in_wasm32_tls_align:
  874. second_tls_get(TLS_ALIGN_SYM);
  875. in_wasm32_tls_base:
  876. second_tls_get(TLS_BASE_SYM);
  877. in_wasm32_set_base_pointer:
  878. second_set_base_pointer;
  879. else
  880. inherited pass_generate_code_cpu;
  881. end;
  882. end;
  883. procedure twasminlinenode.second_length;
  884. var
  885. lendef : tdef;
  886. href : treference;
  887. extra_slots: LongInt;
  888. begin
  889. secondpass(left);
  890. if is_shortstring(left.resultdef) then
  891. begin
  892. location_copy(location,left.location);
  893. location.size:=OS_8;
  894. end
  895. else
  896. begin
  897. { length in ansi/wide strings and high in dynamic arrays is at offset -sizeof(pint) }
  898. hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,false);
  899. thlcgwasm(hlcg).a_cmp_const_reg_stack(current_asmdata.CurrAsmList,left.resultdef,OC_EQ,0,left.location.register);
  900. current_asmdata.CurrAsmList.Concat(taicpu.op_functype(a_if,TWasmFuncType.Create([],[wbt_i32])));
  901. thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,1);
  902. current_asmdata.CurrAsmList.Concat(taicpu.op_const(a_i32_const,0));
  903. thlcgwasm(hlcg).incstack(current_asmdata.CurrAsmList,1);
  904. current_asmdata.CurrAsmList.Concat( taicpu.op_none(a_else) );
  905. thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,1);
  906. { the length of a widestring is a 32 bit unsigned int. Since every
  907. character occupies 2 bytes, on a 32 bit platform you can express
  908. the maximum length using 31 bits. On a 64 bit platform, it may be
  909. 32 bits. This means that regardless of the platform, a location
  910. with size OS_SINT/ossinttype can hold the length without
  911. overflowing (this code returns an ossinttype value) }
  912. if is_widestring(left.resultdef) then
  913. lendef:=u32inttype
  914. else
  915. lendef:=ossinttype;
  916. { volatility of the ansistring/widestring refers to the volatility of the
  917. string pointer, not of the string data }
  918. hlcg.reference_reset_base(href,left.resultdef,left.location.register,-lendef.size,ctempposinvalid,lendef.alignment,[]);
  919. extra_slots:=thlcgwasm(hlcg).prepare_stack_for_ref(current_asmdata.CurrAsmList,href,false);
  920. thlcgwasm(hlcg).a_load_ref_stack(current_asmdata.CurrAsmList,lendef,href,extra_slots);
  921. if is_widestring(left.resultdef) then
  922. thlcgwasm(hlcg).a_op_const_stack(current_asmdata.CurrAsmList,OP_SHR,resultdef,1);
  923. { Dynamic arrays do not have their length attached but their maximum index }
  924. if is_dynamic_array(left.resultdef) then
  925. thlcgwasm(hlcg).a_op_const_stack(current_asmdata.CurrAsmList,OP_ADD,resultdef,1);
  926. current_asmdata.CurrAsmList.Concat( taicpu.op_none(a_end_if) );
  927. location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
  928. location.register:=hlcg.getregisterfordef(current_asmdata.CurrAsmList,resultdef);
  929. thlcgwasm(hlcg).a_load_stack_loc(current_asmdata.CurrAsmList,resultdef,location);
  930. end;
  931. end;
  932. procedure twasminlinenode.second_sqr_real;
  933. begin
  934. secondpass(left);
  935. hlcg.location_force_fpureg(current_asmdata.CurrAsmList,left.location,left.resultdef,true);
  936. thlcgwasm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location);
  937. thlcgwasm(hlcg).a_load_loc_stack(current_asmdata.CurrAsmList,left.resultdef,left.location);
  938. case left.location.size of
  939. OS_F32:
  940. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_f32_mul));
  941. OS_F64:
  942. current_asmdata.CurrAsmList.Concat(taicpu.op_none(a_f64_mul));
  943. else
  944. internalerror(2021060102);
  945. end;
  946. thlcgwasm(hlcg).decstack(current_asmdata.CurrAsmList,1);
  947. location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
  948. location.register:=hlcg.getregisterfordef(current_asmdata.CurrAsmList,resultdef);
  949. thlcgwasm(hlcg).a_load_stack_loc(current_asmdata.CurrAsmList,resultdef,location);
  950. end;
  951. begin
  952. cinlinenode:=twasminlinenode;
  953. end.