LLVM  6.0.0svn
SystemZMCCodeEmitter.cpp
Go to the documentation of this file.
1 //===-- SystemZMCCodeEmitter.cpp - Convert SystemZ code to machine code ---===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the SystemZMCCodeEmitter class.
11 //
12 //===----------------------------------------------------------------------===//
13 
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/MC/MCCodeEmitter.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCFixup.h"
21 #include "llvm/MC/MCInst.h"
22 #include "llvm/MC/MCInstrInfo.h"
23 #include "llvm/MC/MCRegisterInfo.h"
27 #include <cassert>
28 #include <cstdint>
29 
30 using namespace llvm;
31 
32 #define DEBUG_TYPE "mccodeemitter"
33 
34 namespace {
35 
36 class SystemZMCCodeEmitter : public MCCodeEmitter {
37  const MCInstrInfo &MCII;
38  MCContext &Ctx;
39 
40 public:
41  SystemZMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
42  : MCII(mcii), Ctx(ctx) {
43  }
44 
45  ~SystemZMCCodeEmitter() override = default;
46 
47  // OVerride MCCodeEmitter.
48  void encodeInstruction(const MCInst &MI, raw_ostream &OS,
50  const MCSubtargetInfo &STI) const override;
51 
52 private:
53  // Automatically generated by TableGen.
54  uint64_t getBinaryCodeForInstr(const MCInst &MI,
56  const MCSubtargetInfo &STI) const;
57 
58  // Called by the TableGen code to get the binary encoding of operand
59  // MO in MI. Fixups is the list of fixups against MI.
60  uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
62  const MCSubtargetInfo &STI) const;
63 
64  // Called by the TableGen code to get the binary encoding of an address.
65  // The index or length, if any, is encoded first, followed by the base,
66  // followed by the displacement. In a 20-bit displacement,
67  // the low 12 bits are encoded before the high 8 bits.
68  uint64_t getBDAddr12Encoding(const MCInst &MI, unsigned OpNum,
70  const MCSubtargetInfo &STI) const;
71  uint64_t getBDAddr20Encoding(const MCInst &MI, unsigned OpNum,
73  const MCSubtargetInfo &STI) const;
74  uint64_t getBDXAddr12Encoding(const MCInst &MI, unsigned OpNum,
76  const MCSubtargetInfo &STI) const;
77  uint64_t getBDXAddr20Encoding(const MCInst &MI, unsigned OpNum,
79  const MCSubtargetInfo &STI) const;
80  uint64_t getBDLAddr12Len4Encoding(const MCInst &MI, unsigned OpNum,
82  const MCSubtargetInfo &STI) const;
83  uint64_t getBDLAddr12Len8Encoding(const MCInst &MI, unsigned OpNum,
85  const MCSubtargetInfo &STI) const;
86  uint64_t getBDRAddr12Encoding(const MCInst &MI, unsigned OpNum,
88  const MCSubtargetInfo &STI) const;
89  uint64_t getBDVAddr12Encoding(const MCInst &MI, unsigned OpNum,
91  const MCSubtargetInfo &STI) const;
92 
93  // Operand OpNum of MI needs a PC-relative fixup of kind Kind at
94  // Offset bytes from the start of MI. Add the fixup to Fixups
95  // and return the in-place addend, which since we're a RELA target
96  // is always 0. If AllowTLS is true and optional operand OpNum + 1
97  // is present, also emit a TLS call fixup for it.
98  uint64_t getPCRelEncoding(const MCInst &MI, unsigned OpNum,
100  unsigned Kind, int64_t Offset,
101  bool AllowTLS) const;
102 
103  uint64_t getPC16DBLEncoding(const MCInst &MI, unsigned OpNum,
104  SmallVectorImpl<MCFixup> &Fixups,
105  const MCSubtargetInfo &STI) const {
106  return getPCRelEncoding(MI, OpNum, Fixups,
107  SystemZ::FK_390_PC16DBL, 2, false);
108  }
109  uint64_t getPC32DBLEncoding(const MCInst &MI, unsigned OpNum,
110  SmallVectorImpl<MCFixup> &Fixups,
111  const MCSubtargetInfo &STI) const {
112  return getPCRelEncoding(MI, OpNum, Fixups,
113  SystemZ::FK_390_PC32DBL, 2, false);
114  }
115  uint64_t getPC16DBLTLSEncoding(const MCInst &MI, unsigned OpNum,
116  SmallVectorImpl<MCFixup> &Fixups,
117  const MCSubtargetInfo &STI) const {
118  return getPCRelEncoding(MI, OpNum, Fixups,
119  SystemZ::FK_390_PC16DBL, 2, true);
120  }
121  uint64_t getPC32DBLTLSEncoding(const MCInst &MI, unsigned OpNum,
122  SmallVectorImpl<MCFixup> &Fixups,
123  const MCSubtargetInfo &STI) const {
124  return getPCRelEncoding(MI, OpNum, Fixups,
125  SystemZ::FK_390_PC32DBL, 2, true);
126  }
127  uint64_t getPC12DBLBPPEncoding(const MCInst &MI, unsigned OpNum,
128  SmallVectorImpl<MCFixup> &Fixups,
129  const MCSubtargetInfo &STI) const {
130  return getPCRelEncoding(MI, OpNum, Fixups,
131  SystemZ::FK_390_PC12DBL, 1, false);
132  }
133  uint64_t getPC16DBLBPPEncoding(const MCInst &MI, unsigned OpNum,
134  SmallVectorImpl<MCFixup> &Fixups,
135  const MCSubtargetInfo &STI) const {
136  return getPCRelEncoding(MI, OpNum, Fixups,
137  SystemZ::FK_390_PC16DBL, 4, false);
138  }
139  uint64_t getPC24DBLBPPEncoding(const MCInst &MI, unsigned OpNum,
140  SmallVectorImpl<MCFixup> &Fixups,
141  const MCSubtargetInfo &STI) const {
142  return getPCRelEncoding(MI, OpNum, Fixups,
143  SystemZ::FK_390_PC24DBL, 3, false);
144  }
145 
146 private:
147  uint64_t computeAvailableFeatures(const FeatureBitset &FB) const;
148  void verifyInstructionPredicates(const MCInst &MI,
149  uint64_t 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:59
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
bool isReg() const
Definition: MCInst.h:58
const FeatureBitset & getFeatureBits() const
getFeatureBits - Return the feature bits.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:36
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:65
Context object for machine code objects.
Definition: MCContext.h:59
const MCExpr * getExpr() const
Definition: MCInst.h:96
static const MCBinaryExpr * createAdd(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:451
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:159
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
int64_t getImm() const
Definition: MCInst.h:76
constexpr bool isUInt< 8 >(uint64_t x)
Definition: MathExtras.h:335
unsigned const MachineRegisterInfo * MRI
Container class for subtarget features.
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:22
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:24
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:23
unsigned getNumOperands() const
Definition: MCInst.h:182
static MCFixup create(uint32_t Offset, const MCExpr *Value, MCFixupKind Kind, SMLoc Loc=SMLoc())
Definition: MCFixup.h:82
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:180
MCCodeEmitter * createSystemZMCCodeEmitter(const MCInstrInfo &MCII, const MCRegisterInfo &MRI, MCContext &Ctx)
#define I(x, y, z)
Definition: MD5.cpp:58
MCSubtargetInfo - Generic base class for all target subtargets.
const unsigned Kind
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
constexpr char Size[]
Key for Kernel::Arg::Metadata::mSize.
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
IRTranslator LLVM IR MI
unsigned getOpcode() const
Definition: MCInst.h:172
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:35
static const MCConstantExpr * create(int64_t Value, MCContext &Ctx)
Definition: MCExpr.cpp:159