summaryrefslogtreecommitdiff
path: root/deps/v8/src/mips64/macro-assembler-mips64.cc
diff options
context:
space:
mode:
authorAli Ijaz Sheikh <ofrobots@google.com>2016-04-07 14:06:55 -0700
committerAli Ijaz Sheikh <ofrobots@google.com>2016-04-14 10:03:39 -0700
commit52af5c4eebf4de8638aef0338bd826656312a02a (patch)
tree628dc9fb0b558c3a73a2160706fef368876fe548 /deps/v8/src/mips64/macro-assembler-mips64.cc
parent6e3e8acc7cc7ebd3d67db5ade1247b8b558efe09 (diff)
downloadnode-new-52af5c4eebf4de8638aef0338bd826656312a02a.tar.gz
deps: upgrade V8 to 5.0.71.32
* Pick up the branch head for V8 5.0 stable [1] * Edit v8 gitignore to allow trace_event copy * Update V8 DEP trace_event as per deps/v8/DEPS [2] [1] https://chromium.googlesource.com/v8/v8.git/+/3c67831 [2] https://chromium.googlesource.com/chromium/src/base/trace_event/common/+/4b09207e447ae5bd34643b4c6321bee7b76d35f9 Ref: https://github.com/nodejs/node/pull/5945 PR-URL: https://github.com/nodejs/node/pull/6111 Reviewed-By: targos - Michaƫl Zasso <mic.besace@gmail.com> Reviewed-By: bnoordhuis - Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: indutny - Fedor Indutny <fedor.indutny@gmail.com>
Diffstat (limited to 'deps/v8/src/mips64/macro-assembler-mips64.cc')
-rw-r--r--deps/v8/src/mips64/macro-assembler-mips64.cc322
1 files changed, 241 insertions, 81 deletions
diff --git a/deps/v8/src/mips64/macro-assembler-mips64.cc b/deps/v8/src/mips64/macro-assembler-mips64.cc
index 7b73ac74e4..b49fa76e06 100644
--- a/deps/v8/src/mips64/macro-assembler-mips64.cc
+++ b/deps/v8/src/mips64/macro-assembler-mips64.cc
@@ -161,9 +161,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);
}
@@ -371,6 +371,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(a4));
+ DCHECK(scratch.is(a5));
+ AssertNotSmi(js_function);
+
+ if (emit_debug_code()) {
+ Daddu(scratch, js_function, Operand(offset - kHeapObjectTag));
+ ld(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;
+ Daddu(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, code_entry);
+
+ Move(a0, js_function);
+ Move(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,
@@ -503,16 +564,14 @@ void MacroAssembler::GetNumberHash(Register reg0, Register scratch) {
// hash = ~hash + (hash << 15);
// The algorithm uses 32-bit integer values.
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);
@@ -520,8 +579,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);
@@ -581,12 +639,10 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss,
// Scale the index by multiplying by the element size.
DCHECK(SeededNumberDictionary::kEntrySize == 3);
- dsll(at, reg2, 1); // 2x.
- daddu(reg2, reg2, at); // reg2 = reg2 * 3.
+ Dlsa(reg2, reg2, reg2, 1); // reg2 = reg2 * 3.
// Check if the key is identical to the name.
- dsll(at, reg2, kPointerSizeLog2);
- daddu(reg2, elements, at);
+ Dlsa(reg2, elements, reg2, kPointerSizeLog2);
ld(at, FieldMemOperand(reg2, SeededNumberDictionary::kElementsStartOffset));
if (i != kNumberDictionaryProbes - 1) {
@@ -1302,6 +1358,35 @@ void MacroAssembler::li(Register dst, Handle<Object> value, LiFlags mode) {
}
}
+static inline int64_t ShiftAndFixSignExtension(int64_t imm, int bitnum) {
+ if ((imm >> (bitnum - 1)) & 0x1) {
+ imm = (imm >> bitnum) + 1;
+ } else {
+ imm = imm >> bitnum;
+ }
+ return imm;
+}
+
+bool MacroAssembler::LiLower32BitHelper(Register rd, Operand j) {
+ bool higher_bits_sign_extended = false;
+ if (is_int16(j.imm64_)) {
+ daddiu(rd, zero_reg, (j.imm64_ & kImm16Mask));
+ } else if (!(j.imm64_ & kHiMask)) {
+ ori(rd, zero_reg, (j.imm64_ & kImm16Mask));
+ } else if (!(j.imm64_ & kImm16Mask)) {
+ lui(rd, (j.imm64_ >> kLuiShift) & kImm16Mask);
+ if ((j.imm64_ >> (kLuiShift + 15)) & 0x1) {
+ higher_bits_sign_extended = true;
+ }
+ } else {
+ lui(rd, (j.imm64_ >> kLuiShift) & kImm16Mask);
+ ori(rd, rd, (j.imm64_ & kImm16Mask));
+ if ((j.imm64_ >> (kLuiShift + 15)) & 0x1) {
+ higher_bits_sign_extended = true;
+ }
+ }
+ return higher_bits_sign_extended;
+}
void MacroAssembler::li(Register rd, Operand j, LiFlags mode) {
DCHECK(!j.is_reg());
@@ -1309,50 +1394,57 @@ void MacroAssembler::li(Register rd, Operand j, LiFlags mode) {
if (!MustUseReg(j.rmode_) && mode == OPTIMIZE_SIZE) {
// Normal load of an immediate value which does not need Relocation Info.
if (is_int32(j.imm64_)) {
- if (is_int16(j.imm64_)) {
- daddiu(rd, zero_reg, (j.imm64_ & kImm16Mask));
- } else if (!(j.imm64_ & kHiMask)) {
- ori(rd, zero_reg, (j.imm64_ & kImm16Mask));
- } else if (!(j.imm64_ & kImm16Mask)) {
- lui(rd, (j.imm64_ >> kLuiShift) & kImm16Mask);
- } else {
- lui(rd, (j.imm64_ >> kLuiShift) & kImm16Mask);
- ori(rd, rd, (j.imm64_ & kImm16Mask));
- }
+ LiLower32BitHelper(rd, j);
} else {
- if (is_int48(j.imm64_)) {
- if ((j.imm64_ >> 32) & kImm16Mask) {
- lui(rd, (j.imm64_ >> 32) & kImm16Mask);
- if ((j.imm64_ >> 16) & kImm16Mask) {
- ori(rd, rd, (j.imm64_ >> 16) & kImm16Mask);
- }
- } else {
- ori(rd, zero_reg, (j.imm64_ >> 16) & kImm16Mask);
+ if (kArchVariant == kMips64r6) {
+ int64_t imm = j.imm64_;
+ bool higher_bits_sign_extended = LiLower32BitHelper(rd, j);
+ imm = ShiftAndFixSignExtension(imm, 32);
+ // If LUI writes 1s to higher bits, we need both DAHI/DATI.
+ if ((imm & kImm16Mask) ||
+ (higher_bits_sign_extended && (j.imm64_ > 0))) {
+ dahi(rd, imm & kImm16Mask);
}
- dsll(rd, rd, 16);
- if (j.imm64_ & kImm16Mask) {
- ori(rd, rd, j.imm64_ & kImm16Mask);
+ imm = ShiftAndFixSignExtension(imm, 16);
+ if ((!is_int48(j.imm64_) && (imm & kImm16Mask)) ||
+ (higher_bits_sign_extended && (j.imm64_ > 0))) {
+ dati(rd, imm & kImm16Mask);
}
} else {
- lui(rd, (j.imm64_ >> 48) & kImm16Mask);
- if ((j.imm64_ >> 32) & kImm16Mask) {
- ori(rd, rd, (j.imm64_ >> 32) & kImm16Mask);
- }
- if ((j.imm64_ >> 16) & kImm16Mask) {
+ if (is_int48(j.imm64_)) {
+ if ((j.imm64_ >> 32) & kImm16Mask) {
+ lui(rd, (j.imm64_ >> 32) & kImm16Mask);
+ if ((j.imm64_ >> 16) & kImm16Mask) {
+ ori(rd, rd, (j.imm64_ >> 16) & kImm16Mask);
+ }
+ } else {
+ ori(rd, zero_reg, (j.imm64_ >> 16) & kImm16Mask);
+ }
dsll(rd, rd, 16);
- ori(rd, rd, (j.imm64_ >> 16) & kImm16Mask);
if (j.imm64_ & kImm16Mask) {
- dsll(rd, rd, 16);
ori(rd, rd, j.imm64_ & kImm16Mask);
- } else {
- dsll(rd, rd, 16);
}
} else {
- if (j.imm64_ & kImm16Mask) {
- dsll32(rd, rd, 0);
- ori(rd, rd, j.imm64_ & kImm16Mask);
+ lui(rd, (j.imm64_ >> 48) & kImm16Mask);
+ if ((j.imm64_ >> 32) & kImm16Mask) {
+ ori(rd, rd, (j.imm64_ >> 32) & kImm16Mask);
+ }
+ if ((j.imm64_ >> 16) & kImm16Mask) {
+ dsll(rd, rd, 16);
+ ori(rd, rd, (j.imm64_ >> 16) & kImm16Mask);
+ if (j.imm64_ & kImm16Mask) {
+ dsll(rd, rd, 16);
+ ori(rd, rd, j.imm64_ & kImm16Mask);
+ } else {
+ dsll(rd, rd, 16);
+ }
} else {
- dsll32(rd, rd, 0);
+ if (j.imm64_ & kImm16Mask) {
+ dsll32(rd, rd, 0);
+ ori(rd, rd, j.imm64_ & kImm16Mask);
+ } else {
+ dsll32(rd, rd, 0);
+ }
}
}
}
@@ -1371,12 +1463,32 @@ void MacroAssembler::li(Register rd, Operand j, LiFlags mode) {
dsll(rd, rd, 16);
ori(rd, rd, j.imm64_ & kImm16Mask);
} else {
- lui(rd, (j.imm64_ >> 48) & kImm16Mask);
- ori(rd, rd, (j.imm64_ >> 32) & kImm16Mask);
- dsll(rd, rd, 16);
- ori(rd, rd, (j.imm64_ >> 16) & kImm16Mask);
- dsll(rd, rd, 16);
- ori(rd, rd, j.imm64_ & kImm16Mask);
+ if (kArchVariant == kMips64r6) {
+ int64_t imm = j.imm64_;
+ lui(rd, (imm >> kLuiShift) & kImm16Mask);
+ if (imm & kImm16Mask) {
+ ori(rd, rd, (imm & kImm16Mask));
+ }
+ if ((imm >> 31) & 0x1) {
+ imm = (imm >> 32) + 1;
+ } else {
+ imm = imm >> 32;
+ }
+ dahi(rd, imm & kImm16Mask);
+ if ((imm >> 15) & 0x1) {
+ imm = (imm >> 16) + 1;
+ } else {
+ imm = imm >> 16;
+ }
+ dati(rd, imm & kImm16Mask);
+ } else {
+ lui(rd, (j.imm64_ >> 48) & kImm16Mask);
+ ori(rd, rd, (j.imm64_ >> 32) & kImm16Mask);
+ dsll(rd, rd, 16);
+ ori(rd, rd, (j.imm64_ >> 16) & kImm16Mask);
+ dsll(rd, rd, 16);
+ ori(rd, rd, j.imm64_ & kImm16Mask);
+ }
}
}
@@ -1596,6 +1708,22 @@ void MacroAssembler::Cvt_d_ul(FPURegister fd, Register rs) {
bind(&conversion_done);
}
+void MacroAssembler::Cvt_s_uw(FPURegister fd, FPURegister fs) {
+ // Move the data from fs to t8.
+ mfc1(t8, fs);
+ Cvt_s_uw(fd, t8);
+}
+
+void MacroAssembler::Cvt_s_uw(FPURegister fd, Register rs) {
+ // Convert rs to a FP value in fd.
+ DCHECK(!rs.is(t9));
+ DCHECK(!rs.is(at));
+
+ // Zero extend int32 in rs.
+ Dext(t9, rs, 0, 32);
+ dmtc1(t9, fd);
+ cvt_s_l(fd, fd);
+}
void MacroAssembler::Cvt_s_ul(FPURegister fd, FPURegister fs) {
// Move the data from fs to t8.
@@ -1672,6 +1800,12 @@ 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_ul_d(FPURegister fd, FPURegister fs,
FPURegister scratch, Register result) {
Trunc_ul_d(fs, t8, scratch, result);
@@ -1738,6 +1872,35 @@ 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::Trunc_ul_d(FPURegister fd, Register rs,
FPURegister scratch, Register result) {
@@ -3714,7 +3877,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) {
@@ -3792,8 +3955,8 @@ void MacroAssembler::Allocate(Register object_size, Register result,
}
// |object_size| and |result_end| may overlap, other registers must not.
- 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));
// Check relative positions of allocation top and limit addresses.
// ARM adds additional checks to make sure the ldm instruction can be
@@ -3839,8 +4002,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) {
- dsll(result_end, object_size, kPointerSizeLog2);
- Daddu(result_end, result, result_end);
+ Dlsa(result_end, result, object_size, kPointerSizeLog2);
} else {
Daddu(result_end, result, Operand(object_size));
}
@@ -4365,7 +4527,7 @@ void MacroAssembler::MovToFloatResult(DoubleRegister src) {
void MacroAssembler::MovToFloatParameters(DoubleRegister src1,
DoubleRegister src2) {
if (!IsMipsSoftFloatABI) {
- const DoubleRegister fparg2 = (kMipsAbi == kN64) ? f13 : f14;
+ const DoubleRegister fparg2 = f13;
if (src2.is(f12)) {
DCHECK(!src1.is(fparg2));
Move(fparg2, src2);
@@ -4479,7 +4641,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);
@@ -5230,18 +5392,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()) {
@@ -5338,9 +5488,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()) {
@@ -5596,8 +5746,7 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles, Register argument_count,
if (argument_count_is_length) {
daddu(sp, sp, argument_count);
} else {
- dsll(t8, argument_count, kPointerSizeLog2);
- daddu(sp, sp, t8);
+ Dlsa(sp, sp, argument_count, kPointerSizeLog2, t8);
}
}
@@ -5880,6 +6029,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()) {
@@ -5969,8 +6129,7 @@ void MacroAssembler::JumpIfInstanceTypeIsNotSequentialOneByte(Register type,
Branch(failure, ne, scratch, Operand(kFlatOneByteStringTag));
}
-
-static const int kRegisterPassedArguments = (kMipsAbi == kN64) ? 8 : 4;
+static const int kRegisterPassedArguments = 8;
int MacroAssembler::CalculateStackPassedWords(int num_reg_arguments,
int num_double_arguments) {
@@ -6185,8 +6344,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);
- dsll(t8, t8, Bitmap::kBytesPerCellLog2);
- Daddu(bitmap_reg, bitmap_reg, t8);
+ Dlsa(bitmap_reg, bitmap_reg, t8, Bitmap::kBytesPerCellLog2);
li(t8, Operand(1));
dsllv(mask_reg, t8, mask_reg);
}
@@ -6251,7 +6409,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 = a5;
Register empty_fixed_array_value = a6;
LoadRoot(empty_fixed_array_value, Heap::kEmptyFixedArrayRootIndex);
Label next, start;
@@ -6265,6 +6424,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);