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

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

Issue 391073: Changes to Intel shift functions... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 1 month 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
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 1170 matching lines...) Expand 10 before | Expand all | Expand 10 after
1181 __ test(answer.reg(), Immediate(kSmiTagMask)); 1181 __ test(answer.reg(), Immediate(kSmiTagMask));
1182 deferred->Branch(not_zero); 1182 deferred->Branch(not_zero);
1183 1183
1184 // Untag both operands. 1184 // Untag both operands.
1185 __ mov(answer.reg(), left->reg()); 1185 __ mov(answer.reg(), left->reg());
1186 __ sar(answer.reg(), kSmiTagSize); 1186 __ sar(answer.reg(), kSmiTagSize);
1187 __ sar(ecx, kSmiTagSize); 1187 __ sar(ecx, kSmiTagSize);
1188 // Perform the operation. 1188 // Perform the operation.
1189 switch (op) { 1189 switch (op) {
1190 case Token::SAR: 1190 case Token::SAR:
1191 __ sar(answer.reg()); 1191 __ sar_cl(answer.reg());
1192 // No checks of result necessary 1192 // No checks of result necessary
1193 break; 1193 break;
1194 case Token::SHR: { 1194 case Token::SHR: {
1195 Label result_ok; 1195 Label result_ok;
1196 __ shr(answer.reg()); 1196 __ shr_cl(answer.reg());
1197 // Check that the *unsigned* result fits in a smi. Neither of 1197 // Check that the *unsigned* result fits in a smi. Neither of
1198 // the two high-order bits can be set: 1198 // the two high-order bits can be set:
1199 // * 0x80000000: high bit would be lost when smi tagging. 1199 // * 0x80000000: high bit would be lost when smi tagging.
1200 // * 0x40000000: this number would convert to negative when smi 1200 // * 0x40000000: this number would convert to negative when smi
1201 // tagging. 1201 // tagging.
1202 // These two cases can only happen with shifts by 0 or 1 when 1202 // These two cases can only happen with shifts by 0 or 1 when
1203 // handed a valid smi. If the answer cannot be represented by a 1203 // handed a valid smi. If the answer cannot be represented by a
1204 // smi, restore the left and right arguments, and jump to slow 1204 // smi, restore the left and right arguments, and jump to slow
1205 // case. The low bit of the left argument may be lost, but only 1205 // case. The low bit of the left argument may be lost, but only
1206 // in a case where it is dropped anyway. 1206 // in a case where it is dropped anyway.
1207 __ test(answer.reg(), Immediate(0xc0000000)); 1207 __ test(answer.reg(), Immediate(0xc0000000));
1208 __ j(zero, &result_ok); 1208 __ j(zero, &result_ok);
1209 ASSERT(kSmiTag == 0); 1209 ASSERT(kSmiTag == 0);
1210 __ shl(ecx, kSmiTagSize); 1210 __ shl(ecx, kSmiTagSize);
1211 deferred->Jump(); 1211 deferred->Jump();
1212 __ bind(&result_ok); 1212 __ bind(&result_ok);
1213 break; 1213 break;
1214 } 1214 }
1215 case Token::SHL: { 1215 case Token::SHL: {
1216 Label result_ok; 1216 Label result_ok;
1217 __ shl(answer.reg()); 1217 __ shl_cl(answer.reg());
1218 // Check that the *signed* result fits in a smi. 1218 // Check that the *signed* result fits in a smi.
1219 __ cmp(answer.reg(), 0xc0000000); 1219 __ cmp(answer.reg(), 0xc0000000);
1220 __ j(positive, &result_ok); 1220 __ j(positive, &result_ok);
1221 ASSERT(kSmiTag == 0); 1221 ASSERT(kSmiTag == 0);
1222 __ shl(ecx, kSmiTagSize); 1222 __ shl(ecx, kSmiTagSize);
1223 deferred->Jump(); 1223 deferred->Jump();
1224 __ bind(&result_ok); 1224 __ bind(&result_ok);
1225 break; 1225 break;
1226 } 1226 }
1227 default: 1227 default:
(...skipping 3534 matching lines...) Expand 10 before | Expand all | Expand 10 after
4762 // See the comment in objects.h. 4762 // See the comment in objects.h.
4763 ASSERT(kLongStringTag == 0); 4763 ASSERT(kLongStringTag == 0);
4764 ASSERT(kMediumStringTag + String::kLongLengthShift == 4764 ASSERT(kMediumStringTag + String::kLongLengthShift ==
4765 String::kMediumLengthShift); 4765 String::kMediumLengthShift);
4766 ASSERT(kShortStringTag + String::kLongLengthShift == 4766 ASSERT(kShortStringTag + String::kLongLengthShift ==
4767 String::kShortLengthShift); 4767 String::kShortLengthShift);
4768 __ and_(ecx, kStringSizeMask); 4768 __ and_(ecx, kStringSizeMask);
4769 __ add(Operand(ecx), Immediate(String::kLongLengthShift)); 4769 __ add(Operand(ecx), Immediate(String::kLongLengthShift));
4770 // Fetch the length field into the temporary register. 4770 // Fetch the length field into the temporary register.
4771 __ mov(temp.reg(), FieldOperand(object.reg(), String::kLengthOffset)); 4771 __ mov(temp.reg(), FieldOperand(object.reg(), String::kLengthOffset));
4772 __ shr(temp.reg()); // The shift amount in ecx is implicit operand. 4772 __ shr_cl(temp.reg());
4773 // Check for index out of range. 4773 // Check for index out of range.
4774 __ cmp(index.reg(), Operand(temp.reg())); 4774 __ cmp(index.reg(), Operand(temp.reg()));
4775 __ j(greater_equal, &slow_case); 4775 __ j(greater_equal, &slow_case);
4776 // Reload the instance type (into the temp register this time).. 4776 // Reload the instance type (into the temp register this time)..
4777 __ mov(temp.reg(), FieldOperand(object.reg(), HeapObject::kMapOffset)); 4777 __ mov(temp.reg(), FieldOperand(object.reg(), HeapObject::kMapOffset));
4778 __ movzx_b(temp.reg(), FieldOperand(temp.reg(), Map::kInstanceTypeOffset)); 4778 __ movzx_b(temp.reg(), FieldOperand(temp.reg(), Map::kInstanceTypeOffset));
4779 4779
4780 // We need special handling for non-flat strings. 4780 // We need special handling for non-flat strings.
4781 ASSERT(kSeqStringTag == 0); 4781 ASSERT(kSeqStringTag == 0);
4782 __ test(temp.reg(), Immediate(kStringRepresentationMask)); 4782 __ test(temp.reg(), Immediate(kStringRepresentationMask));
(...skipping 1896 matching lines...) Expand 10 before | Expand all | Expand 10 after
6679 case Token::SHR: 6679 case Token::SHR:
6680 case Token::SAR: 6680 case Token::SAR:
6681 // Move the second operand into register ecx. 6681 // Move the second operand into register ecx.
6682 __ mov(ecx, Operand(ebx)); 6682 __ mov(ecx, Operand(ebx));
6683 // Remove tags from operands (but keep sign). 6683 // Remove tags from operands (but keep sign).
6684 __ sar(eax, kSmiTagSize); 6684 __ sar(eax, kSmiTagSize);
6685 __ sar(ecx, kSmiTagSize); 6685 __ sar(ecx, kSmiTagSize);
6686 // Perform the operation. 6686 // Perform the operation.
6687 switch (op_) { 6687 switch (op_) {
6688 case Token::SAR: 6688 case Token::SAR:
6689 __ sar(eax); 6689 __ sar_cl(eax);
6690 // No checks of result necessary 6690 // No checks of result necessary
6691 break; 6691 break;
6692 case Token::SHR: 6692 case Token::SHR:
6693 __ shr(eax); 6693 __ shr_cl(eax);
6694 // Check that the *unsigned* result fits in a smi. 6694 // Check that the *unsigned* result fits in a smi.
6695 // Neither of the two high-order bits can be set: 6695 // Neither of the two high-order bits can be set:
6696 // - 0x80000000: high bit would be lost when smi tagging. 6696 // - 0x80000000: high bit would be lost when smi tagging.
6697 // - 0x40000000: this number would convert to negative when 6697 // - 0x40000000: this number would convert to negative when
6698 // Smi tagging these two cases can only happen with shifts 6698 // Smi tagging these two cases can only happen with shifts
6699 // by 0 or 1 when handed a valid smi. 6699 // by 0 or 1 when handed a valid smi.
6700 __ test(eax, Immediate(0xc0000000)); 6700 __ test(eax, Immediate(0xc0000000));
6701 __ j(not_zero, slow, not_taken); 6701 __ j(not_zero, slow, not_taken);
6702 break; 6702 break;
6703 case Token::SHL: 6703 case Token::SHL:
6704 __ shl(eax); 6704 __ shl_cl(eax);
6705 // Check that the *signed* result fits in a smi. 6705 // Check that the *signed* result fits in a smi.
6706 __ cmp(eax, 0xc0000000); 6706 __ cmp(eax, 0xc0000000);
6707 __ j(sign, slow, not_taken); 6707 __ j(sign, slow, not_taken);
6708 break; 6708 break;
6709 default: 6709 default:
6710 UNREACHABLE(); 6710 UNREACHABLE();
6711 } 6711 }
6712 // Tag the result and store it in register eax. 6712 // Tag the result and store it in register eax.
6713 ASSERT(kSmiTagSize == times_2); // adjust code if not the case 6713 ASSERT(kSmiTagSize == times_2); // adjust code if not the case
6714 __ lea(eax, Operand(eax, eax, times_1, kSmiTag)); 6714 __ lea(eax, Operand(eax, eax, times_1, kSmiTag));
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
6869 __ j(parity_even, &operand_conversion_failure); 6869 __ j(parity_even, &operand_conversion_failure);
6870 } 6870 }
6871 6871
6872 // Get int32 operands and perform bitop. 6872 // Get int32 operands and perform bitop.
6873 __ pop(ecx); 6873 __ pop(ecx);
6874 __ pop(eax); 6874 __ pop(eax);
6875 switch (op_) { 6875 switch (op_) {
6876 case Token::BIT_OR: __ or_(eax, Operand(ecx)); break; 6876 case Token::BIT_OR: __ or_(eax, Operand(ecx)); break;
6877 case Token::BIT_AND: __ and_(eax, Operand(ecx)); break; 6877 case Token::BIT_AND: __ and_(eax, Operand(ecx)); break;
6878 case Token::BIT_XOR: __ xor_(eax, Operand(ecx)); break; 6878 case Token::BIT_XOR: __ xor_(eax, Operand(ecx)); break;
6879 case Token::SAR: __ sar(eax); break; 6879 case Token::SAR: __ sar_cl(eax); break;
6880 case Token::SHL: __ shl(eax); break; 6880 case Token::SHL: __ shl_cl(eax); break;
6881 case Token::SHR: __ shr(eax); break; 6881 case Token::SHR: __ shr_cl(eax); break;
6882 default: UNREACHABLE(); 6882 default: UNREACHABLE();
6883 } 6883 }
6884 if (op_ == Token::SHR) { 6884 if (op_ == Token::SHR) {
6885 // Check if result is non-negative and fits in a smi. 6885 // Check if result is non-negative and fits in a smi.
6886 __ test(eax, Immediate(0xc0000000)); 6886 __ test(eax, Immediate(0xc0000000));
6887 __ j(not_zero, &non_smi_result); 6887 __ j(not_zero, &non_smi_result);
6888 } else { 6888 } else {
6889 // Check if result fits in a smi. 6889 // Check if result fits in a smi.
6890 __ cmp(eax, 0xc0000000); 6890 __ cmp(eax, 0xc0000000);
6891 __ j(negative, &non_smi_result); 6891 __ j(negative, &non_smi_result);
(...skipping 1215 matching lines...) Expand 10 before | Expand all | Expand 10 after
8107 8107
8108 int CompareStub::MinorKey() { 8108 int CompareStub::MinorKey() {
8109 // Encode the two parameters in a unique 16 bit value. 8109 // Encode the two parameters in a unique 16 bit value.
8110 ASSERT(static_cast<unsigned>(cc_) < (1 << 15)); 8110 ASSERT(static_cast<unsigned>(cc_) < (1 << 15));
8111 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0); 8111 return (static_cast<unsigned>(cc_) << 1) | (strict_ ? 1 : 0);
8112 } 8112 }
8113 8113
8114 #undef __ 8114 #undef __
8115 8115
8116 } } // namespace v8::internal 8116 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698