4 * Copyright 2013 Xamarin Inc
8 * Copyright 2011 Xamarin Inc
9 * Licensed under the MIT license. See LICENSE file in the project root for full license information.
12 #ifndef __MONO_MINI_ARM64_H__
13 #define __MONO_MINI_ARM64_H__
15 #include <mono/arch/arm64/arm64-codegen.h>
16 #include <mono/mini/mini-arm64-gsharedvt.h>
18 #define MONO_ARCH_CPU_SPEC mono_arm64_cpu_desc
20 #define MONO_MAX_IREGS 32
21 #define MONO_MAX_FREGS 32
23 #define MONO_CONTEXT_SET_LLVM_EXC_REG(ctx, exc) do { (ctx)->regs [0] = (gsize)exc; } while (0)
25 #define MONO_INIT_CONTEXT_FROM_FUNC(ctx,func) do { \
26 MONO_CONTEXT_SET_BP ((ctx), __builtin_frame_address (0)); \
27 MONO_CONTEXT_SET_SP ((ctx), __builtin_frame_address (0)); \
28 MONO_CONTEXT_SET_IP ((ctx), (func)); \
31 #define MONO_ARCH_INIT_TOP_LMF_ENTRY(lmf)
33 /* Parameters used by the register allocator */
34 /* r0..r7, r9..r14 (r15 is the imt/rgctx reg) */
35 #define MONO_ARCH_CALLEE_REGS 0xfeff
37 #define MONO_ARCH_CALLEE_SAVED_REGS (0x3ff << 19)
39 /* v16/v17 is reserved for a scratch reg */
40 #define MONO_ARCH_CALLEE_FREGS 0xfffc00ff
42 #define MONO_ARCH_CALLEE_SAVED_FREGS 0xff00
44 #define MONO_ARCH_USE_FPSTACK FALSE
46 #define MONO_ARCH_INST_SREG2_MASK(ins) (0)
48 #define MONO_ARCH_INST_FIXED_REG(desc) ((desc) == 'a' ? ARMREG_R0 : -1)
50 #define MONO_ARCH_INST_IS_REGPAIR(desc) (0)
52 #define MONO_ARCH_INST_IS_FLOAT(desc) ((desc) == 'f')
54 #define MONO_ARCH_INST_REGPAIR_REG2(desc,hreg1) (-1)
56 #define MONO_ARCH_USE_FPSTACK FALSE
58 #define MONO_ARCH_FRAME_ALIGNMENT 16
60 #define MONO_ARCH_CODE_ALIGNMENT 32
62 /* callee saved regs + fp + sp */
63 #define MONO_ARCH_LMF_REGS ((0x3ff << 19) | (1 << ARMREG_FP) | (1 << ARMREG_SP))
64 #define MONO_ARCH_NUM_LMF_REGS (10 + 2)
65 #define MONO_ARCH_FIRST_LMF_REG ARMREG_R19
66 #define MONO_ARCH_LMF_REG_FP 10
67 #define MONO_ARCH_LMF_REG_SP 11
71 * If the second lowest bit is set to 1, then this is a MonoLMFExt structure, and
72 * the other fields are not valid.
74 gpointer previous_lmf
;
77 host_mgreg_t gregs
[MONO_ARCH_NUM_LMF_REGS
];
80 /* Structure used by the sequence points in AOTed code */
82 gpointer ss_trigger_page
;
83 gpointer bp_trigger_page
;
84 gpointer ss_tramp_addr
;
85 guint8
* bp_addrs
[MONO_ZERO_LEN_ARRAY
];
89 #define FP_PARAM_REGS 8
92 host_mgreg_t res
, res2
;
94 double fpregs
[FP_PARAM_REGS
];
95 int n_fpargs
, n_fpret
, n_stackargs
;
96 /* This should come last as the structure is dynamically extended */
97 /* The +1 is for r8 */
98 host_mgreg_t regs
[PARAM_REGS
+ 1];
103 int saved_gregs_offset
;
104 /* Points to arguments received on the stack */
106 gboolean cond_branch_islands
;
107 MonoInst
*vret_addr_loc
;
108 MonoInst
*seq_point_info_var
;
109 MonoInst
*ss_tramp_var
;
110 MonoInst
*bp_tramp_var
;
115 #ifdef MONO_ARCH_ILP32
116 /* For the watch (starting with series 4), a new ABI is introduced: arm64_32.
117 * We can still use the older AOT compiler to produce bitcode, because it's
118 * "offset compatible". However, since it is targeting arm7k, it makes certain
119 * assumptions that we need to align here. */
120 #define MONO_ARCH_EMULATE_FCONV_TO_I8 1
121 #define MONO_ARCH_EMULATE_FCONV_TO_U8 1
122 #define MONO_ARCH_EMULATE_LCONV_TO_R8 1
123 #define MONO_ARCH_EMULATE_LCONV_TO_R4 1
124 #define MONO_ARCH_EMULATE_LCONV_TO_R8_UN 1
125 #define MONO_ARCH_EMULATE_DIV 1
126 #define MONO_ARCH_EMULATE_CONV_R8_UN 1
128 #define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS 1
129 #define MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS 1
132 #define MONO_ARCH_EMULATE_FREM 1
133 #define MONO_ARCH_EMULATE_LONG_MUL_OVF_OPTS 1
134 #define MONO_ARCH_NEED_DIV_CHECK 1
135 #define MONO_ARCH_EMULATE_MUL_OVF 1
136 #define MONO_ARCH_HAVE_OP_TAILCALL_MEMBASE 1
137 #define MONO_ARCH_HAVE_OP_TAILCALL_REG 1
138 #define MONO_ARCH_RGCTX_REG ARMREG_R15
139 #define MONO_ARCH_IMT_REG MONO_ARCH_RGCTX_REG
140 #define MONO_ARCH_VTABLE_REG ARMREG_R0
141 #define MONO_ARCH_HAVE_GENERALIZED_IMT_TRAMPOLINE 1
142 #define MONO_ARCH_USE_SIGACTION 1
144 #define MONO_ARCH_HAS_NO_PROPER_MONOCTX 1
146 #define MONO_ARCH_HAVE_CONTEXT_SET_INT_REG 1
147 #define MONO_ARCH_GSHARED_SUPPORTED 1
148 #define MONO_ARCH_INTERPRETER_SUPPORTED 1
149 #define MONO_ARCH_HAVE_INTERP_ENTRY_TRAMPOLINE 1
150 #define MONO_ARCH_HAVE_INTERP_NATIVE_TO_MANAGED 1
151 #define MONO_ARCH_AOT_SUPPORTED 1
152 #define MONO_ARCH_LLVM_SUPPORTED 1
153 #define MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES 1
154 #define MONO_ARCH_HAVE_EXCEPTIONS_INIT 1
155 #define MONO_ARCH_HAVE_GET_TRAMPOLINES 1
156 #define MONO_ARCH_DYN_CALL_SUPPORTED 1
157 #define MONO_ARCH_DYN_CALL_PARAM_AREA 0
158 #define MONO_ARCH_SOFT_DEBUG_SUPPORTED 1
159 #define MONO_ARCH_GSHAREDVT_SUPPORTED 1
160 #define MONO_ARCH_HAVE_SETUP_RESUME_FROM_SIGNAL_HANDLER_CTX 1
161 #define MONO_ARCH_HAVE_SETUP_ASYNC_CALLBACK 1
162 #define MONO_ARCH_HAVE_GENERAL_RGCTX_LAZY_FETCH_TRAMPOLINE 1
163 #define MONO_ARCH_HAVE_OBJC_GET_SELECTOR 1
164 #define MONO_ARCH_HAVE_SDB_TRAMPOLINES 1
165 #define MONO_ARCH_HAVE_PATCH_CODE_NEW 1
166 #define MONO_ARCH_HAVE_OP_GENERIC_CLASS_INIT 1
167 #define MONO_ARCH_HAVE_OPCODE_NEEDS_EMULATION 1
168 #define MONO_ARCH_HAVE_DECOMPOSE_LONG_OPTS 1
169 #define MONO_ARCH_FLOAT32_SUPPORTED 1
170 #define MONO_ARCH_HAVE_INTERP_PINVOKE_TRAMP 1
171 #define MONO_ARCH_LLVM_TARGET_LAYOUT "e-i64:64-i128:128-n32:64-S128"
173 // Does the ABI have a volatile non-parameter register, so tailcall
174 // can pass context to generics or interfaces?
175 #define MONO_ARCH_HAVE_VOLATILE_NON_PARAM_REGISTER 1
179 #define MONO_ARCH_REDZONE_SIZE 128
183 #define MONO_ARCH_REDZONE_SIZE 0
187 #if defined(TARGET_IOS) || defined(TARGET_WATCHOS)
188 #define MONO_ARCH_HAVE_UNWIND_BACKTRACE 1
192 #define MONO_R_ARM64_B 1
193 #define MONO_R_ARM64_BCC 2
194 #define MONO_R_ARM64_IMM 3
195 #define MONO_R_ARM64_BL 4
196 #define MONO_R_ARM64_BL_SHORT 5
197 #define MONO_R_ARM64_CBZ 6
208 * Vtype passed in consecutive int registers.
209 * ainfo->reg is the firs register,
210 * ainfo->nregs is the number of registers,
211 * ainfo->size is the size of the structure.
215 ArgVtypeByRefOnStack
,
226 /* ArgVtypeInIRegs/ArgHFA */
231 /* The offsets of the float values inside the arg */
232 guint16 foffsets
[4];
244 int gr
, fr
, stack_usage
;
252 /* General registers + ARMREG_R8 for indirect returns */
253 host_mgreg_t gregs
[PARAM_REGS
+ 1];
254 /* Floating registers */
255 double fregs
[FP_PARAM_REGS
];
256 /* Stack usage, used for passing params on stack */
261 guint8
* mono_arm_emit_imm64 (guint8
*code
, int dreg
, gint64 imm
);
263 guint8
* mono_arm_emit_ldrx (guint8
*code
, int rt
, int rn
, int imm
);
265 guint8
* mono_arm_emit_destroy_frame (guint8
*code
, int stack_offset
, guint64 temp_regs
);
267 guint8
* mono_arm_emit_store_regset (guint8
*code
, guint64 regs
, int basereg
, int offset
);
269 guint8
* mono_arm_emit_store_regarray (guint8
*code
, guint64 regs
, int basereg
, int offset
);
271 guint8
* mono_arm_emit_load_regarray (guint8
*code
, guint64 regs
, int basereg
, int offset
);
273 /* MonoJumpInfo **ji */
274 guint8
* mono_arm_emit_aotconst (gpointer ji
, guint8
*code
, guint8
*code_start
, int dreg
, guint32 patch_type
, gconstpointer data
);
276 void mono_arm_patch (guint8
*code
, guint8
*target
, int relocation
);
278 void mono_arm_throw_exception (gpointer arg
, host_mgreg_t pc
, host_mgreg_t
*int_regs
, gdouble
*fp_regs
, gboolean corlib
, gboolean rethrow
, gboolean preserve_ips
);
280 void mono_arm_gsharedvt_init (void);
282 GSList
* mono_arm_get_exception_trampolines (gboolean aot
);
284 void mono_arm_resume_unwind (gpointer arg
, host_mgreg_t pc
, host_mgreg_t
*int_regs
, gdouble
*fp_regs
, gboolean corlib
, gboolean rethrow
);
286 CallInfo
* mono_arch_get_call_info (MonoMemPool
*mp
, MonoMethodSignature
*sig
);
288 #endif /* __MONO_MINI_ARM64_H__ */