imported everything from my branch (which is slightly harmless).
[mono.git] / mono / mini / mini-ia64.h
1 #ifndef __MONO_MINI_IA64_H__
2 #define __MONO_MINI_IA64_H__
3
4 #include <glib.h>
5
6 #define UNW_LOCAL_ONLY
7 #include <libunwind.h>
8
9 #include <mono/arch/ia64/ia64-codegen.h>
10
11 /* FIXME: regset -> 128 bits ! */
12
13 #define MONO_MAX_IREGS 128
14 #define MONO_MAX_FREGS 128
15
16 /* Parameters used by the register allocator */
17
18 #define MONO_ARCH_HAS_XP_LOCAL_REGALLOC
19
20 /* r8..r11, r14..r29 */
21 #define MONO_ARCH_CALLEE_REGS (0x700UL | 0x3fffc000UL)
22
23 /* f6..f15, f33..f127 */
24 /* FIXME: Use the upper 64 bits as well */
25 #define MONO_ARCH_CALLEE_FREGS (0xfffffffe00000000UL | (0x3ffUL << 6))
26
27 #define MONO_ARCH_CALLEE_SAVED_REGS ~(MONO_ARCH_CALLEE_REGS)
28
29 #define MONO_ARCH_CALLEE_SAVED_FREGS 0
30
31 #define MONO_ARCH_USE_FPSTACK FALSE
32 #define MONO_ARCH_FPSTACK_SIZE 0
33
34 #define MONO_ARCH_INST_FIXED_REG(desc) ((desc == 'r') ? IA64_R8 : ((desc == 'g') ? 8 : -1))
35 #define MONO_ARCH_INST_IS_FLOAT(desc) ((desc == 'f') || (desc == 'g'))
36 #define MONO_ARCH_INST_SREG2_MASK(ins) (0)
37 #define MONO_ARCH_INST_IS_REGPAIR(desc) FALSE
38 #define MONO_ARCH_INST_REGPAIR_REG2(desc,hreg1) (-1)
39
40 #define MONO_ARCH_FRAME_ALIGNMENT 16
41
42 #define MONO_ARCH_CODE_ALIGNMENT 16
43
44 #define MONO_ARCH_RETREG1 IA64_R8
45 #define MONO_ARCH_FRETREG1 8
46
47 struct MonoLMF {
48         gpointer    previous_lmf;
49         gpointer    lmf_addr;
50         MonoMethod *method;
51         gpointer    ip;
52         gpointer    sp;
53         gpointer    ebp;
54 };
55
56 typedef struct MonoContext {
57         unw_cursor_t cursor;
58 } MonoContext;
59
60 typedef struct MonoCompileArch {
61         gint32 stack_alloc_size;
62         gint32 lmf_offset;
63         gint32 localloc_offset;
64         gint32 n_out_regs;
65         gint32 reg_in0;
66         gint32 reg_local0;
67         gint32 reg_out0;
68         gint32 reg_saved_ar_pfs;
69         gint32 reg_saved_b0;
70         gint32 reg_saved_sp;
71         guint32 prolog_end_offset, epilog_begin_offset, epilog_end_offset;
72         unw_dyn_region_info_t *r_pro;
73 } MonoCompileArch;
74
75 static inline unw_word_t
76 mono_ia64_context_get_ip (MonoContext *ctx)
77 {
78         unw_word_t ip;
79         int err;
80
81         err = unw_get_reg (&ctx->cursor, UNW_IA64_IP, &ip);
82         g_assert (err == 0);
83
84         /* Subtrack 1 so ip points into the actual instruction */
85         return ip - 1;
86 }
87
88 static inline unw_word_t
89 mono_ia64_context_get_sp (MonoContext *ctx)
90 {
91         unw_word_t sp;
92         int err;
93
94         err = unw_get_reg (&ctx->cursor, UNW_IA64_SP, &sp);
95         g_assert (err == 0);
96
97         return sp;
98 }
99
100 static inline unw_word_t
101 mono_ia64_context_get_fp (MonoContext *ctx)
102 {
103         unw_cursor_t new_cursor;
104         unw_word_t fp;
105         int err;
106
107         {
108                 unw_word_t ip, sp;
109
110                 err = unw_get_reg (&ctx->cursor, UNW_IA64_SP, &sp);
111                 g_assert (err == 0);
112
113                 err = unw_get_reg (&ctx->cursor, UNW_IA64_IP, &ip);
114                 g_assert (err == 0);
115         }
116
117         /* fp is the SP of the parent frame */
118         new_cursor = ctx->cursor;
119
120         err = unw_step (&new_cursor);
121         g_assert (err >= 0);
122
123         err = unw_get_reg (&new_cursor, UNW_IA64_SP, &fp);
124         g_assert (err == 0);
125
126         return fp;
127 }
128
129 #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)
130 #define MONO_CONTEXT_SET_BP(ctx,ebp) do { } while (0)
131 #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)
132
133 #define MONO_CONTEXT_GET_IP(ctx) ((gpointer)(mono_ia64_context_get_ip ((ctx))))
134 #define MONO_CONTEXT_GET_BP(ctx) ((gpointer)(mono_ia64_context_get_fp ((ctx))))
135 #define MONO_CONTEXT_GET_SP(ctx) ((gpointer)(mono_ia64_context_get_sp ((ctx))))
136
137 #define MONO_INIT_CONTEXT_FROM_FUNC(ctx,start_func) do {        \
138                 mono_arch_flush_register_windows ();    \
139                 MONO_CONTEXT_SET_IP ((ctx), (start_func));      \
140                 MONO_CONTEXT_SET_BP ((ctx), __builtin_frame_address (0));       \
141         } while (0)
142
143 #define MONO_INIT_CONTEXT_FROM_CURRENT(ctx) do { \
144         int res; \
145         res = unw_getcontext (&unw_ctx); \
146         g_assert (res == 0); \
147         res = unw_init_local (&(ctx)->cursor, &unw_ctx); \
148         g_assert (res == 0); \
149 } while (0)
150
151 #define MONO_ARCH_CONTEXT_DEF unw_context_t unw_ctx;
152
153 #define MONO_ARCH_USE_SIGACTION 1
154
155 #ifdef HAVE_WORKING_SIGALTSTACK
156 /* FIXME: */
157 //#define MONO_ARCH_SIGSEGV_ON_ALTSTACK
158 #endif
159
160
161 #define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS
162
163 #define MONO_ARCH_EMULATE_CONV_R8_UN     1
164 #define MONO_ARCH_EMULATE_LCONV_TO_R8_UN 1
165 #define MONO_ARCH_EMULATE_FREM           1
166 #define MONO_ARCH_EMULATE_MUL_DIV        1
167 #define MONO_ARCH_EMULATE_LONG_MUL_OPTS  1
168 #define MONO_ARCH_NEED_DIV_CHECK         1
169
170 #define MONO_ARCH_HAVE_IS_INT_OVERFLOW 1
171
172 #define MONO_ARCH_ENABLE_EMIT_STATE_OPT 1
173 #define MONO_ARCH_HAVE_INVALIDATE_METHOD 1
174 #define MONO_ARCH_HAVE_THROW_CORLIB_EXCEPTION 1
175 #define MONO_ARCH_HAVE_PIC_AOT 1
176 #define MONO_ARCH_HAVE_CREATE_TRAMPOLINE_FROM_TOKEN 1
177 #define MONO_ARCH_HAVE_SAVE_UNWIND_INFO 1
178
179 #endif /* __MONO_MINI_IA64_H__ */