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 |