| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 | 583 |
| 584 | 584 |
| 585 int LCodeGen::ToInteger32(LConstantOperand* op) const { | 585 int LCodeGen::ToInteger32(LConstantOperand* op) const { |
| 586 HConstant* constant = chunk_->LookupConstant(op); | 586 HConstant* constant = chunk_->LookupConstant(op); |
| 587 return constant->Integer32Value(); | 587 return constant->Integer32Value(); |
| 588 } | 588 } |
| 589 | 589 |
| 590 | 590 |
| 591 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { | 591 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { |
| 592 HConstant* constant = chunk_->LookupConstant(op); | 592 HConstant* constant = chunk_->LookupConstant(op); |
| 593 ASSERT(chunk_->LookupLiteralRepresentation(op).IsTagged()); | 593 ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); |
| 594 return constant->handle(); | 594 return constant->handle(); |
| 595 } | 595 } |
| 596 | 596 |
| 597 | 597 |
| 598 double LCodeGen::ToDouble(LConstantOperand* op) const { | 598 double LCodeGen::ToDouble(LConstantOperand* op) const { |
| 599 HConstant* constant = chunk_->LookupConstant(op); | 599 HConstant* constant = chunk_->LookupConstant(op); |
| 600 ASSERT(constant->HasDoubleValue()); | 600 ASSERT(constant->HasDoubleValue()); |
| 601 return constant->DoubleValue(); | 601 return constant->DoubleValue(); |
| 602 } | 602 } |
| 603 | 603 |
| 604 | 604 |
| 605 bool LCodeGen::IsInteger32(LConstantOperand* op) const { | 605 bool LCodeGen::IsInteger32(LConstantOperand* op) const { |
| 606 return chunk_->LookupLiteralRepresentation(op).IsInteger32(); | 606 return chunk_->LookupLiteralRepresentation(op).IsInteger32(); |
| 607 } | 607 } |
| 608 | 608 |
| 609 | 609 |
| 610 bool LCodeGen::IsSmi(LConstantOperand* op) const { |
| 611 return chunk_->LookupLiteralRepresentation(op).IsSmi(); |
| 612 } |
| 613 |
| 614 |
| 610 Operand LCodeGen::ToOperand(LOperand* op) const { | 615 Operand LCodeGen::ToOperand(LOperand* op) const { |
| 611 if (op->IsRegister()) return Operand(ToRegister(op)); | 616 if (op->IsRegister()) return Operand(ToRegister(op)); |
| 612 if (op->IsDoubleRegister()) return Operand(ToDoubleRegister(op)); | 617 if (op->IsDoubleRegister()) return Operand(ToDoubleRegister(op)); |
| 613 ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot()); | 618 ASSERT(op->IsStackSlot() || op->IsDoubleStackSlot()); |
| 614 return Operand(ebp, StackSlotOffset(op->index())); | 619 return Operand(ebp, StackSlotOffset(op->index())); |
| 615 } | 620 } |
| 616 | 621 |
| 617 | 622 |
| 618 Operand LCodeGen::HighOperand(LOperand* op) { | 623 Operand LCodeGen::HighOperand(LOperand* op) { |
| 619 ASSERT(op->IsDoubleStackSlot()); | 624 ASSERT(op->IsDoubleStackSlot()); |
| (...skipping 1474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2094 } | 2099 } |
| 2095 } | 2100 } |
| 2096 | 2101 |
| 2097 | 2102 |
| 2098 void LCodeGen::DoBranch(LBranch* instr) { | 2103 void LCodeGen::DoBranch(LBranch* instr) { |
| 2099 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 2104 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 2100 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 2105 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 2101 CpuFeatureScope scope(masm(), SSE2); | 2106 CpuFeatureScope scope(masm(), SSE2); |
| 2102 | 2107 |
| 2103 Representation r = instr->hydrogen()->value()->representation(); | 2108 Representation r = instr->hydrogen()->value()->representation(); |
| 2104 if (r.IsInteger32()) { | 2109 if (r.IsInteger32() || r.IsSmi()) { |
| 2105 Register reg = ToRegister(instr->value()); | 2110 Register reg = ToRegister(instr->value()); |
| 2106 __ test(reg, Operand(reg)); | 2111 __ test(reg, Operand(reg)); |
| 2107 EmitBranch(true_block, false_block, not_zero); | 2112 EmitBranch(true_block, false_block, not_zero); |
| 2108 } else if (r.IsDouble()) { | 2113 } else if (r.IsDouble()) { |
| 2109 XMMRegister reg = ToDoubleRegister(instr->value()); | 2114 XMMRegister reg = ToDoubleRegister(instr->value()); |
| 2110 __ xorps(xmm0, xmm0); | 2115 __ xorps(xmm0, xmm0); |
| 2111 __ ucomisd(reg, xmm0); | 2116 __ ucomisd(reg, xmm0); |
| 2112 EmitBranch(true_block, false_block, not_equal); | 2117 EmitBranch(true_block, false_block, not_equal); |
| 2113 } else { | 2118 } else { |
| 2114 ASSERT(r.IsTagged()); | 2119 ASSERT(r.IsTagged()); |
| (...skipping 2098 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4213 | 4218 |
| 4214 Register object = ToRegister(instr->object()); | 4219 Register object = ToRegister(instr->object()); |
| 4215 | 4220 |
| 4216 int offset = instr->offset(); | 4221 int offset = instr->offset(); |
| 4217 | 4222 |
| 4218 Handle<Map> transition = instr->transition(); | 4223 Handle<Map> transition = instr->transition(); |
| 4219 | 4224 |
| 4220 if (FLAG_track_fields && representation.IsSmi()) { | 4225 if (FLAG_track_fields && representation.IsSmi()) { |
| 4221 if (instr->value()->IsConstantOperand()) { | 4226 if (instr->value()->IsConstantOperand()) { |
| 4222 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); | 4227 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
| 4223 if (!IsInteger32(operand_value)) { | 4228 if (!IsSmi(operand_value)) { |
| 4224 DeoptimizeIf(no_condition, instr->environment()); | 4229 DeoptimizeIf(no_condition, instr->environment()); |
| 4225 } | 4230 } |
| 4226 } else { | |
| 4227 Register value = ToRegister(instr->value()); | |
| 4228 __ SmiTag(value); | |
| 4229 if (!instr->hydrogen()->value()->range()->IsInSmiRange()) { | |
| 4230 DeoptimizeIf(overflow, instr->environment()); | |
| 4231 } | |
| 4232 } | 4231 } |
| 4233 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { | 4232 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { |
| 4234 if (instr->value()->IsConstantOperand()) { | 4233 if (instr->value()->IsConstantOperand()) { |
| 4235 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); | 4234 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
| 4236 if (IsInteger32(operand_value)) { | 4235 if (IsInteger32(operand_value)) { |
| 4237 DeoptimizeIf(no_condition, instr->environment()); | 4236 DeoptimizeIf(no_condition, instr->environment()); |
| 4238 } | 4237 } |
| 4239 } else { | 4238 } else { |
| 4240 if (!instr->hydrogen()->value()->type().IsHeapObject()) { | 4239 if (!instr->hydrogen()->value()->type().IsHeapObject()) { |
| 4241 Register value = ToRegister(instr->value()); | 4240 Register value = ToRegister(instr->value()); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4286 | 4285 |
| 4287 Register write_register = object; | 4286 Register write_register = object; |
| 4288 if (!instr->is_in_object()) { | 4287 if (!instr->is_in_object()) { |
| 4289 write_register = ToRegister(instr->temp()); | 4288 write_register = ToRegister(instr->temp()); |
| 4290 __ mov(write_register, | 4289 __ mov(write_register, |
| 4291 FieldOperand(object, JSObject::kPropertiesOffset)); | 4290 FieldOperand(object, JSObject::kPropertiesOffset)); |
| 4292 } | 4291 } |
| 4293 | 4292 |
| 4294 if (instr->value()->IsConstantOperand()) { | 4293 if (instr->value()->IsConstantOperand()) { |
| 4295 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); | 4294 LConstantOperand* operand_value = LConstantOperand::cast(instr->value()); |
| 4296 if (IsInteger32(operand_value)) { | 4295 if (operand_value->IsRegister()) { |
| 4297 // In lithium register preparation, we made sure that the constant integer | |
| 4298 // operand fits into smi range. | |
| 4299 Smi* smi_value = Smi::FromInt(ToInteger32(operand_value)); | |
| 4300 __ mov(FieldOperand(write_register, offset), Immediate(smi_value)); | |
| 4301 } else if (operand_value->IsRegister()) { | |
| 4302 __ mov(FieldOperand(write_register, offset), ToRegister(operand_value)); | 4296 __ mov(FieldOperand(write_register, offset), ToRegister(operand_value)); |
| 4303 } else { | 4297 } else { |
| 4304 Handle<Object> handle_value = ToHandle(operand_value); | 4298 Handle<Object> handle_value = ToHandle(operand_value); |
| 4305 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); | 4299 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); |
| 4306 __ mov(FieldOperand(write_register, offset), handle_value); | 4300 __ mov(FieldOperand(write_register, offset), handle_value); |
| 4307 } | 4301 } |
| 4308 } else { | 4302 } else { |
| 4309 __ mov(FieldOperand(write_register, offset), ToRegister(instr->value())); | 4303 __ mov(FieldOperand(write_register, offset), ToRegister(instr->value())); |
| 4310 } | 4304 } |
| 4311 | 4305 |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4762 ASSERT(input->IsRegister() || input->IsStackSlot()); | 4756 ASSERT(input->IsRegister() || input->IsStackSlot()); |
| 4763 LOperand* output = instr->result(); | 4757 LOperand* output = instr->result(); |
| 4764 ASSERT(output->IsDoubleRegister()); | 4758 ASSERT(output->IsDoubleRegister()); |
| 4765 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input)); | 4759 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input)); |
| 4766 } else { | 4760 } else { |
| 4767 UNREACHABLE(); | 4761 UNREACHABLE(); |
| 4768 } | 4762 } |
| 4769 } | 4763 } |
| 4770 | 4764 |
| 4771 | 4765 |
| 4766 void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) { |
| 4767 Register input = ToRegister(instr->value()); |
| 4768 __ SmiTag(input); |
| 4769 if (!instr->hydrogen()->value()->HasRange() || |
| 4770 !instr->hydrogen()->value()->range()->IsInSmiRange()) { |
| 4771 DeoptimizeIf(overflow, instr->environment()); |
| 4772 } |
| 4773 } |
| 4774 |
| 4775 |
| 4772 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { | 4776 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { |
| 4773 CpuFeatureScope scope(masm(), SSE2); | 4777 CpuFeatureScope scope(masm(), SSE2); |
| 4774 LOperand* input = instr->value(); | 4778 LOperand* input = instr->value(); |
| 4775 LOperand* output = instr->result(); | 4779 LOperand* output = instr->result(); |
| 4776 LOperand* temp = instr->temp(); | 4780 LOperand* temp = instr->temp(); |
| 4777 | 4781 |
| 4778 __ LoadUint32(ToDoubleRegister(output), | 4782 __ LoadUint32(ToDoubleRegister(output), |
| 4779 ToRegister(input), | 4783 ToRegister(input), |
| 4780 ToDoubleRegister(temp)); | 4784 ToDoubleRegister(temp)); |
| 4781 } | 4785 } |
| (...skipping 832 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5614 // If input was positive, we are ok and return 0, otherwise | 5618 // If input was positive, we are ok and return 0, otherwise |
| 5615 // deoptimize. | 5619 // deoptimize. |
| 5616 __ and_(result_reg, 1); | 5620 __ and_(result_reg, 1); |
| 5617 DeoptimizeIf(not_zero, instr->environment()); | 5621 DeoptimizeIf(not_zero, instr->environment()); |
| 5618 } | 5622 } |
| 5619 __ bind(&done); | 5623 __ bind(&done); |
| 5620 } | 5624 } |
| 5621 } | 5625 } |
| 5622 | 5626 |
| 5623 | 5627 |
| 5628 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { |
| 5629 LOperand* input = instr->value(); |
| 5630 ASSERT(input->IsDoubleRegister()); |
| 5631 LOperand* result = instr->result(); |
| 5632 ASSERT(result->IsRegister()); |
| 5633 CpuFeatureScope scope(masm(), SSE2); |
| 5634 |
| 5635 XMMRegister input_reg = ToDoubleRegister(input); |
| 5636 Register result_reg = ToRegister(result); |
| 5637 |
| 5638 Label done; |
| 5639 __ cvttsd2si(result_reg, Operand(input_reg)); |
| 5640 __ cvtsi2sd(xmm0, Operand(result_reg)); |
| 5641 __ ucomisd(xmm0, input_reg); |
| 5642 DeoptimizeIf(not_equal, instr->environment()); |
| 5643 DeoptimizeIf(parity_even, instr->environment()); // NaN. |
| 5644 |
| 5645 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 5646 // The integer converted back is equal to the original. We |
| 5647 // only have to test if we got -0 as an input. |
| 5648 __ test(result_reg, Operand(result_reg)); |
| 5649 __ j(not_zero, &done, Label::kNear); |
| 5650 __ movmskpd(result_reg, input_reg); |
| 5651 // Bit 0 contains the sign of the double in input_reg. |
| 5652 // If input was positive, we are ok and return 0, otherwise |
| 5653 // deoptimize. |
| 5654 __ and_(result_reg, 1); |
| 5655 DeoptimizeIf(not_zero, instr->environment()); |
| 5656 __ bind(&done); |
| 5657 } |
| 5658 __ SmiTag(result_reg); |
| 5659 DeoptimizeIf(overflow, instr->environment()); |
| 5660 } |
| 5661 |
| 5662 |
| 5624 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { | 5663 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { |
| 5625 LOperand* input = instr->value(); | 5664 LOperand* input = instr->value(); |
| 5626 __ test(ToOperand(input), Immediate(kSmiTagMask)); | 5665 __ test(ToOperand(input), Immediate(kSmiTagMask)); |
| 5627 DeoptimizeIf(not_zero, instr->environment()); | 5666 DeoptimizeIf(not_zero, instr->environment()); |
| 5628 } | 5667 } |
| 5629 | 5668 |
| 5630 | 5669 |
| 5631 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { | 5670 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { |
| 5632 LOperand* input = instr->value(); | 5671 LOperand* input = instr->value(); |
| 5633 __ test(ToOperand(input), Immediate(kSmiTagMask)); | 5672 __ test(ToOperand(input), Immediate(kSmiTagMask)); |
| (...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6511 FixedArray::kHeaderSize - kPointerSize)); | 6550 FixedArray::kHeaderSize - kPointerSize)); |
| 6512 __ bind(&done); | 6551 __ bind(&done); |
| 6513 } | 6552 } |
| 6514 | 6553 |
| 6515 | 6554 |
| 6516 #undef __ | 6555 #undef __ |
| 6517 | 6556 |
| 6518 } } // namespace v8::internal | 6557 } } // namespace v8::internal |
| 6519 | 6558 |
| 6520 #endif // V8_TARGET_ARCH_IA32 | 6559 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |