summaryrefslogtreecommitdiff
path: root/deps/v8/src/mips64/assembler-mips64.cc
diff options
context:
space:
mode:
authorAli Ijaz Sheikh <ofrobots@google.com>2015-08-23 06:09:40 -0700
committerRod Vagg <rod@vagg.org>2015-09-06 21:38:01 +1000
commit9fddd83cf9adf505bce2e2373881df0c4d41b261 (patch)
tree4272ce14c10fea496af2e78fc6debb187d613451 /deps/v8/src/mips64/assembler-mips64.cc
parent46b7d151674d138e7ea4342d5f3ada1208b87ff2 (diff)
downloadnode-new-9fddd83cf9adf505bce2e2373881df0c4d41b261.tar.gz
deps: upgrade V8 to 4.5.103.24
Upgrade to the latest branch-head for V8 4.5. For the full commit log see https://github.com/v8/v8-git-mirror/commits/4.5.103.24 PR-URL: https://github.com/nodejs/node/pull/2509 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'deps/v8/src/mips64/assembler-mips64.cc')
-rw-r--r--deps/v8/src/mips64/assembler-mips64.cc489
1 files changed, 378 insertions, 111 deletions
diff --git a/deps/v8/src/mips64/assembler-mips64.cc b/deps/v8/src/mips64/assembler-mips64.cc
index 685100f59a..ea497509c6 100644
--- a/deps/v8/src/mips64/assembler-mips64.cc
+++ b/deps/v8/src/mips64/assembler-mips64.cc
@@ -211,13 +211,14 @@ Operand::Operand(Handle<Object> handle) {
}
-MemOperand::MemOperand(Register rm, int64_t offset) : Operand(rm) {
+MemOperand::MemOperand(Register rm, int32_t offset) : Operand(rm) {
offset_ = offset;
}
-MemOperand::MemOperand(Register rm, int64_t unit, int64_t multiplier,
- OffsetAddend offset_addend) : Operand(rm) {
+MemOperand::MemOperand(Register rm, int32_t unit, int32_t multiplier,
+ OffsetAddend offset_addend)
+ : Operand(rm) {
offset_ = unit * multiplier + offset_addend;
}
@@ -290,7 +291,8 @@ void Assembler::GetCode(CodeDesc* desc) {
desc->buffer = buffer_;
desc->buffer_size = buffer_size_;
desc->instr_size = pc_offset();
- desc->reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
+ desc->reloc_size =
+ static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos());
desc->origin = this;
}
@@ -637,7 +639,7 @@ int Assembler::target_at(int pos, bool is_internal) {
}
}
// Check we have a branch or jump instruction.
- DCHECK(IsBranch(instr) || IsLui(instr));
+ DCHECK(IsBranch(instr) || IsJ(instr) || IsJal(instr) || IsLui(instr));
// Do NOT change this to <<2. We rely on arithmetic shifts here, assuming
// the compiler uses arithmetic shifts for signed integers.
if (IsBranch(instr)) {
@@ -673,8 +675,18 @@ int Assembler::target_at(int pos, bool is_internal) {
return pos - delta;
}
} else {
- UNREACHABLE();
- return 0;
+ DCHECK(IsJ(instr) || IsJal(instr));
+ int32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
+ if (imm28 == kEndOfJumpChain) {
+ // EndOfChain sentinel is returned directly, not relative to pc or pos.
+ return kEndOfChain;
+ } else {
+ uint64_t instr_address = reinterpret_cast<int64_t>(buffer_ + pos);
+ instr_address &= kImm28Mask;
+ int delta = static_cast<int>(instr_address - imm28);
+ DCHECK(pos > delta);
+ return pos - delta;
+ }
}
}
@@ -694,7 +706,7 @@ void Assembler::target_at_put(int pos, int target_pos, bool is_internal) {
return;
}
- DCHECK(IsBranch(instr) || IsLui(instr));
+ DCHECK(IsBranch(instr) || IsJ(instr) || IsJal(instr) || IsLui(instr));
if (IsBranch(instr)) {
int32_t imm18 = target_pos - (pos + kBranchPCOffset);
DCHECK((imm18 & 3) == 0);
@@ -725,7 +737,16 @@ void Assembler::target_at_put(int pos, int target_pos, bool is_internal) {
instr_at_put(pos + 3 * Assembler::kInstrSize,
instr_ori2 | (imm & kImm16Mask));
} else {
- UNREACHABLE();
+ DCHECK(IsJ(instr) || IsJal(instr));
+ uint64_t imm28 = reinterpret_cast<uint64_t>(buffer_) + target_pos;
+ imm28 &= kImm28Mask;
+ DCHECK((imm28 & 3) == 0);
+
+ instr &= ~kImm26Mask;
+ uint32_t imm26 = static_cast<uint32_t>(imm28 >> 2);
+ DCHECK(is_uint26(imm26));
+
+ instr_at_put(pos, instr | (imm26 & kImm26Mask));
}
}
@@ -787,7 +808,8 @@ void Assembler::bind_to(Label* L, int pos) {
}
target_at_put(fixup_pos, pos, false);
} else {
- DCHECK(IsJ(instr) || IsLui(instr) || IsEmittedConstant(instr));
+ DCHECK(IsJ(instr) || IsJal(instr) || IsLui(instr) ||
+ IsEmittedConstant(instr));
target_at_put(fixup_pos, pos, false);
}
}
@@ -945,6 +967,20 @@ void Assembler::GenInstrImmediate(Opcode opcode,
}
+void Assembler::GenInstrImmediate(Opcode opcode, Register rs, int32_t j) {
+ DCHECK(rs.is_valid() && (is_uint21(j)));
+ Instr instr = opcode | (rs.code() << kRsShift) | (j & kImm21Mask);
+ emit(instr);
+}
+
+
+void Assembler::GenInstrImmediate(Opcode opcode, int32_t offset26) {
+ DCHECK(is_int26(offset26));
+ Instr instr = opcode | (offset26 & kImm26Mask);
+ emit(instr);
+}
+
+
void Assembler::GenInstrJump(Opcode opcode,
uint32_t address) {
BlockTrampolinePoolScope block_trampoline_pool(this);
@@ -984,7 +1020,6 @@ uint64_t Assembler::jump_address(Label* L) {
return kEndOfJumpChain;
}
}
-
uint64_t imm = reinterpret_cast<uint64_t>(buffer_) + target_pos;
DCHECK((imm & 3) == 0);
@@ -1090,7 +1125,7 @@ int32_t Assembler::branch_offset21_compact(Label* L,
}
}
- int32_t offset = target_pos - pc_offset();
+ int32_t offset = target_pos - (pc_offset() + kBranchPCOffset);
DCHECK((offset & 3) == 0);
DCHECK(((offset >> 2) & 0xFFE00000) == 0); // Offset is 21bit width.
@@ -1137,6 +1172,19 @@ void Assembler::bal(int16_t offset) {
}
+void Assembler::bc(int32_t offset) {
+ DCHECK(kArchVariant == kMips64r6);
+ GenInstrImmediate(BC, offset);
+}
+
+
+void Assembler::balc(int32_t offset) {
+ DCHECK(kArchVariant == kMips64r6);
+ positions_recorder()->WriteRecordedPositions();
+ GenInstrImmediate(BALC, offset);
+}
+
+
void Assembler::beq(Register rs, Register rt, int16_t offset) {
BlockTrampolinePoolScope block_trampoline_pool(this);
GenInstrImmediate(BEQ, rs, rt, offset);
@@ -1336,7 +1384,7 @@ void Assembler::beqc(Register rs, Register rt, int16_t offset) {
void Assembler::beqzc(Register rs, int32_t offset) {
DCHECK(kArchVariant == kMips64r6);
DCHECK(!(rs.is(zero_reg)));
- Instr instr = BEQZC | (rs.code() << kRsShift) | offset;
+ Instr instr = POP66 | (rs.code() << kRsShift) | (offset & kImm21Mask);
emit(instr);
}
@@ -1351,7 +1399,7 @@ void Assembler::bnec(Register rs, Register rt, int16_t offset) {
void Assembler::bnezc(Register rs, int32_t offset) {
DCHECK(kArchVariant == kMips64r6);
DCHECK(!(rs.is(zero_reg)));
- Instr instr = BNEZC | (rs.code() << kRsShift) | offset;
+ Instr instr = POP76 | (rs.code() << kRsShift) | offset;
emit(instr);
}
@@ -1359,12 +1407,14 @@ void Assembler::bnezc(Register rs, int32_t offset) {
void Assembler::j(int64_t target) {
#if DEBUG
// Get pc of delay slot.
- uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize);
- bool in_range = (ipc ^ static_cast<uint64_t>(target) >>
- (kImm26Bits + kImmFieldShift)) == 0;
- DCHECK(in_range && ((target & 3) == 0));
+ if (target != kEndOfJumpChain) {
+ uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize);
+ bool in_range = ((ipc ^ static_cast<uint64_t>(target)) >>
+ (kImm26Bits + kImmFieldShift)) == 0;
+ DCHECK(in_range && ((target & 3) == 0));
+ }
#endif
- GenInstrJump(J, target >> 2);
+ GenInstrJump(J, static_cast<uint32_t>(target >> 2) & kImm26Mask);
}
@@ -1385,13 +1435,15 @@ void Assembler::jr(Register rs) {
void Assembler::jal(int64_t target) {
#ifdef DEBUG
// Get pc of delay slot.
- uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize);
- bool in_range = (ipc ^ static_cast<uint64_t>(target) >>
- (kImm26Bits + kImmFieldShift)) == 0;
- DCHECK(in_range && ((target & 3) == 0));
+ if (target != kEndOfJumpChain) {
+ uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize);
+ bool in_range = ((ipc ^ static_cast<uint64_t>(target)) >>
+ (kImm26Bits + kImmFieldShift)) == 0;
+ DCHECK(in_range && ((target & 3) == 0));
+ }
#endif
positions_recorder()->WriteRecordedPositions();
- GenInstrJump(JAL, target >> 2);
+ GenInstrJump(JAL, static_cast<uint32_t>(target >> 2) & kImm26Mask);
}
@@ -1404,29 +1456,18 @@ void Assembler::jalr(Register rs, Register rd) {
}
-void Assembler::j_or_jr(int64_t target, Register rs) {
- // Get pc of delay slot.
- uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize);
- bool in_range = (ipc ^ static_cast<uint64_t>(target) >>
- (kImm26Bits + kImmFieldShift)) == 0;
- if (in_range) {
- j(target);
- } else {
- jr(t9);
- }
+void Assembler::jic(Register rt, int16_t offset) {
+ DCHECK(kArchVariant == kMips64r6);
+ Instr instr = POP66 | (JIC << kRsShift) | (rt.code() << kRtShift) |
+ (offset & kImm16Mask);
+ emit(instr);
}
-void Assembler::jal_or_jalr(int64_t target, Register rs) {
- // Get pc of delay slot.
- uint64_t ipc = reinterpret_cast<uint64_t>(pc_ + 1 * kInstrSize);
- bool in_range = (ipc ^ static_cast<uint64_t>(target) >>
- (kImm26Bits+kImmFieldShift)) == 0;
- if (in_range) {
- jal(target);
- } else {
- jalr(t9);
- }
+void Assembler::jialc(Register rt, int16_t offset) {
+ DCHECK(kArchVariant == kMips64r6);
+ positions_recorder()->WriteRecordedPositions();
+ GenInstrImmediate(POP76, zero_reg, rt, offset);
}
@@ -1687,7 +1728,7 @@ void Assembler::srav(Register rd, Register rt, Register rs) {
void Assembler::rotr(Register rd, Register rt, uint16_t sa) {
// Should be called via MacroAssembler::Ror.
DCHECK(rd.is_valid() && rt.is_valid() && is_uint5(sa));
- DCHECK(kArchVariant == kMips64r2);
+ DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
Instr instr = SPECIAL | (1 << kRsShift) | (rt.code() << kRtShift)
| (rd.code() << kRdShift) | (sa << kSaShift) | SRL;
emit(instr);
@@ -1697,7 +1738,7 @@ void Assembler::rotr(Register rd, Register rt, uint16_t sa) {
void Assembler::rotrv(Register rd, Register rt, Register rs) {
// Should be called via MacroAssembler::Ror.
DCHECK(rd.is_valid() && rt.is_valid() && rs.is_valid() );
- DCHECK(kArchVariant == kMips64r2);
+ DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
Instr instr = SPECIAL | (rs.code() << kRsShift) | (rt.code() << kRtShift)
| (rd.code() << kRdShift) | (1 << kSaShift) | SRLV;
emit(instr);
@@ -1897,6 +1938,7 @@ void Assembler::lui(Register rd, int32_t j) {
void Assembler::aui(Register rs, Register rt, int32_t j) {
// This instruction uses same opcode as 'lui'. The difference in encoding is
// 'lui' has zero reg. for rs field.
+ DCHECK(!(rs.is(zero_reg)));
DCHECK(is_uint16(j));
GenInstrImmediate(LUI, rs, rt, j);
}
@@ -1960,6 +2002,56 @@ void Assembler::sd(Register rd, const MemOperand& rs) {
}
+// ---------PC-Relative instructions-----------
+
+void Assembler::addiupc(Register rs, int32_t imm19) {
+ DCHECK(kArchVariant == kMips64r6);
+ DCHECK(rs.is_valid() && is_int19(imm19));
+ int32_t imm21 = ADDIUPC << kImm19Bits | (imm19 & kImm19Mask);
+ GenInstrImmediate(PCREL, rs, imm21);
+}
+
+
+void Assembler::lwpc(Register rs, int32_t offset19) {
+ DCHECK(kArchVariant == kMips64r6);
+ DCHECK(rs.is_valid() && is_int19(offset19));
+ int32_t imm21 = LWPC << kImm19Bits | (offset19 & kImm19Mask);
+ GenInstrImmediate(PCREL, rs, imm21);
+}
+
+
+void Assembler::lwupc(Register rs, int32_t offset19) {
+ DCHECK(kArchVariant == kMips64r6);
+ DCHECK(rs.is_valid() && is_int19(offset19));
+ int32_t imm21 = LWUPC << kImm19Bits | (offset19 & kImm19Mask);
+ GenInstrImmediate(PCREL, rs, imm21);
+}
+
+
+void Assembler::ldpc(Register rs, int32_t offset18) {
+ DCHECK(kArchVariant == kMips64r6);
+ DCHECK(rs.is_valid() && is_int18(offset18));
+ int32_t imm21 = LDPC << kImm18Bits | (offset18 & kImm18Mask);
+ GenInstrImmediate(PCREL, rs, imm21);
+}
+
+
+void Assembler::auipc(Register rs, int16_t imm16) {
+ DCHECK(kArchVariant == kMips64r6);
+ DCHECK(rs.is_valid() && is_int16(imm16));
+ int32_t imm21 = AUIPC << kImm16Bits | (imm16 & kImm16Mask);
+ GenInstrImmediate(PCREL, rs, imm21);
+}
+
+
+void Assembler::aluipc(Register rs, int16_t imm16) {
+ DCHECK(kArchVariant == kMips64r6);
+ DCHECK(rs.is_valid() && is_int16(imm16));
+ int32_t imm21 = ALUIPC << kImm16Bits | (imm16 & kImm16Mask);
+ GenInstrImmediate(PCREL, rs, imm21);
+}
+
+
// -------------Misc-instructions--------------
// Break / Trap instructions.
@@ -2141,17 +2233,6 @@ void Assembler::maxa_d(FPURegister fd, FPURegister fs, FPURegister ft) {
}
-void Assembler::sel(SecondaryField fmt, FPURegister fd, FPURegister fs,
- FPURegister ft) {
- DCHECK(kArchVariant == kMips64r6);
- DCHECK((fmt == D) || (fmt == S));
-
- Instr instr = COP1 | fmt << kRsShift | ft.code() << kFtShift |
- fs.code() << kFsShift | fd.code() << kFdShift | SEL;
- emit(instr);
-}
-
-
void Assembler::max(SecondaryField fmt, FPURegister fd, FPURegister fs,
FPURegister ft) {
DCHECK(kArchVariant == kMips64r6);
@@ -2175,14 +2256,6 @@ void Assembler::seleqz(Register rd, Register rs, Register rt) {
}
-// FPR.
-void Assembler::seleqz(SecondaryField fmt, FPURegister fd, FPURegister fs,
- FPURegister ft) {
- DCHECK((fmt == D) || (fmt == S));
- GenInstrRegister(COP1, fmt, ft, fs, fd, SELEQZ_C);
-}
-
-
// GPR.
void Assembler::selnez(Register rd, Register rs, Register rt) {
DCHECK(kArchVariant == kMips64r6);
@@ -2190,15 +2263,6 @@ void Assembler::selnez(Register rd, Register rs, Register rt) {
}
-// FPR.
-void Assembler::selnez(SecondaryField fmt, FPURegister fd, FPURegister fs,
- FPURegister ft) {
- DCHECK(kArchVariant == kMips64r6);
- DCHECK((fmt == D) || (fmt == S));
- GenInstrRegister(COP1, fmt, ft, fs, fd, SELNEZ_C);
-}
-
-
// Bit twiddling.
void Assembler::clz(Register rd, Register rs) {
if (kArchVariant != kMips64r6) {
@@ -2234,6 +2298,18 @@ void Assembler::dext_(Register rt, Register rs, uint16_t pos, uint16_t size) {
}
+void Assembler::bitswap(Register rd, Register rt) {
+ DCHECK(kArchVariant == kMips64r6);
+ GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, BSHFL);
+}
+
+
+void Assembler::dbitswap(Register rd, Register rt) {
+ DCHECK(kArchVariant == kMips64r6);
+ GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, DBSHFL);
+}
+
+
void Assembler::pref(int32_t hint, const MemOperand& rs) {
DCHECK(is_uint5(hint) && is_uint16(rs.offset_));
Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift)
@@ -2242,6 +2318,22 @@ void Assembler::pref(int32_t hint, const MemOperand& rs) {
}
+void Assembler::align(Register rd, Register rs, Register rt, uint8_t bp) {
+ DCHECK(kArchVariant == kMips64r6);
+ DCHECK(is_uint3(bp));
+ uint16_t sa = (ALIGN << kBp2Bits) | bp;
+ GenInstrRegister(SPECIAL3, rs, rt, rd, sa, BSHFL);
+}
+
+
+void Assembler::dalign(Register rd, Register rs, Register rt, uint8_t bp) {
+ DCHECK(kArchVariant == kMips64r6);
+ DCHECK(is_uint3(bp));
+ uint16_t sa = (DALIGN << kBp3Bits) | bp;
+ GenInstrRegister(SPECIAL3, rs, rt, rd, sa, DBSHFL);
+}
+
+
// --------Coprocessor-instructions----------------
// Load, store, move.
@@ -2334,6 +2426,118 @@ void Assembler::DoubleAsTwoUInt32(double d, uint32_t* lo, uint32_t* hi) {
}
+void Assembler::sel(SecondaryField fmt, FPURegister fd, FPURegister fs,
+ FPURegister ft) {
+ DCHECK(kArchVariant == kMips64r6);
+ DCHECK((fmt == D) || (fmt == S));
+
+ GenInstrRegister(COP1, fmt, ft, fs, fd, SEL);
+}
+
+
+void Assembler::sel_s(FPURegister fd, FPURegister fs, FPURegister ft) {
+ sel(S, fd, fs, ft);
+}
+
+
+void Assembler::sel_d(FPURegister fd, FPURegister fs, FPURegister ft) {
+ sel(D, fd, fs, ft);
+}
+
+
+// FPR.
+void Assembler::seleqz(SecondaryField fmt, FPURegister fd, FPURegister fs,
+ FPURegister ft) {
+ DCHECK((fmt == D) || (fmt == S));
+ GenInstrRegister(COP1, fmt, ft, fs, fd, SELEQZ_C);
+}
+
+
+void Assembler::seleqz_d(FPURegister fd, FPURegister fs, FPURegister ft) {
+ seleqz(D, fd, fs, ft);
+}
+
+
+void Assembler::seleqz_s(FPURegister fd, FPURegister fs, FPURegister ft) {
+ seleqz(S, fd, fs, ft);
+}
+
+
+void Assembler::selnez_d(FPURegister fd, FPURegister fs, FPURegister ft) {
+ selnez(D, fd, fs, ft);
+}
+
+
+void Assembler::selnez_s(FPURegister fd, FPURegister fs, FPURegister ft) {
+ selnez(S, fd, fs, ft);
+}
+
+
+void Assembler::movz_s(FPURegister fd, FPURegister fs, Register rt) {
+ DCHECK(kArchVariant == kMips64r2);
+ GenInstrRegister(COP1, S, rt, fs, fd, MOVZ_C);
+}
+
+
+void Assembler::movz_d(FPURegister fd, FPURegister fs, Register rt) {
+ DCHECK(kArchVariant == kMips64r2);
+ GenInstrRegister(COP1, D, rt, fs, fd, MOVZ_C);
+}
+
+
+void Assembler::movt_s(FPURegister fd, FPURegister fs, uint16_t cc) {
+ DCHECK(kArchVariant == kMips64r2);
+ FPURegister ft;
+ ft.code_ = (cc & 0x0007) << 2 | 1;
+ GenInstrRegister(COP1, S, ft, fs, fd, MOVF);
+}
+
+
+void Assembler::movt_d(FPURegister fd, FPURegister fs, uint16_t cc) {
+ DCHECK(kArchVariant == kMips64r2);
+ FPURegister ft;
+ ft.code_ = (cc & 0x0007) << 2 | 1;
+ GenInstrRegister(COP1, D, ft, fs, fd, MOVF);
+}
+
+
+void Assembler::movf_s(FPURegister fd, FPURegister fs, uint16_t cc) {
+ DCHECK(kArchVariant == kMips64r2);
+ FPURegister ft;
+ ft.code_ = (cc & 0x0007) << 2 | 0;
+ GenInstrRegister(COP1, S, ft, fs, fd, MOVF);
+}
+
+
+void Assembler::movf_d(FPURegister fd, FPURegister fs, uint16_t cc) {
+ DCHECK(kArchVariant == kMips64r2);
+ FPURegister ft;
+ ft.code_ = (cc & 0x0007) << 2 | 0;
+ GenInstrRegister(COP1, D, ft, fs, fd, MOVF);
+}
+
+
+void Assembler::movn_s(FPURegister fd, FPURegister fs, Register rt) {
+ DCHECK(kArchVariant == kMips64r2);
+ GenInstrRegister(COP1, S, rt, fs, fd, MOVN_C);
+}
+
+
+void Assembler::movn_d(FPURegister fd, FPURegister fs, Register rt) {
+ DCHECK(kArchVariant == kMips64r2);
+ GenInstrRegister(COP1, D, rt, fs, fd, MOVN_C);
+}
+
+
+// FPR.
+void Assembler::selnez(SecondaryField fmt, FPURegister fd, FPURegister fs,
+ FPURegister ft) {
+ DCHECK(kArchVariant == kMips64r6);
+ DCHECK((fmt == D) || (fmt == S));
+ GenInstrRegister(COP1, fmt, ft, fs, fd, SELNEZ_C);
+}
+
+
// Arithmetic.
void Assembler::add_s(FPURegister fd, FPURegister fs, FPURegister ft) {
@@ -2397,6 +2601,11 @@ void Assembler::mov_d(FPURegister fd, FPURegister fs) {
}
+void Assembler::mov_s(FPURegister fd, FPURegister fs) {
+ GenInstrRegister(COP1, S, f0, fs, fd, MOV_D);
+}
+
+
void Assembler::neg_s(FPURegister fd, FPURegister fs) {
GenInstrRegister(COP1, S, f0, fs, fd, NEG_D);
}
@@ -2417,8 +2626,27 @@ void Assembler::sqrt_d(FPURegister fd, FPURegister fs) {
}
-// Conversions.
+void Assembler::rsqrt_s(FPURegister fd, FPURegister fs) {
+ GenInstrRegister(COP1, S, f0, fs, fd, RSQRT_S);
+}
+
+
+void Assembler::rsqrt_d(FPURegister fd, FPURegister fs) {
+ GenInstrRegister(COP1, D, f0, fs, fd, RSQRT_D);
+}
+
+
+void Assembler::recip_d(FPURegister fd, FPURegister fs) {
+ GenInstrRegister(COP1, D, f0, fs, fd, RECIP_D);
+}
+
+
+void Assembler::recip_s(FPURegister fd, FPURegister fs) {
+ GenInstrRegister(COP1, S, f0, fs, fd, RECIP_S);
+}
+
+// Conversions.
void Assembler::cvt_w_s(FPURegister fd, FPURegister fs) {
GenInstrRegister(COP1, S, f0, fs, fd, CVT_W_S);
}
@@ -2477,30 +2705,30 @@ void Assembler::rint_d(FPURegister fd, FPURegister fs) { rint(D, fd, fs); }
void Assembler::rint(SecondaryField fmt, FPURegister fd, FPURegister fs) {
DCHECK(kArchVariant == kMips64r6);
- GenInstrRegister(COP1, D, f0, fs, fd, RINT);
+ GenInstrRegister(COP1, fmt, f0, fs, fd, RINT);
}
void Assembler::cvt_l_s(FPURegister fd, FPURegister fs) {
- DCHECK(kArchVariant == kMips64r2);
+ DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
GenInstrRegister(COP1, S, f0, fs, fd, CVT_L_S);
}
void Assembler::cvt_l_d(FPURegister fd, FPURegister fs) {
- DCHECK(kArchVariant == kMips64r2);
+ DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
GenInstrRegister(COP1, D, f0, fs, fd, CVT_L_D);
}
void Assembler::trunc_l_s(FPURegister fd, FPURegister fs) {
- DCHECK(kArchVariant == kMips64r2);
+ DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
GenInstrRegister(COP1, S, f0, fs, fd, TRUNC_L_S);
}
void Assembler::trunc_l_d(FPURegister fd, FPURegister fs) {
- DCHECK(kArchVariant == kMips64r2);
+ DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
GenInstrRegister(COP1, D, f0, fs, fd, TRUNC_L_D);
}
@@ -2535,16 +2763,28 @@ void Assembler::ceil_l_d(FPURegister fd, FPURegister fs) {
}
-void Assembler::mina(SecondaryField fmt, FPURegister fd, FPURegister ft,
- FPURegister fs) {
+void Assembler::class_s(FPURegister fd, FPURegister fs) {
+ DCHECK(kArchVariant == kMips64r6);
+ GenInstrRegister(COP1, S, f0, fs, fd, CLASS_S);
+}
+
+
+void Assembler::class_d(FPURegister fd, FPURegister fs) {
+ DCHECK(kArchVariant == kMips64r6);
+ GenInstrRegister(COP1, D, f0, fs, fd, CLASS_D);
+}
+
+
+void Assembler::mina(SecondaryField fmt, FPURegister fd, FPURegister fs,
+ FPURegister ft) {
DCHECK(kArchVariant == kMips64r6);
DCHECK((fmt == D) || (fmt == S));
GenInstrRegister(COP1, fmt, ft, fs, fd, MINA);
}
-void Assembler::maxa(SecondaryField fmt, FPURegister fd, FPURegister ft,
- FPURegister fs) {
+void Assembler::maxa(SecondaryField fmt, FPURegister fd, FPURegister fs,
+ FPURegister ft) {
DCHECK(kArchVariant == kMips64r6);
DCHECK((fmt == D) || (fmt == S));
GenInstrRegister(COP1, fmt, ft, fs, fd, MAXA);
@@ -2557,7 +2797,7 @@ void Assembler::cvt_s_w(FPURegister fd, FPURegister fs) {
void Assembler::cvt_s_l(FPURegister fd, FPURegister fs) {
- DCHECK(kArchVariant == kMips64r2);
+ DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
GenInstrRegister(COP1, L, f0, fs, fd, CVT_S_L);
}
@@ -2573,7 +2813,7 @@ void Assembler::cvt_d_w(FPURegister fd, FPURegister fs) {
void Assembler::cvt_d_l(FPURegister fd, FPURegister fs) {
- DCHECK(kArchVariant == kMips64r2);
+ DCHECK(kArchVariant == kMips64r2 || kArchVariant == kMips64r6);
GenInstrRegister(COP1, L, f0, fs, fd, CVT_D_L);
}
@@ -2594,6 +2834,17 @@ void Assembler::cmp(FPUCondition cond, SecondaryField fmt,
}
+void Assembler::cmp_s(FPUCondition cond, FPURegister fd, FPURegister fs,
+ FPURegister ft) {
+ cmp(cond, W, fd, fs, ft);
+}
+
+void Assembler::cmp_d(FPUCondition cond, FPURegister fd, FPURegister fs,
+ FPURegister ft) {
+ cmp(cond, L, fd, fs, ft);
+}
+
+
void Assembler::bc1eqz(int16_t offset, FPURegister ft) {
DCHECK(kArchVariant == kMips64r6);
Instr instr = COP1 | BC1EQZ | ft.code() << kFtShift | (offset & kImm16Mask);
@@ -2613,6 +2864,7 @@ void Assembler::c(FPUCondition cond, SecondaryField fmt,
FPURegister fs, FPURegister ft, uint16_t cc) {
DCHECK(kArchVariant != kMips64r6);
DCHECK(is_uint3(cc));
+ DCHECK(fmt == S || fmt == D);
DCHECK((fmt & ~(31 << kRsShift)) == 0);
Instr instr = COP1 | fmt | ft.code() << kFtShift | fs.code() << kFsShift
| cc << 8 | 3 << 4 | cond;
@@ -2620,6 +2872,18 @@ void Assembler::c(FPUCondition cond, SecondaryField fmt,
}
+void Assembler::c_s(FPUCondition cond, FPURegister fs, FPURegister ft,
+ uint16_t cc) {
+ c(cond, S, fs, ft, cc);
+}
+
+
+void Assembler::c_d(FPUCondition cond, FPURegister fs, FPURegister ft,
+ uint16_t cc) {
+ c(cond, D, fs, ft, cc);
+}
+
+
void Assembler::fcmp(FPURegister src1, const double src2,
FPUCondition cond) {
DCHECK(src2 == 0.0);
@@ -2656,6 +2920,7 @@ int Assembler::RelocateInternalReference(RelocInfo::Mode rmode, byte* pc,
}
Instr instr = instr_at(pc);
DCHECK(RelocInfo::IsInternalReferenceEncoded(rmode));
+ DCHECK(IsJ(instr) || IsLui(instr) || IsJal(instr));
if (IsLui(instr)) {
Instr instr_lui = instr_at(pc + 0 * Assembler::kInstrSize);
Instr instr_ori = instr_at(pc + 1 * Assembler::kInstrSize);
@@ -2687,8 +2952,21 @@ int Assembler::RelocateInternalReference(RelocInfo::Mode rmode, byte* pc,
instr_ori2 | (imm & kImm16Mask));
return 4; // Number of instructions patched.
} else {
- UNREACHABLE();
- return 0; // Number of instructions patched.
+ uint32_t imm28 = (instr & static_cast<int32_t>(kImm26Mask)) << 2;
+ if (static_cast<int32_t>(imm28) == kEndOfJumpChain) {
+ return 0; // Number of instructions patched.
+ }
+
+ imm28 += pc_delta;
+ imm28 &= kImm28Mask;
+ DCHECK((imm28 & 3) == 0);
+
+ instr &= ~kImm26Mask;
+ uint32_t imm26 = imm28 >> 2;
+ DCHECK(is_uint26(imm26));
+
+ instr_at_put(pc, instr | (imm26 & kImm26Mask));
+ return 1; // Number of instructions patched.
}
}
@@ -2709,7 +2987,8 @@ void Assembler::GrowBuffer() {
desc.buffer = NewArray<byte>(desc.buffer_size);
desc.instr_size = pc_offset();
- desc.reloc_size = (buffer_ + buffer_size_) - reloc_info_writer.pos();
+ desc.reloc_size =
+ static_cast<int>((buffer_ + buffer_size_) - reloc_info_writer.pos());
// Copy the data.
intptr_t pc_delta = desc.buffer - buffer_;
@@ -2754,6 +3033,13 @@ void Assembler::dd(uint32_t data) {
}
+void Assembler::dq(uint64_t data) {
+ CheckBuffer();
+ *reinterpret_cast<uint64_t*>(pc_) = data;
+ pc_ += sizeof(uint64_t);
+}
+
+
void Assembler::dd(Label* label) {
CheckBuffer();
RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE);
@@ -2851,14 +3137,8 @@ void Assembler::CheckTrampolinePool() {
// references until associated instructions are emitted and available
// to be patched.
RecordRelocInfo(RelocInfo::INTERNAL_REFERENCE_ENCODED);
- // TODO(plind): Verify this, presume I cannot use macro-assembler
- // here.
- lui(at, (imm64 >> 32) & kImm16Mask);
- ori(at, at, (imm64 >> 16) & kImm16Mask);
- dsll(at, at, 16);
- ori(at, at, imm64 & kImm16Mask);
+ j(imm64);
}
- jr(at);
nop();
}
bind(&after_pool);
@@ -2963,20 +3243,7 @@ void Assembler::set_target_address_at(Address pc,
}
-Handle<ConstantPoolArray> Assembler::NewConstantPool(Isolate* isolate) {
- // No out-of-line constant pool support.
- DCHECK(!FLAG_enable_ool_constant_pool);
- return isolate->factory()->empty_constant_pool_array();
-}
-
-
-void Assembler::PopulateConstantPool(ConstantPoolArray* constant_pool) {
- // No out-of-line constant pool support.
- DCHECK(!FLAG_enable_ool_constant_pool);
- return;
-}
-
-
-} } // namespace v8::internal
+} // namespace internal
+} // namespace v8
#endif // V8_TARGET_ARCH_MIPS64