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 //===----------------------------------------------------------------------===//
9 
10 #include "CodeTemplate.h"
11 
12 namespace llvm {
13 namespace exegesis {
14 
15 CodeTemplate::CodeTemplate(CodeTemplate &&) = default;
16 
17 CodeTemplate &CodeTemplate::operator=(CodeTemplate &&) = default;
18 
19 InstructionTemplate::InstructionTemplate(const Instruction &Instr)
20     : Instr(Instr), VariableValues(Instr.Variables.size()) {}
21 
22 InstructionTemplate::InstructionTemplate(InstructionTemplate &&) = default;
23 
24 InstructionTemplate &InstructionTemplate::
25 operator=(InstructionTemplate &&) = default;
26 
27 InstructionTemplate::InstructionTemplate(const InstructionTemplate &) = default;
28 
29 InstructionTemplate &InstructionTemplate::
30 operator=(const InstructionTemplate &) = default;
31 
32 unsigned InstructionTemplate::getOpcode() const {
33   return Instr.Description->getOpcode();
34 }
35 
36 llvm::MCOperand &InstructionTemplate::getValueFor(const Variable &Var) {
37   return VariableValues[Var.getIndex()];
38 }
39 
40 const llvm::MCOperand &
41 InstructionTemplate::getValueFor(const Variable &Var) const {
42   return VariableValues[Var.getIndex()];
43 }
44 
45 llvm::MCOperand &InstructionTemplate::getValueFor(const Operand &Op) {
46   return getValueFor(Instr.Variables[Op.getVariableIndex()]);
47 }
48 
49 const llvm::MCOperand &
50 InstructionTemplate::getValueFor(const Operand &Op) const {
51   return getValueFor(Instr.Variables[Op.getVariableIndex()]);
52 }
53 
54 bool InstructionTemplate::hasImmediateVariables() const {
55   return llvm::any_of(Instr.Variables, [this](const Variable &Var) {
56     return Instr.getPrimaryOperand(Var).isImmediate();
57   });
58 }
59 
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;
67 }
68 
69 bool isEnumValue(ExecutionMode Execution) {
70   return llvm::isPowerOf2_32(static_cast<uint32_t>(Execution));
71 }
72 
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";
92   }
93   llvm_unreachable("Missing enum case");
94 }
95 
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,
105   };
106   return llvm::makeArrayRef(kAllExecutionModeBits);
107 }
108 
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;
116 }
117 
118 } // namespace exegesis
119 } // namespace llvm
120