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