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

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

Issue 113518: Allow a few more (multiple-entry) deferred code snippets to take the... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 7 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 | « no previous file | 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 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 4866 matching lines...) Expand 10 before | Expand all | Expand 10 after
4877 // 4877 //
4878 // We combine the overflow and the smi check if we could 4878 // We combine the overflow and the smi check if we could
4879 // successfully allocate a temporary byte register. 4879 // successfully allocate a temporary byte register.
4880 if (tmp.is_valid()) { 4880 if (tmp.is_valid()) {
4881 __ setcc(overflow, tmp.reg()); 4881 __ setcc(overflow, tmp.reg());
4882 __ or_(Operand(tmp.reg()), value.reg()); 4882 __ or_(Operand(tmp.reg()), value.reg());
4883 __ test(tmp.reg(), Immediate(kSmiTagMask)); 4883 __ test(tmp.reg(), Immediate(kSmiTagMask));
4884 tmp.Unuse(); 4884 tmp.Unuse();
4885 deferred->enter()->Branch(not_zero, &value, not_taken); 4885 deferred->enter()->Branch(not_zero, &value, not_taken);
4886 } else { // Otherwise we test separately for overflow and smi check. 4886 } else { // Otherwise we test separately for overflow and smi check.
4887 deferred->SetEntryFrame(&value);
4887 deferred->enter()->Branch(overflow, &value, not_taken); 4888 deferred->enter()->Branch(overflow, &value, not_taken);
4888 __ test(value.reg(), Immediate(kSmiTagMask)); 4889 __ test(value.reg(), Immediate(kSmiTagMask));
4889 deferred->enter()->Branch(not_zero, &value, not_taken); 4890 deferred->enter()->Branch(not_zero, &value, not_taken);
4890 } 4891 }
4891 4892
4892 // Store the new value in the target if not const. 4893 // Store the new value in the target if not const.
4893 deferred->BindExit(&value); 4894 deferred->BindExit(&value);
4894 frame_->Push(&value); 4895 frame_->Push(&value);
4895 if (!is_const) { 4896 if (!is_const) {
4896 target.SetValue(NOT_CONST_INIT); 4897 target.SetValue(NOT_CONST_INIT);
(...skipping 836 matching lines...) Expand 10 before | Expand all | Expand 10 after
5733 ASSERT(answer.is_valid()); 5734 ASSERT(answer.is_valid());
5734 // Perform the smi check. 5735 // Perform the smi check.
5735 if (left->reg().is(right->reg())) { 5736 if (left->reg().is(right->reg())) {
5736 __ test(left->reg(), Immediate(kSmiTagMask)); 5737 __ test(left->reg(), Immediate(kSmiTagMask));
5737 } else { 5738 } else {
5738 __ mov(answer.reg(), left->reg()); 5739 __ mov(answer.reg(), left->reg());
5739 __ or_(answer.reg(), Operand(right->reg())); 5740 __ or_(answer.reg(), Operand(right->reg()));
5740 ASSERT(kSmiTag == 0); // adjust zero check if not the case 5741 ASSERT(kSmiTag == 0); // adjust zero check if not the case
5741 __ test(answer.reg(), Immediate(kSmiTagMask)); 5742 __ test(answer.reg(), Immediate(kSmiTagMask));
5742 } 5743 }
5743 enter()->Branch(not_zero, left, right, not_taken);
5744
5745 // All operations start by copying the left argument into answer.
5746 __ mov(answer.reg(), left->reg());
5747 switch (op_) { 5744 switch (op_) {
5748 case Token::ADD: 5745 case Token::ADD:
5746 SetEntryFrame(left, right);
5747 enter()->Branch(not_zero, left, right, not_taken);
5748 __ mov(answer.reg(), left->reg());
5749 __ add(answer.reg(), Operand(right->reg())); // add optimistically 5749 __ add(answer.reg(), Operand(right->reg())); // add optimistically
5750 enter()->Branch(overflow, left, right, not_taken); 5750 enter()->Branch(overflow, left, right, not_taken);
5751 break; 5751 break;
5752 5752
5753 case Token::SUB: 5753 case Token::SUB:
5754 SetEntryFrame(left, right);
5755 enter()->Branch(not_zero, left, right, not_taken);
5756 __ mov(answer.reg(), left->reg());
5754 __ sub(answer.reg(), Operand(right->reg())); // subtract optimistically 5757 __ sub(answer.reg(), Operand(right->reg())); // subtract optimistically
5755 enter()->Branch(overflow, left, right, not_taken); 5758 enter()->Branch(overflow, left, right, not_taken);
5756 break; 5759 break;
5757 5760
5758 case Token::MUL: { 5761 case Token::MUL: {
5762 SetEntryFrame(left, right);
5763 enter()->Branch(not_zero, left, right, not_taken);
5764 __ mov(answer.reg(), left->reg());
5759 // If the smi tag is 0 we can just leave the tag on one operand. 5765 // If the smi tag is 0 we can just leave the tag on one operand.
5760 ASSERT(kSmiTag == 0); // adjust code below if not the case 5766 ASSERT(kSmiTag == 0); // adjust code below if not the case
5761 // Remove tag from the left operand (but keep sign). 5767 // Remove tag from the left operand (but keep sign).
5762 // Left hand operand has been copied into answer. 5768 // Left hand operand has been copied into answer.
5763 __ sar(answer.reg(), kSmiTagSize); 5769 __ sar(answer.reg(), kSmiTagSize);
5764 // Do multiplication of smis, leaving result in answer. 5770 // Do multiplication of smis, leaving result in answer.
5765 __ imul(answer.reg(), Operand(right->reg())); 5771 __ imul(answer.reg(), Operand(right->reg()));
5766 // Go slow on overflows. 5772 // Go slow on overflows.
5767 enter()->Branch(overflow, left, right, not_taken); 5773 enter()->Branch(overflow, left, right, not_taken);
5768 // Check for negative zero result. If product is zero, 5774 // Check for negative zero result. If product is zero,
5769 // and one argument is negative, go to slow case. 5775 // and one argument is negative, go to slow case.
5770 // The frame is unchanged in this block, so local control flow can 5776 // The frame is unchanged in this block, so local control flow can
5771 // use a Label rather than a JumpTarget. 5777 // use a Label rather than a JumpTarget.
5772 Label non_zero_result; 5778 Label non_zero_result;
5773 __ test(answer.reg(), Operand(answer.reg())); 5779 __ test(answer.reg(), Operand(answer.reg()));
5774 __ j(not_zero, &non_zero_result, taken); 5780 __ j(not_zero, &non_zero_result, taken);
5775 __ mov(answer.reg(), left->reg()); 5781 __ mov(answer.reg(), left->reg());
5776 __ or_(answer.reg(), Operand(right->reg())); 5782 __ or_(answer.reg(), Operand(right->reg()));
5777 enter()->Branch(negative, left, right, not_taken); 5783 enter()->Branch(negative, left, right, not_taken);
5778 __ xor_(answer.reg(), Operand(answer.reg())); // Positive 0 is correct. 5784 __ xor_(answer.reg(), Operand(answer.reg())); // Positive 0 is correct.
5779 __ bind(&non_zero_result); 5785 __ bind(&non_zero_result);
5780 break; 5786 break;
5781 } 5787 }
5782 5788
5783 case Token::DIV: // Fall through. 5789 case Token::DIV: // Fall through.
5784 case Token::MOD: { 5790 case Token::MOD: {
5791 enter()->Branch(not_zero, left, right, not_taken);
5792 __ mov(answer.reg(), left->reg());
5785 // Div and mod use the registers eax and edx. Left and right must 5793 // Div and mod use the registers eax and edx. Left and right must
5786 // be preserved, because the original operands are needed if we switch 5794 // be preserved, because the original operands are needed if we switch
5787 // to the slow case. Move them if either is in eax or edx. 5795 // to the slow case. Move them if either is in eax or edx.
5788 // The Result answer should be changed into an alias for eax. 5796 // The Result answer should be changed into an alias for eax.
5789 // Precondition: 5797 // Precondition:
5790 // The Results left and right are valid. They may be the same register, 5798 // The Results left and right are valid. They may be the same register,
5791 // and may be unspilled. The Result answer is valid and is distinct 5799 // and may be unspilled. The Result answer is valid and is distinct
5792 // from left and right, and is spilled. 5800 // from left and right, and is spilled.
5793 // The value in left is copied to answer. 5801 // The value in left is copied to answer.
5794 5802
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
5912 __ j(not_zero, &non_zero_result, taken); 5920 __ j(not_zero, &non_zero_result, taken);
5913 __ test(left->reg(), Operand(left->reg())); 5921 __ test(left->reg(), Operand(left->reg()));
5914 enter()->Branch(negative, left, right, not_taken); 5922 enter()->Branch(negative, left, right, not_taken);
5915 __ bind(&non_zero_result); 5923 __ bind(&non_zero_result);
5916 // The answer is in edx. 5924 // The answer is in edx.
5917 answer = reg_edx; 5925 answer = reg_edx;
5918 } 5926 }
5919 break; 5927 break;
5920 } 5928 }
5921 case Token::BIT_OR: 5929 case Token::BIT_OR:
5930 enter()->Branch(not_zero, left, right, not_taken);
5931 __ mov(answer.reg(), left->reg());
5922 __ or_(answer.reg(), Operand(right->reg())); 5932 __ or_(answer.reg(), Operand(right->reg()));
5923 break; 5933 break;
5924 5934
5925 case Token::BIT_AND: 5935 case Token::BIT_AND:
5936 enter()->Branch(not_zero, left, right, not_taken);
5937 __ mov(answer.reg(), left->reg());
5926 __ and_(answer.reg(), Operand(right->reg())); 5938 __ and_(answer.reg(), Operand(right->reg()));
5927 break; 5939 break;
5928 5940
5929 case Token::BIT_XOR: 5941 case Token::BIT_XOR:
5942 enter()->Branch(not_zero, left, right, not_taken);
5943 __ mov(answer.reg(), left->reg());
5930 __ xor_(answer.reg(), Operand(right->reg())); 5944 __ xor_(answer.reg(), Operand(right->reg()));
5931 break; 5945 break;
5932 5946
5933 case Token::SHL: 5947 case Token::SHL:
5934 case Token::SHR: 5948 case Token::SHR:
5935 case Token::SAR: 5949 case Token::SAR:
5950 enter()->Branch(not_zero, left, right, not_taken);
5951 __ mov(answer.reg(), left->reg());
5936 // Move right into ecx. 5952 // Move right into ecx.
5937 // Left is in two registers already, so even if left or answer is ecx, 5953 // Left is in two registers already, so even if left or answer is ecx,
5938 // we can move right to it, and use the other one. 5954 // we can move right to it, and use the other one.
5939 // Right operand must be in register cl because x86 likes it that way. 5955 // Right operand must be in register cl because x86 likes it that way.
5940 if (right->reg().is(ecx)) { 5956 if (right->reg().is(ecx)) {
5941 // Right is already in the right place. Left may be in the 5957 // Right is already in the right place. Left may be in the
5942 // same register, which causes problems. Always use answer 5958 // same register, which causes problems. Always use answer
5943 // instead of left, even if left is not ecx, since this avoids 5959 // instead of left, even if left is not ecx, since this avoids
5944 // spilling left. 5960 // spilling left.
5945 *left = answer; 5961 *left = answer;
(...skipping 1311 matching lines...) Expand 10 before | Expand all | Expand 10 after
7257 7273
7258 // Slow-case: Go through the JavaScript implementation. 7274 // Slow-case: Go through the JavaScript implementation.
7259 __ bind(&slow); 7275 __ bind(&slow);
7260 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 7276 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
7261 } 7277 }
7262 7278
7263 7279
7264 #undef __ 7280 #undef __
7265 7281
7266 } } // namespace v8::internal 7282 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698