aot_compiler.h 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #ifndef _AOT_COMPILER_H_
  6. #define _AOT_COMPILER_H_
  7. #include "aot.h"
  8. #include "aot_llvm.h"
  9. #ifdef __cplusplus
  10. extern "C" {
  11. #endif
  12. typedef enum IntCond {
  13. INT_EQZ = 0,
  14. INT_EQ,
  15. INT_NE,
  16. INT_LT_S,
  17. INT_LT_U,
  18. INT_GT_S,
  19. INT_GT_U,
  20. INT_LE_S,
  21. INT_LE_U,
  22. INT_GE_S,
  23. INT_GE_U
  24. } IntCond;
  25. typedef enum FloatCond {
  26. FLOAT_EQ = 0,
  27. FLOAT_NE,
  28. FLOAT_LT,
  29. FLOAT_GT,
  30. FLOAT_LE,
  31. FLOAT_GE
  32. } FloatCond;
  33. typedef enum IntArithmetic {
  34. INT_ADD = 0,
  35. INT_SUB,
  36. INT_MUL,
  37. INT_DIV_S,
  38. INT_DIV_U,
  39. INT_REM_S,
  40. INT_REM_U
  41. } IntArithmetic;
  42. typedef enum IntBitwise {
  43. INT_AND = 0,
  44. INT_OR,
  45. INT_XOR,
  46. } IntBitwise;
  47. typedef enum IntShift {
  48. INT_SHL = 0,
  49. INT_SHR_S,
  50. INT_SHR_U,
  51. INT_ROTL,
  52. INT_ROTR
  53. } IntShift;
  54. typedef enum FloatMath {
  55. FLOAT_ABS = 0,
  56. FLOAT_NEG,
  57. FLOAT_CEIL,
  58. FLOAT_FLOOR,
  59. FLOAT_TRUNC,
  60. FLOAT_NEAREST,
  61. FLOAT_SQRT
  62. } FloatMath;
  63. typedef enum FloatArithmetic {
  64. FLOAT_ADD = 0,
  65. FLOAT_SUB,
  66. FLOAT_MUL,
  67. FLOAT_DIV,
  68. FLOAT_MIN,
  69. FLOAT_MAX
  70. } FloatArithmetic;
  71. #define CHECK_STACK() do { \
  72. if (!func_ctx->block_stack.block_list_end) { \
  73. aot_set_last_error("WASM block stack underflow."); \
  74. goto fail; \
  75. } \
  76. if (!func_ctx->block_stack.block_list_end-> \
  77. value_stack.value_list_end) { \
  78. aot_set_last_error("WASM data stack underflow."); \
  79. goto fail; \
  80. } \
  81. } while (0)
  82. #define POP(llvm_value, value_type) do { \
  83. AOTValue *aot_value; \
  84. CHECK_STACK(); \
  85. aot_value = aot_value_stack_pop \
  86. (&func_ctx->block_stack.block_list_end->value_stack); \
  87. if ((value_type != VALUE_TYPE_I32 \
  88. && aot_value->type != value_type) \
  89. || (value_type == VALUE_TYPE_I32 \
  90. && (aot_value->type != VALUE_TYPE_I32 \
  91. && aot_value->type != VALUE_TYPE_I1))) { \
  92. aot_set_last_error("invalid WASM stack data type."); \
  93. wasm_runtime_free(aot_value); \
  94. goto fail; \
  95. } \
  96. if (aot_value->type == value_type) \
  97. llvm_value = aot_value->value; \
  98. else { \
  99. bh_assert(aot_value->type == VALUE_TYPE_I1); \
  100. if (!(llvm_value = LLVMBuildZExt(comp_ctx->builder, \
  101. aot_value->value, I32_TYPE, "i1toi32"))) { \
  102. aot_set_last_error("invalid WASM stack data type.");\
  103. wasm_runtime_free(aot_value); \
  104. goto fail; \
  105. } \
  106. } \
  107. wasm_runtime_free(aot_value); \
  108. } while (0)
  109. #define POP_I32(v) POP(v, VALUE_TYPE_I32)
  110. #define POP_I64(v) POP(v, VALUE_TYPE_I64)
  111. #define POP_F32(v) POP(v, VALUE_TYPE_F32)
  112. #define POP_F64(v) POP(v, VALUE_TYPE_F64)
  113. #define POP_COND(llvm_value) do { \
  114. AOTValue *aot_value; \
  115. CHECK_STACK(); \
  116. aot_value = aot_value_stack_pop \
  117. (&func_ctx->block_stack.block_list_end->value_stack); \
  118. if (aot_value->type != VALUE_TYPE_I1 \
  119. && aot_value->type != VALUE_TYPE_I32) { \
  120. aot_set_last_error("invalid WASM stack data type."); \
  121. wasm_runtime_free(aot_value); \
  122. goto fail; \
  123. } \
  124. if (aot_value->type == VALUE_TYPE_I1) \
  125. llvm_value = aot_value->value; \
  126. else { \
  127. if (!(llvm_value = LLVMBuildICmp(comp_ctx->builder, \
  128. LLVMIntNE, aot_value->value, I32_ZERO, \
  129. "i1_cond"))){ \
  130. aot_set_last_error("llvm build trunc failed."); \
  131. wasm_runtime_free(aot_value); \
  132. goto fail; \
  133. } \
  134. } \
  135. wasm_runtime_free(aot_value); \
  136. } while (0)
  137. #define PUSH(llvm_value, value_type) do { \
  138. AOTValue *aot_value; \
  139. if (!func_ctx->block_stack.block_list_end) { \
  140. aot_set_last_error("WASM block stack underflow."); \
  141. goto fail; \
  142. } \
  143. aot_value = wasm_runtime_malloc(sizeof(AOTValue)); \
  144. memset(aot_value, 0, sizeof(AOTValue)); \
  145. if (!aot_value) { \
  146. aot_set_last_error("allocate memory failed."); \
  147. goto fail; \
  148. } \
  149. aot_value->type = value_type; \
  150. aot_value->value = llvm_value; \
  151. aot_value_stack_push \
  152. (&func_ctx->block_stack.block_list_end->value_stack,\
  153. aot_value); \
  154. } while (0)
  155. #define PUSH_I32(v) PUSH(v, VALUE_TYPE_I32)
  156. #define PUSH_I64(v) PUSH(v, VALUE_TYPE_I64)
  157. #define PUSH_F32(v) PUSH(v, VALUE_TYPE_F32)
  158. #define PUSH_F64(v) PUSH(v, VALUE_TYPE_F64)
  159. #define PUSH_COND(v) PUSH(v, VALUE_TYPE_I1)
  160. #define TO_LLVM_TYPE(wasm_type) \
  161. wasm_type_to_llvm_type(&comp_ctx->basic_types, wasm_type)
  162. #define I32_TYPE comp_ctx->basic_types.int32_type
  163. #define I64_TYPE comp_ctx->basic_types.int64_type
  164. #define F32_TYPE comp_ctx->basic_types.float32_type
  165. #define F64_TYPE comp_ctx->basic_types.float64_type
  166. #define VOID_TYPE comp_ctx->basic_types.void_type
  167. #define INT1_TYPE comp_ctx->basic_types.int1_type
  168. #define INT8_TYPE comp_ctx->basic_types.int8_type
  169. #define INT16_TYPE comp_ctx->basic_types.int16_type
  170. #define MD_TYPE comp_ctx->basic_types.meta_data_type
  171. #define INT8_PTR_TYPE comp_ctx->basic_types.int8_ptr_type
  172. #define INT16_PTR_TYPE comp_ctx->basic_types.int16_ptr_type
  173. #define INT32_PTR_TYPE comp_ctx->basic_types.int32_ptr_type
  174. #define INT64_PTR_TYPE comp_ctx->basic_types.int64_ptr_type
  175. #define F32_PTR_TYPE comp_ctx->basic_types.float32_ptr_type
  176. #define F64_PTR_TYPE comp_ctx->basic_types.float64_ptr_type
  177. #define I32_CONST(v) LLVMConstInt(I32_TYPE, v, true)
  178. #define I64_CONST(v) LLVMConstInt(I64_TYPE, v, true)
  179. #define F32_CONST(v) LLVMConstReal(F32_TYPE, v)
  180. #define F64_CONST(v) LLVMConstReal(F64_TYPE, v)
  181. #define I8_CONST(v) LLVMConstInt(INT8_TYPE, v, true)
  182. #define I8_ZERO (comp_ctx->llvm_consts.i8_zero)
  183. #define I32_ZERO (comp_ctx->llvm_consts.i32_zero)
  184. #define I64_ZERO (comp_ctx->llvm_consts.i64_zero)
  185. #define F32_ZERO (comp_ctx->llvm_consts.f32_zero)
  186. #define F64_ZERO (comp_ctx->llvm_consts.f64_zero)
  187. #define I32_ONE (comp_ctx->llvm_consts.i32_one)
  188. #define I32_TWO (comp_ctx->llvm_consts.i32_two)
  189. #define I32_THREE (comp_ctx->llvm_consts.i32_three)
  190. #define I32_FOUR (comp_ctx->llvm_consts.i32_four)
  191. #define I32_EIGHT (comp_ctx->llvm_consts.i32_eight)
  192. #define I32_NEG_ONE (comp_ctx->llvm_consts.i32_neg_one)
  193. #define I64_NEG_ONE (comp_ctx->llvm_consts.i64_neg_one)
  194. #define I32_MIN (comp_ctx->llvm_consts.i32_min)
  195. #define I64_MIN (comp_ctx->llvm_consts.i64_min)
  196. #define I32_31 (comp_ctx->llvm_consts.i32_31)
  197. #define I32_32 (comp_ctx->llvm_consts.i32_32)
  198. #define I64_63 (comp_ctx->llvm_consts.i64_63)
  199. #define I64_64 (comp_ctx->llvm_consts.i64_64)
  200. #define CHECK_LLVM_CONST(v) do { \
  201. if (!v) { \
  202. aot_set_last_error("create llvm const failed."); \
  203. goto fail; \
  204. } \
  205. } while (0)
  206. bool
  207. aot_compile_wasm(AOTCompContext *comp_ctx);
  208. bool
  209. aot_emit_llvm_file(AOTCompContext *comp_ctx, const char *file_name);
  210. bool
  211. aot_emit_aot_file(AOTCompContext *comp_ctx,
  212. AOTCompData *comp_data,
  213. const char *file_name);
  214. bool
  215. aot_emit_object_file(AOTCompContext *comp_ctx, char *file_name);
  216. #ifdef __cplusplus
  217. } /* end of extern "C" */
  218. #endif
  219. #endif /* end of _AOT_COMPILER_H_ */