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

Side by Side Diff: src/ia32/codegen-ia32.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/codegen.cc ('k') | src/ia32/full-codegen-ia32.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 7565 matching lines...) Expand 10 before | Expand all | Expand 10 after
7576 // Unary plus has no effect on int32 values. 7576 // Unary plus has no effect on int32 values.
7577 break; 7577 break;
7578 } 7578 }
7579 default: 7579 default:
7580 UNREACHABLE(); 7580 UNREACHABLE();
7581 break; 7581 break;
7582 } 7582 }
7583 frame_->Push(&value); 7583 frame_->Push(&value);
7584 } else { 7584 } else {
7585 Load(node->expression()); 7585 Load(node->expression());
7586 bool overwrite = 7586 bool can_overwrite =
7587 (node->expression()->AsBinaryOperation() != NULL && 7587 (node->expression()->AsBinaryOperation() != NULL &&
7588 node->expression()->AsBinaryOperation()->ResultOverwriteAllowed()); 7588 node->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
7589 UnaryOverwriteMode overwrite =
7590 can_overwrite ? UNARY_OVERWRITE : UNARY_NO_OVERWRITE;
7591 bool no_negative_zero = node->expression()->no_negative_zero();
7589 switch (op) { 7592 switch (op) {
7590 case Token::NOT: 7593 case Token::NOT:
7591 case Token::DELETE: 7594 case Token::DELETE:
7592 case Token::TYPEOF: 7595 case Token::TYPEOF:
7593 UNREACHABLE(); // handled above 7596 UNREACHABLE(); // handled above
7594 break; 7597 break;
7595 7598
7596 case Token::SUB: { 7599 case Token::SUB: {
7597 GenericUnaryOpStub stub(Token::SUB, overwrite); 7600 GenericUnaryOpStub stub(
7601 Token::SUB,
7602 overwrite,
7603 no_negative_zero ? kIgnoreNegativeZero : kStrictNegativeZero);
7598 Result operand = frame_->Pop(); 7604 Result operand = frame_->Pop();
7599 Result answer = frame_->CallStub(&stub, &operand); 7605 Result answer = frame_->CallStub(&stub, &operand);
7600 answer.set_type_info(TypeInfo::Number()); 7606 answer.set_type_info(TypeInfo::Number());
7601 frame_->Push(&answer); 7607 frame_->Push(&answer);
7602 break; 7608 break;
7603 } 7609 }
7604 case Token::BIT_NOT: { 7610 case Token::BIT_NOT: {
7605 // Smi check. 7611 // Smi check.
7606 JumpTarget smi_label; 7612 JumpTarget smi_label;
7607 JumpTarget continue_label; 7613 JumpTarget continue_label;
(...skipping 3319 matching lines...) Expand 10 before | Expand all | Expand 10 after
10927 10933
10928 void GenericUnaryOpStub::Generate(MacroAssembler* masm) { 10934 void GenericUnaryOpStub::Generate(MacroAssembler* masm) {
10929 Label slow, done; 10935 Label slow, done;
10930 10936
10931 if (op_ == Token::SUB) { 10937 if (op_ == Token::SUB) {
10932 // Check whether the value is a smi. 10938 // Check whether the value is a smi.
10933 Label try_float; 10939 Label try_float;
10934 __ test(eax, Immediate(kSmiTagMask)); 10940 __ test(eax, Immediate(kSmiTagMask));
10935 __ j(not_zero, &try_float, not_taken); 10941 __ j(not_zero, &try_float, not_taken);
10936 10942
10937 // Go slow case if the value of the expression is zero 10943 if (negative_zero_ == kStrictNegativeZero) {
10938 // to make sure that we switch between 0 and -0. 10944 // Go slow case if the value of the expression is zero
10939 __ test(eax, Operand(eax)); 10945 // to make sure that we switch between 0 and -0.
10940 __ j(zero, &slow, not_taken); 10946 __ test(eax, Operand(eax));
10947 __ j(zero, &slow, not_taken);
10948 }
10941 10949
10942 // The value of the expression is a smi that is not zero. Try 10950 // The value of the expression is a smi that is not zero. Try
10943 // optimistic subtraction '0 - value'. 10951 // optimistic subtraction '0 - value'.
10944 Label undo; 10952 Label undo;
10945 __ mov(edx, Operand(eax)); 10953 __ mov(edx, Operand(eax));
10946 __ Set(eax, Immediate(0)); 10954 __ Set(eax, Immediate(0));
10947 __ sub(eax, Operand(edx)); 10955 __ sub(eax, Operand(edx));
10948 __ j(overflow, &undo, not_taken); 10956 __ j(no_overflow, &done, taken);
10949
10950 // If result is a smi we are done.
10951 __ test(eax, Immediate(kSmiTagMask));
10952 __ j(zero, &done, taken);
10953 10957
10954 // Restore eax and go slow case. 10958 // Restore eax and go slow case.
10955 __ bind(&undo); 10959 __ bind(&undo);
10956 __ mov(eax, Operand(edx)); 10960 __ mov(eax, Operand(edx));
10957 __ jmp(&slow); 10961 __ jmp(&slow);
10958 10962
10959 // Try floating point case. 10963 // Try floating point case.
10960 __ bind(&try_float); 10964 __ bind(&try_float);
10961 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); 10965 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
10962 __ cmp(edx, Factory::heap_number_map()); 10966 __ cmp(edx, Factory::heap_number_map());
10963 __ j(not_equal, &slow); 10967 __ j(not_equal, &slow);
10964 if (overwrite_) { 10968 if (overwrite_ == UNARY_OVERWRITE) {
10965 __ mov(edx, FieldOperand(eax, HeapNumber::kExponentOffset)); 10969 __ mov(edx, FieldOperand(eax, HeapNumber::kExponentOffset));
10966 __ xor_(edx, HeapNumber::kSignMask); // Flip sign. 10970 __ xor_(edx, HeapNumber::kSignMask); // Flip sign.
10967 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), edx); 10971 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), edx);
10968 } else { 10972 } else {
10969 __ mov(edx, Operand(eax)); 10973 __ mov(edx, Operand(eax));
10970 // edx: operand 10974 // edx: operand
10971 __ AllocateHeapNumber(eax, ebx, ecx, &undo); 10975 __ AllocateHeapNumber(eax, ebx, ecx, &undo);
10972 // eax: allocated 'empty' number 10976 // eax: allocated 'empty' number
10973 __ mov(ecx, FieldOperand(edx, HeapNumber::kExponentOffset)); 10977 __ mov(ecx, FieldOperand(edx, HeapNumber::kExponentOffset));
10974 __ xor_(ecx, HeapNumber::kSignMask); // Flip sign. 10978 __ xor_(ecx, HeapNumber::kSignMask); // Flip sign.
(...skipping 20 matching lines...) Expand all
10995 __ cmp(ecx, 0xc0000000); 10999 __ cmp(ecx, 0xc0000000);
10996 __ j(sign, &try_float, not_taken); 11000 __ j(sign, &try_float, not_taken);
10997 11001
10998 // Tag the result as a smi and we're done. 11002 // Tag the result as a smi and we're done.
10999 ASSERT(kSmiTagSize == 1); 11003 ASSERT(kSmiTagSize == 1);
11000 __ lea(eax, Operand(ecx, times_2, kSmiTag)); 11004 __ lea(eax, Operand(ecx, times_2, kSmiTag));
11001 __ jmp(&done); 11005 __ jmp(&done);
11002 11006
11003 // Try to store the result in a heap number. 11007 // Try to store the result in a heap number.
11004 __ bind(&try_float); 11008 __ bind(&try_float);
11005 if (!overwrite_) { 11009 if (overwrite_ == UNARY_NO_OVERWRITE) {
11006 // Allocate a fresh heap number, but don't overwrite eax until 11010 // Allocate a fresh heap number, but don't overwrite eax until
11007 // we're sure we can do it without going through the slow case 11011 // we're sure we can do it without going through the slow case
11008 // that needs the value in eax. 11012 // that needs the value in eax.
11009 __ AllocateHeapNumber(ebx, edx, edi, &slow); 11013 __ AllocateHeapNumber(ebx, edx, edi, &slow);
11010 __ mov(eax, Operand(ebx)); 11014 __ mov(eax, Operand(ebx));
11011 } 11015 }
11012 if (CpuFeatures::IsSupported(SSE2)) { 11016 if (CpuFeatures::IsSupported(SSE2)) {
11013 CpuFeatures::Scope use_sse2(SSE2); 11017 CpuFeatures::Scope use_sse2(SSE2);
11014 __ cvtsi2sd(xmm0, Operand(ecx)); 11018 __ cvtsi2sd(xmm0, Operand(ecx));
11015 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); 11019 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
(...skipping 2754 matching lines...) Expand 10 before | Expand all | Expand 10 after
13770 masm.GetCode(&desc); 13774 masm.GetCode(&desc);
13771 // Call the function from C++. 13775 // Call the function from C++.
13772 return FUNCTION_CAST<MemCopyFunction>(buffer); 13776 return FUNCTION_CAST<MemCopyFunction>(buffer);
13773 } 13777 }
13774 13778
13775 #undef __ 13779 #undef __
13776 13780
13777 } } // namespace v8::internal 13781 } } // namespace v8::internal
13778 13782
13779 #endif // V8_TARGET_ARCH_IA32 13783 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/codegen.cc ('k') | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698