commit 9001885200b03a20aebf747727688a6637fb13a9
parent 2a4ecd4c3acc79cf571c40f7894171b7e704a630
Author: Rong "Mantle" Bao <webmaster@csmantle.top>
Date: Thu, 27 Nov 2025 11:57:05 +0000
Bug 1996840 - [riscv64] Part 3: Use helpers in [Macro]Assembler. r=nbp
This patch dedupes several sites where helper functions are available:
* HowMany() when calculating headerSize for Assembler::m_buffer
* SetJalOffset() and SetAuipcOffset()
* is_intn() for offsets in both directions, instead of the current '<='
approach
* kEndOfJumpChain instead of magic constant zero
Differential Revision: https://phabricator.services.mozilla.com/D271187
Diffstat:
2 files changed, 19 insertions(+), 31 deletions(-)
diff --git a/js/src/jit/riscv64/Assembler-riscv64.cpp b/js/src/jit/riscv64/Assembler-riscv64.cpp
@@ -126,22 +126,9 @@ void Assembler::processCodeLabels(uint8_t* rawCode) {
void Assembler::WritePoolGuard(BufferOffset branch, Instruction* dest,
BufferOffset afterPool) {
DEBUG_PRINTF("\tWritePoolGuard\n");
- int32_t off = afterPool.getOffset() - branch.getOffset();
- if (!is_int21(off) || !((off & 0x1) == 0)) {
- printf("%d\n", off);
- MOZ_CRASH("imm invalid");
- }
- // JAL encode is
- // 31 | 30 21 | 20 | 19 12 | 11 7 | 6 0 |
- // imm[20] | imm[10:1] | imm[11] | imm[19:12] | rd | opcode|
- // 1 10 1 8 5 7
- // offset[20:1] dest JAL
- int32_t imm20 = (off & 0xff000) | // bits 19-12
- ((off & 0x800) << 9) | // bit 11
- ((off & 0x7fe) << 20) | // bits 10-1
- ((off & 0x100000) << 11); // bit 20
- Instr instr = JAL | (imm20 & kImm20Mask);
- dest->SetInstructionBits(instr);
+ Instr jal = JAL | (0 & kImm20Mask);
+ jal = SetJalOffset(branch.getOffset(), afterPool.getOffset(), jal);
+ dest->SetInstructionBits(jal);
DEBUG_PRINTF("%p(%x): ", dest, branch.getOffset());
disassembleInstr(dest->InstructionBits(), JitSpew_Codegen);
}
@@ -928,8 +915,7 @@ bool Assembler::target_at_put(BufferOffset pos, BufferOffset target_pos,
int32_t Hi20 = (((int32_t)offset + 0x800) >> 12);
int32_t Lo12 = (int32_t)offset << 20 >> 20;
- instr_auipc =
- (instr_auipc & ~kImm31_12Mask) | ((Hi20 & kImm19_0Mask) << 12);
+ instr_auipc = SetAuipcOffset(Hi20, instr_auipc);
instr_at_put(pos, instr_auipc);
const int kImm31_20Mask = ((1 << 12) - 1) << 20;
@@ -1049,8 +1035,9 @@ void Assembler::bind(Label* label, BufferOffset boff) {
if (label->used()) {
uint32_t next;
- // A used label holds a link to branch that uses it.
do {
+ // A used label holds a link to branch that uses it.
+ // It's okay we use it here since next_link() mutates `label`.
BufferOffset b(label);
DEBUG_PRINTF("\tbind next:%d\n", b.getOffset());
// Even a 0 offset may be invalid if we're out of memory.
@@ -1064,12 +1051,12 @@ void Assembler::bind(Label* label, BufferOffset boff) {
DEBUG_PRINTF("\t fixup: %d dest: %d dist: %d %d %d\n", fixup_pos,
dest.getOffset(), dist, nextOffset().getOffset(),
currentOffset());
- Instruction* instruction = editSrc(b);
- Instr instr = instruction->InstructionBits();
+ Instr instr = editSrc(b)->InstructionBits();
if (IsBranch(instr)) {
- if (dist > kMaxBranchOffset) {
+ if (!is_intn(dist, kBranchOffsetBits)) {
MOZ_ASSERT(next != LabelBase::INVALID_OFFSET);
- MOZ_RELEASE_ASSERT((next - fixup_pos) <= kMaxBranchOffset);
+ MOZ_RELEASE_ASSERT(
+ is_intn(static_cast<int>(next) - fixup_pos, kJumpOffsetBits));
MOZ_ASSERT(IsAuipc(editSrc(BufferOffset(next))->InstructionBits()));
MOZ_ASSERT(
IsJalr(editSrc(BufferOffset(next + 4))->InstructionBits()));
@@ -1081,17 +1068,18 @@ void Assembler::bind(Label* label, BufferOffset boff) {
m_buffer.unregisterBranchDeadline(CondBranchRangeType, deadline);
}
} else if (IsJal(instr)) {
- if (dist > kMaxJumpOffset) {
+ if (!is_intn(dist, kJumpOffsetBits)) {
MOZ_ASSERT(next != LabelBase::INVALID_OFFSET);
- MOZ_RELEASE_ASSERT((next - fixup_pos) <= kMaxJumpOffset);
+ MOZ_RELEASE_ASSERT(
+ is_intn(static_cast<int>(next) - fixup_pos, kJumpOffsetBits));
MOZ_ASSERT(IsAuipc(editSrc(BufferOffset(next))->InstructionBits()));
MOZ_ASSERT(
IsJalr(editSrc(BufferOffset(next + 4))->InstructionBits()));
DEBUG_PRINTF("\t\ttrampolining: %d\n", next);
} else {
target_at_put(b, dest);
- BufferOffset deadline(
- b.getOffset() + ImmBranchMaxForwardOffset(UncondBranchRangeType));
+ BufferOffset deadline(b.getOffset() + ImmBranchMaxForwardOffset(
+ UncondBranchRangeType));
m_buffer.unregisterBranchDeadline(UncondBranchRangeType, deadline);
}
} else {
@@ -1540,7 +1528,7 @@ void Assembler::PatchShortRangeBranchToVeneer(Buffer* buffer, unsigned rangeIdx,
// Verify that the branch range matches what's encoded.
DEBUG_PRINTF("\t%p(%x): ", branchInst, branch.getOffset());
disassembleInstr(branchInst->InstructionBits(), JitSpew_Codegen);
- DEBUG_PRINTF("\t instert veneer %x, branch:%x deadline: %x\n",
+ DEBUG_PRINTF("\t insert veneer %x, branch: %x deadline: %x\n",
veneer.getOffset(), branch.getOffset(), deadline.getOffset());
MOZ_ASSERT(branchRange <= UncondBranchRangeType);
MOZ_ASSERT(branchInst->GetImmBranchRangeType() == branchRange);
@@ -1554,13 +1542,13 @@ void Assembler::PatchShortRangeBranchToVeneer(Buffer* buffer, unsigned rangeIdx,
// The veneer should be an unconditional branch.
int32_t nextElemOffset = target_at(buffer->getInst(branch), branch, false);
int32_t dist;
- // If offset is 0, this is the end of the linked list.
+ // If offset is kEndOfChain, this is the end of the linked list.
if (nextElemOffset != kEndOfChain) {
// Make the offset relative to veneer so it targets the same instruction
// as branchInst.
dist = nextElemOffset - veneer.getOffset();
} else {
- dist = 0;
+ dist = kEndOfJumpChain;
}
int32_t Hi20 = (((int32_t)dist + 0x800) >> 12);
int32_t Lo12 = (int32_t)dist << 20 >> 20;
diff --git a/js/src/jit/riscv64/MacroAssembler-riscv64.cpp b/js/src/jit/riscv64/MacroAssembler-riscv64.cpp
@@ -4844,8 +4844,8 @@ bool MacroAssemblerRiscv64::BranchShortHelper(int32_t offset, Label* L,
MOZ_ASSERT(rt.is_reg());
scratch = rt.rm();
}
- BlockTrampolinePoolScope block_trampoline_pool(this, 2);
{
+ BlockTrampolinePoolScope block_trampoline_pool(this, 2);
switch (cond) {
case Always:
if (!CalculateOffset(L, &offset, OffsetSize::kOffset21)) return false;