| OLD | NEW | 
|     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  Loading... | 
|  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(¬_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(¬_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(¬_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(¬_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 4885 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  6595   __ mov(result, Operand(0)); |  6582   __ mov(result, Operand(0)); | 
|  6596   __ Ret(); |  6583   __ Ret(); | 
|  6597 } |  6584 } | 
|  6598  |  6585  | 
|  6599  |  6586  | 
|  6600 #undef __ |  6587 #undef __ | 
|  6601  |  6588  | 
|  6602 } }  // namespace v8::internal |  6589 } }  // namespace v8::internal | 
|  6603  |  6590  | 
|  6604 #endif  // V8_TARGET_ARCH_ARM |  6591 #endif  // V8_TARGET_ARCH_ARM | 
| OLD | NEW |