OLD | NEW |
---|---|
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 Loading... | |
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 } | |
1024 } | 1029 } |
1025 | 1030 |
1026 | 1031 |
1032 // The return value is either in r0/r1 or d0. | |
1027 void Simulator::SetFpResult(const double& result) { | 1033 void Simulator::SetFpResult(const double& result) { |
1028 char buffer[2 * sizeof(registers_[0])]; | 1034 if (FLAG_hardfloat) { |
1029 memcpy(buffer, &result, sizeof(buffer)); | 1035 char buffer[2 * sizeof(vfp_register[0])]; |
1030 // result -> registers 0 and 1. | 1036 memcpy(buffer, &result, sizeof(buffer)); |
1031 memcpy(registers_, buffer, sizeof(buffer)); | 1037 // Copy result to d0. |
1038 memcpy(vfp_register, buffer, sizeof(buffer)); | |
1039 } else { | |
1040 char buffer[2 * sizeof(registers_[0])]; | |
1041 memcpy(buffer, &result, sizeof(buffer)); | |
1042 // Copy result to r0 and r1. | |
1043 memcpy(registers_, buffer, sizeof(buffer)); | |
1044 } | |
1032 } | 1045 } |
1033 | 1046 |
1034 | 1047 |
1035 void Simulator::TrashCallerSaveRegisters() { | 1048 void Simulator::TrashCallerSaveRegisters() { |
1036 // We don't trash the registers with the return value. | 1049 // We don't trash the registers with the return value. |
1037 registers_[2] = 0x50Bad4U; | 1050 registers_[2] = 0x50Bad4U; |
1038 registers_[3] = 0x50Bad4U; | 1051 registers_[3] = 0x50Bad4U; |
1039 registers_[12] = 0x50Bad4U; | 1052 registers_[12] = 0x50Bad4U; |
1040 } | 1053 } |
1041 | 1054 |
(...skipping 636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1678 (get_register(sp) | 1691 (get_register(sp) |
1679 & (::v8::internal::FLAG_sim_stack_alignment - 1)) == 0; | 1692 & (::v8::internal::FLAG_sim_stack_alignment - 1)) == 0; |
1680 Redirection* redirection = Redirection::FromSwiInstruction(instr); | 1693 Redirection* redirection = Redirection::FromSwiInstruction(instr); |
1681 int32_t arg0 = get_register(r0); | 1694 int32_t arg0 = get_register(r0); |
1682 int32_t arg1 = get_register(r1); | 1695 int32_t arg1 = get_register(r1); |
1683 int32_t arg2 = get_register(r2); | 1696 int32_t arg2 = get_register(r2); |
1684 int32_t arg3 = get_register(r3); | 1697 int32_t arg3 = get_register(r3); |
1685 int32_t* stack_pointer = reinterpret_cast<int32_t*>(get_register(sp)); | 1698 int32_t* stack_pointer = reinterpret_cast<int32_t*>(get_register(sp)); |
1686 int32_t arg4 = stack_pointer[0]; | 1699 int32_t arg4 = stack_pointer[0]; |
1687 int32_t arg5 = stack_pointer[1]; | 1700 int32_t arg5 = stack_pointer[1]; |
1701 bool fp_call = | |
1702 (redirection->type() == ExternalReference::BUILTIN_FP_FP_CALL) || | |
1703 (redirection->type() == ExternalReference::BUILTIN_FP_CALL) || | |
1704 (redirection->type() == ExternalReference::BUILTIN_FP_INT_CALL); | |
1705 if (FLAG_hardfloat) { | |
1706 // With the hard floating point calling convention, double | |
1707 // arguments are passed in VFP registers. Fetch the arguments | |
1708 // from there and call the builtin using soft floating point | |
1709 // convention. | |
1710 switch (redirection->type()) { | |
1711 case ExternalReference::BUILTIN_FP_FP_CALL: | |
1712 arg0 = vfp_register[0]; | |
1713 arg1 = vfp_register[1]; | |
1714 arg2 = vfp_register[2]; | |
1715 arg3 = vfp_register[3]; | |
1716 break; | |
1717 case ExternalReference::BUILTIN_FP_CALL: | |
1718 arg0 = vfp_register[0]; | |
1719 arg1 = vfp_register[1]; | |
1720 break; | |
1721 case ExternalReference::BUILTIN_FP_INT_CALL: | |
1722 arg0 = vfp_register[0]; | |
1723 arg1 = vfp_register[1]; | |
1724 arg2 = get_register(0); | |
1725 break; | |
1726 default: | |
1727 break; | |
1728 } | |
1729 } | |
1688 // This is dodgy but it works because the C entry stubs are never moved. | 1730 // This is dodgy but it works because the C entry stubs are never moved. |
1689 // See comment in codegen-arm.cc and bug 1242173. | 1731 // See comment in codegen-arm.cc and bug 1242173. |
1690 int32_t saved_lr = get_register(lr); | 1732 int32_t saved_lr = get_register(lr); |
1691 intptr_t external = | 1733 intptr_t external = |
1692 reinterpret_cast<intptr_t>(redirection->external_function()); | 1734 reinterpret_cast<intptr_t>(redirection->external_function()); |
1693 if (redirection->type() == ExternalReference::FP_RETURN_CALL) { | 1735 if (fp_call) { |
1694 SimulatorRuntimeFPCall target = | 1736 SimulatorRuntimeFPCall target = |
1695 reinterpret_cast<SimulatorRuntimeFPCall>(external); | 1737 reinterpret_cast<SimulatorRuntimeFPCall>(external); |
1696 if (::v8::internal::FLAG_trace_sim || !stack_aligned) { | 1738 if (::v8::internal::FLAG_trace_sim || !stack_aligned) { |
Søren Thygesen Gjesse
2011/04/27 08:19:01
This printout of the arguments is not correct. It
Karl Klose
2011/04/27 12:54:13
Done.
| |
1697 double x, y; | 1739 double x, y; |
1698 GetFpArgs(&x, &y); | 1740 GetFpArgs(&x, &y); |
1699 PrintF("Call to host function at %p with args %f, %f", | 1741 PrintF("Call to host function at %p with args %f, %f", |
1700 FUNCTION_ADDR(target), x, y); | 1742 FUNCTION_ADDR(target), x, y); |
1701 if (!stack_aligned) { | 1743 if (!stack_aligned) { |
1702 PrintF(" with unaligned stack %08x\n", get_register(sp)); | 1744 PrintF(" with unaligned stack %08x\n", get_register(sp)); |
1703 } | 1745 } |
1704 PrintF("\n"); | 1746 PrintF("\n"); |
1705 } | 1747 } |
1706 CHECK(stack_aligned); | 1748 CHECK(stack_aligned); |
(...skipping 1598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3305 uintptr_t address = *stack_slot; | 3347 uintptr_t address = *stack_slot; |
3306 set_register(sp, current_sp + sizeof(uintptr_t)); | 3348 set_register(sp, current_sp + sizeof(uintptr_t)); |
3307 return address; | 3349 return address; |
3308 } | 3350 } |
3309 | 3351 |
3310 } } // namespace v8::internal | 3352 } } // namespace v8::internal |
3311 | 3353 |
3312 #endif // USE_SIMULATOR | 3354 #endif // USE_SIMULATOR |
3313 | 3355 |
3314 #endif // V8_TARGET_ARCH_ARM | 3356 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |