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 7115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7126 overwrite_mode); | 7126 overwrite_mode); |
7127 } | 7127 } |
7128 break; | 7128 break; |
7129 } | 7129 } |
7130 } | 7130 } |
7131 ASSERT(answer.is_valid()); | 7131 ASSERT(answer.is_valid()); |
7132 return answer; | 7132 return answer; |
7133 } | 7133 } |
7134 | 7134 |
7135 | 7135 |
| 7136 void CodeGenerator::JumpIfNotBothSmiUsingTypeInfo(Register left, |
| 7137 Register right, |
| 7138 TypeInfo left_info, |
| 7139 TypeInfo right_info, |
| 7140 DeferredCode* deferred) { |
| 7141 if (!left_info.IsSmi() && !right_info.IsSmi()) { |
| 7142 __ JumpIfNotBothSmi(left, right, deferred->entry_label()); |
| 7143 } else if (!left_info.IsSmi()) { |
| 7144 __ JumpIfNotSmi(left, deferred->entry_label()); |
| 7145 } else if (!right_info.IsSmi()) { |
| 7146 __ JumpIfNotSmi(right, deferred->entry_label()); |
| 7147 } |
| 7148 if (FLAG_debug_code) { |
| 7149 __ AbortIfNotSmi(left); |
| 7150 __ AbortIfNotSmi(right); |
| 7151 } |
| 7152 } |
| 7153 |
| 7154 |
7136 // Implements a binary operation using a deferred code object and some | 7155 // Implements a binary operation using a deferred code object and some |
7137 // inline code to operate on smis quickly. | 7156 // inline code to operate on smis quickly. |
7138 Result CodeGenerator::LikelySmiBinaryOperation(BinaryOperation* expr, | 7157 Result CodeGenerator::LikelySmiBinaryOperation(BinaryOperation* expr, |
7139 Result* left, | 7158 Result* left, |
7140 Result* right, | 7159 Result* right, |
7141 OverwriteMode overwrite_mode) { | 7160 OverwriteMode overwrite_mode) { |
7142 // Copy the type info because left and right may be overwritten. | 7161 // Copy the type info because left and right may be overwritten. |
7143 TypeInfo left_type_info = left->type_info(); | 7162 TypeInfo left_type_info = left->type_info(); |
7144 TypeInfo right_type_info = right->type_info(); | 7163 TypeInfo right_type_info = right->type_info(); |
7145 USE(left_type_info); | |
7146 USE(right_type_info); | |
7147 // TODO(X64): Use type information in calculations. | |
7148 Token::Value op = expr->op(); | 7164 Token::Value op = expr->op(); |
7149 Result answer; | 7165 Result answer; |
7150 // Special handling of div and mod because they use fixed registers. | 7166 // Special handling of div and mod because they use fixed registers. |
7151 if (op == Token::DIV || op == Token::MOD) { | 7167 if (op == Token::DIV || op == Token::MOD) { |
7152 // We need rax as the quotient register, rdx as the remainder | 7168 // We need rax as the quotient register, rdx as the remainder |
7153 // register, neither left nor right in rax or rdx, and left copied | 7169 // register, neither left nor right in rax or rdx, and left copied |
7154 // to rax. | 7170 // to rax. |
7155 Result quotient; | 7171 Result quotient; |
7156 Result remainder; | 7172 Result remainder; |
7157 bool left_is_in_rax = false; | 7173 bool left_is_in_rax = false; |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7214 frame_->Spill(rax); | 7230 frame_->Spill(rax); |
7215 frame_->Spill(rdx); | 7231 frame_->Spill(rdx); |
7216 | 7232 |
7217 // Check that left and right are smi tagged. | 7233 // Check that left and right are smi tagged. |
7218 DeferredInlineBinaryOperation* deferred = | 7234 DeferredInlineBinaryOperation* deferred = |
7219 new DeferredInlineBinaryOperation(op, | 7235 new DeferredInlineBinaryOperation(op, |
7220 (op == Token::DIV) ? rax : rdx, | 7236 (op == Token::DIV) ? rax : rdx, |
7221 left->reg(), | 7237 left->reg(), |
7222 right->reg(), | 7238 right->reg(), |
7223 overwrite_mode); | 7239 overwrite_mode); |
7224 __ JumpIfNotBothSmi(left->reg(), right->reg(), deferred->entry_label()); | 7240 JumpIfNotBothSmiUsingTypeInfo(left->reg(), right->reg(), |
| 7241 left_type_info, right_type_info, deferred); |
7225 | 7242 |
7226 if (op == Token::DIV) { | 7243 if (op == Token::DIV) { |
7227 __ SmiDiv(rax, left->reg(), right->reg(), deferred->entry_label()); | 7244 __ SmiDiv(rax, left->reg(), right->reg(), deferred->entry_label()); |
7228 deferred->BindExit(); | 7245 deferred->BindExit(); |
7229 left->Unuse(); | 7246 left->Unuse(); |
7230 right->Unuse(); | 7247 right->Unuse(); |
7231 answer = quotient; | 7248 answer = quotient; |
7232 } else { | 7249 } else { |
7233 ASSERT(op == Token::MOD); | 7250 ASSERT(op == Token::MOD); |
7234 __ SmiMod(rdx, left->reg(), right->reg(), deferred->entry_label()); | 7251 __ SmiMod(rdx, left->reg(), right->reg(), deferred->entry_label()); |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7296 deferred->Branch(equal); | 7313 deferred->Branch(equal); |
7297 // TODO(lrn): Inline shifts on int32 here instead of first smi-tagging. | 7314 // TODO(lrn): Inline shifts on int32 here instead of first smi-tagging. |
7298 __ Integer32ToSmi(answer.reg(), answer.reg()); | 7315 __ Integer32ToSmi(answer.reg(), answer.reg()); |
7299 } else { | 7316 } else { |
7300 // Fast case - both are actually smis. | 7317 // Fast case - both are actually smis. |
7301 if (FLAG_debug_code) { | 7318 if (FLAG_debug_code) { |
7302 __ AbortIfNotSmi(left->reg()); | 7319 __ AbortIfNotSmi(left->reg()); |
7303 } | 7320 } |
7304 } | 7321 } |
7305 } else { | 7322 } else { |
7306 __ JumpIfNotBothSmi(left->reg(), rcx, deferred->entry_label()); | 7323 JumpIfNotBothSmiUsingTypeInfo(left->reg(), rcx, |
| 7324 left_type_info, right_type_info, deferred); |
7307 } | 7325 } |
7308 __ bind(&do_op); | 7326 __ bind(&do_op); |
7309 | 7327 |
7310 // Perform the operation. | 7328 // Perform the operation. |
7311 switch (op) { | 7329 switch (op) { |
7312 case Token::SAR: | 7330 case Token::SAR: |
7313 __ SmiShiftArithmeticRight(answer.reg(), left->reg(), rcx); | 7331 __ SmiShiftArithmeticRight(answer.reg(), left->reg(), rcx); |
7314 break; | 7332 break; |
7315 case Token::SHR: { | 7333 case Token::SHR: { |
7316 __ SmiShiftLogicalRight(answer.reg(), | 7334 __ SmiShiftLogicalRight(answer.reg(), |
(...skipping 27 matching lines...) Expand all Loading... |
7344 answer = allocator_->Allocate(); | 7362 answer = allocator_->Allocate(); |
7345 ASSERT(answer.is_valid()); | 7363 ASSERT(answer.is_valid()); |
7346 | 7364 |
7347 // Perform the smi tag check. | 7365 // Perform the smi tag check. |
7348 DeferredInlineBinaryOperation* deferred = | 7366 DeferredInlineBinaryOperation* deferred = |
7349 new DeferredInlineBinaryOperation(op, | 7367 new DeferredInlineBinaryOperation(op, |
7350 answer.reg(), | 7368 answer.reg(), |
7351 left->reg(), | 7369 left->reg(), |
7352 right->reg(), | 7370 right->reg(), |
7353 overwrite_mode); | 7371 overwrite_mode); |
7354 __ JumpIfNotBothSmi(left->reg(), right->reg(), deferred->entry_label()); | 7372 JumpIfNotBothSmiUsingTypeInfo(left->reg(), right->reg(), |
| 7373 left_type_info, right_type_info, deferred); |
7355 | 7374 |
7356 switch (op) { | 7375 switch (op) { |
7357 case Token::ADD: | 7376 case Token::ADD: |
7358 __ SmiAdd(answer.reg(), | 7377 __ SmiAdd(answer.reg(), |
7359 left->reg(), | 7378 left->reg(), |
7360 right->reg(), | 7379 right->reg(), |
7361 deferred->entry_label()); | 7380 deferred->entry_label()); |
7362 break; | 7381 break; |
7363 | 7382 |
7364 case Token::SUB: | 7383 case Token::SUB: |
(...skipping 4546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11911 } | 11930 } |
11912 | 11931 |
11913 #endif | 11932 #endif |
11914 | 11933 |
11915 | 11934 |
11916 #undef __ | 11935 #undef __ |
11917 | 11936 |
11918 } } // namespace v8::internal | 11937 } } // namespace v8::internal |
11919 | 11938 |
11920 #endif // V8_TARGET_ARCH_X64 | 11939 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |