mirror of
https://github.com/libretro/parallel-ps2.git
synced 2026-11-10 17:26:34 -10:00
Three changes, one intent: bare `make` and bare cmake now build the C89 emitter with nothing to specify, and common/emitter contains only the six headers the recompilers actually use (c89emit.h, x86emitter.h, x86types.h, instructions.h, legacy_instructions.h, x86emitter_shim.h). Default flip. Makefile gains `C89_EMITTER ?= 1` -- set BEFORE the Makefile.common include, because the source exclusion there reads it. The first attempt set it next to the CXXFLAGS append at line 839, after the include: the define applied but the exclusion never fired, and the build went on linking reference objects it no longer needed. Caught by `make -n` grep: a bare plan now names zero reference objects, a C89_EMITTER=0 plan names all eight. CMake's option defaults to ON with the same semantics (-DC89_EMITTER=OFF for the reference). Reference headers. internal.h, legacy_internal.h and the thirteen-header implement/ tree move to tests/emitter/reference beside the sources that need them. internal.h now includes the implement set itself -- it is the reference implementation's own root and must be self-sufficient; x86types.h includes them only under the reference configuration, for the extern declarations in instructions.h's #else branches. The three G*Type operator enums move into x86types.h: recompilers name their values, which makes them API, not implementation. iR5900-32.cpp's MOVQ-workaround include of internal.h was already reference-gated and is repointed. cmake's installed- header list is repointed too (the stale entries failed configure). Legacy jump API. The fourteen rel8/rel32 wrappers become macros over two static helpers (J8Rel, J32Rel), matching the C89 core's idiom. The helpers are static -- internal linkage per TU -- so there is no header-linkage subtlety left to get wrong, where the previous inline definitions carried one. The speculative conditional mode initially drafted into J32Rel was removed before commit: only the unconditional form has callers. The legacy SSE C-API wrappers (SSE_MINSS_XMM_to_XMM and friends) now emit through E_SSE_RR directly instead of hopping through the C++ shim objects. Their constants are proven end-to-end in newbind: reference function vs C89 macro across all register pairs, 2,048 cases within the 110,070 total. Verified: six suites green, switchover identical, both compile gates 31/31 in both configurations, bare make links at 11,351,104 bytes with zero reference encoder symbols and boots, cmake configure passes in both configurations. The cmake three-target build has not completed in this container (cmake 4 needs -DCMAKE_POLICY_VERSION_MINIMUM=3.5 for the vendored cpuinfo; GL dev packages were also missing) -- it needs one run on a normally-provisioned machine. C89_EMITTER=0 static: the gates and suites compile and byte-verify that configuration; its last full link ran two commits ago unchanged.
141 lines
4.5 KiB
C++
141 lines
4.5 KiB
C++
/* PCSX2 - PS2 Emulator for PCs
|
|
* Copyright (C) 2002-2022 PCSX2 Dev Team
|
|
*
|
|
* PCSX2 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 Found-
|
|
* ation, either version 3 of the License, or (at your option) any later version.
|
|
*
|
|
* PCSX2 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 General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with PCSX2.
|
|
* If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "tests/emitter/reference/internal.h"
|
|
|
|
// warning: suggest braces around initialization of subobject [-Wmissing-braces]
|
|
#ifdef __clang__
|
|
#pragma clang diagnostic push
|
|
#pragma clang diagnostic ignored "-Wmissing-braces"
|
|
#endif
|
|
|
|
namespace x86Emitter
|
|
{
|
|
#ifndef PCSX2_C89_EMITTER
|
|
const xImplAVX_Move xVMOVAPS = {0x00, 0x28, 0x29};
|
|
#endif
|
|
#ifndef PCSX2_C89_EMITTER
|
|
const xImplAVX_Move xVMOVUPS = {0x00, 0x10, 0x11};
|
|
|
|
#endif
|
|
#ifndef PCSX2_C89_EMITTER
|
|
const xImplAVX_ThreeArgYMM xVPAND = {0x66, 0xDB};
|
|
#endif
|
|
#ifndef PCSX2_C89_EMITTER
|
|
const xImplAVX_CmpInt xVPCMP = {
|
|
{0x66, 0x74}, // VPCMPEQB
|
|
{0x66, 0x75}, // VPCMPEQW
|
|
{0x66, 0x76}, // VPCMPEQD
|
|
{0x66, 0x64}, // VPCMPGTB
|
|
{0x66, 0x65}, // VPCMPGTW
|
|
{0x66, 0x66}, // VPCMPGTD
|
|
};
|
|
|
|
#endif
|
|
void xVMOVMSKPS(const xRegister32& to, const xRegisterSSE& from)
|
|
{
|
|
xOpWriteC5(0x00, 0x50, to, xRegister32(), from);
|
|
}
|
|
|
|
void xVMOVMSKPD(const xRegister32& to, const xRegisterSSE& from)
|
|
{
|
|
xOpWriteC5(0x66, 0x50, to, xRegister32(), from);
|
|
}
|
|
|
|
void xImplAVX_Move::operator()(const xRegisterSSE& to, const xRegisterSSE& from) const
|
|
{
|
|
if (to != from)
|
|
xOpWriteC5(Prefix, LoadOpcode, to, xRegisterSSE(), from);
|
|
}
|
|
|
|
void xImplAVX_Move::operator()(const xRegisterSSE& to, const xIndirectVoid& from) const
|
|
{
|
|
xOpWriteC5(Prefix, LoadOpcode, to, xRegisterSSE(), from);
|
|
}
|
|
|
|
void xImplAVX_Move::operator()(const xIndirectVoid& to, const xRegisterSSE& from) const
|
|
{
|
|
xOpWriteC5(Prefix, StoreOpcode, from, xRegisterSSE(), to);
|
|
}
|
|
|
|
void xImplAVX_ThreeArg::operator()(const xRegisterSSE& to, const xRegisterSSE& from1, const xRegisterSSE& from2) const
|
|
{
|
|
xOpWriteC5(Prefix, Opcode, to, from1, from2);
|
|
}
|
|
|
|
void xImplAVX_ThreeArg::operator()(const xRegisterSSE& to, const xRegisterSSE& from1, const xIndirectVoid& from2) const
|
|
{
|
|
xOpWriteC5(Prefix, Opcode, to, from1, from2);
|
|
}
|
|
|
|
void xImplAVX_ThreeArgYMM::operator()(const xRegisterSSE& to, const xRegisterSSE& from1, const xRegisterSSE& from2) const
|
|
{
|
|
xOpWriteC5(Prefix, Opcode, to, from1, from2);
|
|
}
|
|
|
|
void xImplAVX_ThreeArgYMM::operator()(const xRegisterSSE& to, const xRegisterSSE& from1, const xIndirectVoid& from2) const
|
|
{
|
|
xOpWriteC5(Prefix, Opcode, to, from1, from2);
|
|
}
|
|
|
|
void xImplAVX_CmpFloatHelper::PS(const xRegisterSSE& to, const xRegisterSSE& from1, const xRegisterSSE& from2) const
|
|
{
|
|
xOpWriteC5(0x00, 0xC2, to, from1, from2);
|
|
xWrite8(static_cast<u8>(CType));
|
|
}
|
|
|
|
void xImplAVX_CmpFloatHelper::PS(const xRegisterSSE& to, const xRegisterSSE& from1, const xIndirectVoid& from2) const
|
|
{
|
|
xOpWriteC5(0x00, 0xC2, to, from1, from2);
|
|
xWrite8(static_cast<u8>(CType));
|
|
}
|
|
|
|
void xImplAVX_CmpFloatHelper::PD(const xRegisterSSE& to, const xRegisterSSE& from1, const xIndirectVoid& from2) const
|
|
{
|
|
xOpWriteC5(0x66, 0xC2, to, from1, from2);
|
|
xWrite8(static_cast<u8>(CType));
|
|
}
|
|
|
|
void xImplAVX_CmpFloatHelper::PD(const xRegisterSSE& to, const xRegisterSSE& from1, const xRegisterSSE& from2) const
|
|
{
|
|
xOpWriteC5(0x66, 0xC2, to, from1, from2);
|
|
xWrite8(static_cast<u8>(CType));
|
|
}
|
|
|
|
void xImplAVX_CmpFloatHelper::SS(const xRegisterSSE& to, const xRegisterSSE& from1, const xRegisterSSE& from2) const
|
|
{
|
|
xOpWriteC5(0xF3, 0xC2, to, from1, from2);
|
|
xWrite8(static_cast<u8>(CType));
|
|
}
|
|
|
|
void xImplAVX_CmpFloatHelper::SS(const xRegisterSSE& to, const xRegisterSSE& from1, const xIndirectVoid& from2) const
|
|
{
|
|
xOpWriteC5(0xF3, 0xC2, to, from1, from2);
|
|
xWrite8(static_cast<u8>(CType));
|
|
}
|
|
|
|
void xImplAVX_CmpFloatHelper::SD(const xRegisterSSE& to, const xRegisterSSE& from1, const xIndirectVoid& from2) const
|
|
{
|
|
xOpWriteC5(0xF2, 0xC2, to, from1, from2);
|
|
xWrite8(static_cast<u8>(CType));
|
|
}
|
|
|
|
void xImplAVX_CmpFloatHelper::SD(const xRegisterSSE& to, const xRegisterSSE& from1, const xRegisterSSE& from2) const
|
|
{
|
|
xOpWriteC5(0xF2, 0xC2, to, from1, from2);
|
|
xWrite8(static_cast<u8>(CType));
|
|
}
|
|
} // namespace x86Emitter
|