diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:46:15 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2015-12-30 11:46:15 +0000 | 
| commit | dd58ef019b700900793a1eb48b52123db01b654e (patch) | |
| tree | fcfbb4df56a744f4ddc6122c50521dd3f1c5e196 /lib/Target/Mips/Disassembler/MipsDisassembler.cpp | |
| parent | 2fe5752e3a7c345cdb59e869278d36af33c13fa4 (diff) | |
Notes
Diffstat (limited to 'lib/Target/Mips/Disassembler/MipsDisassembler.cpp')
| -rw-r--r-- | lib/Target/Mips/Disassembler/MipsDisassembler.cpp | 318 | 
1 files changed, 274 insertions, 44 deletions
| diff --git a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp index a34ba3bd0ee8..3c1a771f97e9 100644 --- a/lib/Target/Mips/Disassembler/MipsDisassembler.cpp +++ b/lib/Target/Mips/Disassembler/MipsDisassembler.cpp @@ -229,6 +229,13 @@ static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,                                           uint64_t Address,                                           const void *Decoder); +// DecodeBranchTarget26MM - Decode microMIPS branch offset, which is +// shifted left by 1 bit. +static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst, +                                           unsigned Offset, +                                           uint64_t Address, +                                           const void *Decoder); +  // DecodeJumpTargetMM - Decode microMIPS jump target, which is  // shifted left by 1 bit.  static DecodeStatus DecodeJumpTargetMM(MCInst &Inst, @@ -241,17 +248,42 @@ static DecodeStatus DecodeMem(MCInst &Inst,                                uint64_t Address,                                const void *Decoder); +static DecodeStatus DecodeMemEVA(MCInst &Inst, +                                 unsigned Insn, +                                 uint64_t Address, +                                 const void *Decoder); + +static DecodeStatus DecodeLoadByte9(MCInst &Inst, +                                    unsigned Insn, +                                    uint64_t Address, +                                    const void *Decoder); + +static DecodeStatus DecodeLoadByte15(MCInst &Inst, +                                     unsigned Insn, +                                     uint64_t Address, +                                     const void *Decoder); +  static DecodeStatus DecodeCacheOp(MCInst &Inst,                                unsigned Insn,                                uint64_t Address,                                const void *Decoder); -static DecodeStatus DecodeCacheOpR6(MCInst &Inst, +static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst, +                                             unsigned Insn, +                                             uint64_t Address, +                                             const void *Decoder); + +static DecodeStatus DecodeCacheOpMM(MCInst &Inst,                                      unsigned Insn,                                      uint64_t Address,                                      const void *Decoder); -static DecodeStatus DecodeCacheOpMM(MCInst &Inst, +static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst, +                                       unsigned Insn, +                                       uint64_t Address, +                                       const void *Decoder); + +static DecodeStatus DecodePrefeOpMM(MCInst &Inst,                                      unsigned Insn,                                      uint64_t Address,                                      const void *Decoder); @@ -261,6 +293,11 @@ static DecodeStatus DecodeSyncI(MCInst &Inst,                                  uint64_t Address,                                  const void *Decoder); +static DecodeStatus DecodeSynciR6(MCInst &Inst, +                                  unsigned Insn, +                                  uint64_t Address, +                                  const void *Decoder); +  static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,                                      uint64_t Address, const void *Decoder); @@ -284,6 +321,11 @@ static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,                                                 uint64_t Address,                                                 const void *Decoder); +static DecodeStatus DecodeMemMMImm9(MCInst &Inst, +                                    unsigned Insn, +                                    uint64_t Address, +                                    const void *Decoder); +  static DecodeStatus DecodeMemMMImm12(MCInst &Inst,                                       unsigned Insn,                                       uint64_t Address, @@ -330,6 +372,11 @@ static DecodeStatus DecodeLiSimm7(MCInst &Inst,                                    uint64_t Address,                                    const void *Decoder); +static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst, +                                              unsigned Value, +                                              uint64_t Address, +                                              const void *Decoder); +  static DecodeStatus DecodeSimm4(MCInst &Inst,                                  unsigned Value,                                  uint64_t Address, @@ -340,23 +387,15 @@ static DecodeStatus DecodeSimm16(MCInst &Inst,                                   uint64_t Address,                                   const void *Decoder); -// Decode the immediate field of an LSA instruction which -// is off by one. -static DecodeStatus DecodeLSAImm(MCInst &Inst, -                                 unsigned Insn, -                                 uint64_t Address, -                                 const void *Decoder); +template <unsigned Bits, int Offset> +static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value, +                                         uint64_t Address, const void *Decoder);  static DecodeStatus DecodeInsSize(MCInst &Inst,                                    unsigned Insn,                                    uint64_t Address,                                    const void *Decoder); -static DecodeStatus DecodeExtSize(MCInst &Inst, -                                  unsigned Insn, -                                  uint64_t Address, -                                  const void *Decoder); -  static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,                                       uint64_t Address, const void *Decoder); @@ -830,9 +869,24 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,    if (IsMicroMips) {      Result = readInstruction16(Bytes, Address, Size, Insn, IsBigEndian); +    if (Result == MCDisassembler::Fail) +      return MCDisassembler::Fail; + +    if (hasMips32r6()) { +      DEBUG(dbgs() << "Trying MicroMipsR616 table (16-bit instructions):\n"); +      // Calling the auto-generated decoder function for microMIPS32R6 +      // (and microMIPS64R6) 16-bit instructions. +      Result = decodeInstruction(DecoderTableMicroMipsR616, Instr, Insn, +                                 Address, this, STI); +      if (Result != MCDisassembler::Fail) { +        Size = 2; +        return Result; +      } +    }      DEBUG(dbgs() << "Trying MicroMips16 table (16-bit instructions):\n"); -    // Calling the auto-generated decoder function. +    // Calling the auto-generated decoder function for microMIPS 16-bit +    // instructions.      Result = decodeInstruction(DecoderTableMicroMips16, Instr, Insn, Address,                                 this, STI);      if (Result != MCDisassembler::Fail) { @@ -847,24 +901,33 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,      if (hasMips32r6()) {        DEBUG(dbgs() << "Trying MicroMips32r632 table (32-bit instructions):\n");        // Calling the auto-generated decoder function. -      Result = decodeInstruction(DecoderTableMicroMips32r632, Instr, Insn, Address, -                                 this, STI); -    } else { -      DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n"); -      // Calling the auto-generated decoder function. -      Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address, +      Result = decodeInstruction(DecoderTableMicroMipsR632, Instr, Insn, Address,                                   this, STI); +      if (Result != MCDisassembler::Fail) { +        Size = 4; +        return Result; +      }      } + +    DEBUG(dbgs() << "Trying MicroMips32 table (32-bit instructions):\n"); +    // Calling the auto-generated decoder function. +    Result = decodeInstruction(DecoderTableMicroMips32, Instr, Insn, Address, +                               this, STI);      if (Result != MCDisassembler::Fail) {        Size = 4;        return Result;      } +    // This is an invalid instruction. Let the disassembler move forward by the +    // minimum instruction size. +    Size = 2;      return MCDisassembler::Fail;    }    Result = readInstruction32(Bytes, Address, Size, Insn, IsBigEndian, false); -  if (Result == MCDisassembler::Fail) +  if (Result == MCDisassembler::Fail) { +    Size = 4;      return MCDisassembler::Fail; +  }    if (hasCOP3()) {      DEBUG(dbgs() << "Trying COP3_ table (32-bit opcodes):\n"); @@ -925,6 +988,7 @@ DecodeStatus MipsDisassembler::getInstruction(MCInst &Instr, uint64_t &Size,      return Result;    } +  Size = 4;    return MCDisassembler::Fail;  } @@ -1079,10 +1143,66 @@ static DecodeStatus DecodeMem(MCInst &Inst,    Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);    Base = getReg(Decoder, Mips::GPR32RegClassID, Base); -  if(Inst.getOpcode() == Mips::SC || -     Inst.getOpcode() == Mips::SCD){ +  if (Inst.getOpcode() == Mips::SC || +      Inst.getOpcode() == Mips::SCD)      Inst.addOperand(MCOperand::createReg(Reg)); -  } + +  Inst.addOperand(MCOperand::createReg(Reg)); +  Inst.addOperand(MCOperand::createReg(Base)); +  Inst.addOperand(MCOperand::createImm(Offset)); + +  return MCDisassembler::Success; +} + +static DecodeStatus DecodeMemEVA(MCInst &Inst, +                                 unsigned Insn, +                                 uint64_t Address, +                                 const void *Decoder) { +  int Offset = SignExtend32<9>(Insn >> 7); +  unsigned Reg = fieldFromInstruction(Insn, 16, 5); +  unsigned Base = fieldFromInstruction(Insn, 21, 5); + +  Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); +  Base = getReg(Decoder, Mips::GPR32RegClassID, Base); + +   if (Inst.getOpcode() == Mips::SCE) +     Inst.addOperand(MCOperand::createReg(Reg)); + +  Inst.addOperand(MCOperand::createReg(Reg)); +  Inst.addOperand(MCOperand::createReg(Base)); +  Inst.addOperand(MCOperand::createImm(Offset)); + +  return MCDisassembler::Success; +} + +static DecodeStatus DecodeLoadByte9(MCInst &Inst, +                                    unsigned Insn, +                                    uint64_t Address, +                                    const void *Decoder) { +  int Offset = SignExtend32<9>(Insn & 0x1ff); +  unsigned Base = fieldFromInstruction(Insn, 16, 5); +  unsigned Reg = fieldFromInstruction(Insn, 21, 5); + +  Base = getReg(Decoder, Mips::GPR32RegClassID, Base); +  Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); + +  Inst.addOperand(MCOperand::createReg(Reg)); +  Inst.addOperand(MCOperand::createReg(Base)); +  Inst.addOperand(MCOperand::createImm(Offset)); + +  return MCDisassembler::Success; +} + +static DecodeStatus DecodeLoadByte15(MCInst &Inst, +                                     unsigned Insn, +                                     uint64_t Address, +                                     const void *Decoder) { +  int Offset = SignExtend32<16>(Insn & 0xffff); +  unsigned Base = fieldFromInstruction(Insn, 16, 5); +  unsigned Reg = fieldFromInstruction(Insn, 21, 5); + +  Base = getReg(Decoder, Mips::GPR32RegClassID, Base); +  Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg);    Inst.addOperand(MCOperand::createReg(Reg));    Inst.addOperand(MCOperand::createReg(Base)); @@ -1125,11 +1245,28 @@ static DecodeStatus DecodeCacheOpMM(MCInst &Inst,    return MCDisassembler::Success;  } -static DecodeStatus DecodeCacheOpR6(MCInst &Inst, +static DecodeStatus DecodePrefeOpMM(MCInst &Inst,                                      unsigned Insn,                                      uint64_t Address,                                      const void *Decoder) { -  int Offset = fieldFromInstruction(Insn, 7, 9); +  int Offset = SignExtend32<9>(Insn & 0x1ff); +  unsigned Base = fieldFromInstruction(Insn, 16, 5); +  unsigned Hint = fieldFromInstruction(Insn, 21, 5); + +  Base = getReg(Decoder, Mips::GPR32RegClassID, Base); + +  Inst.addOperand(MCOperand::createReg(Base)); +  Inst.addOperand(MCOperand::createImm(Offset)); +  Inst.addOperand(MCOperand::createImm(Hint)); + +  return MCDisassembler::Success; +} + +static DecodeStatus DecodeCacheeOp_CacheOpR6(MCInst &Inst, +                                             unsigned Insn, +                                             uint64_t Address, +                                             const void *Decoder) { +  int Offset = SignExtend32<9>(Insn >> 7);    unsigned Hint = fieldFromInstruction(Insn, 16, 5);    unsigned Base = fieldFromInstruction(Insn, 21, 5); @@ -1142,6 +1279,24 @@ static DecodeStatus DecodeCacheOpR6(MCInst &Inst,    return MCDisassembler::Success;  } +static DecodeStatus DecodeStoreEvaOpMM(MCInst &Inst, +                                       unsigned Insn, +                                       uint64_t Address, +                                       const void *Decoder) { +  int Offset = SignExtend32<9>(Insn & 0x1ff); +  unsigned Reg = fieldFromInstruction(Insn, 21, 5); +  unsigned Base = fieldFromInstruction(Insn, 16, 5); + +  Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); +  Base = getReg(Decoder, Mips::GPR32RegClassID, Base); + +  Inst.addOperand(MCOperand::createReg(Reg)); +  Inst.addOperand(MCOperand::createReg(Base)); +  Inst.addOperand(MCOperand::createImm(Offset)); + +  return MCDisassembler::Success; +} +  static DecodeStatus DecodeSyncI(MCInst &Inst,                                unsigned Insn,                                uint64_t Address, @@ -1157,6 +1312,21 @@ static DecodeStatus DecodeSyncI(MCInst &Inst,    return MCDisassembler::Success;  } +static DecodeStatus DecodeSynciR6(MCInst &Inst, +                                  unsigned Insn, +                                  uint64_t Address, +                                  const void *Decoder) { +  int Immediate = SignExtend32<16>(Insn & 0xffff); +  unsigned Base = fieldFromInstruction(Insn, 16, 5); + +  Base = getReg(Decoder, Mips::GPR32RegClassID, Base); + +  Inst.addOperand(MCOperand::createReg(Base)); +  Inst.addOperand(MCOperand::createImm(Immediate)); + +  return MCDisassembler::Success; +} +  static DecodeStatus DecodeMSA128Mem(MCInst &Inst, unsigned Insn,                                      uint64_t Address, const void *Decoder) {    int Offset = SignExtend32<10>(fieldFromInstruction(Insn, 16, 10)); @@ -1220,8 +1390,11 @@ static DecodeStatus DecodeMemMMImm4(MCInst &Inst,          return MCDisassembler::Fail;        break;      case Mips::SB16_MM: +    case Mips::SB16_MMR6:      case Mips::SH16_MM: +    case Mips::SH16_MMR6:      case Mips::SW16_MM: +    case Mips::SW16_MMR6:        if (DecodeGPRMM16ZeroRegisterClass(Inst, Reg, Address, Decoder)              == MCDisassembler::Fail)          return MCDisassembler::Fail; @@ -1240,14 +1413,17 @@ static DecodeStatus DecodeMemMMImm4(MCInst &Inst,          Inst.addOperand(MCOperand::createImm(Offset));        break;      case Mips::SB16_MM: +    case Mips::SB16_MMR6:        Inst.addOperand(MCOperand::createImm(Offset));        break;      case Mips::LHU16_MM:      case Mips::SH16_MM: +    case Mips::SH16_MMR6:        Inst.addOperand(MCOperand::createImm(Offset << 1));        break;      case Mips::LW16_MM:      case Mips::SW16_MM: +    case Mips::SW16_MMR6:        Inst.addOperand(MCOperand::createImm(Offset << 2));        break;    } @@ -1291,7 +1467,16 @@ static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,                                                 unsigned Insn,                                                 uint64_t Address,                                                 const void *Decoder) { -  int Offset = SignExtend32<4>(Insn & 0xf); +  int Offset; +  switch (Inst.getOpcode()) { +  case Mips::LWM16_MMR6: +  case Mips::SWM16_MMR6: +    Offset = fieldFromInstruction(Insn, 4, 4); +    break; +  default: +    Offset = SignExtend32<4>(Insn & 0xf); +    break; +  }    if (DecodeRegListOperand16(Inst, Insn, Address, Decoder)        == MCDisassembler::Fail) @@ -1303,6 +1488,27 @@ static DecodeStatus DecodeMemMMReglistImm4Lsl2(MCInst &Inst,    return MCDisassembler::Success;  } +static DecodeStatus DecodeMemMMImm9(MCInst &Inst, +                                    unsigned Insn, +                                    uint64_t Address, +                                    const void *Decoder) { +  int Offset = SignExtend32<9>(Insn & 0x1ff); +  unsigned Reg = fieldFromInstruction(Insn, 21, 5); +  unsigned Base = fieldFromInstruction(Insn, 16, 5); + +  Reg = getReg(Decoder, Mips::GPR32RegClassID, Reg); +  Base = getReg(Decoder, Mips::GPR32RegClassID, Base); + +  if (Inst.getOpcode() == Mips::SCE_MM) +    Inst.addOperand(MCOperand::createReg(Reg)); + +  Inst.addOperand(MCOperand::createReg(Reg)); +  Inst.addOperand(MCOperand::createReg(Base)); +  Inst.addOperand(MCOperand::createImm(Offset)); + +  return MCDisassembler::Success; +} +  static DecodeStatus DecodeMemMMImm12(MCInst &Inst,                                       unsigned Insn,                                       uint64_t Address, @@ -1659,6 +1865,16 @@ static DecodeStatus DecodeBranchTargetMM(MCInst &Inst,    return MCDisassembler::Success;  } +static DecodeStatus DecodeBranchTarget26MM(MCInst &Inst, +  unsigned Offset, +  uint64_t Address, +  const void *Decoder) { +  int32_t BranchOffset = SignExtend32<26>(Offset) << 1; + +  Inst.addOperand(MCOperand::createImm(BranchOffset)); +  return MCDisassembler::Success; +} +  static DecodeStatus DecodeJumpTargetMM(MCInst &Inst,                                         unsigned Insn,                                         uint64_t Address, @@ -1700,6 +1916,14 @@ static DecodeStatus DecodeLiSimm7(MCInst &Inst,    return MCDisassembler::Success;  } +static DecodeStatus DecodePOOL16BEncodedField(MCInst &Inst, +                                              unsigned Value, +                                              uint64_t Address, +                                              const void *Decoder) { +  Inst.addOperand(MCOperand::createImm(Value == 0x0 ? 8 : Value)); +  return MCDisassembler::Success; +} +  static DecodeStatus DecodeSimm4(MCInst &Inst,                                  unsigned Value,                                  uint64_t Address, @@ -1716,12 +1940,12 @@ static DecodeStatus DecodeSimm16(MCInst &Inst,    return MCDisassembler::Success;  } -static DecodeStatus DecodeLSAImm(MCInst &Inst, -                                 unsigned Insn, -                                 uint64_t Address, -                                 const void *Decoder) { -  // We add one to the immediate field as it was encoded as 'imm - 1'. -  Inst.addOperand(MCOperand::createImm(Insn + 1)); +template <unsigned Bits, int Offset> +static DecodeStatus DecodeUImmWithOffset(MCInst &Inst, unsigned Value, +                                         uint64_t Address, +                                         const void *Decoder) { +  Value &= ((1 << Bits) - 1); +  Inst.addOperand(MCOperand::createImm(Value + Offset));    return MCDisassembler::Success;  } @@ -1736,15 +1960,6 @@ static DecodeStatus DecodeInsSize(MCInst &Inst,    return MCDisassembler::Success;  } -static DecodeStatus DecodeExtSize(MCInst &Inst, -                                  unsigned Insn, -                                  uint64_t Address, -                                  const void *Decoder) { -  int Size = (int) Insn  + 1; -  Inst.addOperand(MCOperand::createImm(SignExtend32<16>(Size))); -  return MCDisassembler::Success; -} -  static DecodeStatus DecodeSimm19Lsl2(MCInst &Inst, unsigned Insn,                                       uint64_t Address, const void *Decoder) {    Inst.addOperand(MCOperand::createImm(SignExtend32<19>(Insn) * 4)); @@ -1792,15 +2007,21 @@ static DecodeStatus DecodeRegListOperand(MCInst &Inst,                                           uint64_t Address,                                           const void *Decoder) {    unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3, Mips::S4, Mips::S5, -                     Mips::S6, Mips::FP}; +                     Mips::S6, Mips::S7, Mips::FP};    unsigned RegNum;    unsigned RegLst = fieldFromInstruction(Insn, 21, 5); +    // Empty register lists are not allowed.    if (RegLst == 0)      return MCDisassembler::Fail;    RegNum = RegLst & 0xf; + +  // RegLst values 10-15, and 26-31 are reserved. +  if (RegNum > 9) +    return MCDisassembler::Fail; +    for (unsigned i = 0; i < RegNum; i++)      Inst.addOperand(MCOperand::createReg(Regs[i])); @@ -1814,7 +2035,16 @@ static DecodeStatus DecodeRegListOperand16(MCInst &Inst, unsigned Insn,                                             uint64_t Address,                                             const void *Decoder) {    unsigned Regs[] = {Mips::S0, Mips::S1, Mips::S2, Mips::S3}; -  unsigned RegLst = fieldFromInstruction(Insn, 4, 2); +  unsigned RegLst; +  switch(Inst.getOpcode()) { +  default: +    RegLst = fieldFromInstruction(Insn, 4, 2); +    break; +  case Mips::LWM16_MMR6: +  case Mips::SWM16_MMR6: +    RegLst = fieldFromInstruction(Insn, 8, 2); +    break; +  }    unsigned RegNum = RegLst & 0x3;    for (unsigned i = 0; i <= RegNum; i++) | 
