[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC 21/38] target-i386: emulate atomic instructions + barr
From: |
Emilio G. Cota |
Subject: |
[Qemu-devel] [RFC 21/38] target-i386: emulate atomic instructions + barriers using AIE |
Date: |
Sun, 23 Aug 2015 20:23:50 -0400 |
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;
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
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
--
1.9.1
- Re: [Qemu-devel] [RFC 22/38] cpu: update interrupt_request atomically, (continued)
[Qemu-devel] [RFC 31/38] cpu: protect l1_map with tb_lock in full-system mode, Emilio G. Cota, 2015/08/23
[Qemu-devel] [RFC 27/38] cpu-exec: convert tb_invalidated_flag into a per-TB flag, Emilio G. Cota, 2015/08/23
[Qemu-devel] [RFC 33/38] cpu: introduce cpu_tcg_sched_work to run work while other CPUs sleep, Emilio G. Cota, 2015/08/23
[Qemu-devel] [RFC 21/38] target-i386: emulate atomic instructions + barriers using AIE,
Emilio G. Cota <=
[Qemu-devel] [RFC 38/38] Revert "target-i386: yield to another VCPU on PAUSE", Emilio G. Cota, 2015/08/23
[Qemu-devel] [RFC 37/38] cpus: remove async_run_safe_work_on_cpu, Emilio G. Cota, 2015/08/23
[Qemu-devel] [RFC 32/38] cpu list: convert to RCU QLIST, Emilio G. Cota, 2015/08/23
[Qemu-devel] [RFC 28/38] cpu-exec: use RCU to perform lockless TB lookups, Emilio G. Cota, 2015/08/23
Re: [Qemu-devel] [RFC 00/38] MTTCG: i386, user+system mode, Paolo Bonzini, 2015/08/24
Re: [Qemu-devel] [RFC 00/38] MTTCG: i386, user+system mode, Artyom Tarasenko, 2015/08/24