summaryrefslogtreecommitdiff
path: root/deps/v8/src/mips/macro-assembler-mips.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/mips/macro-assembler-mips.cc')
-rw-r--r--deps/v8/src/mips/macro-assembler-mips.cc194
1 files changed, 143 insertions, 51 deletions
diff --git a/deps/v8/src/mips/macro-assembler-mips.cc b/deps/v8/src/mips/macro-assembler-mips.cc
index 3c866ac453..e3544c5eec 100644
--- a/deps/v8/src/mips/macro-assembler-mips.cc
+++ b/deps/v8/src/mips/macro-assembler-mips.cc
@@ -159,9 +159,9 @@ void MacroAssembler::InNewSpace(Register object,
Condition cc,
Label* branch) {
DCHECK(cc == eq || cc == ne);
- And(scratch, object, Operand(ExternalReference::new_space_mask(isolate())));
- Branch(branch, cc, scratch,
- Operand(ExternalReference::new_space_start(isolate())));
+ const int mask =
+ 1 << MemoryChunk::IN_FROM_SPACE | 1 << MemoryChunk::IN_TO_SPACE;
+ CheckPageFlag(object, scratch, mask, cc, branch);
}
@@ -369,6 +369,67 @@ void MacroAssembler::RecordWrite(
}
}
+void MacroAssembler::RecordWriteCodeEntryField(Register js_function,
+ Register code_entry,
+ Register scratch) {
+ const int offset = JSFunction::kCodeEntryOffset;
+
+ // Since a code entry (value) is always in old space, we don't need to update
+ // remembered set. If incremental marking is off, there is nothing for us to
+ // do.
+ if (!FLAG_incremental_marking) return;
+
+ DCHECK(js_function.is(a1));
+ DCHECK(code_entry.is(t0));
+ DCHECK(scratch.is(t1));
+ AssertNotSmi(js_function);
+
+ if (emit_debug_code()) {
+ Addu(scratch, js_function, Operand(offset - kHeapObjectTag));
+ lw(at, MemOperand(scratch));
+ Assert(eq, kWrongAddressOrValuePassedToRecordWrite, at,
+ Operand(code_entry));
+ }
+
+ // First, check if a write barrier is even needed. The tests below
+ // catch stores of Smis and stores into young gen.
+ Label done;
+
+ CheckPageFlag(code_entry, scratch,
+ MemoryChunk::kPointersToHereAreInterestingMask, eq, &done);
+ CheckPageFlag(js_function, scratch,
+ MemoryChunk::kPointersFromHereAreInterestingMask, eq, &done);
+
+ const Register dst = scratch;
+ Addu(dst, js_function, Operand(offset - kHeapObjectTag));
+
+ // Save caller-saved registers. js_function and code_entry are in the
+ // caller-saved register list.
+ DCHECK(kJSCallerSaved & js_function.bit());
+ DCHECK(kJSCallerSaved & code_entry.bit());
+ MultiPush(kJSCallerSaved | ra.bit());
+
+ int argument_count = 3;
+
+ PrepareCallCFunction(argument_count, 0, code_entry);
+
+ mov(a0, js_function);
+ mov(a1, dst);
+ li(a2, Operand(ExternalReference::isolate_address(isolate())));
+
+ {
+ AllowExternalCallThatCantCauseGC scope(this);
+ CallCFunction(
+ ExternalReference::incremental_marking_record_write_code_entry_function(
+ isolate()),
+ argument_count);
+ }
+
+ // Restore caller-saved registers.
+ MultiPop(kJSCallerSaved | ra.bit());
+
+ bind(&done);
+}
void MacroAssembler::RememberedSetHelper(Register object, // For debug tests.
Register address,
@@ -499,16 +560,14 @@ void MacroAssembler::GetNumberHash(Register reg0, Register scratch) {
//
// hash = ~hash + (hash << 15);
nor(scratch, reg0, zero_reg);
- sll(at, reg0, 15);
- addu(reg0, scratch, at);
+ Lsa(reg0, scratch, reg0, 15);
// hash = hash ^ (hash >> 12);
srl(at, reg0, 12);
xor_(reg0, reg0, at);
// hash = hash + (hash << 2);
- sll(at, reg0, 2);
- addu(reg0, reg0, at);
+ Lsa(reg0, reg0, reg0, 2);
// hash = hash ^ (hash >> 4);
srl(at, reg0, 4);
@@ -516,8 +575,7 @@ void MacroAssembler::GetNumberHash(Register reg0, Register scratch) {
// hash = hash * 2057;
sll(scratch, reg0, 11);
- sll(at, reg0, 3);
- addu(reg0, reg0, at);
+ Lsa(reg0, reg0, reg0, 3);
addu(reg0, reg0, scratch);
// hash = hash ^ (hash >> 16);
@@ -577,12 +635,10 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss,
// Scale the index by multiplying by the element size.
DCHECK(SeededNumberDictionary::kEntrySize == 3);
- sll(at, reg2, 1); // 2x.
- addu(reg2, reg2, at); // reg2 = reg2 * 3.
+ Lsa(reg2, reg2, reg2, 1); // reg2 = reg2 * 3.
// Check if the key is identical to the name.
- sll(at, reg2, kPointerSizeLog2);
- addu(reg2, elements, at);
+ Lsa(reg2, elements, reg2, kPointerSizeLog2);
lw(at, FieldMemOperand(reg2, SeededNumberDictionary::kElementsStartOffset));
if (i != kNumberDictionaryProbes - 1) {
@@ -1322,6 +1378,11 @@ void MacroAssembler::Trunc_uw_d(FPURegister fd,
mtc1(t8, fd);
}
+void MacroAssembler::Trunc_uw_s(FPURegister fd, FPURegister fs,
+ FPURegister scratch) {
+ Trunc_uw_s(fs, t8, scratch);
+ mtc1(t8, fd);
+}
void MacroAssembler::Trunc_w_d(FPURegister fd, FPURegister fs) {
if (IsMipsArchVariant(kLoongson) && fd.is(fs)) {
@@ -1399,21 +1460,54 @@ void MacroAssembler::Trunc_uw_d(FPURegister fd,
bind(&done);
}
+void MacroAssembler::Trunc_uw_s(FPURegister fd, Register rs,
+ FPURegister scratch) {
+ DCHECK(!fd.is(scratch));
+ DCHECK(!rs.is(at));
+
+ // Load 2^31 into scratch as its float representation.
+ li(at, 0x4F000000);
+ mtc1(at, scratch);
+ // Test if scratch > fd.
+ // If fd < 2^31 we can convert it normally.
+ Label simple_convert;
+ BranchF32(&simple_convert, NULL, lt, fd, scratch);
+
+ // First we subtract 2^31 from fd, then trunc it to rs
+ // and add 2^31 to rs.
+ sub_s(scratch, fd, scratch);
+ trunc_w_s(scratch, scratch);
+ mfc1(rs, scratch);
+ Or(rs, rs, 1 << 31);
+
+ Label done;
+ Branch(&done);
+ // Simple conversion.
+ bind(&simple_convert);
+ trunc_w_s(scratch, fd);
+ mfc1(rs, scratch);
+
+ bind(&done);
+}
void MacroAssembler::Mthc1(Register rt, FPURegister fs) {
- if (IsFp64Mode()) {
- mthc1(rt, fs);
- } else {
+ if (IsFp32Mode()) {
mtc1(rt, fs.high());
+ } else {
+ DCHECK(IsFp64Mode() || IsFpxxMode());
+ DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
+ mthc1(rt, fs);
}
}
void MacroAssembler::Mfhc1(Register rt, FPURegister fs) {
- if (IsFp64Mode()) {
- mfhc1(rt, fs);
- } else {
+ if (IsFp32Mode()) {
mfc1(rt, fs.high());
+ } else {
+ DCHECK(IsFp64Mode() || IsFpxxMode());
+ DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
+ mfhc1(rt, fs);
}
}
@@ -1619,13 +1713,15 @@ void MacroAssembler::BranchShortF(SecondaryField sizeField, Label* target,
void MacroAssembler::FmoveLow(FPURegister dst, Register src_low) {
- if (IsFp64Mode()) {
+ if (IsFp32Mode()) {
+ mtc1(src_low, dst);
+ } else {
+ DCHECK(IsFp64Mode() || IsFpxxMode());
+ DCHECK(IsMipsArchVariant(kMips32r2) || IsMipsArchVariant(kMips32r6));
DCHECK(!src_low.is(at));
mfhc1(at, dst);
mtc1(src_low, dst);
mthc1(at, dst);
- } else {
- mtc1(src_low, dst);
}
}
@@ -3271,7 +3367,7 @@ void MacroAssembler::Allocate(int object_size,
return;
}
- DCHECK(!AreAliased(result, scratch1, scratch2, t9));
+ DCHECK(!AreAliased(result, scratch1, scratch2, t9, at));
// Make object size into bytes.
if ((flags & SIZE_IN_WORDS) != 0) {
@@ -3357,8 +3453,8 @@ void MacroAssembler::Allocate(Register object_size, Register result,
// |object_size| and |result_end| may overlap if the DOUBLE_ALIGNMENT flag
// is not specified. Other registers must not overlap.
- DCHECK(!AreAliased(object_size, result, scratch, t9));
- DCHECK(!AreAliased(result_end, result, scratch, t9));
+ DCHECK(!AreAliased(object_size, result, scratch, t9, at));
+ DCHECK(!AreAliased(result_end, result, scratch, t9, at));
DCHECK((flags & DOUBLE_ALIGNMENT) == 0 || !object_size.is(result_end));
// Check relative positions of allocation top and limit addresses.
@@ -3412,8 +3508,7 @@ void MacroAssembler::Allocate(Register object_size, Register result,
// to calculate the new top. Object size may be in words so a shift is
// required to get the number of bytes.
if ((flags & SIZE_IN_WORDS) != 0) {
- sll(result_end, object_size, kPointerSizeLog2);
- Addu(result_end, result, result_end);
+ Lsa(result_end, result, object_size, kPointerSizeLog2);
} else {
Addu(result_end, result, Operand(object_size));
}
@@ -3775,8 +3870,7 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
lw(mantissa_reg, FieldMemOperand(value_reg, HeapNumber::kMantissaOffset));
bind(&have_double_value);
- sll(scratch1, key_reg, kDoubleSizeLog2 - kSmiTagSize);
- Addu(scratch1, scratch1, elements_reg);
+ Lsa(scratch1, elements_reg, key_reg, kDoubleSizeLog2 - kSmiTagSize);
sw(mantissa_reg,
FieldMemOperand(scratch1, FixedDoubleArray::kHeaderSize - elements_offset
+ kHoleNanLower32Offset));
@@ -3802,8 +3896,7 @@ void MacroAssembler::StoreNumberToDoubleElements(Register value_reg,
Addu(scratch1, elements_reg,
Operand(FixedDoubleArray::kHeaderSize - kHeapObjectTag -
elements_offset));
- sll(scratch2, key_reg, kDoubleSizeLog2 - kSmiTagSize);
- Addu(scratch1, scratch1, scratch2);
+ Lsa(scratch1, scratch1, key_reg, kDoubleSizeLog2 - kSmiTagSize);
// scratch1 is now effective address of the double element
Register untagged_value = scratch2;
@@ -4059,7 +4152,7 @@ void MacroAssembler::FloodFunctionIfStepping(Register fun, Register new_target,
}
Push(fun);
Push(fun);
- CallRuntime(Runtime::kDebugPrepareStepInIfStepping, 1);
+ CallRuntime(Runtime::kDebugPrepareStepInIfStepping);
Pop(fun);
if (new_target.is_valid()) {
Pop(new_target);
@@ -4579,18 +4672,6 @@ void MacroAssembler::JumpToExternalReference(const ExternalReference& builtin,
}
-void MacroAssembler::InvokeBuiltin(int native_context_index, InvokeFlag flag,
- const CallWrapper& call_wrapper) {
- // You can't call a builtin without a valid frame.
- DCHECK(flag == JUMP_FUNCTION || has_frame());
-
- // Fake a parameter count to avoid emitting code to do the check.
- ParameterCount expected(0);
- LoadNativeContextSlot(native_context_index, a1);
- InvokeFunctionCode(a1, no_reg, expected, expected, flag, call_wrapper);
-}
-
-
void MacroAssembler::SetCounter(StatsCounter* counter, int value,
Register scratch1, Register scratch2) {
if (FLAG_native_code_counters && counter->Enabled()) {
@@ -4687,9 +4768,9 @@ void MacroAssembler::Abort(BailoutReason reason) {
// We don't actually want to generate a pile of code for this, so just
// claim there is a stack frame, without generating one.
FrameScope scope(this, StackFrame::NONE);
- CallRuntime(Runtime::kAbort, 1);
+ CallRuntime(Runtime::kAbort);
} else {
- CallRuntime(Runtime::kAbort, 1);
+ CallRuntime(Runtime::kAbort);
}
// Will not return here.
if (is_trampoline_pool_blocked()) {
@@ -4945,8 +5026,7 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count,
if (argument_count_is_length) {
addu(sp, sp, argument_count);
} else {
- sll(t8, argument_count, kPointerSizeLog2);
- addu(sp, sp, t8);
+ Lsa(sp, sp, argument_count, kPointerSizeLog2, t8);
}
}
@@ -5160,6 +5240,17 @@ void MacroAssembler::AssertBoundFunction(Register object) {
}
+void MacroAssembler::AssertReceiver(Register object) {
+ if (emit_debug_code()) {
+ STATIC_ASSERT(kSmiTag == 0);
+ SmiTst(object, t8);
+ Check(ne, kOperandIsASmiAndNotAReceiver, t8, Operand(zero_reg));
+ GetObjectType(object, t8, t8);
+ Check(ge, kOperandIsNotAReceiver, t8, Operand(FIRST_JS_RECEIVER_TYPE));
+ }
+}
+
+
void MacroAssembler::AssertUndefinedOrAllocationSite(Register object,
Register scratch) {
if (emit_debug_code()) {
@@ -5473,8 +5564,7 @@ void MacroAssembler::GetMarkBits(Register addr_reg,
Ext(mask_reg, addr_reg, kPointerSizeLog2, Bitmap::kBitsPerCellLog2);
const int kLowBits = kPointerSizeLog2 + Bitmap::kBitsPerCellLog2;
Ext(t8, addr_reg, kLowBits, kPageSizeBits - kLowBits);
- sll(t8, t8, kPointerSizeLog2);
- Addu(bitmap_reg, bitmap_reg, t8);
+ Lsa(bitmap_reg, bitmap_reg, t8, kPointerSizeLog2, t8);
li(t8, Operand(1));
sllv(mask_reg, t8, mask_reg);
}
@@ -5533,7 +5623,8 @@ void MacroAssembler::LoadAccessor(Register dst, Register holder,
}
-void MacroAssembler::CheckEnumCache(Register null_value, Label* call_runtime) {
+void MacroAssembler::CheckEnumCache(Label* call_runtime) {
+ Register null_value = t1;
Register empty_fixed_array_value = t2;
LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex);
Label next, start;
@@ -5547,6 +5638,7 @@ void MacroAssembler::CheckEnumCache(Register null_value, Label* call_runtime) {
Branch(
call_runtime, eq, a3, Operand(Smi::FromInt(kInvalidEnumCacheSentinel)));
+ LoadRoot(null_value, Heap::kNullValueRootIndex);
jmp(&start);
bind(&next);