2 Copyright (C) 2001 Radek Doulik
10 #define FLOAT_REGS 2 /* No. float registers for parms */
11 #define GENERAL_REGS 5 /* No. general registers for parms */
13 #define ARG_BASE s390_r10 /* Register for addressing arguments*/
15 (i*(sizeof(stackval))) /* Displacement of ith argument */
17 #define MINV_POS 96 /* MonoInvocation stack offset */
18 #define STACK_POS (MINV_POS - sizeof (stackval) * sig->param_count)
20 #define TYPE_OFFSET (G_STRUCT_OFFSET (stackval, type))
22 #define MIN_CACHE_LINE 256
24 /*------------------------------------------------------------------*/
25 /* Sequence to add an int/long long to parameters to stack_from_data*/
26 /*------------------------------------------------------------------*/
27 #define ADD_ISTACK_PARM(r, i) \
28 if (reg_param < GENERAL_REGS-(r)) { \
29 s390_la (p, s390_r4, 0, STK_BASE, \
30 local_start + (reg_param - this_flag) * sizeof(long)); \
33 s390_la (p, s390_r4, 0, STK_BASE, \
34 sz.stack_size + MINV_POS + stack_param * sizeof(long)); \
38 /*------------------------------------------------------------------*/
39 /* Sequence to add a float/double to parameters to stack_from_data */
40 /*------------------------------------------------------------------*/
41 #define ADD_RSTACK_PARM(i) \
42 if (fpr_param < FLOAT_REGS) { \
43 s390_la (p, s390_r4, 0, STK_BASE, \
44 float_pos + (fpr_param * sizeof(float) * (i))); \
47 stack_param += (stack_param % (i)); \
48 s390_la (p, s390_r4, 0, STK_BASE, \
49 sz.stack_size + MINV_POS + stack_param * sizeof(float) * (i)); \
53 /*------------------------------------------------------------------*/
54 /* Sequence to add a structure ptr to parameters to stack_from_data */
55 /*------------------------------------------------------------------*/
56 #define ADD_TSTACK_PARM \
57 if (reg_param < GENERAL_REGS) { \
58 s390_l (p, s390_r4, 0, STK_BASE, \
59 local_start + (reg_param - this_flag) * sizeof(long)); \
62 s390_l (p, s390_r4, 0, STK_BASE, \
63 sz.stack_size + MINV_POS + stack_param * sizeof(long)); \
67 #define ADD_PSTACK_PARM(r, i) \
68 if (reg_param < GENERAL_REGS-(r)) { \
69 s390_la (p, s390_r4, 0, STK_BASE, \
70 local_start + (reg_param - this_flag) * sizeof(long)); \
73 s390_l (p, s390_r4, 0, STK_BASE, \
74 sz.stack_size + MINV_POS + stack_param * sizeof(long)); \
117 } S390SpecialRegister;
119 #define s390_is_imm16(val) ((gint)val >= (gint)-(1<<15) && \
120 (gint)val <= (gint)((1<<15)-1))
121 #define s390_is_uimm16(val) ((gint)val >= 0 && (gint)val <= 65535)
122 #define s390_is_imm12(val) ((gint)val >= (gint)-(1<<11) && \
123 (gint)val <= (gint)((1<<15)-1))
124 #define s390_is_uimm12(val) ((gint)val >= 0 && (gint)val <= 4095)
126 #define STK_BASE s390_r15
127 #define S390_MINIMAL_STACK_SIZE 96
128 #define S390_REG_SAVE_OFFSET 24
129 #define S390_RET_ADDR_OFFSET 56
136 #define S390_CC_GE 11
137 #define S390_CC_LE 13
139 #define S390_CC_NO 14
141 #define S390_CC_NC 12
142 #define S390_CC_UN 15
144 #define s390_word(addr, value) do {*((guint32 *) addr) = (guint32) (value); \
145 ((guint32 *) addr)++;} while (0)
146 #define s390_float(addr, value) do {*((guint32 *) addr) = (guint32) (value); \
147 ((guint32 *) addr)++;} while (0)
148 #define s390_llong(addr, value) do {*((guint64 *) addr) = (guint64) (value); \
149 ((guint64 *) addr)++;} while (0)
150 #define s390_double(addr, value) do {*((guint64 *) addr) = (guint64) (value); \
151 ((guint64 *) addr)++;} while (0)
152 #define s390_emit16(c, x) do {*((guint16 *) c) = x; ((guint16 *) c)++;} while(0)
153 #define s390_emit32(c, x) do {*((guint32 *) c) = x; ((guint32 *) c)++;} while(0)
154 #define s390_basr(code, r1, r2) s390_emit16 (code, (13 << 8 | (r1) << 4 | (r2)))
155 #define s390_bras(code, r, o) s390_emit32 (code, (167 << 24 | (r) << 20 | 5 << 16 | (o)))
156 #define s390_brasl(code, r, o) do {s390_emit16 (code, (192 << 8 | (r) << 4 | 5)); \
157 s390_emit32 (code, (o));} while(0)
158 #define s390_ahi(code, r, v) s390_emit32 (code, (167 << 24 | (r) << 20 | 10 << 16 | ((v) & 0xffff)))
159 #define s390_alcr(code, r1, r2) s390_emit32 (code, (185 << 24 | 152 << 16 | (r1) << 4 | (r2)))
160 #define s390_ar(code, r1, r2) s390_emit16 (code, (26 << 8 | (r1) << 4 | (r2)))
161 #define s390_alr(code, r1, r2) s390_emit16 (code, (30 << 8 | (r1) << 4 | (r2)))
162 #define s390_a(code, r, x, b, d) s390_emit32 (code, (90 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
163 #define s390_al(code, r, x, b, d) s390_emit32 (code, (94 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
164 #define s390_slbr(code, r1, r2) s390_emit32 (code, (185 << 24 | 153 << 16 | (r1) << 4 | (r2)))
165 #define s390_sr(code, r1, r2) s390_emit16 (code, (27 << 8 | (r1) << 4 | (r2)))
166 #define s390_slr(code, r1, r2) s390_emit16 (code, (31 << 8 | (r1) << 4 | (r2)))
167 #define s390_s(code, r, x, b, d) s390_emit32 (code, (91 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
168 #define s390_sl(code, r, x, b, d) s390_emit32 (code, (95 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
169 #define s390_mr(code, r1, r2) s390_emit16 (code, (28 << 8 | (r1) << 4 | (r2)))
170 #define s390_m(code, r, x, b, d) s390_emit32 (code, (92 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
171 #define s390_msr(code, r1, r2) s390_emit32 (code, (178 << 24 | 82 << 16 | (r1) << 4| (r2)))
172 #define s390_ms(code, r, x, b, d) s390_emit32 (code, (113 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
173 #define s390_mlr(code, r1, r2) s390_emit32 (code, (185 << 24 | 150 << 16 | (r1) << 4| (r2)))
174 #define s390_dr(code, r1, r2) s390_emit16 (code, (29 << 8 | (r1) << 4 | (r2)))
175 #define s390_d(code, r, x, b, d) s390_emit32 (code, (93 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
176 #define s390_dlr(code, r1, r2) s390_emit32 (code, (185 << 24 | 151 << 16 | (r1) << 4| (r2)))
177 #define s390_br(code, r) s390_emit16 (code, (7 << 8 | 15 << 4 | (r)))
178 #define s390_nr(code, r1, r2) s390_emit16 (code, (20 << 8 | (r1) << 4 | (r2)))
179 #define s390_n(code, r, x, b, d) s390_emit32 (code, (84 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
180 #define s390_or(code, r1, r2) s390_emit16 (code, (22 << 8 | (r1) << 4 | (r2)))
181 #define s390_o(code, r, x, b, d) s390_emit32 (code, (86 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
182 #define s390_xr(code, r1, r2) s390_emit16 (code, (23 << 8 | (r1) << 4 | (r2)))
183 #define s390_x(code, r, x, b, d) s390_emit32 (code, (87 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
184 #define s390_lr(code, r1, r2) s390_emit16 (code, (24 << 8 | (r1) << 4 | (r2)))
185 #define s390_ltr(code, r1, r2) s390_emit16 (code, (18 << 8 | (r1) << 4 | (r2)))
186 #define s390_l(code, r, x, b, d) s390_emit32 (code, (88 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
187 #define s390_lcr(code, r1, r2) s390_emit16 (code, (19 << 8 | (r1) << 4 | (r2)))
188 #define s390_lnr(code, r1, r2) s390_emit16 (code, (17 << 8 | (r1) << 4 | (r2)))
189 #define s390_lpr(code, r1, r2) s390_emit16 (code, (16 << 8 | (r1) << 4 | (r2)))
190 #define s390_lm(code, r1, r2, b, d) s390_emit32 (code, (152 << 24 | (r1) << 20 | (r2) << 16 \
191 | (b) << 12 | ((d) & 0xfff)))
192 #define s390_lh(code, r, x, b, d) s390_emit32 (code, (72 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
193 #define s390_lhi(code, r, v) s390_emit32 (code, (167 << 24 | (r) << 20 | 8 << 16 | ((v) & 0xffff)))
194 #define s390_ic(code, r, x, b, d) s390_emit32 (code, (67 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
195 #define s390_icm(code, r, m, b, d) s390_emit32 (code, (191 << 24 | (r) << 20 | (m) << 16 | (b) << 12 | ((d) & 0xfff)))
196 #define s390_st(code, r, x, b, d) s390_emit32 (code, (80 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
197 #define s390_stm(code, r1, r2, b, d) s390_emit32 (code, (144 << 24 | (r1) << 20 | (r2) << 16 \
198 | (b) << 12 | ((d) & 0xfff)))
199 #define s390_stam(c, r1, r2, b, d) s390_emit32 (code, (155 << 24 | (r1) << 20 | (r2) << 16 \
200 | (b) << 12 | ((d) & 0xfff)))
201 #define s390_lam(c, r1, r2, b, d) s390_emit32 (code, (154 << 24 | (r1) << 20 | (r2) << 16 \
202 | (b) << 12 | ((d) & 0xfff)))
203 #define s390_sth(code, r, x, b, d) s390_emit32 (code, (64 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
204 #define s390_stc(code, r, x, b, d) s390_emit32 (code, (66 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
205 #define s390_stcm(code, r, m, b, d) s390_emit32 (code, (190 << 24 | (r) << 20 | (m) << 16 | (b) << 12 | ((d) & 0xfff)))
206 #define s390_la(code, r, x, b, d) s390_emit32 (code, (65 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
207 #define s390_larl(code, r, o) do { \
208 s390_emit16 (code, (192 << 8 | (r) << 4)); \
209 s390_emit32 (code, (o)); \
211 #define s390_ld(code, f, x, b, d) s390_emit32 (code, (104 << 24 | (f) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
212 #define s390_le(code, f, x, b, d) s390_emit32 (code, (120 << 24 | (f) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
213 #define s390_std(code, f, x, b, d) s390_emit32 (code, (96 << 24 | (f) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
214 #define s390_ste(code, f, x, b, d) s390_emit32 (code, (112 << 24 | (f) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
215 #define s390_mvc(c, l, b1, d1, b2, d2) do {s390_emit32 (c, (210 << 24 | ((((l)-1) << 16) & 0x00ff0000) | \
216 (b1) << 12 | ((d1) & 0xfff))); \
217 s390_emit16 (c, ((b2) << 12 | ((d2) & 0xfff)));} while (0)
218 #define s390_mvcl(c, r1, r2) s390_emit16 (c, (14 << 8 | (r1) << 4 | (r2)))
219 #define s390_break(c) s390_emit16 (c, 0)
220 #define s390_nill(c, r1, v) s390_emit32 (c, (165 << 24 | (r1) << 20 | 7 << 16 | ((v) & 0xffff)))
221 #define s390_nilh(c, r1, v) s390_emit32 (c, (165 << 24 | (r1) << 20 | 6 << 16 | ((v) & 0xffff)))
222 #define s390_brc(c, m, d) s390_emit32 (c, (167 << 24 | ((m) & 0xff) << 20 | 4 << 16 | ((d) & 0xffff)))
223 #define s390_cr(c, r1, r2) s390_emit16 (c, (25 << 8 | (r1) << 4 | (r2)))
224 #define s390_clr(c, r1, r2) s390_emit16 (c, (21 << 8 | (r1) << 4 | (r2)))
225 #define s390_c(c, r, x, b, d) s390_emit32 (c, (89 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
226 #define s390_cl(c, r, x, b, d) s390_emit32 (c, (85 << 24 | (r) << 20 | (x) << 16 | (b) << 12 | ((d) & 0xfff)))
227 #define s390_j(c,d) s390_brc(c, S390_CC_UN, d)
228 #define s390_je(c, d) s390_brc(c, S390_CC_EQ, d)
229 #define s390_jeo(c, d) s390_brc(c, S390_CC_ZR|S390_CC_OV, d)
230 #define s390_jz(c, d) s390_brc(c, S390_CC_ZR, d)
231 #define s390_jnz(c, d) s390_brc(c, S390_CC_NZ, d)
232 #define s390_jne(c, d) s390_brc(c, S390_CC_NZ, d)
233 #define s390_jp(c, d) s390_brc(c, S390_CC_GT, d)
234 #define s390_jm(c, d) s390_brc(c, S390_CC_LT, d)
235 #define s390_jh(c, d) s390_brc(c, S390_CC_GT, d)
236 #define s390_jl(c, d) s390_brc(c, S390_CC_LT, d)
237 #define s390_jnh(c, d) s390_brc(c, S390_CC_LE, d)
238 #define s390_jo(c, d) s390_brc(c, S390_CC_OV, d)
239 #define s390_jnl(c, d) s390_brc(c, S390_CC_GE, d)
240 #define s390_jlo(c, d) s390_brc(c, S390_CC_LT|S390_CC_OV, d)
241 #define s390_jho(c, d) s390_brc(c, S390_CC_GT|S390_CC_OV, d)
242 #define s390_jc(c, m, d) s390_brc(c, m, d)
243 #define s390_jcl(c, m, d) do {s390_emit16 (c, (192 << 8 | (m) << 4 | 4)); \
244 s390_emit32 (c, (d));} while(0)
245 #define s390_slda(c, r, b, d) s390_emit32 (c, (143 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
246 #define s390_sldl(c, r, b, d) s390_emit32 (c, (141 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
247 #define s390_srda(c, r, b, d) s390_emit32 (c, (142 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
248 #define s390_srdl(c, r, b, d) s390_emit32 (c, (140 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
249 #define s390_sla(c, r, b, d) s390_emit32 (c, (139 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
250 #define s390_sll(c, r, b, d) s390_emit32 (c, (137 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
251 #define s390_sra(c, r, b, d) s390_emit32 (c, (138 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
252 #define s390_srl(c, r, b, d) s390_emit32 (c, (136 << 24 | (r) << 20 | (b) << 12 | ((d) & 0xfff)))
253 #define s390_sqdbr(c, r1, r2) s390_emit32 (c, (179 << 24 | 21 << 16 | ((r1) << 4) | (r2)))
254 #define s390_sqebr(c, r1, r2) s390_emit32 (c, (179 << 24 | 20 << 16 | ((r1) << 4) | (r2)))
255 #define s390_adbr(c, r1, r2) s390_emit32 (c, (179 << 24 | 26 << 16 | ((r1) << 4) | (r2)))
256 #define s390_aebr(c, r1, r2) s390_emit32 (c, (179 << 24 | 10 << 16 | ((r1) << 4) | (r2)))
257 #define s390_adb(c, r, x, b, d) do {s390_emit32 (c, (237 << 24 | (r) << 20 | \
258 (x) << 16 | (b) << 12 | ((d) & 0xfff))); \
259 s390_emit16 (c, (26)); \
261 #define s390_sdbr(c, r1, r2) s390_emit32 (c, (179 << 24 | 27 << 16 | ((r1) << 4) | (r2)))
262 #define s390_sdb(c, r, x, b, d) do {s390_emit32 (c, (237 << 24 | (r) << 20 | \
263 (x) << 16 | (b) << 12 | ((d) & 0xfff))); \
264 s390_emit16 (c, (27)); \
266 #define s390_sebr(c, r1, r2) s390_emit32 (c, (179 << 24 | 11 << 16 | ((r1) << 4) | (r2)))
267 #define s390_mdbr(c, r1, r2) s390_emit32 (c, (179 << 24 | 28 << 16 | ((r1) << 4) | (r2)))
268 #define s390_meebr(c, r1, r2) s390_emit32 (c, (179 << 24 | 23 << 16 | ((r1) << 4) | (r2)))
269 #define s390_ldr(c, r1, r2) s390_emit16 (c, (40 << 8 | (r1) << 4 | (r2)))
270 #define s390_ler(c, r1, r2) s390_emit16 (c, (56 << 8 | (r1) << 4 | (r2)))
271 #define s390_lzdr(c, r1) s390_emit32 (c, (179 << 24 | 117 << 16 | (r1) << 4))
272 #define s390_lzer(c, r1) s390_emit32 (c, (179 << 24 | 116 << 16 | (r1) << 4))
273 #define s390_ddbr(c, r1, r2) s390_emit32 (c, (179 << 24 | 29 << 16 | ((r1) << 4) | (r2)))
274 #define s390_debr(c, r1, r2) s390_emit32 (c, (179 << 24 | 13 << 16 | ((r1) << 4) | (r2)))
275 #define s390_didbr(c, r1, r2, m, r3) s390_emit32 (c, (179 << 24 | 91 << 16 | ((r3) << 12) | ((m) << 8) | ((r1) << 4) | (r2)))
276 #define s390_lcdbr(c, r1, r2) s390_emit32 (c, (179 << 24 | 19 << 16 | ((r1) << 4) | (r2)))
277 #define s390_lndbr(c, r1, r2) s390_emit32 (c, (179 << 24 | 17 << 16 | ((r1) << 4) | (r2)))
278 #define s390_ldebr(c, r1, r2) s390_emit32 (c, (179 << 24 | 4 << 16 | ((r1) << 4) | (r2)))
279 #define s390_lnebr(c, r1, r2) s390_emit32 (c, (179 << 24 | 1 << 16 | ((r1) << 4) | (r2)))
280 #define s390_ledbr(c, r1, r2) s390_emit32 (c, (179 << 24 | 68 << 16 | ((r1) << 4) | (r2)))
281 #define s390_cfdbr(c, r1, m, f2) s390_emit32 (c, (179 << 24 | 153 << 16 | (m) << 8 | (r1) << 4 | (f2)))
282 #define s390_cdfbr(c, r1, r2) s390_emit32 (c, (179 << 24 | 149 << 16 | (r1) << 4 | (r2)))
283 #define s390_cefbr(c, r1, r2) s390_emit32 (c, (179 << 24 | 148 << 16 | (r1) << 4 | (r2)))
284 #define s390_cdbr(c, r1, r2) s390_emit32 (c, (179 << 24 | 25 << 16 | (r1) << 4 | (r2)))
285 #define s390_cebr(c, r1, r2) s390_emit32 (c, (179 << 24 | 9 << 16 | (r1) << 4 | (r2)))
286 #define s390_cdb(c, r, x, b, d) do {s390_emit32 (c, (237 << 24 | (r) << 20 | \
287 (x) << 16 | (b) << 12 | ((d) & 0xfff))); \
288 s390_emit16 (c, (25)); \
290 #define s390_tcdb(c, r, x, b, d) do {s390_emit32 (c, (237 << 24 | (r) << 20 | \
291 (x) << 16 | (b) << 12 | ((d) & 0xfff))); \
292 s390_emit16 (c, (17)); \
294 #define s390_tedb(c, r, x, b, d) do {s390_emit32 (c, (237 << 24 | (r) << 20 | \
295 (x) << 16 | (b) << 12 | ((d) & 0xfff))); \
296 s390_emit16 (c, (16)); \
298 #define s390_stfpc(c, b, d) s390_emit32 (c, (178 << 24 | 156 << 16 | \
299 (b) << 12 | ((d) & 0xfff)))