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

Side by Side Diff: src/arm/code-stubs-arm.cc

Issue 7232010: Version 3.4.6 (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 9 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/code-stubs-arm.h ('k') | src/arm/frames-arm.h » ('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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 1592 matching lines...) Expand 10 before | Expand all | Expand 10 after
1603 __ mov(r0, Operand(Smi::FromInt(ncr))); 1603 __ mov(r0, Operand(Smi::FromInt(ncr)));
1604 __ push(r0); 1604 __ push(r0);
1605 } 1605 }
1606 1606
1607 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) 1607 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater)
1608 // tagged as a small integer. 1608 // tagged as a small integer.
1609 __ InvokeBuiltin(native, JUMP_FUNCTION); 1609 __ InvokeBuiltin(native, JUMP_FUNCTION);
1610 } 1610 }
1611 1611
1612 1612
1613 // This stub does not handle the inlined cases (Smis, Booleans, undefined).
1614 // The stub returns zero for false, and a non-zero value for true. 1613 // The stub returns zero for false, and a non-zero value for true.
1615 void ToBooleanStub::Generate(MacroAssembler* masm) { 1614 void ToBooleanStub::Generate(MacroAssembler* masm) {
1616 // This stub uses VFP3 instructions. 1615 // This stub uses VFP3 instructions.
1617 CpuFeatures::Scope scope(VFP3); 1616 CpuFeatures::Scope scope(VFP3);
1618 1617
1619 Label false_result; 1618 Label false_result, true_result, not_string;
1620 Label not_heap_number; 1619 const Register map = r9.is(tos_) ? r7 : r9;
1621 Register scratch = r9.is(tos_) ? r7 : r9;
1622 1620
1623 // undefined -> false 1621 // undefined -> false
1624 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex); 1622 __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
1625 __ cmp(tos_, ip); 1623 __ cmp(tos_, ip);
1626 __ b(eq, &false_result); 1624 __ b(eq, &false_result);
1627 1625
1628 // Boolean -> its value 1626 // Boolean -> its value
1629 __ LoadRoot(ip, Heap::kFalseValueRootIndex); 1627 __ LoadRoot(ip, Heap::kFalseValueRootIndex);
1630 __ cmp(tos_, ip); 1628 __ cmp(tos_, ip);
1631 __ b(eq, &false_result); 1629 __ b(eq, &false_result);
1632 __ LoadRoot(ip, Heap::kTrueValueRootIndex); 1630 __ LoadRoot(ip, Heap::kTrueValueRootIndex);
1633 __ cmp(tos_, ip); 1631 __ cmp(tos_, ip);
1634 // "tos_" is a register and contains a non-zero value. Hence we implicitly 1632 // "tos_" is a register and contains a non-zero value. Hence we implicitly
1635 // return true if the equal condition is satisfied. 1633 // return true if the equal condition is satisfied.
1636 __ Ret(eq); 1634 __ Ret(eq);
1637 1635
1638 // Smis: 0 -> false, all other -> true 1636 // Smis: 0 -> false, all other -> true
1639 __ tst(tos_, tos_); 1637 __ tst(tos_, tos_);
1640 __ b(eq, &false_result); 1638 __ b(eq, &false_result);
1641 __ tst(tos_, Operand(kSmiTagMask)); 1639 __ tst(tos_, Operand(kSmiTagMask));
1642 // "tos_" is a register and contains a non-zero value. Hence we implicitly 1640 // "tos_" is a register and contains a non-zero value. Hence we implicitly
1643 // return true if the not equal condition is satisfied. 1641 // return true if the not equal condition is satisfied.
1644 __ Ret(eq); 1642 __ Ret(eq);
1645 1643
1646 // 'null' -> false 1644 // 'null' -> false
1647 __ LoadRoot(ip, Heap::kNullValueRootIndex); 1645 __ LoadRoot(ip, Heap::kNullValueRootIndex);
1648 __ cmp(tos_, ip); 1646 __ cmp(tos_, ip);
1649 __ b(eq, &false_result); 1647 __ b(eq, &false_result);
1650 1648
1651 // HeapNumber => false iff +0, -0, or NaN. 1649 // Get the map of the heap object.
1652 __ ldr(scratch, FieldMemOperand(tos_, HeapObject::kMapOffset)); 1650 __ ldr(map, FieldMemOperand(tos_, HeapObject::kMapOffset));
1653 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); 1651
1654 __ cmp(scratch, ip); 1652 // Undetectable -> false.
1655 __ b(&not_heap_number, ne); 1653 __ ldrb(ip, FieldMemOperand(map, Map::kBitFieldOffset));
1654 __ tst(ip, Operand(1 << Map::kIsUndetectable));
1655 __ b(&false_result, ne);
1656
1657 // JavaScript object -> true.
1658 __ CompareInstanceType(map, ip, FIRST_SPEC_OBJECT_TYPE);
1659 // "tos_" is a register and contains a non-zero value. Hence we implicitly
1660 // return true if the greater than condition is satisfied.
1661 __ Ret(ge);
1662
1663 // String value -> false iff empty.
1664 __ CompareInstanceType(map, ip, FIRST_NONSTRING_TYPE);
1665 __ b(&not_string, ge);
1666 __ ldr(tos_, FieldMemOperand(tos_, String::kLengthOffset));
1667 // Return string length as boolean value, i.e. return false iff length is 0.
1668 __ Ret();
1669
1670 __ bind(&not_string);
1671 // HeapNumber -> false iff +0, -0, or NaN.
1672 __ CompareRoot(map, Heap::kHeapNumberMapRootIndex);
1673 __ b(&true_result, ne);
1656 __ vldr(d1, FieldMemOperand(tos_, HeapNumber::kValueOffset)); 1674 __ vldr(d1, FieldMemOperand(tos_, HeapNumber::kValueOffset));
1657 __ VFPCompareAndSetFlags(d1, 0.0); 1675 __ VFPCompareAndSetFlags(d1, 0.0);
1658 // "tos_" is a register, and contains a non zero value by default. 1676 // "tos_" is a register, and contains a non zero value by default.
1659 // Hence we only need to overwrite "tos_" with zero to return false for 1677 // Hence we only need to overwrite "tos_" with zero to return false for
1660 // FP_ZERO or FP_NAN cases. Otherwise, by default it returns true. 1678 // FP_ZERO or FP_NAN cases. Otherwise, by default it returns true.
1661 __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, eq); // for FP_ZERO 1679 __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, eq); // for FP_ZERO
1662 __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, vs); // for FP_NAN 1680 __ mov(tos_, Operand(0, RelocInfo::NONE), LeaveCC, vs); // for FP_NAN
1663 __ Ret(); 1681 __ Ret();
1664 1682
1665 __ bind(&not_heap_number); 1683 // Return 1/0 for true/false in tos_.
1666 1684 __ bind(&true_result);
1667 // It can be an undetectable object. 1685 __ mov(tos_, Operand(1, RelocInfo::NONE));
1668 // Undetectable => false.
1669 __ ldr(ip, FieldMemOperand(tos_, HeapObject::kMapOffset));
1670 __ ldrb(scratch, FieldMemOperand(ip, Map::kBitFieldOffset));
1671 __ and_(scratch, scratch, Operand(1 << Map::kIsUndetectable));
1672 __ cmp(scratch, Operand(1 << Map::kIsUndetectable));
1673 __ b(&false_result, eq);
1674
1675 // JavaScript object => true.
1676 __ ldr(scratch, FieldMemOperand(tos_, HeapObject::kMapOffset));
1677 __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
1678 __ cmp(scratch, Operand(FIRST_SPEC_OBJECT_TYPE));
1679 // "tos_" is a register and contains a non-zero value.
1680 // Hence we implicitly return true if the greater than
1681 // condition is satisfied.
1682 __ Ret(gt);
1683
1684 // Check for string
1685 __ ldr(scratch, FieldMemOperand(tos_, HeapObject::kMapOffset));
1686 __ ldrb(scratch, FieldMemOperand(scratch, Map::kInstanceTypeOffset));
1687 __ cmp(scratch, Operand(FIRST_NONSTRING_TYPE));
1688 // "tos_" is a register and contains a non-zero value.
1689 // Hence we implicitly return true if the greater than
1690 // condition is satisfied.
1691 __ Ret(gt);
1692
1693 // String value => false iff empty, i.e., length is zero
1694 __ ldr(tos_, FieldMemOperand(tos_, String::kLengthOffset));
1695 // If length is zero, "tos_" contains zero ==> false.
1696 // If length is not zero, "tos_" contains a non-zero value ==> true.
1697 __ Ret(); 1686 __ Ret();
1698
1699 // Return 0 in "tos_" for false .
1700 __ bind(&false_result); 1687 __ bind(&false_result);
1701 __ mov(tos_, Operand(0, RelocInfo::NONE)); 1688 __ mov(tos_, Operand(0, RelocInfo::NONE));
1702 __ Ret(); 1689 __ Ret();
1703 } 1690 }
1704 1691
1705 1692
1706 const char* UnaryOpStub::GetName() { 1693 const char* UnaryOpStub::GetName() {
1707 if (name_ != NULL) return name_; 1694 if (name_ != NULL) return name_;
1708 const int kMaxNameLength = 100; 1695 const int kMaxNameLength = 100;
1709 name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray( 1696 name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
(...skipping 1833 matching lines...) Expand 10 before | Expand all | Expand 10 after
3543 // r3: argc 3530 // r3: argc
3544 // [sp+0]: argv 3531 // [sp+0]: argv
3545 3532
3546 Label invoke, exit; 3533 Label invoke, exit;
3547 3534
3548 // Called from C, so do not pop argc and args on exit (preserve sp) 3535 // Called from C, so do not pop argc and args on exit (preserve sp)
3549 // No need to save register-passed args 3536 // No need to save register-passed args
3550 // Save callee-saved registers (incl. cp and fp), sp, and lr 3537 // Save callee-saved registers (incl. cp and fp), sp, and lr
3551 __ stm(db_w, sp, kCalleeSaved | lr.bit()); 3538 __ stm(db_w, sp, kCalleeSaved | lr.bit());
3552 3539
3540 if (CpuFeatures::IsSupported(VFP3)) {
3541 CpuFeatures::Scope scope(VFP3);
3542 // Save callee-saved vfp registers.
3543 __ vstm(db_w, sp, kFirstCalleeSavedDoubleReg, kLastCalleeSavedDoubleReg);
3544 }
3545
3553 // Get address of argv, see stm above. 3546 // Get address of argv, see stm above.
3554 // r0: code entry 3547 // r0: code entry
3555 // r1: function 3548 // r1: function
3556 // r2: receiver 3549 // r2: receiver
3557 // r3: argc 3550 // r3: argc
3558 __ ldr(r4, MemOperand(sp, (kNumCalleeSaved + 1) * kPointerSize)); // argv 3551
3552 // Setup argv in r4.
3553 int offset_to_argv = (kNumCalleeSaved + 1) * kPointerSize;
3554 if (CpuFeatures::IsSupported(VFP3)) {
3555 offset_to_argv += kNumDoubleCalleeSaved * kDoubleSize;
3556 }
3557 __ ldr(r4, MemOperand(sp, offset_to_argv));
3559 3558
3560 // Push a frame with special values setup to mark it as an entry frame. 3559 // Push a frame with special values setup to mark it as an entry frame.
3561 // r0: code entry 3560 // r0: code entry
3562 // r1: function 3561 // r1: function
3563 // r2: receiver 3562 // r2: receiver
3564 // r3: argc 3563 // r3: argc
3565 // r4: argv 3564 // r4: argv
3566 Isolate* isolate = masm->isolate(); 3565 Isolate* isolate = masm->isolate();
3567 __ mov(r8, Operand(-1)); // Push a bad frame pointer to fail if it is used. 3566 __ mov(r8, Operand(-1)); // Push a bad frame pointer to fail if it is used.
3568 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; 3567 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY;
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
3673 3672
3674 // Reset the stack to the callee saved registers. 3673 // Reset the stack to the callee saved registers.
3675 __ add(sp, sp, Operand(-EntryFrameConstants::kCallerFPOffset)); 3674 __ add(sp, sp, Operand(-EntryFrameConstants::kCallerFPOffset));
3676 3675
3677 // Restore callee-saved registers and return. 3676 // Restore callee-saved registers and return.
3678 #ifdef DEBUG 3677 #ifdef DEBUG
3679 if (FLAG_debug_code) { 3678 if (FLAG_debug_code) {
3680 __ mov(lr, Operand(pc)); 3679 __ mov(lr, Operand(pc));
3681 } 3680 }
3682 #endif 3681 #endif
3682
3683 if (CpuFeatures::IsSupported(VFP3)) {
3684 CpuFeatures::Scope scope(VFP3);
3685 // Restore callee-saved vfp registers.
3686 __ vldm(ia_w, sp, kFirstCalleeSavedDoubleReg, kLastCalleeSavedDoubleReg);
3687 }
3688
3683 __ ldm(ia_w, sp, kCalleeSaved | pc.bit()); 3689 __ ldm(ia_w, sp, kCalleeSaved | pc.bit());
3684 } 3690 }
3685 3691
3686 3692
3687 // Uses registers r0 to r4. 3693 // Uses registers r0 to r4.
3688 // Expected input (depending on whether args are in registers or on the stack): 3694 // Expected input (depending on whether args are in registers or on the stack):
3689 // * object: r0 or at sp + 1 * kPointerSize. 3695 // * object: r0 or at sp + 1 * kPointerSize.
3690 // * function: r1 or at sp. 3696 // * function: r1 or at sp.
3691 // 3697 //
3692 // An inlined call site may have been generated before calling this stub. 3698 // An inlined call site may have been generated before calling this stub.
(...skipping 2902 matching lines...) Expand 10 before | Expand all | Expand 10 after
6595 __ mov(result, Operand(0)); 6601 __ mov(result, Operand(0));
6596 __ Ret(); 6602 __ Ret();
6597 } 6603 }
6598 6604
6599 6605
6600 #undef __ 6606 #undef __
6601 6607
6602 } } // namespace v8::internal 6608 } } // namespace v8::internal
6603 6609
6604 #endif // V8_TARGET_ARCH_ARM 6610 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.h ('k') | src/arm/frames-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698