simd_bitwise_ops.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "simd_bitwise_ops.h"
  6. #include "../aot_emit_exception.h"
  7. #include "../../aot/aot_runtime.h"
  8. static bool
  9. v128_bitwise_two_component(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx,
  10. V128Bitwise bitwise_op)
  11. {
  12. LLVMValueRef vector1, vector2, result;
  13. POP_V128(vector2);
  14. POP_V128(vector1);
  15. switch (bitwise_op) {
  16. case V128_AND:
  17. if (!(result = LLVMBuildAnd(comp_ctx->builder, vector1, vector2,
  18. "and"))) {
  19. HANDLE_FAILURE("LLVMBuildAnd");
  20. goto fail;
  21. }
  22. break;
  23. case V128_OR:
  24. if (!(result =
  25. LLVMBuildOr(comp_ctx->builder, vector1, vector2, "or"))) {
  26. HANDLE_FAILURE("LLVMBuildAnd");
  27. goto fail;
  28. }
  29. break;
  30. case V128_XOR:
  31. if (!(result = LLVMBuildXor(comp_ctx->builder, vector1, vector2,
  32. "xor"))) {
  33. HANDLE_FAILURE("LLVMBuildAnd");
  34. goto fail;
  35. }
  36. break;
  37. case V128_ANDNOT:
  38. {
  39. /* v128.and(a, v128.not(b)) */
  40. if (!(vector2 = LLVMBuildNot(comp_ctx->builder, vector2, "not"))) {
  41. HANDLE_FAILURE("LLVMBuildNot");
  42. goto fail;
  43. }
  44. if (!(result = LLVMBuildAnd(comp_ctx->builder, vector1, vector2,
  45. "and"))) {
  46. HANDLE_FAILURE("LLVMBuildAnd");
  47. goto fail;
  48. }
  49. break;
  50. }
  51. default:
  52. bh_assert(0);
  53. goto fail;
  54. }
  55. PUSH_V128(result);
  56. return true;
  57. fail:
  58. return false;
  59. }
  60. static bool
  61. v128_bitwise_not(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
  62. {
  63. LLVMValueRef vector, result;
  64. POP_V128(vector);
  65. if (!(result = LLVMBuildNot(comp_ctx->builder, vector, "not"))) {
  66. HANDLE_FAILURE("LLVMBuildNot");
  67. goto fail;
  68. }
  69. PUSH_V128(result);
  70. return true;
  71. fail:
  72. return false;
  73. }
  74. /* v128.or(v128.and(v1, c), v128.and(v2, v128.not(c))) */
  75. static bool
  76. v128_bitwise_bitselect(AOTCompContext *comp_ctx, AOTFuncContext *func_ctx)
  77. {
  78. LLVMValueRef vector1, vector2, vector3, result;
  79. POP_V128(vector3);
  80. POP_V128(vector2);
  81. POP_V128(vector1);
  82. if (!(vector1 =
  83. LLVMBuildAnd(comp_ctx->builder, vector1, vector3, "a_and_c"))) {
  84. HANDLE_FAILURE("LLVMBuildAdd");
  85. goto fail;
  86. }
  87. if (!(vector3 = LLVMBuildNot(comp_ctx->builder, vector3, "not_c"))) {
  88. HANDLE_FAILURE("LLVMBuildNot");
  89. goto fail;
  90. }
  91. if (!(vector2 =
  92. LLVMBuildAnd(comp_ctx->builder, vector2, vector3, "b_and_c"))) {
  93. HANDLE_FAILURE("LLVMBuildAdd");
  94. goto fail;
  95. }
  96. if (!(result =
  97. LLVMBuildOr(comp_ctx->builder, vector1, vector2, "a_or_b"))) {
  98. HANDLE_FAILURE("LLVMBuildOr");
  99. goto fail;
  100. }
  101. PUSH_V128(result);
  102. return true;
  103. fail:
  104. return false;
  105. }
  106. bool
  107. aot_compile_simd_v128_bitwise(AOTCompContext *comp_ctx,
  108. AOTFuncContext *func_ctx, V128Bitwise bitwise_op)
  109. {
  110. switch (bitwise_op) {
  111. case V128_AND:
  112. case V128_OR:
  113. case V128_XOR:
  114. case V128_ANDNOT:
  115. return v128_bitwise_two_component(comp_ctx, func_ctx, bitwise_op);
  116. case V128_NOT:
  117. return v128_bitwise_not(comp_ctx, func_ctx);
  118. case V128_BITSELECT:
  119. return v128_bitwise_bitselect(comp_ctx, func_ctx);
  120. default:
  121. bh_assert(0);
  122. return false;
  123. }
  124. }