2006-06-04 Zoltan Varga <vargaz@gmail.com>
[mono.git] / mono / mini / inssel-long.brg
index 11c707077d804206d47c5d9992e238fdf5371849..d828f9952a5d83d234b6e3d55545fbce137ca780 100644 (file)
@@ -9,6 +9,10 @@
 # (C) 2002 Ximian, Inc.
 #
 
+reg: OP_I8CONST {
+       MONO_EMIT_NEW_I8CONST (s, state->reg1, tree->inst_l);
+}
+
 reg: CEE_LDIND_I8 (base) {
        MONO_EMIT_LOAD_MEMBASE_OP (s, tree, OP_LOADI8_MEMBASE, state->reg1, 
                                   state->left->tree->inst_basereg, state->left->tree->inst_offset);
@@ -19,29 +23,773 @@ stmt: CEE_STIND_I8 (base, reg) {
                                 state->left->tree->inst_offset, state->right->reg1);
 }
 
+stmt: CEE_STIND_REF (base, OP_I8CONST),
+stmt: CEE_STIND_I (base, OP_I8CONST),
+stmt: CEE_STIND_I8 (base, OP_I8CONST),
+stmt: CEE_STIND_REF (base, OP_ICONST),
+stmt: CEE_STIND_I (base, OP_ICONST),
 stmt: CEE_STIND_I8 (base, OP_ICONST) {
        MONO_EMIT_STORE_MEMBASE_IMM (s, tree, OP_STOREI8_MEMBASE_IMM, state->left->tree->inst_basereg,
-                                    state->left->tree->inst_offset, state->right->tree->inst_c0);
+                                    state->left->tree->inst_offset, state->right->tree->inst_l);
+}
+
+stmt: CEE_STIND_I8 (reg, reg) {
+       MONO_EMIT_STORE_MEMBASE (s, tree, OP_STOREI8_MEMBASE_REG, state->left->tree->inst_basereg,
+                                state->left->tree->inst_offset, state->right->reg1);
+}
+
+base: OP_LADD (base, OP_ICONST) "0" {
+       tree->inst_offset = state->left->tree->inst_offset + state->right->tree->inst_c0;
+       tree->inst_basereg = state->left->tree->inst_basereg;
+}
+
+base: OP_LADD (CEE_LDIND_REF (OP_REGVAR), OP_ICONST),
+base: OP_LADD (CEE_LDIND_I (OP_REGVAR), OP_ICONST) "0" {
+       tree->inst_offset = state->right->tree->inst_c0;
+       tree->inst_basereg = state->left->left->tree->dreg;
+}
+
+reg: OP_LADD (reg, reg) {
+       MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+reg: OP_LADD (reg, OP_ICONST) {
+       MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+reg: OP_LADD (reg, OP_ICONST) {
+       MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+reg: OP_LADD (CEE_LDIND_I (OP_REGVAR), OP_ICONST),
+reg: OP_LADD (CEE_LDIND_REF (OP_REGVAR), OP_ICONST) {
+       MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, state->reg1, state->left->left->tree->dreg, state->right->tree->inst_c0);
+}
+
+reg: OP_LSUB (reg, reg) {
+       MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+reg: OP_LNEG (reg) {
+       MONO_EMIT_NEW_UNALU (s, CEE_NEG, state->reg1, state->left->reg1);
+}
+
+reg: OP_LNOT (reg) {
+       MONO_EMIT_NEW_UNALU (s, CEE_NOT, state->reg1, state->left->reg1);
+}
+
+reg: OP_LAND (reg, reg) {
+       MONO_EMIT_NEW_BIALU (s, CEE_AND, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+reg: OP_LOR (reg, reg) {
+       MONO_EMIT_NEW_BIALU (s, CEE_OR, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+reg: OP_LXOR (reg, reg) {
+       MONO_EMIT_NEW_BIALU (s, CEE_XOR, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+
+reg: OP_LADD_OVF (reg, reg) {
+       MONO_EMIT_NEW_BIALU (s, OP_ADDCC, state->reg1, state->left->reg1, state->right->reg1);
+       MONO_EMIT_NEW_COND_EXC (s, OV, "OverflowException");
+}
+
+reg: OP_LADD_OVF_UN (reg, reg) {
+       MONO_EMIT_NEW_BIALU (s, OP_ADDCC, state->reg1, state->left->reg1, state->right->reg1);
+       MONO_EMIT_NEW_COND_EXC (s, C, "OverflowException");
+}
+
+reg: OP_LSUB_OVF (reg, reg) {
+       MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1);
+       MONO_EMIT_NEW_COND_EXC (s, OV, "OverflowException");
+}
+
+reg: OP_LSUB_OVF_UN (reg, reg) {
+       MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1);
+       MONO_EMIT_NEW_COND_EXC (s, C, "OverflowException");
+}
+
+reg: OP_LONG_SHRUN_32 (reg) {
+       MONO_EMIT_BIALU_IMM (s, tree, OP_LSHR_UN_IMM, state->reg1, state->left->reg1, 32);
+}
+
+#
+# shift operations
+#
+
+reg: OP_LSHL (reg, reg) {
+       MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+reg: OP_LSHL (reg, OP_ICONST) {
+       MONO_EMIT_BIALU_IMM (s, tree, OP_LSHL_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+reg: OP_LSHR (reg, reg) {
+       MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+reg: OP_LSHR (reg, OP_ICONST) {
+       MONO_EMIT_BIALU_IMM (s, tree, OP_LSHR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+reg: OP_LSHR_UN (reg, reg) {
+       MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+reg: OP_LSHR_UN (reg, OP_ICONST) {
+       MONO_EMIT_BIALU_IMM (s, tree, OP_LSHR_UN_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+#
+# Conversions
+#
+
+reg: CEE_CONV_I8 (reg) {
+       /* Sign extend the value in the lower word into the upper word */
+       tree->sreg1 = state->left->reg1;
+       tree->dreg = state->reg1;
+       mono_bblock_add_inst (s->cbb, tree);    
+}
+
+reg: CEE_CONV_U8 (reg) {
+       /* Clean out the upper word */
+       /* Sign extend the value in the lower word into the upper word */
+       tree->sreg1 = state->left->reg1;
+       tree->dreg = state->reg1;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+i8con: CEE_CONV_U8 (OP_ICONST) "0" {
+       /*
+        * This is needed since constant propagation eliminates some 
+     * stind.i4/ldind.i4 pairs, along with the conversions done by them.
+        */
+       int data = state->left->tree->inst_c0;
+       tree->opcode = OP_I8CONST;
+       tree->inst_ls_word = data;
+       tree->inst_ms_word = 0;
 }
 
 reg: OP_FCONV_TO_I8 (freg) {
-       g_assert_not_reached ();
+       MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
 }
 
 reg: OP_FCONV_TO_U8 (freg) {
-       g_assert_not_reached ();
+       MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCONV_TO_I4 (i8con) {
+     MONO_EMIT_NEW_ICONST (s, state->reg1, state->left->tree->inst_ls_word);
+}
+
+reg: OP_LCONV_TO_I4 (reg) {
+       /* Sign extend the value in the lower word into the upper word */
+       MONO_EMIT_BIALU_IMM (s, tree, OP_LSHR_IMM, state->reg1, state->left->reg1, 0);
+}
+
+reg: OP_LCONV_TO_U4 (reg) {
+       /* Clean out the upper word */
+       MONO_EMIT_BIALU_IMM (s, tree, OP_ISHR_UN_IMM, state->reg1, state->left->reg1, 0);
+}
+
+reg: OP_LCONV_TO_U8 (reg) {
+       MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCONV_TO_I8 (reg) {
+       MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCONV_TO_U (reg) {
+       MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCONV_TO_I (reg) {
+       MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCONV_TO_I1 (reg) {
+       MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCONV_TO_U1 (reg) {
+       MONO_EMIT_UNALU (s, tree, CEE_CONV_U1, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCONV_TO_I2 (reg) {
+       MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCONV_TO_U2 (reg) {
+       MONO_EMIT_UNALU (s, tree, CEE_CONV_U2, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCONV_TO_OVF_I1 (reg) {
+       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 127);
+       MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -128);
+       MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+       MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCONV_TO_OVF_I1_UN (reg) {
+       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 127);
+       MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
+       MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCONV_TO_OVF_U1 (reg) {
+       /* probe value to be within 0 to 255 */
+       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 255);
+       MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
+       MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, 0xff);
+}
+
+reg: OP_LCONV_TO_OVF_U1_UN (reg) {
+       /* probe value to be within 0 to 255 */
+       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 255);
+       MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
+       MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, 0xff);
+}
+
+reg: OP_LCONV_TO_OVF_I2 (reg) {
+       /* Probe value to be within -32768 and 32767 */
+       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 32767);
+       MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -32768);
+       MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+       MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCONV_TO_OVF_I2_UN (reg) {
+       /* Probe value to be within 0 and 32767 */
+       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 32767);
+       MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
+       MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCONV_TO_OVF_U2 (reg) {
+       /* Probe value to be within 0 and 65535 */
+       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0xffff);
+       MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
+       MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, 0xffff);
+}
+
+reg: OP_LCONV_TO_OVF_U2_UN (reg) {
+       /* Probe value to be within 0 and 65535 */
+       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0xffff);
+       MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
+       MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, 0xffff);
+}
+
+reg: OP_LCONV_TO_OVF_I4 (reg) {
+       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0x7fffffff);
+       MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
+       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -2147483648);
+       MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+       MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCONV_TO_OVF_I4_UN (reg) {
+       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0x7fffffff);
+       MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
+       MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCONV_TO_OVF_U4 (reg) {
+       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0xffffffffUL);
+       MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
+       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg1, 0);
+       MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+       MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCONV_TO_OVF_U4_UN (reg) {
+       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0xffffffff);
+       MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
+       MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCONV_TO_OVF_I_UN (reg),
+reg: OP_LCONV_TO_OVF_I8_UN (reg) {
+       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg1, 0);
+       MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+
+       MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCONV_TO_OVF_U8 (reg) {
+       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg1, 0);
+       MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+
+       MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCONV_TO_OVF_I8 (reg) {
+       MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCONV_TO_OVF_U8_UN (reg) {
+       MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCONV_TO_OVF_I (reg) {
+       MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
+}
+
+freg: OP_LCONV_TO_R_UN (lreg) {
+       MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
+}
+
+reg: CEE_CONV_OVF_I8 (reg) {
+       /* Sign extend the value in the lower word into the upper word */
+       MONO_EMIT_UNALU (s, tree, CEE_CONV_I8, state->reg1, state->left->reg1);
+}
+
+reg: CEE_CONV_OVF_I8_UN (reg),
+reg: CEE_CONV_OVF_U8_UN (reg) {
+       /* an unsigned 32 bit num always fits in an (un)signed 64 bit one */
+       /* Clean out the upper word */
+       MONO_EMIT_UNALU (s, tree, CEE_CONV_U8, state->reg1, state->left->reg1);
+}
+
+reg: CEE_CONV_OVF_U8 (reg) {
+       MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 0);
+       MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+       MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCALLVIRT (reg) {
+       mini_emit_virtual_call (s, state, tree, OP_LCALL, OP_LCALL_MEMBASE);
+}
+
+reg: OP_LCALL {
+       tree->dreg = state->reg1;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+reg: OP_LCALL_REG (reg) {
+       tree->sreg1 = state->left->reg1;
+       tree->dreg = state->reg1;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+reg: OP_LCALL_REG (OP_ICONST) {
+       tree->opcode = OP_LCALL;
+       ((MonoCallInst*)tree)->fptr = state->left->tree->inst_p0;
+       tree->dreg = state->reg1;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+
+
+stmt: CEE_STIND_I4 (OP_REGVAR, OP_ICONST) {
+       tree->inst_c0 = state->right->tree->inst_c0;
+       tree->opcode = OP_ICONST;
+       tree->dreg = state->left->tree->dreg;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+stmt: CEE_STIND_I4 (OP_REGVAR, reg) {
+       MONO_EMIT_UNALU (s, tree, OP_MOVE, state->left->tree->dreg, state->right->reg1);
+}
+
+stmt: CEE_STIND_I4 (OP_REGVAR, CEE_LDIND_I4 (OP_REGVAR)) {
+       MONO_EMIT_UNALU (s, tree, OP_MOVE, state->left->tree->dreg, state->right->left->tree->dreg);
+}
+
+stmt: CEE_STIND_I4 (OP_REGVAR, CEE_LDIND_I4 (base)) {
+       MONO_EMIT_LOAD_MEMBASE_OP (s, tree, OP_LOADI4_MEMBASE, state->left->tree->dreg, 
+                                  state->right->left->tree->inst_basereg, 
+                                  state->right->left->tree->inst_offset);
+}
+
+cflags: OP_LCOMPARE (reg, reg) {
+       tree->sreg1 = state->left->reg1;
+       tree->sreg2 = state->right->reg1;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+cflags: OP_LCOMPARE (CEE_LDIND_I8 (OP_REGVAR), reg) {
+       tree->sreg1 = state->left->left->tree->dreg;
+       tree->sreg2 = state->right->reg1;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+cflags: OP_LCOMPARE (CEE_LDIND_I (OP_REGVAR), CEE_LDIND_I (OP_REGVAR)) {
+       tree->sreg1 = state->left->left->tree->dreg;
+       tree->sreg2 = state->right->left->tree->dreg;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+cflags: OP_LCOMPARE (CEE_LDIND_I8 (OP_REGVAR), OP_ICONST) {
+       tree->opcode = OP_COMPARE_IMM;
+       tree->sreg1 = state->left->left->tree->dreg;
+       tree->inst_imm = state->right->tree->inst_c0;
+       mono_bblock_add_inst (s->cbb, tree);
+} cost {
+       MBCOND (mono_arch_is_inst_imm (state->right->tree->inst_c0));
+
+       return 0;
+}      
+
+cflags: OP_LCOMPARE (reg, OP_ICONST) {
+       tree->opcode = OP_COMPARE_IMM;
+       tree->sreg1 = state->left->reg1;
+       tree->inst_imm = state->right->tree->inst_c0;
+       mono_bblock_add_inst (s->cbb, tree);
+} cost {
+       MBCOND (mono_arch_is_inst_imm (state->right->tree->inst_c0));
+
+       return 0;
+}      
+
+cflags: OP_LCOMPARE (reg, OP_I8CONST) {
+       tree->opcode = OP_COMPARE_IMM;
+       tree->sreg1 = state->left->reg1;
+       tree->inst_imm = state->right->tree->inst_l;
+       mono_bblock_add_inst (s->cbb, tree);
+} cost {
+       MBCOND (mono_arch_is_inst_imm (state->right->tree->inst_l));
+
+       return 0;
+}      
+
+stmt: CEE_BNE_UN (cflags) {
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+stmt: CEE_BEQ (cflags) {
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+stmt: CEE_BLT (cflags) {
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+stmt: CEE_BLT_UN (cflags) {
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+stmt: CEE_BGT (cflags) {
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+stmt: CEE_BGT_UN (cflags) {
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+stmt: CEE_BGE  (cflags) {
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+stmt: CEE_BGE_UN (cflags) {
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+stmt: CEE_BLE  (cflags) {
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+stmt: CEE_BLE_UN (cflags) {
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+#
+# 32 bit rules
+#
+
+#
+# basic alu operations
+#
+
+reg: CEE_AND (reg, reg) {
+       MONO_EMIT_BIALU (s, tree, OP_IAND, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+reg: CEE_AND (reg, OP_ICONST) {
+       MONO_EMIT_BIALU_IMM (s, tree, OP_IAND_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+reg: CEE_OR (reg, reg) {
+       MONO_EMIT_BIALU (s, tree, OP_IOR, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+reg: CEE_OR (reg, OP_ICONST) {
+       MONO_EMIT_BIALU_IMM (s, tree, OP_IOR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+reg: CEE_XOR (reg, reg) {
+       MONO_EMIT_BIALU (s, tree, OP_IXOR, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+reg: CEE_XOR (reg, OP_ICONST) {
+       MONO_EMIT_BIALU_IMM (s, tree, OP_IXOR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+reg: CEE_NEG (reg) {
+       MONO_EMIT_UNALU (s, tree, OP_INEG, state->reg1, state->left->reg1);
+}
+
+reg: CEE_NOT (reg) {
+       MONO_EMIT_UNALU (s, tree, OP_INOT, state->reg1, state->left->reg1);
+}
+
+reg: CEE_ADD (reg, reg) {
+       MONO_EMIT_BIALU (s, tree, OP_IADD, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+reg: CEE_ADD (reg, OP_ICONST) {
+       MONO_EMIT_BIALU_IMM (s, tree, OP_IADD_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+reg: CEE_ADD_OVF (reg, reg) {
+       MONO_EMIT_NEW_BIALU (s, OP_IADDCC, state->reg1, state->left->reg1, state->right->reg1);
+       MONO_EMIT_NEW_COND_EXC (s, IOV, "OverflowException");
+}
+
+reg: CEE_ADD_OVF_UN (reg, reg) {
+       MONO_EMIT_NEW_BIALU (s, OP_IADDCC, state->reg1, state->left->reg1, state->right->reg1);
+       MONO_EMIT_NEW_COND_EXC (s, IC, "OverflowException");
+}
+
+reg: CEE_SUB (reg, reg) {
+       MONO_EMIT_BIALU (s, tree, OP_ISUB, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+reg: CEE_SUB (reg, CEE_LDIND_I4 (OP_REGVAR)) {
+       MONO_EMIT_BIALU (s, tree, OP_ISUB, state->reg1, state->left->reg1, state->right->left->tree->dreg);
+}
+
+reg: CEE_SUB (reg, OP_ICONST) {
+       MONO_EMIT_BIALU_IMM (s, tree, OP_ISUB_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+reg: CEE_SUB_OVF (reg, reg) {
+       MONO_EMIT_NEW_BIALU (s, OP_ISUBCC, state->reg1, state->left->reg1, state->right->reg1);
+       MONO_EMIT_NEW_COND_EXC (s, IOV, "OverflowException");
+}
+
+reg: CEE_SUB_OVF_UN (reg, reg) {
+       MONO_EMIT_NEW_BIALU (s, OP_ISUBCC, state->reg1, state->left->reg1, state->right->reg1);
+       MONO_EMIT_NEW_COND_EXC (s, IC, "OverflowException");
+}
+
+#
+# shift operations
+#
+
+reg: CEE_SHL (reg, reg) {
+       MONO_EMIT_BIALU (s, tree, OP_ISHL, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+reg: CEE_SHL (reg, OP_ICONST) {
+       MONO_EMIT_BIALU_IMM (s, tree, OP_ISHL_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+reg: CEE_SHR (reg, reg) {
+       MONO_EMIT_BIALU (s, tree, OP_ISHR, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+reg: CEE_SHR (reg, OP_ICONST) {
+       MONO_EMIT_BIALU_IMM (s, tree, OP_ISHR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+reg: CEE_SHR_UN (reg, reg) {
+       MONO_EMIT_BIALU (s, tree, OP_ISHR_UN, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+reg: CEE_SHR_UN (reg, OP_ICONST) {
+       MONO_EMIT_BIALU_IMM (s, tree, OP_ISHR_UN_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+#
+# mult/div operations
+#
+
+reg: CEE_MUL (reg, reg) {
+       MONO_EMIT_BIALU (s, tree, OP_IMUL, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+reg: CEE_MUL (reg, OP_ICONST) {
+       MONO_EMIT_BIALU_IMM (s, tree, OP_IMUL_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+reg: CEE_MUL_OVF (reg, reg) {
+       MONO_EMIT_BIALU (s, tree, OP_IMUL_OVF, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+reg: CEE_MUL_OVF_UN (reg, reg) {
+       MONO_EMIT_BIALU (s, tree, OP_IMUL_OVF_UN, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+reg: CEE_DIV (reg, reg) {
+       MONO_EMIT_BIALU (s, tree, OP_IDIV, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+#reg: CEE_DIV (reg, OP_ICONST) {
+#      MONO_EMIT_BIALU_IMM (s, tree, OP_IDIV_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+#}
+
+reg: CEE_DIV_UN (reg, reg) {
+       MONO_EMIT_BIALU (s, tree, OP_IDIV_UN, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+#reg: CEE_DIV_UN (reg, OP_ICONST) {
+#      MONO_EMIT_BIALU_IMM (s, tree, OP_IDIV_UN_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+#}
+
+reg: CEE_REM (reg, reg) {
+       MONO_EMIT_BIALU (s, tree, OP_IREM, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+#reg: CEE_REM (reg, OP_ICONST) {
+#      MONO_EMIT_BIALU_IMM (s, tree, OP_IREM_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+#}
+
+reg: CEE_REM_UN (reg, reg) {
+       MONO_EMIT_BIALU (s, tree, OP_IREM_UN, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+#reg: CEE_REM_UN (reg, OP_ICONST) {
+#      MONO_EMIT_BIALU_IMM (s, tree, OP_IREM_UN_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+#}
+
+reg: OP_IMUL_IMM (reg) {
+       tree->sreg1 = state->left->reg1;
+       tree->dreg = state->reg1;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+reg: OP_LMUL_IMM (reg) {
+       tree->sreg1 = state->left->reg1;
+       tree->dreg = state->reg1;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+c32flags: OP_COMPARE (reg, reg) {
+       tree->opcode = OP_ICOMPARE;
+       tree->sreg1 = state->left->reg1;
+       tree->sreg2 = state->right->reg1;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+c32flags: OP_COMPARE (CEE_LDIND_I (OP_REGVAR), CEE_LDIND_I (OP_REGVAR)) {
+       tree->opcode = OP_ICOMPARE;
+       tree->sreg1 = state->left->left->tree->dreg;
+       tree->sreg2 = state->right->left->tree->dreg;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+c32flags: OP_COMPARE (CEE_LDIND_I (OP_REGVAR), OP_ICONST) {
+       tree->opcode = OP_ICOMPARE_IMM;
+       tree->sreg1 = state->left->left->tree->dreg;
+       tree->inst_imm = state->right->tree->inst_c0;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+c32flags: OP_COMPARE (CEE_LDIND_I4 (OP_REGVAR), reg) {
+       tree->opcode = OP_ICOMPARE;
+       tree->sreg1 = state->left->left->tree->dreg;
+       tree->sreg2 = state->right->reg1;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+c32flags: OP_COMPARE (CEE_LDIND_I4 (OP_REGVAR), OP_ICONST) {
+       tree->opcode = OP_ICOMPARE_IMM;
+       tree->sreg1 = state->left->left->tree->dreg;
+       tree->inst_imm = state->right->tree->inst_c0;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+c32flags: OP_COMPARE (reg, OP_ICONST) {
+       tree->opcode = OP_ICOMPARE_IMM;
+       tree->sreg1 = state->left->reg1;
+       tree->inst_imm = state->right->tree->inst_c0;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+stmt: CEE_BNE_UN (c32flags) {
+       tree->opcode = OP_IBNE_UN;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+stmt: CEE_BEQ (c32flags) {
+       tree->opcode = OP_IBEQ;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+stmt: CEE_BLT (c32flags) {
+       tree->opcode = OP_IBLT;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+stmt: CEE_BLT_UN (c32flags) {
+       tree->opcode = OP_IBLT_UN;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+stmt: CEE_BGT (c32flags) {
+       tree->opcode = OP_IBGT;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+stmt: CEE_BGT_UN (c32flags) {
+       tree->opcode = OP_IBGT_UN;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+stmt: CEE_BGE  (c32flags) {
+       tree->opcode = OP_IBGE;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+stmt: CEE_BGE_UN (c32flags) {
+       tree->opcode = OP_IBGE_UN;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+stmt: CEE_BLE  (c32flags) {
+       tree->opcode = OP_IBLE;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+stmt: CEE_BLE_UN (c32flags) {
+       tree->opcode = OP_IBLE_UN;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+reg: OP_CEQ (c32flags) {       
+       tree->opcode = OP_ICEQ;
+       tree->dreg = state->reg1;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
+reg: OP_CLT (c32flags) {       
+       tree->opcode = OP_ICLT;
+       tree->dreg = state->reg1;
+       mono_bblock_add_inst (s->cbb, tree);
 }
 
-freg: CEE_CONV_R_UN (reg) {
-       g_assert_not_reached ();
+reg: OP_CLT_UN (c32flags) {    
+       tree->opcode = OP_ICLT_UN;
+       tree->dreg = state->reg1;
+       mono_bblock_add_inst (s->cbb, tree);
 }
 
-freg: CEE_CONV_R4 (reg) {
-       g_assert_not_reached ();
+reg: OP_CGT (c32flags) {       
+       tree->opcode = OP_ICGT;
+       tree->dreg = state->reg1;
+       mono_bblock_add_inst (s->cbb, tree);
 }
 
-freg: CEE_CONV_R8 (reg) {
-       g_assert_not_reached ();
+reg: OP_CGT_UN (c32flags) {    
+       tree->opcode = OP_ICGT_UN;
+       tree->dreg = state->reg1;
+       mono_bblock_add_inst (s->cbb, tree);
 }
 
 %%