| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |