OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 <limits.h> // For LONG_MIN, LONG_MAX. | 5 #include <limits.h> // For LONG_MIN, LONG_MAX. |
6 | 6 |
7 #if V8_TARGET_ARCH_MIPS64 | 7 #if V8_TARGET_ARCH_MIPS64 |
8 | 8 |
9 #include "src/base/division-by-constant.h" | 9 #include "src/base/division-by-constant.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 4639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4650 Register filler) { | 4650 Register filler) { |
4651 Label loop, entry; | 4651 Label loop, entry; |
4652 Branch(&entry); | 4652 Branch(&entry); |
4653 bind(&loop); | 4653 bind(&loop); |
4654 sd(filler, MemOperand(current_address)); | 4654 sd(filler, MemOperand(current_address)); |
4655 Daddu(current_address, current_address, kPointerSize); | 4655 Daddu(current_address, current_address, kPointerSize); |
4656 bind(&entry); | 4656 bind(&entry); |
4657 Branch(&loop, ult, current_address, Operand(end_address)); | 4657 Branch(&loop, ult, current_address, Operand(end_address)); |
4658 } | 4658 } |
4659 | 4659 |
4660 void MacroAssembler::CheckFastObjectElements(Register map, | |
4661 Register scratch, | |
4662 Label* fail) { | |
4663 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | |
4664 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | |
4665 STATIC_ASSERT(FAST_ELEMENTS == 2); | |
4666 STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3); | |
4667 lbu(scratch, FieldMemOperand(map, Map::kBitField2Offset)); | |
4668 Branch(fail, ls, scratch, | |
4669 Operand(Map::kMaximumBitField2FastHoleySmiElementValue)); | |
4670 Branch(fail, hi, scratch, | |
4671 Operand(Map::kMaximumBitField2FastHoleyElementValue)); | |
4672 } | |
4673 | |
4674 | |
4675 void MacroAssembler::CheckFastSmiElements(Register map, | |
4676 Register scratch, | |
4677 Label* fail) { | |
4678 STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); | |
4679 STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); | |
4680 lbu(scratch, FieldMemOperand(map, Map::kBitField2Offset)); | |
4681 Branch(fail, hi, scratch, | |
4682 Operand(Map::kMaximumBitField2FastHoleySmiElementValue)); | |
4683 } | |
4684 | |
4685 | |
4686 void MacroAssembler::StoreNumberToDoubleElements(Register value_reg, | |
4687 Register key_reg, | |
4688 Register elements_reg, | |
4689 Register scratch1, | |
4690 Register scratch2, | |
4691 Label* fail, | |
4692 int elements_offset) { | |
4693 DCHECK(!AreAliased(value_reg, key_reg, elements_reg, scratch1, scratch2)); | |
4694 Label smi_value, done; | |
4695 | |
4696 // Handle smi values specially. | |
4697 JumpIfSmi(value_reg, &smi_value); | |
4698 | |
4699 // Ensure that the object is a heap number. | |
4700 CheckMap(value_reg, | |
4701 scratch1, | |
4702 Heap::kHeapNumberMapRootIndex, | |
4703 fail, | |
4704 DONT_DO_SMI_CHECK); | |
4705 | |
4706 // Double value, turn potential sNaN into qNan. | |
4707 DoubleRegister double_result = f0; | |
4708 DoubleRegister double_scratch = f2; | |
4709 | |
4710 ldc1(double_result, FieldMemOperand(value_reg, HeapNumber::kValueOffset)); | |
4711 Branch(USE_DELAY_SLOT, &done); // Canonicalization is one instruction. | |
4712 FPUCanonicalizeNaN(double_result, double_result); | |
4713 | |
4714 bind(&smi_value); | |
4715 // Untag and transfer. | |
4716 dsrl32(scratch1, value_reg, 0); | |
4717 mtc1(scratch1, double_scratch); | |
4718 cvt_d_w(double_result, double_scratch); | |
4719 | |
4720 bind(&done); | |
4721 Daddu(scratch1, elements_reg, | |
4722 Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag - | |
4723 elements_offset)); | |
4724 dsra(scratch2, key_reg, 32 - kDoubleSizeLog2); | |
4725 Daddu(scratch1, scratch1, scratch2); | |
4726 // scratch1 is now effective address of the double element. | |
4727 sdc1(double_result, MemOperand(scratch1, 0)); | |
4728 } | |
4729 | |
4730 void MacroAssembler::SubNanPreservePayloadAndSign_s(FPURegister fd, | 4660 void MacroAssembler::SubNanPreservePayloadAndSign_s(FPURegister fd, |
4731 FPURegister fs, | 4661 FPURegister fs, |
4732 FPURegister ft) { | 4662 FPURegister ft) { |
4733 FloatRegister dest = fd.is(fs) || fd.is(ft) ? kLithiumScratchDouble : fd; | 4663 FloatRegister dest = fd.is(fs) || fd.is(ft) ? kLithiumScratchDouble : fd; |
4734 Label check_nan, save_payload, done; | 4664 Label check_nan, save_payload, done; |
4735 Register scratch1 = t8; | 4665 Register scratch1 = t8; |
4736 Register scratch2 = t9; | 4666 Register scratch2 = t9; |
4737 | 4667 |
4738 sub_s(dest, fs, ft); | 4668 sub_s(dest, fs, ft); |
4739 // Check if the result of subtraction is NaN. | 4669 // Check if the result of subtraction is NaN. |
(...skipping 1211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5951 ld(dst, MemOperand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX))); | 5881 ld(dst, MemOperand(dst, Context::SlotOffset(Context::PREVIOUS_INDEX))); |
5952 } | 5882 } |
5953 } else { | 5883 } else { |
5954 // Slot is in the current function context. Move it into the | 5884 // Slot is in the current function context. Move it into the |
5955 // destination register in case we store into it (the write barrier | 5885 // destination register in case we store into it (the write barrier |
5956 // cannot be allowed to destroy the context in esi). | 5886 // cannot be allowed to destroy the context in esi). |
5957 Move(dst, cp); | 5887 Move(dst, cp); |
5958 } | 5888 } |
5959 } | 5889 } |
5960 | 5890 |
5961 | |
5962 void MacroAssembler::LoadTransitionedArrayMapConditional( | |
5963 ElementsKind expected_kind, | |
5964 ElementsKind transitioned_kind, | |
5965 Register map_in_out, | |
5966 Register scratch, | |
5967 Label* no_map_match) { | |
5968 DCHECK(IsFastElementsKind(expected_kind)); | |
5969 DCHECK(IsFastElementsKind(transitioned_kind)); | |
5970 | |
5971 // Check that the function's map is the same as the expected cached map. | |
5972 ld(scratch, NativeContextMemOperand()); | |
5973 ld(at, ContextMemOperand(scratch, Context::ArrayMapIndex(expected_kind))); | |
5974 Branch(no_map_match, ne, map_in_out, Operand(at)); | |
5975 | |
5976 // Use the transitioned cached map. | |
5977 ld(map_in_out, | |
5978 ContextMemOperand(scratch, Context::ArrayMapIndex(transitioned_kind))); | |
5979 } | |
5980 | |
5981 | |
5982 void MacroAssembler::LoadNativeContextSlot(int index, Register dst) { | 5891 void MacroAssembler::LoadNativeContextSlot(int index, Register dst) { |
5983 ld(dst, NativeContextMemOperand()); | 5892 ld(dst, NativeContextMemOperand()); |
5984 ld(dst, ContextMemOperand(dst, index)); | 5893 ld(dst, ContextMemOperand(dst, index)); |
5985 } | 5894 } |
5986 | 5895 |
5987 | 5896 |
5988 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, | 5897 void MacroAssembler::LoadGlobalFunctionInitialMap(Register function, |
5989 Register map, | 5898 Register map, |
5990 Register scratch) { | 5899 Register scratch) { |
5991 // Load the initial map. The global functions all have initial maps. | 5900 // Load the initial map. The global functions all have initial maps. |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6360 | 6269 |
6361 | 6270 |
6362 void MacroAssembler::UntagAndJumpIfSmi(Register dst, | 6271 void MacroAssembler::UntagAndJumpIfSmi(Register dst, |
6363 Register src, | 6272 Register src, |
6364 Label* smi_case) { | 6273 Label* smi_case) { |
6365 // DCHECK(!dst.is(src)); | 6274 // DCHECK(!dst.is(src)); |
6366 JumpIfSmi(src, smi_case, at, USE_DELAY_SLOT); | 6275 JumpIfSmi(src, smi_case, at, USE_DELAY_SLOT); |
6367 SmiUntag(dst, src); | 6276 SmiUntag(dst, src); |
6368 } | 6277 } |
6369 | 6278 |
6370 | |
6371 void MacroAssembler::UntagAndJumpIfNotSmi(Register dst, | |
6372 Register src, | |
6373 Label* non_smi_case) { | |
6374 // DCHECK(!dst.is(src)); | |
6375 JumpIfNotSmi(src, non_smi_case, at, USE_DELAY_SLOT); | |
6376 SmiUntag(dst, src); | |
6377 } | |
6378 | |
6379 void MacroAssembler::JumpIfSmi(Register value, | 6279 void MacroAssembler::JumpIfSmi(Register value, |
6380 Label* smi_label, | 6280 Label* smi_label, |
6381 Register scratch, | 6281 Register scratch, |
6382 BranchDelaySlot bd) { | 6282 BranchDelaySlot bd) { |
6383 DCHECK_EQ(0, kSmiTag); | 6283 DCHECK_EQ(0, kSmiTag); |
6384 andi(scratch, value, kSmiTagMask); | 6284 andi(scratch, value, kSmiTagMask); |
6385 Branch(bd, smi_label, eq, scratch, Operand(zero_reg)); | 6285 Branch(bd, smi_label, eq, scratch, Operand(zero_reg)); |
6386 } | 6286 } |
6387 | 6287 |
6388 void MacroAssembler::JumpIfNotSmi(Register value, | 6288 void MacroAssembler::JumpIfNotSmi(Register value, |
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7035 for (int i = 0; i < config->num_allocatable_general_registers(); ++i) { | 6935 for (int i = 0; i < config->num_allocatable_general_registers(); ++i) { |
7036 int code = config->GetAllocatableGeneralCode(i); | 6936 int code = config->GetAllocatableGeneralCode(i); |
7037 Register candidate = Register::from_code(code); | 6937 Register candidate = Register::from_code(code); |
7038 if (regs & candidate.bit()) continue; | 6938 if (regs & candidate.bit()) continue; |
7039 return candidate; | 6939 return candidate; |
7040 } | 6940 } |
7041 UNREACHABLE(); | 6941 UNREACHABLE(); |
7042 return no_reg; | 6942 return no_reg; |
7043 } | 6943 } |
7044 | 6944 |
7045 | |
7046 void MacroAssembler::JumpIfDictionaryInPrototypeChain( | |
7047 Register object, | |
7048 Register scratch0, | |
7049 Register scratch1, | |
7050 Label* found) { | |
7051 DCHECK(!scratch1.is(scratch0)); | |
7052 Factory* factory = isolate()->factory(); | |
7053 Register current = scratch0; | |
7054 Label loop_again, end; | |
7055 | |
7056 // Scratch contained elements pointer. | |
7057 Move(current, object); | |
7058 ld(current, FieldMemOperand(current, HeapObject::kMapOffset)); | |
7059 ld(current, FieldMemOperand(current, Map::kPrototypeOffset)); | |
7060 Branch(&end, eq, current, Operand(factory->null_value())); | |
7061 | |
7062 // Loop based on the map going up the prototype chain. | |
7063 bind(&loop_again); | |
7064 ld(current, FieldMemOperand(current, HeapObject::kMapOffset)); | |
7065 lbu(scratch1, FieldMemOperand(current, Map::kInstanceTypeOffset)); | |
7066 STATIC_ASSERT(JS_VALUE_TYPE < JS_OBJECT_TYPE); | |
7067 STATIC_ASSERT(JS_PROXY_TYPE < JS_OBJECT_TYPE); | |
7068 Branch(found, lo, scratch1, Operand(JS_OBJECT_TYPE)); | |
7069 lb(scratch1, FieldMemOperand(current, Map::kBitField2Offset)); | |
7070 DecodeField<Map::ElementsKindBits>(scratch1); | |
7071 Branch(found, eq, scratch1, Operand(DICTIONARY_ELEMENTS)); | |
7072 ld(current, FieldMemOperand(current, Map::kPrototypeOffset)); | |
7073 Branch(&loop_again, ne, current, Operand(factory->null_value())); | |
7074 | |
7075 bind(&end); | |
7076 } | |
7077 | |
7078 | |
7079 bool AreAliased(Register reg1, Register reg2, Register reg3, Register reg4, | 6945 bool AreAliased(Register reg1, Register reg2, Register reg3, Register reg4, |
7080 Register reg5, Register reg6, Register reg7, Register reg8, | 6946 Register reg5, Register reg6, Register reg7, Register reg8, |
7081 Register reg9, Register reg10) { | 6947 Register reg9, Register reg10) { |
7082 int n_of_valid_regs = reg1.is_valid() + reg2.is_valid() + reg3.is_valid() + | 6948 int n_of_valid_regs = reg1.is_valid() + reg2.is_valid() + reg3.is_valid() + |
7083 reg4.is_valid() + reg5.is_valid() + reg6.is_valid() + | 6949 reg4.is_valid() + reg5.is_valid() + reg6.is_valid() + |
7084 reg7.is_valid() + reg8.is_valid() + reg9.is_valid() + | 6950 reg7.is_valid() + reg8.is_valid() + reg9.is_valid() + |
7085 reg10.is_valid(); | 6951 reg10.is_valid(); |
7086 | 6952 |
7087 RegList regs = 0; | 6953 RegList regs = 0; |
7088 if (reg1.is_valid()) regs |= reg1.bit(); | 6954 if (reg1.is_valid()) regs |= reg1.bit(); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7162 if (mag.shift > 0) sra(result, result, mag.shift); | 7028 if (mag.shift > 0) sra(result, result, mag.shift); |
7163 srl(at, dividend, 31); | 7029 srl(at, dividend, 31); |
7164 Addu(result, result, Operand(at)); | 7030 Addu(result, result, Operand(at)); |
7165 } | 7031 } |
7166 | 7032 |
7167 | 7033 |
7168 } // namespace internal | 7034 } // namespace internal |
7169 } // namespace v8 | 7035 } // namespace v8 |
7170 | 7036 |
7171 #endif // V8_TARGET_ARCH_MIPS64 | 7037 #endif // V8_TARGET_ARCH_MIPS64 |
OLD | NEW |