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

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

Issue 552188: Port bit not unary op stub to ARM. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 10 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 | « no previous file | no next file » | 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 3707 matching lines...) Expand 10 before | Expand all | Expand 10 after
3718 frame_->EmitPush(r0); 3718 frame_->EmitPush(r0);
3719 3719
3720 } else if (op == Token::TYPEOF) { 3720 } else if (op == Token::TYPEOF) {
3721 // Special case for loading the typeof expression; see comment on 3721 // Special case for loading the typeof expression; see comment on
3722 // LoadTypeofExpression(). 3722 // LoadTypeofExpression().
3723 LoadTypeofExpression(node->expression()); 3723 LoadTypeofExpression(node->expression());
3724 frame_->CallRuntime(Runtime::kTypeof, 1); 3724 frame_->CallRuntime(Runtime::kTypeof, 1);
3725 frame_->EmitPush(r0); // r0 has result 3725 frame_->EmitPush(r0); // r0 has result
3726 3726
3727 } else { 3727 } else {
3728 bool overwrite =
3729 (node->expression()->AsBinaryOperation() != NULL &&
3730 node->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
3728 LoadAndSpill(node->expression()); 3731 LoadAndSpill(node->expression());
3729 frame_->EmitPop(r0); 3732 frame_->EmitPop(r0);
3730 switch (op) { 3733 switch (op) {
3731 case Token::NOT: 3734 case Token::NOT:
3732 case Token::DELETE: 3735 case Token::DELETE:
3733 case Token::TYPEOF: 3736 case Token::TYPEOF:
3734 UNREACHABLE(); // handled above 3737 UNREACHABLE(); // handled above
3735 break; 3738 break;
3736 3739
3737 case Token::SUB: { 3740 case Token::SUB: {
3738 bool overwrite =
3739 (node->expression()->AsBinaryOperation() != NULL &&
3740 node->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
3741 GenericUnaryOpStub stub(Token::SUB, overwrite); 3741 GenericUnaryOpStub stub(Token::SUB, overwrite);
3742 frame_->CallStub(&stub, 0); 3742 frame_->CallStub(&stub, 0);
3743 break; 3743 break;
3744 } 3744 }
3745 3745
3746 case Token::BIT_NOT: { 3746 case Token::BIT_NOT: {
3747 // smi check 3747 // smi check
3748 JumpTarget smi_label; 3748 JumpTarget smi_label;
3749 JumpTarget continue_label; 3749 JumpTarget continue_label;
3750 __ tst(r0, Operand(kSmiTagMask)); 3750 __ tst(r0, Operand(kSmiTagMask));
3751 smi_label.Branch(eq); 3751 smi_label.Branch(eq);
3752 3752
3753 frame_->EmitPush(r0); 3753 GenericUnaryOpStub stub(Token::BIT_NOT, overwrite);
3754 frame_->InvokeBuiltin(Builtins::BIT_NOT, CALL_JS, 1); 3754 frame_->CallStub(&stub, 0);
3755 continue_label.Jump();
3755 3756
3756 continue_label.Jump();
3757 smi_label.Bind(); 3757 smi_label.Bind();
3758 __ mvn(r0, Operand(r0)); 3758 __ mvn(r0, Operand(r0));
3759 __ bic(r0, r0, Operand(kSmiTagMask)); // bit-clear inverted smi-tag 3759 __ bic(r0, r0, Operand(kSmiTagMask)); // bit-clear inverted smi-tag
3760 continue_label.Bind(); 3760 continue_label.Bind();
3761 break; 3761 break;
3762 } 3762 }
3763 3763
3764 case Token::VOID: 3764 case Token::VOID:
3765 // since the stack top is cached in r0, popping and then 3765 // since the stack top is cached in r0, popping and then
3766 // pushing a value can be done by just writing to r0. 3766 // pushing a value can be done by just writing to r0.
(...skipping 2303 matching lines...) Expand 10 before | Expand all | Expand 10 after
6070 // argument, so give it a Smi. 6070 // argument, so give it a Smi.
6071 __ mov(r0, Operand(Smi::FromInt(0))); 6071 __ mov(r0, Operand(Smi::FromInt(0)));
6072 __ push(r0); 6072 __ push(r0);
6073 __ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1, 1); 6073 __ TailCallRuntime(ExternalReference(Runtime::kStackGuard), 1, 1);
6074 6074
6075 __ StubReturn(1); 6075 __ StubReturn(1);
6076 } 6076 }
6077 6077
6078 6078
6079 void GenericUnaryOpStub::Generate(MacroAssembler* masm) { 6079 void GenericUnaryOpStub::Generate(MacroAssembler* masm) {
6080 ASSERT(op_ == Token::SUB); 6080 Label slow, done;
6081 6081
6082 Label undo; 6082 if (op_ == Token::SUB) {
6083 Label slow; 6083 // Check whether the value is a smi.
6084 Label not_smi; 6084 Label try_float;
6085 __ tst(r0, Operand(kSmiTagMask));
6086 __ b(ne, &try_float);
6085 6087
6086 // Enter runtime system if the value is not a smi. 6088 // Go slow case if the value of the expression is zero
6087 __ tst(r0, Operand(kSmiTagMask)); 6089 // to make sure that we switch between 0 and -0.
6088 __ b(ne, &not_smi); 6090 __ cmp(r0, Operand(0));
6091 __ b(eq, &slow);
6089 6092
6090 // Enter runtime system if the value of the expression is zero 6093 // The value of the expression is a smi that is not zero. Try
6091 // to make sure that we switch between 0 and -0. 6094 // optimistic subtraction '0 - value'.
6092 __ cmp(r0, Operand(0)); 6095 __ rsb(r1, r0, Operand(0), SetCC);
6093 __ b(eq, &slow); 6096 __ b(vs, &slow);
6094 6097
6095 // The value of the expression is a smi that is not zero. Try 6098 __ mov(r0, Operand(r1)); // Set r0 to result.
6096 // optimistic subtraction '0 - value'. 6099 __ b(&done);
6097 __ rsb(r1, r0, Operand(0), SetCC);
6098 __ b(vs, &slow);
6099 6100
6100 __ mov(r0, Operand(r1)); // Set r0 to result. 6101 __ bind(&try_float);
6102 __ CompareObjectType(r0, r1, r1, HEAP_NUMBER_TYPE);
6103 __ b(ne, &slow);
6104 // r0 is a heap number. Get a new heap number in r1.
6105 if (overwrite_) {
6106 __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset));
6107 __ eor(r2, r2, Operand(HeapNumber::kSignMask)); // Flip sign.
6108 __ str(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset));
6109 } else {
6110 AllocateHeapNumber(masm, &slow, r1, r2, r3);
6111 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset));
6112 __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset));
6113 __ str(r3, FieldMemOperand(r1, HeapNumber::kMantissaOffset));
6114 __ eor(r2, r2, Operand(HeapNumber::kSignMask)); // Flip sign.
6115 __ str(r2, FieldMemOperand(r1, HeapNumber::kExponentOffset));
6116 __ mov(r0, Operand(r1));
6117 }
6118 } else if (op_ == Token::BIT_NOT) {
6119 // Check if the operand is a heap number.
6120 __ CompareObjectType(r0, r1, r1, HEAP_NUMBER_TYPE);
6121 __ b(ne, &slow);
6122
6123 // Convert the heap number is r0 to an untagged integer in r1.
6124 GetInt32(masm, r0, r1, r2, r3, &slow);
6125
6126 // Do the bitwise operation (move negated) and check if the result
6127 // fits in a smi.
6128 Label try_float;
6129 __ mvn(r1, Operand(r1));
6130 __ add(r2, r1, Operand(0x40000000), SetCC);
6131 __ b(mi, &try_float);
6132 __ mov(r0, Operand(r1, LSL, kSmiTagSize));
6133 __ b(&done);
6134
6135 __ bind(&try_float);
6136 if (!overwrite_) {
6137 // Allocate a fresh heap number, but don't overwrite r0 until
6138 // we're sure we can do it without going through the slow case
6139 // that needs the value in r0.
6140 AllocateHeapNumber(masm, &slow, r2, r3, r4);
6141 __ mov(r0, Operand(r2));
6142 }
6143
6144 // WriteInt32ToHeapNumberStub does not trigger GC, so we do not
6145 // have to set up a frame.
6146 WriteInt32ToHeapNumberStub stub(r1, r0, r2);
6147 __ push(lr);
6148 __ Call(stub.GetCode(), RelocInfo::CODE_TARGET);
6149 __ pop(lr);
6150 } else {
6151 UNIMPLEMENTED();
6152 }
6153
6154 __ bind(&done);
6101 __ StubReturn(1); 6155 __ StubReturn(1);
6102 6156
6103 // Enter runtime system. 6157 // Handle the slow case by jumping to the JavaScript builtin.
6104 __ bind(&slow); 6158 __ bind(&slow);
6105 __ push(r0); 6159 __ push(r0);
6106 __ InvokeBuiltin(Builtins::UNARY_MINUS, JUMP_JS); 6160 switch (op_) {
6107 6161 case Token::SUB:
6108 __ bind(&not_smi); 6162 __ InvokeBuiltin(Builtins::UNARY_MINUS, JUMP_JS);
6109 __ CompareObjectType(r0, r1, r1, HEAP_NUMBER_TYPE); 6163 break;
6110 __ b(ne, &slow); 6164 case Token::BIT_NOT:
6111 // r0 is a heap number. Get a new heap number in r1. 6165 __ InvokeBuiltin(Builtins::BIT_NOT, JUMP_JS);
6112 if (overwrite_) { 6166 break;
6113 __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset)); 6167 default:
6114 __ eor(r2, r2, Operand(HeapNumber::kSignMask)); // Flip sign. 6168 UNREACHABLE();
6115 __ str(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset));
6116 } else {
6117 AllocateHeapNumber(masm, &slow, r1, r2, r3);
6118 __ ldr(r3, FieldMemOperand(r0, HeapNumber::kMantissaOffset));
6119 __ ldr(r2, FieldMemOperand(r0, HeapNumber::kExponentOffset));
6120 __ str(r3, FieldMemOperand(r1, HeapNumber::kMantissaOffset));
6121 __ eor(r2, r2, Operand(HeapNumber::kSignMask)); // Flip sign.
6122 __ str(r2, FieldMemOperand(r1, HeapNumber::kExponentOffset));
6123 __ mov(r0, Operand(r1));
6124 } 6169 }
6125 __ StubReturn(1);
6126 } 6170 }
6127 6171
6128 6172
6129 int CEntryStub::MinorKey() { 6173 int CEntryStub::MinorKey() {
6130 ASSERT(result_size_ <= 2); 6174 ASSERT(result_size_ <= 2);
6131 // Result returned in r0 or r0+r1 by default. 6175 // Result returned in r0 or r0+r1 by default.
6132 return 0; 6176 return 0;
6133 } 6177 }
6134 6178
6135 6179
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after
6870 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) 6914 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater)
6871 // tagged as a small integer. 6915 // tagged as a small integer.
6872 __ bind(&runtime); 6916 __ bind(&runtime);
6873 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); 6917 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1);
6874 } 6918 }
6875 6919
6876 6920
6877 #undef __ 6921 #undef __
6878 6922
6879 } } // namespace v8::internal 6923 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698