Repository: dotnet/runtime
File: src/coreclr/jit/emitriscv64.cpp (C++)

Code before:
            assert(numberOfInstructions < absMaxInsCount);
            if (doEmit)
            {
                id->ins[numberOfInstructions - 1]    = INS_srli;
                id->values[numberOfInstructions - 1] = srliShiftAmount;
            }
        }

        if (doEmit)
        {
            id->idCodeSize(numberOfInstructions * 4);
            id->idIns(id->ins[numberOfInstructions - 1]);
            appendToCurIG(id);
        }

        return numberOfInstructions;
    }
    else if (EA_SIZE(size) == EA_PTRSIZE)
    {
        if (doEmit)
        {
            assert(!emitComp->compGeneratingProlog && !emitComp->compGeneratingEpilog);
            auto constAddr = emitDataConst(&originalImm, sizeof(long), sizeof(long), TYP_LONG);
            emitIns_R_C(INS_ld, EA_PTRSIZE, reg, REG_NA, emitComp->eeFindJitDataOffs(constAddr));
        }
        return 2;
    }
    else
    {
        assert(false && "If number of instruction exceeds MAX_NUM_OF_LOAD_IMM_INS, imm must be 8 bytes");
    }
    return 0;
}

/*****************************************************************************
 *
 *  Emits load of 64-bit constant to register.
 *
 */
void emitter::emitLoadImmediate(emitAttr size, regNumber reg, ssize_t imm)
{
    assert(!EA_IS_RELOC(size));
    assert(isGeneralRegister(reg));

    if (isValidSimm12(imm))
    {
        emitIns_R_R_I(INS_addi, size, reg, REG_R0, imm & 0xFFF);
        return;
    }

    emitLoadImmediateLarge(size, reg, imm, /* doEmit */ true);

Review comment (performance):
The cost looks distorted here.

This case generates a 8-byte data constant (not included currently in size) and `auipc+ld` to retrieve it (loads are more expensive than instructions on registers). 

Code after:
                }
            }
            shift = 0;
        }
        if (chunkLsbPos == 0)
        {
            break;
        }
        shift += (chunkLsbPos < 11) ? chunkLsbPos : 11;
        chunkMask = (chunkLsbPos < 11) ? (chunkMask >> (11 - chunkLsbPos)) : WordMask(11);
        chunkLsbPos -= (chunkLsbPos < 11) ? chunkLsbPos : 11;
    }
    if (shift > 0)
    {
        numberOfInstructions += 1;
        if (doEmit && (numberOfInstructions <= insCountLimit))
        {
            ins[numberOfInstructions - 1]    = INS_slli;
            values[numberOfInstructions - 1] = shift;
        }
    }

    // STEP 6: Determine whether to use emitDataConst or emit generated instructions

    if (numberOfInstructions <= insCountLimit)
    {
        instrDescLoadImm* id;
        if (doEmit)
        {
            id = static_cast<instrDescLoadImm*>(emitNewInstrLoadImm(size, originalImm));
            id->idReg1(reg);
            memcpy(id->ins, ins, sizeof(instruction) * numberOfInstructions);
            memcpy(id->values, values, sizeof(int32_t) * numberOfInstructions);
        }

        if (utilizeSRLI)
        {
            numberOfInstructions += 1;
            assert(numberOfInstructions < absMaxInsCount);
            if (doEmit)
            {
                id->ins[numberOfInstructions - 1]    = INS_srli;
                id->values[numberOfInstructions - 1] = srliShiftAmount;
            }
        }

        if (doEmit)
        {
            id->idCodeSize(numberOfInstructions * 4);
            id->idIns(id->ins[numberOfInstructions - 1]);
            appendToCurIG(id);