| Index: src/mips/disasm-mips.cc
 | 
| diff --git a/src/mips/disasm-mips.cc b/src/mips/disasm-mips.cc
 | 
| index 381e2f14474e951aa49576f42ab048af8b63ecd2..73169ca00f732d9489384067ccdf5de87a4ac3b1 100644
 | 
| --- a/src/mips/disasm-mips.cc
 | 
| +++ b/src/mips/disasm-mips.cc
 | 
| @@ -81,13 +81,20 @@ class Decoder {
 | 
|    void PrintSs2(Instruction* instr);
 | 
|    void PrintBc(Instruction* instr);
 | 
|    void PrintCc(Instruction* instr);
 | 
| +  void PrintBp2(Instruction* instr);
 | 
|    void PrintFunction(Instruction* instr);
 | 
|    void PrintSecondaryField(Instruction* instr);
 | 
|    void PrintUImm16(Instruction* instr);
 | 
|    void PrintSImm16(Instruction* instr);
 | 
|    void PrintXImm16(Instruction* instr);
 | 
| +  void PrintXImm18(Instruction* instr);
 | 
| +  void PrintSImm18(Instruction* instr);
 | 
| +  void PrintXImm19(Instruction* instr);
 | 
| +  void PrintSImm19(Instruction* instr);
 | 
|    void PrintXImm21(Instruction* instr);
 | 
| +  void PrintSImm21(Instruction* instr);
 | 
|    void PrintXImm26(Instruction* instr);
 | 
| +  void PrintSImm26(Instruction* instr);
 | 
|    void PrintCode(Instruction* instr);   // For break and trap instructions.
 | 
|    void PrintFormat(Instruction* instr);  // For floating format postfix.
 | 
|    // Printing of instruction name.
 | 
| @@ -236,6 +243,12 @@ void Decoder::PrintCc(Instruction* instr) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| +void Decoder::PrintBp2(Instruction* instr) {
 | 
| +  int bp2 = instr->Bp2Value();
 | 
| +  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", bp2);
 | 
| +}
 | 
| +
 | 
| +
 | 
|  // Print 16-bit unsigned immediate value.
 | 
|  void Decoder::PrintUImm16(Instruction* instr) {
 | 
|    int32_t imm = instr->Imm16Value();
 | 
| @@ -257,6 +270,38 @@ void Decoder::PrintXImm16(Instruction* instr) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| +// Print 18-bit signed immediate value.
 | 
| +void Decoder::PrintSImm18(Instruction* instr) {
 | 
| +  int32_t imm =
 | 
| +      ((instr->Imm18Value()) << (32 - kImm18Bits)) >> (32 - kImm18Bits);
 | 
| +  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
 | 
| +}
 | 
| +
 | 
| +
 | 
| +// Print 18-bit hexa immediate value.
 | 
| +void Decoder::PrintXImm18(Instruction* instr) {
 | 
| +  int32_t imm = instr->Imm18Value();
 | 
| +  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
 | 
| +}
 | 
| +
 | 
| +
 | 
| +// Print 19-bit hexa immediate value.
 | 
| +void Decoder::PrintXImm19(Instruction* instr) {
 | 
| +  int32_t imm = instr->Imm19Value();
 | 
| +  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
 | 
| +}
 | 
| +
 | 
| +
 | 
| +// Print 19-bit signed immediate value.
 | 
| +void Decoder::PrintSImm19(Instruction* instr) {
 | 
| +  int32_t imm19 = instr->Imm19Value();
 | 
| +  // set sign
 | 
| +  imm19 <<= (32 - kImm19Bits);
 | 
| +  imm19 >>= (32 - kImm19Bits);
 | 
| +  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm19);
 | 
| +}
 | 
| +
 | 
| +
 | 
|  // Print 21-bit immediate value.
 | 
|  void Decoder::PrintXImm21(Instruction* instr) {
 | 
|    uint32_t imm = instr->Imm21Value();
 | 
| @@ -264,13 +309,33 @@ void Decoder::PrintXImm21(Instruction* instr) {
 | 
|  }
 | 
|  
 | 
|  
 | 
| -// Print 26-bit immediate value.
 | 
| +// Print 21-bit signed immediate value.
 | 
| +void Decoder::PrintSImm21(Instruction* instr) {
 | 
| +  int32_t imm21 = instr->Imm21Value();
 | 
| +  // set sign
 | 
| +  imm21 <<= (32 - kImm21Bits);
 | 
| +  imm21 >>= (32 - kImm21Bits);
 | 
| +  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm21);
 | 
| +}
 | 
| +
 | 
| +
 | 
| +// Print 26-bit hex immediate value.
 | 
|  void Decoder::PrintXImm26(Instruction* instr) {
 | 
|    uint32_t imm = instr->Imm26Value() << kImmFieldShift;
 | 
|    out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm);
 | 
|  }
 | 
|  
 | 
|  
 | 
| +// Print 26-bit signed immediate value.
 | 
| +void Decoder::PrintSImm26(Instruction* instr) {
 | 
| +  int32_t imm26 = instr->Imm26Value();
 | 
| +  // set sign
 | 
| +  imm26 <<= (32 - kImm26Bits);
 | 
| +  imm26 >>= (32 - kImm26Bits);
 | 
| +  out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm26);
 | 
| +}
 | 
| +
 | 
| +
 | 
|  // Print 26-bit immediate value.
 | 
|  void Decoder::PrintCode(Instruction* instr) {
 | 
|    if (instr->OpcodeFieldRaw() != SPECIAL)
 | 
| @@ -389,25 +454,75 @@ int Decoder::FormatOption(Instruction* instr, const char* format) {
 | 
|      }
 | 
|      case 'i': {   // 'imm16u or 'imm26.
 | 
|        if (format[3] == '1') {
 | 
| -        DCHECK(STRING_STARTS_WITH(format, "imm16"));
 | 
| -        if (format[5] == 's') {
 | 
| -          DCHECK(STRING_STARTS_WITH(format, "imm16s"));
 | 
| -          PrintSImm16(instr);
 | 
| -        } else if (format[5] == 'u') {
 | 
| -          DCHECK(STRING_STARTS_WITH(format, "imm16u"));
 | 
| -          PrintSImm16(instr);
 | 
| -        } else {
 | 
| -          DCHECK(STRING_STARTS_WITH(format, "imm16x"));
 | 
| -          PrintXImm16(instr);
 | 
| +        if (format[4] == '6') {
 | 
| +          DCHECK(STRING_STARTS_WITH(format, "imm16"));
 | 
| +          switch (format[5]) {
 | 
| +            case 's':
 | 
| +              DCHECK(STRING_STARTS_WITH(format, "imm16s"));
 | 
| +              PrintSImm16(instr);
 | 
| +              break;
 | 
| +            case 'u':
 | 
| +              DCHECK(STRING_STARTS_WITH(format, "imm16u"));
 | 
| +              PrintSImm16(instr);
 | 
| +              break;
 | 
| +            case 'x':
 | 
| +              DCHECK(STRING_STARTS_WITH(format, "imm16x"));
 | 
| +              PrintXImm16(instr);
 | 
| +              break;
 | 
| +          }
 | 
| +          return 6;
 | 
| +        } else if (format[4] == '8') {
 | 
| +          DCHECK(STRING_STARTS_WITH(format, "imm18"));
 | 
| +          switch (format[5]) {
 | 
| +            case 's':
 | 
| +              DCHECK(STRING_STARTS_WITH(format, "imm18s"));
 | 
| +              PrintSImm18(instr);
 | 
| +              break;
 | 
| +            case 'x':
 | 
| +              DCHECK(STRING_STARTS_WITH(format, "imm18x"));
 | 
| +              PrintXImm18(instr);
 | 
| +              break;
 | 
| +          }
 | 
| +          return 6;
 | 
| +        } else if (format[4] == '9') {
 | 
| +          DCHECK(STRING_STARTS_WITH(format, "imm19"));
 | 
| +          switch (format[5]) {
 | 
| +            case 's':
 | 
| +              DCHECK(STRING_STARTS_WITH(format, "imm19s"));
 | 
| +              PrintSImm19(instr);
 | 
| +              break;
 | 
| +            case 'x':
 | 
| +              DCHECK(STRING_STARTS_WITH(format, "imm19x"));
 | 
| +              PrintXImm19(instr);
 | 
| +              break;
 | 
| +          }
 | 
| +          return 6;
 | 
|          }
 | 
| -        return 6;
 | 
|        } else if (format[3] == '2' && format[4] == '1') {
 | 
| -        DCHECK(STRING_STARTS_WITH(format, "imm21x"));
 | 
| -        PrintXImm21(instr);
 | 
| +        DCHECK(STRING_STARTS_WITH(format, "imm21"));
 | 
| +        switch (format[5]) {
 | 
| +          case 's':
 | 
| +            DCHECK(STRING_STARTS_WITH(format, "imm21s"));
 | 
| +            PrintSImm21(instr);
 | 
| +            break;
 | 
| +          case 'x':
 | 
| +            DCHECK(STRING_STARTS_WITH(format, "imm21x"));
 | 
| +            PrintXImm21(instr);
 | 
| +            break;
 | 
| +        }
 | 
|          return 6;
 | 
|        } else if (format[3] == '2' && format[4] == '6') {
 | 
| -        DCHECK(STRING_STARTS_WITH(format, "imm26x"));
 | 
| -        PrintXImm26(instr);
 | 
| +        DCHECK(STRING_STARTS_WITH(format, "imm26"));
 | 
| +        switch (format[5]) {
 | 
| +          case 's':
 | 
| +            DCHECK(STRING_STARTS_WITH(format, "imm26s"));
 | 
| +            PrintSImm26(instr);
 | 
| +            break;
 | 
| +          case 'x':
 | 
| +            DCHECK(STRING_STARTS_WITH(format, "imm26x"));
 | 
| +            PrintXImm26(instr);
 | 
| +            break;
 | 
| +        }
 | 
|          return 6;
 | 
|        }
 | 
|      }
 | 
| @@ -442,10 +557,23 @@ int Decoder::FormatOption(Instruction* instr, const char* format) {
 | 
|          }
 | 
|        }
 | 
|      }
 | 
| -    case 'b': {   // 'bc - Special for bc1 cc field.
 | 
| -      DCHECK(STRING_STARTS_WITH(format, "bc"));
 | 
| -      PrintBc(instr);
 | 
| -      return 2;
 | 
| +    case 'b': {
 | 
| +      switch (format[1]) {
 | 
| +        case 'c': {  // 'bc - Special for bc1 cc field.
 | 
| +          DCHECK(STRING_STARTS_WITH(format, "bc"));
 | 
| +          PrintBc(instr);
 | 
| +          return 2;
 | 
| +        }
 | 
| +        case 'p': {
 | 
| +          switch (format[2]) {
 | 
| +            case '2': {  // 'bp2
 | 
| +              DCHECK(STRING_STARTS_WITH(format, "bp2"));
 | 
| +              PrintBp2(instr);
 | 
| +              return 3;
 | 
| +            }
 | 
| +          }
 | 
| +        }
 | 
| +      }
 | 
|      }
 | 
|      case 'C': {   // 'Cc - Special for c.xx.d cc field.
 | 
|        DCHECK(STRING_STARTS_WITH(format, "Cc"));
 | 
| @@ -941,7 +1069,7 @@ void Decoder::DecodeTypeRegisterSPECIAL2(Instruction* instr) {
 | 
|  void Decoder::DecodeTypeRegisterSPECIAL3(Instruction* instr) {
 | 
|    switch (instr->FunctionFieldRaw()) {
 | 
|      case INS: {
 | 
| -      if (IsMipsArchVariant(kMips32r2)) {
 | 
| +      if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
 | 
|          Format(instr, "ins     'rt, 'rs, 'sa, 'ss2");
 | 
|        } else {
 | 
|          Unknown(instr);
 | 
| @@ -949,18 +1077,45 @@ void Decoder::DecodeTypeRegisterSPECIAL3(Instruction* instr) {
 | 
|        break;
 | 
|      }
 | 
|      case EXT: {
 | 
| -      if (IsMipsArchVariant(kMips32r2)) {
 | 
| +      if (IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6)) {
 | 
|          Format(instr, "ext     'rt, 'rs, 'sa, 'ss1");
 | 
|        } else {
 | 
|          Unknown(instr);
 | 
|        }
 | 
|        break;
 | 
|      }
 | 
| -    case BITSWAP: {
 | 
| -      if (IsMipsArchVariant(kMips32r6)) {
 | 
| -        Format(instr, "bitswap 'rd, 'rt");
 | 
| -      } else {
 | 
| -        Unknown(instr);
 | 
| +    case BSHFL: {
 | 
| +      int sa = instr->SaFieldRaw() >> kSaShift;
 | 
| +      switch (sa) {
 | 
| +        case BITSWAP: {
 | 
| +          if (IsMipsArchVariant(kMips32r6)) {
 | 
| +            Format(instr, "bitswap 'rd, 'rt");
 | 
| +          } else {
 | 
| +            Unknown(instr);
 | 
| +          }
 | 
| +          break;
 | 
| +        }
 | 
| +        case SEB:
 | 
| +        case SEH:
 | 
| +        case WSBH:
 | 
| +          UNREACHABLE();
 | 
| +          break;
 | 
| +        default: {
 | 
| +          sa >>= kBp2Bits;
 | 
| +          switch (sa) {
 | 
| +            case ALIGN: {
 | 
| +              if (IsMipsArchVariant(kMips32r6)) {
 | 
| +                Format(instr, "align  'rd, 'rs, 'rt, 'bp2");
 | 
| +              } else {
 | 
| +                Unknown(instr);
 | 
| +              }
 | 
| +              break;
 | 
| +            }
 | 
| +            default:
 | 
| +              UNREACHABLE();
 | 
| +              break;
 | 
| +          }
 | 
| +        }
 | 
|        }
 | 
|        break;
 | 
|      }
 | 
| @@ -1087,6 +1242,12 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) {
 | 
|      case BEQ:
 | 
|        Format(instr, "beq     'rs, 'rt, 'imm16u");
 | 
|        break;
 | 
| +    case BC:
 | 
| +      Format(instr, "bc      'imm26s");
 | 
| +      break;
 | 
| +    case BALC:
 | 
| +      Format(instr, "balc    'imm26s");
 | 
| +      break;
 | 
|      case BNE:
 | 
|        Format(instr, "bne     'rs, 'rt, 'imm16u");
 | 
|        break;
 | 
| @@ -1152,13 +1313,17 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) {
 | 
|          UNREACHABLE();
 | 
|        }
 | 
|        break;
 | 
| -    case BEQZC:
 | 
| -      if (instr->RsFieldRaw() != 0) {
 | 
| -        Format(instr, "beqzc   'rs, 'imm21x");
 | 
| +    case POP66:
 | 
| +      if (instr->RsValue() == JIC) {
 | 
| +        Format(instr, "jic     'rt, 'imm16s");
 | 
| +      } else {
 | 
| +        Format(instr, "beqzc   'rs, 'imm21s");
 | 
|        }
 | 
|        break;
 | 
| -    case BNEZC:
 | 
| -      if (instr->RsFieldRaw() != 0) {
 | 
| +    case POP76:
 | 
| +      if (instr->RsValue() == JIALC) {
 | 
| +        Format(instr, "jialc   'rt, 'imm16x");
 | 
| +      } else {
 | 
|          Format(instr, "bnezc   'rs, 'imm21x");
 | 
|        }
 | 
|        break;
 | 
| @@ -1270,6 +1435,35 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) {
 | 
|      case SDC1:
 | 
|        Format(instr, "sdc1    'ft, 'imm16s('rs)");
 | 
|        break;
 | 
| +    case PCREL: {
 | 
| +      int32_t imm21 = instr->Imm21Value();
 | 
| +      // rt field: 5-bits checking
 | 
| +      uint8_t rt = (imm21 >> kImm16Bits);
 | 
| +      switch (rt) {
 | 
| +        case ALUIPC:
 | 
| +          Format(instr, "aluipc  'rs, 'imm16s");
 | 
| +          break;
 | 
| +        case AUIPC:
 | 
| +          Format(instr, "auipc   'rs, 'imm16s");
 | 
| +          break;
 | 
| +        default: {
 | 
| +          // rt field: checking of the most significant 2-bits
 | 
| +          rt = (imm21 >> kImm19Bits);
 | 
| +          switch (rt) {
 | 
| +            case LWPC:
 | 
| +              Format(instr, "lwpc    'rs, 'imm19s");
 | 
| +              break;
 | 
| +            case ADDIUPC:
 | 
| +              Format(instr, "addiupc 'rs, 'imm19s");
 | 
| +              break;
 | 
| +            default:
 | 
| +              UNREACHABLE();
 | 
| +              break;
 | 
| +          }
 | 
| +        }
 | 
| +      }
 | 
| +      break;
 | 
| +    }
 | 
|      default:
 | 
|        printf("a 0x%x \n", instr->OpcodeFieldRaw());
 | 
|        UNREACHABLE();
 | 
| 
 |