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.
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,
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,
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>
186SystemZMCCodeEmitter::getLenEncoding(const MCInst &MI, unsigned OpNum,
188 const MCSubtargetInfo &STI) const {
189 return getImmOpValue<Kind>(MI, OpNum, Fixups, STI) - 1;
190}
191
193SystemZMCCodeEmitter::getPCRelEncoding(const MCInst &MI, unsigned OpNum,
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}
uint64_t Size
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
This file defines the SmallVector class.
static void addFixup(SmallVectorImpl< MCFixup > &Fixups, uint32_t Offset, const MCExpr *Value, uint16_t Kind, bool PCRel=false)
static unsigned getSize(unsigned Kind)
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition: MCExpr.h:343
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:23
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.
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
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
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:27
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
Generic base class for all target subtargets.
Represents a location in source code.
Definition: SMLoc.h:23
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:574
void push_back(const T &Elt)
Definition: SmallVector.h:414
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.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:477
@ FirstTargetFixupKind
Definition: MCFixup.h:44
MCCodeEmitter * createSystemZMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)
uint8_t TargetSize
The number of bits written by this fixup.
Definition: MCAsmBackend.h:48