xref: /freebsd/contrib/llvm-project/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp (revision 34b696e41259e41ae3ac61a539bd152d3afb73ae)
1  //===------ PPCDisassembler.cpp - Disassembler for PowerPC ------*- 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/PPCMCTargetDesc.h"
10  #include "TargetInfo/PowerPCTargetInfo.h"
11  #include "llvm/MC/MCDecoderOps.h"
12  #include "llvm/MC/MCDisassembler/MCDisassembler.h"
13  #include "llvm/MC/MCInst.h"
14  #include "llvm/MC/MCSubtargetInfo.h"
15  #include "llvm/MC/TargetRegistry.h"
16  #include "llvm/Support/Endian.h"
17  
18  using namespace llvm;
19  
20  DEFINE_PPC_REGCLASSES;
21  
22  #define DEBUG_TYPE "ppc-disassembler"
23  
24  typedef MCDisassembler::DecodeStatus DecodeStatus;
25  
26  namespace {
27  class PPCDisassembler : public MCDisassembler {
28    bool IsLittleEndian;
29  
30  public:
31    PPCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
32                    bool IsLittleEndian)
33        : MCDisassembler(STI, Ctx), IsLittleEndian(IsLittleEndian) {}
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  } // end anonymous namespace
40  
41  static MCDisassembler *createPPCDisassembler(const Target &T,
42                                               const MCSubtargetInfo &STI,
43                                               MCContext &Ctx) {
44    return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/false);
45  }
46  
47  static MCDisassembler *createPPCLEDisassembler(const Target &T,
48                                                 const MCSubtargetInfo &STI,
49                                                 MCContext &Ctx) {
50    return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/true);
51  }
52  
53  extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializePowerPCDisassembler() {
54    // Register the disassembler for each target.
55    TargetRegistry::RegisterMCDisassembler(getThePPC32Target(),
56                                           createPPCDisassembler);
57    TargetRegistry::RegisterMCDisassembler(getThePPC32LETarget(),
58                                           createPPCLEDisassembler);
59    TargetRegistry::RegisterMCDisassembler(getThePPC64Target(),
60                                           createPPCDisassembler);
61    TargetRegistry::RegisterMCDisassembler(getThePPC64LETarget(),
62                                           createPPCLEDisassembler);
63  }
64  
65  static DecodeStatus decodeCondBrTarget(MCInst &Inst, unsigned Imm,
66                                         uint64_t /*Address*/,
67                                         const MCDisassembler * /*Decoder*/) {
68    Inst.addOperand(MCOperand::createImm(SignExtend32<14>(Imm)));
69    return MCDisassembler::Success;
70  }
71  
72  static DecodeStatus decodeDirectBrTarget(MCInst &Inst, unsigned Imm,
73                                           uint64_t /*Address*/,
74                                           const MCDisassembler * /*Decoder*/) {
75    int32_t Offset = SignExtend32<24>(Imm);
76    Inst.addOperand(MCOperand::createImm(Offset));
77    return MCDisassembler::Success;
78  }
79  
80  // FIXME: These can be generated by TableGen from the existing register
81  // encoding values!
82  
83  template <std::size_t N>
84  static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
85                                          const MCPhysReg (&Regs)[N]) {
86    assert(RegNo < N && "Invalid register number");
87    Inst.addOperand(MCOperand::createReg(Regs[RegNo]));
88    return MCDisassembler::Success;
89  }
90  
91  static DecodeStatus DecodeCRRCRegisterClass(MCInst &Inst, uint64_t RegNo,
92                                              uint64_t Address,
93                                              const MCDisassembler *Decoder) {
94    return decodeRegisterClass(Inst, RegNo, CRRegs);
95  }
96  
97  static DecodeStatus DecodeCRBITRCRegisterClass(MCInst &Inst, uint64_t RegNo,
98                                                 uint64_t Address,
99                                                 const MCDisassembler *Decoder) {
100    return decodeRegisterClass(Inst, RegNo, CRBITRegs);
101  }
102  
103  static DecodeStatus DecodeF4RCRegisterClass(MCInst &Inst, uint64_t RegNo,
104                                              uint64_t Address,
105                                              const MCDisassembler *Decoder) {
106    return decodeRegisterClass(Inst, RegNo, FRegs);
107  }
108  
109  static DecodeStatus DecodeF8RCRegisterClass(MCInst &Inst, uint64_t RegNo,
110                                              uint64_t Address,
111                                              const MCDisassembler *Decoder) {
112    return decodeRegisterClass(Inst, RegNo, FRegs);
113  }
114  
115  static DecodeStatus DecodeVFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
116                                              uint64_t Address,
117                                              const MCDisassembler *Decoder) {
118    return decodeRegisterClass(Inst, RegNo, VFRegs);
119  }
120  
121  static DecodeStatus DecodeVRRCRegisterClass(MCInst &Inst, uint64_t RegNo,
122                                              uint64_t Address,
123                                              const MCDisassembler *Decoder) {
124    return decodeRegisterClass(Inst, RegNo, VRegs);
125  }
126  
127  static DecodeStatus DecodeVSRCRegisterClass(MCInst &Inst, uint64_t RegNo,
128                                              uint64_t Address,
129                                              const MCDisassembler *Decoder) {
130    return decodeRegisterClass(Inst, RegNo, VSRegs);
131  }
132  
133  static DecodeStatus DecodeVSFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
134                                               uint64_t Address,
135                                               const MCDisassembler *Decoder) {
136    return decodeRegisterClass(Inst, RegNo, VSFRegs);
137  }
138  
139  static DecodeStatus DecodeVSSRCRegisterClass(MCInst &Inst, uint64_t RegNo,
140                                               uint64_t Address,
141                                               const MCDisassembler *Decoder) {
142    return decodeRegisterClass(Inst, RegNo, VSSRegs);
143  }
144  
145  static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
146                                              uint64_t Address,
147                                              const MCDisassembler *Decoder) {
148    return decodeRegisterClass(Inst, RegNo, RRegs);
149  }
150  
151  static DecodeStatus
152  DecodeGPRC_NOR0RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address,
153                               const MCDisassembler *Decoder) {
154    return decodeRegisterClass(Inst, RegNo, RRegsNoR0);
155  }
156  
157  static DecodeStatus DecodeG8RCRegisterClass(MCInst &Inst, uint64_t RegNo,
158                                              uint64_t Address,
159                                              const MCDisassembler *Decoder) {
160    return decodeRegisterClass(Inst, RegNo, XRegs);
161  }
162  
163  static DecodeStatus DecodeG8pRCRegisterClass(MCInst &Inst, uint64_t RegNo,
164                                               uint64_t Address,
165                                               const MCDisassembler *Decoder) {
166    return decodeRegisterClass(Inst, RegNo, XRegs);
167  }
168  
169  static DecodeStatus
170  DecodeG8RC_NOX0RegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address,
171                               const MCDisassembler *Decoder) {
172    return decodeRegisterClass(Inst, RegNo, XRegsNoX0);
173  }
174  
175  #define DecodePointerLikeRegClass0 DecodeGPRCRegisterClass
176  #define DecodePointerLikeRegClass1 DecodeGPRC_NOR0RegisterClass
177  
178  static DecodeStatus DecodeSPERCRegisterClass(MCInst &Inst, uint64_t RegNo,
179                                               uint64_t Address,
180                                               const MCDisassembler *Decoder) {
181    return decodeRegisterClass(Inst, RegNo, SPERegs);
182  }
183  
184  static DecodeStatus DecodeACCRCRegisterClass(MCInst &Inst, uint64_t RegNo,
185                                               uint64_t Address,
186                                               const MCDisassembler *Decoder) {
187    return decodeRegisterClass(Inst, RegNo, ACCRegs);
188  }
189  
190  static DecodeStatus DecodeVSRpRCRegisterClass(MCInst &Inst, uint64_t RegNo,
191                                                uint64_t Address,
192                                                const MCDisassembler *Decoder) {
193    return decodeRegisterClass(Inst, RegNo, VSRpRegs);
194  }
195  
196  #define DecodeQSRCRegisterClass DecodeQFRCRegisterClass
197  #define DecodeQBRCRegisterClass DecodeQFRCRegisterClass
198  
199  template <unsigned N>
200  static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
201                                        int64_t Address,
202                                        const MCDisassembler *Decoder) {
203    assert(isUInt<N>(Imm) && "Invalid immediate");
204    Inst.addOperand(MCOperand::createImm(Imm));
205    return MCDisassembler::Success;
206  }
207  
208  template <unsigned N>
209  static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
210                                        int64_t Address,
211                                        const MCDisassembler *Decoder) {
212    assert(isUInt<N>(Imm) && "Invalid immediate");
213    Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
214    return MCDisassembler::Success;
215  }
216  
217  static DecodeStatus decodeImmZeroOperand(MCInst &Inst, uint64_t Imm,
218                                           int64_t Address,
219                                           const MCDisassembler *Decoder) {
220    if (Imm != 0)
221      return MCDisassembler::Fail;
222    Inst.addOperand(MCOperand::createImm(Imm));
223    return MCDisassembler::Success;
224  }
225  
226  static DecodeStatus decodeVSRpEvenOperands(MCInst &Inst, uint64_t RegNo,
227                                             uint64_t Address,
228                                             const MCDisassembler *Decoder) {
229    if (RegNo & 1)
230      return MCDisassembler::Fail;
231    Inst.addOperand(MCOperand::createReg(VSRpRegs[RegNo >> 1]));
232    return MCDisassembler::Success;
233  }
234  
235  static DecodeStatus decodeMemRIOperands(MCInst &Inst, uint64_t Imm,
236                                          int64_t Address,
237                                          const MCDisassembler *Decoder) {
238    // Decode the memri field (imm, reg), which has the low 16-bits as the
239    // displacement and the next 5 bits as the register #.
240  
241    uint64_t Base = Imm >> 16;
242    uint64_t Disp = Imm & 0xFFFF;
243  
244    assert(Base < 32 && "Invalid base register");
245  
246    switch (Inst.getOpcode()) {
247    default: break;
248    case PPC::LBZU:
249    case PPC::LHAU:
250    case PPC::LHZU:
251    case PPC::LWZU:
252    case PPC::LFSU:
253    case PPC::LFDU:
254      // Add the tied output operand.
255      Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
256      break;
257    case PPC::STBU:
258    case PPC::STHU:
259    case PPC::STWU:
260    case PPC::STFSU:
261    case PPC::STFDU:
262      Inst.insert(Inst.begin(), MCOperand::createReg(RRegsNoR0[Base]));
263      break;
264    }
265  
266    Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp)));
267    Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
268    return MCDisassembler::Success;
269  }
270  
271  static DecodeStatus decodeMemRIXOperands(MCInst &Inst, uint64_t Imm,
272                                           int64_t Address,
273                                           const MCDisassembler *Decoder) {
274    // Decode the memrix field (imm, reg), which has the low 14-bits as the
275    // displacement and the next 5 bits as the register #.
276  
277    uint64_t Base = Imm >> 14;
278    uint64_t Disp = Imm & 0x3FFF;
279  
280    assert(Base < 32 && "Invalid base register");
281  
282    if (Inst.getOpcode() == PPC::LDU)
283      // Add the tied output operand.
284      Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
285    else if (Inst.getOpcode() == PPC::STDU)
286      Inst.insert(Inst.begin(), MCOperand::createReg(RRegsNoR0[Base]));
287  
288    Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp << 2)));
289    Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
290    return MCDisassembler::Success;
291  }
292  
293  static DecodeStatus decodeMemRIHashOperands(MCInst &Inst, uint64_t Imm,
294                                              int64_t Address,
295                                              const MCDisassembler *Decoder) {
296    // Decode the memrix field for a hash store or hash check operation.
297    // The field is composed of a register and an immediate value that is 6 bits
298    // and covers the range -8 to -512. The immediate is always negative and 2s
299    // complement which is why we sign extend a 7 bit value.
300    const uint64_t Base = Imm >> 6;
301    const int64_t Disp = SignExtend64<7>((Imm & 0x3F) + 64) * 8;
302  
303    assert(Base < 32 && "Invalid base register");
304  
305    Inst.addOperand(MCOperand::createImm(Disp));
306    Inst.addOperand(MCOperand::createReg(RRegs[Base]));
307    return MCDisassembler::Success;
308  }
309  
310  static DecodeStatus decodeMemRIX16Operands(MCInst &Inst, uint64_t Imm,
311                                             int64_t Address,
312                                             const MCDisassembler *Decoder) {
313    // Decode the memrix16 field (imm, reg), which has the low 12-bits as the
314    // displacement with 16-byte aligned, and the next 5 bits as the register #.
315  
316    uint64_t Base = Imm >> 12;
317    uint64_t Disp = Imm & 0xFFF;
318  
319    assert(Base < 32 && "Invalid base register");
320  
321    Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp << 4)));
322    Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
323    return MCDisassembler::Success;
324  }
325  
326  static DecodeStatus decodeMemRI34PCRelOperands(MCInst &Inst, uint64_t Imm,
327                                                 int64_t Address,
328                                                 const MCDisassembler *Decoder) {
329    // Decode the memri34_pcrel field (imm, reg), which has the low 34-bits as the
330    // displacement, and the next 5 bits as an immediate 0.
331    uint64_t Base = Imm >> 34;
332    uint64_t Disp = Imm & 0x3FFFFFFFFUL;
333  
334    assert(Base < 32 && "Invalid base register");
335  
336    Inst.addOperand(MCOperand::createImm(SignExtend64<34>(Disp)));
337    return decodeImmZeroOperand(Inst, Base, Address, Decoder);
338  }
339  
340  static DecodeStatus decodeMemRI34Operands(MCInst &Inst, uint64_t Imm,
341                                            int64_t Address,
342                                            const MCDisassembler *Decoder) {
343    // Decode the memri34 field (imm, reg), which has the low 34-bits as the
344    // displacement, and the next 5 bits as the register #.
345    uint64_t Base = Imm >> 34;
346    uint64_t Disp = Imm & 0x3FFFFFFFFUL;
347  
348    assert(Base < 32 && "Invalid base register");
349  
350    Inst.addOperand(MCOperand::createImm(SignExtend64<34>(Disp)));
351    Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
352    return MCDisassembler::Success;
353  }
354  
355  static DecodeStatus decodeSPE8Operands(MCInst &Inst, uint64_t Imm,
356                                         int64_t Address,
357                                         const MCDisassembler *Decoder) {
358    // Decode the spe8disp field (imm, reg), which has the low 5-bits as the
359    // displacement with 8-byte aligned, and the next 5 bits as the register #.
360  
361    uint64_t Base = Imm >> 5;
362    uint64_t Disp = Imm & 0x1F;
363  
364    assert(Base < 32 && "Invalid base register");
365  
366    Inst.addOperand(MCOperand::createImm(Disp << 3));
367    Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
368    return MCDisassembler::Success;
369  }
370  
371  static DecodeStatus decodeSPE4Operands(MCInst &Inst, uint64_t Imm,
372                                         int64_t Address,
373                                         const MCDisassembler *Decoder) {
374    // Decode the spe4disp field (imm, reg), which has the low 5-bits as the
375    // displacement with 4-byte aligned, and the next 5 bits as the register #.
376  
377    uint64_t Base = Imm >> 5;
378    uint64_t Disp = Imm & 0x1F;
379  
380    assert(Base < 32 && "Invalid base register");
381  
382    Inst.addOperand(MCOperand::createImm(Disp << 2));
383    Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
384    return MCDisassembler::Success;
385  }
386  
387  static DecodeStatus decodeSPE2Operands(MCInst &Inst, uint64_t Imm,
388                                         int64_t Address,
389                                         const MCDisassembler *Decoder) {
390    // Decode the spe2disp field (imm, reg), which has the low 5-bits as the
391    // displacement with 2-byte aligned, and the next 5 bits as the register #.
392  
393    uint64_t Base = Imm >> 5;
394    uint64_t Disp = Imm & 0x1F;
395  
396    assert(Base < 32 && "Invalid base register");
397  
398    Inst.addOperand(MCOperand::createImm(Disp << 1));
399    Inst.addOperand(MCOperand::createReg(RRegsNoR0[Base]));
400    return MCDisassembler::Success;
401  }
402  
403  static DecodeStatus decodeCRBitMOperand(MCInst &Inst, uint64_t Imm,
404                                          int64_t Address,
405                                          const MCDisassembler *Decoder) {
406    // The cr bit encoding is 0x80 >> cr_reg_num.
407  
408    unsigned Zeros = countTrailingZeros(Imm);
409    assert(Zeros < 8 && "Invalid CR bit value");
410  
411    Inst.addOperand(MCOperand::createReg(CRRegs[7 - Zeros]));
412    return MCDisassembler::Success;
413  }
414  
415  #include "PPCGenDisassemblerTables.inc"
416  
417  DecodeStatus PPCDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
418                                               ArrayRef<uint8_t> Bytes,
419                                               uint64_t Address,
420                                               raw_ostream &CS) const {
421    auto *ReadFunc = IsLittleEndian ? support::endian::read32le
422                                    : support::endian::read32be;
423  
424    // If this is an 8-byte prefixed instruction, handle it here.
425    // Note: prefixed instructions aren't technically 8-byte entities - the prefix
426    //       appears in memory at an address 4 bytes prior to that of the base
427    //       instruction regardless of endianness. So we read the two pieces and
428    //       rebuild the 8-byte instruction.
429    // TODO: In this function we call decodeInstruction several times with
430    //       different decoder tables. It may be possible to only call once by
431    //       looking at the top 6 bits of the instruction.
432    if (STI.getFeatureBits()[PPC::FeaturePrefixInstrs] && Bytes.size() >= 8) {
433      uint32_t Prefix = ReadFunc(Bytes.data());
434      uint32_t BaseInst = ReadFunc(Bytes.data() + 4);
435      uint64_t Inst = BaseInst | (uint64_t)Prefix << 32;
436      DecodeStatus result = decodeInstruction(DecoderTable64, MI, Inst, Address,
437                                              this, STI);
438      if (result != MCDisassembler::Fail) {
439        Size = 8;
440        return result;
441      }
442    }
443  
444    // Get the four bytes of the instruction.
445    Size = 4;
446    if (Bytes.size() < 4) {
447      Size = 0;
448      return MCDisassembler::Fail;
449    }
450  
451    // Read the instruction in the proper endianness.
452    uint64_t Inst = ReadFunc(Bytes.data());
453  
454    if (STI.getFeatureBits()[PPC::FeatureSPE]) {
455      DecodeStatus result =
456          decodeInstruction(DecoderTableSPE32, MI, Inst, Address, this, STI);
457      if (result != MCDisassembler::Fail)
458        return result;
459    }
460  
461    return decodeInstruction(DecoderTable32, MI, Inst, Address, this, STI);
462  }
463