Chromium Code Reviews| Index: src/mips/disasm-mips.cc |
| diff --git a/src/mips/disasm-mips.cc b/src/mips/disasm-mips.cc |
| index 4f725cff54a90d6cc1e768987e79e858c73c25ee..62ea55da0471585508e4f44bc16867969b530ff6 100644 |
| --- a/src/mips/disasm-mips.cc |
| +++ b/src/mips/disasm-mips.cc |
| @@ -99,7 +99,13 @@ class Decoder { |
| void Format(Instruction* instr, const char* format); |
| void Unknown(Instruction* instr); |
| + |
| // Each of these functions decodes one particular instruction type. |
| + void DecodeTypeRegisterDRsType(Instruction* instr); |
| + void DecodeTypeRegisterLRsType(Instruction* instr); |
| + void DecodeTypeRegisterSPECIAL(Instruction* instr); |
|
paul.l...
2015/03/31 04:02:01
nit: consider naming here, maybe: DecodeTypeRegist
|
| + void DecodeTypeRegisterSPECIAL2(Instruction* instr); |
| + void DecodeTypeRegisterSPECIAL3(Instruction* instr); |
| void DecodeTypeRegister(Instruction* instr); |
| void DecodeTypeImmediate(Instruction* instr); |
| void DecodeTypeJump(Instruction* instr); |
| @@ -449,6 +455,357 @@ void Decoder::Unknown(Instruction* instr) { |
| } |
| +void Decoder::DecodeTypeRegisterDRsType(Instruction* instr) { |
| + switch (instr->FunctionFieldRaw()) { |
| + case ADD_D: |
| + Format(instr, "add.d 'fd, 'fs, 'ft"); |
| + break; |
| + case SUB_D: |
| + Format(instr, "sub.d 'fd, 'fs, 'ft"); |
| + break; |
| + case MUL_D: |
| + Format(instr, "mul.d 'fd, 'fs, 'ft"); |
| + break; |
| + case DIV_D: |
| + Format(instr, "div.d 'fd, 'fs, 'ft"); |
| + break; |
| + case ABS_D: |
| + Format(instr, "abs.d 'fd, 'fs"); |
| + break; |
| + case MOV_D: |
| + Format(instr, "mov.d 'fd, 'fs"); |
| + break; |
| + case NEG_D: |
| + Format(instr, "neg.d 'fd, 'fs"); |
| + break; |
| + case SQRT_D: |
| + Format(instr, "sqrt.d 'fd, 'fs"); |
| + break; |
| + case CVT_W_D: |
| + Format(instr, "cvt.w.d 'fd, 'fs"); |
| + break; |
| + case CVT_L_D: |
| + Format(instr, "cvt.l.d 'fd, 'fs"); |
| + break; |
| + case TRUNC_W_D: |
| + Format(instr, "trunc.w.d 'fd, 'fs"); |
| + break; |
| + case TRUNC_L_D: |
| + Format(instr, "trunc.l.d 'fd, 'fs"); |
| + break; |
| + case ROUND_W_D: |
| + Format(instr, "round.w.d 'fd, 'fs"); |
| + break; |
| + case FLOOR_W_D: |
| + Format(instr, "floor.w.d 'fd, 'fs"); |
| + break; |
| + case CEIL_W_D: |
| + Format(instr, "ceil.w.d 'fd, 'fs"); |
| + break; |
| + case CVT_S_D: |
| + Format(instr, "cvt.s.d 'fd, 'fs"); |
| + break; |
| + case C_F_D: |
| + Format(instr, "c.f.d 'fs, 'ft, 'Cc"); |
| + break; |
| + case C_UN_D: |
| + Format(instr, "c.un.d 'fs, 'ft, 'Cc"); |
| + break; |
| + case C_EQ_D: |
| + Format(instr, "c.eq.d 'fs, 'ft, 'Cc"); |
| + break; |
| + case C_UEQ_D: |
| + Format(instr, "c.ueq.d 'fs, 'ft, 'Cc"); |
| + break; |
| + case C_OLT_D: |
| + Format(instr, "c.olt.d 'fs, 'ft, 'Cc"); |
| + break; |
| + case C_ULT_D: |
| + Format(instr, "c.ult.d 'fs, 'ft, 'Cc"); |
| + break; |
| + case C_OLE_D: |
| + Format(instr, "c.ole.d 'fs, 'ft, 'Cc"); |
| + break; |
| + case C_ULE_D: |
| + Format(instr, "c.ule.d 'fs, 'ft, 'Cc"); |
| + break; |
| + default: |
| + Format(instr, "unknown.cop1.d"); |
| + break; |
| + } |
| +} |
| + |
| + |
| +void Decoder::DecodeTypeRegisterLRsType(Instruction* instr) { |
| + switch (instr->FunctionFieldRaw()) { |
| + case CVT_D_L: |
| + Format(instr, "cvt.d.l 'fd, 'fs"); |
| + break; |
| + 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(); |
| + } |
| +} |
| + |
| + |
| +void Decoder::DecodeTypeRegisterSPECIAL(Instruction* instr) { |
| + switch (instr->FunctionFieldRaw()) { |
| + case JR: |
| + Format(instr, "jr 'rs"); |
| + break; |
| + case JALR: |
| + Format(instr, "jalr 'rs"); |
| + break; |
| + case SLL: |
| + if (0x0 == static_cast<int>(instr->InstructionBits())) |
| + Format(instr, "nop"); |
| + else |
| + Format(instr, "sll 'rd, 'rt, 'sa"); |
| + break; |
| + case SRL: |
| + if (instr->RsValue() == 0) { |
| + Format(instr, "srl 'rd, 'rt, 'sa"); |
| + } else { |
| + if (IsMipsArchVariant(kMips32r2)) { |
| + Format(instr, "rotr 'rd, 'rt, 'sa"); |
| + } else { |
| + Unknown(instr); |
| + } |
| + } |
| + break; |
| + case SRA: |
| + Format(instr, "sra 'rd, 'rt, 'sa"); |
| + break; |
| + case SLLV: |
| + Format(instr, "sllv 'rd, 'rt, 'rs"); |
| + break; |
| + case SRLV: |
| + if (instr->SaValue() == 0) { |
| + Format(instr, "srlv 'rd, 'rt, 'rs"); |
| + } else { |
| + if (IsMipsArchVariant(kMips32r2)) { |
| + Format(instr, "rotrv 'rd, 'rt, 'rs"); |
| + } else { |
| + Unknown(instr); |
| + } |
| + } |
| + break; |
| + case SRAV: |
| + Format(instr, "srav 'rd, 'rt, 'rs"); |
| + break; |
| + case MFHI: |
| + 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: // @Mips32r6 == MUL_MUH. |
| + if (!IsMipsArchVariant(kMips32r6)) { |
| + 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 MULTU: // @Mips32r6 == MUL_MUH_U. |
| + if (!IsMipsArchVariant(kMips32r6)) { |
| + 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: // @Mips32r6 == DIV_MOD. |
| + if (!IsMipsArchVariant(kMips32r6)) { |
| + 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 DIVU: // @Mips32r6 == DIV_MOD_U. |
| + if (!IsMipsArchVariant(kMips32r6)) { |
| + 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 ADD: |
| + Format(instr, "add 'rd, 'rs, 'rt"); |
| + break; |
| + case ADDU: |
| + Format(instr, "addu 'rd, 'rs, 'rt"); |
| + break; |
| + case SUB: |
| + Format(instr, "sub 'rd, 'rs, 'rt"); |
| + break; |
| + case SUBU: |
| + Format(instr, "subu 'rd, 'rs, 'rt"); |
| + break; |
| + case AND: |
| + Format(instr, "and 'rd, 'rs, 'rt"); |
| + break; |
| + case OR: |
| + if (0 == instr->RsValue()) { |
| + Format(instr, "mov 'rd, 'rt"); |
| + } else if (0 == instr->RtValue()) { |
| + Format(instr, "mov 'rd, 'rs"); |
| + } else { |
| + Format(instr, "or 'rd, 'rs, 'rt"); |
| + } |
| + break; |
| + case XOR: |
| + Format(instr, "xor 'rd, 'rs, 'rt"); |
| + break; |
| + case NOR: |
| + Format(instr, "nor 'rd, 'rs, 'rt"); |
| + break; |
| + case SLT: |
| + Format(instr, "slt 'rd, 'rs, 'rt"); |
| + break; |
| + case SLTU: |
| + Format(instr, "sltu 'rd, 'rs, 'rt"); |
| + break; |
| + case BREAK: |
| + Format(instr, "break, code: 'code"); |
| + break; |
| + case TGE: |
| + Format(instr, "tge 'rs, 'rt, code: 'code"); |
| + break; |
| + case TGEU: |
| + Format(instr, "tgeu 'rs, 'rt, code: 'code"); |
| + break; |
| + case TLT: |
| + Format(instr, "tlt 'rs, 'rt, code: 'code"); |
| + break; |
| + case TLTU: |
| + Format(instr, "tltu 'rs, 'rt, code: 'code"); |
| + break; |
| + case TEQ: |
| + Format(instr, "teq 'rs, 'rt, code: 'code"); |
| + break; |
| + case TNE: |
| + Format(instr, "tne 'rs, 'rt, code: 'code"); |
| + break; |
| + case MOVZ: |
| + Format(instr, "movz 'rd, 'rs, 'rt"); |
| + break; |
| + case MOVN: |
| + Format(instr, "movn 'rd, 'rs, 'rt"); |
| + break; |
| + case MOVCI: |
| + if (instr->Bit(16)) { |
| + Format(instr, "movt 'rd, 'rs, 'bc"); |
| + } else { |
| + Format(instr, "movf 'rd, 'rs, 'bc"); |
| + } |
| + break; |
| + case SELEQZ_S: |
| + Format(instr, "seleqz 'rs, 'rt, 'rd"); |
| + break; |
| + case SELNEZ_S: |
| + Format(instr, "selnez 'rs, 'rt, 'rd"); |
| + break; |
| + default: |
| + UNREACHABLE(); |
| + } |
| +} |
| + |
| + |
| +void Decoder::DecodeTypeRegisterSPECIAL2(Instruction* instr) { |
| + switch (instr->FunctionFieldRaw()) { |
| + case MUL: |
| + Format(instr, "mul 'rd, 'rs, 'rt"); |
| + break; |
| + case CLZ: |
| + if (!IsMipsArchVariant(kMips32r6)) { |
| + Format(instr, "clz 'rd, 'rs"); |
| + } |
| + break; |
| + default: |
| + UNREACHABLE(); |
| + } |
| +} |
| + |
| + |
| +void Decoder::DecodeTypeRegisterSPECIAL3(Instruction* instr) { |
| + switch (instr->FunctionFieldRaw()) { |
| + case INS: { |
| + if (IsMipsArchVariant(kMips32r2)) { |
| + Format(instr, "ins 'rt, 'rs, 'sa, 'ss2"); |
| + } else { |
| + Unknown(instr); |
| + } |
| + break; |
| + } |
| + case EXT: { |
| + if (IsMipsArchVariant(kMips32r2)) { |
| + Format(instr, "ext 'rt, 'rs, 'sa, 'ss1"); |
| + } else { |
| + Unknown(instr); |
| + } |
| + break; |
| + } |
| + default: |
| + UNREACHABLE(); |
| + } |
| +} |
| + |
| + |
| void Decoder::DecodeTypeRegister(Instruction* instr) { |
| switch (instr->OpcodeFieldRaw()) { |
| case COP1: // Coprocessor instructions. |
| @@ -476,83 +833,7 @@ void Decoder::DecodeTypeRegister(Instruction* instr) { |
| Format(instr, "mthc1 'rt, 'fs"); |
| break; |
| case D: |
| - switch (instr->FunctionFieldRaw()) { |
| - case ADD_D: |
| - Format(instr, "add.d 'fd, 'fs, 'ft"); |
| - break; |
| - case SUB_D: |
| - Format(instr, "sub.d 'fd, 'fs, 'ft"); |
| - break; |
| - case MUL_D: |
| - Format(instr, "mul.d 'fd, 'fs, 'ft"); |
| - break; |
| - case DIV_D: |
| - Format(instr, "div.d 'fd, 'fs, 'ft"); |
| - break; |
| - case ABS_D: |
| - Format(instr, "abs.d 'fd, 'fs"); |
| - break; |
| - case MOV_D: |
| - Format(instr, "mov.d 'fd, 'fs"); |
| - break; |
| - case NEG_D: |
| - Format(instr, "neg.d 'fd, 'fs"); |
| - break; |
| - case SQRT_D: |
| - Format(instr, "sqrt.d 'fd, 'fs"); |
| - break; |
| - case CVT_W_D: |
| - Format(instr, "cvt.w.d 'fd, 'fs"); |
| - break; |
| - case CVT_L_D: |
| - Format(instr, "cvt.l.d 'fd, 'fs"); |
| - break; |
| - case TRUNC_W_D: |
| - Format(instr, "trunc.w.d 'fd, 'fs"); |
| - break; |
| - case TRUNC_L_D: |
| - Format(instr, "trunc.l.d 'fd, 'fs"); |
| - break; |
| - case ROUND_W_D: |
| - Format(instr, "round.w.d 'fd, 'fs"); |
| - break; |
| - case FLOOR_W_D: |
| - Format(instr, "floor.w.d 'fd, 'fs"); |
| - break; |
| - case CEIL_W_D: |
| - Format(instr, "ceil.w.d 'fd, 'fs"); |
| - break; |
| - case CVT_S_D: |
| - Format(instr, "cvt.s.d 'fd, 'fs"); |
| - break; |
| - case C_F_D: |
| - Format(instr, "c.f.d 'fs, 'ft, 'Cc"); |
| - break; |
| - case C_UN_D: |
| - Format(instr, "c.un.d 'fs, 'ft, 'Cc"); |
| - break; |
| - case C_EQ_D: |
| - Format(instr, "c.eq.d 'fs, 'ft, 'Cc"); |
| - break; |
| - case C_UEQ_D: |
| - Format(instr, "c.ueq.d 'fs, 'ft, 'Cc"); |
| - break; |
| - case C_OLT_D: |
| - Format(instr, "c.olt.d 'fs, 'ft, 'Cc"); |
| - break; |
| - case C_ULT_D: |
| - Format(instr, "c.ult.d 'fs, 'ft, 'Cc"); |
| - break; |
| - case C_OLE_D: |
| - Format(instr, "c.ole.d 'fs, 'ft, 'Cc"); |
| - break; |
| - case C_ULE_D: |
| - Format(instr, "c.ule.d 'fs, 'ft, 'Cc"); |
| - break; |
| - default: |
| - Format(instr, "unknown.cop1.d"); |
| - break; |
| - } |
| + DecodeTypeRegisterDRsType(instr); |
| break; |
| case S: |
| switch (instr->FunctionFieldRaw()) { |
| @@ -576,46 +857,7 @@ void Decoder::DecodeTypeRegister(Instruction* instr) { |
| } |
| break; |
| case L: |
| - switch (instr->FunctionFieldRaw()) { |
| - case CVT_D_L: |
| - Format(instr, "cvt.d.l 'fd, 'fs"); |
| - break; |
| - 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(); |
| - } |
| + DecodeTypeRegisterLRsType(instr); |
| break; |
| case PS: |
| UNIMPLEMENTED_MIPS(); |
| @@ -634,225 +876,13 @@ void Decoder::DecodeTypeRegister(Instruction* instr) { |
| } |
| break; |
| case SPECIAL: |
| - switch (instr->FunctionFieldRaw()) { |
| - case JR: |
| - Format(instr, "jr 'rs"); |
| - break; |
| - case JALR: |
| - Format(instr, "jalr 'rs"); |
| - break; |
| - case SLL: |
| - if ( 0x0 == static_cast<int>(instr->InstructionBits())) |
| - Format(instr, "nop"); |
| - else |
| - Format(instr, "sll 'rd, 'rt, 'sa"); |
| - break; |
| - case SRL: |
| - if (instr->RsValue() == 0) { |
| - Format(instr, "srl 'rd, 'rt, 'sa"); |
| - } else { |
| - if (IsMipsArchVariant(kMips32r2)) { |
| - Format(instr, "rotr 'rd, 'rt, 'sa"); |
| - } else { |
| - Unknown(instr); |
| - } |
| - } |
| - break; |
| - case SRA: |
| - Format(instr, "sra 'rd, 'rt, 'sa"); |
| - break; |
| - case SLLV: |
| - Format(instr, "sllv 'rd, 'rt, 'rs"); |
| - break; |
| - case SRLV: |
| - if (instr->SaValue() == 0) { |
| - Format(instr, "srlv 'rd, 'rt, 'rs"); |
| - } else { |
| - if (IsMipsArchVariant(kMips32r2)) { |
| - Format(instr, "rotrv 'rd, 'rt, 'rs"); |
| - } else { |
| - Unknown(instr); |
| - } |
| - } |
| - break; |
| - case SRAV: |
| - Format(instr, "srav 'rd, 'rt, 'rs"); |
| - break; |
| - case MFHI: |
| - 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: // @Mips32r6 == MUL_MUH. |
| - if (!IsMipsArchVariant(kMips32r6)) { |
| - 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 MULTU: // @Mips32r6 == MUL_MUH_U. |
| - if (!IsMipsArchVariant(kMips32r6)) { |
| - 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: // @Mips32r6 == DIV_MOD. |
| - if (!IsMipsArchVariant(kMips32r6)) { |
| - 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 DIVU: // @Mips32r6 == DIV_MOD_U. |
| - if (!IsMipsArchVariant(kMips32r6)) { |
| - 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 ADD: |
| - Format(instr, "add 'rd, 'rs, 'rt"); |
| - break; |
| - case ADDU: |
| - Format(instr, "addu 'rd, 'rs, 'rt"); |
| - break; |
| - case SUB: |
| - Format(instr, "sub 'rd, 'rs, 'rt"); |
| - break; |
| - case SUBU: |
| - Format(instr, "subu 'rd, 'rs, 'rt"); |
| - break; |
| - case AND: |
| - Format(instr, "and 'rd, 'rs, 'rt"); |
| - break; |
| - case OR: |
| - if (0 == instr->RsValue()) { |
| - Format(instr, "mov 'rd, 'rt"); |
| - } else if (0 == instr->RtValue()) { |
| - Format(instr, "mov 'rd, 'rs"); |
| - } else { |
| - Format(instr, "or 'rd, 'rs, 'rt"); |
| - } |
| - break; |
| - case XOR: |
| - Format(instr, "xor 'rd, 'rs, 'rt"); |
| - break; |
| - case NOR: |
| - Format(instr, "nor 'rd, 'rs, 'rt"); |
| - break; |
| - case SLT: |
| - Format(instr, "slt 'rd, 'rs, 'rt"); |
| - break; |
| - case SLTU: |
| - Format(instr, "sltu 'rd, 'rs, 'rt"); |
| - break; |
| - case BREAK: |
| - Format(instr, "break, code: 'code"); |
| - break; |
| - case TGE: |
| - Format(instr, "tge 'rs, 'rt, code: 'code"); |
| - break; |
| - case TGEU: |
| - Format(instr, "tgeu 'rs, 'rt, code: 'code"); |
| - break; |
| - case TLT: |
| - Format(instr, "tlt 'rs, 'rt, code: 'code"); |
| - break; |
| - case TLTU: |
| - Format(instr, "tltu 'rs, 'rt, code: 'code"); |
| - break; |
| - case TEQ: |
| - Format(instr, "teq 'rs, 'rt, code: 'code"); |
| - break; |
| - case TNE: |
| - Format(instr, "tne 'rs, 'rt, code: 'code"); |
| - break; |
| - case MOVZ: |
| - Format(instr, "movz 'rd, 'rs, 'rt"); |
| - break; |
| - case MOVN: |
| - Format(instr, "movn 'rd, 'rs, 'rt"); |
| - break; |
| - case MOVCI: |
| - if (instr->Bit(16)) { |
| - Format(instr, "movt 'rd, 'rs, 'bc"); |
| - } else { |
| - 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(); |
| - } |
| + DecodeTypeRegisterSPECIAL(instr); |
| break; |
| case SPECIAL2: |
| - switch (instr->FunctionFieldRaw()) { |
| - case MUL: |
| - Format(instr, "mul 'rd, 'rs, 'rt"); |
| - break; |
| - case CLZ: |
| - if (!IsMipsArchVariant(kMips32r6)) { |
| - Format(instr, "clz 'rd, 'rs"); |
| - } |
| - break; |
| - default: |
| - UNREACHABLE(); |
| - } |
| + DecodeTypeRegisterSPECIAL2(instr); |
| break; |
| case SPECIAL3: |
| - switch (instr->FunctionFieldRaw()) { |
| - case INS: { |
| - if (IsMipsArchVariant(kMips32r2)) { |
| - Format(instr, "ins 'rt, 'rs, 'sa, 'ss2"); |
| - } else { |
| - Unknown(instr); |
| - } |
| - break; |
| - } |
| - case EXT: { |
| - if (IsMipsArchVariant(kMips32r2)) { |
| - Format(instr, "ext 'rt, 'rs, 'sa, 'ss1"); |
| - } else { |
| - Unknown(instr); |
| - } |
| - break; |
| - } |
| - default: |
| - UNREACHABLE(); |
| - } |
| + DecodeTypeRegisterSPECIAL3(instr); |
| break; |
| default: |
| UNREACHABLE(); |