//=- 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/STLExtras.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/MCRegisterInfo.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;

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);
}

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_OFFSET32:
          encodeULEB128(uint32_t(MO.getImm()), OS);
          break;
        case WebAssembly::OPERAND_I64IMM:
          encodeSLEB128(int64_t(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_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 = MCFixupKind(WebAssembly::fixup_sleb128_i32);
          break;
        case WebAssembly::OPERAND_I64IMM:
          FixupKind = MCFixupKind(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 = MCFixupKind(WebAssembly::fixup_uleb128_i32);
          break;
        case WebAssembly::OPERAND_OFFSET64:
          FixupKind = MCFixupKind(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 = MCFixupKind(WebAssembly::fixup_uleb128_i32);
      }
      Fixups.push_back(MCFixup::create(OS.tell() - Start, MO.getExpr(),
                                       FixupKind, MI.getLoc()));
      ++MCNumFixups;
      encodeULEB128(0, OS, PaddedSize);
    } else {
      llvm_unreachable("unexpected operand kind");
    }
  }

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

#include "WebAssemblyGenMCCodeEmitter.inc"
