| 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.
|
|
|