LLVM 19.0.0git
LoongArchMCCodeEmitter.cpp
Go to the documentation of this file.
1//=- LoongArchMCCodeEmitter.cpp - Convert LoongArch 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 LoongArchMCCodeEmitter class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "LoongArchFixupKinds.h"
18#include "llvm/MC/MCContext.h"
20#include "llvm/MC/MCInstrInfo.h"
25
26using namespace llvm;
27
28#define DEBUG_TYPE "mccodeemitter"
29
30namespace {
31class LoongArchMCCodeEmitter : public MCCodeEmitter {
32 LoongArchMCCodeEmitter(const LoongArchMCCodeEmitter &) = delete;
33 void operator=(const LoongArchMCCodeEmitter &) = delete;
34 MCContext &Ctx;
35 MCInstrInfo const &MCII;
36
37public:
38 LoongArchMCCodeEmitter(MCContext &ctx, MCInstrInfo const &MCII)
39 : Ctx(ctx), MCII(MCII) {}
40
41 ~LoongArchMCCodeEmitter() override {}
42
45 const MCSubtargetInfo &STI) const override;
46
47 template <unsigned Opc>
48 void expandToVectorLDI(const MCInst &MI, SmallVectorImpl<char> &CB,
50 const MCSubtargetInfo &STI) const;
51
52 /// TableGen'erated function for getting the binary encoding for an
53 /// instruction.
54 uint64_t getBinaryCodeForInstr(const MCInst &MI,
56 const MCSubtargetInfo &STI) const;
57
58 /// Return binary encoding of operand. If the machine operand requires
59 /// relocation, record the relocation and return zero.
60 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
62 const MCSubtargetInfo &STI) const;
63
64 /// Return binary encoding of an immediate operand specified by OpNo.
65 /// The value returned is the value of the immediate minus 1.
66 /// Note that this function is dedicated to specific immediate types,
67 /// e.g. uimm2_plus1.
68 unsigned getImmOpValueSub1(const MCInst &MI, unsigned OpNo,
70 const MCSubtargetInfo &STI) const;
71
72 /// Return binary encoding of an immediate operand specified by OpNo.
73 /// The value returned is the value of the immediate shifted right
74 // arithmetically by N.
75 /// Note that this function is dedicated to specific immediate types,
76 /// e.g. simm14_lsl2, simm16_lsl2, simm21_lsl2 and simm26_lsl2.
77 template <unsigned N>
78 unsigned getImmOpValueAsr(const MCInst &MI, unsigned OpNo,
80 const MCSubtargetInfo &STI) const {
81 const MCOperand &MO = MI.getOperand(OpNo);
82 if (MO.isImm()) {
83 unsigned Res = MI.getOperand(OpNo).getImm();
84 assert((Res & ((1U << N) - 1U)) == 0 && "lowest N bits are non-zero");
85 return Res >> N;
86 }
87 return getExprOpValue(MI, MO, Fixups, STI);
88 }
89
90 unsigned getExprOpValue(const MCInst &MI, const MCOperand &MO,
92 const MCSubtargetInfo &STI) const;
93};
94} // end namespace
95
96unsigned
97LoongArchMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
99 const MCSubtargetInfo &STI) const {
100
101 if (MO.isReg())
102 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
103
104 if (MO.isImm())
105 return static_cast<unsigned>(MO.getImm());
106
107 // MO must be an Expr.
108 assert(MO.isExpr());
109 return getExprOpValue(MI, MO, Fixups, STI);
110}
111
112unsigned
113LoongArchMCCodeEmitter::getImmOpValueSub1(const MCInst &MI, unsigned OpNo,
115 const MCSubtargetInfo &STI) const {
116 return MI.getOperand(OpNo).getImm() - 1;
117}
118
119unsigned
120LoongArchMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCOperand &MO,
122 const MCSubtargetInfo &STI) const {
123 assert(MO.isExpr() && "getExprOpValue expects only expressions");
124 bool RelaxCandidate = false;
125 bool EnableRelax = STI.hasFeature(LoongArch::FeatureRelax);
126 const MCExpr *Expr = MO.getExpr();
127 MCExpr::ExprKind Kind = Expr->getKind();
129 if (Kind == MCExpr::Target) {
130 const LoongArchMCExpr *LAExpr = cast<LoongArchMCExpr>(Expr);
131
132 RelaxCandidate = LAExpr->getRelaxHint();
133 switch (LAExpr->getKind()) {
136 llvm_unreachable("Unhandled fixup kind!");
139 break;
142 break;
147 break;
150 break;
153 break;
156 break;
159 break;
162 break;
165 break;
168 break;
171 break;
174 break;
177 break;
180 break;
183 break;
186 break;
189 break;
192 break;
195 break;
198 break;
201 break;
204 break;
207 break;
210 break;
213 break;
216 break;
219 break;
222 break;
225 break;
228 break;
231 break;
234 break;
237 break;
240 break;
243 break;
246 break;
247 }
248 } else if (Kind == MCExpr::SymbolRef &&
249 cast<MCSymbolRefExpr>(Expr)->getKind() ==
251 switch (MI.getOpcode()) {
252 default:
253 break;
254 case LoongArch::BEQ:
255 case LoongArch::BNE:
256 case LoongArch::BLT:
257 case LoongArch::BGE:
258 case LoongArch::BLTU:
259 case LoongArch::BGEU:
261 break;
262 case LoongArch::BEQZ:
263 case LoongArch::BNEZ:
264 case LoongArch::BCEQZ:
265 case LoongArch::BCNEZ:
267 break;
268 case LoongArch::B:
269 case LoongArch::BL:
271 break;
272 }
273 }
274
276 "Unhandled expression!");
277
278 Fixups.push_back(
279 MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc()));
280
281 // Emit an R_LARCH_RELAX if linker relaxation is enabled and LAExpr has relax
282 // hint.
283 if (EnableRelax && RelaxCandidate) {
285 Fixups.push_back(MCFixup::create(
286 0, Dummy, MCFixupKind(LoongArch::fixup_loongarch_relax), MI.getLoc()));
287 }
288
289 return 0;
290}
291
292template <unsigned Opc>
293void LoongArchMCCodeEmitter::expandToVectorLDI(
294 const MCInst &MI, SmallVectorImpl<char> &CB,
295 SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const {
296 int64_t Imm = MI.getOperand(1).getImm() & 0x3FF;
297 switch (MI.getOpcode()) {
298 case LoongArch::PseudoVREPLI_B:
299 case LoongArch::PseudoXVREPLI_B:
300 break;
301 case LoongArch::PseudoVREPLI_H:
302 case LoongArch::PseudoXVREPLI_H:
303 Imm |= 0x400;
304 break;
305 case LoongArch::PseudoVREPLI_W:
306 case LoongArch::PseudoXVREPLI_W:
307 Imm |= 0x800;
308 break;
309 case LoongArch::PseudoVREPLI_D:
310 case LoongArch::PseudoXVREPLI_D:
311 Imm |= 0xC00;
312 break;
313 }
314 MCInst TmpInst = MCInstBuilder(Opc).addOperand(MI.getOperand(0)).addImm(Imm);
315 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
317}
318
319void LoongArchMCCodeEmitter::encodeInstruction(
320 const MCInst &MI, SmallVectorImpl<char> &CB,
321 SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const {
322 const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
323 // Get byte count of instruction.
324 unsigned Size = Desc.getSize();
325
326 switch (MI.getOpcode()) {
327 default:
328 break;
329 case LoongArch::PseudoVREPLI_B:
330 case LoongArch::PseudoVREPLI_H:
331 case LoongArch::PseudoVREPLI_W:
332 case LoongArch::PseudoVREPLI_D:
333 return expandToVectorLDI<LoongArch::VLDI>(MI, CB, Fixups, STI);
334 case LoongArch::PseudoXVREPLI_B:
335 case LoongArch::PseudoXVREPLI_H:
336 case LoongArch::PseudoXVREPLI_W:
337 case LoongArch::PseudoXVREPLI_D:
338 return expandToVectorLDI<LoongArch::XVLDI>(MI, CB, Fixups, STI);
339 }
340
341 switch (Size) {
342 default:
343 llvm_unreachable("Unhandled encodeInstruction length!");
344 case 4: {
345 uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
347 break;
348 }
349 }
350}
351
353 MCContext &Ctx) {
354 return new LoongArchMCCodeEmitter(Ctx, MCII);
355}
356
357#include "LoongArchGenMCCodeEmitter.inc"
uint64_t Size
IRTranslator LLVM IR MI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
VariantKind getKind() const
bool getRelaxHint() const
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:21
virtual void encodeInstruction(const MCInst &Inst, SmallVectorImpl< char > &CB, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const =0
Encode the given Inst to bytes and append to CB.
MCCodeEmitter & operator=(const MCCodeEmitter &)=delete
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:194
Context object for machine code objects.
Definition: MCContext.h:76
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
@ SymbolRef
References to labels and assigned expressions.
Definition: MCExpr.h:40
@ Target
Target specific expression.
Definition: MCExpr.h:42
ExprKind getKind() const
Definition: MCExpr.h:81
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Definition: MCFixup.h:87
MCInstBuilder & addOperand(const MCOperand &Op)
Add an operand.
Definition: MCInstBuilder.h:73
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Definition: MCInstBuilder.h:43
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:198
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
int64_t getImm() const
Definition: MCInst.h:80
bool isImm() const
Definition: MCInst.h:62
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:69
bool isReg() const
Definition: MCInst.h:61
const MCExpr * getExpr() const
Definition: MCInst.h:114
bool isExpr() const
Definition: MCInst.h:65
Generic base class for all target subtargets.
bool hasFeature(unsigned Feature) const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
Definition: Endian.h:91
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
MCCodeEmitter * createLoongArchMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:21
#define N
Description of the encoding of one expression Op.