Changed header file usage (abcremoval.h).
[mono.git] / mono / mini / inssel-s390.brg
1 %%
2
3 #
4 # inssel-s390.brg: burg file for special s390 instructions
5 #
6 # Author:
7 #   Neale Ferguson (Neale.Ferguson@SoftwareAG-usa.com)
8 #   Dietmar Maurer (dietmar@ximian.com)
9 #   Paolo Molaro (lupus@ximian.com)
10 #
11 # (C) 2002 Ximian, Inc.
12 #
13
14 stmt: OP_START_HANDLER {
15         MonoInst *spvar = mono_find_spvar_for_region (s, s->cbb->region);
16         tree->inst_left = spvar;
17         mono_bblock_add_inst (s->cbb, tree);
18 }
19
20 stmt: CEE_ENDFINALLY {
21         MonoInst *spvar = mono_find_spvar_for_region (s, s->cbb->region);
22         tree->inst_left = spvar;
23         mono_bblock_add_inst (s->cbb, tree);
24 }
25
26 stmt: OP_ENDFILTER (reg) {
27         MonoInst *spvar = mono_find_spvar_for_region (s, s->cbb->region);
28         tree->inst_left = spvar;
29         tree->sreg1 = state->left->reg1;
30         mono_bblock_add_inst (s->cbb, tree);
31 }
32
33 stmt: CEE_STIND_I8 (OP_REGVAR, lreg) {
34         /* this should only happen for methods returning a long */
35         MONO_EMIT_NEW_UNALU (s, OP_MOVE, s390_r2, state->right->reg1);
36         MONO_EMIT_NEW_UNALU (s, OP_MOVE, s390_r3, state->right->reg2);
37 }
38
39 freg: OP_LCONV_TO_R8 (lreg) {
40         mono_bblock_add_inst (s->cbb, tree);
41 }
42
43 freg: OP_LCONV_TO_R4 (lreg) {
44         mono_bblock_add_inst (s->cbb, tree);
45 }
46
47 freg: CEE_CONV_R_UN (reg) {
48         mono_bblock_add_inst (s->cbb, tree);
49 }
50
51 reg: OP_LOCALLOC (OP_ICONST) {
52         /* microcoded in mini-s390.c */
53         tree->sreg1 = mono_regstate_next_int (s->rs);
54         tree->dreg  = state->reg1;
55         MONO_EMIT_NEW_ICONST (s, tree->sreg1, state->left->tree->inst_c0);
56         mono_bblock_add_inst (s->cbb, tree);
57 }
58
59 reg: OP_LOCALLOC (reg) {
60         tree->dreg = state->reg1;
61         tree->sreg1 = state->left->reg1;
62         mono_bblock_add_inst (s->cbb, tree);
63 }
64
65 stmt: OP_SETRET (reg) {
66         tree->opcode = OP_MOVE;
67         tree->sreg1 = state->left->reg1;
68         tree->dreg = s390_r2;
69         mono_bblock_add_inst (s->cbb, tree);
70 }
71
72 stmt: OP_SETRET (lreg) {
73         tree->opcode = OP_SETLRET;
74         tree->sreg1 = state->left->reg1;
75         tree->sreg2 = state->left->reg2;
76         mono_bblock_add_inst (s->cbb, tree);
77 }
78
79 stmt: OP_SETRET (freg) {
80         tree->opcode = OP_FMOVE;
81         tree->sreg1 = state->left->reg1;
82         tree->dreg = s390_f0;
83         mono_bblock_add_inst (s->cbb, tree);
84 }
85
86 stmt: OP_SETRET (OP_ICONST) {
87         tree->opcode = OP_ICONST;
88         tree->inst_c0 = state->left->tree->inst_c0;
89         tree->dreg = s390_r2;
90         mono_bblock_add_inst (s->cbb, tree);
91 }
92
93 stmt: OP_OUTARG (reg) {
94         if (tree->inst_imm) {
95                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1);
96                 return;
97         }
98         tree->opcode = OP_SETREG;
99         tree->dreg = tree->unused;
100         tree->sreg1 = state->left->reg1;
101         mono_bblock_add_inst (s->cbb, tree);
102 }
103
104 stmt: OP_OUTARG (OP_REGVAR) {
105         if (tree->inst_imm) {
106                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->tree->dreg);
107                 return;
108         }
109         tree->opcode = OP_SETREG;
110         tree->dreg = tree->unused;
111         tree->sreg1 = state->left->tree->dreg;
112         mono_bblock_add_inst (s->cbb, tree);
113 }
114
115 stmt: OP_OUTARG (lreg) {
116         if (tree->inst_imm) {
117                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg2);
118                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm + 4, state->left->reg1);
119                 return;
120         }
121         MONO_EMIT_NEW_UNALU (s, OP_SETREG, tree->unused, state->left->reg2);
122         tree->opcode = OP_SETREG;
123         tree->dreg = tree->unused + 1;
124         tree->sreg1 = state->left->reg1;
125         mono_bblock_add_inst (s->cbb, tree);
126 }
127
128 stmt: OP_OUTARG (OP_ICONST) {
129         if (tree->inst_imm) {
130                 MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STORE_MEMBASE_IMM, s->frame_reg, tree->inst_imm, state->left->tree->inst_c0);
131                 return;
132         }
133         tree->opcode = OP_SETREGIMM;
134         tree->dreg = tree->unused;
135         tree->inst_c0 = state->left->tree->inst_c0;
136         mono_bblock_add_inst (s->cbb, tree);
137 }
138
139 stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)) {
140         if (tree->inst_imm) {
141                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->left->tree->dreg);
142                 return;
143         }
144         tree->opcode = OP_SETREG;
145         tree->sreg1 = state->left->left->tree->dreg;
146         tree->dreg = tree->unused;
147         mono_bblock_add_inst (s->cbb, tree);
148 }
149
150 stmt: OP_OUTARG (freg) {
151         if (tree->inst_imm) {
152                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1);
153                 return;
154         }
155         tree->opcode = OP_SETFREG;
156         tree->sreg1 = state->left->reg1;
157         tree->dreg = tree->unused;
158         mono_bblock_add_inst (s->cbb, tree);
159 }
160
161 stmt: OP_OUTARG_R4 (freg) {
162         if (tree->inst_imm) {
163                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1);
164                 return;
165         }
166         tree->opcode = OP_SETFREG;
167         tree->sreg1 = state->left->reg1;
168         tree->dreg = tree->unused;
169         mono_bblock_add_inst (s->cbb, tree);
170 }
171
172 stmt: OP_OUTARG_R8 (freg) {
173         if (tree->inst_imm) {
174                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, s->frame_reg, tree->inst_imm, state->left->reg1);
175                 return;
176         }
177         tree->opcode = OP_SETFREG;
178         tree->sreg1 = state->left->reg1;
179         tree->dreg = tree->unused;
180         mono_bblock_add_inst (s->cbb, tree);
181 }
182
183 stmt: OP_OUTARG_VT (CEE_LDOBJ (base)) {
184         MonoInst *vt  = state->left->left->tree;
185         int start_reg = tree->sreg2;
186         int size      = tree->unused;
187         int nregs     = size / 4;
188         int soffset   = vt->inst_offset;
189         int i, tmpr;
190         if (size < 0) { 
191                 size = -size;
192                 mini_emit_memcpy (s, s->frame_reg, tree->inst_imm,
193                                   vt->inst_basereg, soffset, size, 0);
194                 if (start_reg != STK_BASE) {
195                         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, start_reg, 
196                                                  s->frame_reg, tree->sreg1);
197                 }
198         } else {
199                 if (start_reg != STK_BASE) {
200                         for (i = 0; i < nregs; ++i) {
201                                 tmpr = mono_regstate_next_int (s->rs);
202                                 MONO_EMIT_NEW_LOAD_MEMBASE (s, tmpr, vt->inst_basereg, 
203                                                             soffset);
204                                 MONO_EMIT_NEW_UNALU (s, OP_SETREG, start_reg + i, tmpr);
205                                 soffset += sizeof (gpointer);
206                         }
207                 } else {
208                         mini_emit_memcpy (s, s->frame_reg, tree->inst_imm, 
209                                           vt->inst_basereg, soffset, size, 0);
210                 }       
211         }
212 }
213
214 stmt: OP_OUTARG_VT (OP_ICONST) {
215         int start_reg = tree->sreg2;
216         int size      = tree->unused;
217         int nregs     = size / 4;
218         int i;
219         if (start_reg != STK_BASE) {
220                 if (nregs) {
221                         tree->opcode  = OP_SETREGIMM;
222                         tree->dreg    = start_reg;
223                         tree->inst_c0 = state->left->tree->inst_c0;
224                         mono_bblock_add_inst (s->cbb, tree);
225                 }
226         } else {
227                 mini_emit_memcpy (s, s->frame_reg, tree->inst_c0, STK_BASE, 
228                                   tree->inst_offset, size, 0);
229         }
230 }
231
232 stmt: OP_OUTARG_VT (reg) {
233         int start_reg = tree->sreg2;
234         int size      = tree->unused;
235         int nregs     = size / 4;
236         int soffset   = tree->inst_imm;
237         int i;
238         if (start_reg != STK_BASE) {
239                 for (i = 0; i < nregs; ++i) {
240                         MONO_EMIT_NEW_LOAD_MEMBASE(s, start_reg, s->frame_reg, 
241                                                    tree->inst_offset);
242                         soffset += sizeof(gpointer);
243                 }
244         } else {
245                 int tmpr;
246                 tmpr = mono_regstate_next_int (s->rs);
247                 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg, 
248                                         s->stack_offset);
249                 mini_emit_memcpy (s, s->frame_reg, soffset, tmpr, 
250                                   tree->sreg1, size, 0);
251         }
252 }
253
254 stmt: CEE_STIND_R8 (OP_REGVAR, freg) {
255         /* nothing to do: the value is already on the FP stack */
256 }
257
258 stmt: CEE_BNE_UN (fpcflags) {
259         tree->opcode = OP_FBNE_UN;
260         mono_bblock_add_inst (s->cbb, tree);
261 }
262
263 stmt: CEE_BEQ (fpcflags) {
264         tree->opcode = OP_FBEQ;
265         mono_bblock_add_inst (s->cbb, tree);
266 }
267
268 stmt: CEE_BLT (fpcflags) {
269         tree->opcode = OP_FBLT;
270         mono_bblock_add_inst (s->cbb, tree);
271 }
272
273 stmt: CEE_BLT_UN (fpcflags) {
274         tree->opcode = OP_FBLT_UN;
275         mono_bblock_add_inst (s->cbb, tree);
276 }
277
278 stmt: CEE_BGT (fpcflags) {
279         tree->opcode = OP_FBGT;
280         mono_bblock_add_inst (s->cbb, tree);
281 }
282
283 stmt: CEE_BGT_UN (fpcflags) {
284         tree->opcode = OP_FBGT_UN;
285         mono_bblock_add_inst (s->cbb, tree);
286 }
287
288 stmt: CEE_BGE  (fpcflags) {
289         tree->opcode = OP_FBGE;
290         mono_bblock_add_inst (s->cbb, tree);
291 }
292
293 stmt: CEE_BGE_UN (fpcflags) {
294         tree->opcode = OP_FBGE_UN;
295         mono_bblock_add_inst (s->cbb, tree);
296 }
297
298 stmt: CEE_BLE  (fpcflags) {
299         tree->opcode = OP_FBLE;
300         mono_bblock_add_inst (s->cbb, tree);
301 }
302
303 stmt: CEE_BLE_UN (fpcflags) {
304         tree->opcode = OP_FBLE_UN;
305         mono_bblock_add_inst (s->cbb, tree);
306 }
307
308 stmt: CEE_POP (freg) "0" {
309         /* nothing to do */
310 }     
311
312 freg: OP_LCONV_TO_R8 (lreg) {
313         /* nothing to do - emulated */
314 }
315
316 freg: OP_LCONV_TO_R4 (lreg) {
317         /* nothing to do - emulated */
318 }
319
320 freg: OP_LCONV_TO_R_UN (lreg) {
321         /* nothing to do - emulated */
322 }
323
324 freg: OP_FREM (freg, freg) {
325         /* nothing to do - emulated */
326 }
327
328 reg: OP_CEQ (OP_COMPARE (freg, freg)) { 
329         MONO_EMIT_BIALU (s, tree, OP_FCEQ, state->reg1, state->left->left->reg1,
330                          state->left->right->reg1);
331 }
332
333 reg: OP_CLT (OP_COMPARE (freg, freg)) { 
334         MONO_EMIT_BIALU (s, tree, OP_FCLT, state->reg1, state->left->left->reg1,
335                          state->left->right->reg1);
336 }
337
338 reg: OP_CLT_UN (OP_COMPARE (freg, freg)) {      
339         MONO_EMIT_BIALU (s, tree, OP_FCLT_UN, state->reg1, state->left->left->reg1,
340                          state->left->right->reg1);
341 }
342
343 reg: OP_CGT (OP_COMPARE (freg, freg)) { 
344         MONO_EMIT_BIALU (s, tree, OP_FCGT, state->reg1, state->left->left->reg1,
345                          state->left->right->reg1);
346 }
347
348 reg: OP_CGT_UN (OP_COMPARE (freg, freg)) {      
349         MONO_EMIT_BIALU (s, tree, OP_FCGT_UN, state->reg1, state->left->left->reg1,
350                          state->left->right->reg1);
351 }
352
353 base: OP_REGOFFSET "0" {
354 }
355
356 base: OP_S390_STKARG "0" {
357         int tmpr;
358         tmpr = mono_regstate_next_int (s->rs);
359         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg, 
360                                 (s->stack_offset+state->tree->unused));
361         tree->inst_offset  = state->tree->inst_offset;
362         tree->inst_basereg = tmpr;
363 }
364
365 base: OP_LDADDR (OP_S390_LOADARG) "0" {
366         int tmpr;
367         tmpr = mono_regstate_next_int (s->rs);
368         MONO_EMIT_NEW_LOAD_MEMBASE (s, tmpr, s->frame_reg, 
369                                     state->left->tree->inst_offset);
370         tree->inst_offset  = 0;
371         tree->inst_basereg = tmpr;
372 }
373
374 base: OP_LDADDR (OP_S390_ARGPTR) "0" {
375         int tmpr;
376         tmpr = mono_regstate_next_int (s->rs);
377         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg, 
378                                  state->left->tree->inst_offset);
379         tree->inst_offset  = 0;
380         tree->inst_basereg = tmpr;
381 }
382
383 base: OP_LDADDR (OP_S390_STKARG) "0" {
384         int tmpr;
385         tmpr = mono_regstate_next_int (s->rs);
386         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg, 
387                                  (s->stack_offset + state->left->tree->unused));
388         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, tmpr, 
389                                  state->left->tree->inst_offset);
390         tree->inst_offset  = 0;
391         tree->inst_basereg = tmpr;
392 }
393
394 reg: OP_LDADDR (OP_S390_LOADARG) "2" {
395         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg, 
396                                  state->left->tree->inst_offset);
397         tree->inst_offset  = 0;
398         tree->inst_basereg = state->reg1;
399 }
400
401 reg: OP_LDADDR (OP_S390_ARGPTR) "2" {
402         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg, 
403                                  state->left->tree->inst_offset);
404         tree->inst_offset  = 0;
405         tree->inst_basereg = state->reg1;
406 }
407
408 reg: OP_LDADDR (OP_S390_STKARG) "2" {
409         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg, 
410                                  (s->stack_offset + state->left->tree->unused));
411         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->reg1, 
412                                  state->left->tree->inst_offset);
413         tree->inst_offset  = 0;
414         tree->inst_basereg = state->reg1;
415 }
416
417 reg: CEE_LDOBJ (OP_S390_LOADARG) "1" {
418         int tmpr;
419         tmpr = mono_regstate_next_int (s->rs);
420         MONO_EMIT_NEW_LOAD_MEMBASE (s, tmpr, s->frame_reg, 
421                                     state->left->tree->inst_offset);
422         tree->inst_offset  = 0;
423         tree->inst_basereg = tmpr;
424 }
425
426 reg: CEE_LDOBJ (OP_S390_ARGPTR) "1" {
427         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg, 
428                                  state->left->tree->inst_offset);
429         tree->inst_offset  = 0;
430         tree->inst_basereg = state->reg1;
431 }
432
433 reg: CEE_LDOBJ (OP_S390_STKARG) "1" {
434         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg,
435                                  (s->stack_offset + state->left->tree->unused));
436         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->reg1,
437                                  state->left->tree->inst_offset);
438         tree->inst_offset  = 0;
439         tree->inst_basereg = state->reg1;
440 }
441
442 base: CEE_LDOBJ (OP_S390_ARGPTR) "0" {
443         int tmpr;
444         tmpr = mono_regstate_next_int (s->rs);
445         MONO_EMIT_NEW_LOAD_MEMBASE (s, tmpr, s->frame_reg, 
446                                     state->left->tree->inst_offset);
447         tree->inst_offset  = 0;
448         tree->inst_basereg = tmpr;
449 }
450
451 base: CEE_LDOBJ (OP_S390_STKARG) "0" {
452         int tmpr;
453         tmpr = mono_regstate_next_int (s->rs);
454         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg,
455                                  (s->stack_offset + state->left->tree->unused));
456         MONO_EMIT_NEW_LOAD_MEMBASE (s, tmpr, tmpr, state->left->tree->inst_offset);
457         tree->inst_offset  = 0;
458         tree->inst_basereg = tmpr;
459 }
460
461 %%