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