| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 748 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 759 n_flag_ = false; | 759 n_flag_ = false; |
| 760 z_flag_ = false; | 760 z_flag_ = false; |
| 761 c_flag_ = false; | 761 c_flag_ = false; |
| 762 v_flag_ = false; | 762 v_flag_ = false; |
| 763 | 763 |
| 764 // Initializing VFP registers. | 764 // Initializing VFP registers. |
| 765 // All registers are initialized to zero to start with | 765 // All registers are initialized to zero to start with |
| 766 // even though s_registers_ & d_registers_ share the same | 766 // even though s_registers_ & d_registers_ share the same |
| 767 // physical registers in the target. | 767 // physical registers in the target. |
| 768 for (int i = 0; i < num_d_registers * 2; i++) { | 768 for (int i = 0; i < num_d_registers * 2; i++) { |
| 769 vfp_register[i] = 0; | 769 vfp_registers_[i] = 0; |
| 770 } | 770 } |
| 771 n_flag_FPSCR_ = false; | 771 n_flag_FPSCR_ = false; |
| 772 z_flag_FPSCR_ = false; | 772 z_flag_FPSCR_ = false; |
| 773 c_flag_FPSCR_ = false; | 773 c_flag_FPSCR_ = false; |
| 774 v_flag_FPSCR_ = false; | 774 v_flag_FPSCR_ = false; |
| 775 FPSCR_rounding_mode_ = RZ; | 775 FPSCR_rounding_mode_ = RZ; |
| 776 | 776 |
| 777 inv_op_vfp_flag_ = false; | 777 inv_op_vfp_flag_ = false; |
| 778 div_zero_vfp_flag_ = false; | 778 div_zero_vfp_flag_ = false; |
| 779 overflow_vfp_flag_ = false; | 779 overflow_vfp_flag_ = false; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 894 return registers_[reg] + ((reg == pc) ? Instruction::kPCReadOffset : 0); | 894 return registers_[reg] + ((reg == pc) ? Instruction::kPCReadOffset : 0); |
| 895 } | 895 } |
| 896 | 896 |
| 897 | 897 |
| 898 double Simulator::get_double_from_register_pair(int reg) { | 898 double Simulator::get_double_from_register_pair(int reg) { |
| 899 ASSERT((reg >= 0) && (reg < num_registers) && ((reg % 2) == 0)); | 899 ASSERT((reg >= 0) && (reg < num_registers) && ((reg % 2) == 0)); |
| 900 | 900 |
| 901 double dm_val = 0.0; | 901 double dm_val = 0.0; |
| 902 // Read the bits from the unsigned integer register_[] array | 902 // Read the bits from the unsigned integer register_[] array |
| 903 // into the double precision floating point value and return it. | 903 // into the double precision floating point value and return it. |
| 904 char buffer[2 * sizeof(vfp_register[0])]; | 904 char buffer[2 * sizeof(vfp_registers_[0])]; |
| 905 memcpy(buffer, ®isters_[reg], 2 * sizeof(registers_[0])); | 905 memcpy(buffer, ®isters_[reg], 2 * sizeof(registers_[0])); |
| 906 memcpy(&dm_val, buffer, 2 * sizeof(registers_[0])); | 906 memcpy(&dm_val, buffer, 2 * sizeof(registers_[0])); |
| 907 return(dm_val); | 907 return(dm_val); |
| 908 } | 908 } |
| 909 | 909 |
| 910 | 910 |
| 911 void Simulator::set_dw_register(int dreg, const int* dbl) { | 911 void Simulator::set_dw_register(int dreg, const int* dbl) { |
| 912 ASSERT((dreg >= 0) && (dreg < num_d_registers)); | 912 ASSERT((dreg >= 0) && (dreg < num_d_registers)); |
| 913 registers_[dreg] = dbl[0]; | 913 registers_[dreg] = dbl[0]; |
| 914 registers_[dreg + 1] = dbl[1]; | 914 registers_[dreg + 1] = dbl[1]; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 929 | 929 |
| 930 // Raw access to the PC register without the special adjustment when reading. | 930 // Raw access to the PC register without the special adjustment when reading. |
| 931 int32_t Simulator::get_pc() const { | 931 int32_t Simulator::get_pc() const { |
| 932 return registers_[pc]; | 932 return registers_[pc]; |
| 933 } | 933 } |
| 934 | 934 |
| 935 | 935 |
| 936 // Getting from and setting into VFP registers. | 936 // Getting from and setting into VFP registers. |
| 937 void Simulator::set_s_register(int sreg, unsigned int value) { | 937 void Simulator::set_s_register(int sreg, unsigned int value) { |
| 938 ASSERT((sreg >= 0) && (sreg < num_s_registers)); | 938 ASSERT((sreg >= 0) && (sreg < num_s_registers)); |
| 939 vfp_register[sreg] = value; | 939 vfp_registers_[sreg] = value; |
| 940 } | 940 } |
| 941 | 941 |
| 942 | 942 |
| 943 unsigned int Simulator::get_s_register(int sreg) const { | 943 unsigned int Simulator::get_s_register(int sreg) const { |
| 944 ASSERT((sreg >= 0) && (sreg < num_s_registers)); | 944 ASSERT((sreg >= 0) && (sreg < num_s_registers)); |
| 945 return vfp_register[sreg]; | 945 return vfp_registers_[sreg]; |
| 946 } | 946 } |
| 947 | 947 |
| 948 | 948 |
| 949 template<class InputType, int register_size> | 949 template<class InputType, int register_size> |
| 950 void Simulator::SetVFPRegister(int reg_index, const InputType& value) { | 950 void Simulator::SetVFPRegister(int reg_index, const InputType& value) { |
| 951 ASSERT(reg_index >= 0); | 951 ASSERT(reg_index >= 0); |
| 952 if (register_size == 1) ASSERT(reg_index < num_s_registers); | 952 if (register_size == 1) ASSERT(reg_index < num_s_registers); |
| 953 if (register_size == 2) ASSERT(reg_index < DwVfpRegister::NumRegisters()); | 953 if (register_size == 2) ASSERT(reg_index < DwVfpRegister::NumRegisters()); |
| 954 | 954 |
| 955 char buffer[register_size * sizeof(vfp_register[0])]; | 955 char buffer[register_size * sizeof(vfp_registers_[0])]; |
| 956 memcpy(buffer, &value, register_size * sizeof(vfp_register[0])); | 956 memcpy(buffer, &value, register_size * sizeof(vfp_registers_[0])); |
| 957 memcpy(&vfp_register[reg_index * register_size], buffer, | 957 memcpy(&vfp_registers_[reg_index * register_size], buffer, |
| 958 register_size * sizeof(vfp_register[0])); | 958 register_size * sizeof(vfp_registers_[0])); |
| 959 } | 959 } |
| 960 | 960 |
| 961 | 961 |
| 962 template<class ReturnType, int register_size> | 962 template<class ReturnType, int register_size> |
| 963 ReturnType Simulator::GetFromVFPRegister(int reg_index) { | 963 ReturnType Simulator::GetFromVFPRegister(int reg_index) { |
| 964 ASSERT(reg_index >= 0); | 964 ASSERT(reg_index >= 0); |
| 965 if (register_size == 1) ASSERT(reg_index < num_s_registers); | 965 if (register_size == 1) ASSERT(reg_index < num_s_registers); |
| 966 if (register_size == 2) ASSERT(reg_index < DwVfpRegister::NumRegisters()); | 966 if (register_size == 2) ASSERT(reg_index < DwVfpRegister::NumRegisters()); |
| 967 | 967 |
| 968 ReturnType value = 0; | 968 ReturnType value = 0; |
| 969 char buffer[register_size * sizeof(vfp_register[0])]; | 969 char buffer[register_size * sizeof(vfp_registers_[0])]; |
| 970 memcpy(buffer, &vfp_register[register_size * reg_index], | 970 memcpy(buffer, &vfp_registers_[register_size * reg_index], |
| 971 register_size * sizeof(vfp_register[0])); | 971 register_size * sizeof(vfp_registers_[0])); |
| 972 memcpy(&value, buffer, register_size * sizeof(vfp_register[0])); | 972 memcpy(&value, buffer, register_size * sizeof(vfp_registers_[0])); |
| 973 return value; | 973 return value; |
| 974 } | 974 } |
| 975 | 975 |
| 976 | 976 |
| 977 // For use in calls that take two double values, constructed either | 977 // For use in calls that take two double values, constructed either |
| 978 // from r0-r3 or d0 and d1. | 978 // from r0-r3 or d0 and d1. |
| 979 void Simulator::GetFpArgs(double* x, double* y) { | 979 void Simulator::GetFpArgs(double* x, double* y) { |
| 980 if (use_eabi_hardfloat()) { | 980 if (use_eabi_hardfloat()) { |
| 981 *x = vfp_register[0]; | 981 *x = vfp_registers_[0]; |
| 982 *y = vfp_register[1]; | 982 *y = vfp_registers_[1]; |
| 983 } else { | 983 } else { |
| 984 // We use a char buffer to get around the strict-aliasing rules which | 984 // We use a char buffer to get around the strict-aliasing rules which |
| 985 // otherwise allow the compiler to optimize away the copy. | 985 // otherwise allow the compiler to optimize away the copy. |
| 986 char buffer[sizeof(*x)]; | 986 char buffer[sizeof(*x)]; |
| 987 // Registers 0 and 1 -> x. | 987 // Registers 0 and 1 -> x. |
| 988 memcpy(buffer, registers_, sizeof(*x)); | 988 memcpy(buffer, registers_, sizeof(*x)); |
| 989 memcpy(x, buffer, sizeof(*x)); | 989 memcpy(x, buffer, sizeof(*x)); |
| 990 // Registers 2 and 3 -> y. | 990 // Registers 2 and 3 -> y. |
| 991 memcpy(buffer, registers_ + 2, sizeof(*y)); | 991 memcpy(buffer, registers_ + 2, sizeof(*y)); |
| 992 memcpy(y, buffer, sizeof(*y)); | 992 memcpy(y, buffer, sizeof(*y)); |
| 993 } | 993 } |
| 994 } | 994 } |
| 995 | 995 |
| 996 // For use in calls that take one double value, constructed either | 996 // For use in calls that take one double value, constructed either |
| 997 // from r0 and r1 or d0. | 997 // from r0 and r1 or d0. |
| 998 void Simulator::GetFpArgs(double* x) { | 998 void Simulator::GetFpArgs(double* x) { |
| 999 if (use_eabi_hardfloat()) { | 999 if (use_eabi_hardfloat()) { |
| 1000 *x = vfp_register[0]; | 1000 *x = vfp_registers_[0]; |
| 1001 } else { | 1001 } else { |
| 1002 // We use a char buffer to get around the strict-aliasing rules which | 1002 // We use a char buffer to get around the strict-aliasing rules which |
| 1003 // otherwise allow the compiler to optimize away the copy. | 1003 // otherwise allow the compiler to optimize away the copy. |
| 1004 char buffer[sizeof(*x)]; | 1004 char buffer[sizeof(*x)]; |
| 1005 // Registers 0 and 1 -> x. | 1005 // Registers 0 and 1 -> x. |
| 1006 memcpy(buffer, registers_, sizeof(*x)); | 1006 memcpy(buffer, registers_, sizeof(*x)); |
| 1007 memcpy(x, buffer, sizeof(*x)); | 1007 memcpy(x, buffer, sizeof(*x)); |
| 1008 } | 1008 } |
| 1009 } | 1009 } |
| 1010 | 1010 |
| 1011 | 1011 |
| 1012 // For use in calls that take one double value constructed either | 1012 // For use in calls that take one double value constructed either |
| 1013 // from r0 and r1 or d0 and one integer value. | 1013 // from r0 and r1 or d0 and one integer value. |
| 1014 void Simulator::GetFpArgs(double* x, int32_t* y) { | 1014 void Simulator::GetFpArgs(double* x, int32_t* y) { |
| 1015 if (use_eabi_hardfloat()) { | 1015 if (use_eabi_hardfloat()) { |
| 1016 *x = vfp_register[0]; | 1016 *x = vfp_registers_[0]; |
| 1017 *y = registers_[1]; | 1017 *y = registers_[1]; |
| 1018 } else { | 1018 } else { |
| 1019 // We use a char buffer to get around the strict-aliasing rules which | 1019 // We use a char buffer to get around the strict-aliasing rules which |
| 1020 // otherwise allow the compiler to optimize away the copy. | 1020 // otherwise allow the compiler to optimize away the copy. |
| 1021 char buffer[sizeof(*x)]; | 1021 char buffer[sizeof(*x)]; |
| 1022 // Registers 0 and 1 -> x. | 1022 // Registers 0 and 1 -> x. |
| 1023 memcpy(buffer, registers_, sizeof(*x)); | 1023 memcpy(buffer, registers_, sizeof(*x)); |
| 1024 memcpy(x, buffer, sizeof(*x)); | 1024 memcpy(x, buffer, sizeof(*x)); |
| 1025 // Register 2 -> y. | 1025 // Register 2 -> y. |
| 1026 memcpy(buffer, registers_ + 2, sizeof(*y)); | 1026 memcpy(buffer, registers_ + 2, sizeof(*y)); |
| 1027 memcpy(y, buffer, sizeof(*y)); | 1027 memcpy(y, buffer, sizeof(*y)); |
| 1028 } | 1028 } |
| 1029 } | 1029 } |
| 1030 | 1030 |
| 1031 | 1031 |
| 1032 // The return value is either in r0/r1 or d0. | 1032 // The return value is either in r0/r1 or d0. |
| 1033 void Simulator::SetFpResult(const double& result) { | 1033 void Simulator::SetFpResult(const double& result) { |
| 1034 if (use_eabi_hardfloat()) { | 1034 if (use_eabi_hardfloat()) { |
| 1035 char buffer[2 * sizeof(vfp_register[0])]; | 1035 char buffer[2 * sizeof(vfp_registers_[0])]; |
| 1036 memcpy(buffer, &result, sizeof(buffer)); | 1036 memcpy(buffer, &result, sizeof(buffer)); |
| 1037 // Copy result to d0. | 1037 // Copy result to d0. |
| 1038 memcpy(vfp_register, buffer, sizeof(buffer)); | 1038 memcpy(vfp_registers_, buffer, sizeof(buffer)); |
| 1039 } else { | 1039 } else { |
| 1040 char buffer[2 * sizeof(registers_[0])]; | 1040 char buffer[2 * sizeof(registers_[0])]; |
| 1041 memcpy(buffer, &result, sizeof(buffer)); | 1041 memcpy(buffer, &result, sizeof(buffer)); |
| 1042 // Copy result to r0 and r1. | 1042 // Copy result to r0 and r1. |
| 1043 memcpy(registers_, buffer, sizeof(buffer)); | 1043 memcpy(registers_, buffer, sizeof(buffer)); |
| 1044 } | 1044 } |
| 1045 } | 1045 } |
| 1046 | 1046 |
| 1047 | 1047 |
| 1048 void Simulator::TrashCallerSaveRegisters() { | 1048 void Simulator::TrashCallerSaveRegisters() { |
| (...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1685 (redirection->type() == ExternalReference::BUILTIN_FP_CALL) || | 1685 (redirection->type() == ExternalReference::BUILTIN_FP_CALL) || |
| 1686 (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL); | 1686 (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL); |
| 1687 if (use_eabi_hardfloat()) { | 1687 if (use_eabi_hardfloat()) { |
| 1688 // With the hard floating point calling convention, double | 1688 // With the hard floating point calling convention, double |
| 1689 // arguments are passed in VFP registers. Fetch the arguments | 1689 // arguments are passed in VFP registers. Fetch the arguments |
| 1690 // from there and call the builtin using soft floating point | 1690 // from there and call the builtin using soft floating point |
| 1691 // convention. | 1691 // convention. |
| 1692 switch (redirection->type()) { | 1692 switch (redirection->type()) { |
| 1693 case ExternalReference::BUILTIN_FP_FP_CALL: | 1693 case ExternalReference::BUILTIN_FP_FP_CALL: |
| 1694 case ExternalReference::BUILTIN_COMPARE_CALL: | 1694 case ExternalReference::BUILTIN_COMPARE_CALL: |
| 1695 arg0 = vfp_register[0]; | 1695 arg0 = vfp_registers_[0]; |
| 1696 arg1 = vfp_register[1]; | 1696 arg1 = vfp_registers_[1]; |
| 1697 arg2 = vfp_register[2]; | 1697 arg2 = vfp_registers_[2]; |
| 1698 arg3 = vfp_register[3]; | 1698 arg3 = vfp_registers_[3]; |
| 1699 break; | 1699 break; |
| 1700 case ExternalReference::BUILTIN_FP_CALL: | 1700 case ExternalReference::BUILTIN_FP_CALL: |
| 1701 arg0 = vfp_register[0]; | 1701 arg0 = vfp_registers_[0]; |
| 1702 arg1 = vfp_register[1]; | 1702 arg1 = vfp_registers_[1]; |
| 1703 break; | 1703 break; |
| 1704 case ExternalReference::BUILTIN_FP_INT_CALL: | 1704 case ExternalReference::BUILTIN_FP_INT_CALL: |
| 1705 arg0 = vfp_register[0]; | 1705 arg0 = vfp_registers_[0]; |
| 1706 arg1 = vfp_register[1]; | 1706 arg1 = vfp_registers_[1]; |
| 1707 arg2 = get_register(0); | 1707 arg2 = get_register(0); |
| 1708 break; | 1708 break; |
| 1709 default: | 1709 default: |
| 1710 break; | 1710 break; |
| 1711 } | 1711 } |
| 1712 } | 1712 } |
| 1713 // This is dodgy but it works because the C entry stubs are never moved. | 1713 // This is dodgy but it works because the C entry stubs are never moved. |
| 1714 // See comment in codegen-arm.cc and bug 1242173. | 1714 // See comment in codegen-arm.cc and bug 1242173. |
| 1715 int32_t saved_lr = get_register(lr); | 1715 int32_t saved_lr = get_register(lr); |
| 1716 intptr_t external = | 1716 intptr_t external = |
| (...skipping 1743 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3460 uintptr_t address = *stack_slot; | 3460 uintptr_t address = *stack_slot; |
| 3461 set_register(sp, current_sp + sizeof(uintptr_t)); | 3461 set_register(sp, current_sp + sizeof(uintptr_t)); |
| 3462 return address; | 3462 return address; |
| 3463 } | 3463 } |
| 3464 | 3464 |
| 3465 } } // namespace v8::internal | 3465 } } // namespace v8::internal |
| 3466 | 3466 |
| 3467 #endif // USE_SIMULATOR | 3467 #endif // USE_SIMULATOR |
| 3468 | 3468 |
| 3469 #endif // V8_TARGET_ARCH_ARM | 3469 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |