Commit 548fb463 authored by bmeurer@chromium.org's avatar bmeurer@chromium.org

[x86] Fix register constraints for multiply-high.

TEST=mjsunit/compiler,unittests
R=titzer@chromium.org

Review URL: https://codereview.chromium.org/671393002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24862 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent e6ac285b
......@@ -469,10 +469,9 @@ void InstructionSelector::VisitInt32Mul(Node* node) {
void InstructionSelector::VisitInt32MulHigh(Node* node) {
IA32OperandGenerator g(this);
InstructionOperand* temps[] = {g.TempRegister(eax)};
size_t temp_count = arraysize(temps);
Emit(kIA32ImulHigh, g.DefineAsFixed(node, edx),
g.UseFixed(node->InputAt(0), eax), g.UseRegister(node->InputAt(1)),
temp_count, temps);
g.UseFixed(node->InputAt(0), eax), g.UseUniqueRegister(node->InputAt(1)),
arraysize(temps), temps);
}
......
......@@ -257,7 +257,7 @@ class UnallocatedOperand : public InstructionOperand {
}
// [lifetime]: Only for non-FIXED_SLOT.
bool IsUsedAtStart() {
bool IsUsedAtStart() const {
DCHECK(basic_policy() == EXTENDED_POLICY);
return LifetimeField::decode(value_) == USED_AT_START;
}
......
......@@ -560,10 +560,9 @@ void InstructionSelector::VisitInt64Mul(Node* node) {
void InstructionSelector::VisitInt32MulHigh(Node* node) {
X64OperandGenerator g(this);
InstructionOperand* temps[] = {g.TempRegister(rax)};
size_t temp_count = arraysize(temps);
Emit(kX64ImulHigh32, g.DefineAsFixed(node, rdx),
g.UseFixed(node->InputAt(0), rax), g.UseRegister(node->InputAt(1)),
temp_count, temps);
g.UseFixed(node->InputAt(0), rax), g.UseUniqueRegister(node->InputAt(1)),
arraysize(temps), temps);
}
......
// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
function Module(stdlib, foreign, buffer) {
"use asm";
var HEAP32 = new stdlib.Int32Array(buffer);
function g(a) {
HEAP32[a] = 9982 * 100;
return a;
}
function f(i1) {
i1 = i1 | 0;
var i2 = HEAP32[i1 >> 2] | 0;
g(i1);
L2909: {
L2: {
if (0) {
if (0) break L2;
g(i2);
break L2909;
}
}
var r = (HEAP32[1] | 0) / 100 | 0;
g(r);
return r;
}
}
return {f: f};
}
var f = Module(this, {}, new ArrayBuffer(64 * 1024)).f;
assertEquals(9982, f(1));
......@@ -593,9 +593,12 @@ TEST_F(InstructionSelectorTest, Int32MulHigh) {
EXPECT_EQ(kIA32ImulHigh, s[0]->arch_opcode());
ASSERT_EQ(2U, s[0]->InputCount());
EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
EXPECT_TRUE(s.IsFixed(s[0]->InputAt(0), eax));
EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
EXPECT_TRUE(!s.IsUsedAtStart(s[0]->InputAt(1)));
ASSERT_EQ(1U, s[0]->OutputCount());
EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
EXPECT_TRUE(s.IsFixed(s[0]->OutputAt(0), edx));
}
} // namespace compiler
......
......@@ -129,6 +129,24 @@ int InstructionSelectorTest::Stream::ToVreg(const Node* node) const {
}
bool InstructionSelectorTest::Stream::IsFixed(const InstructionOperand* operand,
Register reg) const {
if (!operand->IsUnallocated()) return false;
const UnallocatedOperand* unallocated = UnallocatedOperand::cast(operand);
if (!unallocated->HasFixedRegisterPolicy()) return false;
const int index = Register::ToAllocationIndex(reg);
return unallocated->fixed_register_index() == index;
}
bool InstructionSelectorTest::Stream::IsUsedAtStart(
const InstructionOperand* operand) const {
if (!operand->IsUnallocated()) return false;
const UnallocatedOperand* unallocated = UnallocatedOperand::cast(operand);
return unallocated->IsUsedAtStart();
}
// -----------------------------------------------------------------------------
// Return.
......
......@@ -170,6 +170,9 @@ class InstructionSelectorTest : public TestWithContext, public TestWithZone {
int ToVreg(const Node* node) const;
bool IsFixed(const InstructionOperand* operand, Register reg) const;
bool IsUsedAtStart(const InstructionOperand* operand) const;
FrameStateDescriptor* GetFrameStateDescriptor(int deoptimization_id) {
EXPECT_LT(deoptimization_id, GetFrameStateDescriptorCount());
return deoptimization_entries_[deoptimization_id];
......
......@@ -510,9 +510,12 @@ TEST_F(InstructionSelectorTest, Int32MulHigh) {
EXPECT_EQ(kX64ImulHigh32, s[0]->arch_opcode());
ASSERT_EQ(2U, s[0]->InputCount());
EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
EXPECT_TRUE(s.IsFixed(s[0]->InputAt(0), rax));
EXPECT_EQ(s.ToVreg(p1), s.ToVreg(s[0]->InputAt(1)));
EXPECT_TRUE(!s.IsUsedAtStart(s[0]->InputAt(1)));
ASSERT_EQ(1U, s[0]->OutputCount());
EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
EXPECT_TRUE(s.IsFixed(s[0]->OutputAt(0), rdx));
}
} // namespace compiler
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment