Chromium Code Reviews| Index: src/ia32/lithium-ia32.cc |
| diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc |
| index a4b1b865451ec91c3b75332f64ab35f4523e4545..b7e6feb5dcd962dd8a0f72608c211327827d1905 100644 |
| --- a/src/ia32/lithium-ia32.cc |
| +++ b/src/ia32/lithium-ia32.cc |
| @@ -91,6 +91,11 @@ void LInstruction::VerifyCall() { |
| #endif |
| +bool LInstruction::HasDoubleRegisterResult() { |
| + return HasResult() && result()->IsDoubleRegister(); |
| +} |
| + |
| + |
| void LInstruction::PrintTo(StringStream* stream) { |
| stream->Add("%s ", this->Mnemonic()); |
| @@ -542,6 +547,11 @@ LOperand* LChunkBuilder::UseFixedDouble(HValue* value, XMMRegister reg) { |
| } |
| +LOperand* LChunkBuilder::UseX87TopOfStack(HValue* value) { |
| + return Use(value, ToUnallocated(x87tos)); |
| +} |
| + |
| + |
| LOperand* LChunkBuilder::UseRegister(HValue* value) { |
| return Use(value, new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER)); |
| } |
| @@ -1861,20 +1871,33 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { |
| ? TempRegister() |
| : NULL; |
| LNumberUntagD* res = new(zone()) LNumberUntagD(value, temp); |
| - return AssignEnvironment(DefineAsRegister(res)); |
| + if (CpuFeatures::IsSafeForSnapshot(SSE2)) { |
| + return AssignEnvironment(DefineAsRegister(res)); |
| + } else { |
| + return AssignEnvironment(DefineX87TOS(res)); |
| + } |
| } else { |
| ASSERT(to.IsInteger32()); |
| - LOperand* value = UseRegister(instr->value()); |
| if (instr->value()->type().IsSmi()) { |
| + LOperand* value = UseRegister(instr->value()); |
| return DefineSameAsFirst(new(zone()) LSmiUntag(value, false)); |
| } else { |
| bool truncating = instr->CanTruncateToInt32(); |
| - LOperand* xmm_temp = |
| - (truncating && CpuFeatures::IsSupported(SSE3)) |
| - ? NULL |
| - : FixedTemp(xmm1); |
| - LTaggedToI* res = new(zone()) LTaggedToI(value, xmm_temp); |
| - return AssignEnvironment(DefineSameAsFirst(res)); |
| + if (CpuFeatures::IsSafeForSnapshot(SSE2)) { |
| + LOperand* value = UseRegister(instr->value()); |
| + LOperand* xmm_temp = |
| + (truncating && CpuFeatures::IsSupported(SSE3)) |
| + ? NULL |
| + : FixedTemp(xmm1); |
| + LTaggedToI* res = new(zone()) LTaggedToI(value, xmm_temp); |
| + return AssignEnvironment(DefineSameAsFirst(res)); |
| + } else { |
| + LOperand* value = UseFixed(instr->value(), ecx); |
| + LTaggedToINoSSE2* res = |
| + new(zone()) LTaggedToINoSSE2(value, TempRegister(), |
| + TempRegister(), TempRegister()); |
| + return AssignEnvironment(DefineFixed(res, ecx)); |
| + } |
| } |
| } |
| } else if (from.IsDouble()) { |
| @@ -1992,12 +2015,20 @@ LInstruction* LChunkBuilder::DoClampToUint8(HClampToUint8* instr) { |
| return DefineFixed(new(zone()) LClampIToUint8(reg), eax); |
| } else { |
| ASSERT(input_rep.IsTagged()); |
| - LOperand* reg = UseFixed(value, eax); |
| - // Register allocator doesn't (yet) support allocation of double |
| - // temps. Reserve xmm1 explicitly. |
| - LOperand* temp = FixedTemp(xmm1); |
| - LClampTToUint8* result = new(zone()) LClampTToUint8(reg, temp); |
| - return AssignEnvironment(DefineFixed(result, eax)); |
| + if (CpuFeatures::IsSupported(SSE2)) { |
| + LOperand* reg = UseFixed(value, eax); |
| + // Register allocator doesn't (yet) support allocation of double |
| + // temps. Reserve xmm1 explicitly. |
| + LOperand* temp = FixedTemp(xmm1); |
| + LClampTToUint8* result = new(zone()) LClampTToUint8(reg, temp); |
| + return AssignEnvironment(DefineFixed(result, eax)); |
| + } else { |
| + LOperand* value = UseRegister(instr->value()); |
| + LClampTToUint8NoSSE2* res = |
| + new(zone()) LClampTToUint8NoSSE2(value, TempRegister(), |
| + TempRegister(), TempRegister()); |
| + return AssignEnvironment(DefineFixed(res, ecx)); |
| + } |
| } |
| } |
| @@ -2018,10 +2049,13 @@ LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { |
| return DefineAsRegister(new(zone()) LConstantI); |
| } else if (r.IsDouble()) { |
| double value = instr->DoubleValue(); |
| - LOperand* temp = (BitCast<uint64_t, double>(value) != 0) |
| - ? TempRegister() |
| - : NULL; |
| - return DefineAsRegister(new(zone()) LConstantD(temp)); |
| + bool value_is_zero = BitCast<uint64_t, double>(value) == 0; |
| + if (CpuFeatures::IsSafeForSnapshot(SSE2)) { |
| + LOperand* temp = value_is_zero ? NULL : TempRegister(); |
| + return DefineAsRegister(new(zone()) LConstantD(temp)); |
| + } else { |
| + return DefineX87TOS(new(zone()) LConstantD(NULL)); |
| + } |
| } else if (r.IsTagged()) { |
| return DefineAsRegister(new(zone()) LConstantT); |
| } else { |
| @@ -2190,6 +2224,27 @@ LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { |
| } |
| +LOperand* LChunkBuilder::GetStoreKeyedValueOperand(HStoreKeyed* instr) { |
|
danno
2013/04/08 12:57:27
Is this change related?
mvstanton
2013/04/08 16:10:14
Nope, removed
|
| + ElementsKind elements_kind = instr->elements_kind(); |
| + |
| + // Determine if we need a byte register in this case for the value. |
| + bool val_is_fixed_register = |
| + elements_kind == EXTERNAL_BYTE_ELEMENTS || |
| + elements_kind == EXTERNAL_UNSIGNED_BYTE_ELEMENTS || |
| + elements_kind == EXTERNAL_PIXEL_ELEMENTS; |
| + if (val_is_fixed_register) { |
| + return UseFixed(instr->value(), eax); |
| + } |
| + |
| + if (!CpuFeatures::IsSafeForSnapshot(SSE2) && |
| + IsDoubleOrFloatElementsKind(elements_kind)) { |
| + return UseRegisterAtStart(instr->value()); |
| + } |
| + |
| + return UseRegister(instr->value()); |
| +} |
| + |
| + |
| LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { |
| if (!instr->is_external()) { |
| ASSERT(instr->elements()->representation().IsTagged()); |
| @@ -2198,21 +2253,30 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { |
| if (instr->value()->representation().IsDouble()) { |
| LOperand* object = UseRegisterAtStart(instr->elements()); |
| - LOperand* val = UseTempRegister(instr->value()); |
| + LOperand* val = NULL; |
| + if (CpuFeatures::IsSafeForSnapshot(SSE2)) { |
| + val = UseRegisterAtStart(instr->value()); |
| + } else { |
| + if (!instr->IsConstantHoleStore()) { |
| + val = UseX87TopOfStack(instr->value()); |
| + } |
| + } |
| LOperand* key = UseRegisterOrConstantAtStart(instr->key()); |
| - |
| return new(zone()) LStoreKeyed(object, key, val); |
| } else { |
| ASSERT(instr->value()->representation().IsTagged()); |
| bool needs_write_barrier = instr->NeedsWriteBarrier(); |
| LOperand* obj = UseRegister(instr->elements()); |
| - LOperand* val = needs_write_barrier |
| - ? UseTempRegister(instr->value()) |
| - : UseRegisterAtStart(instr->value()); |
| - LOperand* key = needs_write_barrier |
| - ? UseTempRegister(instr->key()) |
| - : UseRegisterOrConstantAtStart(instr->key()); |
| + LOperand* val; |
| + LOperand* key; |
| + if (needs_write_barrier) { |
| + val = UseTempRegister(instr->value()); |
|
mvstanton
2013/04/08 16:10:14
This change is unrelated, removing.
|
| + key = UseTempRegister(instr->key()); |
| + } else { |
| + val = UseRegisterOrConstantAtStart(instr->value()); |
| + key = UseRegisterOrConstantAtStart(instr->key()); |
| + } |
| return new(zone()) LStoreKeyed(obj, key, val); |
| } |
| } |
| @@ -2228,15 +2292,7 @@ LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { |
| ASSERT(instr->elements()->representation().IsExternal()); |
| LOperand* external_pointer = UseRegister(instr->elements()); |
| - // Determine if we need a byte register in this case for the value. |
| - bool val_is_fixed_register = |
| - elements_kind == EXTERNAL_BYTE_ELEMENTS || |
| - elements_kind == EXTERNAL_UNSIGNED_BYTE_ELEMENTS || |
| - elements_kind == EXTERNAL_PIXEL_ELEMENTS; |
| - |
| - LOperand* val = val_is_fixed_register |
| - ? UseFixed(instr->value(), eax) |
| - : UseRegister(instr->value()); |
| + LOperand* val = GetStoreKeyedValueOperand(instr); |
| bool clobbers_key = ExternalArrayOpRequiresTemp( |
| instr->key()->representation(), elements_kind); |
| LOperand* key = clobbers_key |
| @@ -2322,7 +2378,7 @@ LInstruction* LChunkBuilder::DoStoreNamedField(HStoreNamedField* instr) { |
| LOperand* val = needs_write_barrier |
| ? UseTempRegister(instr->value()) |
| - : UseRegister(instr->value()); |
| + : UseRegisterOrConstant(instr->value()); |
|
danno
2013/04/08 12:57:27
Is this change related?
mvstanton
2013/04/08 16:10:14
Nope, removed.
|
| // We only need a scratch register if we have a write barrier or we |
| // have a store into the properties array (not in-object-property). |
| @@ -2461,7 +2517,12 @@ LInstruction* LChunkBuilder::DoParameter(HParameter* instr) { |
| ASSERT(info()->IsStub()); |
| CodeStubInterfaceDescriptor* descriptor = |
| info()->code_stub()->GetInterfaceDescriptor(info()->isolate()); |
| - Register reg = descriptor->register_params_[instr->index()]; |
| + Register reg; |
|
danno
2013/04/08 12:57:27
unrelated change?
mvstanton
2013/04/08 16:10:14
Yep, removed
|
| + if (static_cast<int>(instr->index()) == descriptor->register_param_count_) { |
| + reg = *(descriptor->stack_parameter_count_); |
| + } else { |
| + reg = descriptor->register_params_[instr->index()]; |
| + } |
| return DefineFixed(result, reg); |
| } |
| } |
| @@ -2496,8 +2557,15 @@ LInstruction* LChunkBuilder::DoArgumentsObject(HArgumentsObject* instr) { |
| LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) { |
| LOperand* args = UseRegister(instr->arguments()); |
| - LOperand* length = UseTempRegister(instr->length()); |
| - LOperand* index = Use(instr->index()); |
| + LOperand* length; |
|
danno
2013/04/08 12:57:27
unrelated change?
mvstanton
2013/04/08 16:10:14
Indeed, thx.
|
| + LOperand* index; |
| + if (instr->length()->IsConstant() && instr->index()->IsConstant()) { |
| + length = UseRegisterOrConstant(instr->length()); |
| + index = UseOrConstant(instr->index()); |
| + } else { |
| + length = UseTempRegister(instr->length()); |
| + index = Use(instr->index()); |
| + } |
| return DefineAsRegister(new(zone()) LAccessArgumentsAt(args, length, index)); |
| } |