OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_PPC | 5 #if V8_TARGET_ARCH_PPC |
6 | 6 |
7 #include "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
701 } else { | 701 } else { |
702 StringHelper::GenerateCompareFlatOneByteStrings(masm, lhs, rhs, r5, r6, r7); | 702 StringHelper::GenerateCompareFlatOneByteStrings(masm, lhs, rhs, r5, r6, r7); |
703 } | 703 } |
704 // Never falls through to here. | 704 // Never falls through to here. |
705 | 705 |
706 __ bind(&slow); | 706 __ bind(&slow); |
707 | 707 |
708 __ Push(lhs, rhs); | 708 __ Push(lhs, rhs); |
709 // Figure out which native to call and setup the arguments. | 709 // Figure out which native to call and setup the arguments. |
710 if (cc == eq) { | 710 if (cc == eq) { |
711 __ TailCallRuntime(strict() ? Runtime::kStrictEquals : Runtime::kEquals, 2); | 711 __ TailCallRuntime(strict() ? Runtime::kStrictEquals : Runtime::kEquals); |
712 } else { | 712 } else { |
713 int ncr; // NaN compare result | 713 int ncr; // NaN compare result |
714 if (cc == lt || cc == le) { | 714 if (cc == lt || cc == le) { |
715 ncr = GREATER; | 715 ncr = GREATER; |
716 } else { | 716 } else { |
717 DCHECK(cc == gt || cc == ge); // remaining cases | 717 DCHECK(cc == gt || cc == ge); // remaining cases |
718 ncr = LESS; | 718 ncr = LESS; |
719 } | 719 } |
720 __ LoadSmiLiteral(r3, Smi::FromInt(ncr)); | 720 __ LoadSmiLiteral(r3, Smi::FromInt(ncr)); |
721 __ push(r3); | 721 __ push(r3); |
722 | 722 |
723 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) | 723 // Call the native; it returns -1 (less), 0 (equal), or 1 (greater) |
724 // tagged as a small integer. | 724 // tagged as a small integer. |
725 __ TailCallRuntime( | 725 __ TailCallRuntime(is_strong(strength()) ? Runtime::kCompare_Strong |
726 is_strong(strength()) ? Runtime::kCompare_Strong : Runtime::kCompare, | 726 : Runtime::kCompare); |
727 3); | |
728 } | 727 } |
729 | 728 |
730 __ bind(&miss); | 729 __ bind(&miss); |
731 GenerateMiss(masm); | 730 GenerateMiss(masm); |
732 } | 731 } |
733 | 732 |
734 | 733 |
735 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { | 734 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { |
736 // We don't allow a GC during a store buffer overflow so there is no need to | 735 // We don't allow a GC during a store buffer overflow so there is no need to |
737 // store the registers in any particular way, but we do have to store and | 736 // store the registers in any particular way, but we do have to store and |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
940 __ bne(&done); | 939 __ bne(&done); |
941 // double_exponent may not containe the exponent value if the input was a | 940 // double_exponent may not containe the exponent value if the input was a |
942 // smi. We set it with exponent value before bailing out. | 941 // smi. We set it with exponent value before bailing out. |
943 __ ConvertIntToDouble(exponent, double_exponent); | 942 __ ConvertIntToDouble(exponent, double_exponent); |
944 | 943 |
945 // Returning or bailing out. | 944 // Returning or bailing out. |
946 Counters* counters = isolate()->counters(); | 945 Counters* counters = isolate()->counters(); |
947 if (exponent_type() == ON_STACK) { | 946 if (exponent_type() == ON_STACK) { |
948 // The arguments are still on the stack. | 947 // The arguments are still on the stack. |
949 __ bind(&call_runtime); | 948 __ bind(&call_runtime); |
950 __ TailCallRuntime(Runtime::kMathPowRT, 2); | 949 __ TailCallRuntime(Runtime::kMathPowRT); |
951 | 950 |
952 // The stub is called from non-optimized code, which expects the result | 951 // The stub is called from non-optimized code, which expects the result |
953 // as heap number in exponent. | 952 // as heap number in exponent. |
954 __ bind(&done); | 953 __ bind(&done); |
955 __ AllocateHeapNumber(heapnumber, scratch, scratch2, heapnumbermap, | 954 __ AllocateHeapNumber(heapnumber, scratch, scratch2, heapnumbermap, |
956 &call_runtime); | 955 &call_runtime); |
957 __ stfd(double_result, | 956 __ stfd(double_result, |
958 FieldMemOperand(heapnumber, HeapNumber::kValueOffset)); | 957 FieldMemOperand(heapnumber, HeapNumber::kValueOffset)); |
959 DCHECK(heapnumber.is(r3)); | 958 DCHECK(heapnumber.is(r3)); |
960 __ IncrementCounter(counters->math_pow(), 1, scratch, scratch2); | 959 __ IncrementCounter(counters->math_pow(), 1, scratch, scratch2); |
(...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1484 __ bind(&done); | 1483 __ bind(&done); |
1485 __ StoreRoot(result, Heap::kInstanceofCacheAnswerRootIndex); | 1484 __ StoreRoot(result, Heap::kInstanceofCacheAnswerRootIndex); |
1486 __ Ret(); | 1485 __ Ret(); |
1487 | 1486 |
1488 // Found Proxy or access check needed: Call the runtime | 1487 // Found Proxy or access check needed: Call the runtime |
1489 __ bind(&fast_runtime_fallback); | 1488 __ bind(&fast_runtime_fallback); |
1490 __ Push(object, function_prototype); | 1489 __ Push(object, function_prototype); |
1491 // Invalidate the instanceof cache. | 1490 // Invalidate the instanceof cache. |
1492 __ LoadSmiLiteral(scratch, Smi::FromInt(0)); | 1491 __ LoadSmiLiteral(scratch, Smi::FromInt(0)); |
1493 __ StoreRoot(scratch, Heap::kInstanceofCacheFunctionRootIndex); | 1492 __ StoreRoot(scratch, Heap::kInstanceofCacheFunctionRootIndex); |
1494 __ TailCallRuntime(Runtime::kHasInPrototypeChain, 2); | 1493 __ TailCallRuntime(Runtime::kHasInPrototypeChain); |
1495 | 1494 |
1496 // Slow-case: Call the %InstanceOf runtime function. | 1495 // Slow-case: Call the %InstanceOf runtime function. |
1497 __ bind(&slow_case); | 1496 __ bind(&slow_case); |
1498 __ Push(object, function); | 1497 __ Push(object, function); |
1499 __ TailCallRuntime(Runtime::kInstanceOf, 2); | 1498 __ TailCallRuntime(Runtime::kInstanceOf); |
1500 } | 1499 } |
1501 | 1500 |
1502 | 1501 |
1503 void FunctionPrototypeStub::Generate(MacroAssembler* masm) { | 1502 void FunctionPrototypeStub::Generate(MacroAssembler* masm) { |
1504 Label miss; | 1503 Label miss; |
1505 Register receiver = LoadDescriptor::ReceiverRegister(); | 1504 Register receiver = LoadDescriptor::ReceiverRegister(); |
1506 // Ensure that the vector and slot registers won't be clobbered before | 1505 // Ensure that the vector and slot registers won't be clobbered before |
1507 // calling the miss handler. | 1506 // calling the miss handler. |
1508 DCHECK(!AreAliased(r7, r8, LoadWithVectorDescriptor::VectorRegister(), | 1507 DCHECK(!AreAliased(r7, r8, LoadWithVectorDescriptor::VectorRegister(), |
1509 LoadWithVectorDescriptor::SlotRegister())); | 1508 LoadWithVectorDescriptor::SlotRegister())); |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1594 __ sub(r6, r3, r4); | 1593 __ sub(r6, r3, r4); |
1595 __ SmiToPtrArrayOffset(r6, r6); | 1594 __ SmiToPtrArrayOffset(r6, r6); |
1596 __ add(r6, r5, r6); | 1595 __ add(r6, r5, r6); |
1597 __ LoadP(r3, MemOperand(r6, kDisplacement)); | 1596 __ LoadP(r3, MemOperand(r6, kDisplacement)); |
1598 __ blr(); | 1597 __ blr(); |
1599 | 1598 |
1600 // Slow-case: Handle non-smi or out-of-bounds access to arguments | 1599 // Slow-case: Handle non-smi or out-of-bounds access to arguments |
1601 // by calling the runtime system. | 1600 // by calling the runtime system. |
1602 __ bind(&slow); | 1601 __ bind(&slow); |
1603 __ push(r4); | 1602 __ push(r4); |
1604 __ TailCallRuntime(Runtime::kArguments, 1); | 1603 __ TailCallRuntime(Runtime::kArguments); |
1605 } | 1604 } |
1606 | 1605 |
1607 | 1606 |
1608 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { | 1607 void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) { |
1609 // r4 : function | 1608 // r4 : function |
1610 // r5 : number of parameters (tagged) | 1609 // r5 : number of parameters (tagged) |
1611 // r6 : parameters pointer | 1610 // r6 : parameters pointer |
1612 | 1611 |
1613 DCHECK(r4.is(ArgumentsAccessNewDescriptor::function())); | 1612 DCHECK(r4.is(ArgumentsAccessNewDescriptor::function())); |
1614 DCHECK(r5.is(ArgumentsAccessNewDescriptor::parameter_count())); | 1613 DCHECK(r5.is(ArgumentsAccessNewDescriptor::parameter_count())); |
1615 DCHECK(r6.is(ArgumentsAccessNewDescriptor::parameter_pointer())); | 1614 DCHECK(r6.is(ArgumentsAccessNewDescriptor::parameter_pointer())); |
1616 | 1615 |
1617 // Check if the calling frame is an arguments adaptor frame. | 1616 // Check if the calling frame is an arguments adaptor frame. |
1618 Label runtime; | 1617 Label runtime; |
1619 __ LoadP(r7, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 1618 __ LoadP(r7, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
1620 __ LoadP(r3, MemOperand(r7, StandardFrameConstants::kContextOffset)); | 1619 __ LoadP(r3, MemOperand(r7, StandardFrameConstants::kContextOffset)); |
1621 __ CmpSmiLiteral(r3, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0); | 1620 __ CmpSmiLiteral(r3, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0); |
1622 __ bne(&runtime); | 1621 __ bne(&runtime); |
1623 | 1622 |
1624 // Patch the arguments.length and the parameters pointer in the current frame. | 1623 // Patch the arguments.length and the parameters pointer in the current frame. |
1625 __ LoadP(r5, MemOperand(r7, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 1624 __ LoadP(r5, MemOperand(r7, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
1626 __ SmiToPtrArrayOffset(r6, r5); | 1625 __ SmiToPtrArrayOffset(r6, r5); |
1627 __ add(r6, r6, r7); | 1626 __ add(r6, r6, r7); |
1628 __ addi(r6, r6, Operand(StandardFrameConstants::kCallerSPOffset)); | 1627 __ addi(r6, r6, Operand(StandardFrameConstants::kCallerSPOffset)); |
1629 | 1628 |
1630 __ bind(&runtime); | 1629 __ bind(&runtime); |
1631 __ Push(r4, r6, r5); | 1630 __ Push(r4, r6, r5); |
1632 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3); | 1631 __ TailCallRuntime(Runtime::kNewSloppyArguments); |
1633 } | 1632 } |
1634 | 1633 |
1635 | 1634 |
1636 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { | 1635 void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) { |
1637 // r4 : function | 1636 // r4 : function |
1638 // r5 : number of parameters (tagged) | 1637 // r5 : number of parameters (tagged) |
1639 // r6 : parameters pointer | 1638 // r6 : parameters pointer |
1640 // Registers used over whole function: | 1639 // Registers used over whole function: |
1641 // r8 : arguments count (tagged) | 1640 // r8 : arguments count (tagged) |
1642 // r9 : mapped parameter count (tagged) | 1641 // r9 : mapped parameter count (tagged) |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1864 __ StorePU(r7, MemOperand(r11, kPointerSize)); | 1863 __ StorePU(r7, MemOperand(r11, kPointerSize)); |
1865 __ bdnz(&arguments_loop); | 1864 __ bdnz(&arguments_loop); |
1866 | 1865 |
1867 // Return. | 1866 // Return. |
1868 __ Ret(); | 1867 __ Ret(); |
1869 | 1868 |
1870 // Do the runtime call to allocate the arguments object. | 1869 // Do the runtime call to allocate the arguments object. |
1871 // r8 = argument count (tagged) | 1870 // r8 = argument count (tagged) |
1872 __ bind(&runtime); | 1871 __ bind(&runtime); |
1873 __ Push(r4, r6, r8); | 1872 __ Push(r4, r6, r8); |
1874 __ TailCallRuntime(Runtime::kNewSloppyArguments, 3); | 1873 __ TailCallRuntime(Runtime::kNewSloppyArguments); |
1875 } | 1874 } |
1876 | 1875 |
1877 | 1876 |
1878 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { | 1877 void LoadIndexedInterceptorStub::Generate(MacroAssembler* masm) { |
1879 // Return address is in lr. | 1878 // Return address is in lr. |
1880 Label slow; | 1879 Label slow; |
1881 | 1880 |
1882 Register receiver = LoadDescriptor::ReceiverRegister(); | 1881 Register receiver = LoadDescriptor::ReceiverRegister(); |
1883 Register key = LoadDescriptor::NameRegister(); | 1882 Register key = LoadDescriptor::NameRegister(); |
1884 | 1883 |
1885 // Check that the key is an array index, that is Uint32. | 1884 // Check that the key is an array index, that is Uint32. |
1886 __ TestIfPositiveSmi(key, r0); | 1885 __ TestIfPositiveSmi(key, r0); |
1887 __ bne(&slow, cr0); | 1886 __ bne(&slow, cr0); |
1888 | 1887 |
1889 // Everything is fine, call runtime. | 1888 // Everything is fine, call runtime. |
1890 __ Push(receiver, key); // Receiver, key. | 1889 __ Push(receiver, key); // Receiver, key. |
1891 | 1890 |
1892 // Perform tail call to the entry. | 1891 // Perform tail call to the entry. |
1893 __ TailCallRuntime(Runtime::kLoadElementWithInterceptor, 2); | 1892 __ TailCallRuntime(Runtime::kLoadElementWithInterceptor); |
1894 | 1893 |
1895 __ bind(&slow); | 1894 __ bind(&slow); |
1896 PropertyAccessCompiler::TailCallBuiltin( | 1895 PropertyAccessCompiler::TailCallBuiltin( |
1897 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); | 1896 masm, PropertyAccessCompiler::MissBuiltin(Code::KEYED_LOAD_IC)); |
1898 } | 1897 } |
1899 | 1898 |
1900 | 1899 |
1901 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { | 1900 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { |
1902 // r4 : function | 1901 // r4 : function |
1903 // r5 : number of parameters (tagged) | 1902 // r5 : number of parameters (tagged) |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1975 // Pre-increment r7 with kPointerSize on each iteration. | 1974 // Pre-increment r7 with kPointerSize on each iteration. |
1976 __ StorePU(r8, MemOperand(r7, kPointerSize)); | 1975 __ StorePU(r8, MemOperand(r7, kPointerSize)); |
1977 __ bdnz(&loop); | 1976 __ bdnz(&loop); |
1978 | 1977 |
1979 // Return. | 1978 // Return. |
1980 __ Ret(); | 1979 __ Ret(); |
1981 | 1980 |
1982 // Do the runtime call to allocate the arguments object. | 1981 // Do the runtime call to allocate the arguments object. |
1983 __ bind(&runtime); | 1982 __ bind(&runtime); |
1984 __ Push(r4, r6, r5); | 1983 __ Push(r4, r6, r5); |
1985 __ TailCallRuntime(Runtime::kNewStrictArguments, 3); | 1984 __ TailCallRuntime(Runtime::kNewStrictArguments); |
1986 } | 1985 } |
1987 | 1986 |
1988 | 1987 |
1989 void RestParamAccessStub::GenerateNew(MacroAssembler* masm) { | 1988 void RestParamAccessStub::GenerateNew(MacroAssembler* masm) { |
1990 // Stack layout on entry. | 1989 // Stack layout on entry. |
1991 // sp[0] : language mode | 1990 // sp[0] : language mode |
1992 // sp[4] : index of rest parameter | 1991 // sp[4] : index of rest parameter |
1993 // sp[8] : number of parameters | 1992 // sp[8] : number of parameters |
1994 // sp[12] : receiver displacement | 1993 // sp[12] : receiver displacement |
1995 | 1994 |
1996 Label runtime; | 1995 Label runtime; |
1997 __ LoadP(r5, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 1996 __ LoadP(r5, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
1998 __ LoadP(r6, MemOperand(r5, StandardFrameConstants::kContextOffset)); | 1997 __ LoadP(r6, MemOperand(r5, StandardFrameConstants::kContextOffset)); |
1999 __ CmpSmiLiteral(r6, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0); | 1998 __ CmpSmiLiteral(r6, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR), r0); |
2000 __ bne(&runtime); | 1999 __ bne(&runtime); |
2001 | 2000 |
2002 // Patch the arguments.length and the parameters pointer. | 2001 // Patch the arguments.length and the parameters pointer. |
2003 __ LoadP(r4, MemOperand(r5, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 2002 __ LoadP(r4, MemOperand(r5, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
2004 __ StoreP(r4, MemOperand(sp, 2 * kPointerSize)); | 2003 __ StoreP(r4, MemOperand(sp, 2 * kPointerSize)); |
2005 __ SmiToPtrArrayOffset(r0, r4); | 2004 __ SmiToPtrArrayOffset(r0, r4); |
2006 __ add(r6, r5, r0); | 2005 __ add(r6, r5, r0); |
2007 __ addi(r6, r6, Operand(StandardFrameConstants::kCallerSPOffset)); | 2006 __ addi(r6, r6, Operand(StandardFrameConstants::kCallerSPOffset)); |
2008 __ StoreP(r6, MemOperand(sp, 3 * kPointerSize)); | 2007 __ StoreP(r6, MemOperand(sp, 3 * kPointerSize)); |
2009 | 2008 |
2010 __ bind(&runtime); | 2009 __ bind(&runtime); |
2011 __ TailCallRuntime(Runtime::kNewRestParam, 4); | 2010 __ TailCallRuntime(Runtime::kNewRestParam); |
2012 } | 2011 } |
2013 | 2012 |
2014 | 2013 |
2015 void RegExpExecStub::Generate(MacroAssembler* masm) { | 2014 void RegExpExecStub::Generate(MacroAssembler* masm) { |
2016 // Just jump directly to runtime if native RegExp is not selected at compile | 2015 // Just jump directly to runtime if native RegExp is not selected at compile |
2017 // time or if regexp entry in generated code is turned off runtime switch or | 2016 // time or if regexp entry in generated code is turned off runtime switch or |
2018 // at compilation. | 2017 // at compilation. |
2019 #ifdef V8_INTERPRETED_REGEXP | 2018 #ifdef V8_INTERPRETED_REGEXP |
2020 __ TailCallRuntime(Runtime::kRegExpExec, 4); | 2019 __ TailCallRuntime(Runtime::kRegExpExec); |
2021 #else // V8_INTERPRETED_REGEXP | 2020 #else // V8_INTERPRETED_REGEXP |
2022 | 2021 |
2023 // Stack frame on entry. | 2022 // Stack frame on entry. |
2024 // sp[0]: last_match_info (expected JSArray) | 2023 // sp[0]: last_match_info (expected JSArray) |
2025 // sp[4]: previous index | 2024 // sp[4]: previous index |
2026 // sp[8]: subject string | 2025 // sp[8]: subject string |
2027 // sp[12]: JSRegExp object | 2026 // sp[12]: JSRegExp object |
2028 | 2027 |
2029 const int kLastMatchInfoOffset = 0 * kPointerSize; | 2028 const int kLastMatchInfoOffset = 0 * kPointerSize; |
2030 const int kPreviousIndexOffset = 1 * kPointerSize; | 2029 const int kPreviousIndexOffset = 1 * kPointerSize; |
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2305 // haven't created the exception yet. Handle that in the runtime system. | 2304 // haven't created the exception yet. Handle that in the runtime system. |
2306 // TODO(592): Rerunning the RegExp to get the stack overflow exception. | 2305 // TODO(592): Rerunning the RegExp to get the stack overflow exception. |
2307 __ mov(r4, Operand(isolate()->factory()->the_hole_value())); | 2306 __ mov(r4, Operand(isolate()->factory()->the_hole_value())); |
2308 __ mov(r5, Operand(ExternalReference(Isolate::kPendingExceptionAddress, | 2307 __ mov(r5, Operand(ExternalReference(Isolate::kPendingExceptionAddress, |
2309 isolate()))); | 2308 isolate()))); |
2310 __ LoadP(r3, MemOperand(r5, 0)); | 2309 __ LoadP(r3, MemOperand(r5, 0)); |
2311 __ cmp(r3, r4); | 2310 __ cmp(r3, r4); |
2312 __ beq(&runtime); | 2311 __ beq(&runtime); |
2313 | 2312 |
2314 // For exception, throw the exception again. | 2313 // For exception, throw the exception again. |
2315 __ TailCallRuntime(Runtime::kRegExpExecReThrow, 4); | 2314 __ TailCallRuntime(Runtime::kRegExpExecReThrow); |
2316 | 2315 |
2317 __ bind(&failure); | 2316 __ bind(&failure); |
2318 // For failure and exception return null. | 2317 // For failure and exception return null. |
2319 __ mov(r3, Operand(isolate()->factory()->null_value())); | 2318 __ mov(r3, Operand(isolate()->factory()->null_value())); |
2320 __ addi(sp, sp, Operand(4 * kPointerSize)); | 2319 __ addi(sp, sp, Operand(4 * kPointerSize)); |
2321 __ Ret(); | 2320 __ Ret(); |
2322 | 2321 |
2323 // Process the result from the native regexp code. | 2322 // Process the result from the native regexp code. |
2324 __ bind(&success); | 2323 __ bind(&success); |
2325 __ LoadP(r4, | 2324 __ LoadP(r4, |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2394 __ StorePU(r6, MemOperand(r3, kPointerSize)); | 2393 __ StorePU(r6, MemOperand(r3, kPointerSize)); |
2395 __ bdnz(&next_capture); | 2394 __ bdnz(&next_capture); |
2396 | 2395 |
2397 // Return last match info. | 2396 // Return last match info. |
2398 __ LoadP(r3, MemOperand(sp, kLastMatchInfoOffset)); | 2397 __ LoadP(r3, MemOperand(sp, kLastMatchInfoOffset)); |
2399 __ addi(sp, sp, Operand(4 * kPointerSize)); | 2398 __ addi(sp, sp, Operand(4 * kPointerSize)); |
2400 __ Ret(); | 2399 __ Ret(); |
2401 | 2400 |
2402 // Do the runtime call to execute the regexp. | 2401 // Do the runtime call to execute the regexp. |
2403 __ bind(&runtime); | 2402 __ bind(&runtime); |
2404 __ TailCallRuntime(Runtime::kRegExpExec, 4); | 2403 __ TailCallRuntime(Runtime::kRegExpExec); |
2405 | 2404 |
2406 // Deferred code for string handling. | 2405 // Deferred code for string handling. |
2407 // (6) Not a long external string? If yes, go to (8). | 2406 // (6) Not a long external string? If yes, go to (8). |
2408 __ bind(¬_seq_nor_cons); | 2407 __ bind(¬_seq_nor_cons); |
2409 // Compare flags are still set. | 2408 // Compare flags are still set. |
2410 __ bgt(¬_long_external); // Go to (8). | 2409 __ bgt(¬_long_external); // Go to (8). |
2411 | 2410 |
2412 // (7) External string. Make it, offset-wise, look like a sequential string. | 2411 // (7) External string. Make it, offset-wise, look like a sequential string. |
2413 __ bind(&external_string); | 2412 __ bind(&external_string); |
2414 __ LoadP(r3, FieldMemOperand(subject, HeapObject::kMapOffset)); | 2413 __ LoadP(r3, FieldMemOperand(subject, HeapObject::kMapOffset)); |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2762 } | 2761 } |
2763 | 2762 |
2764 | 2763 |
2765 void CallICStub::GenerateMiss(MacroAssembler* masm) { | 2764 void CallICStub::GenerateMiss(MacroAssembler* masm) { |
2766 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 2765 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
2767 | 2766 |
2768 // Push the function and feedback info. | 2767 // Push the function and feedback info. |
2769 __ Push(r4, r5, r6); | 2768 __ Push(r4, r5, r6); |
2770 | 2769 |
2771 // Call the entry. | 2770 // Call the entry. |
2772 __ CallRuntime(Runtime::kCallIC_Miss, 3); | 2771 __ CallRuntime(Runtime::kCallIC_Miss); |
2773 | 2772 |
2774 // Move result to r4 and exit the internal frame. | 2773 // Move result to r4 and exit the internal frame. |
2775 __ mr(r4, r3); | 2774 __ mr(r4, r3); |
2776 } | 2775 } |
2777 | 2776 |
2778 | 2777 |
2779 // StringCharCodeAtGenerator | 2778 // StringCharCodeAtGenerator |
2780 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { | 2779 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { |
2781 // If the receiver is a smi trigger the non-string case. | 2780 // If the receiver is a smi trigger the non-string case. |
2782 if (check_mode_ == RECEIVER_IS_UNKNOWN) { | 2781 if (check_mode_ == RECEIVER_IS_UNKNOWN) { |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2821 DONT_DO_SMI_CHECK); | 2820 DONT_DO_SMI_CHECK); |
2822 call_helper.BeforeCall(masm); | 2821 call_helper.BeforeCall(masm); |
2823 if (embed_mode == PART_OF_IC_HANDLER) { | 2822 if (embed_mode == PART_OF_IC_HANDLER) { |
2824 __ Push(LoadWithVectorDescriptor::VectorRegister(), | 2823 __ Push(LoadWithVectorDescriptor::VectorRegister(), |
2825 LoadWithVectorDescriptor::SlotRegister(), object_, index_); | 2824 LoadWithVectorDescriptor::SlotRegister(), object_, index_); |
2826 } else { | 2825 } else { |
2827 // index_ is consumed by runtime conversion function. | 2826 // index_ is consumed by runtime conversion function. |
2828 __ Push(object_, index_); | 2827 __ Push(object_, index_); |
2829 } | 2828 } |
2830 if (index_flags_ == STRING_INDEX_IS_NUMBER) { | 2829 if (index_flags_ == STRING_INDEX_IS_NUMBER) { |
2831 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero, 1); | 2830 __ CallRuntime(Runtime::kNumberToIntegerMapMinusZero); |
2832 } else { | 2831 } else { |
2833 DCHECK(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); | 2832 DCHECK(index_flags_ == STRING_INDEX_IS_ARRAY_INDEX); |
2834 // NumberToSmi discards numbers that are not exact integers. | 2833 // NumberToSmi discards numbers that are not exact integers. |
2835 __ CallRuntime(Runtime::kNumberToSmi, 1); | 2834 __ CallRuntime(Runtime::kNumberToSmi); |
2836 } | 2835 } |
2837 // Save the conversion result before the pop instructions below | 2836 // Save the conversion result before the pop instructions below |
2838 // have a chance to overwrite it. | 2837 // have a chance to overwrite it. |
2839 __ Move(index_, r3); | 2838 __ Move(index_, r3); |
2840 if (embed_mode == PART_OF_IC_HANDLER) { | 2839 if (embed_mode == PART_OF_IC_HANDLER) { |
2841 __ Pop(LoadWithVectorDescriptor::VectorRegister(), | 2840 __ Pop(LoadWithVectorDescriptor::VectorRegister(), |
2842 LoadWithVectorDescriptor::SlotRegister(), object_); | 2841 LoadWithVectorDescriptor::SlotRegister(), object_); |
2843 } else { | 2842 } else { |
2844 __ pop(object_); | 2843 __ pop(object_); |
2845 } | 2844 } |
2846 // Reload the instance type. | 2845 // Reload the instance type. |
2847 __ LoadP(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); | 2846 __ LoadP(result_, FieldMemOperand(object_, HeapObject::kMapOffset)); |
2848 __ lbz(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); | 2847 __ lbz(result_, FieldMemOperand(result_, Map::kInstanceTypeOffset)); |
2849 call_helper.AfterCall(masm); | 2848 call_helper.AfterCall(masm); |
2850 // If index is still not a smi, it must be out of range. | 2849 // If index is still not a smi, it must be out of range. |
2851 __ JumpIfNotSmi(index_, index_out_of_range_); | 2850 __ JumpIfNotSmi(index_, index_out_of_range_); |
2852 // Otherwise, return to the fast path. | 2851 // Otherwise, return to the fast path. |
2853 __ b(&got_smi_index_); | 2852 __ b(&got_smi_index_); |
2854 | 2853 |
2855 // Call runtime. We get here when the receiver is a string and the | 2854 // Call runtime. We get here when the receiver is a string and the |
2856 // index is a number, but the code of getting the actual character | 2855 // index is a number, but the code of getting the actual character |
2857 // is too complex (e.g., when the string needs to be flattened). | 2856 // is too complex (e.g., when the string needs to be flattened). |
2858 __ bind(&call_runtime_); | 2857 __ bind(&call_runtime_); |
2859 call_helper.BeforeCall(masm); | 2858 call_helper.BeforeCall(masm); |
2860 __ SmiTag(index_); | 2859 __ SmiTag(index_); |
2861 __ Push(object_, index_); | 2860 __ Push(object_, index_); |
2862 __ CallRuntime(Runtime::kStringCharCodeAtRT, 2); | 2861 __ CallRuntime(Runtime::kStringCharCodeAtRT); |
2863 __ Move(result_, r3); | 2862 __ Move(result_, r3); |
2864 call_helper.AfterCall(masm); | 2863 call_helper.AfterCall(masm); |
2865 __ b(&exit_); | 2864 __ b(&exit_); |
2866 | 2865 |
2867 __ Abort(kUnexpectedFallthroughFromCharCodeAtSlowCase); | 2866 __ Abort(kUnexpectedFallthroughFromCharCodeAtSlowCase); |
2868 } | 2867 } |
2869 | 2868 |
2870 | 2869 |
2871 // ------------------------------------------------------------------------- | 2870 // ------------------------------------------------------------------------- |
2872 // StringCharFromCodeGenerator | 2871 // StringCharFromCodeGenerator |
(...skipping 19 matching lines...) Expand all Loading... |
2892 } | 2891 } |
2893 | 2892 |
2894 | 2893 |
2895 void StringCharFromCodeGenerator::GenerateSlow( | 2894 void StringCharFromCodeGenerator::GenerateSlow( |
2896 MacroAssembler* masm, const RuntimeCallHelper& call_helper) { | 2895 MacroAssembler* masm, const RuntimeCallHelper& call_helper) { |
2897 __ Abort(kUnexpectedFallthroughToCharFromCodeSlowCase); | 2896 __ Abort(kUnexpectedFallthroughToCharFromCodeSlowCase); |
2898 | 2897 |
2899 __ bind(&slow_case_); | 2898 __ bind(&slow_case_); |
2900 call_helper.BeforeCall(masm); | 2899 call_helper.BeforeCall(masm); |
2901 __ push(code_); | 2900 __ push(code_); |
2902 __ CallRuntime(Runtime::kStringCharFromCode, 1); | 2901 __ CallRuntime(Runtime::kStringCharFromCode); |
2903 __ Move(result_, r3); | 2902 __ Move(result_, r3); |
2904 call_helper.AfterCall(masm); | 2903 call_helper.AfterCall(masm); |
2905 __ b(&exit_); | 2904 __ b(&exit_); |
2906 | 2905 |
2907 __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase); | 2906 __ Abort(kUnexpectedFallthroughFromCharFromCodeSlowCase); |
2908 } | 2907 } |
2909 | 2908 |
2910 | 2909 |
2911 enum CopyCharactersFlags { COPY_ONE_BYTE = 1, DEST_ALWAYS_ALIGNED = 2 }; | 2910 enum CopyCharactersFlags { COPY_ONE_BYTE = 1, DEST_ALWAYS_ALIGNED = 2 }; |
2912 | 2911 |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3146 String::TWO_BYTE_ENCODING); | 3145 String::TWO_BYTE_ENCODING); |
3147 | 3146 |
3148 __ bind(&return_r3); | 3147 __ bind(&return_r3); |
3149 Counters* counters = isolate()->counters(); | 3148 Counters* counters = isolate()->counters(); |
3150 __ IncrementCounter(counters->sub_string_native(), 1, r6, r7); | 3149 __ IncrementCounter(counters->sub_string_native(), 1, r6, r7); |
3151 __ Drop(3); | 3150 __ Drop(3); |
3152 __ Ret(); | 3151 __ Ret(); |
3153 | 3152 |
3154 // Just jump to runtime to create the sub string. | 3153 // Just jump to runtime to create the sub string. |
3155 __ bind(&runtime); | 3154 __ bind(&runtime); |
3156 __ TailCallRuntime(Runtime::kSubString, 3); | 3155 __ TailCallRuntime(Runtime::kSubString); |
3157 | 3156 |
3158 __ bind(&single_char); | 3157 __ bind(&single_char); |
3159 // r3: original string | 3158 // r3: original string |
3160 // r4: instance type | 3159 // r4: instance type |
3161 // r5: length | 3160 // r5: length |
3162 // r6: from index (untagged) | 3161 // r6: from index (untagged) |
3163 __ SmiTag(r6, r6); | 3162 __ SmiTag(r6, r6); |
3164 StringCharAtGenerator generator(r3, r6, r5, r3, &runtime, &runtime, &runtime, | 3163 StringCharAtGenerator generator(r3, r6, r5, r3, &runtime, &runtime, &runtime, |
3165 STRING_INDEX_IS_NUMBER, RECEIVER_IS_STRING); | 3164 STRING_INDEX_IS_NUMBER, RECEIVER_IS_STRING); |
3166 generator.GenerateFast(masm); | 3165 generator.GenerateFast(masm); |
(...skipping 19 matching lines...) Expand all Loading... |
3186 __ cmpli(r4, Operand(FIRST_NONSTRING_TYPE)); | 3185 __ cmpli(r4, Operand(FIRST_NONSTRING_TYPE)); |
3187 __ bge(¬_string); | 3186 __ bge(¬_string); |
3188 // Check if string has a cached array index. | 3187 // Check if string has a cached array index. |
3189 __ lwz(r5, FieldMemOperand(r3, String::kHashFieldOffset)); | 3188 __ lwz(r5, FieldMemOperand(r3, String::kHashFieldOffset)); |
3190 __ And(r0, r5, Operand(String::kContainsCachedArrayIndexMask), SetRC); | 3189 __ And(r0, r5, Operand(String::kContainsCachedArrayIndexMask), SetRC); |
3191 __ bne(&slow_string, cr0); | 3190 __ bne(&slow_string, cr0); |
3192 __ IndexFromHash(r5, r3); | 3191 __ IndexFromHash(r5, r3); |
3193 __ blr(); | 3192 __ blr(); |
3194 __ bind(&slow_string); | 3193 __ bind(&slow_string); |
3195 __ push(r3); // Push argument. | 3194 __ push(r3); // Push argument. |
3196 __ TailCallRuntime(Runtime::kStringToNumber, 1); | 3195 __ TailCallRuntime(Runtime::kStringToNumber); |
3197 __ bind(¬_string); | 3196 __ bind(¬_string); |
3198 | 3197 |
3199 Label not_oddball; | 3198 Label not_oddball; |
3200 __ cmpi(r4, Operand(ODDBALL_TYPE)); | 3199 __ cmpi(r4, Operand(ODDBALL_TYPE)); |
3201 __ bne(¬_oddball); | 3200 __ bne(¬_oddball); |
3202 __ LoadP(r3, FieldMemOperand(r3, Oddball::kToNumberOffset)); | 3201 __ LoadP(r3, FieldMemOperand(r3, Oddball::kToNumberOffset)); |
3203 __ blr(); | 3202 __ blr(); |
3204 __ bind(¬_oddball); | 3203 __ bind(¬_oddball); |
3205 | 3204 |
3206 __ push(r3); // Push argument. | 3205 __ push(r3); // Push argument. |
3207 __ TailCallRuntime(Runtime::kToNumber, 1); | 3206 __ TailCallRuntime(Runtime::kToNumber); |
3208 } | 3207 } |
3209 | 3208 |
3210 | 3209 |
3211 void ToLengthStub::Generate(MacroAssembler* masm) { | 3210 void ToLengthStub::Generate(MacroAssembler* masm) { |
3212 // The ToLength stub takes one argument in r3. | 3211 // The ToLength stub takes one argument in r3. |
3213 Label not_smi; | 3212 Label not_smi; |
3214 __ JumpIfNotSmi(r3, ¬_smi); | 3213 __ JumpIfNotSmi(r3, ¬_smi); |
3215 STATIC_ASSERT(kSmiTag == 0); | 3214 STATIC_ASSERT(kSmiTag == 0); |
3216 __ cmpi(r3, Operand::Zero()); | 3215 __ cmpi(r3, Operand::Zero()); |
3217 if (CpuFeatures::IsSupported(ISELECT)) { | 3216 if (CpuFeatures::IsSupported(ISELECT)) { |
3218 __ isel(lt, r3, r0, r3); | 3217 __ isel(lt, r3, r0, r3); |
3219 } else { | 3218 } else { |
3220 Label positive; | 3219 Label positive; |
3221 __ bgt(&positive); | 3220 __ bgt(&positive); |
3222 __ li(r3, Operand::Zero()); | 3221 __ li(r3, Operand::Zero()); |
3223 __ bind(&positive); | 3222 __ bind(&positive); |
3224 } | 3223 } |
3225 __ Ret(); | 3224 __ Ret(); |
3226 __ bind(¬_smi); | 3225 __ bind(¬_smi); |
3227 | 3226 |
3228 __ push(r3); // Push argument. | 3227 __ push(r3); // Push argument. |
3229 __ TailCallRuntime(Runtime::kToLength, 1); | 3228 __ TailCallRuntime(Runtime::kToLength); |
3230 } | 3229 } |
3231 | 3230 |
3232 | 3231 |
3233 void ToStringStub::Generate(MacroAssembler* masm) { | 3232 void ToStringStub::Generate(MacroAssembler* masm) { |
3234 // The ToString stub takes one argument in r3. | 3233 // The ToString stub takes one argument in r3. |
3235 Label is_number; | 3234 Label is_number; |
3236 __ JumpIfSmi(r3, &is_number); | 3235 __ JumpIfSmi(r3, &is_number); |
3237 | 3236 |
3238 __ CompareObjectType(r3, r4, r4, FIRST_NONSTRING_TYPE); | 3237 __ CompareObjectType(r3, r4, r4, FIRST_NONSTRING_TYPE); |
3239 // r3: receiver | 3238 // r3: receiver |
3240 // r4: receiver instance type | 3239 // r4: receiver instance type |
3241 __ Ret(lt); | 3240 __ Ret(lt); |
3242 | 3241 |
3243 Label not_heap_number; | 3242 Label not_heap_number; |
3244 __ cmpi(r4, Operand(HEAP_NUMBER_TYPE)); | 3243 __ cmpi(r4, Operand(HEAP_NUMBER_TYPE)); |
3245 __ bne(¬_heap_number); | 3244 __ bne(¬_heap_number); |
3246 __ bind(&is_number); | 3245 __ bind(&is_number); |
3247 NumberToStringStub stub(isolate()); | 3246 NumberToStringStub stub(isolate()); |
3248 __ TailCallStub(&stub); | 3247 __ TailCallStub(&stub); |
3249 __ bind(¬_heap_number); | 3248 __ bind(¬_heap_number); |
3250 | 3249 |
3251 Label not_oddball; | 3250 Label not_oddball; |
3252 __ cmpi(r4, Operand(ODDBALL_TYPE)); | 3251 __ cmpi(r4, Operand(ODDBALL_TYPE)); |
3253 __ bne(¬_oddball); | 3252 __ bne(¬_oddball); |
3254 __ LoadP(r3, FieldMemOperand(r3, Oddball::kToStringOffset)); | 3253 __ LoadP(r3, FieldMemOperand(r3, Oddball::kToStringOffset)); |
3255 __ Ret(); | 3254 __ Ret(); |
3256 __ bind(¬_oddball); | 3255 __ bind(¬_oddball); |
3257 | 3256 |
3258 __ push(r3); // Push argument. | 3257 __ push(r3); // Push argument. |
3259 __ TailCallRuntime(Runtime::kToString, 1); | 3258 __ TailCallRuntime(Runtime::kToString); |
3260 } | 3259 } |
3261 | 3260 |
3262 | 3261 |
3263 void StringHelper::GenerateFlatOneByteStringEquals(MacroAssembler* masm, | 3262 void StringHelper::GenerateFlatOneByteStringEquals(MacroAssembler* masm, |
3264 Register left, | 3263 Register left, |
3265 Register right, | 3264 Register right, |
3266 Register scratch1, | 3265 Register scratch1, |
3267 Register scratch2) { | 3266 Register scratch2) { |
3268 Register length = scratch1; | 3267 Register length = scratch1; |
3269 | 3268 |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3404 | 3403 |
3405 // Compare flat one-byte strings natively. | 3404 // Compare flat one-byte strings natively. |
3406 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, r5, | 3405 __ IncrementCounter(isolate()->counters()->string_compare_native(), 1, r5, |
3407 r6); | 3406 r6); |
3408 StringHelper::GenerateCompareFlatOneByteStrings(masm, r4, r3, r5, r6, r7); | 3407 StringHelper::GenerateCompareFlatOneByteStrings(masm, r4, r3, r5, r6, r7); |
3409 | 3408 |
3410 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 3409 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
3411 // tagged as a small integer. | 3410 // tagged as a small integer. |
3412 __ bind(&runtime); | 3411 __ bind(&runtime); |
3413 __ Push(r4, r3); | 3412 __ Push(r4, r3); |
3414 __ TailCallRuntime(Runtime::kStringCompare, 2); | 3413 __ TailCallRuntime(Runtime::kStringCompare); |
3415 } | 3414 } |
3416 | 3415 |
3417 | 3416 |
3418 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { | 3417 void BinaryOpICWithAllocationSiteStub::Generate(MacroAssembler* masm) { |
3419 // ----------- S t a t e ------------- | 3418 // ----------- S t a t e ------------- |
3420 // -- r4 : left | 3419 // -- r4 : left |
3421 // -- r3 : right | 3420 // -- r3 : right |
3422 // -- lr : return address | 3421 // -- lr : return address |
3423 // ----------------------------------- | 3422 // ----------------------------------- |
3424 | 3423 |
(...skipping 21 matching lines...) Expand all Loading... |
3446 } | 3445 } |
3447 | 3446 |
3448 | 3447 |
3449 void CompareICStub::GenerateBooleans(MacroAssembler* masm) { | 3448 void CompareICStub::GenerateBooleans(MacroAssembler* masm) { |
3450 DCHECK_EQ(CompareICState::BOOLEAN, state()); | 3449 DCHECK_EQ(CompareICState::BOOLEAN, state()); |
3451 Label miss; | 3450 Label miss; |
3452 | 3451 |
3453 __ CheckMap(r4, r5, Heap::kBooleanMapRootIndex, &miss, DO_SMI_CHECK); | 3452 __ CheckMap(r4, r5, Heap::kBooleanMapRootIndex, &miss, DO_SMI_CHECK); |
3454 __ CheckMap(r3, r6, Heap::kBooleanMapRootIndex, &miss, DO_SMI_CHECK); | 3453 __ CheckMap(r3, r6, Heap::kBooleanMapRootIndex, &miss, DO_SMI_CHECK); |
3455 if (op() != Token::EQ_STRICT && is_strong(strength())) { | 3454 if (op() != Token::EQ_STRICT && is_strong(strength())) { |
3456 __ TailCallRuntime(Runtime::kThrowStrongModeImplicitConversion, 0); | 3455 __ TailCallRuntime(Runtime::kThrowStrongModeImplicitConversion); |
3457 } else { | 3456 } else { |
3458 if (!Token::IsEqualityOp(op())) { | 3457 if (!Token::IsEqualityOp(op())) { |
3459 __ LoadP(r4, FieldMemOperand(r4, Oddball::kToNumberOffset)); | 3458 __ LoadP(r4, FieldMemOperand(r4, Oddball::kToNumberOffset)); |
3460 __ AssertSmi(r4); | 3459 __ AssertSmi(r4); |
3461 __ LoadP(r3, FieldMemOperand(r3, Oddball::kToNumberOffset)); | 3460 __ LoadP(r3, FieldMemOperand(r3, Oddball::kToNumberOffset)); |
3462 __ AssertSmi(r3); | 3461 __ AssertSmi(r3); |
3463 } | 3462 } |
3464 __ sub(r3, r4, r3); | 3463 __ sub(r3, r4, r3); |
3465 __ Ret(); | 3464 __ Ret(); |
3466 } | 3465 } |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3730 tmp2); | 3729 tmp2); |
3731 } else { | 3730 } else { |
3732 StringHelper::GenerateCompareFlatOneByteStrings(masm, left, right, tmp1, | 3731 StringHelper::GenerateCompareFlatOneByteStrings(masm, left, right, tmp1, |
3733 tmp2, tmp3); | 3732 tmp2, tmp3); |
3734 } | 3733 } |
3735 | 3734 |
3736 // Handle more complex cases in runtime. | 3735 // Handle more complex cases in runtime. |
3737 __ bind(&runtime); | 3736 __ bind(&runtime); |
3738 __ Push(left, right); | 3737 __ Push(left, right); |
3739 if (equality) { | 3738 if (equality) { |
3740 __ TailCallRuntime(Runtime::kStringEquals, 2); | 3739 __ TailCallRuntime(Runtime::kStringEquals); |
3741 } else { | 3740 } else { |
3742 __ TailCallRuntime(Runtime::kStringCompare, 2); | 3741 __ TailCallRuntime(Runtime::kStringCompare); |
3743 } | 3742 } |
3744 | 3743 |
3745 __ bind(&miss); | 3744 __ bind(&miss); |
3746 GenerateMiss(masm); | 3745 GenerateMiss(masm); |
3747 } | 3746 } |
3748 | 3747 |
3749 | 3748 |
3750 void CompareICStub::GenerateReceivers(MacroAssembler* masm) { | 3749 void CompareICStub::GenerateReceivers(MacroAssembler* masm) { |
3751 DCHECK_EQ(CompareICState::RECEIVER, state()); | 3750 DCHECK_EQ(CompareICState::RECEIVER, state()); |
3752 Label miss; | 3751 Label miss; |
(...skipping 25 matching lines...) Expand all Loading... |
3778 __ LoadP(r6, FieldMemOperand(r4, HeapObject::kMapOffset)); | 3777 __ LoadP(r6, FieldMemOperand(r4, HeapObject::kMapOffset)); |
3779 __ cmp(r5, r7); | 3778 __ cmp(r5, r7); |
3780 __ bne(&miss); | 3779 __ bne(&miss); |
3781 __ cmp(r6, r7); | 3780 __ cmp(r6, r7); |
3782 __ bne(&miss); | 3781 __ bne(&miss); |
3783 | 3782 |
3784 if (Token::IsEqualityOp(op())) { | 3783 if (Token::IsEqualityOp(op())) { |
3785 __ sub(r3, r3, r4); | 3784 __ sub(r3, r3, r4); |
3786 __ Ret(); | 3785 __ Ret(); |
3787 } else if (is_strong(strength())) { | 3786 } else if (is_strong(strength())) { |
3788 __ TailCallRuntime(Runtime::kThrowStrongModeImplicitConversion, 0); | 3787 __ TailCallRuntime(Runtime::kThrowStrongModeImplicitConversion); |
3789 } else { | 3788 } else { |
3790 if (op() == Token::LT || op() == Token::LTE) { | 3789 if (op() == Token::LT || op() == Token::LTE) { |
3791 __ LoadSmiLiteral(r5, Smi::FromInt(GREATER)); | 3790 __ LoadSmiLiteral(r5, Smi::FromInt(GREATER)); |
3792 } else { | 3791 } else { |
3793 __ LoadSmiLiteral(r5, Smi::FromInt(LESS)); | 3792 __ LoadSmiLiteral(r5, Smi::FromInt(LESS)); |
3794 } | 3793 } |
3795 __ Push(r4, r3, r5); | 3794 __ Push(r4, r3, r5); |
3796 __ TailCallRuntime(Runtime::kCompare, 3); | 3795 __ TailCallRuntime(Runtime::kCompare); |
3797 } | 3796 } |
3798 | 3797 |
3799 __ bind(&miss); | 3798 __ bind(&miss); |
3800 GenerateMiss(masm); | 3799 GenerateMiss(masm); |
3801 } | 3800 } |
3802 | 3801 |
3803 | 3802 |
3804 void CompareICStub::GenerateMiss(MacroAssembler* masm) { | 3803 void CompareICStub::GenerateMiss(MacroAssembler* masm) { |
3805 { | 3804 { |
3806 // Call the runtime system in a fresh internal frame. | 3805 // Call the runtime system in a fresh internal frame. |
3807 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); | 3806 FrameAndConstantPoolScope scope(masm, StackFrame::INTERNAL); |
3808 __ Push(r4, r3); | 3807 __ Push(r4, r3); |
3809 __ Push(r4, r3); | 3808 __ Push(r4, r3); |
3810 __ LoadSmiLiteral(r0, Smi::FromInt(op())); | 3809 __ LoadSmiLiteral(r0, Smi::FromInt(op())); |
3811 __ push(r0); | 3810 __ push(r0); |
3812 __ CallRuntime(Runtime::kCompareIC_Miss, 3); | 3811 __ CallRuntime(Runtime::kCompareIC_Miss); |
3813 // Compute the entry point of the rewritten stub. | 3812 // Compute the entry point of the rewritten stub. |
3814 __ addi(r5, r3, Operand(Code::kHeaderSize - kHeapObjectTag)); | 3813 __ addi(r5, r3, Operand(Code::kHeaderSize - kHeapObjectTag)); |
3815 // Restore registers. | 3814 // Restore registers. |
3816 __ Pop(r4, r3); | 3815 __ Pop(r4, r3); |
3817 } | 3816 } |
3818 | 3817 |
3819 __ JumpToJSEntry(r5); | 3818 __ JumpToJSEntry(r5); |
3820 } | 3819 } |
3821 | 3820 |
3822 | 3821 |
(...skipping 1352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5175 __ LoadP(result, ContextMemOperand(result)); | 5174 __ LoadP(result, ContextMemOperand(result)); |
5176 __ LoadP(result, FieldMemOperand(result, PropertyCell::kValueOffset)); | 5175 __ LoadP(result, FieldMemOperand(result, PropertyCell::kValueOffset)); |
5177 | 5176 |
5178 // If the result is not the_hole, return. Otherwise, handle in the runtime. | 5177 // If the result is not the_hole, return. Otherwise, handle in the runtime. |
5179 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); | 5178 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); |
5180 __ Ret(ne); | 5179 __ Ret(ne); |
5181 | 5180 |
5182 // Fallback to runtime. | 5181 // Fallback to runtime. |
5183 __ SmiTag(slot); | 5182 __ SmiTag(slot); |
5184 __ Push(slot); | 5183 __ Push(slot); |
5185 __ TailCallRuntime(Runtime::kLoadGlobalViaContext, 1); | 5184 __ TailCallRuntime(Runtime::kLoadGlobalViaContext); |
5186 } | 5185 } |
5187 | 5186 |
5188 | 5187 |
5189 void StoreGlobalViaContextStub::Generate(MacroAssembler* masm) { | 5188 void StoreGlobalViaContextStub::Generate(MacroAssembler* masm) { |
5190 Register value = r3; | 5189 Register value = r3; |
5191 Register slot = r5; | 5190 Register slot = r5; |
5192 | 5191 |
5193 Register cell = r4; | 5192 Register cell = r4; |
5194 Register cell_details = r6; | 5193 Register cell_details = r6; |
5195 Register cell_value = r7; | 5194 Register cell_value = r7; |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5303 __ LoadP(scratch, FieldMemOperand(value, HeapObject::kMapOffset)); | 5302 __ LoadP(scratch, FieldMemOperand(value, HeapObject::kMapOffset)); |
5304 __ cmp(cell_value_map, scratch); | 5303 __ cmp(cell_value_map, scratch); |
5305 __ beq(&fast_heapobject_case); | 5304 __ beq(&fast_heapobject_case); |
5306 | 5305 |
5307 // Fallback to runtime. | 5306 // Fallback to runtime. |
5308 __ bind(&slow_case); | 5307 __ bind(&slow_case); |
5309 __ SmiTag(slot); | 5308 __ SmiTag(slot); |
5310 __ Push(slot, value); | 5309 __ Push(slot, value); |
5311 __ TailCallRuntime(is_strict(language_mode()) | 5310 __ TailCallRuntime(is_strict(language_mode()) |
5312 ? Runtime::kStoreGlobalViaContext_Strict | 5311 ? Runtime::kStoreGlobalViaContext_Strict |
5313 : Runtime::kStoreGlobalViaContext_Sloppy, | 5312 : Runtime::kStoreGlobalViaContext_Sloppy); |
5314 2); | |
5315 } | 5313 } |
5316 | 5314 |
5317 | 5315 |
5318 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { | 5316 static int AddressOffset(ExternalReference ref0, ExternalReference ref1) { |
5319 return ref0.address() - ref1.address(); | 5317 return ref0.address() - ref1.address(); |
5320 } | 5318 } |
5321 | 5319 |
5322 | 5320 |
5323 // Calls an API function. Allocates HandleScope, extracts returned value | 5321 // Calls an API function. Allocates HandleScope, extracts returned value |
5324 // from handle and propagates exceptions. Restores context. stack_space | 5322 // from handle and propagates exceptions. Restores context. stack_space |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5440 __ LoadRoot(r14, Heap::kTheHoleValueRootIndex); | 5438 __ LoadRoot(r14, Heap::kTheHoleValueRootIndex); |
5441 __ mov(r15, Operand(ExternalReference::scheduled_exception_address(isolate))); | 5439 __ mov(r15, Operand(ExternalReference::scheduled_exception_address(isolate))); |
5442 __ LoadP(r15, MemOperand(r15)); | 5440 __ LoadP(r15, MemOperand(r15)); |
5443 __ cmp(r14, r15); | 5441 __ cmp(r14, r15); |
5444 __ bne(&promote_scheduled_exception); | 5442 __ bne(&promote_scheduled_exception); |
5445 | 5443 |
5446 __ blr(); | 5444 __ blr(); |
5447 | 5445 |
5448 // Re-throw by promoting a scheduled exception. | 5446 // Re-throw by promoting a scheduled exception. |
5449 __ bind(&promote_scheduled_exception); | 5447 __ bind(&promote_scheduled_exception); |
5450 __ TailCallRuntime(Runtime::kPromoteScheduledException, 0); | 5448 __ TailCallRuntime(Runtime::kPromoteScheduledException); |
5451 | 5449 |
5452 // HandleScope limit has changed. Delete allocated extensions. | 5450 // HandleScope limit has changed. Delete allocated extensions. |
5453 __ bind(&delete_allocated_handles); | 5451 __ bind(&delete_allocated_handles); |
5454 __ StoreP(r15, MemOperand(r17, kLimitOffset)); | 5452 __ StoreP(r15, MemOperand(r17, kLimitOffset)); |
5455 __ mr(r14, r3); | 5453 __ mr(r14, r3); |
5456 __ PrepareCallCFunction(1, r15); | 5454 __ PrepareCallCFunction(1, r15); |
5457 __ mov(r3, Operand(ExternalReference::isolate_address(isolate))); | 5455 __ mov(r3, Operand(ExternalReference::isolate_address(isolate))); |
5458 __ CallCFunction(ExternalReference::delete_handle_scope_extensions(isolate), | 5456 __ CallCFunction(ExternalReference::delete_handle_scope_extensions(isolate), |
5459 1); | 5457 1); |
5460 __ mr(r3, r14); | 5458 __ mr(r3, r14); |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5672 kStackUnwindSpace, NULL, | 5670 kStackUnwindSpace, NULL, |
5673 MemOperand(fp, 6 * kPointerSize), NULL); | 5671 MemOperand(fp, 6 * kPointerSize), NULL); |
5674 } | 5672 } |
5675 | 5673 |
5676 | 5674 |
5677 #undef __ | 5675 #undef __ |
5678 } // namespace internal | 5676 } // namespace internal |
5679 } // namespace v8 | 5677 } // namespace v8 |
5680 | 5678 |
5681 #endif // V8_TARGET_ARCH_PPC | 5679 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |