aot_compiler.c 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "aot_compiler.h"
  6. #include "aot_emit_compare.h"
  7. #include "aot_emit_conversion.h"
  8. #include "aot_emit_memory.h"
  9. #include "aot_emit_variable.h"
  10. #include "aot_emit_const.h"
  11. #include "aot_emit_exception.h"
  12. #include "aot_emit_numberic.h"
  13. #include "aot_emit_control.h"
  14. #include "aot_emit_function.h"
  15. #include "aot_emit_parametric.h"
  16. #include "../aot/aot_runtime.h"
  17. #include "../interpreter/wasm_opcode.h"
  18. #include <errno.h>
  19. #define CHECK_BUF(buf, buf_end, length) do { \
  20. if (buf + length > buf_end) { \
  21. aot_set_last_error("read leb failed: unexpected end."); \
  22. return false; \
  23. } \
  24. } while (0)
  25. static bool
  26. read_leb(const uint8 *buf, const uint8 *buf_end,
  27. uint32 *p_offset, uint32 maxbits,
  28. bool sign, uint64 *p_result)
  29. {
  30. uint64 result = 0;
  31. uint32 shift = 0;
  32. uint32 bcnt = 0;
  33. uint64 byte;
  34. while (true) {
  35. CHECK_BUF(buf, buf_end, 1);
  36. byte = buf[*p_offset];
  37. *p_offset += 1;
  38. result |= ((byte & 0x7f) << shift);
  39. shift += 7;
  40. if ((byte & 0x80) == 0) {
  41. break;
  42. }
  43. bcnt += 1;
  44. }
  45. if (bcnt > (((maxbits + 8) >> 3) - (maxbits + 8))) {
  46. aot_set_last_error("read leb failed: unsigned leb overflow.");
  47. return false;
  48. }
  49. if (sign && (shift < maxbits) && (byte & 0x40)) {
  50. /* Sign extend */
  51. result |= (uint64)(- (((uint64)1) << shift));
  52. }
  53. *p_result = result;
  54. return true;
  55. }
  56. #define read_leb_uint32(p, p_end, res) do { \
  57. uint32 off = 0; \
  58. uint64 res64; \
  59. if (!read_leb(p, p_end, &off, 32, false, &res64)) \
  60. return false; \
  61. p += off; \
  62. res = (uint32)res64; \
  63. } while (0)
  64. #define read_leb_int32(p, p_end, res) do { \
  65. uint32 off = 0; \
  66. uint64 res64; \
  67. if (!read_leb(p, p_end, &off, 32, true, &res64)) \
  68. return false; \
  69. p += off; \
  70. res = (int32)res64; \
  71. } while (0)
  72. #define read_leb_int64(p, p_end, res) do { \
  73. uint32 off = 0; \
  74. uint64 res64; \
  75. if (!read_leb(p, p_end, &off, 64, true, &res64)) \
  76. return false; \
  77. p += off; \
  78. res = (int64)res64; \
  79. } while (0)
  80. #define COMPILE_ATOMIC_RMW(OP, NAME) \
  81. case WASM_OP_ATOMIC_RMW_I32_##NAME: \
  82. bytes = 4; \
  83. op_type = VALUE_TYPE_I32; \
  84. goto OP_ATOMIC_##OP; \
  85. case WASM_OP_ATOMIC_RMW_I64_##NAME: \
  86. bytes = 8; \
  87. op_type = VALUE_TYPE_I64; \
  88. goto OP_ATOMIC_##OP; \
  89. case WASM_OP_ATOMIC_RMW_I32_##NAME##8_U: \
  90. bytes = 1; \
  91. op_type = VALUE_TYPE_I32; \
  92. goto OP_ATOMIC_##OP; \
  93. case WASM_OP_ATOMIC_RMW_I32_##NAME##16_U: \
  94. bytes = 2; \
  95. op_type = VALUE_TYPE_I32; \
  96. goto OP_ATOMIC_##OP; \
  97. case WASM_OP_ATOMIC_RMW_I64_##NAME##8_U: \
  98. bytes = 1; \
  99. op_type = VALUE_TYPE_I64; \
  100. goto OP_ATOMIC_##OP; \
  101. case WASM_OP_ATOMIC_RMW_I64_##NAME##16_U: \
  102. bytes = 2; \
  103. op_type = VALUE_TYPE_I64; \
  104. goto OP_ATOMIC_##OP; \
  105. case WASM_OP_ATOMIC_RMW_I64_##NAME##32_U: \
  106. bytes = 4; \
  107. op_type = VALUE_TYPE_I64; \
  108. OP_ATOMIC_##OP: \
  109. bin_op = LLVMAtomicRMWBinOp##OP; \
  110. goto build_atomic_rmw;
  111. static bool
  112. aot_compile_func(AOTCompContext *comp_ctx, uint32 func_index)
  113. {
  114. AOTFuncContext *func_ctx = comp_ctx->func_ctxes[func_index];
  115. uint8 *frame_ip = func_ctx->aot_func->code, opcode, *p_f32, *p_f64;
  116. uint8 *frame_ip_end = frame_ip + func_ctx->aot_func->code_size;
  117. uint8 *param_types = NULL;
  118. uint8 *result_types = NULL;
  119. uint8 value_type;
  120. uint16 param_count;
  121. uint16 result_count;
  122. uint32 br_depth, *br_depths, br_count;
  123. uint32 func_idx, type_idx, mem_idx, local_idx, global_idx, i;
  124. uint32 bytes = 4, align, offset;
  125. uint32 type_index;
  126. bool sign = true;
  127. int32 i32_const;
  128. int64 i64_const;
  129. float32 f32_const;
  130. float64 f64_const;
  131. AOTFuncType *func_type = NULL;
  132. /* Start to translate the opcodes */
  133. LLVMPositionBuilderAtEnd(comp_ctx->builder,
  134. func_ctx->block_stack.block_list_head
  135. ->llvm_entry_block);
  136. while (frame_ip < frame_ip_end) {
  137. opcode = *frame_ip++;
  138. switch (opcode) {
  139. case WASM_OP_UNREACHABLE:
  140. if (!aot_compile_op_unreachable(comp_ctx, func_ctx, &frame_ip))
  141. return false;
  142. break;
  143. case WASM_OP_NOP:
  144. break;
  145. case WASM_OP_BLOCK:
  146. case WASM_OP_LOOP:
  147. case WASM_OP_IF:
  148. value_type = *frame_ip++;
  149. if (value_type == VALUE_TYPE_I32
  150. || value_type == VALUE_TYPE_I64
  151. || value_type == VALUE_TYPE_F32
  152. || value_type == VALUE_TYPE_F64
  153. || value_type == VALUE_TYPE_VOID) {
  154. param_count = 0;
  155. param_types = NULL;
  156. if (value_type == VALUE_TYPE_VOID) {
  157. result_count = 0;
  158. result_types = NULL;
  159. }
  160. else {
  161. result_count = 1;
  162. result_types = &value_type;
  163. }
  164. }
  165. else {
  166. frame_ip--;
  167. read_leb_uint32(frame_ip, frame_ip_end, type_index);
  168. func_type = comp_ctx->comp_data->func_types[type_index];
  169. param_count = func_type->param_count;
  170. param_types = func_type->types;
  171. result_count = func_type->result_count;
  172. result_types = func_type->types + param_count;
  173. }
  174. if (!aot_compile_op_block(comp_ctx, func_ctx,
  175. &frame_ip, frame_ip_end,
  176. (uint32)(LABEL_TYPE_BLOCK + opcode - WASM_OP_BLOCK),
  177. param_count, param_types,
  178. result_count, result_types))
  179. return false;
  180. break;
  181. case WASM_OP_ELSE:
  182. if (!aot_compile_op_else(comp_ctx, func_ctx, &frame_ip))
  183. return false;
  184. break;
  185. case WASM_OP_END:
  186. if (!aot_compile_op_end(comp_ctx, func_ctx, &frame_ip))
  187. return false;
  188. break;
  189. case WASM_OP_BR:
  190. read_leb_uint32(frame_ip, frame_ip_end, br_depth);
  191. if (!aot_compile_op_br(comp_ctx, func_ctx, br_depth, &frame_ip))
  192. return false;
  193. break;
  194. case WASM_OP_BR_IF:
  195. read_leb_uint32(frame_ip, frame_ip_end, br_depth);
  196. if (!aot_compile_op_br_if(comp_ctx, func_ctx, br_depth, &frame_ip))
  197. return false;
  198. break;
  199. case WASM_OP_BR_TABLE:
  200. read_leb_uint32(frame_ip, frame_ip_end, br_count);
  201. if (!(br_depths =
  202. wasm_runtime_malloc((uint32)sizeof(uint32) * (br_count + 1)))) {
  203. aot_set_last_error("allocate memory failed.");
  204. goto fail;
  205. }
  206. for (i = 0; i <= br_count; i++)
  207. read_leb_uint32(frame_ip, frame_ip_end, br_depths[i]);
  208. if (!aot_compile_op_br_table(comp_ctx, func_ctx,
  209. br_depths, br_count, &frame_ip)) {
  210. wasm_runtime_free(br_depths);
  211. return false;
  212. }
  213. wasm_runtime_free(br_depths);
  214. break;
  215. case WASM_OP_RETURN:
  216. if (!aot_compile_op_return(comp_ctx, func_ctx, &frame_ip))
  217. return false;
  218. break;
  219. case WASM_OP_CALL:
  220. read_leb_uint32(frame_ip, frame_ip_end, func_idx);
  221. if (!aot_compile_op_call(comp_ctx, func_ctx, func_idx, &frame_ip))
  222. return false;
  223. break;
  224. case WASM_OP_CALL_INDIRECT:
  225. read_leb_uint32(frame_ip, frame_ip_end, type_idx);
  226. frame_ip++; /* skip 0x00 */
  227. if (!aot_compile_op_call_indirect(comp_ctx, func_ctx, type_idx))
  228. return false;
  229. break;
  230. case WASM_OP_DROP:
  231. if (!aot_compile_op_drop(comp_ctx, func_ctx, true))
  232. return false;
  233. break;
  234. case WASM_OP_DROP_64:
  235. if (!aot_compile_op_drop(comp_ctx, func_ctx, false))
  236. return false;
  237. break;
  238. case WASM_OP_SELECT:
  239. if (!aot_compile_op_select(comp_ctx, func_ctx, true))
  240. return false;
  241. break;
  242. case WASM_OP_SELECT_64:
  243. if (!aot_compile_op_select(comp_ctx, func_ctx, false))
  244. return false;
  245. break;
  246. case WASM_OP_GET_LOCAL:
  247. read_leb_uint32(frame_ip, frame_ip_end, local_idx);
  248. if (!aot_compile_op_get_local(comp_ctx, func_ctx, local_idx))
  249. return false;
  250. break;
  251. case WASM_OP_SET_LOCAL:
  252. read_leb_uint32(frame_ip, frame_ip_end, local_idx);
  253. if (!aot_compile_op_set_local(comp_ctx, func_ctx, local_idx))
  254. return false;
  255. break;
  256. case WASM_OP_TEE_LOCAL:
  257. read_leb_uint32(frame_ip, frame_ip_end, local_idx);
  258. if (!aot_compile_op_tee_local(comp_ctx, func_ctx, local_idx))
  259. return false;
  260. break;
  261. case WASM_OP_GET_GLOBAL:
  262. read_leb_uint32(frame_ip, frame_ip_end, global_idx);
  263. if (!aot_compile_op_get_global(comp_ctx, func_ctx, global_idx))
  264. return false;
  265. break;
  266. case WASM_OP_SET_GLOBAL:
  267. read_leb_uint32(frame_ip, frame_ip_end, global_idx);
  268. if (!aot_compile_op_set_global(comp_ctx, func_ctx, global_idx))
  269. return false;
  270. break;
  271. case WASM_OP_I32_LOAD:
  272. bytes = 4;
  273. sign = true;
  274. goto op_i32_load;
  275. case WASM_OP_I32_LOAD8_S:
  276. case WASM_OP_I32_LOAD8_U:
  277. bytes = 1;
  278. sign = (opcode == WASM_OP_I32_LOAD8_S) ? true : false;
  279. goto op_i32_load;
  280. case WASM_OP_I32_LOAD16_S:
  281. case WASM_OP_I32_LOAD16_U:
  282. bytes = 2;
  283. sign = (opcode == WASM_OP_I32_LOAD16_S) ? true : false;
  284. op_i32_load:
  285. read_leb_uint32(frame_ip, frame_ip_end, align);
  286. read_leb_uint32(frame_ip, frame_ip_end, offset);
  287. if (!aot_compile_op_i32_load(comp_ctx, func_ctx, align, offset,
  288. bytes, sign, false))
  289. return false;
  290. break;
  291. case WASM_OP_I64_LOAD:
  292. bytes = 8;
  293. sign = true;
  294. goto op_i64_load;
  295. case WASM_OP_I64_LOAD8_S:
  296. case WASM_OP_I64_LOAD8_U:
  297. bytes = 1;
  298. sign = (opcode == WASM_OP_I64_LOAD8_S) ? true : false;
  299. goto op_i64_load;
  300. case WASM_OP_I64_LOAD16_S:
  301. case WASM_OP_I64_LOAD16_U:
  302. bytes = 2;
  303. sign = (opcode == WASM_OP_I64_LOAD16_S) ? true : false;
  304. goto op_i64_load;
  305. case WASM_OP_I64_LOAD32_S:
  306. case WASM_OP_I64_LOAD32_U:
  307. bytes = 4;
  308. sign = (opcode == WASM_OP_I64_LOAD32_S) ? true : false;
  309. op_i64_load:
  310. read_leb_uint32(frame_ip, frame_ip_end, align);
  311. read_leb_uint32(frame_ip, frame_ip_end, offset);
  312. if (!aot_compile_op_i64_load(comp_ctx, func_ctx, align, offset,
  313. bytes, sign, false))
  314. return false;
  315. break;
  316. case WASM_OP_F32_LOAD:
  317. read_leb_uint32(frame_ip, frame_ip_end, align);
  318. read_leb_uint32(frame_ip, frame_ip_end, offset);
  319. if (!aot_compile_op_f32_load(comp_ctx, func_ctx, align, offset))
  320. return false;
  321. break;
  322. case WASM_OP_F64_LOAD:
  323. read_leb_uint32(frame_ip, frame_ip_end, align);
  324. read_leb_uint32(frame_ip, frame_ip_end, offset);
  325. if (!aot_compile_op_f64_load(comp_ctx, func_ctx, align, offset))
  326. return false;
  327. break;
  328. case WASM_OP_I32_STORE:
  329. bytes = 4;
  330. goto op_i32_store;
  331. case WASM_OP_I32_STORE8:
  332. bytes = 1;
  333. goto op_i32_store;
  334. case WASM_OP_I32_STORE16:
  335. bytes = 2;
  336. op_i32_store:
  337. read_leb_uint32(frame_ip, frame_ip_end, align);
  338. read_leb_uint32(frame_ip, frame_ip_end, offset);
  339. if (!aot_compile_op_i32_store(comp_ctx, func_ctx, align,
  340. offset, bytes, false))
  341. return false;
  342. break;
  343. case WASM_OP_I64_STORE:
  344. bytes = 8;
  345. goto op_i64_store;
  346. case WASM_OP_I64_STORE8:
  347. bytes = 1;
  348. goto op_i64_store;
  349. case WASM_OP_I64_STORE16:
  350. bytes = 2;
  351. goto op_i64_store;
  352. case WASM_OP_I64_STORE32:
  353. bytes = 4;
  354. op_i64_store:
  355. read_leb_uint32(frame_ip, frame_ip_end, align);
  356. read_leb_uint32(frame_ip, frame_ip_end, offset);
  357. if (!aot_compile_op_i64_store(comp_ctx, func_ctx, align,
  358. offset, bytes, false))
  359. return false;
  360. break;
  361. case WASM_OP_F32_STORE:
  362. read_leb_uint32(frame_ip, frame_ip_end, align);
  363. read_leb_uint32(frame_ip, frame_ip_end, offset);
  364. if (!aot_compile_op_f32_store(comp_ctx, func_ctx, align, offset))
  365. return false;
  366. break;
  367. case WASM_OP_F64_STORE:
  368. read_leb_uint32(frame_ip, frame_ip_end, align);
  369. read_leb_uint32(frame_ip, frame_ip_end, offset);
  370. if (!aot_compile_op_f64_store(comp_ctx, func_ctx, align, offset))
  371. return false;
  372. break;
  373. case WASM_OP_MEMORY_SIZE:
  374. read_leb_uint32(frame_ip, frame_ip_end, mem_idx);
  375. if (!aot_compile_op_memory_size(comp_ctx, func_ctx))
  376. return false;
  377. (void)mem_idx;
  378. break;
  379. case WASM_OP_MEMORY_GROW:
  380. read_leb_uint32(frame_ip, frame_ip_end, mem_idx);
  381. if (!aot_compile_op_memory_grow(comp_ctx, func_ctx))
  382. return false;
  383. break;
  384. case WASM_OP_I32_CONST:
  385. read_leb_int32(frame_ip, frame_ip_end, i32_const);
  386. if (!aot_compile_op_i32_const(comp_ctx, func_ctx, i32_const))
  387. return false;
  388. break;
  389. case WASM_OP_I64_CONST:
  390. read_leb_int64(frame_ip, frame_ip_end, i64_const);
  391. if (!aot_compile_op_i64_const(comp_ctx, func_ctx, i64_const))
  392. return false;
  393. break;
  394. case WASM_OP_F32_CONST:
  395. p_f32 = (uint8*)&f32_const;
  396. for (i = 0; i < sizeof(float32); i++)
  397. *p_f32++ = *frame_ip++;
  398. if (!aot_compile_op_f32_const(comp_ctx, func_ctx, f32_const))
  399. return false;
  400. break;
  401. case WASM_OP_F64_CONST:
  402. p_f64 = (uint8*)&f64_const;
  403. for (i = 0; i < sizeof(float64); i++)
  404. *p_f64++ = *frame_ip++;
  405. if (!aot_compile_op_f64_const(comp_ctx, func_ctx, f64_const))
  406. return false;
  407. break;
  408. case WASM_OP_I32_EQZ:
  409. case WASM_OP_I32_EQ:
  410. case WASM_OP_I32_NE:
  411. case WASM_OP_I32_LT_S:
  412. case WASM_OP_I32_LT_U:
  413. case WASM_OP_I32_GT_S:
  414. case WASM_OP_I32_GT_U:
  415. case WASM_OP_I32_LE_S:
  416. case WASM_OP_I32_LE_U:
  417. case WASM_OP_I32_GE_S:
  418. case WASM_OP_I32_GE_U:
  419. if (!aot_compile_op_i32_compare(comp_ctx, func_ctx,
  420. INT_EQZ + opcode - WASM_OP_I32_EQZ))
  421. return false;
  422. break;
  423. case WASM_OP_I64_EQZ:
  424. case WASM_OP_I64_EQ:
  425. case WASM_OP_I64_NE:
  426. case WASM_OP_I64_LT_S:
  427. case WASM_OP_I64_LT_U:
  428. case WASM_OP_I64_GT_S:
  429. case WASM_OP_I64_GT_U:
  430. case WASM_OP_I64_LE_S:
  431. case WASM_OP_I64_LE_U:
  432. case WASM_OP_I64_GE_S:
  433. case WASM_OP_I64_GE_U:
  434. if (!aot_compile_op_i64_compare(comp_ctx, func_ctx,
  435. INT_EQZ + opcode - WASM_OP_I64_EQZ))
  436. return false;
  437. break;
  438. case WASM_OP_F32_EQ:
  439. case WASM_OP_F32_NE:
  440. case WASM_OP_F32_LT:
  441. case WASM_OP_F32_GT:
  442. case WASM_OP_F32_LE:
  443. case WASM_OP_F32_GE:
  444. if (!aot_compile_op_f32_compare(comp_ctx, func_ctx,
  445. FLOAT_EQ + opcode - WASM_OP_F32_EQ))
  446. return false;
  447. break;
  448. case WASM_OP_F64_EQ:
  449. case WASM_OP_F64_NE:
  450. case WASM_OP_F64_LT:
  451. case WASM_OP_F64_GT:
  452. case WASM_OP_F64_LE:
  453. case WASM_OP_F64_GE:
  454. if (!aot_compile_op_f64_compare(comp_ctx, func_ctx,
  455. FLOAT_EQ + opcode - WASM_OP_F64_EQ))
  456. return false;
  457. break;
  458. case WASM_OP_I32_CLZ:
  459. if (!aot_compile_op_i32_clz(comp_ctx, func_ctx))
  460. return false;
  461. break;
  462. case WASM_OP_I32_CTZ:
  463. if (!aot_compile_op_i32_ctz(comp_ctx, func_ctx))
  464. return false;
  465. break;
  466. case WASM_OP_I32_POPCNT:
  467. if (!aot_compile_op_i32_popcnt(comp_ctx, func_ctx))
  468. return false;
  469. break;
  470. case WASM_OP_I32_ADD:
  471. case WASM_OP_I32_SUB:
  472. case WASM_OP_I32_MUL:
  473. case WASM_OP_I32_DIV_S:
  474. case WASM_OP_I32_DIV_U:
  475. case WASM_OP_I32_REM_S:
  476. case WASM_OP_I32_REM_U:
  477. if (!aot_compile_op_i32_arithmetic(comp_ctx, func_ctx,
  478. INT_ADD + opcode - WASM_OP_I32_ADD,
  479. &frame_ip))
  480. return false;
  481. break;
  482. case WASM_OP_I32_AND:
  483. case WASM_OP_I32_OR:
  484. case WASM_OP_I32_XOR:
  485. if (!aot_compile_op_i32_bitwise(comp_ctx, func_ctx,
  486. INT_SHL + opcode - WASM_OP_I32_AND))
  487. return false;
  488. break;
  489. case WASM_OP_I32_SHL:
  490. case WASM_OP_I32_SHR_S:
  491. case WASM_OP_I32_SHR_U:
  492. case WASM_OP_I32_ROTL:
  493. case WASM_OP_I32_ROTR:
  494. if (!aot_compile_op_i32_shift(comp_ctx, func_ctx,
  495. INT_SHL + opcode - WASM_OP_I32_SHL))
  496. return false;
  497. break;
  498. case WASM_OP_I64_CLZ:
  499. if (!aot_compile_op_i64_clz(comp_ctx, func_ctx))
  500. return false;
  501. break;
  502. case WASM_OP_I64_CTZ:
  503. if (!aot_compile_op_i64_ctz(comp_ctx, func_ctx))
  504. return false;
  505. break;
  506. case WASM_OP_I64_POPCNT:
  507. if (!aot_compile_op_i64_popcnt(comp_ctx, func_ctx))
  508. return false;
  509. break;
  510. case WASM_OP_I64_ADD:
  511. case WASM_OP_I64_SUB:
  512. case WASM_OP_I64_MUL:
  513. case WASM_OP_I64_DIV_S:
  514. case WASM_OP_I64_DIV_U:
  515. case WASM_OP_I64_REM_S:
  516. case WASM_OP_I64_REM_U:
  517. if (!aot_compile_op_i64_arithmetic(comp_ctx, func_ctx,
  518. INT_ADD + opcode - WASM_OP_I64_ADD,
  519. &frame_ip))
  520. return false;
  521. break;
  522. case WASM_OP_I64_AND:
  523. case WASM_OP_I64_OR:
  524. case WASM_OP_I64_XOR:
  525. if (!aot_compile_op_i64_bitwise(comp_ctx, func_ctx,
  526. INT_SHL + opcode - WASM_OP_I64_AND))
  527. return false;
  528. break;
  529. case WASM_OP_I64_SHL:
  530. case WASM_OP_I64_SHR_S:
  531. case WASM_OP_I64_SHR_U:
  532. case WASM_OP_I64_ROTL:
  533. case WASM_OP_I64_ROTR:
  534. if (!aot_compile_op_i64_shift(comp_ctx, func_ctx,
  535. INT_SHL + opcode - WASM_OP_I64_SHL))
  536. return false;
  537. break;
  538. case WASM_OP_F32_ABS:
  539. case WASM_OP_F32_NEG:
  540. case WASM_OP_F32_CEIL:
  541. case WASM_OP_F32_FLOOR:
  542. case WASM_OP_F32_TRUNC:
  543. case WASM_OP_F32_NEAREST:
  544. case WASM_OP_F32_SQRT:
  545. if (!aot_compile_op_f32_math(comp_ctx, func_ctx,
  546. FLOAT_ABS + opcode - WASM_OP_F32_ABS))
  547. return false;
  548. break;
  549. case WASM_OP_F32_ADD:
  550. case WASM_OP_F32_SUB:
  551. case WASM_OP_F32_MUL:
  552. case WASM_OP_F32_DIV:
  553. case WASM_OP_F32_MIN:
  554. case WASM_OP_F32_MAX:
  555. if (!aot_compile_op_f32_arithmetic(comp_ctx, func_ctx,
  556. FLOAT_ADD + opcode - WASM_OP_F32_ADD))
  557. return false;
  558. break;
  559. case WASM_OP_F32_COPYSIGN:
  560. if (!aot_compile_op_f32_copysign(comp_ctx, func_ctx))
  561. return false;
  562. break;
  563. case WASM_OP_F64_ABS:
  564. case WASM_OP_F64_NEG:
  565. case WASM_OP_F64_CEIL:
  566. case WASM_OP_F64_FLOOR:
  567. case WASM_OP_F64_TRUNC:
  568. case WASM_OP_F64_NEAREST:
  569. case WASM_OP_F64_SQRT:
  570. if (!aot_compile_op_f64_math(comp_ctx, func_ctx,
  571. FLOAT_ABS + opcode - WASM_OP_F64_ABS))
  572. return false;
  573. break;
  574. case WASM_OP_F64_ADD:
  575. case WASM_OP_F64_SUB:
  576. case WASM_OP_F64_MUL:
  577. case WASM_OP_F64_DIV:
  578. case WASM_OP_F64_MIN:
  579. case WASM_OP_F64_MAX:
  580. if (!aot_compile_op_f64_arithmetic(comp_ctx, func_ctx,
  581. FLOAT_ADD + opcode - WASM_OP_F64_ADD))
  582. return false;
  583. break;
  584. case WASM_OP_F64_COPYSIGN:
  585. if (!aot_compile_op_f64_copysign(comp_ctx, func_ctx))
  586. return false;
  587. break;
  588. case WASM_OP_I32_WRAP_I64:
  589. if (!aot_compile_op_i32_wrap_i64(comp_ctx, func_ctx))
  590. return false;
  591. break;
  592. case WASM_OP_I32_TRUNC_S_F32:
  593. case WASM_OP_I32_TRUNC_U_F32:
  594. sign = (opcode == WASM_OP_I32_TRUNC_S_F32) ? true : false;
  595. if (!aot_compile_op_i32_trunc_f32(comp_ctx, func_ctx, sign, false))
  596. return false;
  597. break;
  598. case WASM_OP_I32_TRUNC_S_F64:
  599. case WASM_OP_I32_TRUNC_U_F64:
  600. sign = (opcode == WASM_OP_I32_TRUNC_S_F64) ? true : false;
  601. if (!aot_compile_op_i32_trunc_f64(comp_ctx, func_ctx, sign, false))
  602. return false;
  603. break;
  604. case WASM_OP_I64_EXTEND_S_I32:
  605. case WASM_OP_I64_EXTEND_U_I32:
  606. sign = (opcode == WASM_OP_I64_EXTEND_S_I32) ? true : false;
  607. if (!aot_compile_op_i64_extend_i32(comp_ctx, func_ctx, sign))
  608. return false;
  609. break;
  610. case WASM_OP_I64_TRUNC_S_F32:
  611. case WASM_OP_I64_TRUNC_U_F32:
  612. sign = (opcode == WASM_OP_I64_TRUNC_S_F32) ? true : false;
  613. if (!aot_compile_op_i64_trunc_f32(comp_ctx, func_ctx, sign, false))
  614. return false;
  615. break;
  616. case WASM_OP_I64_TRUNC_S_F64:
  617. case WASM_OP_I64_TRUNC_U_F64:
  618. sign = (opcode == WASM_OP_I64_TRUNC_S_F64) ? true : false;
  619. if (!aot_compile_op_i64_trunc_f64(comp_ctx, func_ctx, sign, false))
  620. return false;
  621. break;
  622. case WASM_OP_F32_CONVERT_S_I32:
  623. case WASM_OP_F32_CONVERT_U_I32:
  624. sign = (opcode == WASM_OP_F32_CONVERT_S_I32) ? true : false;
  625. if (!aot_compile_op_f32_convert_i32(comp_ctx, func_ctx, sign))
  626. return false;
  627. break;
  628. case WASM_OP_F32_CONVERT_S_I64:
  629. case WASM_OP_F32_CONVERT_U_I64:
  630. sign = (opcode == WASM_OP_F32_CONVERT_S_I64) ? true : false;
  631. if (!aot_compile_op_f32_convert_i64(comp_ctx, func_ctx, sign))
  632. return false;
  633. break;
  634. case WASM_OP_F32_DEMOTE_F64:
  635. if (!aot_compile_op_f32_demote_f64(comp_ctx, func_ctx))
  636. return false;
  637. break;
  638. case WASM_OP_F64_CONVERT_S_I32:
  639. case WASM_OP_F64_CONVERT_U_I32:
  640. sign = (opcode == WASM_OP_F64_CONVERT_S_I32) ? true : false;
  641. if (!aot_compile_op_f64_convert_i32(comp_ctx, func_ctx, sign))
  642. return false;
  643. break;
  644. case WASM_OP_F64_CONVERT_S_I64:
  645. case WASM_OP_F64_CONVERT_U_I64:
  646. sign = (opcode == WASM_OP_F64_CONVERT_S_I64) ? true : false;
  647. if (!aot_compile_op_f64_convert_i64(comp_ctx, func_ctx, sign))
  648. return false;
  649. break;
  650. case WASM_OP_F64_PROMOTE_F32:
  651. if (!aot_compile_op_f64_promote_f32(comp_ctx, func_ctx))
  652. return false;
  653. break;
  654. case WASM_OP_I32_REINTERPRET_F32:
  655. if (!aot_compile_op_i32_reinterpret_f32(comp_ctx, func_ctx))
  656. return false;
  657. break;
  658. case WASM_OP_I64_REINTERPRET_F64:
  659. if (!aot_compile_op_i64_reinterpret_f64(comp_ctx, func_ctx))
  660. return false;
  661. break;
  662. case WASM_OP_F32_REINTERPRET_I32:
  663. if (!aot_compile_op_f32_reinterpret_i32(comp_ctx, func_ctx))
  664. return false;
  665. break;
  666. case WASM_OP_F64_REINTERPRET_I64:
  667. if (!aot_compile_op_f64_reinterpret_i64(comp_ctx, func_ctx))
  668. return false;
  669. break;
  670. case WASM_OP_I32_EXTEND8_S:
  671. if (!aot_compile_op_i32_extend_i32(comp_ctx, func_ctx, 8))
  672. return false;
  673. break;
  674. case WASM_OP_I32_EXTEND16_S:
  675. if (!aot_compile_op_i32_extend_i32(comp_ctx, func_ctx, 16))
  676. return false;
  677. break;
  678. case WASM_OP_I64_EXTEND8_S:
  679. if (!aot_compile_op_i64_extend_i64(comp_ctx, func_ctx, 8))
  680. return false;
  681. break;
  682. case WASM_OP_I64_EXTEND16_S:
  683. if (!aot_compile_op_i64_extend_i64(comp_ctx, func_ctx, 16))
  684. return false;
  685. break;
  686. case WASM_OP_I64_EXTEND32_S:
  687. if (!aot_compile_op_i64_extend_i64(comp_ctx, func_ctx, 32))
  688. return false;
  689. break;
  690. case WASM_OP_MISC_PREFIX:
  691. {
  692. uint32 opcode1;
  693. read_leb_uint32(frame_ip, frame_ip_end, opcode1);
  694. opcode = (uint32)opcode1;
  695. switch (opcode) {
  696. case WASM_OP_I32_TRUNC_SAT_S_F32:
  697. case WASM_OP_I32_TRUNC_SAT_U_F32:
  698. sign = (opcode == WASM_OP_I32_TRUNC_SAT_S_F32) ? true : false;
  699. if (!aot_compile_op_i32_trunc_f32(comp_ctx, func_ctx, sign, true))
  700. return false;
  701. break;
  702. case WASM_OP_I32_TRUNC_SAT_S_F64:
  703. case WASM_OP_I32_TRUNC_SAT_U_F64:
  704. sign = (opcode == WASM_OP_I32_TRUNC_SAT_S_F64) ? true : false;
  705. if (!aot_compile_op_i32_trunc_f64(comp_ctx, func_ctx, sign, true))
  706. return false;
  707. break;
  708. case WASM_OP_I64_TRUNC_SAT_S_F32:
  709. case WASM_OP_I64_TRUNC_SAT_U_F32:
  710. sign = (opcode == WASM_OP_I64_TRUNC_SAT_S_F32) ? true : false;
  711. if (!aot_compile_op_i64_trunc_f32(comp_ctx, func_ctx, sign, true))
  712. return false;
  713. break;
  714. case WASM_OP_I64_TRUNC_SAT_S_F64:
  715. case WASM_OP_I64_TRUNC_SAT_U_F64:
  716. sign = (opcode == WASM_OP_I64_TRUNC_SAT_S_F64) ? true : false;
  717. if (!aot_compile_op_i64_trunc_f64(comp_ctx, func_ctx, sign, true))
  718. return false;
  719. break;
  720. #if WASM_ENABLE_BULK_MEMORY != 0
  721. case WASM_OP_MEMORY_INIT:
  722. {
  723. uint32 seg_index;
  724. read_leb_uint32(frame_ip, frame_ip_end, seg_index);
  725. frame_ip ++;
  726. if (!aot_compile_op_memory_init(comp_ctx, func_ctx, seg_index))
  727. return false;
  728. break;
  729. }
  730. case WASM_OP_DATA_DROP:
  731. {
  732. uint32 seg_index;
  733. read_leb_uint32(frame_ip, frame_ip_end, seg_index);
  734. if (!aot_compile_op_data_drop(comp_ctx, func_ctx, seg_index))
  735. return false;
  736. break;
  737. }
  738. case WASM_OP_MEMORY_COPY:
  739. {
  740. frame_ip += 2;
  741. if (!aot_compile_op_memory_copy(comp_ctx, func_ctx))
  742. return false;
  743. break;
  744. }
  745. case WASM_OP_MEMORY_FILL:
  746. {
  747. frame_ip ++;
  748. if (!aot_compile_op_memory_fill(comp_ctx, func_ctx))
  749. return false;
  750. break;
  751. }
  752. #endif /* WASM_ENABLE_BULK_MEMORY */
  753. default:
  754. break;
  755. }
  756. break;
  757. }
  758. #if WASM_ENABLE_SHARED_MEMORY != 0
  759. case WASM_OP_ATOMIC_PREFIX:
  760. {
  761. uint8 bin_op, op_type;
  762. if (frame_ip < frame_ip_end) {
  763. opcode = *frame_ip++;
  764. }
  765. if (opcode != WASM_OP_ATOMIC_FENCE) {
  766. read_leb_uint32(frame_ip, frame_ip_end, align);
  767. read_leb_uint32(frame_ip, frame_ip_end, offset);
  768. }
  769. switch (opcode) {
  770. case WASM_OP_ATOMIC_WAIT32:
  771. if (!aot_compile_op_atomic_wait(comp_ctx, func_ctx, VALUE_TYPE_I32,
  772. align, offset, 4))
  773. return false;
  774. break;
  775. case WASM_OP_ATOMIC_WAIT64:
  776. if (!aot_compile_op_atomic_wait(comp_ctx, func_ctx, VALUE_TYPE_I64,
  777. align, offset, 8))
  778. return false;
  779. break;
  780. case WASM_OP_ATOMIC_NOTIFY:
  781. if (!aot_compiler_op_atomic_notify(comp_ctx, func_ctx, align,
  782. offset, bytes))
  783. return false;
  784. break;
  785. case WASM_OP_ATOMIC_I32_LOAD:
  786. bytes = 4;
  787. goto op_atomic_i32_load;
  788. case WASM_OP_ATOMIC_I32_LOAD8_U:
  789. bytes = 1;
  790. goto op_atomic_i32_load;
  791. case WASM_OP_ATOMIC_I32_LOAD16_U:
  792. bytes = 2;
  793. op_atomic_i32_load:
  794. if (!aot_compile_op_i32_load(comp_ctx, func_ctx, align,
  795. offset, bytes, sign, true))
  796. return false;
  797. break;
  798. case WASM_OP_ATOMIC_I64_LOAD:
  799. bytes = 8;
  800. goto op_atomic_i64_load;
  801. case WASM_OP_ATOMIC_I64_LOAD8_U:
  802. bytes = 1;
  803. goto op_atomic_i64_load;
  804. case WASM_OP_ATOMIC_I64_LOAD16_U:
  805. bytes = 2;
  806. goto op_atomic_i64_load;
  807. case WASM_OP_ATOMIC_I64_LOAD32_U:
  808. bytes = 4;
  809. op_atomic_i64_load:
  810. if (!aot_compile_op_i64_load(comp_ctx, func_ctx, align,
  811. offset, bytes, sign, true))
  812. return false;
  813. break;
  814. case WASM_OP_ATOMIC_I32_STORE:
  815. bytes = 4;
  816. goto op_atomic_i32_store;
  817. case WASM_OP_ATOMIC_I32_STORE8:
  818. bytes = 1;
  819. goto op_atomic_i32_store;
  820. case WASM_OP_ATOMIC_I32_STORE16:
  821. bytes = 2;
  822. op_atomic_i32_store:
  823. if (!aot_compile_op_i32_store(comp_ctx, func_ctx, align,
  824. offset, bytes, true))
  825. return false;
  826. break;
  827. case WASM_OP_ATOMIC_I64_STORE:
  828. bytes = 8;
  829. goto op_atomic_i64_store;
  830. case WASM_OP_ATOMIC_I64_STORE8:
  831. bytes = 1;
  832. goto op_atomic_i64_store;
  833. case WASM_OP_ATOMIC_I64_STORE16:
  834. bytes = 2;
  835. goto op_atomic_i64_store;
  836. case WASM_OP_ATOMIC_I64_STORE32:
  837. bytes = 4;
  838. op_atomic_i64_store:
  839. if (!aot_compile_op_i64_store(comp_ctx, func_ctx, align,
  840. offset, bytes, true))
  841. return false;
  842. break;
  843. case WASM_OP_ATOMIC_RMW_I32_CMPXCHG:
  844. bytes = 4;
  845. op_type = VALUE_TYPE_I32;
  846. goto op_atomic_cmpxchg;
  847. case WASM_OP_ATOMIC_RMW_I64_CMPXCHG:
  848. bytes = 8;
  849. op_type = VALUE_TYPE_I64;
  850. goto op_atomic_cmpxchg;
  851. case WASM_OP_ATOMIC_RMW_I32_CMPXCHG8_U:
  852. bytes = 1;
  853. op_type = VALUE_TYPE_I32;
  854. goto op_atomic_cmpxchg;
  855. case WASM_OP_ATOMIC_RMW_I32_CMPXCHG16_U:
  856. bytes = 2;
  857. op_type = VALUE_TYPE_I32;
  858. goto op_atomic_cmpxchg;
  859. case WASM_OP_ATOMIC_RMW_I64_CMPXCHG8_U:
  860. bytes = 1;
  861. op_type = VALUE_TYPE_I64;
  862. goto op_atomic_cmpxchg;
  863. case WASM_OP_ATOMIC_RMW_I64_CMPXCHG16_U:
  864. bytes = 2;
  865. op_type = VALUE_TYPE_I64;
  866. goto op_atomic_cmpxchg;
  867. case WASM_OP_ATOMIC_RMW_I64_CMPXCHG32_U:
  868. bytes = 4;
  869. op_type = VALUE_TYPE_I64;
  870. op_atomic_cmpxchg:
  871. if (!aot_compile_op_atomic_cmpxchg(comp_ctx, func_ctx,
  872. op_type, align,
  873. offset, bytes))
  874. return false;
  875. break;
  876. COMPILE_ATOMIC_RMW(Add, ADD);
  877. COMPILE_ATOMIC_RMW(Sub, SUB);
  878. COMPILE_ATOMIC_RMW(And, AND);
  879. COMPILE_ATOMIC_RMW(Or, OR);
  880. COMPILE_ATOMIC_RMW(Xor, XOR);
  881. COMPILE_ATOMIC_RMW(Xchg, XCHG);
  882. build_atomic_rmw:
  883. if (!aot_compile_op_atomic_rmw(comp_ctx, func_ctx,
  884. bin_op, op_type,
  885. align, offset, bytes))
  886. return false;
  887. break;
  888. default:
  889. break;
  890. }
  891. break;
  892. }
  893. #endif /* end of WASM_ENABLE_SHARED_MEMORY */
  894. default:
  895. break;
  896. }
  897. }
  898. /* Move func_return block to the bottom */
  899. if (func_ctx->func_return_block) {
  900. LLVMBasicBlockRef last_block =
  901. LLVMGetLastBasicBlock(func_ctx->func);
  902. if (last_block != func_ctx->func_return_block)
  903. LLVMMoveBasicBlockAfter(func_ctx->func_return_block,
  904. last_block);
  905. }
  906. /* Move got_exception block to the bottom */
  907. if (func_ctx->got_exception_block) {
  908. LLVMBasicBlockRef last_block =
  909. LLVMGetLastBasicBlock(func_ctx->func);
  910. if (last_block != func_ctx->got_exception_block)
  911. LLVMMoveBasicBlockAfter(func_ctx->got_exception_block,
  912. last_block);
  913. /* Move all other exception blocks before got_exception block */
  914. for (i = 0; i < EXCE_NUM; i++) {
  915. if (func_ctx->exception_blocks[i])
  916. LLVMMoveBasicBlockBefore(func_ctx->exception_blocks[i],
  917. func_ctx->got_exception_block);
  918. }
  919. }
  920. return true;
  921. fail:
  922. return false;
  923. }
  924. bool
  925. aot_compile_wasm(AOTCompContext *comp_ctx)
  926. {
  927. char *msg = NULL;
  928. bool ret;
  929. uint32 i;
  930. bh_print_time("Begin to compile WASM bytecode to LLVM IR");
  931. for (i = 0; i < comp_ctx->func_ctx_count; i++)
  932. if (!aot_compile_func(comp_ctx, i)) {
  933. #if 0
  934. LLVMDumpModule(comp_ctx->module);
  935. char *err;
  936. LLVMTargetMachineEmitToFile(comp_ctx->target_machine, comp_ctx->module,
  937. "./test.o", LLVMObjectFile, &err);
  938. #endif
  939. return false;
  940. }
  941. #if 0
  942. LLVMDumpModule(comp_ctx->module);
  943. /* Clear error no, LLVMDumpModule may set errno */
  944. errno = 0;
  945. #endif
  946. bh_print_time("Begin to verify LLVM module");
  947. ret = LLVMVerifyModule(comp_ctx->module, LLVMPrintMessageAction, &msg);
  948. if (!ret && msg) {
  949. if (msg[0] != '\0') {
  950. aot_set_last_error(msg);
  951. LLVMDisposeMessage(msg);
  952. return false;
  953. }
  954. LLVMDisposeMessage(msg);
  955. }
  956. bh_print_time("Begin to run function optimization passes");
  957. if (comp_ctx->optimize) {
  958. LLVMInitializeFunctionPassManager(comp_ctx->pass_mgr);
  959. for (i = 0; i < comp_ctx->func_ctx_count; i++)
  960. LLVMRunFunctionPassManager(comp_ctx->pass_mgr,
  961. comp_ctx->func_ctxes[i]->func);
  962. }
  963. return true;
  964. }
  965. bool
  966. aot_emit_llvm_file(AOTCompContext *comp_ctx, const char *file_name)
  967. {
  968. char *err = NULL;
  969. bh_print_time("Begin to emit LLVM IR file");
  970. if (LLVMPrintModuleToFile(comp_ctx->module, file_name, &err) != 0) {
  971. if (err) {
  972. LLVMDisposeMessage(err);
  973. err = NULL;
  974. }
  975. aot_set_last_error("emit llvm ir to file failed.");
  976. return false;
  977. }
  978. return true;
  979. }
  980. bool
  981. aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name)
  982. {
  983. char *err = NULL;
  984. bh_print_time("Begin to emit object file");
  985. if (LLVMTargetMachineEmitToFile(comp_ctx->target_machine,
  986. comp_ctx->module,
  987. file_name,
  988. LLVMObjectFile,
  989. &err) != 0) {
  990. if (err) {
  991. LLVMDisposeMessage(err);
  992. err = NULL;
  993. }
  994. aot_set_last_error("emit elf to memory buffer failed.");
  995. return false;
  996. }
  997. return true;
  998. }