Index: src/codegen-arm.cc |
=================================================================== |
--- src/codegen-arm.cc (revision 1734) |
+++ src/codegen-arm.cc (working copy) |
@@ -654,28 +654,6 @@ |
} |
-class GetPropertyStub : public CodeStub { |
- public: |
- GetPropertyStub() { } |
- |
- private: |
- Major MajorKey() { return GetProperty; } |
- int MinorKey() { return 0; } |
- void Generate(MacroAssembler* masm); |
-}; |
- |
- |
-class SetPropertyStub : public CodeStub { |
- public: |
- SetPropertyStub() { } |
- |
- private: |
- Major MajorKey() { return SetProperty; } |
- int MinorKey() { return 0; } |
- void Generate(MacroAssembler* masm); |
-}; |
- |
- |
class GenericBinaryOpStub : public CodeStub { |
public: |
GenericBinaryOpStub(Token::Value op, |
@@ -4355,170 +4333,6 @@ |
} |
-void GetPropertyStub::Generate(MacroAssembler* masm) { |
- // sp[0]: key |
- // sp[1]: receiver |
- Label slow, fast; |
- // Get the key and receiver object from the stack. |
- __ ldm(ia, sp, r0.bit() | r1.bit()); |
- // Check that the key is a smi. |
- __ tst(r0, Operand(kSmiTagMask)); |
- __ b(ne, &slow); |
- __ mov(r0, Operand(r0, ASR, kSmiTagSize)); |
- // Check that the object isn't a smi. |
- __ tst(r1, Operand(kSmiTagMask)); |
- __ b(eq, &slow); |
- |
- // Check that the object is some kind of JS object EXCEPT JS Value type. |
- // In the case that the object is a value-wrapper object, |
- // we enter the runtime system to make sure that indexing into string |
- // objects work as intended. |
- ASSERT(JS_OBJECT_TYPE > JS_VALUE_TYPE); |
- __ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); |
- __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); |
- __ cmp(r2, Operand(JS_OBJECT_TYPE)); |
- __ b(lt, &slow); |
- |
- // Get the elements array of the object. |
- __ ldr(r1, FieldMemOperand(r1, JSObject::kElementsOffset)); |
- // Check that the object is in fast mode (not dictionary). |
- __ ldr(r3, FieldMemOperand(r1, HeapObject::kMapOffset)); |
- __ cmp(r3, Operand(Factory::hash_table_map())); |
- __ b(eq, &slow); |
- // Check that the key (index) is within bounds. |
- __ ldr(r3, FieldMemOperand(r1, Array::kLengthOffset)); |
- __ cmp(r0, Operand(r3)); |
- __ b(lo, &fast); |
- |
- // Slow case: Push extra copies of the arguments (2). |
- __ bind(&slow); |
- __ ldm(ia, sp, r0.bit() | r1.bit()); |
- __ stm(db_w, sp, r0.bit() | r1.bit()); |
- // Do tail-call to runtime routine. |
- __ TailCallRuntime(ExternalReference(Runtime::kGetProperty), 2); |
- |
- // Fast case: Do the load. |
- __ bind(&fast); |
- __ add(r3, r1, Operand(Array::kHeaderSize - kHeapObjectTag)); |
- __ ldr(r0, MemOperand(r3, r0, LSL, kPointerSizeLog2)); |
- __ cmp(r0, Operand(Factory::the_hole_value())); |
- // In case the loaded value is the_hole we have to consult GetProperty |
- // to ensure the prototype chain is searched. |
- __ b(eq, &slow); |
- |
- __ StubReturn(1); |
-} |
- |
- |
-void SetPropertyStub::Generate(MacroAssembler* masm) { |
- // r0 : value |
- // sp[0] : key |
- // sp[1] : receiver |
- |
- Label slow, fast, array, extra, exit; |
- // Get the key and the object from the stack. |
- __ ldm(ia, sp, r1.bit() | r3.bit()); // r1 = key, r3 = receiver |
- // Check that the key is a smi. |
- __ tst(r1, Operand(kSmiTagMask)); |
- __ b(ne, &slow); |
- // Check that the object isn't a smi. |
- __ tst(r3, Operand(kSmiTagMask)); |
- __ b(eq, &slow); |
- // Get the type of the object from its map. |
- __ ldr(r2, FieldMemOperand(r3, HeapObject::kMapOffset)); |
- __ ldrb(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset)); |
- // Check if the object is a JS array or not. |
- __ cmp(r2, Operand(JS_ARRAY_TYPE)); |
- __ b(eq, &array); |
- // Check that the object is some kind of JS object. |
- __ cmp(r2, Operand(FIRST_JS_OBJECT_TYPE)); |
- __ b(lt, &slow); |
- |
- |
- // Object case: Check key against length in the elements array. |
- __ ldr(r3, FieldMemOperand(r3, JSObject::kElementsOffset)); |
- // Check that the object is in fast mode (not dictionary). |
- __ ldr(r2, FieldMemOperand(r3, HeapObject::kMapOffset)); |
- __ cmp(r2, Operand(Factory::hash_table_map())); |
- __ b(eq, &slow); |
- // Untag the key (for checking against untagged length in the fixed array). |
- __ mov(r1, Operand(r1, ASR, kSmiTagSize)); |
- // Compute address to store into and check array bounds. |
- __ add(r2, r3, Operand(Array::kHeaderSize - kHeapObjectTag)); |
- __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2)); |
- __ ldr(ip, FieldMemOperand(r3, Array::kLengthOffset)); |
- __ cmp(r1, Operand(ip)); |
- __ b(lo, &fast); |
- |
- |
- // Slow case: Push extra copies of the arguments (3). |
- __ bind(&slow); |
- __ ldm(ia, sp, r1.bit() | r3.bit()); // r0 == value, r1 == key, r3 == object |
- __ stm(db_w, sp, r0.bit() | r1.bit() | r3.bit()); |
- // Do tail-call to runtime routine. |
- __ TailCallRuntime(ExternalReference(Runtime::kSetProperty), 3); |
- |
- |
- // Extra capacity case: Check if there is extra capacity to |
- // perform the store and update the length. Used for adding one |
- // element to the array by writing to array[array.length]. |
- // r0 == value, r1 == key, r2 == elements, r3 == object |
- __ bind(&extra); |
- __ b(ne, &slow); // do not leave holes in the array |
- __ mov(r1, Operand(r1, ASR, kSmiTagSize)); // untag |
- __ ldr(ip, FieldMemOperand(r2, Array::kLengthOffset)); |
- __ cmp(r1, Operand(ip)); |
- __ b(hs, &slow); |
- __ mov(r1, Operand(r1, LSL, kSmiTagSize)); // restore tag |
- __ add(r1, r1, Operand(1 << kSmiTagSize)); // and increment |
- __ str(r1, FieldMemOperand(r3, JSArray::kLengthOffset)); |
- __ mov(r3, Operand(r2)); |
- // NOTE: Computing the address to store into must take the fact |
- // that the key has been incremented into account. |
- int displacement = Array::kHeaderSize - kHeapObjectTag - |
- ((1 << kSmiTagSize) * 2); |
- __ add(r2, r2, Operand(displacement)); |
- __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize)); |
- __ b(&fast); |
- |
- |
- // Array case: Get the length and the elements array from the JS |
- // array. Check that the array is in fast mode; if it is the |
- // length is always a smi. |
- // r0 == value, r3 == object |
- __ bind(&array); |
- __ ldr(r2, FieldMemOperand(r3, JSObject::kElementsOffset)); |
- __ ldr(r1, FieldMemOperand(r2, HeapObject::kMapOffset)); |
- __ cmp(r1, Operand(Factory::hash_table_map())); |
- __ b(eq, &slow); |
- |
- // Check the key against the length in the array, compute the |
- // address to store into and fall through to fast case. |
- __ ldr(r1, MemOperand(sp)); |
- // r0 == value, r1 == key, r2 == elements, r3 == object. |
- __ ldr(ip, FieldMemOperand(r3, JSArray::kLengthOffset)); |
- __ cmp(r1, Operand(ip)); |
- __ b(hs, &extra); |
- __ mov(r3, Operand(r2)); |
- __ add(r2, r2, Operand(Array::kHeaderSize - kHeapObjectTag)); |
- __ add(r2, r2, Operand(r1, LSL, kPointerSizeLog2 - kSmiTagSize)); |
- |
- |
- // Fast case: Do the store. |
- // r0 == value, r2 == address to store into, r3 == elements |
- __ bind(&fast); |
- __ str(r0, MemOperand(r2)); |
- // Skip write barrier if the written value is a smi. |
- __ tst(r0, Operand(kSmiTagMask)); |
- __ b(eq, &exit); |
- // Update write barrier for the elements array address. |
- __ sub(r1, r2, Operand(r3)); |
- __ RecordWrite(r3, r1, r2); |
- __ bind(&exit); |
- __ StubReturn(1); |
-} |
- |
- |
static void HandleBinaryOpSlowCases(MacroAssembler* masm, |
Label* not_smi, |
const Builtins::JavaScript& builtin, |
@@ -4578,8 +4392,17 @@ |
#endif |
// Store answer in the overwritable heap number. |
__ pop(r4); |
+#if !defined(__ARM_EABI__) && defined(__arm__) |
+ // Double returned in fp coprocessor register 0 and 1, encoded as register |
+ // cr8. Offsets must be divisible by 4 for coprocessor so we need to |
+ // substract the tag from r4. |
+ __ sub(r5, r4, Operand(kHeapObjectTag)); |
+ __ stc(p1, cr8, MemOperand(r5, HeapNumber::kValueOffset)); |
+#else |
+ // Double returned in fp coprocessor register 0 and 1. |
__ str(r0, FieldMemOperand(r4, HeapNumber::kValueOffset)); |
__ str(r1, FieldMemOperand(r4, HeapNumber::kValueOffset + kPointerSize)); |
+#endif |
__ mov(r0, Operand(r4)); |
// And we are done. |
__ pop(pc); |