agllvmmc.pas 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. {
  2. Copyright (c) 1998-2020 by the Free Pascal team
  3. This unit implements the llvm-mc ("llvm machine code playground")
  4. assembler writer for WebAssembly
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. ****************************************************************************
  17. }
  18. unit agllvmmc;
  19. {$i fpcdefs.inc}
  20. interface
  21. uses
  22. systems,cgutils,
  23. globtype,globals,
  24. symbase,symdef,symtype,symconst,symcpu,
  25. aasmbase,aasmtai,aasmdata,aasmcpu,
  26. assemble,aggas;
  27. type
  28. { TLLVMMachineCodePlaygroundAssembler }
  29. TLLVMMachineCodePlaygroundAssembler=class(TGNUassembler)
  30. protected
  31. FLLVMMajorVersion: Integer;
  32. function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;override;
  33. public
  34. constructor CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean); override;
  35. procedure WriteFuncTypeDirective(hp:tai_functype);override;
  36. end;
  37. { TLLVMMachineCodePlaygroundAssemblerV10 }
  38. TLLVMMachineCodePlaygroundAssemblerV10=class(TLLVMMachineCodePlaygroundAssembler)
  39. constructor CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean); override;
  40. end;
  41. { TLLVMMachineCodePlaygroundAssemblerV11 }
  42. TLLVMMachineCodePlaygroundAssemblerV11=class(TLLVMMachineCodePlaygroundAssembler)
  43. constructor CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean); override;
  44. end;
  45. { TLLVMMachineCodePlaygroundAssemblerV12 }
  46. TLLVMMachineCodePlaygroundAssemblerV12=class(TLLVMMachineCodePlaygroundAssembler)
  47. constructor CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean); override;
  48. end;
  49. { TLLVMMachineCodePlaygroundAssemblerV13 }
  50. TLLVMMachineCodePlaygroundAssemblerV13=class(TLLVMMachineCodePlaygroundAssembler)
  51. constructor CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean); override;
  52. end;
  53. { TLLVMMachineCodePlaygroundAssemblerV14 }
  54. TLLVMMachineCodePlaygroundAssemblerV14=class(TLLVMMachineCodePlaygroundAssembler)
  55. constructor CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean); override;
  56. end;
  57. { TLLVMMachineCodePlaygroundAssemblerV15 }
  58. TLLVMMachineCodePlaygroundAssemblerV15=class(TLLVMMachineCodePlaygroundAssembler)
  59. constructor CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean); override;
  60. end;
  61. { TLLVMMachineCodePlaygroundAssemblerV16 }
  62. TLLVMMachineCodePlaygroundAssemblerV16=class(TLLVMMachineCodePlaygroundAssembler)
  63. constructor CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean); override;
  64. end;
  65. { TLLVMMachineCodePlaygroundAssemblerV17 }
  66. TLLVMMachineCodePlaygroundAssemblerV17=class(TLLVMMachineCodePlaygroundAssembler)
  67. constructor CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean); override;
  68. end;
  69. { TLLVMMachineCodePlaygroundAssemblerV18 }
  70. TLLVMMachineCodePlaygroundAssemblerV18=class(TLLVMMachineCodePlaygroundAssembler)
  71. constructor CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean); override;
  72. end;
  73. { TWASM32InstrWriter }
  74. TWASM32InstrWriter = class(TCPUInstrWriter)
  75. protected
  76. FLLVMMajorVersion: Integer;
  77. public
  78. procedure WriteInstruction(hp : tai);override;
  79. end;
  80. implementation
  81. uses
  82. cutils,
  83. cgbase,
  84. fmodule,finput,
  85. itcpugas,
  86. cpubase,
  87. hlcgobj,hlcgcpu,
  88. verbose;
  89. { TLLVMMachineCodePlaygroundAssemblerV10 }
  90. constructor TLLVMMachineCodePlaygroundAssemblerV10.CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean);
  91. begin
  92. FLLVMMajorVersion:=10;
  93. inherited CreateWithWriter(info, wr, freewriter, smart);
  94. end;
  95. { TLLVMMachineCodePlaygroundAssemblerV11 }
  96. constructor TLLVMMachineCodePlaygroundAssemblerV11.CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean);
  97. begin
  98. FLLVMMajorVersion:=11;
  99. inherited CreateWithWriter(info, wr, freewriter, smart);
  100. end;
  101. { TLLVMMachineCodePlaygroundAssemblerV12 }
  102. constructor TLLVMMachineCodePlaygroundAssemblerV12.CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean);
  103. begin
  104. FLLVMMajorVersion:=12;
  105. inherited CreateWithWriter(info, wr, freewriter, smart);
  106. end;
  107. { TLLVMMachineCodePlaygroundAssemblerV13 }
  108. constructor TLLVMMachineCodePlaygroundAssemblerV13.CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean);
  109. begin
  110. FLLVMMajorVersion:=13;
  111. inherited CreateWithWriter(info, wr, freewriter, smart);
  112. end;
  113. { TLLVMMachineCodePlaygroundAssemblerV14 }
  114. constructor TLLVMMachineCodePlaygroundAssemblerV14.CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean);
  115. begin
  116. FLLVMMajorVersion:=14;
  117. inherited CreateWithWriter(info, wr, freewriter, smart);
  118. end;
  119. { TLLVMMachineCodePlaygroundAssemblerV15 }
  120. constructor TLLVMMachineCodePlaygroundAssemblerV15.CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean);
  121. begin
  122. FLLVMMajorVersion:=15;
  123. inherited CreateWithWriter(info, wr, freewriter, smart);
  124. end;
  125. { TLLVMMachineCodePlaygroundAssemblerV16 }
  126. constructor TLLVMMachineCodePlaygroundAssemblerV16.CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean);
  127. begin
  128. FLLVMMajorVersion:=16;
  129. inherited CreateWithWriter(info, wr, freewriter, smart);
  130. end;
  131. { TLLVMMachineCodePlaygroundAssemblerV17 }
  132. constructor TLLVMMachineCodePlaygroundAssemblerV17.CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean);
  133. begin
  134. FLLVMMajorVersion:=17;
  135. inherited CreateWithWriter(info, wr, freewriter, smart);
  136. end;
  137. { TLLVMMachineCodePlaygroundAssemblerV18 }
  138. constructor TLLVMMachineCodePlaygroundAssemblerV18.CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean);
  139. begin
  140. FLLVMMajorVersion:=18;
  141. inherited CreateWithWriter(info, wr, freewriter, smart);
  142. end;
  143. { TLLVMMachineCodePlaygroundAssembler }
  144. function TLLVMMachineCodePlaygroundAssembler.sectionname(atype: TAsmSectiontype; const aname: string; aorder: TAsmSectionOrder): string;
  145. begin
  146. if (atype=sec_fpc) or
  147. ((atype=sec_threadvar) and not (ts_wasm_threads in current_settings.targetswitches)) then
  148. atype:=sec_data;
  149. if atype=sec_threadvar then
  150. Result:=inherited sectionname(atype, aname, aorder)+',"T",@'
  151. else
  152. Result:=inherited sectionname(atype, aname, aorder)+',"",@';
  153. end;
  154. constructor TLLVMMachineCodePlaygroundAssembler.CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean);
  155. begin
  156. inherited;
  157. InstrWriter:=TWASM32InstrWriter.create(self);
  158. TWASM32InstrWriter(InstrWriter).FLLVMMajorVersion:=FLLVMMajorVersion;
  159. end;
  160. procedure TLLVMMachineCodePlaygroundAssembler.WriteFuncTypeDirective(hp: tai_functype);
  161. begin
  162. if not hp.is_forward or (FLLVMMajorVersion>=13) then
  163. begin
  164. writer.AsmWrite(#9'.functype'#9);
  165. writer.AsmWrite(hp.funcname);
  166. writer.AsmWrite(' ');
  167. WriteFuncType(hp.functype);
  168. writer.AsmLn;
  169. end;
  170. end;
  171. { TWASM32InstrWriter }
  172. procedure TWASM32InstrWriter.WriteInstruction(hp: tai);
  173. function getreferencestring(var ref : treference) : ansistring;
  174. begin
  175. if ref.refaddr=addr_got_tls then
  176. begin
  177. if not assigned(ref.symbol) then
  178. internalerror(2022071401);
  179. if ref.base<>NR_NO then
  180. internalerror(2022071402);
  181. if ref.index<>NR_NO then
  182. internalerror(2022071403);
  183. if ref.offset<>0 then
  184. internalerror(2022071404);
  185. result:=ref.symbol.name+'@GOT@TLS';
  186. end
  187. else if assigned(ref.symbol) then
  188. begin
  189. // global symbol or field -> full type and name
  190. // ref.base can be <> NR_NO in case an instance field is loaded.
  191. // This register is not part of this instruction, it will have
  192. // been placed on the stack by the previous one.
  193. result:=ref.symbol.name;
  194. if ref.base<>NR_NO then
  195. result:=result+'+'+std_regname(ref.base);
  196. if ref.index<>NR_NO then
  197. result:=result+'+'+std_regname(ref.index);
  198. if ref.offset>0 then
  199. result:=result+'+'+tostr(ref.offset)
  200. else if ref.offset<0 then
  201. result:=result+tostr(ref.offset);
  202. end
  203. else
  204. begin
  205. // local symbol -> stack slot, stored in offset
  206. result:='';
  207. if (ref.base<>NR_STACK_POINTER_REG) and (ref.base<>NR_NO) then
  208. result:=std_regname(ref.base);
  209. if ref.index<>NR_NO then
  210. if result<>'' then
  211. result:=result+'+'+std_regname(ref.index)
  212. else
  213. result:=std_regname(ref.index);
  214. if ref.offset>0 then
  215. begin
  216. if result<>'' then
  217. result:=result+'+'+tostr(ref.offset)
  218. else
  219. result:=tostr(ref.offset);
  220. end
  221. else if ref.offset<0 then
  222. result:=result+tostr(ref.offset);
  223. if result='' then
  224. result:='0';
  225. end;
  226. end;
  227. function constfloat(rawfloat: int64; fraction_bits, exponent_bits, exponent_bias: Integer): ansistring;
  228. var
  229. sign: boolean;
  230. fraction: int64;
  231. exponent, fraction_hexdigits: integer;
  232. begin
  233. fraction_hexdigits := (fraction_bits + 3) div 4;
  234. sign:=(rawfloat shr (fraction_bits+exponent_bits))<>0;
  235. fraction:=rawfloat and ((int64(1) shl fraction_bits)-1);
  236. exponent:=(rawfloat shr fraction_bits) and ((1 shl exponent_bits)-1);
  237. if sign then
  238. result:='-'
  239. else
  240. result:='';
  241. if (exponent=(1 shl exponent_bits)-1) then
  242. begin
  243. if fraction=0 then
  244. result:=result+'infinity'
  245. else
  246. begin
  247. result:=result+'nan';
  248. {$ifndef CPUMIPS}
  249. if fraction<>(int64(1) shl (fraction_bits-1)) then
  250. {$else CPUMIPS}
  251. { Legacy mips fpu has a different representation of 'standard' nan }
  252. { Signalling bit is clear to signify non-signalling }
  253. { Standard non-signalling NaN thus has all other bits set }
  254. if fraction<>((int64(1) shl (fraction_bits-1))-1) then
  255. {$endif CPUMIPS}
  256. result:=result+'(0x'+HexStr(fraction,fraction_hexdigits)+')';
  257. end;
  258. end
  259. else if (exponent=0) then
  260. begin
  261. if (fraction=0) then
  262. result:=result+'0x0.0p'+tostr(-exponent_bias)
  263. else
  264. result:=result+'0x0.'+HexStr(fraction shl (fraction_hexdigits*4-fraction_bits),fraction_hexdigits)+'p'+tostr(-exponent_bias+1)
  265. end
  266. else
  267. result:=result+'0x1.'+HexStr(fraction shl (fraction_hexdigits*4-fraction_bits),fraction_hexdigits)+'p'+tostr(exponent-exponent_bias);
  268. end;
  269. function constsingle(s: single): ansistring;
  270. type
  271. tsingleval = record
  272. case byte of
  273. 1: (s: single);
  274. 2: (i: longword);
  275. end;
  276. begin
  277. result:=constfloat(tsingleval(s).i,23,8,127);
  278. end;
  279. function constdouble(d: double): ansistring;
  280. type
  281. tdoubleval = record
  282. case byte of
  283. 1: (d: double);
  284. 2: (i: int64);
  285. end;
  286. begin
  287. result:=constfloat(tdoubleval(d).i,52,11,1023);
  288. end;
  289. function getopstr(const o:toper) : ansistring;
  290. var
  291. d: double;
  292. s: single;
  293. begin
  294. case o.typ of
  295. top_reg:
  296. // should have been translated into a memory location by the
  297. // register allocator)
  298. if (cs_no_regalloc in current_settings.globalswitches) then
  299. getopstr:=std_regname(o.reg)
  300. else
  301. internalerror(2010122803);
  302. top_const:
  303. str(o.val,result);
  304. top_ref:
  305. getopstr:=getreferencestring(o.ref^);
  306. top_single:
  307. begin
  308. result:=constsingle(o.sval);
  309. end;
  310. top_double:
  311. begin
  312. result:=constdouble(o.dval);
  313. end;
  314. {top_string:
  315. begin
  316. result:=constastr(o.pcval,o.pcvallen);
  317. end;
  318. top_wstring:
  319. begin
  320. result:=constwstr(o.pwstrval^.data,getlengthwidestring(o.pwstrval));
  321. end}
  322. else
  323. internalerror(2010122802);
  324. end;
  325. end;
  326. procedure WriteCatchClauses(writer: TExternalAssemblerOutputFile; catch_clauses: TAsmList);
  327. var
  328. hp: taicpu;
  329. i: Integer;
  330. begin
  331. hp:=taicpu(catch_clauses.First);
  332. while Assigned(hp) do
  333. begin
  334. if not (hp.opcode in [a_catch,a_catch_ref,a_catch_all,a_catch_all_ref]) then
  335. internalerror(2025100401);
  336. writer.AsmWrite(#9'('+gas_op2str[hp.opcode]);
  337. if hp.ops<>0 then
  338. begin
  339. for i:=0 to hp.ops-1 do
  340. begin
  341. writer.AsmWrite(#9);
  342. if hp.oper[i]^.typ=top_functype then
  343. owner.WriteFuncType(hp.oper[i]^.functype)
  344. else
  345. writer.AsmWrite(getopstr(hp.oper[i]^));
  346. end;
  347. end;
  348. writer.AsmWrite(')');
  349. hp:=taicpu(hp.Next);
  350. end;
  351. end;
  352. var
  353. cpu : taicpu;
  354. i : integer;
  355. writer: TExternalAssemblerOutputFile;
  356. begin
  357. writer:=owner.writer;
  358. cpu := taicpu(hp);
  359. writer.AsmWrite(#9#9);
  360. if FLLVMMajorVersion<=11 then
  361. case cpu.opcode of
  362. a_memory_atomic_wait32:
  363. writer.AsmWrite('i32.atomic.wait');
  364. a_memory_atomic_wait64:
  365. writer.AsmWrite('i64.atomic.wait');
  366. a_memory_atomic_notify:
  367. writer.AsmWrite('atomic.notify');
  368. else
  369. writer.AsmWrite(gas_op2str[cpu.opcode]);
  370. end
  371. else
  372. writer.AsmWrite(gas_op2str[cpu.opcode]);
  373. if cpu.ops<>0 then
  374. begin
  375. for i:=0 to cpu.ops-1 do
  376. if not ((cpu.opcode=a_call) and (i=1) and (cpu.oper[i]^.typ=top_functype)) then
  377. begin
  378. writer.AsmWrite(#9);
  379. if cpu.oper[i]^.typ=top_functype then
  380. owner.WriteFuncType(cpu.oper[i]^.functype)
  381. else
  382. writer.AsmWrite(getopstr(cpu.oper[i]^));
  383. end;
  384. end;
  385. if Assigned(cpu.try_table_catch_clauses) then
  386. WriteCatchClauses(writer,cpu.try_table_catch_clauses);
  387. writer.AsmLn;
  388. end;
  389. const
  390. as_wasm32_llvm_mc_v11_info : tasminfo =
  391. (
  392. id : as_wasm32_llvm_mc_v11;
  393. idtxt : 'LLVM-MC-11';
  394. asmbin : 'llvm-mc-11';
  395. asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj -o $OBJ $EXTRAOPT $ASM';
  396. supported_targets : [system_wasm32_embedded,system_wasm32_wasip1,system_wasm32_wasip1threads,system_wasm32_wasip2];
  397. flags : [af_smartlink_sections];
  398. labelprefix : '.L';
  399. labelmaxlen : -1;
  400. comment : '# ';
  401. dollarsign : '$';
  402. );
  403. as_wasm32_llvm_mc_v12_info : tasminfo =
  404. (
  405. id : as_wasm32_llvm_mc_v12;
  406. idtxt : 'LLVM-MC-12';
  407. asmbin : 'llvm-mc-12';
  408. asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj -o $OBJ $EXTRAOPT $ASM';
  409. supported_targets : [system_wasm32_embedded,system_wasm32_wasip1,system_wasm32_wasip1threads,system_wasm32_wasip2];
  410. flags : [af_smartlink_sections];
  411. labelprefix : '.L';
  412. labelmaxlen : -1;
  413. comment : '# ';
  414. dollarsign : '$';
  415. );
  416. { LLVM-MC v13 introduces a WebAssembly type checker. Unfortunately, it is
  417. broken and produces spurious errors for valid code, such as:
  418. system.wat:390742:3: error: 19 superfluous return values
  419. We try to disable it with the '--no-type-check' option. However, this
  420. still doesn't work, due to a different LLVM-MC bug, causing a different
  421. kind of spurious errors:
  422. system.wat:396083:3: error: empty stack while popping i32
  423. This means that LLVM-MC v13 is unusable as an external assembler. }
  424. as_wasm32_llvm_mc_v13_info : tasminfo =
  425. (
  426. id : as_wasm32_llvm_mc_v13;
  427. idtxt : 'LLVM-MC-13';
  428. asmbin : 'llvm-mc-13';
  429. asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj --no-type-check -o $OBJ $EXTRAOPT $ASM';
  430. supported_targets : [system_wasm32_embedded,system_wasm32_wasip1,system_wasm32_wasip1threads,system_wasm32_wasip2];
  431. flags : [af_smartlink_sections];
  432. labelprefix : '.L';
  433. labelmaxlen : -1;
  434. comment : '# ';
  435. dollarsign : '$';
  436. );
  437. { LLVM-MC v14 still contains a buggy WebAssembly type checker that cannot be
  438. disabled completely.
  439. This means that LLVM-MC v14 is unusable as an external assembler. }
  440. as_wasm32_llvm_mc_v14_info : tasminfo =
  441. (
  442. id : as_wasm32_llvm_mc_v14;
  443. idtxt : 'LLVM-MC-14';
  444. asmbin : 'llvm-mc-14';
  445. asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj --no-type-check -o $OBJ $EXTRAOPT $ASM';
  446. supported_targets : [system_wasm32_embedded,system_wasm32_wasip1,system_wasm32_wasip1threads,system_wasm32_wasip2];
  447. flags : [af_smartlink_sections];
  448. labelprefix : '.L';
  449. labelmaxlen : -1;
  450. comment : '# ';
  451. dollarsign : '$';
  452. );
  453. { LLVM-MC v15 fixes the bug that causes '--no-type-check' not to disable the
  454. still broken WebAssembly type checker.
  455. This makes LLVM-MC v15 usable as an external assembler. The type checker
  456. is still broken, of course, producing the same spurious errors, but at
  457. least, we can now safely disable it. }
  458. as_wasm32_llvm_mc_v15_info : tasminfo =
  459. (
  460. id : as_wasm32_llvm_mc_v15;
  461. idtxt : 'LLVM-MC-15';
  462. asmbin : 'llvm-mc-15';
  463. asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj --no-type-check -o $OBJ $EXTRAOPT $ASM';
  464. supported_targets : [system_wasm32_embedded,system_wasm32_wasip1,system_wasm32_wasip1threads,system_wasm32_wasip2];
  465. flags : [af_smartlink_sections];
  466. labelprefix : '.L';
  467. labelmaxlen : -1;
  468. comment : '# ';
  469. dollarsign : '$';
  470. );
  471. { LLVM-MC v16 is usable as an external assembler. The type checker is still
  472. broken, producing the same spurious errors, but we at least, we can now
  473. safely disable it. }
  474. as_wasm32_llvm_mc_v16_info : tasminfo =
  475. (
  476. id : as_wasm32_llvm_mc_v16;
  477. idtxt : 'LLVM-MC-16';
  478. asmbin : 'llvm-mc-16';
  479. asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj --no-type-check -o $OBJ $EXTRAOPT $ASM';
  480. supported_targets : [system_wasm32_embedded,system_wasm32_wasip1,system_wasm32_wasip1threads,system_wasm32_wasip2];
  481. flags : [af_smartlink_sections];
  482. labelprefix : '.L';
  483. labelmaxlen : -1;
  484. comment : '# ';
  485. dollarsign : '$';
  486. );
  487. { LLVM-MC v17 features an interesting development. The type checker is still
  488. broken, but now produces fewer and different spurious errors, like this:
  489. system.wat:56092:3: error: br: insufficient values on the type stack
  490. So, we still disable the type checker, making LLVM-MC v17 usable as an
  491. external assembler. The type checker is still useless, though. }
  492. as_wasm32_llvm_mc_v17_info : tasminfo =
  493. (
  494. id : as_wasm32_llvm_mc_v17;
  495. idtxt : 'LLVM-MC-17';
  496. asmbin : 'llvm-mc-17';
  497. asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj --no-type-check -o $OBJ $EXTRAOPT $ASM';
  498. supported_targets : [system_wasm32_embedded,system_wasm32_wasip1,system_wasm32_wasip1threads,system_wasm32_wasip2];
  499. flags : [af_smartlink_sections];
  500. labelprefix : '.L';
  501. labelmaxlen : -1;
  502. comment : '# ';
  503. dollarsign : '$';
  504. );
  505. { LLVM-MC v18 contains the same bugs as v17, so we still need to disable the
  506. type checker. So far LLVM has shipped 6 major LLVM versions with a broken
  507. WebAssembly type checker. }
  508. as_wasm32_llvm_mc_v18_info : tasminfo =
  509. (
  510. id : as_wasm32_llvm_mc;
  511. idtxt : 'LLVM-MC';
  512. asmbin : 'llvm-mc';
  513. asmcmd : '--assemble --arch=wasm32 -mattr=+sign-ext,+exception-handling,+bulk-memory,+atomics,+reference-types --filetype=obj --no-type-check -o $OBJ $EXTRAOPT $ASM';
  514. supported_targets : [system_wasm32_embedded,system_wasm32_wasip1,system_wasm32_wasip1threads,system_wasm32_wasip2];
  515. flags : [af_smartlink_sections];
  516. labelprefix : '.L';
  517. labelmaxlen : -1;
  518. comment : '# ';
  519. dollarsign : '$';
  520. );
  521. initialization
  522. RegisterAssembler(as_wasm32_llvm_mc_v11_info,TLLVMMachineCodePlaygroundAssemblerV11);
  523. RegisterAssembler(as_wasm32_llvm_mc_v12_info,TLLVMMachineCodePlaygroundAssemblerV12);
  524. RegisterAssembler(as_wasm32_llvm_mc_v13_info,TLLVMMachineCodePlaygroundAssemblerV13);
  525. RegisterAssembler(as_wasm32_llvm_mc_v14_info,TLLVMMachineCodePlaygroundAssemblerV14);
  526. RegisterAssembler(as_wasm32_llvm_mc_v15_info,TLLVMMachineCodePlaygroundAssemblerV15);
  527. RegisterAssembler(as_wasm32_llvm_mc_v16_info,TLLVMMachineCodePlaygroundAssemblerV16);
  528. RegisterAssembler(as_wasm32_llvm_mc_v17_info,TLLVMMachineCodePlaygroundAssemblerV17);
  529. RegisterAssembler(as_wasm32_llvm_mc_v18_info,TLLVMMachineCodePlaygroundAssemblerV18);
  530. end.