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

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

Issue 125085: Fix ambiguous method errors by explicitly passing reloc info. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 6 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/arm/builtins-arm.cc ('k') | src/arm/debug-arm.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 1040 matching lines...) Expand 10 before | Expand all | Expand 10 after
1051 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) 1051 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
1052 // tagged as a small integer. 1052 // tagged as a small integer.
1053 frame_->EmitPush(r0); 1053 frame_->EmitPush(r0);
1054 Result arg_count_register = allocator_->Allocate(r0); 1054 Result arg_count_register = allocator_->Allocate(r0);
1055 ASSERT(arg_count_register.is_valid()); 1055 ASSERT(arg_count_register.is_valid());
1056 __ mov(arg_count_register.reg(), Operand(arg_count)); 1056 __ mov(arg_count_register.reg(), Operand(arg_count));
1057 Result result = frame_->InvokeBuiltin(native, 1057 Result result = frame_->InvokeBuiltin(native,
1058 CALL_JS, 1058 CALL_JS,
1059 &arg_count_register, 1059 &arg_count_register,
1060 arg_count + 1); 1060 arg_count + 1);
1061 __ cmp(result.reg(), Operand(0)); 1061 __ cmp(result.reg(), Operand(0, RelocInfo::NONE));
1062 result.Unuse(); 1062 result.Unuse();
1063 exit.Jump(); 1063 exit.Jump();
1064 1064
1065 // test smi equality by pointer comparison. 1065 // test smi equality by pointer comparison.
1066 smi.Bind(); 1066 smi.Bind();
1067 __ cmp(r1, Operand(r0)); 1067 __ cmp(r1, Operand(r0));
1068 1068
1069 exit.Bind(); 1069 exit.Bind();
1070 cc_reg_ = cc; 1070 cc_reg_ = cc;
1071 } 1071 }
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
1228 // Push initial value, if any. 1228 // Push initial value, if any.
1229 // Note: For variables we must not push an initial value (such as 1229 // Note: For variables we must not push an initial value (such as
1230 // 'undefined') because we may have a (legal) redeclaration and we 1230 // 'undefined') because we may have a (legal) redeclaration and we
1231 // must not destroy the current value. 1231 // must not destroy the current value.
1232 if (node->mode() == Variable::CONST) { 1232 if (node->mode() == Variable::CONST) {
1233 __ mov(r0, Operand(Factory::the_hole_value())); 1233 __ mov(r0, Operand(Factory::the_hole_value()));
1234 frame_->EmitPush(r0); 1234 frame_->EmitPush(r0);
1235 } else if (node->fun() != NULL) { 1235 } else if (node->fun() != NULL) {
1236 LoadAndSpill(node->fun()); 1236 LoadAndSpill(node->fun());
1237 } else { 1237 } else {
1238 __ mov(r0, Operand(0)); // no initial value! 1238 __ mov(r0, Operand(0, RelocInfo::NONE)); // no initial value!
1239 frame_->EmitPush(r0); 1239 frame_->EmitPush(r0);
1240 } 1240 }
1241 frame_->CallRuntime(Runtime::kDeclareContextSlot, 4); 1241 frame_->CallRuntime(Runtime::kDeclareContextSlot, 4);
1242 // Ignore the return value (declarations are statements). 1242 // Ignore the return value (declarations are statements).
1243 ASSERT(frame_->height() == original_height); 1243 ASSERT(frame_->height() == original_height);
1244 return; 1244 return;
1245 } 1245 }
1246 1246
1247 ASSERT(!var->is_global()); 1247 ASSERT(!var->is_global());
1248 1248
(...skipping 621 matching lines...) Expand 10 before | Expand all | Expand 10 after
1870 // Check if enumerable is already a JSObject 1870 // Check if enumerable is already a JSObject
1871 __ tst(r0, Operand(kSmiTagMask)); 1871 __ tst(r0, Operand(kSmiTagMask));
1872 primitive.Branch(eq); 1872 primitive.Branch(eq);
1873 __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE); 1873 __ CompareObjectType(r0, r1, r1, FIRST_JS_OBJECT_TYPE);
1874 jsobject.Branch(hs); 1874 jsobject.Branch(hs);
1875 1875
1876 primitive.Bind(); 1876 primitive.Bind();
1877 frame_->EmitPush(r0); 1877 frame_->EmitPush(r0);
1878 Result arg_count = allocator_->Allocate(r0); 1878 Result arg_count = allocator_->Allocate(r0);
1879 ASSERT(arg_count.is_valid()); 1879 ASSERT(arg_count.is_valid());
1880 __ mov(arg_count.reg(), Operand(0)); 1880 __ mov(arg_count.reg(), Operand(0, RelocInfo::NONE));
1881 frame_->InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS, &arg_count, 1); 1881 frame_->InvokeBuiltin(Builtins::TO_OBJECT, CALL_JS, &arg_count, 1);
1882 1882
1883 jsobject.Bind(); 1883 jsobject.Bind();
1884 // Get the set of properties (as a FixedArray or Map). 1884 // Get the set of properties (as a FixedArray or Map).
1885 frame_->EmitPush(r0); // duplicate the object being enumerated 1885 frame_->EmitPush(r0); // duplicate the object being enumerated
1886 frame_->EmitPush(r0); 1886 frame_->EmitPush(r0);
1887 frame_->CallRuntime(Runtime::kGetPropertyNamesFast, 1); 1887 frame_->CallRuntime(Runtime::kGetPropertyNamesFast, 1);
1888 1888
1889 // If we got a Map, we can do a fast modification check. 1889 // If we got a Map, we can do a fast modification check.
1890 // Otherwise, we got a FixedArray, and we have to do a slow check. 1890 // Otherwise, we got a FixedArray, and we have to do a slow check.
(...skipping 1673 matching lines...) Expand 10 before | Expand all | Expand 10 after
3564 case Token::BIT_NOT: { 3564 case Token::BIT_NOT: {
3565 // smi check 3565 // smi check
3566 JumpTarget smi_label; 3566 JumpTarget smi_label;
3567 JumpTarget continue_label; 3567 JumpTarget continue_label;
3568 __ tst(r0, Operand(kSmiTagMask)); 3568 __ tst(r0, Operand(kSmiTagMask));
3569 smi_label.Branch(eq); 3569 smi_label.Branch(eq);
3570 3570
3571 frame_->EmitPush(r0); 3571 frame_->EmitPush(r0);
3572 Result arg_count = allocator_->Allocate(r0); 3572 Result arg_count = allocator_->Allocate(r0);
3573 ASSERT(arg_count.is_valid()); 3573 ASSERT(arg_count.is_valid());
3574 __ mov(arg_count.reg(), Operand(0)); // not counting receiver 3574 // not counting receiver
William Hesse 2009/06/15 08:59:29 // Argument count does not include the receiver. C
3575 __ mov(arg_count.reg(), Operand(0, RelocInfo::NONE));
3575 frame_->InvokeBuiltin(Builtins::BIT_NOT, CALL_JS, &arg_count, 1); 3576 frame_->InvokeBuiltin(Builtins::BIT_NOT, CALL_JS, &arg_count, 1);
3576 3577
3577 continue_label.Jump(); 3578 continue_label.Jump();
3578 smi_label.Bind(); 3579 smi_label.Bind();
3579 __ mvn(r0, Operand(r0)); 3580 __ mvn(r0, Operand(r0));
3580 __ bic(r0, r0, Operand(kSmiTagMask)); // bit-clear inverted smi-tag 3581 __ bic(r0, r0, Operand(kSmiTagMask)); // bit-clear inverted smi-tag
3581 continue_label.Bind(); 3582 continue_label.Bind();
3582 break; 3583 break;
3583 } 3584 }
3584 3585
3585 case Token::VOID: 3586 case Token::VOID:
3586 // since the stack top is cached in r0, popping and then 3587 // since the stack top is cached in r0, popping and then
3587 // pushing a value can be done by just writing to r0. 3588 // pushing a value can be done by just writing to r0.
3588 __ mov(r0, Operand(Factory::undefined_value())); 3589 __ mov(r0, Operand(Factory::undefined_value()));
3589 break; 3590 break;
3590 3591
3591 case Token::ADD: { 3592 case Token::ADD: {
3592 // Smi check. 3593 // Smi check.
3593 JumpTarget continue_label; 3594 JumpTarget continue_label;
3594 __ tst(r0, Operand(kSmiTagMask)); 3595 __ tst(r0, Operand(kSmiTagMask));
3595 continue_label.Branch(eq); 3596 continue_label.Branch(eq);
3596 frame_->EmitPush(r0); 3597 frame_->EmitPush(r0);
3597 Result arg_count = allocator_->Allocate(r0); 3598 Result arg_count = allocator_->Allocate(r0);
3598 ASSERT(arg_count.is_valid()); 3599 ASSERT(arg_count.is_valid());
3599 __ mov(arg_count.reg(), Operand(0)); // not counting receiver 3600 // not counting receiver
3601 __ mov(arg_count.reg(), Operand(0, RelocInfo::NONE));
3600 frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, &arg_count, 1); 3602 frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, &arg_count, 1);
3601 continue_label.Bind(); 3603 continue_label.Bind();
3602 break; 3604 break;
3603 } 3605 }
3604 default: 3606 default:
3605 UNREACHABLE(); 3607 UNREACHABLE();
3606 } 3608 }
3607 frame_->EmitPush(r0); // r0 has result 3609 frame_->EmitPush(r0); // r0 has result
3608 } 3610 }
3609 ASSERT((has_cc() && frame_->height() == original_height) || 3611 ASSERT((has_cc() && frame_->height() == original_height) ||
3610 (!has_cc() && frame_->height() == original_height + 1)); 3612 (!has_cc() && frame_->height() == original_height + 1));
3611 } 3613 }
3612 3614
3613 3615
3614 void CodeGenerator::VisitCountOperation(CountOperation* node) { 3616 void CodeGenerator::VisitCountOperation(CountOperation* node) {
3615 #ifdef DEBUG 3617 #ifdef DEBUG
3616 int original_height = frame_->height(); 3618 int original_height = frame_->height();
3617 #endif 3619 #endif
3618 VirtualFrame::SpilledScope spilled_scope; 3620 VirtualFrame::SpilledScope spilled_scope;
3619 Comment cmnt(masm_, "[ CountOperation"); 3621 Comment cmnt(masm_, "[ CountOperation");
3620 3622
3621 bool is_postfix = node->is_postfix(); 3623 bool is_postfix = node->is_postfix();
3622 bool is_increment = node->op() == Token::INC; 3624 bool is_increment = node->op() == Token::INC;
3623 3625
3624 Variable* var = node->expression()->AsVariableProxy()->AsVariable(); 3626 Variable* var = node->expression()->AsVariableProxy()->AsVariable();
3625 bool is_const = (var != NULL && var->mode() == Variable::CONST); 3627 bool is_const = (var != NULL && var->mode() == Variable::CONST);
3626 3628
3627 // Postfix: Make room for the result. 3629 // Postfix: Make room for the result.
3628 if (is_postfix) { 3630 if (is_postfix) {
3629 __ mov(r0, Operand(0)); 3631 __ mov(r0, Operand(0, RelocInfo::NONE));
3630 frame_->EmitPush(r0); 3632 frame_->EmitPush(r0);
3631 } 3633 }
3632 3634
3633 { Reference target(this, node->expression()); 3635 { Reference target(this, node->expression());
3634 if (target.is_illegal()) { 3636 if (target.is_illegal()) {
3635 // Spoof the virtual frame to have the expected height (one higher 3637 // Spoof the virtual frame to have the expected height (one higher
3636 // than on entry). 3638 // than on entry).
3637 if (!is_postfix) { 3639 if (!is_postfix) {
3638 __ mov(r0, Operand(Smi::FromInt(0))); 3640 __ mov(r0, Operand(Smi::FromInt(0)));
3639 frame_->EmitPush(r0); 3641 frame_->EmitPush(r0);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
3676 __ add(r0, r0, Operand(r1)); 3678 __ add(r0, r0, Operand(r1));
3677 } 3679 }
3678 3680
3679 // Slow case: Convert to number. 3681 // Slow case: Convert to number.
3680 slow.Bind(); 3682 slow.Bind();
3681 { 3683 {
3682 // Convert the operand to a number. 3684 // Convert the operand to a number.
3683 frame_->EmitPush(r0); 3685 frame_->EmitPush(r0);
3684 Result arg_count = allocator_->Allocate(r0); 3686 Result arg_count = allocator_->Allocate(r0);
3685 ASSERT(arg_count.is_valid()); 3687 ASSERT(arg_count.is_valid());
3686 __ mov(arg_count.reg(), Operand(0)); 3688 __ mov(arg_count.reg(), Operand(0, RelocInfo::NONE));
3687 frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, &arg_count, 1); 3689 frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, &arg_count, 1);
3688 } 3690 }
3689 if (is_postfix) { 3691 if (is_postfix) {
3690 // Postfix: store to result (on the stack). 3692 // Postfix: store to result (on the stack).
3691 __ str(r0, frame_->ElementAt(target.size())); 3693 __ str(r0, frame_->ElementAt(target.size()));
3692 } 3694 }
3693 3695
3694 // Compute the new value. 3696 // Compute the new value.
3695 __ mov(r1, Operand(Smi::FromInt(1))); 3697 __ mov(r1, Operand(Smi::FromInt(1)));
3696 frame_->EmitPush(r0); 3698 frame_->EmitPush(r0);
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after
4324 // instruction. On pre-ARM5 hardware this routine gives the wrong answer for 0 4326 // instruction. On pre-ARM5 hardware this routine gives the wrong answer for 0
4325 // (31 instead of 32). 4327 // (31 instead of 32).
4326 static void CountLeadingZeros( 4328 static void CountLeadingZeros(
4327 MacroAssembler* masm, 4329 MacroAssembler* masm,
4328 Register source, 4330 Register source,
4329 Register scratch, 4331 Register scratch,
4330 Register zeros) { 4332 Register zeros) {
4331 #ifdef __ARM_ARCH_5__ 4333 #ifdef __ARM_ARCH_5__
4332 __ clz(zeros, source); // This instruction is only supported after ARM5. 4334 __ clz(zeros, source); // This instruction is only supported after ARM5.
4333 #else 4335 #else
4334 __ mov(zeros, Operand(0)); 4336 __ mov(zeros, Operand(0, RelocInfo::NONE));
4335 __ mov(scratch, source); 4337 __ mov(scratch, source);
4336 // Top 16. 4338 // Top 16.
4337 __ tst(scratch, Operand(0xffff0000)); 4339 __ tst(scratch, Operand(0xffff0000));
4338 __ add(zeros, zeros, Operand(16), LeaveCC, eq); 4340 __ add(zeros, zeros, Operand(16), LeaveCC, eq);
4339 __ mov(scratch, Operand(scratch, LSL, 16), LeaveCC, eq); 4341 __ mov(scratch, Operand(scratch, LSL, 16), LeaveCC, eq);
4340 // Top 8. 4342 // Top 8.
4341 __ tst(scratch, Operand(0xff000000)); 4343 __ tst(scratch, Operand(0xff000000));
4342 __ add(zeros, zeros, Operand(8), LeaveCC, eq); 4344 __ add(zeros, zeros, Operand(8), LeaveCC, eq);
4343 __ mov(scratch, Operand(scratch, LSL, 8), LeaveCC, eq); 4345 __ mov(scratch, Operand(scratch, LSL, 8), LeaveCC, eq);
4344 // Top 4. 4346 // Top 4.
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
4411 #endif 4413 #endif
4412 Label not_special; 4414 Label not_special;
4413 // Convert from Smi to integer. 4415 // Convert from Smi to integer.
4414 __ mov(source_, Operand(source_, ASR, kSmiTagSize)); 4416 __ mov(source_, Operand(source_, ASR, kSmiTagSize));
4415 // Move sign bit from source to destination. This works because the sign bit 4417 // Move sign bit from source to destination. This works because the sign bit
4416 // in the exponent word of the double has the same position and polarity as 4418 // in the exponent word of the double has the same position and polarity as
4417 // the 2's complement sign bit in a Smi. 4419 // the 2's complement sign bit in a Smi.
4418 ASSERT(HeapNumber::kSignMask == 0x80000000u); 4420 ASSERT(HeapNumber::kSignMask == 0x80000000u);
4419 __ and_(exponent, source_, Operand(HeapNumber::kSignMask), SetCC); 4421 __ and_(exponent, source_, Operand(HeapNumber::kSignMask), SetCC);
4420 // Subtract from 0 if source was negative. 4422 // Subtract from 0 if source was negative.
4421 __ rsb(source_, source_, Operand(0), LeaveCC, ne); 4423 __ rsb(source_, source_, Operand(0, RelocInfo::NONE), LeaveCC, ne);
4422 __ cmp(source_, Operand(1)); 4424 __ cmp(source_, Operand(1));
4423 __ b(gt, &not_special); 4425 __ b(gt, &not_special);
4424 4426
4425 // We have -1, 0 or 1, which we treat specially. 4427 // We have -1, 0 or 1, which we treat specially.
4426 __ cmp(source_, Operand(0)); 4428 __ cmp(source_, Operand(0, RelocInfo::NONE));
4427 // For 1 or -1 we need to or in the 0 exponent (biased to 1023). 4429 // For 1 or -1 we need to or in the 0 exponent (biased to 1023).
4428 static const uint32_t exponent_word_for_1 = 4430 static const uint32_t exponent_word_for_1 =
4429 HeapNumber::kExponentBias << HeapNumber::kExponentShift; 4431 HeapNumber::kExponentBias << HeapNumber::kExponentShift;
4430 __ orr(exponent, exponent, Operand(exponent_word_for_1), LeaveCC, ne); 4432 __ orr(exponent, exponent, Operand(exponent_word_for_1), LeaveCC, ne);
4431 // 1, 0 and -1 all have 0 for the second word. 4433 // 1, 0 and -1 all have 0 for the second word.
4432 __ mov(mantissa, Operand(0)); 4434 __ mov(mantissa, Operand(0, RelocInfo::NONE));
4433 __ Ret(); 4435 __ Ret();
4434 4436
4435 __ bind(&not_special); 4437 __ bind(&not_special);
4436 // Count leading zeros. Uses result2 for a scratch register on pre-ARM5. 4438 // Count leading zeros. Uses result2 for a scratch register on pre-ARM5.
4437 // Gets the wrong answer for 0, but we already checked for that case above. 4439 // Gets the wrong answer for 0, but we already checked for that case above.
4438 CountLeadingZeros(masm, source_, mantissa, zeros_); 4440 CountLeadingZeros(masm, source_, mantissa, zeros_);
4439 // Compute exponent and or it into the exponent register. 4441 // Compute exponent and or it into the exponent register.
4440 // We use result2 as a scratch register here. 4442 // We use result2 as a scratch register here.
4441 __ rsb(mantissa, zeros_, Operand(31 + HeapNumber::kExponentBias)); 4443 __ rsb(mantissa, zeros_, Operand(31 + HeapNumber::kExponentBias));
4442 __ orr(exponent, 4444 __ orr(exponent,
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
4505 __ cmp(the_int_, Operand(0x80000000)); 4507 __ cmp(the_int_, Operand(0x80000000));
4506 __ b(eq, &max_negative_int); 4508 __ b(eq, &max_negative_int);
4507 // Set up the correct exponent in scratch_. All non-Smi int32s have the same. 4509 // Set up the correct exponent in scratch_. All non-Smi int32s have the same.
4508 // A non-Smi integer is 1.xxx * 2^30 so the exponent is 30 (biased). 4510 // A non-Smi integer is 1.xxx * 2^30 so the exponent is 30 (biased).
4509 uint32_t non_smi_exponent = 4511 uint32_t non_smi_exponent =
4510 (HeapNumber::kExponentBias + 30) << HeapNumber::kExponentShift; 4512 (HeapNumber::kExponentBias + 30) << HeapNumber::kExponentShift;
4511 __ mov(scratch_, Operand(non_smi_exponent)); 4513 __ mov(scratch_, Operand(non_smi_exponent));
4512 // Set the sign bit in scratch_ if the value was negative. 4514 // Set the sign bit in scratch_ if the value was negative.
4513 __ orr(scratch_, scratch_, Operand(HeapNumber::kSignMask), LeaveCC, cs); 4515 __ orr(scratch_, scratch_, Operand(HeapNumber::kSignMask), LeaveCC, cs);
4514 // Subtract from 0 if the value was negative. 4516 // Subtract from 0 if the value was negative.
4515 __ rsb(the_int_, the_int_, Operand(0), LeaveCC, cs); 4517 __ rsb(the_int_, the_int_, Operand(0, RelocInfo::NONE), LeaveCC, cs);
4516 // We should be masking the implict first digit of the mantissa away here, 4518 // We should be masking the implict first digit of the mantissa away here,
4517 // but it just ends up combining harmlessly with the last digit of the 4519 // but it just ends up combining harmlessly with the last digit of the
4518 // exponent that happens to be 1. The sign bit is 0 so we shift 10 to get 4520 // exponent that happens to be 1. The sign bit is 0 so we shift 10 to get
4519 // the most significant 1 to hit the last bit of the 12 bit sign and exponent. 4521 // the most significant 1 to hit the last bit of the 12 bit sign and exponent.
4520 ASSERT(((1 << HeapNumber::kExponentShift) & non_smi_exponent) != 0); 4522 ASSERT(((1 << HeapNumber::kExponentShift) & non_smi_exponent) != 0);
4521 const int shift_distance = HeapNumber::kNonMantissaBitsInTopWord - 2; 4523 const int shift_distance = HeapNumber::kNonMantissaBitsInTopWord - 2;
4522 __ orr(scratch_, scratch_, Operand(the_int_, LSR, shift_distance)); 4524 __ orr(scratch_, scratch_, Operand(the_int_, LSR, shift_distance));
4523 __ str(scratch_, FieldMemOperand(the_heap_number_, 4525 __ str(scratch_, FieldMemOperand(the_heap_number_,
4524 HeapNumber::kExponentOffset)); 4526 HeapNumber::kExponentOffset));
4525 __ mov(scratch_, Operand(the_int_, LSL, 32 - shift_distance)); 4527 __ mov(scratch_, Operand(the_int_, LSL, 32 - shift_distance));
4526 __ str(scratch_, FieldMemOperand(the_heap_number_, 4528 __ str(scratch_, FieldMemOperand(the_heap_number_,
4527 HeapNumber::kMantissaOffset)); 4529 HeapNumber::kMantissaOffset));
4528 __ Ret(); 4530 __ Ret();
4529 4531
4530 __ bind(&max_negative_int); 4532 __ bind(&max_negative_int);
4531 // The max negative int32 is stored as a positive number in the mantissa of 4533 // The max negative int32 is stored as a positive number in the mantissa of
4532 // a double because it uses a sign bit instead of using two's complement. 4534 // a double because it uses a sign bit instead of using two's complement.
4533 // The actual mantissa bits stored are all 0 because the implicit most 4535 // The actual mantissa bits stored are all 0 because the implicit most
4534 // significant 1 bit is not stored. 4536 // significant 1 bit is not stored.
4535 non_smi_exponent += 1 << HeapNumber::kExponentShift; 4537 non_smi_exponent += 1 << HeapNumber::kExponentShift;
4536 __ mov(ip, Operand(HeapNumber::kSignMask | non_smi_exponent)); 4538 __ mov(ip, Operand(HeapNumber::kSignMask | non_smi_exponent));
4537 __ str(ip, FieldMemOperand(the_heap_number_, HeapNumber::kExponentOffset)); 4539 __ str(ip, FieldMemOperand(the_heap_number_, HeapNumber::kExponentOffset));
4538 __ mov(ip, Operand(0)); 4540 __ mov(ip, Operand(0, RelocInfo::NONE));
4539 __ str(ip, FieldMemOperand(the_heap_number_, HeapNumber::kMantissaOffset)); 4541 __ str(ip, FieldMemOperand(the_heap_number_, HeapNumber::kMantissaOffset));
4540 __ Ret(); 4542 __ Ret();
4541 } 4543 }
4542 4544
4543 4545
4544 // Allocates a heap number or jumps to the label if the young space is full and 4546 // Allocates a heap number or jumps to the label if the young space is full and
4545 // a scavenge is needed. 4547 // a scavenge is needed.
4546 static void AllocateHeapNumber( 4548 static void AllocateHeapNumber(
4547 MacroAssembler* masm, 4549 MacroAssembler* masm,
4548 Label* need_gc, // Jump here if young space is full. 4550 Label* need_gc, // Jump here if young space is full.
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after
4734 // leave the sign bit 0 so we subtract 2 bits from the shift distance. 4736 // leave the sign bit 0 so we subtract 2 bits from the shift distance.
4735 const int shift_distance = HeapNumber::kNonMantissaBitsInTopWord - 2; 4737 const int shift_distance = HeapNumber::kNonMantissaBitsInTopWord - 2;
4736 __ mov(scratch2, Operand(scratch2, LSL, shift_distance)); 4738 __ mov(scratch2, Operand(scratch2, LSL, shift_distance));
4737 // Put sign in zero flag. 4739 // Put sign in zero flag.
4738 __ tst(scratch, Operand(HeapNumber::kSignMask)); 4740 __ tst(scratch, Operand(HeapNumber::kSignMask));
4739 // Get the second half of the double. 4741 // Get the second half of the double.
4740 __ ldr(scratch, FieldMemOperand(source, HeapNumber::kMantissaOffset)); 4742 __ ldr(scratch, FieldMemOperand(source, HeapNumber::kMantissaOffset));
4741 // Shift down 22 bits to get the last 10 bits. 4743 // Shift down 22 bits to get the last 10 bits.
4742 __ orr(dest, scratch2, Operand(scratch, LSR, 32 - shift_distance)); 4744 __ orr(dest, scratch2, Operand(scratch, LSR, 32 - shift_distance));
4743 // Fix sign if sign bit was set. 4745 // Fix sign if sign bit was set.
4744 __ rsb(dest, dest, Operand(0), LeaveCC, ne); 4746 __ rsb(dest, dest, Operand(0, RelocInfo::NONE), LeaveCC, ne);
4745 } 4747 }
4746 4748
4747 4749
4748 // For bitwise ops where the inputs are not both Smis we here try to determine 4750 // For bitwise ops where the inputs are not both Smis we here try to determine
4749 // whether both inputs are either Smis or at least heap numbers that can be 4751 // whether both inputs are either Smis or at least heap numbers that can be
4750 // represented by a 32 bit signed value. We truncate towards zero as required 4752 // represented by a 32 bit signed value. We truncate towards zero as required
4751 // by the ES spec. If this is the case we do the bitwise op and see if the 4753 // by the ES spec. If this is the case we do the bitwise op and see if the
4752 // result is a Smi. If so, great, otherwise we try to find a heap number to 4754 // result is a Smi. If so, great, otherwise we try to find a heap number to
4753 // write the answer into (either by allocating or by overwriting). 4755 // write the answer into (either by allocating or by overwriting).
4754 // On entry the operands are in r0 and r1. On exit the answer is in r0. 4756 // On entry the operands are in r0 and r1. On exit the answer is in r0.
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
5045 Label slow; 5047 Label slow;
5046 Label done; 5048 Label done;
5047 Label not_smi; 5049 Label not_smi;
5048 5050
5049 // Enter runtime system if the value is not a smi. 5051 // Enter runtime system if the value is not a smi.
5050 __ tst(r0, Operand(kSmiTagMask)); 5052 __ tst(r0, Operand(kSmiTagMask));
5051 __ b(ne, &not_smi); 5053 __ b(ne, &not_smi);
5052 5054
5053 // Enter runtime system if the value of the expression is zero 5055 // Enter runtime system if the value of the expression is zero
5054 // to make sure that we switch between 0 and -0. 5056 // to make sure that we switch between 0 and -0.
5055 __ cmp(r0, Operand(0)); 5057 __ cmp(r0, Operand(0, RelocInfo::NONE));
5056 __ b(eq, &slow); 5058 __ b(eq, &slow);
5057 5059
5058 // The value of the expression is a smi that is not zero. Try 5060 // The value of the expression is a smi that is not zero. Try
5059 // optimistic subtraction '0 - value'. 5061 // optimistic subtraction '0 - value'.
5060 __ rsb(r1, r0, Operand(0), SetCC); 5062 __ rsb(r1, r0, Operand(0, RelocInfo::NONE), SetCC);
5061 __ b(vs, &slow); 5063 __ b(vs, &slow);
5062 5064
5063 __ mov(r0, Operand(r1)); // Set r0 to result. 5065 __ mov(r0, Operand(r1)); // Set r0 to result.
5064 __ StubReturn(1); 5066 __ StubReturn(1);
5065 5067
5066 // Enter runtime system. 5068 // Enter runtime system.
5067 __ bind(&slow); 5069 __ bind(&slow);
5068 __ push(r0); 5070 __ push(r0);
5069 __ mov(r0, Operand(0)); // Set number of arguments. 5071 __ mov(r0, Operand(0, RelocInfo::NONE)); // Set number of arguments.
5070 __ InvokeBuiltin(Builtins::UNARY_MINUS, JUMP_JS); 5072 __ InvokeBuiltin(Builtins::UNARY_MINUS, JUMP_JS);
5071 5073
5072 __ bind(&done); 5074 __ bind(&done);
5073 __ StubReturn(1); 5075 __ StubReturn(1);
5074 5076
5075 __ bind(&not_smi); 5077 __ bind(&not_smi);
5076 __ CompareObjectType(r0, r1, r1, HEAP_NUMBER_TYPE); 5078 __ CompareObjectType(r0, r1, r1, HEAP_NUMBER_TYPE);
5077 __ b(ne, &slow); 5079 __ b(ne, &slow);
5078 // r0 is a heap number. Get a new heap number in r1. 5080 // r0 is a heap number. Get a new heap number in r1.
5079 if (overwrite_) { 5081 if (overwrite_) {
(...skipping 26 matching lines...) Expand all
5106 // Restore the next handler and frame pointer, discard handler state. 5108 // Restore the next handler and frame pointer, discard handler state.
5107 ASSERT(StackHandlerConstants::kNextOffset == 0); 5109 ASSERT(StackHandlerConstants::kNextOffset == 0);
5108 __ pop(r2); 5110 __ pop(r2);
5109 __ str(r2, MemOperand(r3)); 5111 __ str(r2, MemOperand(r3));
5110 ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); 5112 ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
5111 __ ldm(ia_w, sp, r3.bit() | fp.bit()); // r3: discarded state. 5113 __ ldm(ia_w, sp, r3.bit() | fp.bit()); // r3: discarded state.
5112 5114
5113 // Before returning we restore the context from the frame pointer if 5115 // Before returning we restore the context from the frame pointer if
5114 // not NULL. The frame pointer is NULL in the exception handler of a 5116 // not NULL. The frame pointer is NULL in the exception handler of a
5115 // JS entry frame. 5117 // JS entry frame.
5116 __ cmp(fp, Operand(0)); 5118 __ cmp(fp, Operand(0, RelocInfo::NONE));
5117 // Set cp to NULL if fp is NULL. 5119 // Set cp to NULL if fp is NULL.
5118 __ mov(cp, Operand(0), LeaveCC, eq); 5120 __ mov(cp, Operand(0, RelocInfo::NONE), LeaveCC, eq);
5119 // Restore cp otherwise. 5121 // Restore cp otherwise.
5120 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne); 5122 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne);
5121 #ifdef DEBUG 5123 #ifdef DEBUG
5122 if (FLAG_debug_code) { 5124 if (FLAG_debug_code) {
5123 __ mov(lr, Operand(pc)); 5125 __ mov(lr, Operand(pc));
5124 } 5126 }
5125 #endif 5127 #endif
5126 ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); 5128 ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize);
5127 __ pop(pc); 5129 __ pop(pc);
5128 } 5130 }
(...skipping 21 matching lines...) Expand all
5150 __ jmp(&loop); 5152 __ jmp(&loop);
5151 __ bind(&done); 5153 __ bind(&done);
5152 5154
5153 // Set the top handler address to next handler past the current ENTRY handler. 5155 // Set the top handler address to next handler past the current ENTRY handler.
5154 ASSERT(StackHandlerConstants::kNextOffset == 0); 5156 ASSERT(StackHandlerConstants::kNextOffset == 0);
5155 __ pop(r0); 5157 __ pop(r0);
5156 __ str(r0, MemOperand(r3)); 5158 __ str(r0, MemOperand(r3));
5157 5159
5158 // Set external caught exception to false. 5160 // Set external caught exception to false.
5159 ExternalReference external_caught(Top::k_external_caught_exception_address); 5161 ExternalReference external_caught(Top::k_external_caught_exception_address);
5160 __ mov(r0, Operand(false)); 5162 __ mov(r0, Operand(0, RelocInfo::NONE));
5161 __ mov(r2, Operand(external_caught)); 5163 __ mov(r2, Operand(external_caught));
5162 __ str(r0, MemOperand(r2)); 5164 __ str(r0, MemOperand(r2));
5163 5165
5164 // Set pending exception and r0 to out of memory exception. 5166 // Set pending exception and r0 to out of memory exception.
5165 Failure* out_of_memory = Failure::OutOfMemoryException(); 5167 Failure* out_of_memory = Failure::OutOfMemoryException();
5166 __ mov(r0, Operand(reinterpret_cast<int32_t>(out_of_memory))); 5168 __ mov(r0, Operand(reinterpret_cast<int32_t>(out_of_memory)));
5167 __ mov(r2, Operand(ExternalReference(Top::k_pending_exception_address))); 5169 __ mov(r2, Operand(ExternalReference(Top::k_pending_exception_address)));
5168 __ str(r0, MemOperand(r2)); 5170 __ str(r0, MemOperand(r2));
5169 5171
5170 // Stack layout at this point. See also StackHandlerConstants. 5172 // Stack layout at this point. See also StackHandlerConstants.
5171 // sp -> state (ENTRY) 5173 // sp -> state (ENTRY)
5172 // fp 5174 // fp
5173 // lr 5175 // lr
5174 5176
5175 // Discard handler state (r2 is not used) and restore frame pointer. 5177 // Discard handler state (r2 is not used) and restore frame pointer.
5176 ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize); 5178 ASSERT(StackHandlerConstants::kFPOffset == 2 * kPointerSize);
5177 __ ldm(ia_w, sp, r2.bit() | fp.bit()); // r2: discarded state. 5179 __ ldm(ia_w, sp, r2.bit() | fp.bit()); // r2: discarded state.
5178 // Before returning we restore the context from the frame pointer if 5180 // Before returning we restore the context from the frame pointer if
5179 // not NULL. The frame pointer is NULL in the exception handler of a 5181 // not NULL. The frame pointer is NULL in the exception handler of a
5180 // JS entry frame. 5182 // JS entry frame.
5181 __ cmp(fp, Operand(0)); 5183 __ cmp(fp, Operand(0, RelocInfo::NONE));
5182 // Set cp to NULL if fp is NULL. 5184 // Set cp to NULL if fp is NULL.
5183 __ mov(cp, Operand(0), LeaveCC, eq); 5185 __ mov(cp, Operand(0, RelocInfo::NONE), LeaveCC, eq);
5184 // Restore cp otherwise. 5186 // Restore cp otherwise.
5185 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne); 5187 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset), ne);
5186 #ifdef DEBUG 5188 #ifdef DEBUG
5187 if (FLAG_debug_code) { 5189 if (FLAG_debug_code) {
5188 __ mov(lr, Operand(pc)); 5190 __ mov(lr, Operand(pc));
5189 } 5191 }
5190 #endif 5192 #endif
5191 ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize); 5193 ASSERT(StackHandlerConstants::kPCOffset == 3 * kPointerSize);
5192 __ pop(pc); 5194 __ pop(pc);
5193 } 5195 }
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
5643 __ b(ne, &slow); 5645 __ b(ne, &slow);
5644 5646
5645 // Fast-case: Invoke the function now. 5647 // Fast-case: Invoke the function now.
5646 // r1: pushed function 5648 // r1: pushed function
5647 ParameterCount actual(argc_); 5649 ParameterCount actual(argc_);
5648 __ InvokeFunction(r1, actual, JUMP_FUNCTION); 5650 __ InvokeFunction(r1, actual, JUMP_FUNCTION);
5649 5651
5650 // Slow-case: Non-function called. 5652 // Slow-case: Non-function called.
5651 __ bind(&slow); 5653 __ bind(&slow);
5652 __ mov(r0, Operand(argc_)); // Setup the number of arguments. 5654 __ mov(r0, Operand(argc_)); // Setup the number of arguments.
5653 __ mov(r2, Operand(0)); 5655 __ mov(r2, Operand(0, RelocInfo::NONE));
5654 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); 5656 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
5655 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), 5657 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)),
5656 RelocInfo::CODE_TARGET); 5658 RelocInfo::CODE_TARGET);
5657 } 5659 }
5658 5660
5659 5661
5660 #undef __ 5662 #undef __
5661 5663
5662 } } // namespace v8::internal 5664 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/arm/builtins-arm.cc ('k') | src/arm/debug-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698