Tue Sep 26 11:57:26 CEST 2006 Paolo Molaro <lupus@ximian.com>
[mono.git] / mono / mini / mini-alpha.h
1 #ifndef __MONO_MINI_ALPHA_H__
2 #define __MONO_MINI_ALPHA_H__
3
4 #include <glib.h>
5
6 #include <mono/arch/alpha/alpha-codegen.h>
7
8 /* Parameters used by the register allocator */
9 #define MONO_ARCH_HAS_XP_LOCAL_REGALLOC
10
11 /* Max number of integer registers (all int regs). Required definition */
12 #define MONO_MAX_IREGS 31
13
14 /* Max number of float registers (all float regs). Required definition */
15 #define MONO_MAX_FREGS 32
16
17 typedef enum {GT_NONE, GT_INT, GT_LONG,
18               GT_PTR, GT_FLOAT, GT_DOUBLE, GT_LD_GTADDR} AlphaGotType;
19
20 typedef struct
21 {
22   union
23   {
24     int i;
25     long l;
26     void *p;
27     float f;
28     double d;
29   } data;
30 } AlphaGotData;
31
32 typedef struct AlphaGotEntry
33 {
34   struct AlphaGotEntry *next;
35
36   AlphaGotType type;
37   AlphaGotData value;
38
39   gpointer  patch_info;
40   gpointer  got_patch_info;
41 } AlphaGotEntry;
42
43 typedef struct MonoCompileArch
44 {
45   gint32 lmf_offset;
46   gint32 localloc_offset;
47   gint32 reg_save_area_offset;
48   gint32 args_save_area_offset;
49   gint32 stack_size;        // Allocated stack size in bytes
50   gint32 params_stack_size;  // Stack size reserved for call params by this compile method
51
52   gpointer    got_data;
53  
54 //  gpointer    litpool;
55 //  glong       litsize;
56   glong       bwx;
57 } MonoCompileArch;
58
59 typedef struct ucontext MonoContext;
60
61 struct MonoLMF
62 {
63   gpointer    previous_lmf;
64   gpointer    lmf_addr;
65   MonoMethod *method;
66   guint64     ebp;          // FP ? caller FP
67   guint64     eip;          // RA ? or caller PC
68   guint64     rsp;          // SP ? caller SP
69   guint64     rgp;          // GP
70 };
71
72 #define MONO_ARCH_FRAME_ALIGNMENT 8
73 #define MONO_ARCH_CODE_ALIGNMENT 8
74
75 // Regs available for allocation in compile unit
76 // For Alpha: r1-r14, r22-r25
77 #define MONO_ARCH_CALLEE_REGS   ((regmask_t)0x03C07FFF)
78 #define MONO_ARCH_CALLEE_FREGS  ((regmask_t)0x03C07FFF)
79
80 // These are the regs that are considered global
81 // and should not be used by JIT reg allocator 
82 // (should be saved in compile unit). The JIT could use them
83 // in regalloc if they assigned as REGVARS (REGOFFSET to keep
84 // vars on stack
85 // the stack space will be reserved for them if they got used
86 // For Alpha - r9-r14. Actually later we could use some of the
87 // upper "t" regs, since local reg allocator doesn't like registers
88 // very much, so we could safely keep vars in them
89 //#define MONO_ARCH_CALLEE_SAVED_REGS ((regmask_t)0xFC0080000)
90 #define MONO_ARCH_CALLEE_SAVED_REGS ((regmask_t)0x3C00FE00)
91 #define MONO_ARCH_CALLEE_SAVED_FREGS 0
92
93 #define ALPHA_IS_CALLEE_SAVED_REG(reg) (MONO_ARCH_CALLEE_SAVED_REGS & (1 << (reg)))
94
95 #define MONO_ARCH_USE_FPSTACK FALSE
96 #define MONO_ARCH_FPSTACK_SIZE 0
97
98 #define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->uc_mcontext.sc_pc))
99 #define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->uc_mcontext.sc_regs[15]))
100 #define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->uc_mcontext.sc_regs[30]))
101
102 #define MONO_CONTEXT_SET_IP(ctx,ip) do { (ctx)->uc_mcontext.sc_pc = (long)(ip); } while (0);
103 #define MONO_CONTEXT_SET_BP(ctx,bp) do { (ctx)->uc_mcontext.sc_regs[15] = (long)(bp); } while (0);
104 #define MONO_CONTEXT_SET_SP(ctx,esp) do { (ctx)->uc_mcontext.sc_regs[30] = (long)(esp); } while (0);
105
106 #define MONO_INIT_CONTEXT_FROM_FUNC(ctx,start_func) do {        \
107    mono_arch_flush_register_windows ();    \
108    MONO_CONTEXT_SET_IP ((ctx), (start_func));      \
109    MONO_CONTEXT_SET_BP ((ctx), __builtin_frame_address (0)); \
110 } while (0)
111
112 #define MONO_ARCH_USE_SIGACTION 1
113
114 /* Use prerefered create trampoline callback method */
115 #define MONO_ARCH_HAVE_CREATE_SPECIFIC_TRAMPOLINE
116
117 //#define MONO_ARCH_INST_FIXED_REG(desc) ((desc == 'r') ? IA64_R8 : ((desc == 'g') ? 8 : -1))
118 //#define MONO_ARCH_INST_IS_FLOAT(desc) ((desc == 'f') || (desc == 'g'))
119 #define MONO_ARCH_INST_SREG2_MASK(ins) (0)
120 #define MONO_ARCH_INST_IS_REGPAIR(desc) FALSE
121 #define MONO_ARCH_INST_REGPAIR_REG2(desc,hreg1) (-1)
122
123 // This define is called to get specific dest register as defined
124 // by md file (letter after "dest"). Overwise return -1
125 //#define MONO_ARCH_INST_FIXED_REG(desc)        (-1)
126 #define MONO_ARCH_INST_FIXED_REG(desc)  ((desc == 'o') ? alpha_at : ( (desc == 'a') ? alpha_r0 : -1) )
127
128 //#define MONO_ARCH_IS_GLOBAL_IREG(reg) (is_hard_ireg (reg) && ((reg) >= cfg->arch.reg_local0) && ((reg) < cfg->arch.reg_out0))
129
130 #define MONO_ARCH_HAVE_CREATE_VARS 1
131
132 #if 0
133
134 /* r8..r11, r14..r29 */
135 #define MONO_ARCH_CALLEE_REGS ((regmask_t)(0x700UL) | (regmask_t)(0x3fffc000UL))
136
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))
140
141 #define MONO_ARCH_CALLEE_SAVED_REGS ~(MONO_ARCH_CALLEE_REGS)
142
143 #define MONO_ARCH_CALLEE_SAVED_FREGS 0
144
145 #define MONO_ARCH_USE_FPSTACK FALSE
146 #define MONO_ARCH_FPSTACK_SIZE 0
147
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)
153
154 #define MONO_ARCH_IS_GLOBAL_IREG(reg) (is_hard_ireg (reg) && ((reg) >= cfg->arch.reg_local0) && ((reg) < cfg->arch.reg_out0))
155
156 #define MONO_ARCH_FRAME_ALIGNMENT 16
157
158 #define MONO_ARCH_CODE_ALIGNMENT 16
159
160 #define MONO_ARCH_RETREG1 IA64_R8
161 #define MONO_ARCH_FRETREG1 8
162
163 #define MONO_ARCH_SIGNAL_STACK_SIZE SIGSTKSZ
164
165 struct MonoLMF
166 {
167         guint64    ebp;
168 };
169
170 typedef struct MonoContext {
171         unw_cursor_t cursor;
172 } MonoContext;
173
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;
195
196 static inline unw_word_t
197 mono_ia64_context_get_ip (MonoContext *ctx)
198 {
199         unw_word_t ip;
200         int err;
201
202         err = unw_get_reg (&ctx->cursor, UNW_IA64_IP, &ip);
203         g_assert (err == 0);
204
205         /* Subtrack 1 so ip points into the actual instruction */
206         return ip - 1;
207 }
208
209 static inline unw_word_t
210 mono_ia64_context_get_sp (MonoContext *ctx)
211 {
212         unw_word_t sp;
213         int err;
214
215         err = unw_get_reg (&ctx->cursor, UNW_IA64_SP, &sp);
216         g_assert (err == 0);
217
218         return sp;
219 }
220
221 static inline unw_word_t
222 mono_ia64_context_get_fp (MonoContext *ctx)
223 {
224         unw_cursor_t new_cursor;
225         unw_word_t fp;
226         int err;
227
228         {
229                 unw_word_t ip, sp;
230
231                 err = unw_get_reg (&ctx->cursor, UNW_IA64_SP, &sp);
232                 g_assert (err == 0);
233
234                 err = unw_get_reg (&ctx->cursor, UNW_IA64_IP, &ip);
235                 g_assert (err == 0);
236         }
237
238         /* fp is the SP of the parent frame */
239         new_cursor = ctx->cursor;
240
241         err = unw_step (&new_cursor);
242         g_assert (err >= 0);
243
244         err = unw_get_reg (&new_cursor, UNW_IA64_SP, &fp);
245         g_assert (err == 0);
246
247         return fp;
248 }
249
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)
253
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))))
257
258 #define MONO_INIT_CONTEXT_FROM_FUNC(ctx,start_func) do {        \
259     MONO_INIT_CONTEXT_FROM_CURRENT (ctx); \
260 } while (0)
261
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)
269
270 #define MONO_ARCH_CONTEXT_DEF unw_context_t unw_ctx;
271
272 #define MONO_ARCH_USE_SIGACTION 1
273
274 #ifdef HAVE_WORKING_SIGALTSTACK
275 #define MONO_ARCH_SIGSEGV_ON_ALTSTACK
276 #endif
277
278 unw_dyn_region_info_t* mono_ia64_create_unwind_region (Ia64CodegenState *code);
279
280 #define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS 1
281 #define MONO_ARCH_NO_EMULATE_MUL_IMM 1
282
283 #define MONO_ARCH_HAVE_IS_INT_OVERFLOW 1
284
285 #define MONO_ARCH_ENABLE_EMIT_STATE_OPT 1
286 #define MONO_ARCH_HAVE_INVALIDATE_METHOD 1
287 #define MONO_ARCH_HAVE_THROW_CORLIB_EXCEPTION 1
288 #define MONO_ARCH_HAVE_PIC_AOT 1
289 #define MONO_ARCH_HAVE_CREATE_TRAMPOLINE_FROM_TOKEN 1
290 #define MONO_ARCH_HAVE_CREATE_SPECIFIC_TRAMPOLINE 1
291 #define MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE 1
292 #define MONO_ARCH_HAVE_SAVE_UNWIND_INFO 1
293
294 #endif
295
296 #define MONO_ARCH_HAVE_THROW_CORLIB_EXCEPTION 1
297
298 #define MONO_ARCH_EMULATE_CONV_R8_UN     1
299 #define MONO_ARCH_EMULATE_LCONV_TO_R8_UN 1
300 #define MONO_ARCH_EMULATE_LCONV_TO_R8    1
301 #define MONO_ARCH_EMULATE_FREM           1
302 #define MONO_ARCH_EMULATE_MUL_DIV        1
303 #define MONO_ARCH_EMULATE_LONG_MUL_OPTS  1
304 #define MONO_ARCH_NEED_DIV_CHECK         1
305
306
307 #define MONO_ARCH_HAVE_CREATE_TRAMPOLINE_FROM_TOKEN 1
308 #define MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE 1
309
310
311 #endif /* __MONO_MINI_ALPHA_H__ */