diff --git a/src/coreclr/jit/codegenriscv64.cpp b/src/coreclr/jit/codegenriscv64.cpp index 640cb5ec6bf330..4bd0f1d4a170d8 100644 --- a/src/coreclr/jit/codegenriscv64.cpp +++ b/src/coreclr/jit/codegenriscv64.cpp @@ -2187,16 +2187,25 @@ void CodeGen::genTableBasedSwitch(GenTree* treeNode) regNumber idxReg = treeNode->AsOp()->gtOp1->GetRegNum(); regNumber baseReg = treeNode->AsOp()->gtOp2->GetRegNum(); - regNumber tmpReg = internalRegisters.GetSingle(treeNode); - // load the ip-relative offset (which is relative to start of fgFirstBB) - GetEmitter()->emitIns_R_R_I(INS_slli, EA_8BYTE, tmpReg, idxReg, 2); - GetEmitter()->emitIns_R_R_R(INS_add, EA_8BYTE, baseReg, baseReg, tmpReg); + assert(treeNode->gtGetOp2()->TypeIs(TYP_I_IMPL)); + if (compiler->compOpportunisticallyDependsOn(InstructionSet_Zba)) + { + emitAttr idxSize = emitTypeSize(treeNode->gtGetOp1()); + instruction sh2add = (idxSize == EA_4BYTE) ? INS_sh2add_uw : INS_sh2add; + GetEmitter()->emitIns_R_R_R(sh2add, idxSize, baseReg, idxReg, baseReg); + } + else + { + assert(treeNode->gtGetOp1()->TypeIs(TYP_I_IMPL)); + GetEmitter()->emitIns_R_R_I(INS_slli, EA_8BYTE, idxReg, idxReg, 2); + GetEmitter()->emitIns_R_R_R(INS_add, EA_8BYTE, baseReg, baseReg, idxReg); + } GetEmitter()->emitIns_R_R_I(INS_lw, EA_4BYTE, baseReg, baseReg, 0); // add it to the absolute address of fgFirstBB - GetEmitter()->emitIns_R_L(INS_lea, EA_PTRSIZE, compiler->fgFirstBB, tmpReg); - GetEmitter()->emitIns_R_R_R(INS_add, EA_PTRSIZE, baseReg, baseReg, tmpReg); + GetEmitter()->emitIns_R_L(INS_lea, EA_PTRSIZE, compiler->fgFirstBB, idxReg); + GetEmitter()->emitIns_R_R_R(INS_add, EA_PTRSIZE, baseReg, baseReg, idxReg); // jr baseReg GetEmitter()->emitIns_R_R_I(INS_jalr, emitActualTypeSize(TYP_I_IMPL), REG_R0, baseReg, 0); diff --git a/src/coreclr/jit/lower.cpp b/src/coreclr/jit/lower.cpp index e1025850ef7c8f..1bd21efe519d36 100644 --- a/src/coreclr/jit/lower.cpp +++ b/src/coreclr/jit/lower.cpp @@ -1345,7 +1345,8 @@ GenTree* Lowering::LowerSwitch(GenTree* node) JITDUMP("Lowering switch " FMT_BB ": using jump table expansion\n", originalSwitchBB->bbNum); #ifdef TARGET_64BIT - if (tempLclType != TYP_I_IMPL) + if (RISCV64_ONLY(!comp->compOpportunisticallyDependsOn(InstructionSet_Zba)&&) // shXadd.uw 0-extends index + tempLclType != TYP_I_IMPL) { // SWITCH_TABLE expects the switch value (the index into the jump table) to be TYP_I_IMPL. // Note that the switch value is unsigned so the cast should be unsigned as well. diff --git a/src/coreclr/jit/lsrariscv64.cpp b/src/coreclr/jit/lsrariscv64.cpp index 213a6ebefbd064..7a0dc3be375ec7 100644 --- a/src/coreclr/jit/lsrariscv64.cpp +++ b/src/coreclr/jit/lsrariscv64.cpp @@ -226,7 +226,6 @@ int LinearScan::BuildNode(GenTree* tree) break; case GT_SWITCH_TABLE: - buildInternalIntRegisterDefForNode(tree); srcCount = BuildBinaryUses(tree->AsOp()); assert(dstCount == 0); break;