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 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 static const ExecutionMode kAllExecutionModeBits[] = { 96 ExecutionMode::ALWAYS_SERIAL_IMPLICIT_REGS_ALIAS, 97 ExecutionMode::ALWAYS_SERIAL_TIED_REGS_ALIAS, 98 ExecutionMode::SERIAL_VIA_MEMORY_INSTR, 99 ExecutionMode::SERIAL_VIA_EXPLICIT_REGS, 100 ExecutionMode::SERIAL_VIA_NON_MEMORY_INSTR, 101 ExecutionMode::ALWAYS_PARALLEL_MISSING_USE_OR_DEF, 102 ExecutionMode::PARALLEL_VIA_EXPLICIT_REGS, 103 }; 104 105 llvm::ArrayRef<ExecutionMode> getAllExecutionBits() { 106 return 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