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