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(CodeTemplate &&) = default; 15 16 CodeTemplate &CodeTemplate::operator=(CodeTemplate &&) = default; 17 18 InstructionTemplate::InstructionTemplate(const Instruction &Instr) 19 : Instr(Instr), VariableValues(Instr.Variables.size()) {} 20 21 InstructionTemplate::InstructionTemplate(InstructionTemplate &&) = default; 22 23 InstructionTemplate &InstructionTemplate:: 24 operator=(InstructionTemplate &&) = default; 25 26 InstructionTemplate::InstructionTemplate(const InstructionTemplate &) = default; 27 28 InstructionTemplate &InstructionTemplate:: 29 operator=(const InstructionTemplate &) = default; 30 31 unsigned InstructionTemplate::getOpcode() const { 32 return Instr.Description->getOpcode(); 33 } 34 35 llvm::MCOperand &InstructionTemplate::getValueFor(const Variable &Var) { 36 return VariableValues[Var.getIndex()]; 37 } 38 39 const llvm::MCOperand & 40 InstructionTemplate::getValueFor(const Variable &Var) const { 41 return VariableValues[Var.getIndex()]; 42 } 43 44 llvm::MCOperand &InstructionTemplate::getValueFor(const Operand &Op) { 45 return getValueFor(Instr.Variables[Op.getVariableIndex()]); 46 } 47 48 const llvm::MCOperand & 49 InstructionTemplate::getValueFor(const Operand &Op) const { 50 return getValueFor(Instr.Variables[Op.getVariableIndex()]); 51 } 52 53 bool InstructionTemplate::hasImmediateVariables() const { 54 return llvm::any_of(Instr.Variables, [this](const Variable &Var) { 55 return Instr.getPrimaryOperand(Var).isImmediate(); 56 }); 57 } 58 59 llvm::MCInst InstructionTemplate::build() const { 60 llvm::MCInst Result; 61 Result.setOpcode(Instr.Description->Opcode); 62 for (const auto &Op : Instr.Operands) 63 if (Op.isExplicit()) 64 Result.addOperand(getValueFor(Op)); 65 return Result; 66 } 67 68 bool isEnumValue(ExecutionMode Execution) { 69 return llvm::isPowerOf2_32(static_cast<uint32_t>(Execution)); 70 } 71 72 llvm::StringRef getName(ExecutionMode Bit) { 73 assert(isEnumValue(Bit) && "Bit must be a power of two"); 74 switch (Bit) { 75 case ExecutionMode::UNKNOWN: 76 return "UNKNOWN"; 77 case ExecutionMode::ALWAYS_SERIAL_IMPLICIT_REGS_ALIAS: 78 return "ALWAYS_SERIAL_IMPLICIT_REGS_ALIAS"; 79 case ExecutionMode::ALWAYS_SERIAL_TIED_REGS_ALIAS: 80 return "ALWAYS_SERIAL_TIED_REGS_ALIAS"; 81 case ExecutionMode::SERIAL_VIA_MEMORY_INSTR: 82 return "SERIAL_VIA_MEMORY_INSTR"; 83 case ExecutionMode::SERIAL_VIA_EXPLICIT_REGS: 84 return "SERIAL_VIA_EXPLICIT_REGS"; 85 case ExecutionMode::SERIAL_VIA_NON_MEMORY_INSTR: 86 return "SERIAL_VIA_NON_MEMORY_INSTR"; 87 case ExecutionMode::ALWAYS_PARALLEL_MISSING_USE_OR_DEF: 88 return "ALWAYS_PARALLEL_MISSING_USE_OR_DEF"; 89 case ExecutionMode::PARALLEL_VIA_EXPLICIT_REGS: 90 return "PARALLEL_VIA_EXPLICIT_REGS"; 91 } 92 llvm_unreachable("Missing enum case"); 93 } 94 95 llvm::ArrayRef<ExecutionMode> getAllExecutionBits() { 96 static const ExecutionMode kAllExecutionModeBits[] = { 97 ExecutionMode::ALWAYS_SERIAL_IMPLICIT_REGS_ALIAS, 98 ExecutionMode::ALWAYS_SERIAL_TIED_REGS_ALIAS, 99 ExecutionMode::SERIAL_VIA_MEMORY_INSTR, 100 ExecutionMode::SERIAL_VIA_EXPLICIT_REGS, 101 ExecutionMode::SERIAL_VIA_NON_MEMORY_INSTR, 102 ExecutionMode::ALWAYS_PARALLEL_MISSING_USE_OR_DEF, 103 ExecutionMode::PARALLEL_VIA_EXPLICIT_REGS, 104 }; 105 return llvm::makeArrayRef(kAllExecutionModeBits); 106 } 107 108 llvm::SmallVector<ExecutionMode, 4> 109 getExecutionModeBits(ExecutionMode Execution) { 110 llvm::SmallVector<ExecutionMode, 4> Result; 111 for (const auto Bit : getAllExecutionBits()) 112 if ((Execution & Bit) == Bit) 113 Result.push_back(Bit); 114 return Result; 115 } 116 117 } // namespace exegesis 118 } // namespace llvm 119