LLVM 17.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
42 void encodeInstruction(const MCInst &MI, raw_ostream &OS,
44 const MCSubtargetInfo &STI) const override;
45
46 /// TableGen'erated function for getting the binary encoding for an
47 /// instruction.
48 uint64_t getBinaryCodeForInstr(const MCInst &MI,
50 const MCSubtargetInfo &STI) const;
51
52 /// Return binary encoding of operand. If the machine operand requires
53 /// relocation, record the relocation and return zero.
54 unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO,
56 const MCSubtargetInfo &STI) const;
57
58 /// Return binary encoding of an immediate operand specified by OpNo.
59 /// The value returned is the value of the immediate minus 1.
60 /// Note that this function is dedicated to specific immediate types,
61 /// e.g. uimm2_plus1.
62 unsigned getImmOpValueSub1(const MCInst &MI, unsigned OpNo,
64 const MCSubtargetInfo &STI) const;
65
66 /// Return binary encoding of an immediate operand specified by OpNo.
67 /// The value returned is the value of the immediate shifted right
68 // arithmetically by 2.
69 /// Note that this function is dedicated to specific immediate types,
70 /// e.g. simm14_lsl2, simm16_lsl2, simm21_lsl2 and simm26_lsl2.
71 unsigned getImmOpValueAsr2(const MCInst &MI, unsigned OpNo,
73 const MCSubtargetInfo &STI) const;
74
75 unsigned getExprOpValue(const MCInst &MI, const MCOperand &MO,
77 const MCSubtargetInfo &STI) const;
78};
79} // end namespace
80
81unsigned
82LoongArchMCCodeEmitter::getMachineOpValue(const MCInst &MI, const MCOperand &MO,
84 const MCSubtargetInfo &STI) const {
85
86 if (MO.isReg())
87 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
88
89 if (MO.isImm())
90 return static_cast<unsigned>(MO.getImm());
91
92 // MO must be an Expr.
93 assert(MO.isExpr());
94 return getExprOpValue(MI, MO, Fixups, STI);
95}
96
97unsigned
98LoongArchMCCodeEmitter::getImmOpValueSub1(const MCInst &MI, unsigned OpNo,
100 const MCSubtargetInfo &STI) const {
101 return MI.getOperand(OpNo).getImm() - 1;
102}
103
104unsigned
105LoongArchMCCodeEmitter::getImmOpValueAsr2(const MCInst &MI, unsigned OpNo,
107 const MCSubtargetInfo &STI) const {
108 const MCOperand &MO = MI.getOperand(OpNo);
109
110 if (MO.isImm()) {
111 unsigned Res = MI.getOperand(OpNo).getImm();
112 assert((Res & 3) == 0 && "lowest 2 bits are non-zero");
113 return Res >> 2;
114 }
115
116 return getExprOpValue(MI, MO, Fixups, STI);
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 const MCExpr *Expr = MO.getExpr();
125 MCExpr::ExprKind Kind = Expr->getKind();
127 if (Kind == MCExpr::Target) {
128 const LoongArchMCExpr *LAExpr = cast<LoongArchMCExpr>(Expr);
129
130 switch (LAExpr->getKind()) {
133 llvm_unreachable("Unhandled fixup kind!");
136 break;
139 break;
144 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;
241 }
242 } else if (Kind == MCExpr::SymbolRef &&
243 cast<MCSymbolRefExpr>(Expr)->getKind() ==
245 switch (MI.getOpcode()) {
246 default:
247 break;
248 case LoongArch::BEQ:
249 case LoongArch::BNE:
250 case LoongArch::BLT:
251 case LoongArch::BGE:
252 case LoongArch::BLTU:
253 case LoongArch::BGEU:
255 break;
256 case LoongArch::BEQZ:
257 case LoongArch::BNEZ:
258 case LoongArch::BCEQZ:
259 case LoongArch::BCNEZ:
261 break;
262 case LoongArch::B:
264 break;
265 }
266 }
267
269 "Unhandled expression!");
270
271 Fixups.push_back(
272 MCFixup::create(0, Expr, MCFixupKind(FixupKind), MI.getLoc()));
273 return 0;
274}
275
276void LoongArchMCCodeEmitter::encodeInstruction(
277 const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups,
278 const MCSubtargetInfo &STI) const {
279 const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
280 // Get byte count of instruction.
281 unsigned Size = Desc.getSize();
282
283 switch (Size) {
284 default:
285 llvm_unreachable("Unhandled encodeInstruction length!");
286 case 4: {
287 uint32_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
289 break;
290 }
291 }
292}
293
295 MCContext &Ctx) {
296 return new LoongArchMCCodeEmitter(Ctx, MCII);
297}
298
299#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, raw_ostream &OS, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const =0
EncodeInstruction - Encode the given Inst to bytes on the output stream OS.
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:87
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
unsigned getSize() const
Return the number of bytes in the encoding of this instruction, or zero if the encoding size cannot b...
Definition: MCInstrDesc.h:600
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
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
#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:97
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