xref: /llvm-project/llvm/lib/Target/SystemZ/Disassembler/SystemZDisassembler.cpp (revision 3943d2b0d7c16b54dabcf34730643da932f1df2f)
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 "MCTargetDesc/SystemZMCTargetDesc.h"
11 #include "SystemZ.h"
12 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
13 #include "llvm/MC/MCFixedLenDisassembler.h"
14 #include "llvm/MC/MCInst.h"
15 #include "llvm/MC/MCSubtargetInfo.h"
16 #include "llvm/Support/MathExtras.h"
17 #include "llvm/Support/TargetRegistry.h"
18 #include <cassert>
19 #include <cstdint>
20 
21 using namespace llvm;
22 
23 #define DEBUG_TYPE "systemz-disassembler"
24 
25 typedef MCDisassembler::DecodeStatus DecodeStatus;
26 
27 namespace {
28 
29 class SystemZDisassembler : public MCDisassembler {
30 public:
31   SystemZDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx)
32     : MCDisassembler(STI, Ctx) {}
33   ~SystemZDisassembler() override = default;
34 
35   DecodeStatus getInstruction(MCInst &instr, uint64_t &Size,
36                               ArrayRef<uint8_t> Bytes, uint64_t Address,
37                               raw_ostream &VStream,
38                               raw_ostream &CStream) const override;
39 };
40 
41 } // end anonymous namespace
42 
43 static MCDisassembler *createSystemZDisassembler(const Target &T,
44                                                  const MCSubtargetInfo &STI,
45                                                  MCContext &Ctx) {
46   return new SystemZDisassembler(STI, Ctx);
47 }
48 
49 extern "C" void LLVMInitializeSystemZDisassembler() {
50   // Register the disassembler.
51   TargetRegistry::RegisterMCDisassembler(getTheSystemZTarget(),
52                                          createSystemZDisassembler);
53 }
54 
55 /// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
56 /// immediate Value in the MCInst.
57 ///
58 /// @param Value      - The immediate Value, has had any PC adjustment made by
59 ///                     the caller.
60 /// @param isBranch   - If the instruction is a branch instruction
61 /// @param Address    - The starting address of the instruction
62 /// @param Offset     - The byte offset to this immediate in the instruction
63 /// @param Width      - The byte width of this immediate in the instruction
64 ///
65 /// If the getOpInfo() function was set when setupForSymbolicDisassembly() was
66 /// called then that function is called to get any symbolic information for the
67 /// immediate in the instruction using the Address, Offset and Width.  If that
68 /// returns non-zero then the symbolic information it returns is used to create
69 /// an MCExpr and that is added as an operand to the MCInst.  If getOpInfo()
70 /// returns zero and isBranch is true then a symbol look up for immediate Value
71 /// is done and if a symbol is found an MCExpr is created with that, else
72 /// an MCExpr with the immediate Value is created.  This function returns true
73 /// if it adds an operand to the MCInst and false otherwise.
74 static bool tryAddingSymbolicOperand(int64_t Value, bool isBranch,
75                                      uint64_t Address, uint64_t Offset,
76                                      uint64_t Width, MCInst &MI,
77                                      const void *Decoder) {
78   const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
79   return Dis->tryAddingSymbolicOperand(MI, Value, Address, isBranch,
80                                        Offset, Width);
81 }
82 
83 static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
84                                         const unsigned *Regs, unsigned Size) {
85   assert(RegNo < Size && "Invalid register");
86   RegNo = Regs[RegNo];
87   if (RegNo == 0)
88     return MCDisassembler::Fail;
89   Inst.addOperand(MCOperand::createReg(RegNo));
90   return MCDisassembler::Success;
91 }
92 
93 static DecodeStatus DecodeGR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
94                                                uint64_t Address,
95                                                const void *Decoder) {
96   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR32Regs, 16);
97 }
98 
99 static DecodeStatus DecodeGRH32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
100                                                 uint64_t Address,
101                                                 const void *Decoder) {
102   return decodeRegisterClass(Inst, RegNo, SystemZMC::GRH32Regs, 16);
103 }
104 
105 static DecodeStatus DecodeGR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
106                                                uint64_t Address,
107                                                const void *Decoder) {
108   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
109 }
110 
111 static DecodeStatus DecodeGR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
112                                                 uint64_t Address,
113                                                 const void *Decoder) {
114   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR128Regs, 16);
115 }
116 
117 static DecodeStatus DecodeADDR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
118                                                  uint64_t Address,
119                                                  const void *Decoder) {
120   return decodeRegisterClass(Inst, RegNo, SystemZMC::GR64Regs, 16);
121 }
122 
123 static DecodeStatus DecodeFP32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
124                                                uint64_t Address,
125                                                const void *Decoder) {
126   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP32Regs, 16);
127 }
128 
129 static DecodeStatus DecodeFP64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
130                                                uint64_t Address,
131                                                const void *Decoder) {
132   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP64Regs, 16);
133 }
134 
135 static DecodeStatus DecodeFP128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
136                                                 uint64_t Address,
137                                                 const void *Decoder) {
138   return decodeRegisterClass(Inst, RegNo, SystemZMC::FP128Regs, 16);
139 }
140 
141 static DecodeStatus DecodeVR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
142                                                uint64_t Address,
143                                                const void *Decoder) {
144   return decodeRegisterClass(Inst, RegNo, SystemZMC::VR32Regs, 32);
145 }
146 
147 static DecodeStatus DecodeVR64BitRegisterClass(MCInst &Inst, uint64_t RegNo,
148                                                uint64_t Address,
149                                                const void *Decoder) {
150   return decodeRegisterClass(Inst, RegNo, SystemZMC::VR64Regs, 32);
151 }
152 
153 static DecodeStatus DecodeVR128BitRegisterClass(MCInst &Inst, uint64_t RegNo,
154                                                 uint64_t Address,
155                                                 const void *Decoder) {
156   return decodeRegisterClass(Inst, RegNo, SystemZMC::VR128Regs, 32);
157 }
158 
159 static DecodeStatus DecodeAR32BitRegisterClass(MCInst &Inst, uint64_t RegNo,
160                                                uint64_t Address,
161                                                const void *Decoder) {
162   return decodeRegisterClass(Inst, RegNo, SystemZMC::AR32Regs, 16);
163 }
164 
165 template<unsigned N>
166 static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm) {
167   if (!isUInt<N>(Imm))
168     return MCDisassembler::Fail;
169   Inst.addOperand(MCOperand::createImm(Imm));
170   return MCDisassembler::Success;
171 }
172 
173 template<unsigned N>
174 static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm) {
175   if (!isUInt<N>(Imm))
176     return MCDisassembler::Fail;
177   Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
178   return MCDisassembler::Success;
179 }
180 
181 static DecodeStatus decodeU1ImmOperand(MCInst &Inst, uint64_t Imm,
182                                        uint64_t Address, const void *Decoder) {
183   return decodeUImmOperand<1>(Inst, Imm);
184 }
185 
186 static DecodeStatus decodeU2ImmOperand(MCInst &Inst, uint64_t Imm,
187                                        uint64_t Address, const void *Decoder) {
188   return decodeUImmOperand<2>(Inst, Imm);
189 }
190 
191 static DecodeStatus decodeU3ImmOperand(MCInst &Inst, uint64_t Imm,
192                                        uint64_t Address, const void *Decoder) {
193   return decodeUImmOperand<3>(Inst, Imm);
194 }
195 
196 static DecodeStatus decodeU4ImmOperand(MCInst &Inst, uint64_t Imm,
197                                        uint64_t Address, const void *Decoder) {
198   return decodeUImmOperand<4>(Inst, Imm);
199 }
200 
201 static DecodeStatus decodeU6ImmOperand(MCInst &Inst, uint64_t Imm,
202                                        uint64_t Address, const void *Decoder) {
203   return decodeUImmOperand<6>(Inst, Imm);
204 }
205 
206 static DecodeStatus decodeU8ImmOperand(MCInst &Inst, uint64_t Imm,
207                                        uint64_t Address, const void *Decoder) {
208   return decodeUImmOperand<8>(Inst, Imm);
209 }
210 
211 static DecodeStatus decodeU12ImmOperand(MCInst &Inst, uint64_t Imm,
212                                         uint64_t Address, const void *Decoder) {
213   return decodeUImmOperand<12>(Inst, Imm);
214 }
215 
216 static DecodeStatus decodeU16ImmOperand(MCInst &Inst, uint64_t Imm,
217                                         uint64_t Address, const void *Decoder) {
218   return decodeUImmOperand<16>(Inst, Imm);
219 }
220 
221 static DecodeStatus decodeU32ImmOperand(MCInst &Inst, uint64_t Imm,
222                                         uint64_t Address, const void *Decoder) {
223   return decodeUImmOperand<32>(Inst, Imm);
224 }
225 
226 static DecodeStatus decodeS8ImmOperand(MCInst &Inst, uint64_t Imm,
227                                        uint64_t Address, const void *Decoder) {
228   return decodeSImmOperand<8>(Inst, Imm);
229 }
230 
231 static DecodeStatus decodeS16ImmOperand(MCInst &Inst, uint64_t Imm,
232                                         uint64_t Address, const void *Decoder) {
233   return decodeSImmOperand<16>(Inst, Imm);
234 }
235 
236 static DecodeStatus decodeS32ImmOperand(MCInst &Inst, uint64_t Imm,
237                                         uint64_t Address, const void *Decoder) {
238   return decodeSImmOperand<32>(Inst, Imm);
239 }
240 
241 template<unsigned N>
242 static DecodeStatus decodePCDBLOperand(MCInst &Inst, uint64_t Imm,
243                                        uint64_t Address,
244                                        bool isBranch,
245                                        const void *Decoder) {
246   assert(isUInt<N>(Imm) && "Invalid PC-relative offset");
247   uint64_t Value = SignExtend64<N>(Imm) * 2 + Address;
248 
249   if (!tryAddingSymbolicOperand(Value, isBranch, Address, 2, N / 8,
250                                 Inst, Decoder))
251     Inst.addOperand(MCOperand::createImm(Value));
252 
253   return MCDisassembler::Success;
254 }
255 
256 static DecodeStatus decodePC12DBLBranchOperand(MCInst &Inst, uint64_t Imm,
257                                                uint64_t Address,
258                                                const void *Decoder) {
259   return decodePCDBLOperand<12>(Inst, Imm, Address, true, Decoder);
260 }
261 
262 static DecodeStatus decodePC16DBLBranchOperand(MCInst &Inst, uint64_t Imm,
263                                                uint64_t Address,
264                                                const void *Decoder) {
265   return decodePCDBLOperand<16>(Inst, Imm, Address, true, Decoder);
266 }
267 
268 static DecodeStatus decodePC24DBLBranchOperand(MCInst &Inst, uint64_t Imm,
269                                                uint64_t Address,
270                                                const void *Decoder) {
271   return decodePCDBLOperand<24>(Inst, Imm, Address, true, Decoder);
272 }
273 
274 static DecodeStatus decodePC32DBLBranchOperand(MCInst &Inst, uint64_t Imm,
275                                                uint64_t Address,
276                                                const void *Decoder) {
277   return decodePCDBLOperand<32>(Inst, Imm, Address, true, Decoder);
278 }
279 
280 static DecodeStatus decodePC32DBLOperand(MCInst &Inst, uint64_t Imm,
281                                          uint64_t Address,
282                                          const void *Decoder) {
283   return decodePCDBLOperand<32>(Inst, Imm, Address, false, Decoder);
284 }
285 
286 static DecodeStatus decodeBDAddr12Operand(MCInst &Inst, uint64_t Field,
287                                           const unsigned *Regs) {
288   uint64_t Base = Field >> 12;
289   uint64_t Disp = Field & 0xfff;
290   assert(Base < 16 && "Invalid BDAddr12");
291   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
292   Inst.addOperand(MCOperand::createImm(Disp));
293   return MCDisassembler::Success;
294 }
295 
296 static DecodeStatus decodeBDAddr20Operand(MCInst &Inst, uint64_t Field,
297                                           const unsigned *Regs) {
298   uint64_t Base = Field >> 20;
299   uint64_t Disp = ((Field << 12) & 0xff000) | ((Field >> 8) & 0xfff);
300   assert(Base < 16 && "Invalid BDAddr20");
301   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
302   Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp)));
303   return MCDisassembler::Success;
304 }
305 
306 static DecodeStatus decodeBDXAddr12Operand(MCInst &Inst, uint64_t Field,
307                                            const unsigned *Regs) {
308   uint64_t Index = Field >> 16;
309   uint64_t Base = (Field >> 12) & 0xf;
310   uint64_t Disp = Field & 0xfff;
311   assert(Index < 16 && "Invalid BDXAddr12");
312   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
313   Inst.addOperand(MCOperand::createImm(Disp));
314   Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index]));
315   return MCDisassembler::Success;
316 }
317 
318 static DecodeStatus decodeBDXAddr20Operand(MCInst &Inst, uint64_t Field,
319                                            const unsigned *Regs) {
320   uint64_t Index = Field >> 24;
321   uint64_t Base = (Field >> 20) & 0xf;
322   uint64_t Disp = ((Field & 0xfff00) >> 8) | ((Field & 0xff) << 12);
323   assert(Index < 16 && "Invalid BDXAddr20");
324   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
325   Inst.addOperand(MCOperand::createImm(SignExtend64<20>(Disp)));
326   Inst.addOperand(MCOperand::createReg(Index == 0 ? 0 : Regs[Index]));
327   return MCDisassembler::Success;
328 }
329 
330 static DecodeStatus decodeBDLAddr12Len8Operand(MCInst &Inst, uint64_t Field,
331                                                const unsigned *Regs) {
332   uint64_t Length = Field >> 16;
333   uint64_t Base = (Field >> 12) & 0xf;
334   uint64_t Disp = Field & 0xfff;
335   assert(Length < 256 && "Invalid BDLAddr12Len8");
336   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
337   Inst.addOperand(MCOperand::createImm(Disp));
338   Inst.addOperand(MCOperand::createImm(Length + 1));
339   return MCDisassembler::Success;
340 }
341 
342 static DecodeStatus decodeBDRAddr12Operand(MCInst &Inst, uint64_t Field,
343                                            const unsigned *Regs) {
344   uint64_t Length = Field >> 16;
345   uint64_t Base = (Field >> 12) & 0xf;
346   uint64_t Disp = Field & 0xfff;
347   assert(Length < 16 && "Invalid BDRAddr12");
348   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
349   Inst.addOperand(MCOperand::createImm(Disp));
350   Inst.addOperand(MCOperand::createReg(Regs[Length]));
351   return MCDisassembler::Success;
352 }
353 
354 static DecodeStatus decodeBDVAddr12Operand(MCInst &Inst, uint64_t Field,
355                                            const unsigned *Regs) {
356   uint64_t Index = Field >> 16;
357   uint64_t Base = (Field >> 12) & 0xf;
358   uint64_t Disp = Field & 0xfff;
359   assert(Index < 32 && "Invalid BDVAddr12");
360   Inst.addOperand(MCOperand::createReg(Base == 0 ? 0 : Regs[Base]));
361   Inst.addOperand(MCOperand::createImm(Disp));
362   Inst.addOperand(MCOperand::createReg(SystemZMC::VR128Regs[Index]));
363   return MCDisassembler::Success;
364 }
365 
366 static DecodeStatus decodeBDAddr32Disp12Operand(MCInst &Inst, uint64_t Field,
367                                                 uint64_t Address,
368                                                 const void *Decoder) {
369   return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR32Regs);
370 }
371 
372 static DecodeStatus decodeBDAddr32Disp20Operand(MCInst &Inst, uint64_t Field,
373                                                 uint64_t Address,
374                                                 const void *Decoder) {
375   return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR32Regs);
376 }
377 
378 static DecodeStatus decodeBDAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
379                                                 uint64_t Address,
380                                                 const void *Decoder) {
381   return decodeBDAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
382 }
383 
384 static DecodeStatus decodeBDAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
385                                                 uint64_t Address,
386                                                 const void *Decoder) {
387   return decodeBDAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
388 }
389 
390 static DecodeStatus decodeBDXAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
391                                                  uint64_t Address,
392                                                  const void *Decoder) {
393   return decodeBDXAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
394 }
395 
396 static DecodeStatus decodeBDXAddr64Disp20Operand(MCInst &Inst, uint64_t Field,
397                                                  uint64_t Address,
398                                                  const void *Decoder) {
399   return decodeBDXAddr20Operand(Inst, Field, SystemZMC::GR64Regs);
400 }
401 
402 static DecodeStatus decodeBDLAddr64Disp12Len8Operand(MCInst &Inst,
403                                                      uint64_t Field,
404                                                      uint64_t Address,
405                                                      const void *Decoder) {
406   return decodeBDLAddr12Len8Operand(Inst, Field, SystemZMC::GR64Regs);
407 }
408 
409 static DecodeStatus decodeBDRAddr64Disp12Operand(MCInst &Inst,
410                                                  uint64_t Field,
411                                                  uint64_t Address,
412                                                  const void *Decoder) {
413   return decodeBDRAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
414 }
415 
416 static DecodeStatus decodeBDVAddr64Disp12Operand(MCInst &Inst, uint64_t Field,
417                                                  uint64_t Address,
418                                                  const void *Decoder) {
419   return decodeBDVAddr12Operand(Inst, Field, SystemZMC::GR64Regs);
420 }
421 
422 #include "SystemZGenDisassemblerTables.inc"
423 
424 DecodeStatus SystemZDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
425                                                  ArrayRef<uint8_t> Bytes,
426                                                  uint64_t Address,
427                                                  raw_ostream &OS,
428                                                  raw_ostream &CS) const {
429   // Get the first two bytes of the instruction.
430   Size = 0;
431   if (Bytes.size() < 2)
432     return MCDisassembler::Fail;
433 
434   // The top 2 bits of the first byte specify the size.
435   const uint8_t *Table;
436   if (Bytes[0] < 0x40) {
437     Size = 2;
438     Table = DecoderTable16;
439   } else if (Bytes[0] < 0xc0) {
440     Size = 4;
441     Table = DecoderTable32;
442   } else {
443     Size = 6;
444     Table = DecoderTable48;
445   }
446 
447   // Read any remaining bytes.
448   if (Bytes.size() < Size)
449     return MCDisassembler::Fail;
450 
451   // Construct the instruction.
452   uint64_t Inst = 0;
453   for (uint64_t I = 0; I < Size; ++I)
454     Inst = (Inst << 8) | Bytes[I];
455 
456   return decodeInstruction(Table, MI, Inst, Address, this, STI);
457 }
458