1 //===-- LlvmState.cpp -------------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
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/MC/TargetRegistry.h"
17 #include "llvm/Target/TargetMachine.h"
18 #include "llvm/Target/TargetOptions.h"
19 #include "llvm/TargetParser/Host.h"
24 Expected
<LLVMState
> LLVMState::Create(std::string TripleName
,
26 const StringRef Features
,
27 bool UseDummyPerfCounters
) {
28 if (TripleName
.empty())
29 TripleName
= Triple::normalize(sys::getDefaultTargetTriple());
31 Triple
TheTriple(TripleName
);
33 // Get the target specific parser.
35 const Target
*TheTarget
=
36 TargetRegistry::lookupTarget(/*MArch=*/"", TheTriple
, Error
);
38 return make_error
<StringError
>("no LLVM target for triple " + TripleName
,
39 inconvertibleErrorCode());
42 // Update Triple with the updated triple from the target lookup.
43 TripleName
= TheTriple
.str();
45 if (CpuName
== "native")
46 CpuName
= std::string(sys::getHostCPUName());
48 std::unique_ptr
<MCSubtargetInfo
> STI(
49 TheTarget
->createMCSubtargetInfo(TripleName
, CpuName
, ""));
50 assert(STI
&& "Unable to create subtarget info!");
51 if (!STI
->isCPUStringValid(CpuName
)) {
52 return make_error
<StringError
>(Twine("invalid CPU name (")
54 .concat(") for triple ")
56 inconvertibleErrorCode());
58 const TargetOptions Options
;
59 std::unique_ptr
<const TargetMachine
> TM(TheTarget
->createTargetMachine(
60 TripleName
, CpuName
, Features
, Options
, Reloc::Model::Static
));
62 return make_error
<StringError
>("unable to create target machine",
63 inconvertibleErrorCode());
66 const ExegesisTarget
*ET
=
67 TripleName
.empty() ? &ExegesisTarget::getDefault()
68 : ExegesisTarget::lookup(TM
->getTargetTriple());
70 return make_error
<StringError
>("no Exegesis target for triple " +
72 inconvertibleErrorCode());
74 const PfmCountersInfo
&PCI
= UseDummyPerfCounters
75 ? ET
->getDummyPfmCounters()
76 : ET
->getPfmCounters(CpuName
);
77 return LLVMState(std::move(TM
), ET
, &PCI
);
80 LLVMState::LLVMState(std::unique_ptr
<const TargetMachine
> TM
,
81 const ExegesisTarget
*ET
, const PfmCountersInfo
*PCI
)
82 : TheExegesisTarget(ET
), TheTargetMachine(std::move(TM
)), PfmCounters(PCI
),
83 OpcodeNameToOpcodeIdxMapping(createOpcodeNameToOpcodeIdxMapping()),
84 RegNameToRegNoMapping(createRegNameToRegNoMapping()) {
85 BitVector ReservedRegs
= getFunctionReservedRegs(getTargetMachine());
86 for (const unsigned Reg
: TheExegesisTarget
->getUnavailableRegisters())
87 ReservedRegs
.set(Reg
);
89 new RegisterAliasingTrackerCache(getRegInfo(), std::move(ReservedRegs
)));
90 IC
.reset(new InstructionsCache(getInstrInfo(), getRATC()));
93 std::unique_ptr
<TargetMachine
> LLVMState::createTargetMachine() const {
94 return std::unique_ptr
<TargetMachine
>(
95 TheTargetMachine
->getTarget().createTargetMachine(
96 TheTargetMachine
->getTargetTriple().normalize(),
97 TheTargetMachine
->getTargetCPU(),
98 TheTargetMachine
->getTargetFeatureString(), TheTargetMachine
->Options
,
99 Reloc::Model::Static
));
102 std::optional
<MCRegister
>
103 LLVMState::getRegisterNumberFromName(StringRef RegisterName
) const {
104 auto RegisterIt
= RegNameToRegNoMapping
->find(RegisterName
);
105 if (RegisterIt
== RegNameToRegNoMapping
->end())
107 return RegisterIt
->second
;
110 std::unique_ptr
<const DenseMap
<StringRef
, unsigned>>
111 LLVMState::createOpcodeNameToOpcodeIdxMapping() const {
112 const MCInstrInfo
&InstrInfo
= getInstrInfo();
113 auto Map
= std::make_unique
<DenseMap
<StringRef
, unsigned>>(
114 InstrInfo
.getNumOpcodes());
115 for (unsigned I
= 0, E
= InstrInfo
.getNumOpcodes(); I
< E
; ++I
)
116 (*Map
)[InstrInfo
.getName(I
)] = I
;
117 assert(Map
->size() == InstrInfo
.getNumOpcodes() && "Size prediction failed");
118 return std::move(Map
);
121 std::unique_ptr
<const DenseMap
<StringRef
, MCRegister
>>
122 LLVMState::createRegNameToRegNoMapping() const {
123 const MCRegisterInfo
&RegInfo
= getRegInfo();
125 std::make_unique
<DenseMap
<StringRef
, MCRegister
>>(RegInfo
.getNumRegs());
126 // Special-case RegNo 0, which would otherwise be spelled as ''.
127 (*Map
)[kNoRegister
] = 0;
128 for (unsigned I
= 1, E
= RegInfo
.getNumRegs(); I
< E
; ++I
)
129 (*Map
)[RegInfo
.getName(I
)] = I
;
130 assert(Map
->size() == RegInfo
.getNumRegs() && "Size prediction failed");
131 return std::move(Map
);
134 bool LLVMState::canAssemble(const MCInst
&Inst
) const {
135 MCContext
Context(TheTargetMachine
->getTargetTriple(),
136 TheTargetMachine
->getMCAsmInfo(),
137 TheTargetMachine
->getMCRegisterInfo(),
138 TheTargetMachine
->getMCSubtargetInfo());
139 std::unique_ptr
<const MCCodeEmitter
> CodeEmitter(
140 TheTargetMachine
->getTarget().createMCCodeEmitter(
141 *TheTargetMachine
->getMCInstrInfo(), Context
));
142 assert(CodeEmitter
&& "unable to create code emitter");
143 SmallVector
<char, 16> Tmp
;
144 SmallVector
<MCFixup
, 4> Fixups
;
145 CodeEmitter
->encodeInstruction(Inst
, Tmp
, Fixups
,
146 *TheTargetMachine
->getMCSubtargetInfo());
147 return Tmp
.size() > 0;
150 } // namespace exegesis