Use 'override/final' instead of 'virtual' for overridden methods
[oota-llvm.git] / lib / Target / SystemZ / Disassembler / SystemZDisassembler.cpp
1 //===-- 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"
11 #include "llvm/MC/MCDisassembler.h"
12 #include "llvm/MC/MCFixedLenDisassembler.h"
13 #include "llvm/MC/MCInst.h"
14 #include "llvm/MC/MCSubtargetInfo.h"
15 #include "llvm/Support/TargetRegistry.h"
16
17 using namespace llvm;
18
19 #define DEBUG_TYPE "systemz-disassembler"
20
21 typedef MCDisassembler::DecodeStatus DecodeStatus;
22
23 namespace {
24 class SystemZDisassembler : public MCDisassembler {
25 public:
26   SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
27     : MCDisassembler(STI, Ctx) {}
28   ~SystemZDisassembler() override {}
29
30   DecodeStatus getInstruction(MCInst &instr, uint64_t &Size,
31                               ArrayRef<uint8_t> Bytes, uint64_t Address,
32                               raw_ostream &VStream,
33                               raw_ostream &CStream) const override;
34 };
35 } // end anonymous namespace
36
37 static MCDisassembler *createSystemZDisassembler(const Target &T,
38                                                  const MCSubtargetInfo &STI,
39                                                  MCContext &Ctx) {
40   return new SystemZDisassembler(STI, Ctx);
41 }
42
43 extern "C" void LLVMInitializeSystemZDisassembler() {
44   // Register the disassembler.
45   TargetRegistry::RegisterMCDisassembler(TheSystemZTarget,
46                                          createSystemZDisassembler);
47 }
48
49 static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
50                                         const unsigned *Regs) {
51   assert(RegNo < 16 && "Invalid register");
52   RegNo = Regs[RegNo];
53   if (RegNo == 0)
54     return MCDisassembler::Fail;
55   Inst.addOperand(MCOperand::CreateReg(RegNo));
56   return MCDisassembler::Success;
57 }
58
59 static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
60                                                uint64_t Address,
61                                                const void *Decoder) {
62   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs);
63 }
64
65 static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
66                                                 uint64_t Address,
67                                                 const void *Decoder) {
68   return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs);
69 }
70
71 static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
72                                                uint64_t Address,
73                                                const void *Decoder) {
74   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs);
75 }
76
77 static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
78                                                 uint64_t Address,
79                                                 const void *Decoder) {
80   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs);
81 }
82
83 static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
84                                                  uint64_t Address,
85                                                  const void *Decoder) {
86   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs);
87 }
88
89 static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
90                                                uint64_t Address,
91                                                const void *Decoder) {
92   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs);
93 }
94
95 static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
96                                                uint64_t Address,
97                                                const void *Decoder) {
98   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs);
99 }
100
101 static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
102                                                 uint64_t Address,
103                                                 const void *Decoder) {
104   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs);
105 }
106
107 template<unsigned N>
108 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) {
109   assert(isUInt<N>(Imm) && "Invalid immediate");
110   Inst.addOperand(MCOperand::CreateImm(Imm));
111   return MCDisassembler::Success;
112 }
113
114 template<unsigned N>
115 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) {
116   assert(isUInt<N>(Imm) && "Invalid immediate");
117   Inst.addOperand(MCOperand::CreateImm(SignExtend64<N>(Imm)));
118   return MCDisassembler::Success;
119 }
120
121 static DecodeStatus decodeAccessRegOperand(MCInst &Inst, uint64_t Imm,
122                                            uint64_t Address,
123                                            const void *Decoder) {
124   return decodeUImmOperand<4>(Inst, Imm);
125 }
126
127 static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm,
128                                        uint64_t Address, const void *Decoder) {
129   return decodeUImmOperand<4>(Inst, Imm);
130 }
131
132 static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm,
133                                        uint64_t Address, const void *Decoder) {
134   return decodeUImmOperand<6>(Inst, Imm);
135 }
136
137 static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm,
138                                        uint64_t Address, const void *Decoder) {
139   return decodeUImmOperand<8>(Inst, Imm);
140 }
141
142 static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm,
143                                         uint64_t Address, const void *Decoder) {
144   return decodeUImmOperand<16>(Inst, Imm);
145 }
146
147 static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm,
148                                         uint64_t Address, const void *Decoder) {
149   return decodeUImmOperand<32>(Inst, Imm);
150 }
151
152 static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm,
153                                        uint64_t Address, const void *Decoder) {
154   return decodeSImmOperand<8>(Inst, Imm);
155 }
156
157 static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm,
158                                         uint64_t Address, const void *Decoder) {
159   return decodeSImmOperand<16>(Inst, Imm);
160 }
161
162 static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm,
163                                         uint64_t Address, const void *Decoder) {
164   return decodeSImmOperand<32>(Inst, Imm);
165 }
166
167 template<unsigned N>
168 static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm,
169                                        uint64_t Address) {
170   assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
171   Inst.addOperand(MCOperand::CreateImm(SignExtend64<N>(Imm) * 2 + Address));
172   return MCDisassembler::Success;
173 }
174
175 static DecodeStatus decodePC16DBLOperand(MCInst &Inst, uint64_t Imm,
176                                          uint64_t Address,
177                                          const void *Decoder) {
178   return decodePCDBLOperand<16>(Inst, Imm, Address);
179 }
180
181 static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm,
182                                          uint64_t Address,
183                                          const void *Decoder) {
184   return decodePCDBLOperand<32>(Inst, Imm, Address);
185 }
186
187 static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field,
188                                           const unsigned *Regs) {
189   uint64_t Base = Field >> 12;
190   uint64_t Disp = Field & 0xfff;
191   assert(Base < 16 && "Invalid BDAddr12");
192   Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
193   Inst.addOperand(MCOperand::CreateImm(Disp));
194   return MCDisassembler::Success;
195 }
196
197 static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field,
198                                           const unsigned *Regs) {
199   uint64_t Base = Field >> 20;
200   uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff);
201   assert(Base < 16 && "Invalid BDAddr20");
202   Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
203   Inst.addOperand(MCOperand::CreateImm(SignExtend64<20>(Disp)));
204   return MCDisassembler::Success;
205 }
206
207 static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field,
208                                            const unsigned *Regs) {
209   uint64_t Index = Field >> 16;
210   uint64_t Base = (Field >> 12) & 0xf;
211   uint64_t Disp = Field & 0xfff;
212   assert(Index < 16 && "Invalid BDXAddr12");
213   Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
214   Inst.addOperand(MCOperand::CreateImm(Disp));
215   Inst.addOperand(MCOperand::CreateReg(Index == 0 ? 0 : Regs[Index]));
216   return MCDisassembler::Success;
217 }
218
219 static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field,
220                                            const unsigned *Regs) {
221   uint64_t Index = Field >> 24;
222   uint64_t Base = (Field >> 20) & 0xf;
223   uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12);
224   assert(Index < 16 && "Invalid BDXAddr20");
225   Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
226   Inst.addOperand(MCOperand::CreateImm(SignExtend64<20>(Disp)));
227   Inst.addOperand(MCOperand::CreateReg(Index == 0 ? 0 : Regs[Index]));
228   return MCDisassembler::Success;
229 }
230
231 static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field,
232                                                const unsigned *Regs) {
233   uint64_t Length = Field >> 16;
234   uint64_t Base = (Field >> 12) & 0xf;
235   uint64_t Disp = Field & 0xfff;
236   assert(Length < 256 && "Invalid BDLAddr12Len8");
237   Inst.addOperand(MCOperand::CreateReg(Base == 0 ? 0 : Regs[Base]));
238   Inst.addOperand(MCOperand::CreateImm(Disp));
239   Inst.addOperand(MCOperand::CreateImm(Length + 1));
240   return MCDisassembler::Success;
241 }
242
243 static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field,
244                                                 uint64_t Address,
245                                                 const void *Decoder) {
246   return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs);
247 }
248
249 static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field,
250                                                 uint64_t Address,
251                                                 const void *Decoder) {
252   return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs);
253 }
254
255 static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
256                                                 uint64_t Address,
257                                                 const void *Decoder) {
258   return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
259 }
260
261 static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
262                                                 uint64_t Address,
263                                                 const void *Decoder) {
264   return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
265 }
266
267 static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
268                                                  uint64_t Address,
269                                                  const void *Decoder) {
270   return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
271 }
272
273 static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
274                                                  uint64_t Address,
275                                                  const void *Decoder) {
276   return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
277 }
278
279 static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst,
280                                                      uint64_t Field,
281                                                      uint64_t Address,
282                                                      const void *Decoder) {
283   return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs);
284 }
285
286 #include "SystemZGenDisassemblerTables.inc"
287
288 DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
289                                                  ArrayRef<uint8_t> Bytes,
290                                                  uint64_t Address,
291                                                  raw_ostream &OS,
292                                                  raw_ostream &CS) const {
293   // Get the first two bytes of the instruction.
294   Size = 0;
295   if (Bytes.size() < 2)
296     return MCDisassembler::Fail;
297
298   // The top 2 bits of the first byte specify the size.
299   const uint8_t *Table;
300   if (Bytes[0] < 0x40) {
301     Size = 2;
302     Table = DecoderTable16;
303   } else if (Bytes[0] < 0xc0) {
304     Size = 4;
305     Table = DecoderTable32;
306   } else {
307     Size = 6;
308     Table = DecoderTable48;
309   }
310
311   // Read any remaining bytes.
312   if (Bytes.size() < Size)
313     return MCDisassembler::Fail;
314
315   // Construct the instruction.
316   uint64_t Inst = 0;
317   for (uint64_t I = 0; I < Size; ++I)
318     Inst = (Inst << 8) | Bytes[I];
319
320   return decodeInstruction(Table, MI, Inst, Address, this, STI);
321 }