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

Side by Side Diff: src/arm/simulator-arm.cc

Issue 1044793002: [turbofan] Add backend support for float32 operations. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Add MachineOperator unit tests. Created 5 years, 8 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdarg.h> 5 #include <stdarg.h>
6 #include <stdlib.h> 6 #include <stdlib.h>
7 #include <cmath> 7 #include <cmath>
8 8
9 #include "src/v8.h" 9 #include "src/v8.h"
10 10
(...skipping 1291 matching lines...) Expand 10 before | Expand all | Expand 10 after
1302 // operands have different signs 1302 // operands have different signs
1303 overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0)) 1303 overflow = ((left < 0 && right >= 0) || (left >= 0 && right < 0))
1304 // and first operand and result have different signs 1304 // and first operand and result have different signs
1305 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0)); 1305 && ((left < 0 && alu_out >= 0) || (left >= 0 && alu_out < 0));
1306 } 1306 }
1307 return overflow; 1307 return overflow;
1308 } 1308 }
1309 1309
1310 1310
1311 // Support for VFP comparisons. 1311 // Support for VFP comparisons.
1312 void Simulator::Compute_FPSCR_Flags(float val1, float val2) {
1313 if (std::isnan(val1) || std::isnan(val2)) {
1314 n_flag_FPSCR_ = false;
1315 z_flag_FPSCR_ = false;
1316 c_flag_FPSCR_ = true;
1317 v_flag_FPSCR_ = true;
1318 // All non-NaN cases.
1319 } else if (val1 == val2) {
1320 n_flag_FPSCR_ = false;
1321 z_flag_FPSCR_ = true;
1322 c_flag_FPSCR_ = true;
1323 v_flag_FPSCR_ = false;
1324 } else if (val1 < val2) {
1325 n_flag_FPSCR_ = true;
1326 z_flag_FPSCR_ = false;
1327 c_flag_FPSCR_ = false;
1328 v_flag_FPSCR_ = false;
1329 } else {
1330 // Case when (val1 > val2).
1331 n_flag_FPSCR_ = false;
1332 z_flag_FPSCR_ = false;
1333 c_flag_FPSCR_ = true;
1334 v_flag_FPSCR_ = false;
1335 }
1336 }
1337
1338
1312 void Simulator::Compute_FPSCR_Flags(double val1, double val2) { 1339 void Simulator::Compute_FPSCR_Flags(double val1, double val2) {
1313 if (std::isnan(val1) || std::isnan(val2)) { 1340 if (std::isnan(val1) || std::isnan(val2)) {
1314 n_flag_FPSCR_ = false; 1341 n_flag_FPSCR_ = false;
1315 z_flag_FPSCR_ = false; 1342 z_flag_FPSCR_ = false;
1316 c_flag_FPSCR_ = true; 1343 c_flag_FPSCR_ = true;
1317 v_flag_FPSCR_ = true; 1344 v_flag_FPSCR_ = true;
1318 // All non-NaN cases. 1345 // All non-NaN cases.
1319 } else if (val1 == val2) { 1346 } else if (val1 == val2) {
1320 n_flag_FPSCR_ = false; 1347 n_flag_FPSCR_ = false;
1321 z_flag_FPSCR_ = true; 1348 z_flag_FPSCR_ = true;
(...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after
1907 } else { 1934 } else {
1908 // This is not a valid svc code. 1935 // This is not a valid svc code.
1909 UNREACHABLE(); 1936 UNREACHABLE();
1910 break; 1937 break;
1911 } 1938 }
1912 } 1939 }
1913 } 1940 }
1914 } 1941 }
1915 1942
1916 1943
1944 float Simulator::canonicalizeNaN(float value) {
1945 // Default NaN value, see "NaN handling" in "IEEE 754 standard implementation
1946 // choices" of the ARM Reference Manual.
1947 const uint32_t kDefaultNaN = 0x7FC00000u;
1948 if (FPSCR_default_NaN_mode_ && std::isnan(value)) {
1949 value = bit_cast<float>(kDefaultNaN);
1950 }
1951 return value;
1952 }
1953
1954
1917 double Simulator::canonicalizeNaN(double value) { 1955 double Simulator::canonicalizeNaN(double value) {
1918 // Default NaN value, see "NaN handling" in "IEEE 754 standard implementation 1956 // Default NaN value, see "NaN handling" in "IEEE 754 standard implementation
1919 // choices" of the ARM Reference Manual. 1957 // choices" of the ARM Reference Manual.
1920 const uint64_t kDefaultNaN = V8_UINT64_C(0x7FF8000000000000); 1958 const uint64_t kDefaultNaN = V8_UINT64_C(0x7FF8000000000000);
1921 if (FPSCR_default_NaN_mode_ && std::isnan(value)) { 1959 if (FPSCR_default_NaN_mode_ && std::isnan(value)) {
1922 value = bit_cast<double>(kDefaultNaN); 1960 value = bit_cast<double>(kDefaultNaN);
1923 } 1961 }
1924 return value; 1962 return value;
1925 } 1963 }
1926 1964
(...skipping 1075 matching lines...) Expand 10 before | Expand all | Expand 10 after
3002 3040
3003 3041
3004 // void Simulator::DecodeTypeVFP(Instruction* instr) 3042 // void Simulator::DecodeTypeVFP(Instruction* instr)
3005 // The Following ARMv7 VFPv instructions are currently supported. 3043 // The Following ARMv7 VFPv instructions are currently supported.
3006 // vmov :Sn = Rt 3044 // vmov :Sn = Rt
3007 // vmov :Rt = Sn 3045 // vmov :Rt = Sn
3008 // vcvt: Dd = Sm 3046 // vcvt: Dd = Sm
3009 // vcvt: Sd = Dm 3047 // vcvt: Sd = Dm
3010 // vcvt.f64.s32 Dd, Dd, #<fbits> 3048 // vcvt.f64.s32 Dd, Dd, #<fbits>
3011 // Dd = vabs(Dm) 3049 // Dd = vabs(Dm)
3050 // Sd = vabs(Sm)
3012 // Dd = vneg(Dm) 3051 // Dd = vneg(Dm)
3052 // Sd = vneg(Sm)
3013 // Dd = vadd(Dn, Dm) 3053 // Dd = vadd(Dn, Dm)
3054 // Sd = vadd(Sn, Sm)
3014 // Dd = vsub(Dn, Dm) 3055 // Dd = vsub(Dn, Dm)
3056 // Sd = vsub(Sn, Sm)
3015 // Dd = vmul(Dn, Dm) 3057 // Dd = vmul(Dn, Dm)
3058 // Sd = vmul(Sn, Sm)
3016 // Dd = vdiv(Dn, Dm) 3059 // Dd = vdiv(Dn, Dm)
3060 // Sd = vdiv(Sn, Sm)
3017 // vcmp(Dd, Dm) 3061 // vcmp(Dd, Dm)
3062 // vcmp(Sd, Sm)
3063 // Dd = vsqrt(Dm)
3064 // Sd = vsqrt(Sm)
3018 // vmrs 3065 // vmrs
3019 // Dd = vsqrt(Dm)
3020 void Simulator::DecodeTypeVFP(Instruction* instr) { 3066 void Simulator::DecodeTypeVFP(Instruction* instr) {
3021 DCHECK((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) ); 3067 DCHECK((instr->TypeValue() == 7) && (instr->Bit(24) == 0x0) );
3022 DCHECK(instr->Bits(11, 9) == 0x5); 3068 DCHECK(instr->Bits(11, 9) == 0x5);
3023 3069
3070 // Obtain single precision register codes.
3071 int m = instr->VFPMRegValue(kSinglePrecision);
3072 int d = instr->VFPDRegValue(kSinglePrecision);
3073 int n = instr->VFPNRegValue(kSinglePrecision);
3024 // Obtain double precision register codes. 3074 // Obtain double precision register codes.
3025 int vm = instr->VFPMRegValue(kDoublePrecision); 3075 int vm = instr->VFPMRegValue(kDoublePrecision);
3026 int vd = instr->VFPDRegValue(kDoublePrecision); 3076 int vd = instr->VFPDRegValue(kDoublePrecision);
3027 int vn = instr->VFPNRegValue(kDoublePrecision); 3077 int vn = instr->VFPNRegValue(kDoublePrecision);
3028 3078
3029 if (instr->Bit(4) == 0) { 3079 if (instr->Bit(4) == 0) {
3030 if (instr->Opc1Value() == 0x7) { 3080 if (instr->Opc1Value() == 0x7) {
3031 // Other data processing instructions 3081 // Other data processing instructions
3032 if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) { 3082 if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x1)) {
3033 // vmov register to register. 3083 // vmov register to register.
3034 if (instr->SzValue() == 0x1) { 3084 if (instr->SzValue() == 0x1) {
3035 int m = instr->VFPMRegValue(kDoublePrecision);
3036 int d = instr->VFPDRegValue(kDoublePrecision);
3037 uint32_t data[2]; 3085 uint32_t data[2];
3038 get_d_register(m, data); 3086 get_d_register(vm, data);
3039 set_d_register(d, data); 3087 set_d_register(vd, data);
3040 } else { 3088 } else {
3041 int m = instr->VFPMRegValue(kSinglePrecision); 3089 set_s_register(d, get_s_register(m));
3042 int d = instr->VFPDRegValue(kSinglePrecision);
3043 set_s_register_from_float(d, get_float_from_s_register(m));
3044 } 3090 }
3045 } else if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x3)) { 3091 } else if ((instr->Opc2Value() == 0x0) && (instr->Opc3Value() == 0x3)) {
3046 // vabs 3092 // vabs
3047 double dm_value = get_double_from_d_register(vm); 3093 if (instr->SzValue() == 0x1) {
3048 double dd_value = std::fabs(dm_value); 3094 double dm_value = get_double_from_d_register(vm);
3049 dd_value = canonicalizeNaN(dd_value); 3095 double dd_value = std::fabs(dm_value);
3050 set_d_register_from_double(vd, dd_value); 3096 dd_value = canonicalizeNaN(dd_value);
3097 set_d_register_from_double(vd, dd_value);
3098 } else {
3099 float sm_value = get_float_from_s_register(m);
3100 float sd_value = std::fabs(sm_value);
3101 sd_value = canonicalizeNaN(sd_value);
3102 set_s_register_from_float(d, sd_value);
3103 }
3051 } else if ((instr->Opc2Value() == 0x1) && (instr->Opc3Value() == 0x1)) { 3104 } else if ((instr->Opc2Value() == 0x1) && (instr->Opc3Value() == 0x1)) {
3052 // vneg 3105 // vneg
3053 double dm_value = get_double_from_d_register(vm); 3106 if (instr->SzValue() == 0x1) {
3054 double dd_value = -dm_value; 3107 double dm_value = get_double_from_d_register(vm);
3055 dd_value = canonicalizeNaN(dd_value); 3108 double dd_value = -dm_value;
3056 set_d_register_from_double(vd, dd_value); 3109 dd_value = canonicalizeNaN(dd_value);
3110 set_d_register_from_double(vd, dd_value);
3111 } else {
3112 float sm_value = get_float_from_s_register(m);
3113 float sd_value = -sm_value;
3114 sd_value = canonicalizeNaN(sd_value);
3115 set_s_register_from_float(d, sd_value);
3116 }
3057 } else if ((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)) { 3117 } else if ((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)) {
3058 DecodeVCVTBetweenDoubleAndSingle(instr); 3118 DecodeVCVTBetweenDoubleAndSingle(instr);
3059 } else if ((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) { 3119 } else if ((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) {
3060 DecodeVCVTBetweenFloatingPointAndInteger(instr); 3120 DecodeVCVTBetweenFloatingPointAndInteger(instr);
3061 } else if ((instr->Opc2Value() == 0xA) && (instr->Opc3Value() == 0x3) && 3121 } else if ((instr->Opc2Value() == 0xA) && (instr->Opc3Value() == 0x3) &&
3062 (instr->Bit(8) == 1)) { 3122 (instr->Bit(8) == 1)) {
3063 // vcvt.f64.s32 Dd, Dd, #<fbits> 3123 // vcvt.f64.s32 Dd, Dd, #<fbits>
3064 int fraction_bits = 32 - ((instr->Bits(3, 0) << 1) | instr->Bit(5)); 3124 int fraction_bits = 32 - ((instr->Bits(3, 0) << 1) | instr->Bit(5));
3065 int fixed_value = get_sinteger_from_s_register(vd * 2); 3125 int fixed_value = get_sinteger_from_s_register(vd * 2);
3066 double divide = 1 << fraction_bits; 3126 double divide = 1 << fraction_bits;
3067 set_d_register_from_double(vd, fixed_value / divide); 3127 set_d_register_from_double(vd, fixed_value / divide);
3068 } else if (((instr->Opc2Value() >> 1) == 0x6) && 3128 } else if (((instr->Opc2Value() >> 1) == 0x6) &&
3069 (instr->Opc3Value() & 0x1)) { 3129 (instr->Opc3Value() & 0x1)) {
3070 DecodeVCVTBetweenFloatingPointAndInteger(instr); 3130 DecodeVCVTBetweenFloatingPointAndInteger(instr);
3071 } else if (((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) && 3131 } else if (((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) &&
3072 (instr->Opc3Value() & 0x1)) { 3132 (instr->Opc3Value() & 0x1)) {
3073 DecodeVCMP(instr); 3133 DecodeVCMP(instr);
3074 } else if (((instr->Opc2Value() == 0x1)) && (instr->Opc3Value() == 0x3)) { 3134 } else if (((instr->Opc2Value() == 0x1)) && (instr->Opc3Value() == 0x3)) {
3075 // vsqrt 3135 // vsqrt
3076 double dm_value = get_double_from_d_register(vm); 3136 if (instr->SzValue() == 0x1) {
3077 double dd_value = fast_sqrt(dm_value); 3137 double dm_value = get_double_from_d_register(vm);
3078 dd_value = canonicalizeNaN(dd_value); 3138 double dd_value = fast_sqrt(dm_value);
3079 set_d_register_from_double(vd, dd_value); 3139 dd_value = canonicalizeNaN(dd_value);
3140 set_d_register_from_double(vd, dd_value);
3141 } else {
3142 float sm_value = get_float_from_s_register(m);
3143 float sd_value = fast_sqrt(sm_value);
3144 sd_value = canonicalizeNaN(sd_value);
3145 set_s_register_from_float(d, sd_value);
3146 }
3080 } else if (instr->Opc3Value() == 0x0) { 3147 } else if (instr->Opc3Value() == 0x0) {
3081 // vmov immediate. 3148 // vmov immediate.
3082 if (instr->SzValue() == 0x1) { 3149 if (instr->SzValue() == 0x1) {
3083 set_d_register_from_double(vd, instr->DoubleImmedVmov()); 3150 set_d_register_from_double(vd, instr->DoubleImmedVmov());
3084 } else { 3151 } else {
3085 UNREACHABLE(); // Not used by v8. 3152 UNREACHABLE(); // Not used by v8.
3086 } 3153 }
3087 } else if (((instr->Opc2Value() == 0x6)) && (instr->Opc3Value() == 0x3)) { 3154 } else if (((instr->Opc2Value() == 0x6)) && (instr->Opc3Value() == 0x3)) {
3088 // vrintz - truncate 3155 // vrintz - truncate
3089 double dm_value = get_double_from_d_register(vm); 3156 double dm_value = get_double_from_d_register(vm);
3090 double dd_value = trunc(dm_value); 3157 double dd_value = trunc(dm_value);
3091 dd_value = canonicalizeNaN(dd_value); 3158 dd_value = canonicalizeNaN(dd_value);
3092 set_d_register_from_double(vd, dd_value); 3159 set_d_register_from_double(vd, dd_value);
3093 } else { 3160 } else {
3094 UNREACHABLE(); // Not used by V8. 3161 UNREACHABLE(); // Not used by V8.
3095 } 3162 }
3096 } else if (instr->Opc1Value() == 0x3) { 3163 } else if (instr->Opc1Value() == 0x3) {
3097 if (instr->SzValue() != 0x1) {
3098 UNREACHABLE(); // Not used by V8.
3099 }
3100
3101 if (instr->Opc3Value() & 0x1) { 3164 if (instr->Opc3Value() & 0x1) {
3102 // vsub 3165 // vsub
3166 if (instr->SzValue() == 0x1) {
3167 double dn_value = get_double_from_d_register(vn);
3168 double dm_value = get_double_from_d_register(vm);
3169 double dd_value = dn_value - dm_value;
3170 dd_value = canonicalizeNaN(dd_value);
3171 set_d_register_from_double(vd, dd_value);
3172 } else {
3173 float sn_value = get_float_from_s_register(n);
3174 float sm_value = get_float_from_s_register(m);
3175 float sd_value = sn_value - sm_value;
3176 sd_value = canonicalizeNaN(sd_value);
3177 set_s_register_from_float(d, sd_value);
3178 }
3179 } else {
3180 // vadd
3181 if (instr->SzValue() == 0x1) {
3182 double dn_value = get_double_from_d_register(vn);
3183 double dm_value = get_double_from_d_register(vm);
3184 double dd_value = dn_value + dm_value;
3185 dd_value = canonicalizeNaN(dd_value);
3186 set_d_register_from_double(vd, dd_value);
3187 } else {
3188 float sn_value = get_float_from_s_register(n);
3189 float sm_value = get_float_from_s_register(m);
3190 float sd_value = sn_value + sm_value;
3191 sd_value = canonicalizeNaN(sd_value);
3192 set_s_register_from_float(d, sd_value);
3193 }
3194 }
3195 } else if ((instr->Opc1Value() == 0x2) && !(instr->Opc3Value() & 0x1)) {
3196 // vmul
3197 if (instr->SzValue() == 0x1) {
3103 double dn_value = get_double_from_d_register(vn); 3198 double dn_value = get_double_from_d_register(vn);
3104 double dm_value = get_double_from_d_register(vm); 3199 double dm_value = get_double_from_d_register(vm);
3105 double dd_value = dn_value - dm_value; 3200 double dd_value = dn_value * dm_value;
3106 dd_value = canonicalizeNaN(dd_value); 3201 dd_value = canonicalizeNaN(dd_value);
3107 set_d_register_from_double(vd, dd_value); 3202 set_d_register_from_double(vd, dd_value);
3108 } else { 3203 } else {
3109 // vadd 3204 float sn_value = get_float_from_s_register(n);
3110 double dn_value = get_double_from_d_register(vn); 3205 float sm_value = get_float_from_s_register(m);
3111 double dm_value = get_double_from_d_register(vm); 3206 float sd_value = sn_value * sm_value;
3112 double dd_value = dn_value + dm_value; 3207 sd_value = canonicalizeNaN(sd_value);
3113 dd_value = canonicalizeNaN(dd_value); 3208 set_s_register_from_float(d, sd_value);
3114 set_d_register_from_double(vd, dd_value);
3115 } 3209 }
3116 } else if ((instr->Opc1Value() == 0x2) && !(instr->Opc3Value() & 0x1)) {
3117 // vmul
3118 if (instr->SzValue() != 0x1) {
3119 UNREACHABLE(); // Not used by V8.
3120 }
3121
3122 double dn_value = get_double_from_d_register(vn);
3123 double dm_value = get_double_from_d_register(vm);
3124 double dd_value = dn_value * dm_value;
3125 dd_value = canonicalizeNaN(dd_value);
3126 set_d_register_from_double(vd, dd_value);
3127 } else if ((instr->Opc1Value() == 0x0)) { 3210 } else if ((instr->Opc1Value() == 0x0)) {
3128 // vmla, vmls 3211 // vmla, vmls
3129 const bool is_vmls = (instr->Opc3Value() & 0x1); 3212 const bool is_vmls = (instr->Opc3Value() & 0x1);
3213 if (instr->SzValue() == 0x1) {
3214 const double dd_val = get_double_from_d_register(vd);
3215 const double dn_val = get_double_from_d_register(vn);
3216 const double dm_val = get_double_from_d_register(vm);
3130 3217
3131 if (instr->SzValue() != 0x1) { 3218 // Note: we do the mul and add/sub in separate steps to avoid getting a
3132 UNREACHABLE(); // Not used by V8. 3219 // result with too high precision.
3133 } 3220 set_d_register_from_double(vd, dn_val * dm_val);
3221 if (is_vmls) {
3222 set_d_register_from_double(
3223 vd, canonicalizeNaN(dd_val - get_double_from_d_register(vd)));
3224 } else {
3225 set_d_register_from_double(
3226 vd, canonicalizeNaN(dd_val + get_double_from_d_register(vd)));
3227 }
3228 } else {
3229 const float sd_val = get_float_from_s_register(d);
3230 const float sn_val = get_float_from_s_register(n);
3231 const float sm_val = get_float_from_s_register(m);
3134 3232
3135 const double dd_val = get_double_from_d_register(vd); 3233 // Note: we do the mul and add/sub in separate steps to avoid getting a
3136 const double dn_val = get_double_from_d_register(vn); 3234 // result with too high precision.
3137 const double dm_val = get_double_from_d_register(vm); 3235 set_s_register_from_float(d, sn_val * sm_val);
3138 3236 if (is_vmls) {
3139 // Note: we do the mul and add/sub in separate steps to avoid getting a 3237 set_s_register_from_float(
3140 // result with too high precision. 3238 d, canonicalizeNaN(sd_val - get_float_from_s_register(d)));
3141 set_d_register_from_double(vd, dn_val * dm_val); 3239 } else {
3142 if (is_vmls) { 3240 set_s_register_from_float(
3143 set_d_register_from_double( 3241 d, canonicalizeNaN(sd_val + get_float_from_s_register(d)));
3144 vd, 3242 }
3145 canonicalizeNaN(dd_val - get_double_from_d_register(vd)));
3146 } else {
3147 set_d_register_from_double(
3148 vd,
3149 canonicalizeNaN(dd_val + get_double_from_d_register(vd)));
3150 } 3243 }
3151 } else if ((instr->Opc1Value() == 0x4) && !(instr->Opc3Value() & 0x1)) { 3244 } else if ((instr->Opc1Value() == 0x4) && !(instr->Opc3Value() & 0x1)) {
3152 // vdiv 3245 // vdiv
3153 if (instr->SzValue() != 0x1) { 3246 if (instr->SzValue() == 0x1) {
3154 UNREACHABLE(); // Not used by V8. 3247 double dn_value = get_double_from_d_register(vn);
3248 double dm_value = get_double_from_d_register(vm);
3249 double dd_value = dn_value / dm_value;
3250 div_zero_vfp_flag_ = (dm_value == 0);
3251 dd_value = canonicalizeNaN(dd_value);
3252 set_d_register_from_double(vd, dd_value);
3253 } else {
3254 float sn_value = get_float_from_s_register(n);
3255 float sm_value = get_float_from_s_register(m);
3256 float sd_value = sn_value / sm_value;
3257 div_zero_vfp_flag_ = (sm_value == 0);
3258 sd_value = canonicalizeNaN(sd_value);
3259 set_s_register_from_float(d, sd_value);
3155 } 3260 }
3156
3157 double dn_value = get_double_from_d_register(vn);
3158 double dm_value = get_double_from_d_register(vm);
3159 double dd_value = dn_value / dm_value;
3160 div_zero_vfp_flag_ = (dm_value == 0);
3161 dd_value = canonicalizeNaN(dd_value);
3162 set_d_register_from_double(vd, dd_value);
3163 } else { 3261 } else {
3164 UNIMPLEMENTED(); // Not used by V8. 3262 UNIMPLEMENTED(); // Not used by V8.
3165 } 3263 }
3166 } else { 3264 } else {
3167 if ((instr->VCValue() == 0x0) && 3265 if ((instr->VCValue() == 0x0) &&
3168 (instr->VAValue() == 0x0)) { 3266 (instr->VAValue() == 0x0)) {
3169 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr); 3267 DecodeVMOVBetweenCoreAndSinglePrecisionRegisters(instr);
3170 } else if ((instr->VLValue() == 0x0) && 3268 } else if ((instr->VLValue() == 0x0) &&
3171 (instr->VCValue() == 0x1) && 3269 (instr->VCValue() == 0x1) &&
3172 (instr->Bit(23) == 0x0)) { 3270 (instr->Bit(23) == 0x0)) {
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
3257 } 3355 }
3258 3356
3259 3357
3260 void Simulator::DecodeVCMP(Instruction* instr) { 3358 void Simulator::DecodeVCMP(Instruction* instr) {
3261 DCHECK((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7)); 3359 DCHECK((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
3262 DCHECK(((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) && 3360 DCHECK(((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) &&
3263 (instr->Opc3Value() & 0x1)); 3361 (instr->Opc3Value() & 0x1));
3264 // Comparison. 3362 // Comparison.
3265 3363
3266 VFPRegPrecision precision = kSinglePrecision; 3364 VFPRegPrecision precision = kSinglePrecision;
3267 if (instr->SzValue() == 1) { 3365 if (instr->SzValue() == 0x1) {
3268 precision = kDoublePrecision; 3366 precision = kDoublePrecision;
3269 } 3367 }
3270 3368
3271 int d = instr->VFPDRegValue(precision); 3369 int d = instr->VFPDRegValue(precision);
3272 int m = 0; 3370 int m = 0;
3273 if (instr->Opc2Value() == 0x4) { 3371 if (instr->Opc2Value() == 0x4) {
3274 m = instr->VFPMRegValue(precision); 3372 m = instr->VFPMRegValue(precision);
3275 } 3373 }
3276 3374
3277 if (precision == kDoublePrecision) { 3375 if (precision == kDoublePrecision) {
3278 double dd_value = get_double_from_d_register(d); 3376 double dd_value = get_double_from_d_register(d);
3279 double dm_value = 0.0; 3377 double dm_value = 0.0;
3280 if (instr->Opc2Value() == 0x4) { 3378 if (instr->Opc2Value() == 0x4) {
3281 dm_value = get_double_from_d_register(m); 3379 dm_value = get_double_from_d_register(m);
3282 } 3380 }
3283 3381
3284 // Raise exceptions for quiet NaNs if necessary. 3382 // Raise exceptions for quiet NaNs if necessary.
3285 if (instr->Bit(7) == 1) { 3383 if (instr->Bit(7) == 1) {
3286 if (std::isnan(dd_value)) { 3384 if (std::isnan(dd_value)) {
3287 inv_op_vfp_flag_ = true; 3385 inv_op_vfp_flag_ = true;
3288 } 3386 }
3289 } 3387 }
3290 3388
3291 Compute_FPSCR_Flags(dd_value, dm_value); 3389 Compute_FPSCR_Flags(dd_value, dm_value);
3292 } else { 3390 } else {
3293 UNIMPLEMENTED(); // Not used by V8. 3391 float sd_value = get_float_from_s_register(d);
3392 float sm_value = 0.0;
3393 if (instr->Opc2Value() == 0x4) {
3394 sm_value = get_float_from_s_register(m);
3395 }
3396
3397 // Raise exceptions for quiet NaNs if necessary.
3398 if (instr->Bit(7) == 1) {
3399 if (std::isnan(sd_value)) {
3400 inv_op_vfp_flag_ = true;
3401 }
3402 }
3403
3404 Compute_FPSCR_Flags(sd_value, sm_value);
3294 } 3405 }
3295 } 3406 }
3296 3407
3297 3408
3298 void Simulator::DecodeVCVTBetweenDoubleAndSingle(Instruction* instr) { 3409 void Simulator::DecodeVCVTBetweenDoubleAndSingle(Instruction* instr) {
3299 DCHECK((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7)); 3410 DCHECK((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7));
3300 DCHECK((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)); 3411 DCHECK((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3));
3301 3412
3302 VFPRegPrecision dst_precision = kDoublePrecision; 3413 VFPRegPrecision dst_precision = kDoublePrecision;
3303 VFPRegPrecision src_precision = kSinglePrecision; 3414 VFPRegPrecision src_precision = kSinglePrecision;
(...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after
4019 uintptr_t address = *stack_slot; 4130 uintptr_t address = *stack_slot;
4020 set_register(sp, current_sp + sizeof(uintptr_t)); 4131 set_register(sp, current_sp + sizeof(uintptr_t));
4021 return address; 4132 return address;
4022 } 4133 }
4023 4134
4024 } } // namespace v8::internal 4135 } } // namespace v8::internal
4025 4136
4026 #endif // USE_SIMULATOR 4137 #endif // USE_SIMULATOR
4027 4138
4028 #endif // V8_TARGET_ARCH_ARM 4139 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698