| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_MIPS | 5 #if V8_TARGET_ARCH_MIPS |
| 6 | 6 |
| 7 #include "src/codegen.h" | 7 #include "src/codegen.h" |
| 8 #include "src/debug/debug.h" | 8 #include "src/debug/debug.h" |
| 9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
| 10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 300 __ CallRuntime(Runtime::kNewObject, 2); | 300 __ CallRuntime(Runtime::kNewObject, 2); |
| 301 __ Pop(a0); | 301 __ Pop(a0); |
| 302 } | 302 } |
| 303 __ Ret(USE_DELAY_SLOT); | 303 __ Ret(USE_DELAY_SLOT); |
| 304 __ sw(a0, FieldMemOperand(v0, JSValue::kValueOffset)); | 304 __ sw(a0, FieldMemOperand(v0, JSValue::kValueOffset)); |
| 305 } | 305 } |
| 306 | 306 |
| 307 | 307 |
| 308 static void CallRuntimePassFunction( | 308 static void CallRuntimePassFunction( |
| 309 MacroAssembler* masm, Runtime::FunctionId function_id) { | 309 MacroAssembler* masm, Runtime::FunctionId function_id) { |
| 310 // ----------- S t a t e ------------- |
| 311 // -- a1 : target function (preserved for callee) |
| 312 // -- a3 : new target (preserved for callee) |
| 313 // ----------------------------------- |
| 314 |
| 310 FrameScope scope(masm, StackFrame::INTERNAL); | 315 FrameScope scope(masm, StackFrame::INTERNAL); |
| 311 // Push a copy of the function onto the stack. | 316 // Push a copy of the target function and the new target. |
| 312 // Push call kind information and function as parameter to the runtime call. | 317 // Push function as parameter to the runtime call. |
| 313 __ Push(a1, a1); | 318 __ Push(a1, a3, a1); |
| 314 | 319 |
| 315 __ CallRuntime(function_id, 1); | 320 __ CallRuntime(function_id, 1); |
| 316 // Restore call kind information and receiver. | 321 // Restore target function and new target. |
| 317 __ Pop(a1); | 322 __ Pop(a1, a3); |
| 318 } | 323 } |
| 319 | 324 |
| 320 | 325 |
| 321 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { | 326 static void GenerateTailCallToSharedCode(MacroAssembler* masm) { |
| 322 __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); | 327 __ lw(a2, FieldMemOperand(a1, JSFunction::kSharedFunctionInfoOffset)); |
| 323 __ lw(a2, FieldMemOperand(a2, SharedFunctionInfo::kCodeOffset)); | 328 __ lw(a2, FieldMemOperand(a2, SharedFunctionInfo::kCodeOffset)); |
| 324 __ Addu(at, a2, Operand(Code::kHeaderSize - kHeapObjectTag)); | 329 __ Addu(at, a2, Operand(Code::kHeaderSize - kHeapObjectTag)); |
| 325 __ Jump(at); | 330 __ Jump(at); |
| 326 } | 331 } |
| 327 | 332 |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 540 __ PushRoot(Heap::kTheHoleValueRootIndex); | 545 __ PushRoot(Heap::kTheHoleValueRootIndex); |
| 541 } | 546 } |
| 542 | 547 |
| 543 // Set up pointer to last argument. | 548 // Set up pointer to last argument. |
| 544 __ Addu(a2, fp, Operand(StandardFrameConstants::kCallerSPOffset)); | 549 __ Addu(a2, fp, Operand(StandardFrameConstants::kCallerSPOffset)); |
| 545 | 550 |
| 546 // Copy arguments and receiver to the expression stack. | 551 // Copy arguments and receiver to the expression stack. |
| 547 // a0: number of arguments | 552 // a0: number of arguments |
| 548 // a1: constructor function | 553 // a1: constructor function |
| 549 // a2: address of last argument (caller sp) | 554 // a2: address of last argument (caller sp) |
| 550 // a3: number of arguments (smi-tagged) | 555 // a3: new target |
| 556 // t4: number of arguments (smi-tagged) |
| 551 // sp[0]: receiver | 557 // sp[0]: receiver |
| 552 // sp[1]: receiver | 558 // sp[1]: receiver |
| 553 // sp[2]: new.target | 559 // sp[2]: new.target |
| 554 // sp[3]: number of arguments (smi-tagged) | 560 // sp[3]: number of arguments (smi-tagged) |
| 555 Label loop, entry; | 561 Label loop, entry; |
| 556 __ SmiTag(a3, a0); | 562 __ SmiTag(t4, a0); |
| 557 __ jmp(&entry); | 563 __ jmp(&entry); |
| 558 __ bind(&loop); | 564 __ bind(&loop); |
| 559 __ sll(t0, a3, kPointerSizeLog2 - kSmiTagSize); | 565 __ sll(t0, t4, kPointerSizeLog2 - kSmiTagSize); |
| 560 __ Addu(t0, a2, Operand(t0)); | 566 __ Addu(t0, a2, Operand(t0)); |
| 561 __ lw(t1, MemOperand(t0)); | 567 __ lw(t1, MemOperand(t0)); |
| 562 __ push(t1); | 568 __ push(t1); |
| 563 __ bind(&entry); | 569 __ bind(&entry); |
| 564 __ Addu(a3, a3, Operand(-2)); | 570 __ Addu(t4, t4, Operand(-2)); |
| 565 __ Branch(&loop, greater_equal, a3, Operand(zero_reg)); | 571 __ Branch(&loop, greater_equal, t4, Operand(zero_reg)); |
| 566 | 572 |
| 567 // Call the function. | 573 // Call the function. |
| 568 // a0: number of arguments | 574 // a0: number of arguments |
| 569 // a1: constructor function | 575 // a1: constructor function |
| 576 // a3: new target |
| 570 if (is_api_function) { | 577 if (is_api_function) { |
| 571 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); | 578 __ lw(cp, FieldMemOperand(a1, JSFunction::kContextOffset)); |
| 572 Handle<Code> code = | 579 Handle<Code> code = |
| 573 masm->isolate()->builtins()->HandleApiCallConstruct(); | 580 masm->isolate()->builtins()->HandleApiCallConstruct(); |
| 574 __ Call(code, RelocInfo::CODE_TARGET); | 581 __ Call(code, RelocInfo::CODE_TARGET); |
| 575 } else { | 582 } else { |
| 576 ParameterCount actual(a0); | 583 ParameterCount actual(a0); |
| 577 __ InvokeFunction(a1, actual, CALL_FUNCTION, NullCallWrapper()); | 584 __ InvokeFunction(a1, a3, actual, CALL_FUNCTION, NullCallWrapper()); |
| 578 } | 585 } |
| 579 | 586 |
| 580 // Store offset of return address for deoptimizer. | 587 // Store offset of return address for deoptimizer. |
| 581 if (create_implicit_receiver && !is_api_function) { | 588 if (create_implicit_receiver && !is_api_function) { |
| 582 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); | 589 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); |
| 583 } | 590 } |
| 584 | 591 |
| 585 // Restore context from the frame. | 592 // Restore context from the frame. |
| 586 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 593 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
| 587 | 594 |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 990 // crawls in MakeCodeYoung. This seems a bit fragile. | 997 // crawls in MakeCodeYoung. This seems a bit fragile. |
| 991 | 998 |
| 992 // Set a0 to point to the head of the PlatformCodeAge sequence. | 999 // Set a0 to point to the head of the PlatformCodeAge sequence. |
| 993 __ Subu(a0, a0, | 1000 __ Subu(a0, a0, |
| 994 Operand(kNoCodeAgeSequenceLength - Assembler::kInstrSize)); | 1001 Operand(kNoCodeAgeSequenceLength - Assembler::kInstrSize)); |
| 995 | 1002 |
| 996 // The following registers must be saved and restored when calling through to | 1003 // The following registers must be saved and restored when calling through to |
| 997 // the runtime: | 1004 // the runtime: |
| 998 // a0 - contains return address (beginning of patch sequence) | 1005 // a0 - contains return address (beginning of patch sequence) |
| 999 // a1 - isolate | 1006 // a1 - isolate |
| 1007 // a3 - new target |
| 1000 RegList saved_regs = | 1008 RegList saved_regs = |
| 1001 (a0.bit() | a1.bit() | ra.bit() | fp.bit()) & ~sp.bit(); | 1009 (a0.bit() | a1.bit() | a3.bit() | ra.bit() | fp.bit()) & ~sp.bit(); |
| 1002 FrameScope scope(masm, StackFrame::MANUAL); | 1010 FrameScope scope(masm, StackFrame::MANUAL); |
| 1003 __ MultiPush(saved_regs); | 1011 __ MultiPush(saved_regs); |
| 1004 __ PrepareCallCFunction(2, 0, a2); | 1012 __ PrepareCallCFunction(2, 0, a2); |
| 1005 __ li(a1, Operand(ExternalReference::isolate_address(masm->isolate()))); | 1013 __ li(a1, Operand(ExternalReference::isolate_address(masm->isolate()))); |
| 1006 __ CallCFunction( | 1014 __ CallCFunction( |
| 1007 ExternalReference::get_make_code_young_function(masm->isolate()), 2); | 1015 ExternalReference::get_make_code_young_function(masm->isolate()), 2); |
| 1008 __ MultiPop(saved_regs); | 1016 __ MultiPop(saved_regs); |
| 1009 __ Jump(a0); | 1017 __ Jump(a0); |
| 1010 } | 1018 } |
| 1011 | 1019 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1029 // pointers. | 1037 // pointers. |
| 1030 | 1038 |
| 1031 // Set a0 to point to the head of the PlatformCodeAge sequence. | 1039 // Set a0 to point to the head of the PlatformCodeAge sequence. |
| 1032 __ Subu(a0, a0, | 1040 __ Subu(a0, a0, |
| 1033 Operand(kNoCodeAgeSequenceLength - Assembler::kInstrSize)); | 1041 Operand(kNoCodeAgeSequenceLength - Assembler::kInstrSize)); |
| 1034 | 1042 |
| 1035 // The following registers must be saved and restored when calling through to | 1043 // The following registers must be saved and restored when calling through to |
| 1036 // the runtime: | 1044 // the runtime: |
| 1037 // a0 - contains return address (beginning of patch sequence) | 1045 // a0 - contains return address (beginning of patch sequence) |
| 1038 // a1 - isolate | 1046 // a1 - isolate |
| 1047 // a3 - new target |
| 1039 RegList saved_regs = | 1048 RegList saved_regs = |
| 1040 (a0.bit() | a1.bit() | ra.bit() | fp.bit()) & ~sp.bit(); | 1049 (a0.bit() | a1.bit() | a3.bit() | ra.bit() | fp.bit()) & ~sp.bit(); |
| 1041 FrameScope scope(masm, StackFrame::MANUAL); | 1050 FrameScope scope(masm, StackFrame::MANUAL); |
| 1042 __ MultiPush(saved_regs); | 1051 __ MultiPush(saved_regs); |
| 1043 __ PrepareCallCFunction(2, 0, a2); | 1052 __ PrepareCallCFunction(2, 0, a2); |
| 1044 __ li(a1, Operand(ExternalReference::isolate_address(masm->isolate()))); | 1053 __ li(a1, Operand(ExternalReference::isolate_address(masm->isolate()))); |
| 1045 __ CallCFunction( | 1054 __ CallCFunction( |
| 1046 ExternalReference::get_mark_code_as_executed_function(masm->isolate()), | 1055 ExternalReference::get_mark_code_as_executed_function(masm->isolate()), |
| 1047 2); | 1056 2); |
| 1048 __ MultiPop(saved_regs); | 1057 __ MultiPop(saved_regs); |
| 1049 | 1058 |
| 1050 // Perform prologue operations usually performed by the young code stub. | 1059 // Perform prologue operations usually performed by the young code stub. |
| (...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1562 // ----------- S t a t e ------------- | 1571 // ----------- S t a t e ------------- |
| 1563 // -- a0 : the number of arguments (not including the receiver) | 1572 // -- a0 : the number of arguments (not including the receiver) |
| 1564 // -- a1 : the function to call (checked to be a JSFunction) | 1573 // -- a1 : the function to call (checked to be a JSFunction) |
| 1565 // -- a2 : the shared function info. | 1574 // -- a2 : the shared function info. |
| 1566 // -- cp : the function context. | 1575 // -- cp : the function context. |
| 1567 // ----------------------------------- | 1576 // ----------------------------------- |
| 1568 | 1577 |
| 1569 __ lw(a2, | 1578 __ lw(a2, |
| 1570 FieldMemOperand(a2, SharedFunctionInfo::kFormalParameterCountOffset)); | 1579 FieldMemOperand(a2, SharedFunctionInfo::kFormalParameterCountOffset)); |
| 1571 __ sra(a2, a2, kSmiTagSize); // Un-tag. | 1580 __ sra(a2, a2, kSmiTagSize); // Un-tag. |
| 1572 __ lw(a3, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); | 1581 __ lw(t0, FieldMemOperand(a1, JSFunction::kCodeEntryOffset)); |
| 1573 ParameterCount actual(a0); | 1582 ParameterCount actual(a0); |
| 1574 ParameterCount expected(a2); | 1583 ParameterCount expected(a2); |
| 1575 __ InvokeCode(a3, expected, actual, JUMP_FUNCTION, NullCallWrapper()); | 1584 __ InvokeCode(t0, no_reg, expected, actual, JUMP_FUNCTION, NullCallWrapper()); |
| 1576 | 1585 |
| 1577 // The function is a "classConstructor", need to raise an exception. | 1586 // The function is a "classConstructor", need to raise an exception. |
| 1578 __ bind(&class_constructor); | 1587 __ bind(&class_constructor); |
| 1579 { | 1588 { |
| 1580 FrameScope frame(masm, StackFrame::INTERNAL); | 1589 FrameScope frame(masm, StackFrame::INTERNAL); |
| 1581 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0); | 1590 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 0); |
| 1582 } | 1591 } |
| 1583 } | 1592 } |
| 1584 | 1593 |
| 1585 | 1594 |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1872 } | 1881 } |
| 1873 } | 1882 } |
| 1874 | 1883 |
| 1875 | 1884 |
| 1876 #undef __ | 1885 #undef __ |
| 1877 | 1886 |
| 1878 } // namespace internal | 1887 } // namespace internal |
| 1879 } // namespace v8 | 1888 } // namespace v8 |
| 1880 | 1889 |
| 1881 #endif // V8_TARGET_ARCH_MIPS | 1890 #endif // V8_TARGET_ARCH_MIPS |
| OLD | NEW |