| Index: src/x64/lithium-codegen-x64.cc
|
| diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
|
| index 3745d16c3d4d698b5e5d1af2c99cb68f6e0f8b63..cdb23951b7383181b5997f1719a987ca0c2336ac 100644
|
| --- a/src/x64/lithium-codegen-x64.cc
|
| +++ b/src/x64/lithium-codegen-x64.cc
|
| @@ -2152,11 +2152,16 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) {
|
| Heap::kFixedArrayMapRootIndex);
|
| __ j(equal, &done);
|
| __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset),
|
| - Heap::kExternalPixelArrayMapRootIndex);
|
| - __ j(equal, &done);
|
| - __ CompareRoot(FieldOperand(result, HeapObject::kMapOffset),
|
| Heap::kFixedCOWArrayMapRootIndex);
|
| - __ Check(equal, "Check for fast elements failed.");
|
| + __ j(equal, &done);
|
| + Register temp((result.is(rax)) ? rbx : rax);
|
| + __ push(temp);
|
| + __ movq(temp, FieldOperand(result, HeapObject::kMapOffset));
|
| + __ movzxbq(temp, FieldOperand(temp, Map::kInstanceTypeOffset));
|
| + __ subq(temp, Immediate(FIRST_EXTERNAL_ARRAY_TYPE));
|
| + __ cmpq(temp, Immediate(kExternalArrayTypeCount));
|
| + __ pop(temp);
|
| + __ Check(below, "Check for fast elements failed.");
|
| __ bind(&done);
|
| }
|
| }
|
| @@ -2207,14 +2212,50 @@ void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
|
| }
|
|
|
|
|
| -void LCodeGen::DoLoadPixelArrayElement(LLoadPixelArrayElement* instr) {
|
| - Register external_elements = ToRegister(instr->external_pointer());
|
| +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_elements));
|
| -
|
| - // Load the result.
|
| - __ movzxbq(result, Operand(external_elements, key, times_1, 0));
|
| + ExternalArrayType array_type = instr->array_type();
|
| + switch (array_type) {
|
| + case kExternalByteArray:
|
| + __ movsxbq(ToRegister(instr->result()),
|
| + Operand(external_pointer, key, times_1, 0));
|
| + break;
|
| + case kExternalUnsignedByteArray:
|
| + case kExternalPixelArray:
|
| + __ movzxbq(ToRegister(instr->result()),
|
| + Operand(external_pointer, key, times_1, 0));
|
| + break;
|
| + case kExternalShortArray:
|
| + __ movsxwq(ToRegister(instr->result()),
|
| + Operand(external_pointer, key, times_2, 0));
|
| + break;
|
| + case kExternalUnsignedShortArray:
|
| + __ movzxwq(ToRegister(instr->result()),
|
| + Operand(external_pointer, key, times_2, 0));
|
| + break;
|
| + case kExternalIntArray:
|
| + __ movsxlq(ToRegister(instr->result()),
|
| + Operand(external_pointer, key, times_4, 0));
|
| + break;
|
| + case kExternalUnsignedIntArray: {
|
| + Register result(ToRegister(instr->result()));
|
| + __ movl(result, Operand(external_pointer, key, times_4, 0));
|
| + __ testl(result, result);
|
| + // 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(negative, instr->environment());
|
| + break;
|
| + }
|
| + case kExternalFloatArray: {
|
| + XMMRegister result(ToDoubleRegister(instr->result()));
|
| + __ movss(result, Operand(external_pointer, key, times_4, 0));
|
| + __ cvtss2sd(result, result);
|
| + break;
|
| + }
|
| + }
|
| }
|
|
|
|
|
| @@ -2828,21 +2869,46 @@ void LCodeGen::DoStoreNamedGeneric(LStoreNamedGeneric* 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());
|
|
|
| - { // Clamp the value to [0..255].
|
| - NearLabel done;
|
| - __ testl(value, Immediate(0xFFFFFF00));
|
| - __ j(zero, &done);
|
| - __ setcc(negative, value); // 1 if negative, 0 if positive.
|
| - __ decb(value); // 0 if negative, 255 if positive.
|
| - __ bind(&done);
|
| + switch (instr->array_type()) {
|
| + case kExternalPixelArray:
|
| + { // Clamp the value to [0..255].
|
| + NearLabel done;
|
| + Register value(ToRegister(instr->value()));
|
| + __ testl(value, Immediate(0xFFFFFF00));
|
| + __ j(zero, &done);
|
| + __ setcc(negative, value); // 1 if negative, 0 if positive.
|
| + __ decb(value); // 0 if negative, 255 if positive.
|
| + __ bind(&done);
|
| + __ movb(Operand(external_pointer, key, times_1, 0), value);
|
| + }
|
| + break;
|
| + case kExternalByteArray:
|
| + case kExternalUnsignedByteArray:
|
| + __ movb(Operand(external_pointer, key, times_1, 0),
|
| + ToRegister(instr->value()));
|
| + break;
|
| + case kExternalShortArray:
|
| + case kExternalUnsignedShortArray:
|
| + __ movw(Operand(external_pointer, key, times_2, 0),
|
| + ToRegister(instr->value()));
|
| + break;
|
| + case kExternalIntArray:
|
| + case kExternalUnsignedIntArray:
|
| + __ movl(Operand(external_pointer, key, times_4, 0),
|
| + ToRegister(instr->value()));
|
| + break;
|
| + case kExternalFloatArray: {
|
| + XMMRegister value(ToDoubleRegister(instr->value()));
|
| + __ cvtsd2ss(value, value);
|
| + __ movss(Operand(external_pointer, key, times_4, 0), value);
|
| + break;
|
| + }
|
| }
|
| -
|
| - __ movb(Operand(external_pointer, key, times_1, 0), value);
|
| }
|
|
|
|
|
|
|