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

Side by Side Diff: bleeding_edge/src/ia32/codegen-ia32.cc

Issue 503079: Add fast case stub for BIT_NOT. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years 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 | « bleeding_edge/src/codegen.cc ('k') | bleeding_edge/src/x64/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 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 5497 matching lines...) Expand 10 before | Expand all | Expand 10 after
5508 // Omit evaluating the value of the primitive literal. 5508 // Omit evaluating the value of the primitive literal.
5509 // It will be discarded anyway, and can have no side effect. 5509 // It will be discarded anyway, and can have no side effect.
5510 frame_->Push(Factory::undefined_value()); 5510 frame_->Push(Factory::undefined_value());
5511 } else { 5511 } else {
5512 Load(node->expression()); 5512 Load(node->expression());
5513 frame_->SetElementAt(0, Factory::undefined_value()); 5513 frame_->SetElementAt(0, Factory::undefined_value());
5514 } 5514 }
5515 5515
5516 } else { 5516 } else {
5517 Load(node->expression()); 5517 Load(node->expression());
5518 bool overwrite =
5519 (node->expression()->AsBinaryOperation() != NULL &&
5520 node->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
5518 switch (op) { 5521 switch (op) {
5519 case Token::SUB: { 5522 case Token::SUB: {
5520 bool overwrite = 5523 GenericUnaryOpStub stub(Token::SUB, overwrite);
5521 (node->expression()->AsBinaryOperation() != NULL &&
5522 node->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
5523 UnarySubStub stub(overwrite);
5524 // TODO(1222589): remove dependency of TOS being cached inside stub 5524 // TODO(1222589): remove dependency of TOS being cached inside stub
5525 Result operand = frame_->Pop(); 5525 Result operand = frame_->Pop();
5526 Result answer = frame_->CallStub(&stub, &operand); 5526 Result answer = frame_->CallStub(&stub, &operand);
5527 frame_->Push(&answer); 5527 frame_->Push(&answer);
5528 break; 5528 break;
5529 } 5529 }
5530 5530
5531 case Token::BIT_NOT: { 5531 case Token::BIT_NOT: {
5532 // Smi check. 5532 // Smi check.
5533 JumpTarget smi_label; 5533 JumpTarget smi_label;
5534 JumpTarget continue_label; 5534 JumpTarget continue_label;
5535 Result operand = frame_->Pop(); 5535 Result operand = frame_->Pop();
5536 operand.ToRegister(); 5536 operand.ToRegister();
5537 __ test(operand.reg(), Immediate(kSmiTagMask)); 5537 __ test(operand.reg(), Immediate(kSmiTagMask));
5538 smi_label.Branch(zero, &operand, taken); 5538 smi_label.Branch(zero, &operand, taken);
5539 5539
5540 frame_->Push(&operand); // undo popping of TOS 5540 GenericUnaryOpStub stub(Token::BIT_NOT, overwrite);
5541 Result answer = frame_->InvokeBuiltin(Builtins::BIT_NOT, 5541 Result answer = frame_->CallStub(&stub, &operand);
5542 CALL_FUNCTION, 1); 5542 continue_label.Jump(&answer);
5543 5543
5544 continue_label.Jump(&answer);
5545 smi_label.Bind(&answer); 5544 smi_label.Bind(&answer);
5546 answer.ToRegister(); 5545 answer.ToRegister();
5547 frame_->Spill(answer.reg()); 5546 frame_->Spill(answer.reg());
5548 __ not_(answer.reg()); 5547 __ not_(answer.reg());
5549 __ and_(answer.reg(), ~kSmiTagMask); // Remove inverted smi-tag. 5548 __ and_(answer.reg(), ~kSmiTagMask); // Remove inverted smi-tag.
5549
5550 continue_label.Bind(&answer); 5550 continue_label.Bind(&answer);
5551 frame_->Push(&answer); 5551 frame_->Push(&answer);
5552 break; 5552 break;
5553 } 5553 }
5554 5554
5555 case Token::ADD: { 5555 case Token::ADD: {
5556 // Smi check. 5556 // Smi check.
5557 JumpTarget continue_label; 5557 JumpTarget continue_label;
5558 Result operand = frame_->Pop(); 5558 Result operand = frame_->Pop();
5559 operand.ToRegister(); 5559 operand.ToRegister();
(...skipping 1715 matching lines...) Expand 10 before | Expand all | Expand 10 after
7275 __ test(eax, Immediate(kSmiTagMask)); 7275 __ test(eax, Immediate(kSmiTagMask));
7276 __ j(not_zero, &skip_allocation, not_taken); 7276 __ j(not_zero, &skip_allocation, not_taken);
7277 // Fall through! 7277 // Fall through!
7278 case NO_OVERWRITE: 7278 case NO_OVERWRITE:
7279 __ AllocateHeapNumber(eax, ecx, edx, &call_runtime); 7279 __ AllocateHeapNumber(eax, ecx, edx, &call_runtime);
7280 __ bind(&skip_allocation); 7280 __ bind(&skip_allocation);
7281 break; 7281 break;
7282 default: UNREACHABLE(); 7282 default: UNREACHABLE();
7283 } 7283 }
7284 // Store the result in the HeapNumber and return. 7284 // Store the result in the HeapNumber and return.
7285 __ mov(Operand(esp, 1 * kPointerSize), ebx); 7285 if (CpuFeatures::IsSupported(SSE2)) {
7286 __ fild_s(Operand(esp, 1 * kPointerSize)); 7286 CpuFeatures::Scope use_sse2(SSE2);
7287 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); 7287 __ cvtsi2sd(xmm0, Operand(ebx));
7288 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
7289 } else {
7290 __ mov(Operand(esp, 1 * kPointerSize), ebx);
7291 __ fild_s(Operand(esp, 1 * kPointerSize));
7292 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
7293 }
7288 GenerateReturn(masm); 7294 GenerateReturn(masm);
7289 } 7295 }
7290 7296
7291 // Go to runtime for non-number inputs. 7297 // Go to runtime for non-number inputs.
7292 __ bind(&operand_conversion_failure); 7298 __ bind(&operand_conversion_failure);
7293 // SHR should return uint32 - go to runtime for non-smi/negative result. 7299 // SHR should return uint32 - go to runtime for non-smi/negative result.
7294 if (op_ == Token::SHR) { 7300 if (op_ == Token::SHR) {
7295 __ bind(&non_smi_result); 7301 __ bind(&non_smi_result);
7296 } 7302 }
7297 __ mov(eax, Operand(esp, 1 * kPointerSize)); 7303 __ mov(eax, Operand(esp, 1 * kPointerSize));
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
7689 __ j(zero, &done); // argument in eax is OK 7695 __ j(zero, &done); // argument in eax is OK
7690 __ mov(scratch, FieldOperand(eax, HeapObject::kMapOffset)); 7696 __ mov(scratch, FieldOperand(eax, HeapObject::kMapOffset));
7691 __ cmp(scratch, Factory::heap_number_map()); 7697 __ cmp(scratch, Factory::heap_number_map());
7692 __ j(not_equal, non_float); // argument in eax is not a number -> NaN 7698 __ j(not_equal, non_float); // argument in eax is not a number -> NaN
7693 7699
7694 // Fall-through: Both operands are numbers. 7700 // Fall-through: Both operands are numbers.
7695 __ bind(&done); 7701 __ bind(&done);
7696 } 7702 }
7697 7703
7698 7704
7699 void UnarySubStub::Generate(MacroAssembler* masm) { 7705 void GenericUnaryOpStub::Generate(MacroAssembler* masm) {
7700 Label undo; 7706 Label slow, done;
7701 Label slow;
7702 Label done;
7703 Label try_float;
7704 7707
7705 // Check whether the value is a smi. 7708 if (op_ == Token::SUB) {
7706 __ test(eax, Immediate(kSmiTagMask)); 7709 // Check whether the value is a smi.
7707 __ j(not_zero, &try_float, not_taken); 7710 Label try_float;
7711 __ test(eax, Immediate(kSmiTagMask));
7712 __ j(not_zero, &try_float, not_taken);
7708 7713
7709 // Enter runtime system if the value of the expression is zero 7714 // Go slow case if the value of the expression is zero
7710 // to make sure that we switch between 0 and -0. 7715 // to make sure that we switch between 0 and -0.
7711 __ test(eax, Operand(eax)); 7716 __ test(eax, Operand(eax));
7712 __ j(zero, &slow, not_taken); 7717 __ j(zero, &slow, not_taken);
7713 7718
7714 // The value of the expression is a smi that is not zero. Try 7719 // The value of the expression is a smi that is not zero. Try
7715 // optimistic subtraction '0 - value'. 7720 // optimistic subtraction '0 - value'.
7716 __ mov(edx, Operand(eax)); 7721 Label undo;
7717 __ Set(eax, Immediate(0)); 7722 __ mov(edx, Operand(eax));
7718 __ sub(eax, Operand(edx)); 7723 __ Set(eax, Immediate(0));
7719 __ j(overflow, &undo, not_taken); 7724 __ sub(eax, Operand(edx));
7725 __ j(overflow, &undo, not_taken);
7720 7726
7721 // If result is a smi we are done. 7727 // If result is a smi we are done.
7722 __ test(eax, Immediate(kSmiTagMask)); 7728 __ test(eax, Immediate(kSmiTagMask));
7723 __ j(zero, &done, taken); 7729 __ j(zero, &done, taken);
7724 7730
7725 // Restore eax and enter runtime system. 7731 // Restore eax and go slow case.
7726 __ bind(&undo); 7732 __ bind(&undo);
7727 __ mov(eax, Operand(edx)); 7733 __ mov(eax, Operand(edx));
7734 __ jmp(&slow);
7728 7735
7729 // Enter runtime system. 7736 // Try floating point case.
7737 __ bind(&try_float);
7738 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
7739 __ cmp(edx, Factory::heap_number_map());
7740 __ j(not_equal, &slow);
7741 if (overwrite_) {
7742 __ mov(edx, FieldOperand(eax, HeapNumber::kExponentOffset));
7743 __ xor_(edx, HeapNumber::kSignMask); // Flip sign.
7744 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), edx);
7745 } else {
7746 __ mov(edx, Operand(eax));
7747 // edx: operand
7748 __ AllocateHeapNumber(eax, ebx, ecx, &undo);
7749 // eax: allocated 'empty' number
7750 __ mov(ecx, FieldOperand(edx, HeapNumber::kExponentOffset));
7751 __ xor_(ecx, HeapNumber::kSignMask); // Flip sign.
7752 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), ecx);
7753 __ mov(ecx, FieldOperand(edx, HeapNumber::kMantissaOffset));
7754 __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx);
7755 }
7756 } else if (op_ == Token::BIT_NOT) {
7757 // Check if the operand is a heap number.
7758 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
7759 __ cmp(edx, Factory::heap_number_map());
7760 __ j(not_equal, &slow, not_taken);
7761
7762 // Convert the heap number in eax to an untagged integer in ecx.
7763 IntegerConvert(masm, eax, CpuFeatures::IsSupported(SSE3), &slow);
7764
7765 // Do the bitwise operation and check if the result fits in a smi.
7766 Label try_float;
7767 __ not_(ecx);
7768 __ cmp(ecx, 0xc0000000);
7769 __ j(sign, &try_float, not_taken);
7770
7771 // Tag the result as a smi and we're done.
7772 ASSERT(kSmiTagSize == 1);
7773 __ lea(eax, Operand(ecx, times_2, kSmiTag));
7774 __ jmp(&done);
7775
7776 // Try to store the result in a heap number.
7777 __ bind(&try_float);
7778 if (!overwrite_) {
7779 // Allocate a fresh heap number, but don't overwrite eax until
7780 // we're sure we can do it without going through the slow case
7781 // that needs the value in eax.
7782 __ AllocateHeapNumber(ebx, edx, edi, &slow);
7783 __ mov(eax, Operand(ebx));
7784 }
7785 if (CpuFeatures::IsSupported(SSE2)) {
7786 CpuFeatures::Scope use_sse2(SSE2);
7787 __ cvtsi2sd(xmm0, Operand(ecx));
7788 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
7789 } else {
7790 __ push(ecx);
7791 __ fild_s(Operand(esp, 0));
7792 __ pop(ecx);
7793 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
7794 }
7795 } else {
7796 UNIMPLEMENTED();
7797 }
7798
7799 // Return from the stub.
7800 __ bind(&done);
7801 __ StubReturn(1);
7802
7803 // Handle the slow case by jumping to the JavaScript builtin.
7730 __ bind(&slow); 7804 __ bind(&slow);
7731 __ pop(ecx); // pop return address 7805 __ pop(ecx); // pop return address.
7732 __ push(eax); 7806 __ push(eax);
7733 __ push(ecx); // push return address 7807 __ push(ecx); // push return address
7734 __ InvokeBuiltin(Builtins::UNARY_MINUS, JUMP_FUNCTION); 7808 switch (op_) {
7735 7809 case Token::SUB:
7736 // Try floating point case. 7810 __ InvokeBuiltin(Builtins::UNARY_MINUS, JUMP_FUNCTION);
7737 __ bind(&try_float); 7811 break;
7738 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); 7812 case Token::BIT_NOT:
7739 __ cmp(edx, Factory::heap_number_map()); 7813 __ InvokeBuiltin(Builtins::BIT_NOT, JUMP_FUNCTION);
7740 __ j(not_equal, &slow); 7814 break;
7741 if (overwrite_) { 7815 default:
7742 __ mov(edx, FieldOperand(eax, HeapNumber::kExponentOffset)); 7816 UNREACHABLE();
7743 __ xor_(edx, HeapNumber::kSignMask); // Flip sign.
7744 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), edx);
7745 } else {
7746 __ mov(edx, Operand(eax));
7747 // edx: operand
7748 __ AllocateHeapNumber(eax, ebx, ecx, &undo);
7749 // eax: allocated 'empty' number
7750 __ mov(ecx, FieldOperand(edx, HeapNumber::kExponentOffset));
7751 __ xor_(ecx, HeapNumber::kSignMask); // Flip sign.
7752 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), ecx);
7753 __ mov(ecx, FieldOperand(edx, HeapNumber::kMantissaOffset));
7754 __ mov(FieldOperand(eax, HeapNumber::kMantissaOffset), ecx);
7755 } 7817 }
7756
7757 __ bind(&done);
7758
7759 __ StubReturn(1);
7760 } 7818 }
7761 7819
7762 7820
7763 void ArgumentsAccessStub::GenerateReadLength(MacroAssembler* masm) { 7821 void ArgumentsAccessStub::GenerateReadLength(MacroAssembler* masm) {
7764 // Check if the calling frame is an arguments adaptor frame. 7822 // Check if the calling frame is an arguments adaptor frame.
7765 Label adaptor; 7823 Label adaptor;
7766 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); 7824 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset));
7767 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); 7825 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset));
7768 __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); 7826 __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR)));
7769 __ j(equal, &adaptor); 7827 __ j(equal, &adaptor);
(...skipping 1156 matching lines...) Expand 10 before | Expand all | Expand 10 after
8926 __ add(Operand(dest), Immediate(2)); 8984 __ add(Operand(dest), Immediate(2));
8927 } 8985 }
8928 __ sub(Operand(count), Immediate(1)); 8986 __ sub(Operand(count), Immediate(1));
8929 __ j(not_zero, &loop); 8987 __ j(not_zero, &loop);
8930 } 8988 }
8931 8989
8932 8990
8933 #undef __ 8991 #undef __
8934 8992
8935 } } // namespace v8::internal 8993 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « bleeding_edge/src/codegen.cc ('k') | bleeding_edge/src/x64/codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698