diff --git a/src/coreclr/jit/codegenriscv64.cpp b/src/coreclr/jit/codegenriscv64.cpp index 540d92a906023c..f1f48942f3f418 100644 --- a/src/coreclr/jit/codegenriscv64.cpp +++ b/src/coreclr/jit/codegenriscv64.cpp @@ -940,13 +940,14 @@ void CodeGen::instGen_Set_Reg_To_Imm(emitAttr size, emitter* emit = GetEmitter(); assert(genIsValidIntReg(reg)); - if (EA_IS_RELOC(size)) + emitAttr emitSize = EA_REMOVE_FLG(size, EA_GCREF_FLG | EA_BYREF_FLG); + if (EA_IS_RELOC(emitSize)) { - emit->emitIns_R_AI(INS_addi, size, reg, reg, imm); + emit->emitIns_R_AI(INS_addi, emitSize, reg, reg, imm); } else { - emit->emitLoadImmediate(size, reg, imm); + emit->emitLoadImmediate(emitSize, reg, imm); } regSet.verifyRegUsed(reg); diff --git a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs index 3ed1f41e378e9d..4ca57a637fdf51 100644 --- a/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs +++ b/src/coreclr/tools/Common/Compiler/DependencyAnalysis/Relocation.cs @@ -579,12 +579,24 @@ private static unsafe void PutRiscV64AuipcCombo(uint* pCode, long offset, bool i int hi20 = (int)(offset - lo12); Debug.Assert((long)lo12 + (long)hi20 == offset); - // Debug.Assert(GetRiscV64AuipcCombo(pCode, isStype) == 0); - pCode[0] |= (uint)hi20; - int bottomBitsPos = isStype ? 7 : 20; - pCode[1] |= (uint)((lo12 >> 5) << 25); // top 7 bits are in the same spot - pCode[1] |= (uint)((lo12 & 0x1F) << bottomBitsPos); - // Debug.Assert(GetRiscV64AuipcCombo(pCode, isStype) == offset); + // Replace existing immediate bits because RISC-V relocation placeholders may already carry addends. + pCode[0] &= 0x00000FFF; + pCode[0] |= (uint)hi20 & 0xFFFFF000; + + uint lo12Bits = (uint)lo12 & 0xFFF; + if (isStype) + { + pCode[1] &= 0x01FFF07F; + pCode[1] |= (lo12Bits & 0xFE0) << 20; + pCode[1] |= (lo12Bits & 0x01F) << 7; + } + else + { + pCode[1] &= 0x000FFFFF; + pCode[1] |= lo12Bits << 20; + } + + Debug.Assert(GetRiscV64AuipcCombo(pCode, isStype) == offset); } public Relocation(RelocType relocType, int offset, ISymbolNode target) diff --git a/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp b/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp index 5c8b3e559215d9..a614d51a74de2e 100644 --- a/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp +++ b/src/coreclr/tools/superpmi/superpmi-shared/spmiutil.cpp @@ -518,11 +518,23 @@ void PutRiscV64AuipcCombo(UINT32 * pCode, INT64 offset, bool isStype) INT32 hi20 = INT32(offset - lo12); _ASSERTE(INT64(lo12) + INT64(hi20) == offset); - _ASSERTE(GetRiscV64AuipcCombo(pCode, isStype) == 0); - pCode[0] |= hi20; - int bottomBitsPos = isStype ? 7 : 20; - pCode[1] |= (lo12 >> 5) << 25; // top 7 bits are in the same spot - pCode[1] |= (lo12 & 0x1F) << bottomBitsPos; + // Replace existing immediate bits because RISC-V relocation placeholders may already carry addends. + pCode[0] &= 0x00000FFF; + pCode[0] |= hi20 & 0xFFFFF000; + + UINT32 lo12Bits = UINT32(lo12) & 0xFFF; + if (isStype) + { + pCode[1] &= 0x01FFF07F; + pCode[1] |= (lo12Bits & 0xFE0) << 20; + pCode[1] |= (lo12Bits & 0x01F) << 7; + } + else + { + pCode[1] &= 0x000FFFFF; + pCode[1] |= lo12Bits << 20; + } + _ASSERTE(GetRiscV64AuipcCombo(pCode, isStype) == offset); } diff --git a/src/coreclr/utilcode/util.cpp b/src/coreclr/utilcode/util.cpp index 4cb88c41fe08f2..fac2837f65952f 100644 --- a/src/coreclr/utilcode/util.cpp +++ b/src/coreclr/utilcode/util.cpp @@ -2261,11 +2261,23 @@ void PutRiscV64AuipcCombo(UINT32 * pCode, INT64 offset, bool isStype) INT32 hi20 = INT32(offset - lo12); _ASSERTE(INT64(lo12) + INT64(hi20) == offset); - _ASSERTE(GetRiscV64AuipcCombo(pCode, isStype) == 0); - pCode[0] |= hi20; - int bottomBitsPos = isStype ? 7 : 20; - pCode[1] |= (lo12 >> 5) << 25; // top 7 bits are in the same spot - pCode[1] |= (lo12 & 0x1F) << bottomBitsPos; + // Replace existing immediate bits because RISC-V relocation placeholders may already carry addends. + pCode[0] &= 0x00000FFF; + pCode[0] |= hi20 & 0xFFFFF000; + + UINT32 lo12Bits = UINT32(lo12) & 0xFFF; + if (isStype) + { + pCode[1] &= 0x01FFF07F; + pCode[1] |= (lo12Bits & 0xFE0) << 20; + pCode[1] |= (lo12Bits & 0x01F) << 7; + } + else + { + pCode[1] &= 0x000FFFFF; + pCode[1] |= lo12Bits << 20; + } + _ASSERTE(GetRiscV64AuipcCombo(pCode, isStype) == offset); }