%% # # inssel-long32.brg: burg file for 64bit instructions on 32bit architectures # # Author: # Dietmar Maurer (dietmar@ximian.com) # # (C) 2002 Ximian, Inc. # # # We use a new non-terminal called "lreg" for 64bit registers, and # emulate lreg with 2 32bit registers. # stmt: CEE_POP (lreg) { /* do nothing */ } i8con: CEE_CONV_I8 (OP_ICONST) "0" { int data = state->left->tree->inst_c0; tree->opcode = OP_I8CONST; tree->inst_c0 = data; if (data < 0) tree->inst_c1 = -1; else tree->inst_c1 = 0; } i8con: CEE_CONV_U8 (OP_ICONST) "0" { int data = state->left->tree->inst_c0; tree->opcode = OP_I8CONST; tree->inst_c0 = data; tree->inst_c1 = 0; } i8con: OP_I8CONST "0" lreg: OP_ICONST { int data = state->tree->inst_c0; MONO_EMIT_NEW_ICONST (s, state->reg1, data); if (data >= 0) MONO_EMIT_NEW_ICONST (s, state->reg2, 0); else MONO_EMIT_NEW_ICONST (s, state->reg2, -1); } lreg: OP_I8CONST { MONO_EMIT_NEW_ICONST (s, state->reg1, tree->inst_c0); MONO_EMIT_NEW_ICONST (s, state->reg2, tree->inst_c1); } lreg: CEE_LDIND_I8 (base) { MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, state->reg1, state->left->tree->inst_basereg, state->left->tree->inst_offset); MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, state->reg2, state->left->tree->inst_basereg, state->left->tree->inst_offset + 4); } stmt: CEE_STIND_I8 (base, lreg) { MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, state->left->tree->inst_basereg, state->left->tree->inst_offset + 4, state->right->reg2); MONO_EMIT_NEW_STORE_MEMBASE (s, OP_STOREI4_MEMBASE_REG, state->left->tree->inst_basereg, state->left->tree->inst_offset, state->right->reg1); } stmt: CEE_STIND_I8 (base, i8con) { MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STOREI4_MEMBASE_IMM, state->left->tree->inst_basereg, state->left->tree->inst_offset + 4, state->right->tree->inst_c1); MONO_EMIT_NEW_STORE_MEMBASE_IMM (s, OP_STOREI4_MEMBASE_IMM, state->left->tree->inst_basereg, state->left->tree->inst_offset, state->right->tree->inst_c0); } lreg: OP_LADD (lreg, lreg) { MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg1, state->left->reg1, state->right->reg1); MONO_EMIT_BIALU (s, tree, OP_ADC, state->reg2, state->left->reg2, state->right->reg2); } lreg: OP_LADD_OVF (lreg, lreg) { /* ADC sets the condition code */ MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg1, state->left->reg1, state->right->reg1); MONO_EMIT_NEW_BIALU (s, OP_ADC, state->reg2, state->left->reg2, state->right->reg2); MONO_EMIT_NEW_COND_EXC (s, OV, "OverflowException"); } lreg: OP_LADD_OVF_UN (lreg, lreg) { /* ADC sets the condition code */ MONO_EMIT_NEW_BIALU (s, CEE_ADD, state->reg1, state->left->reg1, state->right->reg1); MONO_EMIT_NEW_BIALU (s, OP_ADC, state->reg2, state->left->reg2, state->right->reg2); MONO_EMIT_NEW_COND_EXC (s, C, "OverflowException"); } lreg: OP_LADD (lreg, i8con) { MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0); MONO_EMIT_BIALU_IMM (s, tree, OP_ADC_IMM, state->reg2, state->left->reg2, state->right->tree->inst_c1); } lreg: OP_LSUB (lreg, lreg) { MONO_EMIT_NEW_BIALU (s, CEE_SUB, state->reg1, state->left->reg1, state->right->reg1); MONO_EMIT_BIALU (s, tree, OP_SBB, state->reg2, state->left->reg2, state->right->reg2); } lreg: OP_LSUB (lreg, i8con) { MONO_EMIT_NEW_BIALU_IMM (s, OP_SUB_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0); MONO_EMIT_BIALU_IMM (s, tree, OP_SBB_IMM, state->reg2, state->left->reg2, state->right->tree->inst_c1); } lreg: OP_LSUB_OVF (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_SBB, state->reg2, state->left->reg2, state->right->reg2); MONO_EMIT_NEW_COND_EXC (s, OV, "OverflowException"); } 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_SBB, state->reg2, state->left->reg2, state->right->reg2); MONO_EMIT_NEW_COND_EXC (s, C, "OverflowException"); } lreg: OP_LAND (lreg, lreg) { MONO_EMIT_NEW_BIALU (s, CEE_AND, state->reg1, state->left->reg1, state->right->reg1); MONO_EMIT_BIALU (s, tree, CEE_AND, state->reg2, state->left->reg2, state->right->reg2); } lreg: OP_LAND (lreg, i8con) { MONO_EMIT_NEW_BIALU_IMM (s, OP_AND_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0); MONO_EMIT_BIALU_IMM (s, tree, OP_AND_IMM, state->reg2, state->left->reg2, state->right->tree->inst_c1); } lreg: OP_LOR (lreg, lreg) { MONO_EMIT_NEW_BIALU (s, CEE_OR, state->reg1, state->left->reg1, state->right->reg1); MONO_EMIT_BIALU (s, tree, CEE_OR, state->reg2, state->left->reg2, state->right->reg2); } lreg: OP_LOR (lreg, i8con) { MONO_EMIT_NEW_BIALU_IMM (s, OP_OR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0); MONO_EMIT_BIALU_IMM (s, tree, OP_OR_IMM, state->reg2, state->left->reg2, state->right->tree->inst_c1); } lreg: OP_LXOR (lreg, lreg) { MONO_EMIT_NEW_BIALU (s, CEE_XOR, state->reg1, state->left->reg1, state->right->reg1); MONO_EMIT_BIALU (s, tree, CEE_XOR, state->reg2, state->left->reg2, state->right->reg2); } lreg: OP_LXOR (lreg, i8con) { MONO_EMIT_NEW_BIALU_IMM (s, OP_XOR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0); MONO_EMIT_BIALU_IMM (s, tree, OP_XOR_IMM, state->reg2, state->left->reg2, state->right->tree->inst_c1); } lreg: OP_LNOT (lreg) { MONO_EMIT_NEW_UNALU (s, CEE_NOT, state->reg1, state->left->reg1); MONO_EMIT_UNALU (s, tree, CEE_NOT, state->reg2, state->left->reg2); } 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); MONO_EMIT_BIALU_IMM (s, tree, OP_ADC_IMM, state->reg2, state->reg2, 0); } reg: OP_CEQ (OP_COMPARE (lreg, lreg)) { MonoInst *word_differs; MONO_NEW_LABEL (s, word_differs); MONO_EMIT_NEW_ICONST (s, state->reg1, 0); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2); MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, word_differs); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1); MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, word_differs); MONO_EMIT_NEW_ICONST (s, state->reg1, 1); mono_bblock_add_inst (s->cbb, word_differs); } reg: OP_CLT (OP_COMPARE (lreg, lreg)) { MonoInst *set_to_0, *set_to_1; MONO_NEW_LABEL (s, set_to_0); MONO_NEW_LABEL (s, set_to_1); MONO_EMIT_NEW_ICONST (s, state->reg1, 0); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2); MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGT, set_to_0); MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, set_to_1); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1); MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGE_UN, set_to_0); mono_bblock_add_inst (s->cbb, set_to_1); MONO_EMIT_NEW_ICONST (s, state->reg1, 1); mono_bblock_add_inst (s->cbb, set_to_0); } reg: OP_CLT_UN (OP_COMPARE (lreg, lreg)) { MonoInst *set_to_0, *set_to_1; MONO_NEW_LABEL (s, set_to_0); MONO_NEW_LABEL (s, set_to_1); MONO_EMIT_NEW_ICONST (s, state->reg1, 0); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2); MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGT_UN, set_to_0); MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, set_to_1); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1); MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGE_UN, set_to_0); mono_bblock_add_inst (s->cbb, set_to_1); MONO_EMIT_NEW_ICONST (s, state->reg1, 1); mono_bblock_add_inst (s->cbb, set_to_0); } reg: OP_CGT (OP_COMPARE (lreg, lreg)) { MonoInst *set_to_0, *set_to_1; MONO_NEW_LABEL (s, set_to_0); MONO_NEW_LABEL (s, set_to_1); MONO_EMIT_NEW_ICONST (s, state->reg1, 0); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->right->reg2, state->left->left->reg2); MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGT, set_to_0); MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, set_to_1); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->right->reg1, state->left->left->reg1); MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGE_UN, set_to_0); mono_bblock_add_inst (s->cbb, set_to_1); MONO_EMIT_NEW_ICONST (s, state->reg1, 1); mono_bblock_add_inst (s->cbb, set_to_0); } reg: OP_CGT_UN (OP_COMPARE (lreg, lreg)) { MonoInst *set_to_0, *set_to_1; MONO_NEW_LABEL (s, set_to_0); MONO_NEW_LABEL (s, set_to_1); MONO_EMIT_NEW_ICONST (s, state->reg1, 0); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->right->reg2, state->left->left->reg2); MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGT_UN, set_to_0); MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BNE_UN, set_to_1); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->right->reg1, state->left->left->reg1); MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BGE_UN, set_to_0); mono_bblock_add_inst (s->cbb, set_to_1); MONO_EMIT_NEW_ICONST (s, state->reg1, 1); mono_bblock_add_inst (s->cbb, set_to_0); } stmt: CEE_BNE_UN (OP_COMPARE (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)) { MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_c0); 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_c1); mono_bblock_add_inst (s->cbb, tree); } stmt: CEE_BEQ (OP_COMPARE (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_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg2, state->left->right->reg2); mono_bblock_add_inst (s->cbb, tree); } stmt: CEE_BEQ (OP_COMPARE (lreg, i8con)) { MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_c0); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb); MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_c1); mono_bblock_add_inst (s->cbb, tree); } stmt: CEE_BLE (OP_COMPARE (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_BNE_UN, tree->inst_false_bb); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLE_UN, tree->inst_true_bb); } stmt: CEE_BLE (OP_COMPARE (lreg, i8con)) { MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_c1); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT, tree->inst_true_bb); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb); MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_c0); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLE_UN, tree->inst_true_bb); } stmt: CEE_BLE_UN (OP_COMPARE (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_BNE_UN, tree->inst_false_bb); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLE_UN, tree->inst_true_bb); } stmt: CEE_BLE_UN (OP_COMPARE (lreg, i8con)) { MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_c1); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb); MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_c0); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLE_UN, tree->inst_true_bb); } stmt: CEE_BGE (OP_COMPARE (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_BNE_UN, tree->inst_false_bb); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_true_bb); } stmt: CEE_BGE (OP_COMPARE (lreg, i8con)) { MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_c1); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT, tree->inst_true_bb); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb); MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_c0); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_true_bb); } stmt: CEE_BGE_UN (OP_COMPARE (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_BNE_UN, tree->inst_false_bb); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_true_bb); } stmt: CEE_BGE_UN (OP_COMPARE (lreg, i8con)) { MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_c1); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb); MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_c0); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGE_UN, tree->inst_true_bb); } stmt: CEE_BLT (OP_COMPARE (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_BNE_UN, tree->inst_false_bb); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb); } stmt: CEE_BLT (OP_COMPARE (lreg, i8con)) { MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_c1); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT, tree->inst_true_bb); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb); MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_c0); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb); } stmt: CEE_BLT_UN (OP_COMPARE (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_BNE_UN, tree->inst_false_bb); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb); } stmt: CEE_BLT_UN (OP_COMPARE (lreg, i8con)) { MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_c1); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb); MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_c0); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BLT_UN, tree->inst_true_bb); } stmt: CEE_BGT (OP_COMPARE (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_BNE_UN, tree->inst_false_bb); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb); } stmt: CEE_BGT (OP_COMPARE (lreg, i8con)) { MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_c1); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT, tree->inst_true_bb); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb); MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_c0); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb); } stmt: CEE_BGT_UN (OP_COMPARE (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_BNE_UN, tree->inst_false_bb); MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, state->left->left->reg1, state->left->right->reg1); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb); } stmt: CEE_BGT_UN (OP_COMPARE (lreg, i8con)) { MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg2, state->left->right->tree->inst_c1); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BNE_UN, tree->inst_false_bb); MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->left->reg1, state->left->right->tree->inst_c0); MONO_EMIT_NEW_BRANCH_BLOCK (s, CEE_BGT_UN, tree->inst_true_bb); } lreg: CEE_CONV_I8 (OP_ICONST) { int data = state->left->tree->inst_c0; MONO_EMIT_NEW_ICONST (s, state->reg1, data); if (data >= 0) MONO_EMIT_NEW_ICONST (s, state->reg2, 0); else MONO_EMIT_NEW_ICONST (s, state->reg2, -1); } lreg: CEE_CONV_I8 (reg) { MonoInst *is_negative, *end_label; int tmpreg = mono_regstate_next_int (s->rs); MONO_NEW_LABEL (s, is_negative); MONO_NEW_LABEL (s, end_label); /* branchless code: * low = reg; * tmp = low > -1 ? 1: 0; * high = tmp - 1; if low is zero or pos high becomes 0, else -1 * not sure why it doesn't work in practice */ MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1); /*MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->reg1, -1); tree->dreg = tmpreg; tree->opcode = OP_CGT; mono_bblock_add_inst (s->cbb, tree); MONO_EMIT_NEW_BIALU_IMM (s, OP_SUB_IMM, state->reg2, tmpreg, -1);*/ MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->reg1, 0); MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BLT, is_negative); MONO_EMIT_NEW_ICONST (s, tmpreg, 0); MONO_EMIT_NEW_BRANCH_LABEL (s, CEE_BR, end_label); mono_bblock_add_inst (s->cbb, is_negative); MONO_EMIT_NEW_ICONST (s, tmpreg, -1); mono_bblock_add_inst (s->cbb, end_label); MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg2, tmpreg); } lreg: CEE_CONV_U8 (reg) { MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1); MONO_EMIT_NEW_ICONST (s, state->reg2, 0); } lreg: 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_NEW_ICONST (s, state->reg2, 0); MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1); } lreg: CEE_CONV_OVF_I8_UN (reg) { /* an unsigned 32 bit num always fits in a signed 64 bit one */ MONO_EMIT_NEW_ICONST (s, state->reg2, 0); MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1); } lreg: CEE_CONV_OVF_U8_UN (reg) { MONO_EMIT_NEW_ICONST (s, state->reg2, 0); MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1); } freg: OP_LCONV_TO_R_UN (lreg) { MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->left->reg2); } lreg: OP_FCONV_TO_I8 (freg) { MONO_EMIT_UNALU (s, tree, tree->opcode, state->reg1, state->left->reg1); } lreg: OP_FCONV_TO_U8 (freg) { 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_c0); } reg: OP_LCONV_TO_I4 (lreg) { MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1); } 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); } 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_I (lreg) { MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1); } reg: OP_LCONV_TO_I1 (lreg) { MONO_EMIT_UNALU (s, tree, CEE_CONV_I1, state->reg1, state->left->reg1); } reg: OP_LCONV_TO_U1 (lreg) { MONO_EMIT_UNALU (s, tree, CEE_CONV_U1, state->reg1, state->left->reg1); } reg: OP_LCONV_TO_I2 (lreg) { MONO_EMIT_UNALU (s, tree, CEE_CONV_I2, state->reg1, state->left->reg1); } reg: OP_LCONV_TO_U2 (lreg) { MONO_EMIT_UNALU (s, tree, CEE_CONV_U2, state->reg1, state->left->reg1); } reg: OP_LCONV_TO_OVF_I1 (lreg) { 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_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_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"); /* 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 (lreg) { 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"); /* 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_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"); /* 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_U4_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_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1); } reg: OP_LCONV_TO_OVF_I_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_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1); } reg: OP_LCONV_TO_OVF_U4 (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_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1); } reg: OP_LCONV_TO_OVF_I (lreg) { tree->dreg = state->reg1; tree->sreg1 = state->left->reg1; tree->sreg2 = state->left->reg2; mono_bblock_add_inst (s->cbb, tree); } reg: OP_LCONV_TO_OVF_I4 (lreg) { tree->dreg = state->reg1; tree->sreg1 = state->left->reg1; tree->sreg2 = state->left->reg2; tree->opcode = OP_LCONV_TO_OVF_I; mono_bblock_add_inst (s->cbb, tree); } lreg: OP_LCONV_TO_OVF_I8_UN (lreg) { MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0); MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException"); MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1); MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2); } lreg: OP_LCONV_TO_OVF_U8 (lreg) { MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, state->left->reg2, 0); MONO_EMIT_NEW_COND_EXC (s, LT, "OverflowException"); MONO_EMIT_NEW_UNALU (s, OP_MOVE, state->reg1, state->left->reg1); MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg2, state->left->reg2); } %%