Skip to content

Commit

Permalink
[RISC-V] Fixed errors in jit and unwinding (dotnet#85900)
Browse files Browse the repository at this point in the history
* [JIT] Fix some errors in JIT

* Fix errors in unwinding

* [JIT] Pass float value with int arg reg

* [JIT] Fix register overwriting in RSVD

* [JIT] jit-format

* Fix an error

* [JIT] Add LOONGARCH64
  • Loading branch information
clamp03 committed May 9, 2023
1 parent f576c78 commit f1030ed
Show file tree
Hide file tree
Showing 6 changed files with 44 additions and 23 deletions.
6 changes: 3 additions & 3 deletions src/coreclr/jit/codegenriscv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3351,11 +3351,11 @@ void CodeGen::genCodeForCompare(GenTreeOp* tree)
if (varTypeIsFloating(op1Type))
{
assert(tree->OperIs(GT_LT, GT_LE, GT_EQ, GT_NE, GT_GT, GT_GE));
bool IsUnordered = (tree->gtFlags & GTF_RELOP_NAN_UN) != 0;
bool isUnordered = (tree->gtFlags & GTF_RELOP_NAN_UN) != 0;
regNumber regOp1 = op1->GetRegNum();
regNumber regOp2 = op2->GetRegNum();

if (IsUnordered)
if (isUnordered)
{
BasicBlock* skipLabel = nullptr;
if (tree->OperIs(GT_LT))
Expand Down Expand Up @@ -5919,7 +5919,7 @@ void CodeGen::genCodeForCpBlkUnroll(GenTreeBlk* cpBlkNode)

if (size >= 2 * REGSIZE_BYTES)
{
regNumber tempReg2 = rsGetRsvdReg();
regNumber tempReg2 = REG_RA;

for (unsigned regSize = 2 * REGSIZE_BYTES; size >= regSize;
size -= regSize, srcOffset += regSize, dstOffset += regSize)
Expand Down
7 changes: 4 additions & 3 deletions src/coreclr/jit/emitriscv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ void emitter::emitIns_S_R_R(instruction ins, emitAttr attr, regNumber reg1, regN
regNumber reg3 = FPbased ? REG_FPBASE : REG_SPBASE;
regNumber reg2 = offs < 0 ? tmpReg : reg3;
assert(reg2 != REG_NA && reg2 != codeGen->rsGetRsvdReg());
assert(reg1 != codeGen->rsGetRsvdReg());

// regNumber reg2 = reg3;
offs = offs < 0 ? -offs - 8 : offs;
Expand Down Expand Up @@ -365,7 +366,7 @@ void emitter::emitIns_R_S(instruction ins, emitAttr attr, regNumber reg1, int va
break;

default:
NYI_RISCV64("illegal ins within emitIns_S_R!");
NYI_RISCV64("illegal ins within emitIns_R_S!");
return;

} // end switch (ins)
Expand Down Expand Up @@ -502,7 +503,7 @@ void emitter::emitIns_R_I(instruction ins, emitAttr attr, regNumber reg, ssize_t
assert(isGeneralRegisterOrR0(reg));
assert(imm >= -1048576 && imm < 1048576);

code != reg << 7;
code |= reg << 7;
code |= ((imm >> 12) & 0xff) << 12;
code |= ((imm >> 11) & 0x1) << 20;
code |= ((imm >> 1) & 0x3ff) << 21;
Expand Down Expand Up @@ -3370,7 +3371,7 @@ void emitter::emitDisInsName(code_t code, const BYTE* addr, instrDesc* id)
}
return;
case 0x21: // FCVT.D.S
if (opcode4 == 1) // FCVT.D.S
if (opcode3 == 0) // FCVT.D.S
{
printf("fcvt.d.s %s, %s\n", fd, fs1);
}
Expand Down
30 changes: 27 additions & 3 deletions src/coreclr/jit/lclvars.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -914,7 +914,7 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
{
canPassArgInRegisters = varDscInfo->canEnreg(argType, cSlotsToEnregister);
#if defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
// On LoongArch64 and TARGET_RISCV64 , if there aren't any remaining floating-point registers to pass the
// On LoongArch64 and RISCV64, if there aren't any remaining floating-point registers to pass the
// argument,
// integer registers (if any) are used instead.
if (!canPassArgInRegisters && varTypeIsFloating(argType))
Expand Down Expand Up @@ -960,6 +960,7 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
}
else
#elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
unsigned secondAllocatedRegArgNum = 0;
if (argRegTypeInStruct1 != TYP_UNKNOWN)
{
firstAllocatedRegArgNum = varDscInfo->allocRegArg(argRegTypeInStruct1, 1);
Expand Down Expand Up @@ -1022,7 +1023,7 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
varDsc->lvIs4Field1 = (genTypeSize(argRegTypeInStruct1) == 4) ? 1 : 0;
if (argRegTypeInStruct2 != TYP_UNKNOWN)
{
unsigned secondAllocatedRegArgNum = varDscInfo->allocRegArg(argRegTypeInStruct2, 1);
secondAllocatedRegArgNum = varDscInfo->allocRegArg(argRegTypeInStruct2, 1);
varDsc->SetOtherArgReg(genMapRegArgNumToRegNum(secondAllocatedRegArgNum, argRegTypeInStruct2));
varDsc->lvIs4Field2 = (genTypeSize(argRegTypeInStruct2) == 4) ? 1 : 0;
}
Expand Down Expand Up @@ -1114,7 +1115,30 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un
}
}
else
#endif // defined(UNIX_AMD64_ABI)
#elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
if (varTypeIsStruct(argType))
{
if (argRegTypeInStruct1 == TYP_UNKNOWN)
{
printf("first: <not used>");
}
else
{
printf("first: %s",
getRegName(genMapRegArgNumToRegNum(firstAllocatedRegArgNum, argRegTypeInStruct1)));
}
if (argRegTypeInStruct2 == TYP_UNKNOWN)
{
printf(", second: <not used>");
}
else
{
printf(", second: %s",
getRegName(genMapRegArgNumToRegNum(secondAllocatedRegArgNum, argRegTypeInStruct2)));
}
}
else
#endif // UNIX_AMD64_ABI, TARGET_LOONGARCH64, TARGET_RISCV64
{
assert(varTypeUsesFloatReg(argType) || varTypeUsesIntReg(argType));

Expand Down
6 changes: 1 addition & 5 deletions src/coreclr/jit/scopeinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -961,15 +961,11 @@ void CodeGen::psiBegProlog()
else
{
regType = compiler->mangleVarArgsType(lclVarDsc->TypeGet());
#ifdef TARGET_LOONGARCH64
if (emitter::isGeneralRegisterOrR0(lclVarDsc->GetArgReg()) && isFloatRegType(regType))
{
// For LoongArch64's ABI, the float args may be passed by integer register.
// For LoongArch64 and RISCV64's ABI, the float args may be passed by integer register.
regType = TYP_LONG;
}
#else // TARGET_RISCV64
// For RV64GC -mabi=lp64d is assumed, so floats are not passed through integer registers.
#endif
}
#else
var_types regType = compiler->mangleVarArgsType(lclVarDsc->TypeGet());
Expand Down
12 changes: 6 additions & 6 deletions src/coreclr/jit/unwindriscv64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ void Compiler::unwindSaveReg(regNumber reg, int offset)
BYTE x = (BYTE)(reg - REG_F8);
assert(0 <= x && x <= 0x13);

pu->AddCode(0xDC | (BYTE)(x >> 3), (BYTE)(x << 4) | (BYTE)(z >> 8), (BYTE)z); // TODO NEED TO CHECK LATER
pu->AddCode(0xDC | (BYTE)(x >> 4), (BYTE)(x << 4) | (BYTE)(z >> 8), (BYTE)z);
}
}

Expand Down Expand Up @@ -551,19 +551,19 @@ void DumpUnwindInfo(Compiler* comp,
getRegName(REG_F24 + x, true), getRegName(REG_F24 + x + 1, true), (z + 1) * 8);
}
#endif
else if (b1 == 0xDC)
else if ((b1 & 0xDC) == 0xDC)
{
// save_freg: 11011100 | 0xxxzzzz | zzzzzzzz : save reg f(24 + #X) at [sp + #Z * 8], offset <= 2047
// save_freg: 1101110x | xxxxzzzz | zzzzzzzz : save reg f(8 + #X) at [sp + #Z * 8], offset <= 2047
assert(i + 1 < countOfUnwindCodes);
b2 = *pUnwindCode++;
b3 = *pUnwindCode++;
i += 2;

x = (DWORD)(b2 >> 4);
z = ((DWORD)(b2 & 0xF) << 8) | (DWORD)b3;
x = (DWORD)((b1 & 0x1) << 4) | (DWORD)(b2 >> 4);
z = ((DWORD)(2 & 0xF) << 8) | (DWORD)b3;

printf(" %02X %02X %02X save_freg X#%u Z#%u (0x%02X); fsd %s, [sp, #%u]\n", b1, b2, b3, x, z, z,
getRegName(REG_F24 + x), z * 8);
getRegName(REG_F8 + x), z * 8);
}
#if 0
else if (b1 == 0xDE)
Expand Down
6 changes: 3 additions & 3 deletions src/coreclr/unwinder/riscv64/unwinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -885,10 +885,10 @@ Return Value:
}

//
// save_freg (11011100|0xxxzzzz|zzzzzzzz): save reg f(24+#X) at [sp+#Z*8], offset <= 32767
// save_freg (1101110x|xxxxzzzz|zzzzzzzz): save reg f(8+#X) at [sp+#Z*8], offset <= 32767
//

else if (CurCode == 0xdc) {
else if ((CurCode & 0xdc) == 0xdc) {
if (AccumulatedSaveNexts != 0) {
return STATUS_UNWIND_INVALID_SEQUENCE;
}
Expand All @@ -899,7 +899,7 @@ Return Value:
Status = RtlpUnwindRestoreFpRegisterRange(
ContextRecord,
8 * (((NextCode & 0xf) << 8) + NextCode1),
24 + (NextCode >> 4),
8 + (NextCode >> 4) + ((CurCode & 0x1) << 4),
1,
UnwindParams);
}
Expand Down

0 comments on commit f1030ed

Please sign in to comment.