Index: src/mips/macro-assembler-mips.cc |
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc |
index 6e7c28caebc0381dc42b148bf736ecf84feba9f6..2964fbc86c6effb1c67ebf500f1f37288ea07922 100644 |
--- a/src/mips/macro-assembler-mips.cc |
+++ b/src/mips/macro-assembler-mips.cc |
@@ -279,11 +279,18 @@ void MacroAssembler::RecordWrite(Register object, |
} |
-void MacroAssembler::RememberedSetHelper(Register address, |
+void MacroAssembler::RememberedSetHelper(Register object, // For debug tests. |
+ Register address, |
Register scratch, |
SaveFPRegsMode fp_mode, |
RememberedSetFinalAction and_then) { |
Label done; |
+ if (FLAG_debug_code) { |
+ Label ok; |
+ JumpIfNotInNewSpace(object, scratch, &ok); |
+ stop("Remembered set pointer is in new space"); |
+ bind(&ok); |
+ } |
// Load store buffer top. |
ExternalReference store_buffer = |
ExternalReference::store_buffer_top(isolate()); |
@@ -301,7 +308,7 @@ void MacroAssembler::RememberedSetHelper(Register address, |
Branch(&done, eq, t8, Operand(zero_reg)); |
} else { |
ASSERT(and_then == kReturnAtEnd); |
- Ret(ne, t8, Operand(zero_reg)); |
+ Ret(eq, t8, Operand(zero_reg)); |
} |
push(ra); |
StoreBufferOverflowStub store_buffer_overflow = |
@@ -809,7 +816,7 @@ void MacroAssembler::MultiPushFPU(RegList regs) { |
int16_t stack_offset = num_to_push * kDoubleSize; |
Subu(sp, sp, Operand(stack_offset)); |
- for (int16_t i = kNumRegisters; i > 0; i--) { |
+ for (int16_t i = kNumRegisters - 1; i >= 0; i--) { |
if ((regs & (1 << i)) != 0) { |
stack_offset -= kDoubleSize; |
sdc1(FPURegister::from_code(i), MemOperand(sp, stack_offset)); |
@@ -851,7 +858,7 @@ void MacroAssembler::MultiPopReversedFPU(RegList regs) { |
CpuFeatures::Scope scope(FPU); |
int16_t stack_offset = 0; |
- for (int16_t i = kNumRegisters; i > 0; i--) { |
+ for (int16_t i = kNumRegisters - 1; i >= 0; i--) { |
if ((regs & (1 << i)) != 0) { |
ldc1(FPURegister::from_code(i), MemOperand(sp, stack_offset)); |
stack_offset += kDoubleSize; |
@@ -3203,6 +3210,19 @@ void MacroAssembler::CopyBytes(Register src, |
} |
+void MacroAssembler::InitializeFieldsWithFiller(Register start_offset, |
+ Register end_offset, |
+ Register filler) { |
+ Label loop, entry; |
+ Branch(&entry); |
+ bind(&loop); |
+ sw(filler, MemOperand(start_offset)); |
+ Addu(start_offset, start_offset, kPointerSize); |
+ bind(&entry); |
+ Branch(&loop, lt, start_offset, Operand(end_offset)); |
+} |
+ |
+ |
void MacroAssembler::CheckFastElements(Register map, |
Register scratch, |
Label* fail) { |
@@ -3213,6 +3233,117 @@ void MacroAssembler::CheckFastElements(Register map, |
} |
+void MacroAssembler::CheckFastObjectElements(Register map, |
+ Register scratch, |
+ Label* fail) { |
+ STATIC_ASSERT(FAST_SMI_ONLY_ELEMENTS == 0); |
+ STATIC_ASSERT(FAST_ELEMENTS == 1); |
+ lbu(scratch, FieldMemOperand(map, Map::kBitField2Offset)); |
+ Branch(fail, ls, scratch, |
+ Operand(Map::kMaximumBitField2FastSmiOnlyElementValue)); |
+ Branch(fail, hi, scratch, |
+ Operand(Map::kMaximumBitField2FastElementValue)); |
+} |
+ |
+ |
+void MacroAssembler::CheckFastSmiOnlyElements(Register map, |
+ Register scratch, |
+ Label* fail) { |
+ STATIC_ASSERT(FAST_SMI_ONLY_ELEMENTS == 0); |
+ lbu(scratch, FieldMemOperand(map, Map::kBitField2Offset)); |
+ Branch(fail, hi, scratch, |
+ Operand(Map::kMaximumBitField2FastSmiOnlyElementValue)); |
+} |
+ |
+ |
+void MacroAssembler::StoreNumberToDoubleElements(Register value_reg, |
+ Register key_reg, |
+ Register receiver_reg, |
+ Register elements_reg, |
+ Register scratch1, |
+ Register scratch2, |
+ Register scratch3, |
+ Register scratch4, |
+ Label* fail) { |
+ Label smi_value, maybe_nan, have_double_value, is_nan, done; |
+ Register mantissa_reg = scratch2; |
+ Register exponent_reg = scratch3; |
+ |
+ // Handle smi values specially. |
+ JumpIfSmi(value_reg, &smi_value); |
+ |
+ // Ensure that the object is a heap number |
+ CheckMap(value_reg, |
+ scratch1, |
+ isolate()->factory()->heap_number_map(), |
+ fail, |
+ DONT_DO_SMI_CHECK); |
+ |
+ // Check for nan: all NaN values have a value greater (signed) than 0x7ff00000 |
+ // in the exponent. |
+ li(scratch1, Operand(kNaNOrInfinityLowerBoundUpper32)); |
+ lw(exponent_reg, FieldMemOperand(value_reg, HeapNumber::kExponentOffset)); |
+ Branch(&maybe_nan, ge, exponent_reg, Operand(scratch1)); |
+ |
+ lw(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset)); |
+ |
+ bind(&have_double_value); |
+ sll(scratch1, key_reg, kDoubleSizeLog2 - kSmiTagSize); |
+ Addu(scratch1, scratch1, elements_reg); |
+ sw(mantissa_reg, FieldMemOperand(scratch1, FixedDoubleArray::kHeaderSize)); |
+ uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32); |
+ sw(exponent_reg, FieldMemOperand(scratch1, offset)); |
+ jmp(&done); |
+ |
+ bind(&maybe_nan); |
+ // Could be NaN or Infinity. If fraction is not zero, it's NaN, otherwise |
+ // it's an Infinity, and the non-NaN code path applies. |
+ Branch(&is_nan, gt, exponent_reg, Operand(scratch1)); |
+ lw(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset)); |
+ Branch(&have_double_value, eq, mantissa_reg, Operand(zero_reg)); |
+ bind(&is_nan); |
+ // Load canonical NaN for storing into the double array. |
+ uint64_t nan_int64 = BitCast<uint64_t>( |
+ FixedDoubleArray::canonical_not_the_hole_nan_as_double()); |
+ li(mantissa_reg, Operand(static_cast<uint32_t>(nan_int64))); |
+ li(exponent_reg, Operand(static_cast<uint32_t>(nan_int64 >> 32))); |
+ jmp(&have_double_value); |
+ |
+ bind(&smi_value); |
+ Addu(scratch1, elements_reg, |
+ Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag)); |
+ sll(scratch2, key_reg, kDoubleSizeLog2 - kSmiTagSize); |
+ Addu(scratch1, scratch1, scratch2); |
+ // scratch1 is now effective address of the double element |
+ |
+ FloatingPointHelper::Destination destination; |
+ if (CpuFeatures::IsSupported(FPU)) { |
+ destination = FloatingPointHelper::kFPURegisters; |
+ } else { |
+ destination = FloatingPointHelper::kCoreRegisters; |
+ } |
+ |
+ Register untagged_value = receiver_reg; |
+ SmiUntag(untagged_value, value_reg); |
+ FloatingPointHelper::ConvertIntToDouble(this, |
+ untagged_value, |
+ destination, |
+ f0, |
+ mantissa_reg, |
+ exponent_reg, |
+ scratch4, |
+ f2); |
+ if (destination == FloatingPointHelper::kFPURegisters) { |
+ CpuFeatures::Scope scope(FPU); |
+ sdc1(f0, MemOperand(scratch1, 0)); |
+ } else { |
+ sw(mantissa_reg, MemOperand(scratch1, 0)); |
+ sw(exponent_reg, MemOperand(scratch1, Register::kSizeInBytes)); |
+ } |
+ bind(&done); |
+} |
+ |
+ |
void MacroAssembler::CheckMap(Register obj, |
Register scratch, |
Handle<Map> map, |
@@ -4573,23 +4704,15 @@ void MacroAssembler::PrepareCallCFunction(int num_reg_arguments, |
void MacroAssembler::CallCFunction(ExternalReference function, |
int num_reg_arguments, |
int num_double_arguments) { |
- CallCFunctionHelper(no_reg, |
- function, |
- t8, |
- num_reg_arguments, |
- num_double_arguments); |
+ li(t8, Operand(function)); |
+ CallCFunctionHelper(t8, num_reg_arguments, num_double_arguments); |
} |
void MacroAssembler::CallCFunction(Register function, |
- Register scratch, |
int num_reg_arguments, |
int num_double_arguments) { |
- CallCFunctionHelper(function, |
- ExternalReference::the_hole_value_location(isolate()), |
- scratch, |
- num_reg_arguments, |
- num_double_arguments); |
+ CallCFunctionHelper(function, num_reg_arguments, num_double_arguments); |
} |
@@ -4600,15 +4723,12 @@ void MacroAssembler::CallCFunction(ExternalReference function, |
void MacroAssembler::CallCFunction(Register function, |
- Register scratch, |
int num_arguments) { |
- CallCFunction(function, scratch, num_arguments, 0); |
+ CallCFunction(function, num_arguments, 0); |
} |
void MacroAssembler::CallCFunctionHelper(Register function, |
- ExternalReference function_reference, |
- Register scratch, |
int num_reg_arguments, |
int num_double_arguments) { |
ASSERT(has_frame()); |
@@ -4639,10 +4759,7 @@ void MacroAssembler::CallCFunctionHelper(Register function, |
// allow preemption, so the return address in the link register |
// stays correct. |
- if (function.is(no_reg)) { |
- function = t9; |
- li(function, Operand(function_reference)); |
- } else if (!function.is(t9)) { |
+ if (!function.is(t9)) { |
mov(t9, function); |
function = t9; |
} |