Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(708)

Side by Side Diff: runtime/vm/simulator_arm.cc

Issue 19678020: Implements ARM SIMD comparison instructions. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/disassembler_arm.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/disassembler_arm.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698