123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145 |
- //===-- LlvmState.cpp -------------------------------------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- #include "LlvmState.h"
- #include "Target.h"
- #include "llvm/ADT/SmallVector.h"
- #include "llvm/MC/MCCodeEmitter.h"
- #include "llvm/MC/MCContext.h"
- #include "llvm/MC/MCFixup.h"
- #include "llvm/MC/MCObjectFileInfo.h"
- #include "llvm/MC/TargetRegistry.h"
- #include "llvm/Support/Host.h"
- #include "llvm/Support/raw_ostream.h"
- #include "llvm/Target/TargetMachine.h"
- #include "llvm/Target/TargetOptions.h"
- namespace llvm {
- namespace exegesis {
- Expected<LLVMState> LLVMState::Create(std::string TripleName,
- std::string CpuName,
- const StringRef Features) {
- if (TripleName.empty())
- TripleName = Triple::normalize(sys::getDefaultTargetTriple());
- Triple TheTriple(TripleName);
- // Get the target specific parser.
- std::string Error;
- const Target *TheTarget =
- TargetRegistry::lookupTarget(/*MArch=*/"", TheTriple, Error);
- if (!TheTarget) {
- return llvm::make_error<llvm::StringError>("no LLVM target for triple " +
- TripleName,
- llvm::inconvertibleErrorCode());
- }
- // Update Triple with the updated triple from the target lookup.
- TripleName = TheTriple.str();
- if (CpuName == "native")
- CpuName = std::string(llvm::sys::getHostCPUName());
- std::unique_ptr<MCSubtargetInfo> STI(
- TheTarget->createMCSubtargetInfo(TripleName, CpuName, ""));
- assert(STI && "Unable to create subtarget info!");
- if (!STI->isCPUStringValid(CpuName)) {
- return llvm::make_error<llvm::StringError>(Twine("invalid CPU name (")
- .concat(CpuName)
- .concat(") for triple ")
- .concat(TripleName),
- llvm::inconvertibleErrorCode());
- }
- const TargetOptions Options;
- std::unique_ptr<const TargetMachine> TM(
- static_cast<LLVMTargetMachine *>(TheTarget->createTargetMachine(
- TripleName, CpuName, Features, Options, Reloc::Model::Static)));
- if (!TM) {
- return llvm::make_error<llvm::StringError>(
- "unable to create target machine", llvm::inconvertibleErrorCode());
- }
- const ExegesisTarget *ET =
- TripleName.empty() ? &ExegesisTarget::getDefault()
- : ExegesisTarget::lookup(TM->getTargetTriple());
- if (!ET) {
- return llvm::make_error<llvm::StringError>(
- "no Exegesis target for triple " + TripleName,
- llvm::inconvertibleErrorCode());
- }
- return LLVMState(std::move(TM), ET, CpuName);
- }
- LLVMState::LLVMState(std::unique_ptr<const TargetMachine> TM,
- const ExegesisTarget *ET, const StringRef CpuName)
- : TheExegesisTarget(ET), TheTargetMachine(std::move(TM)),
- OpcodeNameToOpcodeIdxMapping(createOpcodeNameToOpcodeIdxMapping()),
- RegNameToRegNoMapping(createRegNameToRegNoMapping()) {
- PfmCounters = &TheExegesisTarget->getPfmCounters(CpuName);
- BitVector ReservedRegs = getFunctionReservedRegs(getTargetMachine());
- for (const unsigned Reg : TheExegesisTarget->getUnavailableRegisters())
- ReservedRegs.set(Reg);
- RATC.reset(
- new RegisterAliasingTrackerCache(getRegInfo(), std::move(ReservedRegs)));
- IC.reset(new InstructionsCache(getInstrInfo(), getRATC()));
- }
- std::unique_ptr<LLVMTargetMachine> LLVMState::createTargetMachine() const {
- return std::unique_ptr<LLVMTargetMachine>(static_cast<LLVMTargetMachine *>(
- TheTargetMachine->getTarget().createTargetMachine(
- TheTargetMachine->getTargetTriple().normalize(),
- TheTargetMachine->getTargetCPU(),
- TheTargetMachine->getTargetFeatureString(), TheTargetMachine->Options,
- Reloc::Model::Static)));
- }
- std::unique_ptr<const DenseMap<StringRef, unsigned>>
- LLVMState::createOpcodeNameToOpcodeIdxMapping() const {
- const MCInstrInfo &InstrInfo = getInstrInfo();
- auto Map = std::make_unique<DenseMap<StringRef, unsigned>>(
- InstrInfo.getNumOpcodes());
- for (unsigned I = 0, E = InstrInfo.getNumOpcodes(); I < E; ++I)
- (*Map)[InstrInfo.getName(I)] = I;
- assert(Map->size() == InstrInfo.getNumOpcodes() && "Size prediction failed");
- return std::move(Map);
- }
- std::unique_ptr<const DenseMap<StringRef, unsigned>>
- LLVMState::createRegNameToRegNoMapping() const {
- const MCRegisterInfo &RegInfo = getRegInfo();
- auto Map =
- std::make_unique<DenseMap<StringRef, unsigned>>(RegInfo.getNumRegs());
- // Special-case RegNo 0, which would otherwise be spelled as ''.
- (*Map)[kNoRegister] = 0;
- for (unsigned I = 1, E = RegInfo.getNumRegs(); I < E; ++I)
- (*Map)[RegInfo.getName(I)] = I;
- assert(Map->size() == RegInfo.getNumRegs() && "Size prediction failed");
- return std::move(Map);
- }
- bool LLVMState::canAssemble(const MCInst &Inst) const {
- MCContext Context(TheTargetMachine->getTargetTriple(),
- TheTargetMachine->getMCAsmInfo(),
- TheTargetMachine->getMCRegisterInfo(),
- TheTargetMachine->getMCSubtargetInfo());
- std::unique_ptr<const MCCodeEmitter> CodeEmitter(
- TheTargetMachine->getTarget().createMCCodeEmitter(
- *TheTargetMachine->getMCInstrInfo(), Context));
- assert(CodeEmitter && "unable to create code emitter");
- SmallVector<char, 16> Tmp;
- raw_svector_ostream OS(Tmp);
- SmallVector<MCFixup, 4> Fixups;
- CodeEmitter->encodeInstruction(Inst, OS, Fixups,
- *TheTargetMachine->getMCSubtargetInfo());
- return Tmp.size() > 0;
- }
- } // namespace exegesis
- } // namespace llvm
|