• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
SystemZDisassembler(const MCSubtargetInfo & STI,MCContext & Ctx)26   SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
27     : MCDisassembler(STI, Ctx) {}
~SystemZDisassembler()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 
createSystemZDisassembler(const Target & T,const MCSubtargetInfo & STI,MCContext & Ctx)37 static MCDisassembler *createSystemZDisassembler(const Target &T,
38                                                  const MCSubtargetInfo &STI,
39                                                  MCContext &Ctx) {
40   return new SystemZDisassembler(STI, Ctx);
41 }
42 
LLVMInitializeSystemZDisassembler()43 extern "C" void LLVMInitializeSystemZDisassembler() {
44   // Register the disassembler.
45   TargetRegistry::RegisterMCDisassembler(TheSystemZTarget,
46                                          createSystemZDisassembler);
47 }
48 
decodeRegisterClass(MCInst & Inst,uint64_t RegNo,const unsigned * Regs,unsigned Size)49 static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
50                                         const unsigned *Regs, unsigned Size) {
51   assert(RegNo < Size && "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 
DecodeGR32BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)59 static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
60                                                uint64_t Address,
61                                                const void *Decoder) {
62   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16);
63 }
64 
DecodeGRH32BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)65 static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
66                                                 uint64_t Address,
67                                                 const void *Decoder) {
68   return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16);
69 }
70 
DecodeGR64BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)71 static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
72                                                uint64_t Address,
73                                                const void *Decoder) {
74   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
75 }
76 
DecodeGR128BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)77 static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
78                                                 uint64_t Address,
79                                                 const void *Decoder) {
80   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16);
81 }
82 
DecodeADDR64BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)83 static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
84                                                  uint64_t Address,
85                                                  const void *Decoder) {
86   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
87 }
88 
DecodeFP32BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)89 static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
90                                                uint64_t Address,
91                                                const void *Decoder) {
92   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16);
93 }
94 
DecodeFP64BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)95 static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
96                                                uint64_t Address,
97                                                const void *Decoder) {
98   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16);
99 }
100 
DecodeFP128BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)101 static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
102                                                 uint64_t Address,
103                                                 const void *Decoder) {
104   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16);
105 }
106 
DecodeVR32BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)107 static DecodeStatus DecodeVR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
108                                                uint64_t Address,
109                                                const void *Decoder) {
110   return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32);
111 }
112 
DecodeVR64BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)113 static DecodeStatus DecodeVR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
114                                                uint64_t Address,
115                                                const void *Decoder) {
116   return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32);
117 }
118 
DecodeVR128BitRegisterClass(MCInst & Inst,uint64_t RegNo,uint64_t Address,const void * Decoder)119 static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
120                                                 uint64_t Address,
121                                                 const void *Decoder) {
122   return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32);
123 }
124 
125 template<unsigned N>
decodeUImmOperand(MCInst & Inst,uint64_t Imm)126 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) {
127   if (!isUInt<N>(Imm))
128     return MCDisassembler::Fail;
129   Inst.addOperand(MCOperand::createImm(Imm));
130   return MCDisassembler::Success;
131 }
132 
133 template<unsigned N>
decodeSImmOperand(MCInst & Inst,uint64_t Imm)134 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) {
135   if (!isUInt<N>(Imm))
136     return MCDisassembler::Fail;
137   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
138   return MCDisassembler::Success;
139 }
140 
decodeAccessRegOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)141 static DecodeStatus decodeAccessRegOperand(MCInst &Inst, uint64_t Imm,
142                                            uint64_t Address,
143                                            const void *Decoder) {
144   return decodeUImmOperand<4>(Inst, Imm);
145 }
146 
decodeU1ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)147 static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm,
148                                        uint64_t Address, const void *Decoder) {
149   return decodeUImmOperand<1>(Inst, Imm);
150 }
151 
decodeU2ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)152 static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm,
153                                        uint64_t Address, const void *Decoder) {
154   return decodeUImmOperand<2>(Inst, Imm);
155 }
156 
decodeU3ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)157 static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm,
158                                        uint64_t Address, const void *Decoder) {
159   return decodeUImmOperand<3>(Inst, Imm);
160 }
161 
decodeU4ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)162 static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm,
163                                        uint64_t Address, const void *Decoder) {
164   return decodeUImmOperand<4>(Inst, Imm);
165 }
166 
decodeU6ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)167 static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm,
168                                        uint64_t Address, const void *Decoder) {
169   return decodeUImmOperand<6>(Inst, Imm);
170 }
171 
decodeU8ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)172 static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm,
173                                        uint64_t Address, const void *Decoder) {
174   return decodeUImmOperand<8>(Inst, Imm);
175 }
176 
decodeU12ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)177 static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm,
178                                         uint64_t Address, const void *Decoder) {
179   return decodeUImmOperand<12>(Inst, Imm);
180 }
181 
decodeU16ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)182 static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm,
183                                         uint64_t Address, const void *Decoder) {
184   return decodeUImmOperand<16>(Inst, Imm);
185 }
186 
decodeU32ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)187 static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm,
188                                         uint64_t Address, const void *Decoder) {
189   return decodeUImmOperand<32>(Inst, Imm);
190 }
191 
decodeS8ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)192 static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm,
193                                        uint64_t Address, const void *Decoder) {
194   return decodeSImmOperand<8>(Inst, Imm);
195 }
196 
decodeS16ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)197 static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm,
198                                         uint64_t Address, const void *Decoder) {
199   return decodeSImmOperand<16>(Inst, Imm);
200 }
201 
decodeS32ImmOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)202 static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm,
203                                         uint64_t Address, const void *Decoder) {
204   return decodeSImmOperand<32>(Inst, Imm);
205 }
206 
207 template<unsigned N>
decodePCDBLOperand(MCInst & Inst,uint64_t Imm,uint64_t Address)208 static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm,
209                                        uint64_t Address) {
210   assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
211   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm) * 2 + Address));
212   return MCDisassembler::Success;
213 }
214 
decodePC16DBLOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)215 static DecodeStatus decodePC16DBLOperand(MCInst &Inst, uint64_t Imm,
216                                          uint64_t Address,
217                                          const void *Decoder) {
218   return decodePCDBLOperand<16>(Inst, Imm, Address);
219 }
220 
decodePC32DBLOperand(MCInst & Inst,uint64_t Imm,uint64_t Address,const void * Decoder)221 static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm,
222                                          uint64_t Address,
223                                          const void *Decoder) {
224   return decodePCDBLOperand<32>(Inst, Imm, Address);
225 }
226 
decodeBDAddr12Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)227 static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field,
228                                           const unsigned *Regs) {
229   uint64_t Base = Field >> 12;
230   uint64_t Disp = Field & 0xfff;
231   assert(Base < 16 && "Invalid BDAddr12");
232   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
233   Inst.addOperand(MCOperand::createImm(Disp));
234   return MCDisassembler::Success;
235 }
236 
decodeBDAddr20Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)237 static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field,
238                                           const unsigned *Regs) {
239   uint64_t Base = Field >> 20;
240   uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff);
241   assert(Base < 16 && "Invalid BDAddr20");
242   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
243   Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp)));
244   return MCDisassembler::Success;
245 }
246 
decodeBDXAddr12Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)247 static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field,
248                                            const unsigned *Regs) {
249   uint64_t Index = Field >> 16;
250   uint64_t Base = (Field >> 12) & 0xf;
251   uint64_t Disp = Field & 0xfff;
252   assert(Index < 16 && "Invalid BDXAddr12");
253   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
254   Inst.addOperand(MCOperand::createImm(Disp));
255   Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index]));
256   return MCDisassembler::Success;
257 }
258 
decodeBDXAddr20Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)259 static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field,
260                                            const unsigned *Regs) {
261   uint64_t Index = Field >> 24;
262   uint64_t Base = (Field >> 20) & 0xf;
263   uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12);
264   assert(Index < 16 && "Invalid BDXAddr20");
265   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
266   Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp)));
267   Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index]));
268   return MCDisassembler::Success;
269 }
270 
decodeBDLAddr12Len8Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)271 static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field,
272                                                const unsigned *Regs) {
273   uint64_t Length = Field >> 16;
274   uint64_t Base = (Field >> 12) & 0xf;
275   uint64_t Disp = Field & 0xfff;
276   assert(Length < 256 && "Invalid BDLAddr12Len8");
277   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
278   Inst.addOperand(MCOperand::createImm(Disp));
279   Inst.addOperand(MCOperand::createImm(Length + 1));
280   return MCDisassembler::Success;
281 }
282 
decodeBDVAddr12Operand(MCInst & Inst,uint64_t Field,const unsigned * Regs)283 static DecodeStatus decodeBDVAddr12Operand(MCInst &Inst, uint64_t Field,
284                                            const unsigned *Regs) {
285   uint64_t Index = Field >> 16;
286   uint64_t Base = (Field >> 12) & 0xf;
287   uint64_t Disp = Field & 0xfff;
288   assert(Index < 32 && "Invalid BDVAddr12");
289   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
290   Inst.addOperand(MCOperand::createImm(Disp));
291   Inst.addOperand(MCOperand::createReg(SystemZMC::VR128Regs[Index]));
292   return MCDisassembler::Success;
293 }
294 
decodeBDAddr32Disp12Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)295 static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field,
296                                                 uint64_t Address,
297                                                 const void *Decoder) {
298   return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs);
299 }
300 
decodeBDAddr32Disp20Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)301 static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field,
302                                                 uint64_t Address,
303                                                 const void *Decoder) {
304   return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs);
305 }
306 
decodeBDAddr64Disp12Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)307 static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
308                                                 uint64_t Address,
309                                                 const void *Decoder) {
310   return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
311 }
312 
decodeBDAddr64Disp20Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)313 static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
314                                                 uint64_t Address,
315                                                 const void *Decoder) {
316   return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
317 }
318 
decodeBDXAddr64Disp12Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)319 static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
320                                                  uint64_t Address,
321                                                  const void *Decoder) {
322   return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
323 }
324 
decodeBDXAddr64Disp20Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)325 static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
326                                                  uint64_t Address,
327                                                  const void *Decoder) {
328   return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
329 }
330 
decodeBDLAddr64Disp12Len8Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)331 static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst,
332                                                      uint64_t Field,
333                                                      uint64_t Address,
334                                                      const void *Decoder) {
335   return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs);
336 }
337 
decodeBDVAddr64Disp12Operand(MCInst & Inst,uint64_t Field,uint64_t Address,const void * Decoder)338 static DecodeStatus decodeBDVAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
339                                                  uint64_t Address,
340                                                  const void *Decoder) {
341   return decodeBDVAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
342 }
343 
344 #include "SystemZGenDisassemblerTables.inc"
345 
getInstruction(MCInst & MI,uint64_t & Size,ArrayRef<uint8_t> Bytes,uint64_t Address,raw_ostream & OS,raw_ostream & CS) const346 DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
347                                                  ArrayRef<uint8_t> Bytes,
348                                                  uint64_t Address,
349                                                  raw_ostream &OS,
350                                                  raw_ostream &CS) const {
351   // Get the first two bytes of the instruction.
352   Size = 0;
353   if (Bytes.size() < 2)
354     return MCDisassembler::Fail;
355 
356   // The top 2 bits of the first byte specify the size.
357   const uint8_t *Table;
358   if (Bytes[0] < 0x40) {
359     Size = 2;
360     Table = DecoderTable16;
361   } else if (Bytes[0] < 0xc0) {
362     Size = 4;
363     Table = DecoderTable32;
364   } else {
365     Size = 6;
366     Table = DecoderTable48;
367   }
368 
369   // Read any remaining bytes.
370   if (Bytes.size() < Size)
371     return MCDisassembler::Fail;
372 
373   // Construct the instruction.
374   uint64_t Inst = 0;
375   for (uint64_t I = 0; I < Size; ++I)
376     Inst = (Inst << 8) | Bytes[I];
377 
378   return decodeInstruction(Table, MI, Inst, Address, this, STI);
379 }
380