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

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

Issue 2850043: Specialize GenericUnaryStub so that it knows whether it needs to... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 5 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/ia32/full-codegen-ia32.cc ('k') | src/x64/full-codegen-x64.cc » ('j') | 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 3355 matching lines...) Expand 10 before | Expand all | Expand 10 after
3366 expression->AsLiteral()->IsNull())) { 3366 expression->AsLiteral()->IsNull())) {
3367 // Omit evaluating the value of the primitive literal. 3367 // Omit evaluating the value of the primitive literal.
3368 // It will be discarded anyway, and can have no side effect. 3368 // It will be discarded anyway, and can have no side effect.
3369 frame_->Push(Factory::undefined_value()); 3369 frame_->Push(Factory::undefined_value());
3370 } else { 3370 } else {
3371 Load(node->expression()); 3371 Load(node->expression());
3372 frame_->SetElementAt(0, Factory::undefined_value()); 3372 frame_->SetElementAt(0, Factory::undefined_value());
3373 } 3373 }
3374 3374
3375 } else { 3375 } else {
3376 bool overwrite = 3376 bool can_overwrite =
3377 (node->expression()->AsBinaryOperation() != NULL && 3377 (node->expression()->AsBinaryOperation() != NULL &&
3378 node->expression()->AsBinaryOperation()->ResultOverwriteAllowed()); 3378 node->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
3379 UnaryOverwriteMode overwrite =
3380 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE;
3381 bool no_negative_zero = node->expression()->no_negative_zero();
3379 Load(node->expression()); 3382 Load(node->expression());
3380 switch (op) { 3383 switch (op) {
3381 case Token::NOT: 3384 case Token::NOT:
3382 case Token::DELETE: 3385 case Token::DELETE:
3383 case Token::TYPEOF: 3386 case Token::TYPEOF:
3384 UNREACHABLE(); // handled above 3387 UNREACHABLE(); // handled above
3385 break; 3388 break;
3386 3389
3387 case Token::SUB: { 3390 case Token::SUB: {
3388 GenericUnaryOpStub stub(Token::SUB, overwrite); 3391 GenericUnaryOpStub stub(
3392 Token::SUB,
3393 overwrite,
3394 no_negative_zero ? kIgnoreNegativeZero : kStrictNegativeZero);
3389 Result operand = frame_->Pop(); 3395 Result operand = frame_->Pop();
3390 Result answer = frame_->CallStub(&stub, &operand); 3396 Result answer = frame_->CallStub(&stub, &operand);
3391 answer.set_type_info(TypeInfo::Number()); 3397 answer.set_type_info(TypeInfo::Number());
3392 frame_->Push(&answer); 3398 frame_->Push(&answer);
3393 break; 3399 break;
3394 } 3400 }
3395 3401
3396 case Token::BIT_NOT: { 3402 case Token::BIT_NOT: {
3397 // Smi check. 3403 // Smi check.
3398 JumpTarget smi_label; 3404 JumpTarget smi_label;
(...skipping 5100 matching lines...) Expand 10 before | Expand all | Expand 10 after
8499 8505
8500 8506
8501 void GenericUnaryOpStub::Generate(MacroAssembler* masm) { 8507 void GenericUnaryOpStub::Generate(MacroAssembler* masm) {
8502 Label slow, done; 8508 Label slow, done;
8503 8509
8504 if (op_ == Token::SUB) { 8510 if (op_ == Token::SUB) {
8505 // Check whether the value is a smi. 8511 // Check whether the value is a smi.
8506 Label try_float; 8512 Label try_float;
8507 __ JumpIfNotSmi(rax, &try_float); 8513 __ JumpIfNotSmi(rax, &try_float);
8508 8514
8515 if (negative_zero_ == kIgnoreNegativeZero) {
8516 __ SmiCompare(rax, Smi::FromInt(0));
8517 __ j(equal, &done);
8518 }
8519
8509 // Enter runtime system if the value of the smi is zero 8520 // Enter runtime system if the value of the smi is zero
8510 // to make sure that we switch between 0 and -0. 8521 // to make sure that we switch between 0 and -0.
8511 // Also enter it if the value of the smi is Smi::kMinValue. 8522 // Also enter it if the value of the smi is Smi::kMinValue.
8512 __ SmiNeg(rax, rax, &done); 8523 __ SmiNeg(rax, rax, &done);
8513 8524
8514 // Either zero or Smi::kMinValue, neither of which become a smi when 8525 // Either zero or Smi::kMinValue, neither of which become a smi when
8515 // negated. 8526 // negated.
8516 __ SmiCompare(rax, Smi::FromInt(0)); 8527 if (negative_zero_ == kStrictNegativeZero) {
8517 __ j(not_equal, &slow); 8528 __ SmiCompare(rax, Smi::FromInt(0));
8518 __ Move(rax, Factory::minus_zero_value()); 8529 __ j(not_equal, &slow);
8519 __ jmp(&done); 8530 __ Move(rax, Factory::minus_zero_value());
8531 __ jmp(&done);
8532 } else {
8533 __ jmp(&slow);
8534 }
8520 8535
8521 // Try floating point case. 8536 // Try floating point case.
8522 __ bind(&try_float); 8537 __ bind(&try_float);
8523 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset)); 8538 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset));
8524 __ CompareRoot(rdx, Heap::kHeapNumberMapRootIndex); 8539 __ CompareRoot(rdx, Heap::kHeapNumberMapRootIndex);
8525 __ j(not_equal, &slow); 8540 __ j(not_equal, &slow);
8526 // Operand is a float, negate its value by flipping sign bit. 8541 // Operand is a float, negate its value by flipping sign bit.
8527 __ movq(rdx, FieldOperand(rax, HeapNumber::kValueOffset)); 8542 __ movq(rdx, FieldOperand(rax, HeapNumber::kValueOffset));
8528 __ movq(kScratchRegister, Immediate(0x01)); 8543 __ movq(kScratchRegister, Immediate(0x01));
8529 __ shl(kScratchRegister, Immediate(63)); 8544 __ shl(kScratchRegister, Immediate(63));
8530 __ xor_(rdx, kScratchRegister); // Flip sign. 8545 __ xor_(rdx, kScratchRegister); // Flip sign.
8531 // rdx is value to store. 8546 // rdx is value to store.
8532 if (overwrite_) { 8547 if (overwrite_ == UNARY_OVERWRITE) {
8533 __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rdx); 8548 __ movq(FieldOperand(rax, HeapNumber::kValueOffset), rdx);
8534 } else { 8549 } else {
8535 __ AllocateHeapNumber(rcx, rbx, &slow); 8550 __ AllocateHeapNumber(rcx, rbx, &slow);
8536 // rcx: allocated 'empty' number 8551 // rcx: allocated 'empty' number
8537 __ movq(FieldOperand(rcx, HeapNumber::kValueOffset), rdx); 8552 __ movq(FieldOperand(rcx, HeapNumber::kValueOffset), rdx);
8538 __ movq(rax, rcx); 8553 __ movq(rax, rcx);
8539 } 8554 }
8540 } else if (op_ == Token::BIT_NOT) { 8555 } else if (op_ == Token::BIT_NOT) {
8541 // Check if the operand is a heap number. 8556 // Check if the operand is a heap number.
8542 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset)); 8557 __ movq(rdx, FieldOperand(rax, HeapObject::kMapOffset));
(...skipping 3526 matching lines...) Expand 10 before | Expand all | Expand 10 after
12069 } 12084 }
12070 12085
12071 #endif 12086 #endif
12072 12087
12073 12088
12074 #undef __ 12089 #undef __
12075 12090
12076 } } // namespace v8::internal 12091 } } // namespace v8::internal
12077 12092
12078 #endif // V8_TARGET_ARCH_X64 12093 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/ia32/full-codegen-ia32.cc ('k') | src/x64/full-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698