ac06ee46ae
Now only missed AVX-512 opcodes now are: 512.66.0F38.W0 13 VCVTPH2PS 512.66.0F3A.W0 1D VCVTPS2PH 512.66.0F38.W0 2C VSCALEFPS 512.66.0F38.W1 2C VSCALEFPD NDS.LIG.66.0F38.W0 2D VSCALESS NDS.LIG.66.0F38.W1 2D VSCALESD 512.66.0F38.W0 4C VRCP14PS 512.66.0F38.W1 4C VRCP14PD NDS.LIG.66.0F38.W0 4D VRCP14SS NDS.LIG.66.0F38.W1 4D VRCP14SD 512.66.0F38.W0 4E VRSQRT14PS 512.66.0F38.W1 4E VRSQRT14PD NDS.LIG.66.0F38.W0 4F VRSQRT14SS NDS.LIG.66.0F38.W1 4F VRSQRT14SD 512.66.0F3A.W0 08 VRNDSCALEPS 512.66.0F3A.W1 09 VRNDSCALEPD NDS.LIG.66.0F3A.W1 0A VRNDSCALESS NDS.LIG.66.0F3A.W1 0B VRNDSCALESD 512.66.0F3A.W0 26 VGETMANTPS 512.66.0F3A.W1 26 VGETMANTPD NDS.LIG.66.0F3A.W0 27 VGETMANTSS NDS.LIG.66.0F3A.W1 27 VGETMANTSD
320 lines
9.6 KiB
C++
320 lines
9.6 KiB
C++
/////////////////////////////////////////////////////////////////////////
|
|
// $Id$
|
|
/////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (c) 2008-2014 Stanislav Shwartsman
|
|
// Written by Stanislav Shwartsman [sshwarts at sourceforge net]
|
|
//
|
|
// This library is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
// License as published by the Free Software Foundation; either
|
|
// version 2 of the License, or (at your option) any later version.
|
|
//
|
|
// This library is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
// Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
// License along with this library; if not, write to the Free Software
|
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA B 02110-1301 USA
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
#define NEED_CPU_REG_SHORTCUTS 1
|
|
#include "bochs.h"
|
|
#include "cpu.h"
|
|
#define LOG_THIS BX_CPU_THIS_PTR
|
|
|
|
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Eb(bxInstruction_c *i)
|
|
{
|
|
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
|
TMP8L = read_virtual_byte(i->seg(), eaddr);
|
|
BX_CPU_CALL_METHOD(i->execute2(), (i));
|
|
}
|
|
|
|
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Ew(bxInstruction_c *i)
|
|
{
|
|
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
|
TMP16 = read_virtual_word(i->seg(), eaddr);
|
|
BX_CPU_CALL_METHOD(i->execute2(), (i));
|
|
}
|
|
|
|
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Ed(bxInstruction_c *i)
|
|
{
|
|
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
|
TMP32 = read_virtual_dword(i->seg(), eaddr);
|
|
BX_CPU_CALL_METHOD(i->execute2(), (i));
|
|
}
|
|
|
|
#if BX_SUPPORT_X86_64
|
|
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Eq(bxInstruction_c *i)
|
|
{
|
|
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
|
TMP64 = read_virtual_qword_64(i->seg(), eaddr);
|
|
BX_CPU_CALL_METHOD(i->execute2(), (i));
|
|
}
|
|
#endif
|
|
|
|
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Wb(bxInstruction_c *i)
|
|
{
|
|
#if BX_CPU_LEVEL >= 6
|
|
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
|
Bit8u val_8 = read_virtual_byte(i->seg(), eaddr);
|
|
BX_WRITE_XMM_REG_LO_BYTE(BX_VECTOR_TMP_REGISTER, val_8);
|
|
|
|
BX_CPU_CALL_METHOD(i->execute2(), (i));
|
|
#endif
|
|
}
|
|
|
|
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Ww(bxInstruction_c *i)
|
|
{
|
|
#if BX_CPU_LEVEL >= 6
|
|
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
|
Bit16u val_16 = read_virtual_word(i->seg(), eaddr);
|
|
BX_WRITE_XMM_REG_LO_WORD(BX_VECTOR_TMP_REGISTER, val_16);
|
|
|
|
BX_CPU_CALL_METHOD(i->execute2(), (i));
|
|
#endif
|
|
}
|
|
|
|
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Wss(bxInstruction_c *i)
|
|
{
|
|
#if BX_CPU_LEVEL >= 6
|
|
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
|
Bit32u val_32 = read_virtual_dword(i->seg(), eaddr);
|
|
BX_WRITE_XMM_REG_LO_DWORD(BX_VECTOR_TMP_REGISTER, val_32);
|
|
|
|
BX_CPU_CALL_METHOD(i->execute2(), (i));
|
|
#endif
|
|
}
|
|
|
|
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Wsd(bxInstruction_c *i)
|
|
{
|
|
#if BX_CPU_LEVEL >= 6
|
|
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
|
Bit64u val_64 = read_virtual_qword(i->seg(), eaddr);
|
|
BX_WRITE_XMM_REG_LO_QWORD(BX_VECTOR_TMP_REGISTER, val_64);
|
|
|
|
BX_CPU_CALL_METHOD(i->execute2(), (i));
|
|
#endif
|
|
}
|
|
|
|
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Wdq(bxInstruction_c *i)
|
|
{
|
|
#if BX_CPU_LEVEL >= 6
|
|
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
|
|
|
if (BX_CPU_THIS_PTR mxcsr.get_MM())
|
|
read_virtual_xmmword(i->seg(), eaddr, &BX_READ_XMM_REG(BX_TMP_REGISTER));
|
|
else
|
|
read_virtual_xmmword_aligned(i->seg(), eaddr, &BX_READ_XMM_REG(BX_VECTOR_TMP_REGISTER));
|
|
|
|
BX_CPU_CALL_METHOD(i->execute2(), (i));
|
|
#endif
|
|
}
|
|
|
|
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LOADU_Wdq(bxInstruction_c *i)
|
|
{
|
|
#if BX_CPU_LEVEL >= 6
|
|
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
|
read_virtual_xmmword(i->seg(), eaddr, &BX_READ_XMM_REG(BX_VECTOR_TMP_REGISTER));
|
|
|
|
BX_CPU_CALL_METHOD(i->execute2(), (i));
|
|
#endif
|
|
}
|
|
|
|
#if BX_SUPPORT_AVX
|
|
|
|
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Vector(bxInstruction_c *i)
|
|
{
|
|
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
|
unsigned vl = i->getVL();
|
|
|
|
#if BX_SUPPORT_EVEX
|
|
if (vl == BX_VL512) {
|
|
read_virtual_zmmword(i->seg(), eaddr, &BX_READ_AVX_REG(BX_VECTOR_TMP_REGISTER));
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
if (vl == BX_VL256)
|
|
read_virtual_ymmword(i->seg(), eaddr, &BX_READ_YMM_REG(BX_VECTOR_TMP_REGISTER));
|
|
else
|
|
read_virtual_xmmword(i->seg(), eaddr, &BX_READ_XMM_REG(BX_VECTOR_TMP_REGISTER));
|
|
}
|
|
|
|
BX_CPU_CALL_METHOD(i->execute2(), (i));
|
|
}
|
|
|
|
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Half_Vector(bxInstruction_c *i)
|
|
{
|
|
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
|
unsigned vl = i->getVL();
|
|
|
|
#if BX_SUPPORT_EVEX
|
|
if (vl == BX_VL512) {
|
|
read_virtual_ymmword(i->seg(), eaddr, &BX_READ_YMM_REG(BX_VECTOR_TMP_REGISTER));
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
if (vl == BX_VL256) {
|
|
read_virtual_xmmword(i->seg(), eaddr, &BX_READ_XMM_REG(BX_VECTOR_TMP_REGISTER));
|
|
}
|
|
else {
|
|
Bit64u val_64 = read_virtual_qword(i->seg(), eaddr);
|
|
BX_WRITE_XMM_REG_LO_QWORD(BX_VECTOR_TMP_REGISTER, val_64);
|
|
}
|
|
}
|
|
|
|
BX_CPU_CALL_METHOD(i->execute2(), (i));
|
|
}
|
|
|
|
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Quarter_Vector(bxInstruction_c *i)
|
|
{
|
|
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
|
unsigned vl = i->getVL();
|
|
|
|
#if BX_SUPPORT_EVEX
|
|
if (vl == BX_VL512) {
|
|
read_virtual_xmmword(i->seg(), eaddr, &BX_READ_XMM_REG(BX_VECTOR_TMP_REGISTER));
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
if (vl == BX_VL256) {
|
|
Bit64u val_64 = read_virtual_qword(i->seg(), eaddr);
|
|
BX_WRITE_XMM_REG_LO_QWORD(BX_VECTOR_TMP_REGISTER, val_64);
|
|
}
|
|
else {
|
|
Bit32u val_32 = read_virtual_dword(i->seg(), eaddr);
|
|
BX_WRITE_XMM_REG_LO_DWORD(BX_VECTOR_TMP_REGISTER, val_32);
|
|
}
|
|
}
|
|
|
|
BX_CPU_CALL_METHOD(i->execute2(), (i));
|
|
}
|
|
|
|
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_Oct_Vector(bxInstruction_c *i)
|
|
{
|
|
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
|
unsigned vl = i->getVL();
|
|
|
|
#if BX_SUPPORT_EVEX
|
|
if (vl == BX_VL512) {
|
|
Bit64u val_64 = read_virtual_qword(i->seg(), eaddr);
|
|
BX_WRITE_XMM_REG_LO_QWORD(BX_VECTOR_TMP_REGISTER, val_64);
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
if (vl == BX_VL256) {
|
|
Bit32u val_32 = read_virtual_dword(i->seg(), eaddr);
|
|
BX_WRITE_XMM_REG_LO_DWORD(BX_VECTOR_TMP_REGISTER, val_32);
|
|
}
|
|
else {
|
|
Bit16u val_16 = read_virtual_word(i->seg(), eaddr);
|
|
BX_WRITE_XMM_REG_LO_WORD(BX_VECTOR_TMP_REGISTER, val_16);
|
|
}
|
|
}
|
|
|
|
BX_CPU_CALL_METHOD(i->execute2(), (i));
|
|
}
|
|
|
|
#endif
|
|
|
|
#if BX_SUPPORT_EVEX
|
|
|
|
#include "simd_int.h"
|
|
|
|
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_BROADCAST_VectorD(bxInstruction_c *i)
|
|
{
|
|
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
|
unsigned vl = i->getVL();
|
|
|
|
if (i->getEvexb()) {
|
|
Bit32u val_32 = read_virtual_dword(i->seg(), eaddr);
|
|
simd_pbroadcastd(&BX_AVX_REG(BX_VECTOR_TMP_REGISTER), val_32, vl * 4);
|
|
}
|
|
else {
|
|
if (vl == BX_VL512)
|
|
read_virtual_zmmword(i->seg(), eaddr, &BX_READ_AVX_REG(BX_VECTOR_TMP_REGISTER));
|
|
if (vl == BX_VL256)
|
|
read_virtual_ymmword(i->seg(), eaddr, &BX_READ_YMM_REG(BX_VECTOR_TMP_REGISTER));
|
|
else
|
|
read_virtual_xmmword(i->seg(), eaddr, &BX_READ_XMM_REG(BX_VECTOR_TMP_REGISTER));
|
|
}
|
|
|
|
BX_CPU_CALL_METHOD(i->execute2(), (i));
|
|
}
|
|
|
|
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_BROADCAST_MASK_VectorD(bxInstruction_c *i)
|
|
{
|
|
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
|
unsigned vl = i->getVL();
|
|
|
|
Bit32u opmask = (i->opmask() != 0) ? BX_READ_16BIT_OPMASK(i->opmask()) : 0xffff;
|
|
|
|
if (opmask == 0) {
|
|
BX_CPU_CALL_METHOD(i->execute2(), (i)); // for now let execute method to deal with zero/merge masking semantics
|
|
return;
|
|
}
|
|
|
|
if (i->getEvexb()) {
|
|
Bit32u val_32 = read_virtual_dword(i->seg(), eaddr);
|
|
simd_pbroadcastd(&BX_AVX_REG(BX_VECTOR_TMP_REGISTER), val_32, vl * 4);
|
|
}
|
|
else {
|
|
avx_masked_load32(i, eaddr, &BX_READ_AVX_REG(BX_VECTOR_TMP_REGISTER), opmask);
|
|
}
|
|
|
|
BX_CPU_CALL_METHOD(i->execute2(), (i));
|
|
}
|
|
|
|
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_BROADCAST_VectorQ(bxInstruction_c *i)
|
|
{
|
|
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
|
unsigned vl = i->getVL();
|
|
|
|
if (i->getEvexb()) {
|
|
Bit64u val_64 = read_virtual_qword(i->seg(), eaddr);
|
|
simd_pbroadcastq(&BX_AVX_REG(BX_VECTOR_TMP_REGISTER), val_64, vl * 2);
|
|
}
|
|
else {
|
|
if (vl == BX_VL512)
|
|
read_virtual_zmmword(i->seg(), eaddr, &BX_READ_AVX_REG(BX_VECTOR_TMP_REGISTER));
|
|
if (vl == BX_VL256)
|
|
read_virtual_ymmword(i->seg(), eaddr, &BX_READ_YMM_REG(BX_VECTOR_TMP_REGISTER));
|
|
else
|
|
read_virtual_xmmword(i->seg(), eaddr, &BX_READ_XMM_REG(BX_VECTOR_TMP_REGISTER));
|
|
}
|
|
|
|
BX_CPU_CALL_METHOD(i->execute2(), (i));
|
|
}
|
|
|
|
BX_INSF_TYPE BX_CPP_AttrRegparmN(1) BX_CPU_C::LOAD_BROADCAST_MASK_VectorQ(bxInstruction_c *i)
|
|
{
|
|
bx_address eaddr = BX_CPU_CALL_METHODR(i->ResolveModrm, (i));
|
|
unsigned vl = i->getVL();
|
|
|
|
Bit32u opmask = (i->opmask() != 0) ? BX_READ_8BIT_OPMASK(i->opmask()) : 0xff;
|
|
|
|
if (opmask == 0) {
|
|
BX_CPU_CALL_METHOD(i->execute2(), (i)); // for now let execute method to deal with zero/merge masking semantics
|
|
return;
|
|
}
|
|
|
|
if (i->getEvexb()) {
|
|
Bit64u val_64 = read_virtual_qword(i->seg(), eaddr);
|
|
simd_pbroadcastq(&BX_AVX_REG(BX_VECTOR_TMP_REGISTER), val_64, vl * 2);
|
|
}
|
|
else {
|
|
avx_masked_load64(i, eaddr, &BX_READ_AVX_REG(BX_VECTOR_TMP_REGISTER), opmask);
|
|
}
|
|
|
|
BX_CPU_CALL_METHOD(i->execute2(), (i));
|
|
}
|
|
|
|
#endif
|