blob: 1806e015f61e5d613e04f167541253a8fd179c91 [file] [log] [blame]
Richard Sandifordeb9af292013-05-14 10:17:52 +00001//===-- SystemZDisassembler.cpp - Disassembler for SystemZ ------*- C++ -*-===//
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#include "SystemZ.h"
Benjamin Kramerf57c1972016-01-26 16:44:37 +000011#include "llvm/MC/MCDisassembler/MCDisassembler.h"
Richard Sandifordeb9af292013-05-14 10:17:52 +000012#include "llvm/MC/MCFixedLenDisassembler.h"
13#include "llvm/MC/MCInst.h"
14#include "llvm/MC/MCSubtargetInfo.h"
Richard Sandifordeb9af292013-05-14 10:17:52 +000015#include "llvm/Support/TargetRegistry.h"
16
17using namespace llvm;
18
Chandler Carruthe96dd892014-04-21 22:55:11 +000019#define DEBUG_TYPE "systemz-disassembler"
20
Richard Sandifordeb9af292013-05-14 10:17:52 +000021typedef MCDisassembler::DecodeStatus DecodeStatus;
22
23namespace {
24class SystemZDisassembler : public MCDisassembler {
25public:
Lang Hamesa1bc0f52014-04-15 04:40:56 +000026 SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
27 : MCDisassembler(STI, Ctx) {}
Alexander Kornienkof817c1c2015-04-11 02:11:45 +000028 ~SystemZDisassembler() override {}
Richard Sandifordeb9af292013-05-14 10:17:52 +000029
Rafael Espindola7fc5b872014-11-12 02:04:27 +000030 DecodeStatus getInstruction(MCInst &instr, uint64_t &Size,
31 ArrayRef<uint8_t> Bytes, uint64_t Address,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +000032 raw_ostream &VStream,
33 raw_ostream &CStream) const override;
Richard Sandifordeb9af292013-05-14 10:17:52 +000034};
35} // end anonymous namespace
36
37static MCDisassembler *createSystemZDisassembler(const Target &T,
Lang Hamesa1bc0f52014-04-15 04:40:56 +000038 const MCSubtargetInfo &STI,
39 MCContext &Ctx) {
40 return new SystemZDisassembler(STI, Ctx);
Richard Sandifordeb9af292013-05-14 10:17:52 +000041}
42
43extern "C" void LLVMInitializeSystemZDisassembler() {
44 // Register the disassembler.
Mehdi Aminif42454b2016-10-09 23:00:34 +000045 TargetRegistry::RegisterMCDisassembler(getTheSystemZTarget(),
Richard Sandifordeb9af292013-05-14 10:17:52 +000046 createSystemZDisassembler);
47}
48
Ulrich Weigand6e648ea2016-04-15 19:55:58 +000049/// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
50/// immediate Value in the MCInst.
51///
52/// @param Value - The immediate Value, has had any PC adjustment made by
53/// the caller.
54/// @param isBranch - If the instruction is a branch instruction
55/// @param Address - The starting address of the instruction
56/// @param Offset - The byte offset to this immediate in the instruction
57/// @param Width - The byte width of this immediate in the instruction
58///
59/// If the getOpInfo() function was set when setupForSymbolicDisassembly() was
60/// called then that function is called to get any symbolic information for the
61/// immediate in the instruction using the Address, Offset and Width. If that
62/// returns non-zero then the symbolic information it returns is used to create
63/// an MCExpr and that is added as an operand to the MCInst. If getOpInfo()
64/// returns zero and isBranch is true then a symbol look up for immediate Value
65/// is done and if a symbol is found an MCExpr is created with that, else
66/// an MCExpr with the immediate Value is created. This function returns true
67/// if it adds an operand to the MCInst and false otherwise.
68static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
69 uint64_t Address, uint64_t Offset,
70 uint64_t Width, MCInst &MI,
71 const void *Decoder) {
72 const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
73 return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch,
74 Offset, Width);
75}
76
Richard Sandifordeb9af292013-05-14 10:17:52 +000077static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000078 const unsigned *Regs, unsigned Size) {
79 assert(RegNo < Size && "Invalid register");
Richard Sandiford09de0912013-11-13 16:57:53 +000080 RegNo = Regs[RegNo];
81 if (RegNo == 0)
82 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +000083 Inst.addOperand(MCOperand::createReg(RegNo));
Richard Sandifordeb9af292013-05-14 10:17:52 +000084 return MCDisassembler::Success;
85}
86
87static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
88 uint64_t Address,
89 const void *Decoder) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000090 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16);
Richard Sandifordeb9af292013-05-14 10:17:52 +000091}
92
Richard Sandifordf9496062013-09-30 10:45:16 +000093static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
94 uint64_t Address,
95 const void *Decoder) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +000096 return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16);
Richard Sandifordf9496062013-09-30 10:45:16 +000097}
98
Richard Sandifordeb9af292013-05-14 10:17:52 +000099static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
100 uint64_t Address,
101 const void *Decoder) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000102 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
Richard Sandifordeb9af292013-05-14 10:17:52 +0000103}
104
105static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
106 uint64_t Address,
107 const void *Decoder) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000108 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16);
Richard Sandifordeb9af292013-05-14 10:17:52 +0000109}
110
111static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
112 uint64_t Address,
113 const void *Decoder) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000114 return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
Richard Sandifordeb9af292013-05-14 10:17:52 +0000115}
116
117static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
118 uint64_t Address,
119 const void *Decoder) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000120 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16);
Richard Sandifordeb9af292013-05-14 10:17:52 +0000121}
122
123static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
124 uint64_t Address,
125 const void *Decoder) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000126 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16);
Richard Sandifordeb9af292013-05-14 10:17:52 +0000127}
128
129static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
130 uint64_t Address,
131 const void *Decoder) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000132 return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16);
133}
134
135static DecodeStatus DecodeVR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
136 uint64_t Address,
137 const void *Decoder) {
138 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32);
139}
140
141static DecodeStatus DecodeVR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
142 uint64_t Address,
143 const void *Decoder) {
144 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32);
145}
146
147static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
148 uint64_t Address,
149 const void *Decoder) {
150 return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32);
Richard Sandifordeb9af292013-05-14 10:17:52 +0000151}
152
Ulrich Weigandfffc7112016-11-08 20:15:26 +0000153static DecodeStatus DecodeAR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
154 uint64_t Address,
155 const void *Decoder) {
156 return decodeRegisterClass(Inst, RegNo, SystemZMC::AR32Regs, 16);
157}
158
Richard Sandifordeb9af292013-05-14 10:17:52 +0000159template<unsigned N>
160static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000161 if (!isUInt<N>(Imm))
162 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +0000163 Inst.addOperand(MCOperand::createImm(Imm));
Richard Sandifordeb9af292013-05-14 10:17:52 +0000164 return MCDisassembler::Success;
165}
166
167template<unsigned N>
168static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) {
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000169 if (!isUInt<N>(Imm))
170 return MCDisassembler::Fail;
Jim Grosbache9119e42015-05-13 18:37:00 +0000171 Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
Richard Sandifordeb9af292013-05-14 10:17:52 +0000172 return MCDisassembler::Success;
173}
174
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000175static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm,
176 uint64_t Address, const void *Decoder) {
177 return decodeUImmOperand<1>(Inst, Imm);
178}
179
180static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm,
181 uint64_t Address, const void *Decoder) {
182 return decodeUImmOperand<2>(Inst, Imm);
183}
184
185static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm,
186 uint64_t Address, const void *Decoder) {
187 return decodeUImmOperand<3>(Inst, Imm);
188}
189
Richard Sandifordeb9af292013-05-14 10:17:52 +0000190static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm,
191 uint64_t Address, const void *Decoder) {
192 return decodeUImmOperand<4>(Inst, Imm);
193}
194
195static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm,
196 uint64_t Address, const void *Decoder) {
197 return decodeUImmOperand<6>(Inst, Imm);
198}
199
200static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm,
201 uint64_t Address, const void *Decoder) {
202 return decodeUImmOperand<8>(Inst, Imm);
203}
204
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000205static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm,
206 uint64_t Address, const void *Decoder) {
207 return decodeUImmOperand<12>(Inst, Imm);
208}
209
Richard Sandifordeb9af292013-05-14 10:17:52 +0000210static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm,
211 uint64_t Address, const void *Decoder) {
212 return decodeUImmOperand<16>(Inst, Imm);
213}
214
215static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm,
216 uint64_t Address, const void *Decoder) {
217 return decodeUImmOperand<32>(Inst, Imm);
218}
219
220static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm,
221 uint64_t Address, const void *Decoder) {
222 return decodeSImmOperand<8>(Inst, Imm);
223}
224
225static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm,
226 uint64_t Address, const void *Decoder) {
227 return decodeSImmOperand<16>(Inst, Imm);
228}
229
230static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm,
231 uint64_t Address, const void *Decoder) {
232 return decodeSImmOperand<32>(Inst, Imm);
233}
234
235template<unsigned N>
236static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm,
Ulrich Weigand6e648ea2016-04-15 19:55:58 +0000237 uint64_t Address,
238 bool isBranch,
239 const void *Decoder) {
Richard Sandifordeb9af292013-05-14 10:17:52 +0000240 assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
Ulrich Weigand6e648ea2016-04-15 19:55:58 +0000241 uint64_t Value = SignExtend64<N>(Imm) * 2 + Address;
242
243 if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, N / 8,
244 Inst, Decoder))
245 Inst.addOperand(MCOperand::createImm(Value));
246
Richard Sandifordeb9af292013-05-14 10:17:52 +0000247 return MCDisassembler::Success;
248}
249
Ulrich Weigand84404f32016-11-28 14:01:51 +0000250static DecodeStatus decodePC12DBLBranchOperand(MCInst &Inst, uint64_t Imm,
251 uint64_t Address,
252 const void *Decoder) {
253 return decodePCDBLOperand<12>(Inst, Imm, Address, true, Decoder);
254}
255
Ulrich Weigand6e648ea2016-04-15 19:55:58 +0000256static DecodeStatus decodePC16DBLBranchOperand(MCInst &Inst, uint64_t Imm,
257 uint64_t Address,
258 const void *Decoder) {
259 return decodePCDBLOperand<16>(Inst, Imm, Address, true, Decoder);
260}
261
Ulrich Weigand84404f32016-11-28 14:01:51 +0000262static DecodeStatus decodePC24DBLBranchOperand(MCInst &Inst, uint64_t Imm,
263 uint64_t Address,
264 const void *Decoder) {
265 return decodePCDBLOperand<24>(Inst, Imm, Address, true, Decoder);
266}
267
Ulrich Weigand6e648ea2016-04-15 19:55:58 +0000268static DecodeStatus decodePC32DBLBranchOperand(MCInst &Inst, uint64_t Imm,
269 uint64_t Address,
270 const void *Decoder) {
271 return decodePCDBLOperand<32>(Inst, Imm, Address, true, Decoder);
Richard Sandifordeb9af292013-05-14 10:17:52 +0000272}
273
274static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm,
275 uint64_t Address,
276 const void *Decoder) {
Ulrich Weigand6e648ea2016-04-15 19:55:58 +0000277 return decodePCDBLOperand<32>(Inst, Imm, Address, false, Decoder);
Richard Sandifordeb9af292013-05-14 10:17:52 +0000278}
279
280static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field,
281 const unsigned *Regs) {
282 uint64_t Base = Field >> 12;
283 uint64_t Disp = Field & 0xfff;
284 assert(Base < 16 && "Invalid BDAddr12");
Jim Grosbache9119e42015-05-13 18:37:00 +0000285 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
286 Inst.addOperand(MCOperand::createImm(Disp));
Richard Sandifordeb9af292013-05-14 10:17:52 +0000287 return MCDisassembler::Success;
288}
289
290static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field,
291 const unsigned *Regs) {
292 uint64_t Base = Field >> 20;
293 uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff);
294 assert(Base < 16 && "Invalid BDAddr20");
Jim Grosbache9119e42015-05-13 18:37:00 +0000295 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
296 Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp)));
Richard Sandifordeb9af292013-05-14 10:17:52 +0000297 return MCDisassembler::Success;
298}
299
300static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field,
301 const unsigned *Regs) {
302 uint64_t Index = Field >> 16;
303 uint64_t Base = (Field >> 12) & 0xf;
304 uint64_t Disp = Field & 0xfff;
305 assert(Index < 16 && "Invalid BDXAddr12");
Jim Grosbache9119e42015-05-13 18:37:00 +0000306 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
307 Inst.addOperand(MCOperand::createImm(Disp));
308 Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index]));
Richard Sandifordeb9af292013-05-14 10:17:52 +0000309 return MCDisassembler::Success;
310}
311
312static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field,
313 const unsigned *Regs) {
314 uint64_t Index = Field >> 24;
315 uint64_t Base = (Field >> 20) & 0xf;
316 uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12);
317 assert(Index < 16 && "Invalid BDXAddr20");
Jim Grosbache9119e42015-05-13 18:37:00 +0000318 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
319 Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp)));
320 Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index]));
Richard Sandifordeb9af292013-05-14 10:17:52 +0000321 return MCDisassembler::Success;
322}
323
Richard Sandiford1d959002013-07-02 14:56:45 +0000324static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field,
325 const unsigned *Regs) {
326 uint64_t Length = Field >> 16;
327 uint64_t Base = (Field >> 12) & 0xf;
328 uint64_t Disp = Field & 0xfff;
329 assert(Length < 256 && "Invalid BDLAddr12Len8");
Jim Grosbache9119e42015-05-13 18:37:00 +0000330 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
331 Inst.addOperand(MCOperand::createImm(Disp));
332 Inst.addOperand(MCOperand::createImm(Length + 1));
Richard Sandiford1d959002013-07-02 14:56:45 +0000333 return MCDisassembler::Success;
334}
335
Ulrich Weigandec5d7792016-10-31 14:21:36 +0000336static DecodeStatus decodeBDRAddr12Operand(MCInst &Inst, uint64_t Field,
337 const unsigned *Regs) {
338 uint64_t Length = Field >> 16;
339 uint64_t Base = (Field >> 12) & 0xf;
340 uint64_t Disp = Field & 0xfff;
341 assert(Length < 16 && "Invalid BDRAddr12");
342 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
343 Inst.addOperand(MCOperand::createImm(Disp));
344 Inst.addOperand(MCOperand::createReg(Regs[Length]));
345 return MCDisassembler::Success;
346}
347
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000348static DecodeStatus decodeBDVAddr12Operand(MCInst &Inst, uint64_t Field,
349 const unsigned *Regs) {
350 uint64_t Index = Field >> 16;
351 uint64_t Base = (Field >> 12) & 0xf;
352 uint64_t Disp = Field & 0xfff;
353 assert(Index < 32 && "Invalid BDVAddr12");
Jim Grosbache9119e42015-05-13 18:37:00 +0000354 Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
355 Inst.addOperand(MCOperand::createImm(Disp));
356 Inst.addOperand(MCOperand::createReg(SystemZMC::VR128Regs[Index]));
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000357 return MCDisassembler::Success;
358}
359
Richard Sandifordeb9af292013-05-14 10:17:52 +0000360static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field,
361 uint64_t Address,
362 const void *Decoder) {
363 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs);
364}
365
366static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field,
367 uint64_t Address,
368 const void *Decoder) {
369 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs);
370}
371
372static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
373 uint64_t Address,
374 const void *Decoder) {
375 return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
376}
377
378static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
379 uint64_t Address,
380 const void *Decoder) {
381 return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
382}
383
384static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
385 uint64_t Address,
386 const void *Decoder) {
387 return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
388}
389
390static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
391 uint64_t Address,
392 const void *Decoder) {
393 return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
394}
395
Richard Sandiford1d959002013-07-02 14:56:45 +0000396static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst,
397 uint64_t Field,
398 uint64_t Address,
399 const void *Decoder) {
400 return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs);
401}
402
Ulrich Weigandec5d7792016-10-31 14:21:36 +0000403static DecodeStatus decodeBDRAddr64Disp12Operand(MCInst &Inst,
404 uint64_t Field,
405 uint64_t Address,
406 const void *Decoder) {
407 return decodeBDRAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
408}
409
Ulrich Weiganda8b04e12015-05-05 19:23:40 +0000410static DecodeStatus decodeBDVAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
411 uint64_t Address,
412 const void *Decoder) {
413 return decodeBDVAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
414}
415
Richard Sandifordeb9af292013-05-14 10:17:52 +0000416#include "SystemZGenDisassemblerTables.inc"
417
418DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000419 ArrayRef<uint8_t> Bytes,
Richard Sandifordeb9af292013-05-14 10:17:52 +0000420 uint64_t Address,
Rafael Espindola4aa6bea2014-11-10 18:11:10 +0000421 raw_ostream &OS,
422 raw_ostream &CS) const {
Richard Sandifordeb9af292013-05-14 10:17:52 +0000423 // Get the first two bytes of the instruction.
Richard Sandifordeb9af292013-05-14 10:17:52 +0000424 Size = 0;
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000425 if (Bytes.size() < 2)
Richard Sandifordeb9af292013-05-14 10:17:52 +0000426 return MCDisassembler::Fail;
427
428 // The top 2 bits of the first byte specify the size.
429 const uint8_t *Table;
430 if (Bytes[0] < 0x40) {
431 Size = 2;
432 Table = DecoderTable16;
433 } else if (Bytes[0] < 0xc0) {
434 Size = 4;
435 Table = DecoderTable32;
436 } else {
437 Size = 6;
438 Table = DecoderTable48;
439 }
440
441 // Read any remaining bytes.
Rafael Espindola7fc5b872014-11-12 02:04:27 +0000442 if (Bytes.size() < Size)
Richard Sandifordeb9af292013-05-14 10:17:52 +0000443 return MCDisassembler::Fail;
444
445 // Construct the instruction.
446 uint64_t Inst = 0;
447 for (uint64_t I = 0; I < Size; ++I)
448 Inst = (Inst << 8) | Bytes[I];
449
450 return decodeInstruction(Table, MI, Inst, Address, this, STI);
451}