Commit 65813ea2 authored by haitao.feng@intel.com's avatar haitao.feng@intel.com

Tweak SmiSub for X64

R=danno@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16976 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 5a5f2d22
...@@ -1699,34 +1699,37 @@ void MacroAssembler::SmiAdd(Register dst, ...@@ -1699,34 +1699,37 @@ void MacroAssembler::SmiAdd(Register dst,
} }
void MacroAssembler::SmiSub(Register dst, template<class T>
static void SmiSubHelper(MacroAssembler* masm,
Register dst,
Register src1, Register src1,
Register src2, T src2,
Label* on_not_smi_result, Label* on_not_smi_result,
Label::Distance near_jump) { Label::Distance near_jump) {
ASSERT_NOT_NULL(on_not_smi_result);
ASSERT(!dst.is(src2));
if (dst.is(src1)) { if (dst.is(src1)) {
cmpq(dst, src2); Label done;
j(overflow, on_not_smi_result, near_jump); masm->subq(dst, src2);
subq(dst, src2); masm->j(no_overflow, &done, Label::kNear);
// Restore src1.
masm->addq(dst, src2);
masm->jmp(on_not_smi_result, near_jump);
masm->bind(&done);
} else { } else {
movq(dst, src1); masm->movq(dst, src1);
subq(dst, src2); masm->subq(dst, src2);
j(overflow, on_not_smi_result, near_jump); masm->j(overflow, on_not_smi_result, near_jump);
} }
} }
void MacroAssembler::SmiSub(Register dst, Register src1, Register src2) { void MacroAssembler::SmiSub(Register dst,
// No overflow checking. Use only when it's known that Register src1,
// overflowing is impossible (e.g., subtracting two positive smis). Register src2,
Label* on_not_smi_result,
Label::Distance near_jump) {
ASSERT_NOT_NULL(on_not_smi_result);
ASSERT(!dst.is(src2)); ASSERT(!dst.is(src2));
if (!dst.is(src1)) { SmiSubHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump);
movq(dst, src1);
}
subq(dst, src2);
Assert(no_overflow, kSmiSubtractionOverflow);
} }
...@@ -1736,29 +1739,36 @@ void MacroAssembler::SmiSub(Register dst, ...@@ -1736,29 +1739,36 @@ void MacroAssembler::SmiSub(Register dst,
Label* on_not_smi_result, Label* on_not_smi_result,
Label::Distance near_jump) { Label::Distance near_jump) {
ASSERT_NOT_NULL(on_not_smi_result); ASSERT_NOT_NULL(on_not_smi_result);
if (dst.is(src1)) { ASSERT(!src2.AddressUsesRegister(dst));
movq(kScratchRegister, src2); SmiSubHelper<Operand>(this, dst, src1, src2, on_not_smi_result, near_jump);
cmpq(src1, kScratchRegister);
j(overflow, on_not_smi_result, near_jump);
subq(src1, kScratchRegister);
} else {
movq(dst, src1);
subq(dst, src2);
j(overflow, on_not_smi_result, near_jump);
}
} }
void MacroAssembler::SmiSub(Register dst, template<class T>
static void SmiSubNoOverflowHelper(MacroAssembler* masm,
Register dst,
Register src1, Register src1,
const Operand& src2) { T src2) {
// No overflow checking. Use only when it's known that // No overflow checking. Use only when it's known that
// overflowing is impossible (e.g., subtracting two positive smis). // overflowing is impossible (e.g., subtracting two positive smis).
if (!dst.is(src1)) { if (!dst.is(src1)) {
movq(dst, src1); masm->movq(dst, src1);
} }
subq(dst, src2); masm->subq(dst, src2);
Assert(no_overflow, kSmiSubtractionOverflow); masm->Assert(no_overflow, kSmiSubtractionOverflow);
}
void MacroAssembler::SmiSub(Register dst, Register src1, Register src2) {
ASSERT(!dst.is(src2));
SmiSubNoOverflowHelper<Register>(this, dst, src1, src2);
}
void MacroAssembler::SmiSub(Register dst,
Register src1,
const Operand& src2) {
SmiSubNoOverflowHelper<Operand>(this, dst, src1, src2);
} }
......
...@@ -596,24 +596,23 @@ class MacroAssembler: public Assembler { ...@@ -596,24 +596,23 @@ class MacroAssembler: public Assembler {
Register src2); Register src2);
// Subtracts smi values and return the result as a smi. // Subtracts smi values and return the result as a smi.
// If dst is src1, then src1 will be destroyed, even if // If dst is src1, then src1 will be destroyed if the operation is
// the operation is unsuccessful. // successful, otherwise kept intact.
void SmiSub(Register dst, void SmiSub(Register dst,
Register src1, Register src1,
Register src2, Register src2,
Label* on_not_smi_result, Label* on_not_smi_result,
Label::Distance near_jump = Label::kFar); Label::Distance near_jump = Label::kFar);
void SmiSub(Register dst,
Register src1,
Register src2);
void SmiSub(Register dst, void SmiSub(Register dst,
Register src1, Register src1,
const Operand& src2, const Operand& src2,
Label* on_not_smi_result, Label* on_not_smi_result,
Label::Distance near_jump = Label::kFar); Label::Distance near_jump = Label::kFar);
void SmiSub(Register dst,
Register src1,
Register src2);
void SmiSub(Register dst, void SmiSub(Register dst,
Register src1, Register src1,
const Operand& src2); const Operand& src2);
......
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