| 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 1291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3734 // the bottom check of the loop condition. | 3752 // the bottom check of the loop condition. |
| 3735 if (node->is_fast_smi_loop()) { | 3753 if (node->is_fast_smi_loop()) { |
| 3736 // Set number type of the loop variable to smi. | 3754 // Set number type of the loop variable to smi. |
| 3737 Slot* slot = node->loop_variable()->slot(); | 3755 Slot* slot = node->loop_variable()->slot(); |
| 3738 ASSERT(slot->type() == Slot::LOCAL); | 3756 ASSERT(slot->type() == Slot::LOCAL); |
| 3739 frame_->SetTypeForLocalAt(slot->index(), NumberInfo::Smi()); | 3757 frame_->SetTypeForLocalAt(slot->index(), NumberInfo::Smi()); |
| 3740 if (FLAG_debug_code) { | 3758 if (FLAG_debug_code) { |
| 3741 frame_->PushLocalAt(slot->index()); | 3759 frame_->PushLocalAt(slot->index()); |
| 3742 Result var = frame_->Pop(); | 3760 Result var = frame_->Pop(); |
| 3743 var.ToRegister(); | 3761 var.ToRegister(); |
| 3744 __ AbortIfNotSmi(var.reg(), "Loop variable not a smi."); | 3762 __ AbortIfNotSmi(var.reg()); |
| 3745 } | 3763 } |
| 3746 } | 3764 } |
| 3747 | 3765 |
| 3748 Visit(node->body()); | 3766 Visit(node->body()); |
| 3749 | 3767 |
| 3750 // If there is an update expression, compile it if necessary. | 3768 // If there is an update expression, compile it if necessary. |
| 3751 if (node->next() != NULL) { | 3769 if (node->next() != NULL) { |
| 3752 if (node->continue_target()->is_linked()) { | 3770 if (node->continue_target()->is_linked()) { |
| 3753 node->continue_target()->Bind(); | 3771 node->continue_target()->Bind(); |
| 3754 } | 3772 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3768 // expression if we are in a fast smi loop condition. | 3786 // expression if we are in a fast smi loop condition. |
| 3769 if (node->is_fast_smi_loop() && has_valid_frame()) { | 3787 if (node->is_fast_smi_loop() && has_valid_frame()) { |
| 3770 // Set number type of the loop variable to smi. | 3788 // Set number type of the loop variable to smi. |
| 3771 Slot* slot = node->loop_variable()->slot(); | 3789 Slot* slot = node->loop_variable()->slot(); |
| 3772 ASSERT(slot->type() == Slot::LOCAL); | 3790 ASSERT(slot->type() == Slot::LOCAL); |
| 3773 frame_->SetTypeForLocalAt(slot->index(), NumberInfo::Smi()); | 3791 frame_->SetTypeForLocalAt(slot->index(), NumberInfo::Smi()); |
| 3774 if (FLAG_debug_code) { | 3792 if (FLAG_debug_code) { |
| 3775 frame_->PushLocalAt(slot->index()); | 3793 frame_->PushLocalAt(slot->index()); |
| 3776 Result var = frame_->Pop(); | 3794 Result var = frame_->Pop(); |
| 3777 var.ToRegister(); | 3795 var.ToRegister(); |
| 3778 __ AbortIfNotSmi(var.reg(), "Loop variable not a smi."); | 3796 __ AbortIfNotSmi(var.reg()); |
| 3779 } | 3797 } |
| 3780 } | 3798 } |
| 3781 | 3799 |
| 3782 // Based on the condition analysis, compile the backward jump as | 3800 // Based on the condition analysis, compile the backward jump as |
| 3783 // necessary. | 3801 // necessary. |
| 3784 switch (info) { | 3802 switch (info) { |
| 3785 case ALWAYS_TRUE: | 3803 case ALWAYS_TRUE: |
| 3786 if (has_valid_frame()) { | 3804 if (has_valid_frame()) { |
| 3787 if (node->next() == NULL) { | 3805 if (node->next() == NULL) { |
| 3788 node->continue_target()->Jump(); | 3806 node->continue_target()->Jump(); |
| (...skipping 2896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6685 break; | 6703 break; |
| 6686 } | 6704 } |
| 6687 case Token::BIT_NOT: { | 6705 case Token::BIT_NOT: { |
| 6688 // Smi check. | 6706 // Smi check. |
| 6689 JumpTarget smi_label; | 6707 JumpTarget smi_label; |
| 6690 JumpTarget continue_label; | 6708 JumpTarget continue_label; |
| 6691 Result operand = frame_->Pop(); | 6709 Result operand = frame_->Pop(); |
| 6692 NumberInfo operand_info = operand.number_info(); | 6710 NumberInfo operand_info = operand.number_info(); |
| 6693 operand.ToRegister(); | 6711 operand.ToRegister(); |
| 6694 if (operand_info.IsSmi()) { | 6712 if (operand_info.IsSmi()) { |
| 6695 if (FLAG_debug_code) { | 6713 if (FLAG_debug_code) __ AbortIfNotSmi(operand.reg()); |
| 6696 __ AbortIfNotSmi(operand.reg(), "Operand not a smi."); | |
| 6697 } | |
| 6698 frame_->Spill(operand.reg()); | 6714 frame_->Spill(operand.reg()); |
| 6699 // Set smi tag bit. It will be reset by the not operation. | 6715 // Set smi tag bit. It will be reset by the not operation. |
| 6700 __ lea(operand.reg(), Operand(operand.reg(), kSmiTagMask)); | 6716 __ lea(operand.reg(), Operand(operand.reg(), kSmiTagMask)); |
| 6701 __ not_(operand.reg()); | 6717 __ not_(operand.reg()); |
| 6702 Result answer = operand; | 6718 Result answer = operand; |
| 6703 answer.set_number_info(NumberInfo::Smi()); | 6719 answer.set_number_info(NumberInfo::Smi()); |
| 6704 frame_->Push(&answer); | 6720 frame_->Push(&answer); |
| 6705 } else { | 6721 } else { |
| 6706 __ test(operand.reg(), Immediate(kSmiTagMask)); | 6722 __ test(operand.reg(), Immediate(kSmiTagMask)); |
| 6707 smi_label.Branch(zero, &operand, taken); | 6723 smi_label.Branch(zero, &operand, taken); |
| (...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6887 // The return value for postfix operations is the | 6903 // The return value for postfix operations is the |
| 6888 // same as the input, and has the same number info. | 6904 // same as the input, and has the same number info. |
| 6889 old_value.set_number_info(new_value.number_info()); | 6905 old_value.set_number_info(new_value.number_info()); |
| 6890 } | 6906 } |
| 6891 | 6907 |
| 6892 // Ensure the new value is writable. | 6908 // Ensure the new value is writable. |
| 6893 frame_->Spill(new_value.reg()); | 6909 frame_->Spill(new_value.reg()); |
| 6894 | 6910 |
| 6895 Result tmp; | 6911 Result tmp; |
| 6896 if (new_value.is_smi()) { | 6912 if (new_value.is_smi()) { |
| 6897 if (FLAG_debug_code) { | 6913 if (FLAG_debug_code) __ AbortIfNotSmi(new_value.reg()); |
| 6898 __ AbortIfNotSmi(new_value.reg(), "Operand not a smi"); | |
| 6899 } | |
| 6900 } else { | 6914 } else { |
| 6901 // We don't know statically if the input is a smi. | 6915 // We don't know statically if the input is a smi. |
| 6902 // In order to combine the overflow and the smi tag check, we need | 6916 // In order to combine the overflow and the smi tag check, we need |
| 6903 // to be able to allocate a byte register. We attempt to do so | 6917 // to be able to allocate a byte register. We attempt to do so |
| 6904 // without spilling. If we fail, we will generate separate overflow | 6918 // without spilling. If we fail, we will generate separate overflow |
| 6905 // and smi tag checks. | 6919 // and smi tag checks. |
| 6906 // We allocate and clear a temporary byte register before performing | 6920 // We allocate and clear a temporary byte register before performing |
| 6907 // the count operation since clearing the register using xor will clear | 6921 // the count operation since clearing the register using xor will clear |
| 6908 // the overflow flag. | 6922 // the overflow flag. |
| 6909 tmp = allocator_->AllocateByteRegisterWithoutSpilling(); | 6923 tmp = allocator_->AllocateByteRegisterWithoutSpilling(); |
| (...skipping 943 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7853 // Use masm-> here instead of the double underscore macro since extra | 7867 // Use masm-> here instead of the double underscore macro since extra |
| 7854 // coverage code can interfere with the patching. | 7868 // coverage code can interfere with the patching. |
| 7855 masm_->cmp(FieldOperand(receiver.reg(), HeapObject::kMapOffset), | 7869 masm_->cmp(FieldOperand(receiver.reg(), HeapObject::kMapOffset), |
| 7856 Immediate(Factory::null_value())); | 7870 Immediate(Factory::null_value())); |
| 7857 deferred->Branch(not_equal); | 7871 deferred->Branch(not_equal); |
| 7858 | 7872 |
| 7859 // Check that the key is a smi. | 7873 // Check that the key is a smi. |
| 7860 if (!key.is_smi()) { | 7874 if (!key.is_smi()) { |
| 7861 __ test(key.reg(), Immediate(kSmiTagMask)); | 7875 __ test(key.reg(), Immediate(kSmiTagMask)); |
| 7862 deferred->Branch(not_zero); | 7876 deferred->Branch(not_zero); |
| 7877 } else { |
| 7878 if (FLAG_debug_code) __ AbortIfNotSmi(key.reg()); |
| 7863 } | 7879 } |
| 7864 | 7880 |
| 7865 // Get the elements array from the receiver and check that it | 7881 // Get the elements array from the receiver and check that it |
| 7866 // is not a dictionary. | 7882 // is not a dictionary. |
| 7867 __ mov(elements.reg(), | 7883 __ mov(elements.reg(), |
| 7868 FieldOperand(receiver.reg(), JSObject::kElementsOffset)); | 7884 FieldOperand(receiver.reg(), JSObject::kElementsOffset)); |
| 7869 __ cmp(FieldOperand(elements.reg(), HeapObject::kMapOffset), | 7885 __ cmp(FieldOperand(elements.reg(), HeapObject::kMapOffset), |
| 7870 Immediate(Factory::fixed_array_map())); | 7886 Immediate(Factory::fixed_array_map())); |
| 7871 deferred->Branch(not_equal); | 7887 deferred->Branch(not_equal); |
| 7872 | 7888 |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8006 | 8022 |
| 8007 | 8023 |
| 8008 static void CheckTwoForSminess(MacroAssembler* masm, | 8024 static void CheckTwoForSminess(MacroAssembler* masm, |
| 8009 Register left, Register right, Register scratch, | 8025 Register left, Register right, Register scratch, |
| 8010 NumberInfo left_info, NumberInfo right_info, | 8026 NumberInfo left_info, NumberInfo right_info, |
| 8011 DeferredInlineBinaryOperation* deferred) { | 8027 DeferredInlineBinaryOperation* deferred) { |
| 8012 if (left.is(right)) { | 8028 if (left.is(right)) { |
| 8013 if (!left_info.IsSmi()) { | 8029 if (!left_info.IsSmi()) { |
| 8014 __ test(left, Immediate(kSmiTagMask)); | 8030 __ test(left, Immediate(kSmiTagMask)); |
| 8015 deferred->Branch(not_zero); | 8031 deferred->Branch(not_zero); |
| 8032 } else { |
| 8033 if (FLAG_debug_code) __ AbortIfNotSmi(left); |
| 8016 } | 8034 } |
| 8017 } else if (!left_info.IsSmi()) { | 8035 } else if (!left_info.IsSmi()) { |
| 8018 if (!right_info.IsSmi()) { | 8036 if (!right_info.IsSmi()) { |
| 8019 __ mov(scratch, left); | 8037 __ mov(scratch, left); |
| 8020 __ or_(scratch, Operand(right)); | 8038 __ or_(scratch, Operand(right)); |
| 8021 __ test(scratch, Immediate(kSmiTagMask)); | 8039 __ test(scratch, Immediate(kSmiTagMask)); |
| 8022 deferred->Branch(not_zero); | 8040 deferred->Branch(not_zero); |
| 8023 } else { | 8041 } else { |
| 8024 __ test(left, Immediate(kSmiTagMask)); | 8042 __ test(left, Immediate(kSmiTagMask)); |
| 8025 deferred->Branch(not_zero); | 8043 deferred->Branch(not_zero); |
| 8044 if (FLAG_debug_code) __ AbortIfNotSmi(right); |
| 8026 } | 8045 } |
| 8027 } else { | 8046 } else { |
| 8047 if (FLAG_debug_code) __ AbortIfNotSmi(left); |
| 8028 if (!right_info.IsSmi()) { | 8048 if (!right_info.IsSmi()) { |
| 8029 __ test(right, Immediate(kSmiTagMask)); | 8049 __ test(right, Immediate(kSmiTagMask)); |
| 8030 deferred->Branch(not_zero); | 8050 deferred->Branch(not_zero); |
| 8051 } else { |
| 8052 if (FLAG_debug_code) __ AbortIfNotSmi(right); |
| 8031 } | 8053 } |
| 8032 } | 8054 } |
| 8033 } | 8055 } |
| 8034 | 8056 |
| 8035 | 8057 |
| 8036 Handle<String> Reference::GetName() { | 8058 Handle<String> Reference::GetName() { |
| 8037 ASSERT(type_ == NAMED); | 8059 ASSERT(type_ == NAMED); |
| 8038 Property* property = expression_->AsProperty(); | 8060 Property* property = expression_->AsProperty(); |
| 8039 if (property == NULL) { | 8061 if (property == NULL) { |
| 8040 // Global variable reference treated as a named property reference. | 8062 // Global variable reference treated as a named property reference. |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8527 __ mov(ebx, eax); | 8549 __ mov(ebx, eax); |
| 8528 __ mov(eax, edx); | 8550 __ mov(eax, edx); |
| 8529 } | 8551 } |
| 8530 } | 8552 } |
| 8531 if (!HasArgsInRegisters()) { | 8553 if (!HasArgsInRegisters()) { |
| 8532 __ mov(right, Operand(esp, 1 * kPointerSize)); | 8554 __ mov(right, Operand(esp, 1 * kPointerSize)); |
| 8533 __ mov(left, Operand(esp, 2 * kPointerSize)); | 8555 __ mov(left, Operand(esp, 2 * kPointerSize)); |
| 8534 } | 8556 } |
| 8535 | 8557 |
| 8536 if (static_operands_type_.IsSmi()) { | 8558 if (static_operands_type_.IsSmi()) { |
| 8559 if (FLAG_debug_code) { |
| 8560 __ AbortIfNotSmi(left); |
| 8561 __ AbortIfNotSmi(right); |
| 8562 } |
| 8537 if (op_ == Token::BIT_OR) { | 8563 if (op_ == Token::BIT_OR) { |
| 8538 __ or_(right, Operand(left)); | 8564 __ or_(right, Operand(left)); |
| 8539 GenerateReturn(masm); | 8565 GenerateReturn(masm); |
| 8540 return; | 8566 return; |
| 8541 } else if (op_ == Token::BIT_AND) { | 8567 } else if (op_ == Token::BIT_AND) { |
| 8542 __ and_(right, Operand(left)); | 8568 __ and_(right, Operand(left)); |
| 8543 GenerateReturn(masm); | 8569 GenerateReturn(masm); |
| 8544 return; | 8570 return; |
| 8545 } else if (op_ == Token::BIT_XOR) { | 8571 } else if (op_ == Token::BIT_XOR) { |
| 8546 __ xor_(right, Operand(left)); | 8572 __ xor_(right, Operand(left)); |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8881 // forever for all other operations (also if smi code is skipped). | 8907 // forever for all other operations (also if smi code is skipped). |
| 8882 GenerateTypeTransition(masm); | 8908 GenerateTypeTransition(masm); |
| 8883 } | 8909 } |
| 8884 | 8910 |
| 8885 Label not_floats; | 8911 Label not_floats; |
| 8886 if (CpuFeatures::IsSupported(SSE2)) { | 8912 if (CpuFeatures::IsSupported(SSE2)) { |
| 8887 CpuFeatures::Scope use_sse2(SSE2); | 8913 CpuFeatures::Scope use_sse2(SSE2); |
| 8888 if (static_operands_type_.IsNumber()) { | 8914 if (static_operands_type_.IsNumber()) { |
| 8889 if (FLAG_debug_code) { | 8915 if (FLAG_debug_code) { |
| 8890 // Assert at runtime that inputs are only numbers. | 8916 // Assert at runtime that inputs are only numbers. |
| 8891 __ AbortIfNotNumber(edx, | 8917 __ AbortIfNotNumber(edx); |
| 8892 "GenericBinaryOpStub operand not a number."); | 8918 __ AbortIfNotNumber(eax); |
| 8893 __ AbortIfNotNumber(eax, | |
| 8894 "GenericBinaryOpStub operand not a number."); | |
| 8895 } | 8919 } |
| 8896 if (static_operands_type_.IsSmi()) { | 8920 if (static_operands_type_.IsSmi()) { |
| 8921 if (FLAG_debug_code) { |
| 8922 __ AbortIfNotSmi(edx); |
| 8923 __ AbortIfNotSmi(eax); |
| 8924 } |
| 8897 FloatingPointHelper::LoadSSE2Smis(masm, ecx); | 8925 FloatingPointHelper::LoadSSE2Smis(masm, ecx); |
| 8898 } else { | 8926 } else { |
| 8899 FloatingPointHelper::LoadSSE2Operands(masm); | 8927 FloatingPointHelper::LoadSSE2Operands(masm); |
| 8900 } | 8928 } |
| 8901 } else { | 8929 } else { |
| 8902 FloatingPointHelper::LoadSSE2Operands(masm, &call_runtime); | 8930 FloatingPointHelper::LoadSSE2Operands(masm, &call_runtime); |
| 8903 } | 8931 } |
| 8904 | 8932 |
| 8905 switch (op_) { | 8933 switch (op_) { |
| 8906 case Token::ADD: __ addsd(xmm0, xmm1); break; | 8934 case Token::ADD: __ addsd(xmm0, xmm1); break; |
| 8907 case Token::SUB: __ subsd(xmm0, xmm1); break; | 8935 case Token::SUB: __ subsd(xmm0, xmm1); break; |
| 8908 case Token::MUL: __ mulsd(xmm0, xmm1); break; | 8936 case Token::MUL: __ mulsd(xmm0, xmm1); break; |
| 8909 case Token::DIV: __ divsd(xmm0, xmm1); break; | 8937 case Token::DIV: __ divsd(xmm0, xmm1); break; |
| 8910 default: UNREACHABLE(); | 8938 default: UNREACHABLE(); |
| 8911 } | 8939 } |
| 8912 GenerateHeapResultAllocation(masm, &call_runtime); | 8940 GenerateHeapResultAllocation(masm, &call_runtime); |
| 8913 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); | 8941 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); |
| 8914 GenerateReturn(masm); | 8942 GenerateReturn(masm); |
| 8915 } else { // SSE2 not available, use FPU. | 8943 } else { // SSE2 not available, use FPU. |
| 8916 if (static_operands_type_.IsNumber()) { | 8944 if (static_operands_type_.IsNumber()) { |
| 8917 if (FLAG_debug_code) { | 8945 if (FLAG_debug_code) { |
| 8918 // Assert at runtime that inputs are only numbers. | 8946 // Assert at runtime that inputs are only numbers. |
| 8919 __ AbortIfNotNumber(edx, | 8947 __ AbortIfNotNumber(edx); |
| 8920 "GenericBinaryOpStub operand not a number."); | 8948 __ AbortIfNotNumber(eax); |
| 8921 __ AbortIfNotNumber(eax, | |
| 8922 "GenericBinaryOpStub operand not a number."); | |
| 8923 } | 8949 } |
| 8924 } else { | 8950 } else { |
| 8925 FloatingPointHelper::CheckFloatOperands(masm, &call_runtime, ebx); | 8951 FloatingPointHelper::CheckFloatOperands(masm, &call_runtime, ebx); |
| 8926 } | 8952 } |
| 8927 FloatingPointHelper::LoadFloatOperands( | 8953 FloatingPointHelper::LoadFloatOperands( |
| 8928 masm, | 8954 masm, |
| 8929 ecx, | 8955 ecx, |
| 8930 FloatingPointHelper::ARGS_IN_REGISTERS); | 8956 FloatingPointHelper::ARGS_IN_REGISTERS); |
| 8931 switch (op_) { | 8957 switch (op_) { |
| 8932 case Token::ADD: __ faddp(1); break; | 8958 case Token::ADD: __ faddp(1); break; |
| (...skipping 709 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9642 Label* conversion_failure) { | 9668 Label* conversion_failure) { |
| 9643 // Check float operands. | 9669 // Check float operands. |
| 9644 Label arg1_is_object, check_undefined_arg1; | 9670 Label arg1_is_object, check_undefined_arg1; |
| 9645 Label arg2_is_object, check_undefined_arg2; | 9671 Label arg2_is_object, check_undefined_arg2; |
| 9646 Label load_arg2, done; | 9672 Label load_arg2, done; |
| 9647 | 9673 |
| 9648 if (!number_info.IsHeapNumber()) { | 9674 if (!number_info.IsHeapNumber()) { |
| 9649 if (!number_info.IsSmi()) { | 9675 if (!number_info.IsSmi()) { |
| 9650 __ test(edx, Immediate(kSmiTagMask)); | 9676 __ test(edx, Immediate(kSmiTagMask)); |
| 9651 __ j(not_zero, &arg1_is_object); | 9677 __ j(not_zero, &arg1_is_object); |
| 9678 } else { |
| 9679 if (FLAG_debug_code) __ AbortIfNotSmi(edx); |
| 9652 } | 9680 } |
| 9653 __ SmiUntag(edx); | 9681 __ SmiUntag(edx); |
| 9654 __ jmp(&load_arg2); | 9682 __ jmp(&load_arg2); |
| 9655 } | 9683 } |
| 9656 | 9684 |
| 9657 __ bind(&arg1_is_object); | 9685 __ bind(&arg1_is_object); |
| 9658 | 9686 |
| 9659 // Get the untagged integer version of the edx heap number in ecx. | 9687 // Get the untagged integer version of the edx heap number in ecx. |
| 9660 IntegerConvert(masm, edx, number_info, use_sse3, conversion_failure); | 9688 IntegerConvert(masm, edx, number_info, use_sse3, conversion_failure); |
| 9661 __ mov(edx, ecx); | 9689 __ mov(edx, ecx); |
| 9662 | 9690 |
| 9663 // Here edx has the untagged integer, eax has a Smi or a heap number. | 9691 // Here edx has the untagged integer, eax has a Smi or a heap number. |
| 9664 __ bind(&load_arg2); | 9692 __ bind(&load_arg2); |
| 9665 if (!number_info.IsHeapNumber()) { | 9693 if (!number_info.IsHeapNumber()) { |
| 9666 // Test if arg2 is a Smi. | 9694 // Test if arg2 is a Smi. |
| 9667 if (!number_info.IsSmi()) { | 9695 if (!number_info.IsSmi()) { |
| 9668 __ test(eax, Immediate(kSmiTagMask)); | 9696 __ test(eax, Immediate(kSmiTagMask)); |
| 9669 __ j(not_zero, &arg2_is_object); | 9697 __ j(not_zero, &arg2_is_object); |
| 9698 } else { |
| 9699 if (FLAG_debug_code) __ AbortIfNotSmi(eax); |
| 9670 } | 9700 } |
| 9671 __ SmiUntag(eax); | 9701 __ SmiUntag(eax); |
| 9672 __ mov(ecx, eax); | 9702 __ mov(ecx, eax); |
| 9673 __ jmp(&done); | 9703 __ jmp(&done); |
| 9674 } | 9704 } |
| 9675 | 9705 |
| 9676 __ bind(&arg2_is_object); | 9706 __ bind(&arg2_is_object); |
| 9677 | 9707 |
| 9678 // Get the untagged integer version of the eax heap number in ecx. | 9708 // Get the untagged integer version of the eax heap number in ecx. |
| 9679 IntegerConvert(masm, eax, number_info, use_sse3, conversion_failure); | 9709 IntegerConvert(masm, eax, number_info, use_sse3, conversion_failure); |
| (...skipping 2568 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12248 | 12278 |
| 12249 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 12279 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
| 12250 // tagged as a small integer. | 12280 // tagged as a small integer. |
| 12251 __ bind(&runtime); | 12281 __ bind(&runtime); |
| 12252 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); | 12282 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); |
| 12253 } | 12283 } |
| 12254 | 12284 |
| 12255 #undef __ | 12285 #undef __ |
| 12256 | 12286 |
| 12257 } } // namespace v8::internal | 12287 } } // namespace v8::internal |
| OLD | NEW |