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