21e1f54247446714b539d72b081d4d50cb343140
[mono.git] / mono / mini / mini-arm64.h
1 /*
2  * mini-arm64.h
3  *
4  * Copyright 2013 Xamarin Inc
5  *
6  * Based on mini-arm.h:
7  *
8  * Copyright 2011 Xamarin Inc
9  */
10
11 #ifndef __MONO_MINI_ARM64_H__
12 #define __MONO_MINI_ARM64_H__
13
14 #include <mono/arch/arm64/arm64-codegen.h>
15 #include <mono/mini/mini-arm64-gsharedvt.h>
16
17 #define MONO_ARCH_CPU_SPEC mono_arm64_cpu_desc
18
19 #define MONO_MAX_IREGS 32
20 #define MONO_MAX_FREGS 32
21
22 #define MONO_CONTEXT_SET_LLVM_EXC_REG(ctx, exc) do { (ctx)->regs [0] = (gsize)exc; } while (0)
23
24 #define MONO_INIT_CONTEXT_FROM_FUNC(ctx,func) do {      \
25                 MONO_CONTEXT_SET_BP ((ctx), __builtin_frame_address (0));       \
26                 MONO_CONTEXT_SET_SP ((ctx), __builtin_frame_address (0));       \
27                 MONO_CONTEXT_SET_IP ((ctx), (func));    \
28         } while (0)
29
30 #define MONO_ARCH_INIT_TOP_LMF_ENTRY(lmf)
31
32 /* Parameters used by the register allocator */
33 /* r0..r7, r9..r14 (r15 is the imt/rgctx reg) */
34 #define MONO_ARCH_CALLEE_REGS 0xfeff
35 /* r19..r28 */
36 #define MONO_ARCH_CALLEE_SAVED_REGS (0x3ff << 19)
37
38 /* v16/v17 is reserved for a scratch reg */
39 #define MONO_ARCH_CALLEE_FREGS 0xfffc00ff
40 /* v8..v15 */
41 #define MONO_ARCH_CALLEE_SAVED_FREGS 0xff00
42
43 #define MONO_ARCH_USE_FPSTACK FALSE
44 #define MONO_ARCH_FPSTACK_SIZE 0
45
46 #define MONO_ARCH_INST_SREG2_MASK(ins) (0)
47
48 #define MONO_ARCH_INST_FIXED_REG(desc) ((desc) == 'a' ? ARMREG_R0 : -1)
49
50 #define MONO_ARCH_INST_IS_REGPAIR(desc) (0)
51
52 #define MONO_ARCH_INST_IS_FLOAT(desc) ((desc) == 'f')
53
54 #define MONO_ARCH_INST_REGPAIR_REG2(desc,hreg1) (-1)
55
56 #define MONO_ARCH_USE_FPSTACK FALSE
57
58 #define MONO_ARCH_FRAME_ALIGNMENT 16
59
60 #define MONO_ARCH_CODE_ALIGNMENT 32
61
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
68
69 struct MonoLMF {
70         /* 
71          * If the second lowest bit is set to 1, then this is a MonoLMFExt structure, and
72          * the other fields are not valid.
73          */
74         gpointer    previous_lmf;
75         gpointer    lmf_addr;
76         mgreg_t    pc;
77         mgreg_t    gregs [MONO_ARCH_NUM_LMF_REGS];
78 };
79
80 /* Structure used by the sequence points in AOTed code */
81 typedef struct {
82         gpointer ss_trigger_page;
83         gpointer bp_trigger_page;
84         gpointer ss_tramp_addr;
85         guint8* bp_addrs [MONO_ZERO_LEN_ARRAY];
86 } SeqPointInfo;
87
88 #define PARAM_REGS 8
89 #define FP_PARAM_REGS 8
90
91 #define DYN_CALL_STACK_ARGS 6
92
93 typedef struct {
94         /* The +1 is for r8 */
95         mgreg_t regs [PARAM_REGS + 1 + DYN_CALL_STACK_ARGS];
96         mgreg_t res, res2;
97         guint8 *ret;
98         double fpregs [FP_PARAM_REGS];
99         int n_fpargs, n_fpret;
100         guint8 buffer [256];
101 } DynCallArgs;
102
103 typedef struct {
104         gpointer cinfo;
105         int saved_gregs_offset;
106         /* Points to arguments received on the stack */
107         int args_reg;
108         gboolean cond_branch_islands;
109         gpointer vret_addr_loc;
110         gpointer seq_point_info_var;
111         gpointer ss_tramp_var;
112         gpointer bp_tramp_var;
113         guint8 *thunks;
114         int thunks_size;
115 } MonoCompileArch;
116
117 #define MONO_ARCH_EMULATE_FREM 1
118 #define MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS 1
119 #define MONO_ARCH_EMULATE_LONG_MUL_OVF_OPTS 1
120 #define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS 1
121 #define MONO_ARCH_NEED_DIV_CHECK 1
122 #define MONO_ARCH_EMULATE_MUL_OVF 1
123 #define MONO_ARCH_HAVE_IMT 1
124 #define MONO_ARCH_HAVE_OP_TAIL_CALL 1
125 #define MONO_ARCH_THIS_AS_FIRST_ARG 1
126 #define MONO_ARCH_RGCTX_REG ARMREG_R15
127 #define MONO_ARCH_IMT_REG MONO_ARCH_RGCTX_REG
128 #define MONO_ARCH_VTABLE_REG ARMREG_R0
129 #define MONO_ARCH_EXC_REG ARMREG_R0
130 #define MONO_ARCH_HAVE_XP_UNWIND 1
131 #define MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE 1
132 #define MONO_ARCH_HAVE_GENERALIZED_IMT_THUNK 1
133 #define MONO_ARCH_USE_SIGACTION 1
134 #define MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX 1
135 #define MONO_ARCH_HAVE_CONTEXT_SET_INT_REG 1
136 #define MONO_ARCH_GSHARED_SUPPORTED 1
137 #define MONO_ARCH_AOT_SUPPORTED 1
138 #define MONO_ARCH_LLVM_SUPPORTED 1
139 #define MONO_ARCH_HAVE_FULL_AOT_TRAMPOLINES 1
140 #define MONO_ARCH_HAVE_EXCEPTIONS_INIT 1
141 #define MONO_ARCH_HAVE_GET_TRAMPOLINES 1
142 #define MONO_ARCH_DYN_CALL_SUPPORTED 1
143 #define MONO_ARCH_DYN_CALL_PARAM_AREA (DYN_CALL_STACK_ARGS * 8)
144 #define MONO_ARCH_SOFT_DEBUG_SUPPORTED 1
145 #ifndef TARGET_ANDROID
146 #define MONO_ARCH_GSHAREDVT_SUPPORTED 1
147 #endif
148 #define MONO_ARCH_HAVE_SETUP_RESUME_FROM_SIGNAL_HANDLER_CTX 1
149 #define MONO_ARCH_HAVE_SETUP_ASYNC_CALLBACK 1
150 #define MONO_ARCH_HAVE_GENERAL_RGCTX_LAZY_FETCH_TRAMPOLINE 1
151 #ifndef MONO_CROSS_COMPILE
152 #define MONO_ARCH_ENABLE_MONO_LMF_VAR 1
153 #endif
154 #define MONO_ARCH_HAVE_OP_GET_EX_OBJ 1
155 #define MONO_ARCH_HAVE_OBJC_GET_SELECTOR 1
156 #define MONO_ARCH_HAVE_SDB_TRAMPOLINES 1
157 #define MONO_ARCH_HAVE_PATCH_CODE_NEW 1
158 #define MONO_ARCH_HAVE_OP_GENERIC_CLASS_INIT 1
159 #define MONO_ARCH_HAVE_OPCODE_NEEDS_EMULATION 1
160 #define MONO_ARCH_HAVE_DECOMPOSE_LONG_OPTS 1
161
162 #ifdef TARGET_IOS
163
164 #define MONO_ARCH_REDZONE_SIZE 128
165
166 #else
167
168 #define MONO_ARCH_REDZONE_SIZE 0
169 #if !defined(__PIC__)
170 #define MONO_ARCH_HAVE_TLS_GET 1
171 #endif
172 #define MONO_ARCH_HAVE_TLS_GET_REG 1
173
174 #endif
175
176 #if defined(TARGET_APPLETVOS)
177 #define MONO_ARCH_HAVE_UNWIND_BACKTRACE 1
178 #endif
179
180 /* Relocations */
181 #define MONO_R_ARM64_B 1
182 #define MONO_R_ARM64_BCC 2
183 #define MONO_R_ARM64_IMM 3
184 #define MONO_R_ARM64_BL 4
185 #define MONO_R_ARM64_BL_SHORT 5
186 #define MONO_R_ARM64_CBZ 6
187
188
189 typedef enum {
190         ArgInIReg,
191         ArgInFReg,
192         ArgInFRegR4,
193         ArgOnStack,
194         ArgOnStackR8,
195         ArgOnStackR4,
196         /*
197          * Vtype passed in consecutive int registers.
198          * ainfo->reg is the firs register,
199          * ainfo->nregs is the number of registers,
200          * ainfo->size is the size of the structure.
201          */
202         ArgVtypeInIRegs,
203         ArgVtypeByRef,
204         ArgVtypeByRefOnStack,
205         ArgVtypeOnStack,
206         ArgHFA,
207         ArgNone
208 } ArgStorage;
209
210 typedef struct {
211         ArgStorage storage;
212         int reg;
213         /* ArgOnStack */
214         int offset;
215         /* ArgVtypeInIRegs/ArgHFA */
216         int nregs, size;
217         /* ArgHFA */
218         int esize;
219         /* ArgHFA */
220         /* The offsets of the float values inside the arg */
221         guint16 foffsets [4];
222         /* ArgOnStack */
223         int slot_size;
224         /* hfa */
225         int nfregs_to_skip;
226         gboolean sign;
227         gboolean gsharedvt;
228         gboolean hfa;
229 } ArgInfo;
230
231 typedef struct {
232         int nargs;
233         int gr, fr, stack_usage;
234         ArgInfo ret;
235         ArgInfo sig_cookie;
236         ArgInfo args [1];
237 } CallInfo;
238
239
240 guint8* mono_arm_emit_imm64 (guint8 *code, int dreg, gint64 imm);
241
242 guint8* mono_arm_emit_ldrx (guint8 *code, int rt, int rn, int imm);
243
244 guint8* mono_arm_emit_destroy_frame (guint8 *code, int stack_offset, guint64 temp_regs);
245
246 guint8* mono_arm_emit_store_regset (guint8 *code, guint64 regs, int basereg, int offset);
247
248 guint8* mono_arm_emit_store_regarray (guint8 *code, guint64 regs, int basereg, int offset);
249
250 guint8* mono_arm_emit_load_regarray (guint8 *code, guint64 regs, int basereg, int offset);
251
252 /* MonoJumpInfo **ji */
253 guint8* mono_arm_emit_aotconst (gpointer ji, guint8 *code, guint8 *code_start, int dreg, guint32 patch_type, gconstpointer data);
254
255 void mono_arm_patch (guint8 *code, guint8 *target, int relocation);
256
257 void mono_arm_throw_exception (gpointer arg, mgreg_t pc, mgreg_t *int_regs, gdouble *fp_regs, gboolean corlib, gboolean rethrow);
258
259 void mono_arm_gsharedvt_init (void);
260
261 GSList* mono_arm_get_exception_trampolines (gboolean aot);
262
263 void mono_arm_resume_unwind (gpointer arg, mgreg_t pc, mgreg_t *int_regs, gdouble *fp_regs, gboolean corlib, gboolean rethrow);
264
265 CallInfo* mono_arch_get_call_info (MonoMemPool *mp, MonoMethodSignature *sig);
266
267 #endif /* __MONO_MINI_ARM64_H__ */