Index: src/mips/disasm-mips.cc |
diff --git a/src/mips/disasm-mips.cc b/src/mips/disasm-mips.cc |
index 822aab415806de88fafe3e045b36059022ee1da2..0f7abab5a2c9b422e232874425522faebe629fe0 100644 |
--- a/src/mips/disasm-mips.cc |
+++ b/src/mips/disasm-mips.cc |
@@ -106,6 +106,7 @@ class Decoder { |
void DecodeTypeRegisterSRsType(Instruction* instr); |
void DecodeTypeRegisterDRsType(Instruction* instr); |
void DecodeTypeRegisterLRsType(Instruction* instr); |
+ void DecodeTypeRegisterWRsType(Instruction* instr); |
void DecodeTypeRegisterSPECIAL(Instruction* instr); |
void DecodeTypeRegisterSPECIAL2(Instruction* instr); |
void DecodeTypeRegisterSPECIAL3(Instruction* instr); |
@@ -486,6 +487,27 @@ void Decoder::Unknown(Instruction* instr) { |
bool Decoder::DecodeTypeRegisterRsType(Instruction* instr) { |
switch (instr->FunctionFieldRaw()) { |
+ case MIN: |
+ Format(instr, "min.'t 'fd, 'fs, 'ft"); |
+ break; |
+ case MAX: |
+ Format(instr, "max.'t 'fd, 'fs, 'ft"); |
+ break; |
+ case MINA: |
+ Format(instr, "mina.'t 'fd, 'fs, 'ft"); |
+ break; |
+ case MAXA: |
+ Format(instr, "maxa.'t 'fd, 'fs, 'ft"); |
+ break; |
+ case SEL: |
+ Format(instr, "sel.'t 'fd, 'fs, 'ft"); |
+ break; |
+ case SELEQZ_C: |
+ Format(instr, "seleqz.'t 'fd, 'fs, 'ft"); |
+ break; |
+ case SELNEZ_C: |
+ Format(instr, "selnez.'t 'fd, 'fs, 'ft"); |
+ break; |
case ADD_D: |
Format(instr, "add.'t 'fd, 'fs, 'ft"); |
break; |
@@ -630,6 +652,53 @@ void Decoder::DecodeTypeRegisterLRsType(Instruction* instr) { |
} |
+void Decoder::DecodeTypeRegisterWRsType(Instruction* instr) { |
+ switch (instr->FunctionValue()) { |
+ 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; |
+ case CMP_AF: |
+ Format(instr, "cmp.af.s 'fd, 'fs, 'ft"); |
+ break; |
+ case CMP_UN: |
+ Format(instr, "cmp.un.s 'fd, 'fs, 'ft"); |
+ break; |
+ case CMP_EQ: |
+ Format(instr, "cmp.eq.s 'fd, 'fs, 'ft"); |
+ break; |
+ case CMP_UEQ: |
+ Format(instr, "cmp.ueq.s 'fd, 'fs, 'ft"); |
+ break; |
+ case CMP_LT: |
+ Format(instr, "cmp.lt.s 'fd, 'fs, 'ft"); |
+ break; |
+ case CMP_ULT: |
+ Format(instr, "cmp.ult.s 'fd, 'fs, 'ft"); |
+ break; |
+ case CMP_LE: |
+ Format(instr, "cmp.le.s 'fd, 'fs, 'ft"); |
+ break; |
+ case CMP_ULE: |
+ Format(instr, "cmp.ule.s 'fd, 'fs, 'ft"); |
+ break; |
+ case CMP_OR: |
+ Format(instr, "cmp.or.s 'fd, 'fs, 'ft"); |
+ break; |
+ case CMP_UNE: |
+ Format(instr, "cmp.une.s 'fd, 'fs, 'ft"); |
+ break; |
+ case CMP_NE: |
+ Format(instr, "cmp.ne.s 'fd, 'fs, 'ft"); |
+ break; |
+ default: |
+ UNREACHABLE(); |
+ } |
+} |
+ |
+ |
void Decoder::DecodeTypeRegisterSPECIAL(Instruction* instr) { |
switch (instr->FunctionFieldRaw()) { |
case JR: |
@@ -805,10 +874,10 @@ void Decoder::DecodeTypeRegisterSPECIAL(Instruction* instr) { |
} |
break; |
case SELEQZ_S: |
- Format(instr, "seleqz 'rs, 'rt, 'rd"); |
+ Format(instr, "seleqz 'rd, 'rs, 'rt"); |
break; |
case SELNEZ_S: |
- Format(instr, "selnez 'rs, 'rt, 'rd"); |
+ Format(instr, "selnez 'rd, 'rs, 'rt"); |
break; |
default: |
UNREACHABLE(); |
@@ -888,21 +957,12 @@ void Decoder::DecodeTypeRegister(Instruction* instr) { |
case D: |
DecodeTypeRegisterDRsType(instr); |
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; |
- default: |
- UNREACHABLE(); |
- } |
- break; |
case L: |
DecodeTypeRegisterLRsType(instr); |
break; |
+ case W: |
+ DecodeTypeRegisterWRsType(instr); |
+ break; |
case PS: |
UNIMPLEMENTED_MIPS(); |
break; |
@@ -951,138 +1011,6 @@ void Decoder::DecodeTypeImmediate(Instruction* instr) { |
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(); |
} |