aot_emit_variable.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  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. CHECK_LOCAL(local_idx);
  30. snprintf(name, sizeof(name), "%s%d%s", "local", local_idx, "#");
  31. if (!(value = LLVMBuildLoad(comp_ctx->builder,
  32. func_ctx->locals[local_idx],
  33. name))) {
  34. aot_set_last_error("llvm build load fail");
  35. return false;
  36. }
  37. PUSH(value, get_local_type(func_ctx, local_idx));
  38. return true;
  39. fail:
  40. return false;
  41. }
  42. bool
  43. aot_compile_op_set_local(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  44. uint32 local_idx)
  45. {
  46. LLVMValueRef value;
  47. CHECK_LOCAL(local_idx);
  48. POP(value, get_local_type(func_ctx, local_idx));
  49. if (!LLVMBuildStore(comp_ctx->builder,
  50. value,
  51. func_ctx->locals[local_idx])) {
  52. aot_set_last_error("llvm build store fail");
  53. return false;
  54. }
  55. return true;
  56. fail:
  57. return false;
  58. }
  59. bool
  60. aot_compile_op_tee_local(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  61. uint32 local_idx)
  62. {
  63. LLVMValueRef value;
  64. uint8 type;
  65. CHECK_LOCAL(local_idx);
  66. type = get_local_type(func_ctx, local_idx);
  67. POP(value, type);
  68. if (!LLVMBuildStore(comp_ctx->builder,
  69. value,
  70. func_ctx->locals[local_idx])) {
  71. aot_set_last_error("llvm build store fail");
  72. return false;
  73. }
  74. PUSH(value, type);
  75. return true;
  76. fail:
  77. return false;
  78. }
  79. static bool
  80. compile_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  81. uint32 global_idx, bool is_set)
  82. {
  83. AOTCompData *comp_data = comp_ctx->comp_data;
  84. uint32 import_global_count = comp_data->import_global_count;
  85. uint32 global_base_offset = offsetof(AOTModuleInstance,
  86. global_table_data.bytes);
  87. uint32 global_offset;
  88. uint8 global_type;
  89. LLVMValueRef offset, global_ptr, global;
  90. LLVMTypeRef ptr_type = NULL;
  91. bh_assert(global_idx < import_global_count + comp_data->global_count);
  92. if (global_idx < import_global_count) {
  93. global_offset = global_base_offset
  94. + comp_data->import_globals[global_idx].data_offset;
  95. global_type = comp_data->import_globals[global_idx].type;
  96. }
  97. else {
  98. global_offset = global_base_offset
  99. + comp_data->globals[global_idx - import_global_count].data_offset;
  100. global_type =
  101. comp_data->globals[global_idx - import_global_count].type;
  102. }
  103. offset = I32_CONST(global_offset);
  104. if (!(global_ptr = LLVMBuildInBoundsGEP(comp_ctx->builder, func_ctx->aot_inst,
  105. &offset, 1, "global_ptr_tmp"))) {
  106. aot_set_last_error("llvm build in bounds gep failed.");
  107. return false;
  108. }
  109. switch (global_type) {
  110. case VALUE_TYPE_I32:
  111. ptr_type = comp_ctx->basic_types.int32_ptr_type;
  112. break;
  113. case VALUE_TYPE_I64:
  114. ptr_type = comp_ctx->basic_types.int64_ptr_type;
  115. break;
  116. case VALUE_TYPE_F32:
  117. ptr_type = comp_ctx->basic_types.float32_ptr_type;
  118. break;
  119. case VALUE_TYPE_F64:
  120. ptr_type = comp_ctx->basic_types.float64_ptr_type;
  121. break;
  122. default:
  123. bh_assert(0);
  124. break;
  125. }
  126. if (!(global_ptr = LLVMBuildBitCast(comp_ctx->builder, global_ptr,
  127. ptr_type, "global_ptr"))) {
  128. aot_set_last_error("llvm build bit cast failed.");
  129. return false;
  130. }
  131. if (!is_set) {
  132. if (!(global = LLVMBuildLoad(comp_ctx->builder,
  133. global_ptr, "global"))) {
  134. aot_set_last_error("llvm build load failed.");
  135. return false;
  136. }
  137. PUSH(global, global_type);
  138. }
  139. else {
  140. POP(global, global_type);
  141. if (!LLVMBuildStore(comp_ctx->builder, global, global_ptr)) {
  142. aot_set_last_error("llvm build store failed.");
  143. return false;
  144. }
  145. }
  146. return true;
  147. fail:
  148. return false;
  149. }
  150. bool
  151. aot_compile_op_get_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  152. uint32 global_idx)
  153. {
  154. return compile_global(comp_ctx, func_ctx, global_idx, false);
  155. }
  156. bool
  157. aot_compile_op_set_global(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  158. uint32 global_idx)
  159. {
  160. return compile_global(comp_ctx, func_ctx, global_idx, true);
  161. }