qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [RFC 21/38] target-i386: emulate atomic instructions +


From: Alex Bennée
Subject: Re: [Qemu-devel] [RFC 21/38] target-i386: emulate atomic instructions + barriers using AIE
Date: Thu, 17 Sep 2015 16:30:38 +0100

Emilio G. Cota <address@hidden> writes:

> Signed-off-by: Emilio G. Cota <address@hidden>
> ---
>  aie-helper.c              |   3 +-
>  linux-user/main.c         |   4 +-
>  target-i386/cpu.h         |   3 -
>  target-i386/excp_helper.c |   7 ++
>  target-i386/helper.h      |   6 +-
>  target-i386/mem_helper.c  |  39 +++------
>  target-i386/translate.c   | 217 
> ++++++++++++++++++++++++++++------------------
>  7 files changed, 162 insertions(+), 117 deletions(-)
>
> diff --git a/aie-helper.c b/aie-helper.c
> index 7521150..a3faf04 100644
> --- a/aie-helper.c
> +++ b/aie-helper.c
> @@ -82,7 +82,8 @@ void HELPER(aie_unlock__done)(CPUArchState *env)
>  
>  void HELPER(aie_ld_pre)(CPUArchState *env, target_ulong vaddr)
>  {
> -    if (likely(!env->aie_lock_enabled) || env->aie_locked) {
> +    assert(env->aie_lock_enabled);
> +    if (env->aie_locked) {
>          return;
>      }
>      aie_ld_lock_ret(env, vaddr, GETRA());
> diff --git a/linux-user/main.c b/linux-user/main.c
> index fd06ce9..98ebe19 100644
> --- a/linux-user/main.c
> +++ b/linux-user/main.c
> @@ -279,9 +279,9 @@ void cpu_loop(CPUX86State *env)
>      target_siginfo_t info;
>  
>      for(;;) {
> -        cpu_exec_start(cs);
> +        cs->running = true;
>          trapnr = cpu_x86_exec(cs);
> -        cpu_exec_end(cs);
> +        cs->running = false;

Hmm I could do with more in the commit message about why it is OK to
replace the cpu_exec_start/end() wrappers with a simple flag setting. 

ION the duplication in linux-user/main.c is terrifying but that's not
your fault ;-) 

>          switch(trapnr) {
>          case 0x80:
>              /* linux syscall from int $0x80 */
> diff --git a/target-i386/cpu.h b/target-i386/cpu.h
> index 3655ff3..ead2832 100644
> --- a/target-i386/cpu.h
> +++ b/target-i386/cpu.h
> @@ -1318,9 +1318,6 @@ static inline MemTxAttrs cpu_get_mem_attrs(CPUX86State 
> *env)
>  void cpu_set_mxcsr(CPUX86State *env, uint32_t val);
>  void cpu_set_fpuc(CPUX86State *env, uint16_t val);
>  
> -/* mem_helper.c */
> -void helper_lock_init(void);
> -
>  /* svm_helper.c */
>  void cpu_svm_check_intercept_param(CPUX86State *env1, uint32_t type,
>                                     uint64_t param);
> diff --git a/target-i386/excp_helper.c b/target-i386/excp_helper.c
> index 99fca84..141cab4 100644
> --- a/target-i386/excp_helper.c
> +++ b/target-i386/excp_helper.c
> @@ -96,6 +96,13 @@ static void QEMU_NORETURN raise_interrupt2(CPUX86State 
> *env, int intno,
>  {
>      CPUState *cs = CPU(x86_env_get_cpu(env));
>  
> +    if (unlikely(env->aie_locked)) {
> +        helper_aie_unlock__done(env);
> +    }
> +    if (unlikely(env->aie_lock_enabled)) {
> +        env->aie_lock_enabled = false;
> +    }
> +
>      if (!is_int) {
>          cpu_svm_check_intercept_param(env, SVM_EXIT_EXCP_BASE + intno,
>                                        error_code);
> diff --git a/target-i386/helper.h b/target-i386/helper.h
> index 74308f4..7d92140 100644
> --- a/target-i386/helper.h
> +++ b/target-i386/helper.h
> @@ -1,8 +1,8 @@
>  DEF_HELPER_FLAGS_4(cc_compute_all, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl, int)
>  DEF_HELPER_FLAGS_4(cc_compute_c, TCG_CALL_NO_RWG_SE, tl, tl, tl, tl, int)
>  
> -DEF_HELPER_0(lock, void)
> -DEF_HELPER_0(unlock, void)
> +DEF_HELPER_1(lock_enable, void, env)
> +DEF_HELPER_1(lock_disable, void, env)
>  DEF_HELPER_3(write_eflags, void, env, tl, i32)
>  DEF_HELPER_1(read_eflags, tl, env)
>  DEF_HELPER_2(divb_AL, void, env, tl)
> @@ -217,3 +217,5 @@ DEF_HELPER_3(rcrl, tl, env, tl, tl)
>  DEF_HELPER_3(rclq, tl, env, tl, tl)
>  DEF_HELPER_3(rcrq, tl, env, tl, tl)
>  #endif
> +
> +#include "qemu/aie-helper.h"
> diff --git a/target-i386/mem_helper.c b/target-i386/mem_helper.c
> index 8bf0da2..60abc8a 100644
> --- a/target-i386/mem_helper.c
> +++ b/target-i386/mem_helper.c
> @@ -21,38 +21,21 @@
>  #include "exec/helper-proto.h"
>  #include "exec/cpu_ldst.h"
>  
> -/* broken thread support */
> +#include "aie-helper.c"
>  
> -#if defined(CONFIG_USER_ONLY)
> -QemuMutex global_cpu_lock;
> -
> -void helper_lock(void)
> -{
> -    qemu_mutex_lock(&global_cpu_lock);
> -}
> -
> -void helper_unlock(void)
> -{
> -    qemu_mutex_unlock(&global_cpu_lock);
> -}
> -
> -void helper_lock_init(void)
> -{
> -    qemu_mutex_init(&global_cpu_lock);
> -}
> -#else
> -void helper_lock(void)
> +void helper_lock_enable(CPUX86State *env)
>  {
> +    env->aie_lock_enabled = true;
>  }
>  
> -void helper_unlock(void)
> -{
> -}
> -
> -void helper_lock_init(void)
> +void helper_lock_disable(CPUX86State *env)
>  {
> +    assert(env->aie_lock_enabled);
> +    if (env->aie_locked) {
> +        h_aie_unlock__done(env);
> +    }
> +    env->aie_lock_enabled = false;
>  }
> -#endif

I'm skipping over the rest of this as the locking of x86 is outside of
my area of expertise. However I'm currently erring in favour of Alvise'
TCG primitive approach over the heavy use of helpers. It will be
interesting to see a head to head in performance on some RISC backends. 

>  
>  void helper_cmpxchg8b(CPUX86State *env, target_ulong a0)
>  {
> @@ -60,6 +43,7 @@ void helper_cmpxchg8b(CPUX86State *env, target_ulong a0)
>      int eflags;
>  
>      eflags = cpu_cc_compute_all(env, CC_OP);
> +    aie_ld_lock_ret(env, a0, GETRA());
>      d = cpu_ldq_data(env, a0);
>      if (d == (((uint64_t)env->regs[R_EDX] << 32) | 
> (uint32_t)env->regs[R_EAX])) {
>          cpu_stq_data(env, a0, ((uint64_t)env->regs[R_ECX] << 32) | 
> (uint32_t)env->regs[R_EBX]);
> @@ -71,6 +55,7 @@ void helper_cmpxchg8b(CPUX86State *env, target_ulong a0)
>          env->regs[R_EAX] = (uint32_t)d;
>          eflags &= ~CC_Z;
>      }
> +    helper_aie_unlock__done(env);
>      CC_SRC = eflags;
>  }
>  
> @@ -84,6 +69,7 @@ void helper_cmpxchg16b(CPUX86State *env, target_ulong a0)
>          raise_exception(env, EXCP0D_GPF);
>      }
>      eflags = cpu_cc_compute_all(env, CC_OP);
> +    aie_ld_lock_ret(env, a0, GETRA());
>      d0 = cpu_ldq_data(env, a0);
>      d1 = cpu_ldq_data(env, a0 + 8);
>      if (d0 == env->regs[R_EAX] && d1 == env->regs[R_EDX]) {
> @@ -98,6 +84,7 @@ void helper_cmpxchg16b(CPUX86State *env, target_ulong a0)
>          env->regs[R_EAX] = d0;
>          eflags &= ~CC_Z;
>      }
> +    helper_aie_unlock__done(env);
>      CC_SRC = eflags;
>  }
>  #endif
> diff --git a/target-i386/translate.c b/target-i386/translate.c
> index 443bf60..4d6030f 100644
> --- a/target-i386/translate.c
> +++ b/target-i386/translate.c
> @@ -300,6 +300,48 @@ static inline bool byte_reg_is_xH(int reg)
>      return true;
>  }
>  
> +static inline void gen_i386_ld_i32(DisasContext *s, TCGv_i32 val, TCGv addr,
> +                                   TCGArg idx, TCGMemOp op)
> +{
> +    if (s->prefix & PREFIX_LOCK) {
> +        gen_helper_aie_ld_pre(cpu_env, addr);
> +    }
> +    tcg_gen_qemu_ld_i32(val, addr, idx, op);
> +}
> +
> +static inline void gen_i386_ld_i64(DisasContext *s, TCGv_i64 val, TCGv addr,
> +                                   TCGArg idx, TCGMemOp op)
> +{
> +    if (s->prefix & PREFIX_LOCK) {
> +        gen_helper_aie_ld_pre(cpu_env, addr);
> +    }
> +    tcg_gen_qemu_ld_i64(val, addr, idx, op);
> +}
> +
> +static inline
> +void gen_i386_st_i32(TCGv_i32 val, TCGv addr, TCGArg idx, TCGMemOp op)
> +{
> +    gen_helper_aie_st_pre(cpu_env, addr);
> +    tcg_gen_qemu_st_i32(val, addr, idx, op);
> +    gen_helper_aie_st_post(cpu_env, addr);
> +}
> +
> +static inline
> +void gen_i386_st_i64(TCGv_i64 val, TCGv addr, TCGArg idx, TCGMemOp op)
> +{
> +    gen_helper_aie_st_pre(cpu_env, addr);
> +    tcg_gen_qemu_st_i64(val, addr, idx, op);
> +    gen_helper_aie_st_post(cpu_env, addr);
> +}
> +
> +#if TARGET_LONG_BITS == 32
> +#define gen_i386_ld_tl  gen_i386_ld_i32
> +#define gen_i386_st_tl  gen_i386_st_i32
> +#else
> +#define gen_i386_ld_tl  gen_i386_ld_i64
> +#define gen_i386_st_tl  gen_i386_st_i64
> +#endif
> +
>  /* Select the size of a push/pop operation.  */
>  static inline TCGMemOp mo_pushpop(DisasContext *s, TCGMemOp ot)
>  {
> @@ -479,11 +521,23 @@ static inline void gen_op_addq_A0_reg_sN(int shift, int 
> reg)
>  
>  static inline void gen_op_ld_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
>  {
> +    gen_i386_ld_tl(s, t0, a0, s->mem_index, idx | MO_LE);
> +}
> +
> +static inline
> +void gen_op_ld_v_nolock(DisasContext *s, int idx, TCGv t0, TCGv a0)
> +{
>      tcg_gen_qemu_ld_tl(t0, a0, s->mem_index, idx | MO_LE);
>  }
>  
>  static inline void gen_op_st_v(DisasContext *s, int idx, TCGv t0, TCGv a0)
>  {
> +    gen_i386_st_tl(t0, a0, s->mem_index, idx | MO_LE);
> +}
> +
> +static inline
> +void gen_op_st_v_nolock(DisasContext *s, int idx, TCGv t0, TCGv a0)
> +{
>      tcg_gen_qemu_st_tl(t0, a0, s->mem_index, idx | MO_LE);
>  }
>  
> @@ -2587,23 +2641,23 @@ static void gen_jmp(DisasContext *s, target_ulong eip)
>  
>  static inline void gen_ldq_env_A0(DisasContext *s, int offset)
>  {
> -    tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
> +    gen_i386_ld_i64(s, cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
>      tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset);
>  }
>  
>  static inline void gen_stq_env_A0(DisasContext *s, int offset)
>  {
>      tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset);
> -    tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
> +    gen_i386_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
>  }
>  
>  static inline void gen_ldo_env_A0(DisasContext *s, int offset)
>  {
>      int mem_index = s->mem_index;
> -    tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, mem_index, MO_LEQ);
> +    gen_i386_ld_i64(s, cpu_tmp1_i64, cpu_A0, mem_index, MO_LEQ);
>      tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, 
> XMM_Q(0)));
>      tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
> -    tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_tmp0, mem_index, MO_LEQ);
> +    gen_i386_ld_i64(s, cpu_tmp1_i64, cpu_tmp0, mem_index, MO_LEQ);
>      tcg_gen_st_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, 
> XMM_Q(1)));
>  }
>  
> @@ -2611,10 +2665,10 @@ static inline void gen_sto_env_A0(DisasContext *s, 
> int offset)
>  {
>      int mem_index = s->mem_index;
>      tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, 
> XMM_Q(0)));
> -    tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, mem_index, MO_LEQ);
> +    gen_i386_st_i64(cpu_tmp1_i64, cpu_A0, mem_index, MO_LEQ);
>      tcg_gen_addi_tl(cpu_tmp0, cpu_A0, 8);
>      tcg_gen_ld_i64(cpu_tmp1_i64, cpu_env, offset + offsetof(XMMReg, 
> XMM_Q(1)));
> -    tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_tmp0, mem_index, MO_LEQ);
> +    gen_i386_st_i64(cpu_tmp1_i64, cpu_tmp0, mem_index, MO_LEQ);
>  }
>  
>  static inline void gen_op_movo(int d_offset, int s_offset)
> @@ -3643,14 +3697,14 @@ static void gen_sse(CPUX86State *env, DisasContext 
> *s, int b,
>                          break;
>                      case 0x21: case 0x31: /* pmovsxbd, pmovzxbd */
>                      case 0x24: case 0x34: /* pmovsxwq, pmovzxwq */
> -                        tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
> -                                            s->mem_index, MO_LEUL);
> +                        gen_i386_ld_i32(s, cpu_tmp2_i32, cpu_A0,
> +                                        s->mem_index, MO_LEUL);
>                          tcg_gen_st_i32(cpu_tmp2_i32, cpu_env, op2_offset +
>                                          offsetof(XMMReg, XMM_L(0)));
>                          break;
>                      case 0x22: case 0x32: /* pmovsxbq, pmovzxbq */
> -                        tcg_gen_qemu_ld_tl(cpu_tmp0, cpu_A0,
> -                                           s->mem_index, MO_LEUW);
> +                        gen_i386_ld_tl(s, cpu_tmp0, cpu_A0, s->mem_index,
> +                                       MO_LEUW);
>                          tcg_gen_st16_tl(cpu_tmp0, cpu_env, op2_offset +
>                                          offsetof(XMMReg, XMM_W(0)));
>                          break;
> @@ -3738,12 +3792,12 @@ static void gen_sse(CPUX86State *env, DisasContext 
> *s, int b,
>  
>                  gen_lea_modrm(env, s, modrm);
>                  if ((b & 1) == 0) {
> -                    tcg_gen_qemu_ld_tl(cpu_T[0], cpu_A0,
> -                                       s->mem_index, ot | MO_BE);
> +                    gen_i386_ld_tl(s, cpu_T[0], cpu_A0, s->mem_index,
> +                                   ot | MO_BE);
>                      gen_op_mov_reg_v(ot, reg, cpu_T[0]);
>                  } else {
> -                    tcg_gen_qemu_st_tl(cpu_regs[reg], cpu_A0,
> -                                       s->mem_index, ot | MO_BE);
> +                    gen_i386_st_tl(cpu_regs[reg], cpu_A0,
> +                                   s->mem_index, ot | MO_BE);
>                  }
>                  break;
>  
> @@ -4079,8 +4133,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, 
> int b,
>                      if (mod == 3) {
>                          gen_op_mov_reg_v(ot, rm, cpu_T[0]);
>                      } else {
> -                        tcg_gen_qemu_st_tl(cpu_T[0], cpu_A0,
> -                                           s->mem_index, MO_UB);
> +                        gen_i386_st_tl(cpu_T[0], cpu_A0, s->mem_index, 
> MO_UB);
>                      }
>                      break;
>                  case 0x15: /* pextrw */
> @@ -4089,8 +4142,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s, 
> int b,
>                      if (mod == 3) {
>                          gen_op_mov_reg_v(ot, rm, cpu_T[0]);
>                      } else {
> -                        tcg_gen_qemu_st_tl(cpu_T[0], cpu_A0,
> -                                           s->mem_index, MO_LEUW);
> +                        gen_i386_st_tl(cpu_T[0], cpu_A0, s->mem_index, 
> MO_LEUW);
>                      }
>                      break;
>                  case 0x16:
> @@ -4101,8 +4153,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s, 
> int b,
>                          if (mod == 3) {
>                              tcg_gen_extu_i32_tl(cpu_regs[rm], cpu_tmp2_i32);
>                          } else {
> -                            tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
> -                                                s->mem_index, MO_LEUL);
> +                            gen_i386_st_i32(cpu_tmp2_i32, cpu_A0,
> +                                            s->mem_index, MO_LEUL);
>                          }
>                      } else { /* pextrq */
>  #ifdef TARGET_X86_64
> @@ -4112,8 +4164,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s, 
> int b,
>                          if (mod == 3) {
>                              tcg_gen_mov_i64(cpu_regs[rm], cpu_tmp1_i64);
>                          } else {
> -                            tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
> -                                                s->mem_index, MO_LEQ);
> +                            gen_i386_st_i64(cpu_tmp1_i64, cpu_A0,
> +                                            s->mem_index, MO_LEQ);
>                          }
>  #else
>                          goto illegal_op;
> @@ -4126,16 +4178,15 @@ static void gen_sse(CPUX86State *env, DisasContext 
> *s, int b,
>                      if (mod == 3) {
>                          gen_op_mov_reg_v(ot, rm, cpu_T[0]);
>                      } else {
> -                        tcg_gen_qemu_st_tl(cpu_T[0], cpu_A0,
> -                                           s->mem_index, MO_LEUL);
> +                        gen_i386_st_tl(cpu_T[0], cpu_A0, s->mem_index, 
> MO_LEUL);
>                      }
>                      break;
>                  case 0x20: /* pinsrb */
>                      if (mod == 3) {
>                          gen_op_mov_v_reg(MO_32, cpu_T[0], rm);
>                      } else {
> -                        tcg_gen_qemu_ld_tl(cpu_T[0], cpu_A0,
> -                                           s->mem_index, MO_UB);
> +                        gen_i386_ld_tl(s, cpu_T[0], cpu_A0, s->mem_index,
> +                                       MO_UB);
>                      }
>                      tcg_gen_st8_tl(cpu_T[0], cpu_env, offsetof(CPUX86State,
>                                              xmm_regs[reg].XMM_B(val & 15)));
> @@ -4146,8 +4197,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s, 
> int b,
>                                          offsetof(CPUX86State,xmm_regs[rm]
>                                                  .XMM_L((val >> 6) & 3)));
>                      } else {
> -                        tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
> -                                            s->mem_index, MO_LEUL);
> +                        gen_i386_ld_i32(s, cpu_tmp2_i32, cpu_A0,
> +                                        s->mem_index, MO_LEUL);
>                      }
>                      tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
>                                      offsetof(CPUX86State,xmm_regs[reg]
> @@ -4174,8 +4225,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s, 
> int b,
>                          if (mod == 3) {
>                              tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_regs[rm]);
>                          } else {
> -                            tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
> -                                                s->mem_index, MO_LEUL);
> +                            gen_i386_ld_i32(s, cpu_tmp2_i32, cpu_A0,
> +                                            s->mem_index, MO_LEUL);
>                          }
>                          tcg_gen_st_i32(cpu_tmp2_i32, cpu_env,
>                                          offsetof(CPUX86State,
> @@ -4185,8 +4236,8 @@ static void gen_sse(CPUX86State *env, DisasContext *s, 
> int b,
>                          if (mod == 3) {
>                              gen_op_mov_v_reg(ot, cpu_tmp1_i64, rm);
>                          } else {
> -                            tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
> -                                                s->mem_index, MO_LEQ);
> +                            gen_i386_ld_i64(s, cpu_tmp1_i64, cpu_A0,
> +                                            s->mem_index, MO_LEQ);
>                          }
>                          tcg_gen_st_i64(cpu_tmp1_i64, cpu_env,
>                                          offsetof(CPUX86State,
> @@ -4567,7 +4618,7 @@ static target_ulong disas_insn(CPUX86State *env, 
> DisasContext *s,
>  
>      /* lock generation */
>      if (prefixes & PREFIX_LOCK)
> -        gen_helper_lock();
> +        gen_helper_lock_enable(cpu_env);
>  
>      /* now check op code */
>   reswitch:
> @@ -5567,13 +5618,15 @@ static target_ulong disas_insn(CPUX86State *env, 
> DisasContext *s,
>          } else {
>              gen_lea_modrm(env, s, modrm);
>              gen_op_mov_v_reg(ot, cpu_T[0], reg);
> -            /* for xchg, lock is implicit */
> -            if (!(prefixes & PREFIX_LOCK))
> -                gen_helper_lock();
> -            gen_op_ld_v(s, ot, cpu_T[1], cpu_A0);
> -            gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
> +            /*
> +             * For xchg, lock is implicit. We then unlock here if the prefix
> +             * was missing; otherwise we unlock later.
> +             */
> +            gen_helper_aie_ld_lock(cpu_env, cpu_A0);
> +            gen_op_ld_v_nolock(s, ot, cpu_T[1], cpu_A0);
> +            gen_op_st_v_nolock(s, ot, cpu_T[0], cpu_A0);
>              if (!(prefixes & PREFIX_LOCK))
> -                gen_helper_unlock();
> +                gen_helper_aie_unlock__done(cpu_env);
>              gen_op_mov_reg_v(ot, reg, cpu_T[1]);
>          }
>          break;
> @@ -5724,24 +5777,24 @@ static target_ulong disas_insn(CPUX86State *env, 
> DisasContext *s,
>  
>                      switch(op >> 4) {
>                      case 0:
> -                        tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
> -                                            s->mem_index, MO_LEUL);
> +                        gen_i386_ld_i32(s, cpu_tmp2_i32, cpu_A0,
> +                                        s->mem_index, MO_LEUL);
>                          gen_helper_flds_FT0(cpu_env, cpu_tmp2_i32);
>                          break;
>                      case 1:
> -                        tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
> -                                            s->mem_index, MO_LEUL);
> +                        gen_i386_ld_i32(s, cpu_tmp2_i32, cpu_A0,
> +                                        s->mem_index, MO_LEUL);
>                          gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
>                          break;
>                      case 2:
> -                        tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
> -                                            s->mem_index, MO_LEQ);
> +                        gen_i386_ld_i64(s, cpu_tmp1_i64, cpu_A0,
> +                                        s->mem_index, MO_LEQ);
>                          gen_helper_fldl_FT0(cpu_env, cpu_tmp1_i64);
>                          break;
>                      case 3:
>                      default:
> -                        tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
> -                                            s->mem_index, MO_LESW);
> +                        gen_i386_ld_i32(s, cpu_tmp2_i32, cpu_A0,
> +                                        s->mem_index, MO_LESW);
>                          gen_helper_fildl_FT0(cpu_env, cpu_tmp2_i32);
>                          break;
>                      }
> @@ -5763,24 +5816,24 @@ static target_ulong disas_insn(CPUX86State *env, 
> DisasContext *s,
>                  case 0:
>                      switch(op >> 4) {
>                      case 0:
> -                        tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
> -                                            s->mem_index, MO_LEUL);
> +                        gen_i386_ld_i32(s, cpu_tmp2_i32, cpu_A0,
> +                                        s->mem_index, MO_LEUL);
>                          gen_helper_flds_ST0(cpu_env, cpu_tmp2_i32);
>                          break;
>                      case 1:
> -                        tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
> -                                            s->mem_index, MO_LEUL);
> +                        gen_i386_ld_i32(s, cpu_tmp2_i32, cpu_A0,
> +                                        s->mem_index, MO_LEUL);
>                          gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
>                          break;
>                      case 2:
> -                        tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0,
> -                                            s->mem_index, MO_LEQ);
> +                        gen_i386_ld_i64(s, cpu_tmp1_i64, cpu_A0,
> +                                        s->mem_index, MO_LEQ);
>                          gen_helper_fldl_ST0(cpu_env, cpu_tmp1_i64);
>                          break;
>                      case 3:
>                      default:
> -                        tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
> -                                            s->mem_index, MO_LESW);
> +                        gen_i386_ld_i32(s, cpu_tmp2_i32, cpu_A0,
> +                                        s->mem_index, MO_LESW);
>                          gen_helper_fildl_ST0(cpu_env, cpu_tmp2_i32);
>                          break;
>                      }
> @@ -5790,19 +5843,19 @@ static target_ulong disas_insn(CPUX86State *env, 
> DisasContext *s,
>                      switch(op >> 4) {
>                      case 1:
>                          gen_helper_fisttl_ST0(cpu_tmp2_i32, cpu_env);
> -                        tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
> -                                            s->mem_index, MO_LEUL);
> +                        gen_i386_st_i32(cpu_tmp2_i32, cpu_A0,
> +                                        s->mem_index, MO_LEUL);
>                          break;
>                      case 2:
>                          gen_helper_fisttll_ST0(cpu_tmp1_i64, cpu_env);
> -                        tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
> -                                            s->mem_index, MO_LEQ);
> +                        gen_i386_st_i64(cpu_tmp1_i64, cpu_A0,
> +                                        s->mem_index, MO_LEQ);
>                          break;
>                      case 3:
>                      default:
>                          gen_helper_fistt_ST0(cpu_tmp2_i32, cpu_env);
> -                        tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
> -                                            s->mem_index, MO_LEUW);
> +                        gen_i386_st_i32(cpu_tmp2_i32, cpu_A0,
> +                                        s->mem_index, MO_LEUW);
>                          break;
>                      }
>                      gen_helper_fpop(cpu_env);
> @@ -5811,24 +5864,24 @@ static target_ulong disas_insn(CPUX86State *env, 
> DisasContext *s,
>                      switch(op >> 4) {
>                      case 0:
>                          gen_helper_fsts_ST0(cpu_tmp2_i32, cpu_env);
> -                        tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
> -                                            s->mem_index, MO_LEUL);
> +                        gen_i386_st_i32(cpu_tmp2_i32, cpu_A0,
> +                                        s->mem_index, MO_LEUL);
>                          break;
>                      case 1:
>                          gen_helper_fistl_ST0(cpu_tmp2_i32, cpu_env);
> -                        tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
> -                                            s->mem_index, MO_LEUL);
> +                        gen_i386_st_i32(cpu_tmp2_i32, cpu_A0,
> +                                        s->mem_index, MO_LEUL);
>                          break;
>                      case 2:
>                          gen_helper_fstl_ST0(cpu_tmp1_i64, cpu_env);
> -                        tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0,
> -                                            s->mem_index, MO_LEQ);
> +                        gen_i386_st_i64(cpu_tmp1_i64, cpu_A0,
> +                                        s->mem_index, MO_LEQ);
>                          break;
>                      case 3:
>                      default:
>                          gen_helper_fist_ST0(cpu_tmp2_i32, cpu_env);
> -                        tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
> -                                            s->mem_index, MO_LEUW);
> +                        gen_i386_st_i32(cpu_tmp2_i32, cpu_A0,
> +                                        s->mem_index, MO_LEUW);
>                          break;
>                      }
>                      if ((op & 7) == 3)
> @@ -5842,8 +5895,7 @@ static target_ulong disas_insn(CPUX86State *env, 
> DisasContext *s,
>                  gen_helper_fldenv(cpu_env, cpu_A0, tcg_const_i32(dflag - 1));
>                  break;
>              case 0x0d: /* fldcw mem */
> -                tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
> -                                    s->mem_index, MO_LEUW);
> +                gen_i386_ld_i32(s, cpu_tmp2_i32, cpu_A0, s->mem_index, 
> MO_LEUW);
>                  gen_helper_fldcw(cpu_env, cpu_tmp2_i32);
>                  break;
>              case 0x0e: /* fnstenv mem */
> @@ -5853,8 +5905,7 @@ static target_ulong disas_insn(CPUX86State *env, 
> DisasContext *s,
>                  break;
>              case 0x0f: /* fnstcw mem */
>                  gen_helper_fnstcw(cpu_tmp2_i32, cpu_env);
> -                tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
> -                                    s->mem_index, MO_LEUW);
> +                gen_i386_st_i32(cpu_tmp2_i32, cpu_A0, s->mem_index, MO_LEUW);
>                  break;
>              case 0x1d: /* fldt mem */
>                  gen_update_cc_op(s);
> @@ -5879,8 +5930,7 @@ static target_ulong disas_insn(CPUX86State *env, 
> DisasContext *s,
>                  break;
>              case 0x2f: /* fnstsw mem */
>                  gen_helper_fnstsw(cpu_tmp2_i32, cpu_env);
> -                tcg_gen_qemu_st_i32(cpu_tmp2_i32, cpu_A0,
> -                                    s->mem_index, MO_LEUW);
> +                gen_i386_st_i32(cpu_tmp2_i32, cpu_A0, s->mem_index, MO_LEUW);
>                  break;
>              case 0x3c: /* fbld */
>                  gen_update_cc_op(s);
> @@ -5894,12 +5944,12 @@ static target_ulong disas_insn(CPUX86State *env, 
> DisasContext *s,
>                  gen_helper_fpop(cpu_env);
>                  break;
>              case 0x3d: /* fildll */
> -                tcg_gen_qemu_ld_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, 
> MO_LEQ);
> +                gen_i386_ld_i64(s, cpu_tmp1_i64, cpu_A0, s->mem_index, 
> MO_LEQ);
>                  gen_helper_fildll_ST0(cpu_env, cpu_tmp1_i64);
>                  break;
>              case 0x3f: /* fistpll */
>                  gen_helper_fistll_ST0(cpu_tmp1_i64, cpu_env);
> -                tcg_gen_qemu_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, 
> MO_LEQ);
> +                gen_i386_st_i64(cpu_tmp1_i64, cpu_A0, s->mem_index, MO_LEQ);
>                  gen_helper_fpop(cpu_env);
>                  break;
>              default:
> @@ -7754,8 +7804,7 @@ static target_ulong disas_insn(CPUX86State *env, 
> DisasContext *s,
>                  goto illegal_op;
>              gen_lea_modrm(env, s, modrm);
>              if (op == 2) {
> -                tcg_gen_qemu_ld_i32(cpu_tmp2_i32, cpu_A0,
> -                                    s->mem_index, MO_LEUL);
> +                gen_i386_ld_i32(s, cpu_tmp2_i32, cpu_A0, s->mem_index, 
> MO_LEUL);
>                  gen_helper_ldmxcsr(cpu_env, cpu_tmp2_i32);
>              } else {
>                  tcg_gen_ld32u_tl(cpu_T[0], cpu_env, offsetof(CPUX86State, 
> mxcsr));
> @@ -7763,9 +7812,12 @@ static target_ulong disas_insn(CPUX86State *env, 
> DisasContext *s,
>              }
>              break;
>          case 5: /* lfence */
> +            tcg_gen_fence_load();
> +            break;
>          case 6: /* mfence */
>              if ((modrm & 0xc7) != 0xc0 || !(s->cpuid_features & CPUID_SSE2))
>                  goto illegal_op;
> +            tcg_gen_fence_full();
>              break;
>          case 7: /* sfence / clflush */
>              if ((modrm & 0xc7) == 0xc0) {
> @@ -7773,6 +7825,7 @@ static target_ulong disas_insn(CPUX86State *env, 
> DisasContext *s,
>                  /* XXX: also check for cpuid_ext2_features & CPUID_EXT2_EMMX 
> */
>                  if (!(s->cpuid_features & CPUID_SSE))
>                      goto illegal_op;
> +                tcg_gen_fence_store();
>              } else {
>                  /* clflush */
>                  if (!(s->cpuid_features & CPUID_CLFLUSH))
> @@ -7841,11 +7894,11 @@ static target_ulong disas_insn(CPUX86State *env, 
> DisasContext *s,
>      }
>      /* lock generation */
>      if (s->prefix & PREFIX_LOCK)
> -        gen_helper_unlock();
> +        gen_helper_lock_disable(cpu_env);
>      return s->pc;
>   illegal_op:
>      if (s->prefix & PREFIX_LOCK)
> -        gen_helper_unlock();
> +        gen_helper_lock_disable(cpu_env);
>      /* XXX: ensure that no lock was generated */
>      gen_exception(s, EXCP06_ILLOP, pc_start - s->cs_base);
>      return s->pc;
> @@ -7899,8 +7952,6 @@ void optimize_flags_init(void)
>                                           offsetof(CPUX86State, regs[i]),
>                                           reg_names[i]);
>      }
> -
> -    helper_lock_init();
>  }
>  
>  /* generate intermediate code in gen_opc_buf and gen_opparam_buf for

-- 
Alex Bennée



reply via email to

[Prev in Thread] Current Thread [Next in Thread]