From a27e88ef20d6d458f9558d6c6f92d90f3df19085 Mon Sep 17 00:00:00 2001 From: qiaopengcheng Date: Wed, 25 May 2022 08:53:12 +0800 Subject: [PATCH] [LoongArch64] Fix some errors for LA-ABI. (#69771) --- src/coreclr/jit/codegenloongarch64.cpp | 8 ++----- src/coreclr/jit/emitloongarch64.cpp | 30 ++++++++++++++++++-------- src/coreclr/jit/lclvars.cpp | 3 +-- src/coreclr/jit/lsraloongarch64.cpp | 5 +---- src/coreclr/jit/morph.cpp | 1 + 5 files changed, 26 insertions(+), 21 deletions(-) diff --git a/src/coreclr/jit/codegenloongarch64.cpp b/src/coreclr/jit/codegenloongarch64.cpp index e05cd20a7da6e..e3b3ebaa6147f 100644 --- a/src/coreclr/jit/codegenloongarch64.cpp +++ b/src/coreclr/jit/codegenloongarch64.cpp @@ -5297,6 +5297,7 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode) case GT_OR: case GT_XOR: case GT_AND: + case GT_AND_NOT: assert(varTypeIsIntegralOrI(treeNode)); FALLTHROUGH; @@ -7116,17 +7117,12 @@ void CodeGen::genCall(GenTreeCall* call) // Deal with multi register passed struct args. if (argNode->OperGet() == GT_FIELD_LIST) { - regNumber argReg = abiInfo.GetRegNum(); for (GenTreeFieldList::Use& use : argNode->AsFieldList()->Uses()) { GenTree* putArgRegNode = use.GetNode(); assert(putArgRegNode->gtOper == GT_PUTARG_REG); genConsumeReg(putArgRegNode); - var_types dstType = emitter::isFloatReg(argReg) ? TYP_DOUBLE : TYP_I_IMPL; - inst_Mov(dstType, argReg, putArgRegNode->GetRegNum(), /* canSkip */ true); - - argReg = genRegArgNext(argReg); } } else if (abiInfo.IsSplit()) @@ -7709,7 +7705,7 @@ void CodeGen::genIntCastOverflowCheck(GenTreeCast* cast, const GenIntCastDesc& d case GenIntCastDesc::CHECK_INT_RANGE: { - const regNumber tempReg = cast->GetSingleTempReg(); + const regNumber tempReg = rsGetRsvdReg(); assert(tempReg != reg); GetEmitter()->emitIns_I_la(EA_8BYTE, tempReg, INT32_MAX); genJumpToThrowHlpBlk_la(SCK_OVERFLOW, INS_blt, tempReg, nullptr, reg); diff --git a/src/coreclr/jit/emitloongarch64.cpp b/src/coreclr/jit/emitloongarch64.cpp index 9fb3e1f9cac1c..c8ba614bcb603 100644 --- a/src/coreclr/jit/emitloongarch64.cpp +++ b/src/coreclr/jit/emitloongarch64.cpp @@ -628,14 +628,18 @@ void emitter::emitIns_S_R(instruction ins, emitAttr attr, regNumber reg1, int va #ifdef DEBUG switch (ins) { - case INS_st_b: - case INS_st_h: - + case INS_st_d: + case INS_stx_d: case INS_st_w: + case INS_stx_w: case INS_fst_s: - - case INS_st_d: case INS_fst_d: + case INS_fstx_s: + case INS_fstx_d: + case INS_st_b: + case INS_st_h: + case INS_stx_b: + case INS_stx_h: break; default: @@ -652,8 +656,8 @@ void emitter::emitIns_S_R(instruction ins, emitAttr attr, regNumber reg1, int va base = emitComp->lvaFrameAddress(varx, &FPbased); imm = offs < 0 ? -offs - 8 : base + offs; - regNumber reg2 = FPbased ? REG_FPBASE : REG_SPBASE; - reg2 = offs < 0 ? REG_R21 : reg2; + regNumber reg3 = FPbased ? REG_FPBASE : REG_SPBASE; + regNumber reg2 = offs < 0 ? REG_R21 : reg3; offs = offs < 0 ? -offs - 8 : offs; if ((-2048 <= imm) && (imm < 2048)) @@ -686,7 +690,15 @@ void emitter::emitIns_S_R(instruction ins, emitAttr attr, regNumber reg1, int va code_t code = emitInsCode(ins); code |= (code_t)(reg1 & 0x1f); code |= (code_t)reg2 << 5; - code |= (code_t)(imm & 0xfff) << 10; + if ((ins == INS_stx_d) || (ins == INS_stx_w) || (ins == INS_stx_h) || (ins == INS_stx_b) || (ins == INS_fstx_d) || + (ins == INS_fstx_s)) + { + code |= (code_t)reg3 << 10; + } + else + { + code |= (code_t)(imm & 0xfff) << 10; + } id->idAddr()->iiaSetInstrEncode(code); id->idAddr()->iiaLclVar.initLclVarAddr(varx, offs); @@ -6633,7 +6645,7 @@ regNumber emitter::emitInsTernary(instruction ins, emitAttr attr, GenTree* dst, else { tempReg1 = REG_RA; - tempReg2 = dst->GetSingleTempReg(); + tempReg2 = codeGen->rsGetRsvdReg(); assert(tempReg1 != tempReg2); assert(tempReg1 != saveOperReg1); assert(tempReg2 != saveOperReg2); diff --git a/src/coreclr/jit/lclvars.cpp b/src/coreclr/jit/lclvars.cpp index 85b24c6373e73..0c9beefde2cc8 100644 --- a/src/coreclr/jit/lclvars.cpp +++ b/src/coreclr/jit/lclvars.cpp @@ -901,7 +901,7 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un assert(varDsc->lvExactSize <= argSize); floatNum = 1; - canPassArgInRegisters = varDscInfo->canEnreg(argRegTypeInStruct1, 1); + canPassArgInRegisters = varDscInfo->canEnreg(TYP_DOUBLE, 1); argRegTypeInStruct1 = (varDsc->lvExactSize == 8) ? TYP_DOUBLE : TYP_FLOAT; } @@ -938,7 +938,6 @@ void Compiler::lvaInitUserArgs(InitVarDscInfo* varDscInfo, unsigned skipArgs, un { // On LoongArch64, if there aren't any remaining floating-point registers to pass the argument, // integer registers (if any) are used instead. - varDscInfo->setAllRegArgUsed(TYP_DOUBLE); canPassArgInRegisters = varDscInfo->canEnreg(argType, cSlotsToEnregister); argRegTypeInStruct1 = TYP_UNKNOWN; diff --git a/src/coreclr/jit/lsraloongarch64.cpp b/src/coreclr/jit/lsraloongarch64.cpp index 2498292e6dd5a..58cffe8b8d939 100644 --- a/src/coreclr/jit/lsraloongarch64.cpp +++ b/src/coreclr/jit/lsraloongarch64.cpp @@ -871,14 +871,11 @@ int LinearScan::BuildCall(GenTreeCall* call) { assert(argNode->isContained()); - // There could be up to 2-4 PUTARG_REGs in the list (3 or 4 can only occur for HFAs) + // There could be up to 2 PUTARG_REGs in the list. for (GenTreeFieldList::Use& use : argNode->AsFieldList()->Uses()) { #ifdef DEBUG assert(use.GetNode()->OperIs(GT_PUTARG_REG)); - assert(use.GetNode()->GetRegNum() == argReg); - // Update argReg for the next putarg_reg (if any) - argReg = genRegArgNext(argReg); #endif BuildUse(use.GetNode(), genRegMask(use.GetNode()->GetRegNum())); srcCount++; diff --git a/src/coreclr/jit/morph.cpp b/src/coreclr/jit/morph.cpp index b709065e65c37..a35e7309748d4 100644 --- a/src/coreclr/jit/morph.cpp +++ b/src/coreclr/jit/morph.cpp @@ -2594,6 +2594,7 @@ void CallArgs::AddFinalArgsAndDetermineABIInfo(Compiler* comp, GenTreeCall* call if (!passUsingFloatRegs) { size = structSize > 8 ? 2 : 1; + structBaseType = structSize <= 8 ? TYP_I_IMPL : TYP_STRUCT; floatFieldFlags = 0; } else if (passUsingFloatRegs)