imported everything from my branch (which is slightly harmless).
[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 lreg: OP_LADD_OVF (lreg, lreg) "0" {
34         /* ADC sets the condition code */
35         MONO_EMIT_NEW_BIALU (s, OP_ADDCC, state->reg1, state->left->reg1, state->right->reg1);
36         MONO_EMIT_NEW_BIALU (s, OP_ADD_OVF_CARRY, state->reg2, state->left->reg2, state->right->reg2);
37 }
38
39 lreg: OP_LADD_OVF_UN (lreg, lreg) "0" {
40         /* ADC sets the condition code */
41         MONO_EMIT_NEW_BIALU (s, OP_ADDCC, state->reg1, state->left->reg1, state->right->reg1);
42         MONO_EMIT_NEW_BIALU (s, OP_ADD_OVF_UN_CARRY, state->reg2, state->left->reg2, state->right->reg2);
43 }
44
45 lreg: OP_LSUB_OVF (lreg, lreg) "0" {
46         /* SBB sets the condition code */
47         MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1);
48         MONO_EMIT_NEW_BIALU (s, OP_SUB_OVF_CARRY, state->reg2, state->left->reg2, state->right->reg2);
49 }
50
51 lreg: OP_LSUB_OVF_UN (lreg, lreg) "0" {
52         /* SBB sets the condition code */
53         MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1);
54         MONO_EMIT_NEW_BIALU (s, OP_SUB_OVF_UN_CARRY, state->reg2, state->left->reg2, state->right->reg2);
55 }
56
57 reg: CEE_ADD_OVF (reg, reg) "0" {
58         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
59 }
60
61 reg: CEE_ADD_OVF_UN (reg, reg) "0" {
62         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
63 }
64
65 reg: CEE_SUB_OVF (reg, reg) "0" {
66         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
67 }
68
69 reg: CEE_SUB_OVF_UN (reg, reg) "0" {
70         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
71 }
72
73 stmt: CEE_STIND_I8 (OP_REGVAR, lreg) {
74         /*------------------------------------------------------*/
75         /* this should only happen for methods returning a long */
76         /* S/390 ABI uses r2/r3 for returning 64-bit integers   */
77         /*------------------------------------------------------*/
78         MONO_EMIT_NEW_UNALU (s, OP_MOVE, s390_r2, state->right->reg1);
79         MONO_EMIT_NEW_UNALU (s, OP_MOVE, s390_r3, state->right->reg2);
80 }
81
82 freg: OP_LCONV_TO_R8 (lreg) {
83         tree->dreg = state->reg1;
84         tree->sreg1 = state->left->reg1;
85         tree->sreg2 = state->left->reg2;
86         mono_bblock_add_inst (s->cbb, tree);
87 }
88
89 freg: OP_LCONV_TO_R4 (lreg) {
90         tree->dreg = state->reg1;
91         tree->sreg1 = state->left->reg1;
92         tree->sreg2 = state->left->reg2;
93         mono_bblock_add_inst (s->cbb, tree);
94 }
95
96 freg: CEE_CONV_R_UN (reg) {
97         tree->dreg = state->reg1;
98         tree->sreg1 = state->left->reg1;
99         mono_bblock_add_inst (s->cbb, tree);
100 }
101
102 freg: CEE_CONV_R_UN (reg) {
103         mono_bblock_add_inst (s->cbb, tree);
104 }
105
106 stmt: OP_MEMCPY (reg, reg) "0" {
107         int size = tree->unused;
108         if (size > 0) 
109                 MONO_EMIT_NEW_MOVE (s, state->left->reg1, 0, 
110                                     state->right->reg1, 0, size);
111 }
112
113 stmt: OP_MEMCPY (base, base) "0" {
114         int size = tree->unused;
115         if (size > 0)  
116                 MONO_EMIT_NEW_MOVE (s, state->left->tree->sreg1, 
117                                     state->left->tree->inst_offset, 
118                                     state->right->tree->sreg1,
119                                     state->right->tree->inst_offset,
120                                     size);
121 }
122
123 reg: OP_LOCALLOC (OP_ICONST) {
124         /* microcoded in mini-s390.c */
125         tree->sreg1 = mono_regstate_next_int (s->rs);
126         tree->dreg  = state->reg1;
127         MONO_EMIT_NEW_ICONST (s, tree->sreg1, state->left->tree->inst_c0);
128         mono_bblock_add_inst (s->cbb, tree);
129 }
130
131 reg: OP_LOCALLOC (reg) {
132         tree->dreg = state->reg1;
133         tree->sreg1 = state->left->reg1;
134         mono_bblock_add_inst (s->cbb, tree);
135 }
136
137 stmt: OP_SETRET (reg) {
138         tree->opcode = OP_MOVE;
139         tree->sreg1 = state->left->reg1;
140         tree->dreg = s390_r2;
141         mono_bblock_add_inst (s->cbb, tree);
142 }
143
144 stmt: OP_SETRET (lreg) {
145         tree->opcode = OP_SETLRET;
146         tree->sreg1 = state->left->reg1;
147         tree->sreg2 = state->left->reg2;
148         mono_bblock_add_inst (s->cbb, tree);
149 }
150
151 stmt: OP_SETRET (freg) {
152         if (mono_method_signature (s->method)->ret->type == MONO_TYPE_R4) {
153                 tree->opcode = OP_S390_SETF4RET;
154                 tree->sreg1  = state->left->reg1;
155                 tree->dreg   = s390_f0;
156         } else {
157                 tree->opcode = OP_FMOVE;
158                 tree->sreg1  = state->left->reg1;
159                 tree->dreg   = s390_f0;
160         }
161         mono_bblock_add_inst (s->cbb, tree);
162 }
163
164 stmt: OP_SETRET (OP_ICONST) {
165         tree->opcode = OP_ICONST;
166         tree->inst_c0 = state->left->tree->inst_c0;
167         tree->dreg = s390_r2;
168         mono_bblock_add_inst (s->cbb, tree);
169 }
170
171 lreg: OP_LSUB_OVF_UN (lreg, lreg) "0" {
172         /*----------------------------------------------------------------------*/
173         /* SBB sets the condition code - CC 0 or 1 indicates Borrow == Overflow */
174         /*----------------------------------------------------------------------*/
175         MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1);
176         MONO_EMIT_NEW_BIALU (s, OP_SBB, state->reg2, state->left->reg2, state->right->reg2);
177         MONO_EMIT_NEW_COND_EXC (s, NC, "OverflowException");
178 }
179
180 stmt: OP_OUTARG (reg) {
181         if (tree->inst_imm) {
182                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, STK_BASE, tree->inst_imm, state->left->reg1);
183                 return;
184         }
185         tree->opcode = OP_SETREG;
186         tree->dreg = tree->unused;
187         tree->sreg1 = state->left->reg1;
188         mono_bblock_add_inst (s->cbb, tree);
189 }
190
191 stmt: OP_OUTARG (OP_REGVAR) {
192         if (tree->inst_imm) {
193                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, STK_BASE, tree->inst_imm, state->left->tree->dreg);
194                 return;
195         }
196         tree->opcode = OP_SETREG;
197         tree->dreg = tree->unused;
198         tree->sreg1 = state->left->tree->dreg;
199         mono_bblock_add_inst (s->cbb, tree);
200 }
201
202 stmt: OP_OUTARG (lreg) {
203         if (tree->inst_imm) {
204                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, STK_BASE, tree->inst_imm, state->left->reg2);
205                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, STK_BASE, tree->inst_imm + 4, state->left->reg1);
206                 return;
207         }
208         MONO_EMIT_NEW_UNALU (s, OP_SETREG, tree->unused, state->left->reg2);
209         tree->opcode = OP_SETREG;
210         tree->dreg = tree->unused + 1;
211         tree->sreg1 = state->left->reg1;
212         mono_bblock_add_inst (s->cbb, tree);
213 }
214
215 stmt: OP_OUTARG (OP_ICONST) {
216         if (tree->inst_imm) {
217                 MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STORE_MEMBASE_IMM, STK_BASE, tree->inst_imm, state->left->tree->inst_c0);
218                 return;
219         }
220         tree->opcode = OP_SETREGIMM;
221         tree->dreg = tree->unused;
222         tree->inst_c0 = state->left->tree->inst_c0;
223         mono_bblock_add_inst (s->cbb, tree);
224 }
225
226 stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)) {
227         if (tree->inst_imm) {
228                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, STK_BASE, tree->inst_imm, state->left->left->tree->dreg);
229                 return;
230         }
231         tree->opcode = OP_SETREG;
232         tree->sreg1 = state->left->left->tree->dreg;
233         tree->dreg = tree->unused;
234         mono_bblock_add_inst (s->cbb, tree);
235 }
236
237 stmt: OP_OUTARG (OP_LDADDR (OP_S390_LOADARG)) {
238         if (tree->inst_imm) {
239                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, STK_BASE, tree->inst_imm, state->left->left->tree->dreg);
240                 return;
241         }
242         MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, tree->unused,
243                              state->left->left->tree->sreg1,
244                              state->left->left->tree->inst_offset);
245 }
246
247 stmt: OP_OUTARG (freg) {
248         if (tree->inst_imm) {
249                 /*----------------------------------------------*/
250                 /* The length stored in unused tells us whether */
251                 /* we need to store a float or a double         */
252                 /*----------------------------------------------*/
253                 if ((tree->unused & 0xff00) == 0x0400) {
254                         MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, 
255                                                      STK_BASE, tree->inst_imm, 
256                                                      state->left->reg1);
257                 } else {
258                         MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, 
259                                                      STK_BASE, tree->inst_imm, 
260                                                      state->left->reg1);
261                 }
262                 return;
263         }
264         tree->opcode = OP_SETFREG;
265         tree->sreg1 = state->left->reg1;
266         tree->dreg = tree->unused;
267         mono_bblock_add_inst (s->cbb, tree);
268 }
269
270 stmt: OP_OUTARG_R4 (freg) {
271         if (tree->inst_imm) {
272                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER4_MEMBASE_REG, STK_BASE, tree->inst_imm, state->left->reg1);
273                 return;
274         }
275         tree->opcode = OP_SETFREG;
276         tree->sreg1 = state->left->reg1;
277         tree->dreg = tree->unused;
278         mono_bblock_add_inst (s->cbb, tree);
279 }
280
281 stmt: OP_OUTARG_R8 (freg) {
282         if (tree->inst_imm) {
283                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, STK_BASE, 
284                                              tree->inst_imm, state->left->reg1);
285                 return;
286         }
287         tree->opcode = OP_SETFREG;
288         tree->sreg1 = state->left->reg1;
289         tree->dreg = tree->unused;
290         mono_bblock_add_inst (s->cbb, tree);
291 }
292
293 stmt: OP_OUTARG_R8 (CEE_LDOBJ (OP_REGOFFSET)) {
294         if (tree->inst_imm) {
295                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORER8_MEMBASE_REG, STK_BASE, 
296                                              tree->inst_imm, state->left->reg1);
297                 return;
298         }
299         tree->opcode = OP_SETFREG;
300         tree->sreg1 = state->left->reg1;
301         tree->dreg = tree->unused;
302         mono_bblock_add_inst (s->cbb, tree);
303 }
304
305 freg: OP_FCONV_TO_R4 (CEE_LDOBJ (OP_REGOFFSET)) {
306         MonoInst *vt = state->left->left->tree;
307  
308         MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADR4_MEMBASE, state->reg1, vt->inst_basereg, 
309                                        vt->inst_offset);
310         MONO_EMIT_NEW_UNALU (s, OP_FCONV_TO_R4, state->reg1, state->reg1);
311 }
312
313 freg: OP_FCONV_TO_R8 (CEE_LDOBJ (OP_REGOFFSET)) {
314         tree->opcode = OP_SETFREG;
315         tree->sreg1 = state->left->reg1;
316         tree->dreg = tree->unused;
317         mono_bblock_add_inst (s->cbb, tree);
318 }
319
320
321 stmt: OP_OUTARG_VT (CEE_LDOBJ (base)) {
322         MonoInst *vt  = state->left->left->tree;
323         int start_reg = tree->sreg1;
324         int size      = tree->unused;
325         int soffset   = vt->inst_offset;
326         int tmpr;
327         
328 //printf("OP_OUTARG_VT(CEE_LDOBJ(base))\n");
329         if (size < 0) { 
330                 size = -size;
331                 if (start_reg != STK_BASE) {
332                         MONO_EMIT_NEW_MOVE(s, STK_BASE, tree->sreg2,
333                                            vt->inst_basereg, soffset, size);
334                         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, start_reg, 
335                                                  STK_BASE, tree->sreg2);
336                 } else { 
337                         MONO_EMIT_NEW_MOVE(s, STK_BASE, tree->sreg2+sizeof(gpointer),
338                                            vt->inst_basereg, soffset, size);
339                         tmpr = mono_regstate_next_int (s->rs);
340                         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, STK_BASE, 
341                                                  tree->sreg2+sizeof(gpointer));
342                         MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, 
343                                                      STK_BASE, tree->sreg2, tmpr);
344                 }
345         } else {
346                 if (start_reg != STK_BASE) {
347                         MONO_OUTPUT_VTR (s, size, start_reg, vt->inst_basereg, soffset);
348                 } else {
349                         MONO_OUTPUT_VTS (s, size, STK_BASE, tree->inst_imm,
350                                          vt->inst_basereg, soffset);
351                 }       
352         }
353 }
354
355 stmt: OP_OUTARG_VT (CEE_LDOBJ (OP_S390_ARGPTR)) {
356         MonoInst *vt  = state->left->left->tree;
357         int start_reg = tree->sreg1;
358         int size      = tree->unused;
359         int soffset   = vt->inst_offset;
360         int tmpr;
361
362 //printf("OP_OUTARG_VT(CEE_LDOBJ(OP_S390_ARGPTR))\n");
363         if (size < 0) { 
364                 size = -size;
365                 if (start_reg != STK_BASE) {
366                         MONO_EMIT_NEW_MOVE (s, STK_BASE, tree->inst_imm,
367                                             vt->inst_basereg, soffset, size);
368                         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, start_reg, 
369                                                  STK_BASE, tree->sreg2);
370                 } else {
371                         MONO_EMIT_NEW_MOVE (s, STK_BASE, 
372                                             tree->inst_imm+sizeof(gpointer),
373                                             vt->inst_basereg, soffset, size);
374                         tmpr = mono_regstate_next_int (s->rs);
375                         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, STK_BASE,
376                                                  tree->inst_imm+sizeof(gpointer));
377                         MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, 
378                                                      STK_BASE, tree->inst_imm,
379                                                      tmpr);
380                 }
381         } else {
382                 if (start_reg != STK_BASE) {
383                         MONO_OUTPUT_VTR (s, size, start_reg, vt->inst_basereg, soffset);
384                 } else {
385                         MONO_OUTPUT_VTS (s, size, STK_BASE, 
386                                          tree->inst_imm,
387                                          vt->inst_basereg, soffset);
388                 }       
389         }
390 }
391
392 stmt: OP_OUTARG_VT (CEE_LDOBJ (OP_REGOFFSET)) "0" {
393         MonoInst *vt  = state->left->left->tree;
394         int start_reg = tree->sreg1;
395         int size      = tree->unused;
396         int soffset   = vt->inst_offset;
397         int tmpr;
398
399 //printf("OP_OUTARG_VT(CEE_LDOBJ(OP_REGOFFSET))\n");
400         if (size < 0) { 
401                 size = -size;
402                 if (start_reg != STK_BASE) {
403                         MONO_EMIT_NEW_MOVE (s, STK_BASE, tree->sreg2, 
404                                             vt->inst_basereg, soffset, size);
405                         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, start_reg, 
406                                                  STK_BASE, tree->sreg2);
407                 } else {
408                         MONO_EMIT_NEW_MOVE (s, STK_BASE, 
409                                             tree->sreg2+sizeof(gpointer),
410                                             vt->inst_basereg, soffset, size);
411                         tmpr = mono_regstate_next_int (s->rs);
412                         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, STK_BASE,
413                                                  tree->sreg2+sizeof(gpointer));
414                         MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, 
415                                                      STK_BASE, tree->sreg2,
416                                                      tmpr);
417                 }
418         } else {
419                 if (start_reg != STK_BASE) {
420                         MONO_OUTPUT_VTR(s, size, start_reg, vt->inst_basereg, soffset);
421                 } else {
422                         MONO_OUTPUT_VTS(s, size, STK_BASE, tree->inst_imm,
423                                           vt->inst_basereg, soffset);
424                 }       
425         }
426 }
427
428 stmt: OP_OUTARG_VT (CEE_LDOBJ (OP_S390_LOADARG)) {
429         MonoInst *vt  = state->left->left->tree;
430         int start_reg = tree->sreg1;
431         int size      = -tree->unused;
432         int soffset   = vt->inst_offset;
433         int tmpr;
434
435 //printf("OP_OUTARG_VT(CEE_LDOBJ(OP_S390_LOADARG))\n");
436         if (start_reg != STK_BASE) {
437                 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, start_reg, STK_BASE, soffset);
438                 MONO_EMIT_NEW_MOVE (s, STK_BASE, tree->sreg2, start_reg, 0, size);
439                 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, start_reg, 
440                                          STK_BASE, tree->sreg2);
441         } else {
442                 MONO_EMIT_NEW_MOVE (s, STK_BASE, 
443                                     tree->inst_imm+sizeof(gpointer),
444                                     vt->inst_basereg, soffset, size);
445                 tmpr = mono_regstate_next_int (s->rs);
446                 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, STK_BASE,
447                                          tree->inst_imm+sizeof(gpointer));
448                 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, 
449                                              STK_BASE, tree->inst_imm,
450                                              tmpr);
451         }
452 }
453
454 stmt: OP_OUTARG_VT (OP_ICONST) {
455         int start_reg = tree->sreg1;
456         int size      = tree->unused;
457         int nregs     = size / 4;
458
459 //printf("OP_OUTARG_VT(OP_ICONST)\n");
460         if (start_reg != STK_BASE) {
461                 if (nregs) {
462                         tree->opcode  = OP_SETREGIMM;
463                         tree->dreg    = start_reg;
464                         tree->inst_c0 = state->left->tree->inst_c0;
465                         mono_bblock_add_inst (s->cbb, tree);
466                 }
467         } else {
468                 MONO_OUTPUT_VTS (s, size, STK_BASE, tree->inst_c0, 
469                                  s->frame_reg, tree->inst_offset);
470         }
471 }
472
473 stmt: OP_OUTARG_VT (reg) {
474         int start_reg = tree->sreg1;
475         int size      = tree->unused;
476         int soffset   = tree->sreg2;
477         int tmpr;
478
479 //printf("OP_OUTARG_VT(reg)\n");
480         if (size < 0) { 
481                 size = -size;
482                 if (start_reg != STK_BASE) {
483                         MONO_EMIT_NEW_MOVE (s, STK_BASE, soffset,
484                                             state->left->tree->sreg1,
485                                             tree->inst_imm, size);
486                         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, start_reg, 
487                                                  STK_BASE, soffset);
488                 } else {
489                         MONO_EMIT_NEW_MOVE (s, STK_BASE, 
490                                             soffset+sizeof(gpointer),
491                                             state->left->tree->sreg1,
492                                             tree->inst_imm, size);
493                         tmpr = mono_regstate_next_int (s->rs);
494                         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, STK_BASE,
495                                                  soffset+sizeof(gpointer));
496                         MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STORE_MEMBASE_REG, 
497                                                      STK_BASE, tree->inst_imm,
498                                                      tmpr);
499                 }
500         } else {
501                 if (start_reg != STK_BASE) {
502 //                      MONO_OUTPUT_VTR (s, size, start_reg, STK_BASE,
503 //                                       state->left->tree->inst_offset);
504                         MONO_OUTPUT_VTR (s, size, start_reg, STK_BASE, soffset);
505                 } else {
506                         MONO_OUTPUT_VTS (s, size, STK_BASE, soffset, tmpr,
507                                          state->left->tree->inst_offset);
508                         tmpr = mono_regstate_next_int (s->rs);
509                         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, STK_BASE, 
510                                                 s->stack_offset);
511                 }
512         }
513 }
514
515 stmt: OP_OUTARG_VT (OP_REFANYTYPE (reg)) "0" {
516 //printf("OP_OUTARG_VT (OP_REFANYTYPE (base))\n");
517         MONO_EMIT_NEW_LOAD_MEMBASE (s, state->tree->sreg1, state->left->left->reg1, 
518                                     G_STRUCT_OFFSET (MonoTypedRef, type));
519 //      MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, STK_BASE,
520 //                                   tree->sreg2, state->reg1);
521 //      MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, STK_BASE, tree->sreg2);
522 }       
523
524 stmt: CEE_STIND_R8 (OP_REGVAR, freg) {
525         /* nothing to do: the value is already on the FP stack */
526 }
527
528 stmt: CEE_BNE_UN (fpcflags) {
529         tree->opcode = OP_FBNE_UN;
530         mono_bblock_add_inst (s->cbb, tree);
531 }
532
533 stmt: CEE_BEQ (fpcflags) {
534         tree->opcode = OP_FBEQ;
535         mono_bblock_add_inst (s->cbb, tree);
536 }
537
538 stmt: CEE_BLT (fpcflags) {
539         tree->opcode = OP_FBLT;
540         mono_bblock_add_inst (s->cbb, tree);
541 }
542
543 stmt: CEE_BLT_UN (fpcflags) {
544         tree->opcode = OP_FBLT_UN;
545         mono_bblock_add_inst (s->cbb, tree);
546 }
547
548 stmt: CEE_BGT (fpcflags) {
549         tree->opcode = OP_FBGT;
550         mono_bblock_add_inst (s->cbb, tree);
551 }
552
553 stmt: CEE_BGT_UN (fpcflags) {
554         tree->opcode = OP_FBGT_UN;
555         mono_bblock_add_inst (s->cbb, tree);
556 }
557
558 stmt: CEE_BGE  (fpcflags) {
559         tree->opcode = OP_FBGE;
560         mono_bblock_add_inst (s->cbb, tree);
561 }
562
563 stmt: CEE_BGE_UN (fpcflags) {
564         tree->opcode = OP_FBGE_UN;
565         mono_bblock_add_inst (s->cbb, tree);
566 }
567
568 stmt: CEE_BLE  (fpcflags) {
569         tree->opcode = OP_FBLE;
570         mono_bblock_add_inst (s->cbb, tree);
571 }
572
573 stmt: CEE_BLE_UN (fpcflags) {
574         tree->opcode = OP_FBLE_UN;
575         mono_bblock_add_inst (s->cbb, tree);
576 }
577
578 stmt: CEE_POP (freg) "0" {
579         /* nothing to do */
580 }     
581
582 freg: OP_LCONV_TO_R8 (lreg) {
583         /* nothing to do - emulated */
584 }
585
586 freg: OP_LCONV_TO_R4 (lreg) {
587         /* nothing to do - emulated */
588 }
589
590 freg: OP_LCONV_TO_R_UN (lreg) {
591         /* nothing to do - emulated */
592 }
593
594 freg: OP_FREM (freg, freg) {
595         /* nothing to do - emulated */
596 }
597
598 reg: OP_CEQ (OP_COMPARE (freg, freg)) { 
599         MONO_EMIT_BIALU (s, tree, OP_FCEQ, state->reg1, state->left->left->reg1,
600                          state->left->right->reg1);
601 }
602
603 reg: OP_CLT (OP_COMPARE (freg, freg)) { 
604         MONO_EMIT_BIALU (s, tree, OP_FCLT, state->reg1, state->left->left->reg1,
605                          state->left->right->reg1);
606 }
607
608 reg: OP_CLT_UN (OP_COMPARE (freg, freg)) {      
609         MONO_EMIT_BIALU (s, tree, OP_FCLT_UN, state->reg1, state->left->left->reg1,
610                          state->left->right->reg1);
611 }
612
613 reg: OP_CGT (OP_COMPARE (freg, freg)) { 
614         MONO_EMIT_BIALU (s, tree, OP_FCGT, state->reg1, state->left->left->reg1,
615                          state->left->right->reg1);
616 }
617
618 reg: OP_CGT_UN (OP_COMPARE (freg, freg)) {      
619         MONO_EMIT_BIALU (s, tree, OP_FCGT_UN, state->reg1, state->left->left->reg1,
620                          state->left->right->reg1);
621 }
622
623 base: OP_S390_STKARG "0" {
624         int tmpr;
625
626         tmpr = mono_regstate_next_int (s->rs);
627 //      MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg, 
628 //                              (s->stack_offset+state->tree->unused));
629         MONO_EMIT_NEW_LOAD_MEMBASE (s, tmpr, s->frame_reg, 0);
630         tree->inst_offset  = state->tree->inst_offset;
631         tree->inst_basereg = tmpr;
632 }
633
634 base: OP_LDADDR (OP_S390_LOADARG) "0" {
635         int tmpr;
636
637         tmpr = mono_regstate_next_int (s->rs);
638         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg, 
639                                  state->left->tree->inst_offset);
640         tree->inst_offset  = 0;
641         tree->inst_basereg = tmpr;
642 }
643
644 base: OP_LDADDR (OP_S390_ARGPTR) "0" {
645         int tmpr;
646
647         tmpr = mono_regstate_next_int (s->rs);
648         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg, 
649                                  state->left->tree->inst_offset);
650         tree->inst_offset  = 0;
651         tree->inst_basereg = tmpr;
652 }
653
654 base: OP_LDADDR (OP_S390_STKARG) "0" {
655         int tmpr;
656
657 printf("OP_LDADDR (OP_S390_STKARG)\n");
658         tmpr = mono_regstate_next_int (s->rs);
659 //      MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg, 
660 //                               (s->stack_offset + state->left->tree->unused));
661         MONO_EMIT_NEW_LOAD_MEMBASE (s, tmpr, s->frame_reg, 0);
662         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, tmpr, 
663                                  state->left->tree->inst_offset);
664         tree->inst_offset  = 0;
665         tree->inst_basereg = tmpr;
666 }
667
668 reg: OP_LDADDR (OP_S390_LOADARG) "2" {
669         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg, 
670                                  state->left->tree->inst_offset);
671         tree->inst_offset  = 0;
672         tree->inst_basereg = state->reg1;
673 }
674
675 reg: OP_LDADDR (OP_S390_ARGPTR) "2" {
676         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg, 
677                                  state->left->tree->inst_offset);
678         tree->inst_offset  = 0;
679         tree->inst_basereg = state->reg1;
680 }
681
682 reg: OP_LDADDR (OP_S390_STKARG) "2" {
683         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg, 
684                                  (s->stack_offset + state->left->tree->unused));
685         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->reg1, 
686                                  state->left->tree->inst_offset);
687         tree->inst_offset  = 0;
688         tree->inst_basereg = state->reg1;
689 }
690
691 reg: CEE_LDOBJ (OP_S390_LOADARG) "1" {
692         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg, 
693                                  state->left->tree->inst_offset);
694 }
695
696 reg: CEE_LDOBJ (OP_S390_ARGPTR) "1" {
697         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg, 
698                              state->left->tree->inst_offset);
699 }
700
701 reg: CEE_LDOBJ (OP_S390_STKARG) "1" {
702         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, s->frame_reg,
703                                  (s->stack_offset + state->left->tree->unused));
704         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->reg1,
705                                  state->left->tree->inst_offset);
706         tree->inst_offset  = 0;
707         tree->inst_basereg = state->reg1;
708 }
709
710 base: CEE_LDOBJ (OP_S390_ARGPTR) "0" {
711         int tmpr;
712
713         tmpr = mono_regstate_next_int (s->rs);
714         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg, 
715                                     state->left->tree->inst_offset);
716         tree->inst_offset  = 0;
717         tree->inst_basereg = tmpr;
718 }
719
720 base: CEE_LDOBJ (OP_S390_STKARG) "0" {
721         int tmpr;
722
723         tmpr = mono_regstate_next_int (s->rs);
724         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, tmpr, s->frame_reg,
725                                  (s->stack_offset + state->left->tree->unused));
726         MONO_EMIT_NEW_LOAD_MEMBASE (s, tmpr, tmpr, state->left->tree->inst_offset);
727         tree->inst_offset  = 0;
728         tree->inst_basereg = tmpr;
729 }
730
731 reg: OP_ATOMIC_ADD_NEW_I4 (base, reg),
732 reg: OP_ATOMIC_ADD_I4 (base, reg) {
733         tree->opcode = tree->opcode;
734         tree->inst_basereg = state->left->tree->inst_basereg; 
735         tree->inst_offset = state->left->tree->inst_offset; 
736         tree->dreg = state->reg1;
737         tree->sreg2 = state->right->reg1;
738     
739         mono_bblock_add_inst (s->cbb, tree);
740 }
741
742 reg: OP_ATOMIC_EXCHANGE_I4 (base, reg) {
743         tree->opcode = OP_ATOMIC_EXCHANGE_I4;
744         tree->dreg = state->reg1;
745         tree->sreg2 = state->right->reg1;
746         tree->inst_basereg = state->left->tree->inst_basereg; 
747         tree->inst_offset = state->left->tree->inst_offset; 
748     
749         mono_bblock_add_inst (s->cbb, tree);
750 }
751
752 %%