LLVM 22.0.0git
SparcMCCodeEmitter.cpp
Go to the documentation of this file.
1//===-- SparcMCCodeEmitter.cpp - Convert Sparc code to machine code -------===//
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// This file implements the SparcMCCodeEmitter class.
10//
11//===----------------------------------------------------------------------===//
12
14#include "SparcMCTargetDesc.h"
16#include "llvm/ADT/Statistic.h"
18#include "llvm/MC/MCAsmInfo.h"
20#include "llvm/MC/MCContext.h"
21#include "llvm/MC/MCExpr.h"
22#include "llvm/MC/MCFixup.h"
23#include "llvm/MC/MCInst.h"
24#include "llvm/MC/MCInstrInfo.h"
28#include "llvm/MC/MCSymbol.h"
31#include <cassert>
32#include <cstdint>
33
34using namespace llvm;
35
36#define DEBUG_TYPE "mccodeemitter"
37
38STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
39
40namespace {
41
42class SparcMCCodeEmitter : public MCCodeEmitter {
43 MCContext &Ctx;
44
45public:
46 SparcMCCodeEmitter(const MCInstrInfo &, MCContext &ctx)
47 : Ctx(ctx) {}
48 SparcMCCodeEmitter(const SparcMCCodeEmitter &) = delete;
49 SparcMCCodeEmitter &operator=(const SparcMCCodeEmitter &) = delete;
50 ~SparcMCCodeEmitter() override = default;
51
52 void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB,
53 SmallVectorImpl<MCFixup> &Fixups,
54 const MCSubtargetInfo &STI) const override;
55
56 // getBinaryCodeForInstr - TableGen'erated function for getting the
57 // binary encoding for an instruction.
58 uint64_t getBinaryCodeForInstr(const MCInst &MI,
59 SmallVectorImpl<MCFixup> &Fixups,
60 const MCSubtargetInfo &STI) const;
61
62 /// getMachineOpValue - Return binary encoding of operand. If the machine
63 /// operand requires relocation, record the relocation and return zero.
64 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
65 SmallVectorImpl<MCFixup> &Fixups,
66 const MCSubtargetInfo &STI) const;
67 unsigned getCallTargetOpValue(const MCInst &MI, unsigned OpNo,
68 SmallVectorImpl<MCFixup> &Fixups,
69 const MCSubtargetInfo &STI) const;
70 unsigned getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
71 SmallVectorImpl<MCFixup> &Fixups,
72 const MCSubtargetInfo &STI) const;
73 unsigned getSImm5OpValue(const MCInst &MI, unsigned OpNo,
74 SmallVectorImpl<MCFixup> &Fixups,
75 const MCSubtargetInfo &STI) const;
76 unsigned getSImm13OpValue(const MCInst &MI, unsigned OpNo,
77 SmallVectorImpl<MCFixup> &Fixups,
78 const MCSubtargetInfo &STI) const;
79 unsigned getBranchPredTargetOpValue(const MCInst &MI, unsigned OpNo,
80 SmallVectorImpl<MCFixup> &Fixups,
81 const MCSubtargetInfo &STI) const;
82 unsigned getBranchOnRegTargetOpValue(const MCInst &MI, unsigned OpNo,
83 SmallVectorImpl<MCFixup> &Fixups,
84 const MCSubtargetInfo &STI) const;
85 unsigned getCompareAndBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
86 SmallVectorImpl<MCFixup> &Fixups,
87 const MCSubtargetInfo &STI) const;
88};
89
90} // end anonymous namespace
91
93 const MCExpr *Value, uint16_t Kind) {
94 bool PCRel = false;
95 switch (Kind) {
96 case ELF::R_SPARC_PC10:
97 case ELF::R_SPARC_PC22:
98 case ELF::R_SPARC_WDISP10:
99 case ELF::R_SPARC_WDISP16:
100 case ELF::R_SPARC_WDISP19:
101 case ELF::R_SPARC_WDISP22:
103 PCRel = true;
104 }
105 Fixups.push_back(MCFixup::create(Offset, Value, Kind, PCRel));
106}
107
108void SparcMCCodeEmitter::encodeInstruction(const MCInst &MI,
111 const MCSubtargetInfo &STI) const {
112 unsigned Bits = getBinaryCodeForInstr(MI, Fixups, STI);
113 support::endian::write(CB, Bits,
117
118 // Some instructions have phantom operands that only contribute a fixup entry.
119 unsigned SymOpNo = 0;
120 switch (MI.getOpcode()) {
121 default: break;
122 case SP::TLS_CALL: SymOpNo = 1; break;
123 case SP::GDOP_LDrr:
124 case SP::GDOP_LDXrr:
125 case SP::TLS_ADDrr:
126 case SP::TLS_LDrr:
127 case SP::TLS_LDXrr: SymOpNo = 3; break;
128 }
129 if (SymOpNo != 0) {
130 const MCOperand &MO = MI.getOperand(SymOpNo);
131 uint64_t op = getMachineOpValue(MI, MO, Fixups, STI);
132 assert(op == 0 && "Unexpected operand value!");
133 (void)op; // suppress warning.
134 }
135
136 ++MCNumEmitted; // Keep track of the # of mi's emitted.
137}
138
139unsigned SparcMCCodeEmitter::
140getMachineOpValue(const MCInst &MI, const MCOperand &MO,
141 SmallVectorImpl<MCFixup> &Fixups,
142 const MCSubtargetInfo &STI) const {
143 if (MO.isReg())
144 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
145
146 if (MO.isImm())
147 return MO.getImm();
148
149 assert(MO.isExpr());
150 const MCExpr *Expr = MO.getExpr();
151 if (auto *SExpr = dyn_cast<MCSpecifierExpr>(Expr)) {
152 addFixup(Fixups, 0, Expr, SExpr->getSpecifier());
153 return 0;
154 }
155
156 int64_t Res;
157 if (Expr->evaluateAsAbsolute(Res))
158 return Res;
159
160 llvm_unreachable("Unhandled expression!");
161 return 0;
162}
163
164unsigned SparcMCCodeEmitter::getSImm5OpValue(const MCInst &MI, unsigned OpNo,
165 SmallVectorImpl<MCFixup> &Fixups,
166 const MCSubtargetInfo &STI) const {
167 const MCOperand &MO = MI.getOperand(OpNo);
168
169 if (MO.isImm())
170 return MO.getImm();
171
172 assert(MO.isExpr() &&
173 "getSImm5OpValue expects only expressions or an immediate");
174
175 const MCExpr *Expr = MO.getExpr();
176
177 // Constant value, no fixup is needed
178 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
179 return CE->getValue();
180
181 if (auto *SExpr = dyn_cast<MCSpecifierExpr>(Expr)) {
182 addFixup(Fixups, 0, Expr, SExpr->getSpecifier());
183 return 0;
184 }
185 addFixup(Fixups, 0, Expr, ELF::R_SPARC_5);
186 return 0;
187}
188
189unsigned
190SparcMCCodeEmitter::getSImm13OpValue(const MCInst &MI, unsigned OpNo,
191 SmallVectorImpl<MCFixup> &Fixups,
192 const MCSubtargetInfo &STI) const {
193 const MCOperand &MO = MI.getOperand(OpNo);
194
195 if (MO.isImm())
196 return MO.getImm();
197
198 assert(MO.isExpr() &&
199 "getSImm13OpValue expects only expressions or an immediate");
200
201 const MCExpr *Expr = MO.getExpr();
202
203 // Constant value, no fixup is needed
204 if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
205 return CE->getValue();
206
207 if (auto *SExpr = dyn_cast<MCSpecifierExpr>(Expr)) {
208 addFixup(Fixups, 0, Expr, SExpr->getSpecifier());
209 return 0;
210 }
211 addFixup(Fixups, 0, Expr, Sparc::fixup_sparc_13);
212 return 0;
213}
214
215unsigned SparcMCCodeEmitter::
216getCallTargetOpValue(const MCInst &MI, unsigned OpNo,
217 SmallVectorImpl<MCFixup> &Fixups,
218 const MCSubtargetInfo &STI) const {
219 if (MI.getOpcode() == SP::TLS_CALL) {
220 // No fixups for __tls_get_addr. Will emit for fixups for tls_symbol in
221 // encodeInstruction.
222 return 0;
223 }
224
225 const MCOperand &MO = MI.getOperand(OpNo);
227 return 0;
228}
229
230unsigned SparcMCCodeEmitter::
231getBranchTargetOpValue(const MCInst &MI, unsigned OpNo,
232 SmallVectorImpl<MCFixup> &Fixups,
233 const MCSubtargetInfo &STI) const {
234 const MCOperand &MO = MI.getOperand(OpNo);
235 if (MO.isReg() || MO.isImm())
236 return getMachineOpValue(MI, MO, Fixups, STI);
237
238 addFixup(Fixups, 0, MO.getExpr(), ELF::R_SPARC_WDISP22);
239 return 0;
240}
241
242unsigned SparcMCCodeEmitter::getBranchPredTargetOpValue(
243 const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
244 const MCSubtargetInfo &STI) const {
245 const MCOperand &MO = MI.getOperand(OpNo);
246 if (MO.isReg() || MO.isImm())
247 return getMachineOpValue(MI, MO, Fixups, STI);
248
249 addFixup(Fixups, 0, MO.getExpr(), ELF::R_SPARC_WDISP19);
250 return 0;
251}
252
253unsigned SparcMCCodeEmitter::getBranchOnRegTargetOpValue(
254 const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
255 const MCSubtargetInfo &STI) const {
256 const MCOperand &MO = MI.getOperand(OpNo);
257 if (MO.isReg() || MO.isImm())
258 return getMachineOpValue(MI, MO, Fixups, STI);
259
260 addFixup(Fixups, 0, MO.getExpr(), ELF::R_SPARC_WDISP16);
261 return 0;
262}
263
264unsigned SparcMCCodeEmitter::getCompareAndBranchTargetOpValue(
265 const MCInst &MI, unsigned OpNo, SmallVectorImpl<MCFixup> &Fixups,
266 const MCSubtargetInfo &STI) const {
267 const MCOperand &MO = MI.getOperand(OpNo);
268 if (MO.isImm())
269 return getMachineOpValue(MI, MO, Fixups, STI);
270
271 addFixup(Fixups, 0, MO.getExpr(), ELF::R_SPARC_WDISP10);
272 return 0;
273}
274
275#include "SparcGenMCCodeEmitter.inc"
276
278 MCContext &Ctx) {
279 return new SparcMCCodeEmitter(MCII, Ctx);
280}
static void addFixup(SmallVectorImpl< MCFixup > &Fixups, uint32_t Offset, const MCExpr *Value, uint16_t Kind, bool PCRel=false)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static uint32_t getBranchTargetOpValue(const MCInst &MI, unsigned OpIdx, unsigned FixupKind, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI)
getBranchTargetOpValue - Helper function to get the branch target operand, which is either an immedia...
#define op(i)
IRTranslator LLVM IR MI
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
bool isLittleEndian() const
True if the target is little endian.
Definition MCAsmInfo.h:452
MCCodeEmitter - Generic instruction encoding interface.
Context object for machine code objects.
Definition MCContext.h:83
const MCRegisterInfo * getRegisterInfo() const
Definition MCContext.h:414
const MCAsmInfo * getAsmInfo() const
Definition MCContext.h:412
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, bool PCRel=false)
Consider bit fields if we need more flags.
Definition MCFixup.h:86
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
Interface to description of machine instruction set.
Definition MCInstrInfo.h:27
int64_t getImm() const
Definition MCInst.h:84
bool isImm() const
Definition MCInst.h:66
bool isReg() const
Definition MCInst.h:65
MCRegister getReg() const
Returns the register number.
Definition MCInst.h:73
const MCExpr * getExpr() const
Definition MCInst.h:118
bool isExpr() const
Definition MCInst.h:69
uint16_t getEncodingValue(MCRegister Reg) const
Returns the encoding for Reg.
Generic base class for all target subtargets.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
LLVM Value Representation.
Definition Value.h:75
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ fixup_sparc_13
fixup_sparc_13 - 13-bit fixup
@ CE
Windows NT (Windows on ARM)
Definition MCAsmInfo.h:48
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
Definition Endian.h:96
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:477
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:644
static void addFixup(SmallVectorImpl< MCFixup > &Fixups, uint32_t Offset, const MCExpr *Value, uint16_t Kind)
MCCodeEmitter * createSparcMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)