Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(301)

Side by Side Diff: src/ia32/codegen-ia32.cc

Issue 965001: Add static analysis to AST expressions that records whether a negative zero w... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | src/rewriter.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1084 matching lines...) Expand 10 before | Expand all | Expand 10 after
1095 default: 1095 default:
1096 UNREACHABLE(); 1096 UNREACHABLE();
1097 } 1097 }
1098 UNREACHABLE(); 1098 UNREACHABLE();
1099 return NumberInfo::Unknown(); 1099 return NumberInfo::Unknown();
1100 } 1100 }
1101 1101
1102 1102
1103 void CodeGenerator::GenericBinaryOperation(Token::Value op, 1103 void CodeGenerator::GenericBinaryOperation(Token::Value op,
1104 StaticType* type, 1104 StaticType* type,
1105 OverwriteMode overwrite_mode) { 1105 OverwriteMode overwrite_mode,
1106 bool no_negative_zero) {
1106 Comment cmnt(masm_, "[ BinaryOperation"); 1107 Comment cmnt(masm_, "[ BinaryOperation");
1107 Comment cmnt_token(masm_, Token::String(op)); 1108 Comment cmnt_token(masm_, Token::String(op));
1108 1109
1109 if (op == Token::COMMA) { 1110 if (op == Token::COMMA) {
1110 // Simply discard left value. 1111 // Simply discard left value.
1111 frame_->Nip(1); 1112 frame_->Nip(1);
1112 return; 1113 return;
1113 } 1114 }
1114 1115
1115 Result right = frame_->Pop(); 1116 Result right = frame_->Pop();
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1163 Result answer; 1164 Result answer;
1164 if (left_is_non_smi_constant || right_is_non_smi_constant) { 1165 if (left_is_non_smi_constant || right_is_non_smi_constant) {
1165 // Go straight to the slow case, with no smi code. 1166 // Go straight to the slow case, with no smi code.
1166 GenericBinaryOpStub stub(op, 1167 GenericBinaryOpStub stub(op,
1167 overwrite_mode, 1168 overwrite_mode,
1168 NO_SMI_CODE_IN_STUB, 1169 NO_SMI_CODE_IN_STUB,
1169 operands_type); 1170 operands_type);
1170 answer = stub.GenerateCall(masm_, frame_, &left, &right); 1171 answer = stub.GenerateCall(masm_, frame_, &left, &right);
1171 } else if (right_is_smi_constant) { 1172 } else if (right_is_smi_constant) {
1172 answer = ConstantSmiBinaryOperation(op, &left, right.handle(), 1173 answer = ConstantSmiBinaryOperation(op, &left, right.handle(),
1173 type, false, overwrite_mode); 1174 type, false, overwrite_mode,
1175 no_negative_zero);
1174 } else if (left_is_smi_constant) { 1176 } else if (left_is_smi_constant) {
1175 answer = ConstantSmiBinaryOperation(op, &right, left.handle(), 1177 answer = ConstantSmiBinaryOperation(op, &right, left.handle(),
1176 type, true, overwrite_mode); 1178 type, true, overwrite_mode,
1179 no_negative_zero);
1177 } else { 1180 } else {
1178 // Set the flags based on the operation, type and loop nesting level. 1181 // Set the flags based on the operation, type and loop nesting level.
1179 // Bit operations always assume they likely operate on Smis. Still only 1182 // Bit operations always assume they likely operate on Smis. Still only
1180 // generate the inline Smi check code if this operation is part of a loop. 1183 // generate the inline Smi check code if this operation is part of a loop.
1181 // For all other operations only inline the Smi check code for likely smis 1184 // For all other operations only inline the Smi check code for likely smis
1182 // if the operation is part of a loop. 1185 // if the operation is part of a loop.
1183 if (loop_nesting() > 0 && 1186 if (loop_nesting() > 0 &&
1184 (Token::IsBitOp(op) || 1187 (Token::IsBitOp(op) ||
1185 operands_type.IsInteger32() || 1188 operands_type.IsInteger32() ||
1186 type->IsLikelySmi())) { 1189 type->IsLikelySmi())) {
1187 answer = LikelySmiBinaryOperation(op, &left, &right, overwrite_mode); 1190 answer = LikelySmiBinaryOperation(op, &left, &right,
1191 overwrite_mode, no_negative_zero);
1188 } else { 1192 } else {
1189 GenericBinaryOpStub stub(op, 1193 GenericBinaryOpStub stub(op,
1190 overwrite_mode, 1194 overwrite_mode,
1191 NO_GENERIC_BINARY_FLAGS, 1195 NO_GENERIC_BINARY_FLAGS,
1192 operands_type); 1196 operands_type);
1193 answer = stub.GenerateCall(masm_, frame_, &left, &right); 1197 answer = stub.GenerateCall(masm_, frame_, &left, &right);
1194 } 1198 }
1195 } 1199 }
1196 1200
1197 answer.set_number_info(result_type); 1201 answer.set_number_info(result_type);
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1284 Register left, Register right, Register scratch, 1288 Register left, Register right, Register scratch,
1285 NumberInfo left_info, NumberInfo right_info, 1289 NumberInfo left_info, NumberInfo right_info,
1286 DeferredInlineBinaryOperation* deferred); 1290 DeferredInlineBinaryOperation* deferred);
1287 1291
1288 1292
1289 // Implements a binary operation using a deferred code object and some 1293 // Implements a binary operation using a deferred code object and some
1290 // inline code to operate on smis quickly. 1294 // inline code to operate on smis quickly.
1291 Result CodeGenerator::LikelySmiBinaryOperation(Token::Value op, 1295 Result CodeGenerator::LikelySmiBinaryOperation(Token::Value op,
1292 Result* left, 1296 Result* left,
1293 Result* right, 1297 Result* right,
1294 OverwriteMode overwrite_mode) { 1298 OverwriteMode overwrite_mode,
1299 bool no_negative_zero) {
1295 Result answer; 1300 Result answer;
1296 // Special handling of div and mod because they use fixed registers. 1301 // Special handling of div and mod because they use fixed registers.
1297 if (op == Token::DIV || op == Token::MOD) { 1302 if (op == Token::DIV || op == Token::MOD) {
1298 // We need eax as the quotient register, edx as the remainder 1303 // We need eax as the quotient register, edx as the remainder
1299 // register, neither left nor right in eax or edx, and left copied 1304 // register, neither left nor right in eax or edx, and left copied
1300 // to eax. 1305 // to eax.
1301 Result quotient; 1306 Result quotient;
1302 Result remainder; 1307 Result remainder;
1303 bool left_is_in_eax = false; 1308 bool left_is_in_eax = false;
1304 // Step 1: get eax for quotient. 1309 // Step 1: get eax for quotient.
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1388 __ test(right->reg(), Operand(right->reg())); 1393 __ test(right->reg(), Operand(right->reg()));
1389 deferred->Branch(zero); 1394 deferred->Branch(zero);
1390 // Divide edx:eax by the right operand. 1395 // Divide edx:eax by the right operand.
1391 __ idiv(right->reg()); 1396 __ idiv(right->reg());
1392 1397
1393 // Complete the operation. 1398 // Complete the operation.
1394 if (op == Token::DIV) { 1399 if (op == Token::DIV) {
1395 // Check for negative zero result. If result is zero, and divisor 1400 // Check for negative zero result. If result is zero, and divisor
1396 // is negative, return a floating point negative zero. The 1401 // is negative, return a floating point negative zero. The
1397 // virtual frame is unchanged in this block, so local control flow 1402 // virtual frame is unchanged in this block, so local control flow
1398 // can use a Label rather than a JumpTarget. 1403 // can use a Label rather than a JumpTarget. If the context of this
1399 Label non_zero_result; 1404 // expression will treat -0 like 0, do not do this test.
1400 __ test(left->reg(), Operand(left->reg())); 1405 if (!no_negative_zero) {
1401 __ j(not_zero, &non_zero_result); 1406 Label non_zero_result;
1402 __ test(right->reg(), Operand(right->reg())); 1407 __ test(left->reg(), Operand(left->reg()));
1403 deferred->Branch(negative); 1408 __ j(not_zero, &non_zero_result);
1404 __ bind(&non_zero_result); 1409 __ test(right->reg(), Operand(right->reg()));
1410 deferred->Branch(negative);
1411 __ bind(&non_zero_result);
1412 }
1405 // Check for the corner case of dividing the most negative smi by 1413 // Check for the corner case of dividing the most negative smi by
1406 // -1. We cannot use the overflow flag, since it is not set by 1414 // -1. We cannot use the overflow flag, since it is not set by
1407 // idiv instruction. 1415 // idiv instruction.
1408 ASSERT(kSmiTag == 0 && kSmiTagSize == 1); 1416 ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
1409 __ cmp(eax, 0x40000000); 1417 __ cmp(eax, 0x40000000);
1410 deferred->Branch(equal); 1418 deferred->Branch(equal);
1411 // Check that the remainder is zero. 1419 // Check that the remainder is zero.
1412 __ test(edx, Operand(edx)); 1420 __ test(edx, Operand(edx));
1413 deferred->Branch(not_zero); 1421 deferred->Branch(not_zero);
1414 // Tag the result and store it in the quotient register. 1422 // Tag the result and store it in the quotient register.
1415 __ SmiTag(eax); 1423 __ SmiTag(eax);
1416 deferred->BindExit(); 1424 deferred->BindExit();
1417 left->Unuse(); 1425 left->Unuse();
1418 right->Unuse(); 1426 right->Unuse();
1419 answer = quotient; 1427 answer = quotient;
1420 } else { 1428 } else {
1421 ASSERT(op == Token::MOD); 1429 ASSERT(op == Token::MOD);
1422 // Check for a negative zero result. If the result is zero, and 1430 // Check for a negative zero result. If the result is zero, and
1423 // the dividend is negative, return a floating point negative 1431 // the dividend is negative, return a floating point negative
1424 // zero. The frame is unchanged in this block, so local control 1432 // zero. The frame is unchanged in this block, so local control
1425 // flow can use a Label rather than a JumpTarget. 1433 // flow can use a Label rather than a JumpTarget.
1426 Label non_zero_result; 1434 if (!no_negative_zero) {
1427 __ test(edx, Operand(edx)); 1435 Label non_zero_result;
1428 __ j(not_zero, &non_zero_result, taken); 1436 __ test(edx, Operand(edx));
1429 __ test(left->reg(), Operand(left->reg())); 1437 __ j(not_zero, &non_zero_result, taken);
1430 deferred->Branch(negative); 1438 __ test(left->reg(), Operand(left->reg()));
1431 __ bind(&non_zero_result); 1439 deferred->Branch(negative);
1440 __ bind(&non_zero_result);
1441 }
1432 deferred->BindExit(); 1442 deferred->BindExit();
1433 left->Unuse(); 1443 left->Unuse();
1434 right->Unuse(); 1444 right->Unuse();
1435 answer = remainder; 1445 answer = remainder;
1436 } 1446 }
1437 ASSERT(answer.is_valid()); 1447 ASSERT(answer.is_valid());
1438 return answer; 1448 return answer;
1439 } 1449 }
1440 1450
1441 // Special handling of shift operations because they use fixed 1451 // Special handling of shift operations because they use fixed
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1564 // Left-hand operand has been copied into answer. 1574 // Left-hand operand has been copied into answer.
1565 __ SmiUntag(answer.reg()); 1575 __ SmiUntag(answer.reg());
1566 // Do multiplication of smis, leaving result in answer. 1576 // Do multiplication of smis, leaving result in answer.
1567 __ imul(answer.reg(), Operand(right->reg())); 1577 __ imul(answer.reg(), Operand(right->reg()));
1568 // Go slow on overflows. 1578 // Go slow on overflows.
1569 deferred->Branch(overflow); 1579 deferred->Branch(overflow);
1570 // Check for negative zero result. If product is zero, and one 1580 // Check for negative zero result. If product is zero, and one
1571 // argument is negative, go to slow case. The frame is unchanged 1581 // argument is negative, go to slow case. The frame is unchanged
1572 // in this block, so local control flow can use a Label rather 1582 // in this block, so local control flow can use a Label rather
1573 // than a JumpTarget. 1583 // than a JumpTarget.
1574 Label non_zero_result; 1584 if (!no_negative_zero) {
1575 __ test(answer.reg(), Operand(answer.reg())); 1585 Label non_zero_result;
1576 __ j(not_zero, &non_zero_result, taken); 1586 __ test(answer.reg(), Operand(answer.reg()));
1577 __ mov(answer.reg(), left->reg()); 1587 __ j(not_zero, &non_zero_result, taken);
1578 __ or_(answer.reg(), Operand(right->reg())); 1588 __ mov(answer.reg(), left->reg());
1579 deferred->Branch(negative); 1589 __ or_(answer.reg(), Operand(right->reg()));
1580 __ xor_(answer.reg(), Operand(answer.reg())); // Positive 0 is correct. 1590 deferred->Branch(negative);
1581 __ bind(&non_zero_result); 1591 __ xor_(answer.reg(), Operand(answer.reg())); // Positive 0 is correct.
1592 __ bind(&non_zero_result);
1593 }
1582 break; 1594 break;
1583 } 1595 }
1584 1596
1585 case Token::BIT_OR: 1597 case Token::BIT_OR:
1586 __ or_(answer.reg(), Operand(right->reg())); 1598 __ or_(answer.reg(), Operand(right->reg()));
1587 break; 1599 break;
1588 1600
1589 case Token::BIT_AND: 1601 case Token::BIT_AND:
1590 __ and_(answer.reg(), Operand(right->reg())); 1602 __ and_(answer.reg(), Operand(right->reg()));
1591 break; 1603 break;
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
1810 igostub.GenerateCall(masm_, dst_, value_); 1822 igostub.GenerateCall(masm_, dst_, value_);
1811 if (!dst_.is(eax)) __ mov(dst_, eax); 1823 if (!dst_.is(eax)) __ mov(dst_, eax);
1812 } 1824 }
1813 1825
1814 1826
1815 Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, 1827 Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op,
1816 Result* operand, 1828 Result* operand,
1817 Handle<Object> value, 1829 Handle<Object> value,
1818 StaticType* type, 1830 StaticType* type,
1819 bool reversed, 1831 bool reversed,
1820 OverwriteMode overwrite_mode) { 1832 OverwriteMode overwrite_mode,
1833 bool no_negative_zero) {
1821 // NOTE: This is an attempt to inline (a bit) more of the code for 1834 // NOTE: This is an attempt to inline (a bit) more of the code for
1822 // some possible smi operations (like + and -) when (at least) one 1835 // some possible smi operations (like + and -) when (at least) one
1823 // of the operands is a constant smi. 1836 // of the operands is a constant smi.
1824 // Consumes the argument "operand". 1837 // Consumes the argument "operand".
1825 // TODO(199): Optimize some special cases of operations involving a 1838 // TODO(199): Optimize some special cases of operations involving a
1826 // smi literal (multiply by 2, shift by 0, etc.). 1839 // smi literal (multiply by 2, shift by 0, etc.).
1827 if (IsUnsafeSmi(value)) { 1840 if (IsUnsafeSmi(value)) {
1828 Result unsafe_operand(value); 1841 Result unsafe_operand(value);
1829 if (reversed) { 1842 if (reversed) {
1830 return LikelySmiBinaryOperation(op, &unsafe_operand, operand, 1843 return LikelySmiBinaryOperation(op, &unsafe_operand, operand,
1831 overwrite_mode); 1844 overwrite_mode, no_negative_zero);
1832 } else { 1845 } else {
1833 return LikelySmiBinaryOperation(op, operand, &unsafe_operand, 1846 return LikelySmiBinaryOperation(op, operand, &unsafe_operand,
1834 overwrite_mode); 1847 overwrite_mode, no_negative_zero);
1835 } 1848 }
1836 } 1849 }
1837 1850
1838 // Get the literal value. 1851 // Get the literal value.
1839 Smi* smi_value = Smi::cast(*value); 1852 Smi* smi_value = Smi::cast(*value);
1840 int int_value = smi_value->value(); 1853 int int_value = smi_value->value();
1841 1854
1842 Result answer; 1855 Result answer;
1843 switch (op) { 1856 switch (op) {
1844 case Token::ADD: { 1857 case Token::ADD: {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1904 } 1917 }
1905 deferred->BindExit(); 1918 deferred->BindExit();
1906 operand->Unuse(); 1919 operand->Unuse();
1907 break; 1920 break;
1908 } 1921 }
1909 1922
1910 case Token::SAR: 1923 case Token::SAR:
1911 if (reversed) { 1924 if (reversed) {
1912 Result constant_operand(value); 1925 Result constant_operand(value);
1913 answer = LikelySmiBinaryOperation(op, &constant_operand, operand, 1926 answer = LikelySmiBinaryOperation(op, &constant_operand, operand,
1914 overwrite_mode); 1927 overwrite_mode, no_negative_zero);
1915 } else { 1928 } else {
1916 // Only the least significant 5 bits of the shift value are used. 1929 // Only the least significant 5 bits of the shift value are used.
1917 // In the slow case, this masking is done inside the runtime call. 1930 // In the slow case, this masking is done inside the runtime call.
1918 int shift_value = int_value & 0x1f; 1931 int shift_value = int_value & 0x1f;
1919 operand->ToRegister(); 1932 operand->ToRegister();
1920 frame_->Spill(operand->reg()); 1933 frame_->Spill(operand->reg());
1921 if (!operand->number_info().IsSmi()) { 1934 if (!operand->number_info().IsSmi()) {
1922 DeferredInlineSmiOperation* deferred = 1935 DeferredInlineSmiOperation* deferred =
1923 new DeferredInlineSmiOperation(op, 1936 new DeferredInlineSmiOperation(op,
1924 operand->reg(), 1937 operand->reg(),
(...skipping 15 matching lines...) Expand all
1940 } 1953 }
1941 } 1954 }
1942 answer = *operand; 1955 answer = *operand;
1943 } 1956 }
1944 break; 1957 break;
1945 1958
1946 case Token::SHR: 1959 case Token::SHR:
1947 if (reversed) { 1960 if (reversed) {
1948 Result constant_operand(value); 1961 Result constant_operand(value);
1949 answer = LikelySmiBinaryOperation(op, &constant_operand, operand, 1962 answer = LikelySmiBinaryOperation(op, &constant_operand, operand,
1950 overwrite_mode); 1963 overwrite_mode, no_negative_zero);
1951 } else { 1964 } else {
1952 // Only the least significant 5 bits of the shift value are used. 1965 // Only the least significant 5 bits of the shift value are used.
1953 // In the slow case, this masking is done inside the runtime call. 1966 // In the slow case, this masking is done inside the runtime call.
1954 int shift_value = int_value & 0x1f; 1967 int shift_value = int_value & 0x1f;
1955 operand->ToRegister(); 1968 operand->ToRegister();
1956 answer = allocator()->Allocate(); 1969 answer = allocator()->Allocate();
1957 ASSERT(answer.is_valid()); 1970 ASSERT(answer.is_valid());
1958 DeferredInlineSmiOperation* deferred = 1971 DeferredInlineSmiOperation* deferred =
1959 new DeferredInlineSmiOperation(op, 1972 new DeferredInlineSmiOperation(op,
1960 answer.reg(), 1973 answer.reg(),
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
2133 deferred->Branch(not_zero); // Branch if non-smi or odd smi. 2146 deferred->Branch(not_zero); // Branch if non-smi or odd smi.
2134 __ sar(operand->reg(), 1); 2147 __ sar(operand->reg(), 1);
2135 deferred->BindExit(); 2148 deferred->BindExit();
2136 answer = *operand; 2149 answer = *operand;
2137 } else { 2150 } else {
2138 // Cannot fall through MOD to default case, so we duplicate the 2151 // Cannot fall through MOD to default case, so we duplicate the
2139 // default case here. 2152 // default case here.
2140 Result constant_operand(value); 2153 Result constant_operand(value);
2141 if (reversed) { 2154 if (reversed) {
2142 answer = LikelySmiBinaryOperation(op, &constant_operand, operand, 2155 answer = LikelySmiBinaryOperation(op, &constant_operand, operand,
2143 overwrite_mode); 2156 overwrite_mode, no_negative_zero);
2144 } else { 2157 } else {
2145 answer = LikelySmiBinaryOperation(op, operand, &constant_operand, 2158 answer = LikelySmiBinaryOperation(op, operand, &constant_operand,
2146 overwrite_mode); 2159 overwrite_mode, no_negative_zero);
2147 } 2160 }
2148 } 2161 }
2149 break; 2162 break;
2150 // Generate inline code for mod of powers of 2 and negative powers of 2. 2163 // Generate inline code for mod of powers of 2 and negative powers of 2.
2151 case Token::MOD: 2164 case Token::MOD:
2152 if (!reversed && 2165 if (!reversed &&
2153 int_value != 0 && 2166 int_value != 0 &&
2154 (IsPowerOf2(int_value) || IsPowerOf2(-int_value))) { 2167 (IsPowerOf2(int_value) || IsPowerOf2(-int_value))) {
2155 operand->ToRegister(); 2168 operand->ToRegister();
2156 frame_->Spill(operand->reg()); 2169 frame_->Spill(operand->reg());
(...skipping 16 matching lines...) Expand all
2173 deferred->BindExit(); 2186 deferred->BindExit();
2174 answer = *operand; 2187 answer = *operand;
2175 break; 2188 break;
2176 } 2189 }
2177 // Fall through if we did not find a power of 2 on the right hand side! 2190 // Fall through if we did not find a power of 2 on the right hand side!
2178 2191
2179 default: { 2192 default: {
2180 Result constant_operand(value); 2193 Result constant_operand(value);
2181 if (reversed) { 2194 if (reversed) {
2182 answer = LikelySmiBinaryOperation(op, &constant_operand, operand, 2195 answer = LikelySmiBinaryOperation(op, &constant_operand, operand,
2183 overwrite_mode); 2196 overwrite_mode, no_negative_zero);
2184 } else { 2197 } else {
2185 answer = LikelySmiBinaryOperation(op, operand, &constant_operand, 2198 answer = LikelySmiBinaryOperation(op, operand, &constant_operand,
2186 overwrite_mode); 2199 overwrite_mode, no_negative_zero);
2187 } 2200 }
2188 break; 2201 break;
2189 } 2202 }
2190 } 2203 }
2191 ASSERT(answer.is_valid()); 2204 ASSERT(answer.is_valid());
2192 return answer; 2205 return answer;
2193 } 2206 }
2194 2207
2195 2208
2196 static bool CouldBeNaN(const Result& result) { 2209 static bool CouldBeNaN(const Result& result) {
(...skipping 2746 matching lines...) Expand 10 before | Expand all | Expand 10 after
4943 if (node->is_compound()) { 4956 if (node->is_compound()) {
4944 Result result = LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF); 4957 Result result = LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF);
4945 frame()->Push(&result); 4958 frame()->Push(&result);
4946 Load(node->value()); 4959 Load(node->value());
4947 4960
4948 bool overwrite_value = 4961 bool overwrite_value =
4949 (node->value()->AsBinaryOperation() != NULL && 4962 (node->value()->AsBinaryOperation() != NULL &&
4950 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); 4963 node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
4951 GenericBinaryOperation(node->binary_op(), 4964 GenericBinaryOperation(node->binary_op(),
4952 node->type(), 4965 node->type(),
4953 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); 4966 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE,
4967 node->no_negative_zero());
4954 } else { 4968 } else {
4955 Load(node->value()); 4969 Load(node->value());
4956 } 4970 }
4957 4971
4958 // Perform the assignment. 4972 // Perform the assignment.
4959 if (var->mode() != Variable::CONST || node->op() == Token::INIT_CONST) { 4973 if (var->mode() != Variable::CONST || node->op() == Token::INIT_CONST) {
4960 CodeForSourcePosition(node->position()); 4974 CodeForSourcePosition(node->position());
4961 StoreToSlot(slot, 4975 StoreToSlot(slot,
4962 node->op() == Token::INIT_CONST ? CONST_INIT : NOT_CONST_INIT); 4976 node->op() == Token::INIT_CONST ? CONST_INIT : NOT_CONST_INIT);
4963 } 4977 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
5020 } 5034 }
5021 Result value = EmitNamedLoad(name, var != NULL); 5035 Result value = EmitNamedLoad(name, var != NULL);
5022 frame()->Push(&value); 5036 frame()->Push(&value);
5023 Load(node->value()); 5037 Load(node->value());
5024 5038
5025 bool overwrite_value = 5039 bool overwrite_value =
5026 (node->value()->AsBinaryOperation() != NULL && 5040 (node->value()->AsBinaryOperation() != NULL &&
5027 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); 5041 node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
5028 GenericBinaryOperation(node->binary_op(), 5042 GenericBinaryOperation(node->binary_op(),
5029 node->type(), 5043 node->type(),
5030 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); 5044 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE,
5045 node->no_negative_zero());
5031 } else { 5046 } else {
5032 Load(node->value()); 5047 Load(node->value());
5033 } 5048 }
5034 5049
5035 // Perform the assignment. It is safe to ignore constants here. 5050 // Perform the assignment. It is safe to ignore constants here.
5036 ASSERT(var == NULL || var->mode() != Variable::CONST); 5051 ASSERT(var == NULL || var->mode() != Variable::CONST);
5037 ASSERT_NE(Token::INIT_CONST, node->op()); 5052 ASSERT_NE(Token::INIT_CONST, node->op());
5038 if (is_trivial_receiver) { 5053 if (is_trivial_receiver) {
5039 Result value = frame()->Pop(); 5054 Result value = frame()->Pop();
5040 frame()->Push(prop->obj()); 5055 frame()->Push(prop->obj());
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
5099 frame()->PushElementAt(1); 5114 frame()->PushElementAt(1);
5100 Result value = EmitKeyedLoad(); 5115 Result value = EmitKeyedLoad();
5101 frame()->Push(&value); 5116 frame()->Push(&value);
5102 Load(node->value()); 5117 Load(node->value());
5103 5118
5104 bool overwrite_value = 5119 bool overwrite_value =
5105 (node->value()->AsBinaryOperation() != NULL && 5120 (node->value()->AsBinaryOperation() != NULL &&
5106 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); 5121 node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
5107 GenericBinaryOperation(node->binary_op(), 5122 GenericBinaryOperation(node->binary_op(),
5108 node->type(), 5123 node->type(),
5109 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); 5124 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE,
5125 node->no_negative_zero());
5110 } else { 5126 } else {
5111 Load(node->value()); 5127 Load(node->value());
5112 } 5128 }
5113 5129
5114 // Perform the assignment. It is safe to ignore constants here. 5130 // Perform the assignment. It is safe to ignore constants here.
5115 ASSERT(node->op() != Token::INIT_CONST); 5131 ASSERT(node->op() != Token::INIT_CONST);
5116 CodeForSourcePosition(node->position()); 5132 CodeForSourcePosition(node->position());
5117 Result answer = EmitKeyedStore(prop->key()->type()); 5133 Result answer = EmitKeyedStore(prop->key()->type());
5118 frame()->Push(&answer); 5134 frame()->Push(&answer);
5119 5135
(...skipping 1741 matching lines...) Expand 10 before | Expand all | Expand 10 after
6861 6877
6862 if (node->left()->IsTrivial()) { 6878 if (node->left()->IsTrivial()) {
6863 Load(node->right()); 6879 Load(node->right());
6864 Result right = frame_->Pop(); 6880 Result right = frame_->Pop();
6865 frame_->Push(node->left()); 6881 frame_->Push(node->left());
6866 frame_->Push(&right); 6882 frame_->Push(&right);
6867 } else { 6883 } else {
6868 Load(node->left()); 6884 Load(node->left());
6869 Load(node->right()); 6885 Load(node->right());
6870 } 6886 }
6871 GenericBinaryOperation(node->op(), node->type(), overwrite_mode); 6887 GenericBinaryOperation(node->op(), node->type(),
6888 overwrite_mode, node->no_negative_zero());
6872 } 6889 }
6873 } 6890 }
6874 6891
6875 6892
6876 void CodeGenerator::VisitThisFunction(ThisFunction* node) { 6893 void CodeGenerator::VisitThisFunction(ThisFunction* node) {
6877 frame_->PushFunction(); 6894 frame_->PushFunction();
6878 } 6895 }
6879 6896
6880 6897
6881 void CodeGenerator::VisitCompareOperation(CompareOperation* node) { 6898 void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
(...skipping 4932 matching lines...) Expand 10 before | Expand all | Expand 10 after
11814 11831
11815 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 11832 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
11816 // tagged as a small integer. 11833 // tagged as a small integer.
11817 __ bind(&runtime); 11834 __ bind(&runtime);
11818 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 11835 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
11819 } 11836 }
11820 11837
11821 #undef __ 11838 #undef __
11822 11839
11823 } } // namespace v8::internal 11840 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | src/rewriter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698