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

Unified Diff: src/arm/lithium-codegen-arm.cc

Issue 6625084: ARM: Improved double to integer truncation.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/arm/lithium-arm.cc ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/lithium-codegen-arm.cc
===================================================================
--- src/arm/lithium-codegen-arm.cc (revision 7157)
+++ src/arm/lithium-codegen-arm.cc (working copy)
@@ -3310,19 +3310,30 @@
void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
- Label done;
Register input_reg = ToRegister(instr->InputAt(0));
- Register scratch = scratch0();
- DoubleRegister dbl_scratch = d0;
- SwVfpRegister flt_scratch = s0;
- DoubleRegister dbl_tmp = ToDoubleRegister(instr->TempAt(0));
+ Register scratch1 = scratch0();
+ Register scratch2 = ToRegister(instr->TempAt(0));
+ DwVfpRegister double_scratch = double_scratch0();
+ SwVfpRegister single_scratch = double_scratch.low();
+ ASSERT(!scratch1.is(input_reg) && !scratch1.is(scratch2));
+ ASSERT(!scratch2.is(input_reg) && !scratch2.is(scratch1));
+
+ Label done;
+
// Heap number map check.
- __ ldr(scratch, FieldMemOperand(input_reg, HeapObject::kMapOffset));
+ __ ldr(scratch1, FieldMemOperand(input_reg, HeapObject::kMapOffset));
__ LoadRoot(ip, Heap::kHeapNumberMapRootIndex);
- __ cmp(scratch, Operand(ip));
+ __ cmp(scratch1, Operand(ip));
if (instr->truncating()) {
+ Register scratch3 = ToRegister(instr->TempAt(1));
+ DwVfpRegister double_scratch2 = ToDoubleRegister(instr->TempAt(2));
+ ASSERT(!scratch3.is(input_reg) &&
+ !scratch3.is(scratch1) &&
+ !scratch3.is(scratch2));
+ // Performs a truncating conversion of a floating point number as used by
+ // the JS bitwise operations.
Label heap_number;
__ b(eq, &heap_number);
// Check for undefined. Undefined is converted to zero for truncating
@@ -3334,36 +3345,38 @@
__ b(&done);
__ bind(&heap_number);
- __ sub(ip, input_reg, Operand(kHeapObjectTag));
- __ vldr(dbl_tmp, ip, HeapNumber::kValueOffset);
- __ vcmp(dbl_tmp, 0.0); // Sets overflow bit in FPSCR flags if NaN.
- __ vcvt_s32_f64(flt_scratch, dbl_tmp);
- __ vmov(input_reg, flt_scratch); // 32-bit result of conversion.
- __ vmrs(pc); // Move vector status bits to normal status bits.
- // Overflow bit is set if dbl_tmp is Nan.
- __ cmn(input_reg, Operand(1), vc); // 0x7fffffff + 1 -> overflow.
- __ cmp(input_reg, Operand(1), vc); // 0x80000000 - 1 -> overflow.
- DeoptimizeIf(vs, instr->environment()); // Saturation may have occured.
+ __ sub(scratch1, input_reg, Operand(kHeapObjectTag));
+ __ vldr(double_scratch2, scratch1, HeapNumber::kValueOffset);
+ __ EmitECMATruncate(input_reg,
+ double_scratch2,
+ single_scratch,
+ scratch1,
+ scratch2,
+ scratch3);
+
} else {
+ CpuFeatures::Scope scope(VFP3);
// Deoptimize if we don't have a heap number.
DeoptimizeIf(ne, instr->environment());
__ sub(ip, input_reg, Operand(kHeapObjectTag));
- __ vldr(dbl_tmp, ip, HeapNumber::kValueOffset);
- __ vcvt_s32_f64(flt_scratch, dbl_tmp);
- __ vmov(input_reg, flt_scratch); // 32-bit result of conversion.
- // Non-truncating conversion means that we cannot lose bits, so we convert
- // back to check; note that using non-overlapping s and d regs would be
- // slightly faster.
- __ vcvt_f64_s32(dbl_scratch, flt_scratch);
- __ VFPCompareAndSetFlags(dbl_scratch, dbl_tmp);
- DeoptimizeIf(ne, instr->environment()); // Not equal or unordered.
+ __ vldr(double_scratch, ip, HeapNumber::kValueOffset);
+ __ EmitVFPTruncate(kRoundToZero,
+ single_scratch,
+ double_scratch,
+ scratch1,
+ scratch2,
+ kCheckForInexactConversion);
+ DeoptimizeIf(ne, instr->environment());
+ // Load the result.
+ __ vmov(input_reg, single_scratch);
+
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
- __ tst(input_reg, Operand(input_reg));
+ __ cmp(input_reg, Operand(0));
__ b(ne, &done);
- __ vmov(lr, ip, dbl_tmp);
- __ tst(ip, Operand(1 << 31)); // Test sign bit.
+ __ vmov(scratch1, double_scratch.high());
+ __ tst(scratch1, Operand(HeapNumber::kSignMask));
DeoptimizeIf(ne, instr->environment());
}
}
@@ -3405,48 +3418,38 @@
void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
- LOperand* input = instr->InputAt(0);
- ASSERT(input->IsDoubleRegister());
- LOperand* result = instr->result();
- ASSERT(result->IsRegister());
-
- DoubleRegister double_input = ToDoubleRegister(input);
- Register result_reg = ToRegister(result);
- SwVfpRegister single_scratch = double_scratch0().low();
+ Register result_reg = ToRegister(instr->result());
Register scratch1 = scratch0();
Register scratch2 = ToRegister(instr->TempAt(0));
+ DwVfpRegister double_input = ToDoubleRegister(instr->InputAt(0));
+ DwVfpRegister double_scratch = double_scratch0();
+ SwVfpRegister single_scratch = double_scratch0().low();
- __ EmitVFPTruncate(kRoundToZero,
- single_scratch,
- double_input,
- scratch1,
- scratch2);
+ Label done;
- // Deoptimize if we had a vfp invalid exception.
- DeoptimizeIf(ne, instr->environment());
-
- // Retrieve the result.
- __ vmov(result_reg, single_scratch);
-
- if (!instr->truncating()) {
- // Convert result back to double and compare with input
- // to check if the conversion was exact.
- __ vmov(single_scratch, result_reg);
- __ vcvt_f64_s32(double_scratch0(), single_scratch);
- __ VFPCompareAndSetFlags(double_scratch0(), double_input);
+ if (instr->truncating()) {
+ Register scratch3 = ToRegister(instr->TempAt(1));
+ __ EmitECMATruncate(result_reg,
+ double_input,
+ single_scratch,
+ scratch1,
+ scratch2,
+ scratch3);
+ } else {
+ VFPRoundingMode rounding_mode = kRoundToMinusInf;
+ __ EmitVFPTruncate(rounding_mode,
+ single_scratch,
+ double_input,
+ scratch1,
+ scratch2,
+ kCheckForInexactConversion);
+ // Deoptimize if we had a vfp invalid exception,
+ // including inexact operation.
DeoptimizeIf(ne, instr->environment());
- if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
- Label done;
- __ cmp(result_reg, Operand(0));
- __ b(ne, &done);
- // Check for -0.
- __ vmov(scratch1, double_input.high());
- __ tst(scratch1, Operand(HeapNumber::kSignMask));
- DeoptimizeIf(ne, instr->environment());
-
- __ bind(&done);
- }
+ // Retrieve the result.
+ __ vmov(result_reg, single_scratch);
}
+ __ bind(&done);
}
« no previous file with comments | « src/arm/lithium-arm.cc ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698