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

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

Issue 1844002: Change calling convention of BinaryOperation code generation functions on x64... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 7 months 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
« no previous file with comments | « src/x64/codegen-x64.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 2664 matching lines...) Expand 10 before | Expand all | Expand 10 after
2675 // side, that are easy to test for: the right hand side is a literal, 2675 // side, that are easy to test for: the right hand side is a literal,
2676 // or the right hand side is a different variable. TakeValue invalidates 2676 // or the right hand side is a different variable. TakeValue invalidates
2677 // the target, with an implicit promise that it will be written to again 2677 // the target, with an implicit promise that it will be written to again
2678 // before it is read. 2678 // before it is read.
2679 if (literal != NULL || (right_var != NULL && right_var != var)) { 2679 if (literal != NULL || (right_var != NULL && right_var != var)) {
2680 target.TakeValue(); 2680 target.TakeValue();
2681 } else { 2681 } else {
2682 target.GetValue(); 2682 target.GetValue();
2683 } 2683 }
2684 Load(node->value()); 2684 Load(node->value());
2685 GenericBinaryOperation(node->binary_op(), 2685 BinaryOperation expr(node, node->binary_op(), node->target(),
2686 node->type(), 2686 node->value());
2687 GenericBinaryOperation(&expr,
2687 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE); 2688 overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
2688 } 2689 }
2689 2690
2690 if (var != NULL && 2691 if (var != NULL &&
2691 var->mode() == Variable::CONST && 2692 var->mode() == Variable::CONST &&
2692 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) { 2693 node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) {
2693 // Assignment ignored - leave the value on the stack. 2694 // Assignment ignored - leave the value on the stack.
2694 UnloadReference(&target); 2695 UnloadReference(&target);
2695 } else { 2696 } else {
2696 CodeForSourcePosition(node->position()); 2697 CodeForSourcePosition(node->position());
(...skipping 836 matching lines...) Expand 10 before | Expand all | Expand 10 after
3533 3534
3534 if (node->left()->IsTrivial()) { 3535 if (node->left()->IsTrivial()) {
3535 Load(node->right()); 3536 Load(node->right());
3536 Result right = frame_->Pop(); 3537 Result right = frame_->Pop();
3537 frame_->Push(node->left()); 3538 frame_->Push(node->left());
3538 frame_->Push(&right); 3539 frame_->Push(&right);
3539 } else { 3540 } else {
3540 Load(node->left()); 3541 Load(node->left());
3541 Load(node->right()); 3542 Load(node->right());
3542 } 3543 }
3543 GenericBinaryOperation(node->op(), node->type(), overwrite_mode); 3544 GenericBinaryOperation(node, overwrite_mode);
3544 } 3545 }
3545 } 3546 }
3546 3547
3547 3548
3548 3549
3549 void CodeGenerator::VisitCompareOperation(CompareOperation* node) { 3550 void CodeGenerator::VisitCompareOperation(CompareOperation* node) {
3550 Comment cmnt(masm_, "[ CompareOperation"); 3551 Comment cmnt(masm_, "[ CompareOperation");
3551 3552
3552 // Get the expressions from the node. 3553 // Get the expressions from the node.
3553 Expression* left = node->left(); 3554 Expression* left = node->left();
(...skipping 2531 matching lines...) Expand 10 before | Expand all | Expand 10 after
6085 // Result is always a number. 6086 // Result is always a number.
6086 return TypeInfo::Number(); 6087 return TypeInfo::Number();
6087 default: 6088 default:
6088 UNREACHABLE(); 6089 UNREACHABLE();
6089 } 6090 }
6090 UNREACHABLE(); 6091 UNREACHABLE();
6091 return TypeInfo::Unknown(); 6092 return TypeInfo::Unknown();
6092 } 6093 }
6093 6094
6094 6095
6095 void CodeGenerator::GenericBinaryOperation(Token::Value op, 6096 void CodeGenerator::GenericBinaryOperation(BinaryOperation* expr,
6096 StaticType* type,
6097 OverwriteMode overwrite_mode) { 6097 OverwriteMode overwrite_mode) {
6098 Comment cmnt(masm_, "[ BinaryOperation"); 6098 Comment cmnt(masm_, "[ BinaryOperation");
6099 Token::Value op = expr->op();
6099 Comment cmnt_token(masm_, Token::String(op)); 6100 Comment cmnt_token(masm_, Token::String(op));
6100 6101
6101 if (op == Token::COMMA) { 6102 if (op == Token::COMMA) {
6102 // Simply discard left value. 6103 // Simply discard left value.
6103 frame_->Nip(1); 6104 frame_->Nip(1);
6104 return; 6105 return;
6105 } 6106 }
6106 6107
6107 Result right = frame_->Pop(); 6108 Result right = frame_->Pop();
6108 Result left = frame_->Pop(); 6109 Result left = frame_->Pop();
6109 6110
6110 if (op == Token::ADD) { 6111 if (op == Token::ADD) {
6111 const bool left_is_string = left.type_info().IsString(); 6112 const bool left_is_string = left.type_info().IsString();
6112 const bool right_is_string = right.type_info().IsString(); 6113 const bool right_is_string = right.type_info().IsString();
6113 // Make sure constant strings have string type info. 6114 // Make sure constant strings have string type info.
6114 ASSERT(!(left.is_constant() && left.handle()->IsString()) || 6115 ASSERT(!(left.is_constant() && left.handle()->IsString()) ||
6115 left_is_string); 6116 left_is_string);
6116 ASSERT(!(right.is_constant() && right.handle()->IsString()) || 6117 ASSERT(!(right.is_constant() && right.handle()->IsString()) ||
6117 right_is_string); 6118 right_is_string);
6118 if (left_is_string || right_is_string) { 6119 if (left_is_string || right_is_string) {
6119 frame_->Push(&left); 6120 frame_->Push(&left);
6120 frame_->Push(&right); 6121 frame_->Push(&right);
6121 Result answer; 6122 Result answer;
6122 if (left_is_string) { 6123 if (left_is_string) {
6123 if (right_is_string) { 6124 if (right_is_string) {
6124 // TODO(lrn): if both are constant strings
6125 // -- do a compile time cons, if allocation during codegen is allowed.
6126 StringAddStub stub(NO_STRING_CHECK_IN_STUB); 6125 StringAddStub stub(NO_STRING_CHECK_IN_STUB);
6127 answer = frame_->CallStub(&stub, 2); 6126 answer = frame_->CallStub(&stub, 2);
6128 } else { 6127 } else {
6129 answer = 6128 answer =
6130 frame_->InvokeBuiltin(Builtins::STRING_ADD_LEFT, CALL_FUNCTION, 2); 6129 frame_->InvokeBuiltin(Builtins::STRING_ADD_LEFT, CALL_FUNCTION, 2);
6131 } 6130 }
6132 } else if (right_is_string) { 6131 } else if (right_is_string) {
6133 answer = 6132 answer =
6134 frame_->InvokeBuiltin(Builtins::STRING_ADD_RIGHT, CALL_FUNCTION, 2); 6133 frame_->InvokeBuiltin(Builtins::STRING_ADD_RIGHT, CALL_FUNCTION, 2);
6135 } 6134 }
(...skipping 18 matching lines...) Expand all
6154 } 6153 }
6155 6154
6156 // Get number type of left and right sub-expressions. 6155 // Get number type of left and right sub-expressions.
6157 TypeInfo operands_type = 6156 TypeInfo operands_type =
6158 TypeInfo::Combine(left.type_info(), right.type_info()); 6157 TypeInfo::Combine(left.type_info(), right.type_info());
6159 6158
6160 TypeInfo result_type = CalculateTypeInfo(operands_type, op, right, left); 6159 TypeInfo result_type = CalculateTypeInfo(operands_type, op, right, left);
6161 6160
6162 Result answer; 6161 Result answer;
6163 if (left_is_non_smi_constant || right_is_non_smi_constant) { 6162 if (left_is_non_smi_constant || right_is_non_smi_constant) {
6163 // Go straight to the slow case, with no smi code.
6164 GenericBinaryOpStub stub(op, 6164 GenericBinaryOpStub stub(op,
6165 overwrite_mode, 6165 overwrite_mode,
6166 NO_SMI_CODE_IN_STUB, 6166 NO_SMI_CODE_IN_STUB,
6167 operands_type); 6167 operands_type);
6168 answer = stub.GenerateCall(masm_, frame_, &left, &right); 6168 answer = stub.GenerateCall(masm_, frame_, &left, &right);
6169 } else if (right_is_smi_constant) { 6169 } else if (right_is_smi_constant) {
6170 answer = ConstantSmiBinaryOperation(op, &left, right.handle(), 6170 answer = ConstantSmiBinaryOperation(expr, &left, right.handle(),
6171 type, false, overwrite_mode); 6171 false, overwrite_mode);
6172 } else if (left_is_smi_constant) { 6172 } else if (left_is_smi_constant) {
6173 answer = ConstantSmiBinaryOperation(op, &right, left.handle(), 6173 answer = ConstantSmiBinaryOperation(expr, &right, left.handle(),
6174 type, true, overwrite_mode); 6174 true, overwrite_mode);
6175 } else { 6175 } else {
6176 // Set the flags based on the operation, type and loop nesting level. 6176 // Set the flags based on the operation, type and loop nesting level.
6177 // Bit operations always assume they likely operate on Smis. Still only 6177 // Bit operations always assume they likely operate on Smis. Still only
6178 // generate the inline Smi check code if this operation is part of a loop. 6178 // generate the inline Smi check code if this operation is part of a loop.
6179 // For all other operations only inline the Smi check code for likely smis 6179 // For all other operations only inline the Smi check code for likely smis
6180 // if the operation is part of a loop. 6180 // if the operation is part of a loop.
6181 if (loop_nesting() > 0 && (Token::IsBitOp(op) || type->IsLikelySmi())) { 6181 if (loop_nesting() > 0 &&
6182 answer = LikelySmiBinaryOperation(op, &left, &right, overwrite_mode); 6182 (Token::IsBitOp(op) ||
6183 operands_type.IsInteger32() ||
6184 expr->type()->IsLikelySmi())) {
6185 answer = LikelySmiBinaryOperation(expr, &left, &right, overwrite_mode);
6183 } else { 6186 } else {
6184 GenericBinaryOpStub stub(op, 6187 GenericBinaryOpStub stub(op,
6185 overwrite_mode, 6188 overwrite_mode,
6186 NO_GENERIC_BINARY_FLAGS, 6189 NO_GENERIC_BINARY_FLAGS,
6187 operands_type); 6190 operands_type);
6188 answer = stub.GenerateCall(masm_, frame_, &left, &right); 6191 answer = stub.GenerateCall(masm_, frame_, &left, &right);
6189 } 6192 }
6190 } 6193 }
6191 6194
6192 answer.set_type_info(result_type); 6195 answer.set_type_info(result_type);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
6264 // For mod we don't generate all the Smi code inline. 6267 // For mod we don't generate all the Smi code inline.
6265 GenericBinaryOpStub stub( 6268 GenericBinaryOpStub stub(
6266 op_, 6269 op_,
6267 overwrite_mode_, 6270 overwrite_mode_,
6268 (op_ == Token::MOD) ? NO_GENERIC_BINARY_FLAGS : NO_SMI_CODE_IN_STUB); 6271 (op_ == Token::MOD) ? NO_GENERIC_BINARY_FLAGS : NO_SMI_CODE_IN_STUB);
6269 stub.GenerateCall(masm_, src_, value_); 6272 stub.GenerateCall(masm_, src_, value_);
6270 if (!dst_.is(rax)) __ movq(dst_, rax); 6273 if (!dst_.is(rax)) __ movq(dst_, rax);
6271 } 6274 }
6272 6275
6273 6276
6274 Result CodeGenerator::ConstantSmiBinaryOperation(Token::Value op, 6277 Result CodeGenerator::ConstantSmiBinaryOperation(BinaryOperation* expr,
6275 Result* operand, 6278 Result* operand,
6276 Handle<Object> value, 6279 Handle<Object> value,
6277 StaticType* type,
6278 bool reversed, 6280 bool reversed,
6279 OverwriteMode overwrite_mode) { 6281 OverwriteMode overwrite_mode) {
6280 // NOTE: This is an attempt to inline (a bit) more of the code for 6282 // NOTE: This is an attempt to inline (a bit) more of the code for
6281 // some possible smi operations (like + and -) when (at least) one 6283 // some possible smi operations (like + and -) when (at least) one
6282 // of the operands is a constant smi. 6284 // of the operands is a constant smi.
6283 // Consumes the argument "operand". 6285 // Consumes the argument "operand".
6284
6285 // TODO(199): Optimize some special cases of operations involving a
6286 // smi literal (multiply by 2, shift by 0, etc.).
6287 if (IsUnsafeSmi(value)) { 6286 if (IsUnsafeSmi(value)) {
6288 Result unsafe_operand(value); 6287 Result unsafe_operand(value);
6289 if (reversed) { 6288 if (reversed) {
6290 return LikelySmiBinaryOperation(op, &unsafe_operand, operand, 6289 return LikelySmiBinaryOperation(expr, &unsafe_operand, operand,
6291 overwrite_mode); 6290 overwrite_mode);
6292 } else { 6291 } else {
6293 return LikelySmiBinaryOperation(op, operand, &unsafe_operand, 6292 return LikelySmiBinaryOperation(expr, operand, &unsafe_operand,
6294 overwrite_mode); 6293 overwrite_mode);
6295 } 6294 }
6296 } 6295 }
6297 6296
6298 // Get the literal value. 6297 // Get the literal value.
6299 Smi* smi_value = Smi::cast(*value); 6298 Smi* smi_value = Smi::cast(*value);
6300 int int_value = smi_value->value(); 6299 int int_value = smi_value->value();
6301 6300
6301 Token::Value op = expr->op();
6302 Result answer; 6302 Result answer;
6303 switch (op) { 6303 switch (op) {
6304 case Token::ADD: { 6304 case Token::ADD: {
6305 operand->ToRegister(); 6305 operand->ToRegister();
6306 frame_->Spill(operand->reg()); 6306 frame_->Spill(operand->reg());
6307 DeferredCode* deferred = NULL; 6307 DeferredCode* deferred = NULL;
6308 if (reversed) { 6308 if (reversed) {
6309 deferred = new DeferredInlineSmiAddReversed(operand->reg(), 6309 deferred = new DeferredInlineSmiAddReversed(operand->reg(),
6310 smi_value, 6310 smi_value,
6311 overwrite_mode); 6311 overwrite_mode);
6312 } else { 6312 } else {
6313 deferred = new DeferredInlineSmiAdd(operand->reg(), 6313 deferred = new DeferredInlineSmiAdd(operand->reg(),
6314 smi_value, 6314 smi_value,
6315 overwrite_mode); 6315 overwrite_mode);
6316 } 6316 }
6317 __ JumpIfNotSmi(operand->reg(), deferred->entry_label()); 6317 __ JumpIfNotSmi(operand->reg(), deferred->entry_label());
6318 __ SmiAddConstant(operand->reg(), 6318 __ SmiAddConstant(operand->reg(),
6319 operand->reg(), 6319 operand->reg(),
6320 smi_value, 6320 smi_value,
6321 deferred->entry_label()); 6321 deferred->entry_label());
6322 deferred->BindExit(); 6322 deferred->BindExit();
6323 answer = *operand; 6323 answer = *operand;
6324 break; 6324 break;
6325 } 6325 }
6326 6326
6327 case Token::SUB: { 6327 case Token::SUB: {
6328 if (reversed) { 6328 if (reversed) {
6329 Result constant_operand(value); 6329 Result constant_operand(value);
6330 answer = LikelySmiBinaryOperation(op, &constant_operand, operand, 6330 answer = LikelySmiBinaryOperation(expr, &constant_operand, operand,
6331 overwrite_mode); 6331 overwrite_mode);
6332 } else { 6332 } else {
6333 operand->ToRegister(); 6333 operand->ToRegister();
6334 frame_->Spill(operand->reg()); 6334 frame_->Spill(operand->reg());
6335 DeferredCode* deferred = new DeferredInlineSmiSub(operand->reg(), 6335 DeferredCode* deferred = new DeferredInlineSmiSub(operand->reg(),
6336 smi_value, 6336 smi_value,
6337 overwrite_mode); 6337 overwrite_mode);
6338 __ JumpIfNotSmi(operand->reg(), deferred->entry_label()); 6338 __ JumpIfNotSmi(operand->reg(), deferred->entry_label());
6339 // A smi currently fits in a 32-bit Immediate. 6339 // A smi currently fits in a 32-bit Immediate.
6340 __ SmiSubConstant(operand->reg(), 6340 __ SmiSubConstant(operand->reg(),
6341 operand->reg(), 6341 operand->reg(),
6342 smi_value, 6342 smi_value,
6343 deferred->entry_label()); 6343 deferred->entry_label());
6344 deferred->BindExit(); 6344 deferred->BindExit();
6345 answer = *operand; 6345 answer = *operand;
6346 } 6346 }
6347 break; 6347 break;
6348 } 6348 }
6349 6349
6350 case Token::SAR: 6350 case Token::SAR:
6351 if (reversed) { 6351 if (reversed) {
6352 Result constant_operand(value); 6352 Result constant_operand(value);
6353 answer = LikelySmiBinaryOperation(op, &constant_operand, operand, 6353 answer = LikelySmiBinaryOperation(expr, &constant_operand, operand,
6354 overwrite_mode); 6354 overwrite_mode);
6355 } else { 6355 } else {
6356 // Only the least significant 5 bits of the shift value are used. 6356 // Only the least significant 5 bits of the shift value are used.
6357 // In the slow case, this masking is done inside the runtime call. 6357 // In the slow case, this masking is done inside the runtime call.
6358 int shift_value = int_value & 0x1f; 6358 int shift_value = int_value & 0x1f;
6359 operand->ToRegister(); 6359 operand->ToRegister();
6360 frame_->Spill(operand->reg()); 6360 frame_->Spill(operand->reg());
6361 DeferredInlineSmiOperation* deferred = 6361 DeferredInlineSmiOperation* deferred =
6362 new DeferredInlineSmiOperation(op, 6362 new DeferredInlineSmiOperation(op,
6363 operand->reg(), 6363 operand->reg(),
6364 operand->reg(), 6364 operand->reg(),
6365 smi_value, 6365 smi_value,
6366 overwrite_mode); 6366 overwrite_mode);
6367 __ JumpIfNotSmi(operand->reg(), deferred->entry_label()); 6367 __ JumpIfNotSmi(operand->reg(), deferred->entry_label());
6368 __ SmiShiftArithmeticRightConstant(operand->reg(), 6368 __ SmiShiftArithmeticRightConstant(operand->reg(),
6369 operand->reg(), 6369 operand->reg(),
6370 shift_value); 6370 shift_value);
6371 deferred->BindExit(); 6371 deferred->BindExit();
6372 answer = *operand; 6372 answer = *operand;
6373 } 6373 }
6374 break; 6374 break;
6375 6375
6376 case Token::SHR: 6376 case Token::SHR:
6377 if (reversed) { 6377 if (reversed) {
6378 Result constant_operand(value); 6378 Result constant_operand(value);
6379 answer = LikelySmiBinaryOperation(op, &constant_operand, operand, 6379 answer = LikelySmiBinaryOperation(expr, &constant_operand, operand,
6380 overwrite_mode); 6380 overwrite_mode);
6381 } else { 6381 } else {
6382 // Only the least significant 5 bits of the shift value are used. 6382 // Only the least significant 5 bits of the shift value are used.
6383 // In the slow case, this masking is done inside the runtime call. 6383 // In the slow case, this masking is done inside the runtime call.
6384 int shift_value = int_value & 0x1f; 6384 int shift_value = int_value & 0x1f;
6385 operand->ToRegister(); 6385 operand->ToRegister();
6386 answer = allocator()->Allocate(); 6386 answer = allocator()->Allocate();
6387 ASSERT(answer.is_valid()); 6387 ASSERT(answer.is_valid());
6388 DeferredInlineSmiOperation* deferred = 6388 DeferredInlineSmiOperation* deferred =
6389 new DeferredInlineSmiOperation(op, 6389 new DeferredInlineSmiOperation(op,
6390 answer.reg(), 6390 answer.reg(),
6391 operand->reg(), 6391 operand->reg(),
6392 smi_value, 6392 smi_value,
6393 overwrite_mode); 6393 overwrite_mode);
6394 __ JumpIfNotSmi(operand->reg(), deferred->entry_label()); 6394 __ JumpIfNotSmi(operand->reg(), deferred->entry_label());
6395 __ SmiShiftLogicalRightConstant(answer.reg(), 6395 __ SmiShiftLogicalRightConstant(answer.reg(),
6396 operand->reg(), 6396 operand->reg(),
6397 shift_value, 6397 shift_value,
6398 deferred->entry_label()); 6398 deferred->entry_label());
6399 deferred->BindExit(); 6399 deferred->BindExit();
6400 operand->Unuse(); 6400 operand->Unuse();
6401 } 6401 }
6402 break; 6402 break;
6403 6403
6404 case Token::SHL: 6404 case Token::SHL:
6405 if (reversed) { 6405 if (reversed) {
6406 Result constant_operand(value); 6406 Result constant_operand(value);
6407 answer = LikelySmiBinaryOperation(op, &constant_operand, operand, 6407 answer = LikelySmiBinaryOperation(expr, &constant_operand, operand,
6408 overwrite_mode); 6408 overwrite_mode);
6409 } else { 6409 } else {
6410 // Only the least significant 5 bits of the shift value are used. 6410 // Only the least significant 5 bits of the shift value are used.
6411 // In the slow case, this masking is done inside the runtime call. 6411 // In the slow case, this masking is done inside the runtime call.
6412 int shift_value = int_value & 0x1f; 6412 int shift_value = int_value & 0x1f;
6413 operand->ToRegister(); 6413 operand->ToRegister();
6414 if (shift_value == 0) { 6414 if (shift_value == 0) {
6415 // Spill operand so it can be overwritten in the slow case. 6415 // Spill operand so it can be overwritten in the slow case.
6416 frame_->Spill(operand->reg()); 6416 frame_->Spill(operand->reg());
6417 DeferredInlineSmiOperation* deferred = 6417 DeferredInlineSmiOperation* deferred =
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
6504 deferred->BindExit(); 6504 deferred->BindExit();
6505 answer = *operand; 6505 answer = *operand;
6506 break; // This break only applies if we generated code for MOD. 6506 break; // This break only applies if we generated code for MOD.
6507 } 6507 }
6508 // Fall through if we did not find a power of 2 on the right hand side! 6508 // Fall through if we did not find a power of 2 on the right hand side!
6509 // The next case must be the default. 6509 // The next case must be the default.
6510 6510
6511 default: { 6511 default: {
6512 Result constant_operand(value); 6512 Result constant_operand(value);
6513 if (reversed) { 6513 if (reversed) {
6514 answer = LikelySmiBinaryOperation(op, &constant_operand, operand, 6514 answer = LikelySmiBinaryOperation(expr, &constant_operand, operand,
6515 overwrite_mode); 6515 overwrite_mode);
6516 } else { 6516 } else {
6517 answer = LikelySmiBinaryOperation(op, operand, &constant_operand, 6517 answer = LikelySmiBinaryOperation(expr, operand, &constant_operand,
6518 overwrite_mode); 6518 overwrite_mode);
6519 } 6519 }
6520 break; 6520 break;
6521 } 6521 }
6522 } 6522 }
6523 ASSERT(answer.is_valid()); 6523 ASSERT(answer.is_valid());
6524 return answer; 6524 return answer;
6525 } 6525 }
6526 6526
6527 Result CodeGenerator::LikelySmiBinaryOperation(Token::Value op, 6527 Result CodeGenerator::LikelySmiBinaryOperation(BinaryOperation* expr,
6528 Result* left, 6528 Result* left,
6529 Result* right, 6529 Result* right,
6530 OverwriteMode overwrite_mode) { 6530 OverwriteMode overwrite_mode) {
6531 Token::Value op = expr->op();
6531 Result answer; 6532 Result answer;
6532 // Special handling of div and mod because they use fixed registers. 6533 // Special handling of div and mod because they use fixed registers.
6533 if (op == Token::DIV || op == Token::MOD) { 6534 if (op == Token::DIV || op == Token::MOD) {
6534 // We need rax as the quotient register, rdx as the remainder 6535 // We need rax as the quotient register, rdx as the remainder
6535 // register, neither left nor right in rax or rdx, and left copied 6536 // register, neither left nor right in rax or rdx, and left copied
6536 // to rax. 6537 // to rax.
6537 Result quotient; 6538 Result quotient;
6538 Result remainder; 6539 Result remainder;
6539 bool left_is_in_rax = false; 6540 bool left_is_in_rax = false;
6540 // Step 1: get rax for quotient. 6541 // Step 1: get rax for quotient.
(...skipping 4490 matching lines...) Expand 10 before | Expand all | Expand 10 after
11031 // Call the function from C++. 11032 // Call the function from C++.
11032 return FUNCTION_CAST<ModuloFunction>(buffer); 11033 return FUNCTION_CAST<ModuloFunction>(buffer);
11033 } 11034 }
11034 11035
11035 #endif 11036 #endif
11036 11037
11037 11038
11038 #undef __ 11039 #undef __
11039 11040
11040 } } // namespace v8::internal 11041 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/x64/codegen-x64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698