%%
#
-# inssel-long32.brg: burg file for 64bit instructions on 32bit architectures
+# inssel-long32.brg: burg file for integer instructions on 32bit architectures
#
# Author:
# Dietmar Maurer (dietmar@ximian.com)
# (C) 2002 Ximian, Inc.
#
+#
+# 32 bit rules
+#
+
+#
+# basic alu operations
+#
+
+reg: CEE_AND (reg, reg),
+reg: CEE_OR (reg, reg),
+reg: CEE_XOR (reg, reg),
+reg: CEE_ADD (reg, reg),
+reg: CEE_SUB (reg, reg),
+reg: CEE_MUL (reg, reg),
+reg: CEE_MUL_OVF (reg, reg),
+reg: CEE_MUL_OVF_UN (reg, reg),
+reg: CEE_DIV (reg, reg),
+reg: CEE_DIV_UN (reg, reg),
+reg: CEE_REM (reg, reg),
+reg: CEE_REM_UN (reg, reg),
+reg: CEE_SHL (reg, reg),
+reg: CEE_SHR (reg, reg),
+reg: CEE_SHR_UN (reg, reg) {
+ MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+reg: CEE_NEG (reg),
+reg: CEE_NOT (reg) {
+ MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1);
+}
+
+
+reg: CEE_AND (reg, OP_ICONST) {
+ MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+reg: CEE_OR (reg, OP_ICONST) {
+ MONO_EMIT_BIALU_IMM (s, tree, OP_OR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+reg: CEE_XOR (reg, OP_ICONST) {
+ MONO_EMIT_BIALU_IMM (s, tree, OP_XOR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+reg: CEE_ADD (reg, OP_ICONST) {
+ MONO_EMIT_BIALU_IMM (s, tree, OP_ADD_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+reg: CEE_SUB (reg, OP_ICONST) {
+ MONO_EMIT_BIALU_IMM (s, tree, OP_SUB_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+reg: CEE_MUL (reg, OP_ICONST) {
+ MONO_EMIT_BIALU_IMM (s, tree, OP_MUL_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+reg: CEE_SHL (reg, OP_ICONST) {
+ MONO_EMIT_BIALU_IMM (s, tree, OP_SHL_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+reg: CEE_SHR (reg, OP_ICONST) {
+ MONO_EMIT_BIALU_IMM (s, tree, OP_SHR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+reg: CEE_SHR_UN (reg, OP_ICONST) {
+ MONO_EMIT_BIALU_IMM (s, tree, OP_SHR_UN_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
+
+reg: CEE_ADD_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: CEE_ADD_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: CEE_SUB (reg, CEE_LDIND_I4 (OP_REGVAR)) {
+ MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->left->tree->dreg);
+}
+
+reg: CEE_SUB_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: CEE_SUB_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");
+}
+
+cflags: OP_COMPARE (reg, reg) {
+ tree->sreg1 = state->left->reg1;
+ tree->sreg2 = state->right->reg1;
+ mono_bblock_add_inst (s->cbb, tree);
+}
+
+cflags: OP_COMPARE (CEE_LDIND_REF (OP_REGVAR), reg),
+cflags: OP_COMPARE (CEE_LDIND_I (OP_REGVAR), reg),
+cflags: OP_COMPARE (CEE_LDIND_I4 (OP_REGVAR), reg),
+cflags: OP_COMPARE (CEE_LDIND_U4 (OP_REGVAR), reg) {
+ tree->sreg1 = state->left->left->tree->dreg;
+ tree->sreg2 = state->right->reg1;
+ mono_bblock_add_inst (s->cbb, tree);
+}
+
+cflags: OP_COMPARE (CEE_LDIND_REF (OP_REGVAR), CEE_LDIND_REF (OP_REGVAR)),
+cflags: OP_COMPARE (CEE_LDIND_I (OP_REGVAR), CEE_LDIND_I (OP_REGVAR)),
+cflags: OP_COMPARE (CEE_LDIND_I4 (OP_REGVAR), CEE_LDIND_I4 (OP_REGVAR)),
+cflags: OP_COMPARE (CEE_LDIND_U4 (OP_REGVAR), CEE_LDIND_U4 (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_COMPARE (CEE_LDIND_REF (OP_REGVAR), OP_ICONST),
+cflags: OP_COMPARE (CEE_LDIND_I (OP_REGVAR), OP_ICONST),
+cflags: OP_COMPARE (CEE_LDIND_I4 (OP_REGVAR), OP_ICONST),
+cflags: OP_COMPARE (CEE_LDIND_U4 (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);
+}
+
+cflags: OP_COMPARE (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);
+}
+
+stmt: CEE_BNE_UN (cflags),
+stmt: CEE_BEQ (cflags),
+stmt: CEE_BLT (cflags),
+stmt: CEE_BLT_UN (cflags),
+stmt: CEE_BGT (cflags),
+stmt: CEE_BGT_UN (cflags),
+stmt: CEE_BGE (cflags),
+stmt: CEE_BGE_UN (cflags),
+stmt: CEE_BLE (cflags),
+stmt: CEE_BLE_UN (cflags) {
+ mono_bblock_add_inst (s->cbb, tree);
+}
+
+reg: OP_CEQ (cflags),
+reg: OP_CLT (cflags),
+reg: OP_CLT_UN (cflags),
+reg: OP_CGT (cflags),
+reg: OP_CGT_UN (cflags) {
+ tree->dreg = state->reg1;
+ mono_bblock_add_inst (s->cbb, tree);
+}
+
+#
+# 64 bit rules
+#
+
#
# We use a new non-terminal called "lreg" for 64bit registers, and
# emulate lreg with 2 32bit registers.
state->left->tree->inst_offset + MINI_LS_WORD_OFFSET, state->right->tree->inst_ls_word);
}
-lreg: OP_BIGMUL (reg, reg) {
- MONO_EMIT_NEW_BIALU (s, OP_BIGMUL, state->reg1, state->left->reg1, state->right->reg1);
+lreg: OP_BIGMUL (reg, reg),
+lreg: OP_BIGMUL_UN (reg, reg) {
+ MONO_EMIT_NEW_BIALU (s, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
}
-lreg: OP_BIGMUL_UN (reg, reg) {
- MONO_EMIT_NEW_BIALU (s, OP_BIGMUL_UN, state->reg1, state->left->reg1, state->right->reg1);
+lreg: OP_LONG_SHRUN_32 (lreg) {
+ /* just move the upper half to the lower and zero the high word */
+ MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg2);
+ MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
+}
+
+reg: OP_LCONV_TO_I4 (OP_LONG_SHRUN_32 (lreg)),
+reg: OP_LCONV_TO_U4 (OP_LONG_SHRUN_32 (lreg)) {
+ MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->left->reg2);
+}
+
+
+lreg: OP_LONG_SHRUN_32 (CEE_LDIND_I8 (base)) {
+ /* just move the upper half to the lower and zero the high word */
+ MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, state->reg1,
+ state->left->left->tree->inst_basereg, state->left->left->tree->inst_offset + MINI_MS_WORD_OFFSET);
+ MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
+}
+
+reg: OP_LCONV_TO_I4 (OP_LONG_SHRUN_32 (CEE_LDIND_I8 (base))),
+reg: OP_LCONV_TO_U4 (OP_LONG_SHRUN_32 (CEE_LDIND_I8 (base))) {
+ /* just move the upper half to the lower and zero the high word */
+ MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, state->reg1,
+ state->left->left->left->tree->inst_basereg,
+ state->left->left->left->tree->inst_offset + MINI_MS_WORD_OFFSET);
}
lreg: OP_LADD (lreg, lreg) {
}
lreg: OP_LADD (lreg, i8con) {
- MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
+ MONO_EMIT_NEW_BIALU_IMM (s, OP_ADDCC_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
MONO_EMIT_BIALU_IMM (s, tree, OP_ADC_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
}
}
lreg: OP_LSUB (lreg, i8con) {
- MONO_EMIT_NEW_BIALU_IMM (s, OP_SUB_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
+ MONO_EMIT_NEW_BIALU_IMM (s, OP_SUBCC_IMM, state->reg1, state->left->reg1, state->right->tree->inst_ls_word);
MONO_EMIT_BIALU_IMM (s, tree, OP_SBB_IMM, state->reg2, state->left->reg2, state->right->tree->inst_ms_word);
}
lreg: OP_LSUB_OVF_UN (lreg, lreg) {
/* SBB sets the condition code */
- MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg1, state->left->reg1, state->right->reg1);
+ MONO_EMIT_NEW_BIALU (s, OP_SUBCC, state->reg1, state->left->reg1, state->right->reg1);
MONO_EMIT_NEW_BIALU (s, OP_SBB, state->reg2, state->left->reg2, state->right->reg2);
MONO_EMIT_NEW_COND_EXC (s, C, "OverflowException");
}
lreg: OP_LNEG (lreg) "4" {
MONO_EMIT_NEW_UNALU (s, CEE_NOT, state->reg1, state->left->reg1);
MONO_EMIT_NEW_UNALU (s, CEE_NOT, state->reg2, state->left->reg2);
- MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->reg1, 1);
+ /* ADC sets the condition codes */
+ MONO_EMIT_NEW_BIALU_IMM (s, OP_ADC_IMM, state->reg1, state->reg1, 1);
MONO_EMIT_BIALU_IMM (s, tree, OP_ADC_IMM, state->reg2, state->reg2, 0);
}
-reg: OP_CEQ (OP_COMPARE (lreg, lreg)) {
+reg: OP_CEQ (OP_LCOMPARE (lreg, lreg)) {
MonoInst *word_differs;
MONO_NEW_LABEL (s, word_differs);
mono_bblock_add_inst (s->cbb, word_differs);
}
-reg: OP_CLT (OP_COMPARE (lreg, lreg)) {
+reg: OP_CLT (OP_LCOMPARE (lreg, lreg)) {
MonoInst *set_to_0, *set_to_1;
MONO_NEW_LABEL (s, set_to_0);
mono_bblock_add_inst (s->cbb, set_to_0);
}
-reg: OP_CLT_UN (OP_COMPARE (lreg, lreg)) {
+reg: OP_CLT_UN (OP_LCOMPARE (lreg, lreg)) {
MonoInst *set_to_0, *set_to_1;
MONO_NEW_LABEL (s, set_to_0);
mono_bblock_add_inst (s->cbb, set_to_0);
}
-reg: OP_CGT (OP_COMPARE (lreg, lreg)) {
+reg: OP_CGT (OP_LCOMPARE (lreg, lreg)) {
MonoInst *set_to_0, *set_to_1;
MONO_NEW_LABEL (s, set_to_0);
mono_bblock_add_inst (s->cbb, set_to_0);
}
-reg: OP_CGT_UN (OP_COMPARE (lreg, lreg)) {
+reg: OP_CGT_UN (OP_LCOMPARE (lreg, lreg)) {
MonoInst *set_to_0, *set_to_1;
MONO_NEW_LABEL (s, set_to_0);
mono_bblock_add_inst (s->cbb, set_to_0);
}
-stmt: CEE_BNE_UN (OP_COMPARE (lreg, lreg)) {
+stmt: CEE_BNE_UN (OP_LCOMPARE (lreg, lreg)) {
MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_true_bb);
MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
mono_bblock_add_inst (s->cbb, tree);
}
-stmt: CEE_BNE_UN (OP_COMPARE (lreg, i8con)) {
+stmt: CEE_BNE_UN (OP_LCOMPARE (lreg, i8con)) {
MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_ls_word);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_true_bb);
MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
mono_bblock_add_inst (s->cbb, tree);
}
-stmt: CEE_BEQ (OP_COMPARE (lreg, lreg)) {
+stmt: CEE_BEQ (OP_LCOMPARE (lreg, lreg)) {
MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
mono_bblock_add_inst (s->cbb, tree);
}
-stmt: CEE_BEQ (OP_COMPARE (lreg, i8con)) {
+stmt: CEE_BEQ (OP_LCOMPARE (lreg, i8con)) {
MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_ls_word);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb);
mono_bblock_add_inst (s->cbb, tree);
}
-stmt: CEE_BLE (OP_COMPARE (lreg, lreg)) {
+stmt: CEE_BLE (OP_LCOMPARE (lreg, lreg)) {
MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT, tree->inst_true_bb);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLE_UN, tree->inst_true_bb);
}
-stmt: CEE_BLE (OP_COMPARE (lreg, i8con)) {
+stmt: CEE_BLE (OP_LCOMPARE (lreg, i8con)) {
MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT, tree->inst_true_bb);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLE_UN, tree->inst_true_bb);
}
-stmt: CEE_BLE_UN (OP_COMPARE (lreg, lreg)) {
+stmt: CEE_BLE_UN (OP_LCOMPARE (lreg, lreg)) {
MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLE_UN, tree->inst_true_bb);
}
-stmt: CEE_BLE_UN (OP_COMPARE (lreg, i8con)) {
+stmt: CEE_BLE_UN (OP_LCOMPARE (lreg, i8con)) {
MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLE_UN, tree->inst_true_bb);
}
-stmt: CEE_BGE (OP_COMPARE (lreg, lreg)) {
+stmt: CEE_BGE (OP_LCOMPARE (lreg, lreg)) {
MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT, tree->inst_true_bb);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_true_bb);
}
-stmt: CEE_BGE (OP_COMPARE (lreg, i8con)) {
+stmt: CEE_BGE (OP_LCOMPARE (lreg, i8con)) {
MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT, tree->inst_true_bb);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_true_bb);
}
-stmt: CEE_BGE_UN (OP_COMPARE (lreg, lreg)) {
+stmt: CEE_BGE_UN (OP_LCOMPARE (lreg, lreg)) {
MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_true_bb);
}
-stmt: CEE_BGE_UN (OP_COMPARE (lreg, i8con)) {
+stmt: CEE_BGE_UN (OP_LCOMPARE (lreg, i8con)) {
MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_true_bb);
}
-stmt: CEE_BLT (OP_COMPARE (lreg, lreg)) {
+stmt: CEE_BLT (OP_LCOMPARE (lreg, lreg)) {
MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT, tree->inst_true_bb);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
}
-stmt: CEE_BLT (OP_COMPARE (lreg, i8con)) {
+stmt: CEE_BLT (OP_LCOMPARE (lreg, i8con)) {
MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT, tree->inst_true_bb);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
}
-stmt: CEE_BLT_UN (OP_COMPARE (lreg, lreg)) {
+stmt: CEE_BLT_UN (OP_LCOMPARE (lreg, lreg)) {
MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
}
-stmt: CEE_BLT_UN (OP_COMPARE (lreg, i8con)) {
+stmt: CEE_BLT_UN (OP_LCOMPARE (lreg, i8con)) {
MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb);
}
-stmt: CEE_BGT (OP_COMPARE (lreg, lreg)) {
+stmt: CEE_BGT (OP_LCOMPARE (lreg, lreg)) {
MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT, tree->inst_true_bb);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
}
-stmt: CEE_BGT (OP_COMPARE (lreg, i8con)) {
+stmt: CEE_BGT (OP_LCOMPARE (lreg, i8con)) {
MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT, tree->inst_true_bb);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
}
-stmt: CEE_BGT_UN (OP_COMPARE (lreg, lreg)) {
+stmt: CEE_BGT_UN (OP_LCOMPARE (lreg, lreg)) {
MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
}
-stmt: CEE_BGT_UN (OP_COMPARE (lreg, i8con)) {
+stmt: CEE_BGT_UN (OP_LCOMPARE (lreg, i8con)) {
MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_ms_word);
MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb);
lreg: CEE_CONV_OVF_I8 (reg) {
/* a signed 32 bit num always fits in a signed 64 bit one */
- MONO_EMIT_NEW_ICONST (s, state->reg2, 0);
+ MONO_EMIT_NEW_BIALU_IMM (s, OP_SHR_IMM, state->reg2, state->left->reg1, 31);
MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
}
MONO_EMIT_NEW_ICONST (s, state->reg1, state->left->tree->inst_ls_word);
}
-reg: OP_LCONV_TO_I4 (lreg) {
- MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
-}
-
+reg: OP_LCONV_TO_I4 (lreg),
reg: OP_LCONV_TO_U4 (lreg) {
MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
}
-lreg: OP_LCONV_TO_U8 (lreg) {
- MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
- MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
+reg: OP_LCONV_TO_I4 (CEE_LDIND_I8 (base)),
+reg: OP_LCONV_TO_U4 (CEE_LDIND_I8 (base)) {
+ MONO_EMIT_LOAD_MEMBASE_OP (s, tree, OP_LOADI4_MEMBASE, state->reg1,
+ state->left->left->tree->inst_basereg,
+ state->left->left->tree->inst_offset + MINI_LS_WORD_OFFSET);
}
+lreg: OP_LCONV_TO_U8 (lreg),
lreg: OP_LCONV_TO_I8 (lreg) {
MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1);
MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
}
-reg: OP_LCONV_TO_U (lreg) {
- MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
-}
-
+reg: OP_LCONV_TO_U (lreg),
reg: OP_LCONV_TO_I (lreg) {
MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
}
MONO_EMIT_UNALU (s, tree, CEE_CONV_U2, state->reg1, state->left->reg1);
}
+reg: OP_LCONV_TO_OVF_I1_UN (lreg) {
+ MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
+ MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
+
+ 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 (lreg) {
+ MonoInst *is_negative, *end_label;
+
+ MONO_NEW_LABEL (s, is_negative);
+ MONO_NEW_LABEL (s, end_label);
+
MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, -1);
MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+ MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
+ MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BLT, is_negative);
+
+ /* Positive */
MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 127);
- MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
+ MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
+ MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BR, end_label);
+
+ /* Negative */
+ mono_bblock_add_inst (s->cbb, is_negative);
MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -128);
- MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+ MONO_EMIT_NEW_COND_EXC (s, LT_UN, "OverflowException");
+ mono_bblock_add_inst (s->cbb, end_label);
+
MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1);
}
+reg: OP_LCONV_TO_OVF_U1_UN (lreg),
reg: OP_LCONV_TO_OVF_U1 (lreg) {
MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
}
reg: OP_LCONV_TO_OVF_I2 (lreg) {
+ MonoInst *is_negative, *end_label;
+
+ MONO_NEW_LABEL (s, is_negative);
+ MONO_NEW_LABEL (s, end_label);
+
MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
MONO_EMIT_NEW_COND_EXC (s, GT, "OverflowException");
MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, -1);
MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException");
+ MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
+ MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BLT, is_negative);
+
+ /* Positive */
+ MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, 32767);
+ MONO_EMIT_NEW_COND_EXC (s, GT_UN, "OverflowException");
+ MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BR, end_label);
+
+ /* Negative */
+ mono_bblock_add_inst (s->cbb, is_negative);
+ MONO_EMIT_NEW_COMPARE_IMM (s, state->left->reg1, -32768);
+ MONO_EMIT_NEW_COND_EXC (s, LT_UN, "OverflowException");
+ mono_bblock_add_inst (s->cbb, end_label);
+
+ MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
+}
+
+reg: OP_LCONV_TO_OVF_I2_UN (lreg) {
+ MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
+ MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
+
/* 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_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1);
}
+reg: OP_LCONV_TO_OVF_U2_UN (lreg),
reg: OP_LCONV_TO_OVF_U2 (lreg) {
MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0);
MONO_EMIT_NEW_COND_EXC (s, NE_UN, "OverflowException");
mono_bblock_add_inst (s->cbb, tree);
}
+reg: OP_LCONV_TO_OVF_I4_UN (lreg),
reg: OP_LCONV_TO_OVF_I4 (lreg) {
tree->dreg = state->reg1;
tree->sreg1 = state->left->reg1;
MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2);
}
+lreg: OP_LCALLVIRT (reg) {
+ mini_emit_virtual_call (s, state, tree, OP_LCALL, OP_LCALL_MEMBASE);
+}
+
+lreg: OP_LCALL {
+ tree->dreg = state->reg1;
+ mono_bblock_add_inst (s->cbb, tree);
+}
+
+lreg: OP_LCALL_REG (reg) {
+ tree->sreg1 = state->left->reg1;
+ tree->dreg = state->reg1;
+ mono_bblock_add_inst (s->cbb, tree);
+}
+
+lreg: 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);
+}
+
%%