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 // The integer converted back is equal to the original. We |
| 5646 // only have to test if we got -0 as an input. |
| 5647 __ test(result_reg, Operand(result_reg)); |
| 5648 __ j(not_zero, &done, Label::kNear); |
| 5649 __ movmskpd(result_reg, input_reg); |
| 5650 // Bit 0 contains the sign of the double in input_reg. |
| 5651 // If input was positive, we are ok and return 0, otherwise |
| 5652 // deoptimize. |
| 5653 __ and_(result_reg, 1); |
| 5654 DeoptimizeIf(not_zero, instr->environment()); |
| 5655 __ bind(&done); |
| 5656 __ SmiTag(result_reg); |
| 5657 DeoptimizeIf(overflow, instr->environment()); |
| 5658 } |
| 5659 |
| 5660 |
5624 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { | 5661 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { |
5625 LOperand* input = instr->value(); | 5662 LOperand* input = instr->value(); |
5626 __ test(ToOperand(input), Immediate(kSmiTagMask)); | 5663 __ test(ToOperand(input), Immediate(kSmiTagMask)); |
5627 DeoptimizeIf(not_zero, instr->environment()); | 5664 DeoptimizeIf(not_zero, instr->environment()); |
5628 } | 5665 } |
5629 | 5666 |
5630 | 5667 |
5631 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { | 5668 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { |
5632 LOperand* input = instr->value(); | 5669 LOperand* input = instr->value(); |
5633 __ test(ToOperand(input), Immediate(kSmiTagMask)); | 5670 __ test(ToOperand(input), Immediate(kSmiTagMask)); |
(...skipping 877 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6511 FixedArray::kHeaderSize - kPointerSize)); | 6548 FixedArray::kHeaderSize - kPointerSize)); |
6512 __ bind(&done); | 6549 __ bind(&done); |
6513 } | 6550 } |
6514 | 6551 |
6515 | 6552 |
6516 #undef __ | 6553 #undef __ |
6517 | 6554 |
6518 } } // namespace v8::internal | 6555 } } // namespace v8::internal |
6519 | 6556 |
6520 #endif // V8_TARGET_ARCH_IA32 | 6557 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |