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,
}
void MacroAssembler::SmiSub(Register dst,
Register src1,
Register src2,
Label* on_not_smi_result,
Label::Distance near_jump) {
ASSERT_NOT_NULL(on_not_smi_result);
ASSERT(!dst.is(src2));
template<class T>
static void SmiSubHelper(MacroAssembler* masm,
Register dst,
Register src1,
T src2,
Label* on_not_smi_result,
Label::Distance near_jump) {
if (dst.is(src1)) {
cmpq(dst, src2);
j(overflow, on_not_smi_result, near_jump);
subq(dst, src2);
Label done;
masm->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 {
movq(dst, src1);
subq(dst, src2);
j(overflow, on_not_smi_result, near_jump);
masm->movq(dst, src1);
masm->subq(dst, src2);
masm->j(overflow, on_not_smi_result, near_jump);
}
}
void MacroAssembler::SmiSub(Register dst, Register src1, Register src2) {
// No overflow checking. Use only when it's known that
// overflowing is impossible (e.g., subtracting two positive smis).
void MacroAssembler::SmiSub(Register dst,
Register src1,
Register src2,
Label* on_not_smi_result,
Label::Distance near_jump) {
ASSERT_NOT_NULL(on_not_smi_result);
ASSERT(!dst.is(src2));
if (!dst.is(src1)) {
movq(dst, src1);
}
subq(dst, src2);
Assert(no_overflow, kSmiSubtractionOverflow);
SmiSubHelper<Register>(this, dst, src1, src2, on_not_smi_result, near_jump);
}
......@@ -1736,29 +1739,36 @@ void MacroAssembler::SmiSub(Register dst,
Label* on_not_smi_result,
Label::Distance near_jump) {
ASSERT_NOT_NULL(on_not_smi_result);
if (dst.is(src1)) {
movq(kScratchRegister, src2);
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);
}
ASSERT(!src2.AddressUsesRegister(dst));
SmiSubHelper<Operand>(this, dst, src1, src2, on_not_smi_result, near_jump);
}
void MacroAssembler::SmiSub(Register dst,
Register src1,
const Operand& src2) {
template<class T>
static void SmiSubNoOverflowHelper(MacroAssembler* masm,
Register dst,
Register src1,
T src2) {
// No overflow checking. Use only when it's known that
// overflowing is impossible (e.g., subtracting two positive smis).
if (!dst.is(src1)) {
movq(dst, src1);
masm->movq(dst, src1);
}
subq(dst, src2);
Assert(no_overflow, kSmiSubtractionOverflow);
masm->subq(dst, src2);
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 {
Register src2);
// Subtracts smi values and return the result as a smi.
// If dst is src1, then src1 will be destroyed, even if
// the operation is unsuccessful.
// If dst is src1, then src1 will be destroyed if the operation is
// successful, otherwise kept intact.
void SmiSub(Register dst,
Register src1,
Register src2,
Label* on_not_smi_result,
Label::Distance near_jump = Label::kFar);
void SmiSub(Register dst,
Register src1,
Register src2);
void SmiSub(Register dst,
Register src1,
const Operand& src2,
Label* on_not_smi_result,
Label::Distance near_jump = Label::kFar);
void SmiSub(Register dst,
Register src1,
Register src2);
void SmiSub(Register dst,
Register src1,
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