| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 2867 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2878 } | 2878 } |
| 2879 | 2879 |
| 2880 | 2880 |
| 2881 // void Simulator::DecodeTypeVFP(Instruction* instr) | 2881 // void Simulator::DecodeTypeVFP(Instruction* instr) |
| 2882 // The Following ARMv7 VFPv instructions are currently supported. | 2882 // The Following ARMv7 VFPv instructions are currently supported. |
| 2883 // vmov :Sn = Rt | 2883 // vmov :Sn = Rt |
| 2884 // vmov :Rt = Sn | 2884 // vmov :Rt = Sn |
| 2885 // vcvt: Dd = Sm | 2885 // vcvt: Dd = Sm |
| 2886 // vcvt: Sd = Dm | 2886 // vcvt: Sd = Dm |
| 2887 // vcvt.f64.s32 Dd, Dd, #<fbits> | 2887 // vcvt.f64.s32 Dd, Dd, #<fbits> |
| 2888 // vcvt.u32.f64 Dd, Dd, #<fbits> |
| 2888 // Dd = vabs(Dm) | 2889 // Dd = vabs(Dm) |
| 2889 // Dd = vneg(Dm) | 2890 // Dd = vneg(Dm) |
| 2890 // Dd = vadd(Dn, Dm) | 2891 // Dd = vadd(Dn, Dm) |
| 2891 // Dd = vsub(Dn, Dm) | 2892 // Dd = vsub(Dn, Dm) |
| 2892 // Dd = vmul(Dn, Dm) | 2893 // Dd = vmul(Dn, Dm) |
| 2893 // Dd = vdiv(Dn, Dm) | 2894 // Dd = vdiv(Dn, Dm) |
| 2894 // vcmp(Dd, Dm) | 2895 // vcmp(Dd, Dm) |
| 2895 // vmrs | 2896 // vmrs |
| 2896 // Dd = vsqrt(Dm) | 2897 // Dd = vsqrt(Dm) |
| 2897 void Simulator::DecodeTypeVFP(Instruction* instr) { | 2898 void Simulator::DecodeTypeVFP(Instruction* instr) { |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2926 } else if ((instr->Opc2Value() == 0x1) && (instr->Opc3Value() == 0x1)) { | 2927 } else if ((instr->Opc2Value() == 0x1) && (instr->Opc3Value() == 0x1)) { |
| 2927 // vneg | 2928 // vneg |
| 2928 double dm_value = get_double_from_d_register(vm); | 2929 double dm_value = get_double_from_d_register(vm); |
| 2929 double dd_value = -dm_value; | 2930 double dd_value = -dm_value; |
| 2930 dd_value = canonicalizeNaN(dd_value); | 2931 dd_value = canonicalizeNaN(dd_value); |
| 2931 set_d_register_from_double(vd, dd_value); | 2932 set_d_register_from_double(vd, dd_value); |
| 2932 } else if ((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)) { | 2933 } else if ((instr->Opc2Value() == 0x7) && (instr->Opc3Value() == 0x3)) { |
| 2933 DecodeVCVTBetweenDoubleAndSingle(instr); | 2934 DecodeVCVTBetweenDoubleAndSingle(instr); |
| 2934 } else if ((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) { | 2935 } else if ((instr->Opc2Value() == 0x8) && (instr->Opc3Value() & 0x1)) { |
| 2935 DecodeVCVTBetweenFloatingPointAndInteger(instr); | 2936 DecodeVCVTBetweenFloatingPointAndInteger(instr); |
| 2936 } else if ((instr->Opc2Value() == 0xA) && (instr->Opc3Value() == 0x3) && | 2937 } else if ((instr->Opc2Value() & 0x2) && (instr->Opc2Value() & 0x8) && |
| 2937 (instr->Bit(8) == 1)) { | 2938 (instr->Opc3Value() == 0x3) && |
| 2938 // vcvt.f64.s32 Dd, Dd, #<fbits> | 2939 (instr->Bit(5) || instr->Bits(3, 0))) { |
| 2939 int fraction_bits = 32 - ((instr->Bit(5) << 4) | instr->Bits(3, 0)); | 2940 DecodeVCVTBetweenFloatingPointAndFixedPoint(instr); |
| 2940 int fixed_value = get_sinteger_from_s_register(vd * 2); | |
| 2941 double divide = 1 << fraction_bits; | |
| 2942 set_d_register_from_double(vd, fixed_value / divide); | |
| 2943 } else if (((instr->Opc2Value() >> 1) == 0x6) && | 2941 } else if (((instr->Opc2Value() >> 1) == 0x6) && |
| 2944 (instr->Opc3Value() & 0x1)) { | 2942 (instr->Opc3Value() & 0x1)) { |
| 2945 DecodeVCVTBetweenFloatingPointAndInteger(instr); | 2943 DecodeVCVTBetweenFloatingPointAndInteger(instr); |
| 2946 } else if (((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) && | 2944 } else if (((instr->Opc2Value() == 0x4) || (instr->Opc2Value() == 0x5)) && |
| 2947 (instr->Opc3Value() & 0x1)) { | 2945 (instr->Opc3Value() & 0x1)) { |
| 2948 DecodeVCMP(instr); | 2946 DecodeVCMP(instr); |
| 2949 } else if (((instr->Opc2Value() == 0x1)) && (instr->Opc3Value() == 0x3)) { | 2947 } else if (((instr->Opc2Value() == 0x1)) && (instr->Opc3Value() == 0x3)) { |
| 2950 // vsqrt | 2948 // vsqrt |
| 2951 double dm_value = get_double_from_d_register(vm); | 2949 double dm_value = get_double_from_d_register(vm); |
| 2952 double dd_value = std::sqrt(dm_value); | 2950 double dd_value = std::sqrt(dm_value); |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3341 set_s_register_from_float( | 3339 set_s_register_from_float( |
| 3342 dst, static_cast<float>(static_cast<uint32_t>(val))); | 3340 dst, static_cast<float>(static_cast<uint32_t>(val))); |
| 3343 } else { | 3341 } else { |
| 3344 set_s_register_from_float(dst, static_cast<float>(val)); | 3342 set_s_register_from_float(dst, static_cast<float>(val)); |
| 3345 } | 3343 } |
| 3346 } | 3344 } |
| 3347 } | 3345 } |
| 3348 } | 3346 } |
| 3349 | 3347 |
| 3350 | 3348 |
| 3349 void Simulator::DecodeVCVTBetweenFloatingPointAndFixedPoint( |
| 3350 Instruction* instr) { |
| 3351 ASSERT((instr->Bit(4) == 0) && (instr->Opc1Value() == 0x7)); |
| 3352 ASSERT((instr->Opc2Value() & 0x2) && (instr->Opc2Value() & 0x8)); |
| 3353 ASSERT(instr->Opc3Value() == 0x3); |
| 3354 ASSERT(instr->Bit(5) || instr->Bits(3, 0)); |
| 3355 |
| 3356 bool to_integer = (instr->Bit(18) == 1); |
| 3357 bool unsigned_integer = (instr->Bit(16) == 1); |
| 3358 |
| 3359 VFPRegPrecision f_precision = (instr->SzValue() == 1) ? kDoublePrecision |
| 3360 : kSinglePrecision; |
| 3361 int fd = instr->VFPDRegValue(f_precision); |
| 3362 int sd = instr->VFPDRegValue(kSinglePrecision); |
| 3363 |
| 3364 int sx = instr->Bit(7); |
| 3365 int fraction_bits = (sx ? 32 : 16) - |
| 3366 ((instr->Bits(3, 0) << 1) | instr->Bit(5)); |
| 3367 double mult = 1 << fraction_bits; |
| 3368 |
| 3369 if (to_integer) { |
| 3370 bool double_precision = (f_precision == kDoublePrecision); |
| 3371 double val = double_precision ? get_double_from_d_register(fd) |
| 3372 : get_float_from_s_register(fd); |
| 3373 |
| 3374 // First check if the value overflows the integer range without |
| 3375 // multiplication. |
| 3376 inv_op_vfp_flag_ = get_inv_op_vfp_flag(RZ, val, unsigned_integer); |
| 3377 |
| 3378 if (!inv_op_vfp_flag_) { |
| 3379 // The original value did not overflow the integer range, so we can |
| 3380 // safely multiply it without fear of double overflow. |
| 3381 val *= mult; |
| 3382 // ARM specifies rounding towards zero for float to fixed conversion. |
| 3383 inv_op_vfp_flag_ = get_inv_op_vfp_flag(RZ, val, unsigned_integer); |
| 3384 } |
| 3385 |
| 3386 int temp = unsigned_integer ? static_cast<uint32_t>(val) |
| 3387 : static_cast<int32_t>(val); |
| 3388 if (inv_op_vfp_flag_) { |
| 3389 temp = VFPConversionSaturate(val, unsigned_integer); |
| 3390 } |
| 3391 |
| 3392 // FIXME: inexact_vfp_flag_ does not model ARM behavior exactly if |
| 3393 // inv_op_vfp_flag_ is set. |
| 3394 double abs_diff = |
| 3395 unsigned_integer ? std::fabs(val - static_cast<uint32_t>(temp)) |
| 3396 : std::fabs(val - temp); |
| 3397 inexact_vfp_flag_ = (abs_diff != 0); |
| 3398 |
| 3399 set_s_register_from_sinteger(sd, temp); |
| 3400 |
| 3401 } else { |
| 3402 int val = get_sinteger_from_s_register(sd); |
| 3403 if (f_precision == kDoublePrecision) { |
| 3404 if (unsigned_integer) { |
| 3405 set_d_register_from_double(fd, static_cast<uint32_t>(val) / mult); |
| 3406 } else { |
| 3407 set_d_register_from_double(fd, val / mult); |
| 3408 } |
| 3409 } else { |
| 3410 if (unsigned_integer) { |
| 3411 set_s_register_from_float( |
| 3412 fd, static_cast<float>(static_cast<uint32_t>(val) / mult)); |
| 3413 } else { |
| 3414 set_s_register_from_float(fd, static_cast<float>(val / mult)); |
| 3415 } |
| 3416 } |
| 3417 } |
| 3418 } |
| 3419 |
| 3420 |
| 3351 // void Simulator::DecodeType6CoprocessorIns(Instruction* instr) | 3421 // void Simulator::DecodeType6CoprocessorIns(Instruction* instr) |
| 3352 // Decode Type 6 coprocessor instructions. | 3422 // Decode Type 6 coprocessor instructions. |
| 3353 // Dm = vmov(Rt, Rt2) | 3423 // Dm = vmov(Rt, Rt2) |
| 3354 // <Rt, Rt2> = vmov(Dm) | 3424 // <Rt, Rt2> = vmov(Dm) |
| 3355 // Ddst = MEM(Rbase + 4*offset). | 3425 // Ddst = MEM(Rbase + 4*offset). |
| 3356 // MEM(Rbase + 4*offset) = Dsrc. | 3426 // MEM(Rbase + 4*offset) = Dsrc. |
| 3357 void Simulator::DecodeType6CoprocessorIns(Instruction* instr) { | 3427 void Simulator::DecodeType6CoprocessorIns(Instruction* instr) { |
| 3358 ASSERT((instr->TypeValue() == 6)); | 3428 ASSERT((instr->TypeValue() == 6)); |
| 3359 | 3429 |
| 3360 if (instr->CoprocessorValue() == 0xA) { | 3430 if (instr->CoprocessorValue() == 0xA) { |
| (...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3852 uintptr_t address = *stack_slot; | 3922 uintptr_t address = *stack_slot; |
| 3853 set_register(sp, current_sp + sizeof(uintptr_t)); | 3923 set_register(sp, current_sp + sizeof(uintptr_t)); |
| 3854 return address; | 3924 return address; |
| 3855 } | 3925 } |
| 3856 | 3926 |
| 3857 } } // namespace v8::internal | 3927 } } // namespace v8::internal |
| 3858 | 3928 |
| 3859 #endif // USE_SIMULATOR | 3929 #endif // USE_SIMULATOR |
| 3860 | 3930 |
| 3861 #endif // V8_TARGET_ARCH_ARM | 3931 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |