未验证 提交 c0b05ae1 编写于 作者: V VincentWu 提交者: GitHub

[RISC-V] Port Mono for RISC-V 64 Arch (1/3) lp64d ABI (#83714)

* support abi lp64d for RISC-V 64

* format
上级 730a0300
......@@ -656,7 +656,7 @@
<_Objcopy Condition="'$(TargetsAndroid)' == 'true' or '$(TargetsLinuxBionic)' == 'true'">$(ANDROID_NDK_ROOT)/toolchains/llvm/prebuilt/$(MonoToolchainPrebuiltOS)/bin/llvm-objcopy</_Objcopy>
<_Objcopy Condition="'$(TargetsLinuxMusl)' == 'true' and '$(CrossBuild)' != 'true'">objcopy</_Objcopy>
<_ObjcopyPrefix Condition="'$(MonoCrossDir)' != '' and '$(Platform)' == 'riscv64'">llvm-objcopy-</_ObjcopyPrefix>
<_ObjcopyPrefix Condition="'$(MonoCrossDir)' != '' and '$(Platform)' == 'riscv64' and $(_Objcopy) == ''">llvm-objcopy-</_ObjcopyPrefix>
</PropertyGroup>
<!-- test viability of objcopy command -->
<Exec Condition="'$(BuildMonoAOTCrossCompilerOnly)' != 'true' and ('$(TargetsLinux)' == 'true' or '$(TargetsAndroid)' == 'true' or '$(TargetsLinuxBionic)' == 'true')" Command="$(_Objcopy) -V" IgnoreStandardErrorWarningFormat="true" ContinueOnError="WarnAndContinue" IgnoreExitCode="true" EchoOff="true" ConsoleToMsBuild="true">
......
......@@ -293,7 +293,8 @@ enum {
(RISCV_BITS ((ins), 12, 8) << 12) | (RISCV_SIGN ((ins)) << 20))
// Check a value for validity as an immediate.
#define RISCV_VALID_IMM(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) \
......
......@@ -255,6 +255,9 @@ DECL_OFFSET(MonoLMF, eip)
DECL_OFFSET(MonoLMF, gregs)
DECL_OFFSET(MonoLMF, fregs)
#elif defined(TARGET_RISCV)
DECL_OFFSET(MonoLMF, lmf_addr)
DECL_OFFSET(MonoLMF, pc)
DECL_OFFSET(MonoLMF, gregs)
DECL_OFFSET(MonoContext, gregs)
DECL_OFFSET(MonoContext, fregs)
#endif
......@@ -314,6 +317,13 @@ DECL_OFFSET(CallContext, stack_size)
DECL_OFFSET(CallContext, stack)
#endif
#if defined(TARGET_RISCV)
DECL_OFFSET(CallContext, gregs)
DECL_OFFSET(CallContext, fregs)
DECL_OFFSET(CallContext, stack_size)
DECL_OFFSET(CallContext, stack)
#endif
#if defined(TARGET_X86)
DECL_OFFSET(GSharedVtCallInfo, stack_usage)
DECL_OFFSET(GSharedVtCallInfo, vret_slot)
......
......@@ -69,7 +69,11 @@ static const gint16 opidx [] = {
#endif
#ifdef TARGET_RISCV64
#define ARCH_PREFIX "riscv64-linux-gnu-"
#else
#define ARCH_PREFIX ""
#endif
//#define ARCH_PREFIX "powerpc64-linux-gnu-"
const char*
......
此差异已折叠。
......@@ -14,6 +14,9 @@
#define MONO_RISCV_ARCHITECTURE "riscv32"
#endif
extern gboolean riscv_stdext_a, riscv_stdext_b, riscv_stdext_c, riscv_stdext_d, riscv_stdext_f, riscv_stdext_j,
riscv_stdext_l, riscv_stdext_m, riscv_stdext_n, riscv_stdext_p, riscv_stdext_q, riscv_stdext_t, riscv_stdext_v;
#if defined (RISCV_FPABI_SOFT)
#define MONO_ARCH_SOFT_FLOAT_FALLBACK
#define RISCV_FP_MODEL "soft-fp"
......@@ -54,8 +57,20 @@
* - x0 is hard-wired to zero and can't be allocated by the register allocator.
*/
#define MONO_ARCH_ARGUMENT_REGS (0b00000000000000111111110000000000)
#define MONO_ARCH_IS_ARGUMENT_REGS(reg) (MONO_ARCH_ARGUMENT_REGS & (1 << (reg)))
#define MONO_ARCH_CALLEE_REGS (0b11110000000000111111110000000000)
#define MONO_ARCH_CALLEE_SAVED_REGS (0b00001111111111000000001100000000)
#define MONO_ARCH_IS_CALLEE_SAVED_REG(reg) (MONO_ARCH_CALLEE_SAVED_REGS & (1 << (reg)))
/**
* callee saved regs + sp
* fp aka s0 is firse reg in LMF_REGS
*/
#define MONO_ARCH_LMF_REGS ((MONO_ARCH_CALLEE_SAVED_REGS) | (1 << RISCV_SP))
#define MONO_ARCH_FIRST_LMF_REG RISCV_S0
#define MONO_ARCH_LMF_REG_FP RISCV_S0
#define MONO_ARCH_LMF_REG_SP RISCV_SP
#ifdef RISCV_FPABI_SOFT
......@@ -64,6 +79,8 @@
#else
#define MONO_ARCH_ARGUMENT_FREGS (0b00000000000000111111110000000000)
#define MONO_ARCH_IS_ARGUMENT_FREGS(reg) (MONO_ARCH_ARGUMENT_FREGS & (1 << (reg)))
#define MONO_ARCH_CALLEE_FREGS (0b11110000000000111111110011111000)
#define MONO_ARCH_CALLEE_SAVED_FREGS (0b00001111111111000000001100000000)
......@@ -94,8 +111,8 @@
#endif
#define MONO_ARCH_RGCTX_REG (RISCV_T2)
#define MONO_ARCH_IMT_REG (RISCV_T2)
#define MONO_ARCH_RGCTX_REG (RISCV_T6)
#define MONO_ARCH_IMT_REG MONO_ARCH_RGCTX_REG
#define MONO_ARCH_VTABLE_REG (RISCV_A0)
#define MONO_ARCH_HAVE_VOLATILE_NON_PARAM_REGISTER 0
......@@ -103,6 +120,7 @@
#define MONO_ARCH_FRAME_ALIGNMENT (16)
#define MONO_ARCH_CODE_ALIGNMENT (32)
// TODO: remove following def
#define MONO_ARCH_EMULATE_MUL_DIV (1)
#define MONO_ARCH_EMULATE_FREM (1)
......@@ -119,12 +137,12 @@
#define MONO_ARCH_EMULATE_LCONV_TO_R8 (1)
#define MONO_ARCH_EMULATE_LCONV_TO_R4 (1)
#define MONO_ARCH_EMULATE_LCONV_TO_R8_UN (1)
#define MONO_ARCH_EMULATE_LONG_MUL_OVF_OPTS (1)
#define MONO_ARCH_NEED_DIV_CHECK (1)
#define MONO_ARCH_HAVE_OP_TAIL_CALL (1)
#define MONO_ARCH_HAVE_OP_GENERIC_CLASS_INIT (1)
#define MONO_ARCH_HAVE_CARD_TABLE_WBARRIER (1)
#define MONO_ARCH_HAVE_GENERALIZED_IMT_TRAMPOLINE (1)
#define MONO_ARCH_HAVE_GENERAL_RGCTX_LAZY_FETCH_TRAMPOLINE (1)
......@@ -152,9 +170,20 @@
// #define MONO_ARCH_HAVE_INTERP_ENTRY_TRAMPOLINE (1)
// #define MONO_ARCH_HAVE_INTERP_PINVOKE_TRAMP (1)
// #define MONO_ARCH_HAVE_INTERP_NATIVE_TO_MANAGED (1)
#define MONO_ARCH_HAVE_INTERP_NATIVE_TO_MANAGED (1)
#define THUNK_SIZE (4 * 4 + 8)
typedef struct {
CallInfo *cinfo;
int saved_gregs_offset;
guint32 saved_iregs;
MonoInst *vret_addr_loc;
MonoInst *seq_point_info_var;
MonoInst *ss_tramp_var;
MonoInst *bp_tramp_var;
guint8 *thunks;
int thunks_size;
} MonoCompileArch;
#define MONO_CONTEXT_SET_LLVM_EXC_REG(ctx, exc) \
......@@ -170,40 +199,126 @@ typedef struct {
} while (0)
struct MonoLMF {
// If the second-lowest bit of this field is set, this is a MonoLMFExt.
gpointer previous_lmf;
gpointer lmf_addr;
host_mgreg_t pc;
host_mgreg_t sp;
host_mgreg_t ra;
host_mgreg_t gregs [RISCV_N_GSREGS]; // s0..s11
double fregs [RISCV_N_FSREGS]; // fs0..fs11
host_mgreg_t gregs [RISCV_N_GREGS];
};
/* Structure used by the sequence points in AOTed code */
struct SeqPointInfo {
gpointer ss_tramp_addr;
guint8 *bp_addrs [MONO_ZERO_LEN_ARRAY];
};
#define MONO_ARCH_INIT_TOP_LMF_ENTRY(lmf)
typedef struct {
/* General registers */
target_mgreg_t gregs [RISCV_N_GREGS];
/* Floating registers */
double fregs [RISCV_N_FREGS];
/* Stack usage, used for passing params on stack */
guint32 stack_size;
guint8 *stack;
} CallContext;
typedef enum {
ArgInIReg = 0x01,
ArgOnStack,
ArgInFReg,
#ifdef TARGET_RISCV64
ArgInFRegR4,
#endif
ArgOnStackR4,
ArgOnStackR8,
ArgStructByVal,
ArgStructByAddr,
/*
* Vtype passed in consecutive int registers.
*/
ArgVtypeByRef,
ArgVtypeByRefOnStack,
ArgVtypeOnStack,
ArgVtypeInIReg,
ArgVtypeInMixed,
ArgNone // only in void return type
} ArgStorage;
typedef struct {
ArgStorage storage;
/* ArgVtypeInIRegs */
guint8 reg;
int size;
guint8 is_regpair;
/* ArgOnStack */
int slot_size;
gint32 offset;
guint8 is_signed : 1;
} ArgInfo;
struct CallInfo {
int nargs;
guint32 next_arg, next_farg;
gboolean pinvoke, vararg;
guint32 stack_usage;
guint32 struct_ret;
ArgInfo ret;
ArgInfo sig_cookie;
ArgInfo args [1];
};
/* Relocations */
enum {
MONO_R_RISCV_IMM = 1,
MONO_R_RISCV_B = 2,
MONO_R_RISCV_BEQ = 3,
MONO_R_RISCV_BNE = 4,
MONO_R_RISCV_BLT = 5,
MONO_R_RISCV_BGE = 6,
MONO_R_RISCV_IMM = 1,
MONO_R_RISCV_B = 2,
MONO_R_RISCV_BEQ = 3,
MONO_R_RISCV_BNE = 4,
MONO_R_RISCV_BLT = 5,
MONO_R_RISCV_BGE = 6,
MONO_R_RISCV_BLTU = 7,
MONO_R_RISCV_BGEU = 8,
MONO_R_RISCV_JAL = 9,
MONO_R_RISCV_JALR = 10,
};
__attribute__ ((warn_unused_result)) guint8 *
mono_riscv_emit_imm (guint8 *code, int rd, gsize imm);
__attribute__ ((warn_unused_result)) guint8 *
mono_riscv_emit_load (guint8 *code, int rd, int rs1, gint32 imm);
__attribute__ ((warn_unused_result)) guint8 *mono_riscv_emit_float_imm (guint8 *code,
int rd,
gsize f_imm,
gboolean isSingle);
__attribute__ ((warn_unused_result)) guint8 *
mono_riscv_emit_store (guint8 *code, int rs1, int rs2, gint32 imm);
__attribute__ ((warn_unused_result)) guint8 *mono_riscv_emit_nop (guint8 *code);
__attribute__ ((warn_unused_result)) guint8 *mono_riscv_emit_load (
guint8 *code, int rd, int rs1, gint32 imm, int length);
__attribute__ ((warn_unused_result)) guint8 *mono_riscv_emit_fload (
guint8 *code, int rd, int rs1, gint32 imm, gboolean isSingle);
__attribute__ ((warn_unused_result)) guint8 *mono_riscv_emit_store (
guint8 *code, int rs2, int rs1, gint32 imm, int length);
__attribute__ ((warn_unused_result)) guint8 *mono_riscv_emit_fstore (
guint8 *code, int rs2, int rs1, gint32 imm, gboolean isSingle);
__attribute__ ((__warn_unused_result__)) guint8 *mono_riscv_emit_destroy_frame (guint8 *code);
__attribute__ ((warn_unused_result)) guint8 *mono_riscv_emit_store_stack (
guint8 *code, guint64 regs, int basereg, int offset, gboolean isFloat);
__attribute__ ((warn_unused_result)) guint8 *mono_riscv_emit_load_stack (
guint8 *code, guint64 used_regs, int basereg, int offset, gboolean isFloat);
__attribute__ ((__warn_unused_result__)) guint8 *mono_riscv_emit_store_regarray (
guint8 *code, guint64 regs, int basereg, int offset, gboolean isFloat);
__attribute__ ((__warn_unused_result__)) guint8 *mono_riscv_emit_load_regarray (
guint8 *code, guint64 regs, int basereg, int offset, gboolean isFloat);
__attribute__ ((__warn_unused_result__)) void mono_riscv_patch (guint8 *code, guint8 *target, int relocation);
#endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册