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

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

Issue 2814050: Version 2.2.23... (Closed) Base URL: http://v8.googlecode.com/svn/trunk/
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/version.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 2046 matching lines...) Expand 10 before | Expand all | Expand 10 after
10589 case Token::MUL: 10604 case Token::MUL:
10590 case Token::DIV: { 10605 case Token::DIV: {
10591 if (runtime_operands_type_ == BinaryOpIC::DEFAULT && 10606 if (runtime_operands_type_ == BinaryOpIC::DEFAULT &&
10592 HasSmiCodeInStub()) { 10607 HasSmiCodeInStub()) {
10593 // Execution reaches this point when the first non-smi argument occurs 10608 // Execution reaches this point when the first non-smi argument occurs
10594 // (and only if smi code is generated). This is the right moment to 10609 // (and only if smi code is generated). This is the right moment to
10595 // patch to HEAP_NUMBERS state. The transition is attempted only for 10610 // patch to HEAP_NUMBERS state. The transition is attempted only for
10596 // the four basic operations. The stub stays in the DEFAULT state 10611 // the four basic operations. The stub stays in the DEFAULT state
10597 // forever for all other operations (also if smi code is skipped). 10612 // forever for all other operations (also if smi code is skipped).
10598 GenerateTypeTransition(masm); 10613 GenerateTypeTransition(masm);
10614 break;
10599 } 10615 }
10600 10616
10601 Label not_floats; 10617 Label not_floats;
10602 // rax: y 10618 // rax: y
10603 // rdx: x 10619 // rdx: x
10604 if (static_operands_type_.IsNumber()) { 10620 if (static_operands_type_.IsNumber()) {
10605 if (FLAG_debug_code) { 10621 if (FLAG_debug_code) {
10606 // Assert at runtime that inputs are only numbers. 10622 // Assert at runtime that inputs are only numbers.
10607 __ AbortIfNotNumber(rdx); 10623 __ AbortIfNotNumber(rdx);
10608 __ AbortIfNotNumber(rax); 10624 __ AbortIfNotNumber(rax);
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
10906 __ push(rdx); 10922 __ push(rdx);
10907 __ push(rax); 10923 __ push(rax);
10908 } 10924 }
10909 __ push(rcx); 10925 __ push(rcx);
10910 } 10926 }
10911 10927
10912 10928
10913 void GenericBinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) { 10929 void GenericBinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
10914 Label get_result; 10930 Label get_result;
10915 10931
10916 // Keep a copy of operands on the stack and make sure they are also in 10932 // Ensure the operands are on the stack.
10917 // rdx, rax.
10918 if (HasArgsInRegisters()) { 10933 if (HasArgsInRegisters()) {
10919 GenerateRegisterArgsPush(masm); 10934 GenerateRegisterArgsPush(masm);
10920 } else {
10921 GenerateLoadArguments(masm);
10922 } 10935 }
10923 10936
10924 // Internal frame is necessary to handle exceptions properly.
10925 __ EnterInternalFrame();
10926
10927 // Push arguments on stack if the stub expects them there.
10928 if (!HasArgsInRegisters()) {
10929 __ push(rdx);
10930 __ push(rax);
10931 }
10932 // Call the stub proper to get the result in rax.
10933 __ call(&get_result);
10934 __ LeaveInternalFrame();
10935
10936 // Left and right arguments are already on stack. 10937 // Left and right arguments are already on stack.
10937 __ pop(rcx); 10938 __ pop(rcx); // Save the return address.
10938 // Push the operation result. The tail call to BinaryOp_Patch will
10939 // return it to the original caller..
10940 __ push(rax);
10941 10939
10942 // Push this stub's key. 10940 // Push this stub's key.
10943 __ Push(Smi::FromInt(MinorKey())); 10941 __ Push(Smi::FromInt(MinorKey()));
10944 10942
10945 // Although the operation and the type info are encoded into the key, 10943 // Although the operation and the type info are encoded into the key,
10946 // the encoding is opaque, so push them too. 10944 // the encoding is opaque, so push them too.
10947 __ Push(Smi::FromInt(op_)); 10945 __ Push(Smi::FromInt(op_));
10948 10946
10949 __ Push(Smi::FromInt(runtime_operands_type_)); 10947 __ Push(Smi::FromInt(runtime_operands_type_));
10950 10948
10951 __ push(rcx); 10949 __ push(rcx); // The return address.
10952 10950
10953 // Perform patching to an appropriate fast case and return the result. 10951 // Perform patching to an appropriate fast case and return the result.
10954 __ TailCallExternalReference( 10952 __ TailCallExternalReference(
10955 ExternalReference(IC_Utility(IC::kBinaryOp_Patch)), 10953 ExternalReference(IC_Utility(IC::kBinaryOp_Patch)),
10956 6, 10954 5,
10957 1); 10955 1);
10958
10959 // The entry point for the result calculation is assumed to be immediately
10960 // after this sequence.
10961 __ bind(&get_result);
10962 } 10956 }
10963 10957
10964 10958
10965 Handle<Code> GetBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info) { 10959 Handle<Code> GetBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info) {
10966 GenericBinaryOpStub stub(key, type_info); 10960 GenericBinaryOpStub stub(key, type_info);
10967 return stub.GetCode(); 10961 return stub.GetCode();
10968 } 10962 }
10969 10963
10970 10964
10971 int CompareStub::MinorKey() { 10965 int CompareStub::MinorKey() {
(...skipping 1097 matching lines...) Expand 10 before | Expand all | Expand 10 after
12069 } 12063 }
12070 12064
12071 #endif 12065 #endif
12072 12066
12073 12067
12074 #undef __ 12068 #undef __
12075 12069
12076 } } // namespace v8::internal 12070 } } // namespace v8::internal
12077 12071
12078 #endif // V8_TARGET_ARCH_X64 12072 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/version.cc ('k') | src/x64/full-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698