diff --git a/src/coreclr/jit/codegen.h b/src/coreclr/jit/codegen.h index 4d17e291d0c8ae..7a2359c9fb5fc9 100644 --- a/src/coreclr/jit/codegen.h +++ b/src/coreclr/jit/codegen.h @@ -1260,6 +1260,7 @@ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX void genCodeForInitBlkLoop(GenTreeBlk* initBlkNode); void genCodeForInitBlkRepStos(GenTreeBlk* initBlkNode); void genCodeForInitBlkUnroll(GenTreeBlk* initBlkNode); + unsigned genEmitJumpTable(GenTree* treeNode, bool relativeAddr); void genJumpTable(GenTree* tree); void genTableBasedSwitch(GenTree* tree); #if defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) diff --git a/src/coreclr/jit/codegenarm.cpp b/src/coreclr/jit/codegenarm.cpp index eefee0e6912cf9..8cf3ac32b3a329 100644 --- a/src/coreclr/jit/codegenarm.cpp +++ b/src/coreclr/jit/codegenarm.cpp @@ -647,30 +647,7 @@ void CodeGen::genTableBasedSwitch(GenTree* treeNode) // void CodeGen::genJumpTable(GenTree* treeNode) { - noway_assert(compiler->compCurBB->KindIs(BBJ_SWITCH)); - assert(treeNode->OperGet() == GT_JMPTABLE); - - unsigned jumpCount = compiler->compCurBB->GetSwitchTargets()->bbsCount; - FlowEdge** jumpTable = compiler->compCurBB->GetSwitchTargets()->bbsDstTab; - unsigned jmpTabBase; - - jmpTabBase = GetEmitter()->emitBBTableDataGenBeg(jumpCount, false); - - JITDUMP("\n J_M%03u_DS%02u LABEL DWORD\n", compiler->compMethodID, jmpTabBase); - - for (unsigned i = 0; i < jumpCount; i++) - { - BasicBlock* target = (*jumpTable)->getDestinationBlock(); - jumpTable++; - noway_assert(target->HasFlag(BBF_HAS_LABEL)); - - JITDUMP(" DD L_M%03u_" FMT_BB "\n", compiler->compMethodID, target->bbNum); - - GetEmitter()->emitDataGenData(i, target); - } - - GetEmitter()->emitDataGenEnd(); - + unsigned jmpTabBase = genEmitJumpTable(treeNode, false); genMov32RelocatableDataLabel(jmpTabBase, treeNode->GetRegNum()); genProduceReg(treeNode); diff --git a/src/coreclr/jit/codegenarm64.cpp b/src/coreclr/jit/codegenarm64.cpp index 4587bace1697ab..498f227e48d5be 100644 --- a/src/coreclr/jit/codegenarm64.cpp +++ b/src/coreclr/jit/codegenarm64.cpp @@ -3750,33 +3750,7 @@ void CodeGen::genTableBasedSwitch(GenTree* treeNode) // emits the table and an instruction to get the address of the first element void CodeGen::genJumpTable(GenTree* treeNode) { - noway_assert(compiler->compCurBB->KindIs(BBJ_SWITCH)); - assert(treeNode->OperGet() == GT_JMPTABLE); - - unsigned jumpCount = compiler->compCurBB->GetSwitchTargets()->bbsCount; - FlowEdge** jumpTable = compiler->compCurBB->GetSwitchTargets()->bbsDstTab; - unsigned jmpTabOffs; - unsigned jmpTabBase; - - jmpTabBase = GetEmitter()->emitBBTableDataGenBeg(jumpCount, true); - - jmpTabOffs = 0; - - JITDUMP("\n J_M%03u_DS%02u LABEL DWORD\n", compiler->compMethodID, jmpTabBase); - - for (unsigned i = 0; i < jumpCount; i++) - { - BasicBlock* target = (*jumpTable)->getDestinationBlock(); - jumpTable++; - noway_assert(target->HasFlag(BBF_HAS_LABEL)); - - JITDUMP(" DD L_M%03u_" FMT_BB "\n", compiler->compMethodID, target->bbNum); - - GetEmitter()->emitDataGenData(i, target); - }; - - GetEmitter()->emitDataGenEnd(); - + unsigned jmpTabBase = genEmitJumpTable(treeNode, true); // Access to inline data is 'abstracted' by a special type of static member // (produced by eeFindJitDataOffs) which the emitter recognizes as being a reference // to constant data, not a real static field. diff --git a/src/coreclr/jit/codegencommon.cpp b/src/coreclr/jit/codegencommon.cpp index 9d7992ea4efe27..bf2bfaa28aad47 100644 --- a/src/coreclr/jit/codegencommon.cpp +++ b/src/coreclr/jit/codegencommon.cpp @@ -6452,6 +6452,47 @@ void CodeGen::genFnProlog() #pragma warning(pop) #endif +//---------------------------------------------------------------------------------- +// genEmitJumpTable: emit jump table and return its base offset +// +// Arguments: +// treeNode - the GT_JMPTABLE node +// relativeAddr - if true, references are treated as 4-byte relative addresses, +// otherwise they are absolute pointers +// +// Return Value: +// base offset to jump table +// +// Assumption: +// The current basic block in process ends with a switch statement +// +unsigned CodeGen::genEmitJumpTable(GenTree* treeNode, bool relativeAddr) +{ + noway_assert(compiler->compCurBB->KindIs(BBJ_SWITCH)); + assert(treeNode->OperGet() == GT_JMPTABLE); + + emitter* emit = GetEmitter(); + const unsigned jumpCount = compiler->compCurBB->GetSwitchTargets()->bbsCount; + FlowEdge** jumpTable = compiler->compCurBB->GetSwitchTargets()->bbsDstTab; + const unsigned jmpTabBase = emit->emitBBTableDataGenBeg(jumpCount, relativeAddr); + + JITDUMP("\n J_M%03u_DS%02u LABEL DWORD\n", compiler->compMethodID, jmpTabBase); + + for (unsigned i = 0; i < jumpCount; i++) + { + BasicBlock* target = (*jumpTable)->getDestinationBlock(); + jumpTable++; + noway_assert(target->HasFlag(BBF_HAS_LABEL)); + + JITDUMP(" DD L_M%03u_" FMT_BB "\n", compiler->compMethodID, target->bbNum); + + emit->emitDataGenData(i, target); + }; + + emit->emitDataGenEnd(); + return jmpTabBase; +} + //------------------------------------------------------------------------ // getCallTarget - Get the node that evaluates to the call target // diff --git a/src/coreclr/jit/codegenloongarch64.cpp b/src/coreclr/jit/codegenloongarch64.cpp index e894d987633317..01e82be425a3cc 100644 --- a/src/coreclr/jit/codegenloongarch64.cpp +++ b/src/coreclr/jit/codegenloongarch64.cpp @@ -2927,33 +2927,7 @@ void CodeGen::genTableBasedSwitch(GenTree* treeNode) // emits the table and an instruction to get the address of the first element void CodeGen::genJumpTable(GenTree* treeNode) { - noway_assert(compiler->compCurBB->KindIs(BBJ_SWITCH)); - assert(treeNode->OperGet() == GT_JMPTABLE); - - unsigned jumpCount = compiler->compCurBB->GetSwitchTargets()->bbsCount; - FlowEdge** jumpTable = compiler->compCurBB->GetSwitchTargets()->bbsDstTab; - unsigned jmpTabOffs; - unsigned jmpTabBase; - - jmpTabBase = GetEmitter()->emitBBTableDataGenBeg(jumpCount, true); - - jmpTabOffs = 0; - - JITDUMP("\n J_M%03u_DS%02u LABEL DWORD\n", compiler->compMethodID, jmpTabBase); - - for (unsigned i = 0; i < jumpCount; i++) - { - BasicBlock* target = (*jumpTable)->getDestinationBlock(); - jumpTable++; - noway_assert(target->HasFlag(BBF_HAS_LABEL)); - - JITDUMP(" DD L_M%03u_" FMT_BB "\n", compiler->compMethodID, target->bbNum); - - GetEmitter()->emitDataGenData(i, target); - }; - - GetEmitter()->emitDataGenEnd(); - + unsigned jmpTabBase = genEmitJumpTable(treeNode, true); // Access to inline data is 'abstracted' by a special type of static member // (produced by eeFindJitDataOffs) which the emitter recognizes as being a reference // to constant data, not a real static field. diff --git a/src/coreclr/jit/codegenriscv64.cpp b/src/coreclr/jit/codegenriscv64.cpp index 90429b89584fd2..c66511fa87b8a2 100644 --- a/src/coreclr/jit/codegenriscv64.cpp +++ b/src/coreclr/jit/codegenriscv64.cpp @@ -2850,33 +2850,7 @@ void CodeGen::genTableBasedSwitch(GenTree* treeNode) // emits the table and an instruction to get the address of the first element void CodeGen::genJumpTable(GenTree* treeNode) { - noway_assert(compiler->compCurBB->KindIs(BBJ_SWITCH)); - assert(treeNode->OperGet() == GT_JMPTABLE); - - unsigned jumpCount = compiler->compCurBB->GetSwitchTargets()->bbsCount; - FlowEdge** jumpTable = compiler->compCurBB->GetSwitchTargets()->bbsDstTab; - unsigned jmpTabOffs; - unsigned jmpTabBase; - - jmpTabBase = GetEmitter()->emitBBTableDataGenBeg(jumpCount, true); - - jmpTabOffs = 0; - - JITDUMP("\n J_M%03u_DS%02u LABEL DWORD\n", compiler->compMethodID, jmpTabBase); - - for (unsigned i = 0; i < jumpCount; i++) - { - BasicBlock* target = (*jumpTable)->getDestinationBlock(); - jumpTable++; - noway_assert(target->HasFlag(BBF_HAS_LABEL)); - - JITDUMP(" DD L_M%03u_" FMT_BB "\n", compiler->compMethodID, target->bbNum); - - GetEmitter()->emitDataGenData(i, target); - }; - - GetEmitter()->emitDataGenEnd(); - + unsigned jmpTabBase = genEmitJumpTable(treeNode, true); // Access to inline data is 'abstracted' by a special type of static member // (produced by eeFindJitDataOffs) which the emitter recognizes as being a reference // to constant data, not a real static field. diff --git a/src/coreclr/jit/codegenxarch.cpp b/src/coreclr/jit/codegenxarch.cpp index 584cb3aab19bb3..223199f35c3276 100644 --- a/src/coreclr/jit/codegenxarch.cpp +++ b/src/coreclr/jit/codegenxarch.cpp @@ -4303,33 +4303,7 @@ void CodeGen::genTableBasedSwitch(GenTree* treeNode) // emits the table and an instruction to get the address of the first element void CodeGen::genJumpTable(GenTree* treeNode) { - noway_assert(compiler->compCurBB->KindIs(BBJ_SWITCH)); - assert(treeNode->OperGet() == GT_JMPTABLE); - - unsigned jumpCount = compiler->compCurBB->GetSwitchTargets()->bbsCount; - FlowEdge** jumpTable = compiler->compCurBB->GetSwitchTargets()->bbsDstTab; - unsigned jmpTabOffs; - unsigned jmpTabBase; - - jmpTabBase = GetEmitter()->emitBBTableDataGenBeg(jumpCount, true); - - jmpTabOffs = 0; - - JITDUMP("\n J_M%03u_DS%02u LABEL DWORD\n", compiler->compMethodID, jmpTabBase); - - for (unsigned i = 0; i < jumpCount; i++) - { - BasicBlock* target = (*jumpTable)->getDestinationBlock(); - jumpTable++; - noway_assert(target->HasFlag(BBF_HAS_LABEL)); - - JITDUMP(" DD L_M%03u_" FMT_BB "\n", compiler->compMethodID, target->bbNum); - - GetEmitter()->emitDataGenData(i, target); - }; - - GetEmitter()->emitDataGenEnd(); - + unsigned jmpTabBase = genEmitJumpTable(treeNode, true); // Access to inline data is 'abstracted' by a special type of static member // (produced by eeFindJitDataOffs) which the emitter recognizes as being a reference // to constant data, not a real static field.