LLVM  10.0.0svn
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 
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/MC/MCCodeEmitter.h"
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"
22 #include "llvm/MC/MCRegisterInfo.h"
26 #include <cassert>
27 #include <cstdint>
28 
29 using namespace llvm;
30 
31 #define DEBUG_TYPE "mccodeemitter"
32 
33 namespace {
34 
35 class SystemZMCCodeEmitter : public MCCodeEmitter {
36  const MCInstrInfo &MCII;
37  MCContext &Ctx;
38 
39 public:
40  SystemZMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
41  : MCII(mcii), Ctx(ctx) {
42  }
43 
44  ~SystemZMCCodeEmitter() override = default;
45 
46  // OVerride MCCodeEmitter.
47  void encodeInstruction(const MCInst &MI, raw_ostream &OS,
49  const MCSubtargetInfo &STI) const override;
50 
51 private:
52  // Automatically generated by TableGen.
53  uint64_t getBinaryCodeForInstr(const MCInst &MI,
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  // Called by the TableGen code to get the binary encoding of an address.
64  // The index or length, if any, is encoded first, followed by the base,
65  // followed by the displacement. In a 20-bit displacement,
66  // the low 12 bits are encoded before the high 8 bits.
67  uint64_t getBDAddr12Encoding(const MCInst &MI, unsigned OpNum,
69  const MCSubtargetInfo &STI) const;
70  uint64_t getBDAddr20Encoding(const MCInst &MI, unsigned OpNum,
72  const MCSubtargetInfo &STI) const;
73  uint64_t getBDXAddr12Encoding(const MCInst &MI, unsigned OpNum,
75  const MCSubtargetInfo &STI) const;
76  uint64_t getBDXAddr20Encoding(const MCInst &MI, unsigned OpNum,
78  const MCSubtargetInfo &STI) const;
79  uint64_t getBDLAddr12Len4Encoding(const MCInst &MI, unsigned OpNum,
81  const MCSubtargetInfo &STI) const;
82  uint64_t getBDLAddr12Len8Encoding(const MCInst &MI, unsigned OpNum,
84  const MCSubtargetInfo &STI) const;
85  uint64_t getBDRAddr12Encoding(const MCInst &MI, unsigned OpNum,
87  const MCSubtargetInfo &STI) const;
88  uint64_t getBDVAddr12Encoding(const MCInst &MI, unsigned OpNum,
90  const MCSubtargetInfo &STI) const;
91 
92  // Operand OpNum of MI needs a PC-relative fixup of kind Kind at
93  // Offset bytes from the start of MI. Add the fixup to Fixups
94  // and return the in-place addend, which since we're a RELA target
95  // is always 0. If AllowTLS is true and optional operand OpNum + 1
96  // is present, also emit a TLS call fixup for it.
97  uint64_t getPCRelEncoding(const MCInst &MI, unsigned OpNum,
99  unsigned Kind, int64_t Offset,
100  bool AllowTLS) const;
101 
102  uint64_t getPC16DBLEncoding(const MCInst &MI, unsigned OpNum,
103  SmallVectorImpl<MCFixup> &Fixups,
104  const MCSubtargetInfo &STI) const {
105  return getPCRelEncoding(MI, OpNum, Fixups,
106  SystemZ::FK_390_PC16DBL, 2, false);
107  }
108  uint64_t getPC32DBLEncoding(const MCInst &MI, unsigned OpNum,
109  SmallVectorImpl<MCFixup> &Fixups,
110  const MCSubtargetInfo &STI) const {
111  return getPCRelEncoding(MI, OpNum, Fixups,
112  SystemZ::FK_390_PC32DBL, 2, false);
113  }
114  uint64_t getPC16DBLTLSEncoding(const MCInst &MI, unsigned OpNum,
115  SmallVectorImpl<MCFixup> &Fixups,
116  const MCSubtargetInfo &STI) const {
117  return getPCRelEncoding(MI, OpNum, Fixups,
118  SystemZ::FK_390_PC16DBL, 2, true);
119  }
120  uint64_t getPC32DBLTLSEncoding(const MCInst &MI, unsigned OpNum,
121  SmallVectorImpl<MCFixup> &Fixups,
122  const MCSubtargetInfo &STI) const {
123  return getPCRelEncoding(MI, OpNum, Fixups,
124  SystemZ::FK_390_PC32DBL, 2, true);
125  }
126  uint64_t getPC12DBLBPPEncoding(const MCInst &MI, unsigned OpNum,
127  SmallVectorImpl<MCFixup> &Fixups,
128  const MCSubtargetInfo &STI) const {
129  return getPCRelEncoding(MI, OpNum, Fixups,
130  SystemZ::FK_390_PC12DBL, 1, false);
131  }
132  uint64_t getPC16DBLBPPEncoding(const MCInst &MI, unsigned OpNum,
133  SmallVectorImpl<MCFixup> &Fixups,
134  const MCSubtargetInfo &STI) const {
135  return getPCRelEncoding(MI, OpNum, Fixups,
136  SystemZ::FK_390_PC16DBL, 4, false);
137  }
138  uint64_t getPC24DBLBPPEncoding(const MCInst &MI, unsigned OpNum,
139  SmallVectorImpl<MCFixup> &Fixups,
140  const MCSubtargetInfo &STI) const {
141  return getPCRelEncoding(MI, OpNum, Fixups,
142  SystemZ::FK_390_PC24DBL, 3, false);
143  }
144 
145 private:
146  FeatureBitset computeAvailableFeatures(const FeatureBitset &FB) const;
147  void
148  verifyInstructionPredicates(const MCInst &MI,
149  const FeatureBitset &AvailableFeatures) const;
150 };
151 
152 } // end anonymous namespace
153 
154 void SystemZMCCodeEmitter::
155 encodeInstruction(const MCInst &MI, raw_ostream &OS,
157  const MCSubtargetInfo &STI) const {
158  verifyInstructionPredicates(MI,
159  computeAvailableFeatures(STI.getFeatureBits()));
160 
161  uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
162  unsigned Size = MCII.get(MI.getOpcode()).getSize();
163  // Big-endian insertion of Size bytes.
164  unsigned ShiftValue = (Size * 8) - 8;
165  for (unsigned I = 0; I != Size; ++I) {
166  OS << uint8_t(Bits >> ShiftValue);
167  ShiftValue -= 8;
168  }
169 }
170 
171 uint64_t SystemZMCCodeEmitter::
172 getMachineOpValue(const MCInst &MI, const MCOperand &MO,
173  SmallVectorImpl<MCFixup> &Fixups,
174  const MCSubtargetInfo &STI) const {
175  if (MO.isReg())
176  return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
177  if (MO.isImm())
178  return static_cast<uint64_t>(MO.getImm());
179  llvm_unreachable("Unexpected operand type!");
180 }
181 
182 uint64_t SystemZMCCodeEmitter::
183 getBDAddr12Encoding(const MCInst &MI, unsigned OpNum,
184  SmallVectorImpl<MCFixup> &Fixups,
185  const MCSubtargetInfo &STI) const {
186  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
187  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
188  assert(isUInt<4>(Base) && isUInt<12>(Disp));
189  return (Base << 12) | Disp;
190 }
191 
192 uint64_t SystemZMCCodeEmitter::
193 getBDAddr20Encoding(const MCInst &MI, unsigned OpNum,
194  SmallVectorImpl<MCFixup> &Fixups,
195  const MCSubtargetInfo &STI) const {
196  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
197  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
198  assert(isUInt<4>(Base) && isInt<20>(Disp));
199  return (Base << 20) | ((Disp & 0xfff) << 8) | ((Disp & 0xff000) >> 12);
200 }
201 
202 uint64_t SystemZMCCodeEmitter::
203 getBDXAddr12Encoding(const MCInst &MI, unsigned OpNum,
204  SmallVectorImpl<MCFixup> &Fixups,
205  const MCSubtargetInfo &STI) const {
206  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
207  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
208  uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI);
209  assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<4>(Index));
210  return (Index << 16) | (Base << 12) | Disp;
211 }
212 
213 uint64_t SystemZMCCodeEmitter::
214 getBDXAddr20Encoding(const MCInst &MI, unsigned OpNum,
215  SmallVectorImpl<MCFixup> &Fixups,
216  const MCSubtargetInfo &STI) const {
217  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
218  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
219  uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI);
220  assert(isUInt<4>(Base) && isInt<20>(Disp) && isUInt<4>(Index));
221  return (Index << 24) | (Base << 20) | ((Disp & 0xfff) << 8)
222  | ((Disp & 0xff000) >> 12);
223 }
224 
225 uint64_t SystemZMCCodeEmitter::
226 getBDLAddr12Len4Encoding(const MCInst &MI, unsigned OpNum,
227  SmallVectorImpl<MCFixup> &Fixups,
228  const MCSubtargetInfo &STI) const {
229  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
230  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
231  uint64_t Len = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI) - 1;
232  assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<4>(Len));
233  return (Len << 16) | (Base << 12) | Disp;
234 }
235 
236 uint64_t SystemZMCCodeEmitter::
237 getBDLAddr12Len8Encoding(const MCInst &MI, unsigned OpNum,
238  SmallVectorImpl<MCFixup> &Fixups,
239  const MCSubtargetInfo &STI) const {
240  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
241  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
242  uint64_t Len = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI) - 1;
243  assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<8>(Len));
244  return (Len << 16) | (Base << 12) | Disp;
245 }
246 
247 uint64_t SystemZMCCodeEmitter::
248 getBDRAddr12Encoding(const MCInst &MI, unsigned OpNum,
249  SmallVectorImpl<MCFixup> &Fixups,
250  const MCSubtargetInfo &STI) const {
251  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
252  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
253  uint64_t Len = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI);
254  assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<4>(Len));
255  return (Len << 16) | (Base << 12) | Disp;
256 }
257 
258 uint64_t SystemZMCCodeEmitter::
259 getBDVAddr12Encoding(const MCInst &MI, unsigned OpNum,
260  SmallVectorImpl<MCFixup> &Fixups,
261  const MCSubtargetInfo &STI) const {
262  uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
263  uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
264  uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI);
265  assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<5>(Index));
266  return (Index << 16) | (Base << 12) | Disp;
267 }
268 
269 uint64_t
270 SystemZMCCodeEmitter::getPCRelEncoding(const MCInst &MI, unsigned OpNum,
271  SmallVectorImpl<MCFixup> &Fixups,
272  unsigned Kind, int64_t Offset,
273  bool AllowTLS) const {
274  const MCOperand &MO = MI.getOperand(OpNum);
275  const MCExpr *Expr;
276  if (MO.isImm())
277  Expr = MCConstantExpr::create(MO.getImm() + Offset, Ctx);
278  else {
279  Expr = MO.getExpr();
280  if (Offset) {
281  // The operand value is relative to the start of MI, but the fixup
282  // is relative to the operand field itself, which is Offset bytes
283  // into MI. Add Offset to the relocation value to cancel out
284  // this difference.
285  const MCExpr *OffsetExpr = MCConstantExpr::create(Offset, Ctx);
286  Expr = MCBinaryExpr::createAdd(Expr, OffsetExpr, Ctx);
287  }
288  }
289  Fixups.push_back(MCFixup::create(Offset, Expr, (MCFixupKind)Kind));
290 
291  // Output the fixup for the TLS marker if present.
292  if (AllowTLS && OpNum + 1 < MI.getNumOperands()) {
293  const MCOperand &MOTLS = MI.getOperand(OpNum + 1);
294  Fixups.push_back(MCFixup::create(0, MOTLS.getExpr(),
296  }
297  return 0;
298 }
299 
300 #define ENABLE_INSTR_PREDICATE_VERIFIER
301 #include "SystemZGenMCCodeEmitter.inc"
302 
304  const MCRegisterInfo &MRI,
305  MCContext &Ctx) {
306  return new SystemZMCCodeEmitter(MCII, Ctx);
307 }
bool isImm() const
Definition: MCInst.h:58
This class represents lattice values for constants.
Definition: AllocatorList.h:23
bool isReg() const
Definition: MCInst.h:57
const FeatureBitset & getFeatureBits() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:41
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:64
Context object for machine code objects.
Definition: MCContext.h:65
const MCExpr * getExpr() const
Definition: MCInst.h:95
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:465
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:158
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false)
Definition: MCExpr.cpp:169
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
int64_t getImm() const
Definition: MCInst.h:75
constexpr bool isUInt< 8 >(uint64_t x)
Definition: MathExtras.h:342
unsigned const MachineRegisterInfo * MRI
Container class for subtarget features.
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:21
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:23
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:22
unsigned getNumOperands() const
Definition: MCInst.h:181
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Definition: MCFixup.h:93
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:179
MCCodeEmitter * createSystemZMCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, MCContext &Ctx)
#define I(x, y, z)
Definition: MD5.cpp:58
Generic base class for all target subtargets.
uint32_t Size
Definition: Profile.cpp:46
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
IRTranslator LLVM IR MI
unsigned getOpcode() const
Definition: MCInst.h:171
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:34