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 #include <assert.h> // For assert | 5 #include <assert.h> // For assert |
6 #include <limits.h> // For LONG_MIN, LONG_MAX. | 6 #include <limits.h> // For LONG_MIN, LONG_MAX. |
7 | 7 |
8 #if V8_TARGET_ARCH_PPC | 8 #if V8_TARGET_ARCH_PPC |
9 | 9 |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 573 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
584 StoreBufferOverflowStub store_buffer_overflow(isolate(), fp_mode); | 584 StoreBufferOverflowStub store_buffer_overflow(isolate(), fp_mode); |
585 CallStub(&store_buffer_overflow); | 585 CallStub(&store_buffer_overflow); |
586 pop(r0); | 586 pop(r0); |
587 mtlr(r0); | 587 mtlr(r0); |
588 bind(&done); | 588 bind(&done); |
589 if (and_then == kReturnAtEnd) { | 589 if (and_then == kReturnAtEnd) { |
590 Ret(); | 590 Ret(); |
591 } | 591 } |
592 } | 592 } |
593 | 593 |
594 | 594 void MacroAssembler::PushCommonFrame(Register marker_reg) { |
595 void MacroAssembler::PushFixedFrame(Register marker_reg) { | 595 int fp_delta = 0; |
596 mflr(r0); | 596 mflr(r0); |
597 if (FLAG_enable_embedded_constant_pool) { | 597 if (FLAG_enable_embedded_constant_pool) { |
598 if (marker_reg.is_valid()) { | 598 if (marker_reg.is_valid()) { |
599 Push(r0, fp, kConstantPoolRegister, cp, marker_reg); | 599 Push(r0, fp, kConstantPoolRegister, marker_reg); |
| 600 fp_delta = 2; |
600 } else { | 601 } else { |
601 Push(r0, fp, kConstantPoolRegister, cp); | 602 Push(r0, fp, kConstantPoolRegister); |
| 603 fp_delta = 1; |
602 } | 604 } |
603 } else { | 605 } else { |
604 if (marker_reg.is_valid()) { | 606 if (marker_reg.is_valid()) { |
605 Push(r0, fp, cp, marker_reg); | 607 Push(r0, fp, marker_reg); |
| 608 fp_delta = 1; |
606 } else { | 609 } else { |
607 Push(r0, fp, cp); | 610 Push(r0, fp); |
| 611 fp_delta = 0; |
608 } | 612 } |
609 } | 613 } |
| 614 addi(fp, sp, Operand(fp_delta * kPointerSize)); |
610 } | 615 } |
611 | 616 |
612 | 617 void MacroAssembler::PopCommonFrame(Register marker_reg) { |
613 void MacroAssembler::PopFixedFrame(Register marker_reg) { | |
614 if (FLAG_enable_embedded_constant_pool) { | 618 if (FLAG_enable_embedded_constant_pool) { |
615 if (marker_reg.is_valid()) { | 619 if (marker_reg.is_valid()) { |
616 Pop(r0, fp, kConstantPoolRegister, cp, marker_reg); | 620 Pop(r0, fp, kConstantPoolRegister, marker_reg); |
617 } else { | 621 } else { |
618 Pop(r0, fp, kConstantPoolRegister, cp); | 622 Pop(r0, fp, kConstantPoolRegister); |
619 } | 623 } |
620 } else { | 624 } else { |
621 if (marker_reg.is_valid()) { | 625 if (marker_reg.is_valid()) { |
622 Pop(r0, fp, cp, marker_reg); | 626 Pop(r0, fp, marker_reg); |
623 } else { | 627 } else { |
624 Pop(r0, fp, cp); | 628 Pop(r0, fp); |
625 } | 629 } |
626 } | 630 } |
627 mtlr(r0); | 631 mtlr(r0); |
628 } | 632 } |
629 | 633 |
| 634 void MacroAssembler::PushStandardFrame(Register function_reg) { |
| 635 int fp_delta = 0; |
| 636 mflr(r0); |
| 637 if (FLAG_enable_embedded_constant_pool) { |
| 638 if (function_reg.is_valid()) { |
| 639 Push(r0, fp, kConstantPoolRegister, cp, function_reg); |
| 640 fp_delta = 3; |
| 641 } else { |
| 642 Push(r0, fp, kConstantPoolRegister, cp); |
| 643 fp_delta = 2; |
| 644 } |
| 645 } else { |
| 646 if (function_reg.is_valid()) { |
| 647 Push(r0, fp, cp, function_reg); |
| 648 fp_delta = 2; |
| 649 } else { |
| 650 Push(r0, fp, cp); |
| 651 fp_delta = 1; |
| 652 } |
| 653 } |
| 654 addi(fp, sp, Operand(fp_delta * kPointerSize)); |
| 655 } |
| 656 |
630 void MacroAssembler::RestoreFrameStateForTailCall() { | 657 void MacroAssembler::RestoreFrameStateForTailCall() { |
631 if (FLAG_enable_embedded_constant_pool) { | 658 if (FLAG_enable_embedded_constant_pool) { |
632 LoadP(kConstantPoolRegister, | 659 LoadP(kConstantPoolRegister, |
633 MemOperand(fp, StandardFrameConstants::kConstantPoolOffset)); | 660 MemOperand(fp, StandardFrameConstants::kConstantPoolOffset)); |
634 set_constant_pool_available(false); | 661 set_constant_pool_available(false); |
635 } | 662 } |
636 LoadP(r0, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); | 663 LoadP(r0, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); |
637 LoadP(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 664 LoadP(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
638 mtlr(r0); | 665 mtlr(r0); |
639 } | 666 } |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
863 int code_start_delta) { | 890 int code_start_delta) { |
864 add_label_offset(kConstantPoolRegister, base, ConstantPoolPosition(), | 891 add_label_offset(kConstantPoolRegister, base, ConstantPoolPosition(), |
865 code_start_delta); | 892 code_start_delta); |
866 } | 893 } |
867 | 894 |
868 | 895 |
869 void MacroAssembler::LoadConstantPoolPointerRegister() { | 896 void MacroAssembler::LoadConstantPoolPointerRegister() { |
870 mov_label_addr(kConstantPoolRegister, ConstantPoolPosition()); | 897 mov_label_addr(kConstantPoolRegister, ConstantPoolPosition()); |
871 } | 898 } |
872 | 899 |
873 | 900 void MacroAssembler::StubPrologue(StackFrame::Type type, Register base, |
874 void MacroAssembler::StubPrologue(Register base, int prologue_offset) { | 901 int prologue_offset) { |
875 LoadSmiLiteral(r11, Smi::FromInt(StackFrame::STUB)); | 902 LoadSmiLiteral(r11, Smi::FromInt(type)); |
876 PushFixedFrame(r11); | 903 PushCommonFrame(r11); |
877 // Adjust FP to point to saved FP. | |
878 addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); | |
879 if (FLAG_enable_embedded_constant_pool) { | 904 if (FLAG_enable_embedded_constant_pool) { |
880 if (!base.is(no_reg)) { | 905 if (!base.is(no_reg)) { |
881 // base contains prologue address | 906 // base contains prologue address |
882 LoadConstantPoolPointerRegister(base, -prologue_offset); | 907 LoadConstantPoolPointerRegister(base, -prologue_offset); |
883 } else { | 908 } else { |
884 LoadConstantPoolPointerRegister(); | 909 LoadConstantPoolPointerRegister(); |
885 } | 910 } |
886 set_constant_pool_available(true); | 911 set_constant_pool_available(true); |
887 } | 912 } |
888 } | 913 } |
(...skipping 15 matching lines...) Expand all Loading... |
904 intptr_t target = reinterpret_cast<intptr_t>(stub->instruction_start()); | 929 intptr_t target = reinterpret_cast<intptr_t>(stub->instruction_start()); |
905 // Don't use Call -- we need to preserve ip and lr | 930 // Don't use Call -- we need to preserve ip and lr |
906 nop(); // marker to detect sequence (see IsOld) | 931 nop(); // marker to detect sequence (see IsOld) |
907 mov(r3, Operand(target)); | 932 mov(r3, Operand(target)); |
908 Jump(r3); | 933 Jump(r3); |
909 for (int i = 0; i < kCodeAgingSequenceNops; i++) { | 934 for (int i = 0; i < kCodeAgingSequenceNops; i++) { |
910 nop(); | 935 nop(); |
911 } | 936 } |
912 } else { | 937 } else { |
913 // This matches the code found in GetNoCodeAgeSequence() | 938 // This matches the code found in GetNoCodeAgeSequence() |
914 PushFixedFrame(r4); | 939 PushStandardFrame(r4); |
915 // Adjust fp to point to saved fp. | |
916 addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); | |
917 for (int i = 0; i < kNoCodeAgeSequenceNops; i++) { | 940 for (int i = 0; i < kNoCodeAgeSequenceNops; i++) { |
918 nop(); | 941 nop(); |
919 } | 942 } |
920 } | 943 } |
921 } | 944 } |
922 if (FLAG_enable_embedded_constant_pool) { | 945 if (FLAG_enable_embedded_constant_pool) { |
923 // base contains prologue address | 946 // base contains prologue address |
924 LoadConstantPoolPointerRegister(base, -prologue_offset); | 947 LoadConstantPoolPointerRegister(base, -prologue_offset); |
925 set_constant_pool_available(true); | 948 set_constant_pool_available(true); |
926 } | 949 } |
927 } | 950 } |
928 | 951 |
929 | 952 |
930 void MacroAssembler::EmitLoadTypeFeedbackVector(Register vector) { | 953 void MacroAssembler::EmitLoadTypeFeedbackVector(Register vector) { |
931 LoadP(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); | 954 LoadP(vector, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset)); |
932 LoadP(vector, FieldMemOperand(vector, JSFunction::kSharedFunctionInfoOffset)); | 955 LoadP(vector, FieldMemOperand(vector, JSFunction::kSharedFunctionInfoOffset)); |
933 LoadP(vector, | 956 LoadP(vector, |
934 FieldMemOperand(vector, SharedFunctionInfo::kFeedbackVectorOffset)); | 957 FieldMemOperand(vector, SharedFunctionInfo::kFeedbackVectorOffset)); |
935 } | 958 } |
936 | 959 |
937 | 960 |
938 void MacroAssembler::EnterFrame(StackFrame::Type type, | 961 void MacroAssembler::EnterFrame(StackFrame::Type type, |
939 bool load_constant_pool_pointer_reg) { | 962 bool load_constant_pool_pointer_reg) { |
940 if (FLAG_enable_embedded_constant_pool && load_constant_pool_pointer_reg) { | 963 if (FLAG_enable_embedded_constant_pool && load_constant_pool_pointer_reg) { |
941 PushFixedFrame(); | 964 // Push type explicitly so we can leverage the constant pool. |
942 // This path should not rely on ip containing code entry. | 965 // This path cannot rely on ip containing code entry. |
| 966 PushCommonFrame(); |
943 LoadConstantPoolPointerRegister(); | 967 LoadConstantPoolPointerRegister(); |
944 LoadSmiLiteral(ip, Smi::FromInt(type)); | 968 LoadSmiLiteral(ip, Smi::FromInt(type)); |
945 push(ip); | 969 push(ip); |
946 } else { | 970 } else { |
947 LoadSmiLiteral(ip, Smi::FromInt(type)); | 971 LoadSmiLiteral(ip, Smi::FromInt(type)); |
948 PushFixedFrame(ip); | 972 PushCommonFrame(ip); |
949 } | 973 } |
950 // Adjust FP to point to saved FP. | 974 if (type == StackFrame::INTERNAL) { |
951 addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); | 975 mov(r0, Operand(CodeObject())); |
952 | 976 push(r0); |
953 mov(r0, Operand(CodeObject())); | 977 } |
954 push(r0); | |
955 } | 978 } |
956 | 979 |
957 | 980 |
958 int MacroAssembler::LeaveFrame(StackFrame::Type type, int stack_adjustment) { | 981 int MacroAssembler::LeaveFrame(StackFrame::Type type, int stack_adjustment) { |
959 ConstantPoolUnavailableScope constant_pool_unavailable(this); | 982 ConstantPoolUnavailableScope constant_pool_unavailable(this); |
960 // r3: preserved | 983 // r3: preserved |
961 // r4: preserved | 984 // r4: preserved |
962 // r5: preserved | 985 // r5: preserved |
963 | 986 |
964 // Drop the execution stack down to the frame pointer and restore | 987 // Drop the execution stack down to the frame pointer and restore |
965 // the caller's state. | 988 // the caller's state. |
966 int frame_ends; | 989 int frame_ends; |
967 LoadP(r0, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); | 990 LoadP(r0, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); |
968 LoadP(ip, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 991 LoadP(ip, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
969 if (FLAG_enable_embedded_constant_pool) { | 992 if (FLAG_enable_embedded_constant_pool) { |
970 const int exitOffset = ExitFrameConstants::kConstantPoolOffset; | 993 LoadP(kConstantPoolRegister, |
971 const int standardOffset = StandardFrameConstants::kConstantPoolOffset; | 994 MemOperand(fp, StandardFrameConstants::kConstantPoolOffset)); |
972 const int offset = | |
973 ((type == StackFrame::EXIT) ? exitOffset : standardOffset); | |
974 LoadP(kConstantPoolRegister, MemOperand(fp, offset)); | |
975 } | 995 } |
976 mtlr(r0); | 996 mtlr(r0); |
977 frame_ends = pc_offset(); | 997 frame_ends = pc_offset(); |
978 Add(sp, fp, StandardFrameConstants::kCallerSPOffset + stack_adjustment, r0); | 998 Add(sp, fp, StandardFrameConstants::kCallerSPOffset + stack_adjustment, r0); |
979 mr(fp, ip); | 999 mr(fp, ip); |
980 return frame_ends; | 1000 return frame_ends; |
981 } | 1001 } |
982 | 1002 |
983 | 1003 |
984 // ExitFrame layout (probably wrongish.. needs updating) | 1004 // ExitFrame layout (probably wrongish.. needs updating) |
(...skipping 16 matching lines...) Expand all Loading... |
1001 // Set up the frame structure on the stack. | 1021 // Set up the frame structure on the stack. |
1002 DCHECK_EQ(2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement); | 1022 DCHECK_EQ(2 * kPointerSize, ExitFrameConstants::kCallerSPDisplacement); |
1003 DCHECK_EQ(1 * kPointerSize, ExitFrameConstants::kCallerPCOffset); | 1023 DCHECK_EQ(1 * kPointerSize, ExitFrameConstants::kCallerPCOffset); |
1004 DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); | 1024 DCHECK_EQ(0 * kPointerSize, ExitFrameConstants::kCallerFPOffset); |
1005 DCHECK(stack_space > 0); | 1025 DCHECK(stack_space > 0); |
1006 | 1026 |
1007 // This is an opportunity to build a frame to wrap | 1027 // This is an opportunity to build a frame to wrap |
1008 // all of the pushes that have happened inside of V8 | 1028 // all of the pushes that have happened inside of V8 |
1009 // since we were called from C code | 1029 // since we were called from C code |
1010 | 1030 |
1011 // replicate ARM frame - TODO make this more closely follow PPC ABI | 1031 LoadSmiLiteral(ip, Smi::FromInt(StackFrame::EXIT)); |
1012 mflr(r0); | 1032 PushCommonFrame(ip); |
1013 Push(r0, fp); | |
1014 mr(fp, sp); | |
1015 // Reserve room for saved entry sp and code object. | 1033 // Reserve room for saved entry sp and code object. |
1016 subi(sp, sp, Operand(ExitFrameConstants::kFrameSize)); | 1034 subi(sp, fp, Operand(ExitFrameConstants::kFixedFrameSizeFromFp)); |
1017 | 1035 |
1018 if (emit_debug_code()) { | 1036 if (emit_debug_code()) { |
1019 li(r8, Operand::Zero()); | 1037 li(r8, Operand::Zero()); |
1020 StoreP(r8, MemOperand(fp, ExitFrameConstants::kSPOffset)); | 1038 StoreP(r8, MemOperand(fp, ExitFrameConstants::kSPOffset)); |
1021 } | 1039 } |
1022 if (FLAG_enable_embedded_constant_pool) { | 1040 if (FLAG_enable_embedded_constant_pool) { |
1023 StoreP(kConstantPoolRegister, | 1041 StoreP(kConstantPoolRegister, |
1024 MemOperand(fp, ExitFrameConstants::kConstantPoolOffset)); | 1042 MemOperand(fp, ExitFrameConstants::kConstantPoolOffset)); |
1025 } | 1043 } |
1026 mov(r8, Operand(CodeObject())); | 1044 mov(r8, Operand(CodeObject())); |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1091 | 1109 |
1092 void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count, | 1110 void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count, |
1093 bool restore_context, | 1111 bool restore_context, |
1094 bool argument_count_is_length) { | 1112 bool argument_count_is_length) { |
1095 ConstantPoolUnavailableScope constant_pool_unavailable(this); | 1113 ConstantPoolUnavailableScope constant_pool_unavailable(this); |
1096 // Optionally restore all double registers. | 1114 // Optionally restore all double registers. |
1097 if (save_doubles) { | 1115 if (save_doubles) { |
1098 // Calculate the stack location of the saved doubles and restore them. | 1116 // Calculate the stack location of the saved doubles and restore them. |
1099 const int kNumRegs = kNumCallerSavedDoubles; | 1117 const int kNumRegs = kNumCallerSavedDoubles; |
1100 const int offset = | 1118 const int offset = |
1101 (ExitFrameConstants::kFrameSize + kNumRegs * kDoubleSize); | 1119 (ExitFrameConstants::kFixedFrameSizeFromFp + kNumRegs * kDoubleSize); |
1102 addi(r6, fp, Operand(-offset)); | 1120 addi(r6, fp, Operand(-offset)); |
1103 MultiPopDoubles(kCallerSavedDoubles, r6); | 1121 MultiPopDoubles(kCallerSavedDoubles, r6); |
1104 } | 1122 } |
1105 | 1123 |
1106 // Clear top frame. | 1124 // Clear top frame. |
1107 li(r6, Operand::Zero()); | 1125 li(r6, Operand::Zero()); |
1108 mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); | 1126 mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); |
1109 StoreP(r6, MemOperand(ip)); | 1127 StoreP(r6, MemOperand(ip)); |
1110 | 1128 |
1111 // Restore current context from top and clear it in debug mode. | 1129 // Restore current context from top and clear it in debug mode. |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1470 | 1488 |
1471 | 1489 |
1472 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, | 1490 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, |
1473 Register scratch, Label* miss) { | 1491 Register scratch, Label* miss) { |
1474 Label same_contexts; | 1492 Label same_contexts; |
1475 | 1493 |
1476 DCHECK(!holder_reg.is(scratch)); | 1494 DCHECK(!holder_reg.is(scratch)); |
1477 DCHECK(!holder_reg.is(ip)); | 1495 DCHECK(!holder_reg.is(ip)); |
1478 DCHECK(!scratch.is(ip)); | 1496 DCHECK(!scratch.is(ip)); |
1479 | 1497 |
1480 // Load current lexical context from the stack frame. | 1498 // Load current lexical context from the active StandardFrame, which |
1481 LoadP(scratch, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 1499 // may require crawling past STUB frames. |
| 1500 Label load_context; |
| 1501 Label has_context; |
| 1502 DCHECK(!ip.is(scratch)); |
| 1503 mr(ip, fp); |
| 1504 bind(&load_context); |
| 1505 LoadP(scratch, |
| 1506 MemOperand(ip, CommonFrameConstants::kContextOrFrameTypeOffset)); |
| 1507 JumpIfNotSmi(scratch, &has_context); |
| 1508 LoadP(ip, MemOperand(ip, CommonFrameConstants::kCallerFPOffset)); |
| 1509 b(&load_context); |
| 1510 bind(&has_context); |
| 1511 |
1482 // In debug mode, make sure the lexical context is set. | 1512 // In debug mode, make sure the lexical context is set. |
1483 #ifdef DEBUG | 1513 #ifdef DEBUG |
1484 cmpi(scratch, Operand::Zero()); | 1514 cmpi(scratch, Operand::Zero()); |
1485 Check(ne, kWeShouldNotHaveAnEmptyLexicalContext); | 1515 Check(ne, kWeShouldNotHaveAnEmptyLexicalContext); |
1486 #endif | 1516 #endif |
1487 | 1517 |
1488 // Load the native context of the current context. | 1518 // Load the native context of the current context. |
1489 LoadP(scratch, ContextMemOperand(scratch, Context::NATIVE_CONTEXT_INDEX)); | 1519 LoadP(scratch, ContextMemOperand(scratch, Context::NATIVE_CONTEXT_INDEX)); |
1490 | 1520 |
1491 // Check the context is a native context. | 1521 // Check the context is a native context. |
(...skipping 3015 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4507 } | 4537 } |
4508 if (mag.shift > 0) srawi(result, result, mag.shift); | 4538 if (mag.shift > 0) srawi(result, result, mag.shift); |
4509 ExtractBit(r0, dividend, 31); | 4539 ExtractBit(r0, dividend, 31); |
4510 add(result, result, r0); | 4540 add(result, result, r0); |
4511 } | 4541 } |
4512 | 4542 |
4513 } // namespace internal | 4543 } // namespace internal |
4514 } // namespace v8 | 4544 } // namespace v8 |
4515 | 4545 |
4516 #endif // V8_TARGET_ARCH_PPC | 4546 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |