| 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 |