Merge pull request #733 from amoiseev-softheme/bugfix/monofix
[mono.git] / mono / mini / mini-sparc.h
1 #ifndef __MONO_MINI_SPARC_H__
2 #define __MONO_MINI_SPARC_H__
3
4 #include <mono/arch/sparc/sparc-codegen.h>
5 #include <mono/utils/mono-context.h>
6
7 #include <glib.h>
8
9 #define MONO_ARCH_CPU_SPEC sparc_desc
10
11 #define MONO_MAX_IREGS 32
12 #define MONO_MAX_FREGS 32
13
14 /* Parameters used by the register allocator */
15
16 /* 
17  * Use %o0..%o5 as local registers, plus %l7 since we need an extra register for
18  * holding the sreg1 in call instructions.
19  */
20 #define MONO_ARCH_CALLEE_REGS ((1 << sparc_o0) | (1 << sparc_o1) | (1 << sparc_o2) | (1 << sparc_o3) | (1 << sparc_o4) | (1 << sparc_o5) | (1 << sparc_l7))
21
22 #define MONO_ARCH_CALLEE_SAVED_REGS ((~MONO_ARCH_CALLEE_REGS) & ~(1 << sparc_g1))
23
24 #ifdef SPARCV9
25 /* Use %d34..%d62 as the double precision floating point local registers */
26 /* %d32 has the same encoding as %f1, so %d36%d38 == 0b1010 == 0xa */
27 #define MONO_ARCH_CALLEE_FREGS (0xaaaaaaa8)
28 #else
29 /* Use %f2..%f30 as the double precision floating point local registers */
30 #define MONO_ARCH_CALLEE_FREGS (0x55555554)
31 #endif
32
33 #define MONO_ARCH_CALLEE_SAVED_FREGS 0
34
35 #define MONO_ARCH_USE_FPSTACK FALSE
36 #define MONO_ARCH_FPSTACK_SIZE 0
37 #ifdef SPARCV9
38 #define MONO_ARCH_INST_FIXED_REG(desc) ((desc == 'o') ? sparc_o0 : -1)
39 #else
40 #define MONO_ARCH_INST_FIXED_REG(desc) ((desc == 'o') ? sparc_o0 : ((desc == 'l') ? sparc_o1 : -1))
41 #endif
42 #define MONO_ARCH_INST_SREG2_MASK(ins) (0)
43
44 #ifdef SPARCV9
45 #define MONO_ARCH_INST_IS_REGPAIR(desc) FALSE
46 #define MONO_ARCH_INST_REGPAIR_REG2(desc,hreg1) (-1)
47 #else
48 #define MONO_ARCH_INST_IS_REGPAIR(desc) ((desc == 'l') || (desc == 'L'))
49 #define MONO_ARCH_INST_REGPAIR_REG2(desc,hreg1) (((desc == 'l') ? sparc_o0 : (desc == 'L' ? (hreg1 + 1) : -1)))
50 #endif
51
52 #if SIZEOF_VOID_P == 8
53 #define MONO_ARCH_FRAME_ALIGNMENT 16
54 #else
55 #define MONO_ARCH_FRAME_ALIGNMENT 8
56 #endif
57
58 #define MONO_ARCH_CODE_ALIGNMENT 32
59
60 #define MONO_ARCH_RETREG1 sparc_i0
61
62 #ifdef SPARCV9
63 #define MONO_SPARC_STACK_BIAS 2047
64 #else
65 #define MONO_SPARC_STACK_BIAS 0
66 #endif
67
68 struct MonoLMF {
69         gpointer    previous_lmf;
70         gpointer    lmf_addr;
71         MonoMethod *method;
72         gpointer    ip;
73         gpointer    sp;
74         gpointer    ebp;
75 };
76
77 typedef struct MonoCompileArch {
78         gint32 lmf_offset;
79         gint32 localloc_offset;
80         void *float_spill_slot;
81 } MonoCompileArch;
82
83 #define MONO_INIT_CONTEXT_FROM_FUNC(ctx,start_func) do {        \
84                 mono_arch_flush_register_windows ();    \
85                 MONO_CONTEXT_SET_IP ((ctx), (start_func));      \
86                 MONO_CONTEXT_SET_BP ((ctx), __builtin_frame_address (0));       \
87                 MONO_CONTEXT_SET_SP ((ctx), __builtin_frame_address (0));       \
88         } while (0)
89
90 #define MONO_ARCH_INIT_TOP_LMF_ENTRY(lmf) do { (lmf)->ebp = -1; } while (0)
91
92 #define MONO_ARCH_USE_SIGACTION 1
93
94 #ifdef HAVE_WORKING_SIGALTSTACK
95 /*#define MONO_ARCH_SIGSEGV_ON_ALTSTACK*/
96 #endif
97
98 #define MONO_ARCH_EMULATE_FCONV_TO_I8   1
99 #define MONO_ARCH_EMULATE_LCONV_TO_R8   1
100 #define MONO_ARCH_EMULATE_LCONV_TO_R4   1
101 #define MONO_ARCH_EMULATE_CONV_R8_UN    1
102 #define MONO_ARCH_EMULATE_LCONV_TO_R8_UN 1
103 #define MONO_ARCH_EMULATE_FREM 1
104 #define MONO_ARCH_NEED_DIV_CHECK 1
105 #define MONO_ARCH_HAVE_IMT 1
106 #define MONO_ARCH_IMT_REG sparc_g1
107 #define MONO_ARCH_HAVE_DECOMPOSE_LONG_OPTS 1
108 #define MONO_ARCH_HAVE_TLS_INIT 1
109
110 void mono_arch_tls_init (void);
111
112 #ifdef SPARCV9
113 #define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS
114 #endif
115
116 #define MONO_ARCH_THIS_AS_FIRST_ARG 1
117
118 #ifndef __GNUC__
119 /* assume Sun compiler if not GCC */
120 static void * __builtin_return_address(int depth)
121 {
122         asm("ta      3");
123         asm("tst     %i0");
124         asm("be      retAddr_End");
125         asm("mov     %fp, %l0");
126         asm("retAddr_Start:");
127         asm("sub     %i0, 1, %i0");
128         asm("tst     %i0");
129         asm("bne     retAddr_Start");
130 #if SPARCV9
131         asm("ldx     [%l0+2159], %l0");
132         asm("retAddr_End:");
133         asm("ldx     [%l0+2167], %i0");
134 #else
135         asm("ld      [%l0+56], %l0");
136         asm("retAddr_End:");
137         asm("ld      [%l0+60], %i0");
138 #endif
139 }
140
141 static void * __builtin_frame_address(int depth)
142 {
143         asm("ta      3");
144         asm("tst     %i0");
145         asm("be      frameAddr_End");
146         asm("mov     %fp, %l0");
147         asm("frameAddr_Start:");
148         asm("sub     %i0, 1, %i0");
149         asm("tst     %i0");
150         asm("bne     frameAddr_Start");
151 #if SPARCV9
152         asm("ldx     [%l0+2159], %l0");
153         asm("frameAddr_End:");
154         asm("ldx     [%l0+2159], %i0");
155 #else
156         asm("ld      [%l0+56], %l0");
157         asm("frameAddr_End:");
158         asm("ld      [%l0+56], %i0");
159 #endif
160 }
161 #endif
162
163 gboolean mono_sparc_is_virtual_call (guint32 *code);
164
165 gpointer* mono_sparc_get_vcall_slot_addr (guint32 *code, mgreg_t *regs);
166
167 void mono_sparc_flushw (void);
168
169 gboolean mono_sparc_is_v9 (void);
170
171 gboolean mono_sparc_is_sparc64 (void);
172
173 struct MonoCompile;
174
175 guint32* mono_sparc_emit_save_lmf (guint32* code, guint32 lmf_offset);
176
177 guint32* mono_sparc_emit_restore_lmf (guint32 *code, guint32 lmf_offset);
178
179 #endif /* __MONO_MINI_SPARC_H__ */