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