OLD | NEW |
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 6508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6519 operand->reg(), | 6519 operand->reg(), |
6520 shift_value, | 6520 shift_value, |
6521 deferred->entry_label()); | 6521 deferred->entry_label()); |
6522 deferred->BindExit(); | 6522 deferred->BindExit(); |
6523 operand->Unuse(); | 6523 operand->Unuse(); |
6524 } | 6524 } |
6525 break; | 6525 break; |
6526 | 6526 |
6527 case Token::SHL: | 6527 case Token::SHL: |
6528 if (reversed) { | 6528 if (reversed) { |
6529 // Move operand into rcx and also into a second register. | |
6530 // If operand is already in a register, take advantage of that. | |
6531 // This lets us modify rcx, but still bail out to deferred code. | |
6532 Result right; | |
6533 Result right_copy_in_rcx; | |
6534 TypeInfo right_type_info = operand->type_info(); | |
6535 operand->ToRegister(); | 6529 operand->ToRegister(); |
| 6530 |
| 6531 // We need rcx to be available to hold operand, and to be spilled. |
| 6532 // SmiShiftLeft implicitly modifies rcx. |
6536 if (operand->reg().is(rcx)) { | 6533 if (operand->reg().is(rcx)) { |
6537 right = allocator()->Allocate(); | 6534 frame_->Spill(operand->reg()); |
6538 __ movq(right.reg(), rcx); | 6535 answer = allocator()->Allocate(); |
6539 frame_->Spill(rcx); | |
6540 right_copy_in_rcx = *operand; | |
6541 } else { | 6536 } else { |
6542 right_copy_in_rcx = allocator()->Allocate(rcx); | 6537 Result rcx_reg = allocator()->Allocate(rcx); |
6543 __ movq(rcx, operand->reg()); | 6538 // answer must not be rcx. |
6544 right = *operand; | 6539 answer = allocator()->Allocate(); |
| 6540 // rcx_reg goes out of scope. |
6545 } | 6541 } |
6546 operand->Unuse(); | |
6547 | 6542 |
6548 answer = allocator()->Allocate(); | |
6549 DeferredInlineSmiOperationReversed* deferred = | 6543 DeferredInlineSmiOperationReversed* deferred = |
6550 new DeferredInlineSmiOperationReversed(op, | 6544 new DeferredInlineSmiOperationReversed(op, |
6551 answer.reg(), | 6545 answer.reg(), |
6552 smi_value, | 6546 smi_value, |
6553 right.reg(), | 6547 operand->reg(), |
6554 overwrite_mode); | 6548 overwrite_mode); |
6555 __ movq(answer.reg(), Immediate(int_value)); | 6549 if (!operand->type_info().IsSmi()) { |
6556 __ SmiToInteger32(rcx, rcx); | 6550 Condition is_smi = masm_->CheckSmi(operand->reg()); |
6557 if (!right_type_info.IsSmi()) { | |
6558 Condition is_smi = masm_->CheckSmi(right.reg()); | |
6559 deferred->Branch(NegateCondition(is_smi)); | 6551 deferred->Branch(NegateCondition(is_smi)); |
6560 } else if (FLAG_debug_code) { | 6552 } else if (FLAG_debug_code) { |
6561 __ AbortIfNotSmi(right.reg(), | 6553 __ AbortIfNotSmi(operand->reg(), |
6562 "Static type info claims non-smi is smi in (const SHL smi)."); | 6554 "Static type info claims non-smi is smi in (const SHL smi)."); |
6563 } | 6555 } |
6564 __ shl_cl(answer.reg()); | 6556 |
6565 __ Integer32ToSmi(answer.reg(), answer.reg()); | 6557 __ Move(answer.reg(), smi_value); |
| 6558 __ SmiShiftLeft(answer.reg(), answer.reg(), operand->reg()); |
| 6559 operand->Unuse(); |
6566 | 6560 |
6567 deferred->BindExit(); | 6561 deferred->BindExit(); |
6568 } else { | 6562 } else { |
6569 // Only the least significant 5 bits of the shift value are used. | 6563 // Only the least significant 5 bits of the shift value are used. |
6570 // In the slow case, this masking is done inside the runtime call. | 6564 // In the slow case, this masking is done inside the runtime call. |
6571 int shift_value = int_value & 0x1f; | 6565 int shift_value = int_value & 0x1f; |
6572 operand->ToRegister(); | 6566 operand->ToRegister(); |
6573 if (shift_value == 0) { | 6567 if (shift_value == 0) { |
6574 // Spill operand so it can be overwritten in the slow case. | 6568 // Spill operand so it can be overwritten in the slow case. |
6575 frame_->Spill(operand->reg()); | 6569 frame_->Spill(operand->reg()); |
(...skipping 12 matching lines...) Expand all Loading... |
6588 ASSERT(answer.is_valid()); | 6582 ASSERT(answer.is_valid()); |
6589 DeferredInlineSmiOperation* deferred = | 6583 DeferredInlineSmiOperation* deferred = |
6590 new DeferredInlineSmiOperation(op, | 6584 new DeferredInlineSmiOperation(op, |
6591 answer.reg(), | 6585 answer.reg(), |
6592 operand->reg(), | 6586 operand->reg(), |
6593 smi_value, | 6587 smi_value, |
6594 overwrite_mode); | 6588 overwrite_mode); |
6595 __ JumpIfNotSmi(operand->reg(), deferred->entry_label()); | 6589 __ JumpIfNotSmi(operand->reg(), deferred->entry_label()); |
6596 __ SmiShiftLeftConstant(answer.reg(), | 6590 __ SmiShiftLeftConstant(answer.reg(), |
6597 operand->reg(), | 6591 operand->reg(), |
6598 shift_value, | 6592 shift_value); |
6599 deferred->entry_label()); | |
6600 deferred->BindExit(); | 6593 deferred->BindExit(); |
6601 operand->Unuse(); | 6594 operand->Unuse(); |
6602 } | 6595 } |
6603 } | 6596 } |
6604 break; | 6597 break; |
6605 | 6598 |
6606 case Token::BIT_OR: | 6599 case Token::BIT_OR: |
6607 case Token::BIT_XOR: | 6600 case Token::BIT_XOR: |
6608 case Token::BIT_AND: { | 6601 case Token::BIT_AND: { |
6609 operand->ToRegister(); | 6602 operand->ToRegister(); |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6830 case Token::SHR: { | 6823 case Token::SHR: { |
6831 __ SmiShiftLogicalRight(answer.reg(), | 6824 __ SmiShiftLogicalRight(answer.reg(), |
6832 left->reg(), | 6825 left->reg(), |
6833 rcx, | 6826 rcx, |
6834 deferred->entry_label()); | 6827 deferred->entry_label()); |
6835 break; | 6828 break; |
6836 } | 6829 } |
6837 case Token::SHL: { | 6830 case Token::SHL: { |
6838 __ SmiShiftLeft(answer.reg(), | 6831 __ SmiShiftLeft(answer.reg(), |
6839 left->reg(), | 6832 left->reg(), |
6840 rcx, | 6833 rcx); |
6841 deferred->entry_label()); | |
6842 break; | 6834 break; |
6843 } | 6835 } |
6844 default: | 6836 default: |
6845 UNREACHABLE(); | 6837 UNREACHABLE(); |
6846 } | 6838 } |
6847 deferred->BindExit(); | 6839 deferred->BindExit(); |
6848 left->Unuse(); | 6840 left->Unuse(); |
6849 right->Unuse(); | 6841 right->Unuse(); |
6850 ASSERT(answer.is_valid()); | 6842 ASSERT(answer.is_valid()); |
6851 return answer; | 6843 return answer; |
(...skipping 3075 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9927 case Token::SHR: | 9919 case Token::SHR: |
9928 case Token::SAR: | 9920 case Token::SAR: |
9929 switch (op_) { | 9921 switch (op_) { |
9930 case Token::SAR: | 9922 case Token::SAR: |
9931 __ SmiShiftArithmeticRight(left, left, right); | 9923 __ SmiShiftArithmeticRight(left, left, right); |
9932 break; | 9924 break; |
9933 case Token::SHR: | 9925 case Token::SHR: |
9934 __ SmiShiftLogicalRight(left, left, right, slow); | 9926 __ SmiShiftLogicalRight(left, left, right, slow); |
9935 break; | 9927 break; |
9936 case Token::SHL: | 9928 case Token::SHL: |
9937 __ SmiShiftLeft(left, left, right, slow); | 9929 __ SmiShiftLeft(left, left, right); |
9938 break; | 9930 break; |
9939 default: | 9931 default: |
9940 UNREACHABLE(); | 9932 UNREACHABLE(); |
9941 } | 9933 } |
9942 __ movq(rax, left); | 9934 __ movq(rax, left); |
9943 break; | 9935 break; |
9944 | 9936 |
9945 default: | 9937 default: |
9946 UNREACHABLE(); | 9938 UNREACHABLE(); |
9947 break; | 9939 break; |
(...skipping 1474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11422 // Call the function from C++. | 11414 // Call the function from C++. |
11423 return FUNCTION_CAST<ModuloFunction>(buffer); | 11415 return FUNCTION_CAST<ModuloFunction>(buffer); |
11424 } | 11416 } |
11425 | 11417 |
11426 #endif | 11418 #endif |
11427 | 11419 |
11428 | 11420 |
11429 #undef __ | 11421 #undef __ |
11430 | 11422 |
11431 } } // namespace v8::internal | 11423 } } // namespace v8::internal |
OLD | NEW |