nwasminl.pas 45 KB

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