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

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

Issue 1668143002: MIPS: Fix FPU min, max, mina, maxa in simulator. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 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
« no previous file with comments | « src/mips64/simulator-mips64.h ('k') | test/cctest/test-assembler-mips.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/mips64/simulator-mips64.cc
diff --git a/src/mips64/simulator-mips64.cc b/src/mips64/simulator-mips64.cc
index 4702e7db44349783c955079b778d3c5b1ca70fde..beabc88e36adc3461de50a09f86768ca203617e3 100644
--- a/src/mips64/simulator-mips64.cc
+++ b/src/mips64/simulator-mips64.cc
@@ -2332,6 +2332,87 @@ void Simulator::SignalException(Exception e) {
static_cast<int>(e));
}
+template <typename T>
+T FPAbs(T a);
+
+template <>
+double FPAbs<double>(double a) {
+ return fabs(a);
+}
+
+template <>
+float FPAbs<float>(float a) {
+ return fabsf(a);
+}
+
+template <typename T>
+bool Simulator::FPUProcessNaNsAndZeros(T a, T b, IsMin min, T& result) {
+ if (std::isnan(a) && std::isnan(b)) {
+ result = a;
+ } else if (std::isnan(a)) {
+ result = b;
+ } else if (std::isnan(b)) {
+ result = a;
+ } else if (b == a) {
+ // Handle -0.0 == 0.0 case.
+ // std::signbit() returns int 0 or 1 so substracting IsMin::kMax negates the
+ // result.
+ result = std::signbit(b) - static_cast<int>(min) ? b : a;
+ } else {
+ return false;
+ }
+ return true;
+}
+
+template <typename T>
+T Simulator::FPUMin(T a, T b) {
+ T result;
+ if (FPUProcessNaNsAndZeros(a, b, IsMin::kMin, result)) {
+ return result;
+ } else {
+ return b < a ? b : a;
+ }
+}
+
+template <typename T>
+T Simulator::FPUMax(T a, T b) {
+ T result;
+ if (FPUProcessNaNsAndZeros(a, b, IsMin::kMax, result)) {
+ return result;
+ } else {
+ return b > a ? b : a;
+ }
+}
+
+template <typename T>
+T Simulator::FPUMinA(T a, T b) {
+ T result;
+ if (!FPUProcessNaNsAndZeros(a, b, IsMin::kMin, result)) {
+ if (FPAbs(a) < FPAbs(b)) {
+ result = a;
+ } else if (FPAbs(b) < FPAbs(a)) {
+ result = b;
+ } else {
+ result = a < b ? a : b;
+ }
+ }
+ return result;
+}
+
+template <typename T>
+T Simulator::FPUMaxA(T a, T b) {
+ T result;
+ if (!FPUProcessNaNsAndZeros(a, b, IsMin::kMin, result)) {
+ if (FPAbs(a) > FPAbs(b)) {
+ result = a;
+ } else if (FPAbs(b) > FPAbs(a)) {
+ result = b;
+ } else {
+ result = a > b ? a : b;
+ }
+ }
+ return result;
+}
// Handle execution based on instruction types.
@@ -2616,71 +2697,19 @@ void Simulator::DecodeTypeRegisterSRsType() {
}
case MINA:
DCHECK(kArchVariant == kMips64r6);
- fs = get_fpu_register_float(fs_reg());
- if (std::isnan(fs) && std::isnan(ft)) {
- set_fpu_register_float(fd_reg(), fs);
- } else if (std::isnan(fs) && !std::isnan(ft)) {
- set_fpu_register_float(fd_reg(), ft);
- } else if (!std::isnan(fs) && std::isnan(ft)) {
- set_fpu_register_float(fd_reg(), fs);
- } else {
- float result;
- if (fabs(fs) > fabs(ft)) {
- result = ft;
- } else if (fabs(fs) < fabs(ft)) {
- result = fs;
- } else {
- result = (fs < ft ? fs : ft);
- }
- set_fpu_register_float(fd_reg(), result);
- }
+ set_fpu_register_float(fd_reg(), FPUMinA(ft, fs));
break;
case MAXA:
DCHECK(kArchVariant == kMips64r6);
- fs = get_fpu_register_float(fs_reg());
- if (std::isnan(fs) && std::isnan(ft)) {
- set_fpu_register_float(fd_reg(), fs);
- } else if (std::isnan(fs) && !std::isnan(ft)) {
- set_fpu_register_float(fd_reg(), ft);
- } else if (!std::isnan(fs) && std::isnan(ft)) {
- set_fpu_register_float(fd_reg(), fs);
- } else {
- float result;
- if (fabs(fs) < fabs(ft)) {
- result = ft;
- } else if (fabs(fs) > fabs(ft)) {
- result = fs;
- } else {
- result = (fs > ft ? fs : ft);
- }
- set_fpu_register_float(fd_reg(), result);
- }
+ set_fpu_register_float(fd_reg(), FPUMaxA(ft, fs));
break;
case MIN:
DCHECK(kArchVariant == kMips64r6);
- fs = get_fpu_register_float(fs_reg());
- if (std::isnan(fs) && std::isnan(ft)) {
- set_fpu_register_float(fd_reg(), fs);
- } else if (std::isnan(fs) && !std::isnan(ft)) {
- set_fpu_register_float(fd_reg(), ft);
- } else if (!std::isnan(fs) && std::isnan(ft)) {
- set_fpu_register_float(fd_reg(), fs);
- } else {
- set_fpu_register_float(fd_reg(), (fs >= ft) ? ft : fs);
- }
+ set_fpu_register_float(fd_reg(), FPUMin(ft, fs));
break;
case MAX:
DCHECK(kArchVariant == kMips64r6);
- fs = get_fpu_register_float(fs_reg());
- if (std::isnan(fs) && std::isnan(ft)) {
- set_fpu_register_float(fd_reg(), fs);
- } else if (std::isnan(fs) && !std::isnan(ft)) {
- set_fpu_register_float(fd_reg(), ft);
- } else if (!std::isnan(fs) && std::isnan(ft)) {
- set_fpu_register_float(fd_reg(), fs);
- } else {
- set_fpu_register_float(fd_reg(), (fs <= ft) ? ft : fs);
- }
+ set_fpu_register_float(fd_reg(), FPUMax(ft, fs));
break;
case SEL:
DCHECK(kArchVariant == kMips64r6);
@@ -2825,71 +2854,19 @@ void Simulator::DecodeTypeRegisterDRsType() {
}
case MINA:
DCHECK(kArchVariant == kMips64r6);
- fs = get_fpu_register_double(fs_reg());
- if (std::isnan(fs) && std::isnan(ft)) {
- set_fpu_register_double(fd_reg(), fs);
- } else if (std::isnan(fs) && !std::isnan(ft)) {
- set_fpu_register_double(fd_reg(), ft);
- } else if (!std::isnan(fs) && std::isnan(ft)) {
- set_fpu_register_double(fd_reg(), fs);
- } else {
- double result;
- if (fabs(fs) > fabs(ft)) {
- result = ft;
- } else if (fabs(fs) < fabs(ft)) {
- result = fs;
- } else {
- result = (fs < ft ? fs : ft);
- }
- set_fpu_register_double(fd_reg(), result);
- }
+ set_fpu_register_double(fd_reg(), FPUMinA(ft, fs));
break;
case MAXA:
DCHECK(kArchVariant == kMips64r6);
- fs = get_fpu_register_double(fs_reg());
- if (std::isnan(fs) && std::isnan(ft)) {
- set_fpu_register_double(fd_reg(), fs);
- } else if (std::isnan(fs) && !std::isnan(ft)) {
- set_fpu_register_double(fd_reg(), ft);
- } else if (!std::isnan(fs) && std::isnan(ft)) {
- set_fpu_register_double(fd_reg(), fs);
- } else {
- double result;
- if (fabs(fs) < fabs(ft)) {
- result = ft;
- } else if (fabs(fs) > fabs(ft)) {
- result = fs;
- } else {
- result = (fs > ft ? fs : ft);
- }
- set_fpu_register_double(fd_reg(), result);
- }
+ set_fpu_register_double(fd_reg(), FPUMaxA(ft, fs));
break;
case MIN:
DCHECK(kArchVariant == kMips64r6);
- fs = get_fpu_register_double(fs_reg());
- if (std::isnan(fs) && std::isnan(ft)) {
- set_fpu_register_double(fd_reg(), fs);
- } else if (std::isnan(fs) && !std::isnan(ft)) {
- set_fpu_register_double(fd_reg(), ft);
- } else if (!std::isnan(fs) && std::isnan(ft)) {
- set_fpu_register_double(fd_reg(), fs);
- } else {
- set_fpu_register_double(fd_reg(), (fs >= ft) ? ft : fs);
- }
+ set_fpu_register_double(fd_reg(), FPUMin(ft, fs));
break;
case MAX:
DCHECK(kArchVariant == kMips64r6);
- fs = get_fpu_register_double(fs_reg());
- if (std::isnan(fs) && std::isnan(ft)) {
- set_fpu_register_double(fd_reg(), fs);
- } else if (std::isnan(fs) && !std::isnan(ft)) {
- set_fpu_register_double(fd_reg(), ft);
- } else if (!std::isnan(fs) && std::isnan(ft)) {
- set_fpu_register_double(fd_reg(), fs);
- } else {
- set_fpu_register_double(fd_reg(), (fs <= ft) ? ft : fs);
- }
+ set_fpu_register_double(fd_reg(), FPUMax(ft, fs));
break;
case ADD_D:
set_fpu_register_double(fd_reg(), fs + ft);
« no previous file with comments | « src/mips64/simulator-mips64.h ('k') | test/cctest/test-assembler-mips.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698