Index: src/arm/code-stubs-arm.h |
=================================================================== |
--- src/arm/code-stubs-arm.h (revision 7552) |
+++ src/arm/code-stubs-arm.h (working copy) |
@@ -71,162 +71,6 @@ |
}; |
-class GenericBinaryOpStub : public CodeStub { |
- public: |
- static const int kUnknownIntValue = -1; |
- |
- GenericBinaryOpStub(Token::Value op, |
- OverwriteMode mode, |
- Register lhs, |
- Register rhs, |
- int constant_rhs = kUnknownIntValue) |
- : op_(op), |
- mode_(mode), |
- lhs_(lhs), |
- rhs_(rhs), |
- constant_rhs_(constant_rhs), |
- specialized_on_rhs_(RhsIsOneWeWantToOptimizeFor(op, constant_rhs)), |
- runtime_operands_type_(BinaryOpIC::UNINIT_OR_SMI), |
- name_(NULL) { } |
- |
- GenericBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info) |
- : op_(OpBits::decode(key)), |
- mode_(ModeBits::decode(key)), |
- lhs_(LhsRegister(RegisterBits::decode(key))), |
- rhs_(RhsRegister(RegisterBits::decode(key))), |
- constant_rhs_(KnownBitsForMinorKey(KnownIntBits::decode(key))), |
- specialized_on_rhs_(RhsIsOneWeWantToOptimizeFor(op_, constant_rhs_)), |
- runtime_operands_type_(type_info), |
- name_(NULL) { } |
- |
- private: |
- Token::Value op_; |
- OverwriteMode mode_; |
- Register lhs_; |
- Register rhs_; |
- int constant_rhs_; |
- bool specialized_on_rhs_; |
- BinaryOpIC::TypeInfo runtime_operands_type_; |
- char* name_; |
- |
- static const int kMaxKnownRhs = 0x40000000; |
- static const int kKnownRhsKeyBits = 6; |
- |
- // Minor key encoding in 17 bits. |
- class ModeBits: public BitField<OverwriteMode, 0, 2> {}; |
- class OpBits: public BitField<Token::Value, 2, 6> {}; |
- class TypeInfoBits: public BitField<int, 8, 3> {}; |
- class RegisterBits: public BitField<bool, 11, 1> {}; |
- class KnownIntBits: public BitField<int, 12, kKnownRhsKeyBits> {}; |
- |
- Major MajorKey() { return GenericBinaryOp; } |
- int MinorKey() { |
- ASSERT((lhs_.is(r0) && rhs_.is(r1)) || |
- (lhs_.is(r1) && rhs_.is(r0))); |
- // Encode the parameters in a unique 18 bit value. |
- return OpBits::encode(op_) |
- | ModeBits::encode(mode_) |
- | KnownIntBits::encode(MinorKeyForKnownInt()) |
- | TypeInfoBits::encode(runtime_operands_type_) |
- | RegisterBits::encode(lhs_.is(r0)); |
- } |
- |
- void Generate(MacroAssembler* masm); |
- void HandleNonSmiBitwiseOp(MacroAssembler* masm, |
- Register lhs, |
- Register rhs); |
- void HandleBinaryOpSlowCases(MacroAssembler* masm, |
- Label* not_smi, |
- Register lhs, |
- Register rhs, |
- const Builtins::JavaScript& builtin); |
- void GenerateTypeTransition(MacroAssembler* masm); |
- |
- static bool RhsIsOneWeWantToOptimizeFor(Token::Value op, int constant_rhs) { |
- if (constant_rhs == kUnknownIntValue) return false; |
- if (op == Token::DIV) return constant_rhs >= 2 && constant_rhs <= 3; |
- if (op == Token::MOD) { |
- if (constant_rhs <= 1) return false; |
- if (constant_rhs <= 10) return true; |
- if (constant_rhs <= kMaxKnownRhs && IsPowerOf2(constant_rhs)) return true; |
- return false; |
- } |
- return false; |
- } |
- |
- int MinorKeyForKnownInt() { |
- if (!specialized_on_rhs_) return 0; |
- if (constant_rhs_ <= 10) return constant_rhs_ + 1; |
- ASSERT(IsPowerOf2(constant_rhs_)); |
- int key = 12; |
- int d = constant_rhs_; |
- while ((d & 1) == 0) { |
- key++; |
- d >>= 1; |
- } |
- ASSERT(key >= 0 && key < (1 << kKnownRhsKeyBits)); |
- return key; |
- } |
- |
- int KnownBitsForMinorKey(int key) { |
- if (!key) return 0; |
- if (key <= 11) return key - 1; |
- int d = 1; |
- while (key != 12) { |
- key--; |
- d <<= 1; |
- } |
- return d; |
- } |
- |
- Register LhsRegister(bool lhs_is_r0) { |
- return lhs_is_r0 ? r0 : r1; |
- } |
- |
- Register RhsRegister(bool lhs_is_r0) { |
- return lhs_is_r0 ? r1 : r0; |
- } |
- |
- bool HasSmiSmiFastPath() { |
- return op_ != Token::DIV; |
- } |
- |
- bool ShouldGenerateSmiCode() { |
- return ((op_ != Token::DIV && op_ != Token::MOD) || specialized_on_rhs_) && |
- runtime_operands_type_ != BinaryOpIC::HEAP_NUMBERS && |
- runtime_operands_type_ != BinaryOpIC::STRINGS; |
- } |
- |
- bool ShouldGenerateFPCode() { |
- return runtime_operands_type_ != BinaryOpIC::STRINGS; |
- } |
- |
- virtual int GetCodeKind() { return Code::BINARY_OP_IC; } |
- |
- virtual InlineCacheState GetICState() { |
- return BinaryOpIC::ToState(runtime_operands_type_); |
- } |
- |
- const char* GetName(); |
- |
- virtual void FinishCode(Code* code) { |
- code->set_binary_op_type(runtime_operands_type_); |
- } |
- |
-#ifdef DEBUG |
- void Print() { |
- if (!specialized_on_rhs_) { |
- PrintF("GenericBinaryOpStub (%s)\n", Token::String(op_)); |
- } else { |
- PrintF("GenericBinaryOpStub (%s by %d)\n", |
- Token::String(op_), |
- constant_rhs_); |
- } |
- } |
-#endif |
-}; |
- |
- |
class TypeRecordingBinaryOpStub: public CodeStub { |
public: |
TypeRecordingBinaryOpStub(Token::Value op, OverwriteMode mode) |
@@ -413,102 +257,6 @@ |
}; |
-// This stub can do a fast mod operation without using fp. |
-// It is tail called from the GenericBinaryOpStub and it always |
-// returns an answer. It never causes GC so it doesn't need a real frame. |
-// |
-// The inputs are always positive Smis. This is never called |
-// where the denominator is a power of 2. We handle that separately. |
-// |
-// If we consider the denominator as an odd number multiplied by a power of 2, |
-// then: |
-// * The exponent (power of 2) is in the shift_distance register. |
-// * The odd number is in the odd_number register. It is always in the range |
-// of 3 to 25. |
-// * The bits from the numerator that are to be copied to the answer (there are |
-// shift_distance of them) are in the mask_bits register. |
-// * The other bits of the numerator have been shifted down and are in the lhs |
-// register. |
-class IntegerModStub : public CodeStub { |
- public: |
- IntegerModStub(Register result, |
- Register shift_distance, |
- Register odd_number, |
- Register mask_bits, |
- Register lhs, |
- Register scratch) |
- : result_(result), |
- shift_distance_(shift_distance), |
- odd_number_(odd_number), |
- mask_bits_(mask_bits), |
- lhs_(lhs), |
- scratch_(scratch) { |
- // We don't code these in the minor key, so they should always be the same. |
- // We don't really want to fix that since this stub is rather large and we |
- // don't want many copies of it. |
- ASSERT(shift_distance_.is(r9)); |
- ASSERT(odd_number_.is(r4)); |
- ASSERT(mask_bits_.is(r3)); |
- ASSERT(scratch_.is(r5)); |
- } |
- |
- private: |
- Register result_; |
- Register shift_distance_; |
- Register odd_number_; |
- Register mask_bits_; |
- Register lhs_; |
- Register scratch_; |
- |
- // Minor key encoding in 16 bits. |
- class ResultRegisterBits: public BitField<int, 0, 4> {}; |
- class LhsRegisterBits: public BitField<int, 4, 4> {}; |
- |
- Major MajorKey() { return IntegerMod; } |
- int MinorKey() { |
- // Encode the parameters in a unique 16 bit value. |
- return ResultRegisterBits::encode(result_.code()) |
- | LhsRegisterBits::encode(lhs_.code()); |
- } |
- |
- void Generate(MacroAssembler* masm); |
- |
- const char* GetName() { return "IntegerModStub"; } |
- |
- // Utility functions. |
- void DigitSum(MacroAssembler* masm, |
- Register lhs, |
- int mask, |
- int shift, |
- Label* entry); |
- void DigitSum(MacroAssembler* masm, |
- Register lhs, |
- Register scratch, |
- int mask, |
- int shift1, |
- int shift2, |
- Label* entry); |
- void ModGetInRangeBySubtraction(MacroAssembler* masm, |
- Register lhs, |
- int shift, |
- int rhs); |
- void ModReduce(MacroAssembler* masm, |
- Register lhs, |
- int max, |
- int denominator); |
- void ModAnswer(MacroAssembler* masm, |
- Register result, |
- Register shift_distance, |
- Register mask_bits, |
- Register sum_of_digits); |
- |
- |
-#ifdef DEBUG |
- void Print() { PrintF("IntegerModStub\n"); } |
-#endif |
-}; |
- |
- |
// This stub can convert a signed int32 to a heap number (double). It does |
// not work for int32s that are in Smi range! No GC occurs during this stub |
// so you don't have to set up the frame. |