| 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 894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 905 double dm_val = 0.0; | 905 double dm_val = 0.0; |
| 906 // Read the bits from the unsigned integer register_[] array | 906 // Read the bits from the unsigned integer register_[] array |
| 907 // into the double precision floating point value and return it. | 907 // into the double precision floating point value and return it. |
| 908 char buffer[2 * sizeof(vfp_registers_[0])]; | 908 char buffer[2 * sizeof(vfp_registers_[0])]; |
| 909 OS::MemCopy(buffer, ®isters_[reg], 2 * sizeof(registers_[0])); | 909 OS::MemCopy(buffer, ®isters_[reg], 2 * sizeof(registers_[0])); |
| 910 OS::MemCopy(&dm_val, buffer, 2 * sizeof(registers_[0])); | 910 OS::MemCopy(&dm_val, buffer, 2 * sizeof(registers_[0])); |
| 911 return(dm_val); | 911 return(dm_val); |
| 912 } | 912 } |
| 913 | 913 |
| 914 | 914 |
| 915 void Simulator::set_register_pair_from_double(int reg, double* value) { |
| 916 ASSERT((reg >= 0) && (reg < num_registers) && ((reg % 2) == 0)); |
| 917 memcpy(registers_ + reg, value, sizeof(*value)); |
| 918 } |
| 919 |
| 920 |
| 915 void Simulator::set_dw_register(int dreg, const int* dbl) { | 921 void Simulator::set_dw_register(int dreg, const int* dbl) { |
| 916 ASSERT((dreg >= 0) && (dreg < num_d_registers)); | 922 ASSERT((dreg >= 0) && (dreg < num_d_registers)); |
| 917 registers_[dreg] = dbl[0]; | 923 registers_[dreg] = dbl[0]; |
| 918 registers_[dreg + 1] = dbl[1]; | 924 registers_[dreg + 1] = dbl[1]; |
| 919 } | 925 } |
| 920 | 926 |
| 921 | 927 |
| 922 void Simulator::get_d_register(int dreg, uint64_t* value) { | 928 void Simulator::get_d_register(int dreg, uint64_t* value) { |
| 923 ASSERT((dreg >= 0) && (dreg < DwVfpRegister::NumRegisters())); | 929 ASSERT((dreg >= 0) && (dreg < DwVfpRegister::NumRegisters())); |
| 924 memcpy(value, vfp_registers_ + dreg * 2, sizeof(*value)); | 930 memcpy(value, vfp_registers_ + dreg * 2, sizeof(*value)); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1019 | 1025 |
| 1020 ReturnType value = 0; | 1026 ReturnType value = 0; |
| 1021 char buffer[register_size * sizeof(vfp_registers_[0])]; | 1027 char buffer[register_size * sizeof(vfp_registers_[0])]; |
| 1022 OS::MemCopy(buffer, &vfp_registers_[register_size * reg_index], | 1028 OS::MemCopy(buffer, &vfp_registers_[register_size * reg_index], |
| 1023 register_size * sizeof(vfp_registers_[0])); | 1029 register_size * sizeof(vfp_registers_[0])); |
| 1024 OS::MemCopy(&value, buffer, register_size * sizeof(vfp_registers_[0])); | 1030 OS::MemCopy(&value, buffer, register_size * sizeof(vfp_registers_[0])); |
| 1025 return value; | 1031 return value; |
| 1026 } | 1032 } |
| 1027 | 1033 |
| 1028 | 1034 |
| 1029 // Runtime FP routines take up to two double arguments and zero | 1035 // Runtime FP routines take: |
| 1030 // or one integer arguments. All are consructed here. | 1036 // - two double arguments |
| 1031 // from r0-r3 or d0 and d1. | 1037 // - one double argument and zero or one integer arguments. |
| 1038 // All are consructed here from r0-r3 or d0, d1 and r0. |
| 1032 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) { | 1039 void Simulator::GetFpArgs(double* x, double* y, int32_t* z) { |
| 1033 if (use_eabi_hardfloat()) { | 1040 if (use_eabi_hardfloat()) { |
| 1034 *x = vfp_registers_[0]; | 1041 *x = get_double_from_d_register(0); |
| 1035 *y = vfp_registers_[1]; | 1042 *y = get_double_from_d_register(1); |
| 1036 *z = registers_[1]; | 1043 *z = get_register(0); |
| 1037 } else { | 1044 } else { |
| 1038 // We use a char buffer to get around the strict-aliasing rules which | |
| 1039 // otherwise allow the compiler to optimize away the copy. | |
| 1040 char buffer[sizeof(*x)]; | |
| 1041 // Registers 0 and 1 -> x. | 1045 // Registers 0 and 1 -> x. |
| 1042 OS::MemCopy(buffer, registers_, sizeof(*x)); | 1046 *x = get_double_from_register_pair(0); |
| 1043 OS::MemCopy(x, buffer, sizeof(*x)); | |
| 1044 // Register 2 and 3 -> y. | 1047 // Register 2 and 3 -> y. |
| 1045 OS::MemCopy(buffer, registers_ + 2, sizeof(*y)); | 1048 *y = get_double_from_register_pair(2); |
| 1046 OS::MemCopy(y, buffer, sizeof(*y)); | |
| 1047 // Register 2 -> z | 1049 // Register 2 -> z |
| 1048 memcpy(buffer, registers_ + 2, sizeof(*z)); | 1050 *z = get_register(2); |
| 1049 memcpy(z, buffer, sizeof(*z)); | |
| 1050 } | 1051 } |
| 1051 } | 1052 } |
| 1052 | 1053 |
| 1053 | 1054 |
| 1054 // The return value is either in r0/r1 or d0. | 1055 // The return value is either in r0/r1 or d0. |
| 1055 void Simulator::SetFpResult(const double& result) { | 1056 void Simulator::SetFpResult(const double& result) { |
| 1056 if (use_eabi_hardfloat()) { | 1057 if (use_eabi_hardfloat()) { |
| 1057 char buffer[2 * sizeof(vfp_registers_[0])]; | 1058 char buffer[2 * sizeof(vfp_registers_[0])]; |
| 1058 OS::MemCopy(buffer, &result, sizeof(buffer)); | 1059 OS::MemCopy(buffer, &result, sizeof(buffer)); |
| 1059 // Copy result to d0. | 1060 // Copy result to d0. |
| (...skipping 651 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1711 int32_t arg2 = get_register(r2); | 1712 int32_t arg2 = get_register(r2); |
| 1712 int32_t arg3 = get_register(r3); | 1713 int32_t arg3 = get_register(r3); |
| 1713 int32_t* stack_pointer = reinterpret_cast<int32_t*>(get_register(sp)); | 1714 int32_t* stack_pointer = reinterpret_cast<int32_t*>(get_register(sp)); |
| 1714 int32_t arg4 = stack_pointer[0]; | 1715 int32_t arg4 = stack_pointer[0]; |
| 1715 int32_t arg5 = stack_pointer[1]; | 1716 int32_t arg5 = stack_pointer[1]; |
| 1716 bool fp_call = | 1717 bool fp_call = |
| 1717 (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) || | 1718 (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) || |
| 1718 (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) || | 1719 (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) || |
| 1719 (redirection->type() == ExternalReference::BUILTIN_FP_CALL) || | 1720 (redirection->type() == ExternalReference::BUILTIN_FP_CALL) || |
| 1720 (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL); | 1721 (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL); |
| 1721 if (use_eabi_hardfloat()) { | |
| 1722 // With the hard floating point calling convention, double | |
| 1723 // arguments are passed in VFP registers. Fetch the arguments | |
| 1724 // from there and call the builtin using soft floating point | |
| 1725 // convention. | |
| 1726 switch (redirection->type()) { | |
| 1727 case ExternalReference::BUILTIN_FP_FP_CALL: | |
| 1728 case ExternalReference::BUILTIN_COMPARE_CALL: | |
| 1729 arg0 = vfp_registers_[0]; | |
| 1730 arg1 = vfp_registers_[1]; | |
| 1731 arg2 = vfp_registers_[2]; | |
| 1732 arg3 = vfp_registers_[3]; | |
| 1733 break; | |
| 1734 case ExternalReference::BUILTIN_FP_CALL: | |
| 1735 arg0 = vfp_registers_[0]; | |
| 1736 arg1 = vfp_registers_[1]; | |
| 1737 break; | |
| 1738 case ExternalReference::BUILTIN_FP_INT_CALL: | |
| 1739 arg0 = vfp_registers_[0]; | |
| 1740 arg1 = vfp_registers_[1]; | |
| 1741 arg2 = get_register(0); | |
| 1742 break; | |
| 1743 default: | |
| 1744 break; | |
| 1745 } | |
| 1746 } | |
| 1747 // This is dodgy but it works because the C entry stubs are never moved. | 1722 // This is dodgy but it works because the C entry stubs are never moved. |
| 1748 // See comment in codegen-arm.cc and bug 1242173. | 1723 // See comment in codegen-arm.cc and bug 1242173. |
| 1749 int32_t saved_lr = get_register(lr); | 1724 int32_t saved_lr = get_register(lr); |
| 1750 intptr_t external = | 1725 intptr_t external = |
| 1751 reinterpret_cast<intptr_t>(redirection->external_function()); | 1726 reinterpret_cast<intptr_t>(redirection->external_function()); |
| 1752 if (fp_call) { | 1727 if (fp_call) { |
| 1753 double dval0, dval1; // one or two double parameters | 1728 double dval0, dval1; // one or two double parameters |
| 1754 int32_t ival; // zero or one integer parameters | 1729 int32_t ival; // zero or one integer parameters |
| 1755 int64_t iresult = 0; // integer return value | 1730 int64_t iresult = 0; // integer return value |
| 1756 double dresult = 0; // double return value | 1731 double dresult = 0; // double return value |
| (...skipping 2052 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3809 | 3784 |
| 3810 // Pop stack passed arguments. | 3785 // Pop stack passed arguments. |
| 3811 CHECK_EQ(entry_stack, get_register(sp)); | 3786 CHECK_EQ(entry_stack, get_register(sp)); |
| 3812 set_register(sp, original_stack); | 3787 set_register(sp, original_stack); |
| 3813 | 3788 |
| 3814 int32_t result = get_register(r0); | 3789 int32_t result = get_register(r0); |
| 3815 return result; | 3790 return result; |
| 3816 } | 3791 } |
| 3817 | 3792 |
| 3818 | 3793 |
| 3819 double Simulator::CallFP(byte* entry, double d0, double d1) { | 3794 void Simulator::CallFP(byte* entry, double d0, double d1) { |
| 3820 if (use_eabi_hardfloat()) { | 3795 if (use_eabi_hardfloat()) { |
| 3821 set_d_register_from_double(0, d0); | 3796 set_d_register_from_double(0, d0); |
| 3822 set_d_register_from_double(1, d1); | 3797 set_d_register_from_double(1, d1); |
| 3823 } else { | 3798 } else { |
| 3824 int buffer[2]; | 3799 set_register_pair_from_double(0, &d0); |
| 3825 ASSERT(sizeof(buffer[0]) * 2 == sizeof(d0)); | 3800 set_register_pair_from_double(2, &d1); |
| 3826 OS::MemCopy(buffer, &d0, sizeof(d0)); | |
| 3827 set_dw_register(0, buffer); | |
| 3828 OS::MemCopy(buffer, &d1, sizeof(d1)); | |
| 3829 set_dw_register(2, buffer); | |
| 3830 } | 3801 } |
| 3831 CallInternal(entry); | 3802 CallInternal(entry); |
| 3803 } |
| 3804 |
| 3805 |
| 3806 int32_t Simulator::CallFPReturnsInt(byte* entry, double d0, double d1) { |
| 3807 CallFP(entry, d0, d1); |
| 3808 int32_t result = get_register(r0); |
| 3809 return result; |
| 3810 } |
| 3811 |
| 3812 |
| 3813 double Simulator::CallFPReturnsDouble(byte* entry, double d0, double d1) { |
| 3814 CallFP(entry, d0, d1); |
| 3832 if (use_eabi_hardfloat()) { | 3815 if (use_eabi_hardfloat()) { |
| 3833 return get_double_from_d_register(0); | 3816 return get_double_from_d_register(0); |
| 3834 } else { | 3817 } else { |
| 3835 return get_double_from_register_pair(0); | 3818 return get_double_from_register_pair(0); |
| 3836 } | 3819 } |
| 3837 } | 3820 } |
| 3838 | 3821 |
| 3839 | 3822 |
| 3840 uintptr_t Simulator::PushAddress(uintptr_t address) { | 3823 uintptr_t Simulator::PushAddress(uintptr_t address) { |
| 3841 int new_sp = get_register(sp) - sizeof(uintptr_t); | 3824 int new_sp = get_register(sp) - sizeof(uintptr_t); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3852 uintptr_t address = *stack_slot; | 3835 uintptr_t address = *stack_slot; |
| 3853 set_register(sp, current_sp + sizeof(uintptr_t)); | 3836 set_register(sp, current_sp + sizeof(uintptr_t)); |
| 3854 return address; | 3837 return address; |
| 3855 } | 3838 } |
| 3856 | 3839 |
| 3857 } } // namespace v8::internal | 3840 } } // namespace v8::internal |
| 3858 | 3841 |
| 3859 #endif // USE_SIMULATOR | 3842 #endif // USE_SIMULATOR |
| 3860 | 3843 |
| 3861 #endif // V8_TARGET_ARCH_ARM | 3844 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |