4 # inssel-long32.brg: burg file for 64bit instructions on 32bit architectures
7 # Dietmar Maurer (dietmar@ximian.com)
9 # (C) 2002 Ximian, Inc.
13 # We use a new non-terminal called "lreg" for 64bit registers, and
14 # emulate lreg with 2 32bit registers.
17 stmt: CEE_POP (lreg) {
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;
26 tree->inst_ms_word = -1;
28 tree->inst_ms_word = 0;
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;
41 int data = state->tree->inst_c0;
43 MONO_EMIT_NEW_ICONST (s, state->reg1, data);
46 MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
48 MONO_EMIT_NEW_ICONST (s, state->reg2, -1);
52 MONO_EMIT_NEW_ICONST (s, state->reg1, tree->inst_ls_word);
53 MONO_EMIT_NEW_ICONST (s, state->reg2, tree->inst_ms_word);
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);
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);
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);
77 lreg: OP_BIGMUL (reg, reg) {
78 MONO_EMIT_NEW_BIALU (s, OP_BIGMUL, state->reg1, state->left->reg1, state->right->reg1);
81 lreg: OP_BIGMUL_UN (reg, reg) {
82 MONO_EMIT_NEW_BIALU (s, OP_BIGMUL_UN, state->reg1, state->left->reg1, state->right->reg1);
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);
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);
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");
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");
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);
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);
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);
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");
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");
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);
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);
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);
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);
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);
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);
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);
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);
182 reg: OP_CEQ (OP_COMPARE (lreg, lreg)) {
183 MonoInst *word_differs;
185 MONO_NEW_LABEL (s, word_differs);
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);
194 mono_bblock_add_inst (s->cbb, word_differs);
197 reg: OP_CLT (OP_COMPARE (lreg, lreg)) {
198 MonoInst *set_to_0, *set_to_1;
200 MONO_NEW_LABEL (s, set_to_0);
201 MONO_NEW_LABEL (s, set_to_1);
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);
214 reg: OP_CLT_UN (OP_COMPARE (lreg, lreg)) {
215 MonoInst *set_to_0, *set_to_1;
217 MONO_NEW_LABEL (s, set_to_0);
218 MONO_NEW_LABEL (s, set_to_1);
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);
231 reg: OP_CGT (OP_COMPARE (lreg, lreg)) {
232 MonoInst *set_to_0, *set_to_1;
234 MONO_NEW_LABEL (s, set_to_0);
235 MONO_NEW_LABEL (s, set_to_1);
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);
248 reg: OP_CGT_UN (OP_COMPARE (lreg, lreg)) {
249 MonoInst *set_to_0, *set_to_1;
251 MONO_NEW_LABEL (s, set_to_0);
252 MONO_NEW_LABEL (s, set_to_1);
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);
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);
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);
279 stmt: CEE_BEQ (OP_COMPARE (lreg, lreg)) {
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);
287 stmt: CEE_BEQ (OP_COMPARE (lreg, i8con)) {
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);
295 stmt: CEE_BLE (OP_COMPARE (lreg, lreg)) {
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);
304 stmt: CEE_BLE (OP_COMPARE (lreg, i8con)) {
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);
313 stmt: CEE_BLE_UN (OP_COMPARE (lreg, lreg)) {
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);
322 stmt: CEE_BLE_UN (OP_COMPARE (lreg, i8con)) {
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);
331 stmt: CEE_BGE (OP_COMPARE (lreg, lreg)) {
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);
340 stmt: CEE_BGE (OP_COMPARE (lreg, i8con)) {
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);
349 stmt: CEE_BGE_UN (OP_COMPARE (lreg, lreg)) {
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);
358 stmt: CEE_BGE_UN (OP_COMPARE (lreg, i8con)) {
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);
367 stmt: CEE_BLT (OP_COMPARE (lreg, lreg)) {
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);
376 stmt: CEE_BLT (OP_COMPARE (lreg, i8con)) {
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);
385 stmt: CEE_BLT_UN (OP_COMPARE (lreg, lreg)) {
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);
394 stmt: CEE_BLT_UN (OP_COMPARE (lreg, i8con)) {
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);
403 stmt: CEE_BGT (OP_COMPARE (lreg, lreg)) {
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);
412 stmt: CEE_BGT (OP_COMPARE (lreg, i8con)) {
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);
421 stmt: CEE_BGT_UN (OP_COMPARE (lreg, lreg)) {
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);
430 stmt: CEE_BGT_UN (OP_COMPARE (lreg, i8con)) {
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);
439 lreg: CEE_CONV_I8 (OP_ICONST) {
440 int data = state->left->tree->inst_c0;
442 MONO_EMIT_NEW_ICONST (s, state->reg1, data);
445 MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
447 MONO_EMIT_NEW_ICONST (s, state->reg2, -1);
450 lreg: CEE_CONV_I8 (reg) {
451 MonoInst *is_negative, *end_label;
452 int tmpreg = mono_regstate_next_int (s->rs);
454 MONO_NEW_LABEL (s, is_negative);
455 MONO_NEW_LABEL (s, end_label);
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
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);
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);
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);
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);
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);
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);
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);
508 freg: OP_LCONV_TO_R_UN (lreg) {
509 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->left->reg2);
512 lreg: OP_FCONV_TO_I8 (freg) {
513 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
516 lreg: OP_FCONV_TO_U8 (freg) {
517 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
520 reg: OP_LCONV_TO_I4 (i8con) {
521 MONO_EMIT_NEW_ICONST (s, state->reg1, state->left->tree->inst_ls_word);
524 reg: OP_LCONV_TO_I4 (lreg) {
525 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
528 reg: OP_LCONV_TO_U4 (lreg) {
529 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
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);
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);
542 reg: OP_LCONV_TO_U (lreg) {
543 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
546 reg: OP_LCONV_TO_I (lreg) {
547 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
550 reg: OP_LCONV_TO_I1 (lreg) {
551 MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
554 reg: OP_LCONV_TO_U1 (lreg) {
555 MONO_EMIT_UNALU (s, tree, CEE_CONV_U1, state->reg1, state->left->reg1);
558 reg: OP_LCONV_TO_I2 (lreg) {
559 MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
562 reg: OP_LCONV_TO_U2 (lreg) {
563 MONO_EMIT_UNALU (s, tree, CEE_CONV_U2, state->reg1, state->left->reg1);
566 reg: OP_LCONV_TO_OVF_I1 (lreg) {
567 MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
568 MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
569 MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, -1);
570 MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
572 MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 127);
573 MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
574 MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -128);
575 MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
576 MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
579 reg: OP_LCONV_TO_OVF_U1 (lreg) {
580 MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
581 MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
583 /* probe value to be within 0 to 255 */
584 MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 255);
585 MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
586 MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, 0xff);
589 reg: OP_LCONV_TO_OVF_I2 (lreg) {
590 MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
591 MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
592 MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, -1);
593 MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
595 /* Probe value to be within -32768 and 32767 */
596 MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 32767);
597 MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
598 MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -32768);
599 MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
600 MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
603 reg: OP_LCONV_TO_OVF_U2 (lreg) {
604 MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
605 MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
607 /* Probe value to be within 0 and 65535 */
608 MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0xffff);
609 MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
610 MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, 0xffff);
614 reg: OP_LCONV_TO_OVF_U4_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);
620 reg: OP_LCONV_TO_OVF_I_UN (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);
626 reg: OP_LCONV_TO_OVF_U4 (lreg) {
627 MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
628 MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
629 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
632 reg: OP_LCONV_TO_OVF_I (lreg) {
633 tree->dreg = state->reg1;
634 tree->sreg1 = state->left->reg1;
635 tree->sreg2 = state->left->reg2;
636 mono_bblock_add_inst (s->cbb, tree);
639 reg: OP_LCONV_TO_OVF_I4 (lreg) {
640 tree->dreg = state->reg1;
641 tree->sreg1 = state->left->reg1;
642 tree->sreg2 = state->left->reg2;
643 tree->opcode = OP_LCONV_TO_OVF_I;
644 mono_bblock_add_inst (s->cbb, tree);
647 lreg: OP_LCONV_TO_OVF_I8_UN (lreg) {
648 MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
649 MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
651 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
652 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
655 lreg: OP_LCONV_TO_OVF_U8 (lreg) {
656 MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
657 MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
659 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
660 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
663 lreg: OP_LCONV_TO_OVF_I8 (lreg) {
664 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
665 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
668 lreg: OP_LCONV_TO_OVF_U8_UN (lreg) {
669 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
670 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);