LLVM 22.0.0git
SystemZMCCodeEmitter.cpp
Go to the documentation of this file.
1//===-- SystemZMCCodeEmitter.cpp - Convert SystemZ 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 SystemZMCCodeEmitter class.
10//
11//===----------------------------------------------------------------------===//
12
17#include "llvm/MC/MCContext.h"
18#include "llvm/MC/MCExpr.h"
19#include "llvm/MC/MCFixup.h"
20#include "llvm/MC/MCInst.h"
21#include "llvm/MC/MCInstrInfo.h"
24#include <cassert>
25#include <cstdint>
26
27using namespace llvm;
28
29#define DEBUG_TYPE "mccodeemitter"
30
31namespace {
32
33class SystemZMCCodeEmitter : public MCCodeEmitter {
34 const MCInstrInfo &MCII;
35 MCContext &Ctx;
36
37public:
38 SystemZMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)
39 : MCII(MCII), Ctx(Ctx) {}
40
41 ~SystemZMCCodeEmitter() override = default;
42
43 // OVerride MCCodeEmitter.
44 void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB,
46 const MCSubtargetInfo &STI) const override;
47
48private:
49 // Automatically generated by TableGen.
50 uint64_t getBinaryCodeForInstr(const MCInst &MI,
52 const MCSubtargetInfo &STI) const;
53 uint32_t getOperandBitOffset(const MCInst &MI, unsigned OpNum,
54 const MCSubtargetInfo &STI) const;
55
56 // Called by the TableGen code to get the binary encoding of operand
57 // MO in MI. Fixups is the list of fixups against MI.
58 uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
60 const MCSubtargetInfo &STI) const;
61
62 // Return the encoded immediate value for the OpNum operand. If it is a
63 // symbol, add a fixup for it and return 0.
64 template <SystemZ::FixupKind Kind>
65 uint64_t getImmOpValue(const MCInst &MI, unsigned OpNum,
67 const MCSubtargetInfo &STI) const;
68
69 // Called by the TableGen code to get the binary encoding of a length value.
70 // Length values are encoded by subtracting 1 from the actual value.
71 template <SystemZ::FixupKind Kind>
72 uint64_t getLenEncoding(const MCInst &MI, unsigned OpNum,
74 const MCSubtargetInfo &STI) const;
75
76 // Operand OpNum of MI needs a PC-relative fixup of kind Kind at
77 // Offset bytes from the start of MI. Add the fixup to Fixups
78 // and return the in-place addend, which since we're a RELA target
79 // is always 0. If AllowTLS is true and optional operand OpNum + 1
80 // is present, also emit a TLS call fixup for it.
81 uint64_t getPCRelEncoding(const MCInst &MI, unsigned OpNum,
83 unsigned Kind, int64_t Offset,
84 bool AllowTLS) const;
85
86 uint64_t getPC16DBLEncoding(const MCInst &MI, unsigned OpNum,
88 const MCSubtargetInfo &STI) const {
89 return getPCRelEncoding(MI, OpNum, Fixups,
90 SystemZ::FK_390_PC16DBL, 2, false);
91 }
92 uint64_t getPC32DBLEncoding(const MCInst &MI, unsigned OpNum,
94 const MCSubtargetInfo &STI) const {
95 return getPCRelEncoding(MI, OpNum, Fixups,
96 SystemZ::FK_390_PC32DBL, 2, false);
97 }
98 uint64_t getPC16DBLTLSEncoding(const MCInst &MI, unsigned OpNum,
100 const MCSubtargetInfo &STI) const {
101 return getPCRelEncoding(MI, OpNum, Fixups,
102 SystemZ::FK_390_PC16DBL, 2, true);
103 }
104 uint64_t getPC32DBLTLSEncoding(const MCInst &MI, unsigned OpNum,
106 const MCSubtargetInfo &STI) const {
107 return getPCRelEncoding(MI, OpNum, Fixups,
108 SystemZ::FK_390_PC32DBL, 2, true);
109 }
110 uint64_t getPC12DBLBPPEncoding(const MCInst &MI, unsigned OpNum,
112 const MCSubtargetInfo &STI) const {
113 return getPCRelEncoding(MI, OpNum, Fixups,
114 SystemZ::FK_390_PC12DBL, 1, false);
115 }
116 uint64_t getPC16DBLBPPEncoding(const MCInst &MI, unsigned OpNum,
118 const MCSubtargetInfo &STI) const {
119 return getPCRelEncoding(MI, OpNum, Fixups,
120 SystemZ::FK_390_PC16DBL, 4, false);
121 }
122 uint64_t getPC24DBLBPPEncoding(const MCInst &MI, unsigned OpNum,
124 const MCSubtargetInfo &STI) const {
125 return getPCRelEncoding(MI, OpNum, Fixups,
126 SystemZ::FK_390_PC24DBL, 3, false);
127 }
128};
129
130} // end anonymous namespace
131 //
133 const MCExpr *Value, uint16_t Kind, bool PCRel = false) {
134 Fixups.push_back(MCFixup::create(Offset, Value, Kind, PCRel));
135}
136
137void SystemZMCCodeEmitter::encodeInstruction(const MCInst &MI,
140 const MCSubtargetInfo &STI) const {
141 uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
142 unsigned Size = MCII.get(MI.getOpcode()).getSize();
143 // Big-endian insertion of Size bytes.
144 unsigned ShiftValue = (Size * 8) - 8;
145 for (unsigned I = 0; I != Size; ++I) {
146 CB.push_back(uint8_t(Bits >> ShiftValue));
147 ShiftValue -= 8;
148 }
149}
150
151uint64_t SystemZMCCodeEmitter::
152getMachineOpValue(const MCInst &MI, const MCOperand &MO,
153 SmallVectorImpl<MCFixup> &Fixups,
154 const MCSubtargetInfo &STI) const {
155 if (MO.isReg())
156 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
157 // SystemZAsmParser::parseAnyRegister() produces KindImm when registers are
158 // specified as integers.
159 if (MO.isImm())
160 return static_cast<uint64_t>(MO.getImm());
161 llvm_unreachable("Unexpected operand type!");
162}
163
164template <SystemZ::FixupKind Kind>
165uint64_t SystemZMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNum,
166 SmallVectorImpl<MCFixup> &Fixups,
167 const MCSubtargetInfo &STI) const {
168 const MCOperand &MO = MI.getOperand(OpNum);
169 if (MO.isImm())
170 return static_cast<uint64_t>(MO.getImm());
171 if (MO.isExpr()) {
172 unsigned MIBitSize = MCII.get(MI.getOpcode()).getSize() * 8;
173 uint32_t RawBitOffset = getOperandBitOffset(MI, OpNum, STI);
174 unsigned OpBitSize =
176 uint32_t BitOffset = MIBitSize - RawBitOffset - OpBitSize;
177 addFixup(Fixups, BitOffset >> 3, MO.getExpr(), Kind);
178 return 0;
179 }
180 llvm_unreachable("Unexpected operand type!");
181}
182
183template <SystemZ::FixupKind Kind>
184uint64_t
185SystemZMCCodeEmitter::getLenEncoding(const MCInst &MI, unsigned OpNum,
186 SmallVectorImpl<MCFixup> &Fixups,
187 const MCSubtargetInfo &STI) const {
188 return getImmOpValue<Kind>(MI, OpNum, Fixups, STI) - 1;
189}
190
191uint64_t
192SystemZMCCodeEmitter::getPCRelEncoding(const MCInst &MI, unsigned OpNum,
193 SmallVectorImpl<MCFixup> &Fixups,
194 unsigned Kind, int64_t Offset,
195 bool AllowTLS) const {
196 SMLoc Loc = MI.getLoc();
197 const MCOperand &MO = MI.getOperand(OpNum);
198 const MCExpr *Expr;
199 if (MO.isImm())
200 Expr = MCConstantExpr::create(MO.getImm() + Offset, Ctx);
201 else {
202 Expr = MO.getExpr();
203 if (Offset) {
204 // The operand value is relative to the start of MI, but the fixup
205 // is relative to the operand field itself, which is Offset bytes
206 // into MI. Add Offset to the relocation value to cancel out
207 // this difference.
208 const MCExpr *OffsetExpr = MCConstantExpr::create(Offset, Ctx);
209 Expr = MCBinaryExpr::createAdd(Expr, OffsetExpr, Ctx, Loc);
210 }
211 }
212 addFixup(Fixups, Offset, Expr, Kind, true);
213
214 // Output the fixup for the TLS marker if present.
215 if (AllowTLS && OpNum + 1 < MI.getNumOperands()) {
216 const MCOperand &MOTLS = MI.getOperand(OpNum + 1);
217 addFixup(Fixups, 0, MOTLS.getExpr(), SystemZ::FK_390_TLS_CALL);
218 }
219 return 0;
220}
221
222#define GET_OPERAND_BIT_OFFSET
223#include "SystemZGenMCCodeEmitter.inc"
224
226 MCContext &Ctx) {
227 return new SystemZMCCodeEmitter(MCII, Ctx);
228}
static void addFixup(SmallVectorImpl< MCFixup > &Fixups, uint32_t Offset, const MCExpr *Value, uint16_t Kind, bool PCRel=false)
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:58
This file defines the SmallVector class.
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:343
MCCodeEmitter - Generic instruction encoding interface.
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
Context object for machine code objects.
Definition MCContext.h:83
const MCRegisterInfo * getRegisterInfo() const
Definition MCContext.h:414
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
unsigned getSize() const
Return the number of bytes in the encoding of this instruction, or zero if the encoding size cannot b...
Interface to description of machine instruction set.
Definition MCInstrInfo.h:27
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Definition MCInstrInfo.h:90
Instances of this class represent operands of the MCInst class.
Definition MCInst.h:40
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...
void push_back(const T &Elt)
LLVM Value Representation.
Definition Value.h:75
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static const MCFixupKindInfo MCFixupKindInfos[SystemZ::NumTargetFixupKinds]
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:477
static void addFixup(SmallVectorImpl< MCFixup > &Fixups, uint32_t Offset, const MCExpr *Value, uint16_t Kind)
@ FirstTargetFixupKind
Definition MCFixup.h:44
MCCodeEmitter * createSystemZMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)
uint8_t TargetSize
The number of bits written by this fixup.