2010-02-02 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / mini / mini-sparc.h
index 984f63d633e8c88381be7d90a12a38dd338dd87c..5cc2ec47a61ba89b58d75fad52d44ddc8bb2450e 100644 (file)
@@ -5,14 +5,57 @@
 
 #include <glib.h>
 
+#define MONO_ARCH_CPU_SPEC sparc_desc
+
 #define MONO_MAX_IREGS 32
 #define MONO_MAX_FREGS 32
 
-#define MONO_ARCH_FRAME_ALIGNMENT (sizeof (gpointer) * 2)
+/* Parameters used by the register allocator */
+
+/* 
+ * Use %o0..%o5 as local registers, plus %l7 since we need an extra register for
+ * holding the sreg1 in call instructions.
+ */
+#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))
+
+#define MONO_ARCH_CALLEE_SAVED_REGS ((~MONO_ARCH_CALLEE_REGS) & ~(1 << sparc_g1))
+
+#ifdef SPARCV9
+/* Use %d34..%d62 as the double precision floating point local registers */
+/* %d32 has the same encoding as %f1, so %d36%d38 == 0b1010 == 0xa */
+#define MONO_ARCH_CALLEE_FREGS (0xaaaaaaa8)
+#else
+/* Use %f2..%f30 as the double precision floating point local registers */
+#define MONO_ARCH_CALLEE_FREGS (0x55555554)
+#endif
+
+#define MONO_ARCH_CALLEE_SAVED_FREGS 0
+
+#define MONO_ARCH_USE_FPSTACK FALSE
+#define MONO_ARCH_FPSTACK_SIZE 0
+#ifdef SPARCV9
+#define MONO_ARCH_INST_FIXED_REG(desc) ((desc == 'o') ? sparc_o0 : -1)
+#else
+#define MONO_ARCH_INST_FIXED_REG(desc) ((desc == 'o') ? sparc_o0 : ((desc == 'l') ? sparc_o1 : -1))
+#endif
+#define MONO_ARCH_INST_SREG2_MASK(ins) (0)
+
+#ifdef SPARCV9
+#define MONO_ARCH_INST_IS_REGPAIR(desc) FALSE
+#define MONO_ARCH_INST_REGPAIR_REG2(desc,hreg1) (-1)
+#else
+#define MONO_ARCH_INST_IS_REGPAIR(desc) ((desc == 'l') || (desc == 'L'))
+#define MONO_ARCH_INST_REGPAIR_REG2(desc,hreg1) (((desc == 'l') ? sparc_o0 : (desc == 'L' ? (hreg1 + 1) : -1)))
+#endif
+
+#if SIZEOF_VOID_P == 8
+#define MONO_ARCH_FRAME_ALIGNMENT 16
+#else
+#define MONO_ARCH_FRAME_ALIGNMENT 8
+#endif
 
 #define MONO_ARCH_CODE_ALIGNMENT 32
 
-#define MONO_ARCH_BASEREG sparc_fp
 #define MONO_ARCH_RETREG1 sparc_i0
 
 #ifdef SPARCV9
@@ -39,6 +82,7 @@ typedef struct MonoContext {
 typedef struct MonoCompileArch {
        gint32 lmf_offset;
        gint32 localloc_offset;
+       void *float_spill_slot;
 } MonoCompileArch;
 
 #define MONO_CONTEXT_SET_IP(ctx,eip) do { (ctx)->ip = (gpointer)(eip); } while (0); 
@@ -53,12 +97,20 @@ typedef struct MonoCompileArch {
                mono_arch_flush_register_windows ();    \
                MONO_CONTEXT_SET_IP ((ctx), (start_func));      \
                MONO_CONTEXT_SET_BP ((ctx), __builtin_frame_address (0));       \
+               MONO_CONTEXT_SET_SP ((ctx), __builtin_frame_address (0));       \
        } while (0)
 
+#ifndef __linux__
+/* 
+ * Can't use sigaction on sparc/linux, since it doesn't support SA_SIGINFO. Instead, we
+ * have to use the obsolete sigcontext parameter:
+ * http://www.ussg.iu.edu/hypermail/linux/kernel/0110.3/1531.html.
+ */
 #define MONO_ARCH_USE_SIGACTION 1
+#endif
 
 #ifdef HAVE_WORKING_SIGALTSTACK
-#define MONO_ARCH_SIGSEGV_ON_ALTSTACK
+/*#define MONO_ARCH_SIGSEGV_ON_ALTSTACK*/
 #endif
 
 #define MONO_ARCH_EMULATE_FCONV_TO_I8   1
@@ -69,6 +121,9 @@ typedef struct MonoCompileArch {
 #define MONO_ARCH_EMULATE_FREM 1
 #define MONO_ARCH_NEED_DIV_CHECK 1
 #define MONO_ARCH_HAVE_THROW_CORLIB_EXCEPTION 1
+#define MONO_ARCH_HAVE_IMT 1
+#define MONO_ARCH_IMT_REG sparc_g1
+#define MONO_ARCH_HAVE_DECOMPOSE_LONG_OPTS 1
 
 #ifdef SPARCV9
 #define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS
@@ -121,7 +176,7 @@ static void * __builtin_frame_address(int depth)
 
 gboolean mono_sparc_is_virtual_call (guint32 *code);
 
-gpointer* mono_sparc_get_vcall_slot_addr (guint32 *code, gpointer *fp);
+gpointer* mono_sparc_get_vcall_slot_addr (guint32 *code, mgreg_t *regs);
 
 void mono_sparc_flushw (void);