Bring s390 JIT up to date.
authorNeale Ferguson <neale@mono-cvs.ximian.com>
Fri, 7 May 2004 19:53:40 +0000 (19:53 -0000)
committerNeale Ferguson <neale@mono-cvs.ximian.com>
Fri, 7 May 2004 19:53:40 +0000 (19:53 -0000)
svn path=/trunk/mono/; revision=26943

mono/arch/s390/s390-codegen.h
mono/arch/s390/tramp.c
mono/mini/cpu-s390.md
mono/mini/exceptions-s390.c
mono/mini/inssel-s390.brg
mono/mini/mini-s390.c
mono/mini/mini-s390.h
mono/mini/mini.c

index 5f6c25569c7f95f0928201fd2fc0244249323958..9e590334b0bcc945ab1bd3043e1251092dde043d 100644 (file)
@@ -7,6 +7,73 @@
 #include <glib.h>
 #include <assert.h>
 
+#define FLOAT_REGS     2       /* No. float registers for parms    */
+#define GENERAL_REGS   5       /* No. general registers for parms  */
+
+#define ARG_BASE s390_r10      /* Register for addressing arguments*/
+#define STKARG \
+       (i*(sizeof(stackval)))  /* Displacement of ith argument     */
+
+#define MINV_POS       96      /* MonoInvocation stack offset      */
+#define STACK_POS      (MINV_POS - sizeof (stackval) * sig->param_count)
+#define OBJ_POS        8
+#define TYPE_OFFSET    (G_STRUCT_OFFSET (stackval, type))
+
+#define MIN_CACHE_LINE 256
+
+/*------------------------------------------------------------------*/
+/* Sequence to add an int/long long to parameters to stack_from_data*/
+/*------------------------------------------------------------------*/
+#define ADD_ISTACK_PARM(r, i) \
+       if (reg_param < GENERAL_REGS-(r)) { \
+               s390_la (p, s390_r4, 0, STK_BASE, \
+                        local_start + (reg_param - this_flag) * sizeof(long)); \
+               reg_param += (i); \
+       } else { \
+               s390_la (p, s390_r4, 0, STK_BASE, \
+                        sz.stack_size + MINV_POS + stack_param * sizeof(long)); \
+               stack_param += (i); \
+       }
+
+/*------------------------------------------------------------------*/
+/* Sequence to add a float/double to parameters to stack_from_data  */
+/*------------------------------------------------------------------*/
+#define ADD_RSTACK_PARM(i) \
+       if (fpr_param < FLOAT_REGS) { \
+               s390_la (p, s390_r4, 0, STK_BASE, \
+                        float_pos + (fpr_param * sizeof(float) * (i))); \
+               fpr_param++; \
+       } else { \
+               stack_param += (stack_param % (i)); \
+               s390_la (p, s390_r4, 0, STK_BASE, \
+                        sz.stack_size + MINV_POS + stack_param * sizeof(float) * (i)); \
+               stack_param += (i); \
+       }
+
+/*------------------------------------------------------------------*/
+/* Sequence to add a structure ptr to parameters to stack_from_data */
+/*------------------------------------------------------------------*/
+#define ADD_TSTACK_PARM \
+       if (reg_param < GENERAL_REGS) { \
+               s390_l (p, s390_r4, 0, STK_BASE, \
+                       local_start + (reg_param - this_flag) * sizeof(long)); \
+               reg_param++; \
+       } else { \
+               s390_l (p, s390_r4, 0, STK_BASE, \
+                       sz.stack_size + MINV_POS + stack_param * sizeof(long)); \
+               stack_param++; \
+       }
+
+#define ADD_PSTACK_PARM(r, i) \
+       if (reg_param < GENERAL_REGS-(r)) { \
+               s390_la (p, s390_r4, 0, STK_BASE, \
+                        local_start + (reg_param - this_flag) * sizeof(long)); \
+               reg_param += (i); \
+       } else { \
+               s390_l (p, s390_r4, 0, STK_BASE, \
+                       sz.stack_size + MINV_POS + stack_param * sizeof(long)); \
+               stack_param++; \
+       }
 typedef enum {
        s390_r0 = 0,
        s390_r1,
@@ -49,34 +116,186 @@ typedef enum {
        s390_fpc = 256,
 } S390SpecialRegister;
 
-#define s390_word(addr, value)         *((guint32 *) addr) = (guint32) (value); ((guint32 *) addr)++
-#define s390_emit16(c, x)              *((guint16 *) c) = x; ((guint16 *) c)++
-#define s390_emit32(c, x)              *((guint32 *) c) = x; ((guint32 *) c)++
+#define s390_is_imm16(val)             ((gint)val >= (gint)-(1<<15) && \
+                                        (gint)val <= (gint)((1<<15)-1))
+#define s390_is_uimm16(val)            ((gint)val >= 0 && (gint)val <= 65535)
+#define s390_is_imm12(val)             ((gint)val >= (gint)-(1<<11) && \
+                                        (gint)val <= (gint)((1<<15)-1))
+#define s390_is_uimm12(val)            ((gint)val >= 0 && (gint)val <= 4095)
+
+#define STK_BASE                       s390_r15
+#define S390_MINIMAL_STACK_SIZE                96
+#define S390_REG_SAVE_OFFSET           24
+#define S390_RET_ADDR_OFFSET           56
+
+#define S390_CC_ZR                     8
+#define S390_CC_NE                     7
+#define S390_CC_NZ                     7
+#define S390_CC_LT                     4
+#define S390_CC_GT                     2
+#define S390_CC_GE                     11
+#define S390_CC_LE                     13
+#define S390_CC_OV                     1
+#define S390_CC_NO                     14
+#define S390_CC_CY                     3
+#define S390_CC_NC                     12
+#define S390_CC_UN                     15
+
+#define s390_word(addr, value)         do {*((guint32 *) addr) = (guint32) (value); \
+                                           ((guint32 *) addr)++;} while (0)
+#define s390_float(addr, value)                do {*((guint32 *) addr) = (guint32) (value); \
+                                           ((guint32 *) addr)++;} while (0)
+#define s390_llong(addr, value)                do {*((guint64 *) addr) = (guint64) (value); \
+                                           ((guint64 *) addr)++;} while (0)
+#define s390_double(addr, value)       do {*((guint64 *) addr) = (guint64) (value); \
+                                           ((guint64 *) addr)++;} while (0)
+#define s390_emit16(c, x)              do {*((guint16 *) c) = x; ((guint16 *) c)++;} while(0)
+#define s390_emit32(c, x)              do {*((guint32 *) c) = x; ((guint32 *) c)++;} while(0)
 #define s390_basr(code, r1, r2)                s390_emit16 (code, (13 << 8 | (r1) << 4 | (r2)))
 #define s390_bras(code, r, o)          s390_emit32 (code, (167 << 24 | (r) << 20 | 5 << 16 | (o)))
+#define s390_brasl(code, r, o)         do {s390_emit16 (code, (192 << 8 | (r) << 4 | 5)); \
+                                           s390_emit32 (code, (o));} while(0)
 #define s390_ahi(code, r, v)           s390_emit32 (code, (167 << 24 | (r) << 20 | 10 << 16 | ((v) & 0xffff)))
+#define s390_alcr(code, r1, r2)                s390_emit32 (code, (185 << 24 | 152 << 16 | (r1) << 4 | (r2)))
+#define s390_ar(code, r1, r2)          s390_emit16 (code, (26 << 8 | (r1) << 4 | (r2)))
+#define s390_alr(code, r1, r2)         s390_emit16 (code, (30 << 8 | (r1) << 4 | (r2)))
+#define s390_a(code, r, x, b, d)       s390_emit32 (code, (90 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
+#define s390_al(code, r, x, b, d)      s390_emit32 (code, (94 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
+#define s390_slbr(code, r1, r2)                s390_emit32 (code, (185 << 24 | 153 << 16 | (r1) << 4 | (r2)))
+#define s390_sr(code, r1, r2)          s390_emit16 (code, (27 << 8 | (r1) << 4 | (r2)))
+#define s390_slr(code, r1, r2)         s390_emit16 (code, (31 << 8 | (r1) << 4 | (r2)))
+#define s390_s(code, r, x, b, d)       s390_emit32 (code, (91 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
+#define s390_sl(code, r, x, b, d)      s390_emit32 (code, (95 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
+#define s390_mr(code, r1, r2)          s390_emit16 (code, (28 << 8 | (r1) << 4 | (r2)))
+#define s390_m(code, r, x, b, d)       s390_emit32 (code, (92 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
+#define s390_msr(code, r1, r2)         s390_emit32 (code, (178 << 24 | 82 << 16 | (r1) << 4| (r2)))
+#define s390_ms(code, r, x, b, d)      s390_emit32 (code, (113 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
+#define s390_mlr(code, r1, r2)         s390_emit32 (code, (185 << 24 | 150 << 16 | (r1) << 4| (r2)))
+#define s390_dr(code, r1, r2)          s390_emit16 (code, (29 << 8 | (r1) << 4 | (r2)))
+#define s390_d(code, r, x, b, d)       s390_emit32 (code, (93 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
+#define s390_dlr(code, r1, r2)         s390_emit32 (code, (185 << 24 | 151 << 16 | (r1) << 4| (r2)))
 #define s390_br(code, r)               s390_emit16 (code, (7 << 8 | 15 << 4 | (r)))
 #define s390_nr(code, r1, r2)          s390_emit16 (code, (20 << 8 | (r1) << 4 | (r2)))
+#define s390_n(code, r, x, b, d)       s390_emit32 (code, (84 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
+#define s390_or(code, r1, r2)          s390_emit16 (code, (22 << 8 | (r1) << 4 | (r2)))
+#define s390_o(code, r, x, b, d)       s390_emit32 (code, (86 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
+#define s390_xr(code, r1, r2)          s390_emit16 (code, (23 << 8 | (r1) << 4 | (r2)))
+#define s390_x(code, r, x, b, d)       s390_emit32 (code, (87 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
 #define s390_lr(code, r1, r2)          s390_emit16 (code, (24 << 8 | (r1) << 4 | (r2)))
-#define s390_l(code, r, b, d)          s390_emit32 (code, (88 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
+#define s390_ltr(code, r1, r2)         s390_emit16 (code, (18 << 8 | (r1) << 4 | (r2)))
+#define s390_l(code, r, x, b, d)       s390_emit32 (code, (88 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
+#define s390_lcr(code, r1, r2)         s390_emit16 (code, (19 << 8 | (r1) << 4 | (r2)))
+#define s390_lnr(code, r1, r2)         s390_emit16 (code, (17 << 8 | (r1) << 4 | (r2)))
+#define s390_lpr(code, r1, r2)         s390_emit16 (code, (16 << 8 | (r1) << 4 | (r2)))
 #define s390_lm(code, r1, r2, b, d)    s390_emit32 (code, (152 << 24 | (r1) << 20 | (r2) << 16 \
                                                    | (b) << 12 | ((d) & 0xfff)))
-#define s390_lh(code, r, b, d)         s390_emit32 (code, (72 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
+#define s390_lh(code, r, x, b, d)      s390_emit32 (code, (72 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
 #define s390_lhi(code, r, v)           s390_emit32 (code, (167 << 24 | (r) << 20 | 8 << 16 | ((v) & 0xffff)))
-#define s390_ic(code, r, b, d)         s390_emit32 (code, (67 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
-#define s390_st(code, r, b, d)         s390_emit32 (code, (80 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
+#define s390_ic(code, r, x, b, d)      s390_emit32 (code, (67 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
+#define s390_icm(code, r, m, b, d)     s390_emit32 (code, (191 << 24 | (r) << 20 | (m) << 16 | (b) << 12 | ((d) & 0xfff)))
+#define s390_st(code, r, x, b, d)      s390_emit32 (code, (80 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
 #define s390_stm(code, r1, r2, b, d)   s390_emit32 (code, (144 << 24 | (r1) << 20 | (r2) << 16 \
                                                    | (b) << 12 | ((d) & 0xfff)))
-#define s390_sth(code, r, b, d)                s390_emit32 (code, (64 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
-#define s390_stc(code, r, b, d)                s390_emit32 (code, (66 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
-#define s390_la(code, r, b, d)         s390_emit32 (code, (65 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
-#define s390_ld(code, f, b, d)         s390_emit32 (code, (104 << 24 | (f) << 20 | (b) << 12 | ((d) & 0xfff)))
-#define s390_le(code, f, b, d)         s390_emit32 (code, (120 << 24 | (f) << 20 | (b) << 12 | ((d) & 0xfff)))
-#define s390_std(code, f, b, d)                s390_emit32 (code, (96 << 24 | (f) << 20 | (b) << 12 | ((d) & 0xfff)))
-#define s390_ste(code, f, b, d)                s390_emit32 (code, (112 << 24 | (f) << 20 | (b) << 12 | ((d) & 0xfff)))
-#define s390_mvc(c, l, b1, d1, b2, d2) s390_emit32 (c, (210 << 24 | ((((l)-1)  << 16) & 0x00ff0000) | \
+#define s390_stam(c, r1, r2, b, d)     s390_emit32 (code, (155 << 24 | (r1) << 20 | (r2) << 16 \
+                                                   | (b) << 12 | ((d) & 0xfff)))
+#define s390_lam(c, r1, r2, b, d)      s390_emit32 (code, (154 << 24 | (r1) << 20 | (r2) << 16 \
+                                                   | (b) << 12 | ((d) & 0xfff)))
+#define s390_sth(code, r, x, b, d)     s390_emit32 (code, (64 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
+#define s390_stc(code, r, x, b, d)     s390_emit32 (code, (66 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
+#define s390_stcm(code, r, m, b, d)    s390_emit32 (code, (190 << 24 | (r) << 20 | (m) << 16 | (b) << 12 | ((d) & 0xfff)))
+#define s390_la(code, r, x, b, d)      s390_emit32 (code, (65 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
+#define s390_larl(code, r, o)          do {                                            \
+                                           s390_emit16 (code, (192 << 8 | (r) << 4));  \
+                                           s390_emit32 (code, (o));                    \
+                                       } while (0)
+#define s390_ld(code, f, x, b, d)      s390_emit32 (code, (104 << 24 | (f) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
+#define s390_le(code, f, x, b, d)      s390_emit32 (code, (120 << 24 | (f) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
+#define s390_std(code, f, x, b, d)     s390_emit32 (code, (96 << 24 | (f) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
+#define s390_ste(code, f, x, b, d)     s390_emit32 (code, (112 << 24 | (f) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
+#define s390_mvc(c, l, b1, d1, b2, d2) do {s390_emit32 (c, (210 << 24 | ((((l)-1)  << 16) & 0x00ff0000) | \
                                                        (b1) << 12 | ((d1) & 0xfff)));            \
-                                       s390_emit16 (c, ((b2) << 12 | ((d2) & 0xfff)))
-#define s390_mvcl(c, r1, r2)           s390_emit16 (c, (14 << 8 | (r1) << 4 | (r2)));
+                                           s390_emit16 (c, ((b2) << 12 | ((d2) & 0xfff)));} while (0)
+#define s390_mvcl(c, r1, r2)           s390_emit16 (c, (14 << 8 | (r1) << 4 | (r2)))
+#define s390_break(c)                  s390_emit16 (c, 0)
+#define s390_nill(c, r1, v)            s390_emit32 (c, (165 << 24 | (r1) << 20 | 7 << 16 | ((v) & 0xffff)))
+#define s390_nilh(c, r1, v)            s390_emit32 (c, (165 << 24 | (r1) << 20 | 6 << 16 | ((v) & 0xffff)))
+#define s390_brc(c, m, d)              s390_emit32 (c, (167 << 24 | ((m) & 0xff) << 20 | 4 << 16 | ((d) & 0xffff)))
+#define s390_cr(c, r1, r2)             s390_emit16 (c, (25 << 8 | (r1) << 4 | (r2)))
+#define s390_clr(c, r1, r2)            s390_emit16 (c, (21 << 8 | (r1) << 4 | (r2)))
+#define s390_c(c, r, x, b, d)          s390_emit32 (c, (89 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
+#define s390_cl(c, r, x, b, d)         s390_emit32 (c, (85 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
+#define s390_j(c,d)                    s390_brc(c, S390_CC_UN, d)
+#define s390_je(c, d)                  s390_brc(c, S390_CC_EQ, d)
+#define s390_jeo(c, d)                 s390_brc(c, S390_CC_ZR|S390_CC_OV, d)
+#define s390_jz(c, d)                  s390_brc(c, S390_CC_ZR, d)
+#define s390_jnz(c, d)                 s390_brc(c, S390_CC_NZ, d)
+#define s390_jne(c, d)                 s390_brc(c, S390_CC_NZ, d)
+#define s390_jp(c, d)                  s390_brc(c, S390_CC_GT, d)
+#define s390_jm(c, d)                  s390_brc(c, S390_CC_LT, d)
+#define s390_jh(c, d)                  s390_brc(c, S390_CC_GT, d)
+#define s390_jl(c, d)                  s390_brc(c, S390_CC_LT, d)
+#define s390_jnh(c, d)                 s390_brc(c, S390_CC_LE, d)
+#define s390_jo(c, d)                  s390_brc(c, S390_CC_OV, d)
+#define s390_jnl(c, d)                 s390_brc(c, S390_CC_GE, d)                      
+#define s390_jlo(c, d)                 s390_brc(c, S390_CC_LT|S390_CC_OV, d)
+#define s390_jho(c, d)                 s390_brc(c, S390_CC_GT|S390_CC_OV, d)           
+#define s390_jc(c, m, d)               s390_brc(c, m, d)
+#define s390_jcl(c, m, d)              do {s390_emit16 (c, (192 << 8 | (m) << 4 | 4)); \
+                                           s390_emit32 (c, (d));} while(0)
+#define s390_slda(c, r, b, d)          s390_emit32 (c, (143 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
+#define s390_sldl(c, r, b, d)          s390_emit32 (c, (141 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
+#define s390_srda(c, r, b, d)          s390_emit32 (c, (142 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
+#define s390_srdl(c, r, b, d)          s390_emit32 (c, (140 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
+#define s390_sla(c, r, b, d)           s390_emit32 (c, (139 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
+#define s390_sll(c, r, b, d)           s390_emit32 (c, (137 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
+#define s390_sra(c, r, b, d)           s390_emit32 (c, (138 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
+#define s390_srl(c, r, b, d)           s390_emit32 (c, (136 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
+#define s390_sqdbr(c, r1, r2)          s390_emit32 (c, (179 << 24 | 21 << 16 | ((r1) << 4) | (r2)))
+#define s390_sqebr(c, r1, r2)          s390_emit32 (c, (179 << 24 | 20 << 16 | ((r1) << 4) | (r2)))
+#define s390_adbr(c, r1, r2)           s390_emit32 (c, (179 << 24 | 26 << 16 | ((r1) << 4) | (r2)))
+#define s390_aebr(c, r1, r2)           s390_emit32 (c, (179 << 24 | 10 << 16 | ((r1) << 4) | (r2)))
+#define s390_adb(c, r, x, b, d)                do {s390_emit32 (c, (237 << 24 | (r) << 20 |    \
+                                            (x) << 16 | (b) << 12 | ((d) & 0xfff)));   \
+                                           s390_emit16 (c, (26));                      \
+                                       } while (0)
+#define s390_sdbr(c, r1, r2)           s390_emit32 (c, (179 << 24 | 27 << 16 | ((r1) << 4) | (r2)))
+#define s390_sdb(c, r, x, b, d)                do {s390_emit32 (c, (237 << 24 | (r) << 20 |    \
+                                            (x) << 16 | (b) << 12 | ((d) & 0xfff)));   \
+                                           s390_emit16 (c, (27));                      \
+                                       } while (0)
+#define s390_sebr(c, r1, r2)           s390_emit32 (c, (179 << 24 | 11 << 16 | ((r1) << 4) | (r2)))
+#define s390_mdbr(c, r1, r2)           s390_emit32 (c, (179 << 24 | 28 << 16 | ((r1) << 4) | (r2)))
+#define s390_meebr(c, r1, r2)          s390_emit32 (c, (179 << 24 | 23 << 16 | ((r1) << 4) | (r2)))
+#define s390_ldr(c, r1, r2)            s390_emit16 (c, (40 << 8 | (r1) << 4 | (r2)))
+#define s390_ler(c, r1, r2)            s390_emit16 (c, (56 << 8 | (r1) << 4 | (r2)))
+#define s390_lzdr(c, r1)               s390_emit32 (c, (179 << 24 | 117 << 16 | (r1) << 4))
+#define s390_lzer(c, r1)               s390_emit32 (c, (179 << 24 | 116 << 16 | (r1) << 4))
+#define s390_ddbr(c, r1, r2)           s390_emit32 (c, (179 << 24 | 29 << 16 | ((r1) << 4) | (r2)))
+#define s390_debr(c, r1, r2)           s390_emit32 (c, (179 << 24 | 13 << 16 | ((r1) << 4) | (r2)))
+#define s390_didbr(c, r1, r2, m, r3)   s390_emit32 (c, (179 << 24 | 91 << 16 | ((r3) << 12) | ((m) << 8) | ((r1) << 4) | (r2)))
+#define s390_lcdbr(c, r1, r2)          s390_emit32 (c, (179 << 24 | 19 << 16 | ((r1) << 4) | (r2)))
+#define s390_lndbr(c, r1, r2)          s390_emit32 (c, (179 << 24 | 17 << 16 | ((r1) << 4) | (r2)))
+#define s390_ldebr(c, r1, r2)          s390_emit32 (c, (179 << 24 | 4 << 16 | ((r1) << 4) | (r2)))
+#define s390_lnebr(c, r1, r2)          s390_emit32 (c, (179 << 24 | 1 << 16 | ((r1) << 4) | (r2)))
+#define s390_ledbr(c, r1, r2)          s390_emit32 (c, (179 << 24 | 68 << 16 | ((r1) << 4) | (r2)))
+#define s390_cfdbr(c, r1, m, f2)       s390_emit32 (c, (179 << 24 | 153 << 16 | (m) << 8 | (r1) << 4 | (f2)))
+#define s390_cdfbr(c, r1, r2)          s390_emit32 (c, (179 << 24 | 149 << 16 | (r1) << 4 | (r2)))
+#define s390_cefbr(c, r1, r2)          s390_emit32 (c, (179 << 24 | 148 << 16 | (r1) << 4 | (r2)))
+#define s390_cdbr(c, r1, r2)           s390_emit32 (c, (179 << 24 | 25 << 16 | (r1) << 4 | (r2)))
+#define s390_cebr(c, r1, r2)           s390_emit32 (c, (179 << 24 | 9 << 16 | (r1) << 4 | (r2)))
+#define s390_cdb(c, r, x, b, d)                do {s390_emit32 (c, (237 << 24 | (r) << 20 |    \
+                                            (x) << 16 | (b) << 12 | ((d) & 0xfff)));   \
+                                           s390_emit16 (c, (25));                      \
+                                       } while (0)
+#define s390_tcdb(c, r, x, b, d)       do {s390_emit32 (c, (237 << 24 | (r) << 20 |    \
+                                            (x) << 16 | (b) << 12 | ((d) & 0xfff)));   \
+                                           s390_emit16 (c, (17));                      \
+                                       } while (0)
+#define s390_tedb(c, r, x, b, d)       do {s390_emit32 (c, (237 << 24 | (r) << 20 |    \
+                                            (x) << 16 | (b) << 12 | ((d) & 0xfff)));   \
+                                           s390_emit16 (c, (16));                      \
+                                       } while (0)
+#define s390_stfpc(c, b, d)            s390_emit32 (c, (178 << 24 | 156 << 16 | \
+                                                   (b) << 12 | ((d) & 0xfff)))
 
 #endif
index 50fa1a458a2417375894371095d341ad185d3b64..d1dec5e96e5030666744790fa67983384323839d 100644 (file)
 #define PROLOG_INS     24      /* Size of emitted prolog           */
 #define CALL_INS       4       /* Size of emitted call             */
 #define EPILOG_INS     18      /* Size of emitted epilog           */
-#define MIN_STACK_SIZE         96      /* Basic size of S/390 stack frame  */
-#define FLOAT_REGS     2       /* No. float registers for parms    */
-#define GENERAL_REGS   5       /* No. general registers for parms  */
-
-#define ARG_BASE s390_r10      /* Register for addressing arguments*/
-#define STK_BASE s390_r15      /* Register for addressing stack    */
-#define STKARG \
-       (i*(sizeof(stackval)))  /* Displacement of ith argument     */
-
-#define MINV_POS       96      /* MonoInvocation stack offset      */
-#define STACK_POS      (MINV_POS - sizeof (stackval) * sig->param_count)
-#define OBJ_POS        8
-#define TYPE_OFFSET    (G_STRUCT_OFFSET (stackval, type))
 
 #define DEBUG(x)
 
-#define MIN_CACHE_LINE 256
-
-/*------------------------------------------------------------------*/
-/* Sequence to add an int/long long to parameters to stack_from_data*/
-/*------------------------------------------------------------------*/
-#define ADD_ISTACK_PARM(r, i) \
-       if (reg_param < GENERAL_REGS-(r)) { \
-               s390_la (p, s390_r4, STK_BASE, \
-                        local_start + (reg_param - this_flag) * sizeof(long)); \
-               reg_param += (i); \
-       } else { \
-               s390_la (p, s390_r4, STK_BASE, \
-                        sz.stack_size + 96 + stack_param * sizeof(long)); \
-               stack_param += (i); \
-       }
-
-/*------------------------------------------------------------------*/
-/* Sequence to add a float/double to parameters to stack_from_data  */
-/*------------------------------------------------------------------*/
-#define ADD_RSTACK_PARM(i) \
-       if (fpr_param < FLOAT_REGS) { \
-               s390_la (p, s390_r4, STK_BASE, \
-                        float_pos + (fpr_param * sizeof(float) * (i))); \
-               fpr_param++; \
-       } else { \
-               stack_param += (stack_param % (i)); \
-               s390_la (p, s390_r4, STK_BASE, \
-                        sz.stack_size + 96 + stack_param * sizeof(float) * (i)); \
-               stack_param += (i); \
-       }
-
-/*------------------------------------------------------------------*/
-/* Sequence to add a structure ptr to parameters to stack_from_data */
-/*------------------------------------------------------------------*/
-#define ADD_TSTACK_PARM \
-       if (reg_param < GENERAL_REGS) { \
-               s390_l (p, s390_r4, STK_BASE, \
-                       local_start + (reg_param - this_flag) * sizeof(long)); \
-               reg_param++; \
-       } else { \
-               s390_l (p, s390_r4, STK_BASE, \
-                       sz.stack_size + 96 + stack_param * sizeof(long)); \
-               stack_param++; \
-       }
-
-#define ADD_PSTACK_PARM(r, i) \
-       if (reg_param < GENERAL_REGS-(r)) { \
-               s390_la (p, s390_r4, STK_BASE, \
-                        local_start + (reg_param - this_flag) * sizeof(long)); \
-               reg_param += (i); \
-       } else { \
-               s390_l (p, s390_r4, STK_BASE, \
-                       sz.stack_size + 96 + stack_param * sizeof(long)); \
-               stack_param++; \
-       }
-
 /*========================= End of Defines =========================*/
 
 /*------------------------------------------------------------------*/
@@ -185,7 +116,7 @@ calculate_sizes (MonoMethodSignature *sig, size_data *sz,
        fr             = 0;
        gr             = 2;
        sz->retStruct  = 0;
-       sz->stack_size = MIN_STACK_SIZE;
+       sz->stack_size = S390_MINIMAL_STACK_SIZE;
        sz->code_size  = (PROLOG_INS + CALL_INS + EPILOG_INS);
        sz->local_size = 0;
 
@@ -385,10 +316,10 @@ emit_prolog (guint8 *p, MonoMethodSignature *sig, size_data *sz)
 
        /* function prolog */
        s390_stm (p, s390_r6, STK_BASE, STK_BASE, 24);
-       s390_l   (p, s390_r7, STK_BASE, 96);
+       s390_l   (p, s390_r7, 0, STK_BASE, MINV_POS);
        s390_lr  (p, s390_r11, STK_BASE);
        s390_ahi (p, STK_BASE, -stack_size);
-       s390_st  (p, s390_r11, STK_BASE, 0);
+       s390_st  (p, s390_r11, 0, STK_BASE, 0);
 
        /*-----------------------------------------*/
        /* Save:                                   */
@@ -436,7 +367,7 @@ emit_save_parameters (guint8 *p, MonoMethodSignature *sig, size_data *sz)
                gr    = 0;
        fr            = 0;
        act_strs      = 0;
-       stack_par_pos = MIN_STACK_SIZE;
+       stack_par_pos = S390_MINIMAL_STACK_SIZE;
        local_pos     = sz->stack_size;
 
        if (sig->hasthis) {
@@ -449,11 +380,11 @@ emit_save_parameters (guint8 *p, MonoMethodSignature *sig, size_data *sz)
                DEBUG(printf("par: %d type: %d ref: %d\n",i,sig->params[i]->type,sig->params[i]->byref));
                if (sig->params [i]->byref) {
                        if (gr < GENERAL_REGS) {
-                               s390_l  (p, s390_r2 + gr, ARG_BASE, STKARG);
+                               s390_l  (p, s390_r2 + gr, 0, ARG_BASE, STKARG);
                                gr ++;
                        } else {
-                               s390_l  (p, s390_r0, ARG_BASE, STKARG);
-                               s390_st (p, s390_r0, STK_BASE, stack_par_pos);
+                               s390_l  (p, s390_r0, 0, ARG_BASE, STKARG);
+                               s390_st (p, s390_r0, 0, STK_BASE, stack_par_pos);
                                stack_par_pos += sizeof(long);
                        }
                        continue;
@@ -477,11 +408,11 @@ emit_save_parameters (guint8 *p, MonoMethodSignature *sig, size_data *sz)
                case MONO_TYPE_STRING:
                case MONO_TYPE_SZARRAY:
                        if (gr < GENERAL_REGS) {
-                               s390_l  (p, s390_r2 + gr, ARG_BASE, STKARG);
+                               s390_l  (p, s390_r2 + gr, 0, ARG_BASE, STKARG);
                                gr ++;
                        } else {
-                               s390_l  (p, s390_r0, ARG_BASE, STKARG);
-                               s390_st (p, s390_r0, STK_BASE, stack_par_pos);
+                               s390_l  (p, s390_r0, 0, ARG_BASE, STKARG);
+                               s390_st (p, s390_r0, 0, STK_BASE, stack_par_pos);
                                stack_par_pos += sizeof(long);
                        }
                        break;
@@ -501,24 +432,24 @@ emit_save_parameters (guint8 *p, MonoMethodSignature *sig, size_data *sz)
                                case 2:
                                case 4:
                                        if (gr < GENERAL_REGS) {
-                                               s390_l  (p, s390_r2 + gr, ARG_BASE, STKARG);
-                                               s390_l  (p, s390_r2 + gr, s390_r2 + gr, 0);
+                                               s390_l  (p, s390_r2 + gr, 0,ARG_BASE, STKARG);
+                                               s390_l  (p, s390_r2 + gr, 0, s390_r2 + gr, 0);
                                                gr++;
                                        } else {
                                                stack_par_pos += (stack_par_pos % align);
-                                               s390_l  (p, s390_r10, ARG_BASE, STKARG);
-                                               s390_l  (p, s390_r10, s390_r10, 0);
-                                               s390_st (p, s390_r10, STK_BASE, stack_par_pos);
+                                               s390_l  (p, s390_r10, 0,ARG_BASE, STKARG);
+                                               s390_l  (p, s390_r10, 0, s390_r10, 0);
+                                               s390_st (p, s390_r10, 0, STK_BASE, stack_par_pos);
                                                stack_par_pos += sizeof(long);
                                        }
                                        break;
                                case 8:
                                        if (gr < GENERAL_REGS-1) {
-                                               s390_l  (p, s390_r2 + gr, ARG_BASE, STKARG);
+                                               s390_l  (p, s390_r2 + gr, 0, ARG_BASE, STKARG);
                                                s390_lm (p, s390_r2 + gr, s390_r3 + gr, s390_r2 + gr, 0);
                                        } else {
                                                stack_par_pos += (stack_par_pos % align);
-                                               s390_l   (p, s390_r10, ARG_BASE, STKARG);
+                                               s390_l   (p, s390_r10, 0, ARG_BASE, STKARG);
                                                s390_mvc (p, sizeof(long long), STK_BASE, stack_par_pos, s390_r10, 0);
                                                stack_par_pos += sizeof(long long);
                                        }
@@ -526,29 +457,29 @@ emit_save_parameters (guint8 *p, MonoMethodSignature *sig, size_data *sz)
                                default:
                                        if (size <= 256) {
                                                local_pos += (local_pos % align);
-                                               s390_l   (p, s390_r13, ARG_BASE, STKARG);
+                                               s390_l   (p, s390_r13, 0, ARG_BASE, STKARG);
                                                s390_mvc (p, size, STK_BASE, local_pos, s390_r13, 0);
-                                               s390_la  (p, s390_r13, STK_BASE, local_pos);
+                                               s390_la  (p, s390_r13, 0, STK_BASE, local_pos);
                                                local_pos += size;
                                        } else {
                                                local_pos += (local_pos % align);
                                                s390_bras (p, s390_r13, 4);
                                                s390_word (p, size);
-                                               s390_l    (p, s390_r1, s390_r13, 0);
-                                               s390_l    (p, s390_r0, ARG_BASE, STKARG);
+                                               s390_l    (p, s390_r1, 0, s390_r13, 0);
+                                               s390_l    (p, s390_r0, 0, ARG_BASE, STKARG);
                                                s390_lr   (p, s390_r14, s390_r12);
-                                               s390_la   (p, s390_r12, STK_BASE, local_pos);
+                                               s390_la   (p, s390_r12, 0, STK_BASE, local_pos);
                                                s390_lr   (p, s390_r13, s390_r1);
                                                s390_mvcl (p, s390_r12, s390_r0);
                                                s390_lr   (p, s390_r12, s390_r14);
-                                               s390_la   (p, s390_r13, STK_BASE, local_pos);
+                                               s390_la   (p, s390_r13, 0, STK_BASE, local_pos);
                                                local_pos += size;
                                        }
                                        if (gr < GENERAL_REGS) {
                                                s390_lr (p, s390_r2 + gr, s390_r13);
                                                gr++;
                                        } else {
-                                               s390_st (p, s390_r13, STK_BASE, stack_par_pos);
+                                               s390_st (p, s390_r13, 0, STK_BASE, stack_par_pos);
                                                stack_par_pos += sizeof(long);
                                        }
                        }
@@ -566,7 +497,7 @@ emit_save_parameters (guint8 *p, MonoMethodSignature *sig, size_data *sz)
                        break;
                case MONO_TYPE_R4:
                        if (fr < FLOAT_REGS) {
-                               s390_le  (p, s390_r0 + fr, ARG_BASE, STKARG);
+                               s390_le  (p, s390_r0 + fr, 0, ARG_BASE, STKARG);
                                fr++;
                        } else {
                                s390_mvc  (p, sizeof(float), STK_BASE, stack_par_pos, ARG_BASE, STKARG);
@@ -575,7 +506,7 @@ emit_save_parameters (guint8 *p, MonoMethodSignature *sig, size_data *sz)
                        break;
                case MONO_TYPE_R8:
                        if (fr < FLOAT_REGS) {
-                               s390_ld  (p, s390_r0 + fr, ARG_BASE, STKARG);
+                               s390_ld  (p, s390_r0 + fr, 0, ARG_BASE, STKARG);
                                fr++;
                        } else {
                                *(guint32 *) p += 7;
@@ -594,7 +525,7 @@ emit_save_parameters (guint8 *p, MonoMethodSignature *sig, size_data *sz)
        /* then point the result area for the called routine        */
        /*----------------------------------------------------------*/
        if (sz->retStruct) {
-               s390_l  (p, s390_r2, s390_r8, 0);
+               s390_l  (p, s390_r2, 0, s390_r8, 0);
        }
 
        return p;
@@ -652,7 +583,7 @@ emit_call_and_store_retval (guint8 *p, MonoMethodSignature *sig,
 
        /* get return value */
        if (sig->ret->byref || string_ctor) {
-               s390_st (p, s390_r2, s390_r8, 0);
+               s390_st (p, s390_r2, 0, s390_r8, 0);
        } else {
                simpletype = sig->ret->type;
 enum_retvalue:
@@ -660,12 +591,12 @@ enum_retvalue:
                case MONO_TYPE_BOOLEAN:
                case MONO_TYPE_I1:
                case MONO_TYPE_U1:
-                       s390_stc (p, s390_r2, s390_r8, 0);
+                       s390_stc (p, s390_r2, 0, s390_r8, 0);
                        break;
                case MONO_TYPE_I2:
                case MONO_TYPE_U2:
                case MONO_TYPE_CHAR:
-                       s390_sth (p, s390_r2, s390_r8, 0);
+                       s390_sth (p, s390_r2, 0, s390_r8, 0);
                        break;
                case MONO_TYPE_I4:
                case MONO_TYPE_U4:
@@ -676,13 +607,13 @@ enum_retvalue:
                case MONO_TYPE_SZARRAY:
                case MONO_TYPE_ARRAY:
                case MONO_TYPE_STRING:
-                       s390_st (p, s390_r2, s390_r8, 0);
+                       s390_st (p, s390_r2, 0, s390_r8, 0);
                        break;
                case MONO_TYPE_R4:
-                       s390_ste (p, s390_f0, s390_r8, 0);
+                       s390_ste (p, s390_f0, 0, s390_r8, 0);
                        break;
                case MONO_TYPE_R8:
-                       s390_std (p, s390_f0, s390_r8, 0);
+                       s390_std (p, s390_f0, 0, s390_r8, 0);
                        break;
                case MONO_TYPE_I8:
                        s390_stm (p, s390_r2, s390_r3, s390_r8, 0);
@@ -701,13 +632,13 @@ printf("Returning %d bytes for type %d (%d)\n",retSize,simpletype,sig->pinvoke);
                        case 0:
                                break;
                        case 1:
-                               s390_stc (p, s390_r2, s390_r8, 0);
+                               s390_stc (p, s390_r2, 0, s390_r8, 0);
                                break;
                        case 2:
-                               s390_sth (p, s390_r2, s390_r8, 0);
+                               s390_sth (p, s390_r2, 0, s390_r8, 0);
                                break;
                        case 4:
-                               s390_st (p, s390_r2, s390_r8, 0);
+                               s390_st (p, s390_r2, 0, s390_r8, 0);
                                break;
                        case 8:
                                s390_stm (p, s390_r2, s390_r3, s390_r8, 0);
@@ -745,8 +676,8 @@ static inline guint8 *
 emit_epilog (guint8 *p, MonoMethodSignature *sig, size_data *sz)
 {
        /* function epilog */
-       s390_l   (p, STK_BASE, STK_BASE, 0);
-       s390_l   (p, s390_r4, STK_BASE, 56);
+       s390_l   (p, STK_BASE, 0, STK_BASE, 0);
+       s390_l   (p, s390_r4, 0, STK_BASE, 56);
        s390_lm  (p, s390_r6, STK_BASE, STK_BASE, 24);
        s390_br  (p, s390_r4);
 
@@ -819,8 +750,7 @@ mono_arch_create_trampoline (MonoMethodSignature *sig, gboolean string_ctor)
 /*     allocate a MonoInvocation structure (inv) on the stack      */
 /*      allocate an array of stackval on the stack with length =    */
 /*          method->signature->param_count + 1 [call it stack_args] */
-/*     set inv->ex, inv->ex_handler,inv->parent to                 */
-/*         NULL                                                    */
+/*     set inv->ex, inv->ex_handler, inv->parent to NULL           */
 /*     set inv->method to method                                   */
 /*     if method is an instance method, set inv->obj to the        */
 /*         'this' argument (the first argument) else set to NULL   */
@@ -878,11 +808,11 @@ mono_arch_create_method_pointer (MonoMethod *method)
        /* prolog                                                   */
        /*----------------------------------------------------------*/ 
        s390_stm (p, s390_r6, STK_BASE, STK_BASE, 24);
-       s390_l   (p, s390_r7, STK_BASE, 96);
+       s390_l   (p, s390_r7, 0, STK_BASE, MINV_POS);
        s390_lr  (p, s390_r0, STK_BASE);
-       s390_ahi (p, STK_BASE, -(sz.stack_size+96));
-       s390_st  (p, s390_r0, STK_BASE, 0);
-       s390_la  (p, s390_r8, STK_BASE, 4);
+       s390_ahi (p, STK_BASE, -(sz.stack_size+MINV_POS));
+       s390_st  (p, s390_r0, 0, STK_BASE, 0);
+       s390_la  (p, s390_r8, 0, STK_BASE, 4);
        s390_lr  (p, s390_r10, s390_r8);
        s390_lhi (p, s390_r9, sz.stack_size+92);
        s390_lhi (p, s390_r11, 0);
@@ -892,19 +822,19 @@ mono_arch_create_method_pointer (MonoMethod *method)
        /* Let's fill MonoInvocation - first zero some fields       */
        /*----------------------------------------------------------*/ 
        s390_lhi (p, s390_r0, 0);
-       s390_st  (p, s390_r0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, ex)));
-       s390_st  (p, s390_r0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, ex_handler)));
-       s390_st  (p, s390_r0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, parent)));
+       s390_st  (p, s390_r0, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, ex)));
+       s390_st  (p, s390_r0, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, ex_handler)));
+       s390_st  (p, s390_r0, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, parent)));
        s390_lhi (p, s390_r0, 1);
-       s390_st  (p, s390_r0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, invoke_trap)));
+       s390_st  (p, s390_r0, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, invoke_trap)));
 
        /*----------------------------------------------------------*/ 
        /* set method pointer                                       */
        /*----------------------------------------------------------*/ 
        s390_bras (p, s390_r13, 4);
        s390_word (p, method);
-       s390_l    (p, s390_r0, s390_r13, 0);
-       s390_st   (p, s390_r0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, method)));
+       s390_l    (p, s390_r0, 0, s390_r13, 0);
+       s390_st   (p, s390_r0, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, method)));
 
        local_start = local_pos = MINV_POS + 
                      sizeof (MonoInvocation) + (sig->param_count + 1) * sizeof (stackval);
@@ -938,21 +868,22 @@ mono_arch_create_method_pointer (MonoMethod *method)
        }
 
        if (this_flag) {
-               s390_st  (p, s390_r2 + reg_save, STK_BASE, 
+               s390_st  (p, s390_r2 + reg_save, 0, STK_BASE, 
                          (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, obj)));
                reg_param++;
        } else {
-               s390_st (p, s390_r2 + reg_save, STK_BASE, local_pos);
+               s390_st (p, s390_r2 + reg_save, 0, STK_BASE, local_pos);
                local_pos += sizeof(int);
-               s390_st (p, s390_r0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, obj)));
+               s390_st (p, s390_r0, 0, STK_BASE, 
+                        (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, obj)));
        }
 
        s390_stm (p, s390_r3 + reg_param, s390_r6, STK_BASE, local_pos);
        local_pos += 4 * sizeof(long);
        float_pos  = local_pos;
-       s390_std (p, s390_f0, STK_BASE, local_pos);
+       s390_std (p, s390_f0, 0, STK_BASE, local_pos);
        local_pos += sizeof(double);
-       s390_std (p, s390_f2, STK_BASE, local_pos);
+       s390_std (p, s390_f2, 0, STK_BASE, local_pos);
        local_pos += sizeof(double);
 
        /*----------------------------------------------------------*/ 
@@ -987,8 +918,8 @@ mono_arch_create_method_pointer (MonoMethod *method)
        /* set MonoInvocation::stack_args                           */
        /*----------------------------------------------------------*/ 
        stackval_arg_pos = MINV_POS + sizeof (MonoInvocation);
-       s390_la  (p, s390_r0, STK_BASE, stackval_arg_pos);
-       s390_st  (p, s390_r0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, stack_args)));
+       s390_la  (p, s390_r0, 0, STK_BASE, stackval_arg_pos);
+       s390_st  (p, s390_r0, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, stack_args)));
 
        /*----------------------------------------------------------*/ 
        /* add stackval arguments                                   */  
@@ -1038,12 +969,12 @@ mono_arch_create_method_pointer (MonoMethod *method)
                }
                                
                if (vtbuf [i] >= 0) {
-                       s390_la  (p, s390_r3, STK_BASE, vt_cur);
-                       s390_st  (p, s390_r3, STK_BASE, stackval_arg_pos);
-                       s390_la  (p, s390_r3, STK_BASE, stackval_arg_pos);
+                       s390_la  (p, s390_r3, 0, STK_BASE, vt_cur);
+                       s390_st  (p, s390_r3, 0, STK_BASE, stackval_arg_pos);
+                       s390_la  (p, s390_r3, 0, STK_BASE, stackval_arg_pos);
                        vt_cur += vtbuf [i];
                } else {
-                       s390_la  (p, s390_r3, STK_BASE, stackval_arg_pos);
+                       s390_la  (p, s390_r3, 0, STK_BASE, stackval_arg_pos);
                }
 
                /*--------------------------------------*/
@@ -1054,12 +985,12 @@ mono_arch_create_method_pointer (MonoMethod *method)
                s390_word (p, sig->params [i]);
                s390_word (p, sig->pinvoke);
                s390_word (p, stackval_from_data);
-               s390_l    (p, s390_r2, s390_r13, 0);
+               s390_l    (p, s390_r2, 0, s390_r13, 0);
 
-               s390_l    (p, s390_r5, s390_r13, 4);
+               s390_l    (p, s390_r5, 0, s390_r13, 4);
 
-               s390_l    (p, s390_r9, s390_r13, 8);
-               s390_basr (p, s390_r14, s390_r9);
+               s390_l    (p, s390_r1, 0, s390_r13, 8);
+               s390_basr (p, s390_r14, s390_r1);
 
                stackval_arg_pos += sizeof(stackval);
 
@@ -1076,13 +1007,13 @@ mono_arch_create_method_pointer (MonoMethod *method)
        /*----------------------------------------------------------*/ 
        /* Set return area pointer.                                 */
        /*----------------------------------------------------------*/ 
-       s390_la (p, s390_r10, STK_BASE, stackval_arg_pos);
-       s390_st (p, s390_r10, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, retval)));
+       s390_la (p, s390_r10, 0, STK_BASE, stackval_arg_pos);
+       s390_st (p, s390_r10, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, retval)));
        if (sig->ret->type == MONO_TYPE_VALUETYPE && !sig->ret->byref) {
                MonoClass *klass  = sig->ret->data.klass;
                if (!klass->enumtype) {
-                       s390_la (p, s390_r9, s390_r10, sizeof(stackval));
-                       s390_st (p, s390_r9, STK_BASE, stackval_arg_pos);
+                       s390_la (p, s390_r9, 0, s390_r10, sizeof(stackval));
+                       s390_st (p, s390_r9, 0,STK_BASE, stackval_arg_pos);
                        stackval_arg_pos += sizeof(stackval);
                }
        }
@@ -1092,9 +1023,9 @@ mono_arch_create_method_pointer (MonoMethod *method)
        /*----------------------------------------------------------*/ 
        s390_bras (p, s390_r13, 4);
        s390_word (p, ves_exec_method);
-       s390_l    (p, s390_r9, s390_r13, 0);
-       s390_la   (p, s390_r2, STK_BASE, MINV_POS);
-       s390_basr (p, s390_r14, s390_r9);
+       s390_l    (p, s390_r1, 0, s390_r13, 0);
+       s390_la   (p, s390_r2, 0, STK_BASE, MINV_POS);
+       s390_basr (p, s390_r14, s390_r1);
 
        /*----------------------------------------------------------*/ 
        /* move retval from stackval to proper place (r3/r4/...)    */
@@ -1102,7 +1033,7 @@ mono_arch_create_method_pointer (MonoMethod *method)
        DEBUG(printf("retType: %d byRef: %d\n",sig->ret->type,sig->ret->byref));
        if (sig->ret->byref) {
                DEBUG (printf ("ret by ref\n"));
-               s390_st (p, s390_r2, s390_r10, 0);
+               s390_st (p, s390_r2, 0, s390_r10, 0);
        } else {
        enum_retvalue:
 DEBUG(printf("Returns: %d\n",sig->ret->type));
@@ -1112,11 +1043,11 @@ DEBUG(printf("Returns: %d\n",sig->ret->type));
                case MONO_TYPE_BOOLEAN:
                case MONO_TYPE_U1:
                        s390_lhi (p, s390_r2, 0);
-                       s390_ic  (p, s390_r2, s390_r10, 0);
+                       s390_ic  (p, s390_r2, 0, s390_r10, 0);
                        break;
                case MONO_TYPE_I2:
                case MONO_TYPE_U2:
-                       s390_lh (p, s390_r2, s390_r10, 0);
+                       s390_lh (p, s390_r2, 0,s390_r10, 0);
                        break;
                case MONO_TYPE_I4:
                case MONO_TYPE_U4:
@@ -1125,20 +1056,18 @@ DEBUG(printf("Returns: %d\n",sig->ret->type));
                case MONO_TYPE_OBJECT:
                case MONO_TYPE_STRING:
                case MONO_TYPE_CLASS:
-                       s390_l (p, s390_r2, s390_r10, 0);
+                       s390_l (p, s390_r2, 0, s390_r10, 0);
                        break;
                case MONO_TYPE_I8:
                        s390_lm (p, s390_r2, s390_r3, s390_r10, 0);
                        break;
                case MONO_TYPE_R4:
-                       s390_le (p, s390_f0, s390_r10, 0);
+                       s390_le (p, s390_f0, 0, s390_r10, 0);
                        break;
                case MONO_TYPE_R8:
-                       s390_ld (p, s390_f0, s390_r10, 0);
+                       s390_ld (p, s390_f0, 0, s390_r10, 0);
                        break;
                case MONO_TYPE_VALUETYPE:
-DEBUG(printf("Returning Structure %d\n",sig->pinvoke));
-DEBUG(printf("Size: %d (%d)\n",retSize,align));
                        if (sig->ret->data.klass->enumtype) {
                                simpletype = sig->ret->data.klass->enum_basetype->type;
                                goto enum_retvalue;
@@ -1151,9 +1080,8 @@ DEBUG(printf("Size: %d (%d)\n",retSize,align));
                        s390_word (p, sig->ret);
                        s390_word (p, sig->pinvoke);
                        s390_word (p, stackval_to_data);
-                       s390_l    (p, s390_r2, s390_r13, 0);
-                       s390_l    (p, s390_r3, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, retval)));
-DEBUG(printf("====> %08X\n",p));
+                       s390_l    (p, s390_r2, 0, s390_r13, 0);
+                       s390_l    (p, s390_r3, 0, STK_BASE, (MINV_POS + G_STRUCT_OFFSET (MonoInvocation, retval)));
                        if (sz.retStruct) {     
                                /*------------------------------------------*/
                                /* Get stackval_to_data to set result area  */
@@ -1163,23 +1091,23 @@ DEBUG(printf("====> %08X\n",p));
                                /*------------------------------------------*/
                                /* Give stackval_to_data a temp result area */
                                /*------------------------------------------*/ 
-                               s390_la (p, s390_r4, STK_BASE, stackval_arg_pos);
+                               s390_la (p, s390_r4, 0, STK_BASE, stackval_arg_pos);
                        }
-                       s390_l    (p, s390_r5, s390_r13, 4);
-                       s390_l    (p, s390_r9, s390_r13, 8);
-                       s390_basr (p, s390_r14, s390_r9);
+                       s390_l    (p, s390_r5, 0,s390_r13, 4);
+                       s390_l    (p, s390_r1, 0, s390_r13, 8);
+                       s390_basr (p, s390_r14, s390_r1);
                        switch (retSize) {
                                case 0:
                                        break;
                                case 1:
                                        s390_lhi (p, s390_r2, 0);
-                                       s390_ic  (p, s390_r2, s390_r10, 0);
+                                       s390_ic  (p, s390_r2, 0, s390_r10, 0);
                                        break;
                                case 2:
-                                       s390_lh (p, s390_r2, s390_r10, 0);
+                                       s390_lh (p, s390_r2, 0, s390_r10, 0);
                                        break;
                                case 4:
-                                       s390_l (p, s390_r2, s390_r10, 0);
+                                       s390_l (p, s390_r2, 0, s390_r10, 0);
                                        break;
                                case 8:
                                        s390_lm (p, s390_r2, s390_r3, s390_r10, 0);
@@ -1200,9 +1128,9 @@ DEBUG(printf("====> %08X\n",p));
        /*----------------------------------------------------------*/ 
        /* epilog                                                   */
        /*----------------------------------------------------------*/ 
-       s390_l   (p, STK_BASE, STK_BASE, 0);
-       s390_l   (p, s390_r4, STK_BASE, 56);
-       s390_lm  (p, s390_r6, STK_BASE, STK_BASE, 24);
+       s390_l   (p, STK_BASE, 0, STK_BASE, 0);
+       s390_l   (p, s390_r4, 0, STK_BASE, S390_RET_ADDR_OFFSET);
+       s390_lm  (p, s390_r6, STK_BASE, STK_BASE, S390_REG_SAVE_OFFSET);
        s390_br  (p, s390_r4);
 
        DEBUG (printf ("emited code size: %d\n", p - code_buffer));
index b02d952a38a68c6c33e7a90bcddd3584c30aef98..256bf4aa609739b33e5bf38d3740a75be8103f08 100644 (file)
@@ -163,7 +163,7 @@ ldstr:
 newobj:
 castclass:
 isinst:
-conv.r.un: dest:f src1:i len:28
+conv.r.un: dest:f src1:i len:30
 unbox:
 throw: src1:i len:8
 ldfld:
@@ -324,17 +324,17 @@ reg:
 regoffset:
 label:
 store_membase_imm: dest:b len:32
-store_membase_reg: dest:b src1:i len:8
+store_membase_reg: dest:b src1:i len:18
 storei1_membase_imm: dest:b len:32
-storei1_membase_reg: dest:b src1:i len:8
+storei1_membase_reg: dest:b src1:i len:18
 storei2_membase_imm: dest:b len:32
-storei2_membase_reg: dest:b src1:i len:8
+storei2_membase_reg: dest:b src1:i len:18
 storei4_membase_imm: dest:b len:32
-storei4_membase_reg: dest:b src1:i len:8
+storei4_membase_reg: dest:b src1:i len:18
 storei8_membase_imm: dest:b 
 storei8_membase_reg: dest:b src1:i 
 storer4_membase_reg: dest:b src1:f len:20
-storer8_membase_reg: dest:b src1:f len:8
+storer8_membase_reg: dest:b src1:f len:20
 load_membase: dest:i src1:b len:18
 loadi1_membase: dest:i src1:b len:40
 loadu1_membase: dest:i src1:b len:26
index 5a48d4ea39d331d145c03628802b6c7e3de9d9e1..826e5223d81a931c2863f94aa44285c499928a72 100644 (file)
 /*                 T y p e d e f s                                  */
 /*------------------------------------------------------------------*/
 
-struct stack_frame
+typedef struct
 {
-  void *next;
+  void *prev;
+  void *unused[5];
+  void *reg6;
+  void *reg7;
+  void *reg8;
+  void *reg9;
+  void *reg10;
+  void *reg11;
+  void *reg12;
+  void *reg13;
   void *return_address;
-};
+} MonoS390StackFrame;
 
 #ifdef MONO_USE_EXC_TABLES
 
@@ -117,7 +126,7 @@ typedef struct frame_state * (*framesf) (void *, struct frame_state *);
 /*                   P r o t o t y p e s                            */
 /*------------------------------------------------------------------*/
 
-gboolean mono_arch_handle_exception (MonoContext *ctx,
+gboolean mono_arch_handle_exception (void     *ctx,
                                     gpointer obj, 
                                     gboolean test_only);
 
@@ -667,7 +676,7 @@ glist_to_array (GList *list)
 
 MonoJitInfo *
 mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls, 
-                        MonoJitInfo *res, MonoContext *ctx, 
+                        MonoJitInfo *res, MonoJitInfo *prev_ji, MonoContext *ctx, 
                         MonoContext *new_ctx, char **trace, MonoLMF **lmf, 
                         int *native_offset, gboolean *managed)
 {
@@ -675,8 +684,14 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
        gpointer ip = MONO_CONTEXT_GET_IP (ctx);
        unsigned long *ptr;
        char *p;
+       MonoS390StackFrame *sframe;
 
-       ji = mono_jit_info_table_find (domain, ip);
+       if (prev_ji && 
+           (ip > prev_ji->code_start && 
+           ((guint8 *) ip < ((guint8 *) prev_ji->code_start) + prev_ji->code_size)))
+               ji = prev_ji;
+       else
+               ji = mono_jit_info_table_find (domain, ip);
 
        if (trace)
                *trace = NULL;
@@ -728,28 +743,9 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
                        g_free (source_location);
                        g_free (tmpaddr);
                }
-#if 0                          
-               offset = -1;
-               /* restore caller saved registers */
-               if (ji->used_regs & X86_EBX_MASK) {
-                       new_ctx->SC_EBX = *((int *)ctx->SC_EBP + offset);
-                       offset--;
-               }
-               if (ji->used_regs & X86_EDI_MASK) {
-                       new_ctx->SC_EDI = *((int *)ctx->SC_EBP + offset);
-                       offset--;
-               }
-               if (ji->used_regs & X86_ESI_MASK) {
-                       new_ctx->SC_ESI = *((int *)ctx->SC_EBP + offset);
-               }
-
-               new_ctx->SC_ESP = ctx->SC_EBP;
-               /* we substract 1, so that the IP points into the call instruction */
-               new_ctx->SC_EIP = *((int *)ctx->SC_EBP + 1) - 1;
-               new_ctx->SC_EBP = *((int *)ctx->SC_EBP);
-#endif
-               MONO_CONTEXT_SET_BP (new_ctx, MONO_CONTEXT_GET_BP (ctx));
-               MONO_CONTEXT_SET_IP (new_ctx, MONO_CONTEXT_GET_IP (ctx));
+               sframe = (MonoS390StackFrame *) MONO_CONTEXT_GET_BP (ctx);
+               MONO_CONTEXT_SET_BP (new_ctx, sframe->prev);
+               MONO_CONTEXT_SET_IP (new_ctx, sframe->return_address);
                *res = *ji;
                return res;
 #ifdef MONO_USE_EXC_TABLES
@@ -774,18 +770,12 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
                        res->method = (*lmf)->method;
                }
 
-#if 0
-               new_ctx->SC_ESI = (*lmf)->esi;
-               new_ctx->SC_EDI = (*lmf)->edi;
-               new_ctx->SC_EBX = (*lmf)->ebx;
-               new_ctx->SC_EBP = (*lmf)->ebp;
-               new_ctx->SC_EIP = (*lmf)->eip;
-               /* the lmf is always stored on the stack, so the following
-                * expression points to a stack location which can be used as ESP */
-               new_ctx->SC_ESP = (unsigned long)&((*lmf)->eip);
-#endif
-               MONO_CONTEXT_SET_BP (new_ctx, MONO_CONTEXT_GET_BP (ctx));
-               MONO_CONTEXT_SET_IP (new_ctx, MONO_CONTEXT_GET_IP (ctx));
+/*
+               MONO_CONTEXT_SET_BP (ctx, (*lmf)->ebp);
+               MONO_CONTEXT_SET_IP (ctx, (*lmf)->eip);
+*/
+               MONO_CONTEXT_SET_BP (new_ctx, (*lmf)->ebp);
+               MONO_CONTEXT_SET_IP (new_ctx, (*lmf)->eip);
                *lmf = (*lmf)->previous_lmf;
 
                return res;
@@ -872,7 +862,9 @@ mono_jit_walk_stack (MonoStackWalk func, gpointer user_data) {
 
        while (MONO_CONTEXT_GET_BP (&ctx) < jit_tls->end_of_stack) {
                
-               ji = mono_arch_find_jit_info (domain, jit_tls, &rji, &ctx, &new_ctx, NULL, &lmf, &native_offset, &managed);
+               ji = mono_arch_find_jit_info (domain, jit_tls, &rji, NULL, 
+                                             &ctx, &new_ctx, NULL, &lmf, 
+                                             &native_offset, &managed);
                g_assert (ji);
 
                if (ji == (gpointer)-1)
@@ -915,7 +907,9 @@ ves_icall_get_frame_info (gint32 skip, MonoBoolean need_file_info,
        skip++;
 
        do {
-               ji = mono_arch_find_jit_info (domain, jit_tls, &rji, &ctx, &new_ctx, NULL, &lmf, native_offset, NULL);
+               ji = mono_arch_find_jit_info (domain, jit_tls, &rji, NULL, 
+                                             &ctx, &new_ctx, NULL, &lmf, 
+                                             native_offset, NULL);
 
                ctx = new_ctx;
                
@@ -965,17 +959,19 @@ ves_icall_get_frame_info (gint32 skip, MonoBoolean need_file_info,
 /*------------------------------------------------------------------*/
 
 gboolean
-mono_arch_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only)
+mono_arch_handle_exception (void *uc, gpointer obj, gboolean test_only)
 {
-       MonoDomain *domain = mono_domain_get ();
-       MonoJitInfo *ji, rji;
-       static int (*call_filter) (MonoContext *, gpointer, gpointer) = NULL;
-       MonoJitTlsData *jit_tls = TlsGetValue (mono_jit_tls_id);
-       MonoLMF *lmf = jit_tls->lmf;            
-       GList *trace_ips = NULL;
-       MonoException *mono_ex;
+       MonoContext     *ctx = uc;
+       MonoDomain      *domain = mono_domain_get ();
+       MonoJitInfo     *ji, rji;
+       static int      (*call_filter) (MonoContext *, gpointer, gpointer) = NULL;
+       MonoJitTlsData  *jit_tls = TlsGetValue (mono_jit_tls_id);
+       MonoLMF         *lmf = jit_tls->lmf;            
+       GList           *trace_ips = NULL;
+       MonoException   *mono_ex;
 
        g_assert (ctx != NULL);
+       memset(&rji, 0, sizeof(rji));
        if (!obj) {
                MonoException *ex = mono_get_exception_null_reference ();
                ex->message = mono_string_new (domain, 
@@ -1012,7 +1008,7 @@ mono_arch_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only)
                MonoContext new_ctx;
                char *trace = NULL;
                
-               ji = mono_arch_find_jit_info (domain, jit_tls, &rji, ctx, &new_ctx, 
+               ji = mono_arch_find_jit_info (domain, jit_tls, &rji, &rji, ctx, &new_ctx, 
                                              test_only ? &trace : NULL, &lmf, NULL, NULL);
                if (!ji) {
                        g_warning ("Exception inside function without unwind info");
@@ -1034,6 +1030,7 @@ mono_arch_handle_exception (MonoContext *ctx, gpointer obj, gboolean test_only)
                                tmp = g_strdup_printf ("%s%s\n", strace, trace);
                                g_free (strace);
 
+printf("%s\n",tmp);
                                mono_ex->stack_trace = mono_string_new (domain, tmp);
 
                                g_free (tmp);
index 9b52e2337b9639c9b10a35a9c8ede5930e11a700..631fdea7f33f2adee877b8e7133fa121475c4256 100644 (file)
@@ -189,7 +189,8 @@ stmt: OP_OUTARG_VT (CEE_LDOBJ (base)) {
        int i, tmpr;
        if (size < 0) { 
                size = -size;
-               mini_emit_memcpy (s, s->frame_reg, tree->sreg1,
+printf("OP_OUTARG_VT (CEE_LDOBJ (base)) src: %d\n",vt->inst_basereg);
+               mini_emit_memcpy (s, s->frame_reg, tree->inst_imm,
                                  vt->inst_basereg, soffset, size, 0);
                if (start_reg != STK_BASE) {
                        MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, start_reg, 
@@ -205,6 +206,7 @@ stmt: OP_OUTARG_VT (CEE_LDOBJ (base)) {
                                soffset += sizeof (gpointer);
                        }
                } else {
+printf("OP_OUTARG_VT (CEELDOBJ (base)) src: %d\n",vt->inst_basereg);
                        mini_emit_memcpy (s, s->frame_reg, tree->inst_imm, 
                                          vt->inst_basereg, soffset, size, 0);
                }       
@@ -242,8 +244,13 @@ stmt: OP_OUTARG_VT (reg) {
                        soffset += sizeof(gpointer);
                }
        } else {
-               mini_emit_memcpy (s, s->frame_reg, tree->inst_imm, tree->sreg1, 
-                                 soffset, size, 0);
+               int tmpr;
+               tmpr = mono_regstate_next_int (s->rs);
+//             MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg, 
+//                                     s->stack_offset);
+printf("OP_OUTARG_VT (reg) size: %d\n",size);
+               mini_emit_memcpy (s, s->frame_reg, soffset, tmpr, 
+                                 tree->sreg1, size, 0);
        }
 }
 
index 4cf569c2424fe92ad62f63625e909b9b69e460fb..d5a3f7359fa6c42aaac107e54a8f523f73696976 100644 (file)
@@ -191,9 +191,9 @@ typedef struct {
 } CallInfo;
 
 typedef struct {
-       gint32  gr[5];
-       gdouble fp[3];
-} RegParm;
+       gint32  gr[5];          /* R2-R6                            */
+       gdouble fp[3];          /* F0-F2                            */
+} __attribute__ ((packed)) RegParm;
 
 /*========================= End of Typedefs ========================*/
 
@@ -1192,7 +1192,7 @@ enum_retvalue:
                                cinfo->args[nParm].reg     = STK_BASE;
                                cinfo->args[nParm].regtype = RegTypeBase;
                                sz->code_size  += 4;
-                               sz->stack_size += 8;
+                               sz->stack_size += 4;
                        }
                        nParm++;
                        break;
@@ -1248,7 +1248,7 @@ mono_arch_allocate_vars (MonoCompile *m)
        MonoInst *inst;
        CallInfo *cinfo;
        size_data sz;
-       int iParm, iVar, offset, size, align, curinst, stackOffset;
+       int iParm, iVar, offset, size, align, curinst;
        int frame_reg = STK_BASE;
        int sArg, eArg;
 
@@ -1271,12 +1271,6 @@ mono_arch_allocate_vars (MonoCompile *m)
        
        cinfo   = calculate_sizes (sig, &sz, sig->pinvoke);
 
-       if (mono_jit_trace_calls != NULL && mono_trace_eval (m)) 
-               stackOffset = S390_ALIGN((S390_TRACE_STACK_SIZE + 8), 
-                                        S390_STACK_ALIGNMENT);
-       else    
-               stackOffset = 0;
-
        if (cinfo->struct_ret) {
                m->ret->opcode = OP_REGVAR;
                m->ret->inst_c0 = s390_r2;
@@ -1291,20 +1285,15 @@ mono_arch_allocate_vars (MonoCompile *m)
                        break;
                }
        }
-       /* local vars are at a positive offset from the stack pointer 
-        * 
-        * also note that if the function uses alloca, we use s390_r11
-        * to point at the local variables.
-        */
-       offset = S390_MINIMAL_STACK_SIZE; /* linkage area */
 
-       /* add parameter area size for called functions */
-       offset += m->param_area;
-       offset  = S390_ALIGN(offset, S390_STACK_ALIGNMENT);
-
-       /* FIXME: check how to handle this stuff... reserve space to save LMF and caller saved registers */
-       if (m->method->save_lmf)
-               offset += sizeof (MonoLMF);
+       /*--------------------------------------------------------------*/
+       /* local vars are at a positive offset from the stack pointer   */
+       /*                                                              */
+       /* also note that if the function uses alloca, we use s390_r11  */
+       /* to point at the local variables.                             */
+       /* add parameter area size for called functions                 */
+       /*--------------------------------------------------------------*/
+       offset = (m->param_area + S390_MINIMAL_STACK_SIZE);
 
        if (cinfo->struct_ret) {
                inst               = m->ret;
@@ -1387,7 +1376,8 @@ mono_arch_allocate_vars (MonoCompile *m)
                                                              : 0);
                                        inst->inst_offset  = cinfo->args[iParm].offset + 
                                                             size;
-                                       inst->unused       = stackOffset;
+//                                     inst->unused       = stackOffset;
+                                       inst->unused       = 0;
                                        size               = sizeof(long);
                                } 
                        }
@@ -1396,9 +1386,22 @@ mono_arch_allocate_vars (MonoCompile *m)
                curinst++;
        }
 
-       /* align the offset */
-       offset          = S390_ALIGN(offset, S390_STACK_ALIGNMENT);
-       m->stack_offset = offset;
+       /*------------------------------------------------------*/
+       /* Allow space for the trace method stack area if needed*/
+       /*------------------------------------------------------*/
+       if (mono_jit_trace_calls != NULL && mono_trace_eval (m)) 
+               offset += S390_TRACE_STACK_SIZE;
+
+       /*------------------------------------------------------*/
+       /* Reserve space to save LMF and caller saved registers */
+       /*------------------------------------------------------*/
+       if (m->method->save_lmf)
+               offset += sizeof (MonoLMF);
+
+       /*------------------------------------------------------*/
+       /* align the offset                                     */
+       /*------------------------------------------------------*/
+       m->stack_offset = S390_ALIGN(offset, S390_STACK_ALIGNMENT);
 
 }
 
@@ -1424,7 +1427,7 @@ MonoCallInst*
 mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb, MonoCallInst *call, int is_virtual) {
        MonoInst *arg, *in;
        MonoMethodSignature *sig;
-       int i, n;
+       int i, n, lParamArea;
        CallInfo *cinfo;
        ArgInfo *ainfo;
        size_data sz;
@@ -1480,8 +1483,8 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb, MonoCallInst *call,
                                        arg->unused = -ainfo->vtsize;
                                else
                                        arg->unused = ainfo->size;
-                               arg->inst_imm = ainfo->offset;
-                               arg->sreg1    = ainfo->offparm;
+                               arg->inst_imm     = ainfo->offset;
+                               arg->sreg1        = ainfo->offparm;
                        } else if (ainfo->regtype == RegTypeBase) {
                                arg->opcode = OP_OUTARG;
                                arg->unused = ainfo->reg | (ainfo->size << 8);
@@ -1517,7 +1520,8 @@ mono_arch_call_opcode (MonoCompile *cfg, MonoBasicBlock* bb, MonoCallInst *call,
        }
        call->stack_usage = cinfo->stack_usage;
 
-       cfg->param_area   = MAX (cfg->param_area, cinfo->stack_usage);
+       lParamArea        = cinfo->stack_usage - S390_MINIMAL_STACK_SIZE;
+       cfg->param_area   = MAX (cfg->param_area, lParamArea);
        cfg->flags       |= MONO_CFG_HAS_CALLS;
        /*----------------------------------------------------------*/ 
        /* should set more info in call, such as the stack space    */
@@ -1563,8 +1567,13 @@ mono_arch_instrument_prolog (MonoCompile *cfg, void *func, void *p,
                             gboolean enable_arguments)
 {
        guchar *code = p;
-       int parmOffset = cfg->stack_usage - S390_TRACE_STACK_SIZE;
-       int fpOffset   = parmOffset + (5*sizeof(gint32));
+       int     parmOffset, 
+               fpOffset;
+
+       parmOffset = cfg->stack_usage - S390_TRACE_STACK_SIZE;
+       if (cfg->method->save_lmf)
+               parmOffset -= sizeof(MonoLMF);
+       fpOffset   = parmOffset + (5*sizeof(gint32));
 
        s390_stm  (code, s390_r2, s390_r6, STK_BASE, parmOffset);
        s390_std  (code, s390_f0, 0, STK_BASE, fpOffset);
@@ -1602,10 +1611,15 @@ mono_arch_instrument_prolog (MonoCompile *cfg, void *func, void *p,
 void*
 mono_arch_instrument_epilog (MonoCompile *cfg, void *func, void *p, gboolean enable_arguments)
 {
-       guchar *code = p;
-       int save_mode = SAVE_NONE;
+       guchar     *code = p;
+       int        save_mode = SAVE_NONE,
+                  saveOffset;
        MonoMethod *method = cfg->method;
-       int rtype = method->signature->ret->type;
+       int        rtype = method->signature->ret->type;
+
+       saveOffset = cfg->stack_usage - S390_TRACE_STACK_SIZE;
+       if (method->save_lmf)
+               saveOffset -= sizeof(MonoLMF);
 
 handle_enum:
        switch (rtype) {
@@ -1638,28 +1652,28 @@ handle_enum:
 
        switch (save_mode) {
        case SAVE_TWO:
-               s390_stm (code, s390_r2, s390_r3, cfg->frame_reg, cfg->stack_usage - 8);
+               s390_stm (code, s390_r2, s390_r3, cfg->frame_reg, saveOffset);
                if (enable_arguments) {
                        s390_lr (code, s390_r4, s390_r3);
                        s390_lr (code, s390_r3, s390_r2);
                }
                break;
        case SAVE_ONE:
-               s390_st (code, s390_r2, 0, cfg->frame_reg, cfg->stack_usage - 4);
+               s390_st (code, s390_r2, 0, cfg->frame_reg, saveOffset);
                if (enable_arguments) {
                        s390_lr (code, s390_r3, s390_r2);
                }
                break;
        case SAVE_FP:
-               s390_std (code, s390_f0, 0, cfg->frame_reg, cfg->stack_usage - 8);
+               s390_std (code, s390_f0, 0, cfg->frame_reg, saveOffset);
                if (enable_arguments) {
                        /* FIXME: what reg?  */
                        s390_ldr (code, s390_f2, s390_f0);
-                       s390_lm  (code, s390_r3, s390_r4, cfg->frame_reg, cfg->stack_usage - 8);
+                       s390_lm  (code, s390_r3, s390_r4, cfg->frame_reg, saveOffset);
                }
                break;
        case SAVE_STRUCT:
-               s390_st (code, s390_r2, 0, cfg->frame_reg, cfg->stack_usage - 4);
+               s390_st (code, s390_r2, 0, cfg->frame_reg, saveOffset);
                if (enable_arguments) {
                        s390_l (code, s390_r3, 0, cfg->frame_reg, 
                                S390_MINIMAL_STACK_SIZE+cfg->param_area);
@@ -1680,16 +1694,16 @@ handle_enum:
 
        switch (save_mode) {
        case SAVE_TWO:
-               s390_lm  (code, s390_r2, s390_r3, cfg->frame_reg, cfg->stack_usage - 8);
+               s390_lm  (code, s390_r2, s390_r3, cfg->frame_reg, saveOffset);
                break;
        case SAVE_ONE:
-               s390_l   (code, s390_r2, 0, cfg->frame_reg, cfg->stack_usage - 4);
+               s390_l   (code, s390_r2, 0, cfg->frame_reg, saveOffset);
                break;
        case SAVE_FP:
-               s390_ld  (code, s390_f0, 0, cfg->frame_reg, cfg->stack_usage - 8);
+               s390_ld  (code, s390_f0, 0, cfg->frame_reg, saveOffset);
                break;
        case SAVE_STRUCT:
-               s390_l   (code, s390_r2, 0, cfg->frame_reg, cfg->stack_usage - 4);
+               s390_l   (code, s390_r2, 0, cfg->frame_reg, saveOffset);
                break;
        case SAVE_NONE:
        default:
@@ -2507,9 +2521,11 @@ mono_arch_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
                } else if (spec [MONO_INST_CLOB] == 'c') {
                        MonoCallInst *cinst = (MonoCallInst*)ins;
                        DEBUG (g_print ("excluding regs 0x%x from cur_iregs (0x%x)\n", cinst->used_iregs, cur_iregs));
+                       DEBUG (g_print ("excluding fpregs 0x%x from cur_fregs (0x%x)\n", cinst->used_fregs, cur_fregs));
                        cur_iregs &= ~cinst->used_iregs;
                        cur_fregs &= ~cinst->used_fregs;
                        DEBUG (g_print ("available cur_iregs: 0x%x\n", cur_iregs));
+                       DEBUG (g_print ("available cur_fregs: 0x%x\n", cur_fregs));
                        /* registers used by the calling convention are excluded from 
                         * allocation: they will be selectively enabled when they are 
                         * assigned by the special SETREG opcodes.
@@ -2518,6 +2534,7 @@ mono_arch_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
                dest_mask = src1_mask = src2_mask = cur_iregs;
                /* update for use with FP regs... */
                if (spec [MONO_INST_DEST] == 'f') {
+                       dest_mask = cur_fregs;
                        if (ins->dreg >= MONO_MAX_FREGS) {
                                val = rs->fassign [ins->dreg];
                                prev_dreg = ins->dreg;
@@ -2620,11 +2637,19 @@ mono_arch_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
                } else {
                        prev_dreg = -1;
                }
-               if (spec [MONO_INST_DEST] != 'f' && reg_is_freeable (ins->dreg) && prev_dreg >= 0 && (reginfo [prev_dreg].born_in >= i)) {
+               if (spec [MONO_INST_DEST] == 'f' && 
+                   freg_is_freeable (ins->dreg) && 
+                   prev_dreg >= 0 && (reginfof [prev_dreg].born_in >= i)) {
+                       DEBUG (g_print ("\tfreeable %s (R%d) (born in %d)\n", mono_arch_regname (ins->dreg), prev_dreg, reginfo [prev_dreg].born_in));
+                       mono_regstate_free_float (rs, ins->dreg);
+               } else if (spec [MONO_INST_DEST] != 'f' && 
+                          reg_is_freeable (ins->dreg) && 
+                          prev_dreg >= 0 && (reginfo [prev_dreg].born_in >= i)) {
                        DEBUG (g_print ("\tfreeable %s (R%d) (born in %d)\n", mono_arch_regname (ins->dreg), prev_dreg, reginfo [prev_dreg].born_in));
-                       mono_regstate_free_int (rs, ins->dreg);
+                        mono_regstate_free_int (rs, ins->dreg);
                }
                if (spec [MONO_INST_SRC1] == 'f') {
+                       src1_mask = cur_fregs;
                        if (ins->sreg1 >= MONO_MAX_FREGS) {
                                val = rs->fassign [ins->sreg1];
                                prev_sreg1 = ins->sreg1;
@@ -2658,28 +2683,13 @@ mono_arch_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
                                if (val < -1) {
                                        /* the register gets spilled after this inst */
                                        spill = -val -1;
+printf("val: %d spill: %d ins->sreg1: %d\n",val,spill,ins->sreg1);
                                }
-                               if (0 && ins->opcode == OP_MOVE) {
-                                       /* 
-                                        * small optimization: the dest register is already allocated
-                                        * but the src one is not: we can simply assign the same register
-                                        * here and peephole will get rid of the instruction later.
-                                        * This optimization may interfere with the clobbering handling:
-                                        * it removes a mov operation that will be added again to handle clobbering.
-                                        * There are also some other issues that should with make testjit.
-                                        */
-                                       mono_regstate_alloc_int (rs, 1 << ins->dreg);
-                                       val = rs->iassign [ins->sreg1] = ins->dreg;
-                                       //g_assert (val >= 0);
-                                       DEBUG (g_print ("\tfast assigned sreg1 %s to R%d\n", mono_arch_regname (val), ins->sreg1));
-                               } else {
-                                       //g_assert (val == -1); /* source cannot be spilled */
-                                       val = mono_regstate_alloc_int (rs, src1_mask);
-                                       if (val < 0)
-                                               val = get_register_spilling (cfg, tmp, ins, src1_mask, ins->sreg1);
-                                       rs->iassign [ins->sreg1] = val;
-                                       DEBUG (g_print ("\tassigned sreg1 %s to R%d\n", mono_arch_regname (val), ins->sreg1));
-                               }
+                               val = mono_regstate_alloc_int (rs, src1_mask);
+                               if (val < 0)
+                                       val = get_register_spilling (cfg, tmp, ins, src1_mask, ins->sreg1);
+                               rs->iassign [ins->sreg1] = val;
+                               DEBUG (g_print ("\tassigned sreg1 %s to R%d\n", mono_arch_regname (val), ins->sreg1));
                                if (spill) {
                                        MonoInst *store = create_spilled_store (cfg, spill, val, prev_sreg1, NULL);
                                        insert_before_ins (ins, tmp, store);
@@ -2713,6 +2723,7 @@ mono_arch_local_regalloc (MonoCompile *cfg, MonoBasicBlock *bb)
                }
 
                if (spec [MONO_INST_SRC2] == 'f') {
+                       src2_mask = cur_fregs;
                        if (ins->sreg2 >= MONO_MAX_FREGS) {
                                val = rs->fassign [ins->sreg2];
                                prev_sreg2 = ins->sreg2;
@@ -3516,9 +3527,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        }
                        break;
                case OP_FCONV_TO_R4:
-                       if (ins->dreg != ins->sreg1) {
-                               s390_ledbr (code, ins->dreg, ins->sreg1);
-                       }
+                       s390_ledbr (code, ins->dreg, ins->sreg1);
                        break;
                case CEE_JMP:
                        g_assert_not_reached ();
@@ -3593,8 +3602,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        s390_br  (code, s390_r14);
                        break;
                case CEE_ENDFINALLY:
-//                     s390_l   (code, STK_BASE, 0, STK_BASE, 0);
-//                     s390_lm  (code, s390_r6, s390_r14, STK_BASE, S390_REG_SAVE_OFFSET);
                        s390_l   (code, s390_r14, 0, ins->inst_left->inst_basereg, ins->inst_left->inst_offset);
                        s390_br  (code, s390_r14);
                        break;
@@ -3813,15 +3820,15 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                case OP_LCONV_TO_OVF_I: {
                        /* Valid ints: 0xffffffff:8000000 to 00000000:0x7f000000 */
                        short int *o[5];
-                       s390_ltr  (code, ins->sreg1, ins->sreg1);
-                       s390_jnl  (code, 0); CODEPTR(code, o[0]);
                        s390_ltr  (code, ins->sreg2, ins->sreg2);
+                       s390_jnl  (code, 0); CODEPTR(code, o[0]);
+                       s390_ltr  (code, ins->sreg1, ins->sreg1);
                        s390_jnl  (code, 0); CODEPTR(code, o[1]);
                        s390_lhi  (code, s390_r13, -1);
-                       s390_cr   (code, ins->sreg2, s390_r13);
+                       s390_cr   (code, ins->sreg1, s390_r13);
                        s390_jnz  (code, 0); CODEPTR(code, o[2]);
-                       if (ins->dreg != ins->sreg1)
-                               s390_lr   (code, ins->dreg, ins->sreg1);
+                       if (ins->dreg != ins->sreg2)
+                               s390_lr   (code, ins->dreg, ins->sreg2);
                        s390_j    (code, 0); CODEPTR(code, o[3]);
                        PTRSLOT(code, o[0]);
                        s390_jz   (code, 0); CODEPTR(code, o[4]);
@@ -4229,27 +4236,33 @@ mono_arch_emit_prolog (MonoCompile *cfg)
        }
 
        alloc_size = cfg->stack_offset;
-       if (tracing)
-               alloc_size += S390_TRACE_STACK_SIZE;
-       pos = 0;
+//     if (tracing)
+//             alloc_size += S390_TRACE_STACK_SIZE;
+//     pos = 0;
        /* reserve room to save return value */
-       if (tracing)
-               pos += 8;
+//     if (tracing)
+//             pos += 8;
 
-       alloc_size += pos;
+//     alloc_size += pos;
 
-       if (method->save_lmf) 
-               alloc_size += sizeof(MonoLMF);
+//     if (method->save_lmf) 
+//             alloc_size += sizeof(MonoLMF);
 
-       alloc_size = S390_ALIGN(alloc_size, S390_STACK_ALIGNMENT);
+//     alloc_size = S390_ALIGN(alloc_size, S390_STACK_ALIGNMENT);
 
        cfg->stack_usage = alloc_size;
-       g_assert (s390_is_imm16 (-alloc_size));
-       if (alloc_size) {
-               s390_lr   (code, s390_r11, STK_BASE);
+       s390_lr   (code, s390_r11, STK_BASE);
+       if (s390_is_imm16 (-alloc_size)) {
                s390_ahi  (code, STK_BASE, -alloc_size);
-               s390_st   (code, s390_r11, 0, STK_BASE, 0);
+       } else { 
+               int stackSize = alloc_size;
+               while (stackSize > 32767) {
+                       s390_ahi  (code, STK_BASE, -32767);
+                       stackSize -= 32767;
+               }
+               s390_ahi  (code, STK_BASE, -stackSize);
        }
+       s390_st   (code, s390_r11, 0, STK_BASE, 0);
 
        if (cfg->flags & MONO_CFG_HAS_ALLOCA)
                s390_lr (code, s390_r11, STK_BASE);
@@ -4396,9 +4409,7 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                /*---------------------------------------------------------------*/
                /* we build the MonoLMF structure on the stack - see mini-s390.h */
                /*---------------------------------------------------------------*/
-               lmfOffset = S390_MINIMAL_STACK_SIZE + cfg->param_area;
-               if (tracing)
-                       lmfOffset += S390_TRACE_STACK_SIZE;
+               lmfOffset = alloc_size - sizeof(MonoLMF);
 
                s390_lr    (code, s390_r13, cfg->frame_reg);
                s390_ahi   (code, s390_r13, lmfOffset);
@@ -4431,12 +4442,15 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                s390_word  (code, method);
                s390_l     (code, s390_r1, 0, s390_r1, 4);
                s390_st    (code, s390_r1, 0, s390_r13, G_STRUCT_OFFSET(MonoLMF, method));
-               s390_st    (code, cfg->frame_reg, 0, s390_r13, G_STRUCT_OFFSET(MonoLMF, ebp));
 
                /*---------------------------------------------------------------*/
                /* save the current IP                                           */
                /*---------------------------------------------------------------*/
-               s390_larl  (code, s390_r1, 0);
+               s390_lr    (code, s390_r1, cfg->frame_reg);
+               s390_ahi   (code, s390_r1, alloc_size);
+               s390_st    (code, s390_r1, 0, s390_r13, G_STRUCT_OFFSET(MonoLMF, ebp));
+               s390_l     (code, s390_r1, 0, s390_r1, S390_RET_ADDR_OFFSET);
+               s390_la    (code, s390_r1, 0, s390_r1, 0);
                s390_st    (code, s390_r1, 0, s390_r13, G_STRUCT_OFFSET(MonoLMF, eip));
 
                /*---------------------------------------------------------------*/
@@ -4479,15 +4493,15 @@ mono_arch_emit_epilog (MonoCompile *cfg)
 
        code = cfg->native_code + cfg->code_len;
 
-       if (mono_jit_trace_calls != NULL && mono_trace_eval (method)) 
+       if (mono_jit_trace_calls != NULL && mono_trace_eval (method)) {
+               code = mono_arch_instrument_epilog (cfg, leave_method, code, TRUE);
                tracing = 1;
+       }
        
        if (method->save_lmf) {
                s390_lr  (code, s390_r13, cfg->frame_reg);
 
-               lmfOffset = S390_MINIMAL_STACK_SIZE + cfg->param_area;
-               if (tracing)
-                       lmfOffset += S390_TRACE_STACK_SIZE;
+               lmfOffset = cfg->stack_usage -  sizeof(MonoLMF);
 
                /*-------------------------------------------------*/
                /* r13 = my lmf                                    */
index 66502582c23b8a5fc2f516f97bf2f8bfc9b31586..3095fadcb15cd973b1f0150365aa5b74d0ee4e01 100644 (file)
@@ -26,11 +26,13 @@ typedef struct ucontext MonoContext;
 typedef struct MonoCompileArch {
 } MonoCompileArch;
 
-#define MONO_ARCH_EMULATE_FCONV_TO_I8 1
-#define MONO_ARCH_EMULATE_LCONV_TO_R8 1
-#define MONO_ARCH_EMULATE_LCONV_TO_R4 1
+#define MONO_ARCH_EMULATE_FCONV_TO_I8  1
+#define MONO_ARCH_EMULATE_LCONV_TO_R8  1
+#define MONO_ARCH_EMULATE_LCONV_TO_R4  1
 #define MONO_ARCH_EMULATE_LCONV_TO_R8_UN 1
-#define MONO_ARCH_EMULATE_LMUL 1
+#define MONO_ARCH_EMULATE_LMUL                 1
+
+#define MONO_ARCH_USE_SIGACTION        1
 
 #define S390_STACK_ALIGNMENT            8
 #define S390_FIRST_ARG_REG             s390_r2
index 2060d423464d39827608f45f008d295790983795..a939483edbf2e384143543708ad7b7496b8c7780 100644 (file)
@@ -8111,7 +8111,7 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
 #ifdef __sparc
 #define GET_CONTEXT \
     void *ctx = context;
-#elif defined(__ppc__) || defined (__powerpc__)
+#elif defined(__ppc__) || defined (__powerpc__) || defined (__s390__)
 #define GET_CONTEXT \
     void *ctx = context;
 #else