Chromium Code Reviews| Index: src/mips64/disasm-mips64.cc |
| diff --git a/src/mips64/disasm-mips64.cc b/src/mips64/disasm-mips64.cc |
| index 9b9cd348f754bfa9d63b5d0824b18ebab5098528..b76fc8fa8401d6ca2b081eaace3c81a5909dfad9 100644 |
| --- a/src/mips64/disasm-mips64.cc |
| +++ b/src/mips64/disasm-mips64.cc |
| @@ -86,6 +86,7 @@ class Decoder { |
| void PrintUImm16(Instruction* instr); |
| void PrintSImm16(Instruction* instr); |
| void PrintXImm16(Instruction* instr); |
| + void PrintXImm21(Instruction* instr); |
| void PrintXImm26(Instruction* instr); |
| void PrintCode(Instruction* instr); // For break and trap instructions. |
| // Printing of instruction name. |
| @@ -247,6 +248,13 @@ void Decoder::PrintXImm16(Instruction* instr) { |
| } |
| +// Print 21-bit immediate value. |
| +void Decoder::PrintXImm21(Instruction* instr) { |
| + uint32_t imm = instr->Imm21Value(); |
| + out_buffer_pos_ += SNPrintF(out_buffer_ + out_buffer_pos_, "0x%x", imm); |
| +} |
| + |
| + |
| // Print 26-bit immediate value. |
| void Decoder::PrintXImm26(Instruction* instr) { |
| uint32_t imm = instr->Imm26Value() << kImmFieldShift; |
| @@ -361,7 +369,11 @@ int Decoder::FormatOption(Instruction* instr, const char* format) { |
| PrintXImm16(instr); |
| } |
| return 6; |
| - } else { |
| + } else if (format[3] == '2' && format[4] == '1') { |
| + ASSERT(STRING_STARTS_WITH(format, "imm21x")); |
| + PrintXImm21(instr); |
| + return 6; |
| + } else if (format[3] == '2' && format[4] == '6') { |
| ASSERT(STRING_STARTS_WITH(format, "imm26x")); |
| PrintXImm26(instr); |
| return 6; |
| @@ -466,9 +478,6 @@ int Decoder::DecodeTypeRegister(Instruction* instr) { |
| switch (instr->OpcodeFieldRaw()) { |
| case COP1: // Coprocessor instructions. |
| switch (instr->RsFieldRaw()) { |
| - case BC1: // bc1 handled in DecodeTypeImmediate. |
| - UNREACHABLE(); |
| - break; |
| case MFC1: |
| Format(instr, "mfc1 'rt, 'fs"); |
| break; |
| @@ -582,14 +591,8 @@ int Decoder::DecodeTypeRegister(Instruction* instr) { |
| break; |
| } |
| break; |
| - case S: |
| - UNIMPLEMENTED_MIPS(); |
| - break; |
| case W: |
| switch (instr->FunctionFieldRaw()) { |
| - case CVT_S_W: // Convert word to float (single). |
| - Format(instr, "cvt.s.w 'fd, 'fs"); |
| - break; |
| case CVT_D_W: // Convert word to double. |
| Format(instr, "cvt.d.w 'fd, 'fs"); |
| break; |
| @@ -605,13 +608,40 @@ int Decoder::DecodeTypeRegister(Instruction* instr) { |
| case CVT_S_L: |
| Format(instr, "cvt.s.l 'fd, 'fs"); |
| break; |
| + case CMP_UN: |
| + Format(instr, "cmp.un.d 'fd, 'fs, 'ft"); |
| + break; |
| + case CMP_EQ: |
| + Format(instr, "cmp.eq.d 'fd, 'fs, 'ft"); |
| + break; |
| + case CMP_UEQ: |
| + Format(instr, "cmp.ueq.d 'fd, 'fs, 'ft"); |
| + break; |
| + case CMP_LT: |
| + Format(instr, "cmp.lt.d 'fd, 'fs, 'ft"); |
| + break; |
| + case CMP_ULT: |
| + Format(instr, "cmp.ult.d 'fd, 'fs, 'ft"); |
| + break; |
| + case CMP_LE: |
| + Format(instr, "cmp.le.d 'fd, 'fs, 'ft"); |
| + break; |
| + case CMP_ULE: |
| + Format(instr, "cmp.ule.d 'fd, 'fs, 'ft"); |
| + break; |
| + case CMP_OR: |
| + Format(instr, "cmp.or.d 'fd, 'fs, 'ft"); |
| + break; |
| + case CMP_UNE: |
| + Format(instr, "cmp.une.d 'fd, 'fs, 'ft"); |
| + break; |
| + case CMP_NE: |
| + Format(instr, "cmp.ne.d 'fd, 'fs, 'ft"); |
| + break; |
| default: |
| UNREACHABLE(); |
| } |
| break; |
| - case PS: |
| - UNIMPLEMENTED_MIPS(); |
| - break; |
| default: |
| UNREACHABLE(); |
| } |
| @@ -634,13 +664,24 @@ int Decoder::DecodeTypeRegister(Instruction* instr) { |
| Format(instr, "jalr 'rs"); |
| break; |
| case SLL: |
| - if ( 0x0 == static_cast<int>(instr->InstructionBits())) |
| + if (0x0 == static_cast<int>(instr->InstructionBits())) |
| Format(instr, "nop"); |
| else |
| Format(instr, "sll 'rd, 'rt, 'sa"); |
| break; |
| case DSLL: |
| - Format(instr, "dsll 'rd, 'rt, 'sa"); |
| + Format(instr, "dsll 'rd, 'rt, 'sa"); |
| + break; |
| + case D_MUL_MUH: // Eqauls to DMUL. |
|
paul.l...
2014/07/29 14:58:04
nit: Eqauls -> Equals
dusmil.imgtec
2014/07/29 17:39:12
Done.
|
| + if (kArchVariant != kMips64r6) { |
| + Format(instr, "dmult 'rs, 'rt"); |
| + } else { |
| + if (instr->SaValue() == MUL_OP) { |
| + Format(instr, "dmul 'rd, 'rs, 'rt"); |
| + } else { |
| + Format(instr, "dmuh 'rd, 'rs, 'rt"); |
| + } |
| + } |
| break; |
| case DSLL32: |
| Format(instr, "dsll32 'rd, 'rt, 'sa"); |
| @@ -714,34 +755,98 @@ int Decoder::DecodeTypeRegister(Instruction* instr) { |
| Format(instr, "dsrav 'rd, 'rt, 'rs"); |
| break; |
| case MFHI: |
| - Format(instr, "mfhi 'rd"); |
| + if (instr->Bits(25, 16) == 0) { |
| + Format(instr, "mfhi 'rd"); |
| + } else { |
| + if ((instr->FunctionFieldRaw() == CLZ_R6) |
| + && (instr->FdValue() == 1)) { |
| + Format(instr, "clz 'rd, 'rs"); |
| + } else if ((instr->FunctionFieldRaw() == CLO_R6) |
| + && (instr->FdValue() == 1)) { |
| + Format(instr, "clo 'rd, 'rs"); |
| + } |
| + } |
| break; |
| case MFLO: |
| Format(instr, "mflo 'rd"); |
| break; |
| - case MULT: |
| - Format(instr, "mult 'rs, 'rt"); |
| - break; |
| - case DMULT: |
| - Format(instr, "dmult 'rs, 'rt"); |
| + case D_MUL_MUH_U: // Equals to DMULTU. |
| + if (kArchVariant != kMips64r6) { |
| + Format(instr, "dmultu 'rs, 'rt"); |
| + } else { |
| + if (instr->SaValue() == MUL_OP) { |
| + Format(instr, "dmulu 'rd, 'rs, 'rt"); |
| + } else { |
| + Format(instr, "dmuhu 'rd, 'rs, 'rt"); |
| + } |
| + } |
| break; |
| - case MULTU: |
| - Format(instr, "multu 'rs, 'rt"); |
| + case MULT: // @Mips64r6 == MUL_MUH. |
| + if (kArchVariant != kMips64r6) { |
| + Format(instr, "mult 'rs, 'rt"); |
| + } else { |
| + if (instr->SaValue() == MUL_OP) { |
| + Format(instr, "mul 'rd, 'rs, 'rt"); |
| + } else { |
| + Format(instr, "muh 'rd, 'rs, 'rt"); |
| + } |
| + } |
| break; |
| - case DMULTU: |
| - Format(instr, "dmultu 'rs, 'rt"); |
| + case MULTU: // @Mips64r6 == MUL_MUH_U. |
| + if (kArchVariant != kMips64r6) { |
| + Format(instr, "multu 'rs, 'rt"); |
| + } else { |
| + if (instr->SaValue() == MUL_OP) { |
| + Format(instr, "mulu 'rd, 'rs, 'rt"); |
| + } else { |
| + Format(instr, "muhu 'rd, 'rs, 'rt"); |
| + } |
| + } |
| + |
| break; |
| - case DIV: |
| - Format(instr, "div 'rs, 'rt"); |
| + case DIV: // @Mips64r6 == DIV_MOD. |
| + if (kArchVariant != kMips64r6) { |
| + Format(instr, "div 'rs, 'rt"); |
| + } else { |
| + if (instr->SaValue() == DIV_OP) { |
| + Format(instr, "div 'rd, 'rs, 'rt"); |
| + } else { |
| + Format(instr, "mod 'rd, 'rs, 'rt"); |
| + } |
| + } |
| break; |
| - case DDIV: |
| - Format(instr, "ddiv 'rs, 'rt"); |
| + case DDIV: // @Mips64r6 == D_DIV_MOD. |
| + if (kArchVariant != kMips64r6) { |
| + Format(instr, "ddiv 'rs, 'rt"); |
| + } else { |
| + if (instr->SaValue() == DIV_OP) { |
| + Format(instr, "ddiv 'rd, 'rs, 'rt"); |
| + } else { |
| + Format(instr, "dmod 'rd, 'rs, 'rt"); |
| + } |
| + } |
| break; |
| - case DIVU: |
| - Format(instr, "divu 'rs, 'rt"); |
| + case DIVU: // @Mips64r6 == DIV_MOD_U. |
| + if (kArchVariant != kMips64r6) { |
| + Format(instr, "divu 'rs, 'rt"); |
| + } else { |
| + if (instr->SaValue() == DIV_OP) { |
| + Format(instr, "divu 'rd, 'rs, 'rt"); |
| + } else { |
| + Format(instr, "modu 'rd, 'rs, 'rt"); |
| + } |
| + } |
| break; |
| - case DDIVU: |
| - Format(instr, "ddivu 'rs, 'rt"); |
| + case DDIVU: // @Mips64r6 == D_DIV_MOD_U. |
| + if (kArchVariant != kMips64r6) { |
| + Format(instr, "ddivu 'rs, 'rt"); |
| + } else { |
| + if (instr->SaValue() == DIV_OP) { |
| + Format(instr, "ddivu 'rd, 'rs, 'rt"); |
| + } else { |
| + Format(instr, "dmodu 'rd, 'rs, 'rt"); |
| + } |
| + } |
| break; |
| case ADD: |
| Format(instr, "add 'rd, 'rs, 'rt"); |
| @@ -824,6 +929,12 @@ int Decoder::DecodeTypeRegister(Instruction* instr) { |
| Format(instr, "movf 'rd, 'rs, 'bc"); |
| } |
| break; |
| + case SELEQZ_S: |
| + Format(instr, "seleqz 'rd, 'rs, 'rt"); |
| + break; |
| + case SELNEZ_S: |
| + Format(instr, "selnez 'rd, 'rs, 'rt"); |
| + break; |
| default: |
| UNREACHABLE(); |
| } |
| @@ -834,7 +945,9 @@ int Decoder::DecodeTypeRegister(Instruction* instr) { |
| Format(instr, "mul 'rd, 'rs, 'rt"); |
| break; |
| case CLZ: |
| - Format(instr, "clz 'rd, 'rs"); |
| + if (kArchVariant != kMips64r6) { |
| + Format(instr, "clz 'rd, 'rs"); |
| + } |
| break; |
| default: |
| UNREACHABLE(); |
| @@ -843,19 +956,11 @@ int Decoder::DecodeTypeRegister(Instruction* instr) { |
| case SPECIAL3: |
| switch (instr->FunctionFieldRaw()) { |
| case INS: { |
| - if (kArchVariant == kMips64r2) { |
| - Format(instr, "ins 'rt, 'rs, 'sa, 'ss2"); |
| - } else { |
| - Unknown(instr); |
| - } |
| + Format(instr, "ins 'rt, 'rs, 'sa, 'ss2"); |
| break; |
| } |
| case EXT: { |
| - if (kArchVariant == kMips64r2) { |
| - Format(instr, "ext 'rt, 'rs, 'sa, 'ss1"); |
| - } else { |
| - Unknown(instr); |
| - } |
| + Format(instr, "ext 'rt, 'rs, 'sa, 'ss1"); |
| break; |
| } |
| default: |
| @@ -871,7 +976,6 @@ int Decoder::DecodeTypeRegister(Instruction* instr) { |
| void Decoder::DecodeTypeImmediate(Instruction* instr) { |
| switch (instr->OpcodeFieldRaw()) { |
| - // ------------- REGIMM class. |
| case COP1: |
| switch (instr->RsFieldRaw()) { |
| case BC1: |
| @@ -881,10 +985,150 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) { |
| Format(instr, "bc1f 'bc, 'imm16u"); |
| } |
| break; |
| + case BC1EQZ: |
| + Format(instr, "bc1eqz 'ft, 'imm16u"); |
| + break; |
| + case BC1NEZ: |
| + Format(instr, "bc1nez 'ft, 'imm16u"); |
| + break; |
| + case W: // CMP.S instruction. |
| + switch (instr->FunctionValue()) { |
| + case CMP_AF: |
| + Format(instr, "cmp.af.S 'ft, 'fs, 'fd"); |
| + break; |
| + case CMP_UN: |
| + Format(instr, "cmp.un.S 'ft, 'fs, 'fd"); |
| + break; |
| + case CMP_EQ: |
| + Format(instr, "cmp.eq.S 'ft, 'fs, 'fd"); |
| + break; |
| + case CMP_UEQ: |
| + Format(instr, "cmp.ueq.S 'ft, 'fs, 'fd"); |
| + break; |
| + case CMP_LT: |
| + Format(instr, "cmp.lt.S 'ft, 'fs, 'fd"); |
| + break; |
| + case CMP_ULT: |
| + Format(instr, "cmp.ult.S 'ft, 'fs, 'fd"); |
| + break; |
| + case CMP_LE: |
| + Format(instr, "cmp.le.S 'ft, 'fs, 'fd"); |
| + break; |
| + case CMP_ULE: |
| + Format(instr, "cmp.ule.S 'ft, 'fs, 'fd"); |
| + break; |
| + case CMP_OR: |
| + Format(instr, "cmp.or.S 'ft, 'fs, 'fd"); |
| + break; |
| + case CMP_UNE: |
| + Format(instr, "cmp.une.S 'ft, 'fs, 'fd"); |
| + break; |
| + case CMP_NE: |
| + Format(instr, "cmp.ne.S 'ft, 'fs, 'fd"); |
| + break; |
| + default: |
| + UNREACHABLE(); |
| + } |
| + break; |
| + case L: // CMP.D instruction. |
| + switch (instr->FunctionValue()) { |
| + case CMP_AF: |
| + Format(instr, "cmp.af.D 'ft, 'fs, 'fd"); |
| + break; |
| + case CMP_UN: |
| + Format(instr, "cmp.un.D 'ft, 'fs, 'fd"); |
| + break; |
| + case CMP_EQ: |
| + Format(instr, "cmp.eq.D 'ft, 'fs, 'fd"); |
| + break; |
| + case CMP_UEQ: |
| + Format(instr, "cmp.ueq.D 'ft, 'fs, 'fd"); |
| + break; |
| + case CMP_LT: |
| + Format(instr, "cmp.lt.D 'ft, 'fs, 'fd"); |
| + break; |
| + case CMP_ULT: |
| + Format(instr, "cmp.ult.D 'ft, 'fs, 'fd"); |
| + break; |
| + case CMP_LE: |
| + Format(instr, "cmp.le.D 'ft, 'fs, 'fd"); |
| + break; |
| + case CMP_ULE: |
| + Format(instr, "cmp.ule.D 'ft, 'fs, 'fd"); |
| + break; |
| + case CMP_OR: |
| + Format(instr, "cmp.or.D 'ft, 'fs, 'fd"); |
| + break; |
| + case CMP_UNE: |
| + Format(instr, "cmp.une.D 'ft, 'fs, 'fd"); |
| + break; |
| + case CMP_NE: |
| + Format(instr, "cmp.ne.D 'ft, 'fs, 'fd"); |
| + break; |
| + default: |
| + UNREACHABLE(); |
| + } |
| + break; |
| + case S: |
| + switch (instr->FunctionValue()) { |
| + case SEL: |
| + Format(instr, "sel.S 'ft, 'fs, 'fd"); |
| + break; |
| + case SELEQZ_C: |
| + Format(instr, "seleqz.S 'ft, 'fs, 'fd"); |
| + break; |
| + case SELNEZ_C: |
| + Format(instr, "selnez.S 'ft, 'fs, 'fd"); |
| + break; |
| + case MIN: |
| + Format(instr, "min.S 'ft, 'fs, 'fd"); |
| + break; |
| + case MINA: |
| + Format(instr, "mina.S 'ft, 'fs, 'fd"); |
| + break; |
| + case MAX: |
| + Format(instr, "max.S 'ft, 'fs, 'fd"); |
| + break; |
| + case MAXA: |
| + Format(instr, "maxa.S 'ft, 'fs, 'fd"); |
| + break; |
| + default: |
| + UNREACHABLE(); |
| + } |
| + break; |
| + case D: |
| + switch (instr->FunctionValue()) { |
| + case SEL: |
| + Format(instr, "sel.D 'ft, 'fs, 'fd"); |
| + break; |
| + case SELEQZ_C: |
| + Format(instr, "seleqz.D 'ft, 'fs, 'fd"); |
| + break; |
| + case SELNEZ_C: |
| + Format(instr, "selnez.D 'ft, 'fs, 'fd"); |
| + break; |
| + case MIN: |
| + Format(instr, "min.D 'ft, 'fs, 'fd"); |
| + break; |
| + case MINA: |
| + Format(instr, "mina.D 'ft, 'fs, 'fd"); |
| + break; |
| + case MAX: |
| + Format(instr, "max.D 'ft, 'fs, 'fd"); |
| + break; |
| + case MAXA: |
| + Format(instr, "maxa.D 'ft, 'fs, 'fd"); |
| + break; |
| + default: |
| + UNREACHABLE(); |
| + } |
| + break; |
| default: |
| UNREACHABLE(); |
| } |
| + |
| break; // Case COP1. |
| + // ------------- REGIMM class. |
| case REGIMM: |
| switch (instr->RtFieldRaw()) { |
| case BLTZ: |
| @@ -899,6 +1143,15 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) { |
| case BGEZAL: |
| Format(instr, "bgezal 'rs, 'imm16u"); |
| break; |
| + case BGEZALL: |
| + Format(instr, "bgezall 'rs, 'imm16u"); |
| + break; |
| + case DAHI: |
| + Format(instr, "dahi 'rs, 'imm16u"); |
| + break; |
| + case DATI: |
| + Format(instr, "dati 'rs, 'imm16u"); |
| + break; |
| default: |
| UNREACHABLE(); |
| } |
| @@ -911,17 +1164,105 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) { |
| Format(instr, "bne 'rs, 'rt, 'imm16u"); |
| break; |
| case BLEZ: |
| - Format(instr, "blez 'rs, 'imm16u"); |
| + if ((instr->RtFieldRaw() == 0) |
| + && (instr->RsFieldRaw() != 0)) { |
| + Format(instr, "blez 'rs, 'imm16u"); |
| + } else if ((instr->RtFieldRaw() != instr->RsFieldRaw()) |
| + && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) { |
| + Format(instr, "bgeuc 'rs, 'rt, 'imm16u"); |
| + } else if ((instr->RtFieldRaw() == instr->RsFieldRaw()) |
| + && (instr->RtFieldRaw() != 0)) { |
| + Format(instr, "bgezalc 'rs, 'imm16u"); |
| + } else if ((instr->RsFieldRaw() == 0) |
| + && (instr->RtFieldRaw() != 0)) { |
| + Format(instr, "blezalc 'rs, 'imm16u"); |
| + } else { |
| + UNREACHABLE(); |
| + } |
| break; |
| case BGTZ: |
| - Format(instr, "bgtz 'rs, 'imm16u"); |
| + if ((instr->RtFieldRaw() == 0) |
| + && (instr->RsFieldRaw() != 0)) { |
| + Format(instr, "bgtz 'rs, 'imm16u"); |
| + } else if ((instr->RtFieldRaw() != instr->RsFieldRaw()) |
| + && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) { |
| + Format(instr, "bltuc 'rs, 'rt, 'imm16u"); |
| + } else if ((instr->RtFieldRaw() == instr->RsFieldRaw()) |
| + && (instr->RtFieldRaw() != 0)) { |
| + Format(instr, "bltzalc 'rt, 'imm16u"); |
| + } else if ((instr->RsFieldRaw() == 0) |
| + && (instr->RtFieldRaw() != 0)) { |
| + Format(instr, "bgtzalc 'rt, 'imm16u"); |
| + } else { |
| + UNREACHABLE(); |
| + } |
| + break; |
| + case BLEZL: |
| + if ((instr->RtFieldRaw() == instr->RsFieldRaw()) |
| + && (instr->RtFieldRaw() != 0)) { |
| + Format(instr, "bgezc 'rt, 'imm16u"); |
| + } else if ((instr->RtFieldRaw() != instr->RsFieldRaw()) |
| + && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) { |
| + Format(instr, "bgec 'rs, 'rt, 'imm16u"); |
| + } else if ((instr->RsFieldRaw() == 0) |
| + && (instr->RtFieldRaw() != 0)) { |
| + Format(instr, "blezc 'rt, 'imm16u"); |
| + } else { |
| + UNREACHABLE(); |
| + } |
| + break; |
| + case BGTZL: |
| + if ((instr->RtFieldRaw() == instr->RsFieldRaw()) |
| + && (instr->RtFieldRaw() != 0)) { |
| + Format(instr, "bltzc 'rt, 'imm16u"); |
| + } else if ((instr->RtFieldRaw() != instr->RsFieldRaw()) |
| + && (instr->RsFieldRaw() != 0) && (instr->RtFieldRaw() != 0)) { |
| + Format(instr, "bltc 'rs, 'rt, 'imm16u"); |
| + } else if ((instr->RsFieldRaw() == 0) |
| + && (instr->RtFieldRaw() != 0)) { |
| + Format(instr, "bgtzc 'rt, 'imm16u"); |
| + } else { |
| + UNREACHABLE(); |
| + } |
| + break; |
| + case BEQZC: |
| + if (instr->RsFieldRaw() != 0) { |
| + Format(instr, "beqzc 'rs, 'imm21x"); |
| + } |
| + break; |
| + case BNEZC: |
| + if (instr->RsFieldRaw() != 0) { |
| + Format(instr, "bnezc 'rs, 'imm21x"); |
| + } |
| break; |
| // ------------- Arithmetic instructions. |
| case ADDI: |
| - Format(instr, "addi 'rt, 'rs, 'imm16s"); |
| + if (kArchVariant != kMips64r6) { |
| + Format(instr, "addi 'rt, 'rs, 'imm16s"); |
| + } else { |
| + // Check if BOVC or BEQC instruction. |
| + if (instr->RsFieldRaw() >= instr->RtFieldRaw()) { |
| + Format(instr, "bovc 'rs, 'rt, 'imm16s"); |
| + } else if (instr->RsFieldRaw() < instr->RtFieldRaw()) { |
| + Format(instr, "beqc 'rs, 'rt, 'imm16s"); |
| + } else { |
| + UNREACHABLE(); |
| + } |
| + } |
| break; |
| case DADDI: |
| - Format(instr, "daddi 'rt, 'rs, 'imm16s"); |
| + if (kArchVariant != kMips64r6) { |
| + Format(instr, "daddi 'rt, 'rs, 'imm16s"); |
| + } else { |
| + // Check if BNVC or BNEC instruction. |
| + if (instr->RsFieldRaw() >= instr->RtFieldRaw()) { |
| + Format(instr, "bnvc 'rs, 'rt, 'imm16s"); |
| + } else if (instr->RsFieldRaw() < instr->RtFieldRaw()) { |
| + Format(instr, "bnec 'rs, 'rt, 'imm16s"); |
| + } else { |
| + UNREACHABLE(); |
| + } |
| + } |
| break; |
| case ADDIU: |
| Format(instr, "addiu 'rt, 'rs, 'imm16s"); |
| @@ -945,7 +1286,18 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) { |
| Format(instr, "xori 'rt, 'rs, 'imm16x"); |
| break; |
| case LUI: |
| - Format(instr, "lui 'rt, 'imm16x"); |
| + if (kArchVariant != kMips64r6) { |
| + Format(instr, "lui 'rt, 'imm16x"); |
| + } else { |
| + if (instr->RsValue() != 0) { |
| + Format(instr, "aui 'rt, 'imm16x"); |
| + } else { |
| + Format(instr, "lui 'rt, 'imm16x"); |
| + } |
| + } |
| + break; |
| + case DAUI: |
| + Format(instr, "daui 'rt, 'imm16x"); |
| break; |
| // ------------- Memory instructions. |
| case LB: |