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