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

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

Issue 6874007: Implement hardfloat calling convention in macro assembler and simulator. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add num_double_arguments to CallCFunction Created 9 years, 7 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') | src/assembler.h » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 991 matching lines...) Expand 10 before | Expand all | Expand 10 after
1002 double dm_val = 0.0; 1002 double dm_val = 0.0;
1003 // Read the bits from the unsigned integer vfp_register[] array 1003 // Read the bits from the unsigned integer vfp_register[] array
1004 // into the double precision floating point value and return it. 1004 // into the double precision floating point value and return it.
1005 char buffer[2 * sizeof(vfp_register[0])]; 1005 char buffer[2 * sizeof(vfp_register[0])];
1006 memcpy(buffer, &vfp_register[2 * dreg], 2 * sizeof(vfp_register[0])); 1006 memcpy(buffer, &vfp_register[2 * dreg], 2 * sizeof(vfp_register[0]));
1007 memcpy(&dm_val, buffer, 2 * sizeof(vfp_register[0])); 1007 memcpy(&dm_val, buffer, 2 * sizeof(vfp_register[0]));
1008 return(dm_val); 1008 return(dm_val);
1009 } 1009 }
1010 1010
1011 1011
1012 // For use in calls that take two double values, constructed from r0, r1, r2 1012 // For use in calls that take two double values, constructed either
1013 // and r3. 1013 // from r0-r3 or d0 and d1.
1014 void Simulator::GetFpArgs(double* x, double* y) { 1014 void Simulator::GetFpArgs(double* x, double* y) {
1015 // We use a char buffer to get around the strict-aliasing rules which 1015 if (FLAG_hardfloat) {
1016 // otherwise allow the compiler to optimize away the copy. 1016 *x = vfp_register[0];
1017 char buffer[2 * sizeof(registers_[0])]; 1017 *y = vfp_register[1];
1018 // Registers 0 and 1 -> x. 1018 } else {
1019 memcpy(buffer, registers_, sizeof(buffer)); 1019 // We use a char buffer to get around the strict-aliasing rules which
1020 memcpy(x, buffer, sizeof(buffer)); 1020 // otherwise allow the compiler to optimize away the copy.
1021 // Registers 2 and 3 -> y. 1021 char buffer[2 * sizeof(registers_[0])];
1022 memcpy(buffer, registers_ + 2, sizeof(buffer)); 1022 // Registers 0 and 1 -> x.
1023 memcpy(y, buffer, sizeof(buffer)); 1023 memcpy(buffer, registers_, sizeof(buffer));
1024 memcpy(x, buffer, sizeof(buffer));
1025 // Registers 2 and 3 -> y.
1026 memcpy(buffer, registers_ + 2, sizeof(buffer));
1027 memcpy(y, buffer, sizeof(buffer));
1028 }
1029 }
1030
1031 // For use in calls that take one double value, constructed either
1032 // from r0 and r1 or d0.
1033 void Simulator::GetFpArgs(double* x) {
1034 if (FLAG_hardfloat) {
1035 *x = vfp_register[0];
1036 } else {
1037 // We use a char buffer to get around the strict-aliasing rules which
1038 // otherwise allow the compiler to optimize away the copy.
1039 char buffer[2 * sizeof(registers_[0])];
1040 // Registers 0 and 1 -> x.
1041 memcpy(buffer, registers_, sizeof(buffer));
1042 memcpy(x, buffer, sizeof(buffer));
1043 }
1024 } 1044 }
1025 1045
1026 1046
1027 void Simulator::SetFpResult(const double& result) { 1047 // For use in calls that take two double values, constructed either
1028 char buffer[2 * sizeof(registers_[0])]; 1048 // from r0-r3 or d0 and d1.
1029 memcpy(buffer, &result, sizeof(buffer)); 1049 void Simulator::GetFpArgs(double* x, int32_t* y) {
1030 // result -> registers 0 and 1. 1050 if (FLAG_hardfloat) {
1031 memcpy(registers_, buffer, sizeof(buffer)); 1051 *x = vfp_register[0];
1052 *y = registers_[1];
1053 } else {
1054 // We use a char buffer to get around the strict-aliasing rules which
1055 // otherwise allow the compiler to optimize away the copy.
1056 char buffer[2 * sizeof(registers_[0])];
1057 // Registers 0 and 1 -> x.
1058 memcpy(buffer, registers_, sizeof(buffer));
1059 memcpy(x, buffer, sizeof(buffer));
1060 // Registers 2 and 3 -> y.
1061 memcpy(buffer, registers_ + 2, sizeof(buffer));
1062 memcpy(y, buffer, sizeof(buffer));
1063 }
1032 } 1064 }
1033 1065
1034 1066
1067 // The return value is either in r0/r1 or d0.
1068 void Simulator::SetFpResult(const double& result) {
1069 if (FLAG_hardfloat) {
1070 char buffer[2 * sizeof(vfp_register[0])];
1071 memcpy(buffer, &result, sizeof(buffer));
1072 // Copy result to d0.
1073 memcpy(vfp_register, buffer, sizeof(buffer));
1074 } else {
1075 char buffer[2 * sizeof(registers_[0])];
1076 memcpy(buffer, &result, sizeof(buffer));
1077 // Copy result to r0 and r1.
1078 memcpy(registers_, buffer, sizeof(buffer));
1079 }
1080 }
1081
1082
1035 void Simulator::TrashCallerSaveRegisters() { 1083 void Simulator::TrashCallerSaveRegisters() {
1036 // We don't trash the registers with the return value. 1084 // We don't trash the registers with the return value.
1037 registers_[2] = 0x50Bad4U; 1085 registers_[2] = 0x50Bad4U;
1038 registers_[3] = 0x50Bad4U; 1086 registers_[3] = 0x50Bad4U;
1039 registers_[12] = 0x50Bad4U; 1087 registers_[12] = 0x50Bad4U;
1040 } 1088 }
1041 1089
1042 // Some Operating Systems allow unaligned access on ARMv7 targets. We 1090 // Some Operating Systems allow unaligned access on ARMv7 targets. We
1043 // assume that unaligned accesses are not allowed unless the v8 build system 1091 // assume that unaligned accesses are not allowed unless the v8 build system
1044 // defines the CAN_USE_UNALIGNED_ACCESSES macro to be non-zero. 1092 // defines the CAN_USE_UNALIGNED_ACCESSES macro to be non-zero.
(...skipping 633 matching lines...) Expand 10 before | Expand all | Expand 10 after
1678 (get_register(sp) 1726 (get_register(sp)
1679 & (::v8::internal::FLAG_sim_stack_alignment - 1)) == 0; 1727 & (::v8::internal::FLAG_sim_stack_alignment - 1)) == 0;
1680 Redirection* redirection = Redirection::FromSwiInstruction(instr); 1728 Redirection* redirection = Redirection::FromSwiInstruction(instr);
1681 int32_t arg0 = get_register(r0); 1729 int32_t arg0 = get_register(r0);
1682 int32_t arg1 = get_register(r1); 1730 int32_t arg1 = get_register(r1);
1683 int32_t arg2 = get_register(r2); 1731 int32_t arg2 = get_register(r2);
1684 int32_t arg3 = get_register(r3); 1732 int32_t arg3 = get_register(r3);
1685 int32_t* stack_pointer = reinterpret_cast<int32_t*>(get_register(sp)); 1733 int32_t* stack_pointer = reinterpret_cast<int32_t*>(get_register(sp));
1686 int32_t arg4 = stack_pointer[0]; 1734 int32_t arg4 = stack_pointer[0];
1687 int32_t arg5 = stack_pointer[1]; 1735 int32_t arg5 = stack_pointer[1];
1736 bool fp_call =
1737 (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) ||
1738 (redirection->type() == ExternalReference::BUILTIN_COMPARE_CALL) ||
1739 (redirection->type() == ExternalReference::BUILTIN_FP_CALL) ||
1740 (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL);
1741 if (FLAG_hardfloat) {
1742 // With the hard floating point calling convention, double
1743 // arguments are passed in VFP registers. Fetch the arguments
1744 // from there and call the builtin using soft floating point
1745 // convention.
1746 switch (redirection->type()) {
1747 case ExternalReference::BUILTIN_FP_FP_CALL:
1748 case ExternalReference::BUILTIN_COMPARE_CALL:
1749 arg0 = vfp_register[0];
1750 arg1 = vfp_register[1];
1751 arg2 = vfp_register[2];
1752 arg3 = vfp_register[3];
1753 break;
1754 case ExternalReference::BUILTIN_FP_CALL:
1755 arg0 = vfp_register[0];
1756 arg1 = vfp_register[1];
1757 break;
1758 case ExternalReference::BUILTIN_FP_INT_CALL:
1759 arg0 = vfp_register[0];
1760 arg1 = vfp_register[1];
1761 arg2 = get_register(0);
1762 break;
1763 default:
1764 break;
1765 }
1766 }
1688 // This is dodgy but it works because the C entry stubs are never moved. 1767 // This is dodgy but it works because the C entry stubs are never moved.
1689 // See comment in codegen-arm.cc and bug 1242173. 1768 // See comment in codegen-arm.cc and bug 1242173.
1690 int32_t saved_lr = get_register(lr); 1769 int32_t saved_lr = get_register(lr);
1691 intptr_t external = 1770 intptr_t external =
1692 reinterpret_cast<intptr_t>(redirection->external_function()); 1771 reinterpret_cast<intptr_t>(redirection->external_function());
1693 if (redirection->type() == ExternalReference::FP_RETURN_CALL) { 1772 if (fp_call) {
1694 SimulatorRuntimeFPCall target = 1773 SimulatorRuntimeFPCall target =
1695 reinterpret_cast<SimulatorRuntimeFPCall>(external); 1774 reinterpret_cast<SimulatorRuntimeFPCall>(external);
1696 if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 1775 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1697 double x, y; 1776 double dval0, dval1;
1698 GetFpArgs(&x, &y); 1777 int32_t ival;
1699 PrintF("Call to host function at %p with args %f, %f", 1778 switch (redirection->type()) {
1700 FUNCTION_ADDR(target), x, y); 1779 case ExternalReference::BUILTIN_FP_FP_CALL:
1780 case ExternalReference::BUILTIN_COMPARE_CALL:
1781 GetFpArgs(&dval0, &dval1);
1782 PrintF("Call to host function at %p with args %f, %f",
1783 FUNCTION_ADDR(target), dval0, dval1);
1784 break;
1785 case ExternalReference::BUILTIN_FP_CALL:
1786 GetFpArgs(&dval0);
1787 PrintF("Call to host function at %p with arg %f",
1788 FUNCTION_ADDR(target), dval1);
1789 break;
1790 case ExternalReference::BUILTIN_FP_INT_CALL:
1791 GetFpArgs(&dval0, &ival);
1792 PrintF("Call to host function at %p with args %f, %d",
1793 FUNCTION_ADDR(target), dval0, ival);
1794 break;
1795 default:
1796 UNREACHABLE();
1797 break;
1798 }
1701 if (!stack_aligned) { 1799 if (!stack_aligned) {
1702 PrintF(" with unaligned stack %08x\n", get_register(sp)); 1800 PrintF(" with unaligned stack %08x\n", get_register(sp));
1703 } 1801 }
1704 PrintF("\n"); 1802 PrintF("\n");
1705 } 1803 }
1706 CHECK(stack_aligned); 1804 CHECK(stack_aligned);
1707 double result = target(arg0, arg1, arg2, arg3); 1805 double result = target(arg0, arg1, arg2, arg3);
1708 SetFpResult(result); 1806 if (redirection->type() != ExternalReference::BUILTIN_COMPARE_CALL) {
1807 SetFpResult(result);
1808 }
1709 } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) { 1809 } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
1710 SimulatorRuntimeDirectApiCall target = 1810 SimulatorRuntimeDirectApiCall target =
1711 reinterpret_cast<SimulatorRuntimeDirectApiCall>(external); 1811 reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
1712 if (::v8::internal::FLAG_trace_sim || !stack_aligned) { 1812 if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
1713 PrintF("Call to host function at %p args %08x", 1813 PrintF("Call to host function at %p args %08x",
1714 FUNCTION_ADDR(target), arg0); 1814 FUNCTION_ADDR(target), arg0);
1715 if (!stack_aligned) { 1815 if (!stack_aligned) {
1716 PrintF(" with unaligned stack %08x\n", get_register(sp)); 1816 PrintF(" with unaligned stack %08x\n", get_register(sp));
1717 } 1817 }
1718 PrintF("\n"); 1818 PrintF("\n");
(...skipping 1586 matching lines...) Expand 10 before | Expand all | Expand 10 after
3305 uintptr_t address = *stack_slot; 3405 uintptr_t address = *stack_slot;
3306 set_register(sp, current_sp + sizeof(uintptr_t)); 3406 set_register(sp, current_sp + sizeof(uintptr_t));
3307 return address; 3407 return address;
3308 } 3408 }
3309 3409
3310 } } // namespace v8::internal 3410 } } // namespace v8::internal
3311 3411
3312 #endif // USE_SIMULATOR 3412 #endif // USE_SIMULATOR
3313 3413
3314 #endif // V8_TARGET_ARCH_ARM 3414 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/simulator-arm.h ('k') | src/assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698