In mono/metadata:
[mono.git] / mono / mini / mini-alpha.h
blob9fdbb505177fe2cd42f672f752f78fe049eb0576
1 #ifndef __MONO_MINI_ALPHA_H__
2 #define __MONO_MINI_ALPHA_H__
4 #include <glib.h>
6 #include <mono/arch/alpha/alpha-codegen.h>
8 #define MONO_ARCH_CPU_SPEC alpha_desc
10 /* Parameters used by the register allocator */
12 /* Max number of integer registers (all int regs). Required definition */
13 #define MONO_MAX_IREGS 31
15 /* Max number of float registers (all float regs). Required definition */
16 #define MONO_MAX_FREGS 32
18 typedef enum {GT_NONE, GT_INT, GT_LONG,
19 GT_PTR, GT_FLOAT, GT_DOUBLE, GT_LD_GTADDR} AlphaGotType;
21 typedef struct
23 union
25 int i;
26 long l;
27 void *p;
28 float f;
29 double d;
30 } data;
31 } AlphaGotData;
33 typedef struct AlphaGotEntry
35 struct AlphaGotEntry *next;
37 AlphaGotType type;
38 AlphaGotData value;
40 gpointer patch_info;
41 gpointer got_patch_info;
42 } AlphaGotEntry;
44 typedef struct MonoCompileArch
46 gint32 lmf_offset;
47 gint32 localloc_offset;
48 gint32 reg_save_area_offset;
49 gint32 args_save_area_offset;
50 gint32 stack_size; // Allocated stack size in bytes
51 gint32 params_stack_size; // Stack size reserved for call params by this compile method
53 gpointer got_data;
54 glong bwx;
55 } MonoCompileArch;
57 typedef struct ucontext MonoContext;
59 struct MonoLMF
61 gpointer previous_lmf;
62 gpointer lmf_addr;
63 MonoMethod *method;
64 guint64 ebp; // FP ? caller FP
65 guint64 eip; // RA ? or caller PC
66 guint64 rsp; // SP ? caller SP
67 guint64 rgp; // GP
68 guint64 r14;
69 guint64 r13;
70 guint64 r12;
73 #define MONO_ARCH_FRAME_ALIGNMENT 8
74 #define MONO_ARCH_CODE_ALIGNMENT 8
76 // Regs available for allocation in compile unit
77 // For Alpha: r1-r14, r22-r25
78 // 1111 1111 1111 1111 1111 1111 1111 1111
79 // 098 7654 3210 9876 5432 1098 7654 3210
80 // RRRR RRLL LLAA AAAA RLLL LLLL LLLL LLLL - No global regs
81 // RRRR RRLL LLAA AAAA RGGG LLLL LLLL LLLL - 3 global regs
82 //#define MONO_ARCH_CALLEE_REGS ((regmask_t)0x03C07FFF)
83 #define MONO_ARCH_CALLEE_REGS ((regmask_t)0x03C00FFF)
84 #define MONO_ARCH_CALLEE_FREGS ((regmask_t)0x03C07FFF)
86 // These are the regs that are considered global
87 // and should not be used by JIT reg allocator
88 // (should be saved in compile unit). The JIT could use them
89 // in regalloc if they assigned as REGVARS (REGOFFSET to keep
90 // vars on stack
91 // the stack space will be reserved for them if they got used
92 // For Alpha - r9-r14. Actually later we could use some of the
93 // upper "t" regs, since local reg allocator doesn't like registers
94 // very much, so we could safely keep vars in them
95 //#define MONO_ARCH_CALLEE_SAVED_REGS ((regmask_t)0x3C00FE00)
96 #define MONO_ARCH_CALLEE_SAVED_REGS ((regmask_t)0x3C00F000)
97 #define MONO_ARCH_CALLEE_SAVED_FREGS 0
99 #define ALPHA_IS_CALLEE_SAVED_REG(reg) (MONO_ARCH_CALLEE_SAVED_REGS & (1 << (reg)))
101 #define MONO_ARCH_USE_FPSTACK FALSE
102 #define MONO_ARCH_FPSTACK_SIZE 0
104 #define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->uc_mcontext.sc_pc))
105 #define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->uc_mcontext.sc_regs[15]))
106 #define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->uc_mcontext.sc_regs[30]))
108 #define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->uc_mcontext.sc_pc = (long)(ip); } while (0);
109 #define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->uc_mcontext.sc_regs[15] = (long)(bp); } while (0);
110 #define MONO_CONTEXT_SET_SP(ctx,esp) do { (ctx)->uc_mcontext.sc_regs[30] = (long)(esp); } while (0);
112 #define MONO_INIT_CONTEXT_FROM_FUNC(ctx,start_func) do { \
113 mono_arch_flush_register_windows (); \
114 MONO_CONTEXT_SET_IP ((ctx), (start_func)); \
115 MONO_CONTEXT_SET_BP ((ctx), __builtin_frame_address (0)); \
116 MONO_CONTEXT_SET_SP ((ctx), __builtin_frame_address (0)); \
117 } while (0)
119 #define MONO_ARCH_USE_SIGACTION 1
121 //#define MONO_ARCH_INST_FIXED_REG(desc) ((desc == 'r') ? IA64_R8 : ((desc == 'g') ? 8 : -1))
122 //#define MONO_ARCH_INST_IS_FLOAT(desc) ((desc == 'f') || (desc == 'g'))
123 #define MONO_ARCH_INST_SREG2_MASK(ins) (0)
124 #define MONO_ARCH_INST_IS_REGPAIR(desc) FALSE
125 #define MONO_ARCH_INST_REGPAIR_REG2(desc,hreg1) (-1)
127 // This define is called to get specific dest register as defined
128 // by md file (letter after "dest"). Overwise return -1
129 //#define MONO_ARCH_INST_FIXED_REG(desc) (-1)
130 #define MONO_ARCH_INST_FIXED_REG(desc) ((desc == 'o') ? alpha_at : ( (desc == 'a') ? alpha_r0 : -1) )
132 #if 0
134 /* r8..r11, r14..r29 */
135 #define MONO_ARCH_CALLEE_REGS ((regmask_t)(0x700UL) | (regmask_t)(0x3fffc000UL))
137 /* f6..f15, f33..f127 */
138 /* FIXME: Use the upper 64 bits as well */
139 #define MONO_ARCH_CALLEE_FREGS ((regmask_t)(0xfffffffe00000000UL) | ((regmask_t)(0x3ffUL) << 6))
141 #define MONO_ARCH_CALLEE_SAVED_REGS ~(MONO_ARCH_CALLEE_REGS)
143 #define MONO_ARCH_CALLEE_SAVED_FREGS 0
145 #define MONO_ARCH_USE_FPSTACK FALSE
146 #define MONO_ARCH_FPSTACK_SIZE 0
148 #define MONO_ARCH_INST_FIXED_REG(desc) ((desc == 'r') ? IA64_R8 : ((desc == 'g') ? 8 : -1))
149 #define MONO_ARCH_INST_IS_FLOAT(desc) ((desc == 'f') || (desc == 'g'))
150 #define MONO_ARCH_INST_SREG2_MASK(ins) (0)
151 #define MONO_ARCH_INST_IS_REGPAIR(desc) FALSE
152 #define MONO_ARCH_INST_REGPAIR_REG2(desc,hreg1) (-1)
154 #define MONO_ARCH_IS_GLOBAL_IREG(reg) (is_hard_ireg (reg) && ((reg) >= cfg->arch.reg_local0) && ((reg) < cfg->arch.reg_out0))
156 #define MONO_ARCH_FRAME_ALIGNMENT 16
158 #define MONO_ARCH_CODE_ALIGNMENT 16
160 #define MONO_ARCH_RETREG1 IA64_R8
161 #define MONO_ARCH_FRETREG1 8
163 #define MONO_ARCH_SIGNAL_STACK_SIZE SIGSTKSZ
165 struct MonoLMF
167 guint64 ebp;
170 typedef struct MonoContext {
171 unw_cursor_t cursor;
172 } MonoContext;
174 typedef struct MonoCompileArch {
175 gint32 stack_alloc_size;
176 gint32 lmf_offset;
177 gint32 localloc_offset;
178 gint32 n_out_regs;
179 gint32 reg_in0;
180 gint32 reg_local0;
181 gint32 reg_out0;
182 gint32 reg_saved_ar_pfs;
183 gint32 reg_saved_b0;
184 gint32 reg_saved_sp;
185 gint32 reg_fp;
186 gint32 reg_saved_return_val;
187 guint32 prolog_end_offset, epilog_begin_offset, epilog_end_offset;
188 void *ret_var_addr_local;
189 unw_dyn_region_info_t *r_pro, *r_epilog;
190 void *last_bb;
191 Ia64CodegenState code;
192 gboolean omit_fp;
193 GHashTable *branch_targets;
194 } MonoCompileArch;
196 static inline unw_word_t
197 mono_ia64_context_get_ip (MonoContext *ctx)
199 unw_word_t ip;
200 int err;
202 err = unw_get_reg (&ctx->cursor, UNW_IA64_IP, &ip);
203 g_assert (err == 0);
205 /* Subtrack 1 so ip points into the actual instruction */
206 return ip - 1;
209 static inline unw_word_t
210 mono_ia64_context_get_sp (MonoContext *ctx)
212 unw_word_t sp;
213 int err;
215 err = unw_get_reg (&ctx->cursor, UNW_IA64_SP, &sp);
216 g_assert (err == 0);
218 return sp;
221 static inline unw_word_t
222 mono_ia64_context_get_fp (MonoContext *ctx)
224 unw_cursor_t new_cursor;
225 unw_word_t fp;
226 int err;
229 unw_word_t ip, sp;
231 err = unw_get_reg (&ctx->cursor, UNW_IA64_SP, &sp);
232 g_assert (err == 0);
234 err = unw_get_reg (&ctx->cursor, UNW_IA64_IP, &ip);
235 g_assert (err == 0);
238 /* fp is the SP of the parent frame */
239 new_cursor = ctx->cursor;
241 err = unw_step (&new_cursor);
242 g_assert (err >= 0);
244 err = unw_get_reg (&new_cursor, UNW_IA64_SP, &fp);
245 g_assert (err == 0);
247 return fp;
250 #define MONO_CONTEXT_SET_IP(ctx,eip) do { int err = unw_set_reg (&(ctx)->cursor, UNW_IA64_IP, (unw_word_t)(eip)); g_assert (err == 0); } while (0)
251 #define MONO_CONTEXT_SET_BP(ctx,ebp) do { } while (0)
252 #define MONO_CONTEXT_SET_SP(ctx,esp) do { int err = unw_set_reg (&(ctx)->cursor, UNW_IA64_SP, (unw_word_t)(esp)); g_assert (err == 0); } while (0)
254 #define MONO_CONTEXT_GET_IP(ctx) ((gpointer)(mono_ia64_context_get_ip ((ctx))))
255 #define MONO_CONTEXT_GET_BP(ctx) ((gpointer)(mono_ia64_context_get_fp ((ctx))))
256 #define MONO_CONTEXT_GET_SP(ctx) ((gpointer)(mono_ia64_context_get_sp ((ctx))))
258 #define MONO_INIT_CONTEXT_FROM_FUNC(ctx,start_func) do { \
259 MONO_INIT_CONTEXT_FROM_CURRENT (ctx); \
260 } while (0)
262 #define MONO_INIT_CONTEXT_FROM_CURRENT(ctx) do { \
263 int res; \
264 res = unw_getcontext (&unw_ctx); \
265 g_assert (res == 0); \
266 res = unw_init_local (&(ctx)->cursor, &unw_ctx); \
267 g_assert (res == 0); \
268 } while (0)
270 #define MONO_ARCH_CONTEXT_DEF unw_context_t unw_ctx;
272 #define MONO_ARCH_USE_SIGACTION 1
274 #ifdef HAVE_WORKING_SIGALTSTACK
275 /*#define MONO_ARCH_SIGSEGV_ON_ALTSTACK*/
276 #endif
278 unw_dyn_region_info_t* mono_ia64_create_unwind_region (Ia64CodegenState *code);
280 #define MONO_ARCH_NO_EMULATE_MUL_IMM 1
282 #define MONO_ARCH_HAVE_IS_INT_OVERFLOW 1
284 #define MONO_ARCH_HAVE_INVALIDATE_METHOD 1
285 #define MONO_ARCH_HAVE_SAVE_UNWIND_INFO 1
287 #endif
289 #define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS 1
291 #define MONO_ARCH_HAVE_THROW_CORLIB_EXCEPTION 1
293 #define MONO_ARCH_EMULATE_CONV_R8_UN 1
294 #define MONO_ARCH_EMULATE_LCONV_TO_R8_UN 1
295 //#define MONO_ARCH_EMULATE_LCONV_TO_R8 1
296 #define MONO_ARCH_EMULATE_FREM 1
297 #define MONO_ARCH_EMULATE_MUL_DIV 1
298 #define MONO_ARCH_EMULATE_LONG_MUL_OPTS 1
299 #define MONO_ARCH_NEED_DIV_CHECK 1
302 #define MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE 1
304 typedef struct {
305 guint8 *address;
306 guint8 *saved_byte;
307 } MonoBreakpointInfo;
309 extern MonoBreakpointInfo mono_breakpoint_info[MONO_BREAKPOINT_ARRAY_SIZE];
310 #endif /* __MONO_MINI_ALPHA_H__ */