/*
 * Copyright 2026 WebAssembly Community Group participants
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//
// Replaces relaxed SIMD instructions with traps.
//

#include <memory>

#include "ir/localize.h"
#include "ir/utils.h"
#include "pass.h"
#include "wasm-builder.h"
#include "wasm.h"

namespace wasm {

struct RemoveRelaxedSIMD : WalkerPass<PostWalker<RemoveRelaxedSIMD>> {
  bool isFunctionParallel() override { return true; }

  std::unique_ptr<Pass> create() override {
    return std::make_unique<RemoveRelaxedSIMD>();
  }

  void replace(Expression* curr) {
    auto* block =
      ChildLocalizer(curr, getFunction(), *getModule(), getPassOptions())
        .getChildrenReplacement();
    block->list.push_back(Builder(*getModule()).makeUnreachable());
    block->type = Type::unreachable;
    replaceCurrent(block);
  }

  void visitUnary(Unary* curr) {
    switch (curr->op) {
      case RelaxedTruncSVecF32x4ToVecI32x4:
      case RelaxedTruncUVecF32x4ToVecI32x4:
      case RelaxedTruncZeroSVecF64x2ToVecI32x4:
      case RelaxedTruncZeroUVecF64x2ToVecI32x4:
        replace(curr);
        return;
      default:
        break;
    }
  }

  void visitBinary(Binary* curr) {
    switch (curr->op) {
      case RelaxedSwizzleVecI8x16:
      case RelaxedMinVecF32x4:
      case RelaxedMaxVecF32x4:
      case RelaxedMinVecF64x2:
      case RelaxedMaxVecF64x2:
      case RelaxedQ15MulrSVecI16x8:
      case RelaxedDotI8x16I7x16SToVecI16x8:
        replace(curr);
        return;
      default:
        break;
    }
  }

  void visitSIMDTernary(SIMDTernary* curr) {
    switch (curr->op) {
      case RelaxedMaddVecF32x4:
      case RelaxedNmaddVecF32x4:
      case RelaxedMaddVecF64x2:
      case RelaxedNmaddVecF64x2:
      case RelaxedLaneselectI8x16:
      case RelaxedLaneselectI16x8:
      case RelaxedLaneselectI32x4:
      case RelaxedLaneselectI64x2:
      case RelaxedDotI8x16I7x16AddSToVecI32x4:
        replace(curr);
        return;
      default:
        break;
    }
  }

  void visitFunction(Function* func) {
    ReFinalize().walkFunctionInModule(func, getModule());
  }
};

Pass* createRemoveRelaxedSIMDPass() { return new RemoveRelaxedSIMD(); }

} // namespace wasm
