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