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 6386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6397 stub.GenerateCall(masm_, value_, src_); | 6397 stub.GenerateCall(masm_, value_, src_); |
6398 if (!dst_.is(rax)) __ movq(dst_, rax); | 6398 if (!dst_.is(rax)) __ movq(dst_, rax); |
6399 } | 6399 } |
6400 | 6400 |
6401 | 6401 |
6402 Result CodeGenerator::ConstantSmiBinaryOperation(BinaryOperation* expr, | 6402 Result CodeGenerator::ConstantSmiBinaryOperation(BinaryOperation* expr, |
6403 Result* operand, | 6403 Result* operand, |
6404 Handle<Object> value, | 6404 Handle<Object> value, |
6405 bool reversed, | 6405 bool reversed, |
6406 OverwriteMode overwrite_mode) { | 6406 OverwriteMode overwrite_mode) { |
6407 // NOTE: This is an attempt to inline (a bit) more of the code for | 6407 // Generate inline code for a binary operation when one of the |
6408 // some possible smi operations (like + and -) when (at least) one | 6408 // operands is a constant smi. Consumes the argument "operand". |
6409 // of the operands is a constant smi. | |
6410 // Consumes the argument "operand". | |
6411 if (IsUnsafeSmi(value)) { | 6409 if (IsUnsafeSmi(value)) { |
6412 Result unsafe_operand(value); | 6410 Result unsafe_operand(value); |
6413 if (reversed) { | 6411 if (reversed) { |
6414 return LikelySmiBinaryOperation(expr, &unsafe_operand, operand, | 6412 return LikelySmiBinaryOperation(expr, &unsafe_operand, operand, |
6415 overwrite_mode); | 6413 overwrite_mode); |
6416 } else { | 6414 } else { |
6417 return LikelySmiBinaryOperation(expr, operand, &unsafe_operand, | 6415 return LikelySmiBinaryOperation(expr, operand, &unsafe_operand, |
6418 overwrite_mode); | 6416 overwrite_mode); |
6419 } | 6417 } |
6420 } | 6418 } |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6678 answer = LikelySmiBinaryOperation(expr, operand, &constant_operand, | 6676 answer = LikelySmiBinaryOperation(expr, operand, &constant_operand, |
6679 overwrite_mode); | 6677 overwrite_mode); |
6680 } | 6678 } |
6681 break; | 6679 break; |
6682 } | 6680 } |
6683 } | 6681 } |
6684 ASSERT(answer.is_valid()); | 6682 ASSERT(answer.is_valid()); |
6685 return answer; | 6683 return answer; |
6686 } | 6684 } |
6687 | 6685 |
| 6686 |
| 6687 // Implements a binary operation using a deferred code object and some |
| 6688 // inline code to operate on smis quickly. |
6688 Result CodeGenerator::LikelySmiBinaryOperation(BinaryOperation* expr, | 6689 Result CodeGenerator::LikelySmiBinaryOperation(BinaryOperation* expr, |
6689 Result* left, | 6690 Result* left, |
6690 Result* right, | 6691 Result* right, |
6691 OverwriteMode overwrite_mode) { | 6692 OverwriteMode overwrite_mode) { |
| 6693 // Copy the type info because left and right may be overwritten. |
| 6694 TypeInfo left_type_info = left->type_info(); |
| 6695 TypeInfo right_type_info = right->type_info(); |
| 6696 USE(left_type_info); |
| 6697 USE(right_type_info); |
| 6698 // TODO(X64): Use type information in calculations. |
6692 Token::Value op = expr->op(); | 6699 Token::Value op = expr->op(); |
6693 Result answer; | 6700 Result answer; |
6694 // Special handling of div and mod because they use fixed registers. | 6701 // Special handling of div and mod because they use fixed registers. |
6695 if (op == Token::DIV || op == Token::MOD) { | 6702 if (op == Token::DIV || op == Token::MOD) { |
6696 // We need rax as the quotient register, rdx as the remainder | 6703 // We need rax as the quotient register, rdx as the remainder |
6697 // register, neither left nor right in rax or rdx, and left copied | 6704 // register, neither left nor right in rax or rdx, and left copied |
6698 // to rax. | 6705 // to rax. |
6699 Result quotient; | 6706 Result quotient; |
6700 Result remainder; | 6707 Result remainder; |
6701 bool left_is_in_rax = false; | 6708 bool left_is_in_rax = false; |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6806 answer = allocator_->Allocate(); | 6813 answer = allocator_->Allocate(); |
6807 ASSERT(answer.is_valid()); | 6814 ASSERT(answer.is_valid()); |
6808 // Check that both operands are smis using the answer register as a | 6815 // Check that both operands are smis using the answer register as a |
6809 // temporary. | 6816 // temporary. |
6810 DeferredInlineBinaryOperation* deferred = | 6817 DeferredInlineBinaryOperation* deferred = |
6811 new DeferredInlineBinaryOperation(op, | 6818 new DeferredInlineBinaryOperation(op, |
6812 answer.reg(), | 6819 answer.reg(), |
6813 left->reg(), | 6820 left->reg(), |
6814 rcx, | 6821 rcx, |
6815 overwrite_mode); | 6822 overwrite_mode); |
6816 __ movq(answer.reg(), left->reg()); | 6823 __ JumpIfNotBothSmi(left->reg(), rcx, deferred->entry_label()); |
6817 __ or_(answer.reg(), rcx); | |
6818 __ JumpIfNotSmi(answer.reg(), deferred->entry_label()); | |
6819 | 6824 |
6820 // Perform the operation. | 6825 // Perform the operation. |
6821 switch (op) { | 6826 switch (op) { |
6822 case Token::SAR: | 6827 case Token::SAR: |
6823 __ SmiShiftArithmeticRight(answer.reg(), left->reg(), rcx); | 6828 __ SmiShiftArithmeticRight(answer.reg(), left->reg(), rcx); |
6824 break; | 6829 break; |
6825 case Token::SHR: { | 6830 case Token::SHR: { |
6826 __ SmiShiftLogicalRight(answer.reg(), | 6831 __ SmiShiftLogicalRight(answer.reg(), |
6827 left->reg(), | 6832 left->reg(), |
6828 rcx, | 6833 rcx, |
(...skipping 4588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11417 // Call the function from C++. | 11422 // Call the function from C++. |
11418 return FUNCTION_CAST<ModuloFunction>(buffer); | 11423 return FUNCTION_CAST<ModuloFunction>(buffer); |
11419 } | 11424 } |
11420 | 11425 |
11421 #endif | 11426 #endif |
11422 | 11427 |
11423 | 11428 |
11424 #undef __ | 11429 #undef __ |
11425 | 11430 |
11426 } } // namespace v8::internal | 11431 } } // namespace v8::internal |
OLD | NEW |