Commit a58c750c authored by balazs.kilvady's avatar balazs.kilvady Committed by Commit bot

MIPS: Fix FPU min, max, mina, maxa in simulator.

BUG=
TEST=cctest/test-assembler-mips/min_max, cctest/test-assembler-mips/mina_maxa, cctest/test-assembler-mips64/min_max, cctest/test-assembler-mips64/mina_maxa

Review URL: https://codereview.chromium.org/1668143002

Cr-Commit-Position: refs/heads/master@{#33790}
parent 3dc2635d
...@@ -2347,6 +2347,89 @@ void Simulator::SignalException(Exception e) { ...@@ -2347,6 +2347,89 @@ void Simulator::SignalException(Exception e) {
static_cast<int>(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.
void Simulator::DecodeTypeRegisterDRsType() { void Simulator::DecodeTypeRegisterDRsType() {
double ft, fs, fd; double ft, fs, fd;
...@@ -2442,72 +2525,19 @@ void Simulator::DecodeTypeRegisterDRsType() { ...@@ -2442,72 +2525,19 @@ void Simulator::DecodeTypeRegisterDRsType() {
} }
case MIN: case MIN:
DCHECK(IsMipsArchVariant(kMips32r6)); DCHECK(IsMipsArchVariant(kMips32r6));
fs = get_fpu_register_double(fs_reg()); set_fpu_register_double(fd_reg(), FPUMin(ft, fs));
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);
}
break; break;
case MINA: case MAX:
DCHECK(IsMipsArchVariant(kMips32r6)); DCHECK(IsMipsArchVariant(kMips32r6));
fs = get_fpu_register_double(fs_reg()); set_fpu_register_double(fd_reg(), FPUMax(ft, fs));
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);
}
break; break;
case MAXA: case MINA:
DCHECK(IsMipsArchVariant(kMips32r6)); DCHECK(IsMipsArchVariant(kMips32r6));
fs = get_fpu_register_double(fs_reg()); set_fpu_register_double(fd_reg(), FPUMinA(ft, fs));
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);
}
break; break;
case MAX: case MAXA:
DCHECK(IsMipsArchVariant(kMips32r6)); DCHECK(IsMipsArchVariant(kMips32r6));
fs = get_fpu_register_double(fs_reg()); set_fpu_register_double(fd_reg(), FPUMaxA(ft, fs));
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);
}
break;
break; break;
case ADD_D: case ADD_D:
set_fpu_register_double(fd_reg(), fs + ft); set_fpu_register_double(fd_reg(), fs + ft);
...@@ -3193,71 +3223,19 @@ void Simulator::DecodeTypeRegisterSRsType() { ...@@ -3193,71 +3223,19 @@ void Simulator::DecodeTypeRegisterSRsType() {
} }
case MIN: case MIN:
DCHECK(IsMipsArchVariant(kMips32r6)); DCHECK(IsMipsArchVariant(kMips32r6));
fs = get_fpu_register_float(fs_reg()); set_fpu_register_float(fd_reg(), FPUMin(ft, fs));
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);
}
break; break;
case MAX: case MAX:
DCHECK(IsMipsArchVariant(kMips32r6)); DCHECK(IsMipsArchVariant(kMips32r6));
fs = get_fpu_register_float(fs_reg()); set_fpu_register_float(fd_reg(), FPUMax(ft, fs));
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);
}
break; break;
case MINA: case MINA:
DCHECK(IsMipsArchVariant(kMips32r6)); DCHECK(IsMipsArchVariant(kMips32r6));
fs = get_fpu_register_float(fs_reg()); set_fpu_register_float(fd_reg(), FPUMinA(ft, fs));
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);
}
break; break;
case MAXA: case MAXA:
DCHECK(IsMipsArchVariant(kMips32r6)); DCHECK(IsMipsArchVariant(kMips32r6));
fs = get_fpu_register_float(fs_reg()); set_fpu_register_float(fd_reg(), FPUMaxA(ft, fs));
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);
}
break; break;
case CVT_L_S: { case CVT_L_S: {
if (IsFp64Mode()) { if (IsFp64Mode()) {
......
...@@ -300,6 +300,24 @@ class Simulator { ...@@ -300,6 +300,24 @@ class Simulator {
inline int32_t SetDoubleHIW(double* addr); inline int32_t SetDoubleHIW(double* addr);
inline int32_t SetDoubleLOW(double* addr); inline int32_t SetDoubleLOW(double* addr);
// Min/Max template functions for Double and Single arguments.
enum class IsMin : int { kMin = 0, kMax = 1 };
template <typename T>
bool FPUProcessNaNsAndZeros(T a, T b, IsMin min, T& result);
template <typename T>
T FPUMin(T a, T b);
template <typename T>
T FPUMax(T a, T b);
template <typename T>
T FPUMinA(T a, T b);
template <typename T>
T FPUMaxA(T a, T b);
// Executing is handled based on the instruction type. // Executing is handled based on the instruction type.
void DecodeTypeRegister(Instruction* instr); void DecodeTypeRegister(Instruction* instr);
......
...@@ -2332,6 +2332,87 @@ void Simulator::SignalException(Exception e) { ...@@ -2332,6 +2332,87 @@ void Simulator::SignalException(Exception e) {
static_cast<int>(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. // Handle execution based on instruction types.
...@@ -2616,71 +2697,19 @@ void Simulator::DecodeTypeRegisterSRsType() { ...@@ -2616,71 +2697,19 @@ void Simulator::DecodeTypeRegisterSRsType() {
} }
case MINA: case MINA:
DCHECK(kArchVariant == kMips64r6); DCHECK(kArchVariant == kMips64r6);
fs = get_fpu_register_float(fs_reg()); set_fpu_register_float(fd_reg(), FPUMinA(ft, fs));
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);
}
break; break;
case MAXA: case MAXA:
DCHECK(kArchVariant == kMips64r6); DCHECK(kArchVariant == kMips64r6);
fs = get_fpu_register_float(fs_reg()); set_fpu_register_float(fd_reg(), FPUMaxA(ft, fs));
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);
}
break; break;
case MIN: case MIN:
DCHECK(kArchVariant == kMips64r6); DCHECK(kArchVariant == kMips64r6);
fs = get_fpu_register_float(fs_reg()); set_fpu_register_float(fd_reg(), FPUMin(ft, fs));
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);
}
break; break;
case MAX: case MAX:
DCHECK(kArchVariant == kMips64r6); DCHECK(kArchVariant == kMips64r6);
fs = get_fpu_register_float(fs_reg()); set_fpu_register_float(fd_reg(), FPUMax(ft, fs));
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);
}
break; break;
case SEL: case SEL:
DCHECK(kArchVariant == kMips64r6); DCHECK(kArchVariant == kMips64r6);
...@@ -2825,71 +2854,19 @@ void Simulator::DecodeTypeRegisterDRsType() { ...@@ -2825,71 +2854,19 @@ void Simulator::DecodeTypeRegisterDRsType() {
} }
case MINA: case MINA:
DCHECK(kArchVariant == kMips64r6); DCHECK(kArchVariant == kMips64r6);
fs = get_fpu_register_double(fs_reg()); set_fpu_register_double(fd_reg(), FPUMinA(ft, fs));
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);
}
break; break;
case MAXA: case MAXA:
DCHECK(kArchVariant == kMips64r6); DCHECK(kArchVariant == kMips64r6);
fs = get_fpu_register_double(fs_reg()); set_fpu_register_double(fd_reg(), FPUMaxA(ft, fs));
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);
}
break; break;
case MIN: case MIN:
DCHECK(kArchVariant == kMips64r6); DCHECK(kArchVariant == kMips64r6);
fs = get_fpu_register_double(fs_reg()); set_fpu_register_double(fd_reg(), FPUMin(ft, fs));
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);
}
break; break;
case MAX: case MAX:
DCHECK(kArchVariant == kMips64r6); DCHECK(kArchVariant == kMips64r6);
fs = get_fpu_register_double(fs_reg()); set_fpu_register_double(fd_reg(), FPUMax(ft, fs));
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);
}
break; break;
case ADD_D: case ADD_D:
set_fpu_register_double(fd_reg(), fs + ft); set_fpu_register_double(fd_reg(), fs + ft);
......
...@@ -315,6 +315,24 @@ class Simulator { ...@@ -315,6 +315,24 @@ class Simulator {
inline int32_t SetDoubleHIW(double* addr); inline int32_t SetDoubleHIW(double* addr);
inline int32_t SetDoubleLOW(double* addr); inline int32_t SetDoubleLOW(double* addr);
// Min/Max template functions for Double and Single arguments.
enum class IsMin : int { kMin = 0, kMax = 1 };
template <typename T>
bool FPUProcessNaNsAndZeros(T a, T b, IsMin min, T& result);
template <typename T>
T FPUMin(T a, T b);
template <typename T>
T FPUMax(T a, T b);
template <typename T>
T FPUMinA(T a, T b);
template <typename T>
T FPUMaxA(T a, T b);
// functions called from DecodeTypeRegister. // functions called from DecodeTypeRegister.
void DecodeTypeRegisterCOP1(); void DecodeTypeRegisterCOP1();
......
...@@ -1456,10 +1456,10 @@ TEST(min_max) { ...@@ -1456,10 +1456,10 @@ TEST(min_max) {
CcTest::InitializeVM(); CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate(); Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate); HandleScope scope(isolate);
MacroAssembler assm(isolate, NULL, 0, MacroAssembler assm(isolate, nullptr, 0,
v8::internal::CodeObjectRequired::kYes); v8::internal::CodeObjectRequired::kYes);
typedef struct test_float { struct TestFloat {
double a; double a;
double b; double b;
double c; double c;
...@@ -1468,21 +1468,35 @@ TEST(min_max) { ...@@ -1468,21 +1468,35 @@ TEST(min_max) {
float f; float f;
float g; float g;
float h; float h;
} TestFloat; };
TestFloat test; TestFloat test;
const double double_nan = std::numeric_limits<double>::quiet_NaN(); const double dnan = std::numeric_limits<double>::quiet_NaN();
const float float_nan = std::numeric_limits<float>::quiet_NaN(); const double dinf = std::numeric_limits<double>::infinity();
const int kTableLength = 5; const double dminf = -std::numeric_limits<double>::infinity();
double inputsa[kTableLength] = {2.0, 3.0, double_nan, 3.0, double_nan}; const float fnan = std::numeric_limits<float>::quiet_NaN();
double inputsb[kTableLength] = {3.0, 2.0, 3.0, double_nan, double_nan}; const float finf = std::numeric_limits<float>::infinity();
double outputsdmin[kTableLength] = {2.0, 2.0, 3.0, 3.0, double_nan}; const float fminf = std::numeric_limits<float>::infinity();
double outputsdmax[kTableLength] = {3.0, 3.0, 3.0, 3.0, double_nan}; const int kTableLength = 13;
double inputsa[kTableLength] = {2.0, 3.0, dnan, 3.0, -0.0, 0.0, dinf,
float inputse[kTableLength] = {2.0, 3.0, float_nan, 3.0, float_nan}; dnan, 42.0, dinf, dminf, dinf, dnan};
float inputsf[kTableLength] = {3.0, 2.0, 3.0, float_nan, float_nan}; double inputsb[kTableLength] = {3.0, 2.0, 3.0, dnan, 0.0, -0.0, dnan,
float outputsfmin[kTableLength] = {2.0, 2.0, 3.0, 3.0, float_nan}; dinf, dinf, 42.0, dinf, dminf, dnan};
float outputsfmax[kTableLength] = {3.0, 3.0, 3.0, 3.0, float_nan}; double outputsdmin[kTableLength] = {2.0, 2.0, 3.0, 3.0, -0.0,
-0.0, dinf, dinf, 42.0, 42.0,
dminf, dminf, dnan};
double outputsdmax[kTableLength] = {3.0, 3.0, 3.0, 3.0, 0.0, 0.0, dinf,
dinf, dinf, dinf, dinf, dinf, dnan};
float inputse[kTableLength] = {2.0, 3.0, fnan, 3.0, -0.0, 0.0, finf,
fnan, 42.0, finf, fminf, finf, fnan};
float inputsf[kTableLength] = {3.0, 2.0, 3.0, fnan, -0.0, 0.0, fnan,
finf, finf, 42.0, finf, fminf, fnan};
float outputsfmin[kTableLength] = {2.0, 2.0, 3.0, 3.0, -0.0,
-0.0, finf, finf, 42.0, 42.0,
fminf, fminf, fnan};
float outputsfmax[kTableLength] = {3.0, 3.0, 3.0, 3.0, 0.0, 0.0, finf,
finf, finf, finf, finf, finf, fnan};
__ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a))); __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)));
__ ldc1(f8, MemOperand(a0, offsetof(TestFloat, b))); __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, b)));
...@@ -1863,16 +1877,20 @@ TEST(Cvt_d_uw) { ...@@ -1863,16 +1877,20 @@ TEST(Cvt_d_uw) {
TEST(mina_maxa) { TEST(mina_maxa) {
if (IsMipsArchVariant(kMips32r6)) { if (IsMipsArchVariant(kMips32r6)) {
const int kTableLength = 15; const int kTableLength = 23;
CcTest::InitializeVM(); CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate(); Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate); HandleScope scope(isolate);
MacroAssembler assm(isolate, NULL, 0, MacroAssembler assm(isolate, nullptr, 0,
v8::internal::CodeObjectRequired::kYes); v8::internal::CodeObjectRequired::kYes);
const double double_nan = std::numeric_limits<double>::quiet_NaN(); const double dnan = std::numeric_limits<double>::quiet_NaN();
const float float_nan = std::numeric_limits<float>::quiet_NaN(); const double dinf = std::numeric_limits<double>::infinity();
const double dminf = -std::numeric_limits<double>::infinity();
typedef struct test_float { const float fnan = std::numeric_limits<float>::quiet_NaN();
const float finf = std::numeric_limits<float>::infinity();
const float fminf = std::numeric_limits<float>::infinity();
struct TestFloat {
double a; double a;
double b; double b;
double resd; double resd;
...@@ -1881,41 +1899,34 @@ TEST(mina_maxa) { ...@@ -1881,41 +1899,34 @@ TEST(mina_maxa) {
float d; float d;
float resf; float resf;
float resf1; float resf1;
}TestFloat; };
TestFloat test; TestFloat test;
double inputsa[kTableLength] = { double inputsa[kTableLength] = {
5.3, 4.8, 6.1, 9.8, 9.8, 9.8, -10.0, -8.9, 5.3, 4.8, 6.1, 9.8, 9.8, 9.8, -10.0, -8.9, -9.8, -10.0, -8.9, -9.8,
-9.8, -10.0, -8.9, -9.8, double_nan, 3.0, double_nan dnan, 3.0, -0.0, 0.0, dinf, dnan, 42.0, dinf, dminf, dinf, dnan};
};
double inputsb[kTableLength] = { double inputsb[kTableLength] = {
4.8, 5.3, 6.1, -10.0, -8.9, -9.8, 9.8, 9.8, 4.8, 5.3, 6.1, -10.0, -8.9, -9.8, 9.8, 9.8, 9.8, -9.8, -11.2, -9.8,
9.8, -9.8, -11.2, -9.8, 3.0, double_nan, double_nan 3.0, dnan, 0.0, -0.0, dnan, dinf, dinf, 42.0, dinf, dminf, dnan};
};
double resd[kTableLength] = { double resd[kTableLength] = {
4.8, 4.8, 6.1, 9.8, -8.9, -9.8, 9.8, -8.9, 4.8, 4.8, 6.1, 9.8, -8.9, -9.8, 9.8, -8.9, -9.8, -9.8, -8.9, -9.8,
-9.8, -9.8, -8.9, -9.8, 3.0, 3.0, double_nan 3.0, 3.0, -0.0, -0.0, dinf, dinf, 42.0, 42.0, dminf, dminf, dnan};
};
double resd1[kTableLength] = { double resd1[kTableLength] = {
5.3, 5.3, 6.1, -10.0, 9.8, 9.8, -10.0, 9.8, 5.3, 5.3, 6.1, -10.0, 9.8, 9.8, -10.0, 9.8, 9.8, -10.0, -11.2, -9.8,
9.8, -10.0, -11.2, -9.8, 3.0, 3.0, double_nan 3.0, 3.0, 0.0, 0.0, dinf, dinf, dinf, dinf, dinf, dinf, dnan};
};
float inputsc[kTableLength] = { float inputsc[kTableLength] = {
5.3, 4.8, 6.1, 9.8, 9.8, 9.8, -10.0, -8.9, 5.3, 4.8, 6.1, 9.8, 9.8, 9.8, -10.0, -8.9, -9.8, -10.0, -8.9, -9.8,
-9.8, -10.0, -8.9, -9.8, float_nan, 3.0, float_nan fnan, 3.0, -0.0, 0.0, finf, fnan, 42.0, finf, fminf, finf, fnan};
}; float inputsd[kTableLength] = {4.8, 5.3, 6.1, -10.0, -8.9, -9.8,
float inputsd[kTableLength] = { 9.8, 9.8, 9.8, -9.8, -11.2, -9.8,
4.8, 5.3, 6.1, -10.0, -8.9, -9.8, 9.8, 9.8, 3.0, fnan, -0.0, 0.0, fnan, finf,
9.8, -9.8, -11.2, -9.8, 3.0, float_nan, float_nan finf, 42.0, finf, fminf, fnan};
};
float resf[kTableLength] = { float resf[kTableLength] = {
4.8, 4.8, 6.1, 9.8, -8.9, -9.8, 9.8, -8.9, 4.8, 4.8, 6.1, 9.8, -8.9, -9.8, 9.8, -8.9, -9.8, -9.8, -8.9, -9.8,
-9.8, -9.8, -8.9, -9.8, 3.0, 3.0, float_nan 3.0, 3.0, -0.0, -0.0, finf, finf, 42.0, 42.0, fminf, fminf, fnan};
};
float resf1[kTableLength] = { float resf1[kTableLength] = {
5.3, 5.3, 6.1, -10.0, 9.8, 9.8, -10.0, 9.8, 5.3, 5.3, 6.1, -10.0, 9.8, 9.8, -10.0, 9.8, 9.8, -10.0, -11.2, -9.8,
9.8, -10.0, -11.2, -9.8, 3.0, 3.0, float_nan 3.0, 3.0, 0.0, 0.0, finf, finf, finf, finf, finf, finf, fnan};
};
__ ldc1(f2, MemOperand(a0, offsetof(TestFloat, a)) ); __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
__ ldc1(f4, MemOperand(a0, offsetof(TestFloat, b)) ); __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, b)) );
......
...@@ -1586,10 +1586,10 @@ TEST(min_max) { ...@@ -1586,10 +1586,10 @@ TEST(min_max) {
CcTest::InitializeVM(); CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate(); Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate); HandleScope scope(isolate);
MacroAssembler assm(isolate, NULL, 0, MacroAssembler assm(isolate, nullptr, 0,
v8::internal::CodeObjectRequired::kYes); v8::internal::CodeObjectRequired::kYes);
typedef struct test_float { struct TestFloat {
double a; double a;
double b; double b;
double c; double c;
...@@ -1598,21 +1598,35 @@ TEST(min_max) { ...@@ -1598,21 +1598,35 @@ TEST(min_max) {
float f; float f;
float g; float g;
float h; float h;
} TestFloat; };
TestFloat test; TestFloat test;
const double double_nan = std::numeric_limits<double>::quiet_NaN(); const double dnan = std::numeric_limits<double>::quiet_NaN();
const float float_nan = std::numeric_limits<float>::quiet_NaN(); const double dinf = std::numeric_limits<double>::infinity();
const int kTableLength = 5; const double dminf = -std::numeric_limits<double>::infinity();
double inputsa[kTableLength] = {2.0, 3.0, double_nan, 3.0, double_nan}; const float fnan = std::numeric_limits<float>::quiet_NaN();
double inputsb[kTableLength] = {3.0, 2.0, 3.0, double_nan, double_nan}; const float finf = std::numeric_limits<float>::infinity();
double outputsdmin[kTableLength] = {2.0, 2.0, 3.0, 3.0, double_nan}; const float fminf = std::numeric_limits<float>::infinity();
double outputsdmax[kTableLength] = {3.0, 3.0, 3.0, 3.0, double_nan}; const int kTableLength = 13;
double inputsa[kTableLength] = {2.0, 3.0, dnan, 3.0, -0.0, 0.0, dinf,
float inputse[kTableLength] = {2.0, 3.0, float_nan, 3.0, float_nan}; dnan, 42.0, dinf, dminf, dinf, dnan};
float inputsf[kTableLength] = {3.0, 2.0, 3.0, float_nan, float_nan}; double inputsb[kTableLength] = {3.0, 2.0, 3.0, dnan, 0.0, -0.0, dnan,
float outputsfmin[kTableLength] = {2.0, 2.0, 3.0, 3.0, float_nan}; dinf, dinf, 42.0, dinf, dminf, dnan};
float outputsfmax[kTableLength] = {3.0, 3.0, 3.0, 3.0, float_nan}; double outputsdmin[kTableLength] = {2.0, 2.0, 3.0, 3.0, -0.0,
-0.0, dinf, dinf, 42.0, 42.0,
dminf, dminf, dnan};
double outputsdmax[kTableLength] = {3.0, 3.0, 3.0, 3.0, 0.0, 0.0, dinf,
dinf, dinf, dinf, dinf, dinf, dnan};
float inputse[kTableLength] = {2.0, 3.0, fnan, 3.0, -0.0, 0.0, finf,
fnan, 42.0, finf, fminf, finf, fnan};
float inputsf[kTableLength] = {3.0, 2.0, 3.0, fnan, -0.0, 0.0, fnan,
finf, finf, 42.0, finf, fminf, fnan};
float outputsfmin[kTableLength] = {2.0, 2.0, 3.0, 3.0, -0.0,
-0.0, finf, finf, 42.0, 42.0,
fminf, fminf, fnan};
float outputsfmax[kTableLength] = {3.0, 3.0, 3.0, 3.0, 0.0, 0.0, finf,
finf, finf, finf, finf, finf, fnan};
__ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a))); __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, a)));
__ ldc1(f8, MemOperand(a0, offsetof(TestFloat, b))); __ ldc1(f8, MemOperand(a0, offsetof(TestFloat, b)));
...@@ -1946,16 +1960,20 @@ TEST(rint_s) { ...@@ -1946,16 +1960,20 @@ TEST(rint_s) {
TEST(mina_maxa) { TEST(mina_maxa) {
if (kArchVariant == kMips64r6) { if (kArchVariant == kMips64r6) {
const int kTableLength = 15; const int kTableLength = 23;
CcTest::InitializeVM(); CcTest::InitializeVM();
Isolate* isolate = CcTest::i_isolate(); Isolate* isolate = CcTest::i_isolate();
HandleScope scope(isolate); HandleScope scope(isolate);
MacroAssembler assm(isolate, NULL, 0, MacroAssembler assm(isolate, nullptr, 0,
v8::internal::CodeObjectRequired::kYes); v8::internal::CodeObjectRequired::kYes);
const double double_nan = std::numeric_limits<double>::quiet_NaN(); const double dnan = std::numeric_limits<double>::quiet_NaN();
const float float_nan = std::numeric_limits<float>::quiet_NaN(); const double dinf = std::numeric_limits<double>::infinity();
const double dminf = -std::numeric_limits<double>::infinity();
typedef struct test_float { const float fnan = std::numeric_limits<float>::quiet_NaN();
const float finf = std::numeric_limits<float>::infinity();
const float fminf = std::numeric_limits<float>::infinity();
struct TestFloat {
double a; double a;
double b; double b;
double resd; double resd;
...@@ -1964,41 +1982,34 @@ TEST(mina_maxa) { ...@@ -1964,41 +1982,34 @@ TEST(mina_maxa) {
float d; float d;
float resf; float resf;
float resf1; float resf1;
}TestFloat; };
TestFloat test; TestFloat test;
double inputsa[kTableLength] = { double inputsa[kTableLength] = {
5.3, 4.8, 6.1, 9.8, 9.8, 9.8, -10.0, -8.9, 5.3, 4.8, 6.1, 9.8, 9.8, 9.8, -10.0, -8.9, -9.8, -10.0, -8.9, -9.8,
-9.8, -10.0, -8.9, -9.8, double_nan, 3.0, double_nan dnan, 3.0, -0.0, 0.0, dinf, dnan, 42.0, dinf, dminf, dinf, dnan};
};
double inputsb[kTableLength] = { double inputsb[kTableLength] = {
4.8, 5.3, 6.1, -10.0, -8.9, -9.8, 9.8, 9.8, 4.8, 5.3, 6.1, -10.0, -8.9, -9.8, 9.8, 9.8, 9.8, -9.8, -11.2, -9.8,
9.8, -9.8, -11.2, -9.8, 3.0, double_nan, double_nan 3.0, dnan, 0.0, -0.0, dnan, dinf, dinf, 42.0, dinf, dminf, dnan};
};
double resd[kTableLength] = { double resd[kTableLength] = {
4.8, 4.8, 6.1, 9.8, -8.9, -9.8, 9.8, -8.9, 4.8, 4.8, 6.1, 9.8, -8.9, -9.8, 9.8, -8.9, -9.8, -9.8, -8.9, -9.8,
-9.8, -9.8, -8.9, -9.8, 3.0, 3.0, double_nan 3.0, 3.0, -0.0, -0.0, dinf, dinf, 42.0, 42.0, dminf, dminf, dnan};
};
double resd1[kTableLength] = { double resd1[kTableLength] = {
5.3, 5.3, 6.1, -10.0, 9.8, 9.8, -10.0, 9.8, 5.3, 5.3, 6.1, -10.0, 9.8, 9.8, -10.0, 9.8, 9.8, -10.0, -11.2, -9.8,
9.8, -10.0, -11.2, -9.8, 3.0, 3.0, double_nan 3.0, 3.0, 0.0, 0.0, dinf, dinf, dinf, dinf, dinf, dinf, dnan};
};
float inputsc[kTableLength] = { float inputsc[kTableLength] = {
5.3, 4.8, 6.1, 9.8, 9.8, 9.8, -10.0, -8.9, 5.3, 4.8, 6.1, 9.8, 9.8, 9.8, -10.0, -8.9, -9.8, -10.0, -8.9, -9.8,
-9.8, -10.0, -8.9, -9.8, float_nan, 3.0, float_nan fnan, 3.0, -0.0, 0.0, finf, fnan, 42.0, finf, fminf, finf, fnan};
}; float inputsd[kTableLength] = {4.8, 5.3, 6.1, -10.0, -8.9, -9.8,
float inputsd[kTableLength] = { 9.8, 9.8, 9.8, -9.8, -11.2, -9.8,
4.8, 5.3, 6.1, -10.0, -8.9, -9.8, 9.8, 9.8, 3.0, fnan, -0.0, 0.0, fnan, finf,
9.8, -9.8, -11.2, -9.8, 3.0, float_nan, float_nan finf, 42.0, finf, fminf, fnan};
};
float resf[kTableLength] = { float resf[kTableLength] = {
4.8, 4.8, 6.1, 9.8, -8.9, -9.8, 9.8, -8.9, 4.8, 4.8, 6.1, 9.8, -8.9, -9.8, 9.8, -8.9, -9.8, -9.8, -8.9, -9.8,
-9.8, -9.8, -8.9, -9.8, 3.0, 3.0, float_nan 3.0, 3.0, -0.0, -0.0, finf, finf, 42.0, 42.0, fminf, fminf, fnan};
};
float resf1[kTableLength] = { float resf1[kTableLength] = {
5.3, 5.3, 6.1, -10.0, 9.8, 9.8, -10.0, 9.8, 5.3, 5.3, 6.1, -10.0, 9.8, 9.8, -10.0, 9.8, 9.8, -10.0, -11.2, -9.8,
9.8, -10.0, -11.2, -9.8, 3.0, 3.0, float_nan 3.0, 3.0, 0.0, 0.0, finf, finf, finf, finf, finf, finf, fnan};
};
__ ldc1(f2, MemOperand(a0, offsetof(TestFloat, a)) ); __ ldc1(f2, MemOperand(a0, offsetof(TestFloat, a)) );
__ ldc1(f4, MemOperand(a0, offsetof(TestFloat, b)) ); __ ldc1(f4, MemOperand(a0, offsetof(TestFloat, b)) );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment