Chromium Code Reviews| 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 |