From f9f29354b301e18c5f00db127b0f583108cbe1d0 Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Fri, 24 Nov 2023 16:33:39 +0100 Subject: [PATCH 01/35] Implemented emitDispIns for riscv --- src/coreclr/jit/emitriscv64.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 57e73e9d2eb7b1..ff8bd18fdb2421 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -3829,10 +3829,18 @@ void emitter::emitDispInsHex(instrDesc* id, BYTE* code, size_t sz) void emitter::emitDispIns( instrDesc* id, bool isNew, bool doffs, bool asmfm, unsigned offset, BYTE* pCode, size_t sz, insGroup* ig) { - // RISCV64 implements this similar by `emitter::emitDisInsName`. - // For RISCV64 maybe the `emitDispIns` is over complicate. - // The `emitter::emitDisInsName` is focused on the most important for debugging. - NYI_RISCV64("RISCV64 not used the emitter::emitDispIns"); + if (ig == nullptr) + return; + + const BYTE* address = emitCodeBlock + offset + writeableOffset; + for (int size = id->idCodeSize(); size > 0;) + { + code_t instruction; + memcpy(&instruction, address, sizeof(code_t)); + emitDisInsName(instruction, address, id); + address += sizeof(code_t); + size -= sizeof(code_t); + } } /***************************************************************************** From c5f4314f5e9269414da62060e04e540cf6e71d75 Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Fri, 24 Nov 2023 16:40:23 +0100 Subject: [PATCH 02/35] Modified emitDispIns name --- src/coreclr/jit/emitriscv64.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index ff8bd18fdb2421..0ba2c3b8f2d585 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -3833,13 +3833,12 @@ void emitter::emitDispIns( return; const BYTE* address = emitCodeBlock + offset + writeableOffset; - for (int size = id->idCodeSize(); size > 0;) + const BYTE* const address_sentinel = address + id->idCodeSize(); + for (; address < address_sentinel; address += sizeof(code_t)) { code_t instruction; memcpy(&instruction, address, sizeof(code_t)); emitDisInsName(instruction, address, id); - address += sizeof(code_t); - size -= sizeof(code_t); } } From 2e7104ae58265f82aa9002f2043ff1f0e0cd9266 Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Fri, 24 Nov 2023 17:08:33 +0100 Subject: [PATCH 03/35] Fixed missed case --- src/coreclr/jit/emitriscv64.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 0ba2c3b8f2d585..b179f3b439ada5 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -3833,8 +3833,8 @@ void emitter::emitDispIns( return; const BYTE* address = emitCodeBlock + offset + writeableOffset; - const BYTE* const address_sentinel = address + id->idCodeSize(); - for (; address < address_sentinel; address += sizeof(code_t)) + const BYTE* const addressSentinel = address + id->idCodeSize(); + for (; address < addressSentinel; address += sizeof(code_t)) { code_t instruction; memcpy(&instruction, address, sizeof(code_t)); From 6e6441fc7557d99e08a59858a3a0e11dc4d16ef3 Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Fri, 24 Nov 2023 18:01:43 +0100 Subject: [PATCH 04/35] Added assert --- src/coreclr/jit/emitriscv64.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index b179f3b439ada5..94605ed324d7f9 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -3829,15 +3829,22 @@ void emitter::emitDispInsHex(instrDesc* id, BYTE* code, size_t sz) void emitter::emitDispIns( instrDesc* id, bool isNew, bool doffs, bool asmfm, unsigned offset, BYTE* pCode, size_t sz, insGroup* ig) { + static constexpr code_t k32BitInstructionLowerMask = 0x1f; // 0b00000011 + static constexpr code_t k32BitInstructionUpperMask = 0x1c; // 0b00011100 + if (ig == nullptr) return; const BYTE* address = emitCodeBlock + offset + writeableOffset; const BYTE* const addressSentinel = address + id->idCodeSize(); + // TODO-RISCV64-C: add support for non-32 bit instructions for (; address < addressSentinel; address += sizeof(code_t)) { code_t instruction; memcpy(&instruction, address, sizeof(code_t)); + // checks whether the instruction is 4 bytes long + assert((instruction & k32BitInstructionUpperMask != k32BitInstructionUpperMask) && + (instruction & k32BitInstructionLowerMask == k32BitInstructionLowerMask)); emitDisInsName(instruction, address, id); } } From b8767cbb1cc2f0ed8d7c6baac045db5d6d7c9da4 Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Fri, 24 Nov 2023 18:02:39 +0100 Subject: [PATCH 05/35] Fixed todo --- src/coreclr/jit/emitriscv64.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 94605ed324d7f9..e332e3f080cdee 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -3837,7 +3837,7 @@ void emitter::emitDispIns( const BYTE* address = emitCodeBlock + offset + writeableOffset; const BYTE* const addressSentinel = address + id->idCodeSize(); - // TODO-RISCV64-C: add support for non-32 bit instructions + // TODO-RISCV64: add support for non-32 bit instructions for (; address < addressSentinel; address += sizeof(code_t)) { code_t instruction; From 1873c0ff1c497cfb44b4c8540ba3b283b06725ae Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Mon, 27 Nov 2023 11:50:45 +0100 Subject: [PATCH 06/35] Added int to jitprintf --- src/coreclr/jit/ee_il_dll.cpp | 5 +++-- src/coreclr/jit/host.h | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/ee_il_dll.cpp b/src/coreclr/jit/ee_il_dll.cpp index 11c7f77ecc4a27..36470dbea8e4b0 100644 --- a/src/coreclr/jit/ee_il_dll.cpp +++ b/src/coreclr/jit/ee_il_dll.cpp @@ -144,12 +144,13 @@ FILE* jitstdout() } // Like printf/logf, but only outputs to jitstdout -- skips call back into EE. -void jitprintf(const char* fmt, ...) +int jitprintf(const char* fmt, ...) { va_list vl; va_start(vl, fmt); - vfprintf(jitstdout(), fmt, vl); + int status = vfprintf(jitstdout(), fmt, vl); va_end(vl); + return status; } void jitShutdown(bool processIsTerminating) diff --git a/src/coreclr/jit/host.h b/src/coreclr/jit/host.h index 0ccefae924e637..6667fbb3994a76 100644 --- a/src/coreclr/jit/host.h +++ b/src/coreclr/jit/host.h @@ -3,7 +3,7 @@ /*****************************************************************************/ -void jitprintf(const char* fmt, ...); +int jitprintf(const char* fmt, ...); #ifdef DEBUG From ce09c4a61477914413e17c64eb76126d11bace42 Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Wed, 29 Nov 2023 09:46:28 +0100 Subject: [PATCH 07/35] Added prototype of the emit disp ins --- src/coreclr/jit/emitriscv64.cpp | 51 +++++++++++++-------------------- src/coreclr/jit/emitriscv64.h | 4 +-- 2 files changed, 22 insertions(+), 33 deletions(-) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index e332e3f080cdee..efd0a867730b04 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -2098,6 +2098,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { BYTE* dstRW = *dp + writeableOffset; BYTE* dstRW2 = dstRW + 4; // addr for updating gc info if needed. + BYTE* const odstRW = dstRW; code_t code = 0; instruction ins; size_t sz; // = emitSizeOfInsDsc(id); @@ -2837,12 +2838,12 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) if (emitComp->opts.disAsm || emitComp->verbose) { - code_t* cp = (code_t*)(*dp + writeableOffset); - while ((BYTE*)cp != dstRW) - { - emitDisInsName(*cp, (BYTE*)cp, id); - cp++; - } +#if DUMP_GC_TABLES + bool dspOffs = emitComp->opts.dspGCtbls; +#else // DUMP_GC_TABLES + bool dspOffs = !emitComp->opts.disDiffable; +#endif // DUMP_GC_TABLES + emitDispIns(id, false, dspOffs, true, 0, *dp, (dstRW - odstRW), ig); } if (emitComp->compDebugBreak) @@ -2868,8 +2869,6 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) /*****************************************************************************/ /*****************************************************************************/ -#ifdef DEBUG - // clang-format off static const char* const RegNames[] = { @@ -2900,20 +2899,6 @@ void emitter::emitDisInsName(code_t code, const BYTE* addr, instrDesc* id) unsigned int opcode = code & 0x7f; assert((opcode & 0x3) == 0x3); - bool disOpcode = !emitComp->opts.disDiffable; - bool disAddr = emitComp->opts.disAddr; - if (disAddr) - { - printf(" 0x%llx", insAdr); - } - - printf(" "); - - if (disOpcode) - { - printf("%08X ", code); - } - switch (opcode) { case 0x37: // LUI @@ -3826,26 +3811,30 @@ void emitter::emitDispInsHex(instrDesc* id, BYTE* code, size_t sz) } } +#ifdef DEBUG + void emitter::emitDispIns( instrDesc* id, bool isNew, bool doffs, bool asmfm, unsigned offset, BYTE* pCode, size_t sz, insGroup* ig) { static constexpr code_t k32BitInstructionLowerMask = 0x1f; // 0b00000011 static constexpr code_t k32BitInstructionUpperMask = 0x1c; // 0b00011100 - if (ig == nullptr) + if (pCode == nullptr) return; - const BYTE* address = emitCodeBlock + offset + writeableOffset; - const BYTE* const addressSentinel = address + id->idCodeSize(); - // TODO-RISCV64: add support for non-32 bit instructions - for (; address < addressSentinel; address += sizeof(code_t)) + printf(" "); + + const BYTE* instr = pCode + writeableOffset; + size_t instrSize; + for (size_t i = 0; i < sz; instr += instrSize, i += instrSize) { + instrSize = sizeof(code_t); code_t instruction; - memcpy(&instruction, address, sizeof(code_t)); + memcpy(&instruction, instr, instrSize); // checks whether the instruction is 4 bytes long - assert((instruction & k32BitInstructionUpperMask != k32BitInstructionUpperMask) && - (instruction & k32BitInstructionLowerMask == k32BitInstructionLowerMask)); - emitDisInsName(instruction, address, id); + // assert(((instruction & k32BitInstructionUpperMask) != k32BitInstructionUpperMask) && + // ((instruction & k32BitInstructionLowerMask) == k32BitInstructionLowerMask)); + emitDisInsName(instruction, instr, id); } } diff --git a/src/coreclr/jit/emitriscv64.h b/src/coreclr/jit/emitriscv64.h index ea9149e2246696..0fea4517064478 100644 --- a/src/coreclr/jit/emitriscv64.h +++ b/src/coreclr/jit/emitriscv64.h @@ -27,8 +27,6 @@ struct CnsVal const char* emitFPregName(unsigned reg, bool varName = true); const char* emitVectorRegName(regNumber reg); - -void emitDisInsName(code_t code, const BYTE* addr, instrDesc* id); #endif // DEBUG void emitIns_J_cond_la(instruction ins, BasicBlock* dst, regNumber reg1 = REG_R0, regNumber reg2 = REG_R0); @@ -62,6 +60,8 @@ bool emitInsIsLoad(instruction ins); bool emitInsIsStore(instruction ins); bool emitInsIsLoadOrStore(instruction ins); +void emitDisInsName(code_t code, const BYTE* addr, instrDesc* id); + emitter::code_t emitInsCode(instruction ins /*, insFormat fmt*/); // Generate code for a load or store operation and handle the case of contained GT_LEA op1 with [base + offset] From 376b79ba853bf4de31f7607dccc8f8b54d36ff96 Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Wed, 29 Nov 2023 10:09:00 +0100 Subject: [PATCH 08/35] Fixes in emit dis ins name --- src/coreclr/jit/emitriscv64.cpp | 25 +++++++++++-------------- src/coreclr/jit/emitriscv64.h | 2 +- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index efd0a867730b04..ac6025238e760e 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -2892,13 +2892,18 @@ static const char* const RegNames[] = // The length of the instruction's name include aligned space is 15. // -void emitter::emitDisInsName(code_t code, const BYTE* addr, instrDesc* id) +void emitter::emitDisInsName(code_t code, BYTE* addr, bool doffs, unsigned offset, instrDesc* id) { - const BYTE* insAdr = addr - writeableOffset; + BYTE* insAdr = addr - writeableOffset; unsigned int opcode = code & 0x7f; assert((opcode & 0x3) == 0x3); + emitDispInsAddr(insAdr); + emitDispInsOffs(offset, doffs); + + printf(" "); + switch (opcode) { case 0x37: // LUI @@ -3811,33 +3816,25 @@ void emitter::emitDispInsHex(instrDesc* id, BYTE* code, size_t sz) } } -#ifdef DEBUG - void emitter::emitDispIns( instrDesc* id, bool isNew, bool doffs, bool asmfm, unsigned offset, BYTE* pCode, size_t sz, insGroup* ig) { - static constexpr code_t k32BitInstructionLowerMask = 0x1f; // 0b00000011 - static constexpr code_t k32BitInstructionUpperMask = 0x1c; // 0b00011100 - if (pCode == nullptr) return; - printf(" "); - - const BYTE* instr = pCode + writeableOffset; + BYTE* instr = pCode + writeableOffset; size_t instrSize; for (size_t i = 0; i < sz; instr += instrSize, i += instrSize) { instrSize = sizeof(code_t); code_t instruction; memcpy(&instruction, instr, instrSize); - // checks whether the instruction is 4 bytes long - // assert(((instruction & k32BitInstructionUpperMask) != k32BitInstructionUpperMask) && - // ((instruction & k32BitInstructionLowerMask) == k32BitInstructionLowerMask)); - emitDisInsName(instruction, instr, id); + emitDisInsName(instruction, instr, doffs, offset, id); } } +#ifdef DEBUG + /***************************************************************************** * * Display a stack frame reference. diff --git a/src/coreclr/jit/emitriscv64.h b/src/coreclr/jit/emitriscv64.h index 0fea4517064478..106eca395c6752 100644 --- a/src/coreclr/jit/emitriscv64.h +++ b/src/coreclr/jit/emitriscv64.h @@ -60,7 +60,7 @@ bool emitInsIsLoad(instruction ins); bool emitInsIsStore(instruction ins); bool emitInsIsLoadOrStore(instruction ins); -void emitDisInsName(code_t code, const BYTE* addr, instrDesc* id); +void emitDisInsName(code_t code, BYTE* addr, bool doffs, unsigned offset, instrDesc* id); emitter::code_t emitInsCode(instruction ins /*, insFormat fmt*/); From e90d883a0589915ec1c3c896ca32a055881c3deb Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Wed, 29 Nov 2023 10:19:55 +0100 Subject: [PATCH 09/35] Reinforced types --- src/coreclr/jit/emit.cpp | 2 +- src/coreclr/jit/emit.h | 2 +- src/coreclr/jit/emitriscv64.cpp | 10 +++++----- src/coreclr/jit/emitriscv64.h | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index b18451d9d1fe88..a3ea52c33e804b 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -1542,7 +1542,7 @@ void emitter::appendToCurIG(instrDesc* id) * Display (optionally) an instruction offset. */ -void emitter::emitDispInsAddr(BYTE* code) +void emitter::emitDispInsAddr(const BYTE* code) { #ifdef DEBUG if (emitComp->opts.disAddr) diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 5471cc0bc0467e..15d4b593f56377 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -2117,7 +2117,7 @@ class emitter void emitDispJumpList(); void emitDispClsVar(CORINFO_FIELD_HANDLE fldHnd, ssize_t offs, bool reloc = false); void emitDispFrameRef(int varx, int disp, int offs, bool asmfm); - void emitDispInsAddr(BYTE* code); + void emitDispInsAddr(const BYTE* code); void emitDispInsOffs(unsigned offs, bool doffs); void emitDispInsHex(instrDesc* id, BYTE* code, size_t sz); void emitDispEmbBroadcastCount(instrDesc* id); diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index ac6025238e760e..0d81ef9e86d929 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -2879,7 +2879,7 @@ static const char* const RegNames[] = //---------------------------------------------------------------------------------------- // Disassemble the given instruction. -// The `emitter::emitDisInsName` is focused on the most important for debugging. +// The `emitter::emitDispInsName` is focused on the most important for debugging. // So it implemented as far as simply and independently which is very useful for // porting easily to the release mode. // @@ -2892,9 +2892,9 @@ static const char* const RegNames[] = // The length of the instruction's name include aligned space is 15. // -void emitter::emitDisInsName(code_t code, BYTE* addr, bool doffs, unsigned offset, instrDesc* id) +void emitter::emitDispInsName(code_t code, const BYTE* addr, bool doffs, unsigned offset, instrDesc* id) { - BYTE* insAdr = addr - writeableOffset; + const BYTE* insAdr = addr - writeableOffset; unsigned int opcode = code & 0x7f; assert((opcode & 0x3) == 0x3); @@ -3822,14 +3822,14 @@ void emitter::emitDispIns( if (pCode == nullptr) return; - BYTE* instr = pCode + writeableOffset; + const BYTE* instr = pCode + writeableOffset; size_t instrSize; for (size_t i = 0; i < sz; instr += instrSize, i += instrSize) { instrSize = sizeof(code_t); code_t instruction; memcpy(&instruction, instr, instrSize); - emitDisInsName(instruction, instr, doffs, offset, id); + emitDispInsName(instruction, instr, doffs, offset, id); } } diff --git a/src/coreclr/jit/emitriscv64.h b/src/coreclr/jit/emitriscv64.h index 106eca395c6752..068afaec852673 100644 --- a/src/coreclr/jit/emitriscv64.h +++ b/src/coreclr/jit/emitriscv64.h @@ -60,7 +60,7 @@ bool emitInsIsLoad(instruction ins); bool emitInsIsStore(instruction ins); bool emitInsIsLoadOrStore(instruction ins); -void emitDisInsName(code_t code, BYTE* addr, bool doffs, unsigned offset, instrDesc* id); +void emitDispInsName(code_t code, const BYTE* addr, bool doffs, unsigned offset, instrDesc* id); emitter::code_t emitInsCode(instruction ins /*, insFormat fmt*/); From 79a1797acc89b14ea3d14014bfc9ff2dd829a253 Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Wed, 29 Nov 2023 10:33:58 +0100 Subject: [PATCH 10/35] Removed useless ifdef statement from emit --- src/coreclr/jit/emit.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index a3ea52c33e804b..c32ed266424688 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -1491,12 +1491,6 @@ void emitter::dispIns(instrDesc* id) // For LoongArch64 using the emitDisInsName(). NYI_LOONGARCH64("Not used on LOONGARCH64."); } -#elif defined(TARGET_RISCV64) -void emitter::dispIns(instrDesc* id) -{ - // For RISCV64 using the emitDisInsName(). - NYI_RISCV64("Not used on RISCV64."); -} #else void emitter::dispIns(instrDesc* id) { From 99e20b20b4728ab60fb56eb8bce5ecf40bebf212 Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Wed, 29 Nov 2023 11:27:23 +0100 Subject: [PATCH 11/35] Fixed bug in emit disp ins --- src/coreclr/jit/emitriscv64.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 0d81ef9e86d929..17ab86b30f6861 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -3822,7 +3822,7 @@ void emitter::emitDispIns( if (pCode == nullptr) return; - const BYTE* instr = pCode + writeableOffset; + const BYTE* instr = pCode + writeableOffset + offset; size_t instrSize; for (size_t i = 0; i < sz; instr += instrSize, i += instrSize) { From f0d1dcbacf8731568d6971713682cb6ba835ab85 Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Wed, 29 Nov 2023 13:34:18 +0100 Subject: [PATCH 12/35] Added release mode emit disp --- src/coreclr/jit/emitriscv64.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 17ab86b30f6861..7773791939bd9a 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -2840,9 +2840,9 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { #if DUMP_GC_TABLES bool dspOffs = emitComp->opts.dspGCtbls; -#else // DUMP_GC_TABLES +#else // !DUMP_GC_TABLES bool dspOffs = !emitComp->opts.disDiffable; -#endif // DUMP_GC_TABLES +#endif // !DUMP_GC_TABLES emitDispIns(id, false, dspOffs, true, 0, *dp, (dstRW - odstRW), ig); } @@ -2855,7 +2855,12 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) assert(!"JitBreakEmitOutputInstr reached"); } } -#endif +#else // !DEBUG + if (emitComp->opts.disAsm) + { + emitDispIns(id, false, false, true, 0, *dp, (dstRW - odstRW), ig); + } +#endif // !DEBUG /* All instructions are expected to generate code */ From cbf60b57df04a50c48877f9448d33f3da1e40ec8 Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Wed, 29 Nov 2023 13:38:08 +0100 Subject: [PATCH 13/35] Formatted riscv64 --- src/coreclr/jit/emitriscv64.cpp | 38 ++++++++++++++++----------------- src/coreclr/jit/emitriscv64.h | 18 ++++++++-------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 7773791939bd9a..737f410d90c6ed 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -941,9 +941,9 @@ void emitter::emitIns_R_AR(instruction ins, emitAttr attr, regNumber ireg, regNu } // This computes address from the immediate which is relocatable. -void emitter::emitIns_R_AI(instruction ins, - emitAttr attr, - regNumber reg, +void emitter::emitIns_R_AI(instruction ins, + emitAttr attr, + regNumber reg, ssize_t addr DEBUGARG(size_t targetHandle) DEBUGARG(GenTreeFlags gtFlags)) { assert(EA_IS_RELOC(attr)); // EA_PTR_DSP_RELOC @@ -1243,8 +1243,8 @@ void emitter::emitLoadImmediate(emitAttr size, regNumber reg, ssize_t imm) void emitter::emitIns_Call(EmitCallType callType, CORINFO_METHOD_HANDLE methHnd, INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo) // used to report call sites to the EE - void* addr, - ssize_t argSize, + void* addr, + ssize_t argSize, emitAttr retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize), VARSET_VALARG_TP ptrVars, regMaskTP gcrefRegs, @@ -1713,9 +1713,9 @@ void emitter::emitJumpDistBind() emitCounts_INS_OPTS_J * (6 << 2); // the max placeholder sizeof(INS_OPTS_JALR) - sizeof(INS_OPTS_J) NATIVE_OFFSET psd = B_DIST_SMALL_MAX_POS - maxPlaceholderSize; -/*****************************************************************************/ -/* If the default small encoding is not enough, we start again here. */ -/*****************************************************************************/ + /*****************************************************************************/ + /* If the default small encoding is not enough, we start again here. */ + /*****************************************************************************/ AGAIN: @@ -1746,7 +1746,7 @@ void emitter::emitJumpDistBind() UNATIVE_OFFSET dstOffs; NATIVE_OFFSET jmpDist; // the relative jump distance, as it will be encoded -/* Make sure the jumps are properly ordered */ + /* Make sure the jumps are properly ordered */ #ifdef DEBUG assert(lastSJ == nullptr || lastIG != jmp->idjIG || lastSJ->idjOffs < (jmp->idjOffs + adjSJ)); @@ -1904,8 +1904,8 @@ void emitter::emitJumpDistBind() instruction ins = jmp->idIns(); assert((INS_jal <= ins) && (ins <= INS_bgeu)); - if (ins > INS_jalr || - (ins < INS_jalr && ins > INS_j)) // jal < beqz < bnez < jalr < beq/bne/blt/bltu/bge/bgeu + if (ins > INS_jalr || (ins < INS_jalr && ins > INS_j)) // jal < beqz < bnez < jalr < + // beq/bne/blt/bltu/bge/bgeu { if (isValidSimm13(jmpDist + maxPlaceholderSize)) { @@ -1981,8 +1981,8 @@ void emitter::emitJumpDistBind() instruction ins = jmp->idIns(); assert((INS_jal <= ins) && (ins <= INS_bgeu)); - if (ins > INS_jalr || - (ins < INS_jalr && ins > INS_j)) // jal < beqz < bnez < jalr < beq/bne/blt/bltu/bge/bgeu + if (ins > INS_jalr || (ins < INS_jalr && ins > INS_j)) // jal < beqz < bnez < jalr < + // beq/bne/blt/bltu/bge/bgeu { if (isValidSimm13(jmpDist + maxPlaceholderSize)) { @@ -2086,7 +2086,7 @@ void emitter::emitJumpDistBind() } /***************************************************************************** -* + * * Append the machine code corresponding to the given instruction descriptor * to the code block at '*dp'; the base of the code block is 'bp', and 'ig' * is the instruction group that contains the instruction. Updates '*dp' to @@ -2505,7 +2505,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) regNumber reg2 = REG_R0; if (INS_beqz != ins && INS_bnez != ins) reg2 = id->idReg2(); - code = emitInsCode(ins) ^ 0x1000; + code = emitInsCode(ins) ^ 0x1000; code |= (code_t)reg1 << 15; /* rj */ code |= (code_t)reg2 << 20; /* rd */ code |= 0x8 << 7; @@ -2585,7 +2585,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) regNumber reg2 = REG_R0; if (INS_beqz != ins && INS_bnez != ins) reg2 = id->idReg2(); - code = emitInsCode(ins) ^ 0x1000; + code = emitInsCode(ins) ^ 0x1000; code |= (code_t)reg1 << 15; /* rj */ code |= (code_t)reg2 << 20; /* rd */ code |= 28 << 7; @@ -2840,7 +2840,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { #if DUMP_GC_TABLES bool dspOffs = emitComp->opts.dspGCtbls; -#else // !DUMP_GC_TABLES +#else // !DUMP_GC_TABLES bool dspOffs = !emitComp->opts.disDiffable; #endif // !DUMP_GC_TABLES emitDispIns(id, false, dspOffs, true, 0, *dp, (dstRW - odstRW), ig); @@ -2855,7 +2855,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) assert(!"JitBreakEmitOutputInstr reached"); } } -#else // !DEBUG +#else // !DEBUG if (emitComp->opts.disAsm) { emitDispIns(id, false, false, true, 0, *dp, (dstRW - odstRW), ig); @@ -3828,7 +3828,7 @@ void emitter::emitDispIns( return; const BYTE* instr = pCode + writeableOffset + offset; - size_t instrSize; + size_t instrSize; for (size_t i = 0; i < sz; instr += instrSize, i += instrSize) { instrSize = sizeof(code_t); diff --git a/src/coreclr/jit/emitriscv64.h b/src/coreclr/jit/emitriscv64.h index 068afaec852673..80288473fdc810 100644 --- a/src/coreclr/jit/emitriscv64.h +++ b/src/coreclr/jit/emitriscv64.h @@ -73,9 +73,9 @@ unsigned emitOutput_Instr(BYTE* dst, code_t code); // Method to do check if mov is redundant with respect to the last instruction. // If yes, the caller of this method can choose to omit current mov instruction. static bool IsMovInstruction(instruction ins); -bool IsRedundantMov(instruction ins, emitAttr size, regNumber dst, regNumber src, bool canSkip); -bool IsRedundantLdStr( - instruction ins, regNumber reg1, regNumber reg2, ssize_t imm, emitAttr size, insFormat fmt); // New functions end. +bool IsRedundantMov(instruction ins, emitAttr size, regNumber dst, regNumber src, bool canSkip); +bool IsRedundantLdStr( + instruction ins, regNumber reg1, regNumber reg2, ssize_t imm, emitAttr size, insFormat fmt); // New functions end. /************************************************************************/ /* Public inline informational methods */ @@ -215,9 +215,9 @@ void emitIns_J_R(instruction ins, emitAttr attr, BasicBlock* dst, regNumber reg) void emitIns_R_AR(instruction ins, emitAttr attr, regNumber ireg, regNumber reg, int offs); -void emitIns_R_AI(instruction ins, - emitAttr attr, - regNumber reg, +void emitIns_R_AI(instruction ins, + emitAttr attr, + regNumber reg, ssize_t disp DEBUGARG(size_t targetHandle = 0) DEBUGARG(GenTreeFlags gtFlags = GTF_EMPTY)); enum EmitCallType @@ -232,7 +232,7 @@ enum EmitCallType EC_FUNC_TOKEN, // Direct call to a helper/static/nonvirtual/global method // EC_FUNC_TOKEN_INDIR, // Indirect call to a helper/static/nonvirtual/global method - // EC_FUNC_ADDR, // Direct call to an absolute address + // EC_FUNC_ADDR, // Direct call to an absolute address // EC_FUNC_VIRTUAL, // Call to a virtual method (using the vtable) EC_INDIR_R, // Indirect call via register @@ -246,8 +246,8 @@ enum EmitCallType void emitIns_Call(EmitCallType callType, CORINFO_METHOD_HANDLE methHnd, INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo) // used to report call sites to the EE - void* addr, - ssize_t argSize, + void* addr, + ssize_t argSize, emitAttr retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize), VARSET_VALARG_TP ptrVars, regMaskTP gcrefRegs, From 64c7a12f988719070c95ab1b4a76ec2440e78e1f Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Fri, 1 Dec 2023 10:30:16 +0100 Subject: [PATCH 14/35] [RISC-V] Added todo comment --- src/coreclr/jit/emitriscv64.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 737f410d90c6ed..2af542265faf75 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -3831,6 +3831,7 @@ void emitter::emitDispIns( size_t instrSize; for (size_t i = 0; i < sz; instr += instrSize, i += instrSize) { + // TODO-RISCV64: support different size instructions instrSize = sizeof(code_t); code_t instruction; memcpy(&instruction, instr, instrSize); From a6fd65347ee66dfc6ad6c2997c1b5edfcdd39c76 Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Fri, 1 Dec 2023 11:02:46 +0100 Subject: [PATCH 15/35] [RISC-V] Applied format patch --- src/coreclr/jit/emitriscv64.cpp | 24 ++++++++++++------------ src/coreclr/jit/emitriscv64.h | 16 ++++++++-------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 2af542265faf75..2fcbf4465f69b0 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -941,9 +941,9 @@ void emitter::emitIns_R_AR(instruction ins, emitAttr attr, regNumber ireg, regNu } // This computes address from the immediate which is relocatable. -void emitter::emitIns_R_AI(instruction ins, - emitAttr attr, - regNumber reg, +void emitter::emitIns_R_AI(instruction ins, + emitAttr attr, + regNumber reg, ssize_t addr DEBUGARG(size_t targetHandle) DEBUGARG(GenTreeFlags gtFlags)) { assert(EA_IS_RELOC(attr)); // EA_PTR_DSP_RELOC @@ -1243,8 +1243,8 @@ void emitter::emitLoadImmediate(emitAttr size, regNumber reg, ssize_t imm) void emitter::emitIns_Call(EmitCallType callType, CORINFO_METHOD_HANDLE methHnd, INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo) // used to report call sites to the EE - void* addr, - ssize_t argSize, + void* addr, + ssize_t argSize, emitAttr retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize), VARSET_VALARG_TP ptrVars, regMaskTP gcrefRegs, @@ -1713,9 +1713,9 @@ void emitter::emitJumpDistBind() emitCounts_INS_OPTS_J * (6 << 2); // the max placeholder sizeof(INS_OPTS_JALR) - sizeof(INS_OPTS_J) NATIVE_OFFSET psd = B_DIST_SMALL_MAX_POS - maxPlaceholderSize; - /*****************************************************************************/ - /* If the default small encoding is not enough, we start again here. */ - /*****************************************************************************/ +/*****************************************************************************/ +/* If the default small encoding is not enough, we start again here. */ +/*****************************************************************************/ AGAIN: @@ -1746,7 +1746,7 @@ void emitter::emitJumpDistBind() UNATIVE_OFFSET dstOffs; NATIVE_OFFSET jmpDist; // the relative jump distance, as it will be encoded - /* Make sure the jumps are properly ordered */ +/* Make sure the jumps are properly ordered */ #ifdef DEBUG assert(lastSJ == nullptr || lastIG != jmp->idjIG || lastSJ->idjOffs < (jmp->idjOffs + adjSJ)); @@ -2107,7 +2107,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) #if DUMP_GC_TABLES bool dspOffs = emitComp->opts.dspGCtbls; #else - bool dspOffs = !emitComp->opts.disDiffable; + bool dspOffs = !emitComp->opts.disDiffable; #endif #endif // DEBUG @@ -2505,7 +2505,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) regNumber reg2 = REG_R0; if (INS_beqz != ins && INS_bnez != ins) reg2 = id->idReg2(); - code = emitInsCode(ins) ^ 0x1000; + code = emitInsCode(ins) ^ 0x1000; code |= (code_t)reg1 << 15; /* rj */ code |= (code_t)reg2 << 20; /* rd */ code |= 0x8 << 7; @@ -2585,7 +2585,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) regNumber reg2 = REG_R0; if (INS_beqz != ins && INS_bnez != ins) reg2 = id->idReg2(); - code = emitInsCode(ins) ^ 0x1000; + code = emitInsCode(ins) ^ 0x1000; code |= (code_t)reg1 << 15; /* rj */ code |= (code_t)reg2 << 20; /* rd */ code |= 28 << 7; diff --git a/src/coreclr/jit/emitriscv64.h b/src/coreclr/jit/emitriscv64.h index 80288473fdc810..bc69e6519cee41 100644 --- a/src/coreclr/jit/emitriscv64.h +++ b/src/coreclr/jit/emitriscv64.h @@ -73,9 +73,9 @@ unsigned emitOutput_Instr(BYTE* dst, code_t code); // Method to do check if mov is redundant with respect to the last instruction. // If yes, the caller of this method can choose to omit current mov instruction. static bool IsMovInstruction(instruction ins); -bool IsRedundantMov(instruction ins, emitAttr size, regNumber dst, regNumber src, bool canSkip); -bool IsRedundantLdStr( - instruction ins, regNumber reg1, regNumber reg2, ssize_t imm, emitAttr size, insFormat fmt); // New functions end. +bool IsRedundantMov(instruction ins, emitAttr size, regNumber dst, regNumber src, bool canSkip); +bool IsRedundantLdStr( + instruction ins, regNumber reg1, regNumber reg2, ssize_t imm, emitAttr size, insFormat fmt); // New functions end. /************************************************************************/ /* Public inline informational methods */ @@ -215,9 +215,9 @@ void emitIns_J_R(instruction ins, emitAttr attr, BasicBlock* dst, regNumber reg) void emitIns_R_AR(instruction ins, emitAttr attr, regNumber ireg, regNumber reg, int offs); -void emitIns_R_AI(instruction ins, - emitAttr attr, - regNumber reg, +void emitIns_R_AI(instruction ins, + emitAttr attr, + regNumber reg, ssize_t disp DEBUGARG(size_t targetHandle = 0) DEBUGARG(GenTreeFlags gtFlags = GTF_EMPTY)); enum EmitCallType @@ -246,8 +246,8 @@ enum EmitCallType void emitIns_Call(EmitCallType callType, CORINFO_METHOD_HANDLE methHnd, INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo) // used to report call sites to the EE - void* addr, - ssize_t argSize, + void* addr, + ssize_t argSize, emitAttr retSize MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize), VARSET_VALARG_TP ptrVars, regMaskTP gcrefRegs, From 30c80aef319ad34426865c2e191e722383928cfd Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Fri, 1 Dec 2023 11:41:35 +0100 Subject: [PATCH 16/35] [RISC-V] Undo the emit.cpp dispIns changes --- src/coreclr/jit/emit.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index c32ed266424688..a3ea52c33e804b 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -1491,6 +1491,12 @@ void emitter::dispIns(instrDesc* id) // For LoongArch64 using the emitDisInsName(). NYI_LOONGARCH64("Not used on LOONGARCH64."); } +#elif defined(TARGET_RISCV64) +void emitter::dispIns(instrDesc* id) +{ + // For RISCV64 using the emitDisInsName(). + NYI_RISCV64("Not used on RISCV64."); +} #else void emitter::dispIns(instrDesc* id) { From 61131a65b654e4eca43247ceccda8b65d58c155d Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Fri, 1 Dec 2023 15:06:51 +0100 Subject: [PATCH 17/35] [RISC-V] Fixed formatting --- src/coreclr/jit/emitriscv64.cpp | 14 +++++++------- src/coreclr/jit/emitriscv64.h | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 2fcbf4465f69b0..59468918dbb0dd 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -1904,8 +1904,8 @@ void emitter::emitJumpDistBind() instruction ins = jmp->idIns(); assert((INS_jal <= ins) && (ins <= INS_bgeu)); - if (ins > INS_jalr || (ins < INS_jalr && ins > INS_j)) // jal < beqz < bnez < jalr < - // beq/bne/blt/bltu/bge/bgeu + if (ins > INS_jalr || + (ins < INS_jalr && ins > INS_j)) // jal < beqz < bnez < jalr < beq/bne/blt/bltu/bge/bgeu { if (isValidSimm13(jmpDist + maxPlaceholderSize)) { @@ -1981,8 +1981,8 @@ void emitter::emitJumpDistBind() instruction ins = jmp->idIns(); assert((INS_jal <= ins) && (ins <= INS_bgeu)); - if (ins > INS_jalr || (ins < INS_jalr && ins > INS_j)) // jal < beqz < bnez < jalr < - // beq/bne/blt/bltu/bge/bgeu + if (ins > INS_jalr || + (ins < INS_jalr && ins > INS_j)) // jal < beqz < bnez < jalr < beq/bne/blt/bltu/bge/bgeu { if (isValidSimm13(jmpDist + maxPlaceholderSize)) { @@ -2086,7 +2086,7 @@ void emitter::emitJumpDistBind() } /***************************************************************************** - * +* * Append the machine code corresponding to the given instruction descriptor * to the code block at '*dp'; the base of the code block is 'bp', and 'ig' * is the instruction group that contains the instruction. Updates '*dp' to @@ -2106,9 +2106,9 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) #ifdef DEBUG #if DUMP_GC_TABLES bool dspOffs = emitComp->opts.dspGCtbls; -#else +#else // !DUMP_GC_TABLES bool dspOffs = !emitComp->opts.disDiffable; -#endif +#endif // !DUMP_GC_TABLES #endif // DEBUG assert(REG_NA == (int)REG_NA); diff --git a/src/coreclr/jit/emitriscv64.h b/src/coreclr/jit/emitriscv64.h index bc69e6519cee41..068afaec852673 100644 --- a/src/coreclr/jit/emitriscv64.h +++ b/src/coreclr/jit/emitriscv64.h @@ -232,7 +232,7 @@ enum EmitCallType EC_FUNC_TOKEN, // Direct call to a helper/static/nonvirtual/global method // EC_FUNC_TOKEN_INDIR, // Indirect call to a helper/static/nonvirtual/global method - // EC_FUNC_ADDR, // Direct call to an absolute address + // EC_FUNC_ADDR, // Direct call to an absolute address // EC_FUNC_VIRTUAL, // Call to a virtual method (using the vtable) EC_INDIR_R, // Indirect call via register From 91759cd2c33735f4352507873ade0fc4664af1fc Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Fri, 1 Dec 2023 15:10:13 +0100 Subject: [PATCH 18/35] Removed dead code --- src/coreclr/jit/emitriscv64.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 59468918dbb0dd..14e8dfad9280b2 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -2103,14 +2103,6 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) instruction ins; size_t sz; // = emitSizeOfInsDsc(id); -#ifdef DEBUG -#if DUMP_GC_TABLES - bool dspOffs = emitComp->opts.dspGCtbls; -#else // !DUMP_GC_TABLES - bool dspOffs = !emitComp->opts.disDiffable; -#endif // !DUMP_GC_TABLES -#endif // DEBUG - assert(REG_NA == (int)REG_NA); insOpts insOp = id->idInsOpt(); From d5acb3de3250cc4b0784c27bea79211e1ee715da Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Mon, 4 Dec 2023 10:06:29 +0100 Subject: [PATCH 19/35] Added emitDispInsDebugOnlyInfo --- src/coreclr/jit/emitriscv64.cpp | 12 ++++++++++++ src/coreclr/jit/emitriscv64.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index e954d197132e6d..80e3c7ae821247 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -3813,9 +3813,21 @@ void emitter::emitDispInsHex(instrDesc* id, BYTE* code, size_t sz) } } +void emitter::emitDispInsDebugOnlyInfo(instrDesc* id) +{ +#ifdef DEBUG + if (!emitComp->verbose) + return; + + printf("IN%04x: ", id->idDebugOnlyInfo()->idNum); +#endif // DEBUG +} + void emitter::emitDispIns( instrDesc* id, bool isNew, bool doffs, bool asmfm, unsigned offset, BYTE* pCode, size_t sz, insGroup* ig) { + emitDispInsDebugOnlyInfo(id); + if (pCode == nullptr) return; diff --git a/src/coreclr/jit/emitriscv64.h b/src/coreclr/jit/emitriscv64.h index 068afaec852673..d7850776be9e3d 100644 --- a/src/coreclr/jit/emitriscv64.h +++ b/src/coreclr/jit/emitriscv64.h @@ -62,6 +62,8 @@ bool emitInsIsLoadOrStore(instruction ins); void emitDispInsName(code_t code, const BYTE* addr, bool doffs, unsigned offset, instrDesc* id); +void emitDispInsDebugOnlyInfo(instrDesc* id); + emitter::code_t emitInsCode(instruction ins /*, insFormat fmt*/); // Generate code for a load or store operation and handle the case of contained GT_LEA op1 with [base + offset] From 0e9c8c3f1c02b1444be6635d23d0a9337fd7bad5 Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Tue, 12 Dec 2023 10:50:37 +0100 Subject: [PATCH 20/35] Added preliminary emitOutputInstrJump --- src/coreclr/jit/emitriscv64.cpp | 45 ++++++++++++++++++++++++++++++--- src/coreclr/jit/emitriscv64.h | 2 ++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 9c1db4a7be21dc..038e8b3034718f 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -2118,15 +2118,51 @@ void emitter::emitJumpDistBind() * Emit a 32-bit RISCV64 instruction */ -/*static*/ unsigned emitter::emitOutput_Instr(BYTE* dst, code_t code) +unsigned emitter::emitOutput_Instr(BYTE* dst, code_t code) { assert(sizeof(code_t) == 4); - BYTE* dstRW = dst + writeableOffset; - *((code_t*)dstRW) = code; - + memcpy(dst + writeableOffset, code, sizeof(code_t)); return sizeof(code_t); } +void emitter::emitOutputInstrJump(BYTE* destination, + BYTE const* const source, + insGroup* instructionGroup, + instrDescJmp* jmp) +{ + UNATIVE_OFFSET sourceOffset = emitCurCodeOffs(source); + UNATIVE_OFFSET distanceOffset = 0; + BYTE const* sourceAddress = emitOffsetToPtr(sourceOffset); + BYTE const* distanceAddress = nullptr; + + if (jmp->idAddr()->iiaHasInstrCount()) + { + printf("iiaHasInstrCount\n"); + assert(instructionGroup != nullptr); + int instuctionCount = jmp->idAddr()->iiaGetInstrCount(); + unsigned instructionNumber = emitFindInsNum(instructionGroup, jmp); + if (instuctionCount < 0) + { + assert(instructionNumber + 1 >= static_cast(-instuctionCount)); + } + + distanceOffset = + instructionGroup->igOffs + emitFindOffset(instructionGroup, instructionNumber + 1 + instuctionCount); + distanceAddress = emitOffsetToPtr(distanceOffset); + } + else + { + printf("iiaHasNotInstrCount\n"); + distanceOffset = jmp->idAddr()->iiaIGlabel->igOffs; + distanceAddress = emitOffsetToPtr(distanceOffset); + } + + ptrdiff_t distanceValue = static_cast(distanceAddress - sourceAddress); + printf( + "SourceOffset: %u, DistanceOffset: %u, SourceAddress: %p, DistanceAddress: %p, UnrectifiedDistanceValue: %i\n", + sourceOffset, distanceOffset, sourceAddress, distanceAddress, distanceValue); +} + /***************************************************************************** * * Append the machine code corresponding to the given instruction descriptor @@ -2139,6 +2175,7 @@ void emitter::emitJumpDistBind() size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { BYTE* dstRW = *dp + writeableOffset; + BYTE* const dst = *dp; BYTE* dstRW2 = dstRW + 4; // addr for updating gc info if needed. BYTE* const odstRW = dstRW; code_t code = 0; diff --git a/src/coreclr/jit/emitriscv64.h b/src/coreclr/jit/emitriscv64.h index 4595346440eba8..9ac9c2bc537c5c 100644 --- a/src/coreclr/jit/emitriscv64.h +++ b/src/coreclr/jit/emitriscv64.h @@ -72,6 +72,8 @@ void emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataReg, GenTr // Emit the 32-bit RISCV64 instruction 'code' into the 'dst' buffer unsigned emitOutput_Instr(BYTE* dst, code_t code); +void emitOutputInstrJump(BYTE* destination, BYTE const* const source, insGroup* igm, instrDescJmp* jmp); + // Method to do check if mov is redundant with respect to the last instruction. // If yes, the caller of this method can choose to omit current mov instruction. static bool IsMovInstruction(instruction ins); From 9213d5ce0e36d5221ed7551ca94cffb9f5b930d2 Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Tue, 12 Dec 2023 13:06:41 +0100 Subject: [PATCH 21/35] Preliminary emitOutputInstrJump impl --- src/coreclr/jit/emit.h | 22 ++++++++++-- src/coreclr/jit/emitriscv64.cpp | 64 +++++++++------------------------ src/coreclr/jit/emitriscv64.h | 5 ++- 3 files changed, 41 insertions(+), 50 deletions(-) diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index c8aae8a405e7cd..40f01b40da309d 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -990,7 +990,7 @@ class emitter regNumber _idReg3 : REGNUM_BITS; regNumber _idReg4 : REGNUM_BITS; }; -#elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) +#elif defined(TARGET_LOONGARCH64) struct { unsigned int iiaEncodedInstr; // instruction's binary encoding. @@ -1021,7 +1021,25 @@ class emitter { return iiaJmpOffset; } -#endif // defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) +#elif defined(TARGET_RISCV64) + struct + { + unsigned int iiaEncodedInstr; // instruction's binary encoding. + regNumber _idReg3 : REGNUM_BITS; + regNumber _idReg4 : REGNUM_BITS; + }; + + emitLclVarAddr iiaLclVar; + + void iiaSetInstrEncode(unsigned int encode) + { + iiaEncodedInstr = encode; + } + unsigned int iiaGetInstrEncode() const + { + return iiaEncodedInstr; + } +#endif // defined(TARGET_RISCV64) } _idAddrUnion; diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 038e8b3034718f..773d24d7f3deab 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -1936,11 +1936,7 @@ void emitter::emitJumpDistBind() assert(jmpDist >= 0); // Forward jump assert(!(jmpDist & 0x3)); - if (isLinkingEnd & 0x2) - { - jmp->idAddr()->iiaSetJmpOffset(jmpDist); - } - else if ((extra > 0) && (jmp->idInsOpt() == INS_OPTS_J || jmp->idInsOpt() == INS_OPTS_J_cond)) + if ((extra > 0) && (jmp->idInsOpt() == INS_OPTS_J || jmp->idInsOpt() == INS_OPTS_J_cond)) { // transform forward INS_OPTS_J/INS_OPTS_J_cond jump when jmpDist exceed the maximum short distance instruction ins = jmp->idIns(); @@ -2013,11 +2009,7 @@ void emitter::emitJumpDistBind() assert(jmpDist >= 0); // Backward jump assert(!(jmpDist & 0x3)); - if (isLinkingEnd & 0x2) - { - jmp->idAddr()->iiaSetJmpOffset(-jmpDist); // Backward jump is negative! - } - else if ((extra > 0) && (jmp->idInsOpt() == INS_OPTS_J || jmp->idInsOpt() == INS_OPTS_J_cond)) + if ((extra > 0) && (jmp->idInsOpt() == INS_OPTS_J || jmp->idInsOpt() == INS_OPTS_J_cond)) { // transform backward INS_OPTS_J/INS_OPTS_J_cond jump when jmpDist exceed the maximum short distance instruction ins = jmp->idIns(); @@ -2121,50 +2113,28 @@ void emitter::emitJumpDistBind() unsigned emitter::emitOutput_Instr(BYTE* dst, code_t code) { assert(sizeof(code_t) == 4); - memcpy(dst + writeableOffset, code, sizeof(code_t)); + memcpy(dst + writeableOffset, &code, sizeof(code_t)); return sizeof(code_t); } -void emitter::emitOutputInstrJump(BYTE* destination, - BYTE const* const source, - insGroup* instructionGroup, - instrDescJmp* jmp) +ssize_t emitter::emitOutputInstrJumpSize(BYTE const* const destination, + BYTE const* const source, + insGroup const* const instructionGroup, + instrDescJmp const* const jumpDescription) { - UNATIVE_OFFSET sourceOffset = emitCurCodeOffs(source); - UNATIVE_OFFSET distanceOffset = 0; - BYTE const* sourceAddress = emitOffsetToPtr(sourceOffset); - BYTE const* distanceAddress = nullptr; + UNATIVE_OFFSET sourceOffset = emitCurCodeOffs(source); + BYTE const* sourceAddress = emitOffsetToPtr(sourceOffset); - if (jmp->idAddr()->iiaHasInstrCount()) - { - printf("iiaHasInstrCount\n"); - assert(instructionGroup != nullptr); - int instuctionCount = jmp->idAddr()->iiaGetInstrCount(); - unsigned instructionNumber = emitFindInsNum(instructionGroup, jmp); - if (instuctionCount < 0) - { - assert(instructionNumber + 1 >= static_cast(-instuctionCount)); - } + assert(!jumpDescription->idAddr()->iiaHasInstrCount()); // not used by riscv64 impl - distanceOffset = - instructionGroup->igOffs + emitFindOffset(instructionGroup, instructionNumber + 1 + instuctionCount); - distanceAddress = emitOffsetToPtr(distanceOffset); - } - else - { - printf("iiaHasNotInstrCount\n"); - distanceOffset = jmp->idAddr()->iiaIGlabel->igOffs; - distanceAddress = emitOffsetToPtr(distanceOffset); - } + UNATIVE_OFFSET distanceOffset = jumpDescription->idAddr()->iiaIGlabel->igOffs; + BYTE const* distanceAddress = emitOffsetToPtr(distanceOffset); - ptrdiff_t distanceValue = static_cast(distanceAddress - sourceAddress); - printf( - "SourceOffset: %u, DistanceOffset: %u, SourceAddress: %p, DistanceAddress: %p, UnrectifiedDistanceValue: %i\n", - sourceOffset, distanceOffset, sourceAddress, distanceAddress, distanceValue); + return static_cast(distanceAddress - sourceAddress); } /***************************************************************************** -* + * * Append the machine code corresponding to the given instruction descriptor * to the code block at '*dp'; the base of the code block is 'bp', and 'ig' * is the instruction group that contains the instruction. Updates '*dp' to @@ -2555,7 +2525,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) regNumber reg1 = id->idReg1(); { - ssize_t imm = (ssize_t)id->idAddr()->iiaGetJmpOffset(); + ssize_t imm = emitOutputInstrJumpSize(dstRW, dst, ig, jmp); imm -= 4; assert((imm & 0x3) == 0); @@ -2724,7 +2694,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) break; case INS_OPTS_J_cond: { - ssize_t imm = (ssize_t)id->idAddr()->iiaGetJmpOffset(); // get jmp's offset relative delay-slot. + ssize_t imm = emitOutputInstrJumpSize(dstRW, dst, ig, static_cast(id)); assert(isValidSimm13(imm)); assert(!(imm & 1)); @@ -2745,7 +2715,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) case INS_OPTS_J: // jal/j/jalr/bnez/beqz/beq/bne/blt/bge/bltu/bgeu dstRW-relative. { - ssize_t imm = (ssize_t)id->idAddr()->iiaGetJmpOffset(); // get jmp's offset relative delay-slot. + ssize_t imm = emitOutputInstrJumpSize(dstRW, dst, ig, static_cast(id)); assert((imm & 3) == 0); ins = id->idIns(); diff --git a/src/coreclr/jit/emitriscv64.h b/src/coreclr/jit/emitriscv64.h index 9ac9c2bc537c5c..a6147896c4440c 100644 --- a/src/coreclr/jit/emitriscv64.h +++ b/src/coreclr/jit/emitriscv64.h @@ -72,7 +72,10 @@ void emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataReg, GenTr // Emit the 32-bit RISCV64 instruction 'code' into the 'dst' buffer unsigned emitOutput_Instr(BYTE* dst, code_t code); -void emitOutputInstrJump(BYTE* destination, BYTE const* const source, insGroup* igm, instrDescJmp* jmp); +ssize_t emitOutputInstrJumpSize(BYTE const* const destination, + BYTE const* const source, + insGroup const* const instructionGroup, + instrDescJmp const* const jumpDescription); // Method to do check if mov is redundant with respect to the last instruction. // If yes, the caller of this method can choose to omit current mov instruction. From 798258d48d3af534fd5713220991eda97a9ded2c Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Tue, 12 Dec 2023 15:34:51 +0100 Subject: [PATCH 22/35] TmpSave --- src/coreclr/jit/emit.h | 38 ++++++++++++++++----------------- src/coreclr/jit/emitriscv64.cpp | 6 ++++-- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 40f01b40da309d..f35fd65430cd69 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -990,7 +990,7 @@ class emitter regNumber _idReg3 : REGNUM_BITS; regNumber _idReg4 : REGNUM_BITS; }; -#elif defined(TARGET_LOONGARCH64) +#elif defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) struct { unsigned int iiaEncodedInstr; // instruction's binary encoding. @@ -1021,24 +1021,24 @@ class emitter { return iiaJmpOffset; } -#elif defined(TARGET_RISCV64) - struct - { - unsigned int iiaEncodedInstr; // instruction's binary encoding. - regNumber _idReg3 : REGNUM_BITS; - regNumber _idReg4 : REGNUM_BITS; - }; - - emitLclVarAddr iiaLclVar; - - void iiaSetInstrEncode(unsigned int encode) - { - iiaEncodedInstr = encode; - } - unsigned int iiaGetInstrEncode() const - { - return iiaEncodedInstr; - } +// #elif defined(TARGET_RISCV64) +// struct +// { +// unsigned int iiaEncodedInstr; // instruction's binary encoding. +// regNumber _idReg3 : REGNUM_BITS; +// regNumber _idReg4 : REGNUM_BITS; +// }; + +// emitLclVarAddr iiaLclVar; + +// void iiaSetInstrEncode(unsigned int encode) +// { +// iiaEncodedInstr = encode; +// } +// unsigned int iiaGetInstrEncode() const +// { +// return iiaEncodedInstr; +// } #endif // defined(TARGET_RISCV64) } _idAddrUnion; diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 773d24d7f3deab..36464b38a5dc31 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -1936,7 +1936,7 @@ void emitter::emitJumpDistBind() assert(jmpDist >= 0); // Forward jump assert(!(jmpDist & 0x3)); - if ((extra > 0) && (jmp->idInsOpt() == INS_OPTS_J || jmp->idInsOpt() == INS_OPTS_J_cond)) + if (!(isLinkingEnd & 0x2) && (extra > 0) && (jmp->idInsOpt() == INS_OPTS_J || jmp->idInsOpt() == INS_OPTS_J_cond)) { // transform forward INS_OPTS_J/INS_OPTS_J_cond jump when jmpDist exceed the maximum short distance instruction ins = jmp->idIns(); @@ -2009,7 +2009,7 @@ void emitter::emitJumpDistBind() assert(jmpDist >= 0); // Backward jump assert(!(jmpDist & 0x3)); - if ((extra > 0) && (jmp->idInsOpt() == INS_OPTS_J || jmp->idInsOpt() == INS_OPTS_J_cond)) + if (!(isLinkingEnd & 0x2) && (extra > 0) && (jmp->idInsOpt() == INS_OPTS_J || jmp->idInsOpt() == INS_OPTS_J_cond)) { // transform backward INS_OPTS_J/INS_OPTS_J_cond jump when jmpDist exceed the maximum short distance instruction ins = jmp->idIns(); @@ -2130,6 +2130,8 @@ ssize_t emitter::emitOutputInstrJumpSize(BYTE const* const destination, UNATIVE_OFFSET distanceOffset = jumpDescription->idAddr()->iiaIGlabel->igOffs; BYTE const* distanceAddress = emitOffsetToPtr(distanceOffset); + printf("Emmiting jump with size: %p\n", distanceAddress - sourceAddress); + return static_cast(distanceAddress - sourceAddress); } From 9bf8da0fc1a69331d34f66a7ce285a51f458a83c Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Wed, 13 Dec 2023 10:17:12 +0100 Subject: [PATCH 23/35] [RISC-V] Changes after review --- src/coreclr/jit/emit.cpp | 3 --- src/coreclr/jit/emitriscv64.cpp | 39 +++++++++++++++++++++++---------- src/coreclr/jit/emitriscv64.h | 4 +++- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index a3ea52c33e804b..bbc052ca9de918 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -4211,8 +4211,6 @@ void emitter::emitDispIG(insGroup* ig, bool displayFunc, bool displayInstruction printf("\n"); -#if !defined(TARGET_RISCV64) - // TODO-RISCV64-Bug: When JitDump is on, it asserts in emitDispIns which is not implemented. if (displayInstructions) { instrDesc* id = emitFirstInstrDesc(ig->igData); @@ -4245,7 +4243,6 @@ void emitter::emitDispIG(insGroup* ig, bool displayFunc, bool displayInstruction printf("\n"); } } -#endif // !TARGET_RISCV64 } } diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 14e8dfad9280b2..9e97ec239ce84a 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -2096,12 +2096,13 @@ void emitter::emitJumpDistBind() size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { - BYTE* dstRW = *dp + writeableOffset; - BYTE* dstRW2 = dstRW + 4; // addr for updating gc info if needed. - BYTE* const odstRW = dstRW; - code_t code = 0; - instruction ins; - size_t sz; // = emitSizeOfInsDsc(id); + BYTE* dstRW = *dp + writeableOffset; + BYTE* dstRW2 = dstRW + 4; // addr for updating gc info if needed. + const BYTE* const odstRW = dstRW; + const BYTE* const odst = *dp; + code_t code = 0; + instruction ins; + size_t sz; // = emitSizeOfInsDsc(id); assert(REG_NA == (int)REG_NA); @@ -2835,7 +2836,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) #else // !DUMP_GC_TABLES bool dspOffs = !emitComp->opts.disDiffable; #endif // !DUMP_GC_TABLES - emitDispIns(id, false, dspOffs, true, 0, *dp, (dstRW - odstRW), ig); + emitDispIns(id, false, dspOffs, true, emitCurCodeOffs(odst), *dp, (dstRW - odstRW), ig); } if (emitComp->compDebugBreak) @@ -2850,7 +2851,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) #else // !DEBUG if (emitComp->opts.disAsm) { - emitDispIns(id, false, false, true, 0, *dp, (dstRW - odstRW), ig); + emitDispIns(id, false, false, true, emitCurCodeOffs(odst), *dp, (dstRW - odstRW), ig); } #endif // !DEBUG @@ -2883,13 +2884,15 @@ static const char* const RegNames[] = // Arguments: // code - The instruction's encoding. // addr - The address of the code. +// doffs - Flag informing whether the instruction's offset should be displayed. +// insOffset - The instruction's offset. // id - The instrDesc of the code if needed. // // Note: // The length of the instruction's name include aligned space is 15. // -void emitter::emitDispInsName(code_t code, const BYTE* addr, bool doffs, unsigned offset, instrDesc* id) +void emitter::emitDispInsName(code_t code, const BYTE* addr, bool doffs, unsigned insOffset, instrDesc* id) { const BYTE* insAdr = addr - writeableOffset; @@ -2897,7 +2900,7 @@ void emitter::emitDispInsName(code_t code, const BYTE* addr, bool doffs, unsigne assert((opcode & 0x3) == 0x3); emitDispInsAddr(insAdr); - emitDispInsOffs(offset, doffs); + emitDispInsOffs(insOffset, doffs); printf(" "); @@ -3813,15 +3816,27 @@ void emitter::emitDispInsHex(instrDesc* id, BYTE* code, size_t sz) } } +void emitter::emitDispInsInstrNum(const instrDesc* id) const +{ +#ifdef DEBUG + if (!emitComp->verbose) + return; + + printf("IN%04x: ", id->idDebugOnlyInfo()->idNum); +#endif // DEBUG +} + void emitter::emitDispIns( instrDesc* id, bool isNew, bool doffs, bool asmfm, unsigned offset, BYTE* pCode, size_t sz, insGroup* ig) { if (pCode == nullptr) return; - const BYTE* instr = pCode + writeableOffset + offset; + emitDispInsInstrNum(id); + + const BYTE* instr = pCode + writeableOffset; size_t instrSize; - for (size_t i = 0; i < sz; instr += instrSize, i += instrSize) + for (size_t i = 0; i < sz; instr += instrSize, i += instrSize, offset += instrSize) { // TODO-RISCV64: support different size instructions instrSize = sizeof(code_t); diff --git a/src/coreclr/jit/emitriscv64.h b/src/coreclr/jit/emitriscv64.h index 068afaec852673..a9b98af9095d1c 100644 --- a/src/coreclr/jit/emitriscv64.h +++ b/src/coreclr/jit/emitriscv64.h @@ -60,7 +60,9 @@ bool emitInsIsLoad(instruction ins); bool emitInsIsStore(instruction ins); bool emitInsIsLoadOrStore(instruction ins); -void emitDispInsName(code_t code, const BYTE* addr, bool doffs, unsigned offset, instrDesc* id); +void emitDispInsName(code_t code, const BYTE* addr, bool doffs, unsigned insOffset, instrDesc* id); + +void emitDispInsInstrNum(const instrDesc* id) const; emitter::code_t emitInsCode(instruction ins /*, insFormat fmt*/); From b19003c1e66ffd49ad2bac359f941b229f441d01 Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Wed, 13 Dec 2023 11:28:39 +0100 Subject: [PATCH 24/35] Fixes after merge --- src/coreclr/jit/emitriscv64.cpp | 5 ----- src/coreclr/jit/emitriscv64.h | 2 -- 2 files changed, 7 deletions(-) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index ce9bdb42304752..18b98a0b18199a 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -2129,9 +2129,6 @@ ssize_t emitter::emitOutputInstrJumpSize(BYTE const* const destination, UNATIVE_OFFSET distanceOffset = jumpDescription->idAddr()->iiaIGlabel->igOffs; BYTE const* distanceAddress = emitOffsetToPtr(distanceOffset); - - printf("Emmiting jump with size: %p\n", distanceAddress - sourceAddress); - return static_cast(distanceAddress - sourceAddress); } @@ -3927,8 +3924,6 @@ void emitter::emitDispInsInstrNum(const instrDesc* id) const void emitter::emitDispIns( instrDesc* id, bool isNew, bool doffs, bool asmfm, unsigned offset, BYTE* pCode, size_t sz, insGroup* ig) { - emitDispInsDebugOnlyInfo(id); - if (pCode == nullptr) return; diff --git a/src/coreclr/jit/emitriscv64.h b/src/coreclr/jit/emitriscv64.h index 34566692225218..4cea72729c5099 100644 --- a/src/coreclr/jit/emitriscv64.h +++ b/src/coreclr/jit/emitriscv64.h @@ -64,8 +64,6 @@ void emitDispInsName(code_t code, const BYTE* addr, bool doffs, unsigned insOffs void emitDispInsInstrNum(const instrDesc* id) const; -void emitDispInsDebugOnlyInfo(instrDesc* id); - emitter::code_t emitInsCode(instruction ins /*, insFormat fmt*/); // Generate code for a load or store operation and handle the case of contained GT_LEA op1 with [base + offset] From ecebd5dab7fcce534637784dc8b53058236675ee Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Wed, 13 Dec 2023 13:40:38 +0100 Subject: [PATCH 25/35] Fixed comment in emmit.h --- src/coreclr/jit/emit.h | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index f35fd65430cd69..c8aae8a405e7cd 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -1021,25 +1021,7 @@ class emitter { return iiaJmpOffset; } -// #elif defined(TARGET_RISCV64) -// struct -// { -// unsigned int iiaEncodedInstr; // instruction's binary encoding. -// regNumber _idReg3 : REGNUM_BITS; -// regNumber _idReg4 : REGNUM_BITS; -// }; - -// emitLclVarAddr iiaLclVar; - -// void iiaSetInstrEncode(unsigned int encode) -// { -// iiaEncodedInstr = encode; -// } -// unsigned int iiaGetInstrEncode() const -// { -// return iiaEncodedInstr; -// } -#endif // defined(TARGET_RISCV64) +#endif // defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) } _idAddrUnion; From d3c8039d4d92b4e780d823961cbd40dbc6db805f Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Wed, 13 Dec 2023 15:11:35 +0100 Subject: [PATCH 26/35] Added label printing --- src/coreclr/jit/emit.cpp | 4 +- src/coreclr/jit/emit.h | 4 +- src/coreclr/jit/emitriscv64.cpp | 118 ++++++++++++++++++++------------ src/coreclr/jit/emitriscv64.h | 4 +- 4 files changed, 83 insertions(+), 47 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 00836b0202915e..ee0593cadcdd64 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -2953,7 +2953,7 @@ void* emitter::emitAddInlineLabel() // emitPrintLabel: Print the assembly label for an insGroup. We could use emitter::emitLabelString() // to be consistent, but that seems silly. // -void emitter::emitPrintLabel(insGroup* ig) +void emitter::emitPrintLabel(const insGroup* ig) const { printf("G_M%03u_IG%02u", emitComp->compMethodID, ig->igNum); } @@ -2966,7 +2966,7 @@ void emitter::emitPrintLabel(insGroup* ig) // Returns: // String with insGroup label // -const char* emitter::emitLabelString(insGroup* ig) +const char* emitter::emitLabelString(const insGroup* ig) const { const int TEMP_BUFFER_LEN = 40; static unsigned curBuf = 0; diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index c8aae8a405e7cd..834a14a1811d98 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -2712,8 +2712,8 @@ class emitter // continues to track GC info as if there was no label. void* emitAddInlineLabel(); - void emitPrintLabel(insGroup* ig); - const char* emitLabelString(insGroup* ig); + void emitPrintLabel(const insGroup* ig) const; + const char* emitLabelString(const insGroup* ig) const; #if defined(TARGET_ARMARCH) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 18b98a0b18199a..4d2348fce34d74 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -1936,7 +1936,8 @@ void emitter::emitJumpDistBind() assert(jmpDist >= 0); // Forward jump assert(!(jmpDist & 0x3)); - if (!(isLinkingEnd & 0x2) && (extra > 0) && (jmp->idInsOpt() == INS_OPTS_J || jmp->idInsOpt() == INS_OPTS_J_cond)) + if (!(isLinkingEnd & 0x2) && (extra > 0) && + (jmp->idInsOpt() == INS_OPTS_J || jmp->idInsOpt() == INS_OPTS_J_cond)) { // transform forward INS_OPTS_J/INS_OPTS_J_cond jump when jmpDist exceed the maximum short distance instruction ins = jmp->idIns(); @@ -2009,7 +2010,8 @@ void emitter::emitJumpDistBind() assert(jmpDist >= 0); // Backward jump assert(!(jmpDist & 0x3)); - if (!(isLinkingEnd & 0x2) && (extra > 0) && (jmp->idInsOpt() == INS_OPTS_J || jmp->idInsOpt() == INS_OPTS_J_cond)) + if (!(isLinkingEnd & 0x2) && (extra > 0) && + (jmp->idInsOpt() == INS_OPTS_J || jmp->idInsOpt() == INS_OPTS_J_cond)) { // transform backward INS_OPTS_J/INS_OPTS_J_cond jump when jmpDist exceed the maximum short distance instruction ins = jmp->idIns(); @@ -2143,7 +2145,7 @@ ssize_t emitter::emitOutputInstrJumpSize(BYTE const* const destination, size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) { - BYTE* const dst = *dp; + BYTE* const dst = *dp; BYTE* dstRW = *dp + writeableOffset; BYTE* dstRW2 = dstRW + 4; // addr for updating gc info if needed. const BYTE* const odstRW = dstRW; @@ -2912,6 +2914,69 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) return sz; } +bool emitter::emitDispBranchInstrType(unsigned opcode2) const +{ + switch (opcode2) + { + case 0: + printf("beq "); + break; + case 1: + printf("bne "); + break; + case 4: + printf("blt "); + break; + case 5: + printf("bge "); + break; + case 6: + printf("bltu"); + break; + case 7: + printf("bgeu"); + break; + default: + return false; + } + return true; +} + +bool emitter::emitDispBranch(unsigned opcode2, + const char* register1Name, + const char* register2Name, + const instrDesc* id) const +{ + if (!emitDispBranchInstrType(opcode2)) + { + return false; + } + printf(" %s, %s, ", register1Name, register2Name); + assert(id != nullptr); + if (id->idIsBound()) + { + if (id->idAddr()->iiaHasInstrCount()) + { + printf("%3d instr", id->idAddr()->iiaGetInstrCount()); + } + else + { + emitPrintLabel(id->idAddr()->iiaIGlabel); + } + } + else + { + printf("L_M%03u_", FMT_BB, emitComp->compMethodID, id->idAddr()->iiaBBlabel->bbNum); + } + printf("\n"); + return true; +} + +void emitter::emitDispIllegalInstruction(code_t instructionCode) +{ + printf("RISCV64 illegal instruction: 0x%08X\n", instructionCode); +} + /*****************************************************************************/ /*****************************************************************************/ @@ -3255,47 +3320,16 @@ void emitter::emitDispInsName(code_t code, const BYTE* addr, bool doffs, unsigne unsigned int opcode2 = (code >> 12) & 0x7; const char* rs1 = RegNames[(code >> 15) & 0x1f]; const char* rs2 = RegNames[(code >> 20) & 0x1f]; - int offset = (((code >> 31) & 0x1) << 12) | (((code >> 7) & 0x1) << 11) | (((code >> 25) & 0x3f) << 5) | - (((code >> 8) & 0xf) << 1); - if (offset & 0x800) + // int offset = (((code >> 31) & 0x1) << 12) | (((code >> 7) & 0x1) << 11) | (((code >> 25) & 0x3f) << 5) | + // (((code >> 8) & 0xf) << 1); + // if (offset & 0x800) + // { + // offset |= 0xfffff000; + // } + if (!emitDispBranch(opcode2, rs1, rs2, id)) { - offset |= 0xfffff000; + emitDispIllegalInstruction(code); } - switch (opcode2) - { - case 0: - printf("beq "); - break; - case 1: - printf("bne "); - break; - case 4: - printf("blt "); - break; - case 5: - printf("bge "); - break; - case 6: - printf("bltu"); - break; - case 7: - printf("bgeu"); - break; - default: - printf("RISCV64 illegal instruction: 0x%08X\n", code); - return; - } - static const int MAX_LEN = 32; - - int len = printf(" %s, %s, %d", rs1, rs2, offset); - if (len <= 0 || len > MAX_LEN) - { - printf("\n"); - return; - } - if (!emitComp->opts.disDiffable) - printf("%*s;; offset=0x%04X", MAX_LEN - len, "", emitCurCodeOffs(insAdr) + offset); - printf("\n"); return; } case 0x03: diff --git a/src/coreclr/jit/emitriscv64.h b/src/coreclr/jit/emitriscv64.h index 4cea72729c5099..96ae997ae1c3dd 100644 --- a/src/coreclr/jit/emitriscv64.h +++ b/src/coreclr/jit/emitriscv64.h @@ -61,8 +61,10 @@ bool emitInsIsStore(instruction ins); bool emitInsIsLoadOrStore(instruction ins); void emitDispInsName(code_t code, const BYTE* addr, bool doffs, unsigned insOffset, instrDesc* id); - void emitDispInsInstrNum(const instrDesc* id) const; +bool emitDispBranch(unsigned opcode2, const char* register1Name, const char* register2Name, const instrDesc* id) const; +bool emitDispBranchInstrType(unsigned opcode2) const; +void emitDispIllegalInstruction(code_t instructionCode); emitter::code_t emitInsCode(instruction ins /*, insFormat fmt*/); From b8893a0e0ebb2859942d07535f2e56c20bde7125 Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Wed, 13 Dec 2023 15:14:43 +0100 Subject: [PATCH 27/35] Removed dead code --- src/coreclr/jit/emitriscv64.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 4d2348fce34d74..99ea8f8058280d 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -2955,14 +2955,7 @@ bool emitter::emitDispBranch(unsigned opcode2, assert(id != nullptr); if (id->idIsBound()) { - if (id->idAddr()->iiaHasInstrCount()) - { - printf("%3d instr", id->idAddr()->iiaGetInstrCount()); - } - else - { - emitPrintLabel(id->idAddr()->iiaIGlabel); - } + emitPrintLabel(id->idAddr()->iiaIGlabel); } else { From 27dac367687fb7d8d7c626f5c82e3abab4eb236d Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Fri, 15 Dec 2023 09:27:26 +0100 Subject: [PATCH 28/35] Improved emitOutputInstrJumpSize --- src/coreclr/jit/emitriscv64.cpp | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 99ea8f8058280d..69a5c2e7520867 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -2124,14 +2124,29 @@ ssize_t emitter::emitOutputInstrJumpSize(BYTE const* const destination, insGroup const* const instructionGroup, instrDescJmp const* const jumpDescription) { - UNATIVE_OFFSET sourceOffset = emitCurCodeOffs(source); - BYTE const* sourceAddress = emitOffsetToPtr(sourceOffset); + UNATIVE_OFFSET sourceOffset = emitCurCodeOffs(source); + BYTE const* const sourceAddress = emitOffsetToPtr(sourceOffset); assert(!jumpDescription->idAddr()->iiaHasInstrCount()); // not used by riscv64 impl - UNATIVE_OFFSET distanceOffset = jumpDescription->idAddr()->iiaIGlabel->igOffs; - BYTE const* distanceAddress = emitOffsetToPtr(distanceOffset); - return static_cast(distanceAddress - sourceAddress); + UNATIVE_OFFSET destinationOffset = jumpDescription->idAddr()->iiaIGlabel->igOffs; + BYTE const* const destinationAddress = emitOffsetToPtr(destinationOffset); + ssize_t jumpSize = static_cast(destinationAddress - sourceAddress); + + if (destinationOffset <= sourceOffset) + { + if (!emitJumpCrossHotColdBoundary(sourceOffset, destinationOffset)) + { + jumpSize -= emitOffsAdj; + destinationOffset -= emitOffsAdj; + } + jumpDescription->idjOffs = destinationOffset; + if (jumpDescription->idjOffs != destinationOffset) + { + IMPL_LIMITATION("Method is too large"); + } + } + return jumpSize; } /***************************************************************************** From 8059994c8dd0f4c9bdba9caf345a78ed979a2793 Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Fri, 15 Dec 2023 09:31:06 +0100 Subject: [PATCH 29/35] Fixed bugs --- src/coreclr/jit/emitriscv64.cpp | 8 ++++---- src/coreclr/jit/emitriscv64.h | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 69a5c2e7520867..fca53155616d21 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -2119,10 +2119,10 @@ unsigned emitter::emitOutput_Instr(BYTE* dst, code_t code) return sizeof(code_t); } -ssize_t emitter::emitOutputInstrJumpSize(BYTE const* const destination, - BYTE const* const source, - insGroup const* const instructionGroup, - instrDescJmp const* const jumpDescription) +ssize_t emitter::emitOutputInstrJumpSize(BYTE const* destination, + BYTE const* source, + insGroup const* instructionGroup, + instrDescJmp* jumpDescription) { UNATIVE_OFFSET sourceOffset = emitCurCodeOffs(source); BYTE const* const sourceAddress = emitOffsetToPtr(sourceOffset); diff --git a/src/coreclr/jit/emitriscv64.h b/src/coreclr/jit/emitriscv64.h index 96ae997ae1c3dd..5bf6414da724a9 100644 --- a/src/coreclr/jit/emitriscv64.h +++ b/src/coreclr/jit/emitriscv64.h @@ -74,10 +74,10 @@ void emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataReg, GenTr // Emit the 32-bit RISCV64 instruction 'code' into the 'dst' buffer unsigned emitOutput_Instr(BYTE* dst, code_t code); -ssize_t emitOutputInstrJumpSize(BYTE const* const destination, - BYTE const* const source, - insGroup const* const instructionGroup, - instrDescJmp const* const jumpDescription); +ssize_t emitOutputInstrJumpSize(BYTE const* destination, + BYTE const* source, + insGroup const* instructionGroup, + instrDescJmp* jumpDescription); // Method to do check if mov is redundant with respect to the last instruction. // If yes, the caller of this method can choose to omit current mov instruction. From 7e8076be97529ccfbd8eda1c6f6a94f21a9e15bf Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Fri, 15 Dec 2023 09:56:56 +0100 Subject: [PATCH 30/35] Fixed bug in emitOutputInstrJumpSize --- src/coreclr/jit/emitriscv64.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index fca53155616d21..a1c02cd5cdeb77 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -2133,8 +2133,14 @@ ssize_t emitter::emitOutputInstrJumpSize(BYTE const* destination, BYTE const* const destinationAddress = emitOffsetToPtr(destinationOffset); ssize_t jumpSize = static_cast(destinationAddress - sourceAddress); - if (destinationOffset <= sourceOffset) + if (destinationOffset > sourceOffset) { + // This is a forward jump + + emitFwdJumps = true; + + // The target offset will be closer by at least 'emitOffsAdj', but only if this + // jump doesn't cross the hot-cold boundary. if (!emitJumpCrossHotColdBoundary(sourceOffset, destinationOffset)) { jumpSize -= emitOffsAdj; From 50fe2d443e762794e3aa5c73e68776dd08e21190 Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Fri, 15 Dec 2023 11:25:17 +0100 Subject: [PATCH 31/35] Added prelimary barch offset printing and reinforced some emitter methods --- src/coreclr/jit/emit.cpp | 8 +++--- src/coreclr/jit/emit.h | 10 ++++---- src/coreclr/jit/emitriscv64.cpp | 43 +++++++++++++++++++++++++++------ src/coreclr/jit/emitriscv64.h | 6 +++-- 4 files changed, 49 insertions(+), 18 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 4b467e5986e528..7f74ee6b5e7bd4 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -4328,7 +4328,7 @@ void emitter::emitDispJumpList() // id - the pointer to the current instrDesc // idSize - the size of the current instrDesc // -void emitter::emitAdvanceInstrDesc(instrDesc** id, size_t idSize) +void emitter::emitAdvanceInstrDesc(instrDesc** id, size_t idSize) const { assert(idSize == emitSizeOfInsDsc(*id)); char* idData = reinterpret_cast(*id); @@ -4346,7 +4346,7 @@ void emitter::emitAdvanceInstrDesc(instrDesc** id, size_t idSize) // Returns: // A pointer to the first instrDesc. // -emitter::instrDesc* emitter::emitFirstInstrDesc(BYTE* idData) +emitter::instrDesc* emitter::emitFirstInstrDesc(BYTE* idData) const { return reinterpret_cast(idData + m_debugInfoSize); } @@ -7664,7 +7664,7 @@ unsigned emitter::emitEndCodeGen(Compiler* comp, * instruction number for this instruction */ -unsigned emitter::emitFindInsNum(insGroup* ig, instrDesc* idMatch) +unsigned emitter::emitFindInsNum(insGroup* ig, instrDesc* idMatch) const { instrDesc* id = emitFirstInstrDesc(ig->igData); @@ -7700,7 +7700,7 @@ unsigned emitter::emitFindInsNum(insGroup* ig, instrDesc* idMatch) * to find the true offset by looking for the instruction within the group. */ -UNATIVE_OFFSET emitter::emitFindOffset(insGroup* ig, unsigned insNum) +UNATIVE_OFFSET emitter::emitFindOffset(insGroup* ig, unsigned insNum) const { instrDesc* id = emitFirstInstrDesc(ig->igData); UNATIVE_OFFSET of = 0; diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index 834a14a1811d98..d8aaf94d5d16fb 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -2202,8 +2202,8 @@ class emitter /* Methods to record a code position and later convert to offset */ /************************************************************************/ - unsigned emitFindInsNum(insGroup* ig, instrDesc* id); - UNATIVE_OFFSET emitFindOffset(insGroup* ig, unsigned insNum); + unsigned emitFindInsNum(insGroup* ig, instrDesc* id) const; + UNATIVE_OFFSET emitFindOffset(insGroup* ig, unsigned insNum) const; /************************************************************************/ /* Members and methods used to issue (encode) instructions. */ @@ -2241,7 +2241,7 @@ class emitter return (UNATIVE_OFFSET)distance; } - BYTE* emitOffsetToPtr(UNATIVE_OFFSET offset) + BYTE* emitOffsetToPtr(UNATIVE_OFFSET offset) const { if (offset < emitTotalHotCodeSize) { @@ -2297,8 +2297,8 @@ class emitter unsigned int emitCounts_INS_OPTS_J; #endif // TARGET_LOONGARCH64 || TARGET_RISCV64 - instrDesc* emitFirstInstrDesc(BYTE* idData); - void emitAdvanceInstrDesc(instrDesc** id, size_t idSize); + instrDesc* emitFirstInstrDesc(BYTE* idData) const; + void emitAdvanceInstrDesc(instrDesc** id, size_t idSize) const; size_t emitIssue1Instr(insGroup* ig, instrDesc* id, BYTE** dp); size_t emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp); diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index a1c02cd5cdeb77..d5612c3973446a 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -2963,10 +2963,37 @@ bool emitter::emitDispBranchInstrType(unsigned opcode2) const return true; } +void emitter::emitDispBranchOffset(instrDesc* id, insGroup* ig) const +{ + static const auto signFn = [](int offset) { return offset >= 0 ? "+" : ""; }; + + int instrCount = id->idAddr()->iiaGetInstrCount(); + if (ig == nullptr) + { + printf("pc%s%d instructions", signFn(instrCount), instrCount); + return; + } + unsigned insNum = emitFindInsNum(ig, id); + UNATIVE_OFFSET srcOffs = ig->igOffs + emitFindOffset(ig, insNum + 1); + UNATIVE_OFFSET dstOffs = ig->igOffs + emitFindOffset(ig, insNum + 1 + instrCount); + ssize_t relOffs = static_cast(emitOffsetToPtr(dstOffs) - emitOffsetToPtr(dstOffs)); + printf("pc%s%d (%d instructions)", signFn(relOffs), static_cast(relOffs), instrCount); +} + +void emitter::emitDispBranchLabel(const instrDesc* id) const +{ + if (id->idIsBound()) + { + return emitPrintLabel(id->idAddr()->iiaIGlabel); + } + printf("L_M%03u_", FMT_BB, emitComp->compMethodID, id->idAddr()->iiaBBlabel->bbNum); +} + bool emitter::emitDispBranch(unsigned opcode2, const char* register1Name, const char* register2Name, - const instrDesc* id) const + instrDesc* id, + insGroup* ig) const { if (!emitDispBranchInstrType(opcode2)) { @@ -2974,13 +3001,15 @@ bool emitter::emitDispBranch(unsigned opcode2, } printf(" %s, %s, ", register1Name, register2Name); assert(id != nullptr); - if (id->idIsBound()) + if (id->idAddr()->iiaHasInstrCount()) { - emitPrintLabel(id->idAddr()->iiaIGlabel); + // Branch is jumping to some non-labeled offset + emitDispBranchOffset(id, ig); } else { - printf("L_M%03u_", FMT_BB, emitComp->compMethodID, id->idAddr()->iiaBBlabel->bbNum); + // Branch is jumping to the labeled offset + emitDispBranchLabel(id); } printf("\n"); return true; @@ -3019,7 +3048,7 @@ static const char* const RegNames[] = // The length of the instruction's name include aligned space is 15. // -void emitter::emitDispInsName(code_t code, const BYTE* addr, bool doffs, unsigned insOffset, instrDesc* id) +void emitter::emitDispInsName(code_t code, const BYTE* addr, bool doffs, unsigned insOffset, instrDesc* id, insGroup* ig) { const BYTE* insAdr = addr - writeableOffset; @@ -3340,7 +3369,7 @@ void emitter::emitDispInsName(code_t code, const BYTE* addr, bool doffs, unsigne // { // offset |= 0xfffff000; // } - if (!emitDispBranch(opcode2, rs1, rs2, id)) + if (!emitDispBranch(opcode2, rs1, rs2, id, ig)) { emitDispIllegalInstruction(code); } @@ -3985,7 +4014,7 @@ void emitter::emitDispIns( instrSize = sizeof(code_t); code_t instruction; memcpy(&instruction, instr, instrSize); - emitDispInsName(instruction, instr, doffs, offset, id); + emitDispInsName(instruction, instr, doffs, offset, id, ig); } } diff --git a/src/coreclr/jit/emitriscv64.h b/src/coreclr/jit/emitriscv64.h index 5bf6414da724a9..38dc61de311a5c 100644 --- a/src/coreclr/jit/emitriscv64.h +++ b/src/coreclr/jit/emitriscv64.h @@ -60,9 +60,11 @@ bool emitInsIsLoad(instruction ins); bool emitInsIsStore(instruction ins); bool emitInsIsLoadOrStore(instruction ins); -void emitDispInsName(code_t code, const BYTE* addr, bool doffs, unsigned insOffset, instrDesc* id); +void emitDispInsName(code_t code, const BYTE* addr, bool doffs, unsigned insOffset, instrDesc* id, insGroup* ig); void emitDispInsInstrNum(const instrDesc* id) const; -bool emitDispBranch(unsigned opcode2, const char* register1Name, const char* register2Name, const instrDesc* id) const; +bool emitDispBranch(unsigned opcode2, const char* register1Name, const char* register2Name, instrDesc* id, insGroup* ig) const; +void emitDispBranchOffset(instrDesc* id, insGroup* ig) const; +void emitDispBranchLabel(const instrDesc* id) const; bool emitDispBranchInstrType(unsigned opcode2) const; void emitDispIllegalInstruction(code_t instructionCode); From e844c41a99e9a89301152445088f24534aca6b10 Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Fri, 15 Dec 2023 11:43:19 +0100 Subject: [PATCH 32/35] Further reinforced disp functions --- src/coreclr/jit/emit.cpp | 4 ++-- src/coreclr/jit/emit.h | 4 ++-- src/coreclr/jit/emitriscv64.cpp | 17 ++++++++--------- src/coreclr/jit/emitriscv64.h | 7 ++++--- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/coreclr/jit/emit.cpp b/src/coreclr/jit/emit.cpp index 7f74ee6b5e7bd4..4cc1d4e23ca96d 100644 --- a/src/coreclr/jit/emit.cpp +++ b/src/coreclr/jit/emit.cpp @@ -7664,7 +7664,7 @@ unsigned emitter::emitEndCodeGen(Compiler* comp, * instruction number for this instruction */ -unsigned emitter::emitFindInsNum(insGroup* ig, instrDesc* idMatch) const +unsigned emitter::emitFindInsNum(const insGroup* ig, const instrDesc* idMatch) const { instrDesc* id = emitFirstInstrDesc(ig->igData); @@ -7700,7 +7700,7 @@ unsigned emitter::emitFindInsNum(insGroup* ig, instrDesc* idMatch) const * to find the true offset by looking for the instruction within the group. */ -UNATIVE_OFFSET emitter::emitFindOffset(insGroup* ig, unsigned insNum) const +UNATIVE_OFFSET emitter::emitFindOffset(const insGroup* ig, unsigned insNum) const { instrDesc* id = emitFirstInstrDesc(ig->igData); UNATIVE_OFFSET of = 0; diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index d8aaf94d5d16fb..b79a748dbe9615 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -2202,8 +2202,8 @@ class emitter /* Methods to record a code position and later convert to offset */ /************************************************************************/ - unsigned emitFindInsNum(insGroup* ig, instrDesc* id) const; - UNATIVE_OFFSET emitFindOffset(insGroup* ig, unsigned insNum) const; + unsigned emitFindInsNum(const insGroup* ig, const instrDesc* id) const; + UNATIVE_OFFSET emitFindOffset(const insGroup* ig, unsigned insNum) const; /************************************************************************/ /* Members and methods used to issue (encode) instructions. */ diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index d5612c3973446a..4c2995d7ce3a5f 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -2963,7 +2963,7 @@ bool emitter::emitDispBranchInstrType(unsigned opcode2) const return true; } -void emitter::emitDispBranchOffset(instrDesc* id, insGroup* ig) const +void emitter::emitDispBranchOffset(const instrDesc* id, const insGroup* ig) const { static const auto signFn = [](int offset) { return offset >= 0 ? "+" : ""; }; @@ -2973,10 +2973,10 @@ void emitter::emitDispBranchOffset(instrDesc* id, insGroup* ig) const printf("pc%s%d instructions", signFn(instrCount), instrCount); return; } - unsigned insNum = emitFindInsNum(ig, id); + unsigned insNum = emitFindInsNum(ig, id); UNATIVE_OFFSET srcOffs = ig->igOffs + emitFindOffset(ig, insNum + 1); UNATIVE_OFFSET dstOffs = ig->igOffs + emitFindOffset(ig, insNum + 1 + instrCount); - ssize_t relOffs = static_cast(emitOffsetToPtr(dstOffs) - emitOffsetToPtr(dstOffs)); + ssize_t relOffs = static_cast(emitOffsetToPtr(dstOffs) - emitOffsetToPtr(dstOffs)); printf("pc%s%d (%d instructions)", signFn(relOffs), static_cast(relOffs), instrCount); } @@ -2989,11 +2989,8 @@ void emitter::emitDispBranchLabel(const instrDesc* id) const printf("L_M%03u_", FMT_BB, emitComp->compMethodID, id->idAddr()->iiaBBlabel->bbNum); } -bool emitter::emitDispBranch(unsigned opcode2, - const char* register1Name, - const char* register2Name, - instrDesc* id, - insGroup* ig) const +bool emitter::emitDispBranch( + unsigned opcode2, const char* register1Name, const char* register2Name, const instrDesc* id, const insGroup* ig) const { if (!emitDispBranchInstrType(opcode2)) { @@ -3043,12 +3040,14 @@ static const char* const RegNames[] = // doffs - Flag informing whether the instruction's offset should be displayed. // insOffset - The instruction's offset. // id - The instrDesc of the code if needed. +// ig - The insGroup of the code if needed // // Note: // The length of the instruction's name include aligned space is 15. // -void emitter::emitDispInsName(code_t code, const BYTE* addr, bool doffs, unsigned insOffset, instrDesc* id, insGroup* ig) +void emitter::emitDispInsName( + code_t code, const BYTE* addr, bool doffs, unsigned insOffset, const instrDesc* id, const insGroup* ig) { const BYTE* insAdr = addr - writeableOffset; diff --git a/src/coreclr/jit/emitriscv64.h b/src/coreclr/jit/emitriscv64.h index 38dc61de311a5c..4e81ca59725aec 100644 --- a/src/coreclr/jit/emitriscv64.h +++ b/src/coreclr/jit/emitriscv64.h @@ -60,10 +60,11 @@ bool emitInsIsLoad(instruction ins); bool emitInsIsStore(instruction ins); bool emitInsIsLoadOrStore(instruction ins); -void emitDispInsName(code_t code, const BYTE* addr, bool doffs, unsigned insOffset, instrDesc* id, insGroup* ig); +void emitDispInsName(code_t code, const BYTE* addr, bool doffs, unsigned insOffset, const instrDesc* id, const insGroup* ig); void emitDispInsInstrNum(const instrDesc* id) const; -bool emitDispBranch(unsigned opcode2, const char* register1Name, const char* register2Name, instrDesc* id, insGroup* ig) const; -void emitDispBranchOffset(instrDesc* id, insGroup* ig) const; +bool emitDispBranch( + unsigned opcode2, const char* register1Name, const char* register2Name, const instrDesc* id, const insGroup* ig) const; +void emitDispBranchOffset(const instrDesc* id, const insGroup* ig) const; void emitDispBranchLabel(const instrDesc* id) const; bool emitDispBranchInstrType(unsigned opcode2) const; void emitDispIllegalInstruction(code_t instructionCode); From 756a4827d28fa4bfdde51f97a9a22669ec83d45f Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Fri, 15 Dec 2023 12:19:14 +0100 Subject: [PATCH 33/35] Splitted emitOutputInstrJumpSize --- src/coreclr/jit/emit.h | 2 +- src/coreclr/jit/emitriscv64.cpp | 61 ++++++++++++++++++++++++--------- src/coreclr/jit/emitriscv64.h | 13 ++++--- 3 files changed, 54 insertions(+), 22 deletions(-) diff --git a/src/coreclr/jit/emit.h b/src/coreclr/jit/emit.h index b79a748dbe9615..87c57113a6513a 100644 --- a/src/coreclr/jit/emit.h +++ b/src/coreclr/jit/emit.h @@ -2222,7 +2222,7 @@ class emitter UNATIVE_OFFSET emitTotalHotCodeSize; UNATIVE_OFFSET emitTotalColdCodeSize; - UNATIVE_OFFSET emitCurCodeOffs(const BYTE* dst) + UNATIVE_OFFSET emitCurCodeOffs(const BYTE* dst) const { size_t distance; if ((dst >= emitCodeBlock) && (dst <= (emitCodeBlock + emitTotalHotCodeSize))) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 4c2995d7ce3a5f..8b1d685d0ea906 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -2119,21 +2119,48 @@ unsigned emitter::emitOutput_Instr(BYTE* dst, code_t code) return sizeof(code_t); } -ssize_t emitter::emitOutputInstrJumpSize(BYTE const* destination, - BYTE const* source, - insGroup const* instructionGroup, - instrDescJmp* jumpDescription) +void emitter::emitOutputInstrJumpSizeHelper( + const insGroup* ig, + instrDescJmp* jmp, + UNATIVE_OFFSET& dstOffs, + const BYTE*& dstAddr) const { - UNATIVE_OFFSET sourceOffset = emitCurCodeOffs(source); - BYTE const* const sourceAddress = emitOffsetToPtr(sourceOffset); + // bug + if (jmp->idAddr()->iiaHasInstrCount()) + { + assert(ig != nullptr); + int instrCount = jmp->idAddr()->iiaGetInstrCount(); + unsigned insNum = emitFindInsNum(ig, jmp); + if (instrCount < 0) + { + // Backward branches using instruction count must be within the same instruction group. + assert(insNum + 1 >= static_cast(-instrCount)); + } + dstOffs = ig->igOffs + emitFindOffset(ig, (insNum + 1 + instrCount)); + dstAddr = emitOffsetToPtr(dstOffs); + return; + } + dstOffs = jmp->idAddr()->iiaIGlabel->igOffs; + dstAddr = emitOffsetToPtr(dstOffs); +} + +ssize_t emitter::emitOutputInstrJumpSize(const BYTE* dst, + const BYTE* src, + const insGroup* ig, + instrDescJmp* jmp) +{ + UNATIVE_OFFSET srcOffs = emitCurCodeOffs(src); + const BYTE* srcAddr = emitOffsetToPtr(srcOffs); - assert(!jumpDescription->idAddr()->iiaHasInstrCount()); // not used by riscv64 impl + assert(!jmp->idAddr()->iiaIsJitDataOffset()); // not used by riscv64 impl - UNATIVE_OFFSET destinationOffset = jumpDescription->idAddr()->iiaIGlabel->igOffs; - BYTE const* const destinationAddress = emitOffsetToPtr(destinationOffset); - ssize_t jumpSize = static_cast(destinationAddress - sourceAddress); + UNATIVE_OFFSET dstOffs{}; + const BYTE* dstAddr = nullptr; + emitOutputInstrJumpSizeHelper(ig, jmp, dstOffs, dstAddr); +; + ssize_t distVal = static_cast(dstAddr - srcAddr); - if (destinationOffset > sourceOffset) + if (dstOffs > srcOffs) { // This is a forward jump @@ -2141,18 +2168,18 @@ ssize_t emitter::emitOutputInstrJumpSize(BYTE const* destination, // The target offset will be closer by at least 'emitOffsAdj', but only if this // jump doesn't cross the hot-cold boundary. - if (!emitJumpCrossHotColdBoundary(sourceOffset, destinationOffset)) + if (!emitJumpCrossHotColdBoundary(srcOffs, dstOffs)) { - jumpSize -= emitOffsAdj; - destinationOffset -= emitOffsAdj; + distVal -= emitOffsAdj; + dstOffs -= emitOffsAdj; } - jumpDescription->idjOffs = destinationOffset; - if (jumpDescription->idjOffs != destinationOffset) + jmp->idjOffs = dstOffs; + if (jmp->idjOffs != dstOffs) { IMPL_LIMITATION("Method is too large"); } } - return jumpSize; + return distVal; } /***************************************************************************** diff --git a/src/coreclr/jit/emitriscv64.h b/src/coreclr/jit/emitriscv64.h index 4e81ca59725aec..b991e4d4e35b3a 100644 --- a/src/coreclr/jit/emitriscv64.h +++ b/src/coreclr/jit/emitriscv64.h @@ -77,10 +77,15 @@ void emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataReg, GenTr // Emit the 32-bit RISCV64 instruction 'code' into the 'dst' buffer unsigned emitOutput_Instr(BYTE* dst, code_t code); -ssize_t emitOutputInstrJumpSize(BYTE const* destination, - BYTE const* source, - insGroup const* instructionGroup, - instrDescJmp* jumpDescription); +ssize_t emitOutputInstrJumpSize(const BYTE* dst, + const BYTE* src, + const insGroup* ig, + instrDescJmp* jmp); +void emitOutputInstrJumpSizeHelper( + const insGroup* ig, + instrDescJmp* jmp, + UNATIVE_OFFSET& dstOffs, + const BYTE*& dstAddr) const; // Method to do check if mov is redundant with respect to the last instruction. // If yes, the caller of this method can choose to omit current mov instruction. From 67f0f68de78e8e9b9b738849d846e3f4390e66c1 Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Fri, 15 Dec 2023 12:20:46 +0100 Subject: [PATCH 34/35] Formatted code --- src/coreclr/jit/emitriscv64.cpp | 37 ++++++++++++++++----------------- src/coreclr/jit/emitriscv64.h | 24 ++++++++++----------- 2 files changed, 30 insertions(+), 31 deletions(-) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 8b1d685d0ea906..9bb50605c291df 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -2119,18 +2119,17 @@ unsigned emitter::emitOutput_Instr(BYTE* dst, code_t code) return sizeof(code_t); } -void emitter::emitOutputInstrJumpSizeHelper( - const insGroup* ig, - instrDescJmp* jmp, - UNATIVE_OFFSET& dstOffs, - const BYTE*& dstAddr) const +void emitter::emitOutputInstrJumpSizeHelper(const insGroup* ig, + instrDescJmp* jmp, + UNATIVE_OFFSET& dstOffs, + const BYTE*& dstAddr) const { // bug if (jmp->idAddr()->iiaHasInstrCount()) { assert(ig != nullptr); - int instrCount = jmp->idAddr()->iiaGetInstrCount(); - unsigned insNum = emitFindInsNum(ig, jmp); + int instrCount = jmp->idAddr()->iiaGetInstrCount(); + unsigned insNum = emitFindInsNum(ig, jmp); if (instrCount < 0) { // Backward branches using instruction count must be within the same instruction group. @@ -2144,21 +2143,18 @@ void emitter::emitOutputInstrJumpSizeHelper( dstAddr = emitOffsetToPtr(dstOffs); } -ssize_t emitter::emitOutputInstrJumpSize(const BYTE* dst, - const BYTE* src, - const insGroup* ig, - instrDescJmp* jmp) +ssize_t emitter::emitOutputInstrJumpSize(const BYTE* dst, const BYTE* src, const insGroup* ig, instrDescJmp* jmp) { - UNATIVE_OFFSET srcOffs = emitCurCodeOffs(src); - const BYTE* srcAddr = emitOffsetToPtr(srcOffs); + UNATIVE_OFFSET srcOffs = emitCurCodeOffs(src); + const BYTE* srcAddr = emitOffsetToPtr(srcOffs); assert(!jmp->idAddr()->iiaIsJitDataOffset()); // not used by riscv64 impl - UNATIVE_OFFSET dstOffs{}; - const BYTE* dstAddr = nullptr; + UNATIVE_OFFSET dstOffs{}; + const BYTE* dstAddr = nullptr; emitOutputInstrJumpSizeHelper(ig, jmp, dstOffs, dstAddr); -; - ssize_t distVal = static_cast(dstAddr - srcAddr); + ; + ssize_t distVal = static_cast(dstAddr - srcAddr); if (dstOffs > srcOffs) { @@ -3016,8 +3012,11 @@ void emitter::emitDispBranchLabel(const instrDesc* id) const printf("L_M%03u_", FMT_BB, emitComp->compMethodID, id->idAddr()->iiaBBlabel->bbNum); } -bool emitter::emitDispBranch( - unsigned opcode2, const char* register1Name, const char* register2Name, const instrDesc* id, const insGroup* ig) const +bool emitter::emitDispBranch(unsigned opcode2, + const char* register1Name, + const char* register2Name, + const instrDesc* id, + const insGroup* ig) const { if (!emitDispBranchInstrType(opcode2)) { diff --git a/src/coreclr/jit/emitriscv64.h b/src/coreclr/jit/emitriscv64.h index b991e4d4e35b3a..a910ae3083e299 100644 --- a/src/coreclr/jit/emitriscv64.h +++ b/src/coreclr/jit/emitriscv64.h @@ -60,10 +60,14 @@ bool emitInsIsLoad(instruction ins); bool emitInsIsStore(instruction ins); bool emitInsIsLoadOrStore(instruction ins); -void emitDispInsName(code_t code, const BYTE* addr, bool doffs, unsigned insOffset, const instrDesc* id, const insGroup* ig); +void emitDispInsName( + code_t code, const BYTE* addr, bool doffs, unsigned insOffset, const instrDesc* id, const insGroup* ig); void emitDispInsInstrNum(const instrDesc* id) const; -bool emitDispBranch( - unsigned opcode2, const char* register1Name, const char* register2Name, const instrDesc* id, const insGroup* ig) const; +bool emitDispBranch(unsigned opcode2, + const char* register1Name, + const char* register2Name, + const instrDesc* id, + const insGroup* ig) const; void emitDispBranchOffset(const instrDesc* id, const insGroup* ig) const; void emitDispBranchLabel(const instrDesc* id) const; bool emitDispBranchInstrType(unsigned opcode2) const; @@ -77,15 +81,11 @@ void emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataReg, GenTr // Emit the 32-bit RISCV64 instruction 'code' into the 'dst' buffer unsigned emitOutput_Instr(BYTE* dst, code_t code); -ssize_t emitOutputInstrJumpSize(const BYTE* dst, - const BYTE* src, - const insGroup* ig, - instrDescJmp* jmp); -void emitOutputInstrJumpSizeHelper( - const insGroup* ig, - instrDescJmp* jmp, - UNATIVE_OFFSET& dstOffs, - const BYTE*& dstAddr) const; +ssize_t emitOutputInstrJumpSize(const BYTE* dst, const BYTE* src, const insGroup* ig, instrDescJmp* jmp); +void emitOutputInstrJumpSizeHelper(const insGroup* ig, + instrDescJmp* jmp, + UNATIVE_OFFSET& dstOffs, + const BYTE*& dstAddr) const; // Method to do check if mov is redundant with respect to the last instruction. // If yes, the caller of this method can choose to omit current mov instruction. From 769deb759e1ace6dbae30a8cfebf71ebeba8c7ab Mon Sep 17 00:00:00 2001 From: Grzegorz Czarnecki Date: Fri, 15 Dec 2023 12:43:47 +0100 Subject: [PATCH 35/35] Last fixes before pr --- src/coreclr/jit/emitriscv64.cpp | 23 ++++++++++++----------- src/coreclr/jit/emitriscv64.h | 12 ++++++------ 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/coreclr/jit/emitriscv64.cpp b/src/coreclr/jit/emitriscv64.cpp index 9bb50605c291df..5945cc61d73eb0 100644 --- a/src/coreclr/jit/emitriscv64.cpp +++ b/src/coreclr/jit/emitriscv64.cpp @@ -2119,12 +2119,13 @@ unsigned emitter::emitOutput_Instr(BYTE* dst, code_t code) return sizeof(code_t); } -void emitter::emitOutputInstrJumpSizeHelper(const insGroup* ig, - instrDescJmp* jmp, - UNATIVE_OFFSET& dstOffs, - const BYTE*& dstAddr) const +void emitter::emitOutputInstrJumpDistanceHelper(const insGroup* ig, + instrDescJmp* jmp, + UNATIVE_OFFSET& dstOffs, + const BYTE*& dstAddr) const { - // bug + // TODO-RISCV64-BUG: iiaEncodedInstrCount is not set by the riscv impl making distinguishing the jumps to label and + // an instruction-count based jumps impossible if (jmp->idAddr()->iiaHasInstrCount()) { assert(ig != nullptr); @@ -2143,7 +2144,7 @@ void emitter::emitOutputInstrJumpSizeHelper(const insGroup* ig, dstAddr = emitOffsetToPtr(dstOffs); } -ssize_t emitter::emitOutputInstrJumpSize(const BYTE* dst, const BYTE* src, const insGroup* ig, instrDescJmp* jmp) +ssize_t emitter::emitOutputInstrJumpDistance(const BYTE* dst, const BYTE* src, const insGroup* ig, instrDescJmp* jmp) { UNATIVE_OFFSET srcOffs = emitCurCodeOffs(src); const BYTE* srcAddr = emitOffsetToPtr(srcOffs); @@ -2152,8 +2153,8 @@ ssize_t emitter::emitOutputInstrJumpSize(const BYTE* dst, const BYTE* src, const UNATIVE_OFFSET dstOffs{}; const BYTE* dstAddr = nullptr; - emitOutputInstrJumpSizeHelper(ig, jmp, dstOffs, dstAddr); - ; + emitOutputInstrJumpDistanceHelper(ig, jmp, dstOffs, dstAddr); + ssize_t distVal = static_cast(dstAddr - srcAddr); if (dstOffs > srcOffs) @@ -2571,7 +2572,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) regNumber reg1 = id->idReg1(); { - ssize_t imm = emitOutputInstrJumpSize(dstRW, dst, ig, jmp); + ssize_t imm = emitOutputInstrJumpDistance(dstRW, dst, ig, jmp); imm -= 4; assert((imm & 0x3) == 0); @@ -2740,7 +2741,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) break; case INS_OPTS_J_cond: { - ssize_t imm = emitOutputInstrJumpSize(dstRW, dst, ig, static_cast(id)); + ssize_t imm = emitOutputInstrJumpDistance(dstRW, dst, ig, static_cast(id)); assert(isValidSimm13(imm)); assert(!(imm & 1)); @@ -2761,7 +2762,7 @@ size_t emitter::emitOutputInstr(insGroup* ig, instrDesc* id, BYTE** dp) case INS_OPTS_J: // jal/j/jalr/bnez/beqz/beq/bne/blt/bge/bltu/bgeu dstRW-relative. { - ssize_t imm = emitOutputInstrJumpSize(dstRW, dst, ig, static_cast(id)); + ssize_t imm = emitOutputInstrJumpDistance(dstRW, dst, ig, static_cast(id)); assert((imm & 3) == 0); ins = id->idIns(); diff --git a/src/coreclr/jit/emitriscv64.h b/src/coreclr/jit/emitriscv64.h index a910ae3083e299..d3b00b2d104356 100644 --- a/src/coreclr/jit/emitriscv64.h +++ b/src/coreclr/jit/emitriscv64.h @@ -78,14 +78,14 @@ emitter::code_t emitInsCode(instruction ins /*, insFormat fmt*/); // Generate code for a load or store operation and handle the case of contained GT_LEA op1 with [base + offset] void emitInsLoadStoreOp(instruction ins, emitAttr attr, regNumber dataReg, GenTreeIndir* indir); -// Emit the 32-bit RISCV64 instruction 'code' into the 'dst' buffer +// Emit the 32-bit RISCV64 instruction 'code' into the 'dst' buffer unsigned emitOutput_Instr(BYTE* dst, code_t code); -ssize_t emitOutputInstrJumpSize(const BYTE* dst, const BYTE* src, const insGroup* ig, instrDescJmp* jmp); -void emitOutputInstrJumpSizeHelper(const insGroup* ig, - instrDescJmp* jmp, - UNATIVE_OFFSET& dstOffs, - const BYTE*& dstAddr) const; +ssize_t emitOutputInstrJumpDistance(const BYTE* dst, const BYTE* src, const insGroup* ig, instrDescJmp* jmp); +void emitOutputInstrJumpDistanceHelper(const insGroup* ig, + instrDescJmp* jmp, + UNATIVE_OFFSET& dstOffs, + const BYTE*& dstAddr) const; // Method to do check if mov is redundant with respect to the last instruction. // If yes, the caller of this method can choose to omit current mov instruction.