Author: zoltan
Date: 2006-06-10 09:26:58 -0400 (Sat, 10 Jun 2006)
New Revision: 61614
Modified:
trunk/mono/mono/mini/inssel-ia64.brg
trunk/mono/mono/mini/mini-ia64.c
Log:
2006-06-10 Zoltan Varga <[EMAIL PROTECTED]>
* mini-ia64.c inssel-ia64.brg: Implement the new net 2.0 Interlocked.Add
methods as instrinsics.
Modified: trunk/mono/mono/mini/inssel-ia64.brg
===================================================================
--- trunk/mono/mono/mini/inssel-ia64.brg 2006-06-10 13:25:10 UTC (rev
61613)
+++ trunk/mono/mono/mini/inssel-ia64.brg 2006-06-10 13:26:58 UTC (rev
61614)
@@ -304,10 +304,17 @@
tree->inst_offset = state->left->tree->inst_offset;
mono_bblock_add_inst (s->cbb, tree);
+} cost {
+ int imm = state->right->tree->inst_imm;
+
+ MBCOND (imm == 1 || imm == 4 || imm == 8 || imm == 16 || imm == -1 ||
imm == -4 || imm == -8 || imm == -16);
+ return 1;
}
reg: OP_ATOMIC_EXCHANGE_I4 (base, reg),
-reg: OP_ATOMIC_EXCHANGE_I8 (base, reg) {
+reg: OP_ATOMIC_EXCHANGE_I8 (base, reg),
+reg: OP_ATOMIC_ADD_NEW_I4 (base, reg),
+reg: OP_ATOMIC_ADD_NEW_I8 (base, reg) {
tree->opcode = tree->opcode;
tree->dreg = state->reg1;
tree->sreg2 = state->right->reg1;
Modified: trunk/mono/mono/mini/mini-ia64.c
===================================================================
--- trunk/mono/mono/mini/mini-ia64.c 2006-06-10 13:25:10 UTC (rev 61613)
+++ trunk/mono/mono/mini/mini-ia64.c 2006-06-10 13:26:58 UTC (rev 61614)
@@ -1627,6 +1627,8 @@
case OP_IA64_FETCHADD8_IMM:
case OP_ATOMIC_EXCHANGE_I4:
case OP_ATOMIC_EXCHANGE_I8:
+ case OP_ATOMIC_ADD_NEW_I4:
+ case OP_ATOMIC_ADD_NEW_I8:
/* There are no membase instructions on ia64 */
if (ia64_is_imm14 (ins->inst_offset)) {
NEW_INS (cfg, temp2, OP_ADD_IMM);
@@ -3091,7 +3093,47 @@
case OP_ATOMIC_EXCHANGE_I8:
ia64_xchg8_hint (code, ins->dreg, ins->inst_basereg,
ins->sreg2, 0);
break;
+ case OP_ATOMIC_ADD_NEW_I4: {
+ guint8 *label, *buf;
+ /* From libatomic_ops */
+ ia64_mf (code);
+
+ ia64_begin_bundle (code);
+ label = code.buf + code.nins;
+ ia64_ld4_acq (code, GP_SCRATCH_REG, ins->sreg1);
+ ia64_add (code, GP_SCRATCH_REG2, GP_SCRATCH_REG,
ins->sreg2);
+ ia64_mov_to_ar_m (code, IA64_CCV, GP_SCRATCH_REG);
+ ia64_cmpxchg4_acq_hint (code, GP_SCRATCH_REG2,
ins->sreg1, GP_SCRATCH_REG2, 0);
+ ia64_cmp4_eq (code, 6, 7, GP_SCRATCH_REG,
GP_SCRATCH_REG2);
+ buf = code.buf + code.nins;
+ ia64_br_cond_pred (code, 7, 0);
+ ia64_begin_bundle (code);
+ ia64_patch (buf, label);
+ ia64_add (code, ins->dreg, GP_SCRATCH_REG, ins->sreg2);
+ break;
+ }
+ case OP_ATOMIC_ADD_NEW_I8: {
+ guint8 *label, *buf;
+
+ /* From libatomic_ops */
+ ia64_mf (code);
+
+ ia64_begin_bundle (code);
+ label = code.buf + code.nins;
+ ia64_ld8_acq (code, GP_SCRATCH_REG, ins->sreg1);
+ ia64_add (code, GP_SCRATCH_REG2, GP_SCRATCH_REG,
ins->sreg2);
+ ia64_mov_to_ar_m (code, IA64_CCV, GP_SCRATCH_REG);
+ ia64_cmpxchg8_acq_hint (code, GP_SCRATCH_REG2,
ins->sreg1, GP_SCRATCH_REG2, 0);
+ ia64_cmp_eq (code, 6, 7, GP_SCRATCH_REG,
GP_SCRATCH_REG2);
+ buf = code.buf + code.nins;
+ ia64_br_cond_pred (code, 7, 0);
+ ia64_begin_bundle (code);
+ ia64_patch (buf, label);
+ ia64_add (code, ins->dreg, GP_SCRATCH_REG, ins->sreg2);
+ break;
+ }
+
/* Exception handling */
case OP_CALL_HANDLER:
/*
@@ -4774,6 +4816,20 @@
ins->inst_i0 = args [0];
ins->inst_i1 = args [1];
+ } else if (strcmp (cmethod->name, "Add") == 0) {
+ guint32 opcode;
+
+ if (fsig->params [0]->type == MONO_TYPE_I4)
+ opcode = OP_ATOMIC_ADD_NEW_I4;
+ else if (fsig->params [0]->type == MONO_TYPE_I8)
+ opcode = OP_ATOMIC_ADD_NEW_I8;
+ else
+ g_assert_not_reached ();
+
+ MONO_INST_NEW (cfg, ins, opcode);
+
+ ins->inst_i0 = args [0];
+ ins->inst_i1 = args [1];
} else if (strcmp (cmethod->name, "Read") == 0 && (fsig->params
[0]->type == MONO_TYPE_I8)) {
/* 64 bit reads are already atomic */
MONO_INST_NEW (cfg, ins, CEE_LDIND_I8);
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches