OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
894 // store the registers in any particular way, but we do have to store and | 894 // store the registers in any particular way, but we do have to store and |
895 // restore them. | 895 // restore them. |
896 for (int i = 0; i < kNumberOfSavedRegs; i++) { | 896 for (int i = 0; i < kNumberOfSavedRegs; i++) { |
897 Register reg = saved_regs[i]; | 897 Register reg = saved_regs[i]; |
898 if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) { | 898 if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) { |
899 push(reg); | 899 push(reg); |
900 } | 900 } |
901 } | 901 } |
902 // R12 to r15 are callee save on all platforms. | 902 // R12 to r15 are callee save on all platforms. |
903 if (fp_mode == kSaveFPRegs) { | 903 if (fp_mode == kSaveFPRegs) { |
904 subq(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters)); | 904 subq(rsp, Immediate(kFloat32x4Size * XMMRegister::kMaxNumRegisters)); |
905 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { | 905 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { |
906 XMMRegister reg = XMMRegister::from_code(i); | 906 XMMRegister reg = XMMRegister::from_code(i); |
907 movsd(Operand(rsp, i * kDoubleSize), reg); | 907 movups(Operand(rsp, i * kFloat32x4Size), reg); |
908 } | 908 } |
909 } | 909 } |
910 } | 910 } |
911 | 911 |
912 | 912 |
913 void MacroAssembler::PopCallerSaved(SaveFPRegsMode fp_mode, | 913 void MacroAssembler::PopCallerSaved(SaveFPRegsMode fp_mode, |
914 Register exclusion1, | 914 Register exclusion1, |
915 Register exclusion2, | 915 Register exclusion2, |
916 Register exclusion3) { | 916 Register exclusion3) { |
917 if (fp_mode == kSaveFPRegs) { | 917 if (fp_mode == kSaveFPRegs) { |
918 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { | 918 for (int i = 0; i < XMMRegister::kMaxNumRegisters; i++) { |
919 XMMRegister reg = XMMRegister::from_code(i); | 919 XMMRegister reg = XMMRegister::from_code(i); |
920 movsd(reg, Operand(rsp, i * kDoubleSize)); | 920 movups(reg, Operand(rsp, i * kFloat32x4Size)); |
921 } | 921 } |
922 addq(rsp, Immediate(kDoubleSize * XMMRegister::kMaxNumRegisters)); | 922 addq(rsp, Immediate(kFloat32x4Size * XMMRegister::kMaxNumRegisters)); |
923 } | 923 } |
924 for (int i = kNumberOfSavedRegs - 1; i >= 0; i--) { | 924 for (int i = kNumberOfSavedRegs - 1; i >= 0; i--) { |
925 Register reg = saved_regs[i]; | 925 Register reg = saved_regs[i]; |
926 if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) { | 926 if (!reg.is(exclusion1) && !reg.is(exclusion2) && !reg.is(exclusion3)) { |
927 pop(reg); | 927 pop(reg); |
928 } | 928 } |
929 } | 929 } |
930 } | 930 } |
931 | 931 |
932 | 932 |
(...skipping 1437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2370 bind(&load_result_from_cache); | 2370 bind(&load_result_from_cache); |
2371 movq(result, | 2371 movq(result, |
2372 FieldOperand(number_string_cache, | 2372 FieldOperand(number_string_cache, |
2373 index, | 2373 index, |
2374 times_1, | 2374 times_1, |
2375 FixedArray::kHeaderSize + kPointerSize)); | 2375 FixedArray::kHeaderSize + kPointerSize)); |
2376 IncrementCounter(isolate()->counters()->number_to_string_native(), 1); | 2376 IncrementCounter(isolate()->counters()->number_to_string_native(), 1); |
2377 } | 2377 } |
2378 | 2378 |
2379 | 2379 |
| 2380 void MacroAssembler::absps(XMMRegister dst) { |
| 2381 static const struct V8_ALIGNED(16) { |
| 2382 uint32_t a; |
| 2383 uint32_t b; |
| 2384 uint32_t c; |
| 2385 uint32_t d; |
| 2386 } float_absolute_constant = |
| 2387 { 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF }; |
| 2388 Set(kScratchRegister, reinterpret_cast<intptr_t>(&float_absolute_constant)); |
| 2389 andps(dst, Operand(kScratchRegister, 0)); |
| 2390 } |
| 2391 |
| 2392 |
| 2393 void MacroAssembler::negateps(XMMRegister dst) { |
| 2394 static const struct V8_ALIGNED(16) { |
| 2395 uint32_t a; |
| 2396 uint32_t b; |
| 2397 uint32_t c; |
| 2398 uint32_t d; |
| 2399 } float_negate_constant = |
| 2400 { 0x80000000, 0x80000000, 0x80000000, 0x80000000 }; |
| 2401 Set(kScratchRegister, reinterpret_cast<intptr_t>(&float_negate_constant)); |
| 2402 xorps(dst, Operand(kScratchRegister, 0)); |
| 2403 } |
| 2404 |
| 2405 |
| 2406 void MacroAssembler::notps(XMMRegister dst) { |
| 2407 static const struct V8_ALIGNED(16) { |
| 2408 uint32_t a; |
| 2409 uint32_t b; |
| 2410 uint32_t c; |
| 2411 uint32_t d; |
| 2412 } float_not_constant = |
| 2413 { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF }; |
| 2414 Set(kScratchRegister, reinterpret_cast<intptr_t>(&float_not_constant)); |
| 2415 xorps(dst, Operand(kScratchRegister, 0)); |
| 2416 } |
| 2417 |
| 2418 |
| 2419 void MacroAssembler::pnegd(XMMRegister dst) { |
| 2420 static const struct V8_ALIGNED(16) { |
| 2421 uint32_t a; |
| 2422 uint32_t b; |
| 2423 uint32_t c; |
| 2424 uint32_t d; |
| 2425 } int32_one_constant = { 0x1, 0x1, 0x1, 0x1 }; |
| 2426 notps(dst); |
| 2427 Set(kScratchRegister, reinterpret_cast<intptr_t>(&int32_one_constant)); |
| 2428 paddd(dst, Operand(kScratchRegister, 0)); |
| 2429 } |
| 2430 |
| 2431 |
| 2432 |
2380 void MacroAssembler::JumpIfNotString(Register object, | 2433 void MacroAssembler::JumpIfNotString(Register object, |
2381 Register object_map, | 2434 Register object_map, |
2382 Label* not_string, | 2435 Label* not_string, |
2383 Label::Distance near_jump) { | 2436 Label::Distance near_jump) { |
2384 Condition is_smi = CheckSmi(object); | 2437 Condition is_smi = CheckSmi(object); |
2385 j(is_smi, not_string, near_jump); | 2438 j(is_smi, not_string, near_jump); |
2386 CmpObjectType(object, FIRST_NONSTRING_TYPE, object_map); | 2439 CmpObjectType(object, FIRST_NONSTRING_TYPE, object_map); |
2387 j(above_equal, not_string, near_jump); | 2440 j(above_equal, not_string, near_jump); |
2388 } | 2441 } |
2389 | 2442 |
(...skipping 1387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3777 | 3830 |
3778 | 3831 |
3779 void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space, | 3832 void MacroAssembler::EnterExitFrameEpilogue(int arg_stack_space, |
3780 bool save_doubles) { | 3833 bool save_doubles) { |
3781 #ifdef _WIN64 | 3834 #ifdef _WIN64 |
3782 const int kShadowSpace = 4; | 3835 const int kShadowSpace = 4; |
3783 arg_stack_space += kShadowSpace; | 3836 arg_stack_space += kShadowSpace; |
3784 #endif | 3837 #endif |
3785 // Optionally save all XMM registers. | 3838 // Optionally save all XMM registers. |
3786 if (save_doubles) { | 3839 if (save_doubles) { |
3787 int space = XMMRegister::kMaxNumAllocatableRegisters * kDoubleSize + | 3840 int space = XMMRegister::kMaxNumRegisters * kFloat32x4Size + |
3788 arg_stack_space * kPointerSize; | 3841 arg_stack_space * kPointerSize; |
3789 subq(rsp, Immediate(space)); | 3842 subq(rsp, Immediate(space)); |
3790 int offset = -2 * kPointerSize; | 3843 int offset = -2 * kPointerSize; |
3791 for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); i++) { | 3844 for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); i++) { |
3792 XMMRegister reg = XMMRegister::FromAllocationIndex(i); | 3845 XMMRegister reg = XMMRegister::FromAllocationIndex(i); |
3793 movsd(Operand(rbp, offset - ((i + 1) * kDoubleSize)), reg); | 3846 movups(Operand(rbp, offset - ((i + 1) * kFloat32x4Size)), reg); |
3794 } | 3847 } |
3795 } else if (arg_stack_space > 0) { | 3848 } else if (arg_stack_space > 0) { |
3796 subq(rsp, Immediate(arg_stack_space * kPointerSize)); | 3849 subq(rsp, Immediate(arg_stack_space * kPointerSize)); |
3797 } | 3850 } |
3798 | 3851 |
3799 // Get the required frame alignment for the OS. | 3852 // Get the required frame alignment for the OS. |
3800 const int kFrameAlignment = OS::ActivationFrameAlignment(); | 3853 const int kFrameAlignment = OS::ActivationFrameAlignment(); |
3801 if (kFrameAlignment > 0) { | 3854 if (kFrameAlignment > 0) { |
3802 ASSERT(IsPowerOf2(kFrameAlignment)); | 3855 ASSERT(IsPowerOf2(kFrameAlignment)); |
3803 ASSERT(is_int8(kFrameAlignment)); | 3856 ASSERT(is_int8(kFrameAlignment)); |
(...skipping 23 matching lines...) Expand all Loading... |
3827 } | 3880 } |
3828 | 3881 |
3829 | 3882 |
3830 void MacroAssembler::LeaveExitFrame(bool save_doubles) { | 3883 void MacroAssembler::LeaveExitFrame(bool save_doubles) { |
3831 // Registers: | 3884 // Registers: |
3832 // r15 : argv | 3885 // r15 : argv |
3833 if (save_doubles) { | 3886 if (save_doubles) { |
3834 int offset = -2 * kPointerSize; | 3887 int offset = -2 * kPointerSize; |
3835 for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); i++) { | 3888 for (int i = 0; i < XMMRegister::NumAllocatableRegisters(); i++) { |
3836 XMMRegister reg = XMMRegister::FromAllocationIndex(i); | 3889 XMMRegister reg = XMMRegister::FromAllocationIndex(i); |
3837 movsd(reg, Operand(rbp, offset - ((i + 1) * kDoubleSize))); | 3890 movups(reg, Operand(rbp, offset - ((i + 1) * kFloat32x4Size))); |
3838 } | 3891 } |
3839 } | 3892 } |
3840 // Get the return address from the stack and restore the frame pointer. | 3893 // Get the return address from the stack and restore the frame pointer. |
3841 movq(rcx, Operand(rbp, 1 * kPointerSize)); | 3894 movq(rcx, Operand(rbp, 1 * kPointerSize)); |
3842 movq(rbp, Operand(rbp, 0 * kPointerSize)); | 3895 movq(rbp, Operand(rbp, 0 * kPointerSize)); |
3843 | 3896 |
3844 // Drop everything up to and including the arguments and the receiver | 3897 // Drop everything up to and including the arguments and the receiver |
3845 // from the caller stack. | 3898 // from the caller stack. |
3846 lea(rsp, Operand(r15, 1 * kPointerSize)); | 3899 lea(rsp, Operand(r15, 1 * kPointerSize)); |
3847 | 3900 |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4267 Label* gc_required) { | 4320 Label* gc_required) { |
4268 // Allocate heap number in new space. | 4321 // Allocate heap number in new space. |
4269 Allocate(HeapNumber::kSize, result, scratch, no_reg, gc_required, TAG_OBJECT); | 4322 Allocate(HeapNumber::kSize, result, scratch, no_reg, gc_required, TAG_OBJECT); |
4270 | 4323 |
4271 // Set the map. | 4324 // Set the map. |
4272 LoadRoot(kScratchRegister, Heap::kHeapNumberMapRootIndex); | 4325 LoadRoot(kScratchRegister, Heap::kHeapNumberMapRootIndex); |
4273 movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); | 4326 movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); |
4274 } | 4327 } |
4275 | 4328 |
4276 | 4329 |
| 4330 void MacroAssembler::AllocateFloat32x4(Register result, |
| 4331 Register scratch, |
| 4332 Label* gc_required) { |
| 4333 // Allocate heap number in new space. |
| 4334 Allocate(Float32x4::kSize, result, scratch, no_reg, gc_required, TAG_OBJECT); |
| 4335 |
| 4336 // Set the map. |
| 4337 LoadRoot(kScratchRegister, Heap::kFloat32x4MapRootIndex); |
| 4338 movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); |
| 4339 } |
| 4340 |
| 4341 |
| 4342 void MacroAssembler::AllocateInt32x4(Register result, |
| 4343 Register scratch, |
| 4344 Label* gc_required) { |
| 4345 // Allocate heap number in new space. |
| 4346 Allocate(Int32x4::kSize, result, scratch, no_reg, gc_required, TAG_OBJECT); |
| 4347 |
| 4348 // Set the map. |
| 4349 LoadRoot(kScratchRegister, Heap::kInt32x4MapRootIndex); |
| 4350 movq(FieldOperand(result, HeapObject::kMapOffset), kScratchRegister); |
| 4351 } |
| 4352 |
| 4353 |
4277 void MacroAssembler::AllocateTwoByteString(Register result, | 4354 void MacroAssembler::AllocateTwoByteString(Register result, |
4278 Register length, | 4355 Register length, |
4279 Register scratch1, | 4356 Register scratch1, |
4280 Register scratch2, | 4357 Register scratch2, |
4281 Register scratch3, | 4358 Register scratch3, |
4282 Label* gc_required) { | 4359 Label* gc_required) { |
4283 // Calculate the number of bytes needed for the characters in the string while | 4360 // Calculate the number of bytes needed for the characters in the string while |
4284 // observing object alignment. | 4361 // observing object alignment. |
4285 const int kHeaderAlignment = SeqTwoByteString::kHeaderSize & | 4362 const int kHeaderAlignment = SeqTwoByteString::kHeaderSize & |
4286 kObjectAlignmentMask; | 4363 kObjectAlignmentMask; |
(...skipping 768 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5055 j(equal, found); | 5132 j(equal, found); |
5056 movq(current, FieldOperand(current, Map::kPrototypeOffset)); | 5133 movq(current, FieldOperand(current, Map::kPrototypeOffset)); |
5057 CompareRoot(current, Heap::kNullValueRootIndex); | 5134 CompareRoot(current, Heap::kNullValueRootIndex); |
5058 j(not_equal, &loop_again); | 5135 j(not_equal, &loop_again); |
5059 } | 5136 } |
5060 | 5137 |
5061 | 5138 |
5062 } } // namespace v8::internal | 5139 } } // namespace v8::internal |
5063 | 5140 |
5064 #endif // V8_TARGET_ARCH_X64 | 5141 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |