1 //===-- LlvmState.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 "LlvmState.h" 10 #include "Target.h" 11 #include "llvm/ADT/SmallVector.h" 12 #include "llvm/MC/MCCodeEmitter.h" 13 #include "llvm/MC/MCContext.h" 14 #include "llvm/MC/MCFixup.h" 15 #include "llvm/MC/MCObjectFileInfo.h" 16 #include "llvm/Support/Host.h" 17 #include "llvm/Support/TargetRegistry.h" 18 #include "llvm/Support/raw_ostream.h" 19 #include "llvm/Target/TargetMachine.h" 20 #include "llvm/Target/TargetOptions.h" 21 22 namespace llvm { 23 namespace exegesis { 24 25 LLVMState::LLVMState(const std::string &Triple, const std::string &CpuName, 26 const std::string &Features) { 27 std::string Error; 28 const Target *const TheTarget = TargetRegistry::lookupTarget(Triple, Error); 29 assert(TheTarget && "unknown target for host"); 30 const TargetOptions Options; 31 TheTargetMachine.reset( 32 static_cast<LLVMTargetMachine *>(TheTarget->createTargetMachine( 33 Triple, CpuName, Features, Options, Reloc::Model::Static))); 34 assert(TheTargetMachine && "unable to create target machine"); 35 TheExegesisTarget = ExegesisTarget::lookup(TheTargetMachine->getTargetTriple()); 36 if (!TheExegesisTarget) { 37 errs() << "no exegesis target for " << Triple << ", using default\n"; 38 TheExegesisTarget = &ExegesisTarget::getDefault(); 39 } 40 PfmCounters = &TheExegesisTarget->getPfmCounters(CpuName); 41 42 BitVector ReservedRegs = getFunctionReservedRegs(getTargetMachine()); 43 for (const unsigned Reg : TheExegesisTarget->getUnavailableRegisters()) 44 ReservedRegs.set(Reg); 45 RATC.reset( 46 new RegisterAliasingTrackerCache(getRegInfo(), std::move(ReservedRegs))); 47 IC.reset(new InstructionsCache(getInstrInfo(), getRATC())); 48 } 49 50 LLVMState::LLVMState(const std::string &CpuName) 51 : LLVMState(sys::getProcessTriple(), 52 CpuName.empty() ? sys::getHostCPUName().str() : CpuName, "") {} 53 54 std::unique_ptr<LLVMTargetMachine> LLVMState::createTargetMachine() const { 55 return std::unique_ptr<LLVMTargetMachine>(static_cast<LLVMTargetMachine *>( 56 TheTargetMachine->getTarget().createTargetMachine( 57 TheTargetMachine->getTargetTriple().normalize(), 58 TheTargetMachine->getTargetCPU(), 59 TheTargetMachine->getTargetFeatureString(), TheTargetMachine->Options, 60 Reloc::Model::Static))); 61 } 62 63 bool LLVMState::canAssemble(const MCInst &Inst) const { 64 MCContext Context(TheTargetMachine->getTargetTriple(), 65 TheTargetMachine->getMCAsmInfo(), 66 TheTargetMachine->getMCRegisterInfo(), 67 TheTargetMachine->getMCSubtargetInfo()); 68 std::unique_ptr<const MCCodeEmitter> CodeEmitter( 69 TheTargetMachine->getTarget().createMCCodeEmitter( 70 *TheTargetMachine->getMCInstrInfo(), *TheTargetMachine->getMCRegisterInfo(), 71 Context)); 72 assert(CodeEmitter && "unable to create code emitter"); 73 SmallVector<char, 16> Tmp; 74 raw_svector_ostream OS(Tmp); 75 SmallVector<MCFixup, 4> Fixups; 76 CodeEmitter->encodeInstruction(Inst, OS, Fixups, 77 *TheTargetMachine->getMCSubtargetInfo()); 78 return Tmp.size() > 0; 79 } 80 81 } // namespace exegesis 82 } // namespace llvm 83