2005-02-05 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mono / mini / mini-s390x.h
1 #ifndef __MONO_MINI_S390X_H__
2 #define __MONO_MINI_S390X_H__
3
4 #include <mono/arch/s390x/s390x-codegen.h>
5 #include <signal.h>
6
7 #define MONO_MAX_IREGS 16
8 #define MONO_MAX_FREGS 16
9
10 #define MONO_ARCH_FRAME_ALIGNMENT 8
11
12 #define MONO_EMIT_NEW_MOVE(cfg,dest,offset,src,imm,size) do {                   \
13                 MonoInst *inst;                                                 \
14                 int tmpr = 0;                                                   \
15                 int sReg, dReg;                                                 \
16                                                                                 \
17                 inst = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoInst)); \
18                 if (size > 256) {                                               \
19                         tmpr = mono_regstate_next_int (cfg->rs);                \
20                         MONO_EMIT_NEW_ICONST(cfg,tmpr,size);                    \
21                         inst->dreg        = dest;                               \
22                         inst->inst_offset = offset;                             \
23                         inst->sreg1       = src;                                \
24                         inst->inst_imm    = imm;                                \
25                         inst->sreg2       = tmpr;                               \
26                 } else {                                                        \
27                         if (s390_is_uimm12(offset)) {                           \
28                                 inst->dreg        = dest;                       \
29                                 inst->inst_offset = offset;                     \
30                         } else {                                                \
31                                 dReg = mono_regstate_next_int (cfg->rs);        \
32                                 MONO_EMIT_NEW_BIALU_IMM(cfg, OP_ADD_IMM,        \
33                                         dReg, dest, offset);                    \
34                                 inst->dreg        = dReg;                       \
35                                 inst->inst_offset = 0;                          \
36                         }                                                       \
37                         if (s390_is_uimm12(imm)) {                              \
38                                 inst->sreg1       = src;                        \
39                                 inst->inst_imm    = imm;                        \
40                         } else {                                                \
41                                 sReg = mono_regstate_next_int (cfg->rs);        \
42                                 MONO_EMIT_NEW_BIALU_IMM(cfg, OP_ADD_IMM,        \
43                                         sReg, src, imm);                        \
44                                 inst->sreg1       = sReg;                       \
45                                 inst->inst_imm    = 0;                          \
46                         }                                                       \
47                 }                                                               \
48                 inst->opcode      = OP_S390_MOVE;                               \
49                 inst->unused      = size;                                       \
50                 mono_bblock_add_inst (cfg->cbb, inst);                          \
51         } while (0)
52
53 #define MONO_OUTPUT_VTR(cfg, size, dr, sr, so) do {                             \
54         switch (size) {                                                         \
55                 case 1:                                                         \
56                         MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU1_MEMBASE,   \
57                                 dr, sr, so);                                    \
58                 break;                                                          \
59                 case 2:                                                         \
60                         MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU2_MEMBASE,   \
61                                 dr, sr, so);                                    \
62                 break;                                                          \
63                 case 4:                                                         \
64                         MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU4_MEMBASE,   \
65                                 dr, sr, so);                                    \
66                 break;                                                          \
67                 case 8:                                                         \
68                         MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOAD_MEMBASE,     \
69                                 dr, sr, so);                                    \
70                 break;                                                          \
71         }                                                                       \
72 } while (0)
73
74 #define MONO_OUTPUT_VTS(cfg, size, dr, dx, sr, so) do {                         \
75         int tmpr;                                                               \
76         switch (size) {                                                         \
77                 case 1:                                                         \
78                         tmpr = mono_regstate_next_int (cfg->rs);                \
79                         MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU1_MEMBASE,   \
80                                 tmpr, sr, so);                                  \
81                         MONO_EMIT_NEW_STORE_MEMBASE(cfg, OP_STORE_MEMBASE_REG,  \
82                                 tmpr, dr, dx);                                  \
83                 break;                                                          \
84                 case 2:                                                         \
85                         tmpr = mono_regstate_next_int (cfg->rs);                \
86                         MONO_EMIT_NEW_LOAD_MEMBASE_OP(cfg, OP_LOADU2_MEMBASE,   \
87                                 tmpr, sr, so);                                  \
88                         MONO_EMIT_NEW_STORE_MEMBASE(cfg, OP_STORE_MEMBASE_REG,  \
89                                 tmpr, dr, dx);                                  \
90                 break;                                                          \
91                 case 4:                                                         \
92                 case 8:                                                         \
93                         MONO_EMIT_NEW_MOVE (cfg, dr, dx, sr, so, size);         \
94                 break;                                                          \
95         }                                                                       \
96 } while (0)
97
98 /* fixme: align to 16byte instead of 32byte (we align to 32byte to get 
99  * reproduceable results for benchmarks */
100 #define MONO_ARCH_CODE_ALIGNMENT 32
101
102 struct MonoLMF {
103         gpointer    previous_lmf;
104         gpointer    lmf_addr;
105         MonoMethod *method;
106         gulong      ebp;
107         gulong      eip;
108         gulong      gregs[16];
109         gdouble     fregs[16];
110 };
111
112 typedef struct ucontext MonoContext;
113
114 typedef struct MonoCompileArch {
115 } MonoCompileArch;
116
117 #define MONO_ARCH_EMULATE_FCONV_TO_I8   1
118 #define MONO_ARCH_EMULATE_LCONV_TO_R8   1
119 #define MONO_ARCH_EMULATE_LCONV_TO_R4   1
120 #define MONO_ARCH_EMULATE_LCONV_TO_R8_UN 1
121 #define MONO_ARCH_EMULATE_LMUL          1
122 #define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS 1
123
124 #define MONO_ARCH_USE_SIGACTION         1
125
126 #define S390_STACK_ALIGNMENT             8
127 #define S390_FIRST_ARG_REG              s390_r2
128 #define S390_LAST_ARG_REG               s390_r6
129 #define S390_FIRST_FPARG_REG            s390_f0
130 #define S390_LAST_FPARG_REG             s390_f2
131 #define S390_PASS_STRUCTS_BY_VALUE       1
132 #define S390_SMALL_RET_STRUCT_IN_REG     1
133
134 #define S390_NUM_REG_ARGS (S390_LAST_ARG_REG-S390_FIRST_ARG_REG+1)
135 #define S390_NUM_REG_FPARGS (S390_LAST_FPARG_REG-S390_FIRST_FPARG_REG)
136
137 #define S390_OFFSET(b, t)       (gint32) ((gint64) (b) - (gint64) (t))
138 #define S390_RELATIVE(b, t)     (gint32) ((((gint64) (b) - (gint64) (t))) / 2)
139
140 #define CODEPTR(c, o) (o) = (short *) ((gint64) c - 2)
141 #define PTRSLOT(c, o) *(o) = (short) ((gint64) c - (gint64) (o) + 2)/2
142
143 #define S390_CC_EQ                      8
144 #define S390_ALIGN(v, a)        (((a) > 0 ? (((v) + ((a) - 1)) & ~((a) - 1)) : (v)))
145
146 static void inline
147 s390_patch (guchar *code, gint32 target)
148 {
149         gint32 *offset = (gint32 *) code;
150         
151         if (target != 00) {
152                 *offset = target;
153         }
154 }
155
156 #endif /* __MONO_MINI_S390_H__ */