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 |