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