rawasmtext.pas 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. {
  2. Copyright (c) 1998-2008 by Carl Eric Codere and Peter Vreman
  3. Copyright (c) 2024 by Nikolay Nikolov
  4. Does the parsing for the WebAssembly styled inline assembler.
  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 rawasmtext;
  19. {$i fpcdefs.inc}
  20. Interface
  21. uses
  22. cclasses,
  23. globtype,
  24. rasm,rawasm,
  25. aasmbase,cpubase;
  26. type
  27. tasmtoken = (
  28. AS_NONE,AS_LPAREN,AS_RPAREN,AS_ID,AS_END,AS_OPCODE,AS_INTNUM,
  29. AS_REALNUM,AS_STRING,AS_PARAM,AS_RESULT,AS_THEN,AS_ELSE,AS_TYPE,AS_VALTYPE
  30. );
  31. tasmkeyword = string[10];
  32. const
  33. token2str : array[tasmtoken] of tasmkeyword=(
  34. '','(',')','identifier','end','opcode','integer','float','string',
  35. 'param','result','then','else','type','valtype');
  36. type
  37. { twasmreader }
  38. twasmreader = class(tasmreader)
  39. private
  40. actwasmbasictype: TWasmBasicType;
  41. actasmpattern_origcase: string;
  42. actasmtoken : tasmtoken;
  43. prevasmtoken : tasmtoken;
  44. procedure SetupTables;
  45. procedure GetToken;
  46. function consume(t : tasmtoken):boolean;
  47. function is_asmopcode(const s: string):boolean;
  48. function is_valtype(const s: string):boolean;
  49. procedure HandleInstruction;
  50. procedure HandleFoldedInstruction;
  51. procedure HandlePlainInstruction;
  52. procedure HandleBlockInstruction;virtual;abstract;
  53. public
  54. function Assemble: tlinkedlist;override;
  55. end;
  56. Implementation
  57. uses
  58. { helpers }
  59. cutils,
  60. { global }
  61. globals,verbose,
  62. systems,
  63. { aasm }
  64. cpuinfo,aasmtai,aasmdata,aasmcpu,
  65. { symtable }
  66. symconst,symbase,symtype,symsym,symtable,symdef,symutil,
  67. { parser }
  68. scanner,pbase,
  69. procinfo,
  70. rabase,rautils,
  71. cgbase,cgutils,cgobj,
  72. { wasm }
  73. itcpuwasm
  74. ;
  75. {*****************************************************************************
  76. twasmreader
  77. *****************************************************************************}
  78. procedure twasmreader.SetupTables;
  79. var
  80. i: TAsmOp;
  81. begin
  82. iasmops:=TFPHashList.create;
  83. for i:=firstop to lastop do
  84. if wasm_op2str[i]<>'end' then
  85. iasmops.Add(wasm_op2str[i],Pointer(PtrInt(i)));
  86. end;
  87. procedure twasmreader.GetToken;
  88. var
  89. len: Integer;
  90. has_sign, is_hex, is_float: Boolean;
  91. tmpS: string;
  92. tmpI, tmpCode: Integer;
  93. begin
  94. c:=scanner.c;
  95. { save old token and reset new token }
  96. prevasmtoken:=actasmtoken;
  97. actasmtoken:=AS_NONE;
  98. { reset }
  99. actasmpattern:='';
  100. { while space, tab, new line or comment, continue scan... }
  101. while c in [' ',#9,#13,#10] do
  102. begin
  103. c:=current_scanner.asmgetchar;
  104. case c of
  105. ';':
  106. begin
  107. c:=current_scanner.asmgetchar;
  108. case c of
  109. { ;; comment until end of line }
  110. ';':
  111. begin
  112. { skip until end of line }
  113. repeat
  114. c:=current_scanner.asmgetchar;
  115. until c in [#13,#10];
  116. end;
  117. else
  118. current_scanner.illegal_char(c);
  119. end;
  120. end;
  121. '(':
  122. begin
  123. current_scanner.gettokenpos;
  124. c:=current_scanner.asmgetchar;
  125. case c of
  126. { (; block comment ;) }
  127. ';':
  128. begin
  129. { skip until ;) }
  130. repeat
  131. c:=current_scanner.asmgetchar;
  132. if c=';' then
  133. begin
  134. c:=current_scanner.asmgetchar;
  135. if c=')' then
  136. begin
  137. c:=current_scanner.asmgetchar;
  138. break;
  139. end;
  140. end;
  141. until false;
  142. end;
  143. else
  144. begin
  145. actasmtoken:=AS_LPAREN;
  146. exit;
  147. end;
  148. end;
  149. end;
  150. end;
  151. end;
  152. current_scanner.gettokenpos;
  153. case c of
  154. ')':
  155. begin
  156. c:=current_scanner.asmgetchar;
  157. actasmtoken:=AS_RPAREN;
  158. end;
  159. '$','a'..'z','A'..'Z':
  160. begin
  161. len:=0;
  162. while c in ['A'..'Z','a'..'z','0'..'9',
  163. '!','#','$','%','&','''','*','+','-','.','/',
  164. ':','<','=','>','?','@','\','^','_','`','|','~'] do
  165. begin
  166. inc(len);
  167. actasmpattern[len]:=c;
  168. c:=current_scanner.asmgetchar;
  169. end;
  170. actasmpattern[0]:=chr(len);
  171. actasmpattern_origcase:=actasmpattern;
  172. if actasmpattern[1]='$' then
  173. actasmtoken:=AS_ID
  174. else if is_asmopcode(actasmpattern) or
  175. is_valtype(actasmpattern) then
  176. exit
  177. else if upper(actasmpattern) = 'END' then
  178. begin
  179. uppervar(actasmpattern);
  180. actasmtoken:=AS_END;
  181. exit;
  182. end
  183. else
  184. begin
  185. message1(asmr_e_unknown_opcode,actasmpattern);
  186. actasmtoken:=AS_NONE;
  187. end;
  188. end;
  189. '0'..'9','+','-':
  190. begin
  191. len:=0;
  192. has_sign:=false;
  193. is_hex:=false;
  194. is_float:=false;
  195. if c in ['+','-'] then
  196. begin
  197. has_sign:=true;
  198. inc(len);
  199. actasmpattern[len]:=c;
  200. c:=current_scanner.asmgetchar;
  201. end;
  202. if c='0' then
  203. begin
  204. inc(len);
  205. actasmpattern[len]:=c;
  206. c:=current_scanner.asmgetchar;
  207. if c='x' then
  208. begin
  209. is_hex:=true;
  210. inc(len);
  211. actasmpattern[len]:=c;
  212. c:=current_scanner.asmgetchar;
  213. end;
  214. end;
  215. if is_hex then
  216. begin
  217. while c in ['0'..'9','a'..'f','A'..'F'] do
  218. begin
  219. inc(len);
  220. actasmpattern[len]:=c;
  221. c:=current_scanner.asmgetchar;
  222. end;
  223. end
  224. else
  225. begin
  226. while c in ['0'..'9'] do
  227. begin
  228. inc(len);
  229. actasmpattern[len]:=c;
  230. c:=current_scanner.asmgetchar;
  231. end;
  232. end;
  233. if c='.' then
  234. begin
  235. is_float:=true;
  236. inc(len);
  237. actasmpattern[len]:=c;
  238. c:=current_scanner.asmgetchar;
  239. { parse the fractional part }
  240. if is_hex then
  241. begin
  242. while c in ['0'..'9','a'..'f','A'..'F'] do
  243. begin
  244. inc(len);
  245. actasmpattern[len]:=c;
  246. c:=current_scanner.asmgetchar;
  247. end;
  248. end
  249. else
  250. begin
  251. while c in ['0'..'9'] do
  252. begin
  253. inc(len);
  254. actasmpattern[len]:=c;
  255. c:=current_scanner.asmgetchar;
  256. end;
  257. end;
  258. end;
  259. if (is_hex and (c in ['p','P'])) or
  260. ((not is_hex) and (c in ['e','E'])) then
  261. begin
  262. inc(len);
  263. actasmpattern[len]:=c;
  264. c:=current_scanner.asmgetchar;
  265. if c in ['+','-'] then
  266. begin
  267. inc(len);
  268. actasmpattern[len]:=c;
  269. c:=current_scanner.asmgetchar;
  270. end;
  271. while c in ['0'..'9'] do
  272. begin
  273. inc(len);
  274. actasmpattern[len]:=c;
  275. c:=current_scanner.asmgetchar;
  276. end;
  277. end;
  278. actasmpattern[0]:=chr(len);
  279. if is_float then
  280. actasmtoken:=AS_REALNUM
  281. else
  282. actasmtoken:=AS_INTNUM;
  283. end;
  284. '"':
  285. begin
  286. actasmpattern:='';
  287. repeat
  288. c:=current_scanner.asmgetchar;
  289. case c of
  290. '\' :
  291. begin
  292. c:=current_scanner.asmgetchar;
  293. case c of
  294. 't':
  295. begin
  296. actasmpattern:=actasmpattern+#9;
  297. c:=current_scanner.asmgetchar;
  298. end;
  299. 'n':
  300. begin
  301. actasmpattern:=actasmpattern+#10;
  302. c:=current_scanner.asmgetchar;
  303. end;
  304. 'r':
  305. begin
  306. actasmpattern:=actasmpattern+#13;
  307. c:=current_scanner.asmgetchar;
  308. end;
  309. '"':
  310. begin
  311. actasmpattern:=actasmpattern+'"';
  312. c:=current_scanner.asmgetchar;
  313. end;
  314. '''':
  315. begin
  316. actasmpattern:=actasmpattern+'''';
  317. c:=current_scanner.asmgetchar;
  318. end;
  319. '\':
  320. begin
  321. actasmpattern:=actasmpattern+'\';
  322. c:=current_scanner.asmgetchar;
  323. end;
  324. 'u':
  325. begin
  326. tmpS:='';
  327. c:=current_scanner.asmgetchar;
  328. while c in ['0'..'9','a'..'f','A'..'F'] do
  329. begin
  330. tmpS:=tmpS+c;
  331. c:=current_scanner.asmgetchar;
  332. end;
  333. if tmpS<>'' then
  334. begin
  335. Val('$'+tmpS,tmpI,tmpCode);
  336. if (tmpI<$D800) or ((tmpI>=$E000) and (tmpI<$110000)) then
  337. begin
  338. if tmpI<=$7F then
  339. actasmpattern:=actasmpattern+Chr(tmpI)
  340. else if tmpI<=$7FF then
  341. actasmpattern:=actasmpattern+
  342. Chr(%11000000 or (tmpI shr 6))+
  343. Chr(%10000000 or (tmpI and $3F))
  344. else if tmpI<=$FFFF then
  345. actasmpattern:=actasmpattern+
  346. Chr(%11100000 or (tmpI shr 12))+
  347. Chr(%10000000 or ((tmpI shr 6) and $3F))+
  348. Chr(%10000000 or (tmpI and $3F))
  349. else
  350. actasmpattern:=actasmpattern+
  351. Chr(%11110000 or (tmpI shr 18))+
  352. Chr(%10000000 or ((tmpI shr 12) and $3F))+
  353. Chr(%10000000 or ((tmpI shr 6) and $3F))+
  354. Chr(%10000000 or (tmpI and $3F))
  355. end
  356. else
  357. Message1(asmr_e_escape_seq_ignored,'u'+tmpS);
  358. end
  359. else
  360. Message1(asmr_e_escape_seq_ignored,'u');
  361. end;
  362. '0'..'9','a'..'f','A'..'F':
  363. begin
  364. tmpS:=c;
  365. c:=current_scanner.asmgetchar;
  366. if c in ['0'..'9','a'..'f','A'..'F'] then
  367. begin
  368. tmpS:=tmpS+c;
  369. c:=current_scanner.asmgetchar;
  370. Val('$'+tmpS,tmpI,tmpCode);
  371. actasmpattern:=actasmpattern+Chr(tmpI);
  372. end
  373. else
  374. begin
  375. Message1(asmr_e_escape_seq_ignored,tmpS+c);
  376. c:=current_scanner.asmgetchar;
  377. end;
  378. end;
  379. else
  380. begin
  381. Message1(asmr_e_escape_seq_ignored,c);
  382. c:=current_scanner.asmgetchar;
  383. end;
  384. end;
  385. end;
  386. '"' :
  387. begin
  388. c:=current_scanner.asmgetchar;
  389. break;
  390. end;
  391. #10,#13:
  392. Message(scan_f_string_exceeds_line);
  393. #0..#9,#11,#12,#14..#31,#127:
  394. current_scanner.illegal_char(c);
  395. else
  396. actasmpattern:=actasmpattern+c;
  397. end;
  398. until false;
  399. actasmtoken:=AS_STRING;
  400. exit;
  401. end;
  402. else
  403. current_scanner.illegal_char(c);
  404. end;
  405. end;
  406. function twasmreader.consume(t: tasmtoken): boolean;
  407. begin
  408. Consume:=true;
  409. if t<>actasmtoken then
  410. begin
  411. Message2(scan_f_syn_expected,token2str[t],token2str[actasmtoken]);
  412. Consume:=false;
  413. end;
  414. repeat
  415. gettoken;
  416. until actasmtoken<>AS_NONE;
  417. end;
  418. function twasmreader.is_asmopcode(const s: string): boolean;
  419. begin
  420. actopcode:=tasmop(PtrUInt(iasmops.Find(s)));
  421. if actopcode<>A_NONE then
  422. begin
  423. actasmtoken:=AS_OPCODE;
  424. is_asmopcode:=true;
  425. end
  426. else
  427. is_asmopcode:=false;
  428. end;
  429. function twasmreader.is_valtype(const s: string): boolean;
  430. begin
  431. actwasmbasictype:=wbt_Unknown;
  432. case s of
  433. 'i32':
  434. actwasmbasictype:=wbt_i32;
  435. 'i64':
  436. actwasmbasictype:=wbt_i64;
  437. 'f32':
  438. actwasmbasictype:=wbt_f32;
  439. 'f64':
  440. actwasmbasictype:=wbt_f64;
  441. 'funcref':
  442. actwasmbasictype:=wbt_funcref;
  443. 'externref':
  444. actwasmbasictype:=wbt_externref;
  445. 'v128':
  446. actwasmbasictype:=wbt_v128;
  447. end;
  448. if actwasmbasictype<>wbt_Unknown then
  449. begin
  450. actasmtoken:=AS_VALTYPE;
  451. is_valtype:=true;
  452. end
  453. else
  454. is_valtype:=false;
  455. end;
  456. procedure twasmreader.HandleInstruction;
  457. begin
  458. case actasmtoken of
  459. AS_LPAREN:
  460. begin
  461. Consume(AS_LPAREN);
  462. HandleFoldedInstruction;
  463. end;
  464. AS_OPCODE:
  465. begin
  466. case actopcode of
  467. a_block,
  468. a_loop,
  469. a_if:
  470. HandleBlockInstruction;
  471. else
  472. HandlePlainInstruction;
  473. end;
  474. end;
  475. else
  476. {error};
  477. end;
  478. end;
  479. procedure twasmreader.HandleFoldedInstruction;
  480. var
  481. HasLabel, HasType, HasParam, HasResult, HasInstructions,
  482. HasThen, HasElse: Boolean;
  483. instr: TWasmInstruction;
  484. tmpS: string;
  485. begin
  486. //Consume(AS_LPAREN);
  487. case actasmtoken of
  488. AS_OPCODE:
  489. begin
  490. case actopcode of
  491. a_block,
  492. a_loop,
  493. a_if:
  494. begin
  495. Consume(AS_OPCODE);
  496. HasType:=False;
  497. HasParam:=False;
  498. HasResult:=False;
  499. HasInstructions:=False;
  500. HasThen:=False;
  501. HasElse:=False;
  502. instr:=TWasmInstruction.create(TWasmOperand);
  503. instr.opcode:=actopcode;
  504. HasLabel:=False;
  505. if actasmtoken=AS_ID then
  506. begin
  507. Consume(AS_ID);
  508. HasLabel:=True;
  509. end;
  510. repeat
  511. case actasmtoken of
  512. AS_LPAREN:
  513. begin
  514. Consume(AS_LPAREN);
  515. case actasmtoken of
  516. AS_TYPE:
  517. begin
  518. if HasElse or HasThen or HasInstructions or HasResult or HasParam or HasType then
  519. begin
  520. {TODO: error}
  521. end;
  522. Consume(AS_TYPE);
  523. //TODO: consume u32 or id
  524. Consume(actasmtoken);
  525. Consume(AS_RPAREN);
  526. end;
  527. AS_PARAM:
  528. begin
  529. if HasElse or HasThen or HasInstructions or HasResult then
  530. begin
  531. {TODO: error}
  532. end;
  533. Consume(AS_PARAM);
  534. if actasmtoken=AS_ID then
  535. begin
  536. tmpS:=actasmpattern;
  537. Consume(AS_ID);
  538. if actasmtoken=AS_VALTYPE then
  539. instr.AddParam(actasmpattern,actwasmbasictype);
  540. Consume(AS_VALTYPE);
  541. end
  542. else
  543. begin
  544. while actasmtoken<>AS_RPAREN do
  545. begin
  546. if actasmtoken=AS_VALTYPE then
  547. instr.AddParam('',actwasmbasictype);
  548. Consume(AS_VALTYPE);
  549. end;
  550. end;
  551. Consume(AS_RPAREN);
  552. end;
  553. AS_RESULT:
  554. begin
  555. if HasElse or HasThen or HasInstructions then
  556. begin
  557. {TODO: error}
  558. end;
  559. Consume(AS_RESULT);
  560. while actasmtoken<>AS_RPAREN do
  561. begin
  562. if actasmtoken=AS_VALTYPE then
  563. instr.AddResult(actwasmbasictype);
  564. Consume(AS_VALTYPE);
  565. end;
  566. Consume(AS_RPAREN);
  567. end;
  568. AS_THEN:
  569. begin
  570. if instr.opcode<>a_if then
  571. {error!};
  572. Consume(AS_THEN);
  573. HasThen:=True;
  574. while actasmtoken<>AS_RPAREN do
  575. HandleInstruction;
  576. Consume(AS_RPAREN);
  577. end;
  578. AS_ELSE:
  579. begin
  580. if instr.opcode<>a_if then
  581. {error!};
  582. Consume(AS_ELSE);
  583. HasElse:=True;
  584. while actasmtoken<>AS_RPAREN do
  585. HandleInstruction;
  586. Consume(AS_RPAREN);
  587. end;
  588. else
  589. begin
  590. HasInstructions:=True;
  591. HandleFoldedInstruction;
  592. end;
  593. end;
  594. end;
  595. end;
  596. until false;
  597. end;
  598. else
  599. begin
  600. HandlePlainInstruction;
  601. {todo: parse next folded instructions, insert plain instruction after these}
  602. end;
  603. end;
  604. end;
  605. else
  606. {error}
  607. end;
  608. end;
  609. procedure twasmreader.HandlePlainInstruction;
  610. var
  611. instr: TWasmInstruction;
  612. begin
  613. case actasmtoken of
  614. AS_OPCODE:
  615. begin
  616. instr:=TWasmInstruction.create(TWasmOperand);
  617. instr.opcode:=actopcode;
  618. case actopcode of
  619. { instructions, which require 0 operands }
  620. a_nop,
  621. a_unreachable,
  622. a_return,
  623. a_ref_is_null,
  624. a_drop,
  625. a_memory_size,
  626. a_memory_grow,
  627. a_memory_fill,
  628. a_memory_copy,
  629. a_i32_clz,a_i32_ctz,a_i32_popcnt,a_i32_add,a_i32_sub,a_i32_mul,a_i32_div_s,a_i32_div_u,a_i32_rem_s,a_i32_rem_u,a_i32_and,a_i32_or,a_i32_xor,a_i32_shl,a_i32_shr_s,a_i32_shr_u,a_i32_rotl,a_i32_rotr,
  630. a_i64_clz,a_i64_ctz,a_i64_popcnt,a_i64_add,a_i64_sub,a_i64_mul,a_i64_div_s,a_i64_div_u,a_i64_rem_s,a_i64_rem_u,a_i64_and,a_i64_or,a_i64_xor,a_i64_shl,a_i64_shr_s,a_i64_shr_u,a_i64_rotl,a_i64_rotr,
  631. a_f32_abs,a_f32_neg,a_f32_ceil,a_f32_floor,a_f32_trunc,a_f32_nearest,a_f32_sqrt,a_f32_add,a_f32_sub,a_f32_mul,a_f32_div,a_f32_min,a_f32_max,a_f32_copysign,
  632. a_f64_abs,a_f64_neg,a_f64_ceil,a_f64_floor,a_f64_trunc,a_f64_nearest,a_f64_sqrt,a_f64_add,a_f64_sub,a_f64_mul,a_f64_div,a_f64_min,a_f64_max,a_f64_copysign,
  633. a_i32_eqz,a_i32_eq,a_i32_ne,a_i32_lt_s,a_i32_lt_u,a_i32_gt_s,a_i32_gt_u,a_i32_le_s,a_i32_le_u,a_i32_ge_s,a_i32_ge_u,
  634. a_i64_eqz,a_i64_eq,a_i64_ne,a_i64_lt_s,a_i64_lt_u,a_i64_gt_s,a_i64_gt_u,a_i64_le_s,a_i64_le_u,a_i64_ge_s,a_i64_ge_u,
  635. a_f32_eq,a_f32_ne,a_f32_lt,a_f32_gt,a_f32_le,a_f32_ge,
  636. a_f64_eq,a_f64_ne,a_f64_lt,a_f64_gt,a_f64_le,a_f64_ge,
  637. a_i32_wrap_i64,
  638. a_i32_trunc_f32_s,
  639. a_i32_trunc_f32_u,
  640. a_i32_trunc_f64_s,
  641. a_i32_trunc_f64_u,
  642. a_i32_trunc_sat_f32_s,
  643. a_i32_trunc_sat_f32_u,
  644. a_i32_trunc_sat_f64_s,
  645. a_i32_trunc_sat_f64_u,
  646. a_i64_extend_i32_s,
  647. a_i64_extend_i32_u,
  648. a_i64_trunc_f32_s,
  649. a_i64_trunc_f32_u,
  650. a_i64_trunc_f64_s,
  651. a_i64_trunc_f64_u,
  652. a_i64_trunc_sat_f32_s,
  653. a_i64_trunc_sat_f32_u,
  654. a_i64_trunc_sat_f64_u,
  655. a_i64_trunc_sat_f64_s,
  656. a_f32_convert_i32_s,
  657. a_f32_convert_i32_u,
  658. a_f32_convert_i64_s,
  659. a_f32_convert_i64_u,
  660. a_f32_demote_f64,
  661. a_f64_convert_i32_s,
  662. a_f64_convert_i32_u,
  663. a_f64_convert_i64_s,
  664. a_f64_convert_i64_u,
  665. a_f64_promote_f32,
  666. a_i32_reinterpret_f32,
  667. a_i64_reinterpret_f64,
  668. a_f32_reinterpret_i32,
  669. a_f64_reinterpret_i64,
  670. a_i32_extend8_s,
  671. a_i32_extend16_s,
  672. a_i64_extend8_s,
  673. a_i64_extend16_s,
  674. a_i64_extend32_s:
  675. ;
  676. end;
  677. end;
  678. else
  679. {error};
  680. end;
  681. end;
  682. function twasmreader.Assemble: tlinkedlist;
  683. begin
  684. Message1(asmr_d_start_reading,'WebAssembly');
  685. firsttoken:=TRUE;
  686. { sets up all opcode and register tables in uppercase }
  687. if not _asmsorted then
  688. begin
  689. SetupTables;
  690. _asmsorted:=TRUE;
  691. end;
  692. curlist:=TAsmList.Create;
  693. { we might need to know which parameters are passed in registers }
  694. if not parse_generic then
  695. current_procinfo.generate_parameter_info;
  696. { start tokenizer }
  697. gettoken;
  698. { main loop }
  699. repeat
  700. Writeln(actasmtoken);
  701. case actasmtoken of
  702. AS_END:
  703. break; { end assembly block }
  704. else
  705. begin
  706. Consume(actasmtoken);
  707. //Message(asmr_e_syntax_error);
  708. //RecoverConsume(false);
  709. end;
  710. end;
  711. until false;
  712. { Return the list in an asmnode }
  713. assemble:=curlist;
  714. Message1(asmr_d_finish_reading,'WebAssembly');
  715. end;
  716. {*****************************************************************************
  717. Initialize
  718. *****************************************************************************}
  719. const
  720. asmmode_wasm_standard_info : tasmmodeinfo =
  721. (
  722. id : asmmode_standard;
  723. idtxt : 'STANDARD';
  724. casmreader : twasmreader;
  725. );
  726. initialization
  727. RegisterAsmMode(asmmode_wasm_standard_info);
  728. end.