Bochs/bochs/cpu/load.cc
Stanislav Shwartsman ac06ee46ae Implemented VPMOVSX*/VPMOVZX* AVX-512 instructions
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
2014-02-02 19:56:08 +00:00

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