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