Revision f230a1cf deps/v8/src/arm/simulator-arm.cc
deps/v8/src/arm/simulator-arm.cc | ||
---|---|---|
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 | 921 |
void Simulator::set_dw_register(int dreg, const int* dbl) { |
916 | 922 |
ASSERT((dreg >= 0) && (dreg < num_d_registers)); |
917 | 923 |
registers_[dreg] = dbl[0]; |
... | ... | |
1026 | 1032 |
} |
1027 | 1033 |
|
1028 | 1034 |
|
1029 |
// Runtime FP routines take up to two double arguments and zero |
|
1030 |
// or one integer arguments. All are consructed here. |
|
1031 |
// from r0-r3 or d0 and d1. |
|
1035 |
// Runtime FP routines take: |
|
1036 |
// - two double arguments |
|
1037 |
// - one double argument and zero or one integer arguments. |
|
1038 |
// All are consructed here from r0-r3 or d0, d1 and r0. |
|
1032 | 1039 |
void Simulator::GetFpArgs(double* x, double* y, int32_t* z) { |
1033 | 1040 |
if (use_eabi_hardfloat()) { |
1034 |
*x = vfp_registers_[0];
|
|
1035 |
*y = vfp_registers_[1];
|
|
1036 |
*z = registers_[1];
|
|
1041 |
*x = get_double_from_d_register(0);
|
|
1042 |
*y = get_double_from_d_register(1);
|
|
1043 |
*z = get_register(0);
|
|
1037 | 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 | 1045 |
// Registers 0 and 1 -> x. |
1042 |
OS::MemCopy(buffer, registers_, sizeof(*x)); |
|
1043 |
OS::MemCopy(x, buffer, sizeof(*x)); |
|
1046 |
*x = get_double_from_register_pair(0); |
|
1044 | 1047 |
// Register 2 and 3 -> y. |
1045 |
OS::MemCopy(buffer, registers_ + 2, sizeof(*y)); |
|
1046 |
OS::MemCopy(y, buffer, sizeof(*y)); |
|
1048 |
*y = get_double_from_register_pair(2); |
|
1047 | 1049 |
// Register 2 -> z |
1048 |
memcpy(buffer, registers_ + 2, sizeof(*z)); |
|
1049 |
memcpy(z, buffer, sizeof(*z)); |
|
1050 |
*z = get_register(2); |
|
1050 | 1051 |
} |
1051 | 1052 |
} |
1052 | 1053 |
|
... | ... | |
1718 | 1719 |
(redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) || |
1719 | 1720 |
(redirection->type() == ExternalReference::BUILTIN_FP_CALL) || |
1720 | 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 | 1722 |
// This is dodgy but it works because the C entry stubs are never moved. |
1748 | 1723 |
// See comment in codegen-arm.cc and bug 1242173. |
1749 | 1724 |
int32_t saved_lr = get_register(lr); |
... | ... | |
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 | 3795 |
if (use_eabi_hardfloat()) { |
3821 | 3796 |
set_d_register_from_double(0, d0); |
3822 | 3797 |
set_d_register_from_double(1, d1); |
3823 | 3798 |
} else { |
3824 |
int buffer[2]; |
|
3825 |
ASSERT(sizeof(buffer[0]) * 2 == sizeof(d0)); |
|
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); |
|
3799 |
set_register_pair_from_double(0, &d0); |
|
3800 |
set_register_pair_from_double(2, &d1); |
|
3830 | 3801 |
} |
3831 | 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 | 3815 |
if (use_eabi_hardfloat()) { |
3833 | 3816 |
return get_double_from_d_register(0); |
3834 | 3817 |
} else { |
Also available in: Unified diff