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