Index: src/mips64/assembler-mips64.cc |
diff --git a/src/mips64/assembler-mips64.cc b/src/mips64/assembler-mips64.cc |
index 49e4dd218b06f05d0723aaf788de0b106c5ff233..12f3044d65066a5de04bf8cefeadff7da4d2a956 100644 |
--- a/src/mips64/assembler-mips64.cc |
+++ b/src/mips64/assembler-mips64.cc |
@@ -967,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); |
@@ -1111,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. |
@@ -1158,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); |
@@ -1357,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); |
} |
@@ -1372,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); |
} |
@@ -1428,29 +1455,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); |
} |
@@ -1921,6 +1937,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); |
} |
@@ -1984,6 +2001,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. |
@@ -2232,13 +2299,13 @@ 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, BITSWAP); |
+ 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, DBITSWAP); |
+ GenInstrRegister(SPECIAL3, zero_reg, rt, rd, 0, DBSHFL); |
} |
@@ -2250,6 +2317,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. |