1 /**
2  * \file
3  */
4 
5 #ifndef __MONO_MINI_S390X_H__
6 #define __MONO_MINI_S390X_H__
7 
8 #include <mono/arch/s390x/s390x-codegen.h>
9 #include <mono/utils/mono-context.h>
10 #include <signal.h>
11 
12 #define MONO_ARCH_CPU_SPEC mono_s390x_cpu_desc
13 
14 #define MONO_MAX_IREGS 16
15 #define MONO_MAX_FREGS 16
16 
17 /*-------------------------------------------*/
18 /* Parameters used by the register allocator */
19 /*-------------------------------------------*/
20 
21 struct MonoLMF {
22 	gpointer    previous_lmf;
23 	gpointer    lmf_addr;
24 	MonoMethod *method;
25 	gulong      ebp;
26 	gulong      eip;
27 	gulong	    pregs[6];
28 	gulong	    gregs[16];
29 	gdouble     fregs[16];
30 };
31 
32 typedef struct MonoCompileArch {
33 	gpointer    litpool;
34 	glong	    litsize;
35 	int         bkchain_reg;
36 } MonoCompileArch;
37 
38 typedef struct
39 {
40 	void *prev;
41 	void *unused[5];
42 	void *regs[8];
43 	void *return_address;
44 } MonoS390StackFrame;
45 
46 // #define MONO_ARCH_SIGSEGV_ON_ALTSTACK		1
47 #define MONO_ARCH_EMULATE_LCONV_TO_R8_UN 		1
48 #define MONO_ARCH_NO_EMULATE_LONG_MUL_OPTS		1
49 #define MONO_ARCH_NO_EMULATE_LONG_SHIFT_OPS		1
50 #define MONO_ARCH_HAVE_IS_INT_OVERFLOW  		1
51 #define MONO_ARCH_NEED_DIV_CHECK			1
52 #define MONO_ARCH_SIGNAL_STACK_SIZE 			256*1024
53 #define MONO_ARCH_HAVE_DECOMPOSE_OPTS 			1
54 #define MONO_ARCH_IMT_REG				s390_r9
55 #define MONO_ARCH_VTABLE_REG				S390_FIRST_ARG_REG
56 #define MONO_ARCH_RGCTX_REG				MONO_ARCH_IMT_REG
57 #define MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX		1
58 #define MONO_ARCH_SOFT_DEBUG_SUPPORTED			1
59 #define MONO_ARCH_HAVE_CONTEXT_SET_INT_REG		1
60 #define MONO_ARCH_USE_SIGACTION 			1
61 #define MONO_ARCH_GC_MAPS_SUPPORTED			1
62 #define MONO_ARCH_GSHARED_SUPPORTED			1
63 #define MONO_ARCH_MONITOR_ENTER_ADJUSTMENT		1
64 #define MONO_ARCH_HAVE_INVALIDATE_METHOD		1
65 #define MONO_ARCH_HAVE_OP_GENERIC_CLASS_INIT		1
66 #define MONO_ARCH_HAVE_SETUP_ASYNC_CALLBACK		1
67 
68 #define S390_STACK_ALIGNMENT		 8
69 #define S390_FIRST_ARG_REG 		s390_r2
70 #define S390_LAST_ARG_REG 		s390_r6
71 #define S390_FIRST_FPARG_REG 		s390_f0
72 #define S390_LAST_FPARG_REG 		s390_f6
73 
74 /*===============================================*/
75 /* Definitions used by mini-codegen.c            */
76 /*===============================================*/
77 
78 /*------------------------------------------------------*/
79 /* use s390_r2-s390_r6 as parm registers                */
80 /* s390_r0, s390_r1, s390_r12, s390_r13 used internally */
81 /* s390_r8..s390_r10 are used for global regalloc       */
82 /* -- except for s390_r9 which is used as IMT pointer   */
83 /* s390_r11 is sometimes used as the frame pointer      */
84 /* s390_r15 is the stack pointer                        */
85 /*------------------------------------------------------*/
86 
87 #define MONO_ARCH_CALLEE_REGS (0x00fc)
88 
89 #define MONO_ARCH_CALLEE_SAVED_REGS 0xfd00
90 
91 /*----------------------------------------*/
92 /* use s390_f1/s390_f3-s390_f15 as temps  */
93 /*----------------------------------------*/
94 
95 #define MONO_ARCH_CALLEE_FREGS (0xfffe)
96 
97 #define MONO_ARCH_CALLEE_SAVED_FREGS 0
98 
99 #define MONO_ARCH_USE_FPSTACK FALSE
100 #define MONO_ARCH_FPSTACK_SIZE 0
101 
102 #define MONO_ARCH_INST_FIXED_REG(desc) ((desc == 'o') ? s390_r2 : 		\
103 					((desc == 'g') ? s390_f0 : 		\
104 					((desc == 'A') ? S390_FIRST_ARG_REG : -1)))
105 
106 #define MONO_ARCH_INST_IS_FLOAT(desc)  ((desc == 'f') || (desc == 'g'))
107 
108 #define MONO_ARCH_INST_SREG2_MASK(ins) (0)
109 
110 #define MONO_ARCH_INST_IS_REGPAIR(desc) (0)
111 #define MONO_ARCH_INST_REGPAIR_REG2(desc,hr) -1
112 
113 #define MONO_ARCH_IS_GLOBAL_IREG(reg) 0
114 
115 #define MONO_ARCH_FRAME_ALIGNMENT 8
116 #define MONO_ARCH_CODE_ALIGNMENT 32
117 
118 /*-----------------------------------------------*/
119 /* SIMD Related Definitions                      */
120 /*-----------------------------------------------*/
121 
122 #define MONO_MAX_XREGS			31
123 #define MONO_ARCH_CALLEE_XREGS		0x0
124 #define MONO_ARCH_CALLEE_SAVED_XREGS	0x0
125 
126 /*-----------------------------------------------*/
127 /* Macros used to generate instructions          */
128 /*-----------------------------------------------*/
129 #define S390_OFFSET(b, t)	(guchar *) ((guint64) (b) - (guint64) (t))
130 #define S390_RELATIVE(b, t)     (guchar *) ((((guint64) (b) - (guint64) (t))) / 2)
131 
132 #define CODEPTR(c, o) (o) = (short *) ((guint64) c - 2)
133 #define PTRSLOT(c, o) *(o) = (short) ((guint64) c - (guint64) (o) + 2)/2
134 
135 #define S390_CC_EQ			8
136 #define S390_ALIGN(v, a)	(((a) > 0 ? (((v) + ((a) - 1)) & ~((a) - 1)) : (v)))
137 
138 #define MONO_INIT_CONTEXT_FROM_FUNC(ctx,func) do {			\
139 		MonoS390StackFrame *sframe;				\
140 		__asm__ volatile("lgr   %0,15" : "=r" (sframe));	\
141 		MONO_CONTEXT_SET_BP ((ctx), sframe->prev);		\
142 		MONO_CONTEXT_SET_SP ((ctx), sframe->prev);		\
143 		MONO_CONTEXT_SET_IP ((ctx), func);			\
144 	} while (0)
145 
146 #define MONO_ARCH_INIT_TOP_LMF_ENTRY(lmf) do { (lmf)->ebp = -1; } while (0)
147 
148 /*------------------------------------------------------------------*/
149 /*                                                                  */
150 /* Name		- s390_patch_rel                                    */
151 /*                                                                  */
152 /* Function	- Patch the code with a given offset. 		    */
153 /*                                                                  */
154 /*------------------------------------------------------------------*/
155 
156 static void inline
s390_patch_rel(guchar * code,guint64 target)157 s390_patch_rel (guchar *code, guint64 target)
158 {
159 	guint32 *offset = (guint32 *) code;
160 
161 	if (target != 0) {
162 		*offset = (guint32) target;
163 	}
164 }
165 
166 /*========================= End of Function ========================*/
167 
168 /*------------------------------------------------------------------*/
169 /*                                                                  */
170 /* Name		- s390_patch_addr                                   */
171 /*                                                                  */
172 /* Function	- Patch the code with a given address.		    */
173 /*                                                                  */
174 /*------------------------------------------------------------------*/
175 
176 static void inline
s390_patch_addr(guchar * code,guint64 target)177 s390_patch_addr (guchar *code, guint64 target)
178 {
179 	guint64 *offset = (guint64 *) code;
180 
181 	if (target != 0) {
182 		*offset = target;
183 	}
184 }
185 
186 /*========================= End of Function ========================*/
187 
188 /*------------------------------------------------------------------*/
189 /*                                                                  */
190 /* Name		- restoreLMF                                        */
191 /*                                                                  */
192 /* Function	- Restore the LMF state prior to exiting a method.  */
193 /*                                                                  */
194 /*------------------------------------------------------------------*/
195 
196 #define restoreLMF(code, frame_reg, stack_usage) do			\
197 {									\
198 	int lmfOffset = 0;						\
199 									\
200 	s390_lgr (code, s390_r13, frame_reg);				\
201 									\
202 	lmfOffset = stack_usage -  sizeof(MonoLMF);			\
203 									\
204 	/*-------------------------------------------------*/		\
205 	/* r13 = my lmf					   */		\
206 	/*-------------------------------------------------*/		\
207 	s390_aghi (code, s390_r13, lmfOffset);				\
208 									\
209 	/*-------------------------------------------------*/		\
210 	/* r6 = &jit_tls->lmf				   */		\
211 	/*-------------------------------------------------*/		\
212 	s390_lg  (code, s390_r6, 0, s390_r13, 				\
213 		  G_STRUCT_OFFSET(MonoLMF, lmf_addr));			\
214 									\
215 	/*-------------------------------------------------*/		\
216 	/* r0 = lmf.previous_lmf			   */		\
217 	/*-------------------------------------------------*/		\
218 	s390_lg  (code, s390_r0, 0, s390_r13, 				\
219 		  G_STRUCT_OFFSET(MonoLMF, previous_lmf));		\
220 									\
221 	/*-------------------------------------------------*/		\
222 	/* jit_tls->lmf = previous_lmf			   */		\
223 	/*-------------------------------------------------*/		\
224 	s390_lg  (code, s390_r13, 0, s390_r6, 0);			\
225 	s390_stg (code, s390_r0, 0, s390_r6, 0);			\
226 } while (0)
227 
228 /*========================= End of Function ========================*/
229 
230 #endif /* __MONO_MINI_S390X_H__ */
231