[ppc] Clean up atomic opcodes.
authorAlex Rønne Petersen <alexrp@xamarin.com>
Tue, 1 Jul 2014 01:01:55 +0000 (03:01 +0200)
committerAlex Rønne Petersen <alexrp@xamarin.com>
Tue, 1 Jul 2014 19:53:56 +0000 (21:53 +0200)
* Support atomic_add_i4 on ppc32 in addition to ppc64.
* Make the atomic_add_* code more in line with the atomic_cas_* code.

mono/mini/cpu-ppc.md
mono/mini/mini-ppc.c

index e8f83655fc85ed4841e679f7692f4014c141bed7..44a482aad1318791135dfa69c99f0fb5d5fb1070 100644 (file)
@@ -313,4 +313,5 @@ vcall2_membase: src1:b len:16 clob:c
 
 jump_table: dest:i len:8
 
+atomic_add_i4: src1:b src2:i dest:i len:20
 atomic_cas_i4: src1:b src2:i src3:i dest:i len:38
index 16f34d1c00d84845426ca22da6f591c288c77e8f..fb388bcad8eefaa1f029b38c8681f86cd158c64f 100644 (file)
@@ -4385,22 +4385,34 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                                ppc_mr (code, ins->dreg, ins->sreg1);
                        break;
                case OP_ATOMIC_ADD_I4:
-               case OP_ATOMIC_ADD_I8: {
-                       guint8 *loop = code, *branch;
+               CASE_PPC64 (OP_ATOMIC_ADD_I8) {
+                       int location = ins->inst_basereg;
+                       int addend = ins->sreg2;
+                       guint8 *loop, *branch;
                        g_assert (ins->inst_offset == 0);
+
+                       loop = code;
                        ppc_sync (code);
                        if (ins->opcode == OP_ATOMIC_ADD_I4)
-                               ppc_lwarx (code, ppc_r0, 0, ins->inst_basereg);
+                               ppc_lwarx (code, ppc_r0, 0, location);
+#ifdef __mono_ppc64__
                        else
-                               ppc_ldarx (code, ppc_r0, 0, ins->inst_basereg);
-                       ppc_add (code, ppc_r0, ppc_r0, ins->sreg2);
+                               ppc_ldarx (code, ppc_r0, 0, location);
+#endif
+
+                       ppc_add (code, ppc_r0, ppc_r0, addend);
+
                        if (ins->opcode == OP_ATOMIC_ADD_I4)
-                               ppc_stwcxd (code, ppc_r0, 0, ins->inst_basereg);
+                               ppc_stwcxd (code, ppc_r0, 0, location);
+#ifdef __mono_ppc64__
                        else
-                               ppc_stdcxd (code, ppc_r0, 0, ins->inst_basereg);
+                               ppc_stdcxd (code, ppc_r0, 0, location);
+#endif
+
                        branch = code;
                        ppc_bc (code, PPC_BR_FALSE, PPC_BR_EQ, 0);
                        ppc_patch (branch, loop);
+
                        ppc_sync (code);
                        ppc_mr (code, ins->dreg, ppc_r0);
                        break;
@@ -4435,10 +4447,11 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        else
                                ppc_ldarx (code, ppc_r0, 0, location);
 #endif
-                       ppc_cmp (code, 0, ins->opcode == OP_ATOMIC_CAS_I4 ? 0 : 1, ppc_r0, comparand);
 
+                       ppc_cmp (code, 0, ins->opcode == OP_ATOMIC_CAS_I4 ? 0 : 1, ppc_r0, comparand);
                        not_equal = code;
                        ppc_bc (code, PPC_BR_FALSE, PPC_BR_EQ, 0);
+
                        if (ins->opcode == OP_ATOMIC_CAS_I4)
                                ppc_stwcxd (code, value, 0, location);
 #ifdef __mono_ppc64__
@@ -4449,8 +4462,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        lost_reservation = code;
                        ppc_bc (code, PPC_BR_FALSE, PPC_BR_EQ, 0);
                        ppc_patch (lost_reservation, start);
-
                        ppc_patch (not_equal, code);
+
                        ppc_sync (code);
                        ppc_mr (code, ins->dreg, ppc_r0);
                        break;
@@ -5950,9 +5963,9 @@ gboolean
 mono_arch_opcode_supported (int opcode)
 {
        switch (opcode) {
+       case OP_ATOMIC_ADD_I4:
        case OP_ATOMIC_CAS_I4:
 #ifdef TARGET_POWERPC64
-       case OP_ATOMIC_ADD_I4: /* Yes, really - see cpu-ppc(64).md. */
        case OP_ATOMIC_ADD_I8:
        case OP_ATOMIC_CAS_I8:
 #endif