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