Index: src/mips64/simulator-mips64.cc |
diff --git a/src/mips64/simulator-mips64.cc b/src/mips64/simulator-mips64.cc |
index 0ed2e3dbe0a562e38f0a928de19d3b325fd01955..4a7fd7c10f27895bbdb7d13ba22dc7a0d8400f0b 100644 |
--- a/src/mips64/simulator-mips64.cc |
+++ b/src/mips64/simulator-mips64.cc |
@@ -3364,8 +3364,17 @@ void Simulator::DecodeTypeRegisterSPECIAL() { |
} |
SetResult(rd_reg(), alu_out); |
break; |
- case MFLO: |
- SetResult(rd_reg(), get_register(LO)); |
+ case MFLO: // MFLO == DCLZ on R6. |
+ if (kArchVariant != kMips64r6) { |
+ DCHECK(sa() == 0); |
+ alu_out = get_register(LO); |
+ } else { |
+ // MIPS spec: If no bits were set in GPR rs(), the result written to |
+ // GPR rd() is 64. |
+ DCHECK(sa() == 1); |
+ alu_out = base::bits::CountLeadingZeros64(static_cast<int64_t>(rs_u())); |
+ } |
+ SetResult(rd_reg(), alu_out); |
break; |
// Instructions using HI and LO registers. |
case MULT: { // MULT == D_MUL_MUH. |
@@ -3665,7 +3674,13 @@ void Simulator::DecodeTypeRegisterSPECIAL2() { |
// MIPS32 spec: If no bits were set in GPR rs(), the result written to |
// GPR rd is 32. |
alu_out = base::bits::CountLeadingZeros32(static_cast<uint32_t>(rs_u())); |
- set_register(rd_reg(), alu_out); |
+ SetResult(rd_reg(), alu_out); |
+ break; |
+ case DCLZ: |
+ // MIPS64 spec: If no bits were set in GPR rs(), the result written to |
+ // GPR rd is 64. |
+ alu_out = base::bits::CountLeadingZeros64(static_cast<uint64_t>(rs_u())); |
+ SetResult(rd_reg(), alu_out); |
break; |
default: |
alu_out = 0x12345678; |