Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
c6832e1
Introduce C extension; decrease code alignment to 2 bytes
fuad1502 Jul 7, 2025
654c6ae
Utilize C extension for the rest of integer register-register operations
fuad1502 Jul 8, 2025
2aa7717
Apply suggestions from code review
fuad1502 Jul 8, 2025
5924e63
Ensure compressed instructions are not yet used in prolog / epilog ge…
fuad1502 Jul 8, 2025
270a63d
Temporarily disable assertion & return early instead when trying to g…
fuad1502 Jul 8, 2025
e5bf174
Fix missed adjustments to unwind info
fuad1502 Jul 12, 2025
e808e45
Update GCInfoTypes and UnwindInfo to reflect code alignment change
fuad1502 Jul 12, 2025
1bb2dd0
Use unsigned type for RVC reg numbers
fuad1502 Jul 12, 2025
1e578a3
Move _MvAdd & MiscAlu cost calculation to the correct place
fuad1502 Jul 12, 2025
29d7cea
Use labels instead of hard coded branch offsets
fuad1502 Jul 13, 2025
e7894f3
Modify TODO comments to TODO-RISCV64-RVC for C extension specific todos
fuad1502 Jul 13, 2025
c44c5ac
Fix skip calculation in unwinder
fuad1502 Jul 15, 2025
bb47230
Update assumption on RISC-V instruction length
fuad1502 Jul 15, 2025
111af3c
Update minimum code alignment of RISC-V in TargetDetails.cs
fuad1502 Jul 15, 2025
f575559
Update RISC-V ELF header to include RVC bit
fuad1502 Jul 15, 2025
cd2d5d4
Adjust and add RISCV64-RVC specific todos
fuad1502 Jul 15, 2025
324258b
Adjust RISC-V RVC instruction formatting in R2RDump
fuad1502 Jul 16, 2025
d56276e
Merge branch 'main' into riscv-jit-opt/c-ext
fuad1502 Jul 16, 2025
47546bb
Add TODO comment on introducing a switch in jitconfigvalues.h to show…
fuad1502 Jul 16, 2025
aa169fe
Fix if defined guard usage
fuad1502 Jul 17, 2025
3aed899
Temporarily disable ProbeRiscV64Quirks
fuad1502 Jul 24, 2025
c011705
Merge branch 'main' into riscv-jit-opt/c-ext
fuad1502 Aug 19, 2025
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
4 changes: 1 addition & 3 deletions src/coreclr/debug/di/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4354,7 +4354,7 @@ HRESULT CordbNativeCode::EnumerateVariableHomes(ICorDebugVariableHomeEnum **ppEn

int CordbNativeCode::GetCallInstructionLength(BYTE *ip, ULONG32 count)
{
#if defined(TARGET_ARM)
#if defined(TARGET_ARM) || defined(TARGET_RISCV64)
if (Is32BitInstruction(*(WORD*)ip))
return 4;
else
Expand Down Expand Up @@ -4726,8 +4726,6 @@ int CordbNativeCode::GetCallInstructionLength(BYTE *ip, ULONG32 count)

_ASSERTE(!"Invalid opcode!");
return -1;
#elif defined(TARGET_RISCV64)
return MAX_INSTRUCTION_LENGTH;
#else
#error Platform not implemented
#endif
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/debug/ee/riscv64/walker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ void NativeWalker::Decode()

LOG((LF_CORDB, LL_INFO100000, "RiscV64Walker::Decode instruction at %p, opcode: %x\n", m_ip, opcode));

// TODO after "C" Standard Extension support implemented, add C.J, C.JAL, C.JR, C.JALR, C.BEQZ, C.BNEZ
// TODO-RISCV64-RVC: after "C" Standard Extension support implemented, add C.J, C.JAL, C.JR, C.JALR, C.BEQZ, C.BNEZ

if ((opcode & 0x7f) == 0x6f) // JAL
{
Expand Down
2 changes: 1 addition & 1 deletion src/coreclr/inc/clrnt.h
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ RtlpGetFunctionEndAddress (
FunctionLength = *(PTR_ULONG64)(ImageBase + FunctionLength) & 0x3ffff;
}

return FunctionEntry->BeginAddress + 4 * FunctionLength;
return FunctionEntry->BeginAddress + 2 * FunctionLength;
}

#define RUNTIME_FUNCTION__BeginAddress(FunctionEntry) ((FunctionEntry)->BeginAddress)
Expand Down
12 changes: 6 additions & 6 deletions src/coreclr/inc/gcinfotypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -803,18 +803,18 @@ struct RISCV64GcInfoEncoding {
// GC Pointers are 8-bytes aligned
static inline constexpr int32_t NORMALIZE_STACK_SLOT (int32_t x) { return ((x)>>3); }
static inline constexpr int32_t DENORMALIZE_STACK_SLOT (int32_t x) { return ((x)<<3); }
// All Instructions are 4 bytes long
static inline constexpr uint32_t NORMALIZE_CODE_LENGTH (uint32_t x) { return ((x)>>2); }
static inline constexpr uint32_t DENORMALIZE_CODE_LENGTH (uint32_t x) { return ((x)<<2); }
// All Instructions are 2/4 bytes long
static inline constexpr uint32_t NORMALIZE_CODE_LENGTH (uint32_t x) { return ((x)>>1); }
static inline constexpr uint32_t DENORMALIZE_CODE_LENGTH (uint32_t x) { return ((x)<<1); }
// Encode Frame pointer X8 as zero, sp/x2 as 1
static inline constexpr uint32_t NORMALIZE_STACK_BASE_REGISTER (uint32_t x) { return ((x) == 8 ? 0u : 1u); }
static inline constexpr uint32_t DENORMALIZE_STACK_BASE_REGISTER (uint32_t x) { return ((x) == 0 ? 8u : 2u); }
static inline constexpr uint32_t NORMALIZE_SIZE_OF_STACK_AREA (uint32_t x) { return ((x)>>3); }
static inline constexpr uint32_t DENORMALIZE_SIZE_OF_STACK_AREA (uint32_t x) { return ((x)<<3); }
static const bool CODE_OFFSETS_NEED_NORMALIZATION = true;
// Instructions are 4 bytes long
static inline constexpr uint32_t NORMALIZE_CODE_OFFSET (uint32_t x) { return ((x)>>2); }
static inline constexpr uint32_t DENORMALIZE_CODE_OFFSET (uint32_t x) { return ((x)<<2); }
// Instructions are 2/4 bytes long
static inline constexpr uint32_t NORMALIZE_CODE_OFFSET (uint32_t x) { return ((x)>>1); }
static inline constexpr uint32_t DENORMALIZE_CODE_OFFSET (uint32_t x) { return ((x)<<1); }

static const int PSP_SYM_STACK_SLOT_ENCBASE = 6;
static const int GENERICS_INST_CONTEXT_STACK_SLOT_ENCBASE = 6;
Expand Down
9 changes: 9 additions & 0 deletions src/coreclr/inc/utilcode.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,15 @@ inline ResultType ThumbCodeToDataPointer(SourceType pCode)

#endif // TARGET_ARM

#ifdef TARGET_RISCV64

inline bool Is32BitInstruction(WORD opcode)
{
return (opcode & 0b11) == 0b11;
}

#endif

// Convert from a PCODE to the corresponding PINSTR. On many architectures this will be the identity function;
// on ARM, this will mask off the THUMB bit.
inline TADDR PCODEToPINSTR(PCODE pc)
Expand Down
21 changes: 16 additions & 5 deletions src/coreclr/jit/codegenriscv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,7 @@ void CodeGen::genZeroInitFrameUsingBlockInit(int untrLclHi, int untrLclLo, regNu
GetEmitter()->emitIns_R_R_R(INS_add, EA_PTRSIZE, rEndAddr, rEndAddr, rAddr);
}

// TODO-RISCV64-RVC: Remove hardcoded branch offset here
GetEmitter()->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_R0, rAddr, padding);
GetEmitter()->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_R0, rAddr, padding + REGSIZE_BYTES);
GetEmitter()->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_R0, rAddr, padding + 2 * REGSIZE_BYTES);
Expand Down Expand Up @@ -1006,10 +1007,11 @@ void CodeGen::genCodeForIncSaturate(GenTree* tree)
regNumber operandReg = genConsumeReg(operand);
emitAttr attr = emitActualTypeSize(tree);

BasicBlock* skip = genCreateTempLabel();
GetEmitter()->emitIns_R_R_I(INS_addi, attr, targetReg, operandReg, 1);
// bne targetReg, zero, 2 * 4
GetEmitter()->emitIns_R_R_I(INS_bne, attr, targetReg, REG_R0, 8);
GetEmitter()->emitIns_J_cond_la(INS_bne, skip, targetReg, REG_R0);
GetEmitter()->emitIns_R_R(INS_not, attr, targetReg, targetReg);
genDefineTempLabel(skip);

genProduceReg(tree);
}
Expand Down Expand Up @@ -1533,6 +1535,8 @@ void CodeGen::genLclHeap(GenTree* tree)
// and localloc size is a multiple of STACK_ALIGN.

// Loop:
BasicBlock* loop = genCreateTempLabel();
genDefineTempLabel(loop);
emit->emitIns_R_R_I(INS_addi, EA_PTRSIZE, REG_SPBASE, REG_SPBASE, -16);

emit->emitIns_R_R_I(INS_sd, EA_PTRSIZE, REG_R0, REG_SPBASE, 8);
Expand All @@ -1546,7 +1550,7 @@ void CodeGen::genLclHeap(GenTree* tree)
emit->emitIns_R_R_I(INS_addi, emitActualTypeSize(type), regCnt, regCnt, -16);

// goto Loop
emit->emitIns_R_R_I(INS_bne, EA_PTRSIZE, regCnt, REG_R0, -4 << 2);
emit->emitIns_J_cond_la(INS_bne, loop, regCnt, REG_R0);

lastTouchDelta = 0;
}
Expand Down Expand Up @@ -1591,8 +1595,10 @@ void CodeGen::genLclHeap(GenTree* tree)
emit->emitIns_R_R_R(INS_sub, EA_PTRSIZE, regCnt, REG_SPBASE, regCnt);

// Overflow, set regCnt to lowest possible value
emit->emitIns_R_R_I(INS_beq, EA_PTRSIZE, tempReg, REG_R0, 2 << 2);
BasicBlock* skip = genCreateTempLabel();
emit->emitIns_J_cond_la(INS_beq, skip, tempReg, REG_R0);
emit->emitIns_R_R(INS_mov, EA_PTRSIZE, regCnt, REG_R0);
genDefineTempLabel(skip);

regNumber rPageSize = internalRegisters.GetSingle(tree);

Expand All @@ -1603,10 +1609,12 @@ void CodeGen::genLclHeap(GenTree* tree)
emit->emitIns_R_R(INS_mov, EA_PTRSIZE, tempReg, REG_SPBASE);

// tickle the page - this triggers a page fault when on the guard page
BasicBlock* loop = genCreateTempLabel();
genDefineTempLabel(loop);
emit->emitIns_R_R_I(INS_lw, EA_4BYTE, REG_R0, tempReg, 0);
emit->emitIns_R_R_R(INS_sub, EA_4BYTE, tempReg, tempReg, rPageSize);

emit->emitIns_R_R_I(INS_bgeu, EA_PTRSIZE, tempReg, regCnt, -2 << 2);
emit->emitIns_J_cond_la(INS_bgeu, loop, tempReg, regCnt);

// lastTouchDelta is dynamic, and can be up to a page. So if we have outgoing arg space,
// we're going to assume the worst and probe.
Expand Down Expand Up @@ -6522,6 +6530,7 @@ void CodeGen::genJumpToThrowHlpBlk_la(
params.addr = helperFunction.addr;
params.callType = EC_FUNC_TOKEN;

// TODO-RISCV64-RVC: Remove hardcoded branch offset here
ssize_t imm = 3 * sizeof(emitter::code_t);
emit->emitIns_R_R_I(ins, EA_PTRSIZE, reg1, reg2, imm);
}
Expand All @@ -6535,12 +6544,14 @@ void CodeGen::genJumpToThrowHlpBlk_la(
params.ireg = REG_DEFAULT_HELPER_CALL_TARGET;
if (compiler->opts.compReloc)
{
// TODO-RISCV64-RVC: Remove hardcoded branch offset here
ssize_t imm = (3 + 1) << 2;
emit->emitIns_R_R_I(ins, EA_PTRSIZE, reg1, reg2, imm);
emit->emitIns_R_AI(INS_jal, EA_PTR_DSP_RELOC, params.ireg, (ssize_t)pAddr);
}
else
{
// TODO-RISCV64-RVC: Remove hardcoded branch offset here
ssize_t imm = 9 << 2;
emit->emitIns_R_R_I(ins, EA_PTRSIZE, reg1, reg2, imm);
// TODO-RISCV64-CQ: In the future we may consider using emitter::emitLoadImmediate instead,
Expand Down
Loading
Loading