2007-11-28 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / mini / inssel-long32-mips.brg
1 %%
2
3 #
4 # inssel-long32-mips.brg: burg file for integer instructions on 32bit MIPS
5 #
6 # Author:
7 #   Mark Mason (mason@broadcom.com)
8 #
9 # Based on inssel-long32.brg by:
10 #   Dietmar Maurer (dietmar@ximian.com)
11 #
12 # (C) 2006 Broadcom
13 # (C) 2002 Ximian, Inc.
14 #
15
16 #
17 # 32 bit rules
18 #
19
20 #
21 # basic alu operations
22 #
23
24 reg: CEE_AND (reg, reg),
25 reg: CEE_OR (reg, reg),
26 reg: CEE_XOR (reg, reg),
27 reg: CEE_ADD (reg, reg),
28 reg: CEE_SUB (reg, reg),
29 reg: CEE_MUL (reg, reg),
30 reg: CEE_MUL_OVF (reg, reg),
31 reg: CEE_MUL_OVF_UN (reg, reg),
32 reg: CEE_DIV (reg, reg),
33 reg: CEE_DIV_UN (reg, reg),
34 reg: CEE_REM (reg, reg),
35 reg: CEE_REM_UN (reg, reg),
36 reg: CEE_SHL (reg, reg),
37 reg: CEE_SHR (reg, reg),
38 reg: CEE_SHR_UN (reg, reg) {
39         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
40 }
41
42 reg: CEE_NEG (reg),
43 reg: CEE_NOT (reg) {
44         MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
45 }
46
47
48 reg: CEE_AND (reg, OP_ICONST) {
49         MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
50 }
51
52 reg: CEE_OR (reg, OP_ICONST) {
53         MONO_EMIT_BIALU_IMM (s, tree, OP_OR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
54 }
55
56 reg: CEE_XOR (reg, OP_ICONST) {
57         MONO_EMIT_BIALU_IMM (s, tree, OP_XOR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
58 }
59
60 reg: CEE_ADD (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: CEE_SUB (reg, OP_ICONST) {
65         MONO_EMIT_BIALU_IMM (s, tree, OP_SUB_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
66 }
67
68 reg: CEE_MUL (reg, OP_ICONST) {
69         MONO_EMIT_BIALU_IMM (s, tree, OP_MUL_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
70 }
71
72 reg: CEE_SHL (reg, OP_ICONST) {
73         MONO_EMIT_BIALU_IMM (s, tree, OP_SHL_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
74 }
75
76 reg: CEE_SHR (reg, OP_ICONST) {
77         MONO_EMIT_BIALU_IMM (s, tree, OP_SHR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
78 }
79
80 reg: CEE_SHR_UN (reg, OP_ICONST) {
81         MONO_EMIT_BIALU_IMM (s, tree, OP_SHR_UN_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
82 }
83
84 reg: CEE_ADD_OVF (reg, reg) {
85         MONO_EMIT_NEW_BIALU (s, OP_ADDCC, state->reg1, state->left->reg1, state->right->reg1);
86         MONO_EMIT_NEW_COND_EXC (s, OV, "OverflowException");
87 }
88
89 reg: CEE_ADD_OVF_UN (reg, reg) {
90         MONO_EMIT_NEW_BIALU (s, OP_ADDCC, state->reg1, state->left->reg1, state->right->reg1);
91         MONO_EMIT_NEW_COND_EXC (s, C, "OverflowException");
92 }
93
94 reg: CEE_SUB (reg, CEE_LDIND_I4 (OP_REGVAR)) {
95         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->left->tree->dreg);
96 }
97
98 reg: CEE_SUB_OVF (reg, reg) {
99         MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1);
100         MONO_EMIT_NEW_COND_EXC (s, OV, "OverflowException");
101 }
102
103 reg: CEE_SUB_OVF_UN (reg, reg) {
104         MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1);
105         MONO_EMIT_NEW_COND_EXC (s, C, "OverflowException");
106 }
107
108 # cflags: OP_COMPARE (reg, reg) {
109 #       tree->sreg1 = state->left->reg1;
110 #       tree->sreg2 = state->right->reg1;
111 #       mono_bblock_add_inst (s->cbb, tree);
112 # }
113
114 # cflags: OP_COMPARE (CEE_LDIND_REF (OP_REGVAR), reg),
115 # cflags: OP_COMPARE (CEE_LDIND_I (OP_REGVAR), reg),
116 # cflags: OP_COMPARE (CEE_LDIND_I4 (OP_REGVAR), reg),
117 # cflags: OP_COMPARE (CEE_LDIND_U4 (OP_REGVAR), reg) {
118 #       tree->sreg1 = state->left->left->tree->dreg;
119 #       tree->sreg2 = state->right->reg1;
120 #       mono_bblock_add_inst (s->cbb, tree);
121 # }
122
123 # cflags: OP_COMPARE (CEE_LDIND_REF (OP_REGVAR), CEE_LDIND_REF (OP_REGVAR)),
124 # cflags: OP_COMPARE (CEE_LDIND_I (OP_REGVAR), CEE_LDIND_I (OP_REGVAR)),
125 # cflags: OP_COMPARE (CEE_LDIND_I4 (OP_REGVAR), CEE_LDIND_I4 (OP_REGVAR)),
126 # cflags: OP_COMPARE (CEE_LDIND_U4 (OP_REGVAR), CEE_LDIND_U4 (OP_REGVAR)) {
127 #       tree->sreg1 = state->left->left->tree->dreg;
128 #       tree->sreg2 = state->right->left->tree->dreg;
129 #       mono_bblock_add_inst (s->cbb, tree);
130 # }
131
132 # cflags: OP_COMPARE (CEE_LDIND_REF (OP_REGVAR), OP_ICONST),
133 # cflags: OP_COMPARE (CEE_LDIND_I (OP_REGVAR), OP_ICONST),
134 # cflags: OP_COMPARE (CEE_LDIND_I4 (OP_REGVAR), OP_ICONST),
135 # cflags: OP_COMPARE (CEE_LDIND_U4 (OP_REGVAR), OP_ICONST) {
136 #       tree->opcode = OP_COMPARE_IMM;
137 #       tree->sreg1 = state->left->left->tree->dreg;
138 #       tree->inst_imm = state->right->tree->inst_c0;
139 #       mono_bblock_add_inst (s->cbb, tree);
140 # }
141
142 # cflags: OP_COMPARE (reg, OP_ICONST) {
143 #       tree->opcode = OP_COMPARE_IMM;
144 #       tree->sreg1 = state->left->reg1;
145 #       tree->inst_imm = state->right->tree->inst_c0;
146 #       mono_bblock_add_inst (s->cbb, tree);
147 # }
148
149 # stmt: CEE_BNE_UN (cflags),
150 # stmt: CEE_BEQ (cflags),
151 # stmt: CEE_BLT (cflags),
152 # stmt: CEE_BLT_UN (cflags),
153 # stmt: CEE_BGT (cflags),
154 # stmt: CEE_BGT_UN (cflags),
155 # stmt: CEE_BGE  (cflags),
156 # stmt: CEE_BGE_UN (cflags),
157 # stmt: CEE_BLE  (cflags),
158 # stmt: CEE_BLE_UN (cflags) {
159 #       mono_bblock_add_inst (s->cbb, tree);
160 # }
161
162 # reg: OP_CEQ (cflags),
163 # reg: OP_CLT (cflags),
164 # reg: OP_CLT_UN (cflags),
165 # reg: OP_CGT (cflags),
166 # reg: OP_CGT_UN (cflags) {     
167 #       tree->dreg = state->reg1;
168 #       mono_bblock_add_inst (s->cbb, tree);
169 # }
170
171
172
173 #
174 # 64 bit rules
175 #
176
177 #
178 # We use a new non-terminal called "lreg" for 64bit registers, and
179 # emulate lreg with 2 32bit registers.
180 #
181
182 stmt: CEE_POP (lreg) {
183         /* do nothing */
184 }
185
186 i8con: CEE_CONV_I8 (OP_ICONST) "0" {
187        int data = state->left->tree->inst_c0;
188         tree->opcode = OP_I8CONST;
189         tree->inst_ls_word = data;
190         if (data < 0)
191                 tree->inst_ms_word = -1;
192         else
193                 tree->inst_ms_word = 0;
194 }
195
196 i8con: CEE_CONV_U8 (OP_ICONST) "0" {
197         int data = state->left->tree->inst_c0;
198         tree->opcode = OP_I8CONST;
199         tree->inst_ls_word = data;
200         tree->inst_ms_word = 0;
201 }
202
203 i8con: OP_I8CONST "0"
204
205 lreg: OP_ICONST {
206        int data = state->tree->inst_c0;
207
208        MONO_EMIT_NEW_ICONST (s, state->reg1, data);
209
210        if (data >= 0)
211                MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
212        else 
213                MONO_EMIT_NEW_ICONST (s, state->reg2, -1);
214 }
215
216 lreg: OP_I8CONST {
217         MONO_EMIT_NEW_ICONST (s, state->reg1, tree->inst_ls_word);
218         MONO_EMIT_NEW_ICONST (s, state->reg2, tree->inst_ms_word);
219 }
220
221 lreg: CEE_LDIND_I8 (base) {
222         MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, state->reg1, 
223                                        state->left->tree->inst_basereg, state->left->tree->inst_offset + MINI_LS_WORD_OFFSET);
224         MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, state->reg2, 
225                                        state->left->tree->inst_basereg, state->left->tree->inst_offset + MINI_MS_WORD_OFFSET);
226 }
227
228 stmt: CEE_STIND_I8 (base, lreg) {
229         MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, state->left->tree->inst_basereg,
230                                      state->left->tree->inst_offset + MINI_LS_WORD_OFFSET, state->right->reg1);
231         MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, state->left->tree->inst_basereg,
232                                      state->left->tree->inst_offset + MINI_MS_WORD_OFFSET, state->right->reg2);
233 }
234
235 stmt: CEE_STIND_I8 (base, i8con) {
236         MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STOREI4_MEMBASE_IMM, state->left->tree->inst_basereg,
237                                          state->left->tree->inst_offset + MINI_LS_WORD_OFFSET, state->right->tree->inst_ls_word);
238         MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STOREI4_MEMBASE_IMM, state->left->tree->inst_basereg,
239                                          state->left->tree->inst_offset + MINI_MS_WORD_OFFSET, state->right->tree->inst_ms_word);
240 }
241
242 lreg: OP_BIGMUL (reg, reg),
243 lreg: OP_BIGMUL_UN (reg, reg) {
244         MONO_EMIT_NEW_BIALU (s, tree->opcode, state->reg1, state->left->reg1, state->right->reg1); 
245 }
246
247 lreg: OP_LONG_SHRUN_32 (lreg) {
248         /* just move the upper half to the lower and zero the high word */
249         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg2);
250         MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
251 }
252
253 reg: OP_LCONV_TO_I4 (OP_LONG_SHRUN_32 (lreg)),
254 reg: OP_LCONV_TO_U4 (OP_LONG_SHRUN_32 (lreg)) {
255         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->left->reg2);
256 }
257
258
259 lreg: OP_LONG_SHRUN_32 (CEE_LDIND_I8 (base)) {
260         /* just move the upper half to the lower and zero the high word */
261         MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, state->reg1, 
262                                        state->left->left->tree->inst_basereg, state->left->left->tree->inst_offset + MINI_MS_WORD_OFFSET);
263         MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
264 }
265
266 reg: OP_LCONV_TO_I4 (OP_LONG_SHRUN_32 (CEE_LDIND_I8 (base))),
267 reg: OP_LCONV_TO_U4 (OP_LONG_SHRUN_32 (CEE_LDIND_I8 (base))) {
268         /* just move the upper half to the lower and zero the high word */
269         MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, state->reg1, 
270                                        state->left->left->left->tree->inst_basereg,
271                                        state->left->left->left->tree->inst_offset + MINI_MS_WORD_OFFSET);
272 }
273
274 lreg: OP_LADD (lreg, i8con) {
275         int tmp1 = mono_regstate_next_int (s->rs);
276
277         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
278         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp1, state->reg1, state->left->reg1);
279         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
280         MONO_EMIT_BIALU (s, tree, CEE_ADD, state->reg2, tmp1, state->reg2);
281 }
282
283 lreg: OP_LADD (lreg, lreg) {
284         int tmp1 = mono_regstate_next_int (s->rs);
285
286         MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg1, state->left->reg1, state->right->reg1);
287         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp1, state->reg1, state->left->reg1);
288         MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg2, state->left->reg2, state->right->reg2);
289         MONO_EMIT_BIALU (s, tree, CEE_ADD, state->reg2, tmp1, state->reg2);
290 }
291
292 lreg: OP_LADD_OVF (lreg, lreg) {
293         int tmp1 = mono_regstate_next_int (s->rs);
294         int tmp2 = mono_regstate_next_int (s->rs);
295         int tmp3 = mono_regstate_next_int (s->rs);
296         int tmp4 = mono_regstate_next_int (s->rs);
297         int tmp5 = mono_regstate_next_int (s->rs);
298
299         MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg1, state->left->reg1, state->right->reg1);
300
301         /* tmp1 holds the carry from the low 32-bit to the high 32-bits */
302
303         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp5, state->reg1, state->left->reg1);
304
305         /* add the high 32-bits, and add in the carry from the low 32-bits */
306
307         MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg2, state->left->reg2, state->right->reg2);
308         MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg2, tmp5, state->reg2);
309
310         /* Overflow happens if
311          *      neg + neg = pos    or
312          *      pos + pos = neg
313          * XOR of the high bits returns 0 if the signs match
314          * XOR of that with the high bit of the result return 1 if overflow.
315          */
316
317         /* tmp1 = 0 if the signs of the two inputs match, 1 otherwise */
318         MONO_EMIT_NEW_BIALU (s, CEE_XOR, tmp1, state->left->reg2, state->right->reg2);
319
320         /* set tmp2 = 0 if bit31 of results matches is different than the operands */
321         MONO_EMIT_NEW_BIALU (s, CEE_XOR, tmp2, state->reg2, state->right->reg2);
322         MONO_EMIT_NEW_UNALU (s, CEE_NOT, tmp2, tmp2);
323
324         /* OR(tmp1, tmp2) = 0 if both conditions are true */
325         MONO_EMIT_NEW_BIALU (s, CEE_OR, tmp3, tmp2, tmp1);
326
327         MONO_EMIT_NEW_BIALU_IMM (s, OP_SHR_IMM, tmp4, tmp3, 31);
328
329         /* Now, if (tmp4 == 0) then overflow */
330         MONO_EMIT_NEW_COMPARE_EXC (s, EQ, tmp4, mips_zero, "OverflowException");
331 }
332
333 lreg: OP_LADD_OVF_UN (lreg, lreg) {
334         int tmp1 = mono_regstate_next_int (s->rs);
335         int tmp2 = mono_regstate_next_int (s->rs);
336
337         MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg1, state->left->reg1, state->right->reg1);
338         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp1, state->reg1, state->left->reg1);
339         MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg2, state->left->reg2, state->right->reg2);
340         MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg2, tmp1, state->reg2);
341         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp2, state->reg2, state->left->reg2);
342         MONO_EMIT_NEW_COMPARE_EXC (s, NE_UN, tmp2, mips_zero, "OverflowException");
343 }
344
345 lreg: OP_LSUB (lreg, i8con) {
346         int tmp1 = mono_regstate_next_int (s->rs);
347
348         MONO_EMIT_NEW_BIALU_IMM (s, OP_SUB_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
349         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp1, state->left->reg1, state->reg1);
350         MONO_EMIT_NEW_BIALU_IMM (s, OP_SUB_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
351         MONO_EMIT_BIALU (s, tree, CEE_SUB, state->reg2, state->reg2, tmp1);
352 }
353
354 lreg: OP_LSUB (lreg, lreg) {
355         int tmp1 = mono_regstate_next_int (s->rs);
356
357         MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg1, state->left->reg1, state->right->reg1);
358         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp1, state->left->reg1, state->reg1);
359         MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg2, state->left->reg2, state->right->reg2);
360         MONO_EMIT_BIALU (s, tree, CEE_SUB, state->reg2, state->reg2, tmp1);
361 }
362
363 lreg: OP_LSUB_OVF (lreg, lreg) {
364         int tmp1 = mono_regstate_next_int (s->rs);
365         int tmp2 = mono_regstate_next_int (s->rs);
366         int tmp3 = mono_regstate_next_int (s->rs);
367         int tmp4 = mono_regstate_next_int (s->rs);
368         int tmp5 = mono_regstate_next_int (s->rs);
369
370         MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg1, state->left->reg1, state->right->reg1);
371         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp5, state->left->reg1, state->reg1);
372         MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg2, state->left->reg2, state->right->reg2);
373         MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg2, state->reg2, tmp5);
374
375         /* Overflow happens if
376          *      neg - pos = pos    or
377          *      pos - neg = neg
378          * XOR of bit31 of the lhs & rhs = 1 if the signs are different
379          *
380          * tmp1 = (lhs ^ rhs)
381          * tmp2 = (lhs ^ result)
382          * if ((tmp1 < 0) & (tmp2 < 0)) then overflow
383          */
384
385         MONO_EMIT_NEW_BIALU (s, CEE_XOR, tmp1, state->left->reg2, state->right->reg2);
386         MONO_EMIT_NEW_BIALU (s, CEE_XOR, tmp2, state->left->reg2, state->reg2);
387         MONO_EMIT_NEW_BIALU (s, CEE_AND, tmp3, tmp2, tmp1);
388         MONO_EMIT_NEW_BIALU_IMM (s, OP_SHR_IMM, tmp4, tmp3, 31);
389
390         /* Now, if (tmp4 == 1) then overflow */
391         MONO_EMIT_NEW_COMPARE_EXC (s, NE_UN, tmp4, mips_zero, "OverflowException");
392 }
393
394 lreg: OP_LSUB_OVF_UN (lreg, lreg) {
395         int tmp1 = mono_regstate_next_int (s->rs);
396         int tmp2 = mono_regstate_next_int (s->rs);
397
398         MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg1, state->left->reg1, state->right->reg1);
399         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp1, state->left->reg1, state->reg1);
400         MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg2, state->left->reg2, state->right->reg2);
401         MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg2, state->reg2, tmp1);
402
403         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp2, state->left->reg2, state->reg2);
404         MONO_EMIT_NEW_COMPARE_EXC (s, NE_UN, tmp2, mips_zero, "OverflowException");
405 }
406
407 lreg: OP_LAND (lreg, lreg) {    
408         MONO_EMIT_NEW_BIALU (s, CEE_AND, state->reg1, state->left->reg1, state->right->reg1);
409         MONO_EMIT_BIALU (s, tree, CEE_AND, state->reg2, state->left->reg2, state->right->reg2);
410 }
411
412 lreg: OP_LAND (lreg, i8con) {   
413         if (state->right->tree->inst_ls_word == 0xffffffff)
414                 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
415         else if (state->right->tree->inst_ls_word == 0)
416                 MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
417         else
418                 MONO_EMIT_NEW_BIALU_IMM (s, OP_AND_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
419         if (state->right->tree->inst_ms_word == 0xffffffff)
420                 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
421         else if (state->right->tree->inst_ms_word == 0)
422                 MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
423         else
424                 MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
425 }
426
427 lreg: OP_LOR (lreg, lreg) {
428         MONO_EMIT_NEW_BIALU (s, CEE_OR, state->reg1, state->left->reg1, state->right->reg1);
429         MONO_EMIT_BIALU (s, tree, CEE_OR, state->reg2, state->left->reg2, state->right->reg2);
430 }
431
432 lreg: OP_LOR (lreg, i8con) {
433         MONO_EMIT_NEW_BIALU_IMM (s, OP_OR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
434         MONO_EMIT_BIALU_IMM (s, tree, OP_OR_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
435 }
436
437 lreg: OP_LXOR (lreg, lreg) {
438         MONO_EMIT_NEW_BIALU (s, CEE_XOR, state->reg1, state->left->reg1, state->right->reg1);
439         MONO_EMIT_BIALU (s, tree, CEE_XOR, state->reg2, state->left->reg2, state->right->reg2);
440 }
441
442 lreg: OP_LXOR (lreg, i8con) {
443         MONO_EMIT_NEW_BIALU_IMM (s, OP_XOR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
444         MONO_EMIT_BIALU_IMM (s, tree, OP_XOR_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
445 }
446
447 lreg: OP_LNOT (lreg) {
448         MONO_EMIT_NEW_UNALU (s, CEE_NOT, state->reg1, state->left->reg1);
449         MONO_EMIT_UNALU (s, tree, CEE_NOT, state->reg2, state->left->reg2);
450 }
451
452 lreg: OP_LNEG (lreg) "4" {
453         MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg1, mips_zero, state->left->reg1);
454         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, mips_zero, state->reg1);
455         MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg2, mips_zero, state->left->reg2);
456         MONO_EMIT_BIALU (s, tree, CEE_SUB, state->reg2, state->reg2, mips_at);
457 }
458
459 reg: OP_CEQ (OP_LCOMPARE (lreg, lreg)) {        
460         MonoInst *word_differs;
461         int lreg1 = state->left->left->reg1;
462         int lreg2 = state->left->left->reg2;
463         int rreg1 = state->left->right->reg1;
464         int rreg2 = state->left->right->reg2;
465         
466         MONO_NEW_LABEL (s, word_differs);
467
468         MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
469         MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BNE_UN, lreg2, rreg2, word_differs);
470         MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BNE_UN, lreg1, rreg1, word_differs);
471         MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
472         
473         mono_bblock_add_inst (s->cbb, word_differs);
474 }
475
476 reg: OP_CLT (OP_LCOMPARE (lreg, lreg)) {        
477         MonoInst *set_to_0, *set_to_1;
478         int lreg1 = state->left->left->reg1;
479         int lreg2 = state->left->left->reg2;
480         int rreg1 = state->left->right->reg1;
481         int rreg2 = state->left->right->reg2;
482         
483         MONO_NEW_LABEL (s, set_to_0);
484         MONO_NEW_LABEL (s, set_to_1);
485
486         MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
487         MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BGT, lreg2, rreg2, set_to_0);
488         MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BNE_UN, lreg2, rreg2, set_to_1);
489         MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BGE_UN, lreg1, rreg1, set_to_0);
490         mono_bblock_add_inst (s->cbb, set_to_1);
491         MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
492         mono_bblock_add_inst (s->cbb, set_to_0);
493 }       
494
495 reg: OP_CLT_UN (OP_LCOMPARE (lreg, lreg)) {     
496         MonoInst *set_to_0, *set_to_1;
497         int lreg1 = state->left->left->reg1;
498         int lreg2 = state->left->left->reg2;
499         int rreg1 = state->left->right->reg1;
500         int rreg2 = state->left->right->reg2;
501         
502         MONO_NEW_LABEL (s, set_to_0);
503         MONO_NEW_LABEL (s, set_to_1);
504
505         MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
506
507         MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
508         MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BGT_UN, lreg2, rreg2, set_to_0);
509         MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BNE_UN, lreg2, rreg2, set_to_1);
510         MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BGE_UN, lreg1, rreg1, set_to_0);
511         mono_bblock_add_inst (s->cbb, set_to_1);
512         MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
513         mono_bblock_add_inst (s->cbb, set_to_0);
514 }
515
516 reg: OP_CGT (OP_LCOMPARE (lreg, lreg)) {        
517         MonoInst *set_to_0, *set_to_1;
518         int lreg1 = state->left->left->reg1;
519         int lreg2 = state->left->left->reg2;
520         int rreg1 = state->left->right->reg1;
521         int rreg2 = state->left->right->reg2;
522         
523         MONO_NEW_LABEL (s, set_to_0);
524         MONO_NEW_LABEL (s, set_to_1);
525
526         MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
527         MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BGT, rreg2, lreg2, set_to_0);
528         MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BNE_UN, rreg2, lreg2, set_to_1);
529         MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BGE_UN, rreg1, lreg1, set_to_0);
530         mono_bblock_add_inst (s->cbb, set_to_1);
531         MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
532         mono_bblock_add_inst (s->cbb, set_to_0);
533 }
534
535 reg: OP_CGT_UN (OP_LCOMPARE (lreg, lreg)) {     
536         MonoInst *set_to_0, *set_to_1;
537         int lreg1 = state->left->left->reg1;
538         int lreg2 = state->left->left->reg2;
539         int rreg1 = state->left->right->reg1;
540         int rreg2 = state->left->right->reg2;
541         
542         MONO_NEW_LABEL (s, set_to_0);
543         MONO_NEW_LABEL (s, set_to_1);
544
545         MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
546         MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BGT_UN, rreg2, lreg2, set_to_0);
547         MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BNE_UN, rreg2, lreg2, set_to_1);
548         MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BGE_UN, rreg1, lreg1, set_to_0);
549         mono_bblock_add_inst (s->cbb, set_to_1);
550         MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
551         mono_bblock_add_inst (s->cbb, set_to_0);
552 }
553
554 stmt: CEE_BNE_UN (OP_LCOMPARE (lreg, lreg)) {
555         int lreg1 = state->left->left->reg1;
556         int lreg2 = state->left->left->reg2;
557         int rreg1 = state->left->right->reg1;
558         int rreg2 = state->left->right->reg2;
559
560         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_true_bb);
561         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg1, rreg1, tree->inst_true_bb);
562 }
563
564 stmt: CEE_BNE_UN (OP_LCOMPARE (lreg, i8con)) {
565         int lreg1 = state->left->left->reg1;
566         int lreg2 = state->left->left->reg2;
567         int rreg1 = mono_regstate_next_int (s->rs);
568         int rreg2 = mono_regstate_next_int (s->rs);
569
570         MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
571         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_true_bb);
572         MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
573         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg1, rreg1, tree->inst_true_bb);
574 }
575
576 stmt: CEE_BEQ (OP_LCOMPARE (lreg, lreg)) {
577         int lreg1 = state->left->left->reg1;
578         int lreg2 = state->left->left->reg2;
579         int rreg1 = state->left->right->reg1;
580         int rreg2 = state->left->right->reg2;
581
582         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_false_bb);
583         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BEQ, lreg1, rreg1, tree->inst_true_bb);
584 }
585
586 stmt: CEE_BEQ (OP_LCOMPARE (lreg, i8con)) {
587         int lreg1 = state->left->left->reg1;
588         int lreg2 = state->left->left->reg2;
589         int rreg1 = mono_regstate_next_int (s->rs);
590         int rreg2 = mono_regstate_next_int (s->rs);
591
592         MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
593         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_false_bb);
594         MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
595         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BEQ, lreg1, rreg1, tree->inst_true_bb);
596 }
597
598 stmt: CEE_BLE (OP_LCOMPARE (lreg, lreg)) {
599         int lreg1 = state->left->left->reg1;
600         int lreg2 = state->left->left->reg2;
601         int rreg1 = state->left->right->reg1;
602         int rreg2 = state->left->right->reg2;
603
604         /* if (lreg2 < rreg2) -> true */
605         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
606         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
607
608         /* if (rreg2 < lreg2) -> false */
609         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, rreg2, lreg2);
610         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
611
612         /* (lreg2 == rreg2), if (lreg1 <= rreg1) -> true  [or if (rreg1 < lreg1) -> false] */
613
614         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
615         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
616         MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
617 }
618
619 stmt: CEE_BLE (OP_LCOMPARE (lreg, i8con)) {
620         int lreg1 = state->left->left->reg1;
621         int lreg2 = state->left->left->reg2;
622         int rreg1 = mono_regstate_next_int (s->rs);
623         int rreg2 = mono_regstate_next_int (s->rs);
624
625         MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
626
627         /* if (lreg2 < rreg2) -> true */
628         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
629         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
630
631         /* if (rreg2 < lreg2) -> false */
632         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, rreg2, lreg2);
633         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
634
635         /* (rreg2 == lreg2), if (lreg1 <= rreg1) -> true  [or if (rreg1 < lreg1) -> false] */
636
637         MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
638         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
639         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
640         MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
641 }
642
643 stmt: CEE_BLE_UN (OP_LCOMPARE (lreg, lreg)) {
644         int lreg1 = state->left->left->reg1;
645         int lreg2 = state->left->left->reg2;
646         int rreg1 = state->left->right->reg1;
647         int rreg2 = state->left->right->reg2;
648
649         /* if (lreg2 < rreg2) -> true */
650         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
651         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
652
653         /* if (rreg2 < lreg2) -> false */
654         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg2, lreg2);
655         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
656
657         /* (lreg2 == rreg2), if (lreg1 <= rreg1) -> true  [or if (rreg1 < lreg1) -> false] */
658
659         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
660         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
661         MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
662 }
663
664 stmt: CEE_BLE_UN (OP_LCOMPARE (lreg, i8con)) {
665         int lreg1 = state->left->left->reg1;
666         int lreg2 = state->left->left->reg2;
667         int rreg1 = mono_regstate_next_int (s->rs);
668         int rreg2 = mono_regstate_next_int (s->rs);
669
670         MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
671
672         /* if (lreg2 < rreg2) -> true */
673         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
674         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
675
676         /* if (rreg2 < lreg2) -> false */
677         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg2, lreg2);
678         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
679
680         /* (rreg2 == lreg2), if (rreg1 <= lreg1) -> true  [or if (rreg1 < lreg1) -> false] */
681
682         MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
683         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
684         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
685         MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
686 }
687
688 stmt: CEE_BGE (OP_LCOMPARE (lreg, lreg)) {
689         int lreg1 = state->left->left->reg1;
690         int lreg2 = state->left->left->reg2;
691         int rreg1 = state->left->right->reg1;
692         int rreg2 = state->left->right->reg2;
693
694         /* if (lreg2 < rreg2) -> false */
695         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
696         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
697
698         /* if (rreg2 != lreg2) -> false */
699         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, rreg2, lreg2, tree->inst_false_bb);
700
701         /* (rreg2 == lreg2), so if (lreg1 < rreg1) -> false */
702         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg1, rreg1);
703         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
704         MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
705 }
706
707 stmt: CEE_BGE (OP_LCOMPARE (lreg, i8con)) {
708         int lreg1 = state->left->left->reg1;
709         int lreg2 = state->left->left->reg2;
710         int rreg1 = mono_regstate_next_int (s->rs);
711         int rreg2 = mono_regstate_next_int (s->rs);
712
713         MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
714
715         /* if (lreg2 < rreg2) -> false */
716         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
717         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
718
719         /* if (rreg2 != lreg2) -> false */
720         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, rreg2, lreg2, tree->inst_false_bb);
721
722         MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
723
724         /* (rreg2 == lreg2), so if (lreg1 < rreg1) -> false */
725         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg1, rreg1);
726         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
727         MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
728 }
729
730 stmt: CEE_BGE_UN (OP_LCOMPARE (lreg, lreg)) {
731         int lreg1 = state->left->left->reg1;
732         int lreg2 = state->left->left->reg2;
733         int rreg1 = state->left->right->reg1;
734         int rreg2 = state->left->right->reg2;
735
736         /* if (lreg2 < rreg2) -> false */
737         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
738         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
739
740         /* if (rreg2 != lreg2) -> false */
741         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, rreg2, lreg2, tree->inst_false_bb);
742
743         /* (rreg2 == lreg2), so if (lreg1 < rreg1) -> false */
744         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg1, rreg1);
745         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
746         MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
747 }
748
749 stmt: CEE_BGE_UN (OP_LCOMPARE (lreg, i8con)) {
750         int lreg1 = state->left->left->reg1;
751         int lreg2 = state->left->left->reg2;
752         int rreg1 = mono_regstate_next_int (s->rs);
753         int rreg2 = mono_regstate_next_int (s->rs);
754
755         MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
756
757         /* if (lreg2 < rreg2) -> false */
758         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
759         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
760
761         /* if (rreg2 != lreg2) -> false */
762         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, rreg2, lreg2, tree->inst_false_bb);
763
764         MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
765
766         /* (rreg2 == lreg2), so if (lreg1 < rreg1) -> false */
767         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg1, rreg1);
768         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
769         MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
770 }
771
772 stmt: CEE_BLT (OP_LCOMPARE (lreg, lreg)) {
773         int lreg1 = state->left->left->reg1;
774         int lreg2 = state->left->left->reg2;
775         int rreg1 = state->left->right->reg1;
776         int rreg2 = state->left->right->reg2;
777
778         /* if (lreg2 < rreg2) -> true */
779         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
780         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
781
782         /* if (rreg2 < lreg2) -> false */
783         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, rreg2, lreg2);
784         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
785
786         /* (lreg2 == rreg2), if (lreg1 < rreg1) -> true */
787         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg1, rreg1);
788         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
789         MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
790 }
791
792 stmt: CEE_BLT (OP_LCOMPARE (lreg, i8con)) {
793         int lreg1 = state->left->left->reg1;
794         int lreg2 = state->left->left->reg2;
795         int rreg1 = mono_regstate_next_int (s->rs);
796         int rreg2 = mono_regstate_next_int (s->rs);
797
798         MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
799
800         /* if (lreg2 < rreg2) -> true */
801         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
802         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
803
804         /* if (rreg2 < lreg2) -> false */
805         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, rreg2, lreg2);
806         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
807
808         MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
809
810         /* (lreg2 == rreg2), if (lreg1 < rreg1) -> true */
811         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg1, rreg1);
812         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
813         MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
814 }
815
816 stmt: CEE_BLT_UN (OP_LCOMPARE (lreg, lreg)) {
817         int lreg1 = state->left->left->reg1;
818         int lreg2 = state->left->left->reg2;
819         int rreg1 = state->left->right->reg1;
820         int rreg2 = state->left->right->reg2;
821
822         /* if (lreg2 < rreg2) -> true */
823         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
824         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
825
826         /* if (rreg2 < lreg2) -> false */
827         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg2, lreg2);
828         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
829
830         /* (lreg2 == rreg2), if (lreg1 < rreg1) -> true */
831         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg1, rreg1);
832         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
833         MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
834 }
835
836 stmt: CEE_BLT_UN (OP_LCOMPARE (lreg, i8con)) {
837         int lreg1 = state->left->left->reg1;
838         int lreg2 = state->left->left->reg2;
839         int rreg1 = mono_regstate_next_int (s->rs);
840         int rreg2 = mono_regstate_next_int (s->rs);
841
842         MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
843
844         /* if (lreg2 < rreg2) -> true */
845         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
846         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
847
848         /* if (rreg2 < lreg2) -> false */
849         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg2, lreg2);
850         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
851
852         MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
853
854         /* (lreg2 == rreg2), if (lreg1 < rreg1) -> true */
855         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg1, rreg1);
856         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
857         MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
858 }
859
860 stmt: CEE_BGT (OP_LCOMPARE (lreg, lreg)) {
861         int lreg1 = state->left->left->reg1;
862         int lreg2 = state->left->left->reg2;
863         int rreg1 = state->left->right->reg1;
864         int rreg2 = state->left->right->reg2;
865
866         /* if (lreg2 < rreg2) -> false */
867         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
868         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
869
870         /* if (rreg2 < lreg2) -> true */
871         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, rreg2, lreg2);
872         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
873
874         /* (rreg2 == lreg2), so if (lreg1 > rreg1) -> true */
875         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
876         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
877         MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
878 }
879
880 stmt: CEE_BGT (OP_LCOMPARE (lreg, i8con)) {
881         int lreg1 = state->left->left->reg1;
882         int lreg2 = state->left->left->reg2;
883         int rreg1 = mono_regstate_next_int (s->rs);
884         int rreg2 = mono_regstate_next_int (s->rs);
885
886         MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
887
888         /* if (lreg2 < rreg2) -> false */
889         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
890         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
891
892         /* if (rreg2 < lreg2) -> true */
893         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, rreg2, lreg2);
894         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
895
896         MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
897
898         /* (rreg2 == lreg2), so if (lreg1 > rreg1) -> true */
899         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
900         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
901         MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
902 }
903
904 stmt: CEE_BGT_UN (OP_LCOMPARE (lreg, lreg)) {
905         int lreg1 = state->left->left->reg1;
906         int lreg2 = state->left->left->reg2;
907         int rreg1 = state->left->right->reg1;
908         int rreg2 = state->left->right->reg2;
909
910         /* if (lreg2 < rreg2) -> false */
911         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
912         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
913
914         /* if (rreg2 < lreg2) -> true */
915         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg2, lreg2);
916         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
917
918         /* (rreg2 == lreg2), so if (lreg1 > rreg1) -> true */
919         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
920         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
921         MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
922 }
923
924 stmt: CEE_BGT_UN (OP_LCOMPARE (lreg, i8con)) {
925         int lreg1 = state->left->left->reg1;
926         int lreg2 = state->left->left->reg2;
927         int rreg1 = mono_regstate_next_int (s->rs);
928         int rreg2 = mono_regstate_next_int (s->rs);
929
930         MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
931
932         /* if (lreg2 < rreg2) -> false */
933         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
934         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
935
936         /* if (rreg2 < lreg2) -> true */
937         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg2, lreg2);
938         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
939
940         MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
941
942         /* (rreg2 == lreg2), so if (lreg1 > rreg1) -> true */
943         MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
944         MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
945         MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
946 }
947
948 lreg: CEE_CONV_I8 (OP_ICONST) {
949         int data = state->left->tree->inst_c0;
950
951        MONO_EMIT_NEW_ICONST (s, state->reg1, data);
952
953        if (data >= 0)
954                MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
955        else 
956                MONO_EMIT_NEW_ICONST (s, state->reg2, -1);
957 }
958
959 lreg: CEE_CONV_I8 (reg) {
960         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
961         MONO_EMIT_NEW_BIALU_IMM (s, OP_SHR_IMM, state->reg2, state->left->reg1, 31);
962 }
963
964 lreg: CEE_CONV_U8 (reg) {
965         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
966         MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
967 }
968
969 lreg: CEE_CONV_OVF_U8 (reg) {
970         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, 0, "OverflowException");
971         MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
972         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
973 }
974
975 lreg: CEE_CONV_OVF_I8 (reg) {
976         /* a signed 32 bit num always fits in a signed 64 bit one */
977         MONO_EMIT_NEW_BIALU_IMM (s, OP_SHR_IMM, state->reg2, state->left->reg1, 31);
978         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
979 }
980
981 lreg: CEE_CONV_OVF_I8_UN (reg) {
982         /* an unsigned 32 bit num always fits in a signed 64 bit one */
983         MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
984         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
985 }
986
987 lreg: CEE_CONV_OVF_U8_UN (reg) {
988         MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
989         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
990 }
991
992 freg: OP_LCONV_TO_R_UN (lreg) {
993         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->left->reg2);
994 }
995
996 lreg: OP_FCONV_TO_I8 (freg) {
997         MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
998 }
999
1000 lreg: OP_FCONV_TO_U8 (freg) {
1001         MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
1002 }
1003
1004 reg: OP_LCONV_TO_I4 (i8con) {
1005         MONO_EMIT_NEW_ICONST (s, state->reg1, state->left->tree->inst_ls_word);
1006 }
1007
1008 reg: OP_LCONV_TO_I4 (lreg),
1009 reg: OP_LCONV_TO_U4 (lreg) {
1010         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
1011 }
1012
1013 reg: OP_LCONV_TO_I4 (CEE_LDIND_I8 (base)),
1014 reg: OP_LCONV_TO_U4 (CEE_LDIND_I8 (base)) {
1015         MONO_EMIT_LOAD_MEMBASE_OP (s, tree, OP_LOADI4_MEMBASE, state->reg1, 
1016                                    state->left->left->tree->inst_basereg, 
1017                                    state->left->left->tree->inst_offset + MINI_LS_WORD_OFFSET);
1018 }
1019
1020 lreg: OP_LCONV_TO_U8 (lreg),
1021 lreg: OP_LCONV_TO_I8 (lreg) {
1022         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
1023         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
1024 }
1025
1026 reg: OP_LCONV_TO_U (lreg),
1027 reg: OP_LCONV_TO_I (lreg) {
1028         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
1029 }
1030
1031 reg: OP_LCONV_TO_I1 (lreg) {
1032         MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
1033 }
1034
1035 reg: OP_LCONV_TO_U1 (lreg) {
1036         MONO_EMIT_UNALU (s, tree, CEE_CONV_U1, state->reg1, state->left->reg1);
1037 }
1038
1039 reg: OP_LCONV_TO_I2 (lreg) {
1040         MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
1041 }
1042
1043 reg: OP_LCONV_TO_U2 (lreg) {
1044         MONO_EMIT_UNALU (s, tree, CEE_CONV_U2, state->reg1, state->left->reg1);
1045 }
1046
1047 reg: OP_LCONV_TO_OVF_I1_UN (lreg) {
1048         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1049
1050         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT, state->left->reg1, 127, "OverflowException");
1051         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, -128, "OverflowException");
1052         MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
1053 }
1054
1055 reg: OP_LCONV_TO_OVF_I1 (lreg) {
1056         MonoInst *is_negative, *end_label;
1057
1058         MONO_NEW_LABEL (s, is_negative);
1059         MONO_NEW_LABEL (s, end_label);
1060
1061         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT, state->left->reg2, 0, "OverflowException");
1062         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg2, -1, "OverflowException");
1063
1064         MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BLT, state->left->reg2, mips_zero, is_negative);
1065
1066         /* Positive */
1067         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 127, "OverflowException");
1068         MONO_EMIT_NEW_BRANCH_LABEL (s, OP_BR, end_label);
1069
1070         /* Negative */
1071         mono_bblock_add_inst (s->cbb, is_negative);
1072         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT_UN, state->left->reg1, -128, "OverflowException");
1073         mono_bblock_add_inst (s->cbb, end_label);
1074
1075         MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
1076 }
1077
1078 reg: OP_LCONV_TO_OVF_U1_UN (lreg),
1079 reg: OP_LCONV_TO_OVF_U1 (lreg) {
1080         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1081
1082         /* probe value to be within 0 to 255 */
1083         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 255, "OverflowException");
1084         MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, 0xff);
1085 }
1086
1087 reg: OP_LCONV_TO_OVF_I2 (lreg) {
1088         MonoInst *is_negative, *end_label;
1089
1090         MONO_NEW_LABEL (s, is_negative);
1091         MONO_NEW_LABEL (s, end_label);
1092
1093         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT, state->left->reg2, 0, "OverflowException");
1094         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg2, -1, "OverflowException");
1095
1096         MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BLT, state->left->reg2, mips_zero, is_negative);
1097
1098         /* Positive */
1099         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 32767, "OverflowException");
1100         MONO_EMIT_NEW_BRANCH_LABEL (s, OP_BR, end_label);
1101
1102         /* Negative */
1103         mono_bblock_add_inst (s->cbb, is_negative);
1104         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT_UN, state->left->reg1, -32768, "OverflowException");
1105         mono_bblock_add_inst (s->cbb, end_label);
1106
1107         MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
1108 }
1109
1110 reg: OP_LCONV_TO_OVF_I2_UN (lreg) {
1111         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1112
1113         /* Probe value to be within -32768 and 32767 */
1114         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT, state->left->reg1, 32767, "OverflowException");
1115         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, -32768, "OverflowException");
1116         MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
1117 }
1118
1119 reg: OP_LCONV_TO_OVF_U2_UN (lreg),
1120 reg: OP_LCONV_TO_OVF_U2 (lreg) {
1121         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1122
1123         /* Probe value to be within 0 and 65535 */
1124         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 0xffff, "OverflowException");
1125         MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, 0xffff);
1126 }
1127
1128
1129 reg: OP_LCONV_TO_OVF_U4_UN (lreg) {
1130         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1131         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
1132 }
1133
1134 reg: OP_LCONV_TO_OVF_I_UN (lreg) {
1135         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1136         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
1137 }
1138
1139 reg: OP_LCONV_TO_OVF_U4 (lreg) {
1140         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1141         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
1142 }
1143
1144 reg: OP_LCONV_TO_OVF_I4_UN (lreg) {
1145         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1146         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, 0, "OverflowException");
1147         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
1148 }
1149
1150 reg: OP_LCONV_TO_OVF_I (lreg),
1151 reg: OP_LCONV_TO_OVF_I4 (lreg) {
1152         int tmp_reg = mono_regstate_next_int (s->rs);
1153
1154         /* Overflows if reg2 != sign extension of reg1 */
1155         MONO_EMIT_BIALU_IMM (s, tree, OP_SHR_IMM, tmp_reg, state->left->reg1, 31);
1156
1157         MONO_EMIT_NEW_COMPARE_EXC (s, NE_UN, state->left->reg2, tmp_reg, "OverflowException");
1158         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
1159 }
1160
1161 lreg: OP_LCONV_TO_OVF_I8_UN (lreg) {
1162         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg2, 0, "OverflowException");
1163
1164         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
1165         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
1166 }
1167
1168 lreg: OP_LCONV_TO_OVF_U8 (lreg) {
1169         MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg2, 0, "OverflowException");
1170
1171         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
1172         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
1173 }
1174
1175 lreg: OP_LCONV_TO_OVF_I8 (lreg) {
1176         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
1177         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
1178 }
1179
1180 lreg: OP_LCONV_TO_OVF_U8_UN (lreg) {
1181         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
1182         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
1183 }
1184
1185 lreg: OP_LCALLVIRT (reg) {
1186         mini_emit_virtual_call (s, state, tree, OP_LCALL, OP_LCALL_MEMBASE);
1187 }
1188
1189 lreg: OP_LCALL {
1190         tree->dreg = state->reg1;
1191         mono_bblock_add_inst (s->cbb, tree);
1192 }
1193
1194 lreg: OP_LCALL_REG (reg) {
1195         tree->sreg1 = state->left->reg1;
1196         tree->dreg = state->reg1;
1197         mono_bblock_add_inst (s->cbb, tree);
1198 }
1199
1200 lreg: OP_LCALL_REG (OP_ICONST) {
1201         tree->opcode = OP_LCALL;
1202         ((MonoCallInst*)tree)->fptr = state->left->tree->inst_p0;
1203         tree->dreg = state->reg1;
1204         mono_bblock_add_inst (s->cbb, tree);
1205 }
1206
1207 %%