diff options
author | Ali Ijaz Sheikh <ofrobots@google.com> | 2015-08-23 06:09:40 -0700 |
---|---|---|
committer | Rod Vagg <rod@vagg.org> | 2015-09-06 21:38:01 +1000 |
commit | 9fddd83cf9adf505bce2e2373881df0c4d41b261 (patch) | |
tree | 4272ce14c10fea496af2e78fc6debb187d613451 /deps/v8/src/mips64/assembler-mips64.cc | |
parent | 46b7d151674d138e7ea4342d5f3ada1208b87ff2 (diff) | |
download | node-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.cc | 489 |
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 |