jit_frontend.c 81 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248
  1. /*
  2. * Copyright (C) 2021 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "jit_compiler.h"
  6. #include "jit_frontend.h"
  7. #include "fe/jit_emit_compare.h"
  8. #include "fe/jit_emit_const.h"
  9. #include "fe/jit_emit_control.h"
  10. #include "fe/jit_emit_conversion.h"
  11. #include "fe/jit_emit_exception.h"
  12. #include "fe/jit_emit_function.h"
  13. #include "fe/jit_emit_memory.h"
  14. #include "fe/jit_emit_numberic.h"
  15. #include "fe/jit_emit_parametric.h"
  16. #include "fe/jit_emit_table.h"
  17. #include "fe/jit_emit_variable.h"
  18. #include "../interpreter/wasm_interp.h"
  19. #include "../interpreter/wasm_opcode.h"
  20. #include "../common/wasm_exec_env.h"
  21. /* clang-format off */
  22. static const char *jit_exception_msgs[] = {
  23. "unreachable", /* JIT_EXCE_UNREACHABLE */
  24. "allocate memory failed", /* JIT_EXCE_OUT_OF_MEMORY */
  25. "out of bounds memory access", /* JIT_EXCE_OUT_OF_BOUNDS_MEMORY_ACCESS */
  26. "integer overflow", /* JIT_EXCE_INTEGER_OVERFLOW */
  27. "integer divide by zero", /* JIT_EXCE_INTEGER_DIVIDE_BY_ZERO */
  28. "invalid conversion to integer", /* JIT_EXCE_INVALID_CONVERSION_TO_INTEGER */
  29. "indirect call type mismatch", /* JIT_EXCE_INVALID_FUNCTION_TYPE_INDEX */
  30. "invalid function index", /* JIT_EXCE_INVALID_FUNCTION_INDEX */
  31. "undefined element", /* JIT_EXCE_UNDEFINED_ELEMENT */
  32. "uninitialized element", /* JIT_EXCE_UNINITIALIZED_ELEMENT */
  33. "failed to call unlinked import function", /* JIT_EXCE_CALL_UNLINKED_IMPORT_FUNC */
  34. "native stack overflow", /* JIT_EXCE_NATIVE_STACK_OVERFLOW */
  35. "unaligned atomic", /* JIT_EXCE_UNALIGNED_ATOMIC */
  36. "wasm auxiliary stack overflow", /* JIT_EXCE_AUX_STACK_OVERFLOW */
  37. "wasm auxiliary stack underflow", /* JIT_EXCE_AUX_STACK_UNDERFLOW */
  38. "out of bounds table access", /* JIT_EXCE_OUT_OF_BOUNDS_TABLE_ACCESS */
  39. "wasm operand stack overflow", /* JIT_EXCE_OPERAND_STACK_OVERFLOW */
  40. "", /* JIT_EXCE_ALREADY_THROWN */
  41. };
  42. /* clang-format on */
  43. JitReg
  44. get_module_inst_reg(JitFrame *frame)
  45. {
  46. JitCompContext *cc = frame->cc;
  47. if (!frame->module_inst_reg) {
  48. frame->module_inst_reg = cc->module_inst_reg;
  49. GEN_INSN(LDPTR, frame->module_inst_reg, cc->exec_env_reg,
  50. NEW_CONST(I32, offsetof(WASMExecEnv, module_inst)));
  51. }
  52. return frame->module_inst_reg;
  53. }
  54. JitReg
  55. get_module_reg(JitFrame *frame)
  56. {
  57. JitCompContext *cc = frame->cc;
  58. JitReg module_inst_reg = get_module_inst_reg(frame);
  59. if (!frame->module_reg) {
  60. frame->module_reg = cc->module_reg;
  61. GEN_INSN(LDPTR, frame->module_reg, module_inst_reg,
  62. NEW_CONST(I32, offsetof(WASMModuleInstance, module)));
  63. }
  64. return frame->module_reg;
  65. }
  66. JitReg
  67. get_fast_jit_func_ptrs_reg(JitFrame *frame)
  68. {
  69. JitCompContext *cc = frame->cc;
  70. JitReg module_inst_reg = get_module_inst_reg(frame);
  71. if (!frame->fast_jit_func_ptrs_reg) {
  72. frame->fast_jit_func_ptrs_reg = cc->fast_jit_func_ptrs_reg;
  73. GEN_INSN(
  74. LDPTR, frame->fast_jit_func_ptrs_reg, module_inst_reg,
  75. NEW_CONST(I32, offsetof(WASMModuleInstance, fast_jit_func_ptrs)));
  76. }
  77. return frame->fast_jit_func_ptrs_reg;
  78. }
  79. JitReg
  80. get_global_data_reg(JitFrame *frame)
  81. {
  82. JitCompContext *cc = frame->cc;
  83. JitReg module_inst_reg = get_module_inst_reg(frame);
  84. if (!frame->global_data_reg) {
  85. frame->global_data_reg = cc->global_data_reg;
  86. GEN_INSN(LDPTR, frame->global_data_reg, module_inst_reg,
  87. NEW_CONST(I32, offsetof(WASMModuleInstance, global_data)));
  88. }
  89. return frame->global_data_reg;
  90. }
  91. JitReg
  92. get_aux_stack_bound_reg(JitFrame *frame)
  93. {
  94. JitCompContext *cc = frame->cc;
  95. if (!frame->aux_stack_bound_reg) {
  96. frame->aux_stack_bound_reg = cc->aux_stack_bound_reg;
  97. GEN_INSN(
  98. LDI32, frame->aux_stack_bound_reg, cc->exec_env_reg,
  99. NEW_CONST(I32, offsetof(WASMExecEnv, aux_stack_boundary.boundary)));
  100. }
  101. return frame->aux_stack_bound_reg;
  102. }
  103. JitReg
  104. get_aux_stack_bottom_reg(JitFrame *frame)
  105. {
  106. JitCompContext *cc = frame->cc;
  107. if (!frame->aux_stack_bottom_reg) {
  108. frame->aux_stack_bottom_reg = cc->aux_stack_bottom_reg;
  109. GEN_INSN(
  110. LDI32, frame->aux_stack_bottom_reg, cc->exec_env_reg,
  111. NEW_CONST(I32, offsetof(WASMExecEnv, aux_stack_bottom.bottom)));
  112. }
  113. return frame->aux_stack_bottom_reg;
  114. }
  115. JitReg
  116. get_memories_reg(JitFrame *frame)
  117. {
  118. JitCompContext *cc = frame->cc;
  119. JitReg module_inst_reg = get_module_inst_reg(frame);
  120. if (!frame->memories_reg) {
  121. frame->memories_reg = cc->memories_reg;
  122. GEN_INSN(LDPTR, frame->memories_reg, module_inst_reg,
  123. NEW_CONST(I32, offsetof(WASMModuleInstance, memories)));
  124. }
  125. return frame->memories_reg;
  126. }
  127. JitReg
  128. get_memory_inst_reg(JitFrame *frame, uint32 mem_idx)
  129. {
  130. JitCompContext *cc = frame->cc;
  131. JitReg memories_reg = get_memories_reg(frame);
  132. if (!frame->memory_regs[mem_idx].memory_inst) {
  133. frame->memory_regs[mem_idx].memory_inst =
  134. cc->memory_regs[mem_idx].memory_inst;
  135. GEN_INSN(
  136. LDPTR, frame->memory_regs[mem_idx].memory_inst, memories_reg,
  137. NEW_CONST(I32, (uint32)sizeof(WASMMemoryInstance *) * mem_idx));
  138. }
  139. return frame->memory_regs[mem_idx].memory_inst;
  140. }
  141. JitReg
  142. get_memory_data_reg(JitFrame *frame, uint32 mem_idx)
  143. {
  144. JitCompContext *cc = frame->cc;
  145. JitReg memory_inst_reg = get_memory_inst_reg(frame, mem_idx);
  146. if (!frame->memory_regs[mem_idx].memory_data) {
  147. frame->memory_regs[mem_idx].memory_data =
  148. cc->memory_regs[mem_idx].memory_data;
  149. GEN_INSN(LDPTR, frame->memory_regs[mem_idx].memory_data,
  150. memory_inst_reg,
  151. NEW_CONST(I32, offsetof(WASMMemoryInstance, memory_data)));
  152. }
  153. return frame->memory_regs[mem_idx].memory_data;
  154. }
  155. JitReg
  156. get_memory_data_end_reg(JitFrame *frame, uint32 mem_idx)
  157. {
  158. JitCompContext *cc = frame->cc;
  159. JitReg memory_inst_reg = get_memory_inst_reg(frame, mem_idx);
  160. if (!frame->memory_regs[mem_idx].memory_data_end) {
  161. frame->memory_regs[mem_idx].memory_data_end =
  162. cc->memory_regs[mem_idx].memory_data_end;
  163. GEN_INSN(LDPTR, frame->memory_regs[mem_idx].memory_data_end,
  164. memory_inst_reg,
  165. NEW_CONST(I32, offsetof(WASMMemoryInstance, memory_data_end)));
  166. }
  167. return frame->memory_regs[mem_idx].memory_data_end;
  168. }
  169. JitReg
  170. get_mem_bound_check_1byte_reg(JitFrame *frame, uint32 mem_idx)
  171. {
  172. JitCompContext *cc = frame->cc;
  173. JitReg memory_inst_reg = get_memory_inst_reg(frame, mem_idx);
  174. if (!frame->memory_regs[mem_idx].mem_bound_check_1byte) {
  175. frame->memory_regs[mem_idx].mem_bound_check_1byte =
  176. cc->memory_regs[mem_idx].mem_bound_check_1byte;
  177. #if UINTPTR_MAX == UINT64_MAX
  178. GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_1byte,
  179. memory_inst_reg,
  180. NEW_CONST(
  181. I32, offsetof(WASMMemoryInstance, mem_bound_check_1byte)));
  182. #else
  183. GEN_INSN(LDI32, frame->memory_regs[mem_idx].mem_bound_check_1byte,
  184. memory_inst_reg,
  185. NEW_CONST(
  186. I32, offsetof(WASMMemoryInstance, mem_bound_check_1byte)));
  187. #endif
  188. }
  189. return frame->memory_regs[mem_idx].mem_bound_check_1byte;
  190. }
  191. JitReg
  192. get_mem_bound_check_2bytes_reg(JitFrame *frame, uint32 mem_idx)
  193. {
  194. JitCompContext *cc = frame->cc;
  195. JitReg memory_inst_reg = get_memory_inst_reg(frame, mem_idx);
  196. if (!frame->memory_regs[mem_idx].mem_bound_check_2bytes) {
  197. frame->memory_regs[mem_idx].mem_bound_check_2bytes =
  198. cc->memory_regs[mem_idx].mem_bound_check_2bytes;
  199. #if UINTPTR_MAX == UINT64_MAX
  200. GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_2bytes,
  201. memory_inst_reg,
  202. NEW_CONST(I32, offsetof(WASMMemoryInstance,
  203. mem_bound_check_2bytes)));
  204. #else
  205. GEN_INSN(LDI32, frame->memory_regs[mem_idx].mem_bound_check_2bytes,
  206. memory_inst_reg,
  207. NEW_CONST(I32, offsetof(WASMMemoryInstance,
  208. mem_bound_check_2bytes)));
  209. #endif
  210. }
  211. return frame->memory_regs[mem_idx].mem_bound_check_2bytes;
  212. }
  213. JitReg
  214. get_mem_bound_check_4bytes_reg(JitFrame *frame, uint32 mem_idx)
  215. {
  216. JitCompContext *cc = frame->cc;
  217. JitReg memory_inst_reg = get_memory_inst_reg(frame, mem_idx);
  218. if (!frame->memory_regs[mem_idx].mem_bound_check_4bytes) {
  219. frame->memory_regs[mem_idx].mem_bound_check_4bytes =
  220. cc->memory_regs[mem_idx].mem_bound_check_4bytes;
  221. #if UINTPTR_MAX == UINT64_MAX
  222. GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_4bytes,
  223. memory_inst_reg,
  224. NEW_CONST(I32, offsetof(WASMMemoryInstance,
  225. mem_bound_check_4bytes)));
  226. #else
  227. GEN_INSN(LDI32, frame->memory_regs[mem_idx].mem_bound_check_4bytes,
  228. memory_inst_reg,
  229. NEW_CONST(I32, offsetof(WASMMemoryInstance,
  230. mem_bound_check_4bytes)));
  231. #endif
  232. }
  233. return frame->memory_regs[mem_idx].mem_bound_check_4bytes;
  234. }
  235. JitReg
  236. get_mem_bound_check_8bytes_reg(JitFrame *frame, uint32 mem_idx)
  237. {
  238. JitCompContext *cc = frame->cc;
  239. JitReg memory_inst_reg = get_memory_inst_reg(frame, mem_idx);
  240. if (!frame->memory_regs[mem_idx].mem_bound_check_8bytes) {
  241. frame->memory_regs[mem_idx].mem_bound_check_8bytes =
  242. cc->memory_regs[mem_idx].mem_bound_check_8bytes;
  243. #if UINTPTR_MAX == UINT64_MAX
  244. GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_8bytes,
  245. memory_inst_reg,
  246. NEW_CONST(I32, offsetof(WASMMemoryInstance,
  247. mem_bound_check_8bytes)));
  248. #else
  249. GEN_INSN(LDI32, frame->memory_regs[mem_idx].mem_bound_check_8bytes,
  250. memory_inst_reg,
  251. NEW_CONST(I32, offsetof(WASMMemoryInstance,
  252. mem_bound_check_8bytes)));
  253. #endif
  254. }
  255. return frame->memory_regs[mem_idx].mem_bound_check_8bytes;
  256. }
  257. JitReg
  258. get_mem_bound_check_16bytes_reg(JitFrame *frame, uint32 mem_idx)
  259. {
  260. JitCompContext *cc = frame->cc;
  261. JitReg memory_inst_reg = get_memory_inst_reg(frame, mem_idx);
  262. if (!frame->memory_regs[mem_idx].mem_bound_check_16bytes) {
  263. frame->memory_regs[mem_idx].mem_bound_check_16bytes =
  264. cc->memory_regs[mem_idx].mem_bound_check_16bytes;
  265. #if UINTPTR_MAX == UINT64_MAX
  266. GEN_INSN(LDI64, frame->memory_regs[mem_idx].mem_bound_check_16bytes,
  267. memory_inst_reg,
  268. NEW_CONST(I32, offsetof(WASMMemoryInstance,
  269. mem_bound_check_16bytes)));
  270. #else
  271. GEN_INSN(LDI32, frame->memory_regs[mem_idx].mem_bound_check_16bytes,
  272. memory_inst_reg,
  273. NEW_CONST(I32, offsetof(WASMMemoryInstance,
  274. mem_bound_check_16bytes)));
  275. #endif
  276. }
  277. return frame->memory_regs[mem_idx].mem_bound_check_16bytes;
  278. }
  279. JitReg
  280. get_tables_reg(JitFrame *frame)
  281. {
  282. JitCompContext *cc = frame->cc;
  283. JitReg inst_reg = get_module_inst_reg(frame);
  284. if (!frame->tables_reg) {
  285. frame->tables_reg = cc->tables_reg;
  286. GEN_INSN(LDPTR, frame->tables_reg, inst_reg,
  287. NEW_CONST(I32, offsetof(WASMModuleInstance, tables)));
  288. }
  289. return frame->tables_reg;
  290. }
  291. JitReg
  292. get_table_inst_reg(JitFrame *frame, uint32 tbl_idx)
  293. {
  294. JitCompContext *cc = frame->cc;
  295. JitReg tables_reg = get_tables_reg(frame);
  296. if (!frame->table_regs[tbl_idx].table_inst) {
  297. frame->table_regs[tbl_idx].table_inst =
  298. cc->table_regs[tbl_idx].table_inst;
  299. GEN_INSN(LDPTR, frame->table_regs[tbl_idx].table_inst, tables_reg,
  300. NEW_CONST(I32, sizeof(WASMTableInstance *) * tbl_idx));
  301. }
  302. return frame->table_regs[tbl_idx].table_inst;
  303. }
  304. JitReg
  305. get_table_data_reg(JitFrame *frame, uint32 tbl_idx)
  306. {
  307. JitCompContext *cc = frame->cc;
  308. JitReg table_reg = get_table_inst_reg(frame, tbl_idx);
  309. if (!frame->table_regs[tbl_idx].table_data) {
  310. frame->table_regs[tbl_idx].table_data =
  311. cc->table_regs[tbl_idx].table_data;
  312. GEN_INSN(ADD, frame->table_regs[tbl_idx].table_data, table_reg,
  313. NEW_CONST(I64, offsetof(WASMTableInstance, base_addr)));
  314. }
  315. return frame->table_regs[tbl_idx].table_data;
  316. }
  317. JitReg
  318. get_table_cur_size_reg(JitFrame *frame, uint32 tbl_idx)
  319. {
  320. JitCompContext *cc = frame->cc;
  321. JitReg table_reg = get_table_inst_reg(frame, tbl_idx);
  322. if (!frame->table_regs[tbl_idx].table_cur_size) {
  323. frame->table_regs[tbl_idx].table_cur_size =
  324. cc->table_regs[tbl_idx].table_cur_size;
  325. GEN_INSN(LDI32, frame->table_regs[tbl_idx].table_cur_size, table_reg,
  326. NEW_CONST(I32, offsetof(WASMTableInstance, cur_size)));
  327. }
  328. return frame->table_regs[tbl_idx].table_cur_size;
  329. }
  330. void
  331. clear_fixed_virtual_regs(JitFrame *frame)
  332. {
  333. WASMModule *module = frame->cc->cur_wasm_module;
  334. uint32 count, i;
  335. frame->module_inst_reg = 0;
  336. frame->module_reg = 0;
  337. frame->fast_jit_func_ptrs_reg = 0;
  338. frame->global_data_reg = 0;
  339. frame->aux_stack_bound_reg = 0;
  340. frame->aux_stack_bottom_reg = 0;
  341. frame->memories_reg = 0;
  342. frame->tables_reg = 0;
  343. count = module->import_memory_count + module->memory_count;
  344. for (i = 0; i < count; i++) {
  345. frame->memory_regs[i].memory_inst = 0;
  346. frame->memory_regs[i].memory_data = 0;
  347. frame->memory_regs[i].memory_data_end = 0;
  348. frame->memory_regs[i].mem_bound_check_1byte = 0;
  349. frame->memory_regs[i].mem_bound_check_2bytes = 0;
  350. frame->memory_regs[i].mem_bound_check_4bytes = 0;
  351. frame->memory_regs[i].mem_bound_check_8bytes = 0;
  352. frame->memory_regs[i].mem_bound_check_16bytes = 0;
  353. }
  354. count = module->import_table_count + module->table_count;
  355. for (i = 0; i < count; i++) {
  356. frame->table_regs[i].table_inst = 0;
  357. frame->table_regs[i].table_data = 0;
  358. frame->table_regs[i].table_cur_size = 0;
  359. }
  360. }
  361. void
  362. clear_memory_regs(JitFrame *frame)
  363. {
  364. WASMModule *module = frame->cc->cur_wasm_module;
  365. uint32 count, i;
  366. count = module->import_memory_count + module->memory_count;
  367. for (i = 0; i < count; i++) {
  368. frame->memory_regs[i].memory_data = 0;
  369. frame->memory_regs[i].memory_data_end = 0;
  370. frame->memory_regs[i].mem_bound_check_1byte = 0;
  371. frame->memory_regs[i].mem_bound_check_2bytes = 0;
  372. frame->memory_regs[i].mem_bound_check_4bytes = 0;
  373. frame->memory_regs[i].mem_bound_check_8bytes = 0;
  374. frame->memory_regs[i].mem_bound_check_16bytes = 0;
  375. }
  376. }
  377. void
  378. clear_table_regs(JitFrame *frame)
  379. {
  380. WASMModule *module = frame->cc->cur_wasm_module;
  381. uint32 count, i;
  382. count = module->import_table_count + module->table_count;
  383. for (i = 0; i < count; i++) {
  384. frame->table_regs[i].table_cur_size = 0;
  385. }
  386. }
  387. JitReg
  388. gen_load_i32(JitFrame *frame, unsigned n)
  389. {
  390. if (!frame->lp[n].reg) {
  391. JitCompContext *cc = frame->cc;
  392. frame->lp[n].reg = jit_cc_new_reg_I32(cc);
  393. GEN_INSN(LDI32, frame->lp[n].reg, cc->fp_reg,
  394. NEW_CONST(I32, offset_of_local(n)));
  395. }
  396. return frame->lp[n].reg;
  397. }
  398. JitReg
  399. gen_load_i64(JitFrame *frame, unsigned n)
  400. {
  401. if (!frame->lp[n].reg) {
  402. JitCompContext *cc = frame->cc;
  403. frame->lp[n].reg = frame->lp[n + 1].reg = jit_cc_new_reg_I64(cc);
  404. GEN_INSN(LDI64, frame->lp[n].reg, cc->fp_reg,
  405. NEW_CONST(I32, offset_of_local(n)));
  406. }
  407. return frame->lp[n].reg;
  408. }
  409. JitReg
  410. gen_load_f32(JitFrame *frame, unsigned n)
  411. {
  412. if (!frame->lp[n].reg) {
  413. JitCompContext *cc = frame->cc;
  414. frame->lp[n].reg = jit_cc_new_reg_F32(cc);
  415. GEN_INSN(LDF32, frame->lp[n].reg, cc->fp_reg,
  416. NEW_CONST(I32, offset_of_local(n)));
  417. }
  418. return frame->lp[n].reg;
  419. }
  420. JitReg
  421. gen_load_f64(JitFrame *frame, unsigned n)
  422. {
  423. if (!frame->lp[n].reg) {
  424. JitCompContext *cc = frame->cc;
  425. frame->lp[n].reg = frame->lp[n + 1].reg = jit_cc_new_reg_F64(cc);
  426. GEN_INSN(LDF64, frame->lp[n].reg, cc->fp_reg,
  427. NEW_CONST(I32, offset_of_local(n)));
  428. }
  429. return frame->lp[n].reg;
  430. }
  431. void
  432. gen_commit_values(JitFrame *frame, JitValueSlot *begin, JitValueSlot *end)
  433. {
  434. JitCompContext *cc = frame->cc;
  435. JitValueSlot *p;
  436. int n;
  437. for (p = begin; p < end; p++) {
  438. if (!p->dirty)
  439. continue;
  440. p->dirty = 0;
  441. n = p - frame->lp;
  442. switch (jit_reg_kind(p->reg)) {
  443. case JIT_REG_KIND_I32:
  444. GEN_INSN(STI32, p->reg, cc->fp_reg,
  445. NEW_CONST(I32, offset_of_local(n)));
  446. break;
  447. case JIT_REG_KIND_I64:
  448. GEN_INSN(STI64, p->reg, cc->fp_reg,
  449. NEW_CONST(I32, offset_of_local(n)));
  450. (++p)->dirty = 0;
  451. break;
  452. case JIT_REG_KIND_F32:
  453. GEN_INSN(STF32, p->reg, cc->fp_reg,
  454. NEW_CONST(I32, offset_of_local(n)));
  455. break;
  456. case JIT_REG_KIND_F64:
  457. GEN_INSN(STF64, p->reg, cc->fp_reg,
  458. NEW_CONST(I32, offset_of_local(n)));
  459. (++p)->dirty = 0;
  460. break;
  461. }
  462. }
  463. }
  464. /**
  465. * Generate instructions to commit SP and IP pointers to the frame.
  466. *
  467. * @param frame the frame information
  468. */
  469. void
  470. gen_commit_sp_ip(JitFrame *frame)
  471. {
  472. JitCompContext *cc = frame->cc;
  473. JitReg sp;
  474. if (frame->sp != frame->committed_sp) {
  475. sp = jit_cc_new_reg_ptr(cc);
  476. GEN_INSN(ADD, sp, cc->fp_reg,
  477. NEW_CONST(PTR, offset_of_local(frame->sp - frame->lp)));
  478. GEN_INSN(STPTR, sp, cc->fp_reg,
  479. NEW_CONST(I32, offsetof(WASMInterpFrame, sp)));
  480. frame->committed_sp = frame->sp;
  481. }
  482. #if 0 /* Disable committing ip currently */
  483. if (frame->ip != frame->committed_ip) {
  484. GEN_INSN(STPTR, NEW_CONST(PTR, (uintptr_t)frame->ip), cc->fp_reg,
  485. NEW_CONST(I32, offsetof(WASMInterpFrame, ip)));
  486. frame->committed_ip = frame->ip;
  487. }
  488. #endif
  489. }
  490. static void
  491. jit_set_exception_with_id(WASMModuleInstance *module_inst, uint32 id)
  492. {
  493. if (id < JIT_EXCE_NUM)
  494. wasm_set_exception(module_inst, jit_exception_msgs[id]);
  495. else
  496. wasm_set_exception(module_inst, "unknown exception");
  497. }
  498. static bool
  499. create_fixed_virtual_regs(JitCompContext *cc)
  500. {
  501. WASMModule *module = cc->cur_wasm_module;
  502. uint64 total_size;
  503. uint32 i, count;
  504. cc->module_inst_reg = jit_cc_new_reg_ptr(cc);
  505. cc->module_reg = jit_cc_new_reg_ptr(cc);
  506. cc->fast_jit_func_ptrs_reg = jit_cc_new_reg_ptr(cc);
  507. cc->global_data_reg = jit_cc_new_reg_ptr(cc);
  508. cc->aux_stack_bound_reg = jit_cc_new_reg_I32(cc);
  509. cc->aux_stack_bottom_reg = jit_cc_new_reg_I32(cc);
  510. cc->memories_reg = jit_cc_new_reg_ptr(cc);
  511. cc->tables_reg = jit_cc_new_reg_ptr(cc);
  512. count = module->import_memory_count + module->memory_count;
  513. if (count > 0) {
  514. total_size = (uint64)sizeof(JitMemRegs) * count;
  515. if (total_size > UINT32_MAX
  516. || !(cc->memory_regs = jit_calloc((uint32)total_size))) {
  517. jit_set_last_error(cc, "allocate memory failed");
  518. return false;
  519. }
  520. for (i = 0; i < count; i++) {
  521. cc->memory_regs[i].memory_inst = jit_cc_new_reg_ptr(cc);
  522. cc->memory_regs[i].memory_data = jit_cc_new_reg_ptr(cc);
  523. cc->memory_regs[i].memory_data_end = jit_cc_new_reg_ptr(cc);
  524. cc->memory_regs[i].mem_bound_check_1byte = jit_cc_new_reg_ptr(cc);
  525. cc->memory_regs[i].mem_bound_check_2bytes = jit_cc_new_reg_ptr(cc);
  526. cc->memory_regs[i].mem_bound_check_4bytes = jit_cc_new_reg_ptr(cc);
  527. cc->memory_regs[i].mem_bound_check_8bytes = jit_cc_new_reg_ptr(cc);
  528. cc->memory_regs[i].mem_bound_check_16bytes = jit_cc_new_reg_ptr(cc);
  529. }
  530. }
  531. count = module->import_table_count + module->table_count;
  532. if (count > 0) {
  533. total_size = (uint64)sizeof(JitTableRegs) * count;
  534. if (total_size > UINT32_MAX
  535. || !(cc->table_regs = jit_calloc((uint32)total_size))) {
  536. jit_set_last_error(cc, "allocate memory failed");
  537. return false;
  538. }
  539. for (i = 0; i < count; i++) {
  540. cc->table_regs[i].table_inst = jit_cc_new_reg_ptr(cc);
  541. cc->table_regs[i].table_data = jit_cc_new_reg_ptr(cc);
  542. cc->table_regs[i].table_cur_size = jit_cc_new_reg_I32(cc);
  543. }
  544. }
  545. return true;
  546. }
  547. static bool
  548. form_and_translate_func(JitCompContext *cc)
  549. {
  550. JitBasicBlock *func_entry_basic_block;
  551. JitReg func_entry_label;
  552. JitInsn *insn;
  553. JitIncomingInsn *incoming_insn, *incoming_insn_next;
  554. uint32 i;
  555. if (!create_fixed_virtual_regs(cc))
  556. return false;
  557. if (!(func_entry_basic_block = jit_frontend_translate_func(cc)))
  558. return false;
  559. jit_cc_reset_insn_hash(cc);
  560. /* The label of the func entry basic block. */
  561. func_entry_label = jit_basic_block_label(func_entry_basic_block);
  562. /* Create a JMP instruction jumping to the func entry. */
  563. if (!(insn = jit_cc_new_insn(cc, JMP, func_entry_label)))
  564. return false;
  565. /* Insert the instruction into the cc entry block. */
  566. jit_basic_block_append_insn(jit_cc_entry_basic_block(cc), insn);
  567. /* Patch INSNs jumping to exception basic blocks. */
  568. for (i = 0; i < JIT_EXCE_NUM; i++) {
  569. incoming_insn = cc->incoming_insns_for_exec_bbs[i];
  570. if (incoming_insn) {
  571. if (!(cc->exce_basic_blocks[i] = jit_cc_new_basic_block(cc, 0))) {
  572. jit_set_last_error(cc, "create basic block failed");
  573. return false;
  574. }
  575. while (incoming_insn) {
  576. incoming_insn_next = incoming_insn->next;
  577. insn = incoming_insn->insn;
  578. if (insn->opcode == JIT_OP_JMP) {
  579. *(jit_insn_opnd(insn, 0)) =
  580. jit_basic_block_label(cc->exce_basic_blocks[i]);
  581. }
  582. else if (insn->opcode >= JIT_OP_BEQ
  583. && insn->opcode <= JIT_OP_BLEU) {
  584. *(jit_insn_opnd(insn, 1)) =
  585. jit_basic_block_label(cc->exce_basic_blocks[i]);
  586. }
  587. incoming_insn = incoming_insn_next;
  588. }
  589. cc->cur_basic_block = cc->exce_basic_blocks[i];
  590. if (i != JIT_EXCE_ALREADY_THROWN) {
  591. JitReg module_inst_reg = jit_cc_new_reg_ptr(cc);
  592. GEN_INSN(LDPTR, module_inst_reg, cc->exec_env_reg,
  593. NEW_CONST(I32, offsetof(WASMExecEnv, module_inst)));
  594. insn = GEN_INSN(
  595. CALLNATIVE, 0,
  596. NEW_CONST(PTR, (uintptr_t)jit_set_exception_with_id), 2);
  597. if (insn) {
  598. *(jit_insn_opndv(insn, 2)) = module_inst_reg;
  599. *(jit_insn_opndv(insn, 3)) = NEW_CONST(I32, i);
  600. }
  601. }
  602. GEN_INSN(RETURN, NEW_CONST(I32, JIT_INTERP_ACTION_THROWN));
  603. *(jit_annl_begin_bcip(cc,
  604. jit_basic_block_label(cc->cur_basic_block))) =
  605. *(jit_annl_end_bcip(
  606. cc, jit_basic_block_label(cc->cur_basic_block))) =
  607. cc->cur_wasm_module->load_addr;
  608. }
  609. }
  610. *(jit_annl_begin_bcip(cc, cc->entry_label)) =
  611. *(jit_annl_end_bcip(cc, cc->entry_label)) =
  612. *(jit_annl_begin_bcip(cc, cc->exit_label)) =
  613. *(jit_annl_end_bcip(cc, cc->exit_label)) =
  614. cc->cur_wasm_module->load_addr;
  615. return true;
  616. }
  617. bool
  618. jit_pass_frontend(JitCompContext *cc)
  619. {
  620. /* Enable necessary annotations required at the current stage. */
  621. if (!jit_annl_enable_begin_bcip(cc) || !jit_annl_enable_end_bcip(cc)
  622. || !jit_annl_enable_end_sp(cc) || !jit_annr_enable_def_insn(cc)
  623. || !jit_cc_enable_insn_hash(cc, 127))
  624. return false;
  625. if (!(form_and_translate_func(cc)))
  626. return false;
  627. /* Release the annotations after local CSE and translation. */
  628. jit_cc_disable_insn_hash(cc);
  629. jit_annl_disable_end_sp(cc);
  630. return true;
  631. }
  632. static JitFrame *
  633. init_func_translation(JitCompContext *cc)
  634. {
  635. JitFrame *jit_frame;
  636. JitReg top, top_boundary, new_top, frame_boundary, frame_sp;
  637. WASMModule *cur_wasm_module = cc->cur_wasm_module;
  638. WASMFunction *cur_wasm_func = cc->cur_wasm_func;
  639. uint32 cur_wasm_func_idx = cc->cur_wasm_func_idx;
  640. uint32 max_locals =
  641. cur_wasm_func->param_cell_num + cur_wasm_func->local_cell_num;
  642. uint32 max_stacks = cur_wasm_func->max_stack_cell_num;
  643. uint64 total_cell_num =
  644. (uint64)cur_wasm_func->param_cell_num
  645. + (uint64)cur_wasm_func->local_cell_num
  646. + (uint64)cur_wasm_func->max_stack_cell_num
  647. + ((uint64)cur_wasm_func->max_block_num) * sizeof(WASMBranchBlock) / 4;
  648. uint32 frame_size, outs_size, local_size, count;
  649. uint32 i, local_off;
  650. uint64 total_size;
  651. if ((uint64)max_locals + (uint64)max_stacks >= UINT32_MAX
  652. || total_cell_num >= UINT32_MAX
  653. || !(jit_frame = jit_calloc(offsetof(JitFrame, lp)
  654. + sizeof(*jit_frame->lp)
  655. * (max_locals + max_stacks)))) {
  656. os_printf("allocate jit frame failed\n");
  657. return NULL;
  658. }
  659. count =
  660. cur_wasm_module->import_memory_count + cur_wasm_module->memory_count;
  661. if (count > 0) {
  662. total_size = (uint64)sizeof(JitMemRegs) * count;
  663. if (total_size > UINT32_MAX
  664. || !(jit_frame->memory_regs = jit_calloc((uint32)total_size))) {
  665. jit_set_last_error(cc, "allocate memory failed");
  666. jit_free(jit_frame);
  667. return NULL;
  668. }
  669. }
  670. count = cur_wasm_module->import_table_count + cur_wasm_module->table_count;
  671. if (count > 0) {
  672. total_size = (uint64)sizeof(JitTableRegs) * count;
  673. if (total_size > UINT32_MAX
  674. || !(jit_frame->table_regs = jit_calloc((uint32)total_size))) {
  675. jit_set_last_error(cc, "allocate memory failed");
  676. if (jit_frame->memory_regs)
  677. jit_free(jit_frame->memory_regs);
  678. jit_free(jit_frame);
  679. return NULL;
  680. }
  681. }
  682. jit_frame->cur_wasm_module = cur_wasm_module;
  683. jit_frame->cur_wasm_func = cur_wasm_func;
  684. jit_frame->cur_wasm_func_idx = cur_wasm_func_idx;
  685. jit_frame->cc = cc;
  686. jit_frame->max_locals = max_locals;
  687. jit_frame->max_stacks = max_stacks;
  688. jit_frame->sp = jit_frame->lp + max_locals;
  689. jit_frame->ip = cur_wasm_func->code;
  690. cc->jit_frame = jit_frame;
  691. cc->cur_basic_block = jit_cc_entry_basic_block(cc);
  692. cc->spill_cache_offset = wasm_interp_interp_frame_size(total_cell_num);
  693. /* Set spill cache size according to max local cell num, max stack cell
  694. num and virtual fixed register num */
  695. cc->spill_cache_size = (max_locals + max_stacks) * 4 + sizeof(void *) * 4;
  696. cc->total_frame_size = cc->spill_cache_offset + cc->spill_cache_size;
  697. cc->jitted_return_address_offset =
  698. offsetof(WASMInterpFrame, jitted_return_addr);
  699. cc->cur_basic_block = jit_cc_entry_basic_block(cc);
  700. frame_size = outs_size = cc->total_frame_size;
  701. local_size =
  702. (cur_wasm_func->param_cell_num + cur_wasm_func->local_cell_num) * 4;
  703. top = jit_cc_new_reg_ptr(cc);
  704. top_boundary = jit_cc_new_reg_ptr(cc);
  705. new_top = jit_cc_new_reg_ptr(cc);
  706. frame_boundary = jit_cc_new_reg_ptr(cc);
  707. frame_sp = jit_cc_new_reg_ptr(cc);
  708. /* top = exec_env->wasm_stack.s.top */
  709. GEN_INSN(LDPTR, top, cc->exec_env_reg,
  710. NEW_CONST(I32, offsetof(WASMExecEnv, wasm_stack.s.top)));
  711. /* top_boundary = exec_env->wasm_stack.s.top_boundary */
  712. GEN_INSN(LDPTR, top_boundary, cc->exec_env_reg,
  713. NEW_CONST(I32, offsetof(WASMExecEnv, wasm_stack.s.top_boundary)));
  714. /* frame_boundary = top + frame_size + outs_size */
  715. GEN_INSN(ADD, frame_boundary, top, NEW_CONST(PTR, frame_size + outs_size));
  716. /* if frame_boundary > top_boundary, throw stack overflow exception */
  717. GEN_INSN(CMP, cc->cmp_reg, frame_boundary, top_boundary);
  718. if (!jit_emit_exception(cc, JIT_EXCE_OPERAND_STACK_OVERFLOW, JIT_OP_BGTU,
  719. cc->cmp_reg, NULL)) {
  720. return NULL;
  721. }
  722. /* Add first and then sub to reduce one used register */
  723. /* new_top = frame_boundary - outs_size = top + frame_size */
  724. GEN_INSN(SUB, new_top, frame_boundary, NEW_CONST(PTR, outs_size));
  725. /* exec_env->wasm_stack.s.top = new_top */
  726. GEN_INSN(STPTR, new_top, cc->exec_env_reg,
  727. NEW_CONST(I32, offsetof(WASMExecEnv, wasm_stack.s.top)));
  728. /* frame_sp = frame->lp + local_size */
  729. GEN_INSN(ADD, frame_sp, top,
  730. NEW_CONST(PTR, offsetof(WASMInterpFrame, lp) + local_size));
  731. /* frame->sp = frame_sp */
  732. GEN_INSN(STPTR, frame_sp, top,
  733. NEW_CONST(I32, offsetof(WASMInterpFrame, sp)));
  734. /* frame->prev_frame = fp_reg */
  735. GEN_INSN(STPTR, cc->fp_reg, top,
  736. NEW_CONST(I32, offsetof(WASMInterpFrame, prev_frame)));
  737. /* TODO: do we need to set frame->function? */
  738. /*
  739. GEN_INSN(STPTR, func_inst, top,
  740. NEW_CONST(I32, offsetof(WASMInterpFrame, function)));
  741. */
  742. /* exec_env->cur_frame = top */
  743. GEN_INSN(STPTR, top, cc->exec_env_reg,
  744. NEW_CONST(I32, offsetof(WASMExecEnv, cur_frame)));
  745. /* fp_reg = top */
  746. GEN_INSN(MOV, cc->fp_reg, top);
  747. /* Initialize local variables, set them to 0 */
  748. local_off = (uint32)offsetof(WASMInterpFrame, lp)
  749. + cur_wasm_func->param_cell_num * 4;
  750. for (i = 0; i < cur_wasm_func->local_cell_num / 2; i++, local_off += 8) {
  751. GEN_INSN(STI64, NEW_CONST(I64, 0), cc->fp_reg,
  752. NEW_CONST(I32, local_off));
  753. }
  754. if (cur_wasm_func->local_cell_num & 1) {
  755. GEN_INSN(STI32, NEW_CONST(I32, 0), cc->fp_reg,
  756. NEW_CONST(I32, local_off));
  757. }
  758. return jit_frame;
  759. }
  760. static void
  761. free_block_memory(JitBlock *block)
  762. {
  763. if (block->param_types)
  764. jit_free(block->param_types);
  765. if (block->result_types)
  766. jit_free(block->result_types);
  767. jit_free(block);
  768. }
  769. static JitBasicBlock *
  770. create_func_block(JitCompContext *cc)
  771. {
  772. JitBlock *jit_block;
  773. WASMFunction *cur_func = cc->cur_wasm_func;
  774. WASMType *func_type = cur_func->func_type;
  775. uint32 param_count = func_type->param_count;
  776. uint32 result_count = func_type->result_count;
  777. if (!(jit_block = jit_calloc(sizeof(JitBlock)))) {
  778. return NULL;
  779. }
  780. if (param_count && !(jit_block->param_types = jit_calloc(param_count))) {
  781. goto fail;
  782. }
  783. if (result_count && !(jit_block->result_types = jit_calloc(result_count))) {
  784. goto fail;
  785. }
  786. /* Set block data */
  787. jit_block->label_type = LABEL_TYPE_FUNCTION;
  788. jit_block->param_count = param_count;
  789. if (param_count) {
  790. bh_memcpy_s(jit_block->param_types, param_count, func_type->types,
  791. param_count);
  792. }
  793. jit_block->result_count = result_count;
  794. if (result_count) {
  795. bh_memcpy_s(jit_block->result_types, result_count,
  796. func_type->types + param_count, result_count);
  797. }
  798. jit_block->wasm_code_end = cur_func->code + cur_func->code_size;
  799. jit_block->frame_sp_begin = cc->jit_frame->sp;
  800. /* Add function entry block */
  801. if (!(jit_block->basic_block_entry = jit_cc_new_basic_block(cc, 0))) {
  802. goto fail;
  803. }
  804. *(jit_annl_begin_bcip(
  805. cc, jit_basic_block_label(jit_block->basic_block_entry))) =
  806. cur_func->code;
  807. jit_block_stack_push(&cc->block_stack, jit_block);
  808. cc->cur_basic_block = jit_block->basic_block_entry;
  809. return jit_block->basic_block_entry;
  810. fail:
  811. free_block_memory(jit_block);
  812. return NULL;
  813. }
  814. #define CHECK_BUF(buf, buf_end, length) \
  815. do { \
  816. if (buf + length > buf_end) { \
  817. jit_set_last_error(cc, "read leb failed: unexpected end."); \
  818. return false; \
  819. } \
  820. } while (0)
  821. static bool
  822. read_leb(JitCompContext *cc, const uint8 *buf, const uint8 *buf_end,
  823. uint32 *p_offset, uint32 maxbits, bool sign, uint64 *p_result)
  824. {
  825. uint64 result = 0;
  826. uint32 shift = 0;
  827. uint32 bcnt = 0;
  828. uint64 byte;
  829. while (true) {
  830. CHECK_BUF(buf, buf_end, 1);
  831. byte = buf[*p_offset];
  832. *p_offset += 1;
  833. result |= ((byte & 0x7f) << shift);
  834. shift += 7;
  835. if ((byte & 0x80) == 0) {
  836. break;
  837. }
  838. bcnt += 1;
  839. }
  840. if (bcnt > (maxbits + 6) / 7) {
  841. jit_set_last_error(cc, "read leb failed: "
  842. "integer representation too long");
  843. return false;
  844. }
  845. if (sign && (shift < maxbits) && (byte & 0x40)) {
  846. /* Sign extend */
  847. result |= (~((uint64)0)) << shift;
  848. }
  849. *p_result = result;
  850. return true;
  851. }
  852. #define read_leb_uint32(p, p_end, res) \
  853. do { \
  854. uint32 off = 0; \
  855. uint64 res64; \
  856. if (!read_leb(cc, p, p_end, &off, 32, false, &res64)) \
  857. return false; \
  858. p += off; \
  859. res = (uint32)res64; \
  860. } while (0)
  861. #define read_leb_int32(p, p_end, res) \
  862. do { \
  863. uint32 off = 0; \
  864. uint64 res64; \
  865. if (!read_leb(cc, p, p_end, &off, 32, true, &res64)) \
  866. return false; \
  867. p += off; \
  868. res = (int32)res64; \
  869. } while (0)
  870. #define read_leb_int64(p, p_end, res) \
  871. do { \
  872. uint32 off = 0; \
  873. uint64 res64; \
  874. if (!read_leb(cc, p, p_end, &off, 64, true, &res64)) \
  875. return false; \
  876. p += off; \
  877. res = (int64)res64; \
  878. } while (0)
  879. static bool
  880. jit_compile_func(JitCompContext *cc)
  881. {
  882. WASMFunction *cur_func = cc->cur_wasm_func;
  883. WASMType *func_type = NULL;
  884. uint8 *frame_ip = cur_func->code, opcode, *p_f32, *p_f64;
  885. uint8 *frame_ip_end = frame_ip + cur_func->code_size;
  886. uint8 *param_types = NULL, *result_types = NULL, value_type;
  887. uint16 param_count, result_count;
  888. uint32 br_depth, *br_depths, br_count;
  889. uint32 func_idx, type_idx, mem_idx, local_idx, global_idx, i;
  890. uint32 bytes = 4, align, offset;
  891. bool merge_cmp_and_if = false, merge_cmp_and_br_if = false;
  892. bool sign = true;
  893. int32 i32_const;
  894. int64 i64_const;
  895. float32 f32_const;
  896. float64 f64_const;
  897. while (frame_ip < frame_ip_end) {
  898. cc->jit_frame->ip = frame_ip;
  899. opcode = *frame_ip++;
  900. #if 0 /* TODO */
  901. #if WASM_ENABLE_THREAD_MGR != 0
  902. /* Insert suspend check point */
  903. if (cc->enable_thread_mgr) {
  904. if (!check_suspend_flags(cc, func_ctx))
  905. return false;
  906. }
  907. #endif
  908. #endif
  909. switch (opcode) {
  910. case WASM_OP_UNREACHABLE:
  911. if (!jit_compile_op_unreachable(cc, &frame_ip))
  912. return false;
  913. break;
  914. case WASM_OP_NOP:
  915. break;
  916. case WASM_OP_BLOCK:
  917. case WASM_OP_LOOP:
  918. case WASM_OP_IF:
  919. {
  920. value_type = *frame_ip++;
  921. if (value_type == VALUE_TYPE_I32 || value_type == VALUE_TYPE_I64
  922. || value_type == VALUE_TYPE_F32
  923. || value_type == VALUE_TYPE_F64
  924. || value_type == VALUE_TYPE_V128
  925. || value_type == VALUE_TYPE_VOID
  926. || value_type == VALUE_TYPE_FUNCREF
  927. || value_type == VALUE_TYPE_EXTERNREF) {
  928. param_count = 0;
  929. param_types = NULL;
  930. if (value_type == VALUE_TYPE_VOID) {
  931. result_count = 0;
  932. result_types = NULL;
  933. }
  934. else {
  935. result_count = 1;
  936. result_types = &value_type;
  937. }
  938. }
  939. else {
  940. jit_set_last_error(cc, "unsupported value type");
  941. return false;
  942. }
  943. if (!jit_compile_op_block(
  944. cc, &frame_ip, frame_ip_end,
  945. (uint32)(LABEL_TYPE_BLOCK + opcode - WASM_OP_BLOCK),
  946. param_count, param_types, result_count, result_types,
  947. merge_cmp_and_if))
  948. return false;
  949. /* Clear flag */
  950. merge_cmp_and_if = false;
  951. break;
  952. }
  953. case EXT_OP_BLOCK:
  954. case EXT_OP_LOOP:
  955. case EXT_OP_IF:
  956. {
  957. read_leb_uint32(frame_ip, frame_ip_end, type_idx);
  958. func_type = cc->cur_wasm_module->types[type_idx];
  959. param_count = func_type->param_count;
  960. param_types = func_type->types;
  961. result_count = func_type->result_count;
  962. result_types = func_type->types + param_count;
  963. if (!jit_compile_op_block(
  964. cc, &frame_ip, frame_ip_end,
  965. (uint32)(LABEL_TYPE_BLOCK + opcode - EXT_OP_BLOCK),
  966. param_count, param_types, result_count, result_types,
  967. merge_cmp_and_if))
  968. return false;
  969. /* Clear flag */
  970. merge_cmp_and_if = false;
  971. break;
  972. }
  973. case WASM_OP_ELSE:
  974. if (!jit_compile_op_else(cc, &frame_ip))
  975. return false;
  976. break;
  977. case WASM_OP_END:
  978. if (!jit_compile_op_end(cc, &frame_ip))
  979. return false;
  980. break;
  981. case WASM_OP_BR:
  982. read_leb_uint32(frame_ip, frame_ip_end, br_depth);
  983. if (!jit_compile_op_br(cc, br_depth, &frame_ip))
  984. return false;
  985. break;
  986. case WASM_OP_BR_IF:
  987. read_leb_uint32(frame_ip, frame_ip_end, br_depth);
  988. if (!jit_compile_op_br_if(cc, br_depth, merge_cmp_and_br_if,
  989. &frame_ip))
  990. return false;
  991. /* Clear flag */
  992. merge_cmp_and_br_if = false;
  993. break;
  994. case WASM_OP_BR_TABLE:
  995. read_leb_uint32(frame_ip, frame_ip_end, br_count);
  996. if (!(br_depths = jit_calloc((uint32)sizeof(uint32)
  997. * (br_count + 1)))) {
  998. jit_set_last_error(cc, "allocate memory failed.");
  999. goto fail;
  1000. }
  1001. #if WASM_ENABLE_FAST_INTERP != 0
  1002. for (i = 0; i <= br_count; i++)
  1003. read_leb_uint32(frame_ip, frame_ip_end, br_depths[i]);
  1004. #else
  1005. for (i = 0; i <= br_count; i++)
  1006. br_depths[i] = *frame_ip++;
  1007. #endif
  1008. if (!jit_compile_op_br_table(cc, br_depths, br_count,
  1009. &frame_ip)) {
  1010. jit_free(br_depths);
  1011. return false;
  1012. }
  1013. jit_free(br_depths);
  1014. break;
  1015. #if WASM_ENABLE_FAST_INTERP == 0
  1016. case EXT_OP_BR_TABLE_CACHE:
  1017. {
  1018. BrTableCache *node = bh_list_first_elem(
  1019. cc->cur_wasm_module->br_table_cache_list);
  1020. BrTableCache *node_next;
  1021. uint8 *p_opcode = frame_ip - 1;
  1022. read_leb_uint32(frame_ip, frame_ip_end, br_count);
  1023. while (node) {
  1024. node_next = bh_list_elem_next(node);
  1025. if (node->br_table_op_addr == p_opcode) {
  1026. br_depths = node->br_depths;
  1027. if (!jit_compile_op_br_table(cc, br_depths, br_count,
  1028. &frame_ip)) {
  1029. return false;
  1030. }
  1031. break;
  1032. }
  1033. node = node_next;
  1034. }
  1035. bh_assert(node);
  1036. break;
  1037. }
  1038. #endif
  1039. case WASM_OP_RETURN:
  1040. if (!jit_compile_op_return(cc, &frame_ip))
  1041. return false;
  1042. break;
  1043. case WASM_OP_CALL:
  1044. read_leb_uint32(frame_ip, frame_ip_end, func_idx);
  1045. if (!jit_compile_op_call(cc, func_idx, false))
  1046. return false;
  1047. break;
  1048. case WASM_OP_CALL_INDIRECT:
  1049. {
  1050. uint32 tbl_idx;
  1051. read_leb_uint32(frame_ip, frame_ip_end, type_idx);
  1052. #if WASM_ENABLE_REF_TYPES != 0
  1053. read_leb_uint32(frame_ip, frame_ip_end, tbl_idx);
  1054. #else
  1055. frame_ip++;
  1056. tbl_idx = 0;
  1057. #endif
  1058. if (!jit_compile_op_call_indirect(cc, type_idx, tbl_idx))
  1059. return false;
  1060. break;
  1061. }
  1062. #if WASM_ENABLE_TAIL_CALL != 0
  1063. case WASM_OP_RETURN_CALL:
  1064. if (!cc->enable_tail_call) {
  1065. jit_set_last_error(cc, "unsupported opcode");
  1066. return false;
  1067. }
  1068. read_leb_uint32(frame_ip, frame_ip_end, func_idx);
  1069. if (!jit_compile_op_call(cc, func_idx, true))
  1070. return false;
  1071. if (!jit_compile_op_return(cc, &frame_ip))
  1072. return false;
  1073. break;
  1074. case WASM_OP_RETURN_CALL_INDIRECT:
  1075. {
  1076. uint32 tbl_idx;
  1077. if (!cc->enable_tail_call) {
  1078. jit_set_last_error(cc, "unsupported opcode");
  1079. return false;
  1080. }
  1081. read_leb_uint32(frame_ip, frame_ip_end, type_idx);
  1082. #if WASM_ENABLE_REF_TYPES != 0
  1083. read_leb_uint32(frame_ip, frame_ip_end, tbl_idx);
  1084. #else
  1085. frame_ip++;
  1086. tbl_idx = 0;
  1087. #endif
  1088. if (!jit_compile_op_call_indirect(cc, type_idx, tbl_idx))
  1089. return false;
  1090. if (!jit_compile_op_return(cc, &frame_ip))
  1091. return false;
  1092. break;
  1093. }
  1094. #endif /* end of WASM_ENABLE_TAIL_CALL */
  1095. case WASM_OP_DROP:
  1096. if (!jit_compile_op_drop(cc, true))
  1097. return false;
  1098. break;
  1099. case WASM_OP_DROP_64:
  1100. if (!jit_compile_op_drop(cc, false))
  1101. return false;
  1102. break;
  1103. case WASM_OP_SELECT:
  1104. if (!jit_compile_op_select(cc, true))
  1105. return false;
  1106. break;
  1107. case WASM_OP_SELECT_64:
  1108. if (!jit_compile_op_select(cc, false))
  1109. return false;
  1110. break;
  1111. #if WASM_ENABLE_REF_TYPES != 0
  1112. case WASM_OP_SELECT_T:
  1113. {
  1114. uint32 vec_len;
  1115. read_leb_uint32(frame_ip, frame_ip_end, vec_len);
  1116. bh_assert(vec_len == 1);
  1117. (void)vec_len;
  1118. type_idx = *frame_ip++;
  1119. if (!jit_compile_op_select(cc,
  1120. (type_idx != VALUE_TYPE_I64)
  1121. && (type_idx != VALUE_TYPE_F64)))
  1122. return false;
  1123. break;
  1124. }
  1125. case WASM_OP_TABLE_GET:
  1126. {
  1127. uint32 tbl_idx;
  1128. read_leb_uint32(frame_ip, frame_ip_end, tbl_idx);
  1129. if (!jit_compile_op_table_get(cc, tbl_idx))
  1130. return false;
  1131. break;
  1132. }
  1133. case WASM_OP_TABLE_SET:
  1134. {
  1135. uint32 tbl_idx;
  1136. read_leb_uint32(frame_ip, frame_ip_end, tbl_idx);
  1137. if (!jit_compile_op_table_set(cc, tbl_idx))
  1138. return false;
  1139. break;
  1140. }
  1141. case WASM_OP_REF_NULL:
  1142. {
  1143. uint32 ref_type;
  1144. read_leb_uint32(frame_ip, frame_ip_end, ref_type);
  1145. if (!jit_compile_op_ref_null(cc, ref_type))
  1146. return false;
  1147. break;
  1148. }
  1149. case WASM_OP_REF_IS_NULL:
  1150. {
  1151. if (!jit_compile_op_ref_is_null(cc))
  1152. return false;
  1153. break;
  1154. }
  1155. case WASM_OP_REF_FUNC:
  1156. {
  1157. read_leb_uint32(frame_ip, frame_ip_end, func_idx);
  1158. if (!jit_compile_op_ref_func(cc, func_idx))
  1159. return false;
  1160. break;
  1161. }
  1162. #endif
  1163. case WASM_OP_GET_LOCAL:
  1164. read_leb_uint32(frame_ip, frame_ip_end, local_idx);
  1165. if (!jit_compile_op_get_local(cc, local_idx))
  1166. return false;
  1167. break;
  1168. case WASM_OP_SET_LOCAL:
  1169. read_leb_uint32(frame_ip, frame_ip_end, local_idx);
  1170. if (!jit_compile_op_set_local(cc, local_idx))
  1171. return false;
  1172. break;
  1173. case WASM_OP_TEE_LOCAL:
  1174. read_leb_uint32(frame_ip, frame_ip_end, local_idx);
  1175. if (!jit_compile_op_tee_local(cc, local_idx))
  1176. return false;
  1177. break;
  1178. case WASM_OP_GET_GLOBAL:
  1179. case WASM_OP_GET_GLOBAL_64:
  1180. read_leb_uint32(frame_ip, frame_ip_end, global_idx);
  1181. if (!jit_compile_op_get_global(cc, global_idx))
  1182. return false;
  1183. break;
  1184. case WASM_OP_SET_GLOBAL:
  1185. case WASM_OP_SET_GLOBAL_64:
  1186. case WASM_OP_SET_GLOBAL_AUX_STACK:
  1187. read_leb_uint32(frame_ip, frame_ip_end, global_idx);
  1188. if (!jit_compile_op_set_global(
  1189. cc, global_idx,
  1190. opcode == WASM_OP_SET_GLOBAL_AUX_STACK ? true : false))
  1191. return false;
  1192. break;
  1193. case WASM_OP_I32_LOAD:
  1194. bytes = 4;
  1195. sign = true;
  1196. goto op_i32_load;
  1197. case WASM_OP_I32_LOAD8_S:
  1198. case WASM_OP_I32_LOAD8_U:
  1199. bytes = 1;
  1200. sign = (opcode == WASM_OP_I32_LOAD8_S) ? true : false;
  1201. goto op_i32_load;
  1202. case WASM_OP_I32_LOAD16_S:
  1203. case WASM_OP_I32_LOAD16_U:
  1204. bytes = 2;
  1205. sign = (opcode == WASM_OP_I32_LOAD16_S) ? true : false;
  1206. op_i32_load:
  1207. read_leb_uint32(frame_ip, frame_ip_end, align);
  1208. read_leb_uint32(frame_ip, frame_ip_end, offset);
  1209. if (!jit_compile_op_i32_load(cc, align, offset, bytes, sign,
  1210. false))
  1211. return false;
  1212. break;
  1213. case WASM_OP_I64_LOAD:
  1214. bytes = 8;
  1215. sign = true;
  1216. goto op_i64_load;
  1217. case WASM_OP_I64_LOAD8_S:
  1218. case WASM_OP_I64_LOAD8_U:
  1219. bytes = 1;
  1220. sign = (opcode == WASM_OP_I64_LOAD8_S) ? true : false;
  1221. goto op_i64_load;
  1222. case WASM_OP_I64_LOAD16_S:
  1223. case WASM_OP_I64_LOAD16_U:
  1224. bytes = 2;
  1225. sign = (opcode == WASM_OP_I64_LOAD16_S) ? true : false;
  1226. goto op_i64_load;
  1227. case WASM_OP_I64_LOAD32_S:
  1228. case WASM_OP_I64_LOAD32_U:
  1229. bytes = 4;
  1230. sign = (opcode == WASM_OP_I64_LOAD32_S) ? true : false;
  1231. op_i64_load:
  1232. read_leb_uint32(frame_ip, frame_ip_end, align);
  1233. read_leb_uint32(frame_ip, frame_ip_end, offset);
  1234. if (!jit_compile_op_i64_load(cc, align, offset, bytes, sign,
  1235. false))
  1236. return false;
  1237. break;
  1238. case WASM_OP_F32_LOAD:
  1239. read_leb_uint32(frame_ip, frame_ip_end, align);
  1240. read_leb_uint32(frame_ip, frame_ip_end, offset);
  1241. if (!jit_compile_op_f32_load(cc, align, offset))
  1242. return false;
  1243. break;
  1244. case WASM_OP_F64_LOAD:
  1245. read_leb_uint32(frame_ip, frame_ip_end, align);
  1246. read_leb_uint32(frame_ip, frame_ip_end, offset);
  1247. if (!jit_compile_op_f64_load(cc, align, offset))
  1248. return false;
  1249. break;
  1250. case WASM_OP_I32_STORE:
  1251. bytes = 4;
  1252. goto op_i32_store;
  1253. case WASM_OP_I32_STORE8:
  1254. bytes = 1;
  1255. goto op_i32_store;
  1256. case WASM_OP_I32_STORE16:
  1257. bytes = 2;
  1258. op_i32_store:
  1259. read_leb_uint32(frame_ip, frame_ip_end, align);
  1260. read_leb_uint32(frame_ip, frame_ip_end, offset);
  1261. if (!jit_compile_op_i32_store(cc, align, offset, bytes, false))
  1262. return false;
  1263. break;
  1264. case WASM_OP_I64_STORE:
  1265. bytes = 8;
  1266. goto op_i64_store;
  1267. case WASM_OP_I64_STORE8:
  1268. bytes = 1;
  1269. goto op_i64_store;
  1270. case WASM_OP_I64_STORE16:
  1271. bytes = 2;
  1272. goto op_i64_store;
  1273. case WASM_OP_I64_STORE32:
  1274. bytes = 4;
  1275. op_i64_store:
  1276. read_leb_uint32(frame_ip, frame_ip_end, align);
  1277. read_leb_uint32(frame_ip, frame_ip_end, offset);
  1278. if (!jit_compile_op_i64_store(cc, align, offset, bytes, false))
  1279. return false;
  1280. break;
  1281. case WASM_OP_F32_STORE:
  1282. read_leb_uint32(frame_ip, frame_ip_end, align);
  1283. read_leb_uint32(frame_ip, frame_ip_end, offset);
  1284. if (!jit_compile_op_f32_store(cc, align, offset))
  1285. return false;
  1286. break;
  1287. case WASM_OP_F64_STORE:
  1288. read_leb_uint32(frame_ip, frame_ip_end, align);
  1289. read_leb_uint32(frame_ip, frame_ip_end, offset);
  1290. if (!jit_compile_op_f64_store(cc, align, offset))
  1291. return false;
  1292. break;
  1293. case WASM_OP_MEMORY_SIZE:
  1294. read_leb_uint32(frame_ip, frame_ip_end, mem_idx);
  1295. if (!jit_compile_op_memory_size(cc, mem_idx))
  1296. return false;
  1297. break;
  1298. case WASM_OP_MEMORY_GROW:
  1299. read_leb_uint32(frame_ip, frame_ip_end, mem_idx);
  1300. if (!jit_compile_op_memory_grow(cc, mem_idx))
  1301. return false;
  1302. break;
  1303. case WASM_OP_I32_CONST:
  1304. read_leb_int32(frame_ip, frame_ip_end, i32_const);
  1305. if (!jit_compile_op_i32_const(cc, i32_const))
  1306. return false;
  1307. break;
  1308. case WASM_OP_I64_CONST:
  1309. read_leb_int64(frame_ip, frame_ip_end, i64_const);
  1310. if (!jit_compile_op_i64_const(cc, i64_const))
  1311. return false;
  1312. break;
  1313. case WASM_OP_F32_CONST:
  1314. p_f32 = (uint8 *)&f32_const;
  1315. for (i = 0; i < sizeof(float32); i++)
  1316. *p_f32++ = *frame_ip++;
  1317. if (!jit_compile_op_f32_const(cc, f32_const))
  1318. return false;
  1319. break;
  1320. case WASM_OP_F64_CONST:
  1321. p_f64 = (uint8 *)&f64_const;
  1322. for (i = 0; i < sizeof(float64); i++)
  1323. *p_f64++ = *frame_ip++;
  1324. if (!jit_compile_op_f64_const(cc, f64_const))
  1325. return false;
  1326. break;
  1327. case WASM_OP_I32_EQZ:
  1328. case WASM_OP_I32_EQ:
  1329. case WASM_OP_I32_NE:
  1330. case WASM_OP_I32_LT_S:
  1331. case WASM_OP_I32_LT_U:
  1332. case WASM_OP_I32_GT_S:
  1333. case WASM_OP_I32_GT_U:
  1334. case WASM_OP_I32_LE_S:
  1335. case WASM_OP_I32_LE_U:
  1336. case WASM_OP_I32_GE_S:
  1337. case WASM_OP_I32_GE_U:
  1338. if (!jit_compile_op_i32_compare(cc, INT_EQZ + opcode
  1339. - WASM_OP_I32_EQZ))
  1340. return false;
  1341. if (frame_ip < frame_ip_end) {
  1342. /* Merge `CMP, SELECTcc, CMP, BNE` insns into `CMP, Bcc` */
  1343. if (*frame_ip == WASM_OP_IF || *frame_ip == EXT_OP_IF)
  1344. merge_cmp_and_if = true;
  1345. if (*frame_ip == WASM_OP_BR_IF)
  1346. merge_cmp_and_br_if = true;
  1347. }
  1348. break;
  1349. case WASM_OP_I64_EQZ:
  1350. case WASM_OP_I64_EQ:
  1351. case WASM_OP_I64_NE:
  1352. case WASM_OP_I64_LT_S:
  1353. case WASM_OP_I64_LT_U:
  1354. case WASM_OP_I64_GT_S:
  1355. case WASM_OP_I64_GT_U:
  1356. case WASM_OP_I64_LE_S:
  1357. case WASM_OP_I64_LE_U:
  1358. case WASM_OP_I64_GE_S:
  1359. case WASM_OP_I64_GE_U:
  1360. if (!jit_compile_op_i64_compare(cc, INT_EQZ + opcode
  1361. - WASM_OP_I64_EQZ))
  1362. return false;
  1363. if (frame_ip < frame_ip_end) {
  1364. /* Merge `CMP, SELECTcc, CMP, BNE` insns into `CMP, Bcc` */
  1365. if (*frame_ip == WASM_OP_IF || *frame_ip == EXT_OP_IF)
  1366. merge_cmp_and_if = true;
  1367. if (*frame_ip == WASM_OP_BR_IF)
  1368. merge_cmp_and_br_if = true;
  1369. }
  1370. break;
  1371. case WASM_OP_F32_EQ:
  1372. case WASM_OP_F32_NE:
  1373. case WASM_OP_F32_LT:
  1374. case WASM_OP_F32_GT:
  1375. case WASM_OP_F32_LE:
  1376. case WASM_OP_F32_GE:
  1377. if (!jit_compile_op_f32_compare(cc, FLOAT_EQ + opcode
  1378. - WASM_OP_F32_EQ))
  1379. return false;
  1380. if (frame_ip < frame_ip_end) {
  1381. /* Merge `CMP, SELECTcc, CMP, BNE` insns into `CMP, Bcc` */
  1382. if (*frame_ip == WASM_OP_IF || *frame_ip == EXT_OP_IF)
  1383. merge_cmp_and_if = true;
  1384. if (*frame_ip == WASM_OP_BR_IF)
  1385. merge_cmp_and_br_if = true;
  1386. }
  1387. break;
  1388. case WASM_OP_F64_EQ:
  1389. case WASM_OP_F64_NE:
  1390. case WASM_OP_F64_LT:
  1391. case WASM_OP_F64_GT:
  1392. case WASM_OP_F64_LE:
  1393. case WASM_OP_F64_GE:
  1394. if (!jit_compile_op_f64_compare(cc, FLOAT_EQ + opcode
  1395. - WASM_OP_F64_EQ))
  1396. return false;
  1397. if (frame_ip < frame_ip_end) {
  1398. /* Merge `CMP, SELECTcc, CMP, BNE` insns into `CMP, Bcc` */
  1399. if (*frame_ip == WASM_OP_IF || *frame_ip == EXT_OP_IF)
  1400. merge_cmp_and_if = true;
  1401. if (*frame_ip == WASM_OP_BR_IF)
  1402. merge_cmp_and_br_if = true;
  1403. }
  1404. break;
  1405. case WASM_OP_I32_CLZ:
  1406. if (!jit_compile_op_i32_clz(cc))
  1407. return false;
  1408. break;
  1409. case WASM_OP_I32_CTZ:
  1410. if (!jit_compile_op_i32_ctz(cc))
  1411. return false;
  1412. break;
  1413. case WASM_OP_I32_POPCNT:
  1414. if (!jit_compile_op_i32_popcnt(cc))
  1415. return false;
  1416. break;
  1417. case WASM_OP_I32_ADD:
  1418. case WASM_OP_I32_SUB:
  1419. case WASM_OP_I32_MUL:
  1420. case WASM_OP_I32_DIV_S:
  1421. case WASM_OP_I32_DIV_U:
  1422. case WASM_OP_I32_REM_S:
  1423. case WASM_OP_I32_REM_U:
  1424. if (!jit_compile_op_i32_arithmetic(
  1425. cc, INT_ADD + opcode - WASM_OP_I32_ADD, &frame_ip))
  1426. return false;
  1427. break;
  1428. case WASM_OP_I32_AND:
  1429. case WASM_OP_I32_OR:
  1430. case WASM_OP_I32_XOR:
  1431. if (!jit_compile_op_i32_bitwise(cc, INT_SHL + opcode
  1432. - WASM_OP_I32_AND))
  1433. return false;
  1434. break;
  1435. case WASM_OP_I32_SHL:
  1436. case WASM_OP_I32_SHR_S:
  1437. case WASM_OP_I32_SHR_U:
  1438. case WASM_OP_I32_ROTL:
  1439. case WASM_OP_I32_ROTR:
  1440. if (!jit_compile_op_i32_shift(cc, INT_SHL + opcode
  1441. - WASM_OP_I32_SHL))
  1442. return false;
  1443. break;
  1444. case WASM_OP_I64_CLZ:
  1445. if (!jit_compile_op_i64_clz(cc))
  1446. return false;
  1447. break;
  1448. case WASM_OP_I64_CTZ:
  1449. if (!jit_compile_op_i64_ctz(cc))
  1450. return false;
  1451. break;
  1452. case WASM_OP_I64_POPCNT:
  1453. if (!jit_compile_op_i64_popcnt(cc))
  1454. return false;
  1455. break;
  1456. case WASM_OP_I64_ADD:
  1457. case WASM_OP_I64_SUB:
  1458. case WASM_OP_I64_MUL:
  1459. case WASM_OP_I64_DIV_S:
  1460. case WASM_OP_I64_DIV_U:
  1461. case WASM_OP_I64_REM_S:
  1462. case WASM_OP_I64_REM_U:
  1463. if (!jit_compile_op_i64_arithmetic(
  1464. cc, INT_ADD + opcode - WASM_OP_I64_ADD, &frame_ip))
  1465. return false;
  1466. break;
  1467. case WASM_OP_I64_AND:
  1468. case WASM_OP_I64_OR:
  1469. case WASM_OP_I64_XOR:
  1470. if (!jit_compile_op_i64_bitwise(cc, INT_SHL + opcode
  1471. - WASM_OP_I64_AND))
  1472. return false;
  1473. break;
  1474. case WASM_OP_I64_SHL:
  1475. case WASM_OP_I64_SHR_S:
  1476. case WASM_OP_I64_SHR_U:
  1477. case WASM_OP_I64_ROTL:
  1478. case WASM_OP_I64_ROTR:
  1479. if (!jit_compile_op_i64_shift(cc, INT_SHL + opcode
  1480. - WASM_OP_I64_SHL))
  1481. return false;
  1482. break;
  1483. case WASM_OP_F32_ABS:
  1484. case WASM_OP_F32_NEG:
  1485. case WASM_OP_F32_CEIL:
  1486. case WASM_OP_F32_FLOOR:
  1487. case WASM_OP_F32_TRUNC:
  1488. case WASM_OP_F32_NEAREST:
  1489. case WASM_OP_F32_SQRT:
  1490. if (!jit_compile_op_f32_math(cc, FLOAT_ABS + opcode
  1491. - WASM_OP_F32_ABS))
  1492. return false;
  1493. break;
  1494. case WASM_OP_F32_ADD:
  1495. case WASM_OP_F32_SUB:
  1496. case WASM_OP_F32_MUL:
  1497. case WASM_OP_F32_DIV:
  1498. case WASM_OP_F32_MIN:
  1499. case WASM_OP_F32_MAX:
  1500. if (!jit_compile_op_f32_arithmetic(cc, FLOAT_ADD + opcode
  1501. - WASM_OP_F32_ADD))
  1502. return false;
  1503. break;
  1504. case WASM_OP_F32_COPYSIGN:
  1505. if (!jit_compile_op_f32_copysign(cc))
  1506. return false;
  1507. break;
  1508. case WASM_OP_F64_ABS:
  1509. case WASM_OP_F64_NEG:
  1510. case WASM_OP_F64_CEIL:
  1511. case WASM_OP_F64_FLOOR:
  1512. case WASM_OP_F64_TRUNC:
  1513. case WASM_OP_F64_NEAREST:
  1514. case WASM_OP_F64_SQRT:
  1515. if (!jit_compile_op_f64_math(cc, FLOAT_ABS + opcode
  1516. - WASM_OP_F64_ABS))
  1517. return false;
  1518. break;
  1519. case WASM_OP_F64_ADD:
  1520. case WASM_OP_F64_SUB:
  1521. case WASM_OP_F64_MUL:
  1522. case WASM_OP_F64_DIV:
  1523. case WASM_OP_F64_MIN:
  1524. case WASM_OP_F64_MAX:
  1525. if (!jit_compile_op_f64_arithmetic(cc, FLOAT_ADD + opcode
  1526. - WASM_OP_F64_ADD))
  1527. return false;
  1528. break;
  1529. case WASM_OP_F64_COPYSIGN:
  1530. if (!jit_compile_op_f64_copysign(cc))
  1531. return false;
  1532. break;
  1533. case WASM_OP_I32_WRAP_I64:
  1534. if (!jit_compile_op_i32_wrap_i64(cc))
  1535. return false;
  1536. break;
  1537. case WASM_OP_I32_TRUNC_S_F32:
  1538. case WASM_OP_I32_TRUNC_U_F32:
  1539. sign = (opcode == WASM_OP_I32_TRUNC_S_F32) ? true : false;
  1540. if (!jit_compile_op_i32_trunc_f32(cc, sign, false))
  1541. return false;
  1542. break;
  1543. case WASM_OP_I32_TRUNC_S_F64:
  1544. case WASM_OP_I32_TRUNC_U_F64:
  1545. sign = (opcode == WASM_OP_I32_TRUNC_S_F64) ? true : false;
  1546. if (!jit_compile_op_i32_trunc_f64(cc, sign, false))
  1547. return false;
  1548. break;
  1549. case WASM_OP_I64_EXTEND_S_I32:
  1550. case WASM_OP_I64_EXTEND_U_I32:
  1551. sign = (opcode == WASM_OP_I64_EXTEND_S_I32) ? true : false;
  1552. if (!jit_compile_op_i64_extend_i32(cc, sign))
  1553. return false;
  1554. break;
  1555. case WASM_OP_I64_TRUNC_S_F32:
  1556. case WASM_OP_I64_TRUNC_U_F32:
  1557. sign = (opcode == WASM_OP_I64_TRUNC_S_F32) ? true : false;
  1558. if (!jit_compile_op_i64_trunc_f32(cc, sign, false))
  1559. return false;
  1560. break;
  1561. case WASM_OP_I64_TRUNC_S_F64:
  1562. case WASM_OP_I64_TRUNC_U_F64:
  1563. sign = (opcode == WASM_OP_I64_TRUNC_S_F64) ? true : false;
  1564. if (!jit_compile_op_i64_trunc_f64(cc, sign, false))
  1565. return false;
  1566. break;
  1567. case WASM_OP_F32_CONVERT_S_I32:
  1568. case WASM_OP_F32_CONVERT_U_I32:
  1569. sign = (opcode == WASM_OP_F32_CONVERT_S_I32) ? true : false;
  1570. if (!jit_compile_op_f32_convert_i32(cc, sign))
  1571. return false;
  1572. break;
  1573. case WASM_OP_F32_CONVERT_S_I64:
  1574. case WASM_OP_F32_CONVERT_U_I64:
  1575. sign = (opcode == WASM_OP_F32_CONVERT_S_I64) ? true : false;
  1576. if (!jit_compile_op_f32_convert_i64(cc, sign))
  1577. return false;
  1578. break;
  1579. case WASM_OP_F32_DEMOTE_F64:
  1580. if (!jit_compile_op_f32_demote_f64(cc))
  1581. return false;
  1582. break;
  1583. case WASM_OP_F64_CONVERT_S_I32:
  1584. case WASM_OP_F64_CONVERT_U_I32:
  1585. sign = (opcode == WASM_OP_F64_CONVERT_S_I32) ? true : false;
  1586. if (!jit_compile_op_f64_convert_i32(cc, sign))
  1587. return false;
  1588. break;
  1589. case WASM_OP_F64_CONVERT_S_I64:
  1590. case WASM_OP_F64_CONVERT_U_I64:
  1591. sign = (opcode == WASM_OP_F64_CONVERT_S_I64) ? true : false;
  1592. if (!jit_compile_op_f64_convert_i64(cc, sign))
  1593. return false;
  1594. break;
  1595. case WASM_OP_F64_PROMOTE_F32:
  1596. if (!jit_compile_op_f64_promote_f32(cc))
  1597. return false;
  1598. break;
  1599. case WASM_OP_I32_REINTERPRET_F32:
  1600. if (!jit_compile_op_i32_reinterpret_f32(cc))
  1601. return false;
  1602. break;
  1603. case WASM_OP_I64_REINTERPRET_F64:
  1604. if (!jit_compile_op_i64_reinterpret_f64(cc))
  1605. return false;
  1606. break;
  1607. case WASM_OP_F32_REINTERPRET_I32:
  1608. if (!jit_compile_op_f32_reinterpret_i32(cc))
  1609. return false;
  1610. break;
  1611. case WASM_OP_F64_REINTERPRET_I64:
  1612. if (!jit_compile_op_f64_reinterpret_i64(cc))
  1613. return false;
  1614. break;
  1615. case WASM_OP_I32_EXTEND8_S:
  1616. if (!jit_compile_op_i32_extend_i32(cc, 8))
  1617. return false;
  1618. break;
  1619. case WASM_OP_I32_EXTEND16_S:
  1620. if (!jit_compile_op_i32_extend_i32(cc, 16))
  1621. return false;
  1622. break;
  1623. case WASM_OP_I64_EXTEND8_S:
  1624. if (!jit_compile_op_i64_extend_i64(cc, 8))
  1625. return false;
  1626. break;
  1627. case WASM_OP_I64_EXTEND16_S:
  1628. if (!jit_compile_op_i64_extend_i64(cc, 16))
  1629. return false;
  1630. break;
  1631. case WASM_OP_I64_EXTEND32_S:
  1632. if (!jit_compile_op_i64_extend_i64(cc, 32))
  1633. return false;
  1634. break;
  1635. case WASM_OP_MISC_PREFIX:
  1636. {
  1637. uint32 opcode1;
  1638. read_leb_uint32(frame_ip, frame_ip_end, opcode1);
  1639. opcode = (uint32)opcode1;
  1640. switch (opcode) {
  1641. case WASM_OP_I32_TRUNC_SAT_S_F32:
  1642. case WASM_OP_I32_TRUNC_SAT_U_F32:
  1643. sign = (opcode == WASM_OP_I32_TRUNC_SAT_S_F32) ? true
  1644. : false;
  1645. if (!jit_compile_op_i32_trunc_f32(cc, sign, true))
  1646. return false;
  1647. break;
  1648. case WASM_OP_I32_TRUNC_SAT_S_F64:
  1649. case WASM_OP_I32_TRUNC_SAT_U_F64:
  1650. sign = (opcode == WASM_OP_I32_TRUNC_SAT_S_F64) ? true
  1651. : false;
  1652. if (!jit_compile_op_i32_trunc_f64(cc, sign, true))
  1653. return false;
  1654. break;
  1655. case WASM_OP_I64_TRUNC_SAT_S_F32:
  1656. case WASM_OP_I64_TRUNC_SAT_U_F32:
  1657. sign = (opcode == WASM_OP_I64_TRUNC_SAT_S_F32) ? true
  1658. : false;
  1659. if (!jit_compile_op_i64_trunc_f32(cc, sign, true))
  1660. return false;
  1661. break;
  1662. case WASM_OP_I64_TRUNC_SAT_S_F64:
  1663. case WASM_OP_I64_TRUNC_SAT_U_F64:
  1664. sign = (opcode == WASM_OP_I64_TRUNC_SAT_S_F64) ? true
  1665. : false;
  1666. if (!jit_compile_op_i64_trunc_f64(cc, sign, true))
  1667. return false;
  1668. break;
  1669. #if WASM_ENABLE_BULK_MEMORY != 0
  1670. case WASM_OP_MEMORY_INIT:
  1671. {
  1672. uint32 seg_idx = 0;
  1673. read_leb_uint32(frame_ip, frame_ip_end, seg_idx);
  1674. read_leb_uint32(frame_ip, frame_ip_end, mem_idx);
  1675. if (!jit_compile_op_memory_init(cc, mem_idx, seg_idx))
  1676. return false;
  1677. break;
  1678. }
  1679. case WASM_OP_DATA_DROP:
  1680. {
  1681. uint32 seg_idx;
  1682. read_leb_uint32(frame_ip, frame_ip_end, seg_idx);
  1683. if (!jit_compile_op_data_drop(cc, seg_idx))
  1684. return false;
  1685. break;
  1686. }
  1687. case WASM_OP_MEMORY_COPY:
  1688. {
  1689. uint32 src_mem_idx, dst_mem_idx;
  1690. read_leb_uint32(frame_ip, frame_ip_end, src_mem_idx);
  1691. read_leb_uint32(frame_ip, frame_ip_end, dst_mem_idx);
  1692. if (!jit_compile_op_memory_copy(cc, src_mem_idx,
  1693. dst_mem_idx))
  1694. return false;
  1695. break;
  1696. }
  1697. case WASM_OP_MEMORY_FILL:
  1698. {
  1699. read_leb_uint32(frame_ip, frame_ip_end, mem_idx);
  1700. if (!jit_compile_op_memory_fill(cc, mem_idx))
  1701. return false;
  1702. break;
  1703. }
  1704. #endif /* WASM_ENABLE_BULK_MEMORY */
  1705. #if WASM_ENABLE_REF_TYPES != 0
  1706. case WASM_OP_TABLE_INIT:
  1707. {
  1708. uint32 tbl_idx, tbl_seg_idx;
  1709. read_leb_uint32(frame_ip, frame_ip_end, tbl_seg_idx);
  1710. read_leb_uint32(frame_ip, frame_ip_end, tbl_idx);
  1711. if (!jit_compile_op_table_init(cc, tbl_idx,
  1712. tbl_seg_idx))
  1713. return false;
  1714. break;
  1715. }
  1716. case WASM_OP_ELEM_DROP:
  1717. {
  1718. uint32 tbl_seg_idx;
  1719. read_leb_uint32(frame_ip, frame_ip_end, tbl_seg_idx);
  1720. if (!jit_compile_op_elem_drop(cc, tbl_seg_idx))
  1721. return false;
  1722. break;
  1723. }
  1724. case WASM_OP_TABLE_COPY:
  1725. {
  1726. uint32 src_tbl_idx, dst_tbl_idx;
  1727. read_leb_uint32(frame_ip, frame_ip_end, dst_tbl_idx);
  1728. read_leb_uint32(frame_ip, frame_ip_end, src_tbl_idx);
  1729. if (!jit_compile_op_table_copy(cc, src_tbl_idx,
  1730. dst_tbl_idx))
  1731. return false;
  1732. break;
  1733. }
  1734. case WASM_OP_TABLE_GROW:
  1735. {
  1736. uint32 tbl_idx;
  1737. read_leb_uint32(frame_ip, frame_ip_end, tbl_idx);
  1738. if (!jit_compile_op_table_grow(cc, tbl_idx))
  1739. return false;
  1740. break;
  1741. }
  1742. case WASM_OP_TABLE_SIZE:
  1743. {
  1744. uint32 tbl_idx;
  1745. read_leb_uint32(frame_ip, frame_ip_end, tbl_idx);
  1746. if (!jit_compile_op_table_size(cc, tbl_idx))
  1747. return false;
  1748. break;
  1749. }
  1750. case WASM_OP_TABLE_FILL:
  1751. {
  1752. uint32 tbl_idx;
  1753. read_leb_uint32(frame_ip, frame_ip_end, tbl_idx);
  1754. if (!jit_compile_op_table_fill(cc, tbl_idx))
  1755. return false;
  1756. break;
  1757. }
  1758. #endif /* WASM_ENABLE_REF_TYPES */
  1759. default:
  1760. jit_set_last_error(cc, "unsupported opcode");
  1761. return false;
  1762. }
  1763. break;
  1764. }
  1765. #if WASM_ENABLE_SHARED_MEMORY != 0
  1766. case WASM_OP_ATOMIC_PREFIX:
  1767. {
  1768. uint8 bin_op, op_type;
  1769. if (frame_ip < frame_ip_end) {
  1770. opcode = *frame_ip++;
  1771. }
  1772. if (opcode != WASM_OP_ATOMIC_FENCE) {
  1773. read_leb_uint32(frame_ip, frame_ip_end, align);
  1774. read_leb_uint32(frame_ip, frame_ip_end, offset);
  1775. }
  1776. switch (opcode) {
  1777. case WASM_OP_ATOMIC_WAIT32:
  1778. if (!jit_compile_op_atomic_wait(cc, VALUE_TYPE_I32,
  1779. align, offset, 4))
  1780. return false;
  1781. break;
  1782. case WASM_OP_ATOMIC_WAIT64:
  1783. if (!jit_compile_op_atomic_wait(cc, VALUE_TYPE_I64,
  1784. align, offset, 8))
  1785. return false;
  1786. break;
  1787. case WASM_OP_ATOMIC_NOTIFY:
  1788. if (!jit_compiler_op_atomic_notify(cc, align, offset,
  1789. bytes))
  1790. return false;
  1791. break;
  1792. case WASM_OP_ATOMIC_I32_LOAD:
  1793. bytes = 4;
  1794. goto op_atomic_i32_load;
  1795. case WASM_OP_ATOMIC_I32_LOAD8_U:
  1796. bytes = 1;
  1797. goto op_atomic_i32_load;
  1798. case WASM_OP_ATOMIC_I32_LOAD16_U:
  1799. bytes = 2;
  1800. op_atomic_i32_load:
  1801. if (!jit_compile_op_i32_load(cc, align, offset, bytes,
  1802. sign, true))
  1803. return false;
  1804. break;
  1805. case WASM_OP_ATOMIC_I64_LOAD:
  1806. bytes = 8;
  1807. goto op_atomic_i64_load;
  1808. case WASM_OP_ATOMIC_I64_LOAD8_U:
  1809. bytes = 1;
  1810. goto op_atomic_i64_load;
  1811. case WASM_OP_ATOMIC_I64_LOAD16_U:
  1812. bytes = 2;
  1813. goto op_atomic_i64_load;
  1814. case WASM_OP_ATOMIC_I64_LOAD32_U:
  1815. bytes = 4;
  1816. op_atomic_i64_load:
  1817. if (!jit_compile_op_i64_load(cc, align, offset, bytes,
  1818. sign, true))
  1819. return false;
  1820. break;
  1821. case WASM_OP_ATOMIC_I32_STORE:
  1822. bytes = 4;
  1823. goto op_atomic_i32_store;
  1824. case WASM_OP_ATOMIC_I32_STORE8:
  1825. bytes = 1;
  1826. goto op_atomic_i32_store;
  1827. case WASM_OP_ATOMIC_I32_STORE16:
  1828. bytes = 2;
  1829. op_atomic_i32_store:
  1830. if (!jit_compile_op_i32_store(cc, align, offset, bytes,
  1831. true))
  1832. return false;
  1833. break;
  1834. case WASM_OP_ATOMIC_I64_STORE:
  1835. bytes = 8;
  1836. goto op_atomic_i64_store;
  1837. case WASM_OP_ATOMIC_I64_STORE8:
  1838. bytes = 1;
  1839. goto op_atomic_i64_store;
  1840. case WASM_OP_ATOMIC_I64_STORE16:
  1841. bytes = 2;
  1842. goto op_atomic_i64_store;
  1843. case WASM_OP_ATOMIC_I64_STORE32:
  1844. bytes = 4;
  1845. op_atomic_i64_store:
  1846. if (!jit_compile_op_i64_store(cc, align, offset, bytes,
  1847. true))
  1848. return false;
  1849. break;
  1850. case WASM_OP_ATOMIC_RMW_I32_CMPXCHG:
  1851. bytes = 4;
  1852. op_type = VALUE_TYPE_I32;
  1853. goto op_atomic_cmpxchg;
  1854. case WASM_OP_ATOMIC_RMW_I64_CMPXCHG:
  1855. bytes = 8;
  1856. op_type = VALUE_TYPE_I64;
  1857. goto op_atomic_cmpxchg;
  1858. case WASM_OP_ATOMIC_RMW_I32_CMPXCHG8_U:
  1859. bytes = 1;
  1860. op_type = VALUE_TYPE_I32;
  1861. goto op_atomic_cmpxchg;
  1862. case WASM_OP_ATOMIC_RMW_I32_CMPXCHG16_U:
  1863. bytes = 2;
  1864. op_type = VALUE_TYPE_I32;
  1865. goto op_atomic_cmpxchg;
  1866. case WASM_OP_ATOMIC_RMW_I64_CMPXCHG8_U:
  1867. bytes = 1;
  1868. op_type = VALUE_TYPE_I64;
  1869. goto op_atomic_cmpxchg;
  1870. case WASM_OP_ATOMIC_RMW_I64_CMPXCHG16_U:
  1871. bytes = 2;
  1872. op_type = VALUE_TYPE_I64;
  1873. goto op_atomic_cmpxchg;
  1874. case WASM_OP_ATOMIC_RMW_I64_CMPXCHG32_U:
  1875. bytes = 4;
  1876. op_type = VALUE_TYPE_I64;
  1877. op_atomic_cmpxchg:
  1878. if (!jit_compile_op_atomic_cmpxchg(cc, op_type, align,
  1879. offset, bytes))
  1880. return false;
  1881. break;
  1882. /* TODO */
  1883. /*
  1884. COMPILE_ATOMIC_RMW(Add, ADD);
  1885. COMPILE_ATOMIC_RMW(Sub, SUB);
  1886. COMPILE_ATOMIC_RMW(And, AND);
  1887. COMPILE_ATOMIC_RMW(Or, OR);
  1888. COMPILE_ATOMIC_RMW(Xor, XOR);
  1889. COMPILE_ATOMIC_RMW(Xchg, XCHG);
  1890. */
  1891. build_atomic_rmw:
  1892. if (!jit_compile_op_atomic_rmw(cc, bin_op, op_type,
  1893. align, offset, bytes))
  1894. return false;
  1895. break;
  1896. default:
  1897. jit_set_last_error(cc, "unsupported opcode");
  1898. return false;
  1899. }
  1900. break;
  1901. }
  1902. #endif /* end of WASM_ENABLE_SHARED_MEMORY */
  1903. default:
  1904. jit_set_last_error(cc, "unsupported opcode");
  1905. return false;
  1906. }
  1907. /* Error may occur when creating registers, basic blocks, insns,
  1908. consts and labels, in which the return value may be unchecked,
  1909. here we check again */
  1910. if (jit_get_last_error(cc)) {
  1911. return false;
  1912. }
  1913. }
  1914. (void)func_idx;
  1915. return true;
  1916. fail:
  1917. return false;
  1918. }
  1919. JitBasicBlock *
  1920. jit_frontend_translate_func(JitCompContext *cc)
  1921. {
  1922. JitFrame *jit_frame;
  1923. JitBasicBlock *basic_block_entry;
  1924. if (!(jit_frame = init_func_translation(cc))) {
  1925. return NULL;
  1926. }
  1927. if (!(basic_block_entry = create_func_block(cc))) {
  1928. return NULL;
  1929. }
  1930. if (!jit_compile_func(cc)) {
  1931. return NULL;
  1932. }
  1933. return basic_block_entry;
  1934. }
  1935. #if 0
  1936. #if WASM_ENABLE_THREAD_MGR != 0
  1937. bool
  1938. check_suspend_flags(JitCompContext *cc, JITFuncContext *func_ctx)
  1939. {
  1940. LLVMValueRef terminate_addr, terminate_flags, flag, offset, res;
  1941. JitBasicBlock *terminate_check_block, non_terminate_block;
  1942. JITFuncType *jit_func_type = func_ctx->jit_func->func_type;
  1943. JitBasicBlock *terminate_block;
  1944. /* Offset of suspend_flags */
  1945. offset = I32_FIVE;
  1946. if (!(terminate_addr = LLVMBuildInBoundsGEP(
  1947. cc->builder, func_ctx->exec_env, &offset, 1, "terminate_addr"))) {
  1948. jit_set_last_error("llvm build in bounds gep failed");
  1949. return false;
  1950. }
  1951. if (!(terminate_addr =
  1952. LLVMBuildBitCast(cc->builder, terminate_addr, INT32_PTR_TYPE,
  1953. "terminate_addr_ptr"))) {
  1954. jit_set_last_error("llvm build bit cast failed");
  1955. return false;
  1956. }
  1957. if (!(terminate_flags =
  1958. LLVMBuildLoad(cc->builder, terminate_addr, "terminate_flags"))) {
  1959. jit_set_last_error("llvm build bit cast failed");
  1960. return false;
  1961. }
  1962. /* Set terminate_flags memory accecc to volatile, so that the value
  1963. will always be loaded from memory rather than register */
  1964. LLVMSetVolatile(terminate_flags, true);
  1965. CREATE_BASIC_BLOCK(terminate_check_block, "terminate_check");
  1966. MOVE_BASIC_BLOCK_AFTER_CURR(terminate_check_block);
  1967. CREATE_BASIC_BLOCK(non_terminate_block, "non_terminate");
  1968. MOVE_BASIC_BLOCK_AFTER_CURR(non_terminate_block);
  1969. BUILD_ICMP(LLVMIntSGT, terminate_flags, I32_ZERO, res, "need_terminate");
  1970. BUILD_COND_BR(res, terminate_check_block, non_terminate_block);
  1971. /* Move builder to terminate check block */
  1972. SET_BUILDER_POS(terminate_check_block);
  1973. CREATE_BASIC_BLOCK(terminate_block, "terminate");
  1974. MOVE_BASIC_BLOCK_AFTER_CURR(terminate_block);
  1975. if (!(flag = LLVMBuildAnd(cc->builder, terminate_flags, I32_ONE,
  1976. "termination_flag"))) {
  1977. jit_set_last_error("llvm build AND failed");
  1978. return false;
  1979. }
  1980. BUILD_ICMP(LLVMIntSGT, flag, I32_ZERO, res, "need_terminate");
  1981. BUILD_COND_BR(res, terminate_block, non_terminate_block);
  1982. /* Move builder to terminate block */
  1983. SET_BUILDER_POS(terminate_block);
  1984. if (!jit_build_zero_function_ret(cc, func_ctx, jit_func_type)) {
  1985. goto fail;
  1986. }
  1987. /* Move builder to terminate block */
  1988. SET_BUILDER_POS(non_terminate_block);
  1989. return true;
  1990. fail:
  1991. return false;
  1992. }
  1993. #endif /* End of WASM_ENABLE_THREAD_MGR */
  1994. #endif