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"
25#include <cassert>
26#include <cstdint>
27
28using namespace llvm;
29
30#define DEBUG_TYPE "mccodeemitter"
31
32namespace {
33
34class SystemZMCCodeEmitter : public MCCodeEmitter {
35 const MCInstrInfo &MCII;
36 MCContext &Ctx;
37
38public:
39 SystemZMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)
40 : MCII(MCII), Ctx(Ctx) {}
41
42 ~SystemZMCCodeEmitter() override = default;
43
44 // OVerride MCCodeEmitter.
45 void encodeInstruction(const MCInst &MI, SmallVectorImpl<char> &CB,
47 const MCSubtargetInfo &STI) const override;
48
49private:
50 // Automatically generated by TableGen.
51 uint64_t getBinaryCodeForInstr(const MCInst &MI,
53 const MCSubtargetInfo &STI) const;
54 uint32_t getOperandBitOffset(const MCInst &MI, unsigned OpNum,
55 const MCSubtargetInfo &STI) const;
56
57 // Called by the TableGen code to get the binary encoding of operand
58 // MO in MI. Fixups is the list of fixups against MI.
59 uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
61 const MCSubtargetInfo &STI) const;
62
63 // Return the encoded immediate value for the OpNum operand. If it is a
64 // symbol, add a fixup for it and return 0.
65 template <SystemZ::FixupKind Kind>
66 uint64_t getImmOpValue(const MCInst &MI, unsigned OpNum,
68 const MCSubtargetInfo &STI) const;
69
70 // Called by the TableGen code to get the binary encoding of a length value.
71 // Length values are encoded by subtracting 1 from the actual value.
72 template <SystemZ::FixupKind Kind>
73 uint64_t getLenEncoding(const MCInst &MI, unsigned OpNum,
75 const MCSubtargetInfo &STI) const;
76
77 // Operand OpNum of MI needs a PC-relative fixup of kind Kind at
78 // Offset bytes from the start of MI. Add the fixup to Fixups
79 // and return the in-place addend, which since we're a RELA target
80 // is always 0. If AllowTLS is true and optional operand OpNum + 1
81 // is present, also emit a TLS call fixup for it.
82 uint64_t getPCRelEncoding(const MCInst &MI, unsigned OpNum,
84 unsigned Kind, int64_t Offset,
85 bool AllowTLS) const;
86
87 uint64_t getPC16DBLEncoding(const MCInst &MI, unsigned OpNum,
89 const MCSubtargetInfo &STI) const {
90 return getPCRelEncoding(MI, OpNum, Fixups,
91 SystemZ::FK_390_PC16DBL, 2, false);
92 }
93 uint64_t getPC32DBLEncoding(const MCInst &MI, unsigned OpNum,
95 const MCSubtargetInfo &STI) const {
96 return getPCRelEncoding(MI, OpNum, Fixups,
97 SystemZ::FK_390_PC32DBL, 2, false);
98 }
99 uint64_t getPC16DBLTLSEncoding(const MCInst &MI, unsigned OpNum,
101 const MCSubtargetInfo &STI) const {
102 return getPCRelEncoding(MI, OpNum, Fixups,
103 SystemZ::FK_390_PC16DBL, 2, true);
104 }
105 uint64_t getPC32DBLTLSEncoding(const MCInst &MI, unsigned OpNum,
107 const MCSubtargetInfo &STI) const {
108 return getPCRelEncoding(MI, OpNum, Fixups,
109 SystemZ::FK_390_PC32DBL, 2, true);
110 }
111 uint64_t getPC12DBLBPPEncoding(const MCInst &MI, unsigned OpNum,
113 const MCSubtargetInfo &STI) const {
114 return getPCRelEncoding(MI, OpNum, Fixups,
115 SystemZ::FK_390_PC12DBL, 1, false);
116 }
117 uint64_t getPC16DBLBPPEncoding(const MCInst &MI, unsigned OpNum,
119 const MCSubtargetInfo &STI) const {
120 return getPCRelEncoding(MI, OpNum, Fixups,
121 SystemZ::FK_390_PC16DBL, 4, false);
122 }
123 uint64_t getPC24DBLBPPEncoding(const MCInst &MI, unsigned OpNum,
125 const MCSubtargetInfo &STI) const {
126 return getPCRelEncoding(MI, OpNum, Fixups,
127 SystemZ::FK_390_PC24DBL, 3, false);
128 }
129};
130
131} // end anonymous namespace
132 //
134 const MCExpr *Value, uint16_t Kind, bool PCRel = false) {
135 Fixups.push_back(MCFixup::create(Offset, Value, Kind, PCRel));
136}
137
138void SystemZMCCodeEmitter::encodeInstruction(const MCInst &MI,
141 const MCSubtargetInfo &STI) const {
142 uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
143 unsigned Size = MCII.get(MI.getOpcode()).getSize();
144 // Big-endian insertion of Size bytes.
145 unsigned ShiftValue = (Size * 8) - 8;
146 for (unsigned I = 0; I != Size; ++I) {
147 CB.push_back(uint8_t(Bits >> ShiftValue));
148 ShiftValue -= 8;
149 }
150}
151
152uint64_t SystemZMCCodeEmitter::
153getMachineOpValue(const MCInst &MI, const MCOperand &MO,
154 SmallVectorImpl<MCFixup> &Fixups,
155 const MCSubtargetInfo &STI) const {
156 if (MO.isReg())
157 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
158 // SystemZAsmParser::parseAnyRegister() produces KindImm when registers are
159 // specified as integers.
160 if (MO.isImm())
161 return static_cast<uint64_t>(MO.getImm());
162 llvm_unreachable("Unexpected operand type!");
163}
164
165template <SystemZ::FixupKind Kind>
166uint64_t SystemZMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNum,
167 SmallVectorImpl<MCFixup> &Fixups,
168 const MCSubtargetInfo &STI) const {
169 const MCOperand &MO = MI.getOperand(OpNum);
170 if (MO.isImm())
171 return static_cast<uint64_t>(MO.getImm());
172 if (MO.isExpr()) {
173 unsigned MIBitSize = MCII.get(MI.getOpcode()).getSize() * 8;
174 uint32_t RawBitOffset = getOperandBitOffset(MI, OpNum, STI);
175 unsigned OpBitSize =
177 uint32_t BitOffset = MIBitSize - RawBitOffset - OpBitSize;
178 addFixup(Fixups, BitOffset >> 3, MO.getExpr(), Kind);
179 return 0;
180 }
181 llvm_unreachable("Unexpected operand type!");
182}
183
184template <SystemZ::FixupKind Kind>
185uint64_t
186SystemZMCCodeEmitter::getLenEncoding(const MCInst &MI, unsigned OpNum,
187 SmallVectorImpl<MCFixup> &Fixups,
188 const MCSubtargetInfo &STI) const {
189 return getImmOpValue<Kind>(MI, OpNum, Fixups, STI) - 1;
190}
191
192uint64_t
193SystemZMCCodeEmitter::getPCRelEncoding(const MCInst &MI, unsigned OpNum,
194 SmallVectorImpl<MCFixup> &Fixups,
195 unsigned Kind, int64_t Offset,
196 bool AllowTLS) const {
197 SMLoc Loc = MI.getLoc();
198 const MCOperand &MO = MI.getOperand(OpNum);
199 const MCExpr *Expr;
200 if (MO.isImm())
201 Expr = MCConstantExpr::create(MO.getImm() + Offset, Ctx);
202 else {
203 Expr = MO.getExpr();
204 if (Offset) {
205 // The operand value is relative to the start of MI, but the fixup
206 // is relative to the operand field itself, which is Offset bytes
207 // into MI. Add Offset to the relocation value to cancel out
208 // this difference.
209 const MCExpr *OffsetExpr = MCConstantExpr::create(Offset, Ctx);
210 Expr = MCBinaryExpr::createAdd(Expr, OffsetExpr, Ctx, Loc);
211 }
212 }
213 addFixup(Fixups, Offset, Expr, Kind, true);
214
215 // Output the fixup for the TLS marker if present.
216 if (AllowTLS && OpNum + 1 < MI.getNumOperands()) {
217 const MCOperand &MOTLS = MI.getOperand(OpNum + 1);
218 addFixup(Fixups, 0, MOTLS.getExpr(), SystemZ::FK_390_TLS_CALL);
219 }
220 return 0;
221}
222
223#define GET_OPERAND_BIT_OFFSET
224#include "SystemZGenMCCodeEmitter.inc"
225
227 MCContext &Ctx) {
228 return new SystemZMCCodeEmitter(MCII, Ctx);
229}
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.