23365a27a56719bde377c1490f5c9f392dc12e31
[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_c0 = data;
25         if (data < 0)
26                 tree->inst_c1 = -1;
27         else
28                 tree->inst_c1 = 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_c0 = data;
35         tree->inst_c1 = 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_c0);
53         MONO_EMIT_NEW_ICONST (s, state->reg2, tree->inst_c1);
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);
59         MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, state->reg2, 
60                                        state->left->tree->inst_basereg, state->left->tree->inst_offset + 4);
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 + 4, 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, 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 + 4, state->right->tree->inst_c1);
73         MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STOREI4_MEMBASE_IMM, state->left->tree->inst_basereg,
74                                          state->left->tree->inst_offset, state->right->tree->inst_c0);
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_c0);
106         MONO_EMIT_BIALU_IMM (s, tree, OP_ADC_IMM, state->reg2, state->left->reg2, state->right->tree->inst_c1);
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_c0);
116         MONO_EMIT_BIALU_IMM (s, tree, OP_SBB_IMM, state->reg2, state->left->reg2, state->right->tree->inst_c1);
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, CEE_SUB, 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_c0);
140         MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg2, state->left->reg2, state->right->tree->inst_c1);
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_c0);
150         MONO_EMIT_BIALU_IMM (s, tree, OP_OR_IMM, state->reg2, state->left->reg2, state->right->tree->inst_c1);
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_c0);
160         MONO_EMIT_BIALU_IMM (s, tree, OP_XOR_IMM, state->reg2, state->left->reg2, state->right->tree->inst_c1);
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         MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->reg1, 1);
172         MONO_EMIT_BIALU_IMM (s, tree, OP_ADC_IMM, state->reg2, state->reg2, 0);
173 }
174
175 reg: OP_CEQ (OP_COMPARE (lreg, lreg)) { 
176         MonoInst *word_differs;
177         
178         MONO_NEW_LABEL (s, word_differs);
179
180         MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
181         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
182         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, word_differs);
183         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
184         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, word_differs);
185         MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
186         
187         mono_bblock_add_inst (s->cbb, word_differs);
188 }
189
190 reg: OP_CLT (OP_COMPARE (lreg, lreg)) { 
191         MonoInst *set_to_0, *set_to_1;
192         
193         MONO_NEW_LABEL (s, set_to_0);
194         MONO_NEW_LABEL (s, set_to_1);
195
196         MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
197         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
198         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGT, set_to_0);
199         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, set_to_1);
200         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
201         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGE_UN, set_to_0);
202         mono_bblock_add_inst (s->cbb, set_to_1);
203         MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
204         mono_bblock_add_inst (s->cbb, set_to_0);
205 }       
206
207 reg: OP_CLT_UN (OP_COMPARE (lreg, lreg)) {      
208         MonoInst *set_to_0, *set_to_1;
209         
210         MONO_NEW_LABEL (s, set_to_0);
211         MONO_NEW_LABEL (s, set_to_1);
212
213         MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
214         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
215         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGT_UN, set_to_0);
216         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, set_to_1);
217         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
218         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGE_UN, set_to_0);
219         mono_bblock_add_inst (s->cbb, set_to_1);
220         MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
221         mono_bblock_add_inst (s->cbb, set_to_0);
222 }       
223
224 reg: OP_CGT (OP_COMPARE (lreg, lreg)) { 
225         MonoInst *set_to_0, *set_to_1;
226         
227         MONO_NEW_LABEL (s, set_to_0);
228         MONO_NEW_LABEL (s, set_to_1);
229
230         MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
231         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->right->reg2, state->left->left->reg2);
232         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGT, set_to_0);
233         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, set_to_1);
234         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->right->reg1, state->left->left->reg1);
235         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGE_UN, set_to_0);
236         mono_bblock_add_inst (s->cbb, set_to_1);
237         MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
238         mono_bblock_add_inst (s->cbb, set_to_0);
239 }       
240
241 reg: OP_CGT_UN (OP_COMPARE (lreg, lreg)) {      
242         MonoInst *set_to_0, *set_to_1;
243         
244         MONO_NEW_LABEL (s, set_to_0);
245         MONO_NEW_LABEL (s, set_to_1);
246
247         MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
248         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->right->reg2, state->left->left->reg2);
249         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGT_UN, set_to_0);
250         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, set_to_1);
251         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->right->reg1, state->left->left->reg1);
252         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGE_UN, set_to_0);
253         mono_bblock_add_inst (s->cbb, set_to_1);
254         MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
255         mono_bblock_add_inst (s->cbb, set_to_0);
256 }       
257
258 stmt: CEE_BNE_UN (OP_COMPARE (lreg, lreg)) {
259         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
260         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_true_bb);
261         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
262         mono_bblock_add_inst (s->cbb, tree);
263 }
264
265 stmt: CEE_BNE_UN (OP_COMPARE (lreg, i8con)) {
266         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_c0);
267         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_true_bb);
268         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_c1);
269         mono_bblock_add_inst (s->cbb, tree);
270 }
271
272 stmt: CEE_BEQ (OP_COMPARE (lreg, lreg)) {
273         
274         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
275         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
276         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
277         mono_bblock_add_inst (s->cbb, tree);
278 }
279
280 stmt: CEE_BEQ (OP_COMPARE (lreg, i8con)) {
281         
282         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_c0);
283         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
284         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_c1);
285         mono_bblock_add_inst (s->cbb, tree);
286 }
287
288 stmt: CEE_BLE (OP_COMPARE (lreg, lreg)) {
289
290         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
291         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT, tree->inst_true_bb);
292         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
293         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
294         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLE_UN, tree->inst_true_bb);
295 }
296
297 stmt: CEE_BLE (OP_COMPARE (lreg, i8con)) {
298
299         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_c1);
300         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT, tree->inst_true_bb);
301         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
302         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_c0);
303         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLE_UN, tree->inst_true_bb);
304 }
305
306 stmt: CEE_BLE_UN (OP_COMPARE (lreg, lreg)) {
307
308         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
309         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
310         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
311         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
312         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLE_UN, tree->inst_true_bb);
313 }
314
315 stmt: CEE_BLE_UN (OP_COMPARE (lreg, i8con)) {
316
317         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_c1);
318         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
319         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
320         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_c0);
321         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLE_UN, tree->inst_true_bb);
322 }
323
324 stmt: CEE_BGE (OP_COMPARE (lreg, lreg)) {
325
326         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
327         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT, tree->inst_true_bb);
328         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
329         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
330         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_true_bb);
331 }
332
333 stmt: CEE_BGE (OP_COMPARE (lreg, i8con)) {
334
335         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_c1);
336         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT, tree->inst_true_bb);
337         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
338         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_c0);
339         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_true_bb);
340 }
341
342 stmt: CEE_BGE_UN (OP_COMPARE (lreg, lreg)) {
343
344         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
345         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
346         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
347         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
348         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_true_bb);
349 }
350
351 stmt: CEE_BGE_UN (OP_COMPARE (lreg, i8con)) {
352
353         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_c1);
354         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
355         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
356         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_c0);
357         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_true_bb);
358 }
359
360 stmt: CEE_BLT (OP_COMPARE (lreg, lreg)) {
361
362         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
363         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT, tree->inst_true_bb);
364         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
365         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
366         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
367 }
368
369 stmt: CEE_BLT (OP_COMPARE (lreg, i8con)) {
370
371         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_c1);
372         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT, tree->inst_true_bb);
373         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
374         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_c0);
375         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
376 }
377
378 stmt: CEE_BLT_UN (OP_COMPARE (lreg, lreg)) {
379
380         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
381         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
382         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
383         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
384         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
385 }
386
387 stmt: CEE_BLT_UN (OP_COMPARE (lreg, i8con)) {
388
389         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_c1);
390         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
391         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
392         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_c0);
393         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
394 }
395
396 stmt: CEE_BGT (OP_COMPARE (lreg, lreg)) {
397
398         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
399         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT, tree->inst_true_bb);
400         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
401         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
402         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
403 }
404
405 stmt: CEE_BGT (OP_COMPARE (lreg, i8con)) {
406
407         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_c1);
408         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT, tree->inst_true_bb);
409         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
410         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_c0);
411         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
412 }
413
414 stmt: CEE_BGT_UN (OP_COMPARE (lreg, lreg)) {
415
416         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
417         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
418         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
419         MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
420         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
421 }
422
423 stmt: CEE_BGT_UN (OP_COMPARE (lreg, i8con)) {
424
425         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_c1);
426         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
427         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
428         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_c0);
429         MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
430 }
431
432 lreg: CEE_CONV_I8 (OP_ICONST) {
433         int data = state->left->tree->inst_c0;
434
435        MONO_EMIT_NEW_ICONST (s, state->reg1, data);
436
437        if (data >= 0)
438                MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
439        else 
440                MONO_EMIT_NEW_ICONST (s, state->reg2, -1);
441 }
442
443 lreg: CEE_CONV_I8 (reg) {
444         MonoInst *is_negative, *end_label;
445         int tmpreg = mono_regstate_next_int (s->rs);
446         
447         MONO_NEW_LABEL (s, is_negative);
448         MONO_NEW_LABEL (s, end_label);
449
450         /* branchless code:
451          * low = reg;
452          * tmp = low > -1 ? 1: 0;
453          * high = tmp - 1; if low is zero or pos high becomes 0, else -1
454          * not sure why it doesn't work in practice
455          */
456         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
457         /*MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->reg1, -1);
458         tree->dreg = tmpreg;
459         tree->opcode = OP_CGT;
460         mono_bblock_add_inst (s->cbb, tree);
461         MONO_EMIT_NEW_BIALU_IMM (s, OP_SUB_IMM, state->reg2, tmpreg, -1);*/
462         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->reg1, 0);
463         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BLT, is_negative);
464         MONO_EMIT_NEW_ICONST (s, tmpreg, 0);
465         MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BR, end_label);
466         mono_bblock_add_inst (s->cbb, is_negative);
467         MONO_EMIT_NEW_ICONST (s, tmpreg, -1);
468         mono_bblock_add_inst (s->cbb, end_label);
469         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg2, tmpreg);
470 }
471
472 lreg: CEE_CONV_U8 (reg) {
473         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
474         MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
475 }
476
477 lreg: CEE_CONV_OVF_U8 (reg) {
478         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0);
479         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
480         MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
481         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
482 }
483
484 lreg: CEE_CONV_OVF_I8 (reg) {
485         /* a signed 32 bit num always fits in a signed 64 bit one */
486         MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
487         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
488 }
489
490 lreg: CEE_CONV_OVF_I8_UN (reg) {
491         /* an unsigned 32 bit num always fits in a signed 64 bit one */
492         MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
493         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
494 }
495
496 lreg: CEE_CONV_OVF_U8_UN (reg) {
497         MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
498         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
499 }
500
501 freg: OP_LCONV_TO_R_UN (lreg) {
502         MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->left->reg2);
503 }
504
505 lreg: OP_FCONV_TO_I8 (freg) {
506         MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
507 }
508
509 lreg: OP_FCONV_TO_U8 (freg) {
510         MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
511 }
512
513 reg: OP_LCONV_TO_I4 (i8con) {
514         MONO_EMIT_NEW_ICONST (s, state->reg1, state->left->tree->inst_c0);
515 }
516
517 reg: OP_LCONV_TO_I4 (lreg) {
518         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
519 }
520
521 reg: OP_LCONV_TO_U4 (lreg) {
522         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
523 }
524
525 lreg: OP_LCONV_TO_U8 (lreg) {
526         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
527         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
528 }
529
530 lreg: OP_LCONV_TO_I8 (lreg) {
531         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
532         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
533 }
534
535 reg: OP_LCONV_TO_U (lreg) {
536         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
537 }
538
539 reg: OP_LCONV_TO_I (lreg) {
540         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
541 }
542
543 reg: OP_LCONV_TO_I1 (lreg) {
544         MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
545 }
546
547 reg: OP_LCONV_TO_U1 (lreg) {
548         MONO_EMIT_UNALU (s, tree, CEE_CONV_U1, state->reg1, state->left->reg1);
549 }
550
551 reg: OP_LCONV_TO_I2 (lreg) {
552         MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
553 }
554
555 reg: OP_LCONV_TO_U2 (lreg) {
556         MONO_EMIT_UNALU (s, tree, CEE_CONV_U2, state->reg1, state->left->reg1);
557 }
558
559 reg: OP_LCONV_TO_OVF_I1 (lreg) {
560         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
561         MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
562         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, -1);
563         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
564
565         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 127);
566         MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
567         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -128);
568         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
569         MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
570 }
571
572 reg: OP_LCONV_TO_OVF_U1 (lreg) {
573         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
574         MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
575
576         /* probe value to be within 0 to 255 */
577         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 255);
578         MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
579         MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, 0xff);
580 }
581
582 reg: OP_LCONV_TO_OVF_I2 (lreg) {
583         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
584         MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
585         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, -1);
586         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
587
588         /* Probe value to be within -32768 and 32767 */
589         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 32767);
590         MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
591         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -32768);
592         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
593         MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
594 }
595
596 reg: OP_LCONV_TO_OVF_U2 (lreg) {
597         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
598         MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
599
600         /* Probe value to be within 0 and 65535 */
601         MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0xffff);
602         MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
603         MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, 0xffff);
604 }
605
606
607 reg: OP_LCONV_TO_OVF_U4_UN (lreg) {
608         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
609         MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
610         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
611 }
612
613 reg: OP_LCONV_TO_OVF_I_UN (lreg) {
614         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
615         MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
616         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
617 }
618
619 reg: OP_LCONV_TO_OVF_U4 (lreg) {
620         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
621         MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
622         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
623 }
624
625 reg: OP_LCONV_TO_OVF_I (lreg) {
626         tree->dreg = state->reg1;
627         tree->sreg1 = state->left->reg1;
628         tree->sreg2 = state->left->reg2;
629         mono_bblock_add_inst (s->cbb, tree);
630 }
631
632 reg: OP_LCONV_TO_OVF_I4 (lreg) {
633         tree->dreg = state->reg1;
634         tree->sreg1 = state->left->reg1;
635         tree->sreg2 = state->left->reg2;
636         tree->opcode = OP_LCONV_TO_OVF_I;
637         mono_bblock_add_inst (s->cbb, tree);
638 }
639
640 lreg: OP_LCONV_TO_OVF_I8_UN (lreg) {
641         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
642         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
643
644         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
645         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
646 }
647
648 lreg: OP_LCONV_TO_OVF_U8 (lreg) {
649         MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
650         MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
651
652         MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
653         MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
654 }
655
656 %%