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