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 |