Index: src/arm/lithium-codegen-arm.cc |
=================================================================== |
--- src/arm/lithium-codegen-arm.cc (revision 6186) |
+++ src/arm/lithium-codegen-arm.cc (working copy) |
@@ -1583,7 +1583,22 @@ |
void LCodeGen::DoLoadElements(LLoadElements* instr) { |
- Abort("DoLoadElements unimplemented."); |
+ ASSERT(instr->result()->Equals(instr->input())); |
+ Register reg = ToRegister(instr->input()); |
+ |
+ __ ldr(reg, FieldMemOperand(reg, JSObject::kElementsOffset)); |
+ if (FLAG_debug_code) { |
+ Label done; |
Søren Thygesen Gjesse
2011/01/06 10:38:11
r9 -> scratch0()
Alexandre
2011/01/06 14:54:44
Done.
|
+ Register scratch = r9; |
+ __ ldr(scratch, FieldMemOperand(reg, HeapObject::kMapOffset)); |
+ __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex); |
+ __ cmp(scratch, ip); |
+ __ b(eq, &done); |
+ __ LoadRoot(ip, Heap::kFixedCOWArrayMapRootIndex); |
+ __ cmp(scratch, ip); |
+ __ Check(eq, "Check for fast elements failed."); |
+ __ bind(&done); |
+ } |
} |
@@ -1593,7 +1608,38 @@ |
void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { |
Søren Thygesen Gjesse
2011/01/06 10:38:11
r9 -> scratch0(), move
Register scratch = scratch
Alexandre
2011/01/06 14:54:44
Done.
|
- Abort("DoLoadKeyedFastElement unimplemented."); |
+ Register elements = ToRegister(instr->elements()); |
+ Register key = EmitLoadRegister(instr->key(), r9); |
+ Register result; |
+ Register scratch = r9; |
+ |
+ if (instr->load_result() != NULL) { |
+ result = ToRegister(instr->load_result()); |
+ } else { |
+ result = ToRegister(instr->result()); |
+ ASSERT(result.is(elements)); |
+ } |
+ |
+ // Load the result. |
+ __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); |
+ __ ldr(result, FieldMemOperand(scratch, FixedArray::kHeaderSize)); |
+ |
+ Representation r = instr->hydrogen()->representation(); |
+ if (r.IsInteger32()) { |
+ // Untag and check for smi. |
+ __ SmiUntag(result); |
+ DeoptimizeIf(cs, instr->environment()); |
+ } else if (r.IsDouble()) { |
+ EmitNumberUntagD(result, |
+ ToDoubleRegister(instr->result()), |
+ instr->environment()); |
+ } else { |
+ // Check for the hole value. |
+ ASSERT(r.IsTagged()); |
+ __ LoadRoot(scratch, Heap::kTheHoleValueRootIndex); |
+ __ cmp(result, scratch); |
+ DeoptimizeIf(eq, instr->environment()); |
+ } |
} |
@@ -1779,7 +1825,36 @@ |
void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
- Abort("DoStoreNamedField unimplemented."); |
+ Register object = ToRegister(instr->object()); |
+ Register value = ToRegister(instr->value()); |
+ Register scratch = r9; |
Søren Thygesen Gjesse
2011/01/06 10:38:11
r9 -> scratch0()
Alexandre
2011/01/06 14:54:44
Done.
|
+ int offset = instr->offset(); |
+ |
+ ASSERT(!object.is(value) && !scratch.is(object) && !scratch.is(value)); |
Søren Thygesen Gjesse
2011/01/06 10:38:11
Remove the scratch check part from the assert.
Alexandre
2011/01/06 14:54:44
Done.
|
+ |
+ if (!instr->transition().is_null()) { |
+ __ mov(scratch, Operand(instr->transition())); |
+ __ str(scratch, FieldMemOperand(object, HeapObject::kMapOffset)); |
+ } |
+ |
+ // Do the store. |
+ if (instr->is_in_object()) { |
+ __ str(value, FieldMemOperand(object, offset)); |
+ if (instr->needs_write_barrier()) { |
Søren Thygesen Gjesse
2011/01/06 10:38:11
I don't think we need a temp register on ARM, as w
Alexandre
2011/01/06 14:54:44
Removed.
On 2011/01/06 10:38:11, Søren Gjesse wrot
|
+ Register temp = ToRegister(instr->temp()); |
+ // Update the write barrier for the object for in-object properties. |
+ __ RecordWrite(object, Operand(offset), value, temp); |
+ } |
+ } else { |
+ Register temp = ToRegister(instr->temp()); |
+ __ ldr(temp, FieldMemOperand(object, JSObject::kPropertiesOffset)); |
+ __ str(value, FieldMemOperand(temp, offset)); |
+ if (instr->needs_write_barrier()) { |
+ // Update the write barrier for the properties array. |
+ // object is used as a scratch register. |
+ __ RecordWrite(temp, Operand(offset), value, object); |
+ } |
+ } |
} |
@@ -1801,7 +1876,29 @@ |
void LCodeGen::DoStoreKeyedFastElement(LStoreKeyedFastElement* instr) { |
- Abort("DoStoreKeyedFastElement unimplemented."); |
+ Register value = ToRegister(instr->value()); |
+ Register elements = ToRegister(instr->object()); |
+ Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg; |
Søren Thygesen Gjesse
2011/01/06 10:38:11
r9 -> scratch0()
Alexandre
2011/01/06 14:54:44
Done.
|
+ Register scratch = r9; |
+ |
+ // Do the store. |
+ if (instr->key()->IsConstantOperand()) { |
+ ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); |
+ LConstantOperand* const_operand = LConstantOperand::cast(instr->key()); |
+ int offset = |
+ ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize; |
+ __ str(value, FieldMemOperand(elements, offset)); |
+ } else { |
+ __ add(scratch, elements, Operand(key, LSL, kPointerSizeLog2)); |
+ __ str(value, FieldMemOperand(scratch, FixedArray::kHeaderSize)); |
+ } |
+ |
+ // Update the write barrier unless we're certain that we're storing a smi. |
Søren Thygesen Gjesse
2011/01/06 10:38:11
Please change comment to something like
// Update
Alexandre
2011/01/06 14:54:44
Removed the comment. The function's name speaks fo
|
+ if (instr->hydrogen()->NeedsWriteBarrier()) { |
+ // Compute address of modified element and store it into key register. |
+ __ add(key, scratch, Operand(FixedArray::kHeaderSize)); |
+ __ RecordWrite(elements, key, value); |
+ } |
} |