[llvm-exegesis] Implements a cache of Instruction objects.
[llvm-core.git] / tools / llvm-exegesis / lib / CodeTemplate.cpp
blobe159b000755acbec6a11516c5b406fee29d0296f
1 //===-- CodeTemplate.cpp ----------------------------------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
10 #include "CodeTemplate.h"
12 namespace llvm {
13 namespace exegesis {
15 CodeTemplate::CodeTemplate(CodeTemplate &&) = default;
17 CodeTemplate &CodeTemplate::operator=(CodeTemplate &&) = default;
19 InstructionTemplate::InstructionTemplate(const Instruction &Instr)
20 : Instr(Instr), VariableValues(Instr.Variables.size()) {}
22 InstructionTemplate::InstructionTemplate(InstructionTemplate &&) = default;
24 InstructionTemplate &InstructionTemplate::
25 operator=(InstructionTemplate &&) = default;
27 InstructionTemplate::InstructionTemplate(const InstructionTemplate &) = default;
29 InstructionTemplate &InstructionTemplate::
30 operator=(const InstructionTemplate &) = default;
32 unsigned InstructionTemplate::getOpcode() const {
33 return Instr.Description->getOpcode();
36 llvm::MCOperand &InstructionTemplate::getValueFor(const Variable &Var) {
37 return VariableValues[Var.getIndex()];
40 const llvm::MCOperand &
41 InstructionTemplate::getValueFor(const Variable &Var) const {
42 return VariableValues[Var.getIndex()];
45 llvm::MCOperand &InstructionTemplate::getValueFor(const Operand &Op) {
46 return getValueFor(Instr.Variables[Op.getVariableIndex()]);
49 const llvm::MCOperand &
50 InstructionTemplate::getValueFor(const Operand &Op) const {
51 return getValueFor(Instr.Variables[Op.getVariableIndex()]);
54 bool InstructionTemplate::hasImmediateVariables() const {
55 return llvm::any_of(Instr.Variables, [this](const Variable &Var) {
56 return Instr.getPrimaryOperand(Var).isImmediate();
57 });
60 llvm::MCInst InstructionTemplate::build() const {
61 llvm::MCInst Result;
62 Result.setOpcode(Instr.Description->Opcode);
63 for (const auto &Op : Instr.Operands)
64 if (Op.isExplicit())
65 Result.addOperand(getValueFor(Op));
66 return Result;
69 bool isEnumValue(ExecutionMode Execution) {
70 return llvm::isPowerOf2_32(static_cast<uint32_t>(Execution));
73 llvm::StringRef getName(ExecutionMode Bit) {
74 assert(isEnumValue(Bit) && "Bit must be a power of two");
75 switch (Bit) {
76 case ExecutionMode::UNKNOWN:
77 return "UNKNOWN";
78 case ExecutionMode::ALWAYS_SERIAL_IMPLICIT_REGS_ALIAS:
79 return "ALWAYS_SERIAL_IMPLICIT_REGS_ALIAS";
80 case ExecutionMode::ALWAYS_SERIAL_TIED_REGS_ALIAS:
81 return "ALWAYS_SERIAL_TIED_REGS_ALIAS";
82 case ExecutionMode::SERIAL_VIA_MEMORY_INSTR:
83 return "SERIAL_VIA_MEMORY_INSTR";
84 case ExecutionMode::SERIAL_VIA_EXPLICIT_REGS:
85 return "SERIAL_VIA_EXPLICIT_REGS";
86 case ExecutionMode::SERIAL_VIA_NON_MEMORY_INSTR:
87 return "SERIAL_VIA_NON_MEMORY_INSTR";
88 case ExecutionMode::ALWAYS_PARALLEL_MISSING_USE_OR_DEF:
89 return "ALWAYS_PARALLEL_MISSING_USE_OR_DEF";
90 case ExecutionMode::PARALLEL_VIA_EXPLICIT_REGS:
91 return "PARALLEL_VIA_EXPLICIT_REGS";
93 llvm_unreachable("Missing enum case");
96 llvm::ArrayRef<ExecutionMode> getAllExecutionBits() {
97 static const ExecutionMode kAllExecutionModeBits[] = {
98 ExecutionMode::ALWAYS_SERIAL_IMPLICIT_REGS_ALIAS,
99 ExecutionMode::ALWAYS_SERIAL_TIED_REGS_ALIAS,
100 ExecutionMode::SERIAL_VIA_MEMORY_INSTR,
101 ExecutionMode::SERIAL_VIA_EXPLICIT_REGS,
102 ExecutionMode::SERIAL_VIA_NON_MEMORY_INSTR,
103 ExecutionMode::ALWAYS_PARALLEL_MISSING_USE_OR_DEF,
104 ExecutionMode::PARALLEL_VIA_EXPLICIT_REGS,
106 return llvm::makeArrayRef(kAllExecutionModeBits);
109 llvm::SmallVector<ExecutionMode, 4>
110 getExecutionModeBits(ExecutionMode Execution) {
111 llvm::SmallVector<ExecutionMode, 4> Result;
112 for (const auto Bit : getAllExecutionBits())
113 if ((Execution & Bit) == Bit)
114 Result.push_back(Bit);
115 return Result;
118 } // namespace exegesis
119 } // namespace llvm