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