| 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 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 96 | 96 |
| 97 | 97 |
| 98 void MacroAssembler::CallJSEntry(Register target) { | 98 void MacroAssembler::CallJSEntry(Register target) { |
| 99 DCHECK(target.is(ip)); | 99 DCHECK(target.is(ip)); |
| 100 Call(target); | 100 Call(target); |
| 101 } | 101 } |
| 102 | 102 |
| 103 | 103 |
| 104 int MacroAssembler::CallSize(Address target, RelocInfo::Mode rmode, | 104 int MacroAssembler::CallSize(Address target, RelocInfo::Mode rmode, |
| 105 Condition cond) { | 105 Condition cond) { |
| 106 Operand mov_operand = Operand(reinterpret_cast<intptr_t>(target), rmode); | 106 return (2 + kMovInstructions) * kInstrSize; |
| 107 return (2 + instructions_required_for_mov(ip, mov_operand)) * kInstrSize; | |
| 108 } | 107 } |
| 109 | 108 |
| 110 | 109 |
| 111 int MacroAssembler::CallSizeNotPredictableCodeSize(Address target, | 110 int MacroAssembler::CallSizeNotPredictableCodeSize(Address target, |
| 112 RelocInfo::Mode rmode, | 111 RelocInfo::Mode rmode, |
| 113 Condition cond) { | 112 Condition cond) { |
| 114 return (2 + kMovInstructionsNoConstantPool) * kInstrSize; | 113 return (2 + kMovInstructions) * kInstrSize; |
| 115 } | 114 } |
| 116 | 115 |
| 117 | 116 |
| 118 void MacroAssembler::Call(Address target, RelocInfo::Mode rmode, | 117 void MacroAssembler::Call(Address target, RelocInfo::Mode rmode, |
| 119 Condition cond) { | 118 Condition cond) { |
| 120 BlockTrampolinePoolScope block_trampoline_pool(this); | 119 BlockTrampolinePoolScope block_trampoline_pool(this); |
| 121 DCHECK(cond == al); | 120 DCHECK(cond == al); |
| 122 | 121 |
| 123 #ifdef DEBUG | 122 #ifdef DEBUG |
| 124 // Check the expected size before generating code to ensure we assume the same | 123 // 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); | 506 mtlr(r0); |
| 508 bind(&done); | 507 bind(&done); |
| 509 if (and_then == kReturnAtEnd) { | 508 if (and_then == kReturnAtEnd) { |
| 510 Ret(); | 509 Ret(); |
| 511 } | 510 } |
| 512 } | 511 } |
| 513 | 512 |
| 514 | 513 |
| 515 void MacroAssembler::PushFixedFrame(Register marker_reg) { | 514 void MacroAssembler::PushFixedFrame(Register marker_reg) { |
| 516 mflr(r0); | 515 mflr(r0); |
| 517 if (FLAG_enable_embedded_constant_pool) { | 516 if (marker_reg.is_valid()) { |
| 518 if (marker_reg.is_valid()) { | 517 Push(r0, fp, cp, marker_reg); |
| 519 Push(r0, fp, kConstantPoolRegister, cp, marker_reg); | |
| 520 } else { | |
| 521 Push(r0, fp, kConstantPoolRegister, cp); | |
| 522 } | |
| 523 } else { | 518 } else { |
| 524 if (marker_reg.is_valid()) { | 519 Push(r0, fp, cp); |
| 525 Push(r0, fp, cp, marker_reg); | |
| 526 } else { | |
| 527 Push(r0, fp, cp); | |
| 528 } | |
| 529 } | 520 } |
| 530 } | 521 } |
| 531 | 522 |
| 532 | 523 |
| 533 void MacroAssembler::PopFixedFrame(Register marker_reg) { | 524 void MacroAssembler::PopFixedFrame(Register marker_reg) { |
| 534 if (FLAG_enable_embedded_constant_pool) { | 525 if (marker_reg.is_valid()) { |
| 535 if (marker_reg.is_valid()) { | 526 Pop(r0, fp, cp, marker_reg); |
| 536 Pop(r0, fp, kConstantPoolRegister, cp, marker_reg); | |
| 537 } else { | |
| 538 Pop(r0, fp, kConstantPoolRegister, cp); | |
| 539 } | |
| 540 } else { | 527 } else { |
| 541 if (marker_reg.is_valid()) { | 528 Pop(r0, fp, cp); |
| 542 Pop(r0, fp, cp, marker_reg); | |
| 543 } else { | |
| 544 Pop(r0, fp, cp); | |
| 545 } | |
| 546 } | 529 } |
| 547 mtlr(r0); | 530 mtlr(r0); |
| 548 } | 531 } |
| 549 | 532 |
| 550 | 533 |
| 551 const RegList MacroAssembler::kSafepointSavedRegisters = Register::kAllocatable; | 534 const RegList MacroAssembler::kSafepointSavedRegisters = Register::kAllocatable; |
| 552 const int MacroAssembler::kNumSafepointSavedRegisters = | 535 const int MacroAssembler::kNumSafepointSavedRegisters = |
| 553 Register::kMaxNumAllocatableRegisters; | 536 Register::kMaxNumAllocatableRegisters; |
| 554 | 537 |
| 555 // Push and pop all registers that can hold pointers. | 538 // Push and pop all registers that can hold pointers. |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 661 } | 644 } |
| 662 | 645 |
| 663 MovDoubleToInt64( | 646 MovDoubleToInt64( |
| 664 #if !V8_TARGET_ARCH_PPC64 | 647 #if !V8_TARGET_ARCH_PPC64 |
| 665 dst_hi, | 648 dst_hi, |
| 666 #endif | 649 #endif |
| 667 dst, double_dst); | 650 dst, double_dst); |
| 668 } | 651 } |
| 669 | 652 |
| 670 | 653 |
| 671 void MacroAssembler::LoadConstantPoolPointerRegisterFromCodeTargetAddress( | |
| 672 Register code_target_address) { | |
| 673 lwz(kConstantPoolRegister, | |
| 674 MemOperand(code_target_address, | |
| 675 Code::kConstantPoolOffset - Code::kHeaderSize)); | |
| 676 add(kConstantPoolRegister, kConstantPoolRegister, code_target_address); | |
| 677 } | |
| 678 | |
| 679 | |
| 680 void MacroAssembler::LoadConstantPoolPointerRegister(Register base, | |
| 681 int code_start_delta) { | |
| 682 add_label_offset(kConstantPoolRegister, base, ConstantPoolPosition(), | |
| 683 code_start_delta); | |
| 684 } | |
| 685 | |
| 686 | |
| 687 void MacroAssembler::LoadConstantPoolPointerRegister() { | |
| 688 mov_label_addr(kConstantPoolRegister, ConstantPoolPosition()); | |
| 689 } | |
| 690 | |
| 691 | |
| 692 void MacroAssembler::StubPrologue(int prologue_offset) { | 654 void MacroAssembler::StubPrologue(int prologue_offset) { |
| 693 LoadSmiLiteral(r11, Smi::FromInt(StackFrame::STUB)); | 655 LoadSmiLiteral(r11, Smi::FromInt(StackFrame::STUB)); |
| 694 PushFixedFrame(r11); | 656 PushFixedFrame(r11); |
| 695 // Adjust FP to point to saved FP. | 657 // Adjust FP to point to saved FP. |
| 696 addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); | 658 addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); |
| 697 if (FLAG_enable_embedded_constant_pool) { | |
| 698 // ip contains prologue address | |
| 699 LoadConstantPoolPointerRegister(ip, -prologue_offset); | |
| 700 set_constant_pool_available(true); | |
| 701 } | |
| 702 } | 659 } |
| 703 | 660 |
| 704 | 661 |
| 705 void MacroAssembler::Prologue(bool code_pre_aging, int prologue_offset) { | 662 void MacroAssembler::Prologue(bool code_pre_aging, int prologue_offset) { |
| 706 { | 663 { |
| 707 PredictableCodeSizeScope predictible_code_size_scope( | 664 PredictableCodeSizeScope predictible_code_size_scope( |
| 708 this, kNoCodeAgeSequenceLength); | 665 this, kNoCodeAgeSequenceLength); |
| 709 Assembler::BlockTrampolinePoolScope block_trampoline_pool(this); | 666 Assembler::BlockTrampolinePoolScope block_trampoline_pool(this); |
| 710 // The following instructions must remain together and unmodified | 667 // The following instructions must remain together and unmodified |
| 711 // for code aging to work properly. | 668 // for code aging to work properly. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 724 } else { | 681 } else { |
| 725 // This matches the code found in GetNoCodeAgeSequence() | 682 // This matches the code found in GetNoCodeAgeSequence() |
| 726 PushFixedFrame(r4); | 683 PushFixedFrame(r4); |
| 727 // Adjust fp to point to saved fp. | 684 // Adjust fp to point to saved fp. |
| 728 addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); | 685 addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); |
| 729 for (int i = 0; i < kNoCodeAgeSequenceNops; i++) { | 686 for (int i = 0; i < kNoCodeAgeSequenceNops; i++) { |
| 730 nop(); | 687 nop(); |
| 731 } | 688 } |
| 732 } | 689 } |
| 733 } | 690 } |
| 734 if (FLAG_enable_embedded_constant_pool) { | |
| 735 // ip contains prologue address | |
| 736 LoadConstantPoolPointerRegister(ip, -prologue_offset); | |
| 737 set_constant_pool_available(true); | |
| 738 } | |
| 739 } | 691 } |
| 740 | 692 |
| 741 | 693 |
| 742 void MacroAssembler::EnterFrame(StackFrame::Type type, | 694 void MacroAssembler::EnterFrame(StackFrame::Type type, |
| 743 bool load_constant_pool_pointer_reg) { | 695 bool load_constant_pool_pointer_reg) { |
| 744 if (FLAG_enable_embedded_constant_pool && load_constant_pool_pointer_reg) { | 696 LoadSmiLiteral(ip, Smi::FromInt(type)); |
| 745 PushFixedFrame(); | 697 PushFixedFrame(ip); |
| 746 // This path should not rely on ip containing code entry. | |
| 747 LoadConstantPoolPointerRegister(); | |
| 748 LoadSmiLiteral(ip, Smi::FromInt(type)); | |
| 749 push(ip); | |
| 750 } else { | |
| 751 LoadSmiLiteral(ip, Smi::FromInt(type)); | |
| 752 PushFixedFrame(ip); | |
| 753 } | |
| 754 // Adjust FP to point to saved FP. | 698 // Adjust FP to point to saved FP. |
| 755 addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); | 699 addi(fp, sp, Operand(StandardFrameConstants::kFixedFrameSizeFromFp)); |
| 756 | 700 |
| 757 mov(r0, Operand(CodeObject())); | 701 mov(r0, Operand(CodeObject())); |
| 758 push(r0); | 702 push(r0); |
| 759 } | 703 } |
| 760 | 704 |
| 761 | 705 |
| 762 int MacroAssembler::LeaveFrame(StackFrame::Type type, int stack_adjustment) { | 706 int MacroAssembler::LeaveFrame(StackFrame::Type type, int stack_adjustment) { |
| 763 ConstantPoolUnavailableScope constant_pool_unavailable(this); | |
| 764 // r3: preserved | 707 // r3: preserved |
| 765 // r4: preserved | 708 // r4: preserved |
| 766 // r5: preserved | 709 // r5: preserved |
| 767 | 710 |
| 768 // Drop the execution stack down to the frame pointer and restore | 711 // Drop the execution stack down to the frame pointer and restore |
| 769 // the caller's state. | 712 // the caller's state. |
| 770 int frame_ends; | 713 int frame_ends; |
| 771 LoadP(r0, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); | 714 LoadP(r0, MemOperand(fp, StandardFrameConstants::kCallerPCOffset)); |
| 772 LoadP(ip, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); | 715 LoadP(ip, MemOperand(fp, StandardFrameConstants::kCallerFPOffset)); |
| 773 if (FLAG_enable_embedded_constant_pool) { | |
| 774 const int exitOffset = ExitFrameConstants::kConstantPoolOffset; | |
| 775 const int standardOffset = StandardFrameConstants::kConstantPoolOffset; | |
| 776 const int offset = | |
| 777 ((type == StackFrame::EXIT) ? exitOffset : standardOffset); | |
| 778 LoadP(kConstantPoolRegister, MemOperand(fp, offset)); | |
| 779 } | |
| 780 mtlr(r0); | 716 mtlr(r0); |
| 781 frame_ends = pc_offset(); | 717 frame_ends = pc_offset(); |
| 782 Add(sp, fp, StandardFrameConstants::kCallerSPOffset + stack_adjustment, r0); | 718 Add(sp, fp, StandardFrameConstants::kCallerSPOffset + stack_adjustment, r0); |
| 783 mr(fp, ip); | 719 mr(fp, ip); |
| 784 return frame_ends; | 720 return frame_ends; |
| 785 } | 721 } |
| 786 | 722 |
| 787 | 723 |
| 788 // ExitFrame layout (probably wrongish.. needs updating) | 724 // ExitFrame layout (probably wrongish.. needs updating) |
| 789 // | 725 // |
| (...skipping 26 matching lines...) Expand all Loading... |
| 816 mflr(r0); | 752 mflr(r0); |
| 817 Push(r0, fp); | 753 Push(r0, fp); |
| 818 mr(fp, sp); | 754 mr(fp, sp); |
| 819 // Reserve room for saved entry sp and code object. | 755 // Reserve room for saved entry sp and code object. |
| 820 subi(sp, sp, Operand(ExitFrameConstants::kFrameSize)); | 756 subi(sp, sp, Operand(ExitFrameConstants::kFrameSize)); |
| 821 | 757 |
| 822 if (emit_debug_code()) { | 758 if (emit_debug_code()) { |
| 823 li(r8, Operand::Zero()); | 759 li(r8, Operand::Zero()); |
| 824 StoreP(r8, MemOperand(fp, ExitFrameConstants::kSPOffset)); | 760 StoreP(r8, MemOperand(fp, ExitFrameConstants::kSPOffset)); |
| 825 } | 761 } |
| 826 if (FLAG_enable_embedded_constant_pool) { | |
| 827 StoreP(kConstantPoolRegister, | |
| 828 MemOperand(fp, ExitFrameConstants::kConstantPoolOffset)); | |
| 829 } | |
| 830 mov(r8, Operand(CodeObject())); | 762 mov(r8, Operand(CodeObject())); |
| 831 StoreP(r8, MemOperand(fp, ExitFrameConstants::kCodeOffset)); | 763 StoreP(r8, MemOperand(fp, ExitFrameConstants::kCodeOffset)); |
| 832 | 764 |
| 833 // Save the frame pointer and the context in top. | 765 // Save the frame pointer and the context in top. |
| 834 mov(r8, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); | 766 mov(r8, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); |
| 835 StoreP(fp, MemOperand(r8)); | 767 StoreP(fp, MemOperand(r8)); |
| 836 mov(r8, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); | 768 mov(r8, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); |
| 837 StoreP(cp, MemOperand(r8)); | 769 StoreP(cp, MemOperand(r8)); |
| 838 | 770 |
| 839 // Optionally save all volatile double registers. | 771 // Optionally save all volatile double registers. |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 889 // if the target platform will need alignment, so this is controlled from a | 821 // if the target platform will need alignment, so this is controlled from a |
| 890 // flag. | 822 // flag. |
| 891 return FLAG_sim_stack_alignment; | 823 return FLAG_sim_stack_alignment; |
| 892 #endif | 824 #endif |
| 893 } | 825 } |
| 894 | 826 |
| 895 | 827 |
| 896 void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count, | 828 void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count, |
| 897 bool restore_context, | 829 bool restore_context, |
| 898 bool argument_count_is_length) { | 830 bool argument_count_is_length) { |
| 899 ConstantPoolUnavailableScope constant_pool_unavailable(this); | |
| 900 // Optionally restore all double registers. | 831 // Optionally restore all double registers. |
| 901 if (save_doubles) { | 832 if (save_doubles) { |
| 902 // Calculate the stack location of the saved doubles and restore them. | 833 // Calculate the stack location of the saved doubles and restore them. |
| 903 const int kNumRegs = DoubleRegister::kNumVolatileRegisters; | 834 const int kNumRegs = DoubleRegister::kNumVolatileRegisters; |
| 904 const int offset = | 835 const int offset = |
| 905 (ExitFrameConstants::kFrameSize + kNumRegs * kDoubleSize); | 836 (ExitFrameConstants::kFrameSize + kNumRegs * kDoubleSize); |
| 906 addi(r6, fp, Operand(-offset)); | 837 addi(r6, fp, Operand(-offset)); |
| 907 RestoreFPRegs(r6, 0, kNumRegs); | 838 RestoreFPRegs(r6, 0, kNumRegs); |
| 908 } | 839 } |
| 909 | 840 |
| (...skipping 2329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3239 isync(); | 3170 isync(); |
| 3240 | 3171 |
| 3241 bind(&done); | 3172 bind(&done); |
| 3242 } | 3173 } |
| 3243 | 3174 |
| 3244 | 3175 |
| 3245 void MacroAssembler::SetRelocatedValue(Register location, Register scratch, | 3176 void MacroAssembler::SetRelocatedValue(Register location, Register scratch, |
| 3246 Register new_value) { | 3177 Register new_value) { |
| 3247 lwz(scratch, MemOperand(location)); | 3178 lwz(scratch, MemOperand(location)); |
| 3248 | 3179 |
| 3249 if (FLAG_enable_embedded_constant_pool) { | |
| 3250 if (emit_debug_code()) { | |
| 3251 // Check that the instruction sequence is a load from the constant pool | |
| 3252 ExtractBitMask(scratch, scratch, 0x1f * B16); | |
| 3253 cmpi(scratch, Operand(kConstantPoolRegister.code())); | |
| 3254 Check(eq, kTheInstructionToPatchShouldBeALoadFromConstantPool); | |
| 3255 // Scratch was clobbered. Restore it. | |
| 3256 lwz(scratch, MemOperand(location)); | |
| 3257 } | |
| 3258 // Get the address of the constant and patch it. | |
| 3259 andi(scratch, scratch, Operand(kImm16Mask)); | |
| 3260 StorePX(new_value, MemOperand(kConstantPoolRegister, scratch)); | |
| 3261 return; | |
| 3262 } | |
| 3263 | |
| 3264 // This code assumes a FIXED_SEQUENCE for lis/ori | 3180 // This code assumes a FIXED_SEQUENCE for lis/ori |
| 3265 | 3181 |
| 3266 // At this point scratch is a lis instruction. | 3182 // At this point scratch is a lis instruction. |
| 3267 if (emit_debug_code()) { | 3183 if (emit_debug_code()) { |
| 3268 And(scratch, scratch, Operand(kOpcodeMask | (0x1f * B16))); | 3184 And(scratch, scratch, Operand(kOpcodeMask | (0x1f * B16))); |
| 3269 Cmpi(scratch, Operand(ADDIS), r0); | 3185 Cmpi(scratch, Operand(ADDIS), r0); |
| 3270 Check(eq, kTheInstructionToPatchShouldBeALis); | 3186 Check(eq, kTheInstructionToPatchShouldBeALis); |
| 3271 lwz(scratch, MemOperand(location)); | 3187 lwz(scratch, MemOperand(location)); |
| 3272 } | 3188 } |
| 3273 | 3189 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3337 #else | 3253 #else |
| 3338 FlushICache(location, 2 * kInstrSize, scratch); | 3254 FlushICache(location, 2 * kInstrSize, scratch); |
| 3339 #endif | 3255 #endif |
| 3340 } | 3256 } |
| 3341 | 3257 |
| 3342 | 3258 |
| 3343 void MacroAssembler::GetRelocatedValue(Register location, Register result, | 3259 void MacroAssembler::GetRelocatedValue(Register location, Register result, |
| 3344 Register scratch) { | 3260 Register scratch) { |
| 3345 lwz(result, MemOperand(location)); | 3261 lwz(result, MemOperand(location)); |
| 3346 | 3262 |
| 3347 if (FLAG_enable_embedded_constant_pool) { | |
| 3348 if (emit_debug_code()) { | |
| 3349 // Check that the instruction sequence is a load from the constant pool | |
| 3350 ExtractBitMask(result, result, 0x1f * B16); | |
| 3351 cmpi(result, Operand(kConstantPoolRegister.code())); | |
| 3352 Check(eq, kTheInstructionToPatchShouldBeALoadFromConstantPool); | |
| 3353 lwz(result, MemOperand(location)); | |
| 3354 } | |
| 3355 // Get the address of the constant and retrieve it. | |
| 3356 andi(result, result, Operand(kImm16Mask)); | |
| 3357 LoadPX(result, MemOperand(kConstantPoolRegister, result)); | |
| 3358 return; | |
| 3359 } | |
| 3360 | |
| 3361 // This code assumes a FIXED_SEQUENCE for lis/ori | 3263 // This code assumes a FIXED_SEQUENCE for lis/ori |
| 3362 if (emit_debug_code()) { | 3264 if (emit_debug_code()) { |
| 3363 And(result, result, Operand(kOpcodeMask | (0x1f * B16))); | 3265 And(result, result, Operand(kOpcodeMask | (0x1f * B16))); |
| 3364 Cmpi(result, Operand(ADDIS), r0); | 3266 Cmpi(result, Operand(ADDIS), r0); |
| 3365 Check(eq, kTheInstructionShouldBeALis); | 3267 Check(eq, kTheInstructionShouldBeALis); |
| 3366 lwz(result, MemOperand(location)); | 3268 lwz(result, MemOperand(location)); |
| 3367 } | 3269 } |
| 3368 | 3270 |
| 3369 // result now holds a lis instruction. Extract the immediate. | 3271 // result now holds a lis instruction. Extract the immediate. |
| 3370 slwi(result, result, Operand(16)); | 3272 slwi(result, result, Operand(16)); |
| (...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3788 } | 3690 } |
| 3789 | 3691 |
| 3790 | 3692 |
| 3791 void MacroAssembler::LoadSmiLiteral(Register dst, Smi* smi) { | 3693 void MacroAssembler::LoadSmiLiteral(Register dst, Smi* smi) { |
| 3792 mov(dst, Operand(smi)); | 3694 mov(dst, Operand(smi)); |
| 3793 } | 3695 } |
| 3794 | 3696 |
| 3795 | 3697 |
| 3796 void MacroAssembler::LoadDoubleLiteral(DoubleRegister result, double value, | 3698 void MacroAssembler::LoadDoubleLiteral(DoubleRegister result, double value, |
| 3797 Register scratch) { | 3699 Register scratch) { |
| 3798 if (FLAG_enable_embedded_constant_pool && is_constant_pool_available() && | |
| 3799 !(scratch.is(r0) && ConstantPoolAccessIsInOverflow())) { | |
| 3800 ConstantPoolEntry::Access access = ConstantPoolAddEntry(value); | |
| 3801 if (access == ConstantPoolEntry::OVERFLOWED) { | |
| 3802 addis(scratch, kConstantPoolRegister, Operand::Zero()); | |
| 3803 lfd(result, MemOperand(scratch, 0)); | |
| 3804 } else { | |
| 3805 lfd(result, MemOperand(kConstantPoolRegister, 0)); | |
| 3806 } | |
| 3807 return; | |
| 3808 } | |
| 3809 | |
| 3810 // avoid gcc strict aliasing error using union cast | 3700 // avoid gcc strict aliasing error using union cast |
| 3811 union { | 3701 union { |
| 3812 double dval; | 3702 double dval; |
| 3813 #if V8_TARGET_ARCH_PPC64 | 3703 #if V8_TARGET_ARCH_PPC64 |
| 3814 intptr_t ival; | 3704 intptr_t ival; |
| 3815 #else | 3705 #else |
| 3816 intptr_t ival[2]; | 3706 intptr_t ival[2]; |
| 3817 #endif | 3707 #endif |
| 3818 } litVal; | 3708 } litVal; |
| 3819 | 3709 |
| (...skipping 815 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4635 } | 4525 } |
| 4636 if (mag.shift > 0) srawi(result, result, mag.shift); | 4526 if (mag.shift > 0) srawi(result, result, mag.shift); |
| 4637 ExtractBit(r0, dividend, 31); | 4527 ExtractBit(r0, dividend, 31); |
| 4638 add(result, result, r0); | 4528 add(result, result, r0); |
| 4639 } | 4529 } |
| 4640 | 4530 |
| 4641 } // namespace internal | 4531 } // namespace internal |
| 4642 } // namespace v8 | 4532 } // namespace v8 |
| 4643 | 4533 |
| 4644 #endif // V8_TARGET_ARCH_PPC | 4534 #endif // V8_TARGET_ARCH_PPC |
| OLD | NEW |