Revision: 6681
Author: [email protected]
Date: Tue Feb 8 06:37:50 2011
Log: x64: Add MulI and DivI to lithium instructions.
Review URL: http://codereview.chromium.org/6448001
http://code.google.com/p/v8/source/detail?r=6681
Added:
/branches/bleeding_edge/test/mjsunit/regress/regress-1117.js
Modified:
/branches/bleeding_edge/src/arm/lithium-arm.cc
/branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
/branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
/branches/bleeding_edge/src/ia32/lithium-ia32.cc
/branches/bleeding_edge/src/x64/assembler-x64.cc
/branches/bleeding_edge/src/x64/assembler-x64.h
/branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
/branches/bleeding_edge/src/x64/lithium-x64.cc
/branches/bleeding_edge/src/x64/lithium-x64.h
=======================================
--- /dev/null
+++ /branches/bleeding_edge/test/mjsunit/regress/regress-1117.js Tue Feb 8
06:37:50 2011
@@ -0,0 +1,35 @@
+// 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.
+
+// Test that we actually return the right value (-0) when we multiply
+// constant 0 with a negative integer.
+
+function foo(y) {return 0 * y; }
+for( var i = 0; i< 1000000; i++){
+ foo(42);
+}
+assertEquals(1/foo(-42), -Infinity);
=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc Tue Feb 8 02:45:21 2011
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc Tue Feb 8 06:37:50 2011
@@ -1306,10 +1306,10 @@
// the generated code, which requires registers r0
// and r1 to be used. We should remove that
// when we provide a native implementation.
- LOperand* value = UseFixed(instr->left(), r0);
+ LOperand* dividend = UseFixed(instr->left(), r0);
LOperand* divisor = UseFixed(instr->right(), r1);
return AssignEnvironment(AssignPointerMap(
- DefineFixed(new LDivI(value, divisor), r0)));
+ DefineFixed(new LDivI(dividend, divisor), r0)));
} else {
return DoArithmeticT(Token::DIV, instr);
}
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Feb 8
02:08:47 2011
+++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Tue Feb 8
06:37:50 2011
@@ -1188,7 +1188,7 @@
__ tst(left, Operand(left));
__ b(ne, &done);
if (instr->InputAt(1)->IsConstantOperand()) {
- if (ToInteger32(LConstantOperand::cast(instr->InputAt(1))) < 0) {
+ if (ToInteger32(LConstantOperand::cast(instr->InputAt(1))) <= 0) {
DeoptimizeIf(kNoCondition, instr->environment());
}
} else {
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue Feb 8
02:08:47 2011
+++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Tue Feb 8
06:37:50 2011
@@ -804,7 +804,7 @@
__ test(left, Operand(left));
__ j(not_zero, &done);
if (right->IsConstantOperand()) {
- if (ToInteger32(LConstantOperand::cast(right)) < 0) {
+ if (ToInteger32(LConstantOperand::cast(right)) <= 0) {
DeoptimizeIf(no_condition, instr->environment());
}
} else {
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Tue Feb 8 02:45:21
2011
+++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Tue Feb 8 06:37:50
2011
@@ -1322,9 +1322,9 @@
// The temporary operand is necessary to ensure that right is not
allocated
// into edx.
LOperand* temp = FixedTemp(edx);
- LOperand* value = UseFixed(instr->left(), eax);
+ LOperand* dividend = UseFixed(instr->left(), eax);
LOperand* divisor = UseRegister(instr->right());
- LDivI* result = new LDivI(value, divisor, temp);
+ LDivI* result = new LDivI(dividend, divisor, temp);
return AssignEnvironment(DefineFixed(result, eax));
} else {
ASSERT(instr->representation().IsTagged());
=======================================
--- /branches/bleeding_edge/src/x64/assembler-x64.cc Mon Feb 7 06:15:05
2011
+++ /branches/bleeding_edge/src/x64/assembler-x64.cc Tue Feb 8 06:37:50
2011
@@ -1186,6 +1186,16 @@
emit(0xAF);
emit_modrm(dst, src);
}
+
+
+void Assembler::imull(Register dst, const Operand& src) {
+ EnsureSpace ensure_space(this);
+ last_pc_ = pc_;
+ emit_optional_rex_32(dst, src);
+ emit(0x0F);
+ emit(0xAF);
+ emit_operand(dst, src);
+}
void Assembler::imull(Register dst, Register src, Immediate imm) {
=======================================
--- /branches/bleeding_edge/src/x64/assembler-x64.h Mon Feb 7 23:49:59 2011
+++ /branches/bleeding_edge/src/x64/assembler-x64.h Tue Feb 8 06:37:50 2011
@@ -865,6 +865,7 @@
void imul(Register dst, Register src, Immediate imm); // dst = src *
imm.
// Signed 32-bit multiply instructions.
void imull(Register dst, Register src); // dst = dst *
src.
+ void imull(Register dst, const Operand& src); // dst = dst *
src.
void imull(Register dst, Register src, Immediate imm); // dst = src *
imm.
void incq(Register dst);
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Tue Feb 8
03:26:42 2011
+++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Tue Feb 8
06:37:50 2011
@@ -657,11 +657,92 @@
void LCodeGen::DoDivI(LDivI* instr) {
- Abort("Unimplemented: %s", "DoDivI");}
+ LOperand* right = instr->InputAt(1);
+ ASSERT(ToRegister(instr->result()).is(rax));
+ ASSERT(ToRegister(instr->InputAt(0)).is(rax));
+ ASSERT(!ToRegister(instr->InputAt(1)).is(rax));
+ ASSERT(!ToRegister(instr->InputAt(1)).is(rdx));
+
+ Register left_reg = rax;
+
+ // Check for x / 0.
+ Register right_reg = ToRegister(right);
+ if (instr->hydrogen()->CheckFlag(HValue::kCanBeDivByZero)) {
+ __ testl(right_reg, right_reg);
+ DeoptimizeIf(zero, instr->environment());
+ }
+
+ // Check for (0 / -x) that will produce negative zero.
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ NearLabel left_not_zero;
+ __ testl(left_reg, left_reg);
+ __ j(not_zero, &left_not_zero);
+ __ testl(right_reg, right_reg);
+ DeoptimizeIf(sign, instr->environment());
+ __ bind(&left_not_zero);
+ }
+
+ // Check for (-kMinInt / -1).
+ if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
+ NearLabel left_not_min_int;
+ __ cmpl(left_reg, Immediate(kMinInt));
+ __ j(not_zero, &left_not_min_int);
+ __ cmpl(right_reg, Immediate(-1));
+ DeoptimizeIf(zero, instr->environment());
+ __ bind(&left_not_min_int);
+ }
+
+ // Sign extend to rdx.
+ __ cdq();
+ __ idivl(right_reg);
+
+ // Deoptimize if remainder is not 0.
+ __ testl(rdx, rdx);
+ DeoptimizeIf(not_zero, instr->environment());
+}
void LCodeGen::DoMulI(LMulI* instr) {
- Abort("Unimplemented: %s", "DoMultI");}
+ Register left = ToRegister(instr->InputAt(0));
+ LOperand* right = instr->InputAt(1);
+
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ __ movl(kScratchRegister, left);
+ }
+
+ if (right->IsConstantOperand()) {
+ int right_value = ToInteger32(LConstantOperand::cast(right));
+ __ imull(left, left, Immediate(right_value));
+ } else if (right->IsStackSlot()) {
+ __ imull(left, ToOperand(right));
+ } else {
+ __ imull(left, ToRegister(right));
+ }
+
+ if (instr->hydrogen()->CheckFlag(HValue::kCanOverflow)) {
+ DeoptimizeIf(overflow, instr->environment());
+ }
+
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ // Bail out if the result is supposed to be negative zero.
+ NearLabel done;
+ __ testl(left, left);
+ __ j(not_zero, &done);
+ if (right->IsConstantOperand()) {
+ if (ToInteger32(LConstantOperand::cast(right)) <= 0) {
+ DeoptimizeIf(no_condition, instr->environment());
+ }
+ } else if (right->IsStackSlot()) {
+ __ or_(kScratchRegister, ToOperand(right));
+ DeoptimizeIf(sign, instr->environment());
+ } else {
+ // Test the non-zero operand for negative sign.
+ __ or_(kScratchRegister, ToRegister(right));
+ DeoptimizeIf(sign, instr->environment());
+ }
+ __ bind(&done);
+ }
+}
void LCodeGen::DoBitI(LBitI* instr) {
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc Tue Feb 8 03:26:42 2011
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc Tue Feb 8 06:37:50 2011
@@ -1264,8 +1264,20 @@
LInstruction* LChunkBuilder::DoDiv(HDiv* instr) {
- Abort("Unimplemented: %s", "DoDiv");
- return NULL;
+ if (instr->representation().IsDouble()) {
+ return DoArithmeticD(Token::DIV, instr);
+ } else if (instr->representation().IsInteger32()) {
+ // The temporary operand is necessary to ensure that right is not
allocated
+ // into rdx.
+ LOperand* temp = FixedTemp(rdx);
+ LOperand* dividend = UseFixed(instr->left(), rax);
+ LOperand* divisor = UseRegister(instr->right());
+ LDivI* result = new LDivI(dividend, divisor, temp);
+ return AssignEnvironment(DefineFixed(result, rax));
+ } else {
+ ASSERT(instr->representation().IsTagged());
+ return DoArithmeticT(Token::DIV, instr);
+ }
}
@@ -1276,8 +1288,19 @@
LInstruction* LChunkBuilder::DoMul(HMul* instr) {
- Abort("Unimplemented: %s", "DoMul");
- return NULL;
+ if (instr->representation().IsInteger32()) {
+ ASSERT(instr->left()->representation().IsInteger32());
+ ASSERT(instr->right()->representation().IsInteger32());
+ LOperand* left = UseRegisterAtStart(instr->LeastConstantOperand());
+ LOperand* right = UseOrConstant(instr->MostConstantOperand());
+ LMulI* mul = new LMulI(left, right);
+ return AssignEnvironment(DefineSameAsFirst(mul));
+ } else if (instr->representation().IsDouble()) {
+ return DoArithmeticD(Token::MUL, instr);
+ } else {
+ ASSERT(instr->representation().IsTagged());
+ return DoArithmeticT(Token::MUL, instr);
+ }
}
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.h Tue Feb 8 02:45:21 2011
+++ /branches/bleeding_edge/src/x64/lithium-x64.h Tue Feb 8 06:37:50 2011
@@ -539,12 +539,11 @@
};
-class LMulI: public LTemplateInstruction<1, 2, 1> {
+class LMulI: public LTemplateInstruction<1, 2, 0> {
public:
- LMulI(LOperand* left, LOperand* right, LOperand* temp) {
+ LMulI(LOperand* left, LOperand* right) {
inputs_[0] = left;
inputs_[1] = right;
- temps_[0] = temp;
}
DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev