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