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 (lreg2 != rreg2) -> false */
609 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_false_bb);
611 /* (lreg2 == rreg2), if (lreg1 <= rreg1) -> true [or if (rreg1 < lreg1) -> false] */
613 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
614 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
615 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
618 stmt: CEE_BLE (OP_LCOMPARE (lreg, i8con)) {
619 int lreg1 = state->left->left->reg1;
620 int lreg2 = state->left->left->reg2;
621 int rreg1 = mono_regstate_next_int (s->rs);
622 int rreg2 = mono_regstate_next_int (s->rs);
624 MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
626 /* if (lreg2 < rreg2) -> true */
627 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
628 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
630 /* if (lreg2 != rreg2) -> false */
631 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_false_bb);
633 /* (rreg2 == lreg2), if (lreg1 <= rreg1) -> true [or if (rreg1 < lreg1) -> false] */
635 MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
636 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
637 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
638 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
641 stmt: CEE_BLE_UN (OP_LCOMPARE (lreg, lreg)) {
642 int lreg1 = state->left->left->reg1;
643 int lreg2 = state->left->left->reg2;
644 int rreg1 = state->left->right->reg1;
645 int rreg2 = state->left->right->reg2;
647 /* if (lreg2 < rreg2) -> true */
648 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
649 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
651 /* if (lreg2 != rreg2) -> false */
652 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_false_bb);
654 /* (lreg2 == rreg2), if (lreg1 <= rreg1) -> true [or if (rreg1 < lreg1) -> false] */
656 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
657 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
658 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
661 stmt: CEE_BLE_UN (OP_LCOMPARE (lreg, i8con)) {
662 int lreg1 = state->left->left->reg1;
663 int lreg2 = state->left->left->reg2;
664 int rreg1 = mono_regstate_next_int (s->rs);
665 int rreg2 = mono_regstate_next_int (s->rs);
667 MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
669 /* if (lreg2 < rreg2) -> true */
670 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
671 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
673 /* if (lreg2 != rreg2) -> false */
674 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_false_bb);
676 /* (rreg2 == lreg2), if (rreg1 <= lreg1) -> true [or if (rreg1 < lreg1) -> false] */
678 MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
679 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
680 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
681 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
684 stmt: CEE_BGE (OP_LCOMPARE (lreg, lreg)) {
685 int lreg1 = state->left->left->reg1;
686 int lreg2 = state->left->left->reg2;
687 int rreg1 = state->left->right->reg1;
688 int rreg2 = state->left->right->reg2;
690 /* if (lreg2 < rreg2) -> false */
691 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
692 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
694 /* if (lreg2 != rreg2) -> true */
695 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_true_bb);
697 /* (lreg2 == rreg2), so if (lreg1 < rreg1) -> false */
698 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg1, rreg1);
699 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
700 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
703 stmt: CEE_BGE (OP_LCOMPARE (lreg, i8con)) {
704 int lreg1 = state->left->left->reg1;
705 int lreg2 = state->left->left->reg2;
706 int rreg1 = mono_regstate_next_int (s->rs);
707 int rreg2 = mono_regstate_next_int (s->rs);
709 MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
711 /* if (lreg2 < rreg2) -> false */
712 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
713 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
715 /* if (lreg2 != rreg2) -> true */
716 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_true_bb);
718 MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
720 /* (lreg2 == rreg2), so if (lreg1 < rreg1) -> false */
721 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg1, rreg1);
722 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
723 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
726 stmt: CEE_BGE_UN (OP_LCOMPARE (lreg, lreg)) {
727 int lreg1 = state->left->left->reg1;
728 int lreg2 = state->left->left->reg2;
729 int rreg1 = state->left->right->reg1;
730 int rreg2 = state->left->right->reg2;
732 /* if (lreg2 < rreg2) -> false */
733 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
734 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
736 /* if (lreg2 != rreg2) -> true */
737 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_true_bb);
739 /* (rreg2 == lreg2), so if (lreg1 < rreg1) -> false */
740 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg1, rreg1);
741 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
742 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
745 stmt: CEE_BGE_UN (OP_LCOMPARE (lreg, i8con)) {
746 int lreg1 = state->left->left->reg1;
747 int lreg2 = state->left->left->reg2;
748 int rreg1 = mono_regstate_next_int (s->rs);
749 int rreg2 = mono_regstate_next_int (s->rs);
751 MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
753 /* if (lreg2 < rreg2) -> false */
754 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
755 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
757 /* if (lreg2 != rreg2) -> true */
758 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_true_bb);
760 MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
762 /* (lreg2 == rreg2), so if (lreg1 < rreg1) -> false */
763 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg1, rreg1);
764 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
765 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_true_bb);
768 stmt: CEE_BLT (OP_LCOMPARE (lreg, lreg)) {
769 int lreg1 = state->left->left->reg1;
770 int lreg2 = state->left->left->reg2;
771 int rreg1 = state->left->right->reg1;
772 int rreg2 = state->left->right->reg2;
774 /* if (lreg2 < rreg2) -> true */
775 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
776 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
778 /* if (lreg2 != rreg2) -> false */
779 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_false_bb);
781 /* (lreg2 == rreg2), if (lreg1 < rreg1) -> true */
782 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg1, rreg1);
783 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
784 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
787 stmt: CEE_BLT (OP_LCOMPARE (lreg, i8con)) {
788 int lreg1 = state->left->left->reg1;
789 int lreg2 = state->left->left->reg2;
790 int rreg1 = mono_regstate_next_int (s->rs);
791 int rreg2 = mono_regstate_next_int (s->rs);
793 MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
795 /* if (lreg2 < rreg2) -> true */
796 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
797 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
799 /* if (lreg2 != rreg2) -> false */
800 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_false_bb);
802 MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
804 /* (lreg2 == rreg2), if (lreg1 < rreg1) -> true */
805 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg1, rreg1);
806 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
807 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
810 stmt: CEE_BLT_UN (OP_LCOMPARE (lreg, lreg)) {
811 int lreg1 = state->left->left->reg1;
812 int lreg2 = state->left->left->reg2;
813 int rreg1 = state->left->right->reg1;
814 int rreg2 = state->left->right->reg2;
816 /* if (lreg2 < rreg2) -> true */
817 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
818 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
820 /* if (lreg2 != rreg2) -> false */
821 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_false_bb);
823 /* (lreg2 == rreg2), if (lreg1 < rreg1) -> true */
824 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg1, rreg1);
825 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
826 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
829 stmt: CEE_BLT_UN (OP_LCOMPARE (lreg, i8con)) {
830 int lreg1 = state->left->left->reg1;
831 int lreg2 = state->left->left->reg2;
832 int rreg1 = mono_regstate_next_int (s->rs);
833 int rreg2 = mono_regstate_next_int (s->rs);
835 MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
837 /* if (lreg2 < rreg2) -> true */
838 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
839 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
841 /* if (lreg2 != rreg2) -> false */
842 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_false_bb);
844 MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
846 /* (lreg2 == rreg2), if (lreg1 < rreg1) -> true */
847 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg1, rreg1);
848 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
849 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
852 stmt: CEE_BGT (OP_LCOMPARE (lreg, lreg)) {
853 int lreg1 = state->left->left->reg1;
854 int lreg2 = state->left->left->reg2;
855 int rreg1 = state->left->right->reg1;
856 int rreg2 = state->left->right->reg2;
858 /* if (lreg2 < rreg2) -> false */
859 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
860 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
862 /* if (lreg2 != rreg2) -> true */
863 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_true_bb);
865 /* (rreg2 == lreg2), so if (lreg1 > rreg1) -> true */
866 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
867 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
868 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
871 stmt: CEE_BGT (OP_LCOMPARE (lreg, i8con)) {
872 int lreg1 = state->left->left->reg1;
873 int lreg2 = state->left->left->reg2;
874 int rreg1 = mono_regstate_next_int (s->rs);
875 int rreg2 = mono_regstate_next_int (s->rs);
877 MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
879 /* if (lreg2 < rreg2) -> false */
880 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLT, mips_at, lreg2, rreg2);
881 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
883 /* if (lreg2 != rreg2) -> true */
884 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_true_bb);
886 MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
888 /* (rreg2 == lreg2), so if (lreg1 > rreg1) -> true */
889 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
890 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
891 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
894 stmt: CEE_BGT_UN (OP_LCOMPARE (lreg, lreg)) {
895 int lreg1 = state->left->left->reg1;
896 int lreg2 = state->left->left->reg2;
897 int rreg1 = state->left->right->reg1;
898 int rreg2 = state->left->right->reg2;
900 /* if (lreg2 < rreg2) -> false */
901 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
902 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
904 /* if (lreg2 != rreg2) -> true */
905 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_true_bb);
907 /* (rreg2 == lreg2), so if (lreg1 > rreg1) -> true */
908 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
909 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
910 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
913 stmt: CEE_BGT_UN (OP_LCOMPARE (lreg, i8con)) {
914 int lreg1 = state->left->left->reg1;
915 int lreg2 = state->left->left->reg2;
916 int rreg1 = mono_regstate_next_int (s->rs);
917 int rreg2 = mono_regstate_next_int (s->rs);
919 MONO_EMIT_NEW_ICONST (s, rreg2, state->left->right->tree->inst_ms_word);
921 /* if (lreg2 < rreg2) -> false */
922 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, lreg2, rreg2);
923 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_false_bb);
925 /* if (lreg2 != rreg2) -> true */
926 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, lreg2, rreg2, tree->inst_true_bb);
928 MONO_EMIT_NEW_ICONST (s, rreg1, state->left->right->tree->inst_ls_word);
930 /* (rreg2 == lreg2), so if (lreg1 > rreg1) -> true */
931 MONO_EMIT_NEW_BIALU (s, OP_MIPS_SLTU, mips_at, rreg1, lreg1);
932 MONO_EMIT_NEW_COMPARE_BRANCH_BLOCK (s, OP_MIPS_BNE, mips_at, mips_zero, tree->inst_true_bb);
933 MONO_EMIT_NEW_BRANCH_BLOCK (s, OP_BR, tree->inst_false_bb);
936 lreg: CEE_CONV_I8 (OP_ICONST) {
937 int data = state->left->tree->inst_c0;
939 MONO_EMIT_NEW_ICONST (s, state->reg1, data);
942 MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
944 MONO_EMIT_NEW_ICONST (s, state->reg2, -1);
947 lreg: CEE_CONV_I8 (reg) {
948 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
949 MONO_EMIT_NEW_BIALU_IMM (s, OP_SHR_IMM, state->reg2, state->left->reg1, 31);
952 lreg: CEE_CONV_U8 (reg) {
953 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
954 MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
957 lreg: CEE_CONV_OVF_U8 (reg) {
958 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, 0, "OverflowException");
959 MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
960 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
963 lreg: CEE_CONV_OVF_I8 (reg) {
964 /* a signed 32 bit num always fits in a signed 64 bit one */
965 MONO_EMIT_NEW_BIALU_IMM (s, OP_SHR_IMM, state->reg2, state->left->reg1, 31);
966 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
969 lreg: CEE_CONV_OVF_I8_UN (reg) {
970 /* an unsigned 32 bit num always fits in a signed 64 bit one */
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_U8_UN (reg) {
976 MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
977 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
980 freg: OP_LCONV_TO_R_UN (lreg) {
981 MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->left->reg2);
984 lreg: OP_FCONV_TO_I8 (freg) {
985 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
988 lreg: OP_FCONV_TO_U8 (freg) {
989 MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
992 reg: OP_LCONV_TO_I4 (i8con) {
993 MONO_EMIT_NEW_ICONST (s, state->reg1, state->left->tree->inst_ls_word);
996 reg: OP_LCONV_TO_I4 (lreg),
997 reg: OP_LCONV_TO_U4 (lreg) {
998 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
1001 reg: OP_LCONV_TO_I4 (CEE_LDIND_I8 (base)),
1002 reg: OP_LCONV_TO_U4 (CEE_LDIND_I8 (base)) {
1003 MONO_EMIT_LOAD_MEMBASE_OP (s, tree, OP_LOADI4_MEMBASE, state->reg1,
1004 state->left->left->tree->inst_basereg,
1005 state->left->left->tree->inst_offset + MINI_LS_WORD_OFFSET);
1008 lreg: OP_LCONV_TO_U8 (lreg),
1009 lreg: OP_LCONV_TO_I8 (lreg) {
1010 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
1011 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
1014 reg: OP_LCONV_TO_U (lreg),
1015 reg: OP_LCONV_TO_I (lreg) {
1016 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
1019 reg: OP_LCONV_TO_I1 (lreg) {
1020 MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
1023 reg: OP_LCONV_TO_U1 (lreg) {
1024 MONO_EMIT_UNALU (s, tree, CEE_CONV_U1, state->reg1, state->left->reg1);
1027 reg: OP_LCONV_TO_I2 (lreg) {
1028 MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
1031 reg: OP_LCONV_TO_U2 (lreg) {
1032 MONO_EMIT_UNALU (s, tree, CEE_CONV_U2, state->reg1, state->left->reg1);
1035 reg: OP_LCONV_TO_OVF_I1_UN (lreg) {
1036 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1038 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT, state->left->reg1, 127, "OverflowException");
1039 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, -128, "OverflowException");
1040 MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
1043 reg: OP_LCONV_TO_OVF_I1 (lreg) {
1044 MonoInst *is_negative, *end_label;
1046 MONO_NEW_LABEL (s, is_negative);
1047 MONO_NEW_LABEL (s, end_label);
1049 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT, state->left->reg2, 0, "OverflowException");
1050 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg2, -1, "OverflowException");
1052 MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BLT, state->left->reg2, mips_zero, is_negative);
1055 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 127, "OverflowException");
1056 MONO_EMIT_NEW_BRANCH_LABEL (s, OP_BR, end_label);
1059 mono_bblock_add_inst (s->cbb, is_negative);
1060 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT_UN, state->left->reg1, -128, "OverflowException");
1061 mono_bblock_add_inst (s->cbb, end_label);
1063 MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
1066 reg: OP_LCONV_TO_OVF_U1_UN (lreg),
1067 reg: OP_LCONV_TO_OVF_U1 (lreg) {
1068 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1070 /* probe value to be within 0 to 255 */
1071 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 255, "OverflowException");
1072 MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, 0xff);
1075 reg: OP_LCONV_TO_OVF_I2 (lreg) {
1076 MonoInst *is_negative, *end_label;
1078 MONO_NEW_LABEL (s, is_negative);
1079 MONO_NEW_LABEL (s, end_label);
1081 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT, state->left->reg2, 0, "OverflowException");
1082 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg2, -1, "OverflowException");
1084 MONO_EMIT_NEW_COMPARE_BRANCH_LABEL (s, CEE_BLT, state->left->reg2, mips_zero, is_negative);
1087 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 32767, "OverflowException");
1088 MONO_EMIT_NEW_BRANCH_LABEL (s, OP_BR, end_label);
1091 mono_bblock_add_inst (s->cbb, is_negative);
1092 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT_UN, state->left->reg1, -32768, "OverflowException");
1093 mono_bblock_add_inst (s->cbb, end_label);
1095 MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
1098 reg: OP_LCONV_TO_OVF_I2_UN (lreg) {
1099 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1101 /* Probe value to be within -32768 and 32767 */
1102 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT, state->left->reg1, 32767, "OverflowException");
1103 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, -32768, "OverflowException");
1104 MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
1107 reg: OP_LCONV_TO_OVF_U2_UN (lreg),
1108 reg: OP_LCONV_TO_OVF_U2 (lreg) {
1109 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1111 /* Probe value to be within 0 and 65535 */
1112 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, GT_UN, state->left->reg1, 0xffff, "OverflowException");
1113 MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, 0xffff);
1117 reg: OP_LCONV_TO_OVF_U4_UN (lreg) {
1118 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1119 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
1122 reg: OP_LCONV_TO_OVF_I_UN (lreg) {
1123 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1124 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
1127 reg: OP_LCONV_TO_OVF_U4 (lreg) {
1128 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1129 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
1132 reg: OP_LCONV_TO_OVF_I4_UN (lreg) {
1133 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, NE_UN, state->left->reg2, 0, "OverflowException");
1134 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg1, 0, "OverflowException");
1135 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
1138 reg: OP_LCONV_TO_OVF_I (lreg),
1139 reg: OP_LCONV_TO_OVF_I4 (lreg) {
1140 int tmp_reg = mono_regstate_next_int (s->rs);
1142 /* Overflows if reg2 != sign extension of reg1 */
1143 MONO_EMIT_BIALU_IMM (s, tree, OP_SHR_IMM, tmp_reg, state->left->reg1, 31);
1145 MONO_EMIT_NEW_COMPARE_EXC (s, NE_UN, state->left->reg2, tmp_reg, "OverflowException");
1146 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
1149 lreg: OP_LCONV_TO_OVF_I8_UN (lreg) {
1150 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg2, 0, "OverflowException");
1152 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
1153 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
1156 lreg: OP_LCONV_TO_OVF_U8 (lreg) {
1157 MONO_EMIT_NEW_COMPARE_IMM_EXC (s, LT, state->left->reg2, 0, "OverflowException");
1159 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
1160 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
1163 lreg: OP_LCONV_TO_OVF_I8 (lreg) {
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_UN (lreg) {
1169 MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
1170 MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
1173 lreg: OP_LCALLVIRT (reg) {
1174 mini_emit_virtual_call (s, state, tree, OP_LCALL, OP_LCALL_MEMBASE);
1178 tree->dreg = state->reg1;
1179 mono_bblock_add_inst (s->cbb, tree);
1182 lreg: OP_LCALL_RGCTX (reg) {
1183 emit_rgctx_argument (s, tree, state->left->reg1, OP_LCALL);
1185 tree->dreg = state->reg1;
1186 mono_bblock_add_inst (s->cbb, tree);
1189 lreg: OP_LCALL_REG (reg) {
1190 tree->sreg1 = state->left->reg1;
1191 tree->dreg = state->reg1;
1192 mono_bblock_add_inst (s->cbb, tree);
1195 lreg: OP_LCALL_REG_RGCTX (reg, reg) {
1196 emit_rgctx_argument (s, tree, state->right->reg1, OP_LCALL_REG);
1198 tree->sreg1 = state->left->reg1;
1199 tree->dreg = state->reg1;
1200 mono_bblock_add_inst (s->cbb, tree);
1203 lreg: OP_LCALL_REG (OP_ICONST) {
1204 tree->opcode = OP_LCALL;
1205 ((MonoCallInst*)tree)->fptr = state->left->tree->inst_p0;
1206 tree->dreg = state->reg1;
1207 mono_bblock_add_inst (s->cbb, tree);