2008-05-28 Zoltan Varga <vargaz@gmail.com>
authorZoltan Varga <vargaz@gmail.com>
Wed, 28 May 2008 11:11:38 +0000 (11:11 -0000)
committerZoltan Varga <vargaz@gmail.com>
Wed, 28 May 2008 11:11:38 +0000 (11:11 -0000)
* mini-x86.h mini-x86.c inssel-x86.brg cpu-x86.md: Add support for
CAS instrinsics. Optimize the implementation of the ATOMIC_EXCHANGE
opcodes.

svn path=/trunk/mono/; revision=104233

mono/mini/ChangeLog
mono/mini/cpu-x86.md
mono/mini/inssel-x86.brg
mono/mini/mini-x86.c
mono/mini/mini-x86.h

index d047279b536af4a24315508205201af82d04c6f0..828e32cbcfde84a9472cb52f9631e0ecb1faab53 100644 (file)
@@ -1,3 +1,9 @@
+2008-05-28  Zoltan Varga  <vargaz@gmail.com>
+
+       * mini-x86.h mini-x86.c inssel-x86.brg cpu-x86.md: Add support for
+       CAS instrinsics. Optimize the implementation of the ATOMIC_EXCHANGE 
+       opcodes.
+
 2008-05-27  Zoltan Varga  <vargaz@gmail.com>
 
        * mini.c (mini_get_inst_for_method): Add support for CAS instrinsics when
index 6dde0fa18e52d399c4815c0767dd0bb62964b322..fc1aaaccfd81be471856c7bc9e80179e10f14442 100644 (file)
@@ -302,6 +302,7 @@ sext_i2: dest:i src1:y len:3
 tls_get: dest:i len:20
 atomic_add_i4: src1:b src2:i dest:i len:16
 atomic_add_new_i4: src1:b src2:i dest:i len:16
-atomic_exchange_i4: src1:b src2:i dest:i len:24
+atomic_exchange_i4: src1:b src2:i dest:a len:24
+atomic_cas_imm_i4: src1:b src2:i dest:a len:24
 memory_barrier: len:16
 
index 15e12f728febda7f8f39dfd122a84d175ef8a683..e7070a1763cf4ec612f02fc95095a9aafa1f8ad1 100644 (file)
@@ -721,22 +721,14 @@ lreg: OP_LSHR_UN (lreg, OP_ICONST) "0" {
 }
 
 reg: OP_ATOMIC_ADD_NEW_I4 (base, reg),
-reg: OP_ATOMIC_ADD_I4 (base, reg) {
+reg: OP_ATOMIC_ADD_I4 (base, reg),
+reg: OP_ATOMIC_EXCHANGE_I4 (base, reg),
+reg: OP_ATOMIC_CAS_IMM_I4 (base, reg) {
        tree->opcode = tree->opcode;
-       tree->inst_basereg = state->left->tree->inst_basereg; 
-       tree->inst_offset = state->left->tree->inst_offset; 
        tree->dreg = state->reg1;
        tree->sreg2 = state->right->reg1;
-    
-       mono_bblock_add_inst (s->cbb, tree);
-}
-
-reg: OP_ATOMIC_EXCHANGE_I4 (base, reg) {
-    tree->opcode = OP_ATOMIC_EXCHANGE_I4;
-    tree->dreg = state->reg1;
-    tree->sreg2 = state->right->reg1;
-    tree->inst_basereg = state->left->tree->inst_basereg; 
-    tree->inst_offset = state->left->tree->inst_offset; 
+       tree->inst_basereg = state->left->tree->inst_basereg; 
+       tree->inst_offset = state->left->tree->inst_offset; 
     
        mono_bblock_add_inst (s->cbb, tree);
 }
index b2c1eb58ef85ec39358938a96b579fc4e65a4825..fc390b83a683a6cdf2d5e78053f6bf07c2454cb2 100644 (file)
@@ -3346,7 +3346,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
 
                        break;
                }
-               case OP_ATOMIC_EXCHANGE_I4: {
+               case OP_ATOMIC_EXCHANGE_I4:
+               case OP_ATOMIC_CAS_IMM_I4: {
                        guchar *br[2];
                        int sreg2 = ins->sreg2;
                        int breg = ins->inst_basereg;
@@ -3355,8 +3356,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                         * hack to overcome limits in x86 reg allocator 
                         * (req: dreg == eax and sreg2 != eax and breg != eax) 
                         */
-                       if (ins->dreg != X86_EAX)
-                               x86_push_reg (code, X86_EAX);
+                       g_assert (ins->dreg == X86_EAX);
                        
                        /* We need the EAX reg for the cmpxchg */
                        if (ins->sreg2 == X86_EAX) {
@@ -3371,21 +3371,23 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                                breg = X86_ESI;
                        }
 
-                       x86_mov_reg_membase (code, X86_EAX, breg, ins->inst_offset, 4);
+                       if (ins->opcode == OP_ATOMIC_CAS_IMM_I4) {
+                               x86_mov_reg_imm (code, X86_EAX, ins->backend.data);
 
-                       br [0] = code; x86_prefix (code, X86_LOCK_PREFIX);
-                       x86_cmpxchg_membase_reg (code, breg, ins->inst_offset, sreg2);
-                       br [1] = code; x86_branch8 (code, X86_CC_NE, -1, FALSE);
-                       x86_patch (br [1], br [0]);
+                               x86_prefix (code, X86_LOCK_PREFIX);
+                               x86_cmpxchg_membase_reg (code, breg, ins->inst_offset, sreg2);
+                       } else {
+                               x86_mov_reg_membase (code, X86_EAX, breg, ins->inst_offset, 4);
+
+                               br [0] = code; x86_prefix (code, X86_LOCK_PREFIX);
+                               x86_cmpxchg_membase_reg (code, breg, ins->inst_offset, sreg2);
+                               br [1] = code; x86_branch8 (code, X86_CC_NE, -1, FALSE);
+                               x86_patch (br [1], br [0]);
+                       }
 
                        if (breg != ins->inst_basereg)
                                x86_pop_reg (code, X86_ESI);
 
-                       if (ins->dreg != X86_EAX) {
-                               x86_mov_reg_reg (code, ins->dreg, X86_EAX, 4);
-                               x86_pop_reg (code, X86_EAX);
-                       }
-
                        if (ins->sreg2 != sreg2)
                                x86_pop_reg (code, X86_EDX);
 
index 97109d61c2873adf4aaae2618bf01b7d89d6d1e5..9d0812ec5dacab592dfa34255d35c455b8576f3e 100644 (file)
@@ -272,6 +272,7 @@ typedef struct {
 #define MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE 1
 #define MONO_ARCH_HAVE_ATOMIC_ADD 1
 #define MONO_ARCH_HAVE_ATOMIC_EXCHANGE 1
+#define MONO_ARCH_HAVE_ATOMIC_CAS_IMM 1
 #define MONO_ARCH_HAVE_IMT 1
 #define MONO_ARCH_HAVE_TLS_GET 1
 #define MONO_ARCH_IMT_REG X86_EDX