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

Side by Side Diff: src/ia32/codegen-ia32.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/heap.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 2245 matching lines...) Expand 10 before | Expand all | Expand 10 after
9853 case Token::MUL: 9859 case Token::MUL:
9854 case Token::DIV: { 9860 case Token::DIV: {
9855 if (runtime_operands_type_ == BinaryOpIC::DEFAULT && 9861 if (runtime_operands_type_ == BinaryOpIC::DEFAULT &&
9856 HasSmiCodeInStub()) { 9862 HasSmiCodeInStub()) {
9857 // Execution reaches this point when the first non-smi argument occurs 9863 // Execution reaches this point when the first non-smi argument occurs
9858 // (and only if smi code is generated). This is the right moment to 9864 // (and only if smi code is generated). This is the right moment to
9859 // patch to HEAP_NUMBERS state. The transition is attempted only for 9865 // patch to HEAP_NUMBERS state. The transition is attempted only for
9860 // the four basic operations. The stub stays in the DEFAULT state 9866 // the four basic operations. The stub stays in the DEFAULT state
9861 // forever for all other operations (also if smi code is skipped). 9867 // forever for all other operations (also if smi code is skipped).
9862 GenerateTypeTransition(masm); 9868 GenerateTypeTransition(masm);
9869 break;
9863 } 9870 }
9864 9871
9865 Label not_floats; 9872 Label not_floats;
9866 if (CpuFeatures::IsSupported(SSE2)) { 9873 if (CpuFeatures::IsSupported(SSE2)) {
9867 CpuFeatures::Scope use_sse2(SSE2); 9874 CpuFeatures::Scope use_sse2(SSE2);
9868 if (static_operands_type_.IsNumber()) { 9875 if (static_operands_type_.IsNumber()) {
9869 if (FLAG_debug_code) { 9876 if (FLAG_debug_code) {
9870 // Assert at runtime that inputs are only numbers. 9877 // Assert at runtime that inputs are only numbers.
9871 __ AbortIfNotNumber(edx); 9878 __ AbortIfNotNumber(edx);
9872 __ AbortIfNotNumber(eax); 9879 __ AbortIfNotNumber(eax);
(...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after
10200 __ push(edx); 10207 __ push(edx);
10201 } else { 10208 } else {
10202 __ push(edx); 10209 __ push(edx);
10203 __ push(eax); 10210 __ push(eax);
10204 } 10211 }
10205 __ push(ecx); 10212 __ push(ecx);
10206 } 10213 }
10207 10214
10208 10215
10209 void GenericBinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) { 10216 void GenericBinaryOpStub::GenerateTypeTransition(MacroAssembler* masm) {
10210 Label get_result; 10217 // Ensure the operands are on the stack.
10211
10212 // Keep a copy of operands on the stack and make sure they are also in
10213 // edx, eax.
10214 if (HasArgsInRegisters()) { 10218 if (HasArgsInRegisters()) {
10215 GenerateRegisterArgsPush(masm); 10219 GenerateRegisterArgsPush(masm);
10216 } else {
10217 GenerateLoadArguments(masm);
10218 } 10220 }
10219 10221
10220 // Internal frame is necessary to handle exceptions properly. 10222 __ pop(ecx); // Save return address.
10221 __ EnterInternalFrame();
10222 10223
10223 // Push arguments on stack if the stub expects them there.
10224 if (!HasArgsInRegisters()) {
10225 __ push(edx);
10226 __ push(eax);
10227 }
10228 // Call the stub proper to get the result in eax.
10229 __ call(&get_result);
10230 __ LeaveInternalFrame();
10231
10232 __ pop(ecx); // Return address.
10233 // Left and right arguments are now on top. 10224 // Left and right arguments are now on top.
10234 // Push the operation result. The tail call to BinaryOp_Patch will
10235 // return it to the original caller.
10236 __ push(eax);
10237 // Push this stub's key. Although the operation and the type info are 10225 // Push this stub's key. Although the operation and the type info are
10238 // encoded into the key, the encoding is opaque, so push them too. 10226 // encoded into the key, the encoding is opaque, so push them too.
10239 __ push(Immediate(Smi::FromInt(MinorKey()))); 10227 __ push(Immediate(Smi::FromInt(MinorKey())));
10240 __ push(Immediate(Smi::FromInt(op_))); 10228 __ push(Immediate(Smi::FromInt(op_)));
10241 __ push(Immediate(Smi::FromInt(runtime_operands_type_))); 10229 __ push(Immediate(Smi::FromInt(runtime_operands_type_)));
10242 10230
10243 __ push(ecx); // Return address. 10231 __ push(ecx); // Push return address.
10244 10232
10245 // Patch the caller to an appropriate specialized stub 10233 // Patch the caller to an appropriate specialized stub and return the
10246 // and return the operation result. 10234 // operation result to the caller of the stub.
10247 __ TailCallExternalReference( 10235 __ TailCallExternalReference(
10248 ExternalReference(IC_Utility(IC::kBinaryOp_Patch)), 10236 ExternalReference(IC_Utility(IC::kBinaryOp_Patch)),
10249 6, 10237 5,
10250 1); 10238 1);
10251
10252 // The entry point for the result calculation is assumed to be immediately
10253 // after this sequence.
10254 __ bind(&get_result);
10255 } 10239 }
10256 10240
10257 10241
10258 Handle<Code> GetBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info) { 10242 Handle<Code> GetBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info) {
10259 GenericBinaryOpStub stub(key, type_info); 10243 GenericBinaryOpStub stub(key, type_info);
10260 return stub.GetCode(); 10244 return stub.GetCode();
10261 } 10245 }
10262 10246
10263 10247
10264 void TranscendentalCacheStub::Generate(MacroAssembler* masm) { 10248 void TranscendentalCacheStub::Generate(MacroAssembler* masm) {
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after
10927 10911
10928 void GenericUnaryOpStub::Generate(MacroAssembler* masm) { 10912 void GenericUnaryOpStub::Generate(MacroAssembler* masm) {
10929 Label slow, done; 10913 Label slow, done;
10930 10914
10931 if (op_ == Token::SUB) { 10915 if (op_ == Token::SUB) {
10932 // Check whether the value is a smi. 10916 // Check whether the value is a smi.
10933 Label try_float; 10917 Label try_float;
10934 __ test(eax, Immediate(kSmiTagMask)); 10918 __ test(eax, Immediate(kSmiTagMask));
10935 __ j(not_zero, &try_float, not_taken); 10919 __ j(not_zero, &try_float, not_taken);
10936 10920
10937 // Go slow case if the value of the expression is zero 10921 if (negative_zero_ == kStrictNegativeZero) {
10938 // to make sure that we switch between 0 and -0. 10922 // Go slow case if the value of the expression is zero
10939 __ test(eax, Operand(eax)); 10923 // to make sure that we switch between 0 and -0.
10940 __ j(zero, &slow, not_taken); 10924 __ test(eax, Operand(eax));
10925 __ j(zero, &slow, not_taken);
10926 }
10941 10927
10942 // The value of the expression is a smi that is not zero. Try 10928 // The value of the expression is a smi that is not zero. Try
10943 // optimistic subtraction '0 - value'. 10929 // optimistic subtraction '0 - value'.
10944 Label undo; 10930 Label undo;
10945 __ mov(edx, Operand(eax)); 10931 __ mov(edx, Operand(eax));
10946 __ Set(eax, Immediate(0)); 10932 __ Set(eax, Immediate(0));
10947 __ sub(eax, Operand(edx)); 10933 __ sub(eax, Operand(edx));
10948 __ j(overflow, &undo, not_taken); 10934 __ 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 10935
10954 // Restore eax and go slow case. 10936 // Restore eax and go slow case.
10955 __ bind(&undo); 10937 __ bind(&undo);
10956 __ mov(eax, Operand(edx)); 10938 __ mov(eax, Operand(edx));
10957 __ jmp(&slow); 10939 __ jmp(&slow);
10958 10940
10959 // Try floating point case. 10941 // Try floating point case.
10960 __ bind(&try_float); 10942 __ bind(&try_float);
10961 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset)); 10943 __ mov(edx, FieldOperand(eax, HeapObject::kMapOffset));
10962 __ cmp(edx, Factory::heap_number_map()); 10944 __ cmp(edx, Factory::heap_number_map());
10963 __ j(not_equal, &slow); 10945 __ j(not_equal, &slow);
10964 if (overwrite_) { 10946 if (overwrite_ == UNARY_OVERWRITE) {
10965 __ mov(edx, FieldOperand(eax, HeapNumber::kExponentOffset)); 10947 __ mov(edx, FieldOperand(eax, HeapNumber::kExponentOffset));
10966 __ xor_(edx, HeapNumber::kSignMask); // Flip sign. 10948 __ xor_(edx, HeapNumber::kSignMask); // Flip sign.
10967 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), edx); 10949 __ mov(FieldOperand(eax, HeapNumber::kExponentOffset), edx);
10968 } else { 10950 } else {
10969 __ mov(edx, Operand(eax)); 10951 __ mov(edx, Operand(eax));
10970 // edx: operand 10952 // edx: operand
10971 __ AllocateHeapNumber(eax, ebx, ecx, &undo); 10953 __ AllocateHeapNumber(eax, ebx, ecx, &undo);
10972 // eax: allocated 'empty' number 10954 // eax: allocated 'empty' number
10973 __ mov(ecx, FieldOperand(edx, HeapNumber::kExponentOffset)); 10955 __ mov(ecx, FieldOperand(edx, HeapNumber::kExponentOffset));
10974 __ xor_(ecx, HeapNumber::kSignMask); // Flip sign. 10956 __ xor_(ecx, HeapNumber::kSignMask); // Flip sign.
(...skipping 20 matching lines...) Expand all
10995 __ cmp(ecx, 0xc0000000); 10977 __ cmp(ecx, 0xc0000000);
10996 __ j(sign, &try_float, not_taken); 10978 __ j(sign, &try_float, not_taken);
10997 10979
10998 // Tag the result as a smi and we're done. 10980 // Tag the result as a smi and we're done.
10999 ASSERT(kSmiTagSize == 1); 10981 ASSERT(kSmiTagSize == 1);
11000 __ lea(eax, Operand(ecx, times_2, kSmiTag)); 10982 __ lea(eax, Operand(ecx, times_2, kSmiTag));
11001 __ jmp(&done); 10983 __ jmp(&done);
11002 10984
11003 // Try to store the result in a heap number. 10985 // Try to store the result in a heap number.
11004 __ bind(&try_float); 10986 __ bind(&try_float);
11005 if (!overwrite_) { 10987 if (overwrite_ == UNARY_NO_OVERWRITE) {
11006 // Allocate a fresh heap number, but don't overwrite eax until 10988 // 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 10989 // we're sure we can do it without going through the slow case
11008 // that needs the value in eax. 10990 // that needs the value in eax.
11009 __ AllocateHeapNumber(ebx, edx, edi, &slow); 10991 __ AllocateHeapNumber(ebx, edx, edi, &slow);
11010 __ mov(eax, Operand(ebx)); 10992 __ mov(eax, Operand(ebx));
11011 } 10993 }
11012 if (CpuFeatures::IsSupported(SSE2)) { 10994 if (CpuFeatures::IsSupported(SSE2)) {
11013 CpuFeatures::Scope use_sse2(SSE2); 10995 CpuFeatures::Scope use_sse2(SSE2);
11014 __ cvtsi2sd(xmm0, Operand(ecx)); 10996 __ cvtsi2sd(xmm0, Operand(ecx));
11015 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); 10997 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0);
(...skipping 2754 matching lines...) Expand 10 before | Expand all | Expand 10 after
13770 masm.GetCode(&desc); 13752 masm.GetCode(&desc);
13771 // Call the function from C++. 13753 // Call the function from C++.
13772 return FUNCTION_CAST<MemCopyFunction>(buffer); 13754 return FUNCTION_CAST<MemCopyFunction>(buffer);
13773 } 13755 }
13774 13756
13775 #undef __ 13757 #undef __
13776 13758
13777 } } // namespace v8::internal 13759 } } // namespace v8::internal
13778 13760
13779 #endif // V8_TARGET_ARCH_IA32 13761 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/heap.cc ('k') | src/ia32/full-codegen-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698