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
This commit is contained in:
haitao.feng@intel.com 2013-09-27 07:46:52 +00:00
parent 5a5f2d22e1
commit 65813ea24e
2 changed files with 54 additions and 45 deletions

View File

@ -1699,6 +1699,29 @@ void MacroAssembler::SmiAdd(Register dst,
}
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)) {
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 {
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,
@ -1706,27 +1729,7 @@ void MacroAssembler::SmiSub(Register dst,
Label::Distance near_jump) {
ASSERT_NOT_NULL(on_not_smi_result);
ASSERT(!dst.is(src2));
if (dst.is(src1)) {
cmpq(dst, src2);
j(overflow, on_not_smi_result, near_jump);
subq(dst, src2);
} else {
movq(dst, src1);
subq(dst, src2);
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).
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);
}
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)) {
masm->movq(dst, src1);
}
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) {
// 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);
}
subq(dst, src2);
Assert(no_overflow, kSmiSubtractionOverflow);
SmiSubNoOverflowHelper<Operand>(this, dst, src1, src2);
}

View File

@ -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,
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,
Label* on_not_smi_result,
Label::Distance near_jump = Label::kFar);
void SmiSub(Register dst,
Register src1,
const Operand& src2);