Commit 8eb8c738 authored by Emilio G. Cota's avatar Emilio G. Cota Committed by Richard Henderson
Browse files

target-i386: emulate LOCK'ed NEG using cmpxchg helper



[rth: Move redundant qemu_load out of cmpxchg loop.]

Signed-off-by: default avatarEmilio G. Cota <cota@braap.org>
Message-Id: <1467054136-10430-16-git-send-email-cota@braap.org>
Signed-off-by: default avatarRichard Henderson <rth@twiddle.net>
parent 2a5fe8ae
Loading
Loading
Loading
Loading
+34 −4
Original line number Diff line number Diff line
@@ -4712,12 +4712,42 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
            }
            break;
        case 3: /* neg */
            if (s->prefix & PREFIX_LOCK) {
                TCGLabel *label1;
                TCGv a0, t0, t1, t2;

                if (mod == 3) {
                    goto illegal_op;
                }
                a0 = tcg_temp_local_new();
                t0 = tcg_temp_local_new();
                label1 = gen_new_label();

                tcg_gen_mov_tl(a0, cpu_A0);
                tcg_gen_mov_tl(t0, cpu_T0);

                gen_set_label(label1);
                t1 = tcg_temp_new();
                t2 = tcg_temp_new();
                tcg_gen_mov_tl(t2, t0);
                tcg_gen_neg_tl(t1, t0);
                tcg_gen_atomic_cmpxchg_tl(t0, a0, t0, t1,
                                          s->mem_index, ot | MO_LE);
                tcg_temp_free(t1);
                tcg_gen_brcond_tl(TCG_COND_NE, t0, t2, label1);

                tcg_temp_free(t2);
                tcg_temp_free(a0);
                tcg_gen_mov_tl(cpu_T0, t0);
                tcg_temp_free(t0);
            } else {
                tcg_gen_neg_tl(cpu_T0, cpu_T0);
                if (mod != 3) {
                    gen_op_st_v(s, ot, cpu_T0, cpu_A0);
                } else {
                    gen_op_mov_reg_v(ot, rm, cpu_T0);
                }
            }
            gen_op_update_neg_cc();
            set_cc_op(s, CC_OP_SUBB + ot);
            break;