LLVM 20.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
133void SystemZMCCodeEmitter::encodeInstruction(const MCInst &MI,
136 const MCSubtargetInfo &STI) const {
137 uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
138 unsigned Size = MCII.get(MI.getOpcode()).getSize();
139 // Big-endian insertion of Size bytes.
140 unsigned ShiftValue = (Size * 8) - 8;
141 for (unsigned I = 0; I != Size; ++I) {
142 CB.push_back(uint8_t(Bits >> ShiftValue));
143 ShiftValue -= 8;
144 }
145}
146
147uint64_t SystemZMCCodeEmitter::
148getMachineOpValue(const MCInst &MI, const MCOperand &MO,
150 const MCSubtargetInfo &STI) const {
151 if (MO.isReg())
152 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
153 // SystemZAsmParser::parseAnyRegister() produces KindImm when registers are
154 // specified as integers.
155 if (MO.isImm())
156 return static_cast<uint64_t>(MO.getImm());
157 llvm_unreachable("Unexpected operand type!");
158}
159
160template <SystemZ::FixupKind Kind>
161uint64_t SystemZMCCodeEmitter::getImmOpValue(const MCInst &MI, unsigned OpNum,
163 const MCSubtargetInfo &STI) const {
164 const MCOperand &MO = MI.getOperand(OpNum);
165 if (MO.isImm())
166 return static_cast<uint64_t>(MO.getImm());
167 if (MO.isExpr()) {
168 unsigned MIBitSize = MCII.get(MI.getOpcode()).getSize() * 8;
169 uint32_t RawBitOffset = getOperandBitOffset(MI, OpNum, STI);
170 unsigned OpBitSize =
172 uint32_t BitOffset = MIBitSize - RawBitOffset - OpBitSize;
173 Fixups.push_back(MCFixup::create(BitOffset >> 3, MO.getExpr(),
174 (MCFixupKind)Kind, MI.getLoc()));
175 return 0;
176 }
177 llvm_unreachable("Unexpected operand type!");
178}
179
180template <SystemZ::FixupKind Kind>
182SystemZMCCodeEmitter::getLenEncoding(const MCInst &MI, unsigned OpNum,
184 const MCSubtargetInfo &STI) const {
185 return getImmOpValue<Kind>(MI, OpNum, Fixups, STI) - 1;
186}
187
189SystemZMCCodeEmitter::getPCRelEncoding(const MCInst &MI, unsigned OpNum,
191 unsigned Kind, int64_t Offset,
192 bool AllowTLS) const {
193 SMLoc Loc = MI.getLoc();
194 const MCOperand &MO = MI.getOperand(OpNum);
195 const MCExpr *Expr;
196 if (MO.isImm())
197 Expr = MCConstantExpr::create(MO.getImm() + Offset, Ctx);
198 else {
199 Expr = MO.getExpr();
200 if (Offset) {
201 // The operand value is relative to the start of MI, but the fixup
202 // is relative to the operand field itself, which is Offset bytes
203 // into MI. Add Offset to the relocation value to cancel out
204 // this difference.
205 const MCExpr *OffsetExpr = MCConstantExpr::create(Offset, Ctx);
206 Expr = MCBinaryExpr::createAdd(Expr, OffsetExpr, Ctx);
207 }
208 }
209 Fixups.push_back(MCFixup::create(Offset, Expr, (MCFixupKind)Kind, Loc));
210
211 // Output the fixup for the TLS marker if present.
212 if (AllowTLS && OpNum + 1 < MI.getNumOperands()) {
213 const MCOperand &MOTLS = MI.getOperand(OpNum + 1);
214 Fixups.push_back(MCFixup::create(
215 0, MOTLS.getExpr(), (MCFixupKind)SystemZ::FK_390_TLS_CALL, Loc));
216 }
217 return 0;
218}
219
220#define GET_OPERAND_BIT_OFFSET
221#include "SystemZGenMCCodeEmitter.inc"
222
224 MCContext &Ctx) {
225 return new SystemZMCCodeEmitter(MCII, Ctx);
226}
uint64_t Size
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
This file defines the SmallVector class.
static unsigned getSize(unsigned Kind)
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:537
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.
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition: MCExpr.cpp:222
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, SMLoc Loc=SMLoc())
Definition: MCFixup.h:87
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:185
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:37
int64_t getImm() const
Definition: MCInst.h:81
bool isImm() const
Definition: MCInst.h:63
bool isReg() const
Definition: MCInst.h:62
MCRegister getReg() const
Returns the register number.
Definition: MCInst.h:70
const MCExpr * getExpr() const
Definition: MCInst.h:115
bool isExpr() const
Definition: MCInst.h:66
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:573
void push_back(const T &Elt)
Definition: SmallVector.h:413
#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:480
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:21
@ FirstTargetFixupKind
Definition: MCFixup.h:45
MCCodeEmitter * createSystemZMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)
unsigned TargetSize
The number of bits written by this fixup.