Index: src/mips64/simulator-mips64.cc |
diff --git a/src/mips64/simulator-mips64.cc b/src/mips64/simulator-mips64.cc |
index 1ed7443781a8fd45c6ed2a6d2f297235bbec2d95..0ed2e3dbe0a562e38f0a928de19d3b325fd01955 100644 |
--- a/src/mips64/simulator-mips64.cc |
+++ b/src/mips64/simulator-mips64.cc |
@@ -3393,8 +3393,22 @@ void Simulator::DecodeTypeRegisterSPECIAL() { |
case MULTU: |
u64hilo = static_cast<uint64_t>(rs_u() & 0xffffffff) * |
static_cast<uint64_t>(rt_u() & 0xffffffff); |
- set_register(LO, static_cast<int32_t>(u64hilo & 0xffffffff)); |
- set_register(HI, static_cast<int32_t>(u64hilo >> 32)); |
+ if (kArchVariant != kMips64r6) { |
+ set_register(LO, static_cast<int32_t>(u64hilo & 0xffffffff)); |
+ set_register(HI, static_cast<int32_t>(u64hilo >> 32)); |
+ } else { |
+ switch (sa()) { |
+ case MUL_OP: |
+ set_register(rd_reg(), static_cast<int32_t>(u64hilo & 0xffffffff)); |
+ break; |
+ case MUH_OP: |
+ set_register(rd_reg(), static_cast<int32_t>(u64hilo >> 32)); |
+ break; |
+ default: |
+ UNIMPLEMENTED_MIPS(); |
+ break; |
+ } |
+ } |
break; |
case DMULT: // DMULT == D_MUL_MUH. |
if (kArchVariant != kMips64r6) { |
@@ -3462,17 +3476,61 @@ void Simulator::DecodeTypeRegisterSPECIAL() { |
break; |
} |
case DIVU: |
- if (rt_u() != 0) { |
- uint32_t rt_u_32 = static_cast<uint32_t>(rt_u()); |
- uint32_t rs_u_32 = static_cast<uint32_t>(rs_u()); |
- set_register(LO, rs_u_32 / rt_u_32); |
- set_register(HI, rs_u_32 % rt_u_32); |
+ switch (kArchVariant) { |
+ case kMips64r6: { |
+ uint32_t rt_u_32 = static_cast<uint32_t>(rt_u()); |
+ uint32_t rs_u_32 = static_cast<uint32_t>(rs_u()); |
+ switch (get_instr()->SaValue()) { |
+ case DIV_OP: |
+ if (rt_u_32 != 0) { |
+ set_register(rd_reg(), rs_u_32 / rt_u_32); |
+ } |
+ break; |
+ case MOD_OP: |
+ if (rt_u() != 0) { |
+ set_register(rd_reg(), rs_u_32 % rt_u_32); |
+ } |
+ break; |
+ default: |
+ UNIMPLEMENTED_MIPS(); |
+ break; |
+ } |
+ } break; |
+ default: { |
+ if (rt_u() != 0) { |
+ uint32_t rt_u_32 = static_cast<uint32_t>(rt_u()); |
+ uint32_t rs_u_32 = static_cast<uint32_t>(rs_u()); |
+ set_register(LO, rs_u_32 / rt_u_32); |
+ set_register(HI, rs_u_32 % rt_u_32); |
+ } |
+ } |
} |
break; |
case DDIVU: |
- if (rt_u() != 0) { |
- set_register(LO, rs_u() / rt_u()); |
- set_register(HI, rs_u() % rt_u()); |
+ switch (kArchVariant) { |
+ case kMips64r6: { |
+ switch (get_instr()->SaValue()) { |
+ case DIV_OP: |
+ if (rt_u() != 0) { |
+ set_register(rd_reg(), rs_u() / rt_u()); |
+ } |
+ break; |
+ case MOD_OP: |
+ if (rt_u() != 0) { |
+ set_register(rd_reg(), rs_u() % rt_u()); |
+ } |
+ break; |
+ default: |
+ UNIMPLEMENTED_MIPS(); |
+ break; |
+ } |
+ } break; |
+ default: { |
+ if (rt_u() != 0) { |
+ set_register(LO, rs_u() / rt_u()); |
+ set_register(HI, rs_u() % rt_u()); |
+ } |
+ } |
} |
break; |
case ADD: |