LLVM 18.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"
24
25using namespace llvm;
26
27#define DEBUG_TYPE "mccodeemitter"
28
29namespace {
30class LoongArchMCCodeEmitter : public MCCodeEmitter {
31 LoongArchMCCodeEmitter(const LoongArchMCCodeEmitter &) = delete;
32 void operator=(const LoongArchMCCodeEmitter &) = delete;
33 MCContext &Ctx;
34 MCInstrInfo const &MCII;
35
36public:
37 LoongArchMCCodeEmitter(MCContext &ctx, MCInstrInfo const &MCII)
38 : Ctx(ctx), MCII(MCII) {}
39
40 ~LoongArchMCCodeEmitter() override {}
41
44 const MCSubtargetInfo &STI) const override;
45
46 template <unsigned Opc>
47 void expandToVectorLDI(const MCInst &MI, SmallVectorImpl<char> &CB,
49 const MCSubtargetInfo &STI) const;
50
51 /// TableGen'erated function for getting the binary encoding for an
52 /// instruction.
53 uint64_t getBinaryCodeForInstr(const MCInst &MI,
55 const MCSubtargetInfo &STI) const;
56
57 /// Return binary encoding of operand. If the machine operand requires
58 /// relocation, record the relocation and return zero.
59 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
61 const MCSubtargetInfo &STI) const;
62
63 /// Return binary encoding of an immediate operand specified by OpNo.
64 /// The value returned is the value of the immediate minus 1.
65 /// Note that this function is dedicated to specific immediate types,
66 /// e.g. uimm2_plus1.
67 unsigned getImmOpValueSub1(const MCInst &MI, unsigned OpNo,
69 const MCSubtargetInfo &STI) const;
70
71 /// Return binary encoding of an immediate operand specified by OpNo.
72 /// The value returned is the value of the immediate shifted right
73 // arithmetically by N.
74 /// Note that this function is dedicated to specific immediate types,
75 /// e.g. simm14_lsl2, simm16_lsl2, simm21_lsl2 and simm26_lsl2.
76 template <unsigned N>
77 unsigned getImmOpValueAsr(const MCInst &MI, unsigned OpNo,
79 const MCSubtargetInfo &STI) const {
80 const MCOperand &MO = MI.getOperand(OpNo);
81 if (MO.isImm()) {
82 unsigned Res = MI.getOperand(OpNo).getImm();
83 assert((Res & ((1U << N) - 1U)) == 0 && "lowest N bits are non-zero");
84 return Res >> N;
85 }
86 return getExprOpValue(MI, MO, Fixups, STI);
87 }
88
89 unsigned getExprOpValue(const MCInst &MI, const MCOperand &MO,
91 const MCSubtargetInfo &STI) const;
92};
93} // end namespace
94
95unsigned
96LoongArchMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
98 const MCSubtargetInfo &STI) const {
99
100 if (MO.isReg())
101 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
102
103 if (MO.isImm())
104 return static_cast<unsigned>(MO.getImm());
105
106 // MO must be an Expr.
107 assert(MO.isExpr());
108 return getExprOpValue(MI, MO, Fixups, STI);
109}
110
111unsigned
112LoongArchMCCodeEmitter::getImmOpValueSub1(const MCInst &MI, unsigned OpNo,
114 const MCSubtargetInfo &STI) const {
115 return MI.getOperand(OpNo).getImm() - 1;
116}
117
118unsigned
119LoongArchMCCodeEmitter::getExprOpValue(const MCInst &MI, const MCOperand &MO,
121 const MCSubtargetInfo &STI) const {
122 assert(MO.isExpr() && "getExprOpValue expects only expressions");
123 const MCExpr *Expr = MO.getExpr();
124 MCExpr::ExprKind Kind = Expr->getKind();
126 if (Kind == MCExpr::Target) {
127 const LoongArchMCExpr *LAExpr = cast<LoongArchMCExpr>(Expr);
128
129 switch (LAExpr->getKind()) {
132 llvm_unreachable("Unhandled fixup kind!");
135 break;
138 break;
143 break;
146 break;
149 break;
152 break;
155 break;
158 break;
161 break;
164 break;
167 break;
170 break;
173 break;
176 break;
179 break;
182 break;
185 break;
188 break;
191 break;
194 break;
197 break;
200 break;
203 break;
206 break;
209 break;
212 break;
215 break;
218 break;
221 break;
224 break;
227 break;
230 break;
233 break;
236 break;
239 break;
240 }
241 } else if (Kind == MCExpr::SymbolRef &&
242 cast<MCSymbolRefExpr>(Expr)->getKind() ==
244 switch (MI.getOpcode()) {
245 default:
246 break;
247 case LoongArch::BEQ:
248 case LoongArch::BNE:
249 case LoongArch::BLT:
250 case LoongArch::BGE:
251 case LoongArch::BLTU:
252 case LoongArch::BGEU:
254 break;
255 case LoongArch::BEQZ:
256 case LoongArch::BNEZ:
257 case LoongArch::BCEQZ:
258 case LoongArch::BCNEZ:
260 break;
261 case LoongArch::B:
263 break;
264 }
265 }
266
268 "Unhandled expression!");
269
270 Fixups.push_back(
271 MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc()));
272 return 0;
273}
274
275template <unsigned Opc>
276void LoongArchMCCodeEmitter::expandToVectorLDI(
277 const MCInst &MI, SmallVectorImpl<char> &CB,
278 SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const {
279 int64_t Imm = MI.getOperand(1).getImm() & 0x3FF;
280 switch (MI.getOpcode()) {
281 case LoongArch::PseudoVREPLI_B:
282 case LoongArch::PseudoXVREPLI_B:
283 break;
284 case LoongArch::PseudoVREPLI_H:
285 case LoongArch::PseudoXVREPLI_H:
286 Imm |= 0x400;
287 break;
288 case LoongArch::PseudoVREPLI_W:
289 case LoongArch::PseudoXVREPLI_W:
290 Imm |= 0x800;
291 break;
292 case LoongArch::PseudoVREPLI_D:
293 case LoongArch::PseudoXVREPLI_D:
294 Imm |= 0xC00;
295 break;
296 }
297 MCInst TmpInst = MCInstBuilder(Opc).addOperand(MI.getOperand(0)).addImm(Imm);
298 uint32_t Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
300}
301
302void LoongArchMCCodeEmitter::encodeInstruction(
303 const MCInst &MI, SmallVectorImpl<char> &CB,
304 SmallVectorImpl<MCFixup> &Fixups, const MCSubtargetInfo &STI) const {
305 const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
306 // Get byte count of instruction.
307 unsigned Size = Desc.getSize();
308
309 switch (MI.getOpcode()) {
310 default:
311 break;
312 case LoongArch::PseudoVREPLI_B:
313 case LoongArch::PseudoVREPLI_H:
314 case LoongArch::PseudoVREPLI_W:
315 case LoongArch::PseudoVREPLI_D:
316 return expandToVectorLDI<LoongArch::VLDI>(MI, CB, Fixups, STI);
317 case LoongArch::PseudoXVREPLI_B:
318 case LoongArch::PseudoXVREPLI_H:
319 case LoongArch::PseudoXVREPLI_W:
320 case LoongArch::PseudoXVREPLI_D:
321 return expandToVectorLDI<LoongArch::XVLDI>(MI, CB, Fixups, STI);
322 }
323
324 switch (Size) {
325 default:
326 llvm_unreachable("Unhandled encodeInstruction length!");
327 case 4: {
328 uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
330 break;
331 }
332 }
333}
334
336 MCContext &Ctx) {
337 return new LoongArchMCCodeEmitter(Ctx, MCII);
338}
339
340#include "LoongArchGenMCCodeEmitter.inc"
uint64_t Size
IRTranslator LLVM IR MI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
VariantKind getKind() 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
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:86
MCInstBuilder & addOperand(const MCOperand &Op)
Add an operand.
Definition: MCInstBuilder.h:67
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Definition: MCInstBuilder.h:37
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.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:577
#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:96
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.