Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(820)

Unified Diff: src/mips/simulator-mips.cc

Issue 6993054: MIPS: Fixed FPU rounding checks and related errors in the Simulator. (Closed)
Patch Set: Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/mips/simulator-mips.cc
diff --git a/src/mips/simulator-mips.cc b/src/mips/simulator-mips.cc
index 74b81e72a0a06b728650f81ccf58863a164b4f89..938982ba2a5456f1b73aed03f0b9be9c6060f6a1 100644
--- a/src/mips/simulator-mips.cc
+++ b/src/mips/simulator-mips.cc
@@ -1159,15 +1159,30 @@ bool Simulator::test_fcsr_bit(uint32_t cc) {
// Sets the rounding error codes in FCSR based on the result of the rounding.
// Returns true if the operation was invalid.
bool Simulator::set_fcsr_round_error(double original, double rounded) {
- if (!isfinite(original) ||
- rounded > LONG_MAX ||
- rounded < LONG_MIN) {
- set_fcsr_bit(6, true); // Invalid operation.
- return true;
- } else if (original != static_cast<double>(rounded)) {
- set_fcsr_bit(2, true); // Inexact.
+ bool ret = false;
+
+ if (!isfinite(original) || !isfinite(rounded)) {
+ set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
+ ret = true;
}
- return false;
+
+ if (original != rounded) {
+ set_fcsr_bit(kFCSRInexactFlagBit, true);
+ }
+
+ if (rounded < DBL_MIN && rounded > -DBL_MIN && rounded != 0) {
+ set_fcsr_bit(kFCSRUnderflowFlagBit, true);
+ ret = true;
+ }
+
+ if (rounded > INT_MAX || rounded < INT_MIN) {
+ set_fcsr_bit(kFCSROverflowFlagBit, true);
+ // The reference is not really clear but it seems this is required:
+ set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
+ ret = true;
+ }
+
+ return ret;
}
@@ -2054,9 +2069,10 @@ void Simulator::DecodeTypeRegister(Instruction* instr) {
break;
case TRUNC_W_D: // Truncate double to word (round towards 0).
{
- int32_t result = static_cast<int32_t>(fs);
+ double rounded = trunc(fs);
+ int32_t result = static_cast<int32_t>(rounded);
set_fpu_register(fd_reg, result);
- if (set_fcsr_round_error(fs, static_cast<double>(result))) {
+ if (set_fcsr_round_error(fs, rounded)) {
set_fpu_register(fd_reg, kFPUInvalidResult);
}
}
@@ -2084,16 +2100,20 @@ void Simulator::DecodeTypeRegister(Instruction* instr) {
case CVT_S_D: // Convert double to float (single).
set_fpu_register_float(fd_reg, static_cast<float>(fs));
break;
- case CVT_L_D: // Mips32r2: Truncate double to 64-bit long-word.
- i64 = static_cast<int64_t>(fs);
+ case CVT_L_D: { // Mips32r2: Truncate double to 64-bit long-word.
+ double rounded = trunc(fs);
+ i64 = static_cast<int64_t>(rounded);
set_fpu_register(fd_reg, i64 & 0xffffffff);
set_fpu_register(fd_reg + 1, i64 >> 32);
break;
- case TRUNC_L_D: // Mips32r2 instruction.
- i64 = static_cast<int64_t>(fs);
+ }
+ case TRUNC_L_D: { // Mips32r2 instruction.
+ double rounded = trunc(fs);
+ i64 = static_cast<int64_t>(rounded);
set_fpu_register(fd_reg, i64 & 0xffffffff);
set_fpu_register(fd_reg + 1, i64 >> 32);
break;
+ }
case ROUND_L_D: { // Mips32r2 instruction.
double rounded = fs > 0 ? floor(fs + 0.5) : ceil(fs - 0.5);
i64 = static_cast<int64_t>(rounded);

Powered by Google App Engine
This is Rietveld 408576698