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

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

Issue 1592001: Simplify IA32 code generator API. (Closed)
Patch Set: Created 10 years, 8 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
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | no next file » | 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 1203 matching lines...) Expand 10 before | Expand all | Expand 10 after
1214 // Result is always a number. 1214 // Result is always a number.
1215 return TypeInfo::Number(); 1215 return TypeInfo::Number();
1216 default: 1216 default:
1217 UNREACHABLE(); 1217 UNREACHABLE();
1218 } 1218 }
1219 UNREACHABLE(); 1219 UNREACHABLE();
1220 return TypeInfo::Unknown(); 1220 return TypeInfo::Unknown();
1221 } 1221 }
1222 1222
1223 1223
1224 void CodeGenerator::GenericBinaryOperation(Token::Value op, 1224 void CodeGenerator::GenericBinaryOperation(BinaryOperation* expr,
1225 StaticType* type, 1225 OverwriteMode overwrite_mode) {
1226 OverwriteMode overwrite_mode,
1227 bool no_negative_zero) {
1228 Comment cmnt(masm_, "[ BinaryOperation"); 1226 Comment cmnt(masm_, "[ BinaryOperation");
1227 Token::Value op = expr->op();
1229 Comment cmnt_token(masm_, Token::String(op)); 1228 Comment cmnt_token(masm_, Token::String(op));
1230 1229
1231 if (op == Token::COMMA) { 1230 if (op == Token::COMMA) {
1232 // Simply discard left value. 1231 // Simply discard left value.
1233 frame_->Nip(1); 1232 frame_->Nip(1);
1234 return; 1233 return;
1235 } 1234 }
1236 1235
1237 Result right = frame_->Pop(); 1236 Result right = frame_->Pop();
1238 Result left = frame_->Pop(); 1237 Result left = frame_->Pop();
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1291 1290
1292 Result answer; 1291 Result answer;
1293 if (left_is_non_smi_constant || right_is_non_smi_constant) { 1292 if (left_is_non_smi_constant || right_is_non_smi_constant) {
1294 // Go straight to the slow case, with no smi code. 1293 // Go straight to the slow case, with no smi code.
1295 GenericBinaryOpStub stub(op, 1294 GenericBinaryOpStub stub(op,
1296 overwrite_mode, 1295 overwrite_mode,
1297 NO_SMI_CODE_IN_STUB, 1296 NO_SMI_CODE_IN_STUB,
1298 operands_type); 1297 operands_type);
1299 answer = stub.GenerateCall(masm_, frame_, &left, &right); 1298 answer = stub.GenerateCall(masm_, frame_, &left, &right);
1300 } else if (right_is_smi_constant) { 1299 } else if (right_is_smi_constant) {
1301 answer = ConstantSmiBinaryOperation(op, &left, right.handle(), 1300 answer = ConstantSmiBinaryOperation(expr, &left, right.handle(),
1302 type, false, overwrite_mode, 1301 false, overwrite_mode);
1303 no_negative_zero);
1304 } else if (left_is_smi_constant) { 1302 } else if (left_is_smi_constant) {
1305 answer = ConstantSmiBinaryOperation(op, &right, left.handle(), 1303 answer = ConstantSmiBinaryOperation(expr, &right, left.handle(),
1306 type, true, overwrite_mode, 1304 true, overwrite_mode);
1307 no_negative_zero);
1308 } else { 1305 } else {
1309 // Set the flags based on the operation, type and loop nesting level. 1306 // Set the flags based on the operation, type and loop nesting level.
1310 // Bit operations always assume they likely operate on Smis. Still only 1307 // Bit operations always assume they likely operate on Smis. Still only
1311 // generate the inline Smi check code if this operation is part of a loop. 1308 // generate the inline Smi check code if this operation is part of a loop.
1312 // For all other operations only inline the Smi check code for likely smis 1309 // For all other operations only inline the Smi check code for likely smis
1313 // if the operation is part of a loop. 1310 // if the operation is part of a loop.
1314 if (loop_nesting() > 0 && 1311 if (loop_nesting() > 0 &&
1315 (Token::IsBitOp(op) || 1312 (Token::IsBitOp(op) ||
1316 operands_type.IsInteger32() || 1313 operands_type.IsInteger32() ||
1317 type->IsLikelySmi())) { 1314 expr->type()->IsLikelySmi())) {
1318 answer = LikelySmiBinaryOperation(op, &left, &right, 1315 answer = LikelySmiBinaryOperation(expr, &left, &right, overwrite_mode);
1319 overwrite_mode, no_negative_zero);
1320 } else { 1316 } else {
1321 GenericBinaryOpStub stub(op, 1317 GenericBinaryOpStub stub(op,
1322 overwrite_mode, 1318 overwrite_mode,
1323 NO_GENERIC_BINARY_FLAGS, 1319 NO_GENERIC_BINARY_FLAGS,
1324 operands_type); 1320 operands_type);
1325 answer = stub.GenerateCall(masm_, frame_, &left, &right); 1321 answer = stub.GenerateCall(masm_, frame_, &left, &right);
1326 } 1322 }
1327 } 1323 }
1328 1324
1329 answer.set_type_info(result_type); 1325 answer.set_type_info(result_type);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1413 1409
1414 1410
1415 static void CheckTwoForSminess(MacroAssembler* masm, 1411 static void CheckTwoForSminess(MacroAssembler* masm,
1416 Register left, Register right, Register scratch, 1412 Register left, Register right, Register scratch,
1417 TypeInfo left_info, TypeInfo right_info, 1413 TypeInfo left_info, TypeInfo right_info,
1418 DeferredInlineBinaryOperation* deferred); 1414 DeferredInlineBinaryOperation* deferred);
1419 1415
1420 1416
1421 // Implements a binary operation using a deferred code object and some 1417 // Implements a binary operation using a deferred code object and some
1422 // inline code to operate on smis quickly. 1418 // inline code to operate on smis quickly.
1423 Result CodeGenerator::LikelySmiBinaryOperation(Token::Value op, 1419 Result CodeGenerator::LikelySmiBinaryOperation(BinaryOperation* expr,
1424 Result* left, 1420 Result* left,
1425 Result* right, 1421 Result* right,
1426 OverwriteMode overwrite_mode, 1422 OverwriteMode overwrite_mode) {
1427 bool no_negative_zero) { 1423 Token::Value op = expr->op();
1428 Result answer; 1424 Result answer;
1429 // Special handling of div and mod because they use fixed registers. 1425 // Special handling of div and mod because they use fixed registers.
1430 if (op == Token::DIV || op == Token::MOD) { 1426 if (op == Token::DIV || op == Token::MOD) {
1431 // We need eax as the quotient register, edx as the remainder 1427 // We need eax as the quotient register, edx as the remainder
1432 // register, neither left nor right in eax or edx, and left copied 1428 // register, neither left nor right in eax or edx, and left copied
1433 // to eax. 1429 // to eax.
1434 Result quotient; 1430 Result quotient;
1435 Result remainder; 1431 Result remainder;
1436 bool left_is_in_eax = false; 1432 bool left_is_in_eax = false;
1437 // Step 1: get eax for quotient. 1433 // Step 1: get eax for quotient.
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
1523 // Divide edx:eax by the right operand. 1519 // Divide edx:eax by the right operand.
1524 __ idiv(right->reg()); 1520 __ idiv(right->reg());
1525 1521
1526 // Complete the operation. 1522 // Complete the operation.
1527 if (op == Token::DIV) { 1523 if (op == Token::DIV) {
1528 // Check for negative zero result. If result is zero, and divisor 1524 // Check for negative zero result. If result is zero, and divisor
1529 // is negative, return a floating point negative zero. The 1525 // is negative, return a floating point negative zero. The
1530 // virtual frame is unchanged in this block, so local control flow 1526 // virtual frame is unchanged in this block, so local control flow
1531 // can use a Label rather than a JumpTarget. If the context of this 1527 // can use a Label rather than a JumpTarget. If the context of this
1532 // expression will treat -0 like 0, do not do this test. 1528 // expression will treat -0 like 0, do not do this test.
1533 if (!no_negative_zero) { 1529 if (!expr->no_negative_zero()) {
1534 Label non_zero_result; 1530 Label non_zero_result;
1535 __ test(left->reg(), Operand(left->reg())); 1531 __ test(left->reg(), Operand(left->reg()));
1536 __ j(not_zero, &non_zero_result); 1532 __ j(not_zero, &non_zero_result);
1537 __ test(right->reg(), Operand(right->reg())); 1533 __ test(right->reg(), Operand(right->reg()));
1538 deferred->Branch(negative); 1534 deferred->Branch(negative);
1539 __ bind(&non_zero_result); 1535 __ bind(&non_zero_result);
1540 } 1536 }
1541 // Check for the corner case of dividing the most negative smi by 1537 // Check for the corner case of dividing the most negative smi by
1542 // -1. We cannot use the overflow flag, since it is not set by 1538 // -1. We cannot use the overflow flag, since it is not set by
1543 // idiv instruction. 1539 // idiv instruction.
1544 ASSERT(kSmiTag == 0 && kSmiTagSize == 1); 1540 ASSERT(kSmiTag == 0 && kSmiTagSize == 1);
1545 __ cmp(eax, 0x40000000); 1541 __ cmp(eax, 0x40000000);
1546 deferred->Branch(equal); 1542 deferred->Branch(equal);
1547 // Check that the remainder is zero. 1543 // Check that the remainder is zero.
1548 __ test(edx, Operand(edx)); 1544 __ test(edx, Operand(edx));
1549 deferred->Branch(not_zero); 1545 deferred->Branch(not_zero);
1550 // Tag the result and store it in the quotient register. 1546 // Tag the result and store it in the quotient register.
1551 __ SmiTag(eax); 1547 __ SmiTag(eax);
1552 deferred->BindExit(); 1548 deferred->BindExit();
1553 left->Unuse(); 1549 left->Unuse();
1554 right->Unuse(); 1550 right->Unuse();
1555 answer = quotient; 1551 answer = quotient;
1556 } else { 1552 } else {
1557 ASSERT(op == Token::MOD); 1553 ASSERT(op == Token::MOD);
1558 // Check for a negative zero result. If the result is zero, and 1554 // Check for a negative zero result. If the result is zero, and
1559 // the dividend is negative, return a floating point negative 1555 // the dividend is negative, return a floating point negative
1560 // zero. The frame is unchanged in this block, so local control 1556 // zero. The frame is unchanged in this block, so local control
1561 // flow can use a Label rather than a JumpTarget. 1557 // flow can use a Label rather than a JumpTarget.
1562 if (!no_negative_zero) { 1558 if (!expr->no_negative_zero()) {
1563 Label non_zero_result; 1559 Label non_zero_result;
1564 __ test(edx, Operand(edx)); 1560 __ test(edx, Operand(edx));
1565 __ j(not_zero, &non_zero_result, taken); 1561 __ j(not_zero, &non_zero_result, taken);
1566 __ test(left->reg(), Operand(left->reg())); 1562 __ test(left->reg(), Operand(left->reg()));
1567 deferred->Branch(negative); 1563 deferred->Branch(negative);
1568 __ bind(&non_zero_result); 1564 __ bind(&non_zero_result);
1569 } 1565 }
1570 deferred->BindExit(); 1566 deferred->BindExit();
1571 left->Unuse(); 1567 left->Unuse();
1572 right->Unuse(); 1568 right->Unuse();
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1736 // Left-hand operand has been copied into answer. 1732 // Left-hand operand has been copied into answer.
1737 __ SmiUntag(answer.reg()); 1733 __ SmiUntag(answer.reg());
1738 // Do multiplication of smis, leaving result in answer. 1734 // Do multiplication of smis, leaving result in answer.
1739 __ imul(answer.reg(), Operand(right->reg())); 1735 __ imul(answer.reg(), Operand(right->reg()));
1740 // Go slow on overflows. 1736 // Go slow on overflows.
1741 deferred->Branch(overflow); 1737 deferred->Branch(overflow);
1742 // Check for negative zero result. If product is zero, and one 1738 // Check for negative zero result. If product is zero, and one
1743 // argument is negative, go to slow case. The frame is unchanged 1739 // argument is negative, go to slow case. The frame is unchanged
1744 // in this block, so local control flow can use a Label rather 1740 // in this block, so local control flow can use a Label rather
1745 // than a JumpTarget. 1741 // than a JumpTarget.
1746 if (!no_negative_zero) { 1742 if (!expr->no_negative_zero()) {
1747 Label non_zero_result; 1743 Label non_zero_result;
1748 __ test(answer.reg(), Operand(answer.reg())); 1744 __ test(answer.reg(), Operand(answer.reg()));
1749 __ j(not_zero, &non_zero_result, taken); 1745 __ j(not_zero, &non_zero_result, taken);
1750 __ mov(answer.reg(), left->reg()); 1746 __ mov(answer.reg(), left->reg());
1751 __ or_(answer.reg(), Operand(right->reg())); 1747 __ or_(answer.reg(), Operand(right->reg()));
1752 deferred->Branch(negative); 1748 deferred->Branch(negative);
1753 __ xor_(answer.reg(), Operand(answer.reg())); // Positive 0 is correct. 1749 __ xor_(answer.reg(), Operand(answer.reg())); // Positive 0 is correct.
1754 __ bind(&non_zero_result); 1750 __ bind(&non_zero_result);
1755 } 1751 }
1756 break; 1752 break;
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1979 GenericBinaryOpStub igostub( 1975 GenericBinaryOpStub igostub(
1980 Token::SUB, 1976 Token::SUB,
1981 overwrite_mode_, 1977 overwrite_mode_,
1982 NO_SMI_CODE_IN_STUB, 1978 NO_SMI_CODE_IN_STUB,
1983 TypeInfo::Combine(TypeInfo::Smi(), type_info_)); 1979 TypeInfo::Combine(TypeInfo::Smi(), type_info_));
1984 igostub.GenerateCall(masm_, dst_, value_); 1980 igostub.GenerateCall(masm_, dst_, value_);
1985 if (!dst_.is(eax)) __ mov(dst_, eax); 1981 if (!dst_.is(eax)) __ mov(dst_, eax);
1986 } 1982 }
1987 1983
1988 1984
1989 Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, 1985 Result CodeGenerator::ConstantSmiBinaryOperation(
1990 Result* operand, 1986 BinaryOperation* expr,
1991 Handle<Object> value, 1987 Result* operand,
1992 StaticType* type, 1988 Handle<Object> value,
1993 bool reversed, 1989 bool reversed,
1994 OverwriteMode overwrite_mode, 1990 OverwriteMode overwrite_mode) {
1995 bool no_negative_zero) {
1996 // NOTE: This is an attempt to inline (a bit) more of the code for 1991 // NOTE: This is an attempt to inline (a bit) more of the code for
1997 // some possible smi operations (like + and -) when (at least) one 1992 // some possible smi operations (like + and -) when (at least) one
1998 // of the operands is a constant smi. 1993 // of the operands is a constant smi.
1999 // Consumes the argument "operand". 1994 // Consumes the argument "operand".
2000 // TODO(199): Optimize some special cases of operations involving a 1995 // TODO(199): Optimize some special cases of operations involving a
2001 // smi literal (multiply by 2, shift by 0, etc.). 1996 // smi literal (multiply by 2, shift by 0, etc.).
2002 if (IsUnsafeSmi(value)) { 1997 if (IsUnsafeSmi(value)) {
2003 Result unsafe_operand(value); 1998 Result unsafe_operand(value);
2004 if (reversed) { 1999 if (reversed) {
2005 return LikelySmiBinaryOperation(op, &unsafe_operand, operand, 2000 return LikelySmiBinaryOperation(expr, &unsafe_operand, operand,
2006 overwrite_mode, no_negative_zero); 2001 overwrite_mode);
2007 } else { 2002 } else {
2008 return LikelySmiBinaryOperation(op, operand, &unsafe_operand, 2003 return LikelySmiBinaryOperation(expr, operand, &unsafe_operand,
2009 overwrite_mode, no_negative_zero); 2004 overwrite_mode);
2010 } 2005 }
2011 } 2006 }
2012 2007
2013 // Get the literal value. 2008 // Get the literal value.
2014 Smi* smi_value = Smi::cast(*value); 2009 Smi* smi_value = Smi::cast(*value);
2015 int int_value = smi_value->value(); 2010 int int_value = smi_value->value();
2016 2011
2012 Token::Value op = expr->op();
2017 Result answer; 2013 Result answer;
2018 switch (op) { 2014 switch (op) {
2019 case Token::ADD: { 2015 case Token::ADD: {
2020 operand->ToRegister(); 2016 operand->ToRegister();
2021 frame_->Spill(operand->reg()); 2017 frame_->Spill(operand->reg());
2022 2018
2023 // Optimistically add. Call the specialized add stub if the 2019 // Optimistically add. Call the specialized add stub if the
2024 // result is not a smi or overflows. 2020 // result is not a smi or overflows.
2025 DeferredCode* deferred = NULL; 2021 DeferredCode* deferred = NULL;
2026 if (reversed) { 2022 if (reversed) {
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2082 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg()); 2078 if (FLAG_debug_code) __ AbortIfNotSmi(operand->reg());
2083 } 2079 }
2084 deferred->BindExit(); 2080 deferred->BindExit();
2085 operand->Unuse(); 2081 operand->Unuse();
2086 break; 2082 break;
2087 } 2083 }
2088 2084
2089 case Token::SAR: 2085 case Token::SAR:
2090 if (reversed) { 2086 if (reversed) {
2091 Result constant_operand(value); 2087 Result constant_operand(value);
2092 answer = LikelySmiBinaryOperation(op, &constant_operand, operand, 2088 answer = LikelySmiBinaryOperation(expr, &constant_operand, operand,
2093 overwrite_mode, no_negative_zero); 2089 overwrite_mode);
2094 } else { 2090 } else {
2095 // Only the least significant 5 bits of the shift value are used. 2091 // Only the least significant 5 bits of the shift value are used.
2096 // In the slow case, this masking is done inside the runtime call. 2092 // In the slow case, this masking is done inside the runtime call.
2097 int shift_value = int_value & 0x1f; 2093 int shift_value = int_value & 0x1f;
2098 operand->ToRegister(); 2094 operand->ToRegister();
2099 frame_->Spill(operand->reg()); 2095 frame_->Spill(operand->reg());
2100 if (!operand->type_info().IsSmi()) { 2096 if (!operand->type_info().IsSmi()) {
2101 DeferredInlineSmiOperation* deferred = 2097 DeferredInlineSmiOperation* deferred =
2102 new DeferredInlineSmiOperation(op, 2098 new DeferredInlineSmiOperation(op,
2103 operand->reg(), 2099 operand->reg(),
(...skipping 15 matching lines...) Expand all
2119 __ and_(operand->reg(), ~kSmiTagMask); 2115 __ and_(operand->reg(), ~kSmiTagMask);
2120 } 2116 }
2121 } 2117 }
2122 answer = *operand; 2118 answer = *operand;
2123 } 2119 }
2124 break; 2120 break;
2125 2121
2126 case Token::SHR: 2122 case Token::SHR:
2127 if (reversed) { 2123 if (reversed) {
2128 Result constant_operand(value); 2124 Result constant_operand(value);
2129 answer = LikelySmiBinaryOperation(op, &constant_operand, operand, 2125 answer = LikelySmiBinaryOperation(expr, &constant_operand, operand,
2130 overwrite_mode, no_negative_zero); 2126 overwrite_mode);
2131 } else { 2127 } else {
2132 // Only the least significant 5 bits of the shift value are used. 2128 // Only the least significant 5 bits of the shift value are used.
2133 // In the slow case, this masking is done inside the runtime call. 2129 // In the slow case, this masking is done inside the runtime call.
2134 int shift_value = int_value & 0x1f; 2130 int shift_value = int_value & 0x1f;
2135 operand->ToRegister(); 2131 operand->ToRegister();
2136 answer = allocator()->Allocate(); 2132 answer = allocator()->Allocate();
2137 ASSERT(answer.is_valid()); 2133 ASSERT(answer.is_valid());
2138 DeferredInlineSmiOperation* deferred = 2134 DeferredInlineSmiOperation* deferred =
2139 new DeferredInlineSmiOperation(op, 2135 new DeferredInlineSmiOperation(op,
2140 answer.reg(), 2136 answer.reg(),
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
2320 __ test(operand->reg(), Immediate(3)); 2316 __ test(operand->reg(), Immediate(3));
2321 deferred->Branch(not_zero); // Branch if non-smi or odd smi. 2317 deferred->Branch(not_zero); // Branch if non-smi or odd smi.
2322 __ sar(operand->reg(), 1); 2318 __ sar(operand->reg(), 1);
2323 deferred->BindExit(); 2319 deferred->BindExit();
2324 answer = *operand; 2320 answer = *operand;
2325 } else { 2321 } else {
2326 // Cannot fall through MOD to default case, so we duplicate the 2322 // Cannot fall through MOD to default case, so we duplicate the
2327 // default case here. 2323 // default case here.
2328 Result constant_operand(value); 2324 Result constant_operand(value);
2329 if (reversed) { 2325 if (reversed) {
2330 answer = LikelySmiBinaryOperation(op, &constant_operand, operand, 2326 answer = LikelySmiBinaryOperation(expr, &constant_operand, operand,
2331 overwrite_mode, no_negative_zero); 2327 overwrite_mode);
2332 } else { 2328 } else {
2333 answer = LikelySmiBinaryOperation(op, operand, &constant_operand, 2329 answer = LikelySmiBinaryOperation(expr, operand, &constant_operand,
2334 overwrite_mode, no_negative_zero); 2330 overwrite_mode);
2335 } 2331 }
2336 } 2332 }
2337 break; 2333 break;
2338 // Generate inline code for mod of powers of 2 and negative powers of 2. 2334 // Generate inline code for mod of powers of 2 and negative powers of 2.
2339 case Token::MOD: 2335 case Token::MOD:
2340 if (!reversed && 2336 if (!reversed &&
2341 int_value != 0 && 2337 int_value != 0 &&
2342 (IsPowerOf2(int_value) || IsPowerOf2(-int_value))) { 2338 (IsPowerOf2(int_value) || IsPowerOf2(-int_value))) {
2343 operand->ToRegister(); 2339 operand->ToRegister();
2344 frame_->Spill(operand->reg()); 2340 frame_->Spill(operand->reg());
(...skipping 15 matching lines...) Expand all
2360 } 2356 }
2361 deferred->BindExit(); 2357 deferred->BindExit();
2362 answer = *operand; 2358 answer = *operand;
2363 break; 2359 break;
2364 } 2360 }
2365 // Fall through if we did not find a power of 2 on the right hand side! 2361 // Fall through if we did not find a power of 2 on the right hand side!
2366 2362
2367 default: { 2363 default: {
2368 Result constant_operand(value); 2364 Result constant_operand(value);
2369 if (reversed) { 2365 if (reversed) {
2370 answer = LikelySmiBinaryOperation(op, &constant_operand, operand, 2366 answer = LikelySmiBinaryOperation(expr, &constant_operand, operand,
2371 overwrite_mode, no_negative_zero); 2367 overwrite_mode);
2372 } else { 2368 } else {
2373 answer = LikelySmiBinaryOperation(op, operand, &constant_operand, 2369 answer = LikelySmiBinaryOperation(expr, operand, &constant_operand,
2374 overwrite_mode, no_negative_zero); 2370 overwrite_mode);
2375 } 2371 }
2376 break; 2372 break;
2377 } 2373 }
2378 } 2374 }
2379 ASSERT(answer.is_valid()); 2375 ASSERT(answer.is_valid());
2380 return answer; 2376 return answer;
2381 } 2377 }
2382 2378
2383 2379
2384 static bool CouldBeNaN(const Result& result) { 2380 static bool CouldBeNaN(const Result& result) {
(...skipping 2979 matching lines...) Expand 10 before | Expand all | Expand 10 after
5364 5360
5365 // Evaluate the right-hand side. 5361 // Evaluate the right-hand side.
5366 if (node->is_compound()) { 5362 if (node->is_compound()) {
5367 Result result = LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF); 5363 Result result = LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF);
5368 frame()->Push(&result); 5364 frame()->Push(&result);
5369 Load(node->value()); 5365 Load(node->value());
5370 5366
5371 bool overwrite_value = 5367 bool overwrite_value =
5372 (node->value()->AsBinaryOperation() != NULL && 5368 (node->value()->AsBinaryOperation() != NULL &&
5373 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); 5369 node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
5374 GenericBinaryOperation(node->binary_op(), 5370 // Construct the implicit binary operation.
5375 node->type(), 5371 BinaryOperation expr(node, node->binary_op(), node->target(),
5376 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE, 5372 node->value());
5377 node->no_negative_zero()); 5373 GenericBinaryOperation(&expr,
5374 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
5378 } else { 5375 } else {
5379 Load(node->value()); 5376 Load(node->value());
5380 } 5377 }
5381 5378
5382 // Perform the assignment. 5379 // Perform the assignment.
5383 if (var->mode() != Variable::CONST || node->op() == Token::INIT_CONST) { 5380 if (var->mode() != Variable::CONST || node->op() == Token::INIT_CONST) {
5384 CodeForSourcePosition(node->position()); 5381 CodeForSourcePosition(node->position());
5385 StoreToSlot(slot, 5382 StoreToSlot(slot,
5386 node->op() == Token::INIT_CONST ? CONST_INIT : NOT_CONST_INIT); 5383 node->op() == Token::INIT_CONST ? CONST_INIT : NOT_CONST_INIT);
5387 } 5384 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
5442 } else { 5439 } else {
5443 frame()->Dup(); 5440 frame()->Dup();
5444 } 5441 }
5445 Result value = EmitNamedLoad(name, var != NULL); 5442 Result value = EmitNamedLoad(name, var != NULL);
5446 frame()->Push(&value); 5443 frame()->Push(&value);
5447 Load(node->value()); 5444 Load(node->value());
5448 5445
5449 bool overwrite_value = 5446 bool overwrite_value =
5450 (node->value()->AsBinaryOperation() != NULL && 5447 (node->value()->AsBinaryOperation() != NULL &&
5451 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); 5448 node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
5452 GenericBinaryOperation(node->binary_op(), 5449 // Construct the implicit binary operation.
5453 node->type(), 5450 BinaryOperation expr(node, node->binary_op(), node->target(),
5454 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE, 5451 node->value());
5455 node->no_negative_zero()); 5452 GenericBinaryOperation(&expr,
5453 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
5456 } else { 5454 } else {
5457 Load(node->value()); 5455 Load(node->value());
5458 } 5456 }
5459 5457
5460 // Perform the assignment. It is safe to ignore constants here. 5458 // Perform the assignment. It is safe to ignore constants here.
5461 ASSERT(var == NULL || var->mode() != Variable::CONST); 5459 ASSERT(var == NULL || var->mode() != Variable::CONST);
5462 ASSERT_NE(Token::INIT_CONST, node->op()); 5460 ASSERT_NE(Token::INIT_CONST, node->op());
5463 if (is_trivial_receiver) { 5461 if (is_trivial_receiver) {
5464 Result value = frame()->Pop(); 5462 Result value = frame()->Pop();
5465 frame()->Push(prop->obj()); 5463 frame()->Push(prop->obj());
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
5522 // Duplicate receiver and key. 5520 // Duplicate receiver and key.
5523 frame()->PushElementAt(1); 5521 frame()->PushElementAt(1);
5524 frame()->PushElementAt(1); 5522 frame()->PushElementAt(1);
5525 Result value = EmitKeyedLoad(); 5523 Result value = EmitKeyedLoad();
5526 frame()->Push(&value); 5524 frame()->Push(&value);
5527 Load(node->value()); 5525 Load(node->value());
5528 5526
5529 bool overwrite_value = 5527 bool overwrite_value =
5530 (node->value()->AsBinaryOperation() != NULL && 5528 (node->value()->AsBinaryOperation() != NULL &&
5531 node->value()->AsBinaryOperation()->ResultOverwriteAllowed()); 5529 node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
5532 GenericBinaryOperation(node->binary_op(), 5530 BinaryOperation expr(node, node->binary_op(), node->target(),
5533 node->type(), 5531 node->value());
5534 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE, 5532 GenericBinaryOperation(&expr,
5535 node->no_negative_zero()); 5533 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
5536 } else { 5534 } else {
5537 Load(node->value()); 5535 Load(node->value());
5538 } 5536 }
5539 5537
5540 // Perform the assignment. It is safe to ignore constants here. 5538 // Perform the assignment. It is safe to ignore constants here.
5541 ASSERT(node->op() != Token::INIT_CONST); 5539 ASSERT(node->op() != Token::INIT_CONST);
5542 CodeForSourcePosition(node->position()); 5540 CodeForSourcePosition(node->position());
5543 Result answer = EmitKeyedStore(prop->key()->type()); 5541 Result answer = EmitKeyedStore(prop->key()->type());
5544 frame()->Push(&answer); 5542 frame()->Push(&answer);
5545 5543
(...skipping 2083 matching lines...) Expand 10 before | Expand all | Expand 10 after
7629 7627
7630 if (node->left()->IsTrivial()) { 7628 if (node->left()->IsTrivial()) {
7631 Load(node->right()); 7629 Load(node->right());
7632 Result right = frame_->Pop(); 7630 Result right = frame_->Pop();
7633 frame_->Push(node->left()); 7631 frame_->Push(node->left());
7634 frame_->Push(&right); 7632 frame_->Push(&right);
7635 } else { 7633 } else {
7636 Load(node->left()); 7634 Load(node->left());
7637 Load(node->right()); 7635 Load(node->right());
7638 } 7636 }
7639 GenericBinaryOperation(node->op(), node->type(), 7637 GenericBinaryOperation(node, overwrite_mode);
7640 overwrite_mode, node->no_negative_zero());
7641 } 7638 }
7642 } 7639 }
7643 7640
7644 7641
7645 void CodeGenerator::VisitThisFunction(ThisFunction* node) { 7642 void CodeGenerator::VisitThisFunction(ThisFunction* node) {
7646 ASSERT(!in_safe_int32_mode()); 7643 ASSERT(!in_safe_int32_mode());
7647 frame_->PushFunction(); 7644 frame_->PushFunction();
7648 } 7645 }
7649 7646
7650 7647
(...skipping 4953 matching lines...) Expand 10 before | Expand all | Expand 10 after
12604 12601
12605 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 12602 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
12606 // tagged as a small integer. 12603 // tagged as a small integer.
12607 __ bind(&runtime); 12604 __ bind(&runtime);
12608 __ TailCallRuntime(Runtime::kStringCompare, 2, 1); 12605 __ TailCallRuntime(Runtime::kStringCompare, 2, 1);
12609 } 12606 }
12610 12607
12611 #undef __ 12608 #undef __
12612 12609
12613 } } // namespace v8::internal 12610 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/codegen-ia32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698