Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(450)

Side by Side Diff: src/arm/simulator-arm.cc

Issue 23496062: ARM: Fix simulator when using hard floating point ABI. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/simulator-arm.h ('k') | test/cctest/test-code-stubs-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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, &registers_[reg], 2 * sizeof(registers_[0])); 909 OS::MemCopy(buffer, &registers_[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
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
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
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
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
OLDNEW
« no previous file with comments | « src/arm/simulator-arm.h ('k') | test/cctest/test-code-stubs-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698