2004-07-23 zovarga <vargaz@freemail.hu>
[mono.git] / mono / mini / inssel-long32.brg
1 %%
2
3 #
4 # inssel-long32.brg: burg file for integer instructions on 32bit architectures
5 #
6 # Author:
7 #   Dietmar Maurer (dietmar@ximian.com)
8 #
9 # (C) 2002 Ximian, Inc.
10 #
11
12 #
13 # 32 bit rules
14 #
15
16 #
17 # basic alu operations
18 #
19
20 reg: CEE_AND (reg, reg) {
21         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
22 }
23
24 reg: CEE_AND (reg, OP_ICONST) {
25         MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
26 }
27
28 reg: CEE_OR (reg, reg) {
29         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
30 }
31
32 reg: CEE_OR (reg, OP_ICONST) {
33         MONO_EMIT_BIALU_IMM (s, tree, OP_OR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
34 }
35
36 reg: CEE_XOR (reg, reg) {
37         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
38 }
39
40 reg: CEE_XOR (reg, OP_ICONST) {
41         MONO_EMIT_BIALU_IMM (s, tree, OP_XOR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
42 }
43
44 reg: CEE_NEG (reg) {
45         MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
46 }
47
48 reg: CEE_NOT (reg) {
49         MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
50 }
51
52 reg: CEE_ADD (reg, reg) {
53         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
54 }
55
56 reg: CEE_ADD (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: CEE_ADD_OVF (reg, reg) {
61         MONO_EMIT_NEW_BIALU (s, OP_ADDCC, state->reg1, state->left->reg1, state->right->reg1);
62         MONO_EMIT_NEW_COND_EXC (s, OV, "OverflowException");
63 }
64
65 reg: CEE_ADD_OVF_UN (reg, reg) {
66         MONO_EMIT_NEW_BIALU (s, OP_ADDCC, state->reg1, state->left->reg1, state->right->reg1);
67         MONO_EMIT_NEW_COND_EXC (s, C, "OverflowException");
68 }
69
70 reg: CEE_SUB (reg, reg) {
71         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
72 }
73
74 reg: CEE_SUB (reg, CEE_LDIND_I4 (OP_REGVAR)) {
75         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->left->tree->dreg);
76 }
77
78 reg: CEE_SUB (reg, OP_ICONST) {
79         MONO_EMIT_BIALU_IMM (s, tree, OP_SUB_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
80 }
81
82 reg: CEE_SUB_OVF (reg, reg) {
83         MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1);
84         MONO_EMIT_NEW_COND_EXC (s, OV, "OverflowException");
85 }
86
87 reg: CEE_SUB_OVF_UN (reg, reg) {
88         MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1);
89         MONO_EMIT_NEW_COND_EXC (s, C, "OverflowException");
90 }
91
92 #
93 # mult/div operations
94 #
95
96 reg: CEE_MUL (reg, reg) {
97         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
98 }
99
100 reg: CEE_MUL (reg, OP_ICONST) {
101         MONO_EMIT_BIALU_IMM (s, tree, OP_MUL_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
102 }
103
104 reg: CEE_MUL_OVF (reg, reg) {
105         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
106 }
107
108 reg: CEE_MUL_OVF_UN (reg, reg) {
109         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
110 }
111
112 reg: CEE_DIV (reg, reg) {
113         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
114 }
115
116 #reg: CEE_DIV (reg, OP_ICONST) {
117 #       MONO_EMIT_BIALU_IMM (s, tree, OP_DIV_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
118 #}
119
120 reg: CEE_DIV_UN (reg, reg) {
121         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
122 }
123
124 #reg: CEE_DIV_UN (reg, OP_ICONST) {
125 #       MONO_EMIT_BIALU_IMM (s, tree, OP_DIV_UN_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
126 #}
127
128 reg: CEE_REM (reg, reg) {
129         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
130 }
131
132 #reg: CEE_REM (reg, OP_ICONST) {
133 #       MONO_EMIT_BIALU_IMM (s, tree, OP_REM_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
134 #}
135
136 reg: CEE_REM_UN (reg, reg) {
137         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
138 }
139
140 #reg: CEE_REM_UN (reg, OP_ICONST) {
141 #       MONO_EMIT_BIALU_IMM (s, tree, OP_REM_UN_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
142 #}
143
144 #
145 # shift operations
146 #
147
148 reg: CEE_SHL (reg, reg) {
149         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
150 }
151
152 reg: CEE_SHL (reg, OP_ICONST) {
153         MONO_EMIT_BIALU_IMM (s, tree, OP_SHL_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
154 }
155
156 reg: CEE_SHR (reg, reg) {
157         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
158 }
159
160 reg: CEE_SHR (reg, OP_ICONST) {
161         MONO_EMIT_BIALU_IMM (s, tree, OP_SHR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
162 }
163
164 reg: CEE_SHR_UN (reg, reg) {
165         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
166 }
167
168 reg: CEE_SHR_UN (reg, OP_ICONST) {
169         MONO_EMIT_BIALU_IMM (s, tree, OP_SHR_UN_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
170 }
171
172 cflags: OP_COMPARE (reg, reg) {
173         tree->sreg1 = state->left->reg1;
174         tree->sreg2 = state->right->reg1;
175         mono_bblock_add_inst (s->cbb, tree);
176 }
177
178 cflags: OP_COMPARE (CEE_LDIND_REF (OP_REGVAR), reg),
179 cflags: OP_COMPARE (CEE_LDIND_I (OP_REGVAR), reg),
180 cflags: OP_COMPARE (CEE_LDIND_I4 (OP_REGVAR), reg),
181 cflags: OP_COMPARE (CEE_LDIND_U4 (OP_REGVAR), reg) {
182         tree->sreg1 = state->left->left->tree->dreg;
183         tree->sreg2 = state->right->reg1;
184         mono_bblock_add_inst (s->cbb, tree);
185 }
186
187 cflags: OP_COMPARE (CEE_LDIND_REF (OP_REGVAR), CEE_LDIND_REF (OP_REGVAR)),
188 cflags: OP_COMPARE (CEE_LDIND_I (OP_REGVAR), CEE_LDIND_I (OP_REGVAR)),
189 cflags: OP_COMPARE (CEE_LDIND_I4 (OP_REGVAR), CEE_LDIND_I4 (OP_REGVAR)),
190 cflags: OP_COMPARE (CEE_LDIND_U4 (OP_REGVAR), CEE_LDIND_U4 (OP_REGVAR)) {
191         tree->sreg1 = state->left->left->tree->dreg;
192         tree->sreg2 = state->right->left->tree->dreg;
193         mono_bblock_add_inst (s->cbb, tree);
194 }
195
196 cflags: OP_COMPARE (CEE_LDIND_REF (OP_REGVAR), OP_ICONST),
197 cflags: OP_COMPARE (CEE_LDIND_I (OP_REGVAR), OP_ICONST),
198 cflags: OP_COMPARE (CEE_LDIND_I4 (OP_REGVAR), OP_ICONST),
199 cflags: OP_COMPARE (CEE_LDIND_U4 (OP_REGVAR), OP_ICONST) {
200         tree->opcode = OP_COMPARE_IMM;
201         tree->sreg1 = state->left->left->tree->dreg;
202         tree->inst_imm = state->right->tree->inst_c0;
203         mono_bblock_add_inst (s->cbb, tree);
204 }
205
206 cflags: OP_COMPARE (reg, OP_ICONST) {
207         tree->opcode = OP_COMPARE_IMM;
208         tree->sreg1 = state->left->reg1;
209         tree->inst_imm = state->right->tree->inst_c0;
210         mono_bblock_add_inst (s->cbb, tree);
211 }
212
213 stmt: CEE_BNE_UN (cflags) {
214         mono_bblock_add_inst (s->cbb, tree);
215 }
216
217 stmt: CEE_BEQ (cflags) {
218         mono_bblock_add_inst (s->cbb, tree);
219 }
220
221 stmt: CEE_BLT (cflags) {
222         mono_bblock_add_inst (s->cbb, tree);
223 }
224
225 stmt: CEE_BLT_UN (cflags) {
226         mono_bblock_add_inst (s->cbb, tree);
227 }
228
229 stmt: CEE_BGT (cflags) {
230         mono_bblock_add_inst (s->cbb, tree);
231 }
232
233 stmt: CEE_BGT_UN (cflags) {
234         mono_bblock_add_inst (s->cbb, tree);
235 }
236
237 stmt: CEE_BGE  (cflags) {
238         mono_bblock_add_inst (s->cbb, tree);
239 }
240
241 stmt: CEE_BGE_UN (cflags) {
242         mono_bblock_add_inst (s->cbb, tree);
243 }
244
245 stmt: CEE_BLE  (cflags) {
246         mono_bblock_add_inst (s->cbb, tree);
247 }
248
249 stmt: CEE_BLE_UN (cflags) {
250         mono_bblock_add_inst (s->cbb, tree);
251 }
252
253 reg: OP_CEQ (cflags) {  
254         tree->dreg = state->reg1;
255         mono_bblock_add_inst (s->cbb, tree);
256 }
257
258 reg: OP_CLT (cflags) {  
259         tree->dreg = state->reg1;
260         mono_bblock_add_inst (s->cbb, tree);
261 }
262
263 reg: OP_CLT_UN (cflags) {       
264         tree->dreg = state->reg1;
265         mono_bblock_add_inst (s->cbb, tree);
266 }
267
268 reg: OP_CGT (cflags) {  
269         tree->dreg = state->reg1;
270         mono_bblock_add_inst (s->cbb, tree);
271 }
272
273 reg: OP_CGT_UN (cflags) {       
274         tree->dreg = state->reg1;
275         mono_bblock_add_inst (s->cbb, tree);
276 }
277
278 #
279 # 64 bit rules
280 #
281
282 #
283 # We use a new non-terminal called "lreg" for 64bit registers, and
284 # emulate lreg with 2 32bit registers.
285 #
286
287 stmt: CEE_POP (lreg) {
288         /* do nothing */
289 }
290
291 i8con: CEE_CONV_I8 (OP_ICONST) "0" {
292        int data = state->left->tree->inst_c0;
293         tree->opcode = OP_I8CONST;
294         tree->inst_ls_word = data;
295         if (data < 0)
296                 tree->inst_ms_word = -1;
297         else
298                 tree->inst_ms_word = 0;
299 }
300
301 i8con: CEE_CONV_U8 (OP_ICONST) "0" {
302         int data = state->left->tree->inst_c0;
303         tree->opcode = OP_I8CONST;
304         tree->inst_ls_word = data;
305         tree->inst_ms_word = 0;
306 }
307
308 i8con: OP_I8CONST "0"
309
310 lreg: OP_ICONST {
311        int data = state->tree->inst_c0;
312
313        MONO_EMIT_NEW_ICONST (s, state->reg1, data);
314
315        if (data >= 0)
316                MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
317        else 
318                MONO_EMIT_NEW_ICONST (s, state->reg2, -1);
319 }
320
321 lreg: OP_I8CONST {
322         MONO_EMIT_NEW_ICONST (s, state->reg1, tree->inst_ls_word);
323         MONO_EMIT_NEW_ICONST (s, state->reg2, tree->inst_ms_word);
324 }
325
326 lreg: CEE_LDIND_I8 (base) {
327         MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, state->reg1, 
328                                        state->left->tree->inst_basereg, state->left->tree->inst_offset + MINI_LS_WORD_OFFSET);
329         MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, state->reg2, 
330                                        state->left->tree->inst_basereg, state->left->tree->inst_offset + MINI_MS_WORD_OFFSET);
331 }
332
333 stmt: CEE_STIND_I8 (base, lreg) {
334         MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, state->left->tree->inst_basereg,
335                                      state->left->tree->inst_offset + MINI_MS_WORD_OFFSET, state->right->reg2);
336         MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, state->left->tree->inst_basereg,
337                                      state->left->tree->inst_offset + MINI_LS_WORD_OFFSET, state->right->reg1);
338 }
339
340 stmt: CEE_STIND_I8 (base, i8con) {
341         MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STOREI4_MEMBASE_IMM, state->left->tree->inst_basereg,
342                                          state->left->tree->inst_offset + MINI_MS_WORD_OFFSET, state->right->tree->inst_ms_word);
343         MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STOREI4_MEMBASE_IMM, state->left->tree->inst_basereg,
344                                          state->left->tree->inst_offset + MINI_LS_WORD_OFFSET, state->right->tree->inst_ls_word);
345 }
346
347 lreg: OP_BIGMUL (reg, reg) {
348         MONO_EMIT_NEW_BIALU (s, OP_BIGMUL, state->reg1, state->left->reg1, state->right->reg1); 
349 }
350
351 lreg: OP_BIGMUL_UN (reg, reg) {
352         MONO_EMIT_NEW_BIALU (s, OP_BIGMUL_UN, state->reg1, state->left->reg1, state->right->reg1); 
353 }
354
355 lreg: OP_LONG_SHRUN_32 (lreg) {
356         /* just move the upper half to the lower and zero the high word */
357         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg2);
358         MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
359 }
360
361 lreg: OP_LADD (lreg, lreg) {
362         MONO_EMIT_NEW_BIALU (s, OP_ADDCC, state->reg1, state->left->reg1, state->right->reg1);
363         MONO_EMIT_BIALU (s, tree, OP_ADC, state->reg2, state->left->reg2, state->right->reg2);
364 }
365
366 lreg: OP_LADD_OVF (lreg, lreg) {
367         /* ADC sets the condition code */
368         MONO_EMIT_NEW_BIALU (s, OP_ADDCC, state->reg1, state->left->reg1, state->right->reg1);
369         MONO_EMIT_NEW_BIALU (s, OP_ADC, state->reg2, state->left->reg2, state->right->reg2);
370         MONO_EMIT_NEW_COND_EXC (s, OV, "OverflowException");
371 }
372
373 lreg: OP_LADD_OVF_UN (lreg, lreg) {
374         /* ADC sets the condition code */
375         MONO_EMIT_NEW_BIALU (s, OP_ADDCC, state->reg1, state->left->reg1, state->right->reg1);
376         MONO_EMIT_NEW_BIALU (s, OP_ADC, state->reg2, state->left->reg2, state->right->reg2);
377         MONO_EMIT_NEW_COND_EXC (s, C, "OverflowException");
378 }
379
380 lreg: OP_LADD (lreg, i8con) {
381         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
382         MONO_EMIT_BIALU_IMM (s, tree, OP_ADC_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
383 }
384
385 lreg: OP_LSUB (lreg, lreg) {
386         MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1);
387         MONO_EMIT_BIALU (s, tree, OP_SBB, state->reg2, state->left->reg2, state->right->reg2);
388 }
389
390 lreg: OP_LSUB (lreg, i8con) {
391         MONO_EMIT_NEW_BIALU_IMM (s, OP_SUB_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
392         MONO_EMIT_BIALU_IMM (s, tree, OP_SBB_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
393 }
394
395 lreg: OP_LSUB_OVF (lreg, lreg) {
396         /* SBB sets the condition code */
397         MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1);
398         MONO_EMIT_NEW_BIALU (s, OP_SBB, state->reg2, state->left->reg2, state->right->reg2);
399         MONO_EMIT_NEW_COND_EXC (s, OV, "OverflowException");
400 }
401
402 lreg: OP_LSUB_OVF_UN (lreg, lreg) {
403         /* SBB sets the condition code */
404         MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1);
405         MONO_EMIT_NEW_BIALU (s, OP_SBB, state->reg2, state->left->reg2, state->right->reg2);
406         MONO_EMIT_NEW_COND_EXC (s, C, "OverflowException");
407 }
408
409 lreg: OP_LAND (lreg, lreg) {    
410         MONO_EMIT_NEW_BIALU (s, CEE_AND, state->reg1, state->left->reg1, state->right->reg1);
411         MONO_EMIT_BIALU (s, tree, CEE_AND, state->reg2, state->left->reg2, state->right->reg2);
412 }
413
414 lreg: OP_LAND (lreg, i8con) {   
415         MONO_EMIT_NEW_BIALU_IMM (s, OP_AND_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
416         MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
417 }
418
419 lreg: OP_LOR (lreg, lreg) {
420         MONO_EMIT_NEW_BIALU (s, CEE_OR, state->reg1, state->left->reg1, state->right->reg1);
421         MONO_EMIT_BIALU (s, tree, CEE_OR, state->reg2, state->left->reg2, state->right->reg2);
422 }
423
424 lreg: OP_LOR (lreg, i8con) {
425         MONO_EMIT_NEW_BIALU_IMM (s, OP_OR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
426         MONO_EMIT_BIALU_IMM (s, tree, OP_OR_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
427 }
428
429 lreg: OP_LXOR (lreg, lreg) {
430         MONO_EMIT_NEW_BIALU (s, CEE_XOR, state->reg1, state->left->reg1, state->right->reg1);
431         MONO_EMIT_BIALU (s, tree, CEE_XOR, state->reg2, state->left->reg2, state->right->reg2);
432 }
433
434 lreg: OP_LXOR (lreg, i8con) {
435         MONO_EMIT_NEW_BIALU_IMM (s, OP_XOR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
436         MONO_EMIT_BIALU_IMM (s, tree, OP_XOR_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
437 }
438
439 lreg: OP_LNOT (lreg) {
440         MONO_EMIT_NEW_UNALU (s, CEE_NOT, state->reg1, state->left->reg1);
441         MONO_EMIT_UNALU (s, tree, CEE_NOT, state->reg2, state->left->reg2);
442 }
443
444 lreg: OP_LNEG (lreg) "4" {
445         MONO_EMIT_NEW_UNALU (s, CEE_NOT, state->reg1, state->left->reg1);
446         MONO_EMIT_NEW_UNALU (s, CEE_NOT, state->reg2, state->left->reg2);
447         /* ADC sets the condition codes */
448         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADC_IMM, state->reg1, state->reg1, 1);
449         MONO_EMIT_BIALU_IMM (s, tree, OP_ADC_IMM, state->reg2, state->reg2, 0);
450 }
451
452 reg: OP_CEQ (OP_LCOMPARE (lreg, lreg)) {        
453         MonoInst *word_differs;
454         
455         MONO_NEW_LABEL (s, word_differs);
456
457         MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
458         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
459         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, word_differs);
460         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
461         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, word_differs);
462         MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
463         
464         mono_bblock_add_inst (s->cbb, word_differs);
465 }
466
467 reg: OP_CLT (OP_LCOMPARE (lreg, lreg)) {        
468         MonoInst *set_to_0, *set_to_1;
469         
470         MONO_NEW_LABEL (s, set_to_0);
471         MONO_NEW_LABEL (s, set_to_1);
472
473         MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
474         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
475         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGT, set_to_0);
476         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, set_to_1);
477         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
478         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGE_UN, set_to_0);
479         mono_bblock_add_inst (s->cbb, set_to_1);
480         MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
481         mono_bblock_add_inst (s->cbb, set_to_0);
482 }       
483
484 reg: OP_CLT_UN (OP_LCOMPARE (lreg, lreg)) {     
485         MonoInst *set_to_0, *set_to_1;
486         
487         MONO_NEW_LABEL (s, set_to_0);
488         MONO_NEW_LABEL (s, set_to_1);
489
490         MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
491         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
492         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGT_UN, set_to_0);
493         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, set_to_1);
494         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
495         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGE_UN, set_to_0);
496         mono_bblock_add_inst (s->cbb, set_to_1);
497         MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
498         mono_bblock_add_inst (s->cbb, set_to_0);
499 }       
500
501 reg: OP_CGT (OP_LCOMPARE (lreg, lreg)) {        
502         MonoInst *set_to_0, *set_to_1;
503         
504         MONO_NEW_LABEL (s, set_to_0);
505         MONO_NEW_LABEL (s, set_to_1);
506
507         MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
508         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->right->reg2, state->left->left->reg2);
509         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGT, set_to_0);
510         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, set_to_1);
511         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->right->reg1, state->left->left->reg1);
512         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGE_UN, set_to_0);
513         mono_bblock_add_inst (s->cbb, set_to_1);
514         MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
515         mono_bblock_add_inst (s->cbb, set_to_0);
516 }       
517
518 reg: OP_CGT_UN (OP_LCOMPARE (lreg, lreg)) {     
519         MonoInst *set_to_0, *set_to_1;
520         
521         MONO_NEW_LABEL (s, set_to_0);
522         MONO_NEW_LABEL (s, set_to_1);
523
524         MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
525         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->right->reg2, state->left->left->reg2);
526         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGT_UN, set_to_0);
527         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, set_to_1);
528         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->right->reg1, state->left->left->reg1);
529         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGE_UN, 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 stmt: CEE_BNE_UN (OP_LCOMPARE (lreg, lreg)) {
536         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
537         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_true_bb);
538         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
539         mono_bblock_add_inst (s->cbb, tree);
540 }
541
542 stmt: CEE_BNE_UN (OP_LCOMPARE (lreg, i8con)) {
543         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_ls_word);
544         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_true_bb);
545         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
546         mono_bblock_add_inst (s->cbb, tree);
547 }
548
549 stmt: CEE_BEQ (OP_LCOMPARE (lreg, lreg)) {
550         
551         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
552         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
553         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
554         mono_bblock_add_inst (s->cbb, tree);
555 }
556
557 stmt: CEE_BEQ (OP_LCOMPARE (lreg, i8con)) {
558         
559         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_ls_word);
560         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
561         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
562         mono_bblock_add_inst (s->cbb, tree);
563 }
564
565 stmt: CEE_BLE (OP_LCOMPARE (lreg, lreg)) {
566
567         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
568         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT, tree->inst_true_bb);
569         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
570         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
571         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLE_UN, tree->inst_true_bb);
572 }
573
574 stmt: CEE_BLE (OP_LCOMPARE (lreg, i8con)) {
575
576         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
577         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT, tree->inst_true_bb);
578         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
579         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_ls_word);
580         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLE_UN, tree->inst_true_bb);
581 }
582
583 stmt: CEE_BLE_UN (OP_LCOMPARE (lreg, lreg)) {
584
585         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
586         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
587         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
588         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
589         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLE_UN, tree->inst_true_bb);
590 }
591
592 stmt: CEE_BLE_UN (OP_LCOMPARE (lreg, i8con)) {
593
594         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
595         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
596         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
597         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_ls_word);
598         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLE_UN, tree->inst_true_bb);
599 }
600
601 stmt: CEE_BGE (OP_LCOMPARE (lreg, lreg)) {
602
603         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
604         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT, tree->inst_true_bb);
605         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
606         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
607         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_true_bb);
608 }
609
610 stmt: CEE_BGE (OP_LCOMPARE (lreg, i8con)) {
611
612         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
613         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT, tree->inst_true_bb);
614         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
615         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_ls_word);
616         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_true_bb);
617 }
618
619 stmt: CEE_BGE_UN (OP_LCOMPARE (lreg, lreg)) {
620
621         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
622         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
623         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
624         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
625         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_true_bb);
626 }
627
628 stmt: CEE_BGE_UN (OP_LCOMPARE (lreg, i8con)) {
629
630         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
631         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
632         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
633         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_ls_word);
634         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_true_bb);
635 }
636
637 stmt: CEE_BLT (OP_LCOMPARE (lreg, lreg)) {
638
639         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
640         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT, tree->inst_true_bb);
641         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
642         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
643         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
644 }
645
646 stmt: CEE_BLT (OP_LCOMPARE (lreg, i8con)) {
647
648         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
649         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT, tree->inst_true_bb);
650         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
651         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_ls_word);
652         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
653 }
654
655 stmt: CEE_BLT_UN (OP_LCOMPARE (lreg, lreg)) {
656
657         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
658         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
659         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
660         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
661         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
662 }
663
664 stmt: CEE_BLT_UN (OP_LCOMPARE (lreg, i8con)) {
665
666         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
667         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
668         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
669         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_ls_word);
670         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
671 }
672
673 stmt: CEE_BGT (OP_LCOMPARE (lreg, lreg)) {
674
675         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
676         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT, tree->inst_true_bb);
677         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
678         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
679         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
680 }
681
682 stmt: CEE_BGT (OP_LCOMPARE (lreg, i8con)) {
683
684         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
685         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT, tree->inst_true_bb);
686         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
687         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_ls_word);
688         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
689 }
690
691 stmt: CEE_BGT_UN (OP_LCOMPARE (lreg, lreg)) {
692
693         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
694         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
695         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
696         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
697         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
698 }
699
700 stmt: CEE_BGT_UN (OP_LCOMPARE (lreg, i8con)) {
701
702         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
703         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
704         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
705         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_ls_word);
706         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
707 }
708
709 lreg: CEE_CONV_I8 (OP_ICONST) {
710         int data = state->left->tree->inst_c0;
711
712        MONO_EMIT_NEW_ICONST (s, state->reg1, data);
713
714        if (data >= 0)
715                MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
716        else 
717                MONO_EMIT_NEW_ICONST (s, state->reg2, -1);
718 }
719
720 lreg: CEE_CONV_I8 (reg) {
721         MonoInst *is_negative, *end_label;
722         int tmpreg = mono_regstate_next_int (s->rs);
723         
724         MONO_NEW_LABEL (s, is_negative);
725         MONO_NEW_LABEL (s, end_label);
726
727         /* branchless code:
728          * low = reg;
729          * tmp = low > -1 ? 1: 0;
730          * high = tmp - 1; if low is zero or pos high becomes 0, else -1
731          * not sure why it doesn't work in practice
732          */
733         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
734         /*MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->reg1, -1);
735         tree->dreg = tmpreg;
736         tree->opcode = OP_CGT;
737         mono_bblock_add_inst (s->cbb, tree);
738         MONO_EMIT_NEW_BIALU_IMM (s, OP_SUB_IMM, state->reg2, tmpreg, -1);*/
739         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->reg1, 0);
740         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BLT, is_negative);
741         MONO_EMIT_NEW_ICONST (s, tmpreg, 0);
742         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BR, end_label);
743         mono_bblock_add_inst (s->cbb, is_negative);
744         MONO_EMIT_NEW_ICONST (s, tmpreg, -1);
745         mono_bblock_add_inst (s->cbb, end_label);
746         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg2, tmpreg);
747 }
748
749 lreg: CEE_CONV_U8 (reg) {
750         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
751         MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
752 }
753
754 lreg: CEE_CONV_OVF_U8 (reg) {
755         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0);
756         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
757         MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
758         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
759 }
760
761 lreg: CEE_CONV_OVF_I8 (reg) {
762         /* a signed 32 bit num always fits in a signed 64 bit one */
763         MONO_EMIT_NEW_BIALU_IMM (s, OP_SHR_IMM, state->reg2, state->left->reg1, 31);
764         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
765 }
766
767 lreg: CEE_CONV_OVF_I8_UN (reg) {
768         /* an unsigned 32 bit num always fits in a signed 64 bit one */
769         MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
770         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
771 }
772
773 lreg: CEE_CONV_OVF_U8_UN (reg) {
774         MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
775         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
776 }
777
778 freg: OP_LCONV_TO_R_UN (lreg) {
779         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->left->reg2);
780 }
781
782 lreg: OP_FCONV_TO_I8 (freg) {
783         MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
784 }
785
786 lreg: OP_FCONV_TO_U8 (freg) {
787         MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
788 }
789
790 reg: OP_LCONV_TO_I4 (i8con) {
791         MONO_EMIT_NEW_ICONST (s, state->reg1, state->left->tree->inst_ls_word);
792 }
793
794 reg: OP_LCONV_TO_I4 (lreg) {
795         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
796 }
797
798 reg: OP_LCONV_TO_U4 (lreg) {
799         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
800 }
801
802 lreg: OP_LCONV_TO_U8 (lreg) {
803         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
804         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
805 }
806
807 lreg: OP_LCONV_TO_I8 (lreg) {
808         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
809         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
810 }
811
812 reg: OP_LCONV_TO_U (lreg) {
813         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
814 }
815
816 reg: OP_LCONV_TO_I (lreg) {
817         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
818 }
819
820 reg: OP_LCONV_TO_I1 (lreg) {
821         MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
822 }
823
824 reg: OP_LCONV_TO_U1 (lreg) {
825         MONO_EMIT_UNALU (s, tree, CEE_CONV_U1, state->reg1, state->left->reg1);
826 }
827
828 reg: OP_LCONV_TO_I2 (lreg) {
829         MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
830 }
831
832 reg: OP_LCONV_TO_U2 (lreg) {
833         MONO_EMIT_UNALU (s, tree, CEE_CONV_U2, state->reg1, state->left->reg1);
834 }
835
836 reg: OP_LCONV_TO_OVF_I1_UN (lreg) {
837         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
838         MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
839
840         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 127);
841         MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
842         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -128);
843         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
844         MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
845 }
846
847 reg: OP_LCONV_TO_OVF_I1 (lreg) {
848         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
849         MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
850         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, -1);
851         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
852
853         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 127);
854         MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
855         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -128);
856         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
857         MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
858 }
859
860 reg: OP_LCONV_TO_OVF_U1_UN (lreg),
861 reg: OP_LCONV_TO_OVF_U1 (lreg) {
862         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
863         MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
864
865         /* probe value to be within 0 to 255 */
866         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 255);
867         MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
868         MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, 0xff);
869 }
870
871 reg: OP_LCONV_TO_OVF_I2 (lreg) {
872         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
873         MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
874         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, -1);
875         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
876
877         /* Probe value to be within -32768 and 32767 */
878         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 32767);
879         MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
880         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -32768);
881         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
882         MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
883 }
884
885 reg: OP_LCONV_TO_OVF_I2_UN (lreg) {
886         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
887         MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
888
889         /* Probe value to be within -32768 and 32767 */
890         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 32767);
891         MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
892         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -32768);
893         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
894         MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
895 }
896
897 reg: OP_LCONV_TO_OVF_U2_UN (lreg),
898 reg: OP_LCONV_TO_OVF_U2 (lreg) {
899         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
900         MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
901
902         /* Probe value to be within 0 and 65535 */
903         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0xffff);
904         MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
905         MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, 0xffff);
906 }
907
908
909 reg: OP_LCONV_TO_OVF_U4_UN (lreg) {
910         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
911         MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
912         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
913 }
914
915 reg: OP_LCONV_TO_OVF_I_UN (lreg) {
916         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
917         MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
918         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
919 }
920
921 reg: OP_LCONV_TO_OVF_U4 (lreg) {
922         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
923         MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
924         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
925 }
926
927 reg: OP_LCONV_TO_OVF_I (lreg) {
928         tree->dreg = state->reg1;
929         tree->sreg1 = state->left->reg1;
930         tree->sreg2 = state->left->reg2;
931         mono_bblock_add_inst (s->cbb, tree);
932 }
933
934 reg: OP_LCONV_TO_OVF_I4_UN (lreg),
935 reg: OP_LCONV_TO_OVF_I4 (lreg) {
936         tree->dreg = state->reg1;
937         tree->sreg1 = state->left->reg1;
938         tree->sreg2 = state->left->reg2;
939         tree->opcode = OP_LCONV_TO_OVF_I;
940         mono_bblock_add_inst (s->cbb, tree);
941 }
942
943 lreg: OP_LCONV_TO_OVF_I8_UN (lreg) {
944         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
945         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
946
947         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
948         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
949 }
950
951 lreg: OP_LCONV_TO_OVF_U8 (lreg) {
952         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
953         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
954
955         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
956         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
957 }
958
959 lreg: OP_LCONV_TO_OVF_I8 (lreg) {
960         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
961         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
962 }
963
964 lreg: OP_LCONV_TO_OVF_U8_UN (lreg) {
965         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
966         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
967 }
968
969 lreg: OP_LCALLVIRT (reg) {
970         mini_emit_virtual_call (s, state, tree, OP_LCALL, OP_LCALL_MEMBASE);
971 }
972
973 lreg: OP_LCALL {
974         tree->dreg = state->reg1;
975         mono_bblock_add_inst (s->cbb, tree);
976 }
977
978 lreg: OP_LCALL_REG (reg) {
979         tree->sreg1 = state->left->reg1;
980         tree->dreg = state->reg1;
981         mono_bblock_add_inst (s->cbb, tree);
982 }
983
984 lreg: OP_LCALL_REG (OP_ICONST) {
985         tree->opcode = OP_LCALL;
986         ((MonoCallInst*)tree)->fptr = state->left->tree->inst_p0;
987         tree->dreg = state->reg1;
988         mono_bblock_add_inst (s->cbb, tree);
989 }
990
991 %%