Index: src/x64/macro-assembler-x64.h |
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h |
index ca13ca3955423c54f3bcc5136186b4adc9ba3600..d57b4da4126f1f34bd7f451209159aabe7f21c8e 100644 |
--- a/src/x64/macro-assembler-x64.h |
+++ b/src/x64/macro-assembler-x64.h |
@@ -375,12 +375,60 @@ class MacroAssembler: public Assembler { |
// --------------------------------------------------------------------------- |
// Smi tagging, untagging and operations on tagged smis. |
+ class SmiInstructionWrapper { |
danno
2013/08/19 21:47:44
My general feedback to this class is that it's too
|
+ public: |
+ SmiInstructionWrapper() { } |
+ virtual ~SmiInstructionWrapper() { } |
+ virtual bool NeedsCheckOverflow() const = 0; |
+ virtual bool NeedsCheckMinusZero() const = 0; |
danno
2013/08/19 21:47:44
You never call NeedsCheckMinusZero anywhere. Can y
haitao.feng
2013/08/20 15:09:30
I have planned to use it for SmiMul. If the caller
danno
2013/08/20 15:58:14
Yes, but this is specific to the Mul operation, se
haitao.feng
2013/08/21 13:18:03
We will handle this when https://codereview.chromi
|
+ virtual bool NeedsKeepSourceOperandsIntact() const = 0; |
danno
2013/08/19 21:47:44
I think you can avoid this one, too. See my commen
|
+ virtual void BailoutIf(Condition cc) const = 0; |
+ }; |
+ |
+ class SafeSmiInstructionWrapper : public SmiInstructionWrapper { |
danno
2013/08/19 21:47:44
This class is never used, please remove it.
haitao.feng
2013/08/20 15:09:30
I have planned to unify the interface. So the curr
|
+ public: |
+ SafeSmiInstructionWrapper() { } |
+ virtual ~SafeSmiInstructionWrapper() { } |
+ virtual bool NeedsCheckOverflow() const { return false; } |
+ virtual bool NeedsCheckMinusZero() const { return false; } |
+ virtual bool NeedsKeepSourceOperandsIntact() const { return false; } |
+ virtual void BailoutIf(Condition cc) const { } |
+ }; |
+ |
+ class StrictSmiInstructionWrapper : public SmiInstructionWrapper { |
+ public: |
+ StrictSmiInstructionWrapper(MacroAssembler* macro_assembler, |
+ Label* on_invalid, |
+ Label::Distance near_jump = Label::kFar) |
+ : macro_assembler_(macro_assembler), |
+ on_invalid_(on_invalid), |
+ near_jump_(near_jump) { } |
+ virtual ~StrictSmiInstructionWrapper() { } |
+ virtual bool NeedsCheckOverflow() const { return true; } |
+ virtual bool NeedsCheckMinusZero() const { return true; } |
+ virtual bool NeedsKeepSourceOperandsIntact() const { return true; } |
+ virtual void BailoutIf(Condition cc) const { |
+ ASSERT_NOT_NULL(on_invalid_); |
+ macro_assembler_->j(cc, on_invalid_, near_jump_); |
+ } |
+ |
+ private: |
+ MacroAssembler* macro_assembler_; |
+ Label* on_invalid_; |
+ Label::Distance near_jump_; |
+ }; |
+ |
void InitializeSmiConstantRegister() { |
movq(kSmiConstantRegister, |
reinterpret_cast<uint64_t>(Smi::FromInt(kSmiConstantRegisterValue)), |
RelocInfo::NONE64); |
} |
+ // Support for constant splitting. |
+ bool IsUnsafeInt(const int x); |
danno
2013/08/19 21:47:44
shouldn't this be a int32_t just to be clear?
haitao.feng
2013/08/20 15:09:30
I will change this when I gather all the SMI funct
|
+ void SafeMove(Register dst, Smi* src); |
+ void SafePush(Smi* src); |
+ |
// Conversions between tagged smi values and non-tagged integer values. |
// Tag an integer value. The result must be known to be a valid smi value. |
@@ -484,10 +532,17 @@ class MacroAssembler: public Assembler { |
// Jump if the value cannot be represented by a smi. |
void JumpIfNotValidSmiValue(Register src, Label* on_invalid, |
Label::Distance near_jump = Label::kFar); |
+ // Jump if the value can be represented by a smi. |
+ void JumpIfValidSmiValue(Register src, Label* on_valid, |
+ Label::Distance near_jump = Label::kFar); |
// Jump if the unsigned integer value cannot be represented by a smi. |
void JumpIfUIntNotValidSmiValue(Register src, Label* on_invalid, |
Label::Distance near_jump = Label::kFar); |
+ // Jump if the unsigned integer value can be represented by a smi. |
+ void JumpIfUIntValidSmiValue(Register src, Label* on_valid, |
+ Label::Distance near_jump = Label::kFar); |
+ |
// Jump to label if the value is a tagged smi. |
void JumpIfSmi(Register src, |
@@ -549,8 +604,7 @@ class MacroAssembler: public Assembler { |
void SmiAddConstant(Register dst, |
Register src, |
Smi* constant, |
- Label* on_not_smi_result, |
- Label::Distance near_jump = Label::kFar); |
+ const SmiInstructionWrapper& wrapper); |
// Subtract an integer constant from a tagged smi, giving a tagged smi as |
// result. No testing on the result is done. Sets the N and Z flags |
@@ -558,12 +612,11 @@ class MacroAssembler: public Assembler { |
void SmiSubConstant(Register dst, Register src, Smi* constant); |
// Subtract an integer constant from a tagged smi, giving a tagged smi as |
- // result, or jumping to a label if the result cannot be represented by a smi. |
+ // result, or bailout if the result cannot be represented by a smi. |
void SmiSubConstant(Register dst, |
Register src, |
Smi* constant, |
- Label* on_not_smi_result, |
- Label::Distance near_jump = Label::kFar); |
+ const SmiInstructionWrapper& wrapper); |
// Negating a smi can give a negative zero or too large positive value. |
// NOTICE: This operation jumps on success, not failure! |
@@ -573,31 +626,23 @@ class MacroAssembler: public Assembler { |
Label::Distance near_jump = Label::kFar); |
// Adds smi values and return the result as a smi. |
- // If dst is src1, then src1 will be destroyed, even if |
- // the operation is unsuccessful. |
void SmiAdd(Register dst, |
Register src1, |
Register src2, |
- Label* on_not_smi_result, |
- Label::Distance near_jump = Label::kFar); |
+ const SmiInstructionWrapper& wrapper); |
void SmiAdd(Register dst, |
Register src1, |
const Operand& src2, |
- Label* on_not_smi_result, |
- Label::Distance near_jump = Label::kFar); |
- |
+ const SmiInstructionWrapper& wrapper); |
void SmiAdd(Register dst, |
Register src1, |
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. |
void SmiSub(Register dst, |
Register src1, |
Register src2, |
- Label* on_not_smi_result, |
- Label::Distance near_jump = Label::kFar); |
+ const SmiInstructionWrapper& wrapper); |
void SmiSub(Register dst, |
Register src1, |
@@ -606,8 +651,7 @@ class MacroAssembler: public Assembler { |
void SmiSub(Register dst, |
Register src1, |
const Operand& src2, |
- Label* on_not_smi_result, |
- Label::Distance near_jump = Label::kFar); |
+ const SmiInstructionWrapper& wrapper); |
void SmiSub(Register dst, |
Register src1, |
@@ -650,7 +694,8 @@ class MacroAssembler: public Assembler { |
void SmiShiftLeftConstant(Register dst, |
Register src, |
- int shift_value); |
+ int shift_value, |
+ const SmiInstructionWrapper& wrapper); |
void SmiShiftLogicalRightConstant(Register dst, |
Register src, |
int shift_value, |
@@ -664,7 +709,8 @@ class MacroAssembler: public Assembler { |
// Uses and clobbers rcx, so dst may not be rcx. |
void SmiShiftLeft(Register dst, |
Register src1, |
- Register src2); |
+ Register src2, |
+ Label* on_not_smi_result); |
// Shifts a smi value to the right, shifting in zero bits at the top, and |
// returns the unsigned intepretation of the result if that is a smi. |
// Uses and clobbers rcx, so dst may not be rcx. |
@@ -722,6 +768,9 @@ class MacroAssembler: public Assembler { |
void Push(Smi* smi); |
void Test(const Operand& dst, Smi* source); |
+ void PushInt64AsTwoSmis(Register src, Register scratch = kScratchRegister); |
+ void PopInt64AsTwoSmis(Register dst, Register scratch = kScratchRegister); |
+ static bool IsUnsafeSmiOperator(Token::Value op); |
// --------------------------------------------------------------------------- |
// String macros. |
@@ -774,11 +823,6 @@ class MacroAssembler: public Assembler { |
// Move if the registers are not identical. |
void Move(Register target, Register source); |
- // Support for constant splitting. |
- bool IsUnsafeInt(const int x); |
- void SafeMove(Register dst, Smi* src); |
- void SafePush(Smi* src); |
- |
// Bit-field support. |
void TestBit(const Operand& dst, int bit_index); |