2004-10-14 Joe Shaw <joeshaw@novell.com>
[mono.git] / mono / mini / inssel-x86.brg
index e750498ae7fbd73620f9286eceb0d9f95e6b8929..ad694bc889afaebf33e3b97156abcd47a6373498 100644 (file)
@@ -127,6 +127,17 @@ cflags: OP_COMPARE (CEE_LDIND_U4 (base), reg) {
        mono_bblock_add_inst (s->cbb, tree);
 }
 
+cflags: OP_COMPARE (CEE_LDIND_REF (base), CEE_LDIND_REF (OP_REGVAR)),
+cflags: OP_COMPARE (CEE_LDIND_I (base), CEE_LDIND_REF (OP_REGVAR)),
+cflags: OP_COMPARE (CEE_LDIND_I4 (base), CEE_LDIND_REF (OP_REGVAR)),
+cflags: OP_COMPARE (CEE_LDIND_U4 (base), CEE_LDIND_REF (OP_REGVAR)) {
+       tree->opcode = OP_X86_COMPARE_MEMBASE_REG;
+       tree->inst_basereg = state->left->left->tree->inst_basereg;
+       tree->inst_offset = state->left->left->tree->inst_offset;
+       tree->sreg2 = state->right->left->tree->dreg;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
 cflags: OP_COMPARE (CEE_LDIND_REF (base), OP_ICONST),
 cflags: OP_COMPARE (CEE_LDIND_I (base), OP_ICONST),
 cflags: OP_COMPARE (CEE_LDIND_I4 (base), OP_ICONST),
@@ -149,6 +160,17 @@ cflags: OP_COMPARE (reg, CEE_LDIND_U4 (base)) {
        mono_bblock_add_inst (s->cbb, tree);
 }
 
+cflags: OP_COMPARE (CEE_LDIND_REF (OP_REGVAR), CEE_LDIND_REF (base)),
+cflags: OP_COMPARE (CEE_LDIND_I (OP_REGVAR), CEE_LDIND_I (base)),
+cflags: OP_COMPARE (CEE_LDIND_I4 (OP_REGVAR), CEE_LDIND_I4 (base)),
+cflags: OP_COMPARE (CEE_LDIND_U4 (OP_REGVAR), CEE_LDIND_U4 (base)) {
+       tree->opcode = OP_X86_COMPARE_REG_MEMBASE;
+       tree->sreg2 = state->right->left->tree->inst_basereg;
+       tree->inst_offset = state->right->left->tree->inst_offset;
+       tree->sreg1 = state->left->left->tree->dreg;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
 cflags : OP_CEQ (OP_COMPARE (OP_CEQ (cflags), OP_ICONST)) {
        tree->opcode = OP_CNE;
        tree->dreg = state->reg1;
@@ -168,15 +190,6 @@ stmt: CEE_STIND_I1 (base, OP_CEQ (OP_COMPARE (OP_CEQ (cflags), OP_ICONST))) {
        return 1;
 }
 
-cflags: OP_COMPARE (CEE_LDIND_I1 (base), OP_ICONST),
-cflags: OP_COMPARE (CEE_LDIND_U1 (base), OP_ICONST) {
-       tree->opcode = OP_X86_COMPARE_MEMBASE8_IMM;
-       tree->inst_basereg = state->left->left->tree->inst_basereg;
-       tree->inst_offset = state->left->left->tree->inst_offset;
-       tree->inst_imm = state->right->tree->inst_c0;
-       mono_bblock_add_inst (s->cbb, tree);
-}
-
 stmt: CEE_STIND_I1 (base, OP_CEQ (cflags)) {
        tree->opcode = OP_X86_SETEQ_MEMBASE;
        tree->inst_offset = state->left->tree->inst_offset;
@@ -188,6 +201,7 @@ reg: OP_LOCALLOC (OP_ICONST) {
        if (tree->flags & MONO_INST_INIT) {
                /* microcoded in mini-x86.c */
                tree->sreg1 = mono_regstate_next_int (s->rs);
+               tree->dreg = state->reg1;
                MONO_EMIT_NEW_ICONST (s, tree->sreg1, state->left->tree->inst_c0);
                mono_bblock_add_inst (s->cbb, tree);
        } else {
@@ -198,32 +212,24 @@ reg: OP_LOCALLOC (OP_ICONST) {
 
 reg: OP_LOCALLOC (reg) {
        tree->sreg1 = state->left->tree->dreg;
+       tree->dreg = state->reg1;
        mono_bblock_add_inst (s->cbb, tree);
 }
 
 stmt: OP_SETRET (reg) {
-       tree->opcode = OP_MOVE;
-       tree->sreg1 = state->left->reg1;
-       tree->dreg = X86_EAX;
-       mono_bblock_add_inst (s->cbb, tree);
+       MONO_EMIT_UNALU (s, tree, OP_MOVE, X86_EAX, state->left->reg1);
 }
 
 stmt: OP_SETRET (lreg) {
        MONO_EMIT_NEW_UNALU (s, OP_MOVE, X86_EDX, state->left->reg2);
-       tree->opcode = OP_MOVE;
-       tree->sreg1 = state->left->reg1;
-       tree->dreg = X86_EAX;
-       mono_bblock_add_inst (s->cbb, tree);
+       MONO_EMIT_UNALU (s, tree, OP_MOVE, X86_EAX, state->left->reg1);
 }
 
 stmt: OP_SETRET (CEE_LDIND_REF (OP_REGVAR)),
 stmt: OP_SETRET (CEE_LDIND_I (OP_REGVAR)),
 stmt: OP_SETRET (CEE_LDIND_I4 (OP_REGVAR)),
 stmt: OP_SETRET (CEE_LDIND_U4 (OP_REGVAR)) {
-       tree->opcode = OP_MOVE;
-       tree->sreg1 = state->left->left->tree->dreg;
-       tree->dreg = X86_EAX;
-       mono_bblock_add_inst (s->cbb, tree);
+       MONO_EMIT_UNALU (s, tree, OP_MOVE, X86_EAX, state->left->left->tree->dreg);
 }
 
 stmt: OP_SETRET (freg) {
@@ -237,31 +243,20 @@ stmt: OP_SETRET (OP_ICONST) {
        mono_bblock_add_inst (s->cbb, tree);
 }
 
-stmt: OP_OUTARG (reg) {
-       tree->opcode = OP_X86_PUSH;
-       tree->sreg1 = state->left->reg1;
-       mono_bblock_add_inst (s->cbb, tree);
-}
-
-# we need to reduce this code duplication with some burg syntax extension
-stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)) {
-       tree->opcode = OP_X86_PUSH;
-       tree->sreg1 = state->left->left->tree->dreg;
-       mono_bblock_add_inst (s->cbb, tree);
-}
-
-stmt: OP_OUTARG (CEE_LDIND_I4 (OP_REGVAR)) {
-       tree->opcode = OP_X86_PUSH;
-       tree->sreg1 = state->left->left->tree->dreg;
-       mono_bblock_add_inst (s->cbb, tree);
+stmt: OP_SETRET (i8con) {
+       MONO_EMIT_NEW_ICONST (s, X86_EAX, state->left->tree->inst_ls_word);
+       MONO_EMIT_NEW_ICONST (s, X86_EDX, state->left->tree->inst_ms_word);
 }
 
-stmt: OP_OUTARG (CEE_LDIND_U4 (OP_REGVAR)) {
+stmt: OP_OUTARG (reg) {
        tree->opcode = OP_X86_PUSH;
-       tree->sreg1 = state->left->left->tree->dreg;
+       tree->sreg1 = state->left->reg1;
        mono_bblock_add_inst (s->cbb, tree);
 }
 
+stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)),
+stmt: OP_OUTARG (CEE_LDIND_I4 (OP_REGVAR)),
+stmt: OP_OUTARG (CEE_LDIND_U4 (OP_REGVAR)),
 stmt: OP_OUTARG (CEE_LDIND_I (OP_REGVAR)) {
        tree->opcode = OP_X86_PUSH;
        tree->sreg1 = state->left->left->tree->dreg;
@@ -295,27 +290,21 @@ stmt: OP_OUTARG (OP_ICONST) {
        mono_bblock_add_inst (s->cbb, tree);
 }
 
-stmt: OP_OUTARG (CEE_LDIND_I4 (base)) {
-       tree->opcode = OP_X86_PUSH_MEMBASE;
-       tree->inst_basereg = state->left->left->tree->inst_basereg;
-       tree->inst_offset = state->left->left->tree->inst_offset;
-       mono_bblock_add_inst (s->cbb, tree);
-}
-
-stmt: OP_OUTARG (CEE_LDIND_U4 (base)) {
-       tree->opcode = OP_X86_PUSH_MEMBASE;
-       tree->inst_basereg = state->left->left->tree->inst_basereg;
-       tree->inst_offset = state->left->left->tree->inst_offset;
-       mono_bblock_add_inst (s->cbb, tree);
-}
+stmt: OP_OUTARG (i8con) {
+       MonoInst *ins;
+       ins = mono_mempool_alloc0 (s->mempool, sizeof (MonoInst));
+       ins->opcode = OP_X86_PUSH_IMM;
+       ins->inst_imm = state->left->tree->inst_ms_word;
+       mono_bblock_add_inst (s->cbb, ins);
 
-stmt: OP_OUTARG (CEE_LDIND_I (base)) {
-       tree->opcode = OP_X86_PUSH_MEMBASE;
-       tree->inst_basereg = state->left->left->tree->inst_basereg;
-       tree->inst_offset = state->left->left->tree->inst_offset;
+       tree->opcode = OP_X86_PUSH_IMM;
+       tree->inst_imm = state->left->tree->inst_ls_word;
        mono_bblock_add_inst (s->cbb, tree);
 }
 
+stmt: OP_OUTARG (CEE_LDIND_I4 (base)),
+stmt: OP_OUTARG (CEE_LDIND_U4 (base)),
+stmt: OP_OUTARG (CEE_LDIND_I (base)),
 stmt: OP_OUTARG (CEE_LDIND_REF (base)) {
        tree->opcode = OP_X86_PUSH_MEMBASE;
        tree->inst_basereg = state->left->left->tree->inst_basereg;
@@ -323,12 +312,6 @@ stmt: OP_OUTARG (CEE_LDIND_REF (base)) {
        mono_bblock_add_inst (s->cbb, tree);
 }
 
-stmt: OP_OUTARG (CEE_LDIND_REF (OP_REGVAR)) {
-       tree->opcode = OP_X86_PUSH;
-       tree->sreg1 = state->left->left->tree->dreg;
-       mono_bblock_add_inst (s->cbb, tree);
-}
-
 stmt: OP_OUTARG (CEE_LDOBJ (reg)) {
        tree->opcode = OP_X86_PUSH;
        tree->sreg1 = state->left->reg1;
@@ -400,31 +383,16 @@ stmt: OP_OUTARG_VT (reg) {
        mono_bblock_add_inst (s->cbb, tree);
 }
 
-reg: OP_LDADDR (OP_REGOFFSET) "1" {
-       if (state->left->tree->inst_offset) {
-               tree->opcode = OP_X86_LEA_MEMBASE;
-               tree->sreg1 = state->left->tree->inst_basereg;
-               tree->inst_imm = state->left->tree->inst_offset;
-               tree->dreg = state->reg1;
-       } else {
-               tree->opcode = OP_MOVE;
-               tree->sreg1 = state->left->tree->inst_basereg;
-               tree->dreg = state->reg1;
-       }
-       mono_bblock_add_inst (s->cbb, tree);
-}
-
-reg: CEE_LDOBJ (OP_REGOFFSET) "1" {
+reg: OP_LDADDR (OP_REGOFFSET),
+reg: CEE_LDOBJ (OP_REGOFFSET) {
        if (state->left->tree->inst_offset) {
                tree->opcode = OP_X86_LEA_MEMBASE;
-               tree->sreg1 = state->left->tree->inst_basereg;
                tree->inst_imm = state->left->tree->inst_offset;
-               tree->dreg = state->reg1;
-       } else {
+       } else
                tree->opcode = OP_MOVE;
-               tree->sreg1 = state->left->tree->inst_basereg;
-               tree->dreg = state->reg1;
-       }
+       
+       tree->sreg1 = state->left->tree->inst_basereg;
+       tree->dreg = state->reg1;
        mono_bblock_add_inst (s->cbb, tree);
 }
 
@@ -564,6 +532,20 @@ reg: CEE_LDIND_I2 (OP_REGVAR) {
        MONO_EMIT_UNALU (s, tree, OP_SEXT_I2, state->reg1, state->left->tree->dreg);
 }
 
+# The XOR rule
+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) {
+       int r = state->left->tree->dreg;
+       MONO_EMIT_BIALU (s, tree, CEE_XOR, r, r, r);
+} cost {
+       MBCOND (!state->right->tree->inst_c0);
+       
+       return 0;
+}
+
 # on x86, fp compare overwrites EAX, so we must
 # either improve the local register allocator or
 # emit coarse opcodes which saves EAX for us.
@@ -717,4 +699,10 @@ lreg: OP_LSHR_UN (lreg, reg) "0" {
 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);
 }
+
+reg: OP_X86_TLS_GET {
+       tree->dreg = state->reg1;
+       mono_bblock_add_inst (s->cbb, tree);
+}
+
 %%