2004-08-26 Ben Maurer <bmaurer@users.sourceforge.net>
[mono.git] / mono / mini / inssel-long.brg
1 %%
2
3 #
4 # inssel-long.brg: burg file for 64bit architectures
5 #
6 # Author:
7 #   Dietmar Maurer (dietmar@ximian.com)
8 #
9 # (C) 2002 Ximian, Inc.
10 #
11
12 reg: OP_I8CONST {
13         MONO_EMIT_NEW_I8CONST (s, state->reg1, tree->inst_l);
14 }
15
16 reg: CEE_LDIND_I8 (base) {
17         MONO_EMIT_LOAD_MEMBASE_OP (s, tree, OP_LOADI8_MEMBASE, state->reg1, 
18                                    state->left->tree->inst_basereg, state->left->tree->inst_offset);
19 }
20
21 stmt: CEE_STIND_I8 (base, reg) {
22         MONO_EMIT_STORE_MEMBASE (s, tree, OP_STOREI8_MEMBASE_REG, state->left->tree->inst_basereg,
23                                  state->left->tree->inst_offset, state->right->reg1);
24 }
25
26 stmt: CEE_STIND_REF (base, OP_I8CONST),
27 stmt: CEE_STIND_I (base, OP_I8CONST),
28 stmt: CEE_STIND_I8 (base, OP_I8CONST),
29 stmt: CEE_STIND_REF (base, OP_ICONST),
30 stmt: CEE_STIND_I (base, OP_ICONST),
31 stmt: CEE_STIND_I8 (base, OP_ICONST) {
32         MONO_EMIT_STORE_MEMBASE_IMM (s, tree, OP_STOREI8_MEMBASE_IMM, state->left->tree->inst_basereg,
33                                      state->left->tree->inst_offset, state->right->tree->inst_l);
34 }
35
36 stmt: CEE_STIND_I8 (reg, reg) {
37         MONO_EMIT_STORE_MEMBASE (s, tree, OP_STOREI8_MEMBASE_REG, state->left->tree->inst_basereg,
38                                  state->left->tree->inst_offset, state->right->reg1);
39 }
40
41 reg: OP_LADD (reg, reg) {
42         MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg1, state->left->reg1, state->right->reg1);
43 }
44
45 reg: OP_LSUB (reg, reg) {
46         MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg1, state->left->reg1, state->right->reg1);
47 }
48
49 reg: OP_LNEG (reg) {
50         MONO_EMIT_NEW_UNALU (s, CEE_NEG, state->reg1, state->left->reg1);
51 }
52
53 reg: OP_LNOT (reg) {
54         MONO_EMIT_NEW_UNALU (s, CEE_NOT, state->reg1, state->left->reg1);
55 }
56
57 reg: OP_LAND (reg, reg) {
58         MONO_EMIT_NEW_BIALU (s, CEE_AND, state->reg1, state->left->reg1, state->right->reg1);
59 }
60
61 reg: OP_LOR (reg, reg) {
62         MONO_EMIT_NEW_BIALU (s, CEE_OR, state->reg1, state->left->reg1, state->right->reg1);
63 }
64
65 reg: OP_LXOR (reg, reg) {
66         MONO_EMIT_NEW_BIALU (s, CEE_XOR, state->reg1, state->left->reg1, state->right->reg1);
67 }
68
69
70 reg: OP_LADD_OVF (reg, reg) {
71         MONO_EMIT_NEW_BIALU (s, OP_ADDCC, state->reg1, state->left->reg1, state->right->reg1);
72         MONO_EMIT_NEW_COND_EXC (s, OV, "OverflowException");
73 }
74
75 reg: OP_LADD_OVF_UN (reg, reg) {
76         MONO_EMIT_NEW_BIALU (s, OP_ADDCC, state->reg1, state->left->reg1, state->right->reg1);
77         MONO_EMIT_NEW_COND_EXC (s, C, "OverflowException");
78 }
79
80 reg: OP_LSUB_OVF (reg, reg) {
81         MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1);
82         MONO_EMIT_NEW_COND_EXC (s, OV, "OverflowException");
83 }
84
85 reg: OP_LSUB_OVF_UN (reg, reg) {
86         MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1);
87         MONO_EMIT_NEW_COND_EXC (s, C, "OverflowException");
88 }
89
90 reg: OP_LONG_SHRUN_32 (reg) {
91         MONO_EMIT_BIALU_IMM (s, tree, OP_LSHR_UN_IMM, state->reg1, state->left->reg1, 32);
92 }
93
94 #
95 # shift operations
96 #
97
98 reg: OP_LSHL (reg, reg) {
99         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
100 }
101
102 reg: OP_LSHL (reg, OP_ICONST) {
103         MONO_EMIT_BIALU_IMM (s, tree, OP_LSHL_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
104 }
105
106 reg: OP_LSHR (reg, reg) {
107         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
108 }
109
110 reg: OP_LSHR_IMM (reg, OP_ICONST) {
111         MONO_EMIT_BIALU_IMM (s, tree, OP_LSHR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
112 }
113
114 reg: OP_LSHR_UN (reg, reg) {
115         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
116 }
117
118 reg: OP_LSHR_UN (reg, OP_ICONST) {
119         MONO_EMIT_BIALU_IMM (s, tree, OP_LSHR_UN_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
120 }
121
122 #
123 # Conversions
124 #
125
126 reg: CEE_CONV_I8 (reg) {
127         /* Sign extend the value in the lower word into the upper word */
128         tree->sreg1 = state->left->reg1;
129         tree->dreg = state->reg1;
130         mono_bblock_add_inst (s->cbb, tree);    
131 }
132
133 reg: CEE_CONV_U8 (reg) {
134         /* Clean out the upper word */
135         /* Sign extend the value in the lower word into the upper word */
136         tree->sreg1 = state->left->reg1;
137         tree->dreg = state->reg1;
138         mono_bblock_add_inst (s->cbb, tree);
139 }
140
141 i8con: CEE_CONV_U8 (OP_ICONST) "0" {
142         /*
143          * This is needed since constant propagation eliminates some 
144      * stind.i4/ldind.i4 pairs, along with the conversions done by them.
145          */
146         int data = state->left->tree->inst_c0;
147         tree->opcode = OP_I8CONST;
148         tree->inst_ls_word = data;
149         tree->inst_ms_word = 0;
150 }
151
152 reg: OP_LCONV_TO_I4 (reg) {
153         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
154 }
155
156 reg: OP_FCONV_TO_I8 (freg) {
157         MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
158 }
159
160 reg: OP_FCONV_TO_U8 (freg) {
161         MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
162 }
163
164 reg: OP_LCONV_TO_I4 (i8con) {
165      MONO_EMIT_NEW_ICONST (s, state->reg1, state->left->tree->inst_ls_word);
166 }
167
168 reg: OP_LCONV_TO_I4 (reg) {
169         /* Sign extend the value in the lower word into the upper word */
170         MONO_EMIT_BIALU_IMM (s, tree, OP_SHR_IMM, state->reg1, state->left->reg1, 0);
171 }
172
173 reg: OP_LCONV_TO_U4 (reg) {
174         /* Clean out the upper word */
175         MONO_EMIT_BIALU_IMM (s, tree, OP_SHR_UN_IMM, state->reg1, state->left->reg1, 0);
176 }
177
178 reg: OP_LCONV_TO_U8 (reg) {
179         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
180 }
181
182 reg: OP_LCONV_TO_I8 (reg) {
183         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
184 }
185
186 reg: OP_LCONV_TO_U (reg) {
187         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
188 }
189
190 reg: OP_LCONV_TO_I (reg) {
191         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
192 }
193
194 reg: OP_LCONV_TO_I1 (reg) {
195         MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
196 }
197
198 reg: OP_LCONV_TO_U1 (reg) {
199         MONO_EMIT_UNALU (s, tree, CEE_CONV_U1, state->reg1, state->left->reg1);
200 }
201
202 reg: OP_LCONV_TO_I2 (reg) {
203         MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
204 }
205
206 reg: OP_LCONV_TO_U2 (reg) {
207         MONO_EMIT_UNALU (s, tree, CEE_CONV_U2, state->reg1, state->left->reg1);
208 }
209
210
211 reg: OP_LCONV_TO_OVF_I1 (reg) {
212         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 127);
213         MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
214         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -128);
215         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
216         MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
217 }
218
219 reg: OP_LCONV_TO_OVF_U1 (reg) {
220         /* probe value to be within 0 to 255 */
221         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 255);
222         MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
223         MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, 0xff);
224 }
225
226 reg: OP_LCONV_TO_OVF_U1_UN (reg) {
227         /* probe value to be within 0 to 255 */
228         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 255);
229         MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
230         MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, 0xff);
231 }
232
233 reg: OP_LCONV_TO_OVF_I2 (reg) {
234         /* Probe value to be within -32768 and 32767 */
235         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 32767);
236         MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
237         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -32768);
238         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
239         MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
240 }
241
242 reg: OP_LCONV_TO_OVF_U2 (reg) {
243         /* Probe value to be within 0 and 65535 */
244         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0xffff);
245         MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
246         MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, 0xffff);
247 }
248
249 reg: OP_LCONV_TO_OVF_U2_UN (reg) {
250         /* Probe value to be within 0 and 65535 */
251         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0xffff);
252         MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
253         MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, 0xffff);
254 }
255
256 reg: OP_LCONV_TO_OVF_I4 (reg) {
257         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0x7fffffff);
258         MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
259         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -2147483648);
260         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
261         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
262 }
263
264 reg: OP_LCONV_TO_OVF_U4_UN (reg) {
265         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0xffffffff);
266         MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
267         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
268 }
269
270 reg: OP_LCONV_TO_OVF_U4 (reg) {
271         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0xffffffffUL);
272         MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
273         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg1, 0);
274         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
275         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
276 }
277
278 reg: OP_LCONV_TO_OVF_I_UN (reg),
279 reg: OP_LCONV_TO_OVF_I8_UN (reg) {
280         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg1, 0);
281         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
282
283         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
284 }
285
286 reg: OP_LCONV_TO_OVF_U8 (reg) {
287         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg1, 0);
288         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
289
290         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
291 }
292
293 reg: OP_LCONV_TO_OVF_I8 (reg) {
294         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
295 }
296
297 reg: OP_LCONV_TO_OVF_U8_UN (reg) {
298         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
299 }
300
301 reg: OP_LCONV_TO_OVF_I (reg) {
302         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
303 }
304
305 freg: OP_LCONV_TO_R_UN (lreg) {
306         MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
307 }
308
309 reg: CEE_CONV_OVF_I8 (reg) {
310         /* Sign extend the value in the lower word into the upper word */
311         MONO_EMIT_BIALU_IMM (s, tree, OP_SHR_IMM, state->reg1, state->left->reg1, 0);
312 }
313
314 reg: CEE_CONV_OVF_I8_UN (reg) {
315         /* an unsigned 32 bit num always fits in a signed 64 bit one */
316         /* Clean out the upper word */
317         MONO_EMIT_BIALU_IMM (s, tree, OP_SHR_UN_IMM, state->reg1, state->left->reg1, 0);
318 }
319
320 reg: CEE_CONV_OVF_U8 (reg) {
321         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0);
322         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
323         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
324 }
325
326 reg: CEE_CONV_OVF_U8_UN (reg) {
327         g_assert_not_reached ();
328 }
329
330
331
332
333 reg: OP_LCALLVIRT (reg) {
334         mini_emit_virtual_call (s, state, tree, OP_LCALL, OP_LCALL_MEMBASE);
335 }
336
337 reg: OP_LCALL {
338         tree->dreg = state->reg1;
339         mono_bblock_add_inst (s->cbb, tree);
340 }
341
342 reg: OP_LCALL_REG (reg) {
343         tree->sreg1 = state->left->reg1;
344         tree->dreg = state->reg1;
345         mono_bblock_add_inst (s->cbb, tree);
346 }
347
348 reg: OP_LCALL_REG (OP_ICONST) {
349         tree->opcode = OP_LCALL;
350         ((MonoCallInst*)tree)->fptr = state->left->tree->inst_p0;
351         tree->dreg = state->reg1;
352         mono_bblock_add_inst (s->cbb, tree);
353 }
354
355
356
357 stmt: CEE_STIND_I4 (OP_REGVAR, OP_ICONST) {
358         tree->inst_c0 = state->right->tree->inst_c0;
359         tree->opcode = OP_ICONST;
360         tree->dreg = state->left->tree->dreg;
361         mono_bblock_add_inst (s->cbb, tree);
362 }
363
364 stmt: CEE_STIND_I4 (OP_REGVAR, reg) {
365         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->left->tree->dreg, state->right->reg1);
366 }
367
368 stmt: CEE_STIND_I4 (OP_REGVAR, CEE_LDIND_I4 (OP_REGVAR)) {
369         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->left->tree->dreg, state->right->left->tree->dreg);
370 }
371
372 stmt: CEE_STIND_I4 (OP_REGVAR, CEE_LDIND_I4 (base)) {
373         MONO_EMIT_LOAD_MEMBASE_OP (s, tree, OP_LOADI4_MEMBASE, state->left->tree->dreg, 
374                                    state->right->left->tree->inst_basereg, 
375                                    state->right->left->tree->inst_offset);
376 }
377
378 cflags: OP_LCOMPARE (reg, reg) {
379         tree->sreg1 = state->left->reg1;
380         tree->sreg2 = state->right->reg1;
381         mono_bblock_add_inst (s->cbb, tree);
382 }
383
384 cflags: OP_LCOMPARE (CEE_LDIND_I8 (OP_REGVAR), reg) {
385         tree->sreg1 = state->left->left->tree->dreg;
386         tree->sreg2 = state->right->reg1;
387         mono_bblock_add_inst (s->cbb, tree);
388 }
389
390 cflags: OP_LCOMPARE (CEE_LDIND_I (OP_REGVAR), CEE_LDIND_I (OP_REGVAR)) {
391         tree->sreg1 = state->left->left->tree->dreg;
392         tree->sreg2 = state->right->left->tree->dreg;
393         mono_bblock_add_inst (s->cbb, tree);
394 }
395
396 cflags: OP_LCOMPARE (CEE_LDIND_I8 (OP_REGVAR), OP_ICONST) {
397         tree->opcode = OP_COMPARE_IMM;
398         tree->sreg1 = state->left->left->tree->dreg;
399         tree->inst_imm = state->right->tree->inst_c0;
400         mono_bblock_add_inst (s->cbb, tree);
401 } cost {
402         MBCOND (mono_arch_is_inst_imm (state->right->tree->inst_c0));
403
404         return 0;
405 }       
406
407 cflags: OP_LCOMPARE (reg, OP_ICONST) {
408         tree->opcode = OP_COMPARE_IMM;
409         tree->sreg1 = state->left->reg1;
410         tree->inst_imm = state->right->tree->inst_c0;
411         mono_bblock_add_inst (s->cbb, tree);
412 } cost {
413         MBCOND (mono_arch_is_inst_imm (state->right->tree->inst_c0));
414
415         return 0;
416 }       
417
418 cflags: OP_LCOMPARE (reg, OP_I8CONST) {
419         tree->opcode = OP_COMPARE_IMM;
420         tree->sreg1 = state->left->reg1;
421         tree->inst_imm = state->right->tree->inst_l;
422         mono_bblock_add_inst (s->cbb, tree);
423 } cost {
424         MBCOND (mono_arch_is_inst_imm (state->right->tree->inst_l));
425
426         return 0;
427 }       
428
429 stmt: CEE_BNE_UN (cflags) {
430         mono_bblock_add_inst (s->cbb, tree);
431 }
432
433 stmt: CEE_BEQ (cflags) {
434         mono_bblock_add_inst (s->cbb, tree);
435 }
436
437 stmt: CEE_BLT (cflags) {
438         mono_bblock_add_inst (s->cbb, tree);
439 }
440
441 stmt: CEE_BLT_UN (cflags) {
442         mono_bblock_add_inst (s->cbb, tree);
443 }
444
445 stmt: CEE_BGT (cflags) {
446         mono_bblock_add_inst (s->cbb, tree);
447 }
448
449 stmt: CEE_BGT_UN (cflags) {
450         mono_bblock_add_inst (s->cbb, tree);
451 }
452
453 stmt: CEE_BGE  (cflags) {
454         mono_bblock_add_inst (s->cbb, tree);
455 }
456
457 stmt: CEE_BGE_UN (cflags) {
458         mono_bblock_add_inst (s->cbb, tree);
459 }
460
461 stmt: CEE_BLE  (cflags) {
462         mono_bblock_add_inst (s->cbb, tree);
463 }
464
465 stmt: CEE_BLE_UN (cflags) {
466         mono_bblock_add_inst (s->cbb, tree);
467 }
468
469 #
470 # 32 bit rules
471 #
472
473 #
474 # basic alu operations
475 #
476
477 reg: CEE_AND (reg, reg) {
478         MONO_EMIT_BIALU (s, tree, OP_IAND, state->reg1, state->left->reg1, state->right->reg1);
479 }
480
481 reg: CEE_AND (reg, OP_ICONST) {
482         MONO_EMIT_BIALU_IMM (s, tree, OP_IAND_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
483 }
484
485 reg: CEE_OR (reg, reg) {
486         MONO_EMIT_BIALU (s, tree, OP_IOR, state->reg1, state->left->reg1, state->right->reg1);
487 }
488
489 reg: CEE_OR (reg, OP_ICONST) {
490         MONO_EMIT_BIALU_IMM (s, tree, OP_IOR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
491 }
492
493 reg: CEE_XOR (reg, reg) {
494         MONO_EMIT_BIALU (s, tree, OP_IXOR, state->reg1, state->left->reg1, state->right->reg1);
495 }
496
497 reg: CEE_XOR (reg, OP_ICONST) {
498         MONO_EMIT_BIALU_IMM (s, tree, OP_IXOR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
499 }
500
501 reg: CEE_NEG (reg) {
502         MONO_EMIT_UNALU (s, tree, OP_INEG, state->reg1, state->left->reg1);
503 }
504
505 reg: CEE_NOT (reg) {
506         MONO_EMIT_UNALU (s, tree, OP_INOT, state->reg1, state->left->reg1);
507 }
508
509 reg: CEE_ADD (reg, reg) {
510         MONO_EMIT_BIALU (s, tree, OP_IADD, state->reg1, state->left->reg1, state->right->reg1);
511 }
512
513 reg: CEE_ADD (reg, OP_ICONST) {
514         MONO_EMIT_BIALU_IMM (s, tree, OP_IADD_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
515 }
516
517 reg: CEE_ADD_OVF (reg, reg) {
518         MONO_EMIT_NEW_BIALU (s, OP_IADDCC, state->reg1, state->left->reg1, state->right->reg1);
519         MONO_EMIT_NEW_COND_EXC (s, IOV, "OverflowException");
520 }
521
522 reg: CEE_ADD_OVF_UN (reg, reg) {
523         MONO_EMIT_NEW_BIALU (s, OP_IADDCC, state->reg1, state->left->reg1, state->right->reg1);
524         MONO_EMIT_NEW_COND_EXC (s, IC, "OverflowException");
525 }
526
527 reg: CEE_SUB (reg, reg) {
528         MONO_EMIT_BIALU (s, tree, OP_ISUB, state->reg1, state->left->reg1, state->right->reg1);
529 }
530
531 reg: CEE_SUB (reg, CEE_LDIND_I4 (OP_REGVAR)) {
532         MONO_EMIT_BIALU (s, tree, OP_ISUB, state->reg1, state->left->reg1, state->right->left->tree->dreg);
533 }
534
535 reg: CEE_SUB (reg, OP_ICONST) {
536         MONO_EMIT_BIALU_IMM (s, tree, OP_ISUB_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
537 }
538
539 reg: CEE_SUB_OVF (reg, reg) {
540         MONO_EMIT_NEW_BIALU (s, OP_ISUBCC, state->reg1, state->left->reg1, state->right->reg1);
541         MONO_EMIT_NEW_COND_EXC (s, IOV, "OverflowException");
542 }
543
544 reg: CEE_SUB_OVF_UN (reg, reg) {
545         MONO_EMIT_NEW_BIALU (s, OP_ISUBCC, state->reg1, state->left->reg1, state->right->reg1);
546         MONO_EMIT_NEW_COND_EXC (s, IC, "OverflowException");
547 }
548
549 #
550 # shift operations
551 #
552
553 reg: CEE_SHL (reg, reg) {
554         MONO_EMIT_BIALU (s, tree, OP_ISHL, state->reg1, state->left->reg1, state->right->reg1);
555 }
556
557 reg: CEE_SHL (reg, OP_ICONST) {
558         MONO_EMIT_BIALU_IMM (s, tree, OP_ISHL_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
559 }
560
561 reg: CEE_SHR (reg, reg) {
562         MONO_EMIT_BIALU (s, tree, OP_ISHR, state->reg1, state->left->reg1, state->right->reg1);
563 }
564
565 reg: CEE_SHR (reg, OP_ICONST) {
566         MONO_EMIT_BIALU_IMM (s, tree, OP_ISHR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
567 }
568
569 reg: CEE_SHR_UN (reg, reg) {
570         MONO_EMIT_BIALU (s, tree, OP_ISHR_UN, state->reg1, state->left->reg1, state->right->reg1);
571 }
572
573 reg: CEE_SHR_UN (reg, OP_ICONST) {
574         MONO_EMIT_BIALU_IMM (s, tree, OP_ISHR_UN_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
575 }
576
577 #
578 # mult/div operations
579 #
580
581 reg: CEE_MUL (reg, reg) {
582         MONO_EMIT_BIALU (s, tree, OP_IMUL, state->reg1, state->left->reg1, state->right->reg1);
583 }
584
585 reg: CEE_MUL (reg, OP_ICONST) {
586         MONO_EMIT_BIALU_IMM (s, tree, OP_IMUL_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
587 }
588
589 reg: CEE_MUL_OVF (reg, reg) {
590         MONO_EMIT_BIALU (s, tree, OP_IMUL_OVF, state->reg1, state->left->reg1, state->right->reg1);
591 }
592
593 reg: CEE_MUL_OVF_UN (reg, reg) {
594         MONO_EMIT_BIALU (s, tree, OP_IMUL_OVF_UN, state->reg1, state->left->reg1, state->right->reg1);
595 }
596
597 reg: CEE_DIV (reg, reg) {
598         MONO_EMIT_BIALU (s, tree, OP_IDIV, state->reg1, state->left->reg1, state->right->reg1);
599 }
600
601 #reg: CEE_DIV (reg, OP_ICONST) {
602 #       MONO_EMIT_BIALU_IMM (s, tree, OP_IDIV_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
603 #}
604
605 reg: CEE_DIV_UN (reg, reg) {
606         MONO_EMIT_BIALU (s, tree, OP_IDIV_UN, state->reg1, state->left->reg1, state->right->reg1);
607 }
608
609 #reg: CEE_DIV_UN (reg, OP_ICONST) {
610 #       MONO_EMIT_BIALU_IMM (s, tree, OP_IDIV_UN_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
611 #}
612
613 reg: CEE_REM (reg, reg) {
614         MONO_EMIT_BIALU (s, tree, OP_IREM, state->reg1, state->left->reg1, state->right->reg1);
615 }
616
617 #reg: CEE_REM (reg, OP_ICONST) {
618 #       MONO_EMIT_BIALU_IMM (s, tree, OP_IREM_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
619 #}
620
621 reg: CEE_REM_UN (reg, reg) {
622         MONO_EMIT_BIALU (s, tree, OP_IREM_UN, state->reg1, state->left->reg1, state->right->reg1);
623 }
624
625 #reg: CEE_REM_UN (reg, OP_ICONST) {
626 #       MONO_EMIT_BIALU_IMM (s, tree, OP_IREM_UN_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
627 #}
628
629 c32flags: OP_COMPARE (reg, reg) {
630         tree->opcode = OP_ICOMPARE;
631         tree->sreg1 = state->left->reg1;
632         tree->sreg2 = state->right->reg1;
633         mono_bblock_add_inst (s->cbb, tree);
634 }
635
636 c32flags: OP_COMPARE (CEE_LDIND_I (OP_REGVAR), CEE_LDIND_I (OP_REGVAR)) {
637         tree->opcode = OP_ICOMPARE;
638         tree->sreg1 = state->left->left->tree->dreg;
639         tree->sreg2 = state->right->left->tree->dreg;
640         mono_bblock_add_inst (s->cbb, tree);
641 }
642
643 c32flags: OP_COMPARE (CEE_LDIND_I (OP_REGVAR), OP_ICONST) {
644         tree->opcode = OP_ICOMPARE_IMM;
645         tree->sreg1 = state->left->left->tree->dreg;
646         tree->inst_imm = state->right->tree->inst_c0;
647         mono_bblock_add_inst (s->cbb, tree);
648 }
649
650 c32flags: OP_COMPARE (CEE_LDIND_I4 (OP_REGVAR), reg) {
651         tree->opcode = OP_ICOMPARE;
652         tree->sreg1 = state->left->left->tree->dreg;
653         tree->sreg2 = state->right->reg1;
654         mono_bblock_add_inst (s->cbb, tree);
655 }
656
657 c32flags: OP_COMPARE (CEE_LDIND_I4 (OP_REGVAR), OP_ICONST) {
658         tree->opcode = OP_ICOMPARE_IMM;
659         tree->sreg1 = state->left->left->tree->dreg;
660         tree->inst_imm = state->right->tree->inst_c0;
661         mono_bblock_add_inst (s->cbb, tree);
662 }
663
664 c32flags: OP_COMPARE (reg, OP_ICONST) {
665         tree->opcode = OP_ICOMPARE_IMM;
666         tree->sreg1 = state->left->reg1;
667         tree->inst_imm = state->right->tree->inst_c0;
668         mono_bblock_add_inst (s->cbb, tree);
669 }
670
671 stmt: CEE_BNE_UN (c32flags) {
672         tree->opcode = OP_IBNE_UN;
673         mono_bblock_add_inst (s->cbb, tree);
674 }
675
676 stmt: CEE_BEQ (c32flags) {
677         tree->opcode = OP_IBEQ;
678         mono_bblock_add_inst (s->cbb, tree);
679 }
680
681 stmt: CEE_BLT (c32flags) {
682         tree->opcode = OP_IBLT;
683         mono_bblock_add_inst (s->cbb, tree);
684 }
685
686 stmt: CEE_BLT_UN (c32flags) {
687         tree->opcode = OP_IBLT_UN;
688         mono_bblock_add_inst (s->cbb, tree);
689 }
690
691 stmt: CEE_BGT (c32flags) {
692         tree->opcode = OP_IBGT;
693         mono_bblock_add_inst (s->cbb, tree);
694 }
695
696 stmt: CEE_BGT_UN (c32flags) {
697         tree->opcode = OP_IBGT_UN;
698         mono_bblock_add_inst (s->cbb, tree);
699 }
700
701 stmt: CEE_BGE  (c32flags) {
702         tree->opcode = OP_IBGE;
703         mono_bblock_add_inst (s->cbb, tree);
704 }
705
706 stmt: CEE_BGE_UN (c32flags) {
707         tree->opcode = OP_IBGE_UN;
708         mono_bblock_add_inst (s->cbb, tree);
709 }
710
711 stmt: CEE_BLE  (c32flags) {
712         tree->opcode = OP_IBLE;
713         mono_bblock_add_inst (s->cbb, tree);
714 }
715
716 stmt: CEE_BLE_UN (c32flags) {
717         tree->opcode = OP_IBLE_UN;
718         mono_bblock_add_inst (s->cbb, tree);
719 }
720
721 reg: OP_CEQ (c32flags) {        
722         tree->opcode = OP_ICEQ;
723         tree->dreg = state->reg1;
724         mono_bblock_add_inst (s->cbb, tree);
725 }
726
727 reg: OP_CLT (c32flags) {        
728         tree->opcode = OP_ICLT;
729         tree->dreg = state->reg1;
730         mono_bblock_add_inst (s->cbb, tree);
731 }
732
733 reg: OP_CLT_UN (c32flags) {     
734         tree->opcode = OP_ICLT_UN;
735         tree->dreg = state->reg1;
736         mono_bblock_add_inst (s->cbb, tree);
737 }
738
739 reg: OP_CGT (c32flags) {        
740         tree->opcode = OP_ICGT;
741         tree->dreg = state->reg1;
742         mono_bblock_add_inst (s->cbb, tree);
743 }
744
745 reg: OP_CGT_UN (c32flags) {     
746         tree->opcode = OP_ICGT_UN;
747         tree->dreg = state->reg1;
748         mono_bblock_add_inst (s->cbb, tree);
749 }
750
751 %%