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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 } | 217 } |
218 | 218 |
219 | 219 |
220 void MacroAssembler::Move(DoubleRegister dst, DoubleRegister src) { | 220 void MacroAssembler::Move(DoubleRegister dst, DoubleRegister src) { |
221 if (!dst.is(src)) { | 221 if (!dst.is(src)) { |
222 fmr(dst, src); | 222 fmr(dst, src); |
223 } | 223 } |
224 } | 224 } |
225 | 225 |
226 | 226 |
227 void MacroAssembler::MultiPush(RegList regs) { | 227 void MacroAssembler::MultiPush(RegList regs, Register location) { |
228 int16_t num_to_push = NumberOfBitsSet(regs); | 228 int16_t num_to_push = NumberOfBitsSet(regs); |
229 int16_t stack_offset = num_to_push * kPointerSize; | 229 int16_t stack_offset = num_to_push * kPointerSize; |
230 | 230 |
231 subi(sp, sp, Operand(stack_offset)); | 231 subi(location, location, Operand(stack_offset)); |
232 for (int16_t i = kNumRegisters - 1; i >= 0; i--) { | 232 for (int16_t i = Register::kNumRegisters - 1; i >= 0; i--) { |
233 if ((regs & (1 << i)) != 0) { | 233 if ((regs & (1 << i)) != 0) { |
234 stack_offset -= kPointerSize; | 234 stack_offset -= kPointerSize; |
235 StoreP(ToRegister(i), MemOperand(sp, stack_offset)); | 235 StoreP(ToRegister(i), MemOperand(location, stack_offset)); |
236 } | 236 } |
237 } | 237 } |
238 } | 238 } |
239 | 239 |
240 | 240 |
241 void MacroAssembler::MultiPop(RegList regs) { | 241 void MacroAssembler::MultiPop(RegList regs, Register location) { |
242 int16_t stack_offset = 0; | 242 int16_t stack_offset = 0; |
243 | 243 |
244 for (int16_t i = 0; i < kNumRegisters; i++) { | 244 for (int16_t i = 0; i < Register::kNumRegisters; i++) { |
245 if ((regs & (1 << i)) != 0) { | 245 if ((regs & (1 << i)) != 0) { |
246 LoadP(ToRegister(i), MemOperand(sp, stack_offset)); | 246 LoadP(ToRegister(i), MemOperand(location, stack_offset)); |
247 stack_offset += kPointerSize; | 247 stack_offset += kPointerSize; |
248 } | 248 } |
249 } | 249 } |
250 addi(sp, sp, Operand(stack_offset)); | 250 addi(location, location, Operand(stack_offset)); |
251 } | 251 } |
252 | 252 |
253 | 253 |
| 254 void MacroAssembler::MultiPushDoubles(RegList dregs, Register location) { |
| 255 int16_t num_to_push = NumberOfBitsSet(dregs); |
| 256 int16_t stack_offset = num_to_push * kDoubleSize; |
| 257 |
| 258 subi(location, location, Operand(stack_offset)); |
| 259 for (int16_t i = DoubleRegister::kNumRegisters - 1; i >= 0; i--) { |
| 260 if ((dregs & (1 << i)) != 0) { |
| 261 DoubleRegister dreg = DoubleRegister::from_code(i); |
| 262 stack_offset -= kDoubleSize; |
| 263 stfd(dreg, MemOperand(location, stack_offset)); |
| 264 } |
| 265 } |
| 266 } |
| 267 |
| 268 |
| 269 void MacroAssembler::MultiPopDoubles(RegList dregs, Register location) { |
| 270 int16_t stack_offset = 0; |
| 271 |
| 272 for (int16_t i = 0; i < DoubleRegister::kNumRegisters; i++) { |
| 273 if ((dregs & (1 << i)) != 0) { |
| 274 DoubleRegister dreg = DoubleRegister::from_code(i); |
| 275 lfd(dreg, MemOperand(location, stack_offset)); |
| 276 stack_offset += kDoubleSize; |
| 277 } |
| 278 } |
| 279 addi(location, location, Operand(stack_offset)); |
| 280 } |
| 281 |
| 282 |
254 void MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index, | 283 void MacroAssembler::LoadRoot(Register destination, Heap::RootListIndex index, |
255 Condition cond) { | 284 Condition cond) { |
256 DCHECK(cond == al); | 285 DCHECK(cond == al); |
257 LoadP(destination, MemOperand(kRootRegister, index << kPointerSizeLog2), r0); | 286 LoadP(destination, MemOperand(kRootRegister, index << kPointerSizeLog2), r0); |
258 } | 287 } |
259 | 288 |
260 | 289 |
261 void MacroAssembler::StoreRoot(Register source, Heap::RootListIndex index, | 290 void MacroAssembler::StoreRoot(Register source, Heap::RootListIndex index, |
262 Condition cond) { | 291 Condition cond) { |
263 DCHECK(Heap::RootCanBeWrittenAfterInitialization(index)); | 292 DCHECK(Heap::RootCanBeWrittenAfterInitialization(index)); |
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
818 StoreP(r8, MemOperand(fp, ExitFrameConstants::kCodeOffset)); | 847 StoreP(r8, MemOperand(fp, ExitFrameConstants::kCodeOffset)); |
819 | 848 |
820 // Save the frame pointer and the context in top. | 849 // Save the frame pointer and the context in top. |
821 mov(r8, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); | 850 mov(r8, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); |
822 StoreP(fp, MemOperand(r8)); | 851 StoreP(fp, MemOperand(r8)); |
823 mov(r8, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); | 852 mov(r8, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); |
824 StoreP(cp, MemOperand(r8)); | 853 StoreP(cp, MemOperand(r8)); |
825 | 854 |
826 // Optionally save all volatile double registers. | 855 // Optionally save all volatile double registers. |
827 if (save_doubles) { | 856 if (save_doubles) { |
828 SaveFPRegs(sp, 0, DoubleRegister::kNumVolatileRegisters); | 857 MultiPushDoubles(kCallerSavedDoubles); |
829 // Note that d0 will be accessible at | 858 // Note that d0 will be accessible at |
830 // fp - ExitFrameConstants::kFrameSize - | 859 // fp - ExitFrameConstants::kFrameSize - |
831 // kNumVolatileRegisters * kDoubleSize, | 860 // kNumVolatileRegisters * kDoubleSize, |
832 // since the sp slot and code slot were pushed after the fp. | 861 // since the sp slot and code slot were pushed after the fp. |
833 } | 862 } |
834 | 863 |
835 addi(sp, sp, Operand(-stack_space * kPointerSize)); | 864 addi(sp, sp, Operand(-stack_space * kPointerSize)); |
836 | 865 |
837 // Allocate and align the frame preparing for calling the runtime | 866 // Allocate and align the frame preparing for calling the runtime |
838 // function. | 867 // function. |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
884 bool restore_context, | 913 bool restore_context, |
885 bool argument_count_is_length) { | 914 bool argument_count_is_length) { |
886 ConstantPoolUnavailableScope constant_pool_unavailable(this); | 915 ConstantPoolUnavailableScope constant_pool_unavailable(this); |
887 // Optionally restore all double registers. | 916 // Optionally restore all double registers. |
888 if (save_doubles) { | 917 if (save_doubles) { |
889 // Calculate the stack location of the saved doubles and restore them. | 918 // Calculate the stack location of the saved doubles and restore them. |
890 const int kNumRegs = DoubleRegister::kNumVolatileRegisters; | 919 const int kNumRegs = DoubleRegister::kNumVolatileRegisters; |
891 const int offset = | 920 const int offset = |
892 (ExitFrameConstants::kFrameSize + kNumRegs * kDoubleSize); | 921 (ExitFrameConstants::kFrameSize + kNumRegs * kDoubleSize); |
893 addi(r6, fp, Operand(-offset)); | 922 addi(r6, fp, Operand(-offset)); |
894 RestoreFPRegs(r6, 0, kNumRegs); | 923 MultiPopDoubles(kCallerSavedDoubles, r6); |
895 } | 924 } |
896 | 925 |
897 // Clear top frame. | 926 // Clear top frame. |
898 li(r6, Operand::Zero()); | 927 li(r6, Operand::Zero()); |
899 mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); | 928 mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate()))); |
900 StoreP(r6, MemOperand(ip)); | 929 StoreP(r6, MemOperand(ip)); |
901 | 930 |
902 // Restore current context from top and clear it in debug mode. | 931 // Restore current context from top and clear it in debug mode. |
903 if (restore_context) { | 932 if (restore_context) { |
904 mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); | 933 mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate()))); |
(...skipping 2043 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2948 Register filler) { | 2977 Register filler) { |
2949 Label done; | 2978 Label done; |
2950 sub(r0, end_offset, start_offset, LeaveOE, SetRC); | 2979 sub(r0, end_offset, start_offset, LeaveOE, SetRC); |
2951 beq(&done, cr0); | 2980 beq(&done, cr0); |
2952 ShiftRightImm(r0, r0, Operand(kPointerSizeLog2)); | 2981 ShiftRightImm(r0, r0, Operand(kPointerSizeLog2)); |
2953 InitializeNFieldsWithFiller(start_offset, r0, filler); | 2982 InitializeNFieldsWithFiller(start_offset, r0, filler); |
2954 bind(&done); | 2983 bind(&done); |
2955 } | 2984 } |
2956 | 2985 |
2957 | 2986 |
2958 void MacroAssembler::SaveFPRegs(Register location, int first, int count) { | |
2959 DCHECK(count > 0); | |
2960 int cur = first; | |
2961 subi(location, location, Operand(count * kDoubleSize)); | |
2962 for (int i = 0; i < count; i++) { | |
2963 DoubleRegister reg = DoubleRegister::from_code(cur++); | |
2964 stfd(reg, MemOperand(location, i * kDoubleSize)); | |
2965 } | |
2966 } | |
2967 | |
2968 | |
2969 void MacroAssembler::RestoreFPRegs(Register location, int first, int count) { | |
2970 DCHECK(count > 0); | |
2971 int cur = first + count - 1; | |
2972 for (int i = count - 1; i >= 0; i--) { | |
2973 DoubleRegister reg = DoubleRegister::from_code(cur--); | |
2974 lfd(reg, MemOperand(location, i * kDoubleSize)); | |
2975 } | |
2976 addi(location, location, Operand(count * kDoubleSize)); | |
2977 } | |
2978 | |
2979 | |
2980 void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte( | 2987 void MacroAssembler::JumpIfBothInstanceTypesAreNotSequentialOneByte( |
2981 Register first, Register second, Register scratch1, Register scratch2, | 2988 Register first, Register second, Register scratch1, Register scratch2, |
2982 Label* failure) { | 2989 Label* failure) { |
2983 const int kFlatOneByteStringMask = | 2990 const int kFlatOneByteStringMask = |
2984 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; | 2991 kIsNotStringMask | kStringEncodingMask | kStringRepresentationMask; |
2985 const int kFlatOneByteStringTag = | 2992 const int kFlatOneByteStringTag = |
2986 kStringTag | kOneByteStringTag | kSeqStringTag; | 2993 kStringTag | kOneByteStringTag | kSeqStringTag; |
2987 andi(scratch1, first, Operand(kFlatOneByteStringMask)); | 2994 andi(scratch1, first, Operand(kFlatOneByteStringMask)); |
2988 andi(scratch2, second, Operand(kFlatOneByteStringMask)); | 2995 andi(scratch2, second, Operand(kFlatOneByteStringMask)); |
2989 cmpi(scratch1, Operand(kFlatOneByteStringTag)); | 2996 cmpi(scratch1, Operand(kFlatOneByteStringTag)); |
(...skipping 1652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4642 } | 4649 } |
4643 if (mag.shift > 0) srawi(result, result, mag.shift); | 4650 if (mag.shift > 0) srawi(result, result, mag.shift); |
4644 ExtractBit(r0, dividend, 31); | 4651 ExtractBit(r0, dividend, 31); |
4645 add(result, result, r0); | 4652 add(result, result, r0); |
4646 } | 4653 } |
4647 | 4654 |
4648 } // namespace internal | 4655 } // namespace internal |
4649 } // namespace v8 | 4656 } // namespace v8 |
4650 | 4657 |
4651 #endif // V8_TARGET_ARCH_PPC | 4658 #endif // V8_TARGET_ARCH_PPC |
OLD | NEW |