diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 527a39dbba4a1..562e000ea1f1b 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -1258,19 +1258,34 @@ void emitter::emitLoadImmediate(emitAttr size, regNumber reg, ssize_t imm) INT32 high19 = ((int32_t)(high31 + 0x800)) >> 12; emitIns_R_I(INS_lui, size, reg, high19); - emitIns_R_R_I(INS_addiw, size, reg, reg, high31 & 0xFFF); + if (high31 & 0xFFF) + { + emitIns_R_R_I(INS_addiw, size, reg, reg, high31 & 0xFFF); + } // And load remaining part part by batches of 11 bits size. INT32 remainingShift = msb - 30; + + UINT32 shiftAccumulator = 0; while (remainingShift > 0) { UINT32 shift = remainingShift >= 11 ? 11 : remainingShift % 11; - emitIns_R_R_I(INS_slli, size, reg, reg, shift); + UINT32 mask = 0x7ff >> (11 - shift); + remainingShift -= shift; + ssize_t low11 = (imm >> remainingShift) & mask; + shiftAccumulator += shift; + + if (low11) + { + emitIns_R_R_I(INS_slli, size, reg, reg, shiftAccumulator); + shiftAccumulator = 0; - UINT32 mask = 0x7ff >> (11 - shift); - ssize_t low11 = (imm >> (remainingShift - shift)) & mask; - emitIns_R_R_I(INS_addi, size, reg, reg, low11); - remainingShift = remainingShift - shift; + emitIns_R_R_I(INS_addi, size, reg, reg, low11); + } + } + if (shiftAccumulator) + { + emitIns_R_R_I(INS_slli, size, reg, reg, shiftAccumulator); } } diff --git a/src/coreclr/vm/riscv64/stubs.cpp b/src/coreclr/vm/riscv64/stubs.cpp index ca242f9a10175..c170b00438893 100644 --- a/src/coreclr/vm/riscv64/stubs.cpp +++ b/src/coreclr/vm/riscv64/stubs.cpp @@ -1071,7 +1071,10 @@ void StubLinkerCPU::EmitMovConstant(IntReg reg, UINT64 imm) EmitLuImm(reg, high19); int low12 = int(high31) << (32-12) >> (32-12); - EmitAddImm(reg, reg, low12); + if (low12) + { + EmitAddImm(reg, reg, low12); + } // And load remaining part by batches of 11 bits size. INT32 remainingShift = msb - 30;