Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions src/coreclr/jit/codegenriscv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2351,7 +2351,7 @@ void CodeGen::genCodeForCmpXchg(GenTreeCmpXchg* treeNode)
e->emitIns_R_R_R(is4 ? INS_lr_w : INS_lr_d, size, target, loc, REG_R0); // load original value
e->emitIns_J_cond_la(INS_bne, fail, target, comparand); // fail if doesn’t match
e->emitIns_R_R_R(is4 ? INS_sc_w : INS_sc_d, size, storeErr, loc, val); // try to update
e->emitIns_J(INS_bnez, retry, storeErr); // retry if update failed
e->emitIns_J_cond_la(INS_bnez, retry, storeErr); // retry if update failed
genDefineTempLabel(fail);

gcInfo.gcMarkRegSetNpt(locOp->gtGetRegMask());
Expand Down Expand Up @@ -3292,8 +3292,7 @@ void CodeGen::genCodeForJumpCompare(GenTreeOpCC* tree)
}

assert(emitter::isGeneralRegisterOrR0(reg1) && emitter::isGeneralRegisterOrR0(reg2));
int regs = (int)reg1 | (((int)reg2) << 5);
GetEmitter()->emitIns_J(ins, compiler->compCurBB->GetTrueTarget(), regs);
GetEmitter()->emitIns_J_cond_la(ins, compiler->compCurBB->GetTrueTarget(), reg1, reg2);

// If we cannot fall into the false target, emit a jump to it
BasicBlock* falseTarget = compiler->compCurBB->GetFalseTarget();
Expand Down Expand Up @@ -5336,7 +5335,7 @@ void CodeGen::genCodeForInitBlkLoop(GenTreeBlk* initBlkNode)
// tempReg = tempReg - 8
GetEmitter()->emitIns_R_R_I(INS_addi, EA_PTRSIZE, tempReg, tempReg, -8);
// if (tempReg != dstReg) goto loop;
GetEmitter()->emitIns_J(INS_bne, loop, (int)tempReg | ((int)dstReg << 5));
GetEmitter()->emitIns_J_cond_la(INS_bne, loop, tempReg, dstReg);
GetEmitter()->emitEnableGC();

gcInfo.gcMarkRegSetNpt(genRegMask(dstReg));
Expand Down Expand Up @@ -6283,10 +6282,8 @@ void CodeGen::genJumpToThrowHlpBlk_la(
#endif // !FEATURE_FIXED_OUT_ARGS
}

noway_assert(excpRaisingBlock != nullptr);

// Jump to the exception-throwing block on error.
emit->emitIns_J(ins, excpRaisingBlock, (int)reg1 | ((int)reg2 << 5)); // 5-bits;
emit->emitIns_J_cond_la(ins, excpRaisingBlock, reg1, reg2);
}
else
{
Expand Down
64 changes: 47 additions & 17 deletions src/coreclr/jit/emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1306,7 +1306,7 @@ void emitter::emitBegFN(bool hasFramePtr
emitFirstColdIG = nullptr;
emitTotalCodeSize = 0;

#if defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
#if defined(TARGET_LOONGARCH64)
emitCounts_INS_OPTS_J = 0;
#endif

Expand Down Expand Up @@ -4840,15 +4840,15 @@ void emitter::emitRemoveJumpToNextInst()
/*****************************************************************************
* Bind targets of relative jumps to choose the smallest possible encoding.
* X86 and AMD64 have a small and large encoding.
* ARM has a small, medium, and large encoding. The large encoding is a pseudo-op
* ARM and RISC-V have a small, medium, and large encoding. The large encoding is a pseudo-op
* to handle greater range than the conditional branch instructions can handle.
* ARM64 has a small and large encoding for both conditional branch and loading label addresses.
* The large encodings are pseudo-ops that represent a multiple instruction sequence, similar to ARM. (Currently
* NYI).
* LoongArch64 has an individual implementation for emitJumpDistBind().
*/

#if !defined(TARGET_LOONGARCH64) && !defined(TARGET_RISCV64)
#if !defined(TARGET_LOONGARCH64)
void emitter::emitJumpDistBind()
{
#ifdef DEBUG
Expand All @@ -4873,9 +4873,9 @@ void emitter::emitJumpDistBind()
// to a small jump. If it is small enough, we will iterate in hopes of
// converting those jumps we missed converting the first (or second...) time.

#if defined(TARGET_ARM)
#if defined(TARGET_ARM) || defined(TARGET_RISCV64)
UNATIVE_OFFSET minMediumExtra; // Same as 'minShortExtra', but for medium-sized jumps.
#endif // TARGET_ARM
#endif // TARGET_ARM || TARGET_RISCV64

UNATIVE_OFFSET adjIG;
UNATIVE_OFFSET adjLJ;
Expand Down Expand Up @@ -4911,9 +4911,9 @@ void emitter::emitJumpDistBind()
adjIG = 0;
minShortExtra = (UNATIVE_OFFSET)-1;

#if defined(TARGET_ARM)
#if defined(TARGET_ARM) || defined(TARGET_RISCV64)
minMediumExtra = (UNATIVE_OFFSET)-1;
#endif // TARGET_ARM
#endif // TARGET_ARM || TARGET_RISCV64

for (jmp = emitJumpList; jmp; jmp = jmp->idjNext)
{
Expand All @@ -4926,12 +4926,12 @@ void emitter::emitJumpDistBind()
NATIVE_OFFSET nsd = 0; // small jump max. neg distance
NATIVE_OFFSET psd = 0; // small jump max. pos distance

#if defined(TARGET_ARM)
#if defined(TARGET_ARM) || defined(TARGET_RISCV64)
UNATIVE_OFFSET msz = 0; // medium jump size
NATIVE_OFFSET nmd = 0; // medium jump max. neg distance
NATIVE_OFFSET pmd = 0; // medium jump max. pos distance
NATIVE_OFFSET mextra; // How far beyond the medium jump range is this jump offset?
#endif // TARGET_ARM
#endif // TARGET_ARM || TARGET_RISCV64

NATIVE_OFFSET extra; // How far beyond the short jump range is this jump offset?
UNATIVE_OFFSET srcInstrOffs; // offset of the source instruction of the jump
Expand Down Expand Up @@ -5039,6 +5039,34 @@ void emitter::emitJumpDistBind()
}
#endif // TARGET_ARM64

#ifdef TARGET_RISCV64
/* Figure out the smallest size we can end up with */

// TODO-RISC64-RVC: add compressed branches and jumps
if (emitIsCmpJump(jmp))
{
ssz = sizeof(code_t);
nsd = B_DIST_SMALL_MAX_NEG;
psd = B_DIST_SMALL_MAX_POS;

// 2 instructions: "reverse cmp-and-branch; jal offset;"
// Move bounds to the right by 'ssz' to account for the reversed branch instruction size.
msz = sizeof(code_t) * 2;
nmd = J_DIST_SMALL_MAX_NEG + ssz;
pmd = J_DIST_SMALL_MAX_POS + ssz;
}
else if (emitIsUncondJump(jmp))
{
ssz = sizeof(code_t);
nsd = J_DIST_SMALL_MAX_NEG;
psd = J_DIST_SMALL_MAX_POS;
}
else
{
assert(!"Unknown jump instruction");
}
#endif // TARGET_RISCV64

/* Make sure the jumps are properly ordered */

#ifdef DEBUG
Expand Down Expand Up @@ -5244,9 +5272,9 @@ void emitter::emitJumpDistBind()
#if defined(TARGET_ARM)
srcEncodingOffs =
srcInstrOffs + 4; // For relative branches, ARM PC is always considered to be the instruction address + 4
#elif defined(TARGET_ARM64)
srcEncodingOffs =
srcInstrOffs; // For relative branches, ARM64 PC is always considered to be the instruction address
#elif defined(TARGET_ARM64) || defined(TARGET_RISCV64)
srcEncodingOffs = srcInstrOffs; // For relative branches, ARM64 and RISC-V PC is always considered to be the
// instruction address
#else
srcEncodingOffs = srcInstrOffs + ssz; // Encoding offset of relative offset for small branch
#endif
Expand Down Expand Up @@ -5360,14 +5388,14 @@ void emitter::emitJumpDistBind()
minShortExtra = (unsigned)extra;
}

#if defined(TARGET_ARM)
#if defined(TARGET_ARM) || defined(TARGET_RISCV64)

// If we're here, we couldn't convert to a small jump.
// Handle conversion to medium-sized conditional jumps.
// 'srcInstrOffs', 'srcEncodingOffs', 'dstOffs', 'jmpDist' have already been computed
// and don't need to be recomputed.

if (emitIsCondJump(jmp))
if (emitIsCmpJump(jmp))
{
if (jmpIG->igNum < tgtIG->igNum)
{
Expand Down Expand Up @@ -5432,7 +5460,7 @@ void emitter::emitJumpDistBind()
minMediumExtra = (unsigned)mextra;
}

#endif // TARGET_ARM
#endif // TARGET_ARM || TARGET_RISCV64

/*****************************************************************************
* We arrive here if the jump must stay long, at least for now.
Expand Down Expand Up @@ -5475,13 +5503,15 @@ void emitter::emitJumpDistBind()
// The size of IF_LARGEJMP/IF_LARGEADR/IF_LARGELDC are 8 or 12.
// All other code size is 4.
assert((sizeDif == 4) || (sizeDif == 8));
#elif defined(TARGET_RISCV64)
assert((sizeDif == 0) || (sizeDif == 4) || (sizeDif == 8));
#else
#error Unsupported or unset target architecture
#endif

goto NEXT_JMP;

#if defined(TARGET_ARM)
#if defined(TARGET_ARM) || defined(TARGET_RISCV64)

/*****************************************************************************/
/* Handle conversion to medium jump */
Expand All @@ -5508,7 +5538,7 @@ void emitter::emitJumpDistBind()

goto NEXT_JMP;

#endif // TARGET_ARM
#endif // TARGET_ARM || TARGET_RISCV64

/*****************************************************************************/

Expand Down
4 changes: 2 additions & 2 deletions src/coreclr/jit/emit.h
Original file line number Diff line number Diff line change
Expand Up @@ -2636,9 +2636,9 @@ class emitter
#endif // defined(TARGET_X86)
#endif // !defined(HOST_64BIT)

#if defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
#if defined(TARGET_LOONGARCH64)
unsigned int emitCounts_INS_OPTS_J;
#endif // TARGET_LOONGARCH64 || TARGET_RISCV64
#endif // TARGET_LOONGARCH64

instrDesc* emitFirstInstrDesc(BYTE* idData) const;
void emitAdvanceInstrDesc(instrDesc** id, size_t idSize) const;
Expand Down
Loading
Loading