Chromium Code Reviews| Index: src/ia32/lithium-codegen-ia32.cc |
| diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc |
| index a3c0990e676089f3d6a4c266508c16dbd34f9469..4302f2636d42d44279fdcadc2b72cacd75e37f75 100644 |
| --- a/src/ia32/lithium-codegen-ia32.cc |
| +++ b/src/ia32/lithium-codegen-ia32.cc |
| @@ -2183,11 +2183,16 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) { |
| Immediate(factory()->fixed_array_map())); |
| __ j(equal, &done); |
| __ cmp(FieldOperand(result, HeapObject::kMapOffset), |
| - Immediate(factory()->external_pixel_array_map())); |
| - __ j(equal, &done); |
| - __ cmp(FieldOperand(result, HeapObject::kMapOffset), |
| Immediate(factory()->fixed_cow_array_map())); |
| - __ Check(equal, "Check for fast elements or pixel array failed."); |
| + __ j(equal, &done); |
| + Register temp((result.is(eax)) ? ebx : eax); |
|
Mads Ager (chromium)
2011/03/24 11:31:20
Does it hurt anything to just let the register all
danno
2011/03/24 13:18:38
Since this is only for debug code to verify/assert
fschneider
2011/03/24 13:26:11
No worry :) It's only when FLAG_debug_code is on.
|
| + __ push(temp); |
| + __ mov(temp, FieldOperand(result, HeapObject::kMapOffset)); |
| + __ movzx_b(temp, FieldOperand(temp, Map::kInstanceTypeOffset)); |
| + __ sub(Operand(temp), Immediate(FIRST_EXTERNAL_ARRAY_TYPE)); |
| + __ cmp(Operand(temp), Immediate(kExternalArrayTypeCount)); |
| + __ pop(temp); |
| + __ Check(below, "Check for fast elements or pixel array failed."); |
| __ bind(&done); |
| } |
| } |
| @@ -2235,14 +2240,50 @@ void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { |
| } |
| -void LCodeGen::DoLoadPixelArrayElement(LLoadPixelArrayElement* instr) { |
| +void LCodeGen::DoLoadKeyedSpecializedArrayElement( |
| + LLoadKeyedSpecializedArrayElement* instr) { |
| Register external_pointer = ToRegister(instr->external_pointer()); |
| Register key = ToRegister(instr->key()); |
| - Register result = ToRegister(instr->result()); |
| - ASSERT(result.is(external_pointer)); |
| - |
| - // Load the result. |
| - __ movzx_b(result, Operand(external_pointer, key, times_1, 0)); |
| + ExternalArrayType array_type = instr->array_type(); |
| + switch (array_type) { |
| + case kExternalByteArray: |
| + __ movsx_b(ToRegister(instr->result()), |
|
Kevin Millikin (Chromium)
2011/03/24 11:21:00
I think if you named ToRegister(instr->result()) w
danno
2011/03/24 13:18:38
The problem is that the ToRegister asserts in the
Kevin Millikin (Chromium)
2011/03/24 13:29:40
I didn't think of the ToDoubleRegister case. You
|
| + Operand(external_pointer, key, times_1, 0)); |
| + break; |
| + case kExternalUnsignedByteArray: |
| + case kExternalPixelArray: |
| + __ movzx_b(ToRegister(instr->result()), |
| + Operand(external_pointer, key, times_1, 0)); |
| + break; |
| + case kExternalShortArray: |
| + __ movsx_w(ToRegister(instr->result()), |
| + Operand(external_pointer, key, times_2, 0)); |
| + break; |
| + case kExternalUnsignedShortArray: |
| + __ movzx_w(ToRegister(instr->result()), |
| + Operand(external_pointer, key, times_2, 0)); |
| + break; |
| + case kExternalIntArray: |
| + __ mov(ToRegister(instr->result()), |
| + Operand(external_pointer, key, times_4, 0)); |
| + break; |
| + case kExternalUnsignedIntArray: { |
| + Register result(ToRegister(instr->result())); |
|
Kevin Millikin (Chromium)
2011/03/24 11:21:00
Indentation looks off a bit.
danno
2011/03/24 13:18:38
Not sure what you mean, I introduced a separate sc
Kevin Millikin (Chromium)
2011/03/24 13:29:40
"Register" looks indented by 3 (lines up with the
|
| + __ mov(result, Operand(external_pointer, key, times_4, 0)); |
| + __ cmp(Operand(result), Immediate(0x80000000)); |
|
Kevin Millikin (Chromium)
2011/03/24 11:21:00
Alternatively (seems more idiomatic to me for some
danno
2011/03/24 13:18:38
Done.
Lasse Reichstein
2011/03/24 22:09:02
Or use:
__ test(result, Operand(result));
Deop
|
| + // TODO(danno): we could be more clever here, perhaps having a special |
| + // version of the stub that detects if the overflow case actually happens, |
| + // and generate code that returns a double rather than int. |
| + DeoptimizeIf(above_equal, instr->environment()); |
| + break; |
| + } |
| + case kExternalFloatArray: { |
| + XMMRegister result(ToDoubleRegister(instr->result())); |
| + __ movss(result, Operand(external_pointer, key, times_4, 0)); |
| + __ cvtss2sd(result, result); |
| + break; |
| + } |
| + } |
| } |
| @@ -2867,22 +2908,47 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { |
| } |
| -void LCodeGen::DoStorePixelArrayElement(LStorePixelArrayElement* instr) { |
| +void LCodeGen::DoStoreKeyedSpecializedArrayElement( |
| + LStoreKeyedSpecializedArrayElement* instr) { |
| Register external_pointer = ToRegister(instr->external_pointer()); |
| Register key = ToRegister(instr->key()); |
| - Register value = ToRegister(instr->value()); |
| - ASSERT(ToRegister(instr->TempAt(0)).is(eax)); |
| - __ mov(eax, value); |
| - { // Clamp the value to [0..255]. |
| - NearLabel done; |
| - __ test(eax, Immediate(0xFFFFFF00)); |
| - __ j(zero, &done); |
| - __ setcc(negative, eax); // 1 if negative, 0 if positive. |
| - __ dec_b(eax); // 0 if negative, 255 if positive. |
| - __ bind(&done); |
| + switch (instr->array_type()) { |
| + case kExternalPixelArray: |
| + { // Clamp the value to [0..255]. |
| + ASSERT(ToRegister(instr->TempAt(0)).is(eax)); |
|
Mads Ager (chromium)
2011/03/24 11:31:20
Instead of having this assert, let's just do
Regi
danno
2011/03/24 13:18:38
Actually, I think this assert it important, since
|
| + __ mov(eax, ToRegister(instr->value())); |
| + NearLabel done; |
| + __ test(eax, Immediate(0xFFFFFF00)); |
| + __ j(zero, &done); |
| + __ setcc(negative, eax); // 1 if negative, 0 if positive. |
| + __ dec_b(eax); // 0 if negative, 255 if positive. |
| + __ bind(&done); |
| + __ mov_b(Operand(external_pointer, key, times_1, 0), eax); |
| + } |
| + break; |
| + case kExternalByteArray: |
| + case kExternalUnsignedByteArray: |
| + __ mov_b(Operand(external_pointer, key, times_1, 0), |
| + ToRegister(instr->value())); |
| + break; |
| + case kExternalShortArray: |
| + case kExternalUnsignedShortArray: |
| + __ mov_w(Operand(external_pointer, key, times_2, 0), |
| + ToRegister(instr->value())); |
| + break; |
| + case kExternalIntArray: |
| + case kExternalUnsignedIntArray: |
| + __ mov(Operand(external_pointer, key, times_4, 0), |
| + ToRegister(instr->value())); |
| + break; |
| + case kExternalFloatArray: { |
| + XMMRegister temp(ToDoubleRegister(instr->TempAt(0))); |
| + __ cvtsd2ss(temp, ToDoubleRegister(instr->value())); |
| + __ movss(Operand(external_pointer, key, times_4, 0), temp); |
| + break; |
| + } |
| } |
| - __ mov_b(Operand(external_pointer, key, times_1, 0), eax); |
| } |