[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 36/37] target/i386: move 3DNow completely out of gen_sse
From: |
Paolo Bonzini |
Subject: |
[PATCH 36/37] target/i386: move 3DNow completely out of gen_sse |
Date: |
Mon, 12 Sep 2022 01:04:16 +0200 |
Everything else has been converted to the new decoder, so separate the
part that survives.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
target/i386/tcg/translate.c | 104 +++++++++++++++++++++++-------------
1 file changed, 68 insertions(+), 36 deletions(-)
diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c
index f312663110..0783b1e7ee 100644
--- a/target/i386/tcg/translate.c
+++ b/target/i386/tcg/translate.c
@@ -2918,7 +2918,6 @@ static bool first = true; static unsigned long limit;
#define SSE_OPF_CMP (1 << 1) /* does not write for first operand */
#define SSE_OPF_BLENDV (1 << 2) /* blendv* instruction */
#define SSE_OPF_SPECIAL (1 << 3) /* magic */
-#define SSE_OPF_3DNOW (1 << 4) /* 3DNow! instruction */
#define SSE_OPF_MMX (1 << 5) /* MMX/integer/AVX2 instruction */
#define SSE_OPF_SCALAR (1 << 6) /* Has SSE scalar variants */
#define SSE_OPF_SHUF (1 << 9) /* pshufx/shufpx */
@@ -2952,13 +2951,9 @@ struct SSEOpHelper_table1 {
SSEFuncs fn[4];
};
-#define SSE_3DNOW { SSE_OPF_3DNOW }
#define SSE_SPECIAL { SSE_OPF_SPECIAL }
static const struct SSEOpHelper_table1 sse_op_table1[256] = {
- /* 3DNow! extensions */
- [0x0e] = SSE_SPECIAL, /* femms */
- [0x0f] = SSE_3DNOW, /* pf... (sse_op_table5) */
/* pure SSE operations */
[0x10] = SSE_SPECIAL, /* movups, movupd, movss, movsd */
[0x11] = SSE_SPECIAL, /* movups, movupd, movss, movsd */
@@ -3172,7 +3167,7 @@ static void gen_helper_pavgusb(TCGv_ptr env, TCGv_ptr
reg_a, TCGv_ptr reg_b)
gen_helper_pavgb_mmx(env, reg_a, reg_a, reg_b);
}
-static const SSEFunc_0_epp sse_op_table5[256] = {
+static const SSEFunc_0_epp op_3dnow[256] = {
[0x0c] = gen_helper_pi2fw,
[0x0d] = gen_helper_pi2fd,
[0x1c] = gen_helper_pf2iw,
@@ -3351,7 +3346,7 @@ static void gen_sse(CPUX86State *env, DisasContext *s,
int b,
b1 = 0;
sse_op_flags = sse_op_table1[b].flags;
sse_op_fn = sse_op_table1[b].fn[b1];
- if ((sse_op_flags & (SSE_OPF_SPECIAL | SSE_OPF_3DNOW)) == 0
+ if ((sse_op_flags & SSE_OPF_SPECIAL) == 0
&& !sse_op_fn.op1) {
goto unknown_op;
}
@@ -3365,11 +3360,6 @@ static void gen_sse(CPUX86State *env, DisasContext *s,
int b,
is_xmm = 1;
}
}
- if (sse_op_flags & SSE_OPF_3DNOW) {
- if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) {
- goto illegal_op;
- }
- }
/* simple MMX/SSE operation */
if (s->flags & HF_TS_MASK) {
gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
@@ -3385,15 +3375,6 @@ static void gen_sse(CPUX86State *env, DisasContext *s,
int b,
&& (b != 0x38 && b != 0x3a)) {
goto unknown_op;
}
- if (b == 0x0e) {
- if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) {
- /* If we were fully decoding this we might use illegal_op. */
- goto unknown_op;
- }
- /* femms */
- gen_helper_emms(cpu_env);
- return;
- }
if (b == 0x77) {
/* emms */
gen_helper_emms(cpu_env);
@@ -4536,18 +4517,6 @@ static void gen_sse(CPUX86State *env, DisasContext *s,
int b,
rm = (modrm & 7);
op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
}
- if (sse_op_flags & SSE_OPF_3DNOW) {
- /* 3DNow! data insns */
- val = x86_ldub_code(env, s);
- SSEFunc_0_epp op_3dnow = sse_op_table5[val];
- if (!op_3dnow) {
- goto unknown_op;
- }
- tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset);
- tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
- op_3dnow(cpu_env, s->ptr0, s->ptr1);
- return;
- }
}
@@ -4598,6 +4567,70 @@ static void gen_sse(CPUX86State *env, DisasContext *s,
int b,
}
}
+static void gen_3dnow(CPUX86State *env, DisasContext *s, int b,
+ target_ulong pc_start)
+{
+ int op1_offset, op2_offset, val;
+ int modrm, mod, rm, reg;
+ SSEFunc_0_epp fn;
+
+ /* simple MMX/SSE operation */
+ if (s->flags & HF_TS_MASK) {
+ gen_exception(s, EXCP07_PREX, pc_start - s->cs_base);
+ return;
+ }
+ if (s->flags & HF_EM_MASK) {
+ goto illegal_op;
+ return;
+ }
+ if (b == 0x10e) {
+ if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) {
+ /* If we were fully decoding this we might use illegal_op. */
+ goto unknown_op;
+ }
+ /* femms */
+ gen_helper_emms(cpu_env);
+ return;
+ }
+
+ if (!(s->cpuid_ext2_features & CPUID_EXT2_3DNOW)) {
+ goto illegal_op;
+ }
+
+ gen_helper_enter_mmx(cpu_env);
+
+ modrm = x86_ldub_code(env, s);
+ reg = ((modrm >> 3) & 7);
+ mod = (modrm >> 6) & 3;
+
+ op1_offset = offsetof(CPUX86State,fpregs[reg].mmx);
+ if (mod != 3) {
+ gen_lea_modrm(env, s, modrm);
+ op2_offset = offsetof(CPUX86State,mmx_t0);
+ gen_ldq_env_A0(s, op2_offset);
+ } else {
+ rm = (modrm & 7);
+ op2_offset = offsetof(CPUX86State,fpregs[rm].mmx);
+ }
+
+ val = x86_ldub_code(env, s);
+ fn = op_3dnow[val];
+ if (!fn) {
+ goto unknown_op;
+ }
+ tcg_gen_addi_ptr(s->ptr0, cpu_env, op1_offset);
+ tcg_gen_addi_ptr(s->ptr1, cpu_env, op2_offset);
+ fn(cpu_env, s->ptr0, s->ptr1);
+ return;
+
+illegal_op:
+ gen_illegal_opcode(s);
+ return;
+
+unknown_op:
+ gen_unknown_opcode(env, s);
+}
+
/* convert one instruction. s->base.is_jmp is set if the translation must
be stopped. Return the next pc value */
static target_ulong disas_insn(DisasContext *s, CPUState *cpu)
@@ -8505,9 +8538,8 @@ static target_ulong disas_insn(DisasContext *s, CPUState
*cpu)
set_cc_op(s, CC_OP_POPCNT);
break;
case 0x10e ... 0x10f:
- /* 3DNow! instructions, ignore prefixes */
- s->prefix &= ~(PREFIX_REPZ | PREFIX_REPNZ | PREFIX_DATA);
- /* fall through */
+ gen_3dnow(env, s, b, pc_start);
+ break;
case 0x110 ... 0x117:
case 0x128 ... 0x12f:
case 0x138 ... 0x13a:
--
2.37.2
- Re: [PATCH 31/37] target/i386: reimplement 0x0f 0x28-0x2f, add AVX, (continued)
- [PATCH 32/37] target/i386: implement XSAVE and XRSTOR of AVX registers, Paolo Bonzini, 2022/09/11
- [PATCH 33/37] target/i386: Enable AVX cpuid bits when using TCG, Paolo Bonzini, 2022/09/11
- [PATCH 36/37] target/i386: move 3DNow completely out of gen_sse,
Paolo Bonzini <=
- [PATCH 34/37] target/i386: implement VLDMXCSR/VSTMXCSR, Paolo Bonzini, 2022/09/11
- [PATCH 35/37] tests/tcg: extend SSE tests to AVX, Paolo Bonzini, 2022/09/11
- Re: [RFC PATCH 00/37] target/i386: new decoder + AVX implementation, Richard Henderson, 2022/09/13