/* 66 0F 3A 62 */ void BX_CPP_AttrRegparmN(1) BX_CPU_C::PCMPISTRM_VdqWdqIb(bxInstruction_c *i) { #if (BX_SUPPORT_SSE >= 5) || (BX_SUPPORT_SSE >= 4 && BX_SUPPORT_SSE_EXTENSION > 0) BX_CPU_THIS_PTR prepareSSE(); BxPackedXmmRegister op1 = BX_READ_XMM_REG(i->nnn()), op2, result; Bit8u imm8 = i->Ib(); /* op2 is a register or memory reference */ if (i->modC0()) { op2 = BX_READ_XMM_REG(i->rm()); } else { BX_CPU_CALL_METHODR(i->ResolveModrm, (i)); /* pointer, segment address pair */ readVirtualDQwordAligned(i->seg(), RMAddr(i), (Bit8u *) &op2); } // compare all pairs of Ai, Bj bx_bool BoolRes[16][16]; compare_strings(BoolRes, op1, op2, imm8); unsigned num_elements = (imm8 & 0x1) ? 8 : 16; unsigned len1 = find_eos(op1, imm8); unsigned len2 = find_eos(op2, imm8); Bit16u result2 = aggregate(BoolRes, len1, len2, imm8); // As defined by imm8[6], result2 is then either stored to the least // significant bits of XMM0 (zero extended to 128 bits) or expanded // into a byte/word-mask and then stored to XMM0 if (imm8 & 0x40) { if (num_elements == 8) { for (int index = 0; index < 8; index++) result.xmm16u(index) = (result2 & (1<<index)) ? 0xffff : 0; } else { // num_elements = 16 for (int index = 0; index < 16; index++) result.xmmubyte(index) = (result2 & (1<<index)) ? 0xff : 0; } } else { result.xmm64u(1) = 0; result.xmm64u(0) = (Bit64u) result2; } Bit32u flags = 0; if (result2 != 0) flags |= EFlagsCFMask; if (len1 < num_elements) flags |= EFlagsSFMask; if (len2 < num_elements) flags |= EFlagsZFMask; if (result2 & 0x1) flags |= EFlagsOFMask; setEFlagsOSZAPC(flags); BX_WRITE_XMM_REG(0, result); /* store result XMM0 */ #else BX_INFO(("PCMPISTRM_VdqWdqIb: required SSE4.2, use --enable-sse and --enable-sse-extension options")); UndefinedOpcode(i); #endif }
/* 66 0F 3A 63 */ void BX_CPP_AttrRegparmN(1) BX_CPU_C::PCMPISTRI_VdqWdqIb(bxInstruction_c *i) { #if (BX_SUPPORT_SSE >= 5) || (BX_SUPPORT_SSE >= 4 && BX_SUPPORT_SSE_EXTENSION > 0) BX_CPU_THIS_PTR prepareSSE(); BxPackedXmmRegister op1 = BX_READ_XMM_REG(i->nnn()), op2; Bit8u imm8 = i->Ib(); /* op2 is a register or memory reference */ if (i->modC0()) { op2 = BX_READ_XMM_REG(i->rm()); } else { BX_CPU_CALL_METHODR(i->ResolveModrm, (i)); /* pointer, segment address pair */ readVirtualDQwordAligned(i->seg(), RMAddr(i), (Bit8u *) &op2); } // compare all pairs of Ai, Bj bx_bool BoolRes[16][16]; compare_strings(BoolRes, op1, op2, imm8); unsigned num_elements = (imm8 & 0x1) ? 8 : 16; int index; unsigned len1 = find_eos(op1, imm8); unsigned len2 = find_eos(op2, imm8); Bit16u result2 = aggregate(BoolRes, len1, len2, imm8); // The index of the first (or last, according to imm8[6]) set bit of result2 // is returned to ECX. If no bits are set in IntRes2, ECX is set to 16 (8) if (imm8 & 0x40) { // The index returned to ECX is of the MSB in result2 for (index=num_elements-1; index>=0; index--) if (result2 & (1<<index)) break; if (index < 0) index = num_elements; } else { // The index returned to ECX is of the LSB in result2 for (index=0; index<(int)num_elements; index++) if (result2 & (1<<index)) break; } RCX = index; Bit32u flags = 0; if (result2 != 0) flags |= EFlagsCFMask; if (len1 < num_elements) flags |= EFlagsSFMask; if (len2 < num_elements) flags |= EFlagsZFMask; if (result2 & 0x1) flags |= EFlagsOFMask; setEFlagsOSZAPC(flags); #else BX_INFO(("PCMPISTRI_VdqWdqIb: required SSE4.2, use --enable-sse and --enable-sse-extension options")); UndefinedOpcode(i); #endif }
/* 66 0F 3A 60 */ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::PCMPESTRM_VdqWdqIbR(bxInstruction_c *i) { BxPackedXmmRegister op1 = BX_READ_XMM_REG(i->nnn()); BxPackedXmmRegister op2 = BX_READ_XMM_REG(i->rm()), result; Bit8u imm8 = i->Ib(); // compare all pairs of Ai, Bj Bit8u BoolRes[16][16]; compare_strings(BoolRes, op1, op2, imm8); unsigned len1, len2, num_elements = (imm8 & 0x1) ? 8 : 16; #if BX_SUPPORT_X86_64 if (i->os64L()) { len1 = find_eos64(RAX, imm8); len2 = find_eos64(RDX, imm8); } else #endif { len1 = find_eos32(EAX, imm8); len2 = find_eos32(EDX, imm8); } Bit16u result2 = aggregate(BoolRes, len1, len2, imm8); // As defined by imm8[6], result2 is then either stored to the least // significant bits of XMM0 (zero extended to 128 bits) or expanded // into a byte/word-mask and then stored to XMM0 if (imm8 & 0x40) { if (num_elements == 8) { for (int index = 0; index < 8; index++) result.xmm16u(index) = (result2 & (1<<index)) ? 0xffff : 0; } else { // num_elements = 16 for (int index = 0; index < 16; index++) result.xmmubyte(index) = (result2 & (1<<index)) ? 0xff : 0; } } else { result.xmm64u(1) = 0; result.xmm64u(0) = (Bit64u) result2; } Bit32u flags = 0; if (result2 != 0) flags |= EFlagsCFMask; if (len1 < num_elements) flags |= EFlagsSFMask; if (len2 < num_elements) flags |= EFlagsZFMask; if (result2 & 0x1) flags |= EFlagsOFMask; setEFlagsOSZAPC(flags); BX_WRITE_XMM_REGZ(0, result, i->getVL()); /* store result XMM0 */ BX_NEXT_INSTR(i); }
/* 66 0F 3A 61 */ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::PCMPESTRI_VdqWdqIbR(bxInstruction_c *i) { BxPackedXmmRegister op1 = BX_READ_XMM_REG(i->nnn()), op2 = BX_READ_XMM_REG(i->rm()); Bit8u imm8 = i->Ib(); // compare all pairs of Ai, Bj Bit8u BoolRes[16][16]; compare_strings(BoolRes, op1, op2, imm8); unsigned len1, len2, num_elements = (imm8 & 0x1) ? 8 : 16; int index; #if BX_SUPPORT_X86_64 if (i->os64L()) { len1 = find_eos64(RAX, imm8); len2 = find_eos64(RDX, imm8); } else #endif { len1 = find_eos32(EAX, imm8); len2 = find_eos32(EDX, imm8); } Bit16u result2 = aggregate(BoolRes, len1, len2, imm8); // The index of the first (or last, according to imm8[6]) set bit of result2 // is returned to ECX. If no bits are set in IntRes2, ECX is set to 16 (8) if (imm8 & 0x40) { // The index returned to ECX is of the MSB in result2 for (index=num_elements-1; index>=0; index--) if (result2 & (1<<index)) break; if (index < 0) index = num_elements; } else { // The index returned to ECX is of the LSB in result2 for (index=0; index<(int)num_elements; index++) if (result2 & (1<<index)) break; } RCX = index; Bit32u flags = 0; if (result2 != 0) flags |= EFlagsCFMask; if (len1 < num_elements) flags |= EFlagsSFMask; if (len2 < num_elements) flags |= EFlagsZFMask; if (result2 & 0x1) flags |= EFlagsOFMask; setEFlagsOSZAPC(flags); BX_NEXT_INSTR(i); }
/* VMOVSS: VEX.F3.0F 10 (VEX.W ignore) */ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::VMOVSS_VssHpsWssR(bxInstruction_c *i) { BxPackedXmmRegister op = BX_READ_XMM_REG(i->vvv()); op.xmm32u(0) = BX_READ_XMM_REG_LO_DWORD(i->rm()); BX_WRITE_XMM_REG_CLEAR_HIGH(i->nnn(), op); BX_NEXT_INSTR(i); }
/* Opcode: VEX.66.0F.3A 18 (VEX.W=0) */ BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::VINSERTF128_VdqHdqWdqIbR(bxInstruction_c *i) { BxPackedAvxRegister op1 = BX_READ_AVX_REG(i->vvv()); op1.avx128(i->Ib() & 1) = BX_READ_XMM_REG(i->rm()); BX_WRITE_AVX_REG(i->nnn(), op1); BX_NEXT_INSTR(i); }