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