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 |