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