Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 927 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 938 vfp_register[sreg] = value; | 938 vfp_register[sreg] = value; |
| 939 } | 939 } |
| 940 | 940 |
| 941 | 941 |
| 942 unsigned int Simulator::get_s_register(int sreg) const { | 942 unsigned int Simulator::get_s_register(int sreg) const { |
| 943 ASSERT((sreg >= 0) && (sreg < num_s_registers)); | 943 ASSERT((sreg >= 0) && (sreg < num_s_registers)); |
| 944 return vfp_register[sreg]; | 944 return vfp_register[sreg]; |
| 945 } | 945 } |
| 946 | 946 |
| 947 | 947 |
| 948 void Simulator::set_s_register_from_float(int sreg, const float flt) { | 948 template<class InputType, int register_size> |
| 949 ASSERT((sreg >= 0) && (sreg < num_s_registers)); | 949 void Simulator::SetVFPRegister(int reg_index, const InputType& value) { |
| 950 // Read the bits from the single precision floating point value | 950 ASSERT(reg_index >= 0); |
| 951 // into the unsigned integer element of vfp_register[] given by index=sreg. | 951 if (register_size == 1) ASSERT(reg_index < num_s_registers); |
| 952 char buffer[sizeof(vfp_register[0])]; | 952 if (register_size == 2) ASSERT(reg_index < num_d_registers); |
| 953 memcpy(buffer, &flt, sizeof(vfp_register[0])); | 953 |
| 954 memcpy(&vfp_register[sreg], buffer, sizeof(vfp_register[0])); | 954 char buffer[register_size * sizeof(vfp_register[0])]; |
| 955 memcpy(buffer, &value, register_size * sizeof(vfp_register[0])); | |
| 956 memcpy(&vfp_register[reg_index * register_size], buffer, | |
| 957 register_size * sizeof(vfp_register[0])); | |
| 955 } | 958 } |
| 956 | 959 |
| 957 | 960 |
| 958 void Simulator::set_s_register_from_sinteger(int sreg, const int sint) { | 961 template<class ReturnType, int register_size> |
| 959 ASSERT((sreg >= 0) && (sreg < num_s_registers)); | 962 ReturnType Simulator::GetFromVFPRegister(int reg_index) { |
| 960 // Read the bits from the integer value into the unsigned integer element of | 963 ASSERT(reg_index >= 0); |
| 961 // vfp_register[] given by index=sreg. | 964 if (register_size == 1) ASSERT(reg_index < num_s_registers); |
| 962 char buffer[sizeof(vfp_register[0])]; | 965 if (register_size == 2) ASSERT(reg_index < num_d_registers); |
| 963 memcpy(buffer, &sint, sizeof(vfp_register[0])); | 966 |
| 964 memcpy(&vfp_register[sreg], buffer, sizeof(vfp_register[0])); | 967 ReturnType value = 0; |
| 968 char buffer[register_size * sizeof(vfp_register[0])]; | |
| 969 memcpy(buffer, &vfp_register[register_size * reg_index], | |
| 970 register_size * sizeof(vfp_register[0])); | |
| 971 memcpy(&value, buffer, register_size * sizeof(vfp_register[0])); | |
| 972 return value; | |
| 965 } | 973 } |
| 966 | 974 |
| 967 | 975 |
| 968 void Simulator::set_d_register_from_double(int dreg, const double& dbl) { | |
| 969 ASSERT((dreg >= 0) && (dreg < num_d_registers)); | |
| 970 // Read the bits from the double precision floating point value into the two | |
| 971 // consecutive unsigned integer elements of vfp_register[] given by index | |
| 972 // 2*sreg and 2*sreg+1. | |
| 973 char buffer[2 * sizeof(vfp_register[0])]; | |
| 974 memcpy(buffer, &dbl, 2 * sizeof(vfp_register[0])); | |
| 975 memcpy(&vfp_register[dreg * 2], buffer, 2 * sizeof(vfp_register[0])); | |
| 976 } | |
| 977 | |
| 978 | |
| 979 float Simulator::get_float_from_s_register(int sreg) { | |
| 980 ASSERT((sreg >= 0) && (sreg < num_s_registers)); | |
| 981 | |
| 982 float sm_val = 0.0; | |
| 983 // Read the bits from the unsigned integer vfp_register[] array | |
| 984 // into the single precision floating point value and return it. | |
| 985 char buffer[sizeof(vfp_register[0])]; | |
| 986 memcpy(buffer, &vfp_register[sreg], sizeof(vfp_register[0])); | |
| 987 memcpy(&sm_val, buffer, sizeof(vfp_register[0])); | |
| 988 return(sm_val); | |
| 989 } | |
| 990 | |
| 991 | |
| 992 int Simulator::get_sinteger_from_s_register(int sreg) { | |
| 993 ASSERT((sreg >= 0) && (sreg < num_s_registers)); | |
| 994 | |
| 995 int sm_val = 0; | |
| 996 // Read the bits from the unsigned integer vfp_register[] array | |
| 997 // into the single precision floating point value and return it. | |
| 998 char buffer[sizeof(vfp_register[0])]; | |
| 999 memcpy(buffer, &vfp_register[sreg], sizeof(vfp_register[0])); | |
| 1000 memcpy(&sm_val, buffer, sizeof(vfp_register[0])); | |
| 1001 return(sm_val); | |
| 1002 } | |
| 1003 | |
| 1004 | |
| 1005 double Simulator::get_double_from_d_register(int dreg) { | |
| 1006 ASSERT((dreg >= 0) && (dreg < num_d_registers)); | |
| 1007 | |
| 1008 double dm_val = 0.0; | |
| 1009 // Read the bits from the unsigned integer vfp_register[] array | |
| 1010 // into the double precision floating point value and return it. | |
| 1011 char buffer[2 * sizeof(vfp_register[0])]; | |
| 1012 memcpy(buffer, &vfp_register[2 * dreg], 2 * sizeof(vfp_register[0])); | |
| 1013 memcpy(&dm_val, buffer, 2 * sizeof(vfp_register[0])); | |
| 1014 return(dm_val); | |
| 1015 } | |
| 1016 | |
| 1017 | |
| 1018 // For use in calls that take two double values, constructed either | 976 // For use in calls that take two double values, constructed either |
| 1019 // from r0-r3 or d0 and d1. | 977 // from r0-r3 or d0 and d1. |
| 1020 void Simulator::GetFpArgs(double* x, double* y) { | 978 void Simulator::GetFpArgs(double* x, double* y) { |
| 1021 if (use_eabi_hardfloat()) { | 979 if (use_eabi_hardfloat()) { |
| 1022 *x = vfp_register[0]; | 980 *x = vfp_register[0]; |
| 1023 *y = vfp_register[1]; | 981 *y = vfp_register[1]; |
| 1024 } else { | 982 } else { |
| 1025 // We use a char buffer to get around the strict-aliasing rules which | 983 // We use a char buffer to get around the strict-aliasing rules which |
| 1026 // otherwise allow the compiler to optimize away the copy. | 984 // otherwise allow the compiler to optimize away the copy. |
| 1027 char buffer[sizeof(*x)]; | 985 char buffer[sizeof(*x)]; |
| (...skipping 1676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2704 | 2662 |
| 2705 void Simulator::DecodeType7(Instruction* instr) { | 2663 void Simulator::DecodeType7(Instruction* instr) { |
| 2706 if (instr->Bit(24) == 1) { | 2664 if (instr->Bit(24) == 1) { |
| 2707 SoftwareInterrupt(instr); | 2665 SoftwareInterrupt(instr); |
| 2708 } else { | 2666 } else { |
| 2709 DecodeTypeVFP(instr); | 2667 DecodeTypeVFP(instr); |
| 2710 } | 2668 } |
| 2711 } | 2669 } |
| 2712 | 2670 |
| 2713 | 2671 |
| 2672 // Currently supports: | |
| 2673 // Dd = vorr(Dn, Dm) | |
| 2674 void Simulator::DecodeSpecialCondition(Instruction* instr) { | |
| 2675 // See ARM DDI 0406A, A7-12 for how to detect which instruction this is. | |
| 2676 if (instr->Bits(11, 8) == 0x1 && | |
| 2677 instr->Bit(4) == 0x1 && | |
| 2678 instr->Bit(24) == 0x0 && | |
| 2679 instr->Opc1Value() == 0x2) { | |
|
Erik Corry
2012/08/06 10:44:40
Same question here as in the disassembler?
Jakob Kummerow
2012/08/06 14:08:43
Same answer: removed vorr.
| |
| 2680 // vorr | |
| 2681 | |
| 2682 // Obtain double precision register codes. | |
| 2683 int vm = instr->VFPMRegValue(kDoublePrecision); | |
| 2684 int vd = instr->VFPDRegValue(kDoublePrecision); | |
| 2685 int vn = instr->VFPNRegValue(kDoublePrecision); | |
| 2686 | |
| 2687 int64_t dn_value = get_raw_bits_from_d_register(vn); | |
| 2688 int64_t dm_value = get_raw_bits_from_d_register(vm); | |
| 2689 set_d_register_from_raw_bits(vd, dn_value | dm_value); | |
| 2690 } else { | |
| 2691 UNREACHABLE(); // Not used by V8. | |
| 2692 } | |
| 2693 } | |
| 2694 | |
| 2695 | |
| 2714 // void Simulator::DecodeTypeVFP(Instruction* instr) | 2696 // void Simulator::DecodeTypeVFP(Instruction* instr) |
| 2715 // The Following ARMv7 VFPv instructions are currently supported. | 2697 // The Following ARMv7 VFPv instructions are currently supported. |
| 2716 // vmov :Sn = Rt | 2698 // vmov :Sn = Rt |
| 2717 // vmov :Rt = Sn | 2699 // vmov :Rt = Sn |
| 2718 // vcvt: Dd = Sm | 2700 // vcvt: Dd = Sm |
| 2719 // vcvt: Sd = Dm | 2701 // vcvt: Sd = Dm |
| 2720 // Dd = vabs(Dm) | 2702 // Dd = vabs(Dm) |
| 2721 // Dd = vneg(Dm) | 2703 // Dd = vneg(Dm) |
| 2722 // Dd = vadd(Dn, Dm) | 2704 // Dd = vadd(Dn, Dm) |
| 2723 // Dd = vsub(Dn, Dm) | 2705 // Dd = vsub(Dn, Dm) |
| (...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3233 if (::v8::internal::FLAG_trace_sim) { | 3215 if (::v8::internal::FLAG_trace_sim) { |
| 3234 disasm::NameConverter converter; | 3216 disasm::NameConverter converter; |
| 3235 disasm::Disassembler dasm(converter); | 3217 disasm::Disassembler dasm(converter); |
| 3236 // use a reasonably large buffer | 3218 // use a reasonably large buffer |
| 3237 v8::internal::EmbeddedVector<char, 256> buffer; | 3219 v8::internal::EmbeddedVector<char, 256> buffer; |
| 3238 dasm.InstructionDecode(buffer, | 3220 dasm.InstructionDecode(buffer, |
| 3239 reinterpret_cast<byte*>(instr)); | 3221 reinterpret_cast<byte*>(instr)); |
| 3240 PrintF(" 0x%08x %s\n", reinterpret_cast<intptr_t>(instr), buffer.start()); | 3222 PrintF(" 0x%08x %s\n", reinterpret_cast<intptr_t>(instr), buffer.start()); |
| 3241 } | 3223 } |
| 3242 if (instr->ConditionField() == kSpecialCondition) { | 3224 if (instr->ConditionField() == kSpecialCondition) { |
| 3243 UNIMPLEMENTED(); | 3225 DecodeSpecialCondition(instr); |
| 3244 } else if (ConditionallyExecute(instr)) { | 3226 } else if (ConditionallyExecute(instr)) { |
| 3245 switch (instr->TypeValue()) { | 3227 switch (instr->TypeValue()) { |
| 3246 case 0: | 3228 case 0: |
| 3247 case 1: { | 3229 case 1: { |
| 3248 DecodeType01(instr); | 3230 DecodeType01(instr); |
| 3249 break; | 3231 break; |
| 3250 } | 3232 } |
| 3251 case 2: { | 3233 case 2: { |
| 3252 DecodeType2(instr); | 3234 DecodeType2(instr); |
| 3253 break; | 3235 break; |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3426 uintptr_t address = *stack_slot; | 3408 uintptr_t address = *stack_slot; |
| 3427 set_register(sp, current_sp + sizeof(uintptr_t)); | 3409 set_register(sp, current_sp + sizeof(uintptr_t)); |
| 3428 return address; | 3410 return address; |
| 3429 } | 3411 } |
| 3430 | 3412 |
| 3431 } } // namespace v8::internal | 3413 } } // namespace v8::internal |
| 3432 | 3414 |
| 3433 #endif // USE_SIMULATOR | 3415 #endif // USE_SIMULATOR |
| 3434 | 3416 |
| 3435 #endif // V8_TARGET_ARCH_ARM | 3417 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |