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