Re: [Xen-devel] [PATCH v3 10/25] x86emul: support 3DNow! insns
On 02/02/18 15:22, Jan Beulich wrote: On 02.02.18 at 14:02, wrote: >> On 07/12/17 14:05, Jan Beulich wrote: >>> --- a/xen/arch/x86/x86_emulate/x86_emulate.c >>> +++ b/xen/arch/x86/x86_emulate/x86_emulate.c >>> @@ -355,6 +355,36 @@ static const struct { >>> [0xff] = { ModRM } >>> }; >>> >>> +static const uint16_t _3dnow_table[16] = { >> Comment explaining how these mappings work? It looks like nibble >> splits, but I still can't work out how to crossreference with the opcode >> tables. > Will do. Array index is high opcode nibble, bit index is low opcode > nibble. > >>> +[0x0] = (1 << 0xd) /* pi2fd */, >>> +[0x1] = (1 << 0xd) /* pf2id */, >>> +[0x9] = (1 << 0x0) /* pfcmpge */ | >>> +(1 << 0x4) /* pfmin */ | >>> +(1 << 0x6) /* pfrcp */ | >>> +(1 << 0x7) /* pfrsqrt */ | >>> +(1 << 0xa) /* pfsub */ | >>> +(1 << 0xe) /* pfadd */, >>> +[0xa] = (1 << 0x0) /* pfcmpge */ | >>> +(1 << 0x4) /* pfmax */ | >>> +(1 << 0x6) /* pfrcpit1 */ | >>> +(1 << 0x7) /* pfrsqit1 */ | >>> +(1 << 0xa) /* pfsubr */ | >>> +(1 << 0xe) /* pfacc */, >>> +[0xb] = (1 << 0x0) /* pfcmpeq */ | >>> +(1 << 0x4) /* pfmul */ | >>> +(1 << 0x6) /* pfrcpit2 */ | >>> +(1 << 0x7) /* pmulhrw */ | >>> +(1 << 0xf) /* pavgusb */, >>> +}; >>> + >>> +static const uint16_t _3dnow_ext_table[16] = { >>> +[0x1] = (1 << 0xd) /* pi2fw */, >>> +[0x1] = (1 << 0xc) /* pf2iw */, >> You presumably want an | in here instead? > No, the first of the two lines is wrong and needs to be > > [0x0] = (1 << 0xc) /* pi2fw */, > > (wrong post-copy-and-paste editing). > >>> @@ -5505,6 +5537,26 @@ x86_emulate( >>> case X86EMUL_OPC(0x0f, 0x19) ... X86EMUL_OPC(0x0f, 0x1f): /* nop */ >>> break; >> 0f 0d prefetches? They are 3DNow instructions, but available on later >> processors. > And it is for that latter reason (I assume) that we have these > already. Ah. I see now that they are just out of context above this hunk. Sorry for the noise. ~Andrew ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v3 10/25] x86emul: support 3DNow! insns
>>> On 02.02.18 at 14:02, wrote: > On 07/12/17 14:05, Jan Beulich wrote: >> --- a/xen/arch/x86/x86_emulate/x86_emulate.c >> +++ b/xen/arch/x86/x86_emulate/x86_emulate.c >> @@ -355,6 +355,36 @@ static const struct { >> [0xff] = { ModRM } >> }; >> >> +static const uint16_t _3dnow_table[16] = { > > Comment explaining how these mappings work? It looks like nibble > splits, but I still can't work out how to crossreference with the opcode > tables. Will do. Array index is high opcode nibble, bit index is low opcode nibble. >> +[0x0] = (1 << 0xd) /* pi2fd */, >> +[0x1] = (1 << 0xd) /* pf2id */, >> +[0x9] = (1 << 0x0) /* pfcmpge */ | >> +(1 << 0x4) /* pfmin */ | >> +(1 << 0x6) /* pfrcp */ | >> +(1 << 0x7) /* pfrsqrt */ | >> +(1 << 0xa) /* pfsub */ | >> +(1 << 0xe) /* pfadd */, >> +[0xa] = (1 << 0x0) /* pfcmpge */ | >> +(1 << 0x4) /* pfmax */ | >> +(1 << 0x6) /* pfrcpit1 */ | >> +(1 << 0x7) /* pfrsqit1 */ | >> +(1 << 0xa) /* pfsubr */ | >> +(1 << 0xe) /* pfacc */, >> +[0xb] = (1 << 0x0) /* pfcmpeq */ | >> +(1 << 0x4) /* pfmul */ | >> +(1 << 0x6) /* pfrcpit2 */ | >> +(1 << 0x7) /* pmulhrw */ | >> +(1 << 0xf) /* pavgusb */, >> +}; >> + >> +static const uint16_t _3dnow_ext_table[16] = { >> +[0x1] = (1 << 0xd) /* pi2fw */, >> +[0x1] = (1 << 0xc) /* pf2iw */, > > You presumably want an | in here instead? No, the first of the two lines is wrong and needs to be [0x0] = (1 << 0xc) /* pi2fw */, (wrong post-copy-and-paste editing). >> @@ -5505,6 +5537,26 @@ x86_emulate( >> case X86EMUL_OPC(0x0f, 0x19) ... X86EMUL_OPC(0x0f, 0x1f): /* nop */ >> break; > > 0f 0d prefetches? They are 3DNow instructions, but available on later > processors. And it is for that latter reason (I assume) that we have these already. Jan ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v3 10/25] x86emul: support 3DNow! insns
On 07/12/17 14:05, Jan Beulich wrote: > --- a/xen/arch/x86/x86_emulate/x86_emulate.c > +++ b/xen/arch/x86/x86_emulate/x86_emulate.c > @@ -355,6 +355,36 @@ static const struct { > [0xff] = { ModRM } > }; > > +static const uint16_t _3dnow_table[16] = { Comment explaining how these mappings work? It looks like nibble splits, but I still can't work out how to crossreference with the opcode tables. > +[0x0] = (1 << 0xd) /* pi2fd */, > +[0x1] = (1 << 0xd) /* pf2id */, > +[0x9] = (1 << 0x0) /* pfcmpge */ | > +(1 << 0x4) /* pfmin */ | > +(1 << 0x6) /* pfrcp */ | > +(1 << 0x7) /* pfrsqrt */ | > +(1 << 0xa) /* pfsub */ | > +(1 << 0xe) /* pfadd */, > +[0xa] = (1 << 0x0) /* pfcmpge */ | > +(1 << 0x4) /* pfmax */ | > +(1 << 0x6) /* pfrcpit1 */ | > +(1 << 0x7) /* pfrsqit1 */ | > +(1 << 0xa) /* pfsubr */ | > +(1 << 0xe) /* pfacc */, > +[0xb] = (1 << 0x0) /* pfcmpeq */ | > +(1 << 0x4) /* pfmul */ | > +(1 << 0x6) /* pfrcpit2 */ | > +(1 << 0x7) /* pmulhrw */ | > +(1 << 0xf) /* pavgusb */, > +}; > + > +static const uint16_t _3dnow_ext_table[16] = { > +[0x1] = (1 << 0xd) /* pi2fw */, > +[0x1] = (1 << 0xc) /* pf2iw */, You presumably want an | in here instead? > +[0x8] = (1 << 0xa) /* pfnacc */ | > +(1 << 0xa) /* pfpnacc */, > +[0xb] = (1 << 0xb) /* pfswapd */, > +}; > + > /* > * "two_op" and "four_op" below refer to the number of register operands > * (one of which possibly also allowing to be a memory one). The named > @@ -1671,6 +1701,8 @@ static bool vcpu_has( > #define vcpu_has_rdrand() vcpu_has( 1, ECX, 30, ctxt, ops) > #define vcpu_has_mmxext() (vcpu_has(0x8001, EDX, 22, ctxt, ops) || \ > vcpu_has_sse()) > +#define vcpu_has_3dnow_ext() vcpu_has(0x8001, EDX, 30, ctxt, ops) > +#define vcpu_has_3dnow() vcpu_has(0x8001, EDX, 31, ctxt, ops) > #define vcpu_has_lahf_lm() vcpu_has(0x8001, ECX, 0, ctxt, ops) > #define vcpu_has_cr8_legacy() vcpu_has(0x8001, ECX, 4, ctxt, ops) > #define vcpu_has_lzcnt() vcpu_has(0x8001, ECX, 5, ctxt, ops) > @@ -5505,6 +5537,26 @@ x86_emulate( > case X86EMUL_OPC(0x0f, 0x19) ... X86EMUL_OPC(0x0f, 0x1f): /* nop */ > break; > 0f 0d prefetches? They are 3DNow instructions, but available on later processors. ~Andrew > +case X86EMUL_OPC(0x0f, 0x0e): /* femms */ > +host_and_vcpu_must_have(3dnow); > +asm volatile ( "femms" ); > +break; > + > +case X86EMUL_OPC(0x0f, 0x0f): /* 3DNow! */ > +if ( _3dnow_ext_table[(imm1 >> 4) & 0xf] & (1 << (imm1 & 0xf)) ) > +host_and_vcpu_must_have(3dnow_ext); > +else if ( _3dnow_table[(imm1 >> 4) & 0xf] & (1 << (imm1 & 0xf)) ) > +host_and_vcpu_must_have(3dnow); > +else > +generate_exception(EXC_UD); > + > +get_fpu(X86EMUL_FPU_mmx, &fic); > + > +d = DstReg | SrcMem; > +op_bytes = 8; > +state->simd_size = simd_other; > +goto simd_0f_imm8; > + > #define CASE_SIMD_PACKED_INT(pfx, opc) \ > case X86EMUL_OPC(pfx, opc): \ > case X86EMUL_OPC_66(pfx, opc) > --- a/xen/include/asm-x86/cpufeature.h > +++ b/xen/include/asm-x86/cpufeature.h > @@ -71,6 +71,8 @@ > && boot_cpu_has(X86_FEATURE_FFXSR)) > #define cpu_has_page1gb boot_cpu_has(X86_FEATURE_PAGE1GB) > #define cpu_has_rdtscp boot_cpu_has(X86_FEATURE_RDTSCP) > +#define cpu_has_3dnow_ext boot_cpu_has(X86_FEATURE_3DNOWEXT) > +#define cpu_has_3dnow boot_cpu_has(X86_FEATURE_3DNOW) > > /* CPUID level 0x8001.ecx */ > #define cpu_has_cmp_legacy boot_cpu_has(X86_FEATURE_CMP_LEGACY) > > ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel