OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 5721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5732 Register left_reg = left_side.reg(); | 5732 Register left_reg = left_side.reg(); |
5733 Handle<Object> right_val = right_side.handle(); | 5733 Handle<Object> right_val = right_side.handle(); |
5734 | 5734 |
5735 // Here we split control flow to the stub call and inlined cases | 5735 // Here we split control flow to the stub call and inlined cases |
5736 // before finally splitting it to the control destination. We use | 5736 // before finally splitting it to the control destination. We use |
5737 // a jump target and branching to duplicate the virtual frame at | 5737 // a jump target and branching to duplicate the virtual frame at |
5738 // the first split. We manually handle the off-frame references | 5738 // the first split. We manually handle the off-frame references |
5739 // by reconstituting them on the non-fall-through path. | 5739 // by reconstituting them on the non-fall-through path. |
5740 JumpTarget is_smi; | 5740 JumpTarget is_smi; |
5741 | 5741 |
5742 Condition left_is_smi = masm_->CheckSmi(left_side.reg()); | 5742 if (left_side.is_smi()) { |
5743 is_smi.Branch(left_is_smi); | 5743 if (FLAG_debug_code) { |
| 5744 __ AbortIfNotSmi(left_side.reg(), "Non-smi value inferred as smi."); |
| 5745 } |
| 5746 } else { |
| 5747 Condition left_is_smi = masm_->CheckSmi(left_side.reg()); |
| 5748 is_smi.Branch(left_is_smi); |
5744 | 5749 |
5745 bool is_loop_condition = (node->AsExpression() != NULL) && | 5750 bool is_loop_condition = (node->AsExpression() != NULL) && |
5746 node->AsExpression()->is_loop_condition(); | 5751 node->AsExpression()->is_loop_condition(); |
5747 if (!is_loop_condition && right_val->IsSmi()) { | 5752 if (!is_loop_condition && right_val->IsSmi()) { |
5748 // Right side is a constant smi and left side has been checked | 5753 // Right side is a constant smi and left side has been checked |
5749 // not to be a smi. | 5754 // not to be a smi. |
5750 JumpTarget not_number; | 5755 JumpTarget not_number; |
5751 __ Cmp(FieldOperand(left_reg, HeapObject::kMapOffset), | 5756 __ Cmp(FieldOperand(left_reg, HeapObject::kMapOffset), |
5752 Factory::heap_number_map()); | 5757 Factory::heap_number_map()); |
5753 not_number.Branch(not_equal, &left_side); | 5758 not_number.Branch(not_equal, &left_side); |
5754 __ movsd(xmm1, | 5759 __ movsd(xmm1, |
5755 FieldOperand(left_reg, HeapNumber::kValueOffset)); | 5760 FieldOperand(left_reg, HeapNumber::kValueOffset)); |
5756 int value = Smi::cast(*right_val)->value(); | 5761 int value = Smi::cast(*right_val)->value(); |
5757 if (value == 0) { | 5762 if (value == 0) { |
5758 __ xorpd(xmm0, xmm0); | 5763 __ xorpd(xmm0, xmm0); |
5759 } else { | 5764 } else { |
5760 Result temp = allocator()->Allocate(); | 5765 Result temp = allocator()->Allocate(); |
5761 __ movl(temp.reg(), Immediate(value)); | 5766 __ movl(temp.reg(), Immediate(value)); |
5762 __ cvtlsi2sd(xmm0, temp.reg()); | 5767 __ cvtlsi2sd(xmm0, temp.reg()); |
5763 temp.Unuse(); | 5768 temp.Unuse(); |
| 5769 } |
| 5770 __ ucomisd(xmm1, xmm0); |
| 5771 // Jump to builtin for NaN. |
| 5772 not_number.Branch(parity_even, &left_side); |
| 5773 left_side.Unuse(); |
| 5774 dest->true_target()->Branch(DoubleCondition(cc)); |
| 5775 dest->false_target()->Jump(); |
| 5776 not_number.Bind(&left_side); |
5764 } | 5777 } |
5765 __ ucomisd(xmm1, xmm0); | 5778 |
5766 // Jump to builtin for NaN. | 5779 // Setup and call the compare stub. |
5767 not_number.Branch(parity_even, &left_side); | 5780 CompareStub stub(cc, strict, kCantBothBeNaN); |
5768 left_side.Unuse(); | 5781 Result result = frame_->CallStub(&stub, &left_side, &right_side); |
5769 dest->true_target()->Branch(DoubleCondition(cc)); | 5782 result.ToRegister(); |
| 5783 __ testq(result.reg(), result.reg()); |
| 5784 result.Unuse(); |
| 5785 dest->true_target()->Branch(cc); |
5770 dest->false_target()->Jump(); | 5786 dest->false_target()->Jump(); |
5771 not_number.Bind(&left_side); | 5787 |
| 5788 is_smi.Bind(); |
5772 } | 5789 } |
5773 | 5790 |
5774 // Setup and call the compare stub. | |
5775 CompareStub stub(cc, strict, kCantBothBeNaN); | |
5776 Result result = frame_->CallStub(&stub, &left_side, &right_side); | |
5777 result.ToRegister(); | |
5778 __ testq(result.reg(), result.reg()); | |
5779 result.Unuse(); | |
5780 dest->true_target()->Branch(cc); | |
5781 dest->false_target()->Jump(); | |
5782 | |
5783 is_smi.Bind(); | |
5784 left_side = Result(left_reg); | 5791 left_side = Result(left_reg); |
5785 right_side = Result(right_val); | 5792 right_side = Result(right_val); |
5786 // Test smi equality and comparison by signed int comparison. | 5793 // Test smi equality and comparison by signed int comparison. |
5787 // Both sides are smis, so we can use an Immediate. | 5794 // Both sides are smis, so we can use an Immediate. |
5788 __ SmiCompare(left_side.reg(), Smi::cast(*right_side.handle())); | 5795 __ SmiCompare(left_side.reg(), Smi::cast(*right_side.handle())); |
5789 left_side.Unuse(); | 5796 left_side.Unuse(); |
5790 right_side.Unuse(); | 5797 right_side.Unuse(); |
5791 dest->Split(cc); | 5798 dest->Split(cc); |
5792 } | 5799 } |
5793 } else if (cc == equal && | 5800 } else if (cc == equal && |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5945 // Compare the first character of the string with the | 5952 // Compare the first character of the string with the |
5946 // constant 1-character string. | 5953 // constant 1-character string. |
5947 uint8_t char_value = | 5954 uint8_t char_value = |
5948 static_cast<uint8_t>(String::cast(*right_side.handle())->Get(0)); | 5955 static_cast<uint8_t>(String::cast(*right_side.handle())->Get(0)); |
5949 __ cmpb(temp2.reg(), Immediate(char_value)); | 5956 __ cmpb(temp2.reg(), Immediate(char_value)); |
5950 Label characters_were_different; | 5957 Label characters_were_different; |
5951 __ j(not_equal, &characters_were_different); | 5958 __ j(not_equal, &characters_were_different); |
5952 // If the first character is the same then the long string sorts after | 5959 // If the first character is the same then the long string sorts after |
5953 // the short one. | 5960 // the short one. |
5954 __ SmiCompare(FieldOperand(left_side.reg(), String::kLengthOffset), | 5961 __ SmiCompare(FieldOperand(left_side.reg(), String::kLengthOffset), |
5955 Smi::FromInt(1)); | 5962 Smi::FromInt(1)); |
5956 __ bind(&characters_were_different); | 5963 __ bind(&characters_were_different); |
5957 } | 5964 } |
5958 temp2.Unuse(); | 5965 temp2.Unuse(); |
5959 left_side.Unuse(); | 5966 left_side.Unuse(); |
5960 right_side.Unuse(); | 5967 right_side.Unuse(); |
5961 dest->Split(cc); | 5968 dest->Split(cc); |
5962 } | 5969 } |
5963 } else { | 5970 } else { |
5964 // Neither side is a constant Smi, constant 1-char string, or constant null. | 5971 // Neither side is a constant Smi, constant 1-char string, or constant null. |
5965 // If either side is a non-smi constant, skip the smi check. | 5972 // If either side is a non-smi constant, skip the smi check. |
(...skipping 5547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11513 // Call the function from C++. | 11520 // Call the function from C++. |
11514 return FUNCTION_CAST<ModuloFunction>(buffer); | 11521 return FUNCTION_CAST<ModuloFunction>(buffer); |
11515 } | 11522 } |
11516 | 11523 |
11517 #endif | 11524 #endif |
11518 | 11525 |
11519 | 11526 |
11520 #undef __ | 11527 #undef __ |
11521 | 11528 |
11522 } } // namespace v8::internal | 11529 } } // namespace v8::internal |
OLD | NEW |