| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 609 int64_t src1, | 609 int64_t src1, |
| 610 int64_t src2, | 610 int64_t src2, |
| 611 int64_t carry_in) { | 611 int64_t carry_in) { |
| 612 ASSERT((carry_in == 0) || (carry_in == 1)); | 612 ASSERT((carry_in == 0) || (carry_in == 1)); |
| 613 ASSERT((reg_size == kXRegSizeInBits) || (reg_size == kWRegSizeInBits)); | 613 ASSERT((reg_size == kXRegSizeInBits) || (reg_size == kWRegSizeInBits)); |
| 614 | 614 |
| 615 uint64_t u1, u2; | 615 uint64_t u1, u2; |
| 616 int64_t result; | 616 int64_t result; |
| 617 int64_t signed_sum = src1 + src2 + carry_in; | 617 int64_t signed_sum = src1 + src2 + carry_in; |
| 618 | 618 |
| 619 uint32_t N, Z, C, V; | 619 bool N, Z, C, V; |
| 620 | 620 |
| 621 if (reg_size == kWRegSizeInBits) { | 621 if (reg_size == kWRegSizeInBits) { |
| 622 u1 = static_cast<uint64_t>(src1) & kWRegMask; | 622 u1 = static_cast<uint64_t>(src1) & kWRegMask; |
| 623 u2 = static_cast<uint64_t>(src2) & kWRegMask; | 623 u2 = static_cast<uint64_t>(src2) & kWRegMask; |
| 624 | 624 |
| 625 result = signed_sum & kWRegMask; | 625 result = signed_sum & kWRegMask; |
| 626 // Compute the C flag by comparing the sum to the max unsigned integer. | 626 // Compute the C flag by comparing the sum to the max unsigned integer. |
| 627 C = ((kWMaxUInt - u1) < (u2 + carry_in)) || | 627 C = ((kWMaxUInt - u1) < (u2 + carry_in)) || |
| 628 ((kWMaxUInt - u1 - carry_in) < u2); | 628 ((kWMaxUInt - u1 - carry_in) < u2); |
| 629 // Overflow iff the sign bit is the same for the two inputs and different | 629 // Overflow iff the sign bit is the same for the two inputs and different |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 824 // TODO(jbramley): Find a more elegant way of defining these. | 824 // TODO(jbramley): Find a more elegant way of defining these. |
| 825 char const * const clr_normal = (FLAG_log_colour) ? ("\033[m") : (""); | 825 char const * const clr_normal = (FLAG_log_colour) ? ("\033[m") : (""); |
| 826 char const * const clr_flag_name = (FLAG_log_colour) ? ("\033[1;30m") : (""); | 826 char const * const clr_flag_name = (FLAG_log_colour) ? ("\033[1;30m") : (""); |
| 827 char const * const clr_flag_value = (FLAG_log_colour) ? ("\033[1;37m") : (""); | 827 char const * const clr_flag_value = (FLAG_log_colour) ? ("\033[1;37m") : (""); |
| 828 | 828 |
| 829 static SimSystemRegister last_nzcv; | 829 static SimSystemRegister last_nzcv; |
| 830 if (print_all || first_run || (last_nzcv.RawValue() != nzcv().RawValue())) { | 830 if (print_all || first_run || (last_nzcv.RawValue() != nzcv().RawValue())) { |
| 831 fprintf(stream_, "# %sFLAGS: %sN:%d Z:%d C:%d V:%d%s\n", | 831 fprintf(stream_, "# %sFLAGS: %sN:%d Z:%d C:%d V:%d%s\n", |
| 832 clr_flag_name, | 832 clr_flag_name, |
| 833 clr_flag_value, | 833 clr_flag_value, |
| 834 N(), Z(), C(), V(), | 834 nzcv().N(), nzcv().Z(), nzcv().C(), nzcv().V(), |
| 835 clr_normal); | 835 clr_normal); |
| 836 } | 836 } |
| 837 last_nzcv = nzcv(); | 837 last_nzcv = nzcv(); |
| 838 | 838 |
| 839 static SimSystemRegister last_fpcr; | 839 static SimSystemRegister last_fpcr; |
| 840 if (print_all || first_run || (last_fpcr.RawValue() != fpcr().RawValue())) { | 840 if (print_all || first_run || (last_fpcr.RawValue() != fpcr().RawValue())) { |
| 841 static const char * rmode[] = { | 841 static const char * rmode[] = { |
| 842 "0b00 (Round to Nearest)", | 842 "0b00 (Round to Nearest)", |
| 843 "0b01 (Round towards Plus Infinity)", | 843 "0b01 (Round towards Plus Infinity)", |
| 844 "0b10 (Round towards Minus Infinity)", | 844 "0b10 (Round towards Minus Infinity)", |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1128 int64_t new_val; | 1128 int64_t new_val; |
| 1129 | 1129 |
| 1130 if ((instr->Mask(AddSubOpMask) == SUB) || instr->Mask(AddSubOpMask) == SUBS) { | 1130 if ((instr->Mask(AddSubOpMask) == SUB) || instr->Mask(AddSubOpMask) == SUBS) { |
| 1131 op2 = ~op2; | 1131 op2 = ~op2; |
| 1132 } | 1132 } |
| 1133 | 1133 |
| 1134 new_val = AddWithCarry(reg_size, | 1134 new_val = AddWithCarry(reg_size, |
| 1135 instr->FlagsUpdate(), | 1135 instr->FlagsUpdate(), |
| 1136 reg(reg_size, instr->Rn()), | 1136 reg(reg_size, instr->Rn()), |
| 1137 op2, | 1137 op2, |
| 1138 C()); | 1138 nzcv().C()); |
| 1139 | 1139 |
| 1140 set_reg(reg_size, instr->Rd(), new_val); | 1140 set_reg(reg_size, instr->Rd(), new_val); |
| 1141 } | 1141 } |
| 1142 | 1142 |
| 1143 | 1143 |
| 1144 void Simulator::VisitLogicalShifted(Instruction* instr) { | 1144 void Simulator::VisitLogicalShifted(Instruction* instr) { |
| 1145 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits | 1145 unsigned reg_size = instr->SixtyFourBits() ? kXRegSizeInBits |
| 1146 : kWRegSizeInBits; | 1146 : kWRegSizeInBits; |
| 1147 Shift shift_type = static_cast<Shift>(instr->ShiftDP()); | 1147 Shift shift_type = static_cast<Shift>(instr->ShiftDP()); |
| 1148 unsigned shift_amount = instr->ImmDPShift(); | 1148 unsigned shift_amount = instr->ImmDPShift(); |
| (...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1924 } | 1924 } |
| 1925 } | 1925 } |
| 1926 | 1926 |
| 1927 | 1927 |
| 1928 void Simulator::VisitFPIntegerConvert(Instruction* instr) { | 1928 void Simulator::VisitFPIntegerConvert(Instruction* instr) { |
| 1929 AssertSupportedFPCR(); | 1929 AssertSupportedFPCR(); |
| 1930 | 1930 |
| 1931 unsigned dst = instr->Rd(); | 1931 unsigned dst = instr->Rd(); |
| 1932 unsigned src = instr->Rn(); | 1932 unsigned src = instr->Rn(); |
| 1933 | 1933 |
| 1934 FPRounding round = RMode(); | 1934 FPRounding round = fpcr().RMode(); |
| 1935 | 1935 |
| 1936 switch (instr->Mask(FPIntegerConvertMask)) { | 1936 switch (instr->Mask(FPIntegerConvertMask)) { |
| 1937 case FCVTAS_ws: set_wreg(dst, FPToInt32(sreg(src), FPTieAway)); break; | 1937 case FCVTAS_ws: set_wreg(dst, FPToInt32(sreg(src), FPTieAway)); break; |
| 1938 case FCVTAS_xs: set_xreg(dst, FPToInt64(sreg(src), FPTieAway)); break; | 1938 case FCVTAS_xs: set_xreg(dst, FPToInt64(sreg(src), FPTieAway)); break; |
| 1939 case FCVTAS_wd: set_wreg(dst, FPToInt32(dreg(src), FPTieAway)); break; | 1939 case FCVTAS_wd: set_wreg(dst, FPToInt32(dreg(src), FPTieAway)); break; |
| 1940 case FCVTAS_xd: set_xreg(dst, FPToInt64(dreg(src), FPTieAway)); break; | 1940 case FCVTAS_xd: set_xreg(dst, FPToInt64(dreg(src), FPTieAway)); break; |
| 1941 case FCVTAU_ws: set_wreg(dst, FPToUInt32(sreg(src), FPTieAway)); break; | 1941 case FCVTAU_ws: set_wreg(dst, FPToUInt32(sreg(src), FPTieAway)); break; |
| 1942 case FCVTAU_xs: set_xreg(dst, FPToUInt64(sreg(src), FPTieAway)); break; | 1942 case FCVTAU_xs: set_xreg(dst, FPToUInt64(sreg(src), FPTieAway)); break; |
| 1943 case FCVTAU_wd: set_wreg(dst, FPToUInt32(dreg(src), FPTieAway)); break; | 1943 case FCVTAU_wd: set_wreg(dst, FPToUInt32(dreg(src), FPTieAway)); break; |
| 1944 case FCVTAU_xd: set_xreg(dst, FPToUInt64(dreg(src), FPTieAway)); break; | 1944 case FCVTAU_xd: set_xreg(dst, FPToUInt64(dreg(src), FPTieAway)); break; |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2009 } | 2009 } |
| 2010 | 2010 |
| 2011 | 2011 |
| 2012 void Simulator::VisitFPFixedPointConvert(Instruction* instr) { | 2012 void Simulator::VisitFPFixedPointConvert(Instruction* instr) { |
| 2013 AssertSupportedFPCR(); | 2013 AssertSupportedFPCR(); |
| 2014 | 2014 |
| 2015 unsigned dst = instr->Rd(); | 2015 unsigned dst = instr->Rd(); |
| 2016 unsigned src = instr->Rn(); | 2016 unsigned src = instr->Rn(); |
| 2017 int fbits = 64 - instr->FPScale(); | 2017 int fbits = 64 - instr->FPScale(); |
| 2018 | 2018 |
| 2019 FPRounding round = RMode(); | 2019 FPRounding round = fpcr().RMode(); |
| 2020 | 2020 |
| 2021 switch (instr->Mask(FPFixedPointConvertMask)) { | 2021 switch (instr->Mask(FPFixedPointConvertMask)) { |
| 2022 // A 32-bit input can be handled in the same way as a 64-bit input, since | 2022 // A 32-bit input can be handled in the same way as a 64-bit input, since |
| 2023 // the sign- or zero-extension will not affect the conversion. | 2023 // the sign- or zero-extension will not affect the conversion. |
| 2024 case SCVTF_dx_fixed: | 2024 case SCVTF_dx_fixed: |
| 2025 set_dreg(dst, FixedToDouble(xreg(src), fbits, round)); | 2025 set_dreg(dst, FixedToDouble(xreg(src), fbits, round)); |
| 2026 break; | 2026 break; |
| 2027 case SCVTF_dw_fixed: | 2027 case SCVTF_dw_fixed: |
| 2028 set_dreg(dst, FixedToDouble(wreg(src), fbits, round)); | 2028 set_dreg(dst, FixedToDouble(wreg(src), fbits, round)); |
| 2029 break; | 2029 break; |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2469 } | 2469 } |
| 2470 default: UNIMPLEMENTED(); | 2470 default: UNIMPLEMENTED(); |
| 2471 } | 2471 } |
| 2472 return int_result; | 2472 return int_result; |
| 2473 } | 2473 } |
| 2474 | 2474 |
| 2475 | 2475 |
| 2476 double Simulator::FPToDouble(float value) { | 2476 double Simulator::FPToDouble(float value) { |
| 2477 switch (std::fpclassify(value)) { | 2477 switch (std::fpclassify(value)) { |
| 2478 case FP_NAN: { | 2478 case FP_NAN: { |
| 2479 if (DN()) return kFP64DefaultNaN; | 2479 if (fpcr().DN()) return kFP64DefaultNaN; |
| 2480 | 2480 |
| 2481 // Convert NaNs as the processor would: | 2481 // Convert NaNs as the processor would: |
| 2482 // - The sign is propagated. | 2482 // - The sign is propagated. |
| 2483 // - The payload (mantissa) is transferred entirely, except that the top | 2483 // - The payload (mantissa) is transferred entirely, except that the top |
| 2484 // bit is forced to '1', making the result a quiet NaN. The unused | 2484 // bit is forced to '1', making the result a quiet NaN. The unused |
| 2485 // (low-order) payload bits are set to 0. | 2485 // (low-order) payload bits are set to 0. |
| 2486 uint32_t raw = float_to_rawbits(value); | 2486 uint32_t raw = float_to_rawbits(value); |
| 2487 | 2487 |
| 2488 uint64_t sign = raw >> 31; | 2488 uint64_t sign = raw >> 31; |
| 2489 uint64_t exponent = (1 << 11) - 1; | 2489 uint64_t exponent = (1 << 11) - 1; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2510 } | 2510 } |
| 2511 | 2511 |
| 2512 | 2512 |
| 2513 float Simulator::FPToFloat(double value, FPRounding round_mode) { | 2513 float Simulator::FPToFloat(double value, FPRounding round_mode) { |
| 2514 // Only the FPTieEven rounding mode is implemented. | 2514 // Only the FPTieEven rounding mode is implemented. |
| 2515 ASSERT(round_mode == FPTieEven); | 2515 ASSERT(round_mode == FPTieEven); |
| 2516 USE(round_mode); | 2516 USE(round_mode); |
| 2517 | 2517 |
| 2518 switch (std::fpclassify(value)) { | 2518 switch (std::fpclassify(value)) { |
| 2519 case FP_NAN: { | 2519 case FP_NAN: { |
| 2520 if (DN()) return kFP32DefaultNaN; | 2520 if (fpcr().DN()) return kFP32DefaultNaN; |
| 2521 | 2521 |
| 2522 // Convert NaNs as the processor would: | 2522 // Convert NaNs as the processor would: |
| 2523 // - The sign is propagated. | 2523 // - The sign is propagated. |
| 2524 // - The payload (mantissa) is transferred as much as possible, except | 2524 // - The payload (mantissa) is transferred as much as possible, except |
| 2525 // that the top bit is forced to '1', making the result a quiet NaN. | 2525 // that the top bit is forced to '1', making the result a quiet NaN. |
| 2526 uint64_t raw = double_to_rawbits(value); | 2526 uint64_t raw = double_to_rawbits(value); |
| 2527 | 2527 |
| 2528 uint32_t sign = raw >> 63; | 2528 uint32_t sign = raw >> 63; |
| 2529 uint32_t exponent = (1 << 8) - 1; | 2529 uint32_t exponent = (1 << 8) - 1; |
| 2530 uint32_t payload = unsigned_bitextract_64(50, 52 - 23, raw); | 2530 uint32_t payload = unsigned_bitextract_64(50, 52 - 23, raw); |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2807 } else { | 2807 } else { |
| 2808 // Other cases should be handled by standard arithmetic. | 2808 // Other cases should be handled by standard arithmetic. |
| 2809 return op1 - op2; | 2809 return op1 - op2; |
| 2810 } | 2810 } |
| 2811 } | 2811 } |
| 2812 | 2812 |
| 2813 | 2813 |
| 2814 template <typename T> | 2814 template <typename T> |
| 2815 T Simulator::FPProcessNaN(T op) { | 2815 T Simulator::FPProcessNaN(T op) { |
| 2816 ASSERT(std::isnan(op)); | 2816 ASSERT(std::isnan(op)); |
| 2817 return DN() ? FPDefaultNaN<T>() : ToQuietNaN(op); | 2817 return fpcr().DN() ? FPDefaultNaN<T>() : ToQuietNaN(op); |
| 2818 } | 2818 } |
| 2819 | 2819 |
| 2820 | 2820 |
| 2821 template <typename T> | 2821 template <typename T> |
| 2822 T Simulator::FPProcessNaNs(T op1, T op2) { | 2822 T Simulator::FPProcessNaNs(T op1, T op2) { |
| 2823 if (IsSignallingNaN(op1)) { | 2823 if (IsSignallingNaN(op1)) { |
| 2824 return FPProcessNaN(op1); | 2824 return FPProcessNaN(op1); |
| 2825 } else if (IsSignallingNaN(op2)) { | 2825 } else if (IsSignallingNaN(op2)) { |
| 2826 return FPProcessNaN(op2); | 2826 return FPProcessNaN(op2); |
| 2827 } else if (std::isnan(op1)) { | 2827 } else if (std::isnan(op1)) { |
| (...skipping 827 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3655 default: | 3655 default: |
| 3656 UNIMPLEMENTED(); | 3656 UNIMPLEMENTED(); |
| 3657 } | 3657 } |
| 3658 } | 3658 } |
| 3659 | 3659 |
| 3660 #endif // USE_SIMULATOR | 3660 #endif // USE_SIMULATOR |
| 3661 | 3661 |
| 3662 } } // namespace v8::internal | 3662 } } // namespace v8::internal |
| 3663 | 3663 |
| 3664 #endif // V8_TARGET_ARCH_A64 | 3664 #endif // V8_TARGET_ARCH_A64 |
| OLD | NEW |