Index: src/arm/codegen-arm.h |
=================================================================== |
--- src/arm/codegen-arm.h (revision 4950) |
+++ src/arm/codegen-arm.h (working copy) |
@@ -881,6 +881,74 @@ |
}; |
+// 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"; } |
+ |
+#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. |