Skip to content

Commit 56d7e5d

Browse files
authored
[RISC-V] Support SV48 Virtual Memory Layout (#101966)
1 parent 5376eca commit 56d7e5d

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

src/coreclr/jit/emitriscv64.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -956,7 +956,9 @@ void emitter::emitIns_R_C(
956956
id->idCodeSize(8);
957957
}
958958
else
959-
id->idCodeSize(16);
959+
{
960+
id->idCodeSize(24);
961+
}
960962

961963
if (EA_IS_GCREF(attr))
962964
{
@@ -1056,11 +1058,11 @@ void emitter::emitIns_R_L(instruction ins, emitAttr attr, BasicBlock* dst, regNu
10561058
// auipc reg, offset-hi20
10571059
// addi reg, reg, offset-lo12
10581060
//
1059-
// else: 3-ins:
1060-
// lui tmp, dst-hi-20bits
1061+
// else: 5-ins:
1062+
// lui tmp, dst-lo-20bits
10611063
// 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
10641066
// add reg, tmp, reg
10651067

10661068
instrDesc* id = emitNewInstr(attr);
@@ -1586,7 +1588,7 @@ unsigned emitter::emitOutputCall(const insGroup* ig, BYTE* dst, instrDesc* id, c
15861588
// jalr t2
15871589

15881590
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
15901592

15911593
int reg2 = (int)(imm & 1);
15921594
imm -= reg2;
@@ -2984,14 +2986,16 @@ BYTE* emitter::emitOutputInstr_OptsRcReloc(BYTE* dst, instruction* ins, unsigned
29842986
BYTE* emitter::emitOutputInstr_OptsRcNoReloc(BYTE* dst, instruction* ins, unsigned offset, regNumber reg1)
29852987
{
29862988
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
29882990
const regNumber rsvdReg = codeGen->rsGetRsvdReg();
29892991

29902992
const instruction lastIns = (*ins == INS_jal) ? (*ins = INS_addi) : *ins;
2991-
const ssize_t high = immediate >> 11;
2993+
const ssize_t high = immediate >> 16;
29922994

29932995
dst += emitOutput_UTypeInstr(dst, INS_lui, rsvdReg, UpperNBitsOfWordSignExtend<20>(high));
29942996
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));
29952999
dst += emitOutput_ITypeInstr(dst, INS_slli, rsvdReg, rsvdReg, 11);
29963000
dst += emitOutput_ITypeInstr(dst, lastIns, reg1, rsvdReg, LowerNBitsOfWord<11>(immediate));
29973001
return dst;
@@ -3027,15 +3031,15 @@ BYTE* emitter::emitOutputInstr_OptsRlReloc(BYTE* dst, ssize_t igOffs, regNumber
30273031
BYTE* emitter::emitOutputInstr_OptsRlNoReloc(BYTE* dst, ssize_t igOffs, regNumber reg1)
30283032
{
30293033
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
30313035

30323036
const regNumber rsvdReg = codeGen->rsGetRsvdReg();
30333037
const ssize_t upperSignExt = UpperWordOfDoubleWordDoubleSignExtend<32, 52>(immediate);
30343038

30353039
dst += emitOutput_UTypeInstr(dst, INS_lui, rsvdReg, UpperNBitsOfWordSignExtend<20>(immediate));
30363040
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);
30393043
dst += emitOutput_RTypeInstr(dst, INS_add, reg1, reg1, rsvdReg);
30403044
return dst;
30413045
}

0 commit comments

Comments
 (0)