| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include <math.h> // for isnan. | 5 #include <math.h> // for isnan. |
| 6 #include <setjmp.h> | 6 #include <setjmp.h> |
| 7 #include <stdlib.h> | 7 #include <stdlib.h> |
| 8 | 8 |
| 9 #include "vm/globals.h" | 9 #include "vm/globals.h" |
| 10 #if defined(TARGET_ARCH_ARM) | 10 #if defined(TARGET_ARCH_ARM) |
| (...skipping 2882 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2893 } else { | 2893 } else { |
| 2894 UnimplementedInstruction(instr); | 2894 UnimplementedInstruction(instr); |
| 2895 } | 2895 } |
| 2896 } | 2896 } |
| 2897 } else { | 2897 } else { |
| 2898 UnimplementedInstruction(instr); | 2898 UnimplementedInstruction(instr); |
| 2899 } | 2899 } |
| 2900 } | 2900 } |
| 2901 | 2901 |
| 2902 | 2902 |
| 2903 static float arm_recip_estimate(float a) { |
| 2904 // From the ARM Architecture Reference Manual A2-85. |
| 2905 if (isinf(a) || (abs(a) >= exp2f(126))) return 0.0; |
| 2906 else if (a == 0.0) return INFINITY; |
| 2907 else if (isnan(a)) return a; |
| 2908 |
| 2909 uint32_t a_bits = bit_cast<uint32_t, float>(a); |
| 2910 // scaled = '0011 1111 1110' : a<22:0> : Zeros(29) |
| 2911 uint64_t scaled = (static_cast<uint64_t>(0x3fe) << 52) | |
| 2912 ((static_cast<uint64_t>(a_bits) & 0x7fffff) << 29); |
| 2913 // result_exp = 253 - UInt(a<30:23>) |
| 2914 int32_t result_exp = 253 - ((a_bits >> 23) & 0xff); |
| 2915 ASSERT((result_exp >= 1) && (result_exp <= 252)); |
| 2916 |
| 2917 double scaled_d = bit_cast<double, uint64_t>(scaled); |
| 2918 ASSERT((scaled_d >= 0.5) && (scaled_d < 1.0)); |
| 2919 |
| 2920 // a in units of 1/512 rounded down. |
| 2921 int32_t q = static_cast<int32_t>(scaled_d * 512.0); |
| 2922 // reciprocal r. |
| 2923 double r = 1.0 / ((static_cast<double>(q) + 0.5) / 512.0); |
| 2924 // r in units of 1/256 rounded to nearest. |
| 2925 int32_t s = static_cast<int32_t>(256.0 * r + 0.5); |
| 2926 double estimate = static_cast<double>(s) / 256.0; |
| 2927 ASSERT((estimate >= 1.0) && (estimate <= (511.0/256.0))); |
| 2928 |
| 2929 // result = sign : result_exp<7:0> : estimate<51:29> |
| 2930 int32_t result_bits = |
| 2931 (a_bits & 0x80000000) | ((result_exp & 0xff) << 23) | |
| 2932 ((bit_cast<uint64_t, double>(estimate) >> 29) & 0x7fffff); |
| 2933 return bit_cast<float, int32_t>(result_bits); |
| 2934 } |
| 2935 |
| 2936 |
| 2903 void Simulator::DecodeSIMDDataProcessing(Instr* instr) { | 2937 void Simulator::DecodeSIMDDataProcessing(Instr* instr) { |
| 2904 ASSERT(instr->ConditionField() == kSpecialCondition); | 2938 ASSERT(instr->ConditionField() == kSpecialCondition); |
| 2905 | 2939 |
| 2906 if (instr->Bit(6) == 1) { | 2940 if (instr->Bit(6) == 1) { |
| 2907 // Q = 1, Using 128-bit Q registers. | 2941 // Q = 1, Using 128-bit Q registers. |
| 2908 const QRegister qd = instr->QdField(); | 2942 const QRegister qd = instr->QdField(); |
| 2909 const QRegister qn = instr->QnField(); | 2943 const QRegister qn = instr->QnField(); |
| 2910 const QRegister qm = instr->QmField(); | 2944 const QRegister qm = instr->QmField(); |
| 2911 simd_value_t s8d; | 2945 simd_value_t s8d; |
| 2912 simd_value_t s8n = get_qregister(qn); | 2946 simd_value_t s8n = get_qregister(qn); |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3031 // Format(instr, "vmovq 'qd, 'qm"); | 3065 // Format(instr, "vmovq 'qd, 'qm"); |
| 3032 for (int i = 0; i < 4; i++) { | 3066 for (int i = 0; i < 4; i++) { |
| 3033 s8d.data_[i].u = s8m.data_[i].u; | 3067 s8d.data_[i].u = s8m.data_[i].u; |
| 3034 } | 3068 } |
| 3035 } else { | 3069 } else { |
| 3036 // Format(instr, "vorrq 'qd, 'qm"); | 3070 // Format(instr, "vorrq 'qd, 'qm"); |
| 3037 for (int i = 0; i < 4; i++) { | 3071 for (int i = 0; i < 4; i++) { |
| 3038 s8d.data_[i].u = s8n.data_[i].u | s8m.data_[i].u; | 3072 s8d.data_[i].u = s8n.data_[i].u | s8m.data_[i].u; |
| 3039 } | 3073 } |
| 3040 } | 3074 } |
| 3075 } else if ((instr->Bits(8, 4) == 15) && (instr->Bit(4) == 0) && |
| 3076 (instr->Bits(20, 2) == 2) && (instr->Bits(23, 2) == 0)) { |
| 3077 // Format(instr, "vminqs 'qd, 'qn, 'qm"); |
| 3078 for (int i = 0; i < 4; i++) { |
| 3079 s8d.data_[i].f = |
| 3080 s8n.data_[i].f <= s8m.data_[i].f ? s8n.data_[i].f : s8m.data_[i].f; |
| 3081 } |
| 3082 } else if ((instr->Bits(8, 4) == 15) && (instr->Bit(4) == 0) && |
| 3083 (instr->Bits(20, 2) == 0) && (instr->Bits(23, 2) == 0)) { |
| 3084 // Format(instr, "vmaxqs 'qd, 'qn, 'qm"); |
| 3085 for (int i = 0; i < 4; i++) { |
| 3086 s8d.data_[i].f = |
| 3087 s8n.data_[i].f >= s8m.data_[i].f ? s8n.data_[i].f : s8m.data_[i].f; |
| 3088 } |
| 3089 } else if ((instr->Bits(7, 5) == 10) && (instr->Bit(4) == 0) && |
| 3090 (instr->Bits(20, 2) == 3) && (instr->Bits(23, 2) == 3) && |
| 3091 (instr->Bits(16, 4) == 11)) { |
| 3092 // Format(instr, "vrecpeq 'qd, 'qm"); |
| 3093 for (int i = 0; i < 4; i++) { |
| 3094 s8d.data_[i].f = arm_recip_estimate(s8m.data_[i].f); |
| 3095 } |
| 3096 } else if ((instr->Bits(8, 4) == 15) && (instr->Bit(4) == 1) && |
| 3097 (instr->Bits(20, 2) == 0) && (instr->Bits(23, 2) == 0)) { |
| 3098 // Format(instr, "vrecpsq 'qd, 'qn, 'qm"); |
| 3099 for (int i = 0; i < 4; i++) { |
| 3100 s8d.data_[i].f = 2.0 - (s8n.data_[i].f * s8m.data_[i].f); |
| 3101 } |
| 3041 } else if ((instr->Bits(8, 4) == 12) && (instr->Bit(4) == 0) && | 3102 } else if ((instr->Bits(8, 4) == 12) && (instr->Bit(4) == 0) && |
| 3042 (instr->Bits(20, 2) == 3) && (instr->Bits(23, 2) == 3) && | 3103 (instr->Bits(20, 2) == 3) && (instr->Bits(23, 2) == 3) && |
| 3043 (instr->Bit(7) == 0)) { | 3104 (instr->Bit(7) == 0)) { |
| 3044 DRegister dm = instr->DmField(); | 3105 DRegister dm = instr->DmField(); |
| 3045 int64_t dm_value = get_dregister_bits(dm); | 3106 int64_t dm_value = get_dregister_bits(dm); |
| 3046 int32_t imm4 = instr->Bits(16, 4); | 3107 int32_t imm4 = instr->Bits(16, 4); |
| 3047 int32_t idx; | 3108 int32_t idx; |
| 3048 if ((imm4 & 1) != 0) { | 3109 if ((imm4 & 1) != 0) { |
| 3049 // Format(instr, "vdupb 'qd, 'dm['imm4_vdup]"); | 3110 // Format(instr, "vdupb 'qd, 'dm['imm4_vdup]"); |
| 3050 int8_t* dm_b = reinterpret_cast<int8_t*>(&dm_value); | 3111 int8_t* dm_b = reinterpret_cast<int8_t*>(&dm_value); |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3475 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception)); | 3536 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception)); |
| 3476 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); | 3537 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); |
| 3477 buf->Longjmp(); | 3538 buf->Longjmp(); |
| 3478 } | 3539 } |
| 3479 | 3540 |
| 3480 } // namespace dart | 3541 } // namespace dart |
| 3481 | 3542 |
| 3482 #endif // !defined(HOST_ARCH_ARM) | 3543 #endif // !defined(HOST_ARCH_ARM) |
| 3483 | 3544 |
| 3484 #endif // defined TARGET_ARCH_ARM | 3545 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |