| 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 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 493 __ ldc1(dbl_scratch, mem_op); | 493 __ ldc1(dbl_scratch, mem_op); |
| 494 return dbl_scratch; | 494 return dbl_scratch; |
| 495 } | 495 } |
| 496 UNREACHABLE(); | 496 UNREACHABLE(); |
| 497 return dbl_scratch; | 497 return dbl_scratch; |
| 498 } | 498 } |
| 499 | 499 |
| 500 | 500 |
| 501 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { | 501 Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { |
| 502 HConstant* constant = chunk_->LookupConstant(op); | 502 HConstant* constant = chunk_->LookupConstant(op); |
| 503 ASSERT(chunk_->LookupLiteralRepresentation(op).IsTagged()); | 503 ASSERT(chunk_->LookupLiteralRepresentation(op).IsSmiOrTagged()); |
| 504 return constant->handle(); | 504 return constant->handle(); |
| 505 } | 505 } |
| 506 | 506 |
| 507 | 507 |
| 508 bool LCodeGen::IsInteger32(LConstantOperand* op) const { | 508 bool LCodeGen::IsInteger32(LConstantOperand* op) const { |
| 509 return chunk_->LookupLiteralRepresentation(op).IsInteger32(); | 509 return chunk_->LookupLiteralRepresentation(op).IsInteger32(); |
| 510 } | 510 } |
| 511 | 511 |
| 512 | 512 |
| 513 bool LCodeGen::IsSmi(LConstantOperand* op) const { |
| 514 return chunk_->LookupLiteralRepresentation(op).IsSmi(); |
| 515 } |
| 516 |
| 517 |
| 513 int LCodeGen::ToInteger32(LConstantOperand* op) const { | 518 int LCodeGen::ToInteger32(LConstantOperand* op) const { |
| 514 HConstant* constant = chunk_->LookupConstant(op); | 519 HConstant* constant = chunk_->LookupConstant(op); |
| 515 return constant->Integer32Value(); | 520 return constant->Integer32Value(); |
| 516 } | 521 } |
| 517 | 522 |
| 518 | 523 |
| 519 double LCodeGen::ToDouble(LConstantOperand* op) const { | 524 double LCodeGen::ToDouble(LConstantOperand* op) const { |
| 520 HConstant* constant = chunk_->LookupConstant(op); | 525 HConstant* constant = chunk_->LookupConstant(op); |
| 521 ASSERT(constant->HasDoubleValue()); | 526 ASSERT(constant->HasDoubleValue()); |
| 522 return constant->DoubleValue(); | 527 return constant->DoubleValue(); |
| (...skipping 1307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1830 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { | 1835 void LCodeGen::DoDebugBreak(LDebugBreak* instr) { |
| 1831 __ stop("LDebugBreak"); | 1836 __ stop("LDebugBreak"); |
| 1832 } | 1837 } |
| 1833 | 1838 |
| 1834 | 1839 |
| 1835 void LCodeGen::DoBranch(LBranch* instr) { | 1840 void LCodeGen::DoBranch(LBranch* instr) { |
| 1836 int true_block = chunk_->LookupDestination(instr->true_block_id()); | 1841 int true_block = chunk_->LookupDestination(instr->true_block_id()); |
| 1837 int false_block = chunk_->LookupDestination(instr->false_block_id()); | 1842 int false_block = chunk_->LookupDestination(instr->false_block_id()); |
| 1838 | 1843 |
| 1839 Representation r = instr->hydrogen()->value()->representation(); | 1844 Representation r = instr->hydrogen()->value()->representation(); |
| 1840 if (r.IsInteger32()) { | 1845 if (r.IsInteger32() || r.IsSmi()) { |
| 1841 Register reg = ToRegister(instr->value()); | 1846 Register reg = ToRegister(instr->value()); |
| 1842 EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg)); | 1847 EmitBranch(true_block, false_block, ne, reg, Operand(zero_reg)); |
| 1843 } else if (r.IsDouble()) { | 1848 } else if (r.IsDouble()) { |
| 1844 DoubleRegister reg = ToDoubleRegister(instr->value()); | 1849 DoubleRegister reg = ToDoubleRegister(instr->value()); |
| 1845 // Test the double value. Zero and NaN are false. | 1850 // Test the double value. Zero and NaN are false. |
| 1846 EmitBranchF(true_block, false_block, nue, reg, kDoubleRegZero); | 1851 EmitBranchF(true_block, false_block, nue, reg, kDoubleRegZero); |
| 1847 } else { | 1852 } else { |
| 1848 ASSERT(r.IsTagged()); | 1853 ASSERT(r.IsTagged()); |
| 1849 Register reg = ToRegister(instr->value()); | 1854 Register reg = ToRegister(instr->value()); |
| 1850 HType type = instr->hydrogen()->value()->type(); | 1855 HType type = instr->hydrogen()->value()->type(); |
| (...skipping 2040 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3891 | 3896 |
| 3892 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { | 3897 void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) { |
| 3893 Representation representation = instr->representation(); | 3898 Representation representation = instr->representation(); |
| 3894 | 3899 |
| 3895 Register object = ToRegister(instr->object()); | 3900 Register object = ToRegister(instr->object()); |
| 3896 Register scratch = scratch0(); | 3901 Register scratch = scratch0(); |
| 3897 int offset = instr->offset(); | 3902 int offset = instr->offset(); |
| 3898 | 3903 |
| 3899 Handle<Map> transition = instr->transition(); | 3904 Handle<Map> transition = instr->transition(); |
| 3900 | 3905 |
| 3901 if (FLAG_track_fields && representation.IsSmi()) { | 3906 if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { |
| 3902 Register value = ToRegister(instr->value()); | |
| 3903 __ SmiTagCheckOverflow(value, value, scratch); | |
| 3904 if (!instr->hydrogen()->value()->range()->IsInSmiRange()) { | |
| 3905 DeoptimizeIf(lt, instr->environment(), scratch, Operand(zero_reg)); | |
| 3906 } | |
| 3907 } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) { | |
| 3908 Register value = ToRegister(instr->value()); | 3907 Register value = ToRegister(instr->value()); |
| 3909 if (!instr->hydrogen()->value()->type().IsHeapObject()) { | 3908 if (!instr->hydrogen()->value()->type().IsHeapObject()) { |
| 3910 __ And(scratch, value, Operand(kSmiTagMask)); | 3909 __ And(scratch, value, Operand(kSmiTagMask)); |
| 3911 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg)); | 3910 DeoptimizeIf(eq, instr->environment(), scratch, Operand(zero_reg)); |
| 3912 } | 3911 } |
| 3913 } else if (FLAG_track_double_fields && representation.IsDouble()) { | 3912 } else if (FLAG_track_double_fields && representation.IsDouble()) { |
| 3914 ASSERT(transition.is_null()); | 3913 ASSERT(transition.is_null()); |
| 3915 ASSERT(instr->is_in_object()); | 3914 ASSERT(instr->is_in_object()); |
| 3916 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); | 3915 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); |
| 3917 DoubleRegister value = ToDoubleRegister(instr->value()); | 3916 DoubleRegister value = ToDoubleRegister(instr->value()); |
| (...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4400 Register scratch = scratch0(); | 4399 Register scratch = scratch0(); |
| 4401 __ lw(scratch, ToMemOperand(input)); | 4400 __ lw(scratch, ToMemOperand(input)); |
| 4402 __ mtc1(scratch, single_scratch); | 4401 __ mtc1(scratch, single_scratch); |
| 4403 } else { | 4402 } else { |
| 4404 __ mtc1(ToRegister(input), single_scratch); | 4403 __ mtc1(ToRegister(input), single_scratch); |
| 4405 } | 4404 } |
| 4406 __ cvt_d_w(ToDoubleRegister(output), single_scratch); | 4405 __ cvt_d_w(ToDoubleRegister(output), single_scratch); |
| 4407 } | 4406 } |
| 4408 | 4407 |
| 4409 | 4408 |
| 4409 void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) { |
| 4410 LOperand* input = instr->value(); |
| 4411 ASSERT(input->IsRegister()); |
| 4412 LOperand* output = instr->result(); |
| 4413 ASSERT(output->IsRegister()); |
| 4414 Register scratch = scratch0(); |
| 4415 |
| 4416 __ SmiTagCheckOverflow(ToRegister(output), ToRegister(input), scratch); |
| 4417 if (!instr->hydrogen()->value()->HasRange() || |
| 4418 !instr->hydrogen()->value()->range()->IsInSmiRange()) { |
| 4419 DeoptimizeIf(lt, instr->environment(), scratch, Operand(zero_reg)); |
| 4420 } |
| 4421 } |
| 4422 |
| 4423 |
| 4410 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { | 4424 void LCodeGen::DoUint32ToDouble(LUint32ToDouble* instr) { |
| 4411 LOperand* input = instr->value(); | 4425 LOperand* input = instr->value(); |
| 4412 LOperand* output = instr->result(); | 4426 LOperand* output = instr->result(); |
| 4413 | 4427 |
| 4414 FPURegister dbl_scratch = double_scratch0(); | 4428 FPURegister dbl_scratch = double_scratch0(); |
| 4415 __ mtc1(ToRegister(input), dbl_scratch); | 4429 __ mtc1(ToRegister(input), dbl_scratch); |
| 4416 __ Cvt_d_uw(ToDoubleRegister(output), dbl_scratch, f22); | 4430 __ Cvt_d_uw(ToDoubleRegister(output), dbl_scratch, f22); |
| 4417 } | 4431 } |
| 4418 | 4432 |
| 4419 | 4433 |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4859 __ EmitFPUTruncate(kRoundToMinusInf, | 4873 __ EmitFPUTruncate(kRoundToMinusInf, |
| 4860 result_reg, | 4874 result_reg, |
| 4861 double_input, | 4875 double_input, |
| 4862 scratch1, | 4876 scratch1, |
| 4863 double_scratch0(), | 4877 double_scratch0(), |
| 4864 except_flag, | 4878 except_flag, |
| 4865 kCheckForInexactConversion); | 4879 kCheckForInexactConversion); |
| 4866 | 4880 |
| 4867 // Deopt if the operation did not succeed (except_flag != 0). | 4881 // Deopt if the operation did not succeed (except_flag != 0). |
| 4868 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); | 4882 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); |
| 4883 |
| 4884 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 4885 Label done; |
| 4886 __ Branch(&done, ne, result_reg, Operand(zero_reg)); |
| 4887 __ mfc1(scratch1, double_input.high()); |
| 4888 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); |
| 4889 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); |
| 4890 __ bind(&done); |
| 4891 } |
| 4869 } | 4892 } |
| 4870 } | 4893 } |
| 4871 | 4894 |
| 4872 | 4895 |
| 4896 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { |
| 4897 Register result_reg = ToRegister(instr->result()); |
| 4898 Register scratch1 = scratch0(); |
| 4899 Register scratch2 = ToRegister(instr->temp()); |
| 4900 DoubleRegister double_input = ToDoubleRegister(instr->value()); |
| 4901 |
| 4902 if (instr->truncating()) { |
| 4903 Register scratch3 = ToRegister(instr->temp2()); |
| 4904 FPURegister single_scratch = double_scratch0().low(); |
| 4905 __ EmitECMATruncate(result_reg, |
| 4906 double_input, |
| 4907 single_scratch, |
| 4908 scratch1, |
| 4909 scratch2, |
| 4910 scratch3); |
| 4911 } else { |
| 4912 Register except_flag = scratch2; |
| 4913 |
| 4914 __ EmitFPUTruncate(kRoundToMinusInf, |
| 4915 result_reg, |
| 4916 double_input, |
| 4917 scratch1, |
| 4918 double_scratch0(), |
| 4919 except_flag, |
| 4920 kCheckForInexactConversion); |
| 4921 |
| 4922 // Deopt if the operation did not succeed (except_flag != 0). |
| 4923 DeoptimizeIf(ne, instr->environment(), except_flag, Operand(zero_reg)); |
| 4924 |
| 4925 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 4926 Label done; |
| 4927 __ Branch(&done, ne, result_reg, Operand(zero_reg)); |
| 4928 __ mfc1(scratch1, double_input.high()); |
| 4929 __ And(scratch1, scratch1, Operand(HeapNumber::kSignMask)); |
| 4930 DeoptimizeIf(ne, instr->environment(), scratch1, Operand(zero_reg)); |
| 4931 __ bind(&done); |
| 4932 } |
| 4933 } |
| 4934 __ SmiTagCheckOverflow(result_reg, result_reg, scratch1); |
| 4935 DeoptimizeIf(lt, instr->environment(), scratch1, Operand(zero_reg)); |
| 4936 } |
| 4937 |
| 4938 |
| 4873 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { | 4939 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { |
| 4874 LOperand* input = instr->value(); | 4940 LOperand* input = instr->value(); |
| 4875 __ And(at, ToRegister(input), Operand(kSmiTagMask)); | 4941 __ And(at, ToRegister(input), Operand(kSmiTagMask)); |
| 4876 DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg)); | 4942 DeoptimizeIf(ne, instr->environment(), at, Operand(zero_reg)); |
| 4877 } | 4943 } |
| 4878 | 4944 |
| 4879 | 4945 |
| 4880 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { | 4946 void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { |
| 4881 LOperand* input = instr->value(); | 4947 LOperand* input = instr->value(); |
| 4882 __ And(at, ToRegister(input), Operand(kSmiTagMask)); | 4948 __ And(at, ToRegister(input), Operand(kSmiTagMask)); |
| (...skipping 790 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5673 __ Subu(scratch, result, scratch); | 5739 __ Subu(scratch, result, scratch); |
| 5674 __ lw(result, FieldMemOperand(scratch, | 5740 __ lw(result, FieldMemOperand(scratch, |
| 5675 FixedArray::kHeaderSize - kPointerSize)); | 5741 FixedArray::kHeaderSize - kPointerSize)); |
| 5676 __ bind(&done); | 5742 __ bind(&done); |
| 5677 } | 5743 } |
| 5678 | 5744 |
| 5679 | 5745 |
| 5680 #undef __ | 5746 #undef __ |
| 5681 | 5747 |
| 5682 } } // namespace v8::internal | 5748 } } // namespace v8::internal |
| OLD | NEW |