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 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #if V8_TARGET_ARCH_PPC | 10 #if V8_TARGET_ARCH_PPC |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
97 | 97 |
98 | 98 |
99 void MacroAssembler::CallJSEntry(Register target) { | 99 void MacroAssembler::CallJSEntry(Register target) { |
100 DCHECK(target.is(ip)); | 100 DCHECK(target.is(ip)); |
101 Call(target); | 101 Call(target); |
102 } | 102 } |
103 | 103 |
104 | 104 |
105 int MacroAssembler::CallSize(Address target, RelocInfo::Mode rmode, | 105 int MacroAssembler::CallSize(Address target, RelocInfo::Mode rmode, |
106 Condition cond) { | 106 Condition cond) { |
107 return (2 + kMovInstructions) * kInstrSize; | 107 Operand mov_operand = Operand(reinterpret_cast<intptr_t>(target), rmode); |
108 return (2 + instructions_required_for_mov(mov_operand)) * kInstrSize; | |
108 } | 109 } |
109 | 110 |
110 | 111 |
111 int MacroAssembler::CallSizeNotPredictableCodeSize(Address target, | 112 int MacroAssembler::CallSizeNotPredictableCodeSize(Address target, |
112 RelocInfo::Mode rmode, | 113 RelocInfo::Mode rmode, |
113 Condition cond) { | 114 Condition cond) { |
114 return (2 + kMovInstructions) * kInstrSize; | 115 return (2 + kMovInstructionsNoConstantPool) * kInstrSize; |
115 } | 116 } |
116 | 117 |
117 | 118 |
118 void MacroAssembler::Call(Address target, RelocInfo::Mode rmode, | 119 void MacroAssembler::Call(Address target, RelocInfo::Mode rmode, |
119 Condition cond) { | 120 Condition cond) { |
120 BlockTrampolinePoolScope block_trampoline_pool(this); | 121 BlockTrampolinePoolScope block_trampoline_pool(this); |
121 DCHECK(cond == al); | 122 DCHECK(cond == al); |
122 | 123 |
123 #ifdef DEBUG | 124 #ifdef DEBUG |
124 // Check the expected size before generating code to ensure we assume the same | 125 // Check the expected size before generating code to ensure we assume the same |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
507 mtlr(r0); | 508 mtlr(r0); |
508 bind(&done); | 509 bind(&done); |
509 if (and_then == kReturnAtEnd) { | 510 if (and_then == kReturnAtEnd) { |
510 Ret(); | 511 Ret(); |
511 } | 512 } |
512 } | 513 } |
513 | 514 |
514 | 515 |
515 void MacroAssembler::PushFixedFrame(Register marker_reg) { | 516 void MacroAssembler::PushFixedFrame(Register marker_reg) { |
516 mflr(r0); | 517 mflr(r0); |
518 if (FLAG_enable_embedded_constant_pool) { | |
519 if (marker_reg.is_valid()) { | |
520 Push(r0, fp, kConstantPoolRegister, cp, marker_reg); | |
521 } else { | |
522 Push(r0, fp, kConstantPoolRegister, cp); | |
523 } | |
524 return; | |
525 } | |
526 | |
517 if (marker_reg.is_valid()) { | 527 if (marker_reg.is_valid()) { |
518 Push(r0, fp, cp, marker_reg); | 528 Push(r0, fp, cp, marker_reg); |
519 } else { | 529 } else { |
520 Push(r0, fp, cp); | 530 Push(r0, fp, cp); |
521 } | 531 } |
522 } | 532 } |
523 | 533 |
524 | 534 |
525 void MacroAssembler::PopFixedFrame(Register marker_reg) { | 535 void MacroAssembler::PopFixedFrame(Register marker_reg) { |
536 if (FLAG_enable_embedded_constant_pool) { | |
537 if (marker_reg.is_valid()) { | |
538 Pop(r0, fp, kConstantPoolRegister, cp, marker_reg); | |
539 } else { | |
540 Pop(r0, fp, kConstantPoolRegister, cp); | |
541 } | |
542 mtlr(r0); | |
543 return; | |
544 } | |
545 | |
526 if (marker_reg.is_valid()) { | 546 if (marker_reg.is_valid()) { |
527 Pop(r0, fp, cp, marker_reg); | 547 Pop(r0, fp, cp, marker_reg); |
528 } else { | 548 } else { |
529 Pop(r0, fp, cp); | 549 Pop(r0, fp, cp); |
530 } | 550 } |
531 mtlr(r0); | 551 mtlr(r0); |
532 } | 552 } |
533 | 553 |
534 | 554 |
535 const RegList MacroAssembler::kSafepointSavedRegisters = Register::kAllocatable; | 555 const RegList MacroAssembler::kSafepointSavedRegisters = Register::kAllocatable; |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
645 } | 665 } |
646 | 666 |
647 MovDoubleToInt64( | 667 MovDoubleToInt64( |
648 #if !V8_TARGET_ARCH_PPC64 | 668 #if !V8_TARGET_ARCH_PPC64 |
649 dst_hi, | 669 dst_hi, |
650 #endif | 670 #endif |
651 dst, double_dst); | 671 dst, double_dst); |
652 } | 672 } |
653 | 673 |
654 | 674 |
675 void MacroAssembler::LoadTargetConstantPoolPointerRegister(Register target) { | |
676 lwz(kConstantPoolRegister, | |
677 MemOperand(target, Code::kConstantPoolOffset - Code::kHeaderSize)); | |
678 add(kConstantPoolRegister, kConstantPoolRegister, target); | |
679 } | |
680 | |
681 | |
682 void MacroAssembler::LoadOwnConstantPoolPointerRegister(Register base, | |
683 int code_start_delta) { | |
684 if (base.is(no_reg)) { | |
685 mov_label_addr(kConstantPoolRegister, ConstantPoolPosition()); | |
686 } else { | |
rmcilroy
2015/04/08 12:38:55
I think these should be two separate functions (wi
MTBrandyberry
2015/05/07 20:38:32
Acknowledged.
| |
687 add_label_offset(kConstantPoolRegister, base, ConstantPoolPosition(), | |
688 code_start_delta); | |
689 } | |
690 } | |
691 | |
692 | |
655 void MacroAssembler::StubPrologue(int prologue_offset) { | 693 void MacroAssembler::StubPrologue(int prologue_offset) { |
656 LoadSmiLiteral(r11, Smi::FromInt(StackFrame::STUB)); | 694 LoadSmiLiteral(r11, Smi::FromInt(StackFrame::STUB)); |
657 PushFixedFrame(r11); | 695 PushFixedFrame(r11); |
658 // Adjust FP to point to saved FP. | 696 // Adjust FP to point to saved FP. |
659 addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); | 697 addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); |
698 if (FLAG_enable_embedded_constant_pool) { | |
699 // ip contains prologue address | |
700 LoadOwnConstantPoolPointerRegister(ip, -prologue_offset); | |
rmcilroy
2015/04/08 12:38:55
Where does ip get set to the prologue address?
MTBrandyberry
2015/05/07 20:38:32
All calls to JS code are done via the ip register.
| |
701 set_constant_pool_available(true); | |
702 } | |
660 } | 703 } |
661 | 704 |
662 | 705 |
663 void MacroAssembler::Prologue(bool code_pre_aging, int prologue_offset) { | 706 void MacroAssembler::Prologue(bool code_pre_aging, int prologue_offset) { |
664 { | 707 { |
665 PredictableCodeSizeScope predictible_code_size_scope( | 708 PredictableCodeSizeScope predictible_code_size_scope( |
666 this, kNoCodeAgeSequenceLength); | 709 this, kNoCodeAgeSequenceLength); |
667 Assembler::BlockTrampolinePoolScope block_trampoline_pool(this); | 710 Assembler::BlockTrampolinePoolScope block_trampoline_pool(this); |
668 // The following instructions must remain together and unmodified | 711 // The following instructions must remain together and unmodified |
669 // for code aging to work properly. | 712 // for code aging to work properly. |
(...skipping 12 matching lines...) Expand all Loading... | |
682 } else { | 725 } else { |
683 // This matches the code found in GetNoCodeAgeSequence() | 726 // This matches the code found in GetNoCodeAgeSequence() |
684 PushFixedFrame(r4); | 727 PushFixedFrame(r4); |
685 // Adjust fp to point to saved fp. | 728 // Adjust fp to point to saved fp. |
686 addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); | 729 addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); |
687 for (int i = 0; i < kNoCodeAgeSequenceNops; i++) { | 730 for (int i = 0; i < kNoCodeAgeSequenceNops; i++) { |
688 nop(); | 731 nop(); |
689 } | 732 } |
690 } | 733 } |
691 } | 734 } |
735 if (FLAG_enable_embedded_constant_pool) { | |
736 // ip contains prologue address | |
737 LoadOwnConstantPoolPointerRegister(ip, -prologue_offset); | |
rmcilroy
2015/04/08 12:38:55
ditto
MTBrandyberry
2015/05/07 20:38:32
see above.
| |
738 set_constant_pool_available(true); | |
739 } | |
692 } | 740 } |
693 | 741 |
694 | 742 |
695 void MacroAssembler::EnterFrame(StackFrame::Type type, | 743 void MacroAssembler::EnterFrame(StackFrame::Type type, |
696 bool load_constant_pool_pointer_reg) { | 744 bool load_constant_pool_pointer_reg) { |
697 LoadSmiLiteral(ip, Smi::FromInt(type)); | 745 if (FLAG_enable_embedded_constant_pool && load_constant_pool_pointer_reg) { |
698 PushFixedFrame(ip); | 746 PushFixedFrame(); |
747 // This path should not rely on ip containing code entry. | |
748 LoadOwnConstantPoolPointerRegister(); | |
749 LoadSmiLiteral(ip, Smi::FromInt(type)); | |
750 push(ip); | |
751 } else { | |
752 LoadSmiLiteral(ip, Smi::FromInt(type)); | |
753 PushFixedFrame(ip); | |
754 } | |
699 // Adjust FP to point to saved FP. | 755 // Adjust FP to point to saved FP. |
700 addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); | 756 addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); |
701 | 757 |
702 mov(r0, Operand(CodeObject())); | 758 mov(r0, Operand(CodeObject())); |
703 push(r0); | 759 push(r0); |
704 } | 760 } |
705 | 761 |
706 | 762 |
707 int MacroAssembler::LeaveFrame(StackFrame::Type type, int stack_adjustment) { | 763 int MacroAssembler::LeaveFrame(StackFrame::Type type, int stack_adjustment) { |
764 ConstantPoolUnavailableScope constant_pool_unavailable(this); | |
708 // r3: preserved | 765 // r3: preserved |
709 // r4: preserved | 766 // r4: preserved |
710 // r5: preserved | 767 // r5: preserved |
711 | 768 |
712 // Drop the execution stack down to the frame pointer and restore | 769 // Drop the execution stack down to the frame pointer and restore |
713 // the caller's state. | 770 // the caller's state. |
714 int frame_ends; | 771 int frame_ends; |
715 LoadP(r0, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); | 772 LoadP(r0, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); |
716 LoadP(ip, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 773 LoadP(ip, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
774 if (FLAG_enable_embedded_constant_pool) { | |
775 const int exitOffset = ExitFrameConstants::kConstantPoolOffset; | |
776 const int standardOffset = StandardFrameConstants::kConstantPoolOffset; | |
777 const int offset = | |
778 ((type == StackFrame::EXIT) ? exitOffset : standardOffset); | |
779 LoadP(kConstantPoolRegister, MemOperand(fp, offset)); | |
780 } | |
717 mtlr(r0); | 781 mtlr(r0); |
718 frame_ends = pc_offset(); | 782 frame_ends = pc_offset(); |
719 Add(sp, fp, StandardFrameConstants::kCallerSPOffset + stack_adjustment, r0); | 783 Add(sp, fp, StandardFrameConstants::kCallerSPOffset + stack_adjustment, r0); |
720 mr(fp, ip); | 784 mr(fp, ip); |
721 return frame_ends; | 785 return frame_ends; |
722 } | 786 } |
723 | 787 |
724 | 788 |
725 // ExitFrame layout (probably wrongish.. needs updating) | 789 // ExitFrame layout (probably wrongish.. needs updating) |
726 // | 790 // |
(...skipping 26 matching lines...) Expand all Loading... | |
753 mflr(r0); | 817 mflr(r0); |
754 Push(r0, fp); | 818 Push(r0, fp); |
755 mr(fp, sp); | 819 mr(fp, sp); |
756 // Reserve room for saved entry sp and code object. | 820 // Reserve room for saved entry sp and code object. |
757 subi(sp, sp, Operand(ExitFrameConstants::kFrameSize)); | 821 subi(sp, sp, Operand(ExitFrameConstants::kFrameSize)); |
758 | 822 |
759 if (emit_debug_code()) { | 823 if (emit_debug_code()) { |
760 li(r8, Operand::Zero()); | 824 li(r8, Operand::Zero()); |
761 StoreP(r8, MemOperand(fp, ExitFrameConstants::kSPOffset)); | 825 StoreP(r8, MemOperand(fp, ExitFrameConstants::kSPOffset)); |
762 } | 826 } |
827 if (FLAG_enable_embedded_constant_pool) { | |
828 StoreP(kConstantPoolRegister, | |
829 MemOperand(fp, ExitFrameConstants::kConstantPoolOffset)); | |
830 } | |
763 mov(r8, Operand(CodeObject())); | 831 mov(r8, Operand(CodeObject())); |
764 StoreP(r8, MemOperand(fp, ExitFrameConstants::kCodeOffset)); | 832 StoreP(r8, MemOperand(fp, ExitFrameConstants::kCodeOffset)); |
765 | 833 |
766 // Save the frame pointer and the context in top. | 834 // Save the frame pointer and the context in top. |
767 mov(r8, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); | 835 mov(r8, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); |
768 StoreP(fp, MemOperand(r8)); | 836 StoreP(fp, MemOperand(r8)); |
769 mov(r8, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); | 837 mov(r8, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); |
770 StoreP(cp, MemOperand(r8)); | 838 StoreP(cp, MemOperand(r8)); |
771 | 839 |
772 // Optionally save all volatile double registers. | 840 // Optionally save all volatile double registers. |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
822 // if the target platform will need alignment, so this is controlled from a | 890 // if the target platform will need alignment, so this is controlled from a |
823 // flag. | 891 // flag. |
824 return FLAG_sim_stack_alignment; | 892 return FLAG_sim_stack_alignment; |
825 #endif | 893 #endif |
826 } | 894 } |
827 | 895 |
828 | 896 |
829 void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count, | 897 void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count, |
830 bool restore_context, | 898 bool restore_context, |
831 bool argument_count_is_length) { | 899 bool argument_count_is_length) { |
900 ConstantPoolUnavailableScope constant_pool_unavailable(this); | |
832 // Optionally restore all double registers. | 901 // Optionally restore all double registers. |
833 if (save_doubles) { | 902 if (save_doubles) { |
834 // Calculate the stack location of the saved doubles and restore them. | 903 // Calculate the stack location of the saved doubles and restore them. |
835 const int kNumRegs = DoubleRegister::kNumVolatileRegisters; | 904 const int kNumRegs = DoubleRegister::kNumVolatileRegisters; |
836 const int offset = | 905 const int offset = |
837 (ExitFrameConstants::kFrameSize + kNumRegs * kDoubleSize); | 906 (ExitFrameConstants::kFrameSize + kNumRegs * kDoubleSize); |
838 addi(r6, fp, Operand(-offset)); | 907 addi(r6, fp, Operand(-offset)); |
839 RestoreFPRegs(r6, 0, kNumRegs); | 908 RestoreFPRegs(r6, 0, kNumRegs); |
840 } | 909 } |
841 | 910 |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1079 | 1148 |
1080 void MacroAssembler::DebugBreak() { | 1149 void MacroAssembler::DebugBreak() { |
1081 li(r3, Operand::Zero()); | 1150 li(r3, Operand::Zero()); |
1082 mov(r4, Operand(ExternalReference(Runtime::kDebugBreak, isolate()))); | 1151 mov(r4, Operand(ExternalReference(Runtime::kDebugBreak, isolate()))); |
1083 CEntryStub ces(isolate(), 1); | 1152 CEntryStub ces(isolate(), 1); |
1084 DCHECK(AllowThisStubCall(&ces)); | 1153 DCHECK(AllowThisStubCall(&ces)); |
1085 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); | 1154 Call(ces.GetCode(), RelocInfo::DEBUG_BREAK); |
1086 } | 1155 } |
1087 | 1156 |
1088 | 1157 |
1089 void MacroAssembler::PushTryHandler(StackHandler::Kind kind, | 1158 void MacroAssembler::PushStackHandler() { |
1090 int handler_index) { | |
1091 // Adjust this code if not the case. | 1159 // Adjust this code if not the case. |
1092 STATIC_ASSERT(StackHandlerConstants::kSize == 3 * kPointerSize); | 1160 STATIC_ASSERT(StackHandlerConstants::kSize == 1 * kPointerSize); |
1093 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); | 1161 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0 * kPointerSize); |
1094 STATIC_ASSERT(StackHandlerConstants::kStateOffset == 1 * kPointerSize); | |
1095 STATIC_ASSERT(StackHandlerConstants::kContextOffset == 2 * kPointerSize); | |
1096 | |
1097 // For the JSEntry handler, we must preserve r1-r7, r0,r8-r12 are available. | |
1098 // We want the stack to look like | |
1099 // sp -> NextOffset | |
1100 // index | |
1101 // context | |
1102 | 1162 |
1103 // Link the current handler as the next handler. | 1163 // Link the current handler as the next handler. |
1164 // Preserve r3-r7. | |
1104 mov(r8, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); | 1165 mov(r8, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); |
1105 LoadP(r0, MemOperand(r8)); | 1166 LoadP(r0, MemOperand(r8)); |
1106 StorePU(r0, MemOperand(sp, -StackHandlerConstants::kSize)); | 1167 push(r0); |
1168 | |
1107 // Set this new handler as the current one. | 1169 // Set this new handler as the current one. |
1108 StoreP(sp, MemOperand(r8)); | 1170 StoreP(sp, MemOperand(r8)); |
1109 | |
1110 mov(r8, Operand(handler_index)); | |
1111 if (kind == StackHandler::JS_ENTRY) { | |
1112 LoadSmiLiteral(cp, Smi::FromInt(0)); // Indicates no context. | |
1113 } | |
1114 StoreP(r8, MemOperand(sp, StackHandlerConstants::kStateOffset)); | |
1115 StoreP(cp, MemOperand(sp, StackHandlerConstants::kContextOffset)); | |
1116 } | 1171 } |
1117 | 1172 |
1118 | 1173 |
1119 void MacroAssembler::PopTryHandler() { | 1174 void MacroAssembler::PopStackHandler() { |
1175 STATIC_ASSERT(StackHandlerConstants::kSize == 1 * kPointerSize); | |
1120 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); | 1176 STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); |
1177 | |
1121 pop(r4); | 1178 pop(r4); |
1122 mov(ip, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); | 1179 mov(ip, Operand(ExternalReference(Isolate::kHandlerAddress, isolate()))); |
1123 addi(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize)); | |
1124 StoreP(r4, MemOperand(ip)); | 1180 StoreP(r4, MemOperand(ip)); |
1125 } | 1181 } |
1126 | 1182 |
1127 | 1183 |
1128 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, | 1184 void MacroAssembler::CheckAccessGlobalProxy(Register holder_reg, |
1129 Register scratch, Label* miss) { | 1185 Register scratch, Label* miss) { |
1130 Label same_contexts; | 1186 Label same_contexts; |
1131 | 1187 |
1132 DCHECK(!holder_reg.is(scratch)); | 1188 DCHECK(!holder_reg.is(scratch)); |
1133 DCHECK(!holder_reg.is(ip)); | 1189 DCHECK(!holder_reg.is(ip)); |
(...skipping 2050 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3184 isync(); | 3240 isync(); |
3185 | 3241 |
3186 bind(&done); | 3242 bind(&done); |
3187 } | 3243 } |
3188 | 3244 |
3189 | 3245 |
3190 void MacroAssembler::SetRelocatedValue(Register location, Register scratch, | 3246 void MacroAssembler::SetRelocatedValue(Register location, Register scratch, |
3191 Register new_value) { | 3247 Register new_value) { |
3192 lwz(scratch, MemOperand(location)); | 3248 lwz(scratch, MemOperand(location)); |
3193 | 3249 |
3250 if (FLAG_enable_embedded_constant_pool) { | |
3251 if (emit_debug_code()) { | |
3252 // Check that the instruction sequence is a load from the constant pool | |
3253 ExtractBitMask(scratch, scratch, 0x1f * B16); | |
3254 cmpi(scratch, Operand(kConstantPoolRegister.code())); | |
3255 Check(eq, kTheInstructionToPatchShouldBeALoadFromConstantPool); | |
3256 // Scratch was clobbered. Restore it. | |
3257 lwz(scratch, MemOperand(location)); | |
3258 } | |
3259 // Get the address of the constant and patch it. | |
3260 andi(scratch, scratch, Operand(kImm16Mask)); | |
3261 StorePX(new_value, MemOperand(kConstantPoolRegister, scratch)); | |
3262 return; | |
3263 } | |
3264 | |
3194 // This code assumes a FIXED_SEQUENCE for lis/ori | 3265 // This code assumes a FIXED_SEQUENCE for lis/ori |
3195 | 3266 |
3196 // At this point scratch is a lis instruction. | 3267 // At this point scratch is a lis instruction. |
3197 if (emit_debug_code()) { | 3268 if (emit_debug_code()) { |
3198 And(scratch, scratch, Operand(kOpcodeMask | (0x1f * B16))); | 3269 And(scratch, scratch, Operand(kOpcodeMask | (0x1f * B16))); |
3199 Cmpi(scratch, Operand(ADDIS), r0); | 3270 Cmpi(scratch, Operand(ADDIS), r0); |
3200 Check(eq, kTheInstructionToPatchShouldBeALis); | 3271 Check(eq, kTheInstructionToPatchShouldBeALis); |
3201 lwz(scratch, MemOperand(location)); | 3272 lwz(scratch, MemOperand(location)); |
3202 } | 3273 } |
3203 | 3274 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3267 #else | 3338 #else |
3268 FlushICache(location, 2 * kInstrSize, scratch); | 3339 FlushICache(location, 2 * kInstrSize, scratch); |
3269 #endif | 3340 #endif |
3270 } | 3341 } |
3271 | 3342 |
3272 | 3343 |
3273 void MacroAssembler::GetRelocatedValue(Register location, Register result, | 3344 void MacroAssembler::GetRelocatedValue(Register location, Register result, |
3274 Register scratch) { | 3345 Register scratch) { |
3275 lwz(result, MemOperand(location)); | 3346 lwz(result, MemOperand(location)); |
3276 | 3347 |
3348 if (FLAG_enable_embedded_constant_pool) { | |
3349 if (emit_debug_code()) { | |
3350 // Check that the instruction sequence is a load from the constant pool | |
3351 ExtractBitMask(result, result, 0x1f * B16); | |
3352 cmpi(result, Operand(kConstantPoolRegister.code())); | |
3353 Check(eq, kTheInstructionToPatchShouldBeALoadFromConstantPool); | |
3354 lwz(result, MemOperand(location)); | |
3355 } | |
3356 // Get the address of the constant and retrieve it. | |
3357 andi(result, result, Operand(kImm16Mask)); | |
3358 LoadPX(result, MemOperand(kConstantPoolRegister, result)); | |
3359 return; | |
3360 } | |
3361 | |
3277 // This code assumes a FIXED_SEQUENCE for lis/ori | 3362 // This code assumes a FIXED_SEQUENCE for lis/ori |
3278 if (emit_debug_code()) { | 3363 if (emit_debug_code()) { |
3279 And(result, result, Operand(kOpcodeMask | (0x1f * B16))); | 3364 And(result, result, Operand(kOpcodeMask | (0x1f * B16))); |
3280 Cmpi(result, Operand(ADDIS), r0); | 3365 Cmpi(result, Operand(ADDIS), r0); |
3281 Check(eq, kTheInstructionShouldBeALis); | 3366 Check(eq, kTheInstructionShouldBeALis); |
3282 lwz(result, MemOperand(location)); | 3367 lwz(result, MemOperand(location)); |
3283 } | 3368 } |
3284 | 3369 |
3285 // result now holds a lis instruction. Extract the immediate. | 3370 // result now holds a lis instruction. Extract the immediate. |
3286 slwi(result, result, Operand(16)); | 3371 slwi(result, result, Operand(16)); |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3704 } | 3789 } |
3705 | 3790 |
3706 | 3791 |
3707 void MacroAssembler::LoadSmiLiteral(Register dst, Smi* smi) { | 3792 void MacroAssembler::LoadSmiLiteral(Register dst, Smi* smi) { |
3708 mov(dst, Operand(smi)); | 3793 mov(dst, Operand(smi)); |
3709 } | 3794 } |
3710 | 3795 |
3711 | 3796 |
3712 void MacroAssembler::LoadDoubleLiteral(DoubleRegister result, double value, | 3797 void MacroAssembler::LoadDoubleLiteral(DoubleRegister result, double value, |
3713 Register scratch) { | 3798 Register scratch) { |
3799 if (FLAG_enable_embedded_constant_pool && is_constant_pool_available() && | |
3800 !is_constant_pool_full()) { | |
3801 ConstantPoolAddEntry(value); | |
3802 lfd(result, MemOperand(kConstantPoolRegister, 0)); | |
3803 return; | |
3804 } | |
3805 | |
3714 // avoid gcc strict aliasing error using union cast | 3806 // avoid gcc strict aliasing error using union cast |
3715 union { | 3807 union { |
3716 double dval; | 3808 double dval; |
3717 #if V8_TARGET_ARCH_PPC64 | 3809 #if V8_TARGET_ARCH_PPC64 |
3718 intptr_t ival; | 3810 intptr_t ival; |
3719 #else | 3811 #else |
3720 intptr_t ival[2]; | 3812 intptr_t ival[2]; |
3721 #endif | 3813 #endif |
3722 } litVal; | 3814 } litVal; |
3723 | 3815 |
(...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4539 } | 4631 } |
4540 if (mag.shift > 0) srawi(result, result, mag.shift); | 4632 if (mag.shift > 0) srawi(result, result, mag.shift); |
4541 ExtractBit(r0, dividend, 31); | 4633 ExtractBit(r0, dividend, 31); |
4542 add(result, result, r0); | 4634 add(result, result, r0); |
4543 } | 4635 } |
4544 | 4636 |
4545 } // namespace internal | 4637 } // namespace internal |
4546 } // namespace v8 | 4638 } // namespace v8 |
4547 | 4639 |
4548 #endif // V8_TARGET_ARCH_PPC | 4640 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |