jit_emit_parametric.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "jit_emit_parametric.h"
  6. #include "../jit_frontend.h"
  7. static bool
  8. pop_value_from_wasm_stack(JitCompContext *cc, bool is_32bit, JitReg *p_value,
  9. uint8 *p_type)
  10. {
  11. JitValue *jit_value;
  12. JitReg value;
  13. uint8 type;
  14. if (!jit_block_stack_top(&cc->block_stack)) {
  15. jit_set_last_error(cc, "WASM block stack underflow.");
  16. return false;
  17. }
  18. if (!jit_block_stack_top(&cc->block_stack)->value_stack.value_list_end) {
  19. jit_set_last_error(cc, "WASM data stack underflow.");
  20. return false;
  21. }
  22. jit_value = jit_value_stack_pop(
  23. &jit_block_stack_top(&cc->block_stack)->value_stack);
  24. type = jit_value->type;
  25. if (p_type != NULL) {
  26. *p_type = jit_value->type;
  27. }
  28. wasm_runtime_free(jit_value);
  29. /* is_32: i32, f32, ref.func, ref.extern, v128 */
  30. if (is_32bit
  31. && !(type == VALUE_TYPE_I32 || type == VALUE_TYPE_F32
  32. #if WASM_ENABLE_REF_TYPES != 0
  33. || type == VALUE_TYPE_FUNCREF || type == VALUE_TYPE_EXTERNREF
  34. #endif
  35. || type == VALUE_TYPE_V128)) {
  36. jit_set_last_error(cc, "invalid WASM stack data type.");
  37. return false;
  38. }
  39. /* !is_32: i64, f64 */
  40. if (!is_32bit && !(type == VALUE_TYPE_I64 || type == VALUE_TYPE_F64)) {
  41. jit_set_last_error(cc, "invalid WASM stack data type.");
  42. return false;
  43. }
  44. switch (type) {
  45. case VALUE_TYPE_I32:
  46. #if WASM_ENABLE_REF_TYPES != 0
  47. case VALUE_TYPE_FUNCREF:
  48. case VALUE_TYPE_EXTERNREF:
  49. #endif
  50. value = pop_i32(cc->jit_frame);
  51. break;
  52. case VALUE_TYPE_I64:
  53. value = pop_i64(cc->jit_frame);
  54. break;
  55. case VALUE_TYPE_F32:
  56. value = pop_f32(cc->jit_frame);
  57. break;
  58. case VALUE_TYPE_F64:
  59. value = pop_f64(cc->jit_frame);
  60. break;
  61. default:
  62. bh_assert(0);
  63. return false;
  64. }
  65. if (p_value != NULL) {
  66. *p_value = value;
  67. }
  68. return true;
  69. }
  70. bool
  71. jit_compile_op_drop(JitCompContext *cc, bool is_drop_32)
  72. {
  73. if (!pop_value_from_wasm_stack(cc, is_drop_32, NULL, NULL))
  74. return false;
  75. return true;
  76. }
  77. bool
  78. jit_compile_op_select(JitCompContext *cc, bool is_select_32)
  79. {
  80. JitReg val1, val2, cond, selected;
  81. uint8 val1_type, val2_type;
  82. POP_I32(cond);
  83. if (!pop_value_from_wasm_stack(cc, is_select_32, &val2, &val2_type)
  84. || !pop_value_from_wasm_stack(cc, is_select_32, &val1, &val1_type)) {
  85. return false;
  86. }
  87. if (val1_type != val2_type) {
  88. jit_set_last_error(cc, "invalid stack values with different type");
  89. return false;
  90. }
  91. switch (val1_type) {
  92. case VALUE_TYPE_I32:
  93. selected = jit_cc_new_reg_I32(cc);
  94. break;
  95. case VALUE_TYPE_I64:
  96. selected = jit_cc_new_reg_I64(cc);
  97. break;
  98. case VALUE_TYPE_F32:
  99. selected = jit_cc_new_reg_F32(cc);
  100. break;
  101. case VALUE_TYPE_F64:
  102. selected = jit_cc_new_reg_F64(cc);
  103. break;
  104. default:
  105. bh_assert(0);
  106. return false;
  107. }
  108. GEN_INSN(CMP, cc->cmp_reg, cond, NEW_CONST(I32, 0));
  109. GEN_INSN(SELECTNE, selected, cc->cmp_reg, val1, val2);
  110. PUSH(selected, val1_type);
  111. return true;
  112. fail:
  113. return false;
  114. }