aot_emit_variable.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "aot_emit_variable.h"
  6. #include "../aot/aot_runtime.h"
  7. #define CHECK_LOCAL(idx) do { \
  8. if (idx >= func_ctx->aot_func->func_type->param_count \
  9. + func_ctx->aot_func->local_count) { \
  10. aot_set_last_error("local index out of range"); \
  11. return false; \
  12. } \
  13. } while (0)
  14. static uint8
  15. get_local_type(AOTFuncContext *func_ctx, uint32 local_idx)
  16. {
  17. AOTFunc *aot_func = func_ctx->aot_func;
  18. uint32 param_count = aot_func->func_type->param_count;
  19. return local_idx < param_count
  20. ? aot_func->func_type->types[local_idx]
  21. : aot_func->local_types[local_idx - param_count];
  22. }
  23. bool
  24. aot_compile_op_get_local(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  25. uint32 local_idx)
  26. {
  27. char name[32];
  28. LLVMValueRef value;
  29. AOTValue *aot_value;
  30. CHECK_LOCAL(local_idx);
  31. snprintf(name, sizeof(name), "%s%d%s", "local", local_idx, "#");
  32. if (!(value = LLVMBuildLoad(comp_ctx->builder,
  33. func_ctx->locals[local_idx],
  34. name))) {
  35. aot_set_last_error("llvm build load fail");
  36. return false;
  37. }
  38. PUSH(value, get_local_type(func_ctx, local_idx));
  39. aot_value = func_ctx->block_stack.block_list_end->value_stack.value_list_end;
  40. aot_value->is_local = true;
  41. aot_value->local_idx = local_idx;
  42. return true;
  43. fail:
  44. return false;
  45. }
  46. bool
  47. aot_compile_op_set_local(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  48. uint32 local_idx)
  49. {
  50. LLVMValueRef value;
  51. CHECK_LOCAL(local_idx);
  52. POP(value, get_local_type(func_ctx, local_idx));
  53. if (!LLVMBuildStore(comp_ctx->builder,
  54. value,
  55. func_ctx->locals[local_idx])) {
  56. aot_set_last_error("llvm build store fail");
  57. return false;
  58. }
  59. aot_checked_addr_list_del(func_ctx, local_idx);
  60. return true;
  61. fail:
  62. return false;
  63. }
  64. bool
  65. aot_compile_op_tee_local(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  66. uint32 local_idx)
  67. {
  68. LLVMValueRef value;
  69. uint8 type;
  70. CHECK_LOCAL(local_idx);
  71. type = get_local_type(func_ctx, local_idx);
  72. POP(value, type);
  73. if (!LLVMBuildStore(comp_ctx->builder,
  74. value,
  75. func_ctx->locals[local_idx])) {
  76. aot_set_last_error("llvm build store fail");
  77. return false;
  78. }
  79. PUSH(value, type);
  80. aot_checked_addr_list_del(func_ctx, local_idx);
  81. return true;
  82. fail:
  83. return false;
  84. }
  85. static bool
  86. compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  87. uint32 global_idx, bool is_set)
  88. {
  89. AOTCompData *comp_data = comp_ctx->comp_data;
  90. uint32 import_global_count = comp_data->import_global_count;
  91. uint32 global_base_offset =
  92. offsetof(AOTModuleInstance, global_table_data.bytes)
  93. + sizeof(AOTMemoryInstance) * comp_ctx->comp_data->memory_count;
  94. uint32 global_offset;
  95. uint8 global_type;
  96. LLVMValueRef offset, global_ptr, global, res;
  97. LLVMTypeRef ptr_type = NULL;
  98. bh_assert(global_idx < import_global_count + comp_data->global_count);
  99. if (global_idx < import_global_count) {
  100. global_offset = global_base_offset
  101. + comp_data->import_globals[global_idx].data_offset;
  102. global_type = comp_data->import_globals[global_idx].type;
  103. }
  104. else {
  105. global_offset = global_base_offset
  106. + comp_data->globals[global_idx - import_global_count].data_offset;
  107. global_type =
  108. comp_data->globals[global_idx - import_global_count].type;
  109. }
  110. offset = I32_CONST(global_offset);
  111. if (!(global_ptr = LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
  112. &offset, 1, "global_ptr_tmp"))) {
  113. aot_set_last_error("llvm build in bounds gep failed.");
  114. return false;
  115. }
  116. switch (global_type) {
  117. case VALUE_TYPE_I32:
  118. ptr_type = comp_ctx->basic_types.int32_ptr_type;
  119. break;
  120. case VALUE_TYPE_I64:
  121. ptr_type = comp_ctx->basic_types.int64_ptr_type;
  122. break;
  123. case VALUE_TYPE_F32:
  124. ptr_type = comp_ctx->basic_types.float32_ptr_type;
  125. break;
  126. case VALUE_TYPE_F64:
  127. ptr_type = comp_ctx->basic_types.float64_ptr_type;
  128. break;
  129. case VALUE_TYPE_V128:
  130. ptr_type = comp_ctx->basic_types.v128_ptr_type;
  131. break;
  132. default:
  133. bh_assert(0);
  134. break;
  135. }
  136. if (!(global_ptr = LLVMBuildBitCast(comp_ctx->builder, global_ptr,
  137. ptr_type, "global_ptr"))) {
  138. aot_set_last_error("llvm build bit cast failed.");
  139. return false;
  140. }
  141. if (!is_set) {
  142. if (!(global = LLVMBuildLoad(comp_ctx->builder,
  143. global_ptr, "global"))) {
  144. aot_set_last_error("llvm build load failed.");
  145. return false;
  146. }
  147. /* All globals' data is 4-byte aligned */
  148. LLVMSetAlignment(global, 4);
  149. PUSH(global, global_type);
  150. }
  151. else {
  152. POP(global, global_type);
  153. if (!(res = LLVMBuildStore(comp_ctx->builder,
  154. global, global_ptr))) {
  155. aot_set_last_error("llvm build store failed.");
  156. return false;
  157. }
  158. /* All globals' data is 4-byte aligned */
  159. LLVMSetAlignment(res, 4);
  160. }
  161. return true;
  162. fail:
  163. return false;
  164. }
  165. bool
  166. aot_compile_op_get_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  167. uint32 global_idx)
  168. {
  169. return compile_global(comp_ctx, func_ctx, global_idx, false);
  170. }
  171. bool
  172. aot_compile_op_set_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  173. uint32 global_idx)
  174. {
  175. return compile_global(comp_ctx, func_ctx, global_idx, true);
  176. }