In corlib/System.Runtime.InteropServices:
[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
6 #include <glib.h>
7
8 #define MONO_ARCH_CPU_SPEC sparc_desc
9
10 #define MONO_MAX_IREGS 32
11 #define MONO_MAX_FREGS 32
12
13 /* Parameters used by the register allocator */
14
15 #define MONO_ARCH_HAS_XP_LOCAL_REGALLOC
16
17 /* 
18  * Use %o0..%o5 as local registers, plus %l7 since we need an extra register for
19  * holding the sreg1 in call instructions.
20  */
21 #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))
22
23 #define MONO_ARCH_CALLEE_SAVED_REGS (~MONO_ARCH_CALLEE_REGS)
24
25 #ifdef SPARCV9
26 /* Use %d34..%d62 as the double precision floating point local registers */
27 /* %d32 has the same encoding as %f1, so %d36%d38 == 0b1010 == 0xa */
28 #define MONO_ARCH_CALLEE_FREGS (0xaaaaaaa8)
29 #else
30 /* Use %f2..%f30 as the double precision floating point local registers */
31 #define MONO_ARCH_CALLEE_FREGS (0x55555554)
32 #endif
33
34 #define MONO_ARCH_CALLEE_SAVED_FREGS 0
35
36 #define MONO_ARCH_USE_FPSTACK FALSE
37 #define MONO_ARCH_FPSTACK_SIZE 0
38 #ifdef SPARCV9
39 #define MONO_ARCH_INST_FIXED_REG(desc) ((desc == 'o') ? sparc_o0 : -1)
40 #else
41 #define MONO_ARCH_INST_FIXED_REG(desc) ((desc == 'o') ? sparc_o0 : ((desc == 'l') ? sparc_o1 : -1))
42 #endif
43 #define MONO_ARCH_INST_SREG2_MASK(ins) (0)
44
45 #ifdef SPARCV9
46 #define MONO_ARCH_INST_IS_REGPAIR(desc) FALSE
47 #define MONO_ARCH_INST_REGPAIR_REG2(desc,hreg1) (-1)
48 #else
49 #define MONO_ARCH_INST_IS_REGPAIR(desc) ((desc == 'l') || (desc == 'L'))
50 #define MONO_ARCH_INST_REGPAIR_REG2(desc,hreg1) (((desc == 'l') ? sparc_o0 : (desc == 'L' ? (hreg1 + 1) : -1)))
51 #endif
52
53 #if SIZEOF_VOID_P == 8
54 #define MONO_ARCH_FRAME_ALIGNMENT 16
55 #else
56 #define MONO_ARCH_FRAME_ALIGNMENT 8
57 #endif
58
59 #define MONO_ARCH_CODE_ALIGNMENT 32
60
61 #define MONO_ARCH_BASEREG sparc_fp
62 #define MONO_ARCH_RETREG1 sparc_i0
63
64 #ifdef SPARCV9
65 #define MONO_SPARC_STACK_BIAS 2047
66 #else
67 #define MONO_SPARC_STACK_BIAS 0
68 #endif
69
70 struct MonoLMF {
71         gpointer    previous_lmf;
72         gpointer    lmf_addr;
73         MonoMethod *method;
74         gpointer    ip;
75         gpointer    sp;
76         gpointer    ebp;
77 };
78
79 typedef struct MonoContext {
80         guint8 *ip;
81         gpointer *sp;
82         gpointer *fp;
83 } MonoContext;
84
85 typedef struct MonoCompileArch {
86         gint32 lmf_offset;
87         gint32 localloc_offset;
88 } MonoCompileArch;
89
90 #define MONO_CONTEXT_SET_IP(ctx,eip) do { (ctx)->ip = (gpointer)(eip); } while (0); 
91 #define MONO_CONTEXT_SET_BP(ctx,ebp) do { (ctx)->fp = (gpointer*)(ebp); } while (0); 
92 #define MONO_CONTEXT_SET_SP(ctx,esp) do { (ctx)->sp = (gpointer*)(esp); } while (0); 
93
94 #define MONO_CONTEXT_GET_IP(ctx) ((gpointer)((ctx)->ip))
95 #define MONO_CONTEXT_GET_BP(ctx) ((gpointer)((ctx)->fp))
96 #define MONO_CONTEXT_GET_SP(ctx) ((gpointer)((ctx)->sp))
97
98 #define MONO_INIT_CONTEXT_FROM_FUNC(ctx,start_func) do {        \
99                 mono_arch_flush_register_windows ();    \
100                 MONO_CONTEXT_SET_IP ((ctx), (start_func));      \
101                 MONO_CONTEXT_SET_BP ((ctx), __builtin_frame_address (0));       \
102                 MONO_CONTEXT_SET_SP ((ctx), __builtin_frame_address (0));       \
103         } while (0)
104
105 #ifndef __linux__
106 /* 
107  * Can't use sigaction on sparc/linux, since it doesn't support SA_SIGINFO. Instead, we
108  * have to use the obsolete sigcontext parameter:
109  * http://www.ussg.iu.edu/hypermail/linux/kernel/0110.3/1531.html.
110  */
111 #define MONO_ARCH_USE_SIGACTION 1
112 #endif
113
114 #ifdef HAVE_WORKING_SIGALTSTACK
115 #define MONO_ARCH_SIGSEGV_ON_ALTSTACK
116 #endif
117
118 #define MONO_ARCH_EMULATE_FCONV_TO_I8   1
119 #define MONO_ARCH_EMULATE_LCONV_TO_R8   1
120 #define MONO_ARCH_EMULATE_LCONV_TO_R4   1
121 #define MONO_ARCH_EMULATE_CONV_R8_UN    1
122 #define MONO_ARCH_EMULATE_LCONV_TO_R8_UN 1
123 #define MONO_ARCH_EMULATE_FREM 1
124 #define MONO_ARCH_NEED_DIV_CHECK 1
125 #define MONO_ARCH_ENABLE_EMIT_STATE_OPT 1
126 #define MONO_ARCH_HAVE_THROW_CORLIB_EXCEPTION 1
127 #define MONO_ARCH_HAVE_CREATE_TRAMPOLINE_FROM_TOKEN 1
128 #define MONO_ARCH_HAVE_CREATE_SPECIFIC_TRAMPOLINE 1
129
130 #ifdef SPARCV9
131 #define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS
132 #endif
133
134 #ifndef __GNUC__
135 /* assume Sun compiler if not GCC */
136 static void * __builtin_return_address(int depth)
137 {
138         asm("ta      3");
139         asm("tst     %i0");
140         asm("be      retAddr_End");
141         asm("mov     %fp, %l0");
142         asm("retAddr_Start:");
143         asm("sub     %i0, 1, %i0");
144         asm("tst     %i0");
145         asm("bne     retAddr_Start");
146 #if SPARCV9
147         asm("ldx     [%l0+2159], %l0");
148         asm("retAddr_End:");
149         asm("ldx     [%l0+2167], %i0");
150 #else
151         asm("ld      [%l0+56], %l0");
152         asm("retAddr_End:");
153         asm("ld      [%l0+60], %i0");
154 #endif
155 }
156
157 static void * __builtin_frame_address(int depth)
158 {
159         asm("ta      3");
160         asm("tst     %i0");
161         asm("be      frameAddr_End");
162         asm("mov     %fp, %l0");
163         asm("frameAddr_Start:");
164         asm("sub     %i0, 1, %i0");
165         asm("tst     %i0");
166         asm("bne     frameAddr_Start");
167 #if SPARCV9
168         asm("ldx     [%l0+2159], %l0");
169         asm("frameAddr_End:");
170         asm("ldx     [%l0+2159], %i0");
171 #else
172         asm("ld      [%l0+56], %l0");
173         asm("frameAddr_End:");
174         asm("ld      [%l0+56], %i0");
175 #endif
176 }
177 #endif
178
179 gboolean mono_sparc_is_virtual_call (guint32 *code);
180
181 gpointer* mono_sparc_get_vcall_slot_addr (guint32 *code, gpointer *regs);
182
183 void mono_sparc_flushw (void);
184
185 gboolean mono_sparc_is_v9 (void);
186
187 gboolean mono_sparc_is_sparc64 (void);
188
189 struct MonoCompile;
190
191 guint32* mono_sparc_emit_save_lmf (guint32* code, guint32 lmf_offset);
192
193 guint32* mono_sparc_emit_restore_lmf (guint32 *code, guint32 lmf_offset);
194
195 #endif /* __MONO_MINI_SPARC_H__ */