Update PointConverter.cs
[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 <mono/utils/mono-context.h>
6 #include <signal.h>
7
8 #define MONO_ARCH_CPU_SPEC s390x_cpu_desc
9
10 #define MONO_MAX_IREGS 16
11 #define MONO_MAX_FREGS 16
12
13 /*-------------------------------------------*/
14 /* Parameters used by the register allocator */
15 /*-------------------------------------------*/
16
17 #define S390_LONG(loc, opy, op, r, ix, br, off)                                 \
18         if (has_ld) {                                                           \
19                 if (s390_is_imm20(off)) {                                       \
20                         s390_##opy (loc, r, ix, br, off);                       \
21                 } else {                                                        \
22                         s390_basr (code, s390_r13, 0);                          \
23                         s390_j    (code, 6);                                    \
24                         s390_llong(code, off);                                  \
25                         s390_lg   (code, s390_r13, 0, s390_r13, 4);             \
26                         s390_##op (code, r, s390_r13, br, 0);                   \
27                 }                                                               \
28         } else {                                                                \
29                 if (s390_is_uimm12(off)) {                                      \
30                         s390_##op (loc, r, ix, br, off);                        \
31                 } else {                                                        \
32                         s390_basr (code, s390_r13, 0);                          \
33                         s390_j    (code, 6);                                    \
34                         s390_llong(code, off);                                  \
35                         s390_lg   (code, s390_r13, 0, s390_r13, 4);             \
36                         s390_##op (code, r, s390_r13, br, 0);                   \
37                 }                                                               \
38         }
39
40 struct MonoLMF {
41         gpointer    previous_lmf;
42         gpointer    lmf_addr;
43         MonoMethod *method;
44         gulong      ebp;
45         gulong      eip;
46         gulong      pregs[6];
47         gulong      gregs[16];
48         gdouble     fregs[16];
49 };
50
51 typedef struct MonoCompileArch {
52         gpointer    litpool;
53         glong       litsize;
54         int         bkchain_reg;
55 } MonoCompileArch;
56
57 typedef struct
58 {
59         void *prev;
60         void *unused[5];
61         void *regs[8];
62         void *return_address;
63 } MonoS390StackFrame;
64
65 typedef struct
66 {
67         char    n3:1;           // N3 instructions present
68         char    zArch:1;        // z/Architecture mode installed
69         char    zAct:1;         // z/Architecture mode active
70         char    date:1;         // DATE enhancement facility
71         char    idte1:1;        // IDTE present (PST)
72         char    idte2:1;        // IDTE present (REG)
73         char    asnlx:1;        // ASN and LX reuse facility
74         char    stfle:1;        // STFLE installed
75         char    zDATe:1;        // Enhanced DAT in z mode
76         char    srstat:1;       // Sense running status facility
77         char    cSSKE:1;        // Conditional SSKE facility
78         char    topo:1;         // COnfiguration topology facility
79         char    xTrans2:1;      // Extended translation facility 2
80         char    msgSec:1;       // Message security facility
81         char    longDsp:1;      // Long displacement facility
82         char    hiPerfLD:1;     // High performance long displacement facility
83         char    hfpMAS:1;       // HFP multiply-and-add/subtrace facility
84         char    xImm:1;         // Extended immediate facility
85         char    xTrans3:1;      // Extended translation facility 3
86         char    hfpUnX:1;       // HFP unnormalized extension facility
87         char    etf2:1;         // ETF2-enhancement facility
88         char    stckf:1;        // Store-clock-fast facility
89         char    parse:1;        // Parsing enhancement facility
90         char    mvcos:1;        // MVCOS facility
91         char    todSteer:1;     // TOD-clock steering facility
92         char    etf3:1;         // ETF3-enhancement facility
93         char    xCPUtm:1;       // Extract CPU time facility
94         char    csst:1;         // Compare-swap-and-store facility
95         char    csst2:1;        // Compare-swap-and-store facility 2
96         char    giX:1;          // General instructions extension facility
97         char    exX:1;          // Execute extensions facility
98         char    ibm:1;          // IBM internal use
99         char    fps:1;          // Floating point support enhancement
100         char    dfp:1;          // Decimal floating point facility
101         char    hiDFP:1;        // High Performance DFP facility
102         char    pfpo:1;         // PFPO instruction facility
103 } __attribute__((aligned(8))) facilityList_t;
104         
105 // #define MONO_ARCH_SIGSEGV_ON_ALTSTACK                1
106 #define MONO_ARCH_EMULATE_LCONV_TO_R8_UN                1
107 #define MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS              1
108 #define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS             1
109 #define MONO_ARCH_HAVE_IS_INT_OVERFLOW                  1
110 #define MONO_ARCH_NEED_DIV_CHECK                        1
111 #define MONO_ARCH_HAVE_ATOMIC_ADD                       1
112 #define MONO_ARCH_HAVE_ATOMIC_EXCHANGE                  1
113 #define MONO_ARCH_SIGNAL_STACK_SIZE                     256*1024
114 #define MONO_ARCH_HAVE_DECOMPOSE_OPTS                   1
115 #define MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE       1
116 #define MONO_ARCH_HAVE_IMT                              1
117 #define MONO_ARCH_HAVE_TLS_GET                          1
118 #define MONO_ARCH_ENABLE_MONO_LMF_VAR                   1
119 #define MONO_ARCH_IMT_REG                               s390_r9
120 #define MONO_ARCH_VTABLE_REG                            MONO_ARCH_IMT_REG
121 #define MONO_ARCH_RGCTX_REG                             MONO_ARCH_IMT_REG
122 #define MONO_ARCH_THIS_AS_FIRST_ARG                     1
123 #define MONO_ARCH_HAVE_XP_UNWIND                        1
124 #define MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX                1
125 #define MONO_ARCH_SOFT_DEBUG_SUPPORTED                  1
126 #define MONO_ARCH_HAVE_CONTEXT_SET_INT_REG              1
127 #define MONO_ARCH_USE_SIGACTION                         1
128 #define MONO_ARCH_GC_MAPS_SUPPORTED                     1
129 #define MONO_ARCH_GSHARED_SUPPORTED                     1
130 #define MONO_ARCH_MONITOR_ENTER_ADJUSTMENT              1
131
132 #define S390_STACK_ALIGNMENT             8
133 #define S390_FIRST_ARG_REG              s390_r2
134 #define S390_LAST_ARG_REG               s390_r6
135 #define S390_FIRST_FPARG_REG            s390_f0
136 #define S390_LAST_FPARG_REG             s390_f6
137 #define S390_PASS_STRUCTS_BY_VALUE       1
138 #define S390_SMALL_RET_STRUCT_IN_REG     1
139
140 #define S390_NUM_REG_ARGS (S390_LAST_ARG_REG-S390_FIRST_ARG_REG+1)
141 #define S390_NUM_REG_FPARGS ((S390_LAST_FPARG_REG-S390_FIRST_FPARG_REG)/2)
142
143 /*===============================================*/
144 /* Definitions used by mini-codegen.c            */
145 /*===============================================*/
146
147 /*------------------------------------------------------*/
148 /* use s390_r2-s390_r6 as parm registers                */
149 /* s390_r0, s390_r1, s390_r12, s390_r13 used internally */
150 /* s390_r8..s390_r11 are used for global regalloc       */
151 /* s390_r15 is the stack pointer                        */
152 /*------------------------------------------------------*/
153
154 #define MONO_ARCH_CALLEE_REGS (0xfc)
155
156 #define MONO_ARCH_CALLEE_SAVED_REGS 0xff80
157
158 /*----------------------------------------*/
159 /* use s390_f1/s390_f3-s390_f15 as temps  */
160 /*----------------------------------------*/
161
162 #define MONO_ARCH_CALLEE_FREGS (0xfffe)
163
164 #define MONO_ARCH_CALLEE_SAVED_FREGS 0
165
166 #define MONO_ARCH_USE_FPSTACK FALSE
167 #define MONO_ARCH_FPSTACK_SIZE 0
168
169 #define MONO_ARCH_INST_FIXED_REG(desc) ((desc == 'o') ? s390_r2 :               \
170                                         ((desc == 'g') ? s390_f0 : - 1))
171
172 #define MONO_ARCH_INST_IS_FLOAT(desc)  ((desc == 'f') || (desc == 'g'))
173
174 #define MONO_ARCH_INST_SREG2_MASK(ins) (0)
175
176 #define MONO_ARCH_INST_IS_REGPAIR(desc) (0)
177 #define MONO_ARCH_INST_REGPAIR_REG2(desc,hr) -1
178
179 #define MONO_ARCH_IS_GLOBAL_IREG(reg) 0
180
181 #define MONO_ARCH_FRAME_ALIGNMENT 8
182 #define MONO_ARCH_CODE_ALIGNMENT 32
183
184 #define MONO_ARCH_RETREG1 s390_r2
185
186 /*-----------------------------------------------*/
187 /* Macros used to generate instructions          */
188 /*-----------------------------------------------*/
189 #define S390_OFFSET(b, t)       (guchar *) ((guint64) (b) - (guint64) (t))
190 #define S390_RELATIVE(b, t)     (guchar *) ((((guint64) (b) - (guint64) (t))) / 2)
191
192 #define CODEPTR(c, o) (o) = (short *) ((guint64) c - 2)
193 #define PTRSLOT(c, o) *(o) = (short) ((guint64) c - (guint64) (o) + 2)/2
194
195 #define S390_CC_EQ                      8
196 #define S390_ALIGN(v, a)        (((a) > 0 ? (((v) + ((a) - 1)) & ~((a) - 1)) : (v)))
197
198 #define MONO_INIT_CONTEXT_FROM_FUNC(ctx,func) do {                      \
199                 MonoS390StackFrame *sframe;                             \
200                 __asm__ volatile("lgr   %0,15" : "=r" (sframe));        \
201                 MONO_CONTEXT_SET_BP ((ctx), sframe->prev);              \
202                 MONO_CONTEXT_SET_SP ((ctx), sframe->prev);              \
203                 MONO_CONTEXT_SET_IP ((ctx), func);                      \
204         } while (0)
205
206 #define MONO_ARCH_INIT_TOP_LMF_ENTRY(lmf) do { (lmf)->ebp = -1; } while (0)
207
208 /*------------------------------------------------------------------*/
209 /*                                                                  */
210 /* Name         - s390_patch_rel                                    */
211 /*                                                                  */
212 /* Function     - Patch the code with a given offset.               */
213 /*                                                                  */
214 /*------------------------------------------------------------------*/
215
216 static void inline
217 s390_patch_rel (guchar *code, guint64 target)
218 {
219         guint32 *offset = (guint32 *) code;
220         
221         if (target != 0) {
222                 *offset = (guint32) target;
223         }
224 }
225
226 /*========================= End of Function ========================*/
227
228 /*------------------------------------------------------------------*/
229 /*                                                                  */
230 /* Name         - s390_patch_addr                                   */
231 /*                                                                  */
232 /* Function     - Patch the code with a given address.              */
233 /*                                                                  */
234 /*------------------------------------------------------------------*/
235
236 static void inline
237 s390_patch_addr (guchar *code, guint64 target)
238 {
239         guint64 *offset = (guint64 *) code;
240         
241         if (target != 0) {
242                 *offset = target;
243         }
244 }
245
246 /*========================= End of Function ========================*/
247
248 /*------------------------------------------------------------------*/
249 /*                                                                  */
250 /* Name         - restoreLMF                                        */
251 /*                                                                  */
252 /* Function     - Restore the LMF state prior to exiting a method.  */
253 /*                                                                  */
254 /*------------------------------------------------------------------*/
255
256 #define restoreLMF(code, frame_reg, stack_usage) do                     \
257 {                                                                       \
258         int lmfOffset = 0;                                              \
259                                                                         \
260         s390_lgr (code, s390_r13, frame_reg);                           \
261                                                                         \
262         lmfOffset = stack_usage -  sizeof(MonoLMF);                     \
263                                                                         \
264         /*-------------------------------------------------*/           \
265         /* r13 = my lmf                                    */           \
266         /*-------------------------------------------------*/           \
267         s390_aghi (code, s390_r13, lmfOffset);                          \
268                                                                         \
269         /*-------------------------------------------------*/           \
270         /* r6 = &jit_tls->lmf                              */           \
271         /*-------------------------------------------------*/           \
272         s390_lg  (code, s390_r6, 0, s390_r13,                           \
273                   G_STRUCT_OFFSET(MonoLMF, lmf_addr));                  \
274                                                                         \
275         /*-------------------------------------------------*/           \
276         /* r0 = lmf.previous_lmf                           */           \
277         /*-------------------------------------------------*/           \
278         s390_lg  (code, s390_r0, 0, s390_r13,                           \
279                   G_STRUCT_OFFSET(MonoLMF, previous_lmf));              \
280                                                                         \
281         /*-------------------------------------------------*/           \
282         /* jit_tls->lmf = previous_lmf                     */           \
283         /*-------------------------------------------------*/           \
284         s390_lg  (code, s390_r13, 0, s390_r6, 0);                       \
285         s390_stg (code, s390_r0, 0, s390_r6, 0);                        \
286 } while (0)
287
288 /*========================= End of Function ========================*/
289
290 #endif /* __MONO_MINI_S390X_H__ */