//===-- 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
