@@ -956,7 +956,9 @@ void emitter::emitIns_R_C(
956
956
id->idCodeSize (8 );
957
957
}
958
958
else
959
- id->idCodeSize (16 );
959
+ {
960
+ id->idCodeSize (24 );
961
+ }
960
962
961
963
if (EA_IS_GCREF (attr))
962
964
{
@@ -1056,11 +1058,11 @@ void emitter::emitIns_R_L(instruction ins, emitAttr attr, BasicBlock* dst, regNu
1056
1058
// auipc reg, offset-hi20
1057
1059
// addi reg, reg, offset-lo12
1058
1060
//
1059
- // else: 3 -ins:
1060
- // lui tmp, dst-hi -20bits
1061
+ // else: 5 -ins:
1062
+ // lui tmp, dst-lo -20bits
1061
1063
// addi tmp, tmp, dst-lo-12bits
1062
- // lui reg, 0xff << 12
1063
- // slli reg, reg, 32
1064
+ // lui reg, dst-hi-15bits
1065
+ // slli reg, reg, 20
1064
1066
// add reg, tmp, reg
1065
1067
1066
1068
instrDesc* id = emitNewInstr (attr);
@@ -1586,7 +1588,7 @@ unsigned emitter::emitOutputCall(const insGroup* ig, BYTE* dst, instrDesc* id, c
1586
1588
// jalr t2
1587
1589
1588
1590
ssize_t imm = (ssize_t )(id->idAddr ()->iiaAddr );
1589
- assert ((imm >> 32 ) <= 0xff );
1591
+ assert ((uint64_t )( imm >> 32 ) <= 0x7fff ); // RISC-V Linux Kernel SV48
1590
1592
1591
1593
int reg2 = (int )(imm & 1 );
1592
1594
imm -= reg2;
@@ -2984,14 +2986,16 @@ BYTE* emitter::emitOutputInstr_OptsRcReloc(BYTE* dst, instruction* ins, unsigned
2984
2986
BYTE* emitter::emitOutputInstr_OptsRcNoReloc (BYTE* dst, instruction* ins, unsigned offset, regNumber reg1)
2985
2987
{
2986
2988
const ssize_t immediate = reinterpret_cast <ssize_t >(emitConsBlock) + offset;
2987
- assertCodeLength (static_cast <size_t >(immediate), 40 );
2989
+ assertCodeLength (static_cast <size_t >(immediate), 48 ); // RISC-V Linux Kernel SV48
2988
2990
const regNumber rsvdReg = codeGen->rsGetRsvdReg ();
2989
2991
2990
2992
const instruction lastIns = (*ins == INS_jal) ? (*ins = INS_addi) : *ins;
2991
- const ssize_t high = immediate >> 11 ;
2993
+ const ssize_t high = immediate >> 16 ;
2992
2994
2993
2995
dst += emitOutput_UTypeInstr (dst, INS_lui, rsvdReg, UpperNBitsOfWordSignExtend<20 >(high));
2994
2996
dst += emitOutput_ITypeInstr (dst, INS_addi, rsvdReg, rsvdReg, LowerNBitsOfWord<12 >(high));
2997
+ dst += emitOutput_ITypeInstr (dst, INS_slli, rsvdReg, rsvdReg, 5 );
2998
+ dst += emitOutput_ITypeInstr (dst, INS_addi, rsvdReg, rsvdReg, LowerNBitsOfWord<5 >(immediate >> 11 ));
2995
2999
dst += emitOutput_ITypeInstr (dst, INS_slli, rsvdReg, rsvdReg, 11 );
2996
3000
dst += emitOutput_ITypeInstr (dst, lastIns, reg1, rsvdReg, LowerNBitsOfWord<11 >(immediate));
2997
3001
return dst;
@@ -3027,15 +3031,15 @@ BYTE* emitter::emitOutputInstr_OptsRlReloc(BYTE* dst, ssize_t igOffs, regNumber
3027
3031
BYTE* emitter::emitOutputInstr_OptsRlNoReloc (BYTE* dst, ssize_t igOffs, regNumber reg1)
3028
3032
{
3029
3033
const ssize_t immediate = reinterpret_cast <ssize_t >(emitCodeBlock) + igOffs;
3030
- assertCodeLength (static_cast <size_t >(immediate), 32 + 20 );
3034
+ assertCodeLength (static_cast <size_t >(immediate), 48 ); // RISC-V Linux Kernel SV48
3031
3035
3032
3036
const regNumber rsvdReg = codeGen->rsGetRsvdReg ();
3033
3037
const ssize_t upperSignExt = UpperWordOfDoubleWordDoubleSignExtend<32 , 52 >(immediate);
3034
3038
3035
3039
dst += emitOutput_UTypeInstr (dst, INS_lui, rsvdReg, UpperNBitsOfWordSignExtend<20 >(immediate));
3036
3040
dst += emitOutput_ITypeInstr (dst, INS_addi, rsvdReg, rsvdReg, LowerNBitsOfWord<12 >(immediate));
3037
- dst += emitOutput_ITypeInstr (dst, INS_addi , reg1, REG_ZERO, LowerNBitsOfWord<12 >(upperSignExt));
3038
- dst += emitOutput_ITypeInstr (dst, INS_slli, reg1, reg1, 32 );
3041
+ dst += emitOutput_UTypeInstr (dst, INS_lui , reg1, LowerNBitsOfWord<16 >(upperSignExt));
3042
+ dst += emitOutput_ITypeInstr (dst, INS_slli, reg1, reg1, 20 );
3039
3043
dst += emitOutput_RTypeInstr (dst, INS_add, reg1, reg1, rsvdReg);
3040
3044
return dst;
3041
3045
}
0 commit comments