//=- WebAssemblyMCCodeEmitter.cpp - Convert WebAssembly code to machine code -//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements the WebAssemblyMCCodeEmitter class.
///
//===----------------------------------------------------------------------===//

#include "MCTargetDesc/WebAssemblyFixupKinds.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCFixup.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/EndianStream.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;

#define DEBUG_TYPE "mccodeemitter"

STATISTIC(MCNumEmitted, "Number of MC instructions emitted.");
STATISTIC(MCNumFixups, "Number of MC fixups created.");

namespace {
class WebAssemblyMCCodeEmitter final : public MCCodeEmitter {
  const MCInstrInfo &MCII;
  MCContext &Ctx;
  // Implementation generated by tablegen.
  uint64_t getBinaryCodeForInstr(const MCInst &MI,
                                 SmallVectorImpl<MCFixup> &Fixups,
                                 const MCSubtargetInfo &STI) const;

  void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB,
                         SmallVectorImpl<MCFixup> &Fixups,
                         const MCSubtargetInfo &STI) const override;

  void encodeP2AlignAndMemOrder(const MCInst &MI, unsigned P2AlignIdx,
                                const MCInstrDesc &Desc,
                                const MCSubtargetInfo &STI, raw_ostream &OS,
                                SmallVectorImpl<MCFixup> &Fixups,
                                uint64_t Start) const;

  uint8_t getEncodedMemOrder(uint8_t Order, unsigned Opcode) const;

public:
  WebAssemblyMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)
      : MCII(MCII), Ctx{Ctx} {}
};
} // end anonymous namespace

MCCodeEmitter *llvm::createWebAssemblyMCCodeEmitter(const MCInstrInfo &MCII,
                                                    MCContext &Ctx) {
  return new WebAssemblyMCCodeEmitter(MCII, Ctx);
}

uint8_t WebAssemblyMCCodeEmitter::getEncodedMemOrder(uint8_t Order,
                                                     unsigned Opcode) const {
  if (Order == wasm::WASM_MEM_ORDER_ACQ_REL) {
    StringRef Name = MCII.getName(Opcode);
    if (Name.contains("RMW") || Name.contains("CMPXCHG"))
      return wasm::WASM_MEM_ORDER_RMW_ACQ_REL;
  }
  return Order;
}

void WebAssemblyMCCodeEmitter::encodeP2AlignAndMemOrder(
    const MCInst &MI, unsigned P2AlignIdx, const MCInstrDesc &Desc,
    const MCSubtargetInfo &STI, raw_ostream &OS,
    SmallVectorImpl<MCFixup> &Fixups, uint64_t Start) const {
  uint64_t P2Align = MI.getOperand(P2AlignIdx).getImm();
  uint8_t Order = wasm::WASM_MEM_ORDER_SEQ_CST;

  // Atomic instructions always have an ordering, but if it's SEQ_CST then we
  // don't use the relaxed-atomics encoding (even if relaxed-atomics is
  // enabled) because the original encoding is smaller.
  if (P2AlignIdx > 0 && Desc.operands()[P2AlignIdx - 1].OperandType ==
                            WebAssembly::OPERAND_MEMORDER) {
    Order = MI.getOperand(P2AlignIdx - 1).getImm();
    if (Order != wasm::WASM_MEM_ORDER_SEQ_CST) {
      assert(STI.getFeatureBits()[WebAssembly::FeatureRelaxedAtomics] &&
             "Non-default atomic ordering but feature not enabled");
      P2Align |= wasm::WASM_MEMARG_HAS_MEM_ORDER;
    }
  }

  encodeULEB128(P2Align, OS);

  // Memory index will go here once we support multi-memory.

  if (P2Align & wasm::WASM_MEMARG_HAS_MEM_ORDER) {
    support::endian::write<uint8_t>(OS,
                                    getEncodedMemOrder(Order, MI.getOpcode()),
                                    llvm::endianness::little);
  }
}

void WebAssemblyMCCodeEmitter::encodeInstruction(
    const MCInst &MI, SmallVectorImpl<char> &CB,
    SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const {
  raw_svector_ostream OS(CB);
  uint64_t Start = OS.tell();

  uint64_t Binary = getBinaryCodeForInstr(MI, Fixups, STI);
  if (Binary < (1 << 8)) {
    OS << uint8_t(Binary);
  } else if (Binary < (1 << 16)) {
    OS << uint8_t(Binary >> 8);
    encodeULEB128(uint8_t(Binary), OS);
  } else if (Binary < (1 << 24)) {
    OS << uint8_t(Binary >> 16);
    encodeULEB128(uint16_t(Binary), OS);
  } else {
    llvm_unreachable("Very large (prefix + 3 byte) opcodes not supported");
  }

  // For br_table instructions, encode the size of the table. In the MCInst,
  // there's an index operand (if not a stack instruction), one operand for
  // each table entry, and the default operand.
  unsigned Opcode = MI.getOpcode();
  if (Opcode == WebAssembly::BR_TABLE_I32_S ||
      Opcode == WebAssembly::BR_TABLE_I64_S)
    encodeULEB128(MI.getNumOperands() - 1, OS);
  if (Opcode == WebAssembly::BR_TABLE_I32 ||
      Opcode == WebAssembly::BR_TABLE_I64)
    encodeULEB128(MI.getNumOperands() - 2, OS);

  const MCInstrDesc &Desc = MCII.get(Opcode);
  for (unsigned I = 0, E = MI.getNumOperands(); I < E; ++I) {
    const MCOperand &MO = MI.getOperand(I);
    if (MO.isReg()) {
      /* nothing to encode */

    } else if (MO.isImm()) {
      if (I < Desc.getNumOperands()) {
        const MCOperandInfo &Info = Desc.operands()[I];
        LLVM_DEBUG(dbgs() << "Encoding immediate: type="
                          << int(Info.OperandType) << "\n");
        switch (Info.OperandType) {
        case WebAssembly::OPERAND_I32IMM:
          encodeSLEB128(int32_t(MO.getImm()), OS);
          break;
        case WebAssembly::OPERAND_P2ALIGN:
          encodeP2AlignAndMemOrder(MI, I, Desc, STI, OS, Fixups, Start);
          break;
        case WebAssembly::OPERAND_OFFSET32:
          encodeULEB128(uint32_t(MO.getImm()), OS);
          break;
        case WebAssembly::OPERAND_I64IMM:
          encodeSLEB128(MO.getImm(), OS);
          break;
        case WebAssembly::OPERAND_SIGNATURE:
        case WebAssembly::OPERAND_VEC_I8IMM:
          support::endian::write<uint8_t>(OS, MO.getImm(),
                                          llvm::endianness::little);
          break;
        case WebAssembly::OPERAND_VALTYPE_LIST: {
          // A vec of valtypes: emit the ULEB count followed by that many
          // single-byte value types. The count lives in this MCOperand;
          // subsequent MCOperands hold the valtype bytes and are consumed here.
          uint64_t Count = uint64_t(MO.getImm());
          if (Count > uint64_t(E - I - 1))
            report_fatal_error(
                "select t* operand count exceeds MCInst operand count");
          encodeULEB128(Count, OS);
          for (uint64_t K = 0; K < Count; ++K) {
            ++I;
            int64_t Val = MI.getOperand(I).getImm();
            assert(isUInt<8>(Val) && "select t* valtype out of byte range");
            support::endian::write<uint8_t>(OS, Val, llvm::endianness::little);
          }
          break;
        }
        case WebAssembly::OPERAND_MEMORDER: {
          // If there is a p2align operand (everything but fence) it is encoded
          // together with the mem ordering (in the next iteration).
          if (I + 1 < Desc.getNumOperands() &&
              Desc.operands()[I + 1].OperandType ==
                  WebAssembly::OPERAND_P2ALIGN)
            break;
          uint8_t Val = getEncodedMemOrder(MO.getImm(), Opcode);
          if (STI.getFeatureBits()[WebAssembly::FeatureRelaxedAtomics]) {
            support::endian::write<uint8_t>(OS, Val, llvm::endianness::little);
          } else {
            assert(Opcode == WebAssembly::ATOMIC_FENCE_S);
            support::endian::write<uint8_t>(OS, 0, llvm::endianness::little);
          }
          break;
        }
        case WebAssembly::OPERAND_VEC_I16IMM:
          support::endian::write<uint16_t>(OS, MO.getImm(),
                                           llvm::endianness::little);
          break;
        case WebAssembly::OPERAND_VEC_I32IMM:
          support::endian::write<uint32_t>(OS, MO.getImm(),
                                           llvm::endianness::little);
          break;
        case WebAssembly::OPERAND_VEC_I64IMM:
          support::endian::write<uint64_t>(OS, MO.getImm(),
                                           llvm::endianness::little);
          break;
        case WebAssembly::OPERAND_GLOBAL:
          Ctx.reportError(
              SMLoc(),
              Twine("Wasm globals should only be accessed symbolically!"));
          break;
        default:
          encodeULEB128(uint64_t(MO.getImm()), OS);
        }
      } else {
        // Variadic immediate operands are br_table's destination operands or
        // try_table's operands (# of catch clauses, catch sub-opcodes, or catch
        // clause destinations)
        assert(WebAssembly::isBrTable(Opcode) ||
               Opcode == WebAssembly::TRY_TABLE_S);
        encodeULEB128(uint32_t(MO.getImm()), OS);
      }

    } else if (MO.isSFPImm()) {
      uint32_t F = MO.getSFPImm();
      support::endian::write<uint32_t>(OS, F, llvm::endianness::little);
    } else if (MO.isDFPImm()) {
      uint64_t D = MO.getDFPImm();
      support::endian::write<uint64_t>(OS, D, llvm::endianness::little);
    } else if (MO.isExpr()) {
      llvm::MCFixupKind FixupKind;
      size_t PaddedSize = 5;
      if (I < Desc.getNumOperands()) {
        const MCOperandInfo &Info = Desc.operands()[I];
        switch (Info.OperandType) {
        case WebAssembly::OPERAND_I32IMM:
          FixupKind = WebAssembly::fixup_sleb128_i32;
          break;
        case WebAssembly::OPERAND_I64IMM:
          FixupKind = WebAssembly::fixup_sleb128_i64;
          PaddedSize = 10;
          break;
        case WebAssembly::OPERAND_FUNCTION32:
        case WebAssembly::OPERAND_TABLE:
        case WebAssembly::OPERAND_OFFSET32:
        case WebAssembly::OPERAND_SIGNATURE:
        case WebAssembly::OPERAND_TYPEINDEX:
        case WebAssembly::OPERAND_GLOBAL:
        case WebAssembly::OPERAND_TAG:
          FixupKind = WebAssembly::fixup_uleb128_i32;
          break;
        case WebAssembly::OPERAND_OFFSET64:
          FixupKind = WebAssembly::fixup_uleb128_i64;
          PaddedSize = 10;
          break;
        default:
          llvm_unreachable("unexpected symbolic operand kind");
        }
      } else {
        // Variadic expr operands are try_table's catch/catch_ref clauses' tags.
        assert(Opcode == WebAssembly::TRY_TABLE_S);
        FixupKind = WebAssembly::fixup_uleb128_i32;
      }
      Fixups.push_back(
          MCFixup::create(OS.tell() - Start, MO.getExpr(), FixupKind));
      ++MCNumFixups;
      encodeULEB128(0, OS, PaddedSize);
    } else {
      llvm_unreachable("unexpected operand kind");
    }
  }

  ++MCNumEmitted; // Keep track of the # of mi's emitted.
}

#include "WebAssemblyGenMCCodeEmitter.inc"
