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