#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,
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
#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 =========================*/
/*------------------------------------------------------------------*/
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;
/* 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: */
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) {
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;
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;
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);
}
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);
}
}
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);
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;
/* 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;
/* 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:
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:
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);
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);
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);
/* 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 */
/* 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);
/* 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);
}
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);
/*----------------------------------------------------------*/
/* 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 */
}
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);
}
/*--------------------------------------*/
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);
/*----------------------------------------------------------*/
/* 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);
}
}
/*----------------------------------------------------------*/
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/...) */
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));
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:
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;
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 */
/*------------------------------------------*/
/* 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);
/*----------------------------------------------------------*/
/* 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));
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:
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
/* 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
/* 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);
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)
{
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;
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
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;
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)
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;
/*------------------------------------------------------------------*/
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,
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");
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);
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,
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);
}
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);
}
}
} 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 ========================*/
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;
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;
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;
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;
: 0);
inst->inst_offset = cinfo->args[iParm].offset +
size;
- inst->unused = stackOffset;
+// inst->unused = stackOffset;
+ inst->unused = 0;
size = sizeof(long);
}
}
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);
}
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;
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);
}
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 */
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);
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) {
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);
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:
} 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.
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;
} 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;
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);
}
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;
}
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 ();
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;
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]);
}
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);
/*---------------------------------------------------------------*/
/* 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);
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));
/*---------------------------------------------------------------*/
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 */
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
#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