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

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

Issue 222403002: ARM: Avoid VMSR instruction when converting to clamped uint8 (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: Created 6 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 // 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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698