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 998 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1009 ASSERT((reg >= 0) && (reg < kNumSimuRegisters)); | 1009 ASSERT((reg >= 0) && (reg < kNumSimuRegisters)); |
1010 if (reg == pc) { | 1010 if (reg == pc) { |
1011 pc_modified_ = true; | 1011 pc_modified_ = true; |
1012 } | 1012 } |
1013 | 1013 |
1014 // Zero register always holds 0. | 1014 // Zero register always holds 0. |
1015 registers_[reg] = (reg == 0) ? 0 : value; | 1015 registers_[reg] = (reg == 0) ? 0 : value; |
1016 } | 1016 } |
1017 | 1017 |
1018 | 1018 |
| 1019 void Simulator::set_dw_register(int reg, const int* dbl) { |
| 1020 ASSERT((reg >= 0) && (reg < kNumSimuRegisters)); |
| 1021 registers_[reg] = dbl[0]; |
| 1022 registers_[reg + 1] = dbl[1]; |
| 1023 } |
| 1024 |
| 1025 |
1019 void Simulator::set_fpu_register(int fpureg, int32_t value) { | 1026 void Simulator::set_fpu_register(int fpureg, int32_t value) { |
1020 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1027 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1021 FPUregisters_[fpureg] = value; | 1028 FPUregisters_[fpureg] = value; |
1022 } | 1029 } |
1023 | 1030 |
1024 | 1031 |
1025 void Simulator::set_fpu_register_float(int fpureg, float value) { | 1032 void Simulator::set_fpu_register_float(int fpureg, float value) { |
1026 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1033 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1027 *BitCast<float*>(&FPUregisters_[fpureg]) = value; | 1034 *BitCast<float*>(&FPUregisters_[fpureg]) = value; |
1028 } | 1035 } |
1029 | 1036 |
1030 | 1037 |
1031 void Simulator::set_fpu_register_double(int fpureg, double value) { | 1038 void Simulator::set_fpu_register_double(int fpureg, double value) { |
1032 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); | 1039 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); |
1033 *BitCast<double*>(&FPUregisters_[fpureg]) = value; | 1040 *BitCast<double*>(&FPUregisters_[fpureg]) = value; |
1034 } | 1041 } |
1035 | 1042 |
1036 | 1043 |
1037 // Get the register from the architecture state. This function does handle | 1044 // Get the register from the architecture state. This function does handle |
1038 // the special case of accessing the PC register. | 1045 // the special case of accessing the PC register. |
1039 int32_t Simulator::get_register(int reg) const { | 1046 int32_t Simulator::get_register(int reg) const { |
1040 ASSERT((reg >= 0) && (reg < kNumSimuRegisters)); | 1047 ASSERT((reg >= 0) && (reg < kNumSimuRegisters)); |
1041 if (reg == 0) | 1048 if (reg == 0) |
1042 return 0; | 1049 return 0; |
1043 else | 1050 else |
1044 return registers_[reg] + ((reg == pc) ? Instruction::kPCReadOffset : 0); | 1051 return registers_[reg] + ((reg == pc) ? Instruction::kPCReadOffset : 0); |
1045 } | 1052 } |
1046 | 1053 |
1047 | 1054 |
| 1055 double Simulator::get_double_from_register_pair(int reg) { |
| 1056 ASSERT((reg >= 0) && (reg < kNumSimuRegisters) && ((reg % 2) == 0)); |
| 1057 |
| 1058 double dm_val = 0.0; |
| 1059 // Read the bits from the unsigned integer register_[] array |
| 1060 // into the double precision floating point value and return it. |
| 1061 char buffer[2 * sizeof(registers_[0])]; |
| 1062 memcpy(buffer, ®isters_[reg], 2 * sizeof(registers_[0])); |
| 1063 memcpy(&dm_val, buffer, 2 * sizeof(registers_[0])); |
| 1064 return(dm_val); |
| 1065 } |
| 1066 |
| 1067 |
1048 int32_t Simulator::get_fpu_register(int fpureg) const { | 1068 int32_t Simulator::get_fpu_register(int fpureg) const { |
1049 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); | 1069 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters)); |
1050 return FPUregisters_[fpureg]; | 1070 return FPUregisters_[fpureg]; |
1051 } | 1071 } |
1052 | 1072 |
1053 | 1073 |
1054 int64_t Simulator::get_fpu_register_long(int fpureg) const { | 1074 int64_t Simulator::get_fpu_register_long(int fpureg) const { |
1055 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); | 1075 ASSERT((fpureg >= 0) && (fpureg < kNumFPURegisters) && ((fpureg % 2) == 0)); |
1056 return *BitCast<int64_t*>( | 1076 return *BitCast<int64_t*>( |
1057 const_cast<int32_t*>(&FPUregisters_[fpureg])); | 1077 const_cast<int32_t*>(&FPUregisters_[fpureg])); |
(...skipping 1653 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2711 dbg.Debug(); | 2731 dbg.Debug(); |
2712 } else { | 2732 } else { |
2713 InstructionDecode(instr); | 2733 InstructionDecode(instr); |
2714 } | 2734 } |
2715 program_counter = get_pc(); | 2735 program_counter = get_pc(); |
2716 } | 2736 } |
2717 } | 2737 } |
2718 } | 2738 } |
2719 | 2739 |
2720 | 2740 |
2721 int32_t Simulator::Call(byte* entry, int argument_count, ...) { | 2741 void Simulator::CallInternal(byte* entry) { |
2722 va_list parameters; | |
2723 va_start(parameters, argument_count); | |
2724 // Set up arguments. | |
2725 | |
2726 // First four arguments passed in registers. | |
2727 ASSERT(argument_count >= 4); | |
2728 set_register(a0, va_arg(parameters, int32_t)); | |
2729 set_register(a1, va_arg(parameters, int32_t)); | |
2730 set_register(a2, va_arg(parameters, int32_t)); | |
2731 set_register(a3, va_arg(parameters, int32_t)); | |
2732 | |
2733 // Remaining arguments passed on stack. | |
2734 int original_stack = get_register(sp); | |
2735 // Compute position of stack on entry to generated code. | |
2736 int entry_stack = (original_stack - (argument_count - 4) * sizeof(int32_t) | |
2737 - kCArgsSlotsSize); | |
2738 if (OS::ActivationFrameAlignment() != 0) { | |
2739 entry_stack &= -OS::ActivationFrameAlignment(); | |
2740 } | |
2741 // Store remaining arguments on stack, from low to high memory. | |
2742 intptr_t* stack_argument = reinterpret_cast<intptr_t*>(entry_stack); | |
2743 for (int i = 4; i < argument_count; i++) { | |
2744 stack_argument[i - 4 + kCArgSlotCount] = va_arg(parameters, int32_t); | |
2745 } | |
2746 va_end(parameters); | |
2747 set_register(sp, entry_stack); | |
2748 | |
2749 // Prepare to execute the code at entry. | 2742 // Prepare to execute the code at entry. |
2750 set_register(pc, reinterpret_cast<int32_t>(entry)); | 2743 set_register(pc, reinterpret_cast<int32_t>(entry)); |
2751 // Put down marker for end of simulation. The simulator will stop simulation | 2744 // Put down marker for end of simulation. The simulator will stop simulation |
2752 // when the PC reaches this value. By saving the "end simulation" value into | 2745 // when the PC reaches this value. By saving the "end simulation" value into |
2753 // the LR the simulation stops when returning to this call point. | 2746 // the LR the simulation stops when returning to this call point. |
2754 set_register(ra, end_sim_pc); | 2747 set_register(ra, end_sim_pc); |
2755 | 2748 |
2756 // Remember the values of callee-saved registers. | 2749 // Remember the values of callee-saved registers. |
2757 // The code below assumes that r9 is not used as sb (static base) in | 2750 // The code below assumes that r9 is not used as sb (static base) in |
2758 // simulator code and therefore is regarded as a callee-saved register. | 2751 // simulator code and therefore is regarded as a callee-saved register. |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2802 set_register(s1, s1_val); | 2795 set_register(s1, s1_val); |
2803 set_register(s2, s2_val); | 2796 set_register(s2, s2_val); |
2804 set_register(s3, s3_val); | 2797 set_register(s3, s3_val); |
2805 set_register(s4, s4_val); | 2798 set_register(s4, s4_val); |
2806 set_register(s5, s5_val); | 2799 set_register(s5, s5_val); |
2807 set_register(s6, s6_val); | 2800 set_register(s6, s6_val); |
2808 set_register(s7, s7_val); | 2801 set_register(s7, s7_val); |
2809 set_register(gp, gp_val); | 2802 set_register(gp, gp_val); |
2810 set_register(sp, sp_val); | 2803 set_register(sp, sp_val); |
2811 set_register(fp, fp_val); | 2804 set_register(fp, fp_val); |
| 2805 } |
| 2806 |
| 2807 |
| 2808 int32_t Simulator::Call(byte* entry, int argument_count, ...) { |
| 2809 va_list parameters; |
| 2810 va_start(parameters, argument_count); |
| 2811 // Set up arguments. |
| 2812 |
| 2813 // First four arguments passed in registers. |
| 2814 ASSERT(argument_count >= 4); |
| 2815 set_register(a0, va_arg(parameters, int32_t)); |
| 2816 set_register(a1, va_arg(parameters, int32_t)); |
| 2817 set_register(a2, va_arg(parameters, int32_t)); |
| 2818 set_register(a3, va_arg(parameters, int32_t)); |
| 2819 |
| 2820 // Remaining arguments passed on stack. |
| 2821 int original_stack = get_register(sp); |
| 2822 // Compute position of stack on entry to generated code. |
| 2823 int entry_stack = (original_stack - (argument_count - 4) * sizeof(int32_t) |
| 2824 - kCArgsSlotsSize); |
| 2825 if (OS::ActivationFrameAlignment() != 0) { |
| 2826 entry_stack &= -OS::ActivationFrameAlignment(); |
| 2827 } |
| 2828 // Store remaining arguments on stack, from low to high memory. |
| 2829 intptr_t* stack_argument = reinterpret_cast<intptr_t*>(entry_stack); |
| 2830 for (int i = 4; i < argument_count; i++) { |
| 2831 stack_argument[i - 4 + kCArgSlotCount] = va_arg(parameters, int32_t); |
| 2832 } |
| 2833 va_end(parameters); |
| 2834 set_register(sp, entry_stack); |
| 2835 |
| 2836 CallInternal(entry); |
2812 | 2837 |
2813 // Pop stack passed arguments. | 2838 // Pop stack passed arguments. |
2814 CHECK_EQ(entry_stack, get_register(sp)); | 2839 CHECK_EQ(entry_stack, get_register(sp)); |
2815 set_register(sp, original_stack); | 2840 set_register(sp, original_stack); |
2816 | 2841 |
2817 int32_t result = get_register(v0); | 2842 int32_t result = get_register(v0); |
2818 return result; | 2843 return result; |
2819 } | 2844 } |
2820 | 2845 |
2821 | 2846 |
| 2847 double Simulator::CallFP(byte* entry, double d0, double d1) { |
| 2848 if (!IsMipsSoftFloatABI) { |
| 2849 set_fpu_register_double(f12, d0); |
| 2850 set_fpu_register_double(f14, d1); |
| 2851 } else { |
| 2852 int buffer[2]; |
| 2853 ASSERT(sizeof(buffer[0]) * 2 == sizeof(d0)); |
| 2854 memcpy(buffer, &d0, sizeof(d0)); |
| 2855 set_dw_register(a0, buffer); |
| 2856 memcpy(buffer, &d1, sizeof(d1)); |
| 2857 set_dw_register(a2, buffer); |
| 2858 } |
| 2859 CallInternal(entry); |
| 2860 if (!IsMipsSoftFloatABI) { |
| 2861 return get_fpu_register_double(f0); |
| 2862 } else { |
| 2863 return get_double_from_register_pair(v0); |
| 2864 } |
| 2865 } |
| 2866 |
| 2867 |
2822 uintptr_t Simulator::PushAddress(uintptr_t address) { | 2868 uintptr_t Simulator::PushAddress(uintptr_t address) { |
2823 int new_sp = get_register(sp) - sizeof(uintptr_t); | 2869 int new_sp = get_register(sp) - sizeof(uintptr_t); |
2824 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp); | 2870 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(new_sp); |
2825 *stack_slot = address; | 2871 *stack_slot = address; |
2826 set_register(sp, new_sp); | 2872 set_register(sp, new_sp); |
2827 return new_sp; | 2873 return new_sp; |
2828 } | 2874 } |
2829 | 2875 |
2830 | 2876 |
2831 uintptr_t Simulator::PopAddress() { | 2877 uintptr_t Simulator::PopAddress() { |
2832 int current_sp = get_register(sp); | 2878 int current_sp = get_register(sp); |
2833 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); | 2879 uintptr_t* stack_slot = reinterpret_cast<uintptr_t*>(current_sp); |
2834 uintptr_t address = *stack_slot; | 2880 uintptr_t address = *stack_slot; |
2835 set_register(sp, current_sp + sizeof(uintptr_t)); | 2881 set_register(sp, current_sp + sizeof(uintptr_t)); |
2836 return address; | 2882 return address; |
2837 } | 2883 } |
2838 | 2884 |
2839 | 2885 |
2840 #undef UNSUPPORTED | 2886 #undef UNSUPPORTED |
2841 | 2887 |
2842 } } // namespace v8::internal | 2888 } } // namespace v8::internal |
2843 | 2889 |
2844 #endif // USE_SIMULATOR | 2890 #endif // USE_SIMULATOR |
2845 | 2891 |
2846 #endif // V8_TARGET_ARCH_MIPS | 2892 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |