//===-- CodeTemplate.cpp ----------------------------------------*- C++ -*-===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "CodeTemplate.h"

namespace llvm {
namespace exegesis {

CodeTemplate::CodeTemplate(CodeTemplate &&) = default;

CodeTemplate &CodeTemplate::operator=(CodeTemplate &&) = default;

InstructionTemplate::InstructionTemplate(const Instruction &Instr)
    : Instr(Instr), VariableValues(Instr.Variables.size()) {}

InstructionTemplate::InstructionTemplate(InstructionTemplate &&) = default;

InstructionTemplate &InstructionTemplate::
operator=(InstructionTemplate &&) = default;

InstructionTemplate::InstructionTemplate(const InstructionTemplate &) = default;

InstructionTemplate &InstructionTemplate::
operator=(const InstructionTemplate &) = default;

unsigned InstructionTemplate::getOpcode() const {
  return Instr.Description->getOpcode();
}

MCOperand &InstructionTemplate::getValueFor(const Variable &Var) {
  return VariableValues[Var.getIndex()];
}

const MCOperand &InstructionTemplate::getValueFor(const Variable &Var) const {
  return VariableValues[Var.getIndex()];
}

MCOperand &InstructionTemplate::getValueFor(const Operand &Op) {
  return getValueFor(Instr.Variables[Op.getVariableIndex()]);
}

const MCOperand &InstructionTemplate::getValueFor(const Operand &Op) const {
  return getValueFor(Instr.Variables[Op.getVariableIndex()]);
}

bool InstructionTemplate::hasImmediateVariables() const {
  return any_of(Instr.Variables, [this](const Variable &Var) {
    return Instr.getPrimaryOperand(Var).isImmediate();
  });
}

MCInst InstructionTemplate::build() const {
  MCInst Result;
  Result.setOpcode(Instr.Description->Opcode);
  for (const auto &Op : Instr.Operands)
    if (Op.isExplicit())
      Result.addOperand(getValueFor(Op));
  return Result;
}

bool isEnumValue(ExecutionMode Execution) {
  return isPowerOf2_32(static_cast<uint32_t>(Execution));
}

StringRef getName(ExecutionMode Bit) {
  assert(isEnumValue(Bit) && "Bit must be a power of two");
  switch (Bit) {
  case ExecutionMode::UNKNOWN:
    return "UNKNOWN";
  case ExecutionMode::ALWAYS_SERIAL_IMPLICIT_REGS_ALIAS:
    return "ALWAYS_SERIAL_IMPLICIT_REGS_ALIAS";
  case ExecutionMode::ALWAYS_SERIAL_TIED_REGS_ALIAS:
    return "ALWAYS_SERIAL_TIED_REGS_ALIAS";
  case ExecutionMode::SERIAL_VIA_MEMORY_INSTR:
    return "SERIAL_VIA_MEMORY_INSTR";
  case ExecutionMode::SERIAL_VIA_EXPLICIT_REGS:
    return "SERIAL_VIA_EXPLICIT_REGS";
  case ExecutionMode::SERIAL_VIA_NON_MEMORY_INSTR:
    return "SERIAL_VIA_NON_MEMORY_INSTR";
  case ExecutionMode::ALWAYS_PARALLEL_MISSING_USE_OR_DEF:
    return "ALWAYS_PARALLEL_MISSING_USE_OR_DEF";
  case ExecutionMode::PARALLEL_VIA_EXPLICIT_REGS:
    return "PARALLEL_VIA_EXPLICIT_REGS";
  }
  llvm_unreachable("Missing enum case");
}

ArrayRef<ExecutionMode> getAllExecutionBits() {
  static const ExecutionMode kAllExecutionModeBits[] = {
      ExecutionMode::ALWAYS_SERIAL_IMPLICIT_REGS_ALIAS,
      ExecutionMode::ALWAYS_SERIAL_TIED_REGS_ALIAS,
      ExecutionMode::SERIAL_VIA_MEMORY_INSTR,
      ExecutionMode::SERIAL_VIA_EXPLICIT_REGS,
      ExecutionMode::SERIAL_VIA_NON_MEMORY_INSTR,
      ExecutionMode::ALWAYS_PARALLEL_MISSING_USE_OR_DEF,
      ExecutionMode::PARALLEL_VIA_EXPLICIT_REGS,
  };
  return makeArrayRef(kAllExecutionModeBits);
}

SmallVector<ExecutionMode, 4> getExecutionModeBits(ExecutionMode Execution) {
  SmallVector<ExecutionMode, 4> Result;
  for (const auto Bit : getAllExecutionBits())
    if ((Execution & Bit) == Bit)
      Result.push_back(Bit);
  return Result;
}

} // namespace exegesis
} // namespace llvm
