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

Side by Side Diff: src/arm/macro-assembler-arm.cc

Issue 11412272: [v8-dev] ARM: Improve double to integer truncation on ARM. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 8 years 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
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 2471 matching lines...) Expand 10 before | Expand all | Expand 10 after
2482 orr(scratch, scratch2, Operand(scratch, LSR, 32 - shift_distance)); 2482 orr(scratch, scratch2, Operand(scratch, LSR, 32 - shift_distance));
2483 // Move down according to the exponent. 2483 // Move down according to the exponent.
2484 mov(dest, Operand(scratch, LSR, dest)); 2484 mov(dest, Operand(scratch, LSR, dest));
2485 // Fix sign if sign bit was set. 2485 // Fix sign if sign bit was set.
2486 rsb(dest, dest, Operand(0, RelocInfo::NONE), LeaveCC, ne); 2486 rsb(dest, dest, Operand(0, RelocInfo::NONE), LeaveCC, ne);
2487 bind(&done); 2487 bind(&done);
2488 } 2488 }
2489 } 2489 }
2490 2490
2491 2491
2492 void MacroAssembler::TryFastDoubleToInt32(Register result,
2493 DwVfpRegister double_input,
2494 DwVfpRegister double_scratch,
2495 Label* done) {
2496 ASSERT(!double_input.is(double_scratch));
2497
2498 vcvt_s32_f64(double_scratch.low(), double_input);
2499 vmov(result, double_scratch.low());
2500 vcvt_f64_s32(double_scratch, double_scratch.low());
2501 VFPCompareAndSetFlags(double_input, double_scratch);
2502 b(eq, done);
2503 }
2504
2505
2492 void MacroAssembler::EmitVFPTruncate(VFPRoundingMode rounding_mode, 2506 void MacroAssembler::EmitVFPTruncate(VFPRoundingMode rounding_mode,
2493 Register result, 2507 Register result,
2494 DwVfpRegister double_input, 2508 DwVfpRegister double_input,
2495 Register scratch, 2509 Register scratch,
2496 DwVfpRegister double_scratch, 2510 DwVfpRegister double_scratch,
2497 CheckForInexactConversion check_inexact) { 2511 CheckForInexactConversion check_inexact) {
2498 ASSERT(!result.is(scratch)); 2512 ASSERT(!result.is(scratch));
2499 ASSERT(!double_input.is(double_scratch)); 2513 ASSERT(!double_input.is(double_scratch));
2500 2514
2501 ASSERT(CpuFeatures::IsSupported(VFP2)); 2515 ASSERT(CpuFeatures::IsSupported(VFP2));
2502 CpuFeatures::Scope scope(VFP2); 2516 CpuFeatures::Scope scope(VFP2);
2503 Register prev_fpscr = result; 2517 Register prev_fpscr = result;
2504 Label done; 2518 Label done;
2505 2519
2506 // Test for values that can be exactly represented as a signed 32-bit integer. 2520 // Test for values that can be exactly represented as a signed 32-bit integer.
2507 vcvt_s32_f64(double_scratch.low(), double_input); 2521 TryFastDoubleToInt32(result, double_input, double_scratch, &done);
2508 vmov(result, double_scratch.low());
2509 vcvt_f64_s32(double_scratch, double_scratch.low());
2510 VFPCompareAndSetFlags(double_input, double_scratch);
2511 b(eq, &done);
2512 2522
2513 // Convert to integer, respecting rounding mode. 2523 // Convert to integer, respecting rounding mode.
2514 int32_t check_inexact_conversion = 2524 int32_t check_inexact_conversion =
2515 (check_inexact == kCheckForInexactConversion) ? kVFPInexactExceptionBit : 0; 2525 (check_inexact == kCheckForInexactConversion) ? kVFPInexactExceptionBit : 0;
2516 2526
2517 // Set custom FPCSR: 2527 // Set custom FPCSR:
2518 // - Set rounding mode. 2528 // - Set rounding mode.
2519 // - Clear vfp cumulative exception flags. 2529 // - Clear vfp cumulative exception flags.
2520 // - Make sure Flush-to-zero mode control bit is unset. 2530 // - Make sure Flush-to-zero mode control bit is unset.
2521 vmrs(prev_fpscr); 2531 vmrs(prev_fpscr);
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
2618 result = sign; 2628 result = sign;
2619 sign = no_reg; 2629 sign = no_reg;
2620 rsb(result, input_high, Operand(0), LeaveCC, ne); 2630 rsb(result, input_high, Operand(0), LeaveCC, ne);
2621 mov(result, input_high, LeaveCC, eq); 2631 mov(result, input_high, LeaveCC, eq);
2622 bind(&done); 2632 bind(&done);
2623 } 2633 }
2624 2634
2625 2635
2626 void MacroAssembler::EmitECMATruncate(Register result, 2636 void MacroAssembler::EmitECMATruncate(Register result,
2627 DwVfpRegister double_input, 2637 DwVfpRegister double_input,
2628 SwVfpRegister single_scratch, 2638 DwVfpRegister double_scratch,
2629 Register scratch, 2639 Register scratch,
2630 Register input_high, 2640 Register input_high,
2631 Register input_low) { 2641 Register input_low) {
2632 CpuFeatures::Scope scope(VFP2); 2642 CpuFeatures::Scope scope(VFP2);
2633 ASSERT(!input_high.is(result)); 2643 ASSERT(!input_high.is(result));
2634 ASSERT(!input_low.is(result)); 2644 ASSERT(!input_low.is(result));
2635 ASSERT(!input_low.is(input_high)); 2645 ASSERT(!input_low.is(input_high));
2636 ASSERT(!scratch.is(result) && 2646 ASSERT(!scratch.is(result) &&
2637 !scratch.is(input_high) && 2647 !scratch.is(input_high) &&
2638 !scratch.is(input_low)); 2648 !scratch.is(input_low));
2639 ASSERT(!single_scratch.is(double_input.low()) && 2649 ASSERT(!double_input.is(double_scratch));
2640 !single_scratch.is(double_input.high()));
2641 2650
2642 Label done; 2651 Label done;
2643 2652
2653 // Test for values that can be exactly represented as a signed 32-bit integer.
2654 TryFastDoubleToInt32(result, double_input, double_scratch, &done);
2655
2644 // Clear cumulative exception flags. 2656 // Clear cumulative exception flags.
2645 ClearFPSCRBits(kVFPExceptionMask, scratch); 2657 ClearFPSCRBits(kVFPExceptionMask, scratch);
2646 // Try a conversion to a signed integer. 2658 // Try a conversion to a signed integer.
2647 vcvt_s32_f64(single_scratch, double_input); 2659 vcvt_s32_f64(double_scratch.low(), double_input);
2648 vmov(result, single_scratch); 2660 vmov(result, double_scratch.low());
2649 // Retrieve he FPSCR. 2661 // Retrieve he FPSCR.
2650 vmrs(scratch); 2662 vmrs(scratch);
2651 // Check for overflow and NaNs. 2663 // Check for overflow and NaNs.
2652 tst(scratch, Operand(kVFPOverflowExceptionBit | 2664 tst(scratch, Operand(kVFPOverflowExceptionBit |
2653 kVFPUnderflowExceptionBit | 2665 kVFPUnderflowExceptionBit |
2654 kVFPInvalidOpExceptionBit)); 2666 kVFPInvalidOpExceptionBit));
2655 // If we had no exceptions we are done. 2667 // If we had no exceptions we are done.
2656 b(eq, &done); 2668 b(eq, &done);
2657 2669
2658 // Load the double value and perform a manual truncation. 2670 // Load the double value and perform a manual truncation.
(...skipping 1241 matching lines...) Expand 10 before | Expand all | Expand 10 after
3900 void CodePatcher::EmitCondition(Condition cond) { 3912 void CodePatcher::EmitCondition(Condition cond) {
3901 Instr instr = Assembler::instr_at(masm_.pc_); 3913 Instr instr = Assembler::instr_at(masm_.pc_);
3902 instr = (instr & ~kCondMask) | cond; 3914 instr = (instr & ~kCondMask) | cond;
3903 masm_.emit(instr); 3915 masm_.emit(instr);
3904 } 3916 }
3905 3917
3906 3918
3907 } } // namespace v8::internal 3919 } } // namespace v8::internal
3908 3920
3909 #endif // V8_TARGET_ARCH_ARM 3921 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698