| 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" |
| 11 #include "src/base/division-by-constant.h" | 11 #include "src/base/division-by-constant.h" |
| 12 #include "src/bootstrapper.h" | 12 #include "src/bootstrapper.h" |
| 13 #include "src/codegen.h" | 13 #include "src/codegen.h" |
| 14 #include "src/debug/debug.h" | 14 #include "src/debug/debug.h" |
| 15 #include "src/register-configuration.h" |
| 16 #include "src/runtime/runtime.h" |
| 17 |
| 15 #include "src/ppc/macro-assembler-ppc.h" | 18 #include "src/ppc/macro-assembler-ppc.h" |
| 16 #include "src/runtime/runtime.h" | |
| 17 | 19 |
| 18 namespace v8 { | 20 namespace v8 { |
| 19 namespace internal { | 21 namespace internal { |
| 20 | 22 |
| 21 MacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size) | 23 MacroAssembler::MacroAssembler(Isolate* arg_isolate, void* buffer, int size) |
| 22 : Assembler(arg_isolate, buffer, size), | 24 : Assembler(arg_isolate, buffer, size), |
| 23 generating_stub_(false), | 25 generating_stub_(false), |
| 24 has_frame_(false) { | 26 has_frame_(false) { |
| 25 if (isolate() != NULL) { | 27 if (isolate() != NULL) { |
| 26 code_object_ = | 28 code_object_ = |
| (...skipping 530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 } else { | 559 } else { |
| 558 Pop(r0, fp, cp); | 560 Pop(r0, fp, cp); |
| 559 } | 561 } |
| 560 } | 562 } |
| 561 mtlr(r0); | 563 mtlr(r0); |
| 562 } | 564 } |
| 563 | 565 |
| 564 | 566 |
| 565 const RegList MacroAssembler::kSafepointSavedRegisters = Register::kAllocatable; | 567 const RegList MacroAssembler::kSafepointSavedRegisters = Register::kAllocatable; |
| 566 const int MacroAssembler::kNumSafepointSavedRegisters = | 568 const int MacroAssembler::kNumSafepointSavedRegisters = |
| 567 Register::kMaxNumAllocatableRegisters; | 569 Register::kNumAllocatable; |
| 568 | 570 |
| 569 // Push and pop all registers that can hold pointers. | 571 // Push and pop all registers that can hold pointers. |
| 570 void MacroAssembler::PushSafepointRegisters() { | 572 void MacroAssembler::PushSafepointRegisters() { |
| 571 // Safepoints expect a block of kNumSafepointRegisters values on the | 573 // Safepoints expect a block of kNumSafepointRegisters values on the |
| 572 // stack, so adjust the stack for unsaved registers. | 574 // stack, so adjust the stack for unsaved registers. |
| 573 const int num_unsaved = kNumSafepointRegisters - kNumSafepointSavedRegisters; | 575 const int num_unsaved = kNumSafepointRegisters - kNumSafepointSavedRegisters; |
| 574 DCHECK(num_unsaved >= 0); | 576 DCHECK(num_unsaved >= 0); |
| 575 if (num_unsaved > 0) { | 577 if (num_unsaved > 0) { |
| 576 subi(sp, sp, Operand(num_unsaved * kPointerSize)); | 578 subi(sp, sp, Operand(num_unsaved * kPointerSize)); |
| 577 } | 579 } |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 616 } | 618 } |
| 617 | 619 |
| 618 | 620 |
| 619 MemOperand MacroAssembler::SafepointRegisterSlot(Register reg) { | 621 MemOperand MacroAssembler::SafepointRegisterSlot(Register reg) { |
| 620 return MemOperand(sp, SafepointRegisterStackIndex(reg.code()) * kPointerSize); | 622 return MemOperand(sp, SafepointRegisterStackIndex(reg.code()) * kPointerSize); |
| 621 } | 623 } |
| 622 | 624 |
| 623 | 625 |
| 624 MemOperand MacroAssembler::SafepointRegistersAndDoublesSlot(Register reg) { | 626 MemOperand MacroAssembler::SafepointRegistersAndDoublesSlot(Register reg) { |
| 625 // General purpose registers are pushed last on the stack. | 627 // General purpose registers are pushed last on the stack. |
| 626 int doubles_size = DoubleRegister::NumAllocatableRegisters() * kDoubleSize; | 628 const RegisterConfiguration* config = RegisterConfiguration::ArchDefault(); |
| 629 int doubles_size = config->num_allocatable_double_registers() * kDoubleSize; |
| 627 int register_offset = SafepointRegisterStackIndex(reg.code()) * kPointerSize; | 630 int register_offset = SafepointRegisterStackIndex(reg.code()) * kPointerSize; |
| 628 return MemOperand(sp, doubles_size + register_offset); | 631 return MemOperand(sp, doubles_size + register_offset); |
| 629 } | 632 } |
| 630 | 633 |
| 631 | 634 |
| 632 void MacroAssembler::CanonicalizeNaN(const DoubleRegister dst, | 635 void MacroAssembler::CanonicalizeNaN(const DoubleRegister dst, |
| 633 const DoubleRegister src) { | 636 const DoubleRegister src) { |
| 634 // Turn potential sNaN into qNaN. | 637 // Turn potential sNaN into qNaN. |
| 635 fsub(dst, src, kDoubleRegZero); | 638 fsub(dst, src, kDoubleRegZero); |
| 636 } | 639 } |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 856 mov(r8, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); | 859 mov(r8, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); |
| 857 StoreP(fp, MemOperand(r8)); | 860 StoreP(fp, MemOperand(r8)); |
| 858 mov(r8, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); | 861 mov(r8, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); |
| 859 StoreP(cp, MemOperand(r8)); | 862 StoreP(cp, MemOperand(r8)); |
| 860 | 863 |
| 861 // Optionally save all volatile double registers. | 864 // Optionally save all volatile double registers. |
| 862 if (save_doubles) { | 865 if (save_doubles) { |
| 863 MultiPushDoubles(kCallerSavedDoubles); | 866 MultiPushDoubles(kCallerSavedDoubles); |
| 864 // Note that d0 will be accessible at | 867 // Note that d0 will be accessible at |
| 865 // fp - ExitFrameConstants::kFrameSize - | 868 // fp - ExitFrameConstants::kFrameSize - |
| 866 // kNumVolatileRegisters * kDoubleSize, | 869 // kNumCallerSavedDoubles * kDoubleSize, |
| 867 // since the sp slot and code slot were pushed after the fp. | 870 // since the sp slot and code slot were pushed after the fp. |
| 868 } | 871 } |
| 869 | 872 |
| 870 addi(sp, sp, Operand(-stack_space * kPointerSize)); | 873 addi(sp, sp, Operand(-stack_space * kPointerSize)); |
| 871 | 874 |
| 872 // Allocate and align the frame preparing for calling the runtime | 875 // Allocate and align the frame preparing for calling the runtime |
| 873 // function. | 876 // function. |
| 874 const int frame_alignment = ActivationFrameAlignment(); | 877 const int frame_alignment = ActivationFrameAlignment(); |
| 875 if (frame_alignment > kPointerSize) { | 878 if (frame_alignment > kPointerSize) { |
| 876 DCHECK(base::bits::IsPowerOfTwo32(frame_alignment)); | 879 DCHECK(base::bits::IsPowerOfTwo32(frame_alignment)); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 915 } | 918 } |
| 916 | 919 |
| 917 | 920 |
| 918 void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count, | 921 void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count, |
| 919 bool restore_context, | 922 bool restore_context, |
| 920 bool argument_count_is_length) { | 923 bool argument_count_is_length) { |
| 921 ConstantPoolUnavailableScope constant_pool_unavailable(this); | 924 ConstantPoolUnavailableScope constant_pool_unavailable(this); |
| 922 // Optionally restore all double registers. | 925 // Optionally restore all double registers. |
| 923 if (save_doubles) { | 926 if (save_doubles) { |
| 924 // Calculate the stack location of the saved doubles and restore them. | 927 // Calculate the stack location of the saved doubles and restore them. |
| 925 const int kNumRegs = DoubleRegister::kNumVolatileRegisters; | 928 const int kNumRegs = kNumCallerSavedDoubles; |
| 926 const int offset = | 929 const int offset = |
| 927 (ExitFrameConstants::kFrameSize + kNumRegs * kDoubleSize); | 930 (ExitFrameConstants::kFrameSize + kNumRegs * kDoubleSize); |
| 928 addi(r6, fp, Operand(-offset)); | 931 addi(r6, fp, Operand(-offset)); |
| 929 MultiPopDoubles(kCallerSavedDoubles, r6); | 932 MultiPopDoubles(kCallerSavedDoubles, r6); |
| 930 } | 933 } |
| 931 | 934 |
| 932 // Clear top frame. | 935 // Clear top frame. |
| 933 li(r6, Operand::Zero()); | 936 li(r6, Operand::Zero()); |
| 934 mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); | 937 mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); |
| 935 StoreP(r6, MemOperand(ip)); | 938 StoreP(r6, MemOperand(ip)); |
| (...skipping 3307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4243 Register reg4, Register reg5, | 4246 Register reg4, Register reg5, |
| 4244 Register reg6) { | 4247 Register reg6) { |
| 4245 RegList regs = 0; | 4248 RegList regs = 0; |
| 4246 if (reg1.is_valid()) regs |= reg1.bit(); | 4249 if (reg1.is_valid()) regs |= reg1.bit(); |
| 4247 if (reg2.is_valid()) regs |= reg2.bit(); | 4250 if (reg2.is_valid()) regs |= reg2.bit(); |
| 4248 if (reg3.is_valid()) regs |= reg3.bit(); | 4251 if (reg3.is_valid()) regs |= reg3.bit(); |
| 4249 if (reg4.is_valid()) regs |= reg4.bit(); | 4252 if (reg4.is_valid()) regs |= reg4.bit(); |
| 4250 if (reg5.is_valid()) regs |= reg5.bit(); | 4253 if (reg5.is_valid()) regs |= reg5.bit(); |
| 4251 if (reg6.is_valid()) regs |= reg6.bit(); | 4254 if (reg6.is_valid()) regs |= reg6.bit(); |
| 4252 | 4255 |
| 4253 for (int i = 0; i < Register::NumAllocatableRegisters(); i++) { | 4256 const RegisterConfiguration* config = RegisterConfiguration::ArchDefault(); |
| 4254 Register candidate = Register::FromAllocationIndex(i); | 4257 for (int i = 0; i < config->num_allocatable_general_registers(); ++i) { |
| 4258 int code = config->GetAllocatableGeneralCode(i); |
| 4259 Register candidate = Register::from_code(code); |
| 4255 if (regs & candidate.bit()) continue; | 4260 if (regs & candidate.bit()) continue; |
| 4256 return candidate; | 4261 return candidate; |
| 4257 } | 4262 } |
| 4258 UNREACHABLE(); | 4263 UNREACHABLE(); |
| 4259 return no_reg; | 4264 return no_reg; |
| 4260 } | 4265 } |
| 4261 | 4266 |
| 4262 | 4267 |
| 4263 void MacroAssembler::JumpIfDictionaryInPrototypeChain(Register object, | 4268 void MacroAssembler::JumpIfDictionaryInPrototypeChain(Register object, |
| 4264 Register scratch0, | 4269 Register scratch0, |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4382 } | 4387 } |
| 4383 if (mag.shift > 0) srawi(result, result, mag.shift); | 4388 if (mag.shift > 0) srawi(result, result, mag.shift); |
| 4384 ExtractBit(r0, dividend, 31); | 4389 ExtractBit(r0, dividend, 31); |
| 4385 add(result, result, r0); | 4390 add(result, result, r0); |
| 4386 } | 4391 } |
| 4387 | 4392 |
| 4388 } // namespace internal | 4393 } // namespace internal |
| 4389 } // namespace v8 | 4394 } // namespace v8 |
| 4390 | 4395 |
| 4391 #endif // V8_TARGET_ARCH_PPC | 4396 #endif // V8_TARGET_ARCH_PPC |
| OLD | NEW |