4 # inssel-long32-mips.brg: burg file for integer instructions on 32bit MIPS
7 # Mark Mason (mason@broadcom.com)
9 # Based on inssel-long32.brg by:
10 # Dietmar Maurer (dietmar@ximian.com)
13 # (C) 2002 Ximian, Inc.
21 # basic alu operations
24 reg: CEE_AND (reg, reg),
25 reg: CEE_OR (reg, reg),
26 reg: CEE_XOR (reg, reg),
27 reg: CEE_ADD (reg, reg),
28 reg: CEE_SUB (reg, reg),
29 reg: CEE_MUL (reg, reg),
30 reg: CEE_MUL_OVF (reg, reg),
31 reg: CEE_MUL_OVF_UN (reg, reg),
32 reg: CEE_DIV (reg, reg),
33 reg: CEE_DIV_UN (reg, reg),
34 reg: CEE_REM (reg, reg),
35 reg: CEE_REM_UN (reg, reg),
36 reg: CEE_SHL (reg, reg),
37 reg: CEE_SHR (reg, reg),
38 reg: CEE_SHR_UN (reg, reg) {
39 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
44 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
48 reg: CEE_AND (reg, OP_ICONST) {
49 MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
52 reg: CEE_OR (reg, OP_ICONST) {
53 MONO_EMIT_BIALU_IMM (s, tree, OP_OR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
56 reg: CEE_XOR (reg, OP_ICONST) {
57 MONO_EMIT_BIALU_IMM (s, tree, OP_XOR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
60 reg: CEE_ADD (reg, OP_ICONST) {
61 MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
64 reg: CEE_SUB (reg, OP_ICONST) {
65 MONO_EMIT_BIALU_IMM (s, tree, OP_SUB_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
68 reg: CEE_MUL (reg, OP_ICONST) {
69 MONO_EMIT_BIALU_IMM (s, tree, OP_MUL_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
72 reg: CEE_SHL (reg, OP_ICONST) {
73 MONO_EMIT_BIALU_IMM (s, tree, OP_SHL_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
76 reg: CEE_SHR (reg, OP_ICONST) {
77 MONO_EMIT_BIALU_IMM (s, tree, OP_SHR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
80 reg: CEE_SHR_UN (reg, OP_ICONST) {
81 MONO_EMIT_BIALU_IMM (s, tree, OP_SHR_UN_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
84 reg: CEE_ADD_OVF (reg, reg) {
85 MONO_EMIT_NEW_BIALU (s, OP_ADDCC, state->reg1, state->left->reg1, state->right->reg1);
86 MONO_EMIT_NEW_COND_EXC (s, OV, "OverflowException");
89 reg: CEE_ADD_OVF_UN (reg, reg) {
90 MONO_EMIT_NEW_BIALU (s, OP_ADDCC, state->reg1, state->left->reg1, state->right->reg1);
91 MONO_EMIT_NEW_COND_EXC (s, C, "OverflowException");
94 reg: CEE_SUB (reg, CEE_LDIND_I4 (OP_REGVAR)) {
95 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->left->tree->dreg);
98 reg: CEE_SUB_OVF (reg, reg) {
99 MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1);
100 MONO_EMIT_NEW_COND_EXC (s, OV, "OverflowException");
103 reg: CEE_SUB_OVF_UN (reg, reg) {
104 MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1);
105 MONO_EMIT_NEW_COND_EXC (s, C, "OverflowException");
108 # cflags: OP_COMPARE (reg, reg) {
109 # tree->sreg1 = state->left->reg1;
110 # tree->sreg2 = state->right->reg1;
111 # mono_bblock_add_inst (s->cbb, tree);
114 # cflags: OP_COMPARE (CEE_LDIND_REF (OP_REGVAR), reg),
115 # cflags: OP_COMPARE (CEE_LDIND_I (OP_REGVAR), reg),
116 # cflags: OP_COMPARE (CEE_LDIND_I4 (OP_REGVAR), reg),
117 # cflags: OP_COMPARE (CEE_LDIND_U4 (OP_REGVAR), reg) {
118 # tree->sreg1 = state->left->left->tree->dreg;
119 # tree->sreg2 = state->right->reg1;
120 # mono_bblock_add_inst (s->cbb, tree);
123 # cflags: OP_COMPARE (CEE_LDIND_REF (OP_REGVAR), CEE_LDIND_REF (OP_REGVAR)),
124 # cflags: OP_COMPARE (CEE_LDIND_I (OP_REGVAR), CEE_LDIND_I (OP_REGVAR)),
125 # cflags: OP_COMPARE (CEE_LDIND_I4 (OP_REGVAR), CEE_LDIND_I4 (OP_REGVAR)),
126 # cflags: OP_COMPARE (CEE_LDIND_U4 (OP_REGVAR), CEE_LDIND_U4 (OP_REGVAR)) {
127 # tree->sreg1 = state->left->left->tree->dreg;
128 # tree->sreg2 = state->right->left->tree->dreg;
129 # mono_bblock_add_inst (s->cbb, tree);
132 # cflags: OP_COMPARE (CEE_LDIND_REF (OP_REGVAR), OP_ICONST),
133 # cflags: OP_COMPARE (CEE_LDIND_I (OP_REGVAR), OP_ICONST),
134 # cflags: OP_COMPARE (CEE_LDIND_I4 (OP_REGVAR), OP_ICONST),
135 # cflags: OP_COMPARE (CEE_LDIND_U4 (OP_REGVAR), OP_ICONST) {
136 # tree->opcode = OP_COMPARE_IMM;
137 # tree->sreg1 = state->left->left->tree->dreg;
138 # tree->inst_imm = state->right->tree->inst_c0;
139 # mono_bblock_add_inst (s->cbb, tree);
142 # cflags: OP_COMPARE (reg, OP_ICONST) {
143 # tree->opcode = OP_COMPARE_IMM;
144 # tree->sreg1 = state->left->reg1;
145 # tree->inst_imm = state->right->tree->inst_c0;
146 # mono_bblock_add_inst (s->cbb, tree);
149 # stmt: CEE_BNE_UN (cflags),
150 # stmt: CEE_BEQ (cflags),
151 # stmt: CEE_BLT (cflags),
152 # stmt: CEE_BLT_UN (cflags),
153 # stmt: CEE_BGT (cflags),
154 # stmt: CEE_BGT_UN (cflags),
155 # stmt: CEE_BGE (cflags),
156 # stmt: CEE_BGE_UN (cflags),
157 # stmt: CEE_BLE (cflags),
158 # stmt: CEE_BLE_UN (cflags) {
159 # mono_bblock_add_inst (s->cbb, tree);
162 # reg: OP_CEQ (cflags),
163 # reg: OP_CLT (cflags),
164 # reg: OP_CLT_UN (cflags),
165 # reg: OP_CGT (cflags),
166 # reg: OP_CGT_UN (cflags) {
167 # tree->dreg = state->reg1;
168 # mono_bblock_add_inst (s->cbb, tree);
178 # We use a new non-terminal called "lreg" for 64bit registers, and
179 # emulate lreg with 2 32bit registers.
182 stmt: CEE_POP (lreg) {
186 i8con: CEE_CONV_I8 (OP_ICONST) "0" {
187 int data = state->left->tree->inst_c0;
188 tree->opcode = OP_I8CONST;
189 tree->inst_ls_word = data;
191 tree->inst_ms_word = -1;
193 tree->inst_ms_word = 0;
196 i8con: CEE_CONV_U8 (OP_ICONST) "0" {
197 int data = state->left->tree->inst_c0;
198 tree->opcode = OP_I8CONST;
199 tree->inst_ls_word = data;
200 tree->inst_ms_word = 0;
203 i8con: OP_I8CONST "0"
206 int data = state->tree->inst_c0;
208 MONO_EMIT_NEW_ICONST (s, state->reg1, data);
211 MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
213 MONO_EMIT_NEW_ICONST (s, state->reg2, -1);
217 MONO_EMIT_NEW_ICONST (s, state->reg1, tree->inst_ls_word);
218 MONO_EMIT_NEW_ICONST (s, state->reg2, tree->inst_ms_word);
221 lreg: CEE_LDIND_I8 (base) {
222 MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, state->reg1,
223 state->left->tree->inst_basereg, state->left->tree->inst_offset + MINI_LS_WORD_OFFSET);
224 MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, state->reg2,
225 state->left->tree->inst_basereg, state->left->tree->inst_offset + MINI_MS_WORD_OFFSET);
228 stmt: CEE_STIND_I8 (base, lreg) {
229 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, state->left->tree->inst_basereg,
230 state->left->tree->inst_offset + MINI_LS_WORD_OFFSET, state->right->reg1);
231 MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, state->left->tree->inst_basereg,
232 state->left->tree->inst_offset + MINI_MS_WORD_OFFSET, state->right->reg2);
235 stmt: CEE_STIND_I8 (base, i8con) {
236 MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STOREI4_MEMBASE_IMM, state->left->tree->inst_basereg,
237 state->left->tree->inst_offset + MINI_LS_WORD_OFFSET, state->right->tree->inst_ls_word);
238 MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STOREI4_MEMBASE_IMM, state->left->tree->inst_basereg,
239 state->left->tree->inst_offset + MINI_MS_WORD_OFFSET, state->right->tree->inst_ms_word);
242 lreg: OP_BIGMUL (reg, reg),
243 lreg: OP_BIGMUL_UN (reg, reg) {
244 MONO_EMIT_NEW_BIALU (s, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
247 lreg: OP_LONG_SHRUN_32 (lreg) {
248 /* just move the upper half to the lower and zero the high word */
249 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg2);
250 MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
253 reg: OP_LCONV_TO_I4 (OP_LONG_SHRUN_32 (lreg)),
254 reg: OP_LCONV_TO_U4 (OP_LONG_SHRUN_32 (lreg)) {
255 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->left->reg2);
259 lreg: OP_LONG_SHRUN_32 (CEE_LDIND_I8 (base)) {
260 /* just move the upper half to the lower and zero the high word */
261 MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, state->reg1,
262 state->left->left->tree->inst_basereg, state->left->left->tree->inst_offset + MINI_MS_WORD_OFFSET);
263 MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
266 reg: OP_LCONV_TO_I4 (OP_LONG_SHRUN_32 (CEE_LDIND_I8 (base))),
267 reg: OP_LCONV_TO_U4 (OP_LONG_SHRUN_32 (CEE_LDIND_I8 (base))) {
268 /* just move the upper half to the lower and zero the high word */
269 MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, state->reg1,
270 state->left->left->left->tree->inst_basereg,
271 state->left->left->left->tree->inst_offset + MINI_MS_WORD_OFFSET);
274 lreg: OP_LADD (lreg, i8con) {
275 int tmp1 = mono_regstate_next_int (s->rs);
277 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
278 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp1, state->reg1, state->left->reg1);
279 MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
280 MONO_EMIT_BIALU (s, tree, CEE_ADD, state->reg2, tmp1, state->reg2);
283 lreg: OP_LADD (lreg, lreg) {
284 int tmp1 = mono_regstate_next_int (s->rs);
286 MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg1, state->left->reg1, state->right->reg1);
287 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp1, state->reg1, state->left->reg1);
288 MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg2, state->left->reg2, state->right->reg2);
289 MONO_EMIT_BIALU (s, tree, CEE_ADD, state->reg2, tmp1, state->reg2);
292 lreg: OP_LADD_OVF (lreg, lreg) {
293 int tmp1 = mono_regstate_next_int (s->rs);
294 int tmp2 = mono_regstate_next_int (s->rs);
295 int tmp3 = mono_regstate_next_int (s->rs);
296 int tmp4 = mono_regstate_next_int (s->rs);
297 int tmp5 = mono_regstate_next_int (s->rs);
299 MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg1, state->left->reg1, state->right->reg1);
301 /* tmp1 holds the carry from the low 32-bit to the high 32-bits */
303 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp5, state->reg1, state->left->reg1);
305 /* add the high 32-bits, and add in the carry from the low 32-bits */
307 MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg2, state->left->reg2, state->right->reg2);
308 MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg2, tmp5, state->reg2);
310 /* Overflow happens if
313 * XOR of the high bits returns 0 if the signs match
314 * XOR of that with the high bit of the result return 1 if overflow.
317 /* tmp1 = 0 if the signs of the two inputs match, 1 otherwise */
318 MONO_EMIT_NEW_BIALU (s, CEE_XOR, tmp1, state->left->reg2, state->right->reg2);
320 /* set tmp2 = 0 if bit31 of results matches is different than the operands */
321 MONO_EMIT_NEW_BIALU (s, CEE_XOR, tmp2, state->reg2, state->right->reg2);
322 MONO_EMIT_NEW_UNALU (s, CEE_NOT, tmp2, tmp2);
324 /* OR(tmp1, tmp2) = 0 if both conditions are true */
325 MONO_EMIT_NEW_BIALU (s, CEE_OR, tmp3, tmp2, tmp1);
327 MONO_EMIT_NEW_BIALU_IMM (s, OP_SHR_IMM, tmp4, tmp3, 31);
329 /* Now, if (tmp4 == 0) then overflow */
330 MONO_EMIT_NEW_COMPARE_EXC (s, EQ, tmp4, mips_zero, "OverflowException");
333 lreg: OP_LADD_OVF_UN (lreg, lreg) {
334 int tmp1 = mono_regstate_next_int (s->rs);
335 int tmp2 = mono_regstate_next_int (s->rs);
337 MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg1, state->left->reg1, state->right->reg1);
338 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp1, state->reg1, state->left->reg1);
339 MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg2, state->left->reg2, state->right->reg2);
340 MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg2, tmp1, state->reg2);
341 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp2, state->reg2, state->left->reg2);
342 MONO_EMIT_NEW_COMPARE_EXC (s, NE_UN, tmp2, mips_zero, "OverflowException");
345 lreg: OP_LSUB (lreg, i8con) {
346 int tmp1 = mono_regstate_next_int (s->rs);
348 MONO_EMIT_NEW_BIALU_IMM (s, OP_SUB_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
349 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp1, state->left->reg1, state->reg1);
350 MONO_EMIT_NEW_BIALU_IMM (s, OP_SUB_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
351 MONO_EMIT_BIALU (s, tree, CEE_SUB, state->reg2, state->reg2, tmp1);
354 lreg: OP_LSUB (lreg, lreg) {
355 int tmp1 = mono_regstate_next_int (s->rs);
357 MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg1, state->left->reg1, state->right->reg1);
358 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp1, state->left->reg1, state->reg1);
359 MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg2, state->left->reg2, state->right->reg2);
360 MONO_EMIT_BIALU (s, tree, CEE_SUB, state->reg2, state->reg2, tmp1);
363 lreg: OP_LSUB_OVF (lreg, lreg) {
364 int tmp1 = mono_regstate_next_int (s->rs);
365 int tmp2 = mono_regstate_next_int (s->rs);
366 int tmp3 = mono_regstate_next_int (s->rs);
367 int tmp4 = mono_regstate_next_int (s->rs);
368 int tmp5 = mono_regstate_next_int (s->rs);
370 MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg1, state->left->reg1, state->right->reg1);
371 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp5, state->left->reg1, state->reg1);
372 MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg2, state->left->reg2, state->right->reg2);
373 MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg2, state->reg2, tmp5);
375 /* Overflow happens if
378 * XOR of bit31 of the lhs & rhs = 1 if the signs are different
381 * tmp2 = (lhs ^ result)
382 * if ((tmp1 < 0) & (tmp2 < 0)) then overflow
385 MONO_EMIT_NEW_BIALU (s, CEE_XOR, tmp1, state->left->reg2, state->right->reg2);
386 MONO_EMIT_NEW_BIALU (s, CEE_XOR, tmp2, state->left->reg2, state->reg2);
387 MONO_EMIT_NEW_BIALU (s, CEE_AND, tmp3, tmp2, tmp1);
388 MONO_EMIT_NEW_BIALU_IMM (s, OP_SHR_IMM, tmp4, tmp3, 31);
390 /* Now, if (tmp4 == 1) then overflow */
391 MONO_EMIT_NEW_COMPARE_EXC (s, NE_UN, tmp4, mips_zero, "OverflowException");
394 lreg: OP_LSUB_OVF_UN (lreg, lreg) {
395 int tmp1 = mono_regstate_next_int (s->rs);
396 int tmp2 = mono_regstate_next_int (s->rs);
398 MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg1, state->left->reg1, state->right->reg1);
399 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp1, state->left->reg1, state->reg1);
400 MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg2, state->left->reg2, state->right->reg2);
401 MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg2, state->reg2, tmp1);
403 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, tmp2, state->left->reg2, state->reg2);
404 MONO_EMIT_NEW_COMPARE_EXC (s, NE_UN, tmp2, mips_zero, "OverflowException");
407 lreg: OP_LAND (lreg, lreg) {
408 MONO_EMIT_NEW_BIALU (s, CEE_AND, state->reg1, state->left->reg1, state->right->reg1);
409 MONO_EMIT_BIALU (s, tree, CEE_AND, state->reg2, state->left->reg2, state->right->reg2);
412 lreg: OP_LAND (lreg, i8con) {
413 if (state->right->tree->inst_ls_word == 0xffffffff)
414 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
415 else if (state->right->tree->inst_ls_word == 0)
416 MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
418 MONO_EMIT_NEW_BIALU_IMM (s, OP_AND_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
419 if (state->right->tree->inst_ms_word == 0xffffffff)
420 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
421 else if (state->right->tree->inst_ms_word == 0)
422 MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
424 MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
427 lreg: OP_LOR (lreg, lreg) {
428 MONO_EMIT_NEW_BIALU (s, CEE_OR, state->reg1, state->left->reg1, state->right->reg1);
429 MONO_EMIT_BIALU (s, tree, CEE_OR, state->reg2, state->left->reg2, state->right->reg2);
432 lreg: OP_LOR (lreg, i8con) {
433 MONO_EMIT_NEW_BIALU_IMM (s, OP_OR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
434 MONO_EMIT_BIALU_IMM (s, tree, OP_OR_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
437 lreg: OP_LXOR (lreg, lreg) {
438 MONO_EMIT_NEW_BIALU (s, CEE_XOR, state->reg1, state->left->reg1, state->right->reg1);
439 MONO_EMIT_BIALU (s, tree, CEE_XOR, state->reg2, state->left->reg2, state->right->reg2);
442 lreg: OP_LXOR (lreg, i8con) {
443 MONO_EMIT_NEW_BIALU_IMM (s, OP_XOR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
444 MONO_EMIT_BIALU_IMM (s, tree, OP_XOR_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
447 lreg: OP_LNOT (lreg) {
448 MONO_EMIT_NEW_UNALU (s, CEE_NOT, state->reg1, state->left->reg1);
449 MONO_EMIT_UNALU (s, tree, CEE_NOT, state->reg2, state->left->reg2);
452 lreg: OP_LNEG (lreg) "4" {
453 MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg1, mips_zero, state->left->reg1);
454 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, mips_zero, state->reg1);
455 MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg2, mips_zero, state->left->reg2);
456 MONO_EMIT_BIALU (s, tree, CEE_SUB, state->reg2, state->reg2, mips_at);
459 reg: OP_CEQ (OP_LCOMPARE (lreg, lreg)) {
460 MonoInst *word_differs;
461 int lreg1 = state->left->left->reg1;
462 int lreg2 = state->left->left->reg2;
463 int rreg1 = state->left->right->reg1;
464 int rreg2 = state->left->right->reg2;
466 MONO_NEW_LABEL (s, word_differs);
468 MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
469 MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BNE_UN, lreg2, rreg2, word_differs);
470 MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BNE_UN, lreg1, rreg1, word_differs);
471 MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
473 mono_bblock_add_inst (s->cbb, word_differs);
476 reg: OP_CLT (OP_LCOMPARE (lreg, lreg)) {
477 MonoInst *set_to_0, *set_to_1;
478 int lreg1 = state->left->left->reg1;
479 int lreg2 = state->left->left->reg2;
480 int rreg1 = state->left->right->reg1;
481 int rreg2 = state->left->right->reg2;
483 MONO_NEW_LABEL (s, set_to_0);
484 MONO_NEW_LABEL (s, set_to_1);
486 MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
487 MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BGT, lreg2, rreg2, set_to_0);
488 MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BNE_UN, lreg2, rreg2, set_to_1);
489 MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BGE_UN, lreg1, rreg1, set_to_0);
490 mono_bblock_add_inst (s->cbb, set_to_1);
491 MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
492 mono_bblock_add_inst (s->cbb, set_to_0);
495 reg: OP_CLT_UN (OP_LCOMPARE (lreg, lreg)) {
496 MonoInst *set_to_0, *set_to_1;
497 int lreg1 = state->left->left->reg1;
498 int lreg2 = state->left->left->reg2;
499 int rreg1 = state->left->right->reg1;
500 int rreg2 = state->left->right->reg2;
502 MONO_NEW_LABEL (s, set_to_0);
503 MONO_NEW_LABEL (s, set_to_1);
505 MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
507 MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
508 MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BGT_UN, lreg2, rreg2, set_to_0);
509 MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BNE_UN, lreg2, rreg2, set_to_1);
510 MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BGE_UN, lreg1, rreg1, set_to_0);
511 mono_bblock_add_inst (s->cbb, set_to_1);
512 MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
513 mono_bblock_add_inst (s->cbb, set_to_0);
516 reg: OP_CGT (OP_LCOMPARE (lreg, lreg)) {
517 MonoInst *set_to_0, *set_to_1;
518 int lreg1 = state->left->left->reg1;
519 int lreg2 = state->left->left->reg2;
520 int rreg1 = state->left->right->reg1;
521 int rreg2 = state->left->right->reg2;
523 MONO_NEW_LABEL (s, set_to_0);
524 MONO_NEW_LABEL (s, set_to_1);
526 MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
527 MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BGT, rreg2, lreg2, set_to_0);
528 MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BNE_UN, rreg2, lreg2, set_to_1);
529 MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BGE_UN, rreg1, lreg1, set_to_0);
530 mono_bblock_add_inst (s->cbb, set_to_1);
531 MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
532 mono_bblock_add_inst (s->cbb, set_to_0);
535 reg: OP_CGT_UN (OP_LCOMPARE (lreg, lreg)) {
536 MonoInst *set_to_0, *set_to_1;
537 int lreg1 = state->left->left->reg1;
538 int lreg2 = state->left->left->reg2;
539 int rreg1 = state->left->right->reg1;
540 int rreg2 = state->left->right->reg2;
542 MONO_NEW_LABEL (s, set_to_0);
543 MONO_NEW_LABEL (s, set_to_1);
545 MONO_EMIT_NEW_ICONST (s, state->reg1, 0);
546 MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BGT_UN, rreg2, lreg2, set_to_0);
547 MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BNE_UN, rreg2, lreg2, set_to_1);
548 MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BGE_UN, rreg1, lreg1, set_to_0);
549 mono_bblock_add_inst (s->cbb, set_to_1);
550 MONO_EMIT_NEW_ICONST (s, state->reg1, 1);
551 mono_bblock_add_inst (s->cbb, set_to_0);
554 stmt: CEE_BNE_UN (OP_LCOMPARE (lreg, lreg)) {
555 int lreg1 = state->left->left->reg1;
556 int lreg2 = state->left->left->reg2;
557 int rreg1 = state->left->right->reg1;
558 int rreg2 = state->left->right->reg2;
560 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_true_bb);
561 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg1, rreg1, tree->inst_true_bb);
564 stmt: CEE_BNE_UN (OP_LCOMPARE (lreg, i8con)) {
565 int lreg1 = state->left->left->reg1;
566 int lreg2 = state->left->left->reg2;
567 int rreg1 = mono_regstate_next_int (s->rs);
568 int rreg2 = mono_regstate_next_int (s->rs);
570 MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
571 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_true_bb);
572 MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
573 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg1, rreg1, tree->inst_true_bb);
576 stmt: CEE_BEQ (OP_LCOMPARE (lreg, lreg)) {
577 int lreg1 = state->left->left->reg1;
578 int lreg2 = state->left->left->reg2;
579 int rreg1 = state->left->right->reg1;
580 int rreg2 = state->left->right->reg2;
582 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_false_bb);
583 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BEQ, lreg1, rreg1, tree->inst_true_bb);
586 stmt: CEE_BEQ (OP_LCOMPARE (lreg, i8con)) {
587 int lreg1 = state->left->left->reg1;
588 int lreg2 = state->left->left->reg2;
589 int rreg1 = mono_regstate_next_int (s->rs);
590 int rreg2 = mono_regstate_next_int (s->rs);
592 MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
593 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_false_bb);
594 MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
595 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BEQ, lreg1, rreg1, tree->inst_true_bb);
598 stmt: CEE_BLE (OP_LCOMPARE (lreg, lreg)) {
599 int lreg1 = state->left->left->reg1;
600 int lreg2 = state->left->left->reg2;
601 int rreg1 = state->left->right->reg1;
602 int rreg2 = state->left->right->reg2;
604 /* if (lreg2 < rreg2) -> true */
605 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
606 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
608 /* if (rreg2 < lreg2) -> false */
609 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, rreg2, lreg2);
610 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
612 /* (lreg2 == rreg2), if (lreg1 <= rreg1) -> true [or if (rreg1 < lreg1) -> false] */
614 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
615 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
616 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
619 stmt: CEE_BLE (OP_LCOMPARE (lreg, i8con)) {
620 int lreg1 = state->left->left->reg1;
621 int lreg2 = state->left->left->reg2;
622 int rreg1 = mono_regstate_next_int (s->rs);
623 int rreg2 = mono_regstate_next_int (s->rs);
625 MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
627 /* if (lreg2 < rreg2) -> true */
628 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
629 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
631 /* if (rreg2 < lreg2) -> false */
632 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, rreg2, lreg2);
633 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
635 /* (rreg2 == lreg2), if (lreg1 <= rreg1) -> true [or if (rreg1 < lreg1) -> false] */
637 MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
638 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
639 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
640 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
643 stmt: CEE_BLE_UN (OP_LCOMPARE (lreg, lreg)) {
644 int lreg1 = state->left->left->reg1;
645 int lreg2 = state->left->left->reg2;
646 int rreg1 = state->left->right->reg1;
647 int rreg2 = state->left->right->reg2;
649 /* if (lreg2 < rreg2) -> true */
650 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
651 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
653 /* if (rreg2 < lreg2) -> false */
654 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg2, lreg2);
655 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
657 /* (lreg2 == rreg2), if (lreg1 <= rreg1) -> true [or if (rreg1 < lreg1) -> false] */
659 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
660 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
661 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
664 stmt: CEE_BLE_UN (OP_LCOMPARE (lreg, i8con)) {
665 int lreg1 = state->left->left->reg1;
666 int lreg2 = state->left->left->reg2;
667 int rreg1 = mono_regstate_next_int (s->rs);
668 int rreg2 = mono_regstate_next_int (s->rs);
670 MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
672 /* if (lreg2 < rreg2) -> true */
673 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
674 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
676 /* if (rreg2 < lreg2) -> false */
677 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg2, lreg2);
678 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
680 /* (rreg2 == lreg2), if (rreg1 <= lreg1) -> true [or if (rreg1 < lreg1) -> false] */
682 MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
683 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
684 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
685 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
688 stmt: CEE_BGE (OP_LCOMPARE (lreg, lreg)) {
689 int lreg1 = state->left->left->reg1;
690 int lreg2 = state->left->left->reg2;
691 int rreg1 = state->left->right->reg1;
692 int rreg2 = state->left->right->reg2;
694 /* if (lreg2 < rreg2) -> false */
695 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
696 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
698 /* if (rreg2 != lreg2) -> false */
699 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, rreg2, lreg2, tree->inst_false_bb);
701 /* (rreg2 == lreg2), so if (lreg1 < rreg1) -> false */
702 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg1, rreg1);
703 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
704 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
707 stmt: CEE_BGE (OP_LCOMPARE (lreg, i8con)) {
708 int lreg1 = state->left->left->reg1;
709 int lreg2 = state->left->left->reg2;
710 int rreg1 = mono_regstate_next_int (s->rs);
711 int rreg2 = mono_regstate_next_int (s->rs);
713 MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
715 /* if (lreg2 < rreg2) -> false */
716 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
717 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
719 /* if (rreg2 != lreg2) -> false */
720 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, rreg2, lreg2, tree->inst_false_bb);
722 MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
724 /* (rreg2 == lreg2), so if (lreg1 < rreg1) -> false */
725 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg1, rreg1);
726 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
727 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
730 stmt: CEE_BGE_UN (OP_LCOMPARE (lreg, lreg)) {
731 int lreg1 = state->left->left->reg1;
732 int lreg2 = state->left->left->reg2;
733 int rreg1 = state->left->right->reg1;
734 int rreg2 = state->left->right->reg2;
736 /* if (lreg2 < rreg2) -> false */
737 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
738 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
740 /* if (rreg2 != lreg2) -> false */
741 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, rreg2, lreg2, tree->inst_false_bb);
743 /* (rreg2 == lreg2), so if (lreg1 < rreg1) -> false */
744 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg1, rreg1);
745 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
746 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
749 stmt: CEE_BGE_UN (OP_LCOMPARE (lreg, i8con)) {
750 int lreg1 = state->left->left->reg1;
751 int lreg2 = state->left->left->reg2;
752 int rreg1 = mono_regstate_next_int (s->rs);
753 int rreg2 = mono_regstate_next_int (s->rs);
755 MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
757 /* if (lreg2 < rreg2) -> false */
758 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
759 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
761 /* if (rreg2 != lreg2) -> false */
762 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, rreg2, lreg2, tree->inst_false_bb);
764 MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
766 /* (rreg2 == lreg2), so if (lreg1 < rreg1) -> false */
767 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg1, rreg1);
768 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
769 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
772 stmt: CEE_BLT (OP_LCOMPARE (lreg, lreg)) {
773 int lreg1 = state->left->left->reg1;
774 int lreg2 = state->left->left->reg2;
775 int rreg1 = state->left->right->reg1;
776 int rreg2 = state->left->right->reg2;
778 /* if (lreg2 < rreg2) -> true */
779 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
780 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
782 /* if (rreg2 < lreg2) -> false */
783 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, rreg2, lreg2);
784 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
786 /* (lreg2 == rreg2), if (lreg1 < rreg1) -> true */
787 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg1, rreg1);
788 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
789 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
792 stmt: CEE_BLT (OP_LCOMPARE (lreg, i8con)) {
793 int lreg1 = state->left->left->reg1;
794 int lreg2 = state->left->left->reg2;
795 int rreg1 = mono_regstate_next_int (s->rs);
796 int rreg2 = mono_regstate_next_int (s->rs);
798 MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
800 /* if (lreg2 < rreg2) -> true */
801 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
802 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
804 /* if (rreg2 < lreg2) -> false */
805 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, rreg2, lreg2);
806 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
808 MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
810 /* (lreg2 == rreg2), if (lreg1 < rreg1) -> true */
811 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg1, rreg1);
812 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
813 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
816 stmt: CEE_BLT_UN (OP_LCOMPARE (lreg, lreg)) {
817 int lreg1 = state->left->left->reg1;
818 int lreg2 = state->left->left->reg2;
819 int rreg1 = state->left->right->reg1;
820 int rreg2 = state->left->right->reg2;
822 /* if (lreg2 < rreg2) -> true */
823 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
824 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
826 /* if (rreg2 < lreg2) -> false */
827 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg2, lreg2);
828 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
830 /* (lreg2 == rreg2), if (lreg1 < rreg1) -> true */
831 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg1, rreg1);
832 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
833 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
836 stmt: CEE_BLT_UN (OP_LCOMPARE (lreg, i8con)) {
837 int lreg1 = state->left->left->reg1;
838 int lreg2 = state->left->left->reg2;
839 int rreg1 = mono_regstate_next_int (s->rs);
840 int rreg2 = mono_regstate_next_int (s->rs);
842 MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
844 /* if (lreg2 < rreg2) -> true */
845 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
846 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
848 /* if (rreg2 < lreg2) -> false */
849 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg2, lreg2);
850 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
852 MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
854 /* (lreg2 == rreg2), if (lreg1 < rreg1) -> true */
855 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg1, rreg1);
856 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
857 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
860 stmt: CEE_BGT (OP_LCOMPARE (lreg, lreg)) {
861 int lreg1 = state->left->left->reg1;
862 int lreg2 = state->left->left->reg2;
863 int rreg1 = state->left->right->reg1;
864 int rreg2 = state->left->right->reg2;
866 /* if (lreg2 < rreg2) -> false */
867 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
868 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
870 /* if (rreg2 < lreg2) -> true */
871 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, rreg2, lreg2);
872 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
874 /* (rreg2 == lreg2), so if (lreg1 > rreg1) -> true */
875 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
876 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
877 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
880 stmt: CEE_BGT (OP_LCOMPARE (lreg, i8con)) {
881 int lreg1 = state->left->left->reg1;
882 int lreg2 = state->left->left->reg2;
883 int rreg1 = mono_regstate_next_int (s->rs);
884 int rreg2 = mono_regstate_next_int (s->rs);
886 MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
888 /* if (lreg2 < rreg2) -> false */
889 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
890 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
892 /* if (rreg2 < lreg2) -> true */
893 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, rreg2, lreg2);
894 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
896 MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
898 /* (rreg2 == lreg2), so if (lreg1 > rreg1) -> true */
899 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
900 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
901 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
904 stmt: CEE_BGT_UN (OP_LCOMPARE (lreg, lreg)) {
905 int lreg1 = state->left->left->reg1;
906 int lreg2 = state->left->left->reg2;
907 int rreg1 = state->left->right->reg1;
908 int rreg2 = state->left->right->reg2;
910 /* if (lreg2 < rreg2) -> false */
911 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
912 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
914 /* if (rreg2 < lreg2) -> true */
915 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg2, lreg2);
916 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
918 /* (rreg2 == lreg2), so if (lreg1 > rreg1) -> true */
919 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
920 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
921 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
924 stmt: CEE_BGT_UN (OP_LCOMPARE (lreg, i8con)) {
925 int lreg1 = state->left->left->reg1;
926 int lreg2 = state->left->left->reg2;
927 int rreg1 = mono_regstate_next_int (s->rs);
928 int rreg2 = mono_regstate_next_int (s->rs);
930 MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
932 /* if (lreg2 < rreg2) -> false */
933 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
934 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
936 /* if (rreg2 < lreg2) -> true */
937 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg2, lreg2);
938 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
940 MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
942 /* (rreg2 == lreg2), so if (lreg1 > rreg1) -> true */
943 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
944 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
945 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
948 lreg: CEE_CONV_I8 (OP_ICONST) {
949 int data = state->left->tree->inst_c0;
951 MONO_EMIT_NEW_ICONST (s, state->reg1, data);
954 MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
956 MONO_EMIT_NEW_ICONST (s, state->reg2, -1);
959 lreg: CEE_CONV_I8 (reg) {
960 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
961 MONO_EMIT_NEW_BIALU_IMM (s, OP_SHR_IMM, state->reg2, state->left->reg1, 31);
964 lreg: CEE_CONV_U8 (reg) {
965 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
966 MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
969 lreg: CEE_CONV_OVF_U8 (reg) {
970 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, 0, "OverflowException");
971 MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
972 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
975 lreg: CEE_CONV_OVF_I8 (reg) {
976 /* a signed 32 bit num always fits in a signed 64 bit one */
977 MONO_EMIT_NEW_BIALU_IMM (s, OP_SHR_IMM, state->reg2, state->left->reg1, 31);
978 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
981 lreg: CEE_CONV_OVF_I8_UN (reg) {
982 /* an unsigned 32 bit num always fits in a signed 64 bit one */
983 MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
984 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
987 lreg: CEE_CONV_OVF_U8_UN (reg) {
988 MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
989 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
992 freg: OP_LCONV_TO_R_UN (lreg) {
993 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->left->reg2);
996 lreg: OP_FCONV_TO_I8 (freg) {
997 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
1000 lreg: OP_FCONV_TO_U8 (freg) {
1001 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
1004 reg: OP_LCONV_TO_I4 (i8con) {
1005 MONO_EMIT_NEW_ICONST (s, state->reg1, state->left->tree->inst_ls_word);
1008 reg: OP_LCONV_TO_I4 (lreg),
1009 reg: OP_LCONV_TO_U4 (lreg) {
1010 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
1013 reg: OP_LCONV_TO_I4 (CEE_LDIND_I8 (base)),
1014 reg: OP_LCONV_TO_U4 (CEE_LDIND_I8 (base)) {
1015 MONO_EMIT_LOAD_MEMBASE_OP (s, tree, OP_LOADI4_MEMBASE, state->reg1,
1016 state->left->left->tree->inst_basereg,
1017 state->left->left->tree->inst_offset + MINI_LS_WORD_OFFSET);
1020 lreg: OP_LCONV_TO_U8 (lreg),
1021 lreg: OP_LCONV_TO_I8 (lreg) {
1022 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
1023 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
1026 reg: OP_LCONV_TO_U (lreg),
1027 reg: OP_LCONV_TO_I (lreg) {
1028 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
1031 reg: OP_LCONV_TO_I1 (lreg) {
1032 MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
1035 reg: OP_LCONV_TO_U1 (lreg) {
1036 MONO_EMIT_UNALU (s, tree, CEE_CONV_U1, state->reg1, state->left->reg1);
1039 reg: OP_LCONV_TO_I2 (lreg) {
1040 MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
1043 reg: OP_LCONV_TO_U2 (lreg) {
1044 MONO_EMIT_UNALU (s, tree, CEE_CONV_U2, state->reg1, state->left->reg1);
1047 reg: OP_LCONV_TO_OVF_I1_UN (lreg) {
1048 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1050 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT, state->left->reg1, 127, "OverflowException");
1051 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, -128, "OverflowException");
1052 MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
1055 reg: OP_LCONV_TO_OVF_I1 (lreg) {
1056 MonoInst *is_negative, *end_label;
1058 MONO_NEW_LABEL (s, is_negative);
1059 MONO_NEW_LABEL (s, end_label);
1061 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT, state->left->reg2, 0, "OverflowException");
1062 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg2, -1, "OverflowException");
1064 MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BLT, state->left->reg2, mips_zero, is_negative);
1067 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 127, "OverflowException");
1068 MONO_EMIT_NEW_BRANCH_LABEL (s, OP_BR, end_label);
1071 mono_bblock_add_inst (s->cbb, is_negative);
1072 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT_UN, state->left->reg1, -128, "OverflowException");
1073 mono_bblock_add_inst (s->cbb, end_label);
1075 MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
1078 reg: OP_LCONV_TO_OVF_U1_UN (lreg),
1079 reg: OP_LCONV_TO_OVF_U1 (lreg) {
1080 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1082 /* probe value to be within 0 to 255 */
1083 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 255, "OverflowException");
1084 MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, 0xff);
1087 reg: OP_LCONV_TO_OVF_I2 (lreg) {
1088 MonoInst *is_negative, *end_label;
1090 MONO_NEW_LABEL (s, is_negative);
1091 MONO_NEW_LABEL (s, end_label);
1093 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT, state->left->reg2, 0, "OverflowException");
1094 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg2, -1, "OverflowException");
1096 MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BLT, state->left->reg2, mips_zero, is_negative);
1099 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 32767, "OverflowException");
1100 MONO_EMIT_NEW_BRANCH_LABEL (s, OP_BR, end_label);
1103 mono_bblock_add_inst (s->cbb, is_negative);
1104 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT_UN, state->left->reg1, -32768, "OverflowException");
1105 mono_bblock_add_inst (s->cbb, end_label);
1107 MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
1110 reg: OP_LCONV_TO_OVF_I2_UN (lreg) {
1111 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1113 /* Probe value to be within -32768 and 32767 */
1114 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT, state->left->reg1, 32767, "OverflowException");
1115 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, -32768, "OverflowException");
1116 MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
1119 reg: OP_LCONV_TO_OVF_U2_UN (lreg),
1120 reg: OP_LCONV_TO_OVF_U2 (lreg) {
1121 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1123 /* Probe value to be within 0 and 65535 */
1124 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 0xffff, "OverflowException");
1125 MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, 0xffff);
1129 reg: OP_LCONV_TO_OVF_U4_UN (lreg) {
1130 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1131 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
1134 reg: OP_LCONV_TO_OVF_I_UN (lreg) {
1135 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1136 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
1139 reg: OP_LCONV_TO_OVF_U4 (lreg) {
1140 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1141 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
1144 reg: OP_LCONV_TO_OVF_I4_UN (lreg) {
1145 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1146 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, 0, "OverflowException");
1147 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
1150 reg: OP_LCONV_TO_OVF_I (lreg),
1151 reg: OP_LCONV_TO_OVF_I4 (lreg) {
1152 int tmp_reg = mono_regstate_next_int (s->rs);
1154 /* Overflows if reg2 != sign extension of reg1 */
1155 MONO_EMIT_BIALU_IMM (s, tree, OP_SHR_IMM, tmp_reg, state->left->reg1, 31);
1157 MONO_EMIT_NEW_COMPARE_EXC (s, NE_UN, state->left->reg2, tmp_reg, "OverflowException");
1158 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
1161 lreg: OP_LCONV_TO_OVF_I8_UN (lreg) {
1162 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg2, 0, "OverflowException");
1164 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
1165 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
1168 lreg: OP_LCONV_TO_OVF_U8 (lreg) {
1169 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg2, 0, "OverflowException");
1171 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
1172 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
1175 lreg: OP_LCONV_TO_OVF_I8 (lreg) {
1176 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
1177 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
1180 lreg: OP_LCONV_TO_OVF_U8_UN (lreg) {
1181 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
1182 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
1185 lreg: OP_LCALLVIRT (reg) {
1186 mini_emit_virtual_call (s, state, tree, OP_LCALL, OP_LCALL_MEMBASE);
1190 tree->dreg = state->reg1;
1191 mono_bblock_add_inst (s->cbb, tree);
1194 lreg: OP_LCALL_REG (reg) {
1195 tree->sreg1 = state->left->reg1;
1196 tree->dreg = state->reg1;
1197 mono_bblock_add_inst (s->cbb, tree);
1200 lreg: OP_LCALL_REG (OP_ICONST) {
1201 tree->opcode = OP_LCALL;
1202 ((MonoCallInst*)tree)->fptr = state->left->tree->inst_p0;
1203 tree->dreg = state->reg1;
1204 mono_bblock_add_inst (s->cbb, tree);