+#define MONO_EMIT_NEW_X86_COMPARE_MEMBASE_REG(cfg,basereg,offset,operand) do { \
+ MonoInst *inst; \
+ inst = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoInst)); \
+ inst->opcode = OP_X86_COMPARE_MEMBASE_REG; \
+ inst->inst_basereg = basereg; \
+ inst->inst_offset = offset; \
+ inst->sreg2 = operand; \
+ mono_bblock_add_inst (cfg->cbb, inst); \
+ } while (0)
+
+#define MONO_EMIT_NEW_X86_COMPARE_MEMBASE_IMM(cfg,basereg,offset,operand) do { \
+ MonoInst *inst; \
+ inst = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoInst)); \
+ inst->opcode = OP_X86_COMPARE_MEMBASE_IMM; \
+ inst->inst_basereg = basereg; \
+ inst->inst_offset = offset; \
+ inst->inst_imm = operand; \
+ mono_bblock_add_inst (cfg->cbb, inst); \
+ } while (0)
+
+/* override the arch independant versions with fast x86 versions */
+
+#undef MONO_EMIT_BOUNDS_CHECK
+#undef MONO_EMIT_BOUNDS_CHECK_IMM
+
+#define MONO_EMIT_BOUNDS_CHECK(cfg, array_reg, array_type, array_length_field, index_reg) do { \
+ if (! (state->tree->flags & MONO_INST_NORANGECHECK)) { \
+ MONO_EMIT_NEW_X86_COMPARE_MEMBASE_REG (cfg, array_reg, G_STRUCT_OFFSET (array_type, array_length_field), 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)) { \
+ MONO_EMIT_NEW_X86_COMPARE_MEMBASE_IMM (cfg, array_reg, G_STRUCT_OFFSET (array_type, array_length_field), index_imm); \
+ MONO_EMIT_NEW_COND_EXC (cfg, LE_UN, "IndexOutOfRangeException"); \
+ } \
+ } while (0)
+
+
%%
#
}
reg: CEE_LDELEMA (reg, reg) "15" {
- int length_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);
if (size == 1 || size == 2 || size == 4 || size == 8) {
static const int fast_log2 [] = { 1, 0, 1, -1, 2, -1, -1, -1, 3 };
mono_bblock_add_inst (s->cbb, tree);
}
+stmt: CEE_STIND_I (OP_REGVAR, CEE_ADD (CEE_LDIND_I (OP_REGVAR), OP_ICONST)),
stmt: CEE_STIND_I4 (OP_REGVAR, CEE_ADD (CEE_LDIND_I4 (OP_REGVAR), OP_ICONST)) {
int con = state->right->right->tree->inst_c0;
int dreg = state->left->tree->dreg;
MONO_EMIT_UNALU (s, tree, OP_X86_FPOP, -1, state->left->reg1);
}
-reg: OP_CALL_REG (OP_ICONST) {
- tree->opcode = OP_CALL_IMM;
- ((MonoCallInst*)tree)->fptr = state->left->tree->inst_c0;
- tree->dreg = state->reg1;
- mono_bblock_add_inst (s->cbb, tree);
+# override the rules in inssel-float.brg that work for machines with FP registers
+
+freg: OP_FCONV_TO_R8 (freg) "0" {
+ /* nothing to do */
}
-stmt: OP_VOIDCALL_REG (OP_ICONST) {
- tree->opcode = OP_VOIDCALL_IMM;
- ((MonoCallInst*)tree)->fptr = state->left->tree->inst_c0;
- mono_bblock_add_inst (s->cbb, tree);
+freg: OP_FCONV_TO_R4 (freg) "0" {
+ /* fixme: nothing to do ??*/
}
-freg: OP_FCALL_REG (OP_ICONST) {
- tree->opcode = OP_FCALL_IMM;
- ((MonoCallInst*)tree)->fptr = state->left->tree->inst_c0;
+reg: CEE_ADD(reg, CEE_LDIND_I4 (base)) {
+ MonoInst *base = state->right->left->tree;
+
tree->dreg = state->reg1;
+ tree->sreg1 = state->left->reg1;
+ tree->sreg2 = base->inst_basereg;
+ tree->inst_offset = base->inst_offset;
+ tree->opcode = OP_X86_ADD_MEMBASE;
mono_bblock_add_inst (s->cbb, tree);
-}
+}
+
+reg: CEE_SUB(reg, CEE_LDIND_I4 (base)) {
+ MonoInst *base = state->right->left->tree;
-lreg: OP_LCALL_REG (OP_ICONST) {
- tree->opcode = OP_LCALL_IMM;
- ((MonoCallInst*)tree)->fptr = state->left->tree->inst_c0;
tree->dreg = state->reg1;
+ tree->sreg1 = state->left->reg1;
+ tree->sreg2 = base->inst_basereg;
+ tree->inst_offset = base->inst_offset;
+ tree->opcode = OP_X86_SUB_MEMBASE;
mono_bblock_add_inst (s->cbb, tree);
+}
+
+reg: CEE_MUL(reg, CEE_LDIND_I4 (base)) {
+ MonoInst *base = state->right->left->tree;
+
+ tree->dreg = state->reg1;
+ tree->sreg1 = state->left->reg1;
+ tree->sreg2 = base->inst_basereg;
+ tree->inst_offset = base->inst_offset;
+ tree->opcode = OP_X86_MUL_MEMBASE;
+ mono_bblock_add_inst (s->cbb, tree);
+}
+
+lreg: OP_LSHL (lreg, reg) "0" {
+ MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
}
-# override the rules in inssel-float.brg that work for machines with FP registers
+lreg: OP_LSHL (lreg, OP_ICONST) "0" {
+ MONO_EMIT_BIALU_IMM (s, tree, OP_LSHL_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
-freg: OP_FCONV_TO_R8 (freg) "0" {
- /* nothing to do */
+lreg: OP_LSHR (lreg, reg) "0" {
+ MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
}
-freg: OP_FCONV_TO_R4 (freg) "0" {
- /* fixme: nothing to do ??*/
+lreg: OP_LSHR (lreg, OP_ICONST) "0" {
+ MONO_EMIT_BIALU_IMM (s, tree, OP_LSHR_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
}
+lreg: OP_LSHR_UN (lreg, reg) "0" {
+ MONO_EMIT_BIALU (s, tree, tree->opcode, state->reg1, state->left->reg1, state->right->reg1);
+}
+
+lreg: OP_LSHR_UN (lreg, OP_ICONST) "0" {
+ MONO_EMIT_BIALU_IMM (s, tree, OP_LSHR_UN_IMM, state->reg1, state->left->reg1, state->right->tree->inst_c0);
+}
%%