2004-09-11 Ben Maurer <bmaurer@users.sourceforge.net>
[mono.git] / mono / mini / inssel.brg
index b07bcfe628871dbd0414a2ecace323cac923117d..0cb8129cca0e0b6754a3569a5a925a9a2cd47ed1 100644 (file)
@@ -8,7 +8,6 @@
  * (C) 2002 Ximian, Inc.
  *
  */
-
 #include <config.h>
 #include <string.h>
 
                (inst)->opcode = OP_LABEL;      \
        } while (0)
 
+#define MONO_EMIT_BOUNDS_CHECK(cfg, array_reg, array_type, array_length_field, index_reg) do { \
+               if (! (state->tree->flags & MONO_INST_NORANGECHECK)) { \
+                       int _length_reg = mono_regstate_next_int (cfg->rs); \
+                       MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI4_MEMBASE, _length_reg, array_reg, G_STRUCT_OFFSET (array_type, array_length_field)); \
+                       MONO_EMIT_NEW_BIALU (cfg, OP_COMPARE, -1, _length_reg, index_reg); \
+                       MONO_EMIT_NEW_COND_EXC (cfg, LE_UN, "IndexOutOfRangeException"); \
+               } \
+       } while (0)
+
+#define MONO_EMIT_BOUNDS_CHECK_IMM(cfg, array_reg, array_type, array_length_field, index_imm) do { \
+               if (! (state->tree->flags & MONO_INST_NORANGECHECK)) { \
+                       int _length_reg = mono_regstate_next_int (cfg->rs); \
+                       MONO_EMIT_NEW_LOAD_MEMBASE_OP (cfg, OP_LOADI4_MEMBASE, _length_reg, array_reg, G_STRUCT_OFFSET (array_type, array_length_field)); \
+                       MONO_EMIT_NEW_BIALU_IMM (cfg, OP_COMPARE_IMM, -1, _length_reg, index_imm); \
+                       MONO_EMIT_NEW_COND_EXC (cfg, LE_UN, "IndexOutOfRangeException"); \
+               } \
+       } while (0)
+
 /* we need to kludge state because monoburg puts this stuff before the definition of MBState */
 void mini_emit_virtual_call (MonoCompile *s, void *state, MonoInst *tree, int novirt_op, int virtop);
 void mini_emit_isninst_cast (MonoCompile *s, int klass_reg, MonoClass *klass, MonoInst *false_target, MonoInst *true_target);
@@ -407,20 +424,8 @@ reg: OP_VTADDR (reg) {
        mono_bblock_add_inst (s->cbb, tree);
 }
 
-reg: CEE_LDIND_REF (OP_REGVAR) {
-       tree->opcode = OP_MOVE;
-       tree->sreg1 = state->left->tree->dreg;
-       tree->dreg = state->reg1;
-       mono_bblock_add_inst (s->cbb, tree);
-}
-
-reg: CEE_LDIND_I4 (OP_REGVAR) {
-       tree->opcode = OP_MOVE;
-       tree->sreg1 = state->left->tree->dreg;
-       tree->dreg = state->reg1;
-       mono_bblock_add_inst (s->cbb, tree);
-}
-
+reg: CEE_LDIND_REF (OP_REGVAR),
+reg: CEE_LDIND_I4 (OP_REGVAR),
 reg: CEE_LDIND_U4 (OP_REGVAR) {
        tree->opcode = OP_MOVE;
        tree->sreg1 = state->left->tree->dreg;
@@ -561,10 +566,19 @@ stmt: CEE_STIND_I4 (OP_REGVAR, CEE_LDIND_I4 (base)) {
                                   state->right->left->tree->inst_offset);
 }
 
-stmt: CEE_STIND_I4 (OP_REGVAR, OP_ICONST) {
+stmt: CEE_STIND_I4 (OP_REGVAR, OP_ICONST),
+stmt: CEE_STIND_I2 (OP_REGVAR, OP_ICONST),
+stmt: CEE_STIND_I1 (OP_REGVAR, OP_ICONST),
+stmt: CEE_STIND_REF (OP_REGVAR, OP_ICONST),
+stmt: CEE_STIND_I (OP_REGVAR, OP_ICONST) {
+       tree->inst_c0 = state->right->tree->inst_c0;
+       if (tree->opcode == CEE_STIND_I2)
+               tree->inst_c0 &= 0xffff;
+       if (tree->opcode == CEE_STIND_I1)
+               tree->inst_c0 &= 0xff;
+       
        tree->opcode = OP_ICONST;
        tree->dreg = state->left->tree->dreg;
-       tree->inst_c0 = state->right->tree->inst_c0;
        mono_bblock_add_inst (s->cbb, tree);
 }
 
@@ -572,13 +586,6 @@ stmt: CEE_STIND_REF (OP_REGVAR, reg) {
        MONO_EMIT_UNALU (s, tree, OP_MOVE, state->left->tree->dreg, state->right->reg1);
 }
 
-stmt: CEE_STIND_REF (OP_REGVAR, OP_ICONST) {
-       tree->opcode = OP_ICONST;
-       tree->dreg = state->left->tree->dreg;
-       tree->inst_c0 = state->right->tree->inst_c0;
-       mono_bblock_add_inst (s->cbb, tree);
-}
-
 stmt: CEE_STIND_I (OP_REGVAR, reg) {
        MONO_EMIT_UNALU (s, tree, OP_MOVE, state->left->tree->dreg, state->right->reg1);
 }
@@ -842,6 +849,10 @@ reg: CEE_SUB (reg, reg) {
        MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
 }
 
+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 (reg, OP_ICONST) {
        MONO_EMIT_BIALU_IMM (s, tree, OP_SUB_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
 }
@@ -1130,6 +1141,12 @@ cflags: OP_COMPARE (CEE_LDIND_I4 (OP_REGVAR), reg) {
        mono_bblock_add_inst (s->cbb, tree);
 }
 
+cflags: OP_COMPARE (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_COMPARE (CEE_LDIND_I4 (OP_REGVAR), OP_ICONST) {
        tree->opcode = OP_COMPARE_IMM;
        tree->sreg1 = state->left->left->tree->dreg;
@@ -1643,46 +1660,16 @@ reg: OP_CCASTCLASS (reg) {
        mono_bblock_add_inst (s->cbb, end_label);
 }
 
-reg: CEE_NEWARR (reg) {
-       g_assert_not_reached ();
-}
-
-lreg: OP_LMUL (lreg, lreg) {
-       g_assert_not_reached ();
-}
-
-lreg: OP_LMUL_OVF (lreg, lreg) {
-       g_assert_not_reached ();
-}
-
-lreg: OP_LMUL_OVF_UN (lreg, lreg) {
-       g_assert_not_reached ();
-}
-
-lreg: OP_LDIV (lreg, lreg) {
-       g_assert_not_reached ();
-}
-
-lreg: OP_LDIV_UN (lreg, lreg) {
-       g_assert_not_reached ();
-}
-
-lreg: OP_LREM (lreg, lreg) {
-       g_assert_not_reached ();
-}
-
-lreg: OP_LREM_UN (lreg, lreg) {
-       g_assert_not_reached ();
-}
-
-lreg: OP_LSHL (lreg, reg) {
-       g_assert_not_reached ();
-}
-
-lreg: OP_LSHR (lreg, reg) {
-       g_assert_not_reached ();
-}
-
+reg: CEE_NEWARR (reg),
+lreg: OP_LMUL (lreg, lreg),
+lreg: OP_LMUL_OVF (lreg, lreg),
+lreg: OP_LMUL_OVF_UN (lreg, lreg),
+lreg: OP_LDIV (lreg, lreg),
+lreg: OP_LDIV_UN (lreg, lreg),
+lreg: OP_LREM (lreg, lreg),
+lreg: OP_LREM_UN (lreg, lreg),
+lreg: OP_LSHL (lreg, reg),
+lreg: OP_LSHR (lreg, reg),
 lreg: OP_LSHR_UN (lreg, reg) {
        g_assert_not_reached ();
 }
@@ -1691,15 +1678,10 @@ lreg: OP_LSHR_UN (lreg, reg) {
 # string support
 #
 reg: OP_GETCHR (reg, reg) {
-       int length_reg = mono_regstate_next_int (s->rs);
        int mult_reg = mono_regstate_next_int (s->rs);
        int add_reg = mono_regstate_next_int (s->rs);
        
-       MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, length_reg, 
-                                      state->left->reg1, G_STRUCT_OFFSET (MonoString, length));
-       MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, length_reg, state->right->reg1);
-       MONO_EMIT_NEW_COND_EXC (s, LE_UN, "IndexOutOfRangeException");
-
+       MONO_EMIT_BOUNDS_CHECK (s, state->left->reg1, MonoString, length, state->right->reg1);
        MONO_EMIT_NEW_BIALU_IMM (s, OP_SHL_IMM, mult_reg, state->right->reg1, 1);
        MONO_EMIT_NEW_BIALU (s, CEE_ADD, add_reg, mult_reg, state->left->reg1);
        MONO_EMIT_LOAD_MEMBASE_OP (s, tree, OP_LOADU2_MEMBASE, state->reg1, 
@@ -1707,14 +1689,9 @@ reg: OP_GETCHR (reg, reg) {
 }
 
 reg: OP_GETCHR (reg, OP_ICONST) {
-       int length_reg = mono_regstate_next_int (s->rs);
-       int ind;
+       int ind = 2 * state->right->tree->inst_c0 + G_STRUCT_OFFSET (MonoString, chars);
 
-       MONO_EMIT_NEW_LOAD_MEMBASE (s, length_reg, state->left->reg1, G_STRUCT_OFFSET (MonoString, length));
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, length_reg, state->right->tree->inst_c0);
-       MONO_EMIT_NEW_COND_EXC (s, LE_UN, "IndexOutOfRangeException");
-       
-       ind = 2 * state->right->tree->inst_c0 + G_STRUCT_OFFSET (MonoString, chars);
+       MONO_EMIT_BOUNDS_CHECK_IMM (s, state->left->reg1, MonoString, length, state->right->tree->inst_c0);
        MONO_EMIT_LOAD_MEMBASE_OP (s, tree, OP_LOADU2_MEMBASE, state->reg1, state->left->reg1, ind);
 }
 
@@ -1759,37 +1736,33 @@ reg: OP_CHECK_ARRAY_TYPE (reg) {
                                       vtable_reg, G_STRUCT_OFFSET (MonoVTable, klass));
        MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOAD_MEMBASE, elclass_reg, 
                                       class_reg, G_STRUCT_OFFSET (MonoClass, element_class));
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, elclass_reg, tree->klass);
+       if (mono_compile_aot) {
+               int klass_reg = mono_regstate_next_int (s->rs);
+               MONO_EMIT_NEW_CLASSCONST (s, klass_reg, tree->klass);
+               MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, elclass_reg, klass_reg);
+       } else {
+               MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, elclass_reg, tree->klass);
+       }
+       
        MONO_EMIT_NEW_COND_EXC (s, NE_UN, "ArrayTypeMismatchException");
        MONO_EMIT_UNALU (s, tree, OP_MOVE, state->reg1, state->left->reg1);
 }
 
 reg: CEE_LDELEMA (reg, OP_ICONST) "15" {
-       int length_reg = mono_regstate_next_int (s->rs);
        guint32 size = mono_class_array_element_size (tree->klass);
-       int ind;
 
-       MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, length_reg, 
-                                      state->left->reg1, G_STRUCT_OFFSET (MonoArray, max_length));
-       MONO_EMIT_NEW_BIALU_IMM (s, OP_COMPARE_IMM, -1, length_reg, state->right->tree->inst_c0);
-       MONO_EMIT_NEW_COND_EXC (s, LE_UN, "IndexOutOfRangeException");
-       
-       ind = size * state->right->tree->inst_c0 + G_STRUCT_OFFSET (MonoArray, vector);
-       
+       int ind = size * state->right->tree->inst_c0 + G_STRUCT_OFFSET (MonoArray, vector);
+
+       MONO_EMIT_BOUNDS_CHECK_IMM (s, state->left->reg1, MonoArray, max_length, state->right->tree->inst_c0);
        MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, state->left->reg1, ind);
 }
 
 reg: CEE_LDELEMA (reg, reg) "20" {
-       int length_reg = mono_regstate_next_int (s->rs);
        int mult_reg = mono_regstate_next_int (s->rs);
        int add_reg = mono_regstate_next_int (s->rs);
        guint32 size = mono_class_array_element_size (tree->klass);
-       
-       MONO_EMIT_NEW_LOAD_MEMBASE_OP (s, OP_LOADI4_MEMBASE, length_reg, 
-                                      state->left->reg1, G_STRUCT_OFFSET (MonoArray, max_length));
-       MONO_EMIT_NEW_BIALU (s, OP_COMPARE, -1, length_reg, state->right->reg1);
-       MONO_EMIT_NEW_COND_EXC (s, LE_UN, "IndexOutOfRangeException");
 
+       MONO_EMIT_BOUNDS_CHECK (s, state->left->reg1, MonoArray, max_length, state->right->reg1);
        MONO_EMIT_NEW_BIALU_IMM (s, OP_MUL_IMM, mult_reg, state->right->reg1, size);
        MONO_EMIT_NEW_BIALU (s, CEE_ADD, add_reg, mult_reg, state->left->reg1);
        MONO_EMIT_NEW_BIALU_IMM (s, OP_ADD_IMM, state->reg1, add_reg, G_STRUCT_OFFSET (MonoArray, vector));