__ and_(scratch, result, Operand(HeapNumber::kSignMask));
__ Vmov(double_scratch0(), 0.5);
- __ vadd(input, input, double_scratch0());
+ __ vadd(double_scratch0(), input, double_scratch0());
// Check sign of the result: if the sign changed, the input
// value was in ]0.5, 0[ and the result should be -0.
- __ vmov(result, input.high());
+ __ vmov(result, double_scratch0().high());
__ eor(result, result, Operand(scratch), SetCC);
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
DeoptimizeIf(mi, instr->environment());
__ EmitVFPTruncate(kRoundToMinusInf,
double_scratch0().low(),
- input,
+ double_scratch0(),
result,
scratch);
DeoptimizeIf(ne, instr->environment());
__ movdbl(xmm_scratch, Operand::StaticVariable(one_half));
__ ucomisd(xmm_scratch, input_reg);
__ j(above, &below_half);
- // input = input + 0.5
- __ addsd(input_reg, xmm_scratch);
+ // xmm_scratch = input + 0.5
+ __ addsd(xmm_scratch, input_reg);
// Compute Math.floor(value + 0.5).
// Use truncating instruction (OK because input is positive).
- __ cvttsd2si(output_reg, Operand(input_reg));
+ __ cvttsd2si(output_reg, Operand(xmm_scratch));
// Overflow is signalled with minint.
__ cmp(output_reg, 0x80000000u);
__ And(scratch, result, Operand(HeapNumber::kSignMask));
__ Move(double_scratch0(), 0.5);
- __ add_d(input, input, double_scratch0());
+ __ add_d(double_scratch0(), input, double_scratch0());
// Check sign of the result: if the sign changed, the input
// value was in ]0.5, 0[ and the result should be -0.
- __ mfc1(result, input.high());
+ __ mfc1(result, double_scratch0().high());
__ Xor(result, result, Operand(scratch));
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
// ARM uses 'mi' here, which is 'lt'
__ EmitFPUTruncate(kRoundToMinusInf,
double_scratch0().low(),
- input,
+ double_scratch0(),
result,
except_flag);
// This addition might give a result that isn't the correct for
// rounding, due to loss of precision, but only for a number that's
// so big that the conversion below will overflow anyway.
- __ addsd(input_reg, xmm_scratch);
+ __ addsd(xmm_scratch, input_reg);
// Compute Math.floor(input).
// Use truncating instruction (OK because input is positive).
- __ cvttsd2si(output_reg, input_reg);
+ __ cvttsd2si(output_reg, xmm_scratch);
// Overflow is signalled with minint.
__ cmpl(output_reg, Immediate(0x80000000));
DeoptimizeIf(equal, instr->environment());
--- /dev/null
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+// Test Math.round with the input reused in the same expression.
+function test(x) {
+ var v = Math.round(x) - x;
+ assertEquals(0.5, v);
+}
+
+for (var i = 0; i < 5; ++i) test(0.5);
+%OptimizeFunctionOnNextCall(test);
+test(0.5);