| Index: src/x64/lithium-codegen-x64.cc
|
| diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
|
| index af072fd18b8ac8b46ab21ea335d5779388b50588..e57f0eaf8d018c6e55c4e25fed8805776803d8d1 100644
|
| --- a/src/x64/lithium-codegen-x64.cc
|
| +++ b/src/x64/lithium-codegen-x64.cc
|
| @@ -2216,11 +2216,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);
|
| }
|
| }
|
| @@ -2271,14 +2276,47 @@ 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();
|
| + if (array_type == kExternalFloatArray) {
|
| + XMMRegister result(ToDoubleRegister(instr->result()));
|
| + __ movss(result, Operand(external_pointer, key, times_4, 0));
|
| + __ cvtss2sd(result, result);
|
| + } else {
|
| + Register result(ToRegister(instr->result()));
|
| + switch (array_type) {
|
| + case kExternalByteArray:
|
| + __ movsxbq(result, Operand(external_pointer, key, times_1, 0));
|
| + break;
|
| + case kExternalUnsignedByteArray:
|
| + case kExternalPixelArray:
|
| + __ movzxbq(result, Operand(external_pointer, key, times_1, 0));
|
| + break;
|
| + case kExternalShortArray:
|
| + __ movsxwq(result, Operand(external_pointer, key, times_2, 0));
|
| + break;
|
| + case kExternalUnsignedShortArray:
|
| + __ movzxwq(result, Operand(external_pointer, key, times_2, 0));
|
| + break;
|
| + case kExternalIntArray:
|
| + __ movsxlq(result, Operand(external_pointer, key, times_4, 0));
|
| + break;
|
| + case kExternalUnsignedIntArray:
|
| + __ 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:
|
| + UNREACHABLE();
|
| + break;
|
| + }
|
| + }
|
| }
|
|
|
|
|
| @@ -2892,21 +2930,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);
|
| + ExternalArrayType array_type = instr->array_type();
|
| + if (array_type == kExternalFloatArray) {
|
| + XMMRegister value(ToDoubleRegister(instr->value()));
|
| + __ cvtsd2ss(value, value);
|
| + __ movss(Operand(external_pointer, key, times_4, 0), value);
|
| + } else {
|
| + Register value(ToRegister(instr->value()));
|
| + switch (array_type) {
|
| + case kExternalPixelArray:
|
| + { // 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);
|
| + __ movb(Operand(external_pointer, key, times_1, 0), value);
|
| + }
|
| + break;
|
| + case kExternalByteArray:
|
| + case kExternalUnsignedByteArray:
|
| + __ movb(Operand(external_pointer, key, times_1, 0), value);
|
| + break;
|
| + case kExternalShortArray:
|
| + case kExternalUnsignedShortArray:
|
| + __ movw(Operand(external_pointer, key, times_2, 0), value);
|
| + break;
|
| + case kExternalIntArray:
|
| + case kExternalUnsignedIntArray:
|
| + __ movl(Operand(external_pointer, key, times_4, 0), value);
|
| + break;
|
| + case kExternalFloatArray:
|
| + UNREACHABLE();
|
| + break;
|
| + }
|
| }
|
| -
|
| - __ movb(Operand(external_pointer, key, times_1, 0), value);
|
| }
|
|
|
|
|
|
|