| 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 814 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 825 Comment cmnt(masm_, "[ ToBoolean"); | 825 Comment cmnt(masm_, "[ ToBoolean"); |
| 826 | 826 |
| 827 // The value to convert should be popped from the frame. | 827 // The value to convert should be popped from the frame. |
| 828 Result value = frame_->Pop(); | 828 Result value = frame_->Pop(); |
| 829 value.ToRegister(); | 829 value.ToRegister(); |
| 830 | 830 |
| 831 if (value.is_integer32()) { // Also takes Smi case. | 831 if (value.is_integer32()) { // Also takes Smi case. |
| 832 Comment cmnt(masm_, "ONLY_INTEGER_32"); | 832 Comment cmnt(masm_, "ONLY_INTEGER_32"); |
| 833 if (FLAG_debug_code) { | 833 if (FLAG_debug_code) { |
| 834 Label ok; | 834 Label ok; |
| 835 __ AbortIfNotNumber(value.reg(), "ToBoolean operand is not a number."); | 835 __ AbortIfNotNumber(value.reg()); |
| 836 __ test(value.reg(), Immediate(kSmiTagMask)); | 836 __ test(value.reg(), Immediate(kSmiTagMask)); |
| 837 __ j(zero, &ok); | 837 __ j(zero, &ok); |
| 838 __ fldz(); | 838 __ fldz(); |
| 839 __ fld_d(FieldOperand(value.reg(), HeapNumber::kValueOffset)); | 839 __ fld_d(FieldOperand(value.reg(), HeapNumber::kValueOffset)); |
| 840 __ FCmp(); | 840 __ FCmp(); |
| 841 __ j(not_zero, &ok); | 841 __ j(not_zero, &ok); |
| 842 __ Abort("Smi was wrapped in HeapNumber in output from bitop"); | 842 __ Abort("Smi was wrapped in HeapNumber in output from bitop"); |
| 843 __ bind(&ok); | 843 __ bind(&ok); |
| 844 } | 844 } |
| 845 // In the integer32 case there are no Smis hidden in heap numbers, so we | 845 // In the integer32 case there are no Smis hidden in heap numbers, so we |
| 846 // need only test for Smi zero. | 846 // need only test for Smi zero. |
| 847 __ test(value.reg(), Operand(value.reg())); | 847 __ test(value.reg(), Operand(value.reg())); |
| 848 dest->false_target()->Branch(zero); | 848 dest->false_target()->Branch(zero); |
| 849 value.Unuse(); | 849 value.Unuse(); |
| 850 dest->Split(not_zero); | 850 dest->Split(not_zero); |
| 851 } else if (value.is_number()) { | 851 } else if (value.is_number()) { |
| 852 Comment cmnt(masm_, "ONLY_NUMBER"); | 852 Comment cmnt(masm_, "ONLY_NUMBER"); |
| 853 // Fast case if NumberInfo indicates only numbers. | 853 // Fast case if NumberInfo indicates only numbers. |
| 854 if (FLAG_debug_code) { | 854 if (FLAG_debug_code) { |
| 855 __ AbortIfNotNumber(value.reg(), "ToBoolean operand is not a number."); | 855 __ AbortIfNotNumber(value.reg()); |
| 856 } | 856 } |
| 857 // Smi => false iff zero. | 857 // Smi => false iff zero. |
| 858 ASSERT(kSmiTag == 0); | 858 ASSERT(kSmiTag == 0); |
| 859 __ test(value.reg(), Operand(value.reg())); | 859 __ test(value.reg(), Operand(value.reg())); |
| 860 dest->false_target()->Branch(zero); | 860 dest->false_target()->Branch(zero); |
| 861 __ test(value.reg(), Immediate(kSmiTagMask)); | 861 __ test(value.reg(), Immediate(kSmiTagMask)); |
| 862 dest->true_target()->Branch(zero); | 862 dest->true_target()->Branch(zero); |
| 863 __ fldz(); | 863 __ fldz(); |
| 864 __ fld_d(FieldOperand(value.reg(), HeapNumber::kValueOffset)); | 864 __ fld_d(FieldOperand(value.reg(), HeapNumber::kValueOffset)); |
| 865 __ FCmp(); | 865 __ FCmp(); |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1031 Factory::heap_number_map()); | 1031 Factory::heap_number_map()); |
| 1032 __ j(not_equal, &call_runtime); | 1032 __ j(not_equal, &call_runtime); |
| 1033 } | 1033 } |
| 1034 __ movdbl(xmm0, FieldOperand(left_, HeapNumber::kValueOffset)); | 1034 __ movdbl(xmm0, FieldOperand(left_, HeapNumber::kValueOffset)); |
| 1035 if (mode_ == OVERWRITE_LEFT) { | 1035 if (mode_ == OVERWRITE_LEFT) { |
| 1036 __ mov(dst_, left_); | 1036 __ mov(dst_, left_); |
| 1037 } | 1037 } |
| 1038 __ jmp(&load_right); | 1038 __ jmp(&load_right); |
| 1039 | 1039 |
| 1040 __ bind(&left_smi); | 1040 __ bind(&left_smi); |
| 1041 } else { |
| 1042 if (FLAG_debug_code) __ AbortIfNotSmi(left_); |
| 1041 } | 1043 } |
| 1042 __ SmiUntag(left_); | 1044 __ SmiUntag(left_); |
| 1043 __ cvtsi2sd(xmm0, Operand(left_)); | 1045 __ cvtsi2sd(xmm0, Operand(left_)); |
| 1044 __ SmiTag(left_); | 1046 __ SmiTag(left_); |
| 1045 if (mode_ == OVERWRITE_LEFT) { | 1047 if (mode_ == OVERWRITE_LEFT) { |
| 1046 Label alloc_failure; | 1048 Label alloc_failure; |
| 1047 __ push(left_); | 1049 __ push(left_); |
| 1048 __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure); | 1050 __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure); |
| 1049 __ pop(left_); | 1051 __ pop(left_); |
| 1050 } | 1052 } |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1063 __ mov(dst_, right_); | 1065 __ mov(dst_, right_); |
| 1064 } else if (mode_ == NO_OVERWRITE) { | 1066 } else if (mode_ == NO_OVERWRITE) { |
| 1065 Label alloc_failure; | 1067 Label alloc_failure; |
| 1066 __ push(left_); | 1068 __ push(left_); |
| 1067 __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure); | 1069 __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure); |
| 1068 __ pop(left_); | 1070 __ pop(left_); |
| 1069 } | 1071 } |
| 1070 __ jmp(&do_op); | 1072 __ jmp(&do_op); |
| 1071 | 1073 |
| 1072 __ bind(&right_smi); | 1074 __ bind(&right_smi); |
| 1075 } else { |
| 1076 if (FLAG_debug_code) __ AbortIfNotSmi(right_); |
| 1073 } | 1077 } |
| 1074 __ SmiUntag(right_); | 1078 __ SmiUntag(right_); |
| 1075 __ cvtsi2sd(xmm1, Operand(right_)); | 1079 __ cvtsi2sd(xmm1, Operand(right_)); |
| 1076 __ SmiTag(right_); | 1080 __ SmiTag(right_); |
| 1077 if (mode_ == OVERWRITE_RIGHT || mode_ == NO_OVERWRITE) { | 1081 if (mode_ == OVERWRITE_RIGHT || mode_ == NO_OVERWRITE) { |
| 1078 Label alloc_failure; | 1082 Label alloc_failure; |
| 1079 __ push(left_); | 1083 __ push(left_); |
| 1080 __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure); | 1084 __ AllocateHeapNumber(dst_, left_, no_reg, &after_alloc_failure); |
| 1081 __ pop(left_); | 1085 __ pop(left_); |
| 1082 } | 1086 } |
| (...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1568 DeferredInlineBinaryOperation* deferred = | 1572 DeferredInlineBinaryOperation* deferred = |
| 1569 new DeferredInlineBinaryOperation(op, | 1573 new DeferredInlineBinaryOperation(op, |
| 1570 answer.reg(), | 1574 answer.reg(), |
| 1571 left->reg(), | 1575 left->reg(), |
| 1572 ecx, | 1576 ecx, |
| 1573 left->number_info(), | 1577 left->number_info(), |
| 1574 right->number_info(), | 1578 right->number_info(), |
| 1575 overwrite_mode); | 1579 overwrite_mode); |
| 1576 | 1580 |
| 1577 Label do_op, left_nonsmi; | 1581 Label do_op, left_nonsmi; |
| 1578 // if right is a smi we make a fast case if left is either a smi | 1582 // If right is a smi we make a fast case if left is either a smi |
| 1579 // or a heapnumber. | 1583 // or a heapnumber. |
| 1580 if (CpuFeatures::IsSupported(SSE2) && right->number_info().IsSmi()) { | 1584 if (CpuFeatures::IsSupported(SSE2) && right->number_info().IsSmi()) { |
| 1581 CpuFeatures::Scope use_sse2(SSE2); | 1585 CpuFeatures::Scope use_sse2(SSE2); |
| 1582 __ mov(answer.reg(), left->reg()); | 1586 __ mov(answer.reg(), left->reg()); |
| 1583 // Fast case - both are actually smis. | 1587 // Fast case - both are actually smis. |
| 1584 if (!left->number_info().IsSmi()) { | 1588 if (!left->number_info().IsSmi()) { |
| 1585 __ test(answer.reg(), Immediate(kSmiTagMask)); | 1589 __ test(answer.reg(), Immediate(kSmiTagMask)); |
| 1586 __ j(not_zero, &left_nonsmi); | 1590 __ j(not_zero, &left_nonsmi); |
| 1591 } else { |
| 1592 if (FLAG_debug_code) __ AbortIfNotSmi(left->reg()); |
| 1587 } | 1593 } |
| 1594 if (FLAG_debug_code) __ AbortIfNotSmi(right->reg()); |
| 1588 __ SmiUntag(answer.reg()); | 1595 __ SmiUntag(answer.reg()); |
| 1589 __ jmp(&do_op); | 1596 __ jmp(&do_op); |
| 1590 | 1597 |
| 1591 __ bind(&left_nonsmi); | 1598 __ bind(&left_nonsmi); |
| 1592 // Branch if not a heapnumber. | 1599 // Branch if not a heapnumber. |
| 1593 __ cmp(FieldOperand(answer.reg(), HeapObject::kMapOffset), | 1600 __ cmp(FieldOperand(answer.reg(), HeapObject::kMapOffset), |
| 1594 Factory::heap_number_map()); | 1601 Factory::heap_number_map()); |
| 1595 deferred->Branch(not_equal); | 1602 deferred->Branch(not_equal); |
| 1596 | 1603 |
| 1597 // Load integer value into answer register using truncation. | 1604 // Load integer value into answer register using truncation. |
| (...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1996 deferred = new DeferredInlineSmiAdd(operand->reg(), | 2003 deferred = new DeferredInlineSmiAdd(operand->reg(), |
| 1997 operand->number_info(), | 2004 operand->number_info(), |
| 1998 smi_value, | 2005 smi_value, |
| 1999 overwrite_mode); | 2006 overwrite_mode); |
| 2000 } | 2007 } |
| 2001 __ add(Operand(operand->reg()), Immediate(value)); | 2008 __ add(Operand(operand->reg()), Immediate(value)); |
| 2002 deferred->Branch(overflow); | 2009 deferred->Branch(overflow); |
| 2003 if (!operand->number_info().IsSmi()) { | 2010 if (!operand->number_info().IsSmi()) { |
| 2004 __ test(operand->reg(), Immediate(kSmiTagMask)); | 2011 __ test(operand->reg(), Immediate(kSmiTagMask)); |
| 2005 deferred->Branch(not_zero); | 2012 deferred->Branch(not_zero); |
| 2013 } else { |
| 2014 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); |
| 2006 } | 2015 } |
| 2007 deferred->BindExit(); | 2016 deferred->BindExit(); |
| 2008 answer = *operand; | 2017 answer = *operand; |
| 2009 break; | 2018 break; |
| 2010 } | 2019 } |
| 2011 | 2020 |
| 2012 case Token::SUB: { | 2021 case Token::SUB: { |
| 2013 DeferredCode* deferred = NULL; | 2022 DeferredCode* deferred = NULL; |
| 2014 if (reversed) { | 2023 if (reversed) { |
| 2015 // The reversed case is only hit when the right operand is not a | 2024 // The reversed case is only hit when the right operand is not a |
| (...skipping 17 matching lines...) Expand all Loading... |
| 2033 deferred = new DeferredInlineSmiSub(operand->reg(), | 2042 deferred = new DeferredInlineSmiSub(operand->reg(), |
| 2034 operand->number_info(), | 2043 operand->number_info(), |
| 2035 smi_value, | 2044 smi_value, |
| 2036 overwrite_mode); | 2045 overwrite_mode); |
| 2037 __ sub(Operand(operand->reg()), Immediate(value)); | 2046 __ sub(Operand(operand->reg()), Immediate(value)); |
| 2038 } | 2047 } |
| 2039 deferred->Branch(overflow); | 2048 deferred->Branch(overflow); |
| 2040 if (!operand->number_info().IsSmi()) { | 2049 if (!operand->number_info().IsSmi()) { |
| 2041 __ test(answer.reg(), Immediate(kSmiTagMask)); | 2050 __ test(answer.reg(), Immediate(kSmiTagMask)); |
| 2042 deferred->Branch(not_zero); | 2051 deferred->Branch(not_zero); |
| 2052 } else { |
| 2053 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); |
| 2043 } | 2054 } |
| 2044 deferred->BindExit(); | 2055 deferred->BindExit(); |
| 2045 operand->Unuse(); | 2056 operand->Unuse(); |
| 2046 break; | 2057 break; |
| 2047 } | 2058 } |
| 2048 | 2059 |
| 2049 case Token::SAR: | 2060 case Token::SAR: |
| 2050 if (reversed) { | 2061 if (reversed) { |
| 2051 Result constant_operand(value); | 2062 Result constant_operand(value); |
| 2052 answer = LikelySmiBinaryOperation(op, &constant_operand, operand, | 2063 answer = LikelySmiBinaryOperation(op, &constant_operand, operand, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2066 smi_value, | 2077 smi_value, |
| 2067 overwrite_mode); | 2078 overwrite_mode); |
| 2068 __ test(operand->reg(), Immediate(kSmiTagMask)); | 2079 __ test(operand->reg(), Immediate(kSmiTagMask)); |
| 2069 deferred->Branch(not_zero); | 2080 deferred->Branch(not_zero); |
| 2070 if (shift_value > 0) { | 2081 if (shift_value > 0) { |
| 2071 __ sar(operand->reg(), shift_value); | 2082 __ sar(operand->reg(), shift_value); |
| 2072 __ and_(operand->reg(), ~kSmiTagMask); | 2083 __ and_(operand->reg(), ~kSmiTagMask); |
| 2073 } | 2084 } |
| 2074 deferred->BindExit(); | 2085 deferred->BindExit(); |
| 2075 } else { | 2086 } else { |
| 2087 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); |
| 2076 if (shift_value > 0) { | 2088 if (shift_value > 0) { |
| 2077 __ sar(operand->reg(), shift_value); | 2089 __ sar(operand->reg(), shift_value); |
| 2078 __ and_(operand->reg(), ~kSmiTagMask); | 2090 __ and_(operand->reg(), ~kSmiTagMask); |
| 2079 } | 2091 } |
| 2080 } | 2092 } |
| 2081 answer = *operand; | 2093 answer = *operand; |
| 2082 } | 2094 } |
| 2083 break; | 2095 break; |
| 2084 | 2096 |
| 2085 case Token::SHR: | 2097 case Token::SHR: |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2097 DeferredInlineSmiOperation* deferred = | 2109 DeferredInlineSmiOperation* deferred = |
| 2098 new DeferredInlineSmiOperation(op, | 2110 new DeferredInlineSmiOperation(op, |
| 2099 answer.reg(), | 2111 answer.reg(), |
| 2100 operand->reg(), | 2112 operand->reg(), |
| 2101 operand->number_info(), | 2113 operand->number_info(), |
| 2102 smi_value, | 2114 smi_value, |
| 2103 overwrite_mode); | 2115 overwrite_mode); |
| 2104 if (!operand->number_info().IsSmi()) { | 2116 if (!operand->number_info().IsSmi()) { |
| 2105 __ test(operand->reg(), Immediate(kSmiTagMask)); | 2117 __ test(operand->reg(), Immediate(kSmiTagMask)); |
| 2106 deferred->Branch(not_zero); | 2118 deferred->Branch(not_zero); |
| 2119 } else { |
| 2120 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); |
| 2107 } | 2121 } |
| 2108 __ mov(answer.reg(), operand->reg()); | 2122 __ mov(answer.reg(), operand->reg()); |
| 2109 __ SmiUntag(answer.reg()); | 2123 __ SmiUntag(answer.reg()); |
| 2110 __ shr(answer.reg(), shift_value); | 2124 __ shr(answer.reg(), shift_value); |
| 2111 // A negative Smi shifted right two is in the positive Smi range. | 2125 // A negative Smi shifted right two is in the positive Smi range. |
| 2112 if (shift_value < 2) { | 2126 if (shift_value < 2) { |
| 2113 __ test(answer.reg(), Immediate(0xc0000000)); | 2127 __ test(answer.reg(), Immediate(0xc0000000)); |
| 2114 deferred->Branch(not_zero); | 2128 deferred->Branch(not_zero); |
| 2115 } | 2129 } |
| 2116 operand->Unuse(); | 2130 operand->Unuse(); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2145 new DeferredInlineSmiOperationReversed(op, | 2159 new DeferredInlineSmiOperationReversed(op, |
| 2146 answer.reg(), | 2160 answer.reg(), |
| 2147 smi_value, | 2161 smi_value, |
| 2148 right.reg(), | 2162 right.reg(), |
| 2149 right.number_info(), | 2163 right.number_info(), |
| 2150 overwrite_mode); | 2164 overwrite_mode); |
| 2151 __ mov(answer.reg(), Immediate(int_value)); | 2165 __ mov(answer.reg(), Immediate(int_value)); |
| 2152 __ sar(ecx, kSmiTagSize); | 2166 __ sar(ecx, kSmiTagSize); |
| 2153 if (!right.number_info().IsSmi()) { | 2167 if (!right.number_info().IsSmi()) { |
| 2154 deferred->Branch(carry); | 2168 deferred->Branch(carry); |
| 2169 } else { |
| 2170 if (FLAG_debug_code) __ AbortIfNotSmi(right.reg()); |
| 2155 } | 2171 } |
| 2156 __ shl_cl(answer.reg()); | 2172 __ shl_cl(answer.reg()); |
| 2157 __ cmp(answer.reg(), 0xc0000000); | 2173 __ cmp(answer.reg(), 0xc0000000); |
| 2158 deferred->Branch(sign); | 2174 deferred->Branch(sign); |
| 2159 __ SmiTag(answer.reg()); | 2175 __ SmiTag(answer.reg()); |
| 2160 | 2176 |
| 2161 deferred->BindExit(); | 2177 deferred->BindExit(); |
| 2162 } else { | 2178 } else { |
| 2163 // Only the least significant 5 bits of the shift value are used. | 2179 // Only the least significant 5 bits of the shift value are used. |
| 2164 // In the slow case, this masking is done inside the runtime call. | 2180 // In the slow case, this masking is done inside the runtime call. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 2185 DeferredInlineSmiOperation* deferred = | 2201 DeferredInlineSmiOperation* deferred = |
| 2186 new DeferredInlineSmiOperation(op, | 2202 new DeferredInlineSmiOperation(op, |
| 2187 answer.reg(), | 2203 answer.reg(), |
| 2188 operand->reg(), | 2204 operand->reg(), |
| 2189 operand->number_info(), | 2205 operand->number_info(), |
| 2190 smi_value, | 2206 smi_value, |
| 2191 overwrite_mode); | 2207 overwrite_mode); |
| 2192 if (!operand->number_info().IsSmi()) { | 2208 if (!operand->number_info().IsSmi()) { |
| 2193 __ test(operand->reg(), Immediate(kSmiTagMask)); | 2209 __ test(operand->reg(), Immediate(kSmiTagMask)); |
| 2194 deferred->Branch(not_zero); | 2210 deferred->Branch(not_zero); |
| 2211 } else { |
| 2212 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); |
| 2195 } | 2213 } |
| 2196 __ mov(answer.reg(), operand->reg()); | 2214 __ mov(answer.reg(), operand->reg()); |
| 2197 ASSERT(kSmiTag == 0); // adjust code if not the case | 2215 ASSERT(kSmiTag == 0); // adjust code if not the case |
| 2198 // We do no shifts, only the Smi conversion, if shift_value is 1. | 2216 // We do no shifts, only the Smi conversion, if shift_value is 1. |
| 2199 if (shift_value > 1) { | 2217 if (shift_value > 1) { |
| 2200 __ shl(answer.reg(), shift_value - 1); | 2218 __ shl(answer.reg(), shift_value - 1); |
| 2201 } | 2219 } |
| 2202 // Convert int result to Smi, checking that it is in int range. | 2220 // Convert int result to Smi, checking that it is in int range. |
| 2203 ASSERT(kSmiTagSize == 1); // adjust code if not the case | 2221 ASSERT(kSmiTagSize == 1); // adjust code if not the case |
| 2204 __ add(answer.reg(), Operand(answer.reg())); | 2222 __ add(answer.reg(), Operand(answer.reg())); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2227 deferred = new DeferredInlineSmiOperation(op, | 2245 deferred = new DeferredInlineSmiOperation(op, |
| 2228 operand->reg(), | 2246 operand->reg(), |
| 2229 operand->reg(), | 2247 operand->reg(), |
| 2230 operand->number_info(), | 2248 operand->number_info(), |
| 2231 smi_value, | 2249 smi_value, |
| 2232 overwrite_mode); | 2250 overwrite_mode); |
| 2233 } | 2251 } |
| 2234 if (!operand->number_info().IsSmi()) { | 2252 if (!operand->number_info().IsSmi()) { |
| 2235 __ test(operand->reg(), Immediate(kSmiTagMask)); | 2253 __ test(operand->reg(), Immediate(kSmiTagMask)); |
| 2236 deferred->Branch(not_zero); | 2254 deferred->Branch(not_zero); |
| 2255 } else { |
| 2256 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); |
| 2237 } | 2257 } |
| 2238 if (op == Token::BIT_AND) { | 2258 if (op == Token::BIT_AND) { |
| 2239 __ and_(Operand(operand->reg()), Immediate(value)); | 2259 __ and_(Operand(operand->reg()), Immediate(value)); |
| 2240 } else if (op == Token::BIT_XOR) { | 2260 } else if (op == Token::BIT_XOR) { |
| 2241 if (int_value != 0) { | 2261 if (int_value != 0) { |
| 2242 __ xor_(Operand(operand->reg()), Immediate(value)); | 2262 __ xor_(Operand(operand->reg()), Immediate(value)); |
| 2243 } | 2263 } |
| 2244 } else { | 2264 } else { |
| 2245 ASSERT(op == Token::BIT_OR); | 2265 ASSERT(op == Token::BIT_OR); |
| 2246 if (int_value != 0) { | 2266 if (int_value != 0) { |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2420 Register left_reg = left_side.reg(); | 2440 Register left_reg = left_side.reg(); |
| 2421 Handle<Object> right_val = right_side.handle(); | 2441 Handle<Object> right_val = right_side.handle(); |
| 2422 | 2442 |
| 2423 // Here we split control flow to the stub call and inlined cases | 2443 // Here we split control flow to the stub call and inlined cases |
| 2424 // before finally splitting it to the control destination. We use | 2444 // before finally splitting it to the control destination. We use |
| 2425 // a jump target and branching to duplicate the virtual frame at | 2445 // a jump target and branching to duplicate the virtual frame at |
| 2426 // the first split. We manually handle the off-frame references | 2446 // the first split. We manually handle the off-frame references |
| 2427 // by reconstituting them on the non-fall-through path. | 2447 // by reconstituting them on the non-fall-through path. |
| 2428 | 2448 |
| 2429 if (left_side.is_smi()) { | 2449 if (left_side.is_smi()) { |
| 2430 if (FLAG_debug_code) { | 2450 if (FLAG_debug_code) __ AbortIfNotSmi(left_side.reg()); |
| 2431 __ AbortIfNotSmi(left_side.reg(), "Argument not a smi"); | |
| 2432 } | |
| 2433 } else { | 2451 } else { |
| 2434 JumpTarget is_smi; | 2452 JumpTarget is_smi; |
| 2435 __ test(left_side.reg(), Immediate(kSmiTagMask)); | 2453 __ test(left_side.reg(), Immediate(kSmiTagMask)); |
| 2436 is_smi.Branch(zero, taken); | 2454 is_smi.Branch(zero, taken); |
| 2437 | 2455 |
| 2438 bool is_for_loop_compare = (node->AsCompareOperation() != NULL) | 2456 bool is_for_loop_compare = (node->AsCompareOperation() != NULL) |
| 2439 && node->AsCompareOperation()->is_for_loop_condition(); | 2457 && node->AsCompareOperation()->is_for_loop_condition(); |
| 2440 if (!is_for_loop_compare | 2458 if (!is_for_loop_compare |
| 2441 && CpuFeatures::IsSupported(SSE2) | 2459 && CpuFeatures::IsSupported(SSE2) |
| 2442 && right_val->IsSmi()) { | 2460 && right_val->IsSmi()) { |
| (...skipping 1290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3733 | 3751 |
| 3734 if (node->is_fast_smi_loop()) { | 3752 if (node->is_fast_smi_loop()) { |
| 3735 // Set number type of the loop variable to smi. | 3753 // Set number type of the loop variable to smi. |
| 3736 Slot* slot = node->loop_variable()->slot(); | 3754 Slot* slot = node->loop_variable()->slot(); |
| 3737 ASSERT(slot->type() == Slot::LOCAL); | 3755 ASSERT(slot->type() == Slot::LOCAL); |
| 3738 frame_->SetTypeForLocalAt(slot->index(), NumberInfo::Smi()); | 3756 frame_->SetTypeForLocalAt(slot->index(), NumberInfo::Smi()); |
| 3739 if (FLAG_debug_code) { | 3757 if (FLAG_debug_code) { |
| 3740 frame_->PushLocalAt(slot->index()); | 3758 frame_->PushLocalAt(slot->index()); |
| 3741 Result var = frame_->Pop(); | 3759 Result var = frame_->Pop(); |
| 3742 var.ToRegister(); | 3760 var.ToRegister(); |
| 3743 __ AbortIfNotSmi(var.reg(), "Loop variable not a smi."); | 3761 __ AbortIfNotSmi(var.reg()); |
| 3744 } | 3762 } |
| 3745 } | 3763 } |
| 3746 | 3764 |
| 3747 Visit(node->body()); | 3765 Visit(node->body()); |
| 3748 | 3766 |
| 3749 // If there is an update expression, compile it if necessary. | 3767 // If there is an update expression, compile it if necessary. |
| 3750 if (node->next() != NULL) { | 3768 if (node->next() != NULL) { |
| 3751 if (node->continue_target()->is_linked()) { | 3769 if (node->continue_target()->is_linked()) { |
| 3752 node->continue_target()->Bind(); | 3770 node->continue_target()->Bind(); |
| 3753 } | 3771 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3767 // set it to smi before compiling the test expression. | 3785 // set it to smi before compiling the test expression. |
| 3768 if (node->is_fast_smi_loop()) { | 3786 if (node->is_fast_smi_loop()) { |
| 3769 // Set number type of the loop variable to smi. | 3787 // Set number type of the loop variable to smi. |
| 3770 Slot* slot = node->loop_variable()->slot(); | 3788 Slot* slot = node->loop_variable()->slot(); |
| 3771 ASSERT(slot->type() == Slot::LOCAL); | 3789 ASSERT(slot->type() == Slot::LOCAL); |
| 3772 frame_->SetTypeForLocalAt(slot->index(), NumberInfo::Smi()); | 3790 frame_->SetTypeForLocalAt(slot->index(), NumberInfo::Smi()); |
| 3773 if (FLAG_debug_code) { | 3791 if (FLAG_debug_code) { |
| 3774 frame_->PushLocalAt(slot->index()); | 3792 frame_->PushLocalAt(slot->index()); |
| 3775 Result var = frame_->Pop(); | 3793 Result var = frame_->Pop(); |
| 3776 var.ToRegister(); | 3794 var.ToRegister(); |
| 3777 __ AbortIfNotSmi(var.reg(), "Loop variable not a smi."); | 3795 __ AbortIfNotSmi(var.reg()); |
| 3778 } | 3796 } |
| 3779 } | 3797 } |
| 3780 | 3798 |
| 3781 // Based on the condition analysis, compile the backward jump as | 3799 // Based on the condition analysis, compile the backward jump as |
| 3782 // necessary. | 3800 // necessary. |
| 3783 switch (info) { | 3801 switch (info) { |
| 3784 case ALWAYS_TRUE: | 3802 case ALWAYS_TRUE: |
| 3785 if (has_valid_frame()) { | 3803 if (has_valid_frame()) { |
| 3786 if (node->next() == NULL) { | 3804 if (node->next() == NULL) { |
| 3787 node->continue_target()->Jump(); | 3805 node->continue_target()->Jump(); |
| (...skipping 2896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6684 break; | 6702 break; |
| 6685 } | 6703 } |
| 6686 case Token::BIT_NOT: { | 6704 case Token::BIT_NOT: { |
| 6687 // Smi check. | 6705 // Smi check. |
| 6688 JumpTarget smi_label; | 6706 JumpTarget smi_label; |
| 6689 JumpTarget continue_label; | 6707 JumpTarget continue_label; |
| 6690 Result operand = frame_->Pop(); | 6708 Result operand = frame_->Pop(); |
| 6691 NumberInfo operand_info = operand.number_info(); | 6709 NumberInfo operand_info = operand.number_info(); |
| 6692 operand.ToRegister(); | 6710 operand.ToRegister(); |
| 6693 if (operand_info.IsSmi()) { | 6711 if (operand_info.IsSmi()) { |
| 6694 if (FLAG_debug_code) { | 6712 if (FLAG_debug_code) __ AbortIfNotSmi(operand.reg()); |
| 6695 __ AbortIfNotSmi(operand.reg(), "Operand not a smi."); | |
| 6696 } | |
| 6697 frame_->Spill(operand.reg()); | 6713 frame_->Spill(operand.reg()); |
| 6698 // Set smi tag bit. It will be reset by the not operation. | 6714 // Set smi tag bit. It will be reset by the not operation. |
| 6699 __ lea(operand.reg(), Operand(operand.reg(), kSmiTagMask)); | 6715 __ lea(operand.reg(), Operand(operand.reg(), kSmiTagMask)); |
| 6700 __ not_(operand.reg()); | 6716 __ not_(operand.reg()); |
| 6701 Result answer = operand; | 6717 Result answer = operand; |
| 6702 answer.set_number_info(NumberInfo::Smi()); | 6718 answer.set_number_info(NumberInfo::Smi()); |
| 6703 frame_->Push(&answer); | 6719 frame_->Push(&answer); |
| 6704 } else { | 6720 } else { |
| 6705 __ test(operand.reg(), Immediate(kSmiTagMask)); | 6721 __ test(operand.reg(), Immediate(kSmiTagMask)); |
| 6706 smi_label.Branch(zero, &operand, taken); | 6722 smi_label.Branch(zero, &operand, taken); |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6886 // The old value that is return for postfix operations has the | 6902 // The old value that is return for postfix operations has the |
| 6887 // same type as the input value we got from the frame. | 6903 // same type as the input value we got from the frame. |
| 6888 old_value.set_number_info(new_value.number_info()); | 6904 old_value.set_number_info(new_value.number_info()); |
| 6889 } | 6905 } |
| 6890 | 6906 |
| 6891 // Ensure the new value is writable. | 6907 // Ensure the new value is writable. |
| 6892 frame_->Spill(new_value.reg()); | 6908 frame_->Spill(new_value.reg()); |
| 6893 | 6909 |
| 6894 Result tmp; | 6910 Result tmp; |
| 6895 if (new_value.is_smi()) { | 6911 if (new_value.is_smi()) { |
| 6896 if (FLAG_debug_code) { | 6912 if (FLAG_debug_code) __ AbortIfNotSmi(new_value.reg()); |
| 6897 __ AbortIfNotSmi(new_value.reg(), "Operand not a smi"); | |
| 6898 } | |
| 6899 } else { | 6913 } else { |
| 6900 // We don't know statically if the input is a smi. | 6914 // We don't know statically if the input is a smi. |
| 6901 // In order to combine the overflow and the smi tag check, we need | 6915 // In order to combine the overflow and the smi tag check, we need |
| 6902 // to be able to allocate a byte register. We attempt to do so | 6916 // to be able to allocate a byte register. We attempt to do so |
| 6903 // without spilling. If we fail, we will generate separate overflow | 6917 // without spilling. If we fail, we will generate separate overflow |
| 6904 // and smi tag checks. | 6918 // and smi tag checks. |
| 6905 // We allocate and clear a temporary byte register before performing | 6919 // We allocate and clear a temporary byte register before performing |
| 6906 // the count operation since clearing the register using xor will clear | 6920 // the count operation since clearing the register using xor will clear |
| 6907 // the overflow flag. | 6921 // the overflow flag. |
| 6908 tmp = allocator_->AllocateByteRegisterWithoutSpilling(); | 6922 tmp = allocator_->AllocateByteRegisterWithoutSpilling(); |
| (...skipping 938 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7847 // Use masm-> here instead of the double underscore macro since extra | 7861 // Use masm-> here instead of the double underscore macro since extra |
| 7848 // coverage code can interfere with the patching. | 7862 // coverage code can interfere with the patching. |
| 7849 masm_->cmp(FieldOperand(receiver.reg(), HeapObject::kMapOffset), | 7863 masm_->cmp(FieldOperand(receiver.reg(), HeapObject::kMapOffset), |
| 7850 Immediate(Factory::null_value())); | 7864 Immediate(Factory::null_value())); |
| 7851 deferred->Branch(not_equal); | 7865 deferred->Branch(not_equal); |
| 7852 | 7866 |
| 7853 // Check that the key is a smi. | 7867 // Check that the key is a smi. |
| 7854 if (!key.is_smi()) { | 7868 if (!key.is_smi()) { |
| 7855 __ test(key.reg(), Immediate(kSmiTagMask)); | 7869 __ test(key.reg(), Immediate(kSmiTagMask)); |
| 7856 deferred->Branch(not_zero); | 7870 deferred->Branch(not_zero); |
| 7871 } else { |
| 7872 if (FLAG_debug_code) __ AbortIfNotSmi(key.reg()); |
| 7857 } | 7873 } |
| 7858 | 7874 |
| 7859 // Get the elements array from the receiver and check that it | 7875 // Get the elements array from the receiver and check that it |
| 7860 // is not a dictionary. | 7876 // is not a dictionary. |
| 7861 __ mov(elements.reg(), | 7877 __ mov(elements.reg(), |
| 7862 FieldOperand(receiver.reg(), JSObject::kElementsOffset)); | 7878 FieldOperand(receiver.reg(), JSObject::kElementsOffset)); |
| 7863 __ cmp(FieldOperand(elements.reg(), HeapObject::kMapOffset), | 7879 __ cmp(FieldOperand(elements.reg(), HeapObject::kMapOffset), |
| 7864 Immediate(Factory::fixed_array_map())); | 7880 Immediate(Factory::fixed_array_map())); |
| 7865 deferred->Branch(not_equal); | 7881 deferred->Branch(not_equal); |
| 7866 | 7882 |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8000 | 8016 |
| 8001 | 8017 |
| 8002 static void CheckTwoForSminess(MacroAssembler* masm, | 8018 static void CheckTwoForSminess(MacroAssembler* masm, |
| 8003 Register left, Register right, Register scratch, | 8019 Register left, Register right, Register scratch, |
| 8004 NumberInfo left_info, NumberInfo right_info, | 8020 NumberInfo left_info, NumberInfo right_info, |
| 8005 DeferredInlineBinaryOperation* deferred) { | 8021 DeferredInlineBinaryOperation* deferred) { |
| 8006 if (left.is(right)) { | 8022 if (left.is(right)) { |
| 8007 if (!left_info.IsSmi()) { | 8023 if (!left_info.IsSmi()) { |
| 8008 __ test(left, Immediate(kSmiTagMask)); | 8024 __ test(left, Immediate(kSmiTagMask)); |
| 8009 deferred->Branch(not_zero); | 8025 deferred->Branch(not_zero); |
| 8026 } else { |
| 8027 if (FLAG_debug_code) __ AbortIfNotSmi(left); |
| 8010 } | 8028 } |
| 8011 } else if (!left_info.IsSmi()) { | 8029 } else if (!left_info.IsSmi()) { |
| 8012 if (!right_info.IsSmi()) { | 8030 if (!right_info.IsSmi()) { |
| 8013 __ mov(scratch, left); | 8031 __ mov(scratch, left); |
| 8014 __ or_(scratch, Operand(right)); | 8032 __ or_(scratch, Operand(right)); |
| 8015 __ test(scratch, Immediate(kSmiTagMask)); | 8033 __ test(scratch, Immediate(kSmiTagMask)); |
| 8016 deferred->Branch(not_zero); | 8034 deferred->Branch(not_zero); |
| 8017 } else { | 8035 } else { |
| 8018 __ test(left, Immediate(kSmiTagMask)); | 8036 __ test(left, Immediate(kSmiTagMask)); |
| 8019 deferred->Branch(not_zero); | 8037 deferred->Branch(not_zero); |
| 8038 if (FLAG_debug_code) __ AbortIfNotSmi(right); |
| 8020 } | 8039 } |
| 8021 } else { | 8040 } else { |
| 8041 if (FLAG_debug_code) __ AbortIfNotSmi(left); |
| 8022 if (!right_info.IsSmi()) { | 8042 if (!right_info.IsSmi()) { |
| 8023 __ test(right, Immediate(kSmiTagMask)); | 8043 __ test(right, Immediate(kSmiTagMask)); |
| 8024 deferred->Branch(not_zero); | 8044 deferred->Branch(not_zero); |
| 8045 } else { |
| 8046 if (FLAG_debug_code) __ AbortIfNotSmi(right); |
| 8025 } | 8047 } |
| 8026 } | 8048 } |
| 8027 } | 8049 } |
| 8028 | 8050 |
| 8029 | 8051 |
| 8030 Handle<String> Reference::GetName() { | 8052 Handle<String> Reference::GetName() { |
| 8031 ASSERT(type_ == NAMED); | 8053 ASSERT(type_ == NAMED); |
| 8032 Property* property = expression_->AsProperty(); | 8054 Property* property = expression_->AsProperty(); |
| 8033 if (property == NULL) { | 8055 if (property == NULL) { |
| 8034 // Global variable reference treated as a named property reference. | 8056 // Global variable reference treated as a named property reference. |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8521 __ mov(ebx, eax); | 8543 __ mov(ebx, eax); |
| 8522 __ mov(eax, edx); | 8544 __ mov(eax, edx); |
| 8523 } | 8545 } |
| 8524 } | 8546 } |
| 8525 if (!HasArgsInRegisters()) { | 8547 if (!HasArgsInRegisters()) { |
| 8526 __ mov(right, Operand(esp, 1 * kPointerSize)); | 8548 __ mov(right, Operand(esp, 1 * kPointerSize)); |
| 8527 __ mov(left, Operand(esp, 2 * kPointerSize)); | 8549 __ mov(left, Operand(esp, 2 * kPointerSize)); |
| 8528 } | 8550 } |
| 8529 | 8551 |
| 8530 if (static_operands_type_.IsSmi()) { | 8552 if (static_operands_type_.IsSmi()) { |
| 8553 if (FLAG_debug_code) { |
| 8554 __ AbortIfNotSmi(left); |
| 8555 __ AbortIfNotSmi(right); |
| 8556 } |
| 8531 if (op_ == Token::BIT_OR) { | 8557 if (op_ == Token::BIT_OR) { |
| 8532 __ or_(right, Operand(left)); | 8558 __ or_(right, Operand(left)); |
| 8533 GenerateReturn(masm); | 8559 GenerateReturn(masm); |
| 8534 return; | 8560 return; |
| 8535 } else if (op_ == Token::BIT_AND) { | 8561 } else if (op_ == Token::BIT_AND) { |
| 8536 __ and_(right, Operand(left)); | 8562 __ and_(right, Operand(left)); |
| 8537 GenerateReturn(masm); | 8563 GenerateReturn(masm); |
| 8538 return; | 8564 return; |
| 8539 } else if (op_ == Token::BIT_XOR) { | 8565 } else if (op_ == Token::BIT_XOR) { |
| 8540 __ xor_(right, Operand(left)); | 8566 __ xor_(right, Operand(left)); |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8875 // forever for all other operations (also if smi code is skipped). | 8901 // forever for all other operations (also if smi code is skipped). |
| 8876 GenerateTypeTransition(masm); | 8902 GenerateTypeTransition(masm); |
| 8877 } | 8903 } |
| 8878 | 8904 |
| 8879 Label not_floats; | 8905 Label not_floats; |
| 8880 if (CpuFeatures::IsSupported(SSE2)) { | 8906 if (CpuFeatures::IsSupported(SSE2)) { |
| 8881 CpuFeatures::Scope use_sse2(SSE2); | 8907 CpuFeatures::Scope use_sse2(SSE2); |
| 8882 if (static_operands_type_.IsNumber()) { | 8908 if (static_operands_type_.IsNumber()) { |
| 8883 if (FLAG_debug_code) { | 8909 if (FLAG_debug_code) { |
| 8884 // Assert at runtime that inputs are only numbers. | 8910 // Assert at runtime that inputs are only numbers. |
| 8885 __ AbortIfNotNumber(edx, | 8911 __ AbortIfNotNumber(edx); |
| 8886 "GenericBinaryOpStub operand not a number."); | 8912 __ AbortIfNotNumber(eax); |
| 8887 __ AbortIfNotNumber(eax, | |
| 8888 "GenericBinaryOpStub operand not a number."); | |
| 8889 } | 8913 } |
| 8890 if (static_operands_type_.IsSmi()) { | 8914 if (static_operands_type_.IsSmi()) { |
| 8915 if (FLAG_debug_code) { |
| 8916 __ AbortIfNotSmi(edx); |
| 8917 __ AbortIfNotSmi(eax); |
| 8918 } |
| 8891 FloatingPointHelper::LoadSSE2Smis(masm, ecx); | 8919 FloatingPointHelper::LoadSSE2Smis(masm, ecx); |
| 8892 } else { | 8920 } else { |
| 8893 FloatingPointHelper::LoadSSE2Operands(masm); | 8921 FloatingPointHelper::LoadSSE2Operands(masm); |
| 8894 } | 8922 } |
| 8895 } else { | 8923 } else { |
| 8896 FloatingPointHelper::LoadSSE2Operands(masm, &call_runtime); | 8924 FloatingPointHelper::LoadSSE2Operands(masm, &call_runtime); |
| 8897 } | 8925 } |
| 8898 | 8926 |
| 8899 switch (op_) { | 8927 switch (op_) { |
| 8900 case Token::ADD: __ addsd(xmm0, xmm1); break; | 8928 case Token::ADD: __ addsd(xmm0, xmm1); break; |
| 8901 case Token::SUB: __ subsd(xmm0, xmm1); break; | 8929 case Token::SUB: __ subsd(xmm0, xmm1); break; |
| 8902 case Token::MUL: __ mulsd(xmm0, xmm1); break; | 8930 case Token::MUL: __ mulsd(xmm0, xmm1); break; |
| 8903 case Token::DIV: __ divsd(xmm0, xmm1); break; | 8931 case Token::DIV: __ divsd(xmm0, xmm1); break; |
| 8904 default: UNREACHABLE(); | 8932 default: UNREACHABLE(); |
| 8905 } | 8933 } |
| 8906 GenerateHeapResultAllocation(masm, &call_runtime); | 8934 GenerateHeapResultAllocation(masm, &call_runtime); |
| 8907 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); | 8935 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); |
| 8908 GenerateReturn(masm); | 8936 GenerateReturn(masm); |
| 8909 } else { // SSE2 not available, use FPU. | 8937 } else { // SSE2 not available, use FPU. |
| 8910 if (static_operands_type_.IsNumber()) { | 8938 if (static_operands_type_.IsNumber()) { |
| 8911 if (FLAG_debug_code) { | 8939 if (FLAG_debug_code) { |
| 8912 // Assert at runtime that inputs are only numbers. | 8940 // Assert at runtime that inputs are only numbers. |
| 8913 __ AbortIfNotNumber(edx, | 8941 __ AbortIfNotNumber(edx); |
| 8914 "GenericBinaryOpStub operand not a number."); | 8942 __ AbortIfNotNumber(eax); |
| 8915 __ AbortIfNotNumber(eax, | |
| 8916 "GenericBinaryOpStub operand not a number."); | |
| 8917 } | 8943 } |
| 8918 } else { | 8944 } else { |
| 8919 FloatingPointHelper::CheckFloatOperands(masm, &call_runtime, ebx); | 8945 FloatingPointHelper::CheckFloatOperands(masm, &call_runtime, ebx); |
| 8920 } | 8946 } |
| 8921 FloatingPointHelper::LoadFloatOperands( | 8947 FloatingPointHelper::LoadFloatOperands( |
| 8922 masm, | 8948 masm, |
| 8923 ecx, | 8949 ecx, |
| 8924 FloatingPointHelper::ARGS_IN_REGISTERS); | 8950 FloatingPointHelper::ARGS_IN_REGISTERS); |
| 8925 switch (op_) { | 8951 switch (op_) { |
| 8926 case Token::ADD: __ faddp(1); break; | 8952 case Token::ADD: __ faddp(1); break; |
| (...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9636 Label* conversion_failure) { | 9662 Label* conversion_failure) { |
| 9637 // Check float operands. | 9663 // Check float operands. |
| 9638 Label arg1_is_object, check_undefined_arg1; | 9664 Label arg1_is_object, check_undefined_arg1; |
| 9639 Label arg2_is_object, check_undefined_arg2; | 9665 Label arg2_is_object, check_undefined_arg2; |
| 9640 Label load_arg2, done; | 9666 Label load_arg2, done; |
| 9641 | 9667 |
| 9642 if (!number_info.IsHeapNumber()) { | 9668 if (!number_info.IsHeapNumber()) { |
| 9643 if (!number_info.IsSmi()) { | 9669 if (!number_info.IsSmi()) { |
| 9644 __ test(edx, Immediate(kSmiTagMask)); | 9670 __ test(edx, Immediate(kSmiTagMask)); |
| 9645 __ j(not_zero, &arg1_is_object); | 9671 __ j(not_zero, &arg1_is_object); |
| 9672 } else { |
| 9673 if (FLAG_debug_code) __ AbortIfNotSmi(edx); |
| 9646 } | 9674 } |
| 9647 __ SmiUntag(edx); | 9675 __ SmiUntag(edx); |
| 9648 __ jmp(&load_arg2); | 9676 __ jmp(&load_arg2); |
| 9649 } | 9677 } |
| 9650 | 9678 |
| 9651 __ bind(&arg1_is_object); | 9679 __ bind(&arg1_is_object); |
| 9652 | 9680 |
| 9653 // Get the untagged integer version of the edx heap number in ecx. | 9681 // Get the untagged integer version of the edx heap number in ecx. |
| 9654 IntegerConvert(masm, edx, number_info, use_sse3, conversion_failure); | 9682 IntegerConvert(masm, edx, number_info, use_sse3, conversion_failure); |
| 9655 __ mov(edx, ecx); | 9683 __ mov(edx, ecx); |
| 9656 | 9684 |
| 9657 // Here edx has the untagged integer, eax has a Smi or a heap number. | 9685 // Here edx has the untagged integer, eax has a Smi or a heap number. |
| 9658 __ bind(&load_arg2); | 9686 __ bind(&load_arg2); |
| 9659 if (!number_info.IsHeapNumber()) { | 9687 if (!number_info.IsHeapNumber()) { |
| 9660 // Test if arg2 is a Smi. | 9688 // Test if arg2 is a Smi. |
| 9661 if (!number_info.IsSmi()) { | 9689 if (!number_info.IsSmi()) { |
| 9662 __ test(eax, Immediate(kSmiTagMask)); | 9690 __ test(eax, Immediate(kSmiTagMask)); |
| 9663 __ j(not_zero, &arg2_is_object); | 9691 __ j(not_zero, &arg2_is_object); |
| 9692 } else { |
| 9693 if (FLAG_debug_code) __ AbortIfNotSmi(eax); |
| 9664 } | 9694 } |
| 9665 __ SmiUntag(eax); | 9695 __ SmiUntag(eax); |
| 9666 __ mov(ecx, eax); | 9696 __ mov(ecx, eax); |
| 9667 __ jmp(&done); | 9697 __ jmp(&done); |
| 9668 } | 9698 } |
| 9669 | 9699 |
| 9670 __ bind(&arg2_is_object); | 9700 __ bind(&arg2_is_object); |
| 9671 | 9701 |
| 9672 // Get the untagged integer version of the eax heap number in ecx. | 9702 // Get the untagged integer version of the eax heap number in ecx. |
| 9673 IntegerConvert(masm, eax, number_info, use_sse3, conversion_failure); | 9703 IntegerConvert(masm, eax, number_info, use_sse3, conversion_failure); |
| (...skipping 2568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12242 | 12272 |
| 12243 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 12273 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
| 12244 // tagged as a small integer. | 12274 // tagged as a small integer. |
| 12245 __ bind(&runtime); | 12275 __ bind(&runtime); |
| 12246 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 12276 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
| 12247 } | 12277 } |
| 12248 | 12278 |
| 12249 #undef __ | 12279 #undef __ |
| 12250 | 12280 |
| 12251 } } // namespace v8::internal | 12281 } } // namespace v8::internal |
| OLD | NEW |