blob: 7082abad716dacf85a0f59124929925ab6e6bdda [file] [log] [blame]
Ulrich Weigand5f613df2013-05-06 16:15:19 +00001//===-- 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
Ulrich Weigand5f613df2013-05-06 16:15:19 +000014#include "MCTargetDesc/SystemZMCTargetDesc.h"
15#include "MCTargetDesc/SystemZMCFixups.h"
16#include "llvm/MC/MCCodeEmitter.h"
17#include "llvm/MC/MCContext.h"
18#include "llvm/MC/MCExpr.h"
Pete Cooper3de83e42015-05-15 21:58:42 +000019#include "llvm/MC/MCInst.h"
Ulrich Weigand5f613df2013-05-06 16:15:19 +000020#include "llvm/MC/MCInstrInfo.h"
Pete Cooper3de83e42015-05-15 21:58:42 +000021#include "llvm/MC/MCRegisterInfo.h"
Ulrich Weigand5f613df2013-05-06 16:15:19 +000022
23using namespace llvm;
24
Chandler Carruth84e68b22014-04-22 02:41:26 +000025#define DEBUG_TYPE "mccodeemitter"
26
Ulrich Weigand5f613df2013-05-06 16:15:19 +000027namespace {
28class SystemZMCCodeEmitter : public MCCodeEmitter {
29 const MCInstrInfo &MCII;
30 MCContext &Ctx;
31
32public:
33 SystemZMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
34 : MCII(mcii), Ctx(ctx) {
35 }
36
Alexander Kornienkof817c1c2015-04-11 02:11:45 +000037 ~SystemZMCCodeEmitter() override {}
Ulrich Weigand5f613df2013-05-06 16:15:19 +000038
39 // OVerride MCCodeEmitter.
Jim Grosbach91df21f2015-05-15 19:13:16 +000040 void encodeInstruction(const MCInst &MI, raw_ostream &OS,
Richard Sandifordb4d67b52014-03-06 12:03:36 +000041 SmallVectorImpl<MCFixup> &Fixups,
42 const MCSubtargetInfo &STI) const override;
Ulrich Weigand5f613df2013-05-06 16:15:19 +000043
44private:
45 // Automatically generated by TableGen.
46 uint64_t getBinaryCodeForInstr(const MCInst &MI,
David Woodhouse3fa98a62014-01-28 23:13:18 +000047 SmallVectorImpl<MCFixup> &Fixups,
48 const MCSubtargetInfo &STI) const;
Ulrich Weigand5f613df2013-05-06 16:15:19 +000049
50 // Called by the TableGen code to get the binary encoding of operand
51 // MO in MI. Fixups is the list of fixups against MI.
Richard Sandifordd454ec02013-05-14 09:28:21 +000052 uint64_t getMachineOpValue(const MCInst &MI, const MCOperand &MO,
David Woodhouse3fa98a62014-01-28 23:13:18 +000053 SmallVectorImpl<MCFixup> &Fixups,
54 const MCSubtargetInfo &STI) const;
Ulrich Weigand5f613df2013-05-06 16:15:19 +000055
Richard Sandifordd454ec02013-05-14 09:28:21 +000056 // Called by the TableGen code to get the binary encoding of an address.
Richard Sandiford1d959002013-07-02 14:56:45 +000057 // The index or length, if any, is encoded first, followed by the base,
Richard Sandifordd454ec02013-05-14 09:28:21 +000058 // followed by the displacement. In a 20-bit displacement,
59 // the low 12 bits are encoded before the high 8 bits.
60 uint64_t getBDAddr12Encoding(const MCInst &MI, unsigned OpNum,
David Woodhouse3fa98a62014-01-28 23:13:18 +000061 SmallVectorImpl<MCFixup> &Fixups,
62 const MCSubtargetInfo &STI) const;
Richard Sandifordd454ec02013-05-14 09:28:21 +000063 uint64_t getBDAddr20Encoding(const MCInst &MI, unsigned OpNum,
David Woodhouse3fa98a62014-01-28 23:13:18 +000064 SmallVectorImpl<MCFixup> &Fixups,
65 const MCSubtargetInfo &STI) const;
Richard Sandifordd454ec02013-05-14 09:28:21 +000066 uint64_t getBDXAddr12Encoding(const MCInst &MI, unsigned OpNum,
David Woodhouse3fa98a62014-01-28 23:13:18 +000067 SmallVectorImpl<MCFixup> &Fixups,
68 const MCSubtargetInfo &STI) const;
Richard Sandifordd454ec02013-05-14 09:28:21 +000069 uint64_t getBDXAddr20Encoding(const MCInst &MI, unsigned OpNum,
David Woodhouse3fa98a62014-01-28 23:13:18 +000070 SmallVectorImpl<MCFixup> &Fixups,
71 const MCSubtargetInfo &STI) const;
Richard Sandiford1d959002013-07-02 14:56:45 +000072 uint64_t getBDLAddr12Len8Encoding(const MCInst &MI, unsigned OpNum,
David Woodhouse3fa98a62014-01-28 23:13:18 +000073 SmallVectorImpl<MCFixup> &Fixups,
74 const MCSubtargetInfo &STI) const;
Ulrich Weigandec5d7792016-10-31 14:21:36 +000075 uint64_t getBDRAddr12Encoding(const MCInst &MI, unsigned OpNum,
76 SmallVectorImpl<MCFixup> &Fixups,
77 const MCSubtargetInfo &STI) const;
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000078 uint64_t getBDVAddr12Encoding(const MCInst &MI, unsigned OpNum,
79 SmallVectorImpl<MCFixup> &Fixups,
80 const MCSubtargetInfo &STI) const;
Richard Sandifordd454ec02013-05-14 09:28:21 +000081
Ulrich Weigand5f613df2013-05-06 16:15:19 +000082 // Operand OpNum of MI needs a PC-relative fixup of kind Kind at
83 // Offset bytes from the start of MI. Add the fixup to Fixups
84 // and return the in-place addend, which since we're a RELA target
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +000085 // is always 0. If AllowTLS is true and optional operand OpNum + 1
86 // is present, also emit a TLS call fixup for it.
Richard Sandifordd454ec02013-05-14 09:28:21 +000087 uint64_t getPCRelEncoding(const MCInst &MI, unsigned OpNum,
Ulrich Weigand5f613df2013-05-06 16:15:19 +000088 SmallVectorImpl<MCFixup> &Fixups,
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +000089 unsigned Kind, int64_t Offset,
90 bool AllowTLS) const;
Ulrich Weigand5f613df2013-05-06 16:15:19 +000091
Richard Sandifordd454ec02013-05-14 09:28:21 +000092 uint64_t getPC16DBLEncoding(const MCInst &MI, unsigned OpNum,
David Woodhouse3fa98a62014-01-28 23:13:18 +000093 SmallVectorImpl<MCFixup> &Fixups,
94 const MCSubtargetInfo &STI) const {
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +000095 return getPCRelEncoding(MI, OpNum, Fixups,
96 SystemZ::FK_390_PC16DBL, 2, false);
Ulrich Weigand5f613df2013-05-06 16:15:19 +000097 }
Richard Sandifordd454ec02013-05-14 09:28:21 +000098 uint64_t getPC32DBLEncoding(const MCInst &MI, unsigned OpNum,
David Woodhouse3fa98a62014-01-28 23:13:18 +000099 SmallVectorImpl<MCFixup> &Fixups,
100 const MCSubtargetInfo &STI) const {
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +0000101 return getPCRelEncoding(MI, OpNum, Fixups,
102 SystemZ::FK_390_PC32DBL, 2, false);
103 }
104 uint64_t getPC16DBLTLSEncoding(const MCInst &MI, unsigned OpNum,
105 SmallVectorImpl<MCFixup> &Fixups,
106 const MCSubtargetInfo &STI) const {
107 return getPCRelEncoding(MI, OpNum, Fixups,
108 SystemZ::FK_390_PC16DBL, 2, true);
109 }
110 uint64_t getPC32DBLTLSEncoding(const MCInst &MI, unsigned OpNum,
111 SmallVectorImpl<MCFixup> &Fixups,
112 const MCSubtargetInfo &STI) const {
113 return getPCRelEncoding(MI, OpNum, Fixups,
114 SystemZ::FK_390_PC32DBL, 2, true);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000115 }
Ulrich Weigand84404f32016-11-28 14:01:51 +0000116 uint64_t getPC12DBLBPPEncoding(const MCInst &MI, unsigned OpNum,
117 SmallVectorImpl<MCFixup> &Fixups,
118 const MCSubtargetInfo &STI) const {
119 return getPCRelEncoding(MI, OpNum, Fixups,
120 SystemZ::FK_390_PC12DBL, 1, false);
121 }
122 uint64_t getPC16DBLBPPEncoding(const MCInst &MI, unsigned OpNum,
123 SmallVectorImpl<MCFixup> &Fixups,
124 const MCSubtargetInfo &STI) const {
125 return getPCRelEncoding(MI, OpNum, Fixups,
126 SystemZ::FK_390_PC16DBL, 4, false);
127 }
128 uint64_t getPC24DBLBPPEncoding(const MCInst &MI, unsigned OpNum,
129 SmallVectorImpl<MCFixup> &Fixups,
130 const MCSubtargetInfo &STI) const {
131 return getPCRelEncoding(MI, OpNum, Fixups,
132 SystemZ::FK_390_PC24DBL, 3, false);
133 }
Daniel Sanders72db2a32016-11-19 13:05:44 +0000134
135private:
136 uint64_t computeAvailableFeatures(const FeatureBitset &FB) const;
137 void verifyInstructionPredicates(const MCInst &MI,
138 uint64_t AvailableFeatures) const;
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000139};
Richard Sandifordc2312692014-03-06 10:38:30 +0000140} // end anonymous namespace
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000141
142MCCodeEmitter *llvm::createSystemZMCCodeEmitter(const MCInstrInfo &MCII,
143 const MCRegisterInfo &MRI,
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000144 MCContext &Ctx) {
145 return new SystemZMCCodeEmitter(MCII, Ctx);
146}
147
148void SystemZMCCodeEmitter::
Jim Grosbach91df21f2015-05-15 19:13:16 +0000149encodeInstruction(const MCInst &MI, raw_ostream &OS,
David Woodhouse9784cef2014-01-28 23:13:07 +0000150 SmallVectorImpl<MCFixup> &Fixups,
151 const MCSubtargetInfo &STI) const {
Daniel Sanders72db2a32016-11-19 13:05:44 +0000152 verifyInstructionPredicates(MI,
153 computeAvailableFeatures(STI.getFeatureBits()));
154
David Woodhouse3fa98a62014-01-28 23:13:18 +0000155 uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000156 unsigned Size = MCII.get(MI.getOpcode()).getSize();
157 // Big-endian insertion of Size bytes.
158 unsigned ShiftValue = (Size * 8) - 8;
159 for (unsigned I = 0; I != Size; ++I) {
160 OS << uint8_t(Bits >> ShiftValue);
161 ShiftValue -= 8;
162 }
163}
164
Richard Sandifordd454ec02013-05-14 09:28:21 +0000165uint64_t SystemZMCCodeEmitter::
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000166getMachineOpValue(const MCInst &MI, const MCOperand &MO,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000167 SmallVectorImpl<MCFixup> &Fixups,
168 const MCSubtargetInfo &STI) const {
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000169 if (MO.isReg())
Bill Wendlingbc07a892013-06-18 07:20:20 +0000170 return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000171 if (MO.isImm())
Richard Sandifordd454ec02013-05-14 09:28:21 +0000172 return static_cast<uint64_t>(MO.getImm());
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000173 llvm_unreachable("Unexpected operand type!");
174}
175
Richard Sandifordd454ec02013-05-14 09:28:21 +0000176uint64_t SystemZMCCodeEmitter::
177getBDAddr12Encoding(const MCInst &MI, unsigned OpNum,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000178 SmallVectorImpl<MCFixup> &Fixups,
179 const MCSubtargetInfo &STI) const {
180 uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
181 uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
Richard Sandifordd454ec02013-05-14 09:28:21 +0000182 assert(isUInt<4>(Base) && isUInt<12>(Disp));
183 return (Base << 12) | Disp;
184}
185
186uint64_t SystemZMCCodeEmitter::
187getBDAddr20Encoding(const MCInst &MI, unsigned OpNum,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000188 SmallVectorImpl<MCFixup> &Fixups,
189 const MCSubtargetInfo &STI) const {
190 uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
191 uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
Richard Sandifordd454ec02013-05-14 09:28:21 +0000192 assert(isUInt<4>(Base) && isInt<20>(Disp));
193 return (Base << 20) | ((Disp & 0xfff) << 8) | ((Disp & 0xff000) >> 12);
194}
195
196uint64_t SystemZMCCodeEmitter::
197getBDXAddr12Encoding(const MCInst &MI, unsigned OpNum,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000198 SmallVectorImpl<MCFixup> &Fixups,
199 const MCSubtargetInfo &STI) const {
200 uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
201 uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
202 uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI);
Richard Sandifordd454ec02013-05-14 09:28:21 +0000203 assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<4>(Index));
204 return (Index << 16) | (Base << 12) | Disp;
205}
206
207uint64_t SystemZMCCodeEmitter::
208getBDXAddr20Encoding(const MCInst &MI, unsigned OpNum,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000209 SmallVectorImpl<MCFixup> &Fixups,
210 const MCSubtargetInfo &STI) const {
211 uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
212 uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
213 uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI);
Richard Sandifordd454ec02013-05-14 09:28:21 +0000214 assert(isUInt<4>(Base) && isInt<20>(Disp) && isUInt<4>(Index));
215 return (Index << 24) | (Base << 20) | ((Disp & 0xfff) << 8)
216 | ((Disp & 0xff000) >> 12);
217}
218
Richard Sandiford1d959002013-07-02 14:56:45 +0000219uint64_t SystemZMCCodeEmitter::
220getBDLAddr12Len8Encoding(const MCInst &MI, unsigned OpNum,
David Woodhouse3fa98a62014-01-28 23:13:18 +0000221 SmallVectorImpl<MCFixup> &Fixups,
222 const MCSubtargetInfo &STI) const {
223 uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
224 uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
225 uint64_t Len = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI) - 1;
Richard Sandiford1d959002013-07-02 14:56:45 +0000226 assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<8>(Len));
227 return (Len << 16) | (Base << 12) | Disp;
228}
229
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000230uint64_t SystemZMCCodeEmitter::
Ulrich Weigandec5d7792016-10-31 14:21:36 +0000231getBDRAddr12Encoding(const MCInst &MI, unsigned OpNum,
232 SmallVectorImpl<MCFixup> &Fixups,
233 const MCSubtargetInfo &STI) const {
234 uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
235 uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
236 uint64_t Len = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI);
237 assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<4>(Len));
238 return (Len << 16) | (Base << 12) | Disp;
239}
240
241uint64_t SystemZMCCodeEmitter::
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000242getBDVAddr12Encoding(const MCInst &MI, unsigned OpNum,
243 SmallVectorImpl<MCFixup> &Fixups,
244 const MCSubtargetInfo &STI) const {
245 uint64_t Base = getMachineOpValue(MI, MI.getOperand(OpNum), Fixups, STI);
246 uint64_t Disp = getMachineOpValue(MI, MI.getOperand(OpNum + 1), Fixups, STI);
247 uint64_t Index = getMachineOpValue(MI, MI.getOperand(OpNum + 2), Fixups, STI);
248 assert(isUInt<4>(Base) && isUInt<12>(Disp) && isUInt<5>(Index));
249 return (Index << 16) | (Base << 12) | Disp;
250}
251
Richard Sandifordd454ec02013-05-14 09:28:21 +0000252uint64_t
253SystemZMCCodeEmitter::getPCRelEncoding(const MCInst &MI, unsigned OpNum,
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000254 SmallVectorImpl<MCFixup> &Fixups,
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +0000255 unsigned Kind, int64_t Offset,
256 bool AllowTLS) const {
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000257 const MCOperand &MO = MI.getOperand(OpNum);
Richard Sandiford1fb58832013-05-14 09:47:26 +0000258 const MCExpr *Expr;
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000259 if (MO.isImm())
Jim Grosbach13760bd2015-05-30 01:25:56 +0000260 Expr = MCConstantExpr::create(MO.getImm() + Offset, Ctx);
Richard Sandiford1fb58832013-05-14 09:47:26 +0000261 else {
262 Expr = MO.getExpr();
263 if (Offset) {
264 // The operand value is relative to the start of MI, but the fixup
265 // is relative to the operand field itself, which is Offset bytes
266 // into MI. Add Offset to the relocation value to cancel out
267 // this difference.
Jim Grosbach13760bd2015-05-30 01:25:56 +0000268 const MCExpr *OffsetExpr = MCConstantExpr::create(Offset, Ctx);
269 Expr = MCBinaryExpr::createAdd(Expr, OffsetExpr, Ctx);
Richard Sandiford1fb58832013-05-14 09:47:26 +0000270 }
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000271 }
Jim Grosbach63661f82015-05-15 19:13:05 +0000272 Fixups.push_back(MCFixup::create(Offset, Expr, (MCFixupKind)Kind));
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +0000273
274 // Output the fixup for the TLS marker if present.
275 if (AllowTLS && OpNum + 1 < MI.getNumOperands()) {
276 const MCOperand &MOTLS = MI.getOperand(OpNum + 1);
Jim Grosbach63661f82015-05-15 19:13:05 +0000277 Fixups.push_back(MCFixup::create(0, MOTLS.getExpr(),
Ulrich Weigand7bdd7c22015-02-18 09:11:36 +0000278 (MCFixupKind)SystemZ::FK_390_TLS_CALL));
279 }
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000280 return 0;
281}
282
Daniel Sanders72db2a32016-11-19 13:05:44 +0000283#define ENABLE_INSTR_PREDICATE_VERIFIER
Ulrich Weigand5f613df2013-05-06 16:15:19 +0000284#include "SystemZGenMCCodeEmitter.inc"