//===-- 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(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 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 getExecutionModeBits(ExecutionMode Execution) { SmallVector Result; for (const auto Bit : getAllExecutionBits()) if ((Execution & Bit) == Bit) Result.push_back(Bit); return Result; } } // namespace exegesis } // namespace llvm