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

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

Issue 1143473003: Revert of MIPS: Add float instructions and test coverage, part one (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 7 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 ed0ef3a26c89a26d4a5491f7fdb1e6e068f0d88e..29fccd0b5974b8d5b81f2002f0d4fd6656d65866 100644
--- a/src/mips64/simulator-mips64.cc
+++ b/src/mips64/simulator-mips64.cc
@@ -1188,16 +1188,6 @@ bool Simulator::test_fcsr_bit(uint32_t cc) {
}
-void Simulator::set_fcsr_rounding_mode(FPURoundingMode mode) {
- FCSR_ |= mode & kFPURoundingModeMask;
-}
-
-
-unsigned int Simulator::get_fcsr_rounding_mode() {
- return FCSR_ & kFPURoundingModeMask;
-}
-
-
// 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) {
@@ -1219,7 +1209,7 @@ bool Simulator::set_fcsr_round_error(double original, double rounded) {
ret = true;
}
- if (rounded >= max_int32 || rounded <= min_int32) {
+ if (rounded > max_int32 || rounded < min_int32) {
set_fcsr_bit(kFCSROverflowFlagBit, true);
// The reference is not really clear but it seems this is required:
set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
@@ -1251,69 +1241,7 @@ bool Simulator::set_fcsr_round64_error(double original, double rounded) {
ret = true;
}
- if (rounded >= max_int64 || rounded <= min_int64) {
- 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;
-}
-
-
-bool Simulator::set_fcsr_round_error(float original, float rounded) {
- bool ret = false;
- double max_int32 = std::numeric_limits<int32_t>::max();
- double min_int32 = std::numeric_limits<int32_t>::min();
-
- if (!std::isfinite(original) || !std::isfinite(rounded)) {
- set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
- ret = true;
- }
-
- if (original != rounded) {
- set_fcsr_bit(kFCSRInexactFlagBit, true);
- }
-
- if (rounded < FLT_MIN && rounded > -FLT_MIN && rounded != 0) {
- set_fcsr_bit(kFCSRUnderflowFlagBit, true);
- ret = true;
- }
-
- if (rounded >= max_int32 || rounded <= min_int32) {
- 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;
-}
-
-
-// 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_round64_error(float original, float rounded) {
- bool ret = false;
- double max_int64 = std::numeric_limits<int64_t>::max();
- double min_int64 = std::numeric_limits<int64_t>::min();
-
- if (!std::isfinite(original) || !std::isfinite(rounded)) {
- set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
- ret = true;
- }
-
- if (original != rounded) {
- set_fcsr_bit(kFCSRInexactFlagBit, true);
- }
-
- if (rounded < FLT_MIN && rounded > -FLT_MIN && rounded != 0) {
- set_fcsr_bit(kFCSRUnderflowFlagBit, true);
- ret = true;
- }
-
- if (rounded >= max_int64 || rounded <= min_int64) {
+ if (rounded > max_int64 || rounded < min_int64) {
set_fcsr_bit(kFCSROverflowFlagBit, true);
// The reference is not really clear but it seems this is required:
set_fcsr_bit(kFCSRInvalidOpFlagBit, true);
@@ -2428,88 +2356,37 @@ void Simulator::DecodeTypeRegisterSRsType(Instruction* instr,
const int32_t& fs_reg,
const int32_t& ft_reg,
const int32_t& fd_reg) {
- float fs, ft, fd;
+ float fs, ft;
fs = get_fpu_register_float(fs_reg);
ft = get_fpu_register_float(ft_reg);
- fd = get_fpu_register_float(fd_reg);
- int32_t ft_int = bit_cast<int32_t>(ft);
- int32_t fd_int = bit_cast<int32_t>(fd);
uint32_t cc, fcsr_cc;
cc = instr->FCccValue();
fcsr_cc = get_fcsr_condition_bit(cc);
switch (instr->FunctionFieldRaw()) {
- case RINT: {
- DCHECK(kArchVariant == kMips64r6);
- float result, temp_result;
- double temp;
- float upper = std::ceil(fs);
- float lower = std::floor(fs);
- switch (get_fcsr_rounding_mode()) {
- case kRoundToNearest:
- if (upper - fs < fs - lower) {
- result = upper;
- } else if (upper - fs > fs - lower) {
- result = lower;
- } else {
- temp_result = upper / 2;
- float reminder = modf(temp_result, &temp);
- if (reminder == 0) {
- result = upper;
- } else {
- result = lower;
- }
- }
- break;
- case kRoundToZero:
- result = (fs > 0 ? lower : upper);
- break;
- case kRoundToPlusInf:
- result = upper;
- break;
- case kRoundToMinusInf:
- result = lower;
- break;
- }
- set_fpu_register_float(fd_reg, result);
- if (result != fs) {
- set_fcsr_bit(kFCSRInexactFlagBit, true);
- }
- break;
- }
- case ADD_S:
+ case ADD_D:
set_fpu_register_float(fd_reg, fs + ft);
break;
- case SUB_S:
+ case SUB_D:
set_fpu_register_float(fd_reg, fs - ft);
break;
- case MUL_S:
+ case MUL_D:
set_fpu_register_float(fd_reg, fs * ft);
break;
- case DIV_S:
+ case DIV_D:
set_fpu_register_float(fd_reg, fs / ft);
break;
- case ABS_S:
+ case ABS_D:
set_fpu_register_float(fd_reg, fabs(fs));
break;
- case MOV_S:
+ case MOV_D:
set_fpu_register_float(fd_reg, fs);
break;
- case NEG_S:
+ case NEG_D:
set_fpu_register_float(fd_reg, -fs);
break;
- case SQRT_S:
+ case SQRT_D:
set_fpu_register_float(fd_reg, fast_sqrt(fs));
break;
- case RSQRT_S: {
- float result = 1.0 / fast_sqrt(fs);
- set_fpu_register_float(fd_reg, result);
- break;
- }
- case RECIP_S: {
- float result = 1.0 / fs;
- set_fpu_register_float(fd_reg, result);
- break;
- }
case C_UN_D:
set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft));
break;
@@ -2534,202 +2411,6 @@ void Simulator::DecodeTypeRegisterSRsType(Instruction* instr,
case CVT_D_S:
set_fpu_register_double(fd_reg, static_cast<double>(fs));
break;
- case TRUNC_W_S: { // Truncate single to word (round towards 0).
- float rounded = trunc(fs);
- int32_t result = static_cast<int32_t>(rounded);
- set_fpu_register_word(fd_reg, result);
- if (set_fcsr_round_error(fs, rounded)) {
- set_fpu_register_word(fd_reg, kFPUInvalidResult);
- }
- } break;
- case TRUNC_L_S: { // Mips64r2 instruction.
- float rounded = trunc(fs);
- int64_t result = static_cast<int64_t>(rounded);
- set_fpu_register(fd_reg, result);
- if (set_fcsr_round64_error(fs, rounded)) {
- set_fpu_register(fd_reg, kFPU64InvalidResult);
- }
- break;
- }
- case ROUND_W_S: {
- float rounded = std::floor(fs + 0.5);
- int32_t result = static_cast<int32_t>(rounded);
- if ((result & 1) != 0 && result - fs == 0.5) {
- // If the number is halfway between two integers,
- // round to the even one.
- result--;
- }
- set_fpu_register_word(fd_reg, result);
- if (set_fcsr_round_error(fs, rounded)) {
- set_fpu_register_word(fd_reg, kFPUInvalidResult);
- }
- break;
- }
- case ROUND_L_S: { // Mips64r2 instruction.
- float rounded = std::floor(fs + 0.5);
- int64_t result = static_cast<int64_t>(rounded);
- if ((result & 1) != 0 && result - fs == 0.5) {
- // If the number is halfway between two integers,
- // round to the even one.
- result--;
- }
- int64_t i64 = static_cast<int64_t>(result);
- set_fpu_register(fd_reg, i64);
- if (set_fcsr_round64_error(fs, rounded)) {
- set_fpu_register(fd_reg, kFPU64InvalidResult);
- }
- break;
- }
- case FLOOR_L_S: { // Mips64r2 instruction.
- float rounded = floor(fs);
- int64_t result = static_cast<int64_t>(rounded);
- set_fpu_register(fd_reg, result);
- if (set_fcsr_round64_error(fs, rounded)) {
- set_fpu_register(fd_reg, kFPU64InvalidResult);
- }
- break;
- }
- case FLOOR_W_S: // Round double to word towards negative infinity.
- {
- float rounded = std::floor(fs);
- int32_t result = static_cast<int32_t>(rounded);
- set_fpu_register_word(fd_reg, result);
- if (set_fcsr_round_error(fs, rounded)) {
- set_fpu_register_word(fd_reg, kFPUInvalidResult);
- }
- } break;
- case CEIL_W_S: // Round double to word towards positive infinity.
- {
- float rounded = std::ceil(fs);
- int32_t result = static_cast<int32_t>(rounded);
- set_fpu_register_word(fd_reg, result);
- if (set_fcsr_round_error(fs, rounded)) {
- set_fpu_register(fd_reg, kFPUInvalidResult);
- }
- } break;
- case CEIL_L_S: { // Mips64r2 instruction.
- float rounded = ceil(fs);
- int64_t result = static_cast<int64_t>(rounded);
- set_fpu_register(fd_reg, result);
- if (set_fcsr_round64_error(fs, rounded)) {
- set_fpu_register(fd_reg, kFPU64InvalidResult);
- }
- break;
- }
- 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);
- }
- 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);
- }
- 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);
- }
- 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);
- }
- break;
- case SEL:
- DCHECK(kArchVariant == kMips64r6);
- set_fpu_register_float(fd_reg, (fd_int & 0x1) == 0 ? fs : ft);
- break;
- case SELEQZ_C:
- DCHECK(kArchVariant == kMips64r6);
- set_fpu_register_float(
- fd_reg, (ft_int & 0x1) == 0 ? get_fpu_register_float(fs_reg) : 0.0);
- break;
- case SELNEZ_C:
- DCHECK(kArchVariant == kMips64r6);
- set_fpu_register_float(
- fd_reg, (ft_int & 0x1) != 0 ? get_fpu_register_float(fs_reg) : 0.0);
- break;
- case MOVZ_C: {
- DCHECK(kArchVariant == kMips64r2);
- int32_t rt_reg = instr->RtValue();
- int64_t rt = get_register(rt_reg);
- if (rt == 0) {
- set_fpu_register_float(fd_reg, fs);
- }
- break;
- }
- case MOVN_C: {
- DCHECK(kArchVariant == kMips64r2);
- int32_t rt_reg = instr->RtValue();
- int64_t rt = get_register(rt_reg);
- if (rt != 0) {
- set_fpu_register_float(fd_reg, fs);
- }
- break;
- }
- case MOVF: {
- // Same function field for MOVT.D and MOVF.D
- uint32_t ft_cc = (ft_reg >> 2) & 0x7;
- ft_cc = get_fcsr_condition_bit(ft_cc);
-
- if (instr->Bit(16)) { // Read Tf bit.
- // MOVT.D
- if (test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg, fs);
- } else {
- // MOVF.D
- if (!test_fcsr_bit(ft_cc)) set_fpu_register_float(fd_reg, fs);
- }
- break;
- }
default:
// CVT_W_S CVT_L_S TRUNC_W_S ROUND_W_S ROUND_L_S FLOOR_W_S FLOOR_L_S
// CEIL_W_S CEIL_L_S CVT_PS_S are unimplemented.
@@ -2745,9 +2426,7 @@ void Simulator::DecodeTypeRegisterDRsType(Instruction* instr,
double ft, fs, fd;
uint32_t cc, fcsr_cc;
fs = get_fpu_register_double(fs_reg);
- if (instr->FunctionFieldRaw() != MOVF) {
- ft = get_fpu_register_double(ft_reg);
- }
+ ft = get_fpu_register_double(ft_reg);
fd = get_fpu_register_double(fd_reg);
cc = instr->FCccValue();
fcsr_cc = get_fcsr_condition_bit(cc);
@@ -2759,7 +2438,7 @@ void Simulator::DecodeTypeRegisterDRsType(Instruction* instr,
double result, temp, temp_result;
double upper = std::ceil(fs);
double lower = std::floor(fs);
- switch (get_fcsr_rounding_mode()) {
+ switch (FCSR_ & 0x3) {
case kRoundToNearest:
if (upper - fs < fs - lower) {
result = upper;
@@ -2803,79 +2482,6 @@ void Simulator::DecodeTypeRegisterDRsType(Instruction* instr,
DCHECK(kArchVariant == kMips64r6);
set_fpu_register_double(fd_reg, (ft_int & 0x1) != 0 ? fs : 0.0);
break;
- case MOVZ_C: {
- DCHECK(kArchVariant == kMips64r2);
- int32_t rt_reg = instr->RtValue();
- int64_t rt = get_register(rt_reg);
- if (rt == 0) {
- set_fpu_register_double(fd_reg, fs);
- }
- break;
- }
- case MOVN_C: {
- DCHECK(kArchVariant == kMips64r2);
- int32_t rt_reg = instr->RtValue();
- int64_t rt = get_register(rt_reg);
- if (rt != 0) {
- set_fpu_register_double(fd_reg, fs);
- }
- break;
- }
- case MOVF: {
- // Same function field for MOVT.D and MOVF.D
- uint32_t ft_cc = (ft_reg >> 2) & 0x7;
- ft_cc = get_fcsr_condition_bit(ft_cc);
- if (instr->Bit(16)) { // Read Tf bit.
- // MOVT.D
- if (test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg, fs);
- } else {
- // MOVF.D
- if (!test_fcsr_bit(ft_cc)) set_fpu_register_double(fd_reg, fs);
- }
- break;
- }
- 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);
- }
- 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);
- }
- break;
case MIN:
DCHECK(kArchVariant == kMips64r6);
fs = get_fpu_register_double(fs_reg);
@@ -2926,16 +2532,6 @@ void Simulator::DecodeTypeRegisterDRsType(Instruction* instr,
case SQRT_D:
set_fpu_register_double(fd_reg, fast_sqrt(fs));
break;
- case RSQRT_D: {
- double result = 1.0 / fast_sqrt(fs);
- set_fpu_register_double(fd_reg, result);
- break;
- }
- case RECIP_D: {
- double result = 1.0 / fs;
- set_fpu_register_double(fd_reg, result);
- break;
- }
case C_UN_D:
set_fcsr_bit(fcsr_cc, std::isnan(fs) || std::isnan(ft));
break;
@@ -3022,15 +2618,10 @@ void Simulator::DecodeTypeRegisterDRsType(Instruction* instr,
break;
}
case ROUND_L_D: { // Mips64r2 instruction.
- double rounded = std::floor(fs + 0.5);
+ // check error cases
+ double rounded = fs > 0 ? floor(fs + 0.5) : ceil(fs - 0.5);
int64_t result = static_cast<int64_t>(rounded);
- if ((result & 1) != 0 && result - fs == 0.5) {
- // If the number is halfway between two integers,
- // round to the even one.
- result--;
- }
- int64_t i64 = static_cast<int64_t>(result);
- set_fpu_register(fd_reg, i64);
+ set_fpu_register(fd_reg, result);
if (set_fcsr_round64_error(fs, rounded)) {
set_fpu_register(fd_reg, kFPU64InvalidResult);
}
« 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