From 24a076ea4acd186d3741e55c34de4ef3bac16ee9 Mon Sep 17 00:00:00 2001 From: WuXinlong <821408745@qq.com> Date: Mon, 20 Mar 2023 18:43:33 +0800 Subject: [PATCH 01/20] update makefile --- src/mono/sample/TestRun/Makefile | 47 ++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 src/mono/sample/TestRun/Makefile diff --git a/src/mono/sample/TestRun/Makefile b/src/mono/sample/TestRun/Makefile new file mode 100644 index 00000000000000..3fa8c7e0f82073 --- /dev/null +++ b/src/mono/sample/TestRun/Makefile @@ -0,0 +1,47 @@ +TOP=../../../../ +DOTNET:=$(TOP)dotnet.sh +DOTNET_Q_ARGS=--nologo -v:q -consoleloggerparameters:NoSummary + +MONO_CONFIG?=Debug +MONO_ARCH=riscv64 +TARGET_OS=linux +AOT?=false + +#NET_TRACE_PATH= +#PGO_BINARY_PATH= +#MIBC_PROFILE_PATH= + +MONO_ENV_DEBUG_OPTIONS = "--trace=all" +MONO_ENV_RUN_OPTIONS = "" + +build: TestRun.cs + @csc TestRun.cs + +run-baseline: build + COMPlus_DebugWriteToStdErr=1 \ + MONO_ENV_OPTIONS=$(MONO_ENV_RUN_OPTIONS) \ + $(TOP)artifacts/bin/testhost/net8.0-$(TARGET_OS)-Debug-x64/dotnet TestRun.exe + +run: build + @COMPlus_DebugWriteToStdErr=1 \ + MONO_ENV_OPTIONS=$(MONO_ENV_RUN_OPTIONS) \ + qemu-riscv64 -L $(TOP)/.tools/rootfs/riscv64/ $(TOP)artifacts/bin/testhost/net8.0-$(TARGET_OS)-Debug-$(MONO_ARCH)/dotnet TestRun.exe + +debug: build + COMPlus_DebugWriteToStdErr=1 \ + MONO_LOG_LEVEL=debug MONO_LOG_MASK=all \ + COREHOST_TRACE=1 COREHOST_TRACE_VERBOSITY=4 \ + MONO_ENV_OPTIONS=$(MONO_ENV_DEBUG_OPTIONS) \ + qemu-riscv64 -L $(TOP)/.tools/rootfs/riscv64/ \ + -g 12345 \ + $(TOP)artifacts/bin/testhost/net8.0-$(TARGET_OS)-Debug-$(MONO_ARCH)/dotnet TestRun.exe &\ + riscv64-unknown-linux-gnu-gdb -ex 'target remote localhost:12345' \ + -ex "set sysroot $(TOP).tools/rootfs/riscv64" -ex "set solib-search-path $(TOP)artifacts/bin/testhost/net8.0-linux-Debug-riscv64/shared/Microsoft.NETCore.App/8.0.0" \ + -ex "b mono_trace_enter_method " \ + $(TOP)artifacts/bin/testhost/net8.0-$(TARGET_OS)-Debug-$(MONO_ARCH)/dotnet + +clean: + rm -f *.exe *.exe.mdb + + +# COMPlus_DebugWriteToStdErr="1" MONO_LOG_LEVEL="debug" MONO_LOG_MASK="all" COREHOST_TRACE="1" COREHOST_TRACE_VERBOSITY="4" MONO_ENV_OPTIONS="--compile-all --trace=all" qemu-riscv64 -L ../../../..//.tools/rootfs/riscv64/ -g 12345 ../../../../artifacts/bin/testhost/net8.0-Linux-Debug-riscv64/dotnet TestRun.exe \ No newline at end of file From 563fb829e71817ea1c02dbccb605a3d7583018cc Mon Sep 17 00:00:00 2001 From: WuXinlong <821408745@qq.com> Date: Mon, 3 Apr 2023 17:53:47 +0800 Subject: [PATCH 02/20] add format file --- src/mono/.clang-format | 83 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 src/mono/.clang-format diff --git a/src/mono/.clang-format b/src/mono/.clang-format new file mode 100644 index 00000000000000..fa2c3737dccb79 --- /dev/null +++ b/src/mono/.clang-format @@ -0,0 +1,83 @@ +--- +Language: Cpp +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignConsecutiveMacros: + Enabled: true +AlignEscapedNewlinesLeft: false +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: false +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterReturnType : AllDefinitions +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: true +BinPackArguments: true +BinPackParameters: false +BraceWrapping: + AfterClass: true + AfterControlStatement: true + AfterEnum: false + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: true + AfterUnion: true + BeforeCatch: true + BeforeElse: true + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Linux +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: true +ColumnLimit: 120 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +ForEachMacros: [ ] +IndentCaseLabels: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 400 +PenaltyBreakComment: 50 +PenaltyBreakFirstLessLess: 500 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 100000 +PointerAlignment: Right +ReflowComments: true +SortIncludes: false +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: Always +SpaceBeforeSquareBrackets: true +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 4 +UseTab: ForIndentation +... From cfa721eb0cbcdb1750ad2502b949d8e330f843d6 Mon Sep 17 00:00:00 2001 From: WuXinlong <821408745@qq.com> Date: Tue, 4 Apr 2023 15:50:20 +0800 Subject: [PATCH 03/20] use mul inst instead of emulate mul process stack size larger than imm32 --- src/mono/mono/arch/riscv/riscv-codegen.h | 2 +- src/mono/mono/mini/cpu-riscv64.mdesc | 27 ++++--- src/mono/mono/mini/mini-riscv.c | 97 ++++++++++++++++++++---- src/mono/mono/mini/mini-riscv.h | 4 +- 4 files changed, 100 insertions(+), 30 deletions(-) diff --git a/src/mono/mono/arch/riscv/riscv-codegen.h b/src/mono/mono/arch/riscv/riscv-codegen.h index 4abff4075c1a6b..da532188a47ac3 100644 --- a/src/mono/mono/arch/riscv/riscv-codegen.h +++ b/src/mono/mono/arch/riscv/riscv-codegen.h @@ -293,7 +293,7 @@ enum { (RISCV_BITS ((ins), 12, 8) << 12) | (RISCV_SIGN ((ins)) << 20)) // Check a value for validity as an immediate. -#define RISCV_VALID_IMM(value) \ +#define RISCV_VALID_IMM32(value) \ (((gint32)value) == (value)) #define RISCV_VALID_I_IMM(value) \ (RISCV_DECODE_I_IMM (RISCV_ENCODE_I_IMM ((value))) == (value)) diff --git a/src/mono/mono/mini/cpu-riscv64.mdesc b/src/mono/mono/mini/cpu-riscv64.mdesc index 7a7a261459f401..2a4caf1465ec7c 100644 --- a/src/mono/mono/mini/cpu-riscv64.mdesc +++ b/src/mono/mono/mini/cpu-riscv64.mdesc @@ -65,22 +65,22 @@ fcall: dest:f len:8 clob:c lcall: dest:a len:16 clob:c lcall_membase: dest:a src1:b len:8 clob:c -store_membase_reg: dest:b src1:i len:4 -storei1_membase_reg: dest:b src1:i len:4 -storei2_membase_reg: dest:b src1:i len:4 -storei4_membase_reg: dest:b src1:i len:4 -storei8_membase_reg: dest:b src1:i len:4 +store_membase_reg: dest:b src1:i len:24 +storei1_membase_reg: dest:b src1:i len:24 +storei2_membase_reg: dest:b src1:i len:24 +storei4_membase_reg: dest:b src1:i len:24 +storei8_membase_reg: dest:b src1:i len:24 storer4_membase_reg: dest:b src1:f len:4 storer8_membase_reg: dest:b src1:f len:4 load_membase: dest:i src1:b len:24 -loadu1_membase: dest:i src1:b len:16 -loadi1_membase: dest:i src1:b len:16 -loadu2_membase: dest:i src1:b len:16 -loadi2_membase: dest:i src1:b len:16 -loadu4_membase: dest:i src1:b len:16 -loadi4_membase: dest:i src1:b len:16 -loadi8_membase: dest:i src1:b len:16 +loadu1_membase: dest:i src1:b len:24 +loadi1_membase: dest:i src1:b len:24 +loadu2_membase: dest:i src1:b len:24 +loadi2_membase: dest:i src1:b len:24 +loadu4_membase: dest:i src1:b len:24 +loadi4_membase: dest:i src1:b len:24 +loadi8_membase: dest:i src1:b len:24 loadr4_membase: dest:f src1:b len:16 loadr8_membase: dest:f src1:b len:16 @@ -110,10 +110,13 @@ int_sub: dest:i src1:i src2:i len:4 long_sub: dest:i src1:i src2:i len:4 int_mul: dest:i src1:i src2:i len:4 r4_mul: dest:f src1:f src2:f len:4 +long_mul: dest:i src1:i src2:i len:4 float_mul: dest:f src1:f src2:f len:4 long_div: dest:i src1:i src2:i len:32 +int_div_un: dest:i src1:i src2:i len:32 long_div_un: dest:i src1:i src2:i len:32 r4_div: dest:f src1:f src2:f len:36 +float_div: dest:f src1:f src2:f len:4 int_rem: dest:i src1:i src2:i len:32 long_rem: dest:i src1:i src2:i len:32 int_rem_un: dest:i src1:i src2:i len:32 diff --git a/src/mono/mono/mini/mini-riscv.c b/src/mono/mono/mini/mini-riscv.c index 2b4dcaa1c54f40..00c01bcc37a231 100644 --- a/src/mono/mono/mini/mini-riscv.c +++ b/src/mono/mono/mini/mini-riscv.c @@ -1704,14 +1704,18 @@ mono_arch_decompose_opts (MonoCompile *cfg, MonoInst *ins) case OP_LMUL: case OP_RMUL: case OP_FMUL: + case OP_IMUL_IMM: case OP_LMUL_IMM: case OP_IDIV: case OP_LDIV: case OP_LDIV_UN: case OP_IDIV_UN: + case OP_IDIV_IMM: + case OP_IDIV_UN_IMM: case OP_RDIV: case OP_IREM: case OP_LREM: + case OP_IREM_IMM: case OP_IREM_UN: case OP_LREM_UN: @@ -1983,9 +1987,13 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) case OP_LSUB: case OP_IADD: case OP_LADD: + case OP_IMUL: + case OP_LMUL: case OP_RMUL: case OP_FMUL: + case OP_FDIV: case OP_LDIV: + case OP_IDIV_UN: case OP_LDIV_UN: case OP_RDIV: case OP_IREM: @@ -2240,11 +2248,38 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) case OP_STOREI8_MEMBASE_REG: #endif case OP_STORER8_MEMBASE_REG: - case OP_STORE_MEMBASE_REG: + case OP_STORE_MEMBASE_REG: { + if (ins->opcode == OP_STORER4_MEMBASE_REG && !cfg->r4fp) { + NEW_INS_BEFORE (cfg, ins, temp, OP_FCONV_TO_R4); + temp->dreg = mono_alloc_freg (cfg); + temp->sreg1 = ins->sreg1; + + ins->sreg1 = temp->dreg; + } // check if offset is valid I-type Imm - if (!RISCV_VALID_I_IMM ((gint32)(gssize)(ins->inst_offset))) - NOT_IMPLEMENTED; + if (!RISCV_VALID_I_IMM ((gint32)(gssize)(ins->inst_offset))) { + g_assert (ins->opcode != OP_STORER4_MEMBASE_REG); + + /** + * iconst t0, offset + * add t0, rd, t0 + * store rs1, 0(t0) + */ + int offset_reg = mono_alloc_ireg (cfg); + NEW_INS_BEFORE (cfg, ins, temp, OP_ICONST); + temp->dreg = offset_reg; + temp->inst_c0 = ins->inst_offset; + + NEW_INS_BEFORE (cfg, ins, temp, OP_IADD); + temp->dreg = offset_reg; + temp->sreg1 = ins->inst_destbasereg; + temp->sreg2 = offset_reg; + + ins->inst_offset = 0; + ins->inst_destbasereg = offset_reg; + } break; + } // Inst L{B|H|W|D} use I-type Imm case OP_LOADI1_MEMBASE: @@ -2505,8 +2540,9 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) case OP_ADD_IMM: case OP_IADD_IMM: case OP_LADD_IMM: - if (!RISCV_VALID_I_IMM ((gint32)(gssize)(ins->inst_imm))) + if (!RISCV_VALID_I_IMM ((gint32)(gssize)(ins->inst_imm))) { mono_decompose_op_imm (cfg, bb, ins); + } break; case OP_ADDCC: case OP_IADDCC: { @@ -2544,6 +2580,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) break; } case OP_MUL_IMM: + case OP_IMUL_IMM: { g_assert (riscv_stdext_m); NEW_INS_BEFORE (cfg, ins, temp, OP_ICONST); temp->inst_c0 = ins->inst_imm; @@ -2552,6 +2589,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) ins->inst_imm = 0; ins->opcode = OP_IMUL; break; + } case OP_IREM_IMM: case OP_LREM_UN_IMM: mono_decompose_op_imm (cfg, bb, ins); @@ -2633,7 +2671,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) break; } #endif - default: + case default: printf ("unable to lowering following IR:"); mono_print_ins (ins); NOT_IMPLEMENTED; @@ -2679,7 +2717,7 @@ mono_riscv_emit_imm (guint8 *code, int rd, gsize imm) * LUI: High 20 bit of imm * ADDIW: Low 12 bit of imm */ - if (RISCV_VALID_IMM (imm)) { + if (RISCV_VALID_IMM32 (imm)) { gint32 Hi = RISCV_BITS (imm, 12, 20); gint32 Lo = RISCV_BITS (imm, 0, 12); @@ -3268,17 +3306,35 @@ mono_arch_emit_prolog (MonoCompile *cfg) // save s0(fp) value stack_size += sizeof (target_mgreg_t); code = mono_riscv_emit_store (code, RISCV_FP, RISCV_SP, cfg->stack_offset - stack_size, 0); - } else - NOT_IMPLEMENTED; + + // set s0(fp) value + riscv_addi (code, RISCV_FP, RISCV_SP, cfg->stack_offset); + } else { + // save current FP into T0 + riscv_addi (code, RISCV_T0, RISCV_FP, 0); + + // FP = SP + riscv_addi (code, RISCV_FP, RISCV_SP, 0); + + // save return value + stack_size += sizeof (target_mgreg_t); + code = mono_riscv_emit_store (code, RISCV_RA, RISCV_FP, -stack_size, 0); + + // save fp value, here is T0 + stack_size += sizeof (target_mgreg_t); + code = mono_riscv_emit_store (code, RISCV_T0, RISCV_FP, stack_size, 0); + + // save stack size into T0 + code = mono_riscv_emit_imm (code, RISCV_T0, cfg->stack_offset); + // calculate SP + riscv_sub (code, RISCV_SP, RISCV_SP, RISCV_T0); + } cfa_offset += cfg->stack_offset; mono_emit_unwind_op_def_cfa_offset (cfg, code, cfa_offset); mono_emit_unwind_op_offset (cfg, code, RISCV_RA, cfa_offset - sizeof (target_mgreg_t)); mono_emit_unwind_op_offset (cfg, code, RISCV_FP, cfa_offset - (sizeof (target_mgreg_t) * 2)); - // set s0(fp) value - riscv_addi (code, RISCV_FP, RISCV_SP, cfg->stack_offset); - // save other registers if (cfg->param_area) /* The param area is below the stack pointer */ @@ -3616,19 +3672,19 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) break; #endif case OP_STORE_MEMBASE_REG: - code = mono_riscv_emit_store (code, ins->sreg1, ins->dreg, ins->inst_offset, 0); + code = mono_riscv_emit_store (code, ins->sreg1, ins->inst_destbasereg, ins->inst_offset, 0); break; case OP_STOREI1_MEMBASE_REG: - code = mono_riscv_emit_store (code, ins->sreg1, ins->dreg, ins->inst_offset, 1); + code = mono_riscv_emit_store (code, ins->sreg1, ins->inst_destbasereg, ins->inst_offset, 1); break; case OP_STOREI2_MEMBASE_REG: - code = mono_riscv_emit_store (code, ins->sreg1, ins->dreg, ins->inst_offset, 2); + code = mono_riscv_emit_store (code, ins->sreg1, ins->inst_destbasereg, ins->inst_offset, 2); break; case OP_STOREI4_MEMBASE_REG: - code = mono_riscv_emit_store (code, ins->sreg1, ins->dreg, ins->inst_offset, 4); + code = mono_riscv_emit_store (code, ins->sreg1, ins->inst_destbasereg, ins->inst_offset, 4); break; case OP_STOREI8_MEMBASE_REG: - code = mono_riscv_emit_store (code, ins->sreg1, ins->dreg, ins->inst_offset, 8); + code = mono_riscv_emit_store (code, ins->sreg1, ins->inst_destbasereg, ins->inst_offset, 8); break; case OP_ICONST: case OP_I8CONST: @@ -3648,6 +3704,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) riscv_sub (code, ins->dreg, ins->sreg1, ins->sreg2); break; case OP_IMUL: + case OP_LMUL: g_assert (riscv_stdext_m); riscv_mul (code, ins->dreg, ins->sreg1, ins->sreg2); break; @@ -3662,12 +3719,20 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) else NOT_IMPLEMENTED; break; + case OP_FDIV: + g_assert (riscv_stdext_f || riscv_stdext_d); + if (riscv_stdext_d) + riscv_fdiv_d (code, RISCV_ROUND_DY, ins->dreg, ins->sreg1, ins->sreg2); + else + riscv_fdiv_d (code, RISCV_ROUND_DY, ins->dreg, ins->sreg1, ins->sreg2); + break; case OP_LDIV: g_assert (riscv_stdext_m); code = mono_riscv_emit_branch_exc (cfg, code, OP_RISCV_EXC_BEQ, ins->sreg2, RISCV_ZERO, "DivideByZeroException"); riscv_div (code, ins->dreg, ins->sreg1, ins->sreg2); break; + case OP_IDIV_UN: case OP_LDIV_UN: g_assert (riscv_stdext_m); code = mono_riscv_emit_branch_exc (cfg, code, OP_RISCV_EXC_BEQ, ins->sreg2, RISCV_ZERO, diff --git a/src/mono/mono/mini/mini-riscv.h b/src/mono/mono/mini/mini-riscv.h index d01227dd01ee7a..e74efc097f8ebe 100644 --- a/src/mono/mono/mini/mini-riscv.h +++ b/src/mono/mono/mini/mini-riscv.h @@ -121,7 +121,9 @@ extern gboolean riscv_stdext_a, riscv_stdext_b, riscv_stdext_c, riscv_stdext_d, #define MONO_ARCH_CODE_ALIGNMENT (32) // TODO: remove following def -#define MONO_ARCH_EMULATE_MUL_DIV (1) +#define MONO_ARCH_EMULATE_MUL_OVF (1) +#define MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS (1) +#define MONO_ARCH_EMULATE_LONG_MUL_OVF_OPTS (1) #define MONO_ARCH_EMULATE_FREM (1) #ifdef TARGET_RISCV64 From 16bb00a1c747ece462e812e187fe9c7b9da78757 Mon Sep 17 00:00:00 2001 From: WuXinlong <821408745@qq.com> Date: Wed, 5 Apr 2023 12:13:57 +0800 Subject: [PATCH 04/20] emit get_throw_trampoline --- src/mono/mono/metadata/jit-icall-reg.h | 1 + src/mono/mono/mini/exceptions-riscv.c | 110 ++++++++++++++++++++++++- src/mono/mono/mini/mini-riscv.c | 12 +-- src/mono/mono/mini/mini-riscv.h | 3 + 4 files changed, 118 insertions(+), 8 deletions(-) diff --git a/src/mono/mono/metadata/jit-icall-reg.h b/src/mono/mono/metadata/jit-icall-reg.h index 984c26721eec57..53bea08c538479 100644 --- a/src/mono/mono/metadata/jit-icall-reg.h +++ b/src/mono/mono/metadata/jit-icall-reg.h @@ -340,6 +340,7 @@ MONO_JIT_ICALL (ves_icall_thread_finish_async_abort) \ MONO_JIT_ICALL (mono_marshal_lookup_pinvoke) \ MONO_JIT_ICALL (mono_gsharedvt_constrained_call_fast) \ MONO_JIT_ICALL (mono_dummy_runtime_init_callback) \ +MONO_JIT_ICALL (mono_riscv_throw_exception) \ \ MONO_JIT_ICALL (count) \ diff --git a/src/mono/mono/mini/exceptions-riscv.c b/src/mono/mono/mini/exceptions-riscv.c index 18b3f08798e1b2..f645dc174d933f 100644 --- a/src/mono/mono/mini/exceptions-riscv.c +++ b/src/mono/mono/mini/exceptions-riscv.c @@ -67,6 +67,12 @@ mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot) return start; } +void +mono_riscv_throw_exception (MonoObject *exc, host_mgreg_t pc, host_mgreg_t sp, host_mgreg_t *int_regs, gdouble *fp_regs, gboolean preserve_ips){ + printf("mono_riscv_throw_exception\n"); + NOT_IMPLEMENTED; +} + gpointer mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) { @@ -74,11 +80,111 @@ mono_arch_get_call_filter (MonoTrampInfo **info, gboolean aot) return nop_stub (0x37); } +static gpointer +get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm, gboolean resume_unwind, const char *tramp_name, MonoTrampInfo **info, gboolean aot, gboolean preserve_ips){ + guint8 *start, *code; + MonoJumpInfo *ji = NULL; + GSList *unwind_ops = NULL; + int i, offset, gregs_offset, fregs_offset, frame_size, num_fregs; + + code = start = mono_global_codeman_reserve (size); + + /* This will being called by JITted code, the exception object/type token is in A0 */ + + /* Compute stack frame size and offsets */ + offset = 0; + /* ra & fp */ + offset += 2 * sizeof(host_mgreg_t); + + /* gregs */ + offset += RISCV_N_GREGS * sizeof(host_mgreg_t); + gregs_offset = offset; + + /* fregs */ + num_fregs = RISCV_N_FREGS; + offset += num_fregs * sizeof(host_mgreg_t); + fregs_offset = offset; + frame_size = ALIGN_TO (offset, MONO_ARCH_FRAME_ALIGNMENT); + + MINI_BEGIN_CODEGEN (); + + /* Setup a frame */ + g_assert(RISCV_VALID_I_IMM(-frame_size)); + riscv_addi (code, RISCV_SP, RISCV_SP, -frame_size); + code = mono_riscv_emit_store (code, RISCV_RA, RISCV_SP, frame_size - sizeof(host_mgreg_t), 0); + code = mono_riscv_emit_store (code, RISCV_FP, RISCV_SP, frame_size - 2 * sizeof(host_mgreg_t), 0); + riscv_addi (code, RISCV_FP, RISCV_SP, frame_size); + + /* Save gregs */ + code = emit_store_stack (code, 0xffffffff, RISCV_FP, -gregs_offset, FALSE); + if (corlib && !llvm) + NOT_IMPLEMENTED; + + /* Save previous fp/sp */ + code = mono_riscv_emit_load (code, RISCV_T0, RISCV_FP, -2 * sizeof(host_mgreg_t), 0); + code = mono_riscv_emit_store (code, RISCV_T0, RISCV_FP, -gregs_offset + (RISCV_FP * sizeof(host_mgreg_t)), 0); + // current fp is previous sp + code = mono_riscv_emit_store (code, RISCV_FP, RISCV_FP, -gregs_offset + (RISCV_SP * sizeof(host_mgreg_t)), 0); + + /* Save fregs */ + if (riscv_stdext_f || riscv_stdext_d) + code = emit_store_stack (code, 0xffffffff, RISCV_FP, -fregs_offset, TRUE); + + /* Call the C trampoline function */ + /* Arg1 = exception object/type token */ + // riscv_addi (code, RISCV_A0, RISCV_A0, 0); + /* Arg2 = caller ip, should be return address in this case */ + if (corlib) + NOT_IMPLEMENTED; + else + code = mono_riscv_emit_load (code, RISCV_A1, RISCV_FP, -sizeof(host_mgreg_t), 0); + /* Arg 3 = gregs */ + riscv_addi (code, RISCV_A2, RISCV_FP, -gregs_offset); + /* Arg 4 = fregs */ + riscv_addi (code, RISCV_A3, RISCV_FP, -fregs_offset); + /* Arg 5 = corlib */ + riscv_addi (code, RISCV_A4, RISCV_ZERO, corlib ? 1 : 0); + /* Arg 6 = rethrow */ + riscv_addi (code, RISCV_A5, RISCV_ZERO, rethrow ? 1 : 0); + if (!resume_unwind) { + /* Arg 7 = preserve_ips */ + riscv_addi (code, RISCV_A6, RISCV_ZERO, preserve_ips ? 1 : 0); + } + + /* Call the function */ + if (aot) { + NOT_IMPLEMENTED; + } + else { + gpointer icall_func; + + if (resume_unwind) + // icall_func = (gpointer)mono_riscv_resume_unwind; + NOT_IMPLEMENTED; + else + icall_func = (gpointer)mono_riscv_throw_exception; + + code = mono_riscv_emit_imm (code, RISCV_RA, (guint64)icall_func); + } + riscv_jalr(code, RISCV_ZERO, RISCV_RA, 0); + /* This shouldn't return */ + /* hang in debugger */ + riscv_ebreak (code); + + g_assert ((code - start) < size); + MINI_END_CODEGEN (start, code - start, MONO_PROFILER_CODE_BUFFER_EXCEPTION_HANDLING, NULL); + + if (info) + *info = mono_tramp_info_create (tramp_name, start, code - start, ji, unwind_ops); + + return MINI_ADDR_TO_FTNPTR (start); + +} + gpointer mono_arch_get_throw_exception (MonoTrampInfo **info, gboolean aot) { - *info = NULL; - return nop_stub (0x77); + return get_throw_trampoline (384, FALSE, FALSE, FALSE, FALSE, "throw_exception", info, aot, FALSE); } gpointer diff --git a/src/mono/mono/mini/mini-riscv.c b/src/mono/mono/mini/mini-riscv.c index 00c01bcc37a231..c5e8ee9d609759 100644 --- a/src/mono/mono/mini/mini-riscv.c +++ b/src/mono/mono/mini/mini-riscv.c @@ -2976,10 +2976,8 @@ mono_riscv_emit_store_regarray (guint8 *code, guint64 regs, int basereg, int off for (int i = 0; i < 32; ++i) { if (regs & (1 << i)) { - if (!isFloat && i == RISCV_SP) - g_assert_not_reached (); - if (isFloat) - code = mono_riscv_emit_fstore (code, i, basereg, offset + (i * sizeof (host_mgreg_t)), FALSE); + if(isFloat) + code = mono_riscv_emit_fstore (code, i, basereg, offset + (i * sizeof(host_mgreg_t)), FALSE); else code = mono_riscv_emit_store (code, i, basereg, offset + (i * sizeof (host_mgreg_t)), 0); } @@ -3009,8 +3007,10 @@ mono_riscv_emit_load_stack (guint8 *code, guint64 regs, int basereg, int offset, for (int i = 0; i < 32; ++i) { if (regs & (1 << i)) { - if (isFloat) - code = mono_riscv_emit_fload (code, i, basereg, (offset + (pos * sizeof (host_mgreg_t))), FALSE); + if(!isFloat && i == RISCV_SP) + g_assert_not_reached (); + if(isFloat) + code = mono_riscv_emit_fload (code, i, basereg, (offset + (pos * sizeof(host_mgreg_t))), FALSE); else code = mono_riscv_emit_load (code, i, basereg, (offset + (pos * sizeof (host_mgreg_t))), 0); pos++; diff --git a/src/mono/mono/mini/mini-riscv.h b/src/mono/mono/mini/mini-riscv.h index e74efc097f8ebe..32914d93f395db 100644 --- a/src/mono/mono/mini/mini-riscv.h +++ b/src/mono/mono/mini/mini-riscv.h @@ -286,6 +286,9 @@ enum { MONO_R_RISCV_JALR = 10, }; +void +mono_riscv_throw_exception (MonoObject *exc, host_mgreg_t pc, host_mgreg_t sp, host_mgreg_t *int_regs, gdouble *fp_regs, gboolean preserve_ips); + __attribute__ ((warn_unused_result)) guint8 * mono_riscv_emit_imm (guint8 *code, int rd, gsize imm); From b461b98e12d003a707d2ea06d342dca72fe59278 Mon Sep 17 00:00:00 2001 From: WuXinlong <821408745@qq.com> Date: Wed, 5 Apr 2023 12:27:23 +0800 Subject: [PATCH 05/20] mono_riscv_throw_exception --- src/mono/mono/mini/exceptions-riscv.c | 42 +++++++++++++++++++++++++-- src/mono/mono/mini/mini-riscv.h | 2 +- 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/mono/mono/mini/exceptions-riscv.c b/src/mono/mono/mini/exceptions-riscv.c index f645dc174d933f..77a68a8f79a4b3 100644 --- a/src/mono/mono/mini/exceptions-riscv.c +++ b/src/mono/mono/mini/exceptions-riscv.c @@ -6,6 +6,7 @@ #include "mini-runtime.h" #include +#include #include #include "mono/utils/mono-tls-inline.h" @@ -68,9 +69,44 @@ mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot) } void -mono_riscv_throw_exception (MonoObject *exc, host_mgreg_t pc, host_mgreg_t sp, host_mgreg_t *int_regs, gdouble *fp_regs, gboolean preserve_ips){ - printf("mono_riscv_throw_exception\n"); - NOT_IMPLEMENTED; +mono_riscv_throw_exception (gpointer arg, host_mgreg_t pc, host_mgreg_t *int_regs, gdouble *fp_regs, gboolean corlib, gboolean rethrow, gboolean preserve_ips){ + ERROR_DECL (error); + MonoContext ctx; + MonoObject *exc = NULL; + guint32 ex_token_index, ex_token; + if (!corlib) + exc = (MonoObject*)arg; + else { + ex_token_index = (guint64)arg; + ex_token = MONO_TOKEN_TYPE_DEF | ex_token_index; + exc = (MonoObject*)mono_exception_from_token (mono_defaults.corlib, ex_token); + } + + /* Adjust pc so it points into the call instruction */ + pc -= 4; + + /* Initialize a ctx based on the arguments */ + memset (&ctx, 0, sizeof (MonoContext)); + memcpy (&(ctx.gregs [0]), int_regs, sizeof (host_mgreg_t) * RISCV_N_GREGS); + memcpy (&(ctx.fregs [0]), fp_regs, sizeof (host_mgreg_t) * RISCV_N_FREGS); + + ctx.gregs[0] = pc; + + if (mono_object_isinst_checked (exc, mono_defaults.exception_class, error)) { + MonoException *mono_ex = (MonoException*)exc; + if (!rethrow && !mono_ex->caught_in_unmanaged) { + mono_ex->stack_trace = NULL; + mono_ex->trace_ips = NULL; + } else if (preserve_ips) { + mono_ex->caught_in_unmanaged = TRUE; + } + } + + mono_error_assert_ok (error); + + mono_handle_exception (&ctx, exc); + + mono_restore_context (&ctx); } gpointer diff --git a/src/mono/mono/mini/mini-riscv.h b/src/mono/mono/mini/mini-riscv.h index 32914d93f395db..349764ef6a7359 100644 --- a/src/mono/mono/mini/mini-riscv.h +++ b/src/mono/mono/mini/mini-riscv.h @@ -287,7 +287,7 @@ enum { }; void -mono_riscv_throw_exception (MonoObject *exc, host_mgreg_t pc, host_mgreg_t sp, host_mgreg_t *int_regs, gdouble *fp_regs, gboolean preserve_ips); +mono_riscv_throw_exception (gpointer arg, host_mgreg_t pc, host_mgreg_t *int_regs, gdouble *fp_regs, gboolean corlib, gboolean rethrow, gboolean preserve_ips); __attribute__ ((warn_unused_result)) guint8 * mono_riscv_emit_imm (guint8 *code, int rd, gsize imm); From c44f58d4313b12e127c36f0ae7a59ff7fdc6a285 Mon Sep 17 00:00:00 2001 From: WuXinlong <821408745@qq.com> Date: Wed, 5 Apr 2023 15:11:48 +0800 Subject: [PATCH 06/20] fix error of stack trace --- src/mono/mono/mini/exceptions-riscv.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/mono/mono/mini/exceptions-riscv.c b/src/mono/mono/mini/exceptions-riscv.c index 77a68a8f79a4b3..4039878b37a28f 100644 --- a/src/mono/mono/mini/exceptions-riscv.c +++ b/src/mono/mono/mini/exceptions-riscv.c @@ -302,8 +302,6 @@ mono_arch_unwind_frame (MonoJitTlsData *jit_tls, MonoJitInfo *ji, MonoContext *ctx, MonoContext *new_ctx, MonoLMF **lmf, host_mgreg_t **save_locations, StackFrameInfo *frame) { - gpointer ip = MONO_CONTEXT_GET_IP (ctx); - memset (frame, 0, sizeof (StackFrameInfo)); frame->ji = ji; @@ -316,7 +314,6 @@ mono_arch_unwind_frame (MonoJitTlsData *jit_tls, MonoJitInfo *ji, guint32 unwind_info_len; guint8 *unwind_info; - if (ji->is_trampoline) frame->type = FRAME_TYPE_TRAMPOLINE; else @@ -332,6 +329,8 @@ mono_arch_unwind_frame (MonoJitTlsData *jit_tls, MonoJitInfo *ji, for (int i = 0; i < 10; i++) (regs + MONO_MAX_IREGS) [i] = *((host_mgreg_t*)&new_ctx->fregs [RISCV_F18 + i]); + gpointer ip = MINI_FTNPTR_TO_ADDR (MONO_CONTEXT_GET_IP (ctx)); + gboolean success = mono_unwind_frame (unwind_info, unwind_info_len, (guint8 *)ji->code_start, (guint8 *)ji->code_start + ji->code_size, (guint8 *)ip, NULL, regs, MONO_MAX_IREGS + 12 + 1, save_locations, MONO_MAX_IREGS, (guint8 **)&cfa); @@ -339,21 +338,23 @@ mono_arch_unwind_frame (MonoJitTlsData *jit_tls, MonoJitInfo *ji, if (!success) return FALSE; - memcpy (&new_ctx->gregs, regs, sizeof (host_mgreg_t) * 32); + memcpy (&new_ctx->gregs, regs, sizeof (host_mgreg_t) * MONO_MAX_IREGS); for (int i = 0; i < 2; i++) *((host_mgreg_t*)&new_ctx->fregs [RISCV_F8 + i]) = (regs + MONO_MAX_IREGS) [i]; for (int i = 0; i < 10; i++) - *((host_mgreg_t*)&new_ctx->fregs [RISCV_F18 + i]) = (regs + MONO_MAX_IREGS) [i]; + *((host_mgreg_t *)&new_ctx->fregs [RISCV_F18 + i]) = (regs + MONO_MAX_IREGS) [2 + i]; + new_ctx->gregs [0] = regs [RISCV_RA]; new_ctx->gregs [RISCV_SP] = (host_mgreg_t)(gsize)cfa; - if (*lmf && (*lmf)->gregs [RISCV_FP] && (MONO_CONTEXT_GET_SP (ctx) >= (gpointer)(*lmf)->gregs [RISCV_SP])) { + if (*lmf && (*lmf)->gregs [MONO_ARCH_LMF_REG_SP] && + (MONO_CONTEXT_GET_SP (ctx) >= (gpointer)(*lmf)->gregs [MONO_ARCH_LMF_REG_SP])) { /* remove any unused lmf */ *lmf = (MonoLMF *)(((gsize)(*lmf)->previous_lmf) & ~(TARGET_SIZEOF_VOID_P - 1)); } - /* we substract 1, so that the pc points into the call instruction */ - new_ctx->gregs [RISCV_ZERO]--; + /* we subtract 1, so that the PC points into the call instruction */ + new_ctx->gregs [0]--; return TRUE; } else if (*lmf) { @@ -365,10 +366,14 @@ mono_arch_unwind_frame (MonoJitTlsData *jit_tls, MonoJitInfo *ji, if (!ji) return FALSE; - memcpy (&new_ctx->gregs, (*lmf)->gregs, sizeof (host_mgreg_t) * RISCV_N_GREGS); + g_assert (MONO_ARCH_LMF_REGS == ((MONO_ARCH_CALLEE_SAVED_REGS) | (1 << RISCV_SP))); + + memcpy (&new_ctx->gregs [0], &(*lmf)->gregs [0], sizeof (host_mgreg_t) * RISCV_N_GREGS); + // new_ctx->gregs [RISCV_FP] = (*lmf)->gregs [MONO_ARCH_LMF_REG_FP]; + // new_ctx->gregs [RISCV_SP] = (*lmf)->gregs [MONO_ARCH_LMF_REG_SP]; new_ctx->gregs [0] = (*lmf)->pc; // use [0] as pc reg since x0 is hard-wired zero - /* we substract 1, so that the IP points into the call instruction */ + /* we subtract 1, so that the PC points into the call instruction */ new_ctx->gregs [0]--; *lmf = (MonoLMF *)(((gsize)(*lmf)->previous_lmf) & ~(TARGET_SIZEOF_VOID_P - 1)); From 0d83ad84cab3a845addbc78bd6991617bbbd4111 Mon Sep 17 00:00:00 2001 From: WuXinlong <821408745@qq.com> Date: Sat, 8 Apr 2023 13:59:43 +0800 Subject: [PATCH 07/20] test case --- src/mono/sample/TestRun/Makefile | 5 +-- src/mono/sample/TestRun/TestRun.cs | 17 +++++++++ src/mono/sample/TestRun/TestRun.csproj | 38 +++++++++++++++++++ .../sample/TestRun/TestRun.runtimeconfig.json | 9 +++++ 4 files changed, 66 insertions(+), 3 deletions(-) create mode 100644 src/mono/sample/TestRun/TestRun.cs create mode 100644 src/mono/sample/TestRun/TestRun.csproj create mode 100644 src/mono/sample/TestRun/TestRun.runtimeconfig.json diff --git a/src/mono/sample/TestRun/Makefile b/src/mono/sample/TestRun/Makefile index 3fa8c7e0f82073..27b38c04ecb7ab 100644 --- a/src/mono/sample/TestRun/Makefile +++ b/src/mono/sample/TestRun/Makefile @@ -11,7 +11,7 @@ AOT?=false #PGO_BINARY_PATH= #MIBC_PROFILE_PATH= -MONO_ENV_DEBUG_OPTIONS = "--trace=all" +MONO_ENV_DEBUG_OPTIONS = "" MONO_ENV_RUN_OPTIONS = "" build: TestRun.cs @@ -30,14 +30,13 @@ run: build debug: build COMPlus_DebugWriteToStdErr=1 \ MONO_LOG_LEVEL=debug MONO_LOG_MASK=all \ - COREHOST_TRACE=1 COREHOST_TRACE_VERBOSITY=4 \ MONO_ENV_OPTIONS=$(MONO_ENV_DEBUG_OPTIONS) \ qemu-riscv64 -L $(TOP)/.tools/rootfs/riscv64/ \ -g 12345 \ $(TOP)artifacts/bin/testhost/net8.0-$(TARGET_OS)-Debug-$(MONO_ARCH)/dotnet TestRun.exe &\ riscv64-unknown-linux-gnu-gdb -ex 'target remote localhost:12345' \ -ex "set sysroot $(TOP).tools/rootfs/riscv64" -ex "set solib-search-path $(TOP)artifacts/bin/testhost/net8.0-linux-Debug-riscv64/shared/Microsoft.NETCore.App/8.0.0" \ - -ex "b mono_trace_enter_method " \ + -ex "b mono_arch_unwind_frame " \ $(TOP)artifacts/bin/testhost/net8.0-$(TARGET_OS)-Debug-$(MONO_ARCH)/dotnet clean: diff --git a/src/mono/sample/TestRun/TestRun.cs b/src/mono/sample/TestRun/TestRun.cs new file mode 100644 index 00000000000000..65df4772fb5e0d --- /dev/null +++ b/src/mono/sample/TestRun/TestRun.cs @@ -0,0 +1,17 @@ +using System; +namespace HelloWorld +{ + class Program + { + static int test(){ + throw new System.Exception(); + } + static int Main() + { + Console.WriteLine($"IsMono: {Type.GetType("Mono.RuntimeStructs") != null}"); + Console.WriteLine("Hello RISC-V"); + test(); + return 0; + } + } +} diff --git a/src/mono/sample/TestRun/TestRun.csproj b/src/mono/sample/TestRun/TestRun.csproj new file mode 100644 index 00000000000000..ef55589c8c175c --- /dev/null +++ b/src/mono/sample/TestRun/TestRun.csproj @@ -0,0 +1,38 @@ + + + Exe + $(NetCoreAppCurrent) + + + + + + + <_AotOutputType>Library + <_AotLibraryFormat>Dylib + false + + + + + + + + + + + + diff --git a/src/mono/sample/TestRun/TestRun.runtimeconfig.json b/src/mono/sample/TestRun/TestRun.runtimeconfig.json new file mode 100644 index 00000000000000..73898c2b118e0a --- /dev/null +++ b/src/mono/sample/TestRun/TestRun.runtimeconfig.json @@ -0,0 +1,9 @@ +{ + "runtimeOptions": { + "framework": { + "name": "Microsoft.NETCore.App", + "version": "8.0.0" + } + } + } + \ No newline at end of file From bd379d61b9422859fc90b6bcf4124f08a00bbb98 Mon Sep 17 00:00:00 2001 From: WuXinlong <821408745@qq.com> Date: Sat, 8 Apr 2023 21:29:43 +0800 Subject: [PATCH 08/20] output inst idiv fix mono_riscv_emit_branch_exc --- src/mono/mono/mini/cpu-riscv64.mdesc | 11 ++++----- src/mono/mono/mini/exceptions-riscv.c | 6 ++--- src/mono/mono/mini/mini-riscv.c | 32 +++++++++++---------------- src/mono/mono/mini/tramp-riscv.c | 15 ++++++------- 4 files changed, 29 insertions(+), 35 deletions(-) diff --git a/src/mono/mono/mini/cpu-riscv64.mdesc b/src/mono/mono/mini/cpu-riscv64.mdesc index 2a4caf1465ec7c..5796a24302e0ab 100644 --- a/src/mono/mono/mini/cpu-riscv64.mdesc +++ b/src/mono/mono/mini/cpu-riscv64.mdesc @@ -112,6 +112,7 @@ int_mul: dest:i src1:i src2:i len:4 r4_mul: dest:f src1:f src2:f len:4 long_mul: dest:i src1:i src2:i len:4 float_mul: dest:f src1:f src2:f len:4 +int_div: dest:i src1:i src2:i len:32 long_div: dest:i src1:i src2:i len:32 int_div_un: dest:i src1:i src2:i len:32 long_div_un: dest:i src1:i src2:i len:32 @@ -176,11 +177,11 @@ riscv_bge: src1:i src2:i len:8 riscv_bgeu: src1:i src2:i len:8 riscv_blt: src1:i src2:i len:8 riscv_bltu: src1:i src2:i len:8 -riscv_exc_beq: src1:i src2:i len:32 -riscv_exc_bne: src1:i src2:i len:32 -riscv_exc_bgeu: src1:i src2:i len:32 -riscv_exc_blt: src1:i src2:i len:32 -riscv_exc_bltu: src1:i src2:i len:32 +riscv_exc_beq: src1:i src2:i len:8 +riscv_exc_bne: src1:i src2:i len:8 +riscv_exc_bgeu: src1:i src2:i len:8 +riscv_exc_blt: src1:i src2:i len:8 +riscv_exc_bltu: src1:i src2:i len:8 riscv_slt: dest:i src1:i src2:i len:4 riscv_sltu: dest:i src1:i src2:i len:4 riscv_slti: dest:i src1:i len:4 diff --git a/src/mono/mono/mini/exceptions-riscv.c b/src/mono/mono/mini/exceptions-riscv.c index 4039878b37a28f..7896031e18568f 100644 --- a/src/mono/mono/mini/exceptions-riscv.c +++ b/src/mono/mono/mini/exceptions-riscv.c @@ -152,7 +152,7 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm riscv_addi (code, RISCV_FP, RISCV_SP, frame_size); /* Save gregs */ - code = emit_store_stack (code, 0xffffffff, RISCV_FP, -gregs_offset, FALSE); + code = mono_riscv_emit_store_stack (code, 0xffffffff, RISCV_FP, -gregs_offset, FALSE); if (corlib && !llvm) NOT_IMPLEMENTED; @@ -164,7 +164,7 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm /* Save fregs */ if (riscv_stdext_f || riscv_stdext_d) - code = emit_store_stack (code, 0xffffffff, RISCV_FP, -fregs_offset, TRUE); + code = mono_riscv_emit_store_stack (code, 0xffffffff, RISCV_FP, -fregs_offset, TRUE); /* Call the C trampoline function */ /* Arg1 = exception object/type token */ @@ -338,7 +338,7 @@ mono_arch_unwind_frame (MonoJitTlsData *jit_tls, MonoJitInfo *ji, if (!success) return FALSE; - memcpy (&new_ctx->gregs, regs, sizeof (host_mgreg_t) * MONO_MAX_IREGS); + memcpy (new_ctx->gregs, regs, sizeof (host_mgreg_t) * MONO_MAX_IREGS); for (int i = 0; i < 2; i++) *((host_mgreg_t*)&new_ctx->fregs [RISCV_F8 + i]) = (regs + MONO_MAX_IREGS) [i]; for (int i = 0; i < 10; i++) diff --git a/src/mono/mono/mini/mini-riscv.c b/src/mono/mono/mini/mini-riscv.c index c5e8ee9d609759..07dc96cfe6cded 100644 --- a/src/mono/mono/mini/mini-riscv.c +++ b/src/mono/mono/mini/mini-riscv.c @@ -622,9 +622,6 @@ riscv_patch_full (MonoCompile *cfg, guint8 *code, guint8 *target, int relocation g_assert_not_reached (); break; } - case MONO_R_RISCV_JALR: - *(guint64 *)code = (guint64)target; - break; default: NOT_IMPLEMENTED; } @@ -1992,6 +1989,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) case OP_RMUL: case OP_FMUL: case OP_FDIV: + case OP_IDIV: case OP_LDIV: case OP_IDIV_UN: case OP_LDIV_UN: @@ -2671,7 +2669,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) break; } #endif - case default: + default: printf ("unable to lowering following IR:"); mono_print_ins (ins); NOT_IMPLEMENTED; @@ -3234,31 +3232,26 @@ mono_riscv_emit_branch_exc (MonoCompile *cfg, guint8 *code, int opcode, int sreg switch (opcode) { case OP_RISCV_EXC_BEQ: - riscv_bne (code, sreg1, sreg2, 16 + sizeof (guint64)); + riscv_bne (code, sreg1, sreg2, 8); break; case OP_RISCV_EXC_BNE: - riscv_beq (code, sreg1, sreg2, 16 + sizeof (guint64)); + riscv_beq (code, sreg1, sreg2, 8); break; case OP_RISCV_EXC_BLT: - riscv_bge (code, sreg1, sreg2, 16 + sizeof (guint64)); + riscv_bge (code, sreg1, sreg2, 8); break; case OP_RISCV_EXC_BLTU: - riscv_bgeu (code, sreg1, sreg2, 16 + sizeof (guint64)); + riscv_bgeu (code, sreg1, sreg2, 8); break; case OP_RISCV_EXC_BGEU: - riscv_bltu (code, sreg1, sreg2, 16 + sizeof (guint64)); + riscv_bltu (code, sreg1, sreg2, 8); break; default: g_print ("can't emit exc branch %d\n", opcode); NOT_IMPLEMENTED; } - riscv_jal (code, RISCV_T6, sizeof (guint64) + 4); - - mono_add_patch_info_rel (cfg, code - cfg->native_code, MONO_PATCH_INFO_EXC, exc_name, MONO_R_RISCV_JALR); - code += sizeof (guint64); - - code = mono_riscv_emit_load (code, RISCV_T6, RISCV_T6, 0, 0); - riscv_jalr (code, RISCV_ZERO, RISCV_T6, 0); + mono_add_patch_info_rel (cfg, code - cfg->native_code, MONO_PATCH_INFO_EXC, exc_name, MONO_R_RISCV_JAL); + riscv_jal (code, RISCV_ZERO, 0); return code; } @@ -3726,6 +3719,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) else riscv_fdiv_d (code, RISCV_ROUND_DY, ins->dreg, ins->sreg1, ins->sreg2); break; + case OP_IDIV: case OP_LDIV: g_assert (riscv_stdext_m); code = mono_riscv_emit_branch_exc (cfg, code, OP_RISCV_EXC_BEQ, ins->sreg2, RISCV_ZERO, @@ -4218,20 +4212,20 @@ mono_arch_emit_exceptions (MonoCompile *cfg) guint8 *code, *ip; guint8 *exc_throw_pos [MONO_EXC_INTRINS_NUM] = {NULL}; guint8 exc_throw_found [MONO_EXC_INTRINS_NUM] = {0}; - int exc_id, max_epilog_size = 0; + int exc_id, size = 0; for (ji = cfg->patch_info; ji; ji = ji->next) { if (ji->type == MONO_PATCH_INFO_EXC) { exc_id = mini_exception_id_by_name ((const char *)ji->data.target); g_assert (exc_id < MONO_EXC_INTRINS_NUM); if (!exc_throw_found [exc_id]) { - max_epilog_size += 40; // 8 Inst for exception + size += 40; // 8 Inst for exception exc_throw_found [exc_id] = TRUE; } } } - code = realloc_code (cfg, max_epilog_size); + code = realloc_code (cfg, size); /* Emit code to raise corlib exceptions */ for (ji = cfg->patch_info; ji; ji = ji->next) { diff --git a/src/mono/mono/mini/tramp-riscv.c b/src/mono/mono/mini/tramp-riscv.c index 87ae6780972f08..7f69f4873e9b91 100644 --- a/src/mono/mono/mini/tramp-riscv.c +++ b/src/mono/mono/mini/tramp-riscv.c @@ -166,17 +166,16 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf } riscv_jalr (code, RISCV_RA, RISCV_T1, 0); - /* a0 contains the address of the tls slot holding the current lmf */ + /* a0 contains the address of the tls slot holding the current (MonoLMF **)lmf */ /* T0 = lmf */ - riscv_addi (code, RISCV_T0, RISCV_FP, -lmf_offset); + riscv_addi(code, RISCV_T0, RISCV_FP, -lmf_offset); /* lmf->lmf_addr = lmf_addr */ - code = mono_riscv_emit_store (code, RISCV_A0, RISCV_FP, -lmf_offset + MONO_STRUCT_OFFSET (MonoLMF, lmf_addr), 0); + code = mono_riscv_emit_store(code, RISCV_A0, RISCV_T0, MONO_STRUCT_OFFSET (MonoLMF, lmf_addr), 0); /* lmf->previous_lmf = *lmf_addr */ - code = mono_riscv_emit_load (code, RISCV_T1, RISCV_A0, 0, 0); - code = - mono_riscv_emit_store (code, RISCV_T1, RISCV_FP, -lmf_offset + MONO_STRUCT_OFFSET (MonoLMF, previous_lmf), 0); + code = mono_riscv_emit_load(code, RISCV_T1, RISCV_A0, 0, 0); + code = mono_riscv_emit_store(code, RISCV_T1, RISCV_T0, MONO_STRUCT_OFFSET (MonoLMF, previous_lmf), 0); /* *lmf_addr = lmf */ code = mono_riscv_emit_store (code, RISCV_T0, RISCV_A0, 0, 0); @@ -216,9 +215,9 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf /* T0 = lmf */ riscv_addi (code, RISCV_T0, RISCV_FP, -lmf_offset); /* T1 = lmf->previous_lmf */ - code = mono_riscv_emit_load (code, RISCV_T1, RISCV_FP, -lmf_offset + MONO_STRUCT_OFFSET (MonoLMF, previous_lmf), 0); + code = mono_riscv_emit_load(code, RISCV_T1, RISCV_T0, MONO_STRUCT_OFFSET (MonoLMF, previous_lmf), 0); /* T0 = lmf->lmf_addr */ - code = mono_riscv_emit_load (code, RISCV_T0, RISCV_FP, -lmf_offset + MONO_STRUCT_OFFSET (MonoLMF, lmf_addr), 0); + code = mono_riscv_emit_load(code, RISCV_T0, RISCV_T0, MONO_STRUCT_OFFSET (MonoLMF, lmf_addr), 0); /* *lmf_addr = previous_lmf */ code = mono_riscv_emit_store (code, RISCV_T1, RISCV_T0, 0, 0); From 8d26d93d4994abffd933b93e2030fbd49090e73e Mon Sep 17 00:00:00 2001 From: WuXinlong <821408745@qq.com> Date: Sat, 8 Apr 2023 21:56:51 +0800 Subject: [PATCH 09/20] implement mono_arch_get_throw_corlib_exception --- src/mono/mono/mini/cpu-riscv64.mdesc | 10 +++++----- src/mono/mono/mini/exceptions-riscv.c | 13 ++++++++----- src/mono/mono/mini/mini-riscv.c | 14 +------------- 3 files changed, 14 insertions(+), 23 deletions(-) diff --git a/src/mono/mono/mini/cpu-riscv64.mdesc b/src/mono/mono/mini/cpu-riscv64.mdesc index 5796a24302e0ab..7ba7da1e8c040d 100644 --- a/src/mono/mono/mini/cpu-riscv64.mdesc +++ b/src/mono/mono/mini/cpu-riscv64.mdesc @@ -177,11 +177,11 @@ riscv_bge: src1:i src2:i len:8 riscv_bgeu: src1:i src2:i len:8 riscv_blt: src1:i src2:i len:8 riscv_bltu: src1:i src2:i len:8 -riscv_exc_beq: src1:i src2:i len:8 -riscv_exc_bne: src1:i src2:i len:8 -riscv_exc_bgeu: src1:i src2:i len:8 -riscv_exc_blt: src1:i src2:i len:8 -riscv_exc_bltu: src1:i src2:i len:8 +riscv_exc_beq: src1:i src2:i len:12 +riscv_exc_bne: src1:i src2:i len:12 +riscv_exc_bgeu: src1:i src2:i len:12 +riscv_exc_blt: src1:i src2:i len:12 +riscv_exc_bltu: src1:i src2:i len:12 riscv_slt: dest:i src1:i src2:i len:4 riscv_sltu: dest:i src1:i src2:i len:4 riscv_slti: dest:i src1:i len:4 diff --git a/src/mono/mono/mini/exceptions-riscv.c b/src/mono/mono/mini/exceptions-riscv.c index 7896031e18568f..315996c967bb5c 100644 --- a/src/mono/mono/mini/exceptions-riscv.c +++ b/src/mono/mono/mini/exceptions-riscv.c @@ -154,7 +154,8 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm /* Save gregs */ code = mono_riscv_emit_store_stack (code, 0xffffffff, RISCV_FP, -gregs_offset, FALSE); if (corlib && !llvm) - NOT_IMPLEMENTED; + /* The real ra is in A1 */ + code = mono_riscv_emit_store (code, RISCV_A1, RISCV_FP, -gregs_offset + (RISCV_RA * sizeof(host_mgreg_t)), 0); /* Save previous fp/sp */ code = mono_riscv_emit_load (code, RISCV_T0, RISCV_FP, -2 * sizeof(host_mgreg_t), 0); @@ -170,8 +171,11 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm /* Arg1 = exception object/type token */ // riscv_addi (code, RISCV_A0, RISCV_A0, 0); /* Arg2 = caller ip, should be return address in this case */ - if (corlib) - NOT_IMPLEMENTED; + if (corlib){ + // caller ip are set to A1 already + if (llvm) + NOT_IMPLEMENTED; + } else code = mono_riscv_emit_load (code, RISCV_A1, RISCV_FP, -sizeof(host_mgreg_t), 0); /* Arg 3 = gregs */ @@ -240,8 +244,7 @@ mono_arch_get_rethrow_preserve_exception (MonoTrampInfo **info, gboolean aot) gpointer mono_arch_get_throw_corlib_exception (MonoTrampInfo **info, gboolean aot) { - *info = NULL; - return nop_stub (0xaa); + return get_throw_trampoline (384, TRUE, FALSE, FALSE, FALSE, "throw_corlib_exception", info, aot, FALSE); } #else diff --git a/src/mono/mono/mini/mini-riscv.c b/src/mono/mono/mini/mini-riscv.c index 07dc96cfe6cded..6015cfb9e3e972 100644 --- a/src/mono/mono/mini/mini-riscv.c +++ b/src/mono/mono/mini/mini-riscv.c @@ -3217,19 +3217,7 @@ mono_riscv_emit_call (MonoCompile *cfg, guint8 *code, MonoJumpInfoType patch_typ static guint8 * mono_riscv_emit_branch_exc (MonoCompile *cfg, guint8 *code, int opcode, int sreg1, int sreg2, const char *exc_name) { - // guint8 *p; - - // riscv_auipc(code, RISCV_T0, 0); - // // load imm - // riscv_jal (code, RISCV_T1, sizeof (guint64) + 4); - // p = code; - // code += sizeof (guint64); - // riscv_ld (code, RISCV_T1, RISCV_T1, 0); - // // pc + imm - // riscv_add(code, RISCV_T0, RISCV_T0, RISCV_T1); - - // *(guint64 *)p = (gsize)code; - + riscv_auipc(code, RISCV_T0, 0); switch (opcode) { case OP_RISCV_EXC_BEQ: riscv_bne (code, sreg1, sreg2, 8); From 31d99e4ba5eff373a1a398ac28ef5a2f57820684 Mon Sep 17 00:00:00 2001 From: WuXinlong <821408745@qq.com> Date: Sun, 9 Apr 2023 14:46:06 +0800 Subject: [PATCH 10/20] fix rdiv --- src/mono/mono/mini/mini-riscv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mono/mono/mini/mini-riscv.c b/src/mono/mono/mini/mini-riscv.c index 6015cfb9e3e972..dafa74bb23905d 100644 --- a/src/mono/mono/mini/mini-riscv.c +++ b/src/mono/mono/mini/mini-riscv.c @@ -3977,7 +3977,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) riscv_fmv_w_x (code, RISCV_FT0, RISCV_ZERO); riscv_feq_s (code, RISCV_T0, ins->sreg2, RISCV_FT0); - code = mono_riscv_emit_branch_exc (cfg, code, OP_RISCV_EXC_BNE, RISCV_T0, RISCV_ZERO, + code = mono_riscv_emit_branch_exc (cfg, code, OP_RISCV_EXC_BEQ, RISCV_T0, RISCV_ZERO, "DivideByZeroException"); riscv_fdiv_s (code, RISCV_ROUND_DY, ins->dreg, ins->sreg1, ins->sreg2); break; From 293069624387f6844bf0983af312d5393d9d2b0e Mon Sep 17 00:00:00 2001 From: Xinlong-Wu <821408745@qq.com> Date: Mon, 10 Apr 2023 18:50:26 +0800 Subject: [PATCH 11/20] move ArgOnStack arg at prologue lowering OP_XOR_IMM&OP_IXOR_IMM --- src/mono/mono/mini/mini-riscv.c | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/src/mono/mono/mini/mini-riscv.c b/src/mono/mono/mini/mini-riscv.c index 6015cfb9e3e972..40f9ad2e0b6524 100644 --- a/src/mono/mono/mini/mini-riscv.c +++ b/src/mono/mono/mini/mini-riscv.c @@ -1723,6 +1723,7 @@ mono_arch_decompose_opts (MonoCompile *cfg, MonoInst *ins) case OP_LADD_OVF_UN: case OP_IMUL_OVF: + case OP_LMUL_OVF_UN: case OP_LMUL_OVF_UN_OOM: case OP_FDIV: @@ -2001,8 +2002,6 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) case OP_CHECK_THIS: case OP_IAND: case OP_LAND: - case OP_XOR_IMM: - case OP_IXOR_IMM: case OP_IXOR: case OP_LXOR: case OP_IOR: @@ -2500,7 +2499,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) NULLIFY_INS (ins); } else if (ins->next->opcode == OP_IL_SEQ_POINT || ins->next->opcode == OP_MOVE || ins->next->opcode == OP_LOAD_MEMBASE || ins->next->opcode == OP_NOP || - ins->next->opcode == OP_LOADI4_MEMBASE) { + ins->next->opcode == OP_LOADI4_MEMBASE || ins->next->opcode == OP_BR ) { /** * there is compare without branch OP followed * @@ -2599,6 +2598,8 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) case OP_LAND_IMM: case OP_IOR_IMM: case OP_LOR_IMM: + case OP_XOR_IMM: + case OP_IXOR_IMM: if (!RISCV_VALID_I_IMM ((gint32)(gssize)(ins->inst_imm))) mono_decompose_op_imm (cfg, bb, ins); break; @@ -2607,6 +2608,21 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) ins->opcode = OP_XOR_IMM; ins->inst_imm = -1; break; + case OP_ICONV_TO_I1: + case OP_LCONV_TO_I1: + // slli a0, a0, 56 + // srai a0, a0, 56 + NEW_INS_BEFORE (cfg, ins, temp, OP_ICONST); + temp->opcode = OP_SHL_IMM; + temp->dreg = ins->dreg; + temp->sreg1 = ins->sreg1; + temp->inst_imm = 56; + + ins->opcode = OP_SHR_IMM; + ins->dreg = ins->dreg; + ins->sreg1 = temp->dreg; + ins->inst_imm = 56; + break; case OP_ICONV_TO_U1: case OP_LCONV_TO_U1: // andi rd, rs1, 255 @@ -3108,14 +3124,18 @@ emit_move_args (MonoCompile *cfg, guint8 *code) if (ins->opcode == OP_REGVAR) { switch (ainfo->storage) { case ArgInIReg: - riscv_addi (code, ins->dreg, ainfo->reg, 0); + if(ins->dreg != ainfo->reg) + riscv_addi (code, ins->dreg, ainfo->reg, 0); if (i == 0 && sig->hasthis) { mono_add_var_location (cfg, ins, TRUE, ainfo->reg, 0, 0, code - cfg->native_code); mono_add_var_location (cfg, ins, TRUE, ins->dreg, 0, code - cfg->native_code, 0); } break; - + case ArgOnStack: + code = mono_riscv_emit_load(code, ins->dreg, RISCV_FP, ainfo->offset, ainfo->slot_size); + break; default: + g_print("Can't handle arg type %d\n", ainfo->storage); NOT_IMPLEMENTED; } } else { From d47bf35cb4c63dde888cca4bb6be8796481ac368 Mon Sep 17 00:00:00 2001 From: Xinlong-Wu <821408745@qq.com> Date: Tue, 11 Apr 2023 22:07:16 +0800 Subject: [PATCH 12/20] fix emit_imm --- src/mono/mono/mini/mini-riscv.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/mono/mono/mini/mini-riscv.c b/src/mono/mono/mini/mini-riscv.c index 40f9ad2e0b6524..a8f02dae4cbe71 100644 --- a/src/mono/mono/mini/mini-riscv.c +++ b/src/mono/mono/mini/mini-riscv.c @@ -2736,17 +2736,16 @@ mono_riscv_emit_imm (guint8 *code, int rd, gsize imm) gint32 Lo = RISCV_BITS (imm, 0, 12); // Lo is in signed num - // if Lo > 0x800 + // if Lo >= 0x800 // convert into ((Hi + 1) << 20) - (0x1000 - Lo) if (Lo >= 0x800) { - Hi += 1; + if (imm > 0) + Hi += 1; Lo = Lo - 0x1000; } - // if Hi is 0 or overflow, skip - if (Hi < 0xfffff) { - riscv_lui (code, rd, Hi); - } + g_assert(Hi <= 0xfffff); + riscv_lui (code, rd, Hi); riscv_addiw (code, rd, rd, Lo); return code; } @@ -3323,7 +3322,7 @@ mono_arch_emit_prolog (MonoCompile *cfg) // save fp value, here is T0 stack_size += sizeof (target_mgreg_t); - code = mono_riscv_emit_store (code, RISCV_T0, RISCV_FP, stack_size, 0); + code = mono_riscv_emit_store (code, RISCV_T0, RISCV_FP, -stack_size, 0); // save stack size into T0 code = mono_riscv_emit_imm (code, RISCV_T0, cfg->stack_offset); From 053f246877c92c548f6eaf00cb07f56820d4b6dd Mon Sep 17 00:00:00 2001 From: Xinlong-Wu <821408745@qq.com> Date: Tue, 11 Apr 2023 22:13:03 +0800 Subject: [PATCH 13/20] test imm --- src/mono/sample/TestRun/test_emit_imm.c | 120 ++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 src/mono/sample/TestRun/test_emit_imm.c diff --git a/src/mono/sample/TestRun/test_emit_imm.c b/src/mono/sample/TestRun/test_emit_imm.c new file mode 100644 index 00000000000000..d192ed6f07cd79 --- /dev/null +++ b/src/mono/sample/TestRun/test_emit_imm.c @@ -0,0 +1,120 @@ +#include +#include + +typedef signed char gint8; +typedef unsigned char guint8; +typedef signed int gint32; +typedef unsigned int guint32; +typedef unsigned int gsize; +typedef signed int gssize; + +#define _riscv_emit(p, insn) \ + do { \ + *(guint32 *) (p) = (insn); \ + (p) += sizeof (guint32); \ + } while (0) + +#define RISCV_BITS(value, start, count) (((value) >> (start)) & ((1 << (count)) - 1)) +#define RISCV_SIGN(value) (-(((value) >> (sizeof (guint32) * 8 - 1)) & 1)) + +#define RISCV_VALID_IMM32(value) \ + (((gint32)value) == (value)) + +#define RISCV_ENCODE_I_IMM(imm) \ + (RISCV_BITS ((imm), 0, 12) << 20) + +#define RISCV_DECODE_I_IMM(ins) \ + ((RISCV_BITS ((ins), 20, 12) << 0) | (RISCV_SIGN ((ins)) << 12)) + +#define RISCV_VALID_I_IMM(value) \ + (RISCV_DECODE_I_IMM (RISCV_ENCODE_I_IMM ((value))) == (value)) + +#define RISCV_DECODE_U_IMM(ins) \ + (RISCV_BITS ((ins), 12, 20) << 0) + +#define RISCV_ENCODE_U_IMM(imm) \ + (RISCV_BITS ((imm), 0, 20) << 12) + +#define RISCV_VALID_U_IMM(value) \ + (RISCV_DECODE_U_IMM (RISCV_ENCODE_U_IMM ((value))) == (value)) + +#define _riscv_u_op(p, opcode, rd, imm) \ + do { \ + assert (RISCV_VALID_U_IMM ((guint32) (gsize) (imm))); \ + _riscv_emit ((p), ((opcode) << 0) | \ + ((rd) << 7) | \ + (RISCV_ENCODE_U_IMM ((guint32) (gsize) (imm)))); \ + } while (0) + +#define _riscv_i_op(p, opcode, funct3, rd, rs1, imm) \ + do { \ + assert (RISCV_VALID_I_IMM ((gint32) (gssize) (imm))); \ + _riscv_emit ((p), ((opcode) << 0) | \ + ((rd) << 7) | \ + ((funct3) << 12) | \ + ((rs1) << 15) | \ + (RISCV_ENCODE_I_IMM ((gint32) (gssize) (imm)))); \ + } while (0) + +#define riscv_lui(p, rd, imm) _riscv_u_op ((p), 0b0110111, (rd), (imm)) +#define riscv_addi(p, rd, rs1, imm) _riscv_i_op ((p), 0b0010011, 0b000, (rd), (rs1), (imm)) +#define riscv_addiw(p, rd, rs1, imm) _riscv_i_op ((p), 0b0011011, 0b000, (rd), (rs1), (imm)) +#define riscv_jalr(p, rd, rs1, imm) _riscv_i_op ((p), 0b1100111, 0b000, (rd), (rs1), (imm)) + +guint8 * +mono_riscv_emit_imm (guint8 *code, int rd, gsize imm) +{ + if (RISCV_VALID_I_IMM (imm)) { + riscv_addi (code, rd, 0, imm); + return code; + } + + /** + * use LUI & ADDIW load 32 bit Imm + * LUI: High 20 bit of imm + * ADDIW: Low 12 bit of imm + */ + if (RISCV_VALID_IMM32 (imm)) { + gint32 Hi = RISCV_BITS (imm, 12, 20); + gint32 Lo = RISCV_BITS (imm, 0, 12); + + // Lo is in signed num + // if Lo >= 0x800 + // convert into ((Hi + 1) << 20) - (0x1000 - Lo) + if (Lo >= 0x800) { + if (imm > 0) + Hi += 1; + Lo = Lo - 0x1000; + } + + assert(Hi <= 0xfffff); + riscv_lui (code, rd, Hi); + riscv_addiw (code, rd, rd, Lo); + return code; + } + + assert(0); +} + +int main(int argc, char const *argv[]) +{ + + + gint8 *code = malloc(10*sizeof(gint8)); + for (int i = -1118200000; i < 2147483647; i++) + { + gint8 *p = mono_riscv_emit_imm(code, 10, i); + riscv_jalr(p, 0, 1, 0); + + int (* func)() = code; + int res = func(); + if(i != res){ + printf("except: %d, got = %d\n", i, res); + return 1; + } + if(i % 1000000 == 0) + printf("progress: %d\n",i); + } + printf("all correct\n"); + return 0; +} From 3f59f4d16e5e0bf263ce478755269dfdaae05b25 Mon Sep 17 00:00:00 2001 From: WuXinlong <821408745@qq.com> Date: Wed, 12 Apr 2023 18:51:05 +0800 Subject: [PATCH 14/20] update test case --- src/mono/sample/TestRun/Makefile | 11 ++++++++--- src/mono/sample/TestRun/TestRun.cs | 6 +++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/mono/sample/TestRun/Makefile b/src/mono/sample/TestRun/Makefile index 27b38c04ecb7ab..09fa37ce83f62d 100644 --- a/src/mono/sample/TestRun/Makefile +++ b/src/mono/sample/TestRun/Makefile @@ -11,7 +11,7 @@ AOT?=false #PGO_BINARY_PATH= #MIBC_PROFILE_PATH= -MONO_ENV_DEBUG_OPTIONS = "" +MONO_ENV_DEBUG_OPTIONS = "-v " MONO_ENV_RUN_OPTIONS = "" build: TestRun.cs @@ -36,11 +36,16 @@ debug: build $(TOP)artifacts/bin/testhost/net8.0-$(TARGET_OS)-Debug-$(MONO_ARCH)/dotnet TestRun.exe &\ riscv64-unknown-linux-gnu-gdb -ex 'target remote localhost:12345' \ -ex "set sysroot $(TOP).tools/rootfs/riscv64" -ex "set solib-search-path $(TOP)artifacts/bin/testhost/net8.0-linux-Debug-riscv64/shared/Microsoft.NETCore.App/8.0.0" \ - -ex "b mono_arch_unwind_frame " \ + -ex "b mini.c:2152 " \ $(TOP)artifacts/bin/testhost/net8.0-$(TARGET_OS)-Debug-$(MONO_ARCH)/dotnet clean: rm -f *.exe *.exe.mdb -# COMPlus_DebugWriteToStdErr="1" MONO_LOG_LEVEL="debug" MONO_LOG_MASK="all" COREHOST_TRACE="1" COREHOST_TRACE_VERBOSITY="4" MONO_ENV_OPTIONS="--compile-all --trace=all" qemu-riscv64 -L ../../../..//.tools/rootfs/riscv64/ -g 12345 ../../../../artifacts/bin/testhost/net8.0-Linux-Debug-riscv64/dotnet TestRun.exe \ No newline at end of file +# COMPlus_DebugWriteToStdErr="1" MONO_LOG_LEVEL="debug" MONO_LOG_MASK="all" COREHOST_TRACE="1" COREHOST_TRACE_VERBOSITY="4" MONO_ENV_OPTIONS="--compile-all --trace=all" qemu-riscv64 -L ../../../..//.tools/rootfs/riscv64/ -g 12345 ../../../../artifacts/bin/testhost/net8.0-Linux-Debug-riscv64/dotnet TestRun.exe + +ROOTFS_DIR="" ./build.sh mono+libs+host -c Debug +./build.sh mono+libs+host -c Debug --cross --arch riscv64 --build + +ROOTFS_DIR="" ./build.sh clr.hosts -c Debug diff --git a/src/mono/sample/TestRun/TestRun.cs b/src/mono/sample/TestRun/TestRun.cs index 65df4772fb5e0d..ed1ee5c4280543 100644 --- a/src/mono/sample/TestRun/TestRun.cs +++ b/src/mono/sample/TestRun/TestRun.cs @@ -3,14 +3,14 @@ namespace HelloWorld { class Program { - static int test(){ - throw new System.Exception(); + static int test(int c){ + return 1 / c; } static int Main() { Console.WriteLine($"IsMono: {Type.GetType("Mono.RuntimeStructs") != null}"); Console.WriteLine("Hello RISC-V"); - test(); + // test(0); return 0; } } From 1dc76d07ffbee9aad9bf761d2e4f3c69dd9b3976 Mon Sep 17 00:00:00 2001 From: WuXinlong <821408745@qq.com> Date: Fri, 14 Apr 2023 16:15:19 +0800 Subject: [PATCH 15/20] use swich to process return value --- src/mono/mono/mini/mini-riscv.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/mini/mini-riscv.c b/src/mono/mono/mini/mini-riscv.c index 0d5d272f7a684a..9255792f593842 100644 --- a/src/mono/mono/mini/mini-riscv.c +++ b/src/mono/mono/mini/mini-riscv.c @@ -924,11 +924,25 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig) // If the reture value would have been passed by reference, // the caller allocates memory for the return value, and // passes the address as an implicit first parameter. - if (cinfo->ret.storage == ArgVtypeByRef) { + + switch (cinfo->ret.storage) { + case ArgVtypeByRef: g_assert (cinfo->ret.reg == RISCV_A0); cinfo->next_arg = RISCV_A1; - } else + break; + + case ArgVtypeInIReg: + case ArgInIReg: + case ArgInFReg: + case ArgNone: cinfo->next_arg = RISCV_A0; + break; + + default: + g_print("Unhandled retyrn type %d\n", cinfo->ret.storage); + NOT_IMPLEMENTED; + break; + } cinfo->next_farg = RISCV_FA0; // reset status From 6032d21c55c92e359f457ad7427d2fd2ff1e1bfb Mon Sep 17 00:00:00 2001 From: Xinlong-Wu <821408745@qq.com> Date: Sun, 16 Apr 2023 20:19:17 +0800 Subject: [PATCH 16/20] fix offset of params in a call --- src/mono/mono/mini/mini-riscv.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/mono/mono/mini/mini-riscv.c b/src/mono/mono/mini/mini-riscv.c index 9255792f593842..b15427ee3411a0 100644 --- a/src/mono/mono/mini/mini-riscv.c +++ b/src/mono/mono/mini/mini-riscv.c @@ -758,10 +758,10 @@ add_valuetype (CallInfo *cinfo, ArgInfo *ainfo, MonoType *t) // Scalars wider than 2×XLEN bits are passed by reference if (aligned_size > sizeof (host_mgreg_t) * 2) { if (cinfo->next_arg > RISCV_A7) { + ainfo->offset = cinfo->stack_usage; ainfo->storage = ArgVtypeByRefOnStack; cinfo->stack_usage += aligned_size; ainfo->slot_size = aligned_size; - ainfo->offset = cinfo->stack_usage; } else { ainfo->storage = ArgVtypeByRef; ainfo->reg = cinfo->next_arg; @@ -774,18 +774,18 @@ add_valuetype (CallInfo *cinfo, ArgInfo *ainfo, MonoType *t) else if (aligned_size == sizeof (host_mgreg_t) * 2) { // If no argument registers are available, the scalar is passed on the stack by value if (cinfo->next_arg > RISCV_A7) { + ainfo->offset = cinfo->stack_usage; ainfo->storage = ArgVtypeOnStack; cinfo->stack_usage += sizeof (host_mgreg_t) * 2; ainfo->slot_size = sizeof (host_mgreg_t) * 2; - ainfo->offset = cinfo->stack_usage; } // If exactly one register is available, the low-order XLEN bits are // passed in the register and the high-order XLEN bits are passed on the stack else if (cinfo->next_arg == RISCV_A7) { + ainfo->offset = cinfo->stack_usage; ainfo->storage = ArgVtypeInMixed; cinfo->stack_usage += sizeof (host_mgreg_t); ainfo->slot_size = sizeof (host_mgreg_t); - ainfo->offset = cinfo->stack_usage; ainfo->reg = cinfo->next_arg; ainfo->size = sizeof (host_mgreg_t); @@ -1388,7 +1388,7 @@ emit_sig_cookie (MonoCompile *cfg, MonoCallInst *call, CallInfo *cinfo) /** * mono_arch_emit_call: - * we process all Args of a function call +* move all Args to corresponding reg/stack in Caller * (return, parameters) */ void @@ -1505,7 +1505,8 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) break; } case ArgVtypeInIReg: - case ArgVtypeByRef: { + case ArgVtypeByRef: + case ArgVtypeOnStack: { MonoInst *ins; guint32 align; guint32 size; @@ -1579,7 +1580,7 @@ mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src) load->inst_basereg = src->dreg; load->inst_offset = i; MONO_ADD_INS (cfg->cbb, load); - MONO_EMIT_NEW_STORE_MEMBASE (cfg, op_load, RISCV_FP, -ainfo->offset + i, load->dreg); + MONO_EMIT_NEW_STORE_MEMBASE (cfg, op_load==OP_LOADI8_MEMBASE ? OP_STOREI8_MEMBASE_REG : OP_STOREI4_MEMBASE_REG, RISCV_SP, ainfo->offset + i, load->dreg); } break; case ArgVtypeByRef: { From b1057d3212451b7654ee55f1ea12d76fcc80a947 Mon Sep 17 00:00:00 2001 From: Xinlong-Wu <821408745@qq.com> Date: Sun, 16 Apr 2023 20:23:51 +0800 Subject: [PATCH 17/20] lowering OP_IDIV_IMM --- src/mono/mono/mini/mini-riscv.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/mono/mono/mini/mini-riscv.c b/src/mono/mono/mini/mini-riscv.c index b15427ee3411a0..bf14593016fa6b 100644 --- a/src/mono/mono/mini/mini-riscv.c +++ b/src/mono/mono/mini/mini-riscv.c @@ -2604,6 +2604,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) } case OP_IREM_IMM: case OP_LREM_UN_IMM: + case OP_IDIV_IMM: mono_decompose_op_imm (cfg, bb, ins); break; From 5c48e118c144810ebc412674fee6cc56e672d82f Mon Sep 17 00:00:00 2001 From: WuXinlong <821408745@qq.com> Date: Thu, 27 Apr 2023 11:47:03 +0800 Subject: [PATCH 18/20] fmt --- src/mono/mono/arch/riscv/riscv-codegen.h | 3 +- src/mono/mono/mini/exceptions-riscv.c | 47 +++++++++++------------- src/mono/mono/mini/mini-riscv.c | 32 ++++++++-------- src/mono/mono/mini/tramp-riscv.c | 12 +++--- 4 files changed, 46 insertions(+), 48 deletions(-) diff --git a/src/mono/mono/arch/riscv/riscv-codegen.h b/src/mono/mono/arch/riscv/riscv-codegen.h index da532188a47ac3..054c0b0744c4e3 100644 --- a/src/mono/mono/arch/riscv/riscv-codegen.h +++ b/src/mono/mono/arch/riscv/riscv-codegen.h @@ -293,8 +293,7 @@ enum { (RISCV_BITS ((ins), 12, 8) << 12) | (RISCV_SIGN ((ins)) << 20)) // Check a value for validity as an immediate. -#define RISCV_VALID_IMM32(value) \ - (((gint32)value) == (value)) +#define RISCV_VALID_IMM32(value) (((gint32)value) == (value)) #define RISCV_VALID_I_IMM(value) \ (RISCV_DECODE_I_IMM (RISCV_ENCODE_I_IMM ((value))) == (value)) #define RISCV_VALID_S_IMM(value) \ diff --git a/src/mono/mono/mini/exceptions-riscv.c b/src/mono/mono/mini/exceptions-riscv.c index 315996c967bb5c..8ae90e7e95a397 100644 --- a/src/mono/mono/mini/exceptions-riscv.c +++ b/src/mono/mono/mini/exceptions-riscv.c @@ -75,11 +75,11 @@ mono_riscv_throw_exception (gpointer arg, host_mgreg_t pc, host_mgreg_t *int_reg MonoObject *exc = NULL; guint32 ex_token_index, ex_token; if (!corlib) - exc = (MonoObject*)arg; + exc = (MonoObject *)arg; else { ex_token_index = (guint64)arg; ex_token = MONO_TOKEN_TYPE_DEF | ex_token_index; - exc = (MonoObject*)mono_exception_from_token (mono_defaults.corlib, ex_token); + exc = (MonoObject *)mono_exception_from_token (mono_defaults.corlib, ex_token); } /* Adjust pc so it points into the call instruction */ @@ -90,10 +90,10 @@ mono_riscv_throw_exception (gpointer arg, host_mgreg_t pc, host_mgreg_t *int_reg memcpy (&(ctx.gregs [0]), int_regs, sizeof (host_mgreg_t) * RISCV_N_GREGS); memcpy (&(ctx.fregs [0]), fp_regs, sizeof (host_mgreg_t) * RISCV_N_FREGS); - ctx.gregs[0] = pc; + ctx.gregs [0] = pc; if (mono_object_isinst_checked (exc, mono_defaults.exception_class, error)) { - MonoException *mono_ex = (MonoException*)exc; + MonoException *mono_ex = (MonoException *)exc; if (!rethrow && !mono_ex->caught_in_unmanaged) { mono_ex->stack_trace = NULL; mono_ex->trace_ips = NULL; @@ -130,38 +130,38 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm /* Compute stack frame size and offsets */ offset = 0; /* ra & fp */ - offset += 2 * sizeof(host_mgreg_t); + offset += 2 * sizeof (host_mgreg_t); /* gregs */ - offset += RISCV_N_GREGS * sizeof(host_mgreg_t); + offset += RISCV_N_GREGS * sizeof (host_mgreg_t); gregs_offset = offset; - + /* fregs */ num_fregs = RISCV_N_FREGS; - offset += num_fregs * sizeof(host_mgreg_t); + offset += num_fregs * sizeof (host_mgreg_t); fregs_offset = offset; frame_size = ALIGN_TO (offset, MONO_ARCH_FRAME_ALIGNMENT); MINI_BEGIN_CODEGEN (); /* Setup a frame */ - g_assert(RISCV_VALID_I_IMM(-frame_size)); + g_assert (RISCV_VALID_I_IMM (-frame_size)); riscv_addi (code, RISCV_SP, RISCV_SP, -frame_size); - code = mono_riscv_emit_store (code, RISCV_RA, RISCV_SP, frame_size - sizeof(host_mgreg_t), 0); - code = mono_riscv_emit_store (code, RISCV_FP, RISCV_SP, frame_size - 2 * sizeof(host_mgreg_t), 0); + code = mono_riscv_emit_store (code, RISCV_RA, RISCV_SP, frame_size - sizeof (host_mgreg_t), 0); + code = mono_riscv_emit_store (code, RISCV_FP, RISCV_SP, frame_size - 2 * sizeof (host_mgreg_t), 0); riscv_addi (code, RISCV_FP, RISCV_SP, frame_size); /* Save gregs */ code = mono_riscv_emit_store_stack (code, 0xffffffff, RISCV_FP, -gregs_offset, FALSE); if (corlib && !llvm) /* The real ra is in A1 */ - code = mono_riscv_emit_store (code, RISCV_A1, RISCV_FP, -gregs_offset + (RISCV_RA * sizeof(host_mgreg_t)), 0); - + code = mono_riscv_emit_store (code, RISCV_A1, RISCV_FP, -gregs_offset + (RISCV_RA * sizeof (host_mgreg_t)), 0); + /* Save previous fp/sp */ - code = mono_riscv_emit_load (code, RISCV_T0, RISCV_FP, -2 * sizeof(host_mgreg_t), 0); - code = mono_riscv_emit_store (code, RISCV_T0, RISCV_FP, -gregs_offset + (RISCV_FP * sizeof(host_mgreg_t)), 0); + code = mono_riscv_emit_load (code, RISCV_T0, RISCV_FP, -2 * sizeof (host_mgreg_t), 0); + code = mono_riscv_emit_store (code, RISCV_T0, RISCV_FP, -gregs_offset + (RISCV_FP * sizeof (host_mgreg_t)), 0); // current fp is previous sp - code = mono_riscv_emit_store (code, RISCV_FP, RISCV_FP, -gregs_offset + (RISCV_SP * sizeof(host_mgreg_t)), 0); + code = mono_riscv_emit_store (code, RISCV_FP, RISCV_FP, -gregs_offset + (RISCV_SP * sizeof (host_mgreg_t)), 0); /* Save fregs */ if (riscv_stdext_f || riscv_stdext_d) @@ -171,13 +171,12 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm /* Arg1 = exception object/type token */ // riscv_addi (code, RISCV_A0, RISCV_A0, 0); /* Arg2 = caller ip, should be return address in this case */ - if (corlib){ + if (corlib) { // caller ip are set to A1 already if (llvm) NOT_IMPLEMENTED; - } - else - code = mono_riscv_emit_load (code, RISCV_A1, RISCV_FP, -sizeof(host_mgreg_t), 0); + } else + code = mono_riscv_emit_load (code, RISCV_A1, RISCV_FP, -sizeof (host_mgreg_t), 0); /* Arg 3 = gregs */ riscv_addi (code, RISCV_A2, RISCV_FP, -gregs_offset); /* Arg 4 = fregs */ @@ -194,8 +193,7 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm /* Call the function */ if (aot) { NOT_IMPLEMENTED; - } - else { + } else { gpointer icall_func; if (resume_unwind) @@ -203,10 +201,10 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm NOT_IMPLEMENTED; else icall_func = (gpointer)mono_riscv_throw_exception; - + code = mono_riscv_emit_imm (code, RISCV_RA, (guint64)icall_func); } - riscv_jalr(code, RISCV_ZERO, RISCV_RA, 0); + riscv_jalr (code, RISCV_ZERO, RISCV_RA, 0); /* This shouldn't return */ /* hang in debugger */ riscv_ebreak (code); @@ -218,7 +216,6 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm *info = mono_tramp_info_create (tramp_name, start, code - start, ji, unwind_ops); return MINI_ADDR_TO_FTNPTR (start); - } gpointer diff --git a/src/mono/mono/mini/mini-riscv.c b/src/mono/mono/mini/mini-riscv.c index bf14593016fa6b..d5f7d416a4998b 100644 --- a/src/mono/mono/mini/mini-riscv.c +++ b/src/mono/mono/mini/mini-riscv.c @@ -939,7 +939,7 @@ get_call_info (MonoMemPool *mp, MonoMethodSignature *sig) break; default: - g_print("Unhandled retyrn type %d\n", cinfo->ret.storage); + g_print ("Unhandled retyrn type %d\n", cinfo->ret.storage); NOT_IMPLEMENTED; break; } @@ -1388,7 +1388,7 @@ emit_sig_cookie (MonoCompile *cfg, MonoCallInst *call, CallInfo *cinfo) /** * mono_arch_emit_call: -* move all Args to corresponding reg/stack in Caller + * move all Args to corresponding reg/stack in Caller * (return, parameters) */ void @@ -1505,7 +1505,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call) break; } case ArgVtypeInIReg: - case ArgVtypeByRef: + case ArgVtypeByRef: case ArgVtypeOnStack: { MonoInst *ins; guint32 align; @@ -1580,7 +1580,9 @@ mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src) load->inst_basereg = src->dreg; load->inst_offset = i; MONO_ADD_INS (cfg->cbb, load); - MONO_EMIT_NEW_STORE_MEMBASE (cfg, op_load==OP_LOADI8_MEMBASE ? OP_STOREI8_MEMBASE_REG : OP_STOREI4_MEMBASE_REG, RISCV_SP, ainfo->offset + i, load->dreg); + MONO_EMIT_NEW_STORE_MEMBASE (cfg, + op_load == OP_LOADI8_MEMBASE ? OP_STOREI8_MEMBASE_REG : OP_STOREI4_MEMBASE_REG, + RISCV_SP, ainfo->offset + i, load->dreg); } break; case ArgVtypeByRef: { @@ -2514,7 +2516,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) NULLIFY_INS (ins); } else if (ins->next->opcode == OP_IL_SEQ_POINT || ins->next->opcode == OP_MOVE || ins->next->opcode == OP_LOAD_MEMBASE || ins->next->opcode == OP_NOP || - ins->next->opcode == OP_LOADI4_MEMBASE || ins->next->opcode == OP_BR ) { + ins->next->opcode == OP_LOADI4_MEMBASE || ins->next->opcode == OP_BR) { /** * there is compare without branch OP followed * @@ -2760,7 +2762,7 @@ mono_riscv_emit_imm (guint8 *code, int rd, gsize imm) Lo = Lo - 0x1000; } - g_assert(Hi <= 0xfffff); + g_assert (Hi <= 0xfffff); riscv_lui (code, rd, Hi); riscv_addiw (code, rd, rd, Lo); return code; @@ -3005,8 +3007,8 @@ mono_riscv_emit_store_regarray (guint8 *code, guint64 regs, int basereg, int off for (int i = 0; i < 32; ++i) { if (regs & (1 << i)) { - if(isFloat) - code = mono_riscv_emit_fstore (code, i, basereg, offset + (i * sizeof(host_mgreg_t)), FALSE); + if (isFloat) + code = mono_riscv_emit_fstore (code, i, basereg, offset + (i * sizeof (host_mgreg_t)), FALSE); else code = mono_riscv_emit_store (code, i, basereg, offset + (i * sizeof (host_mgreg_t)), 0); } @@ -3036,10 +3038,10 @@ mono_riscv_emit_load_stack (guint8 *code, guint64 regs, int basereg, int offset, for (int i = 0; i < 32; ++i) { if (regs & (1 << i)) { - if(!isFloat && i == RISCV_SP) + if (!isFloat && i == RISCV_SP) g_assert_not_reached (); - if(isFloat) - code = mono_riscv_emit_fload (code, i, basereg, (offset + (pos * sizeof(host_mgreg_t))), FALSE); + if (isFloat) + code = mono_riscv_emit_fload (code, i, basereg, (offset + (pos * sizeof (host_mgreg_t))), FALSE); else code = mono_riscv_emit_load (code, i, basereg, (offset + (pos * sizeof (host_mgreg_t))), 0); pos++; @@ -3139,7 +3141,7 @@ emit_move_args (MonoCompile *cfg, guint8 *code) if (ins->opcode == OP_REGVAR) { switch (ainfo->storage) { case ArgInIReg: - if(ins->dreg != ainfo->reg) + if (ins->dreg != ainfo->reg) riscv_addi (code, ins->dreg, ainfo->reg, 0); if (i == 0 && sig->hasthis) { mono_add_var_location (cfg, ins, TRUE, ainfo->reg, 0, 0, code - cfg->native_code); @@ -3147,10 +3149,10 @@ emit_move_args (MonoCompile *cfg, guint8 *code) } break; case ArgOnStack: - code = mono_riscv_emit_load(code, ins->dreg, RISCV_FP, ainfo->offset, ainfo->slot_size); + code = mono_riscv_emit_load (code, ins->dreg, RISCV_FP, ainfo->offset, ainfo->slot_size); break; default: - g_print("Can't handle arg type %d\n", ainfo->storage); + g_print ("Can't handle arg type %d\n", ainfo->storage); NOT_IMPLEMENTED; } } else { @@ -3252,7 +3254,7 @@ mono_riscv_emit_call (MonoCompile *cfg, guint8 *code, MonoJumpInfoType patch_typ static guint8 * mono_riscv_emit_branch_exc (MonoCompile *cfg, guint8 *code, int opcode, int sreg1, int sreg2, const char *exc_name) { - riscv_auipc(code, RISCV_T0, 0); + riscv_auipc (code, RISCV_T0, 0); switch (opcode) { case OP_RISCV_EXC_BEQ: riscv_bne (code, sreg1, sreg2, 8); diff --git a/src/mono/mono/mini/tramp-riscv.c b/src/mono/mono/mini/tramp-riscv.c index 7f69f4873e9b91..414c3a46bda34b 100644 --- a/src/mono/mono/mini/tramp-riscv.c +++ b/src/mono/mono/mini/tramp-riscv.c @@ -168,14 +168,14 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf /* a0 contains the address of the tls slot holding the current (MonoLMF **)lmf */ /* T0 = lmf */ - riscv_addi(code, RISCV_T0, RISCV_FP, -lmf_offset); + riscv_addi (code, RISCV_T0, RISCV_FP, -lmf_offset); /* lmf->lmf_addr = lmf_addr */ - code = mono_riscv_emit_store(code, RISCV_A0, RISCV_T0, MONO_STRUCT_OFFSET (MonoLMF, lmf_addr), 0); + code = mono_riscv_emit_store (code, RISCV_A0, RISCV_T0, MONO_STRUCT_OFFSET (MonoLMF, lmf_addr), 0); /* lmf->previous_lmf = *lmf_addr */ - code = mono_riscv_emit_load(code, RISCV_T1, RISCV_A0, 0, 0); - code = mono_riscv_emit_store(code, RISCV_T1, RISCV_T0, MONO_STRUCT_OFFSET (MonoLMF, previous_lmf), 0); + code = mono_riscv_emit_load (code, RISCV_T1, RISCV_A0, 0, 0); + code = mono_riscv_emit_store (code, RISCV_T1, RISCV_T0, MONO_STRUCT_OFFSET (MonoLMF, previous_lmf), 0); /* *lmf_addr = lmf */ code = mono_riscv_emit_store (code, RISCV_T0, RISCV_A0, 0, 0); @@ -215,9 +215,9 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf /* T0 = lmf */ riscv_addi (code, RISCV_T0, RISCV_FP, -lmf_offset); /* T1 = lmf->previous_lmf */ - code = mono_riscv_emit_load(code, RISCV_T1, RISCV_T0, MONO_STRUCT_OFFSET (MonoLMF, previous_lmf), 0); + code = mono_riscv_emit_load (code, RISCV_T1, RISCV_T0, MONO_STRUCT_OFFSET (MonoLMF, previous_lmf), 0); /* T0 = lmf->lmf_addr */ - code = mono_riscv_emit_load(code, RISCV_T0, RISCV_T0, MONO_STRUCT_OFFSET (MonoLMF, lmf_addr), 0); + code = mono_riscv_emit_load (code, RISCV_T0, RISCV_T0, MONO_STRUCT_OFFSET (MonoLMF, lmf_addr), 0); /* *lmf_addr = previous_lmf */ code = mono_riscv_emit_store (code, RISCV_T1, RISCV_T0, 0, 0); From 85edadf0f3268eb88131bad6d678b0c5ac88a46c Mon Sep 17 00:00:00 2001 From: WuXinlong <821408745@qq.com> Date: Thu, 27 Apr 2023 11:47:46 +0800 Subject: [PATCH 19/20] remove test file --- src/mono/.clang-format | 83 ------------ src/mono/sample/TestRun/Makefile | 51 -------- src/mono/sample/TestRun/TestRun.cs | 17 --- src/mono/sample/TestRun/TestRun.csproj | 38 ------ .../sample/TestRun/TestRun.runtimeconfig.json | 9 -- src/mono/sample/TestRun/test_emit_imm.c | 120 ------------------ 6 files changed, 318 deletions(-) delete mode 100644 src/mono/.clang-format delete mode 100644 src/mono/sample/TestRun/Makefile delete mode 100644 src/mono/sample/TestRun/TestRun.cs delete mode 100644 src/mono/sample/TestRun/TestRun.csproj delete mode 100644 src/mono/sample/TestRun/TestRun.runtimeconfig.json delete mode 100644 src/mono/sample/TestRun/test_emit_imm.c diff --git a/src/mono/.clang-format b/src/mono/.clang-format deleted file mode 100644 index fa2c3737dccb79..00000000000000 --- a/src/mono/.clang-format +++ /dev/null @@ -1,83 +0,0 @@ ---- -Language: Cpp -AccessModifierOffset: -4 -AlignAfterOpenBracket: Align -AlignConsecutiveAssignments: false -AlignConsecutiveDeclarations: false -AlignConsecutiveMacros: - Enabled: true -AlignEscapedNewlinesLeft: false -AlignOperands: true -AlignTrailingComments: true -AllowAllParametersOfDeclarationOnNextLine: true -AllowShortBlocksOnASingleLine: false -AllowShortCaseLabelsOnASingleLine: false -AllowShortFunctionsOnASingleLine: false -AllowShortIfStatementsOnASingleLine: false -AllowShortLoopsOnASingleLine: false -AlwaysBreakAfterReturnType : AllDefinitions -AlwaysBreakBeforeMultilineStrings: false -AlwaysBreakTemplateDeclarations: true -BinPackArguments: true -BinPackParameters: false -BraceWrapping: - AfterClass: true - AfterControlStatement: true - AfterEnum: false - AfterFunction: true - AfterNamespace: false - AfterObjCDeclaration: false - AfterStruct: true - AfterUnion: true - BeforeCatch: true - BeforeElse: true - IndentBraces: false -BreakBeforeBinaryOperators: None -BreakBeforeBraces: Linux -BreakBeforeTernaryOperators: true -BreakConstructorInitializersBeforeComma: true -ColumnLimit: 120 -CommentPragmas: '^ IWYU pragma:' -ConstructorInitializerAllOnOneLineOrOnePerLine: true -ConstructorInitializerIndentWidth: 4 -ContinuationIndentWidth: 4 -Cpp11BracedListStyle: true -DerivePointerAlignment: false -DisableFormat: false -ExperimentalAutoDetectBinPacking: false -ForEachMacros: [ ] -IndentCaseLabels: false -IndentWidth: 4 -IndentWrappedFunctionNames: false -KeepEmptyLinesAtTheStartOfBlocks: true -MacroBlockBegin: '' -MacroBlockEnd: '' -MaxEmptyLinesToKeep: 1 -NamespaceIndentation: None -ObjCBlockIndentWidth: 2 -ObjCSpaceAfterProperty: false -ObjCSpaceBeforeProtocolList: true -PenaltyBreakBeforeFirstCallParameter: 400 -PenaltyBreakComment: 50 -PenaltyBreakFirstLessLess: 500 -PenaltyBreakString: 1000 -PenaltyExcessCharacter: 1000000 -PenaltyReturnTypeOnItsOwnLine: 100000 -PointerAlignment: Right -ReflowComments: true -SortIncludes: false -SpaceAfterCStyleCast: false -SpaceBeforeAssignmentOperators: true -SpaceBeforeParens: Always -SpaceBeforeSquareBrackets: true -SpaceInEmptyParentheses: false -SpacesBeforeTrailingComments: 1 -SpacesInAngles: false -SpacesInContainerLiterals: true -SpacesInCStyleCastParentheses: false -SpacesInParentheses: false -SpacesInSquareBrackets: false -Standard: Cpp11 -TabWidth: 4 -UseTab: ForIndentation -... diff --git a/src/mono/sample/TestRun/Makefile b/src/mono/sample/TestRun/Makefile deleted file mode 100644 index 09fa37ce83f62d..00000000000000 --- a/src/mono/sample/TestRun/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -TOP=../../../../ -DOTNET:=$(TOP)dotnet.sh -DOTNET_Q_ARGS=--nologo -v:q -consoleloggerparameters:NoSummary - -MONO_CONFIG?=Debug -MONO_ARCH=riscv64 -TARGET_OS=linux -AOT?=false - -#NET_TRACE_PATH= -#PGO_BINARY_PATH= -#MIBC_PROFILE_PATH= - -MONO_ENV_DEBUG_OPTIONS = "-v " -MONO_ENV_RUN_OPTIONS = "" - -build: TestRun.cs - @csc TestRun.cs - -run-baseline: build - COMPlus_DebugWriteToStdErr=1 \ - MONO_ENV_OPTIONS=$(MONO_ENV_RUN_OPTIONS) \ - $(TOP)artifacts/bin/testhost/net8.0-$(TARGET_OS)-Debug-x64/dotnet TestRun.exe - -run: build - @COMPlus_DebugWriteToStdErr=1 \ - MONO_ENV_OPTIONS=$(MONO_ENV_RUN_OPTIONS) \ - qemu-riscv64 -L $(TOP)/.tools/rootfs/riscv64/ $(TOP)artifacts/bin/testhost/net8.0-$(TARGET_OS)-Debug-$(MONO_ARCH)/dotnet TestRun.exe - -debug: build - COMPlus_DebugWriteToStdErr=1 \ - MONO_LOG_LEVEL=debug MONO_LOG_MASK=all \ - MONO_ENV_OPTIONS=$(MONO_ENV_DEBUG_OPTIONS) \ - qemu-riscv64 -L $(TOP)/.tools/rootfs/riscv64/ \ - -g 12345 \ - $(TOP)artifacts/bin/testhost/net8.0-$(TARGET_OS)-Debug-$(MONO_ARCH)/dotnet TestRun.exe &\ - riscv64-unknown-linux-gnu-gdb -ex 'target remote localhost:12345' \ - -ex "set sysroot $(TOP).tools/rootfs/riscv64" -ex "set solib-search-path $(TOP)artifacts/bin/testhost/net8.0-linux-Debug-riscv64/shared/Microsoft.NETCore.App/8.0.0" \ - -ex "b mini.c:2152 " \ - $(TOP)artifacts/bin/testhost/net8.0-$(TARGET_OS)-Debug-$(MONO_ARCH)/dotnet - -clean: - rm -f *.exe *.exe.mdb - - -# COMPlus_DebugWriteToStdErr="1" MONO_LOG_LEVEL="debug" MONO_LOG_MASK="all" COREHOST_TRACE="1" COREHOST_TRACE_VERBOSITY="4" MONO_ENV_OPTIONS="--compile-all --trace=all" qemu-riscv64 -L ../../../..//.tools/rootfs/riscv64/ -g 12345 ../../../../artifacts/bin/testhost/net8.0-Linux-Debug-riscv64/dotnet TestRun.exe - -ROOTFS_DIR="" ./build.sh mono+libs+host -c Debug -./build.sh mono+libs+host -c Debug --cross --arch riscv64 --build - -ROOTFS_DIR="" ./build.sh clr.hosts -c Debug diff --git a/src/mono/sample/TestRun/TestRun.cs b/src/mono/sample/TestRun/TestRun.cs deleted file mode 100644 index ed1ee5c4280543..00000000000000 --- a/src/mono/sample/TestRun/TestRun.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -namespace HelloWorld -{ - class Program - { - static int test(int c){ - return 1 / c; - } - static int Main() - { - Console.WriteLine($"IsMono: {Type.GetType("Mono.RuntimeStructs") != null}"); - Console.WriteLine("Hello RISC-V"); - // test(0); - return 0; - } - } -} diff --git a/src/mono/sample/TestRun/TestRun.csproj b/src/mono/sample/TestRun/TestRun.csproj deleted file mode 100644 index ef55589c8c175c..00000000000000 --- a/src/mono/sample/TestRun/TestRun.csproj +++ /dev/null @@ -1,38 +0,0 @@ - - - Exe - $(NetCoreAppCurrent) - - - - - - - <_AotOutputType>Library - <_AotLibraryFormat>Dylib - false - - - - - - - - - - - - diff --git a/src/mono/sample/TestRun/TestRun.runtimeconfig.json b/src/mono/sample/TestRun/TestRun.runtimeconfig.json deleted file mode 100644 index 73898c2b118e0a..00000000000000 --- a/src/mono/sample/TestRun/TestRun.runtimeconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "runtimeOptions": { - "framework": { - "name": "Microsoft.NETCore.App", - "version": "8.0.0" - } - } - } - \ No newline at end of file diff --git a/src/mono/sample/TestRun/test_emit_imm.c b/src/mono/sample/TestRun/test_emit_imm.c deleted file mode 100644 index d192ed6f07cd79..00000000000000 --- a/src/mono/sample/TestRun/test_emit_imm.c +++ /dev/null @@ -1,120 +0,0 @@ -#include -#include - -typedef signed char gint8; -typedef unsigned char guint8; -typedef signed int gint32; -typedef unsigned int guint32; -typedef unsigned int gsize; -typedef signed int gssize; - -#define _riscv_emit(p, insn) \ - do { \ - *(guint32 *) (p) = (insn); \ - (p) += sizeof (guint32); \ - } while (0) - -#define RISCV_BITS(value, start, count) (((value) >> (start)) & ((1 << (count)) - 1)) -#define RISCV_SIGN(value) (-(((value) >> (sizeof (guint32) * 8 - 1)) & 1)) - -#define RISCV_VALID_IMM32(value) \ - (((gint32)value) == (value)) - -#define RISCV_ENCODE_I_IMM(imm) \ - (RISCV_BITS ((imm), 0, 12) << 20) - -#define RISCV_DECODE_I_IMM(ins) \ - ((RISCV_BITS ((ins), 20, 12) << 0) | (RISCV_SIGN ((ins)) << 12)) - -#define RISCV_VALID_I_IMM(value) \ - (RISCV_DECODE_I_IMM (RISCV_ENCODE_I_IMM ((value))) == (value)) - -#define RISCV_DECODE_U_IMM(ins) \ - (RISCV_BITS ((ins), 12, 20) << 0) - -#define RISCV_ENCODE_U_IMM(imm) \ - (RISCV_BITS ((imm), 0, 20) << 12) - -#define RISCV_VALID_U_IMM(value) \ - (RISCV_DECODE_U_IMM (RISCV_ENCODE_U_IMM ((value))) == (value)) - -#define _riscv_u_op(p, opcode, rd, imm) \ - do { \ - assert (RISCV_VALID_U_IMM ((guint32) (gsize) (imm))); \ - _riscv_emit ((p), ((opcode) << 0) | \ - ((rd) << 7) | \ - (RISCV_ENCODE_U_IMM ((guint32) (gsize) (imm)))); \ - } while (0) - -#define _riscv_i_op(p, opcode, funct3, rd, rs1, imm) \ - do { \ - assert (RISCV_VALID_I_IMM ((gint32) (gssize) (imm))); \ - _riscv_emit ((p), ((opcode) << 0) | \ - ((rd) << 7) | \ - ((funct3) << 12) | \ - ((rs1) << 15) | \ - (RISCV_ENCODE_I_IMM ((gint32) (gssize) (imm)))); \ - } while (0) - -#define riscv_lui(p, rd, imm) _riscv_u_op ((p), 0b0110111, (rd), (imm)) -#define riscv_addi(p, rd, rs1, imm) _riscv_i_op ((p), 0b0010011, 0b000, (rd), (rs1), (imm)) -#define riscv_addiw(p, rd, rs1, imm) _riscv_i_op ((p), 0b0011011, 0b000, (rd), (rs1), (imm)) -#define riscv_jalr(p, rd, rs1, imm) _riscv_i_op ((p), 0b1100111, 0b000, (rd), (rs1), (imm)) - -guint8 * -mono_riscv_emit_imm (guint8 *code, int rd, gsize imm) -{ - if (RISCV_VALID_I_IMM (imm)) { - riscv_addi (code, rd, 0, imm); - return code; - } - - /** - * use LUI & ADDIW load 32 bit Imm - * LUI: High 20 bit of imm - * ADDIW: Low 12 bit of imm - */ - if (RISCV_VALID_IMM32 (imm)) { - gint32 Hi = RISCV_BITS (imm, 12, 20); - gint32 Lo = RISCV_BITS (imm, 0, 12); - - // Lo is in signed num - // if Lo >= 0x800 - // convert into ((Hi + 1) << 20) - (0x1000 - Lo) - if (Lo >= 0x800) { - if (imm > 0) - Hi += 1; - Lo = Lo - 0x1000; - } - - assert(Hi <= 0xfffff); - riscv_lui (code, rd, Hi); - riscv_addiw (code, rd, rd, Lo); - return code; - } - - assert(0); -} - -int main(int argc, char const *argv[]) -{ - - - gint8 *code = malloc(10*sizeof(gint8)); - for (int i = -1118200000; i < 2147483647; i++) - { - gint8 *p = mono_riscv_emit_imm(code, 10, i); - riscv_jalr(p, 0, 1, 0); - - int (* func)() = code; - int res = func(); - if(i != res){ - printf("except: %d, got = %d\n", i, res); - return 1; - } - if(i % 1000000 == 0) - printf("progress: %d\n",i); - } - printf("all correct\n"); - return 0; -} From 265c8c6b8faf2813bc83021e22ff15fe6b1708d4 Mon Sep 17 00:00:00 2001 From: WuXinlong <821408745@qq.com> Date: Thu, 4 May 2023 19:04:00 +0800 Subject: [PATCH 20/20] address comment --- src/mono/mono/metadata/jit-icall-reg.h | 1 - src/mono/mono/mini/mini-riscv.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mono/mono/metadata/jit-icall-reg.h b/src/mono/mono/metadata/jit-icall-reg.h index 53bea08c538479..984c26721eec57 100644 --- a/src/mono/mono/metadata/jit-icall-reg.h +++ b/src/mono/mono/metadata/jit-icall-reg.h @@ -340,7 +340,6 @@ MONO_JIT_ICALL (ves_icall_thread_finish_async_abort) \ MONO_JIT_ICALL (mono_marshal_lookup_pinvoke) \ MONO_JIT_ICALL (mono_gsharedvt_constrained_call_fast) \ MONO_JIT_ICALL (mono_dummy_runtime_init_callback) \ -MONO_JIT_ICALL (mono_riscv_throw_exception) \ \ MONO_JIT_ICALL (count) \ diff --git a/src/mono/mono/mini/mini-riscv.c b/src/mono/mono/mini/mini-riscv.c index d5f7d416a4998b..0d9a779ee9dab5 100644 --- a/src/mono/mono/mini/mini-riscv.c +++ b/src/mono/mono/mini/mini-riscv.c @@ -2704,7 +2704,7 @@ mono_arch_lowering_pass (MonoCompile *cfg, MonoBasicBlock *bb) } #endif default: - printf ("unable to lowering following IR:"); + printf ("unable to lower the following IR:"); mono_print_ins (ins); NOT_IMPLEMENTED; break;