Index: src/x64/macro-assembler-x64.cc |
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc |
index 0809ccded9f9e1e321a4a51aae273ff87c12e1a7..633cf17f22ae0eeb2e993d81a2849e76acbd4cc9 100644 |
--- a/src/x64/macro-assembler-x64.cc |
+++ b/src/x64/macro-assembler-x64.cc |
@@ -1554,7 +1554,8 @@ void MacroAssembler::SmiSubConstant(Register dst, Register src, Smi* constant) { |
void MacroAssembler::SmiSubConstant(Register dst, |
Register src, |
Smi* constant, |
- Label* on_not_smi_result, |
+ SmiExecutionMode mode, |
+ Label* bailout_label, |
Label::Distance near_jump) { |
if (constant->value() == 0) { |
if (!dst.is(src)) { |
@@ -1562,36 +1563,30 @@ void MacroAssembler::SmiSubConstant(Register dst, |
} |
} else if (dst.is(src)) { |
ASSERT(!dst.is(kScratchRegister)); |
- if (constant->value() == Smi::kMinValue) { |
- // Subtracting min-value from any non-negative value will overflow. |
- // We test the non-negativeness before doing the subtraction. |
- testq(src, src); |
- j(not_sign, on_not_smi_result, near_jump); |
- LoadSmiConstant(kScratchRegister, constant); |
- subq(dst, kScratchRegister); |
+ LoadSmiConstant(kScratchRegister, constant); |
+ subq(dst, kScratchRegister); |
+ if (mode & SMI_BAILOUT_ON_NO_OVERFLOW) { |
+ j(no_overflow, bailout_label, near_jump); |
+ if (mode & SMI_NEED_RESERVE_SOURCES) { |
+ addq(dst, kScratchRegister); |
+ } |
+ } else if (mode & SMI_BAILOUT_ON_OVERFLOW) { |
+ if (mode & SMI_NEED_RESERVE_SOURCES) { |
+ Label done; |
+ j(no_overflow, &done, Label::kNear); |
+ addq(dst, kScratchRegister); |
+ jmp(bailout_label, near_jump); |
+ bind(&done); |
+ } else { |
+ // Implement this when SimSubConstant is invoked from Crankshaft. |
+ // BailoutHandler->BailoutIf(overflow); |
+ UNIMPLEMENTED(); // Not used. |
+ } |
} else { |
- // Subtract by adding the negation. |
- LoadSmiConstant(kScratchRegister, Smi::FromInt(-constant->value())); |
- addq(kScratchRegister, dst); |
- j(overflow, on_not_smi_result, near_jump); |
- movq(dst, kScratchRegister); |
+ ASSERT(mode == SMI_NO_CONSTRAINT); |
} |
} else { |
- if (constant->value() == Smi::kMinValue) { |
- // Subtracting min-value from any non-negative value will overflow. |
- // We test the non-negativeness before doing the subtraction. |
- testq(src, src); |
- j(not_sign, on_not_smi_result, near_jump); |
- LoadSmiConstant(dst, constant); |
- // Adding and subtracting the min-value gives the same result, it only |
- // differs on the overflow bit, which we don't check here. |
- addq(dst, src); |
- } else { |
- // Subtract by adding the negation. |
- LoadSmiConstant(dst, Smi::FromInt(-(constant->value()))); |
- addq(dst, src); |
- j(overflow, on_not_smi_result, near_jump); |
- } |
+ UNIMPLEMENTED(); // Not used. |
} |
} |