Wed Apr 21 16:38:28 CEST 2004 Paolo Molaro <lupus@ximian.com>
[mono.git] / mono / mini / inssel-long32.brg
1 %%
2
3 #
4 # inssel-long32.brg: burg file for 64bit instructions on 32bit architectures
5 #
6 # Author:
7 #   Dietmar Maurer (dietmar@ximian.com)
8 #
9 # (C) 2002 Ximian, Inc.
10 #
11
12 #
13 # We use a new non-terminal called "lreg" for 64bit registers, and
14 # emulate lreg with 2 32bit registers.
15 #
16
17 stmt: CEE_POP (lreg) {
18         /* do nothing */
19 }
20
21 i8con: CEE_CONV_I8 (OP_ICONST) "0" {
22        int data = state->left->tree->inst_c0;
23         tree->opcode = OP_I8CONST;
24         tree->inst_ls_word = data;
25         if (data < 0)
26                 tree->inst_ms_word = -1;
27         else
28                 tree->inst_ms_word = 0;
29 }
30
31 i8con: CEE_CONV_U8 (OP_ICONST) "0" {
32         int data = state->left->tree->inst_c0;
33         tree->opcode = OP_I8CONST;
34         tree->inst_ls_word = data;
35         tree->inst_ms_word = 0;
36 }
37
38 i8con: OP_I8CONST "0"
39
40 lreg: OP_ICONST {
41        int data = state->tree->inst_c0;
42
43        MONO_EMIT_NEW_ICONST (s, state->reg1, data);
44
45        if (data >= 0)
46                MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
47        else 
48                MONO_EMIT_NEW_ICONST (s, state->reg2, -1);
49 }
50
51 lreg: OP_I8CONST {
52         MONO_EMIT_NEW_ICONST (s, state->reg1, tree->inst_ls_word);
53         MONO_EMIT_NEW_ICONST (s, state->reg2, tree->inst_ms_word);
54 }
55
56 lreg: CEE_LDIND_I8 (base) {
57         MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, state->reg1, 
58                                        state->left->tree->inst_basereg, state->left->tree->inst_offset + MINI_LS_WORD_OFFSET);
59         MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, state->reg2, 
60                                        state->left->tree->inst_basereg, state->left->tree->inst_offset + MINI_MS_WORD_OFFSET);
61 }
62
63 stmt: CEE_STIND_I8 (base, lreg) {
64         MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, state->left->tree->inst_basereg,
65                                      state->left->tree->inst_offset + MINI_MS_WORD_OFFSET, state->right->reg2);
66         MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, state->left->tree->inst_basereg,
67                                      state->left->tree->inst_offset + MINI_LS_WORD_OFFSET, state->right->reg1);
68 }
69
70 stmt: CEE_STIND_I8 (base, i8con) {
71         MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STOREI4_MEMBASE_IMM, state->left->tree->inst_basereg,
72                                          state->left->tree->inst_offset + MINI_MS_WORD_OFFSET, state->right->tree->inst_ms_word);
73         MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STOREI4_MEMBASE_IMM, state->left->tree->inst_basereg,
74                                          state->left->tree->inst_offset + MINI_LS_WORD_OFFSET, state->right->tree->inst_ls_word);
75 }
76
77 lreg: OP_BIGMUL (reg, reg) {
78         MONO_EMIT_NEW_BIALU (s, OP_BIGMUL, state->reg1, state->left->reg1, state->right->reg1); 
79 }
80
81 lreg: OP_BIGMUL_UN (reg, reg) {
82         MONO_EMIT_NEW_BIALU (s, OP_BIGMUL_UN, state->reg1, state->left->reg1, state->right->reg1); 
83 }
84
85 lreg: OP_LADD (lreg, lreg) {
86         MONO_EMIT_NEW_BIALU (s, OP_ADDCC, state->reg1, state->left->reg1, state->right->reg1);
87         MONO_EMIT_BIALU (s, tree, OP_ADC, state->reg2, state->left->reg2, state->right->reg2);
88 }
89
90 lreg: OP_LADD_OVF (lreg, lreg) {
91         /* ADC sets the condition code */
92         MONO_EMIT_NEW_BIALU (s, OP_ADDCC, state->reg1, state->left->reg1, state->right->reg1);
93         MONO_EMIT_NEW_BIALU (s, OP_ADC, state->reg2, state->left->reg2, state->right->reg2);
94         MONO_EMIT_NEW_COND_EXC (s, OV, "OverflowException");
95 }
96
97 lreg: OP_LADD_OVF_UN (lreg, lreg) {
98         /* ADC sets the condition code */
99         MONO_EMIT_NEW_BIALU (s, OP_ADDCC, state->reg1, state->left->reg1, state->right->reg1);
100         MONO_EMIT_NEW_BIALU (s, OP_ADC, state->reg2, state->left->reg2, state->right->reg2);
101         MONO_EMIT_NEW_COND_EXC (s, C, "OverflowException");
102 }
103
104 lreg: OP_LADD (lreg, i8con) {
105         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
106         MONO_EMIT_BIALU_IMM (s, tree, OP_ADC_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
107 }
108
109 lreg: OP_LSUB (lreg, lreg) {
110         MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1);
111         MONO_EMIT_BIALU (s, tree, OP_SBB, state->reg2, state->left->reg2, state->right->reg2);
112 }
113
114 lreg: OP_LSUB (lreg, i8con) {
115         MONO_EMIT_NEW_BIALU_IMM (s, OP_SUB_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
116         MONO_EMIT_BIALU_IMM (s, tree, OP_SBB_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
117 }
118
119 lreg: OP_LSUB_OVF (lreg, lreg) {
120         /* SBB sets the condition code */
121         MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1);
122         MONO_EMIT_NEW_BIALU (s, OP_SBB, state->reg2, state->left->reg2, state->right->reg2);
123         MONO_EMIT_NEW_COND_EXC (s, OV, "OverflowException");
124 }
125
126 lreg: OP_LSUB_OVF_UN (lreg, lreg) {
127         /* SBB sets the condition code */
128         MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1);
129         MONO_EMIT_NEW_BIALU (s, OP_SBB, state->reg2, state->left->reg2, state->right->reg2);
130         MONO_EMIT_NEW_COND_EXC (s, C, "OverflowException");
131 }
132
133 lreg: OP_LAND (lreg, lreg) {    
134         MONO_EMIT_NEW_BIALU (s, CEE_AND, state->reg1, state->left->reg1, state->right->reg1);
135         MONO_EMIT_BIALU (s, tree, CEE_AND, state->reg2, state->left->reg2, state->right->reg2);
136 }
137
138 lreg: OP_LAND (lreg, i8con) {   
139         MONO_EMIT_NEW_BIALU_IMM (s, OP_AND_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
140         MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
141 }
142
143 lreg: OP_LOR (lreg, lreg) {
144         MONO_EMIT_NEW_BIALU (s, CEE_OR, state->reg1, state->left->reg1, state->right->reg1);
145         MONO_EMIT_BIALU (s, tree, CEE_OR, state->reg2, state->left->reg2, state->right->reg2);
146 }
147
148 lreg: OP_LOR (lreg, i8con) {
149         MONO_EMIT_NEW_BIALU_IMM (s, OP_OR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
150         MONO_EMIT_BIALU_IMM (s, tree, OP_OR_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
151 }
152
153 lreg: OP_LXOR (lreg, lreg) {
154         MONO_EMIT_NEW_BIALU (s, CEE_XOR, state->reg1, state->left->reg1, state->right->reg1);
155         MONO_EMIT_BIALU (s, tree, CEE_XOR, state->reg2, state->left->reg2, state->right->reg2);
156 }
157
158 lreg: OP_LXOR (lreg, i8con) {
159         MONO_EMIT_NEW_BIALU_IMM (s, OP_XOR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
160         MONO_EMIT_BIALU_IMM (s, tree, OP_XOR_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
161 }
162
163 lreg: OP_LNOT (lreg) {
164         MONO_EMIT_NEW_UNALU (s, CEE_NOT, state->reg1, state->left->reg1);
165         MONO_EMIT_UNALU (s, tree, CEE_NOT, state->reg2, state->left->reg2);
166 }
167
168 lreg: OP_LNEG (lreg) "4" {
169         MONO_EMIT_NEW_UNALU (s, CEE_NOT, state->reg1, state->left->reg1);
170         MONO_EMIT_NEW_UNALU (s, CEE_NOT, state->reg2, state->left->reg2);
171         /* ADC sets the condition codes */
172         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADC_IMM, state->reg1, state->reg1, 1);
173         MONO_EMIT_BIALU_IMM (s, tree, OP_ADC_IMM, state->reg2, state->reg2, 0);
174 }
175
176 reg: OP_CEQ (OP_COMPARE (lreg, lreg)) { 
177         MonoInst *word_differs;
178         
179         MONO_NEW_LABEL (s, word_differs);
180
181         MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
182         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
183         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, word_differs);
184         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
185         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, word_differs);
186         MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
187         
188         mono_bblock_add_inst (s->cbb, word_differs);
189 }
190
191 reg: OP_CLT (OP_COMPARE (lreg, lreg)) { 
192         MonoInst *set_to_0, *set_to_1;
193         
194         MONO_NEW_LABEL (s, set_to_0);
195         MONO_NEW_LABEL (s, set_to_1);
196
197         MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
198         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
199         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGT, set_to_0);
200         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, set_to_1);
201         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
202         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGE_UN, set_to_0);
203         mono_bblock_add_inst (s->cbb, set_to_1);
204         MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
205         mono_bblock_add_inst (s->cbb, set_to_0);
206 }       
207
208 reg: OP_CLT_UN (OP_COMPARE (lreg, lreg)) {      
209         MonoInst *set_to_0, *set_to_1;
210         
211         MONO_NEW_LABEL (s, set_to_0);
212         MONO_NEW_LABEL (s, set_to_1);
213
214         MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
215         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
216         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGT_UN, set_to_0);
217         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, set_to_1);
218         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
219         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGE_UN, set_to_0);
220         mono_bblock_add_inst (s->cbb, set_to_1);
221         MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
222         mono_bblock_add_inst (s->cbb, set_to_0);
223 }       
224
225 reg: OP_CGT (OP_COMPARE (lreg, lreg)) { 
226         MonoInst *set_to_0, *set_to_1;
227         
228         MONO_NEW_LABEL (s, set_to_0);
229         MONO_NEW_LABEL (s, set_to_1);
230
231         MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
232         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->right->reg2, state->left->left->reg2);
233         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGT, set_to_0);
234         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, set_to_1);
235         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->right->reg1, state->left->left->reg1);
236         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGE_UN, set_to_0);
237         mono_bblock_add_inst (s->cbb, set_to_1);
238         MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
239         mono_bblock_add_inst (s->cbb, set_to_0);
240 }       
241
242 reg: OP_CGT_UN (OP_COMPARE (lreg, lreg)) {      
243         MonoInst *set_to_0, *set_to_1;
244         
245         MONO_NEW_LABEL (s, set_to_0);
246         MONO_NEW_LABEL (s, set_to_1);
247
248         MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
249         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->right->reg2, state->left->left->reg2);
250         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGT_UN, set_to_0);
251         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, set_to_1);
252         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->right->reg1, state->left->left->reg1);
253         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGE_UN, set_to_0);
254         mono_bblock_add_inst (s->cbb, set_to_1);
255         MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
256         mono_bblock_add_inst (s->cbb, set_to_0);
257 }       
258
259 stmt: CEE_BNE_UN (OP_COMPARE (lreg, lreg)) {
260         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
261         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_true_bb);
262         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
263         mono_bblock_add_inst (s->cbb, tree);
264 }
265
266 stmt: CEE_BNE_UN (OP_COMPARE (lreg, i8con)) {
267         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_ls_word);
268         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_true_bb);
269         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
270         mono_bblock_add_inst (s->cbb, tree);
271 }
272
273 stmt: CEE_BEQ (OP_COMPARE (lreg, lreg)) {
274         
275         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
276         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
277         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
278         mono_bblock_add_inst (s->cbb, tree);
279 }
280
281 stmt: CEE_BEQ (OP_COMPARE (lreg, i8con)) {
282         
283         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_ls_word);
284         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
285         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
286         mono_bblock_add_inst (s->cbb, tree);
287 }
288
289 stmt: CEE_BLE (OP_COMPARE (lreg, lreg)) {
290
291         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
292         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT, tree->inst_true_bb);
293         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
294         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
295         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLE_UN, tree->inst_true_bb);
296 }
297
298 stmt: CEE_BLE (OP_COMPARE (lreg, i8con)) {
299
300         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
301         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT, tree->inst_true_bb);
302         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
303         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_ls_word);
304         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLE_UN, tree->inst_true_bb);
305 }
306
307 stmt: CEE_BLE_UN (OP_COMPARE (lreg, lreg)) {
308
309         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
310         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
311         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
312         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
313         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLE_UN, tree->inst_true_bb);
314 }
315
316 stmt: CEE_BLE_UN (OP_COMPARE (lreg, i8con)) {
317
318         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
319         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
320         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
321         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_ls_word);
322         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLE_UN, tree->inst_true_bb);
323 }
324
325 stmt: CEE_BGE (OP_COMPARE (lreg, lreg)) {
326
327         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
328         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT, tree->inst_true_bb);
329         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
330         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
331         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_true_bb);
332 }
333
334 stmt: CEE_BGE (OP_COMPARE (lreg, i8con)) {
335
336         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
337         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT, tree->inst_true_bb);
338         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
339         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_ls_word);
340         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_true_bb);
341 }
342
343 stmt: CEE_BGE_UN (OP_COMPARE (lreg, lreg)) {
344
345         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
346         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
347         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
348         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
349         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_true_bb);
350 }
351
352 stmt: CEE_BGE_UN (OP_COMPARE (lreg, i8con)) {
353
354         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
355         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
356         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
357         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_ls_word);
358         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_true_bb);
359 }
360
361 stmt: CEE_BLT (OP_COMPARE (lreg, lreg)) {
362
363         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
364         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT, tree->inst_true_bb);
365         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
366         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
367         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
368 }
369
370 stmt: CEE_BLT (OP_COMPARE (lreg, i8con)) {
371
372         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
373         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT, tree->inst_true_bb);
374         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
375         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_ls_word);
376         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
377 }
378
379 stmt: CEE_BLT_UN (OP_COMPARE (lreg, lreg)) {
380
381         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
382         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
383         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
384         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
385         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
386 }
387
388 stmt: CEE_BLT_UN (OP_COMPARE (lreg, i8con)) {
389
390         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
391         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
392         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
393         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_ls_word);
394         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
395 }
396
397 stmt: CEE_BGT (OP_COMPARE (lreg, lreg)) {
398
399         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
400         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT, tree->inst_true_bb);
401         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
402         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
403         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
404 }
405
406 stmt: CEE_BGT (OP_COMPARE (lreg, i8con)) {
407
408         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
409         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT, tree->inst_true_bb);
410         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
411         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_ls_word);
412         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
413 }
414
415 stmt: CEE_BGT_UN (OP_COMPARE (lreg, lreg)) {
416
417         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
418         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
419         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
420         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
421         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
422 }
423
424 stmt: CEE_BGT_UN (OP_COMPARE (lreg, i8con)) {
425
426         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
427         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
428         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
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_BGT_UN, tree->inst_true_bb);
431 }
432
433 lreg: CEE_CONV_I8 (OP_ICONST) {
434         int data = state->left->tree->inst_c0;
435
436        MONO_EMIT_NEW_ICONST (s, state->reg1, data);
437
438        if (data >= 0)
439                MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
440        else 
441                MONO_EMIT_NEW_ICONST (s, state->reg2, -1);
442 }
443
444 lreg: CEE_CONV_I8 (reg) {
445         MonoInst *is_negative, *end_label;
446         int tmpreg = mono_regstate_next_int (s->rs);
447         
448         MONO_NEW_LABEL (s, is_negative);
449         MONO_NEW_LABEL (s, end_label);
450
451         /* branchless code:
452          * low = reg;
453          * tmp = low > -1 ? 1: 0;
454          * high = tmp - 1; if low is zero or pos high becomes 0, else -1
455          * not sure why it doesn't work in practice
456          */
457         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
458         /*MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->reg1, -1);
459         tree->dreg = tmpreg;
460         tree->opcode = OP_CGT;
461         mono_bblock_add_inst (s->cbb, tree);
462         MONO_EMIT_NEW_BIALU_IMM (s, OP_SUB_IMM, state->reg2, tmpreg, -1);*/
463         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->reg1, 0);
464         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BLT, is_negative);
465         MONO_EMIT_NEW_ICONST (s, tmpreg, 0);
466         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BR, end_label);
467         mono_bblock_add_inst (s->cbb, is_negative);
468         MONO_EMIT_NEW_ICONST (s, tmpreg, -1);
469         mono_bblock_add_inst (s->cbb, end_label);
470         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg2, tmpreg);
471 }
472
473 lreg: CEE_CONV_U8 (reg) {
474         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
475         MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
476 }
477
478 lreg: CEE_CONV_OVF_U8 (reg) {
479         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0);
480         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
481         MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
482         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
483 }
484
485 lreg: CEE_CONV_OVF_I8 (reg) {
486         /* a signed 32 bit num always fits in a signed 64 bit one */
487         MONO_EMIT_NEW_BIALU_IMM (s, OP_SHR_IMM, state->reg2, state->left->reg1, 31);
488         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
489 }
490
491 lreg: CEE_CONV_OVF_I8_UN (reg) {
492         /* an unsigned 32 bit num always fits in a signed 64 bit one */
493         MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
494         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
495 }
496
497 lreg: CEE_CONV_OVF_U8_UN (reg) {
498         MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
499         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
500 }
501
502 freg: OP_LCONV_TO_R_UN (lreg) {
503         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->left->reg2);
504 }
505
506 lreg: OP_FCONV_TO_I8 (freg) {
507         MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
508 }
509
510 lreg: OP_FCONV_TO_U8 (freg) {
511         MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
512 }
513
514 reg: OP_LCONV_TO_I4 (i8con) {
515         MONO_EMIT_NEW_ICONST (s, state->reg1, state->left->tree->inst_ls_word);
516 }
517
518 reg: OP_LCONV_TO_I4 (lreg) {
519         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
520 }
521
522 reg: OP_LCONV_TO_U4 (lreg) {
523         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
524 }
525
526 lreg: OP_LCONV_TO_U8 (lreg) {
527         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
528         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
529 }
530
531 lreg: OP_LCONV_TO_I8 (lreg) {
532         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
533         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
534 }
535
536 reg: OP_LCONV_TO_U (lreg) {
537         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
538 }
539
540 reg: OP_LCONV_TO_I (lreg) {
541         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
542 }
543
544 reg: OP_LCONV_TO_I1 (lreg) {
545         MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
546 }
547
548 reg: OP_LCONV_TO_U1 (lreg) {
549         MONO_EMIT_UNALU (s, tree, CEE_CONV_U1, state->reg1, state->left->reg1);
550 }
551
552 reg: OP_LCONV_TO_I2 (lreg) {
553         MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
554 }
555
556 reg: OP_LCONV_TO_U2 (lreg) {
557         MONO_EMIT_UNALU (s, tree, CEE_CONV_U2, state->reg1, state->left->reg1);
558 }
559
560 reg: OP_LCONV_TO_OVF_I1 (lreg) {
561         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
562         MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
563         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, -1);
564         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
565
566         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 127);
567         MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
568         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -128);
569         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
570         MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
571 }
572
573 reg: OP_LCONV_TO_OVF_U1 (lreg) {
574         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
575         MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
576
577         /* probe value to be within 0 to 255 */
578         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 255);
579         MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
580         MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, 0xff);
581 }
582
583 reg: OP_LCONV_TO_OVF_I2 (lreg) {
584         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
585         MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
586         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, -1);
587         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
588
589         /* Probe value to be within -32768 and 32767 */
590         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 32767);
591         MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
592         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -32768);
593         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
594         MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
595 }
596
597 reg: OP_LCONV_TO_OVF_U2 (lreg) {
598         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
599         MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
600
601         /* Probe value to be within 0 and 65535 */
602         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0xffff);
603         MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
604         MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, 0xffff);
605 }
606
607
608 reg: OP_LCONV_TO_OVF_U4_UN (lreg) {
609         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
610         MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
611         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
612 }
613
614 reg: OP_LCONV_TO_OVF_I_UN (lreg) {
615         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
616         MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
617         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
618 }
619
620 reg: OP_LCONV_TO_OVF_U4 (lreg) {
621         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
622         MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
623         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
624 }
625
626 reg: OP_LCONV_TO_OVF_I (lreg) {
627         tree->dreg = state->reg1;
628         tree->sreg1 = state->left->reg1;
629         tree->sreg2 = state->left->reg2;
630         mono_bblock_add_inst (s->cbb, tree);
631 }
632
633 reg: OP_LCONV_TO_OVF_I4 (lreg) {
634         tree->dreg = state->reg1;
635         tree->sreg1 = state->left->reg1;
636         tree->sreg2 = state->left->reg2;
637         tree->opcode = OP_LCONV_TO_OVF_I;
638         mono_bblock_add_inst (s->cbb, tree);
639 }
640
641 lreg: OP_LCONV_TO_OVF_I8_UN (lreg) {
642         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
643         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
644
645         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
646         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
647 }
648
649 lreg: OP_LCONV_TO_OVF_U8 (lreg) {
650         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
651         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
652
653         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
654         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
655 }
656
657 lreg: OP_LCONV_TO_OVF_I8 (lreg) {
658         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
659         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
660 }
661
662 lreg: OP_LCONV_TO_OVF_U8_UN (lreg) {
663         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
664         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
665 }
666
667 %%