1 | //===-- CodeTemplate.cpp ----------------------------------------*- C++ -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "CodeTemplate.h" |
10 | |
11 | namespace llvm { |
12 | namespace exegesis { |
13 | |
14 | CodeTemplate::CodeTemplate(const CodeTemplate &) = default; |
15 | |
16 | CodeTemplate::CodeTemplate(CodeTemplate &&) = default; |
17 | |
18 | CodeTemplate &CodeTemplate::operator=(CodeTemplate &&) = default; |
19 | |
20 | CodeTemplate &CodeTemplate::operator=(const CodeTemplate &) = default; |
21 | |
22 | CodeTemplate CodeTemplate::clone() const { |
23 | CodeTemplate CT = *this; |
24 | return CT; |
25 | } |
26 | |
27 | InstructionTemplate::InstructionTemplate(const Instruction *Instr) |
28 | : Instr(Instr), VariableValues(Instr->Variables.size()) {} |
29 | |
30 | InstructionTemplate::InstructionTemplate(InstructionTemplate &&) = default; |
31 | |
32 | InstructionTemplate &InstructionTemplate:: |
33 | operator=(InstructionTemplate &&) = default; |
34 | |
35 | InstructionTemplate::InstructionTemplate(const InstructionTemplate &) = default; |
36 | |
37 | InstructionTemplate &InstructionTemplate:: |
38 | operator=(const InstructionTemplate &) = default; |
39 | |
40 | unsigned InstructionTemplate::getOpcode() const { |
41 | return Instr->Description.getOpcode(); |
42 | } |
43 | |
44 | MCOperand &InstructionTemplate::getValueFor(const Variable &Var) { |
45 | return VariableValues[Var.getIndex()]; |
46 | } |
47 | |
48 | const MCOperand &InstructionTemplate::getValueFor(const Variable &Var) const { |
49 | return VariableValues[Var.getIndex()]; |
50 | } |
51 | |
52 | MCOperand &InstructionTemplate::getValueFor(const Operand &Op) { |
53 | return getValueFor(Var: Instr->Variables[Op.getVariableIndex()]); |
54 | } |
55 | |
56 | const MCOperand &InstructionTemplate::getValueFor(const Operand &Op) const { |
57 | return getValueFor(Var: Instr->Variables[Op.getVariableIndex()]); |
58 | } |
59 | |
60 | bool InstructionTemplate::hasImmediateVariables() const { |
61 | return any_of(Range: Instr->Variables, P: [this](const Variable &Var) { |
62 | return Instr->getPrimaryOperand(Var).isImmediate(); |
63 | }); |
64 | } |
65 | |
66 | MCInst InstructionTemplate::build() const { |
67 | MCInst Result; |
68 | Result.setOpcode(Instr->Description.Opcode); |
69 | for (const auto &Op : Instr->Operands) |
70 | if (Op.isExplicit()) |
71 | Result.addOperand(Op: getValueFor(Op)); |
72 | return Result; |
73 | } |
74 | |
75 | bool isEnumValue(ExecutionMode Execution) { |
76 | return isPowerOf2_32(Value: static_cast<uint32_t>(Execution)); |
77 | } |
78 | |
79 | StringRef getName(ExecutionMode Bit) { |
80 | assert(isEnumValue(Bit) && "Bit must be a power of two" ); |
81 | switch (Bit) { |
82 | case ExecutionMode::UNKNOWN: |
83 | return "UNKNOWN" ; |
84 | case ExecutionMode::ALWAYS_SERIAL_IMPLICIT_REGS_ALIAS: |
85 | return "ALWAYS_SERIAL_IMPLICIT_REGS_ALIAS" ; |
86 | case ExecutionMode::ALWAYS_SERIAL_TIED_REGS_ALIAS: |
87 | return "ALWAYS_SERIAL_TIED_REGS_ALIAS" ; |
88 | case ExecutionMode::SERIAL_VIA_MEMORY_INSTR: |
89 | return "SERIAL_VIA_MEMORY_INSTR" ; |
90 | case ExecutionMode::SERIAL_VIA_EXPLICIT_REGS: |
91 | return "SERIAL_VIA_EXPLICIT_REGS" ; |
92 | case ExecutionMode::SERIAL_VIA_NON_MEMORY_INSTR: |
93 | return "SERIAL_VIA_NON_MEMORY_INSTR" ; |
94 | case ExecutionMode::ALWAYS_PARALLEL_MISSING_USE_OR_DEF: |
95 | return "ALWAYS_PARALLEL_MISSING_USE_OR_DEF" ; |
96 | case ExecutionMode::PARALLEL_VIA_EXPLICIT_REGS: |
97 | return "PARALLEL_VIA_EXPLICIT_REGS" ; |
98 | } |
99 | llvm_unreachable("Missing enum case" ); |
100 | } |
101 | |
102 | ArrayRef<ExecutionMode> getAllExecutionBits() { |
103 | static const ExecutionMode kAllExecutionModeBits[] = { |
104 | ExecutionMode::ALWAYS_SERIAL_IMPLICIT_REGS_ALIAS, |
105 | ExecutionMode::ALWAYS_SERIAL_TIED_REGS_ALIAS, |
106 | ExecutionMode::SERIAL_VIA_MEMORY_INSTR, |
107 | ExecutionMode::SERIAL_VIA_EXPLICIT_REGS, |
108 | ExecutionMode::SERIAL_VIA_NON_MEMORY_INSTR, |
109 | ExecutionMode::ALWAYS_PARALLEL_MISSING_USE_OR_DEF, |
110 | ExecutionMode::PARALLEL_VIA_EXPLICIT_REGS, |
111 | }; |
112 | return ArrayRef(kAllExecutionModeBits); |
113 | } |
114 | |
115 | SmallVector<ExecutionMode, 4> getExecutionModeBits(ExecutionMode Execution) { |
116 | SmallVector<ExecutionMode, 4> Result; |
117 | for (const auto Bit : getAllExecutionBits()) |
118 | if ((Execution & Bit) == Bit) |
119 | Result.push_back(Elt: Bit); |
120 | return Result; |
121 | } |
122 | |
123 | } // namespace exegesis |
124 | } // namespace llvm |
125 | |