simd_bitwise_ops.c 3.7 KB

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