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 |