Index: src/ia32/lithium-codegen-ia32.cc |
=================================================================== |
--- src/ia32/lithium-codegen-ia32.cc (revision 6703) |
+++ src/ia32/lithium-codegen-ia32.cc (working copy) |
@@ -804,7 +804,7 @@ |
__ test(left, Operand(left)); |
__ j(not_zero, &done); |
if (right->IsConstantOperand()) { |
- if (ToInteger32(LConstantOperand::cast(right)) < 0) { |
+ if (ToInteger32(LConstantOperand::cast(right)) <= 0) { |
DeoptimizeIf(no_condition, instr->environment()); |
} |
} else { |
@@ -945,19 +945,31 @@ |
if (BitCast<uint64_t, double>(v) == 0) { |
__ xorpd(res, res); |
} else { |
- int32_t v_int32 = static_cast<int32_t>(v); |
- if (static_cast<double>(v_int32) == v) { |
- __ push_imm32(v_int32); |
- __ cvtsi2sd(res, Operand(esp, 0)); |
- __ add(Operand(esp), Immediate(kPointerSize)); |
+ Register temp = ToRegister(instr->TempAt(0)); |
+ uint64_t int_val = BitCast<uint64_t, double>(v); |
+ int32_t lower = static_cast<int32_t>(int_val); |
+ int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); |
+ if (CpuFeatures::IsSupported(SSE4_1)) { |
+ CpuFeatures::Scope scope(SSE4_1); |
+ if (lower != 0) { |
+ __ Set(temp, Immediate(lower)); |
+ __ movd(res, Operand(temp)); |
+ __ Set(temp, Immediate(upper)); |
+ __ pinsrd(res, Operand(temp), 1); |
+ } else { |
+ __ xorpd(res, res); |
+ __ Set(temp, Immediate(upper)); |
+ __ pinsrd(res, Operand(temp), 1); |
+ } |
} else { |
- uint64_t int_val = BitCast<uint64_t, double>(v); |
- int32_t lower = static_cast<int32_t>(int_val); |
- int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); |
- __ push_imm32(upper); |
- __ push_imm32(lower); |
- __ movdbl(res, Operand(esp, 0)); |
- __ add(Operand(esp), Immediate(2 * kPointerSize)); |
+ __ Set(temp, Immediate(upper)); |
+ __ movd(res, Operand(temp)); |
+ __ psllq(res, 32); |
+ if (lower != 0) { |
+ __ Set(temp, Immediate(lower)); |
+ __ movd(xmm0, Operand(temp)); |
+ __ por(res, xmm0); |
+ } |
} |
} |
} |
@@ -1881,7 +1893,7 @@ |
} |
__ mov(esp, ebp); |
__ pop(ebp); |
- __ ret((ParameterCount() + 1) * kPointerSize); |
+ __ Ret((ParameterCount() + 1) * kPointerSize, ecx); |
} |
@@ -2035,7 +2047,10 @@ |
ASSERT(result.is(elements)); |
// Load the result. |
- __ mov(result, FieldOperand(elements, key, times_4, FixedArray::kHeaderSize)); |
+ __ mov(result, FieldOperand(elements, |
+ key, |
+ times_pointer_size, |
+ FixedArray::kHeaderSize)); |
// Check for the hole value. |
__ cmp(result, Factory::the_hole_value()); |
@@ -2661,13 +2676,20 @@ |
ToInteger32(const_operand) * kPointerSize + FixedArray::kHeaderSize; |
__ mov(FieldOperand(elements, offset), value); |
} else { |
- __ mov(FieldOperand(elements, key, times_4, FixedArray::kHeaderSize), |
+ __ mov(FieldOperand(elements, |
+ key, |
+ times_pointer_size, |
+ FixedArray::kHeaderSize), |
value); |
} |
if (instr->hydrogen()->NeedsWriteBarrier()) { |
// Compute address of modified element and store it into key register. |
- __ lea(key, FieldOperand(elements, key, times_4, FixedArray::kHeaderSize)); |
+ __ lea(key, |
+ FieldOperand(elements, |
+ key, |
+ times_pointer_size, |
+ FixedArray::kHeaderSize)); |
__ RecordWrite(elements, key, value); |
} |
} |
@@ -3577,6 +3599,53 @@ |
} |
+void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) { |
+ Register result = ToRegister(instr->result()); |
+ NearLabel true_label; |
+ NearLabel false_label; |
+ NearLabel done; |
+ |
+ EmitIsConstructCall(result); |
+ __ j(equal, &true_label); |
+ |
+ __ mov(result, Factory::false_value()); |
+ __ jmp(&done); |
+ |
+ __ bind(&true_label); |
+ __ mov(result, Factory::true_value()); |
+ |
+ __ bind(&done); |
+} |
+ |
+ |
+void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) { |
+ Register temp = ToRegister(instr->TempAt(0)); |
+ int true_block = chunk_->LookupDestination(instr->true_block_id()); |
+ int false_block = chunk_->LookupDestination(instr->false_block_id()); |
+ |
+ EmitIsConstructCall(temp); |
+ EmitBranch(true_block, false_block, equal); |
+} |
+ |
+ |
+void LCodeGen::EmitIsConstructCall(Register temp) { |
+ // Get the frame pointer for the calling frame. |
+ __ mov(temp, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
+ |
+ // Skip the arguments adaptor frame if it exists. |
+ NearLabel check_frame_marker; |
+ __ cmp(Operand(temp, StandardFrameConstants::kContextOffset), |
+ Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
+ __ j(not_equal, &check_frame_marker); |
+ __ mov(temp, Operand(temp, StandardFrameConstants::kCallerFPOffset)); |
+ |
+ // Check the marker in the calling frame. |
+ __ bind(&check_frame_marker); |
+ __ cmp(Operand(temp, StandardFrameConstants::kMarkerOffset), |
+ Immediate(Smi::FromInt(StackFrame::CONSTRUCT))); |
+} |
+ |
+ |
void LCodeGen::DoLazyBailout(LLazyBailout* instr) { |
// No code for lazy bailout instruction. Used to capture environment after a |
// call for populating the safepoint data with deoptimization data. |