From 9f1ee39f63de5dcadff4a456e8b4e1b156e445b3 Mon Sep 17 00:00:00 2001 From: mprobst Date: Wed, 11 Mar 2009 14:15:49 +0000 Subject: [PATCH] Make sure x86 ATOMIC_CAS doesn't overwrite its own operands. 2009-03-11 Mark Probst * mini-x86.c (mono_arch_output_basic_block): Use different registers in case the ones we want to overwrite are used by the other operand. Fixes regression in #480807. git-svn-id: svn+ssh://mono-cvs.ximian.com/source/trunk/mono@129058 e3ebcda4-bce8-0310-ba0a-eca2169e7518 --- mono/mini/ChangeLog | 6 ++++++ mono/mini/mini-x86.c | 16 ++++++++-------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/mono/mini/ChangeLog b/mono/mini/ChangeLog index 47a944483..a800f0518 100644 --- a/mono/mini/ChangeLog +++ b/mono/mini/ChangeLog @@ -1,3 +1,9 @@ +2009-03-11 Mark Probst + + * mini-x86.c (mono_arch_output_basic_block): Use different + registers in case the ones we want to overwrite are used by the + other operand. Fixes regression in #480807. + 2009-03-10 Zoltan Varga * aot-compiler.c (mono_compile_assembly): Make the output less verbose. diff --git a/mono/mini/mini-x86.c b/mono/mini/mini-x86.c index 71e31116d..61e514738 100644 --- a/mono/mini/mini-x86.c +++ b/mono/mini/mini-x86.c @@ -3654,15 +3654,15 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) /* We need the EAX reg for the cmpxchg */ if (ins->sreg2 == X86_EAX) { - x86_push_reg (code, X86_EDX); - x86_mov_reg_reg (code, X86_EDX, X86_EAX, 4); - sreg2 = X86_EDX; + sreg2 = (breg == X86_EDX) ? X86_EBX : X86_EDX; + x86_push_reg (code, sreg2); + x86_mov_reg_reg (code, sreg2, X86_EAX, 4); } if (breg == X86_EAX) { - x86_push_reg (code, X86_ESI); - x86_mov_reg_reg (code, X86_ESI, X86_EAX, 4); - breg = X86_ESI; + breg = (sreg2 == X86_ESI) ? X86_EDI : X86_ESI; + x86_push_reg (code, breg); + x86_mov_reg_reg (code, breg, X86_EAX, 4); } if (ins->opcode == OP_ATOMIC_CAS_IMM_I4) { @@ -3680,10 +3680,10 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb) } if (breg != ins->inst_basereg) - x86_pop_reg (code, X86_ESI); + x86_pop_reg (code, breg); if (ins->sreg2 != sreg2) - x86_pop_reg (code, X86_EDX); + x86_pop_reg (code, sreg2); break; } -- 2.11.4.GIT