| 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 2896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2907 // Q = 1, Using 128-bit Q registers. | 2907 // Q = 1, Using 128-bit Q registers. |
| 2908 const QRegister qd = instr->QdField(); | 2908 const QRegister qd = instr->QdField(); |
| 2909 const QRegister qn = instr->QnField(); | 2909 const QRegister qn = instr->QnField(); |
| 2910 const QRegister qm = instr->QmField(); | 2910 const QRegister qm = instr->QmField(); |
| 2911 simd_value_t s8d; | 2911 simd_value_t s8d; |
| 2912 simd_value_t s8n = get_qregister(qn); | 2912 simd_value_t s8n = get_qregister(qn); |
| 2913 simd_value_t s8m = get_qregister(qm); | 2913 simd_value_t s8m = get_qregister(qm); |
| 2914 int8_t* s8d_8 = reinterpret_cast<int8_t*>(&s8d); | 2914 int8_t* s8d_8 = reinterpret_cast<int8_t*>(&s8d); |
| 2915 int8_t* s8n_8 = reinterpret_cast<int8_t*>(&s8n); | 2915 int8_t* s8n_8 = reinterpret_cast<int8_t*>(&s8n); |
| 2916 int8_t* s8m_8 = reinterpret_cast<int8_t*>(&s8m); | 2916 int8_t* s8m_8 = reinterpret_cast<int8_t*>(&s8m); |
| 2917 uint8_t* s8n_u8 = reinterpret_cast<uint8_t*>(&s8n); |
| 2918 uint8_t* s8m_u8 = reinterpret_cast<uint8_t*>(&s8m); |
| 2917 int16_t* s8d_16 = reinterpret_cast<int16_t*>(&s8d); | 2919 int16_t* s8d_16 = reinterpret_cast<int16_t*>(&s8d); |
| 2918 int16_t* s8n_16 = reinterpret_cast<int16_t*>(&s8n); | 2920 int16_t* s8n_16 = reinterpret_cast<int16_t*>(&s8n); |
| 2919 int16_t* s8m_16 = reinterpret_cast<int16_t*>(&s8m); | 2921 int16_t* s8m_16 = reinterpret_cast<int16_t*>(&s8m); |
| 2922 uint16_t* s8n_u16 = reinterpret_cast<uint16_t*>(&s8n); |
| 2923 uint16_t* s8m_u16 = reinterpret_cast<uint16_t*>(&s8m); |
| 2924 int32_t* s8n_32 = reinterpret_cast<int32_t*>(&s8n); |
| 2925 int32_t* s8m_32 = reinterpret_cast<int32_t*>(&s8m); |
| 2920 int64_t* s8d_64 = reinterpret_cast<int64_t*>(&s8d); | 2926 int64_t* s8d_64 = reinterpret_cast<int64_t*>(&s8d); |
| 2921 int64_t* s8n_64 = reinterpret_cast<int64_t*>(&s8n); | 2927 int64_t* s8n_64 = reinterpret_cast<int64_t*>(&s8n); |
| 2922 int64_t* s8m_64 = reinterpret_cast<int64_t*>(&s8m); | 2928 int64_t* s8m_64 = reinterpret_cast<int64_t*>(&s8m); |
| 2923 | 2929 |
| 2924 if ((instr->Bits(8, 4) == 8) && (instr->Bit(4) == 0) && | 2930 if ((instr->Bits(8, 4) == 8) && (instr->Bit(4) == 0) && |
| 2925 (instr->Bits(23, 2) == 0)) { | 2931 (instr->Bits(23, 2) == 0)) { |
| 2926 // Uses q registers. | 2932 // Uses q registers. |
| 2927 // Format(instr, "vadd.'sz 'qd, 'qn, 'qm"); | 2933 // Format(instr, "vadd.'sz 'qd, 'qn, 'qm"); |
| 2928 const int size = instr->Bits(20, 2); | 2934 const int size = instr->Bits(20, 2); |
| 2929 if (size == 0) { | 2935 if (size == 0) { |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3007 for (int i = 0; i < 4; i++) { | 3013 for (int i = 0; i < 4; i++) { |
| 3008 s8d.data_[i].f = s8n.data_[i].f * s8m.data_[i].f; | 3014 s8d.data_[i].f = s8n.data_[i].f * s8m.data_[i].f; |
| 3009 } | 3015 } |
| 3010 } else if ((instr->Bits(8, 4) == 1) && (instr->Bit(4) == 1) && | 3016 } else if ((instr->Bits(8, 4) == 1) && (instr->Bit(4) == 1) && |
| 3011 (instr->Bits(20, 2) == 0) && (instr->Bits(23, 2) == 2)) { | 3017 (instr->Bits(20, 2) == 0) && (instr->Bits(23, 2) == 2)) { |
| 3012 // Format(instr, "veorq 'qd, 'qn, 'qm"); | 3018 // Format(instr, "veorq 'qd, 'qn, 'qm"); |
| 3013 for (int i = 0; i < 4; i++) { | 3019 for (int i = 0; i < 4; i++) { |
| 3014 s8d.data_[i].u = s8n.data_[i].u ^ s8m.data_[i].u; | 3020 s8d.data_[i].u = s8n.data_[i].u ^ s8m.data_[i].u; |
| 3015 } | 3021 } |
| 3016 } else if ((instr->Bits(8, 4) == 1) && (instr->Bit(4) == 1) && | 3022 } else if ((instr->Bits(8, 4) == 1) && (instr->Bit(4) == 1) && |
| 3023 (instr->Bits(20, 2) == 3) && (instr->Bits(23, 2) == 0)) { |
| 3024 // Format(instr, "vornq 'qd, 'qn, 'qm"); |
| 3025 for (int i = 0; i < 4; i++) { |
| 3026 s8d.data_[i].u = s8n.data_[i].u | ~s8m.data_[i].u; |
| 3027 } |
| 3028 } else if ((instr->Bits(8, 4) == 1) && (instr->Bit(4) == 1) && |
| 3017 (instr->Bits(20, 2) == 2) && (instr->Bits(23, 2) == 0)) { | 3029 (instr->Bits(20, 2) == 2) && (instr->Bits(23, 2) == 0)) { |
| 3018 if (qm == qn) { | 3030 if (qm == qn) { |
| 3019 // Format(instr, "vmovq 'qd, 'qm"); | 3031 // Format(instr, "vmovq 'qd, 'qm"); |
| 3020 for (int i = 0; i < 4; i++) { | 3032 for (int i = 0; i < 4; i++) { |
| 3021 s8d.data_[i].u = s8m.data_[i].u; | 3033 s8d.data_[i].u = s8m.data_[i].u; |
| 3022 } | 3034 } |
| 3023 } else { | 3035 } else { |
| 3024 // Format(instr, "vorrq 'qd, 'qm"); | 3036 // Format(instr, "vorrq 'qd, 'qm"); |
| 3025 for (int i = 0; i < 4; i++) { | 3037 for (int i = 0; i < 4; i++) { |
| 3026 s8d.data_[i].u = s8n.data_[i].u | s8m.data_[i].u; | 3038 s8d.data_[i].u = s8n.data_[i].u | s8m.data_[i].u; |
| 3027 } | 3039 } |
| 3028 } | 3040 } |
| 3029 } else if ((instr->Bits(8, 4) == 12) && (instr->Bit(4) == 0) && | 3041 } else if ((instr->Bits(8, 4) == 12) && (instr->Bit(4) == 0) && |
| 3030 (instr->Bits(20, 2) == 3) && (instr->Bits(23, 2) == 3) && | 3042 (instr->Bits(20, 2) == 3) && (instr->Bits(23, 2) == 3) && |
| 3031 (instr->Bit(7) == 0)) { | 3043 (instr->Bit(7) == 0)) { |
| 3032 DRegister dm = instr->DmField(); | 3044 DRegister dm = instr->DmField(); |
| 3033 int64_t dm_value = get_dregister_bits(dm); | 3045 int64_t dm_value = get_dregister_bits(dm); |
| 3034 int32_t imm4 = instr->Bits(16, 4); | 3046 int32_t imm4 = instr->Bits(16, 4); |
| 3035 int32_t idx; | 3047 int32_t idx; |
| 3036 if ((imm4 & 1) != 0) { | 3048 if ((imm4 & 1) != 0) { |
| 3037 // Format(instr, "vdupb 'qd, 'dm['imm4_vdup]"); | 3049 // Format(instr, "vdupb 'qd, 'dm['imm4_vdup]"); |
| 3038 int8_t* dm_b = reinterpret_cast<int8_t*>(&dm_value); | 3050 int8_t* dm_b = reinterpret_cast<int8_t*>(&dm_value); |
| 3039 idx = imm4 >> 1; | 3051 idx = imm4 >> 1; |
| 3052 int8_t val = dm_b[idx]; |
| 3040 for (int i = 0; i < 16; i++) { | 3053 for (int i = 0; i < 16; i++) { |
| 3041 s8d_8[i] = dm_b[idx]; | 3054 s8d_8[i] = val; |
| 3042 } | 3055 } |
| 3043 } else if ((imm4 & 2) != 0) { | 3056 } else if ((imm4 & 2) != 0) { |
| 3044 // Format(instr, "vduph 'qd, 'dm['imm4_vdup]"); | 3057 // Format(instr, "vduph 'qd, 'dm['imm4_vdup]"); |
| 3045 int16_t* dm_h = reinterpret_cast<int16_t*>(&dm_value); | 3058 int16_t* dm_h = reinterpret_cast<int16_t*>(&dm_value); |
| 3046 idx = imm4 >> 2; | 3059 idx = imm4 >> 2; |
| 3060 int16_t val = dm_h[idx]; |
| 3047 for (int i = 0; i < 8; i++) { | 3061 for (int i = 0; i < 8; i++) { |
| 3048 s8d_16[i] = dm_h[idx]; | 3062 s8d_16[i] = val; |
| 3049 } | 3063 } |
| 3050 } else if ((imm4 & 4) != 0) { | 3064 } else if ((imm4 & 4) != 0) { |
| 3051 // Format(instr, "vdupw 'qd, 'dm['imm4_vdup]"); | 3065 // Format(instr, "vdupw 'qd, 'dm['imm4_vdup]"); |
| 3052 int32_t* dm_w = reinterpret_cast<int32_t*>(&dm_value); | 3066 int32_t* dm_w = reinterpret_cast<int32_t*>(&dm_value); |
| 3053 idx = imm4 >> 3; | 3067 idx = imm4 >> 3; |
| 3068 int32_t val = dm_w[idx]; |
| 3054 for (int i = 0; i < 4; i++) { | 3069 for (int i = 0; i < 4; i++) { |
| 3055 s8d.data_[i].u = dm_w[idx]; | 3070 s8d.data_[i].u = val; |
| 3056 } | 3071 } |
| 3057 } else { | 3072 } else { |
| 3058 UnimplementedInstruction(instr); | 3073 UnimplementedInstruction(instr); |
| 3059 } | 3074 } |
| 3075 } else if ((instr->Bits(8, 4) == 8) && (instr->Bit(4) == 1) && |
| 3076 (instr->Bits(23, 2) == 2)) { |
| 3077 // Format(instr, "vceqq'sz 'qd, 'qn, 'qm"); |
| 3078 const int size = instr->Bits(20, 2); |
| 3079 if (size == 0) { |
| 3080 for (int i = 0; i < 16; i++) { |
| 3081 s8d_8[i] = s8n_8[i] == s8m_8[i] ? 0xff : 0; |
| 3082 } |
| 3083 } else if (size == 1) { |
| 3084 for (int i = 0; i < 8; i++) { |
| 3085 s8d_16[i] = s8n_16[i] == s8m_16[i] ? 0xffff : 0; |
| 3086 } |
| 3087 } else if (size == 2) { |
| 3088 for (int i = 0; i < 4; i++) { |
| 3089 s8d.data_[i].u = s8n.data_[i].u == s8m.data_[i].u ? 0xffffffff : 0; |
| 3090 } |
| 3091 } else if (size == 3) { |
| 3092 UnimplementedInstruction(instr); |
| 3093 } else { |
| 3094 UNREACHABLE(); |
| 3095 } |
| 3096 } else if ((instr->Bits(8, 4) == 14) && (instr->Bit(4) == 0) && |
| 3097 (instr->Bits(20, 2) == 0) && (instr->Bits(23, 2) == 0)) { |
| 3098 // Format(instr, "vceqqs 'qd, 'qn, 'qm"); |
| 3099 for (int i = 0; i < 4; i++) { |
| 3100 s8d.data_[i].u = s8n.data_[i].f == s8m.data_[i].f ? 0xffffffff : 0; |
| 3101 } |
| 3102 } else if ((instr->Bits(8, 4) == 3) && (instr->Bit(4) == 1) && |
| 3103 (instr->Bits(23, 2) == 0)) { |
| 3104 // Format(instr, "vcgeq'sz 'qd, 'qn, 'qm"); |
| 3105 const int size = instr->Bits(20, 2); |
| 3106 if (size == 0) { |
| 3107 for (int i = 0; i < 16; i++) { |
| 3108 s8d_8[i] = s8n_8[i] >= s8m_8[i] ? 0xff : 0; |
| 3109 } |
| 3110 } else if (size == 1) { |
| 3111 for (int i = 0; i < 8; i++) { |
| 3112 s8d_16[i] = s8n_16[i] >= s8m_16[i] ? 0xffff : 0; |
| 3113 } |
| 3114 } else if (size == 2) { |
| 3115 for (int i = 0; i < 4; i++) { |
| 3116 s8d.data_[i].u = s8n_32[i] >= s8m_32[i] ? 0xffffffff : 0; |
| 3117 } |
| 3118 } else if (size == 3) { |
| 3119 UnimplementedInstruction(instr); |
| 3120 } else { |
| 3121 UNREACHABLE(); |
| 3122 } |
| 3123 } else if ((instr->Bits(8, 4) == 3) && (instr->Bit(4) == 1) && |
| 3124 (instr->Bits(23, 2) == 2)) { |
| 3125 // Format(instr, "vcugeq'sz 'qd, 'qn, 'qm"); |
| 3126 const int size = instr->Bits(20, 2); |
| 3127 if (size == 0) { |
| 3128 for (int i = 0; i < 16; i++) { |
| 3129 s8d_8[i] = s8n_u8[i] >= s8m_u8[i] ? 0xff : 0; |
| 3130 } |
| 3131 } else if (size == 1) { |
| 3132 for (int i = 0; i < 8; i++) { |
| 3133 s8d_16[i] = s8n_u16[i] >= s8m_u16[i] ? 0xffff : 0; |
| 3134 } |
| 3135 } else if (size == 2) { |
| 3136 for (int i = 0; i < 4; i++) { |
| 3137 s8d.data_[i].u = s8n.data_[i].u >= s8m.data_[i].u ? 0xffffffff : 0; |
| 3138 } |
| 3139 } else if (size == 3) { |
| 3140 UnimplementedInstruction(instr); |
| 3141 } else { |
| 3142 UNREACHABLE(); |
| 3143 } |
| 3144 } else if ((instr->Bits(8, 4) == 14) && (instr->Bit(4) == 0) && |
| 3145 (instr->Bits(20, 2) == 0) && (instr->Bits(23, 2) == 2)) { |
| 3146 // Format(instr, "vcgeqs 'qd, 'qn, 'qm"); |
| 3147 for (int i = 0; i < 4; i++) { |
| 3148 s8d.data_[i].u = s8n.data_[i].f >= s8m.data_[i].f ? 0xffffffff : 0; |
| 3149 } |
| 3150 } else if ((instr->Bits(8, 4) == 3) && (instr->Bit(4) == 0) && |
| 3151 (instr->Bits(23, 2) == 0)) { |
| 3152 // Format(instr, "vcgtq'sz 'qd, 'qn, 'qm"); |
| 3153 const int size = instr->Bits(20, 2); |
| 3154 if (size == 0) { |
| 3155 for (int i = 0; i < 16; i++) { |
| 3156 s8d_8[i] = s8n_8[i] > s8m_8[i] ? 0xff : 0; |
| 3157 } |
| 3158 } else if (size == 1) { |
| 3159 for (int i = 0; i < 8; i++) { |
| 3160 s8d_16[i] = s8n_16[i] > s8m_16[i] ? 0xffff : 0; |
| 3161 } |
| 3162 } else if (size == 2) { |
| 3163 for (int i = 0; i < 4; i++) { |
| 3164 s8d.data_[i].u = s8n_32[i] > s8m_32[i] ? 0xffffffff : 0; |
| 3165 } |
| 3166 } else if (size == 3) { |
| 3167 UnimplementedInstruction(instr); |
| 3168 } else { |
| 3169 UNREACHABLE(); |
| 3170 } |
| 3171 } else if ((instr->Bits(8, 4) == 3) && (instr->Bit(4) == 0) && |
| 3172 (instr->Bits(23, 2) == 2)) { |
| 3173 // Format(instr, "vcugtq'sz 'qd, 'qn, 'qm"); |
| 3174 const int size = instr->Bits(20, 2); |
| 3175 if (size == 0) { |
| 3176 for (int i = 0; i < 16; i++) { |
| 3177 s8d_8[i] = s8n_u8[i] > s8m_u8[i] ? 0xff : 0; |
| 3178 } |
| 3179 } else if (size == 1) { |
| 3180 for (int i = 0; i < 8; i++) { |
| 3181 s8d_16[i] = s8n_u16[i] > s8m_u16[i] ? 0xffff : 0; |
| 3182 } |
| 3183 } else if (size == 2) { |
| 3184 for (int i = 0; i < 4; i++) { |
| 3185 s8d.data_[i].u = s8n.data_[i].u > s8m.data_[i].u ? 0xffffffff : 0; |
| 3186 } |
| 3187 } else if (size == 3) { |
| 3188 UnimplementedInstruction(instr); |
| 3189 } else { |
| 3190 UNREACHABLE(); |
| 3191 } |
| 3192 } else if ((instr->Bits(8, 4) == 14) && (instr->Bit(4) == 0) && |
| 3193 (instr->Bits(20, 2) == 2) && (instr->Bits(23, 2) == 2)) { |
| 3194 // Format(instr, "vcgtqs 'qd, 'qn, 'qm"); |
| 3195 for (int i = 0; i < 4; i++) { |
| 3196 s8d.data_[i].u = s8n.data_[i].f > s8m.data_[i].f ? 0xffffffff : 0; |
| 3197 } |
| 3060 } else { | 3198 } else { |
| 3061 UnimplementedInstruction(instr); | 3199 UnimplementedInstruction(instr); |
| 3062 } | 3200 } |
| 3063 | 3201 |
| 3064 set_qregister(qd, s8d); | 3202 set_qregister(qd, s8d); |
| 3065 } else { | 3203 } else { |
| 3066 // Q == 0, Uses 64-bit D registers. | 3204 // Q == 0, Uses 64-bit D registers. |
| 3067 if ((instr->Bits(23, 2) == 3) && (instr->Bits(20, 2) == 3) && | 3205 if ((instr->Bits(23, 2) == 3) && (instr->Bits(20, 2) == 3) && |
| 3068 (instr->Bits(10, 2) == 2) && (instr->Bit(4) == 0)) { | 3206 (instr->Bits(10, 2) == 2) && (instr->Bit(4) == 0)) { |
| 3069 // Format(instr, "vtbl 'dd, 'dtbllist, 'dm"); | 3207 // Format(instr, "vtbl 'dd, 'dtbllist, 'dm"); |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3337 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception)); | 3475 set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception)); |
| 3338 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); | 3476 set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace)); |
| 3339 buf->Longjmp(); | 3477 buf->Longjmp(); |
| 3340 } | 3478 } |
| 3341 | 3479 |
| 3342 } // namespace dart | 3480 } // namespace dart |
| 3343 | 3481 |
| 3344 #endif // !defined(HOST_ARCH_ARM) | 3482 #endif // !defined(HOST_ARCH_ARM) |
| 3345 | 3483 |
| 3346 #endif // defined TARGET_ARCH_ARM | 3484 #endif // defined TARGET_ARCH_ARM |
| OLD | NEW |