mirror of
https://github.com/izzy2lost/WeeU.git
synced 2026-07-06 00:19:59 -07:00
Make codebase more CPU-agnostic + MacOS disclaimer (#559)
This commit is contained in:
Vendored
+61
-19
@@ -2,10 +2,6 @@
|
||||
|
||||
project ("ih264d")
|
||||
|
||||
set(LIBAVCDEC_X86_INCLUDES "common/x86" "decoder/x86")
|
||||
|
||||
include_directories("common/" "decoder/" ${LIBAVCDEC_X86_INCLUDES})
|
||||
|
||||
add_library (ih264d
|
||||
"common/ih264_buf_mgr.c"
|
||||
"common/ih264_buf_mgr.h"
|
||||
@@ -53,21 +49,6 @@ add_library (ih264d
|
||||
"common/ih264_weighted_pred.h"
|
||||
"common/ithread.c"
|
||||
"common/ithread.h"
|
||||
"common/x86/ih264_chroma_intra_pred_filters_ssse3.c"
|
||||
"common/x86/ih264_deblk_chroma_ssse3.c"
|
||||
"common/x86/ih264_deblk_luma_ssse3.c"
|
||||
"common/x86/ih264_ihadamard_scaling_sse42.c"
|
||||
"common/x86/ih264_ihadamard_scaling_ssse3.c"
|
||||
"common/x86/ih264_inter_pred_filters_ssse3.c"
|
||||
"common/x86/ih264_iquant_itrans_recon_dc_ssse3.c"
|
||||
"common/x86/ih264_iquant_itrans_recon_sse42.c"
|
||||
"common/x86/ih264_iquant_itrans_recon_ssse3.c"
|
||||
"common/x86/ih264_luma_intra_pred_filters_ssse3.c"
|
||||
"common/x86/ih264_mem_fns_ssse3.c"
|
||||
"common/x86/ih264_padding_ssse3.c"
|
||||
"common/x86/ih264_platform_macros.h"
|
||||
"common/x86/ih264_resi_trans_quant_sse42.c"
|
||||
"common/x86/ih264_weighted_pred_sse42.c"
|
||||
"decoder/ih264d.h"
|
||||
"decoder/ih264d_api.c"
|
||||
"decoder/ih264d_bitstrm.c"
|
||||
@@ -134,10 +115,71 @@ add_library (ih264d
|
||||
"decoder/ih264d_vui.h"
|
||||
"decoder/iv.h"
|
||||
"decoder/ivd.h"
|
||||
)
|
||||
|
||||
if (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64")
|
||||
set(LIBAVCDEC_X86_INCLUDES "common/x86" "decoder/x86")
|
||||
include_directories("common/" "decoder/" ${LIBAVCDEC_X86_INCLUDES})
|
||||
target_sources(ih264d PRIVATE
|
||||
"common/x86/ih264_chroma_intra_pred_filters_ssse3.c"
|
||||
"common/x86/ih264_deblk_chroma_ssse3.c"
|
||||
"common/x86/ih264_deblk_luma_ssse3.c"
|
||||
"common/x86/ih264_ihadamard_scaling_sse42.c"
|
||||
"common/x86/ih264_ihadamard_scaling_ssse3.c"
|
||||
"common/x86/ih264_inter_pred_filters_ssse3.c"
|
||||
"common/x86/ih264_iquant_itrans_recon_dc_ssse3.c"
|
||||
"common/x86/ih264_iquant_itrans_recon_sse42.c"
|
||||
"common/x86/ih264_iquant_itrans_recon_ssse3.c"
|
||||
"common/x86/ih264_luma_intra_pred_filters_ssse3.c"
|
||||
"common/x86/ih264_mem_fns_ssse3.c"
|
||||
"common/x86/ih264_padding_ssse3.c"
|
||||
"common/x86/ih264_platform_macros.h"
|
||||
"common/x86/ih264_resi_trans_quant_sse42.c"
|
||||
"common/x86/ih264_weighted_pred_sse42.c"
|
||||
"decoder/x86/ih264d_function_selector.c"
|
||||
"decoder/x86/ih264d_function_selector_sse42.c"
|
||||
"decoder/x86/ih264d_function_selector_ssse3.c"
|
||||
)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
|
||||
enable_language( C CXX ASM )
|
||||
set(LIBAVCDEC_ARM_INCLUDES "common/armv8" "decoder/arm")
|
||||
include_directories("common/" "decoder/" ${LIBAVCDEC_ARM_INCLUDES})
|
||||
target_sources(ih264d PRIVATE
|
||||
"common/armv8/ih264_deblk_chroma_av8.s"
|
||||
"common/armv8/ih264_deblk_luma_av8.s"
|
||||
"common/armv8/ih264_default_weighted_pred_av8.s"
|
||||
"common/armv8/ih264_ihadamard_scaling_av8.s"
|
||||
"common/armv8/ih264_inter_pred_chroma_av8.s"
|
||||
"common/armv8/ih264_inter_pred_filters_luma_horz_av8.s"
|
||||
"common/armv8/ih264_inter_pred_filters_luma_vert_av8.s"
|
||||
"common/armv8/ih264_inter_pred_luma_copy_av8.s"
|
||||
"common/armv8/ih264_inter_pred_luma_horz_hpel_vert_hpel_av8.s"
|
||||
"common/armv8/ih264_inter_pred_luma_horz_hpel_vert_qpel_av8.s"
|
||||
"common/armv8/ih264_inter_pred_luma_horz_qpel_av8.s"
|
||||
"common/armv8/ih264_inter_pred_luma_horz_qpel_vert_hpel_av8.s"
|
||||
"common/armv8/ih264_inter_pred_luma_horz_qpel_vert_qpel_av8.s"
|
||||
"common/armv8/ih264_inter_pred_luma_vert_qpel_av8.s"
|
||||
"common/armv8/ih264_intra_pred_chroma_av8.s"
|
||||
"common/armv8/ih264_intra_pred_luma_16x16_av8.s"
|
||||
"common/armv8/ih264_intra_pred_luma_4x4_av8.s"
|
||||
"common/armv8/ih264_intra_pred_luma_8x8_av8.s"
|
||||
"common/armv8/ih264_iquant_itrans_recon_av8.s"
|
||||
"common/armv8/ih264_iquant_itrans_recon_dc_av8.s"
|
||||
"common/armv8/ih264_mem_fns_neon_av8.s"
|
||||
"common/armv8/ih264_neon_macros.s"
|
||||
"common/armv8/ih264_padding_neon_av8.s"
|
||||
"common/armv8/ih264_platform_macros.h"
|
||||
"common/armv8/ih264_resi_trans_quant_av8.s"
|
||||
"common/armv8/ih264_weighted_bi_pred_av8.s"
|
||||
"common/armv8/ih264_weighted_pred_av8.s"
|
||||
"decoder/arm/ih264d_function_selector_a9q.c"
|
||||
"decoder/arm/ih264d_function_selector_av8.c"
|
||||
"decoder/arm/ih264d_function_selector.c"
|
||||
)
|
||||
target_compile_options(ih264d PRIVATE -DARMV8)
|
||||
else()
|
||||
message(FATAL_ERROR "ih264d unknown architecture: ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
set_property(TARGET ih264d PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
|
||||
@@ -83,7 +83,7 @@ void hleExport_xcx_enterCriticalSection(PPCInterpreter_t* hCPU)
|
||||
osLib_returnFromFunction(hCPU, 0);
|
||||
return;
|
||||
}
|
||||
_mm_pause();
|
||||
_mm_pause();
|
||||
}
|
||||
PPCCore_switchToScheduler();
|
||||
}
|
||||
|
||||
@@ -203,7 +203,6 @@ extern uint64 ppcMainThreadDECCycleStart; // at which cycle the dec register was
|
||||
void PPCTimer_init();
|
||||
void PPCTimer_waitForInit();
|
||||
uint64 PPCTimer_getFromRDTSC();
|
||||
bool PPCTimer_hasInvariantRDTSCSupport();
|
||||
|
||||
uint64 PPCTimer_microsecondsToTsc(uint64 us);
|
||||
uint64 PPCTimer_tscToMicroseconds(uint64 us);
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
#include "Cafe/HW/Espresso/Const.h"
|
||||
#include <immintrin.h>
|
||||
#include "asm/x64util.h"
|
||||
#include "config/ActiveSettings.h"
|
||||
#include "util/helpers/fspinlock.h"
|
||||
#include "util/highresolutiontimer/HighResolutionTimer.h"
|
||||
#include "Common/cpu_features.h"
|
||||
|
||||
#if defined(ARCH_X86_64)
|
||||
#include <immintrin.h>
|
||||
#pragma intrinsic(__rdtsc)
|
||||
#endif
|
||||
|
||||
uint64 _rdtscLastMeasure = 0;
|
||||
uint64 _rdtscFrequency = 0;
|
||||
@@ -18,8 +23,6 @@ static_assert(sizeof(uint128_t) == 16);
|
||||
|
||||
uint128_t _rdtscAcc{};
|
||||
|
||||
#pragma intrinsic(__rdtsc)
|
||||
|
||||
uint64 muldiv64(uint64 a, uint64 b, uint64 d)
|
||||
{
|
||||
uint64 diva = a / d;
|
||||
@@ -29,17 +32,12 @@ uint64 muldiv64(uint64 a, uint64 b, uint64 d)
|
||||
return diva * b + moda * divb + moda * modb / d;
|
||||
}
|
||||
|
||||
bool PPCTimer_hasInvariantRDTSCSupport()
|
||||
{
|
||||
uint32 cpuv[4];
|
||||
cpuid((int*)cpuv, 0x80000007);
|
||||
return ((cpuv[3] >> 8) & 1);
|
||||
}
|
||||
|
||||
uint64 PPCTimer_estimateRDTSCFrequency()
|
||||
{
|
||||
if (PPCTimer_hasInvariantRDTSCSupport() == false)
|
||||
forceLog_printf("Invariant TSC not supported");
|
||||
#if defined(ARCH_X86_64)
|
||||
if (!g_CPUFeatures.x86.invariant_tsc)
|
||||
cemuLog_log(LogType::Force, "Invariant TSC not supported");
|
||||
#endif
|
||||
|
||||
_mm_mfence();
|
||||
uint64 tscStart = __rdtsc();
|
||||
|
||||
@@ -8,11 +8,10 @@
|
||||
#include "Cafe/OS/libs/coreinit/coreinit_CodeGen.h"
|
||||
#include "config/ActiveSettings.h"
|
||||
#include "config/LaunchSettings.h"
|
||||
|
||||
#include "util/helpers/fspinlock.h"
|
||||
#include "Common/ExceptionHandler/ExceptionHandler.h"
|
||||
#include "Common/cpu_features.h"
|
||||
#include "util/helpers/fspinlock.h"
|
||||
#include "util/helpers/helpers.h"
|
||||
|
||||
#include "util/MemMapper/MemMapper.h"
|
||||
|
||||
struct PPCInvalidationRange
|
||||
@@ -461,6 +460,20 @@ void PPCRecompiler_invalidateRange(uint32 startAddr, uint32 endAddr)
|
||||
PPCRecompilerState.recompilerSpinlock.unlock();
|
||||
}
|
||||
|
||||
#if defined(ARCH_X86_64)
|
||||
void PPCRecompiler_initPlatform()
|
||||
{
|
||||
// mxcsr
|
||||
ppcRecompilerInstanceData->_x64XMM_mxCsr_ftzOn = 0x1F80 | 0x8000;
|
||||
ppcRecompilerInstanceData->_x64XMM_mxCsr_ftzOff = 0x1F80;
|
||||
}
|
||||
#else
|
||||
void PPCRecompiler_initPlatform()
|
||||
{
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void PPCRecompiler_init()
|
||||
{
|
||||
if (ActiveSettings::GetCPUMode() == CPUMode::SinglecoreInterpreter)
|
||||
@@ -569,21 +582,9 @@ void PPCRecompiler_init()
|
||||
ppcRecompilerInstanceData->_psq_st_scale_ps0_ps1[(i + 32) * 2 + 1] = br;
|
||||
}
|
||||
|
||||
// mxcsr
|
||||
ppcRecompilerInstanceData->_x64XMM_mxCsr_ftzOn = 0x1F80 | 0x8000;
|
||||
ppcRecompilerInstanceData->_x64XMM_mxCsr_ftzOff = 0x1F80;
|
||||
|
||||
// query processor extensions
|
||||
int cpuInfo[4];
|
||||
cpuid(cpuInfo, 0x80000001);
|
||||
hasLZCNTSupport = ((cpuInfo[2] >> 5) & 1) != 0;
|
||||
cpuid(cpuInfo, 0x1);
|
||||
hasMOVBESupport = ((cpuInfo[2] >> 22) & 1) != 0;
|
||||
hasAVXSupport = ((cpuInfo[2] >> 28) & 1) != 0;
|
||||
cpuidex(cpuInfo, 0x7, 0);
|
||||
hasBMI2Support = ((cpuInfo[1] >> 8) & 1) != 0;
|
||||
|
||||
forceLog_printf("Recompiler initialized. CPU extensions: %s%s%s", hasLZCNTSupport ? "LZCNT " : "", hasMOVBESupport ? "MOVBE " : "", hasAVXSupport ? "AVX " : "");
|
||||
PPCRecompiler_initPlatform();
|
||||
|
||||
forceLog_printf("Recompiler initialized");
|
||||
|
||||
ppcRecompilerEnabled = true;
|
||||
|
||||
|
||||
@@ -384,12 +384,6 @@ extern void ATTR_MS_ABI (*PPCRecompiler_leaveRecompilerCode_unvisited)();
|
||||
|
||||
#define PPC_REC_INVALID_FUNCTION ((PPCRecFunction_t*)-1)
|
||||
|
||||
// CPUID
|
||||
extern bool hasLZCNTSupport;
|
||||
extern bool hasMOVBESupport;
|
||||
extern bool hasBMI2Support;
|
||||
extern bool hasAVXSupport;
|
||||
|
||||
// todo - move some of the stuff above into PPCRecompilerInternal.h
|
||||
|
||||
// recompiler interface
|
||||
|
||||
@@ -3,14 +3,6 @@
|
||||
#include "PPCRecompilerIml.h"
|
||||
#include "Cafe/GameProfile/GameProfile.h"
|
||||
|
||||
bool hasSSE1Support = true;
|
||||
bool hasSSE2Support = true;
|
||||
bool hasSSE3Support = true;
|
||||
bool hasLZCNTSupport = false;
|
||||
bool hasMOVBESupport = false;
|
||||
bool hasBMI2Support = false;
|
||||
bool hasAVXSupport = false;
|
||||
|
||||
void PPCRecompilerImlGen_generateNewInstruction_fpr_r_memory(ppcImlGenContext_t* ppcImlGenContext, uint8 registerDestination, uint8 registerMemory, sint32 immS32, uint32 mode, bool switchEndian, uint8 registerGQR = PPC_REC_INVALID_REGISTER)
|
||||
{
|
||||
// load from memory
|
||||
@@ -145,8 +137,6 @@ void PPRecompilerImmGen_optionalRoundPairFPRToSinglePrecision(ppcImlGenContext_t
|
||||
|
||||
bool PPCRecompilerImlGen_LFS(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||
{
|
||||
if( hasSSE1Support == false )
|
||||
return false;
|
||||
sint32 rA, frD;
|
||||
uint32 imm;
|
||||
PPC_OPC_TEMPL_D_SImm(opcode, frD, rA, imm);
|
||||
@@ -167,8 +157,6 @@ bool PPCRecompilerImlGen_LFS(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode
|
||||
|
||||
bool PPCRecompilerImlGen_LFSU(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||
{
|
||||
if( hasSSE1Support == false )
|
||||
return false;
|
||||
sint32 rA, frD;
|
||||
uint32 imm;
|
||||
PPC_OPC_TEMPL_D_SImm(opcode, frD, rA, imm);
|
||||
@@ -191,8 +179,6 @@ bool PPCRecompilerImlGen_LFSU(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||
|
||||
bool PPCRecompilerImlGen_LFSX(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||
{
|
||||
if( hasSSE2Support == false )
|
||||
return false;
|
||||
sint32 rA, frD, rB;
|
||||
PPC_OPC_TEMPL_X(opcode, frD, rA, rB);
|
||||
if( rA == 0 )
|
||||
@@ -218,8 +204,6 @@ bool PPCRecompilerImlGen_LFSX(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||
|
||||
bool PPCRecompilerImlGen_LFSUX(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||
{
|
||||
if( hasSSE2Support == false )
|
||||
return false;
|
||||
sint32 rA, frD, rB;
|
||||
PPC_OPC_TEMPL_X(opcode, frD, rA, rB);
|
||||
if( rA == 0 )
|
||||
@@ -247,8 +231,6 @@ bool PPCRecompilerImlGen_LFSUX(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||
|
||||
bool PPCRecompilerImlGen_LFD(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||
{
|
||||
if( hasSSE1Support == false )
|
||||
return false;
|
||||
sint32 rA, frD;
|
||||
uint32 imm;
|
||||
PPC_OPC_TEMPL_D_SImm(opcode, frD, rA, imm);
|
||||
@@ -266,8 +248,6 @@ bool PPCRecompilerImlGen_LFD(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode
|
||||
|
||||
bool PPCRecompilerImlGen_LFDU(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||
{
|
||||
if( hasSSE1Support == false )
|
||||
return false;
|
||||
sint32 rA, frD;
|
||||
uint32 imm;
|
||||
PPC_OPC_TEMPL_D_SImm(opcode, frD, rA, imm);
|
||||
@@ -288,8 +268,6 @@ bool PPCRecompilerImlGen_LFDU(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||
|
||||
bool PPCRecompilerImlGen_LFDX(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||
{
|
||||
if( hasSSE2Support == false )
|
||||
return false;
|
||||
sint32 rA, frD, rB;
|
||||
PPC_OPC_TEMPL_X(opcode, frD, rA, rB);
|
||||
if( rA == 0 )
|
||||
@@ -308,8 +286,6 @@ bool PPCRecompilerImlGen_LFDX(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||
|
||||
bool PPCRecompilerImlGen_LFDUX(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||
{
|
||||
if( hasSSE2Support == false )
|
||||
return false;
|
||||
sint32 rA, frD, rB;
|
||||
PPC_OPC_TEMPL_X(opcode, frD, rA, rB);
|
||||
if( rA == 0 )
|
||||
@@ -330,8 +306,6 @@ bool PPCRecompilerImlGen_LFDUX(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||
|
||||
bool PPCRecompilerImlGen_STFS(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||
{
|
||||
if( hasSSE1Support == false )
|
||||
return false;
|
||||
sint32 rA, frD;
|
||||
uint32 imm;
|
||||
PPC_OPC_TEMPL_D_SImm(opcode, frD, rA, imm);
|
||||
@@ -346,8 +320,6 @@ bool PPCRecompilerImlGen_STFS(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||
|
||||
bool PPCRecompilerImlGen_STFSU(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||
{
|
||||
if( hasSSE1Support == false )
|
||||
return false;
|
||||
sint32 rA, frD;
|
||||
uint32 imm;
|
||||
PPC_OPC_TEMPL_D_SImm(opcode, frD, rA, imm);
|
||||
@@ -364,8 +336,6 @@ bool PPCRecompilerImlGen_STFSU(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||
|
||||
bool PPCRecompilerImlGen_STFSX(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||
{
|
||||
if( hasSSE2Support == false )
|
||||
return false;
|
||||
sint32 rA, frS, rB;
|
||||
PPC_OPC_TEMPL_X(opcode, frS, rA, rB);
|
||||
if( rA == 0 )
|
||||
@@ -392,8 +362,6 @@ bool PPCRecompilerImlGen_STFSX(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||
|
||||
bool PPCRecompilerImlGen_STFSUX(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||
{
|
||||
if( hasSSE2Support == false )
|
||||
return false;
|
||||
sint32 rA, frS, rB;
|
||||
PPC_OPC_TEMPL_X(opcode, frS, rA, rB);
|
||||
if( rA == 0 )
|
||||
@@ -415,8 +383,6 @@ bool PPCRecompilerImlGen_STFSUX(ppcImlGenContext_t* ppcImlGenContext, uint32 opc
|
||||
|
||||
bool PPCRecompilerImlGen_STFD(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||
{
|
||||
if( hasSSE1Support == false )
|
||||
return false;
|
||||
sint32 rA, frD;
|
||||
uint32 imm;
|
||||
PPC_OPC_TEMPL_D_SImm(opcode, frD, rA, imm);
|
||||
@@ -435,8 +401,6 @@ bool PPCRecompilerImlGen_STFD(ppcImlGenContext_t* ppcImlGenContext, uint32 opcod
|
||||
|
||||
bool PPCRecompilerImlGen_STFDU(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||
{
|
||||
if( hasSSE1Support == false )
|
||||
return false;
|
||||
sint32 rA, frD;
|
||||
uint32 imm;
|
||||
PPC_OPC_TEMPL_D_SImm(opcode, frD, rA, imm);
|
||||
@@ -458,8 +422,6 @@ bool PPCRecompilerImlGen_STFDU(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||
|
||||
bool PPCRecompilerImlGen_STFDX(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||
{
|
||||
if( hasSSE2Support == false )
|
||||
return false;
|
||||
sint32 rA, frS, rB;
|
||||
PPC_OPC_TEMPL_X(opcode, frS, rA, rB);
|
||||
if( rA == 0 )
|
||||
@@ -485,8 +447,6 @@ bool PPCRecompilerImlGen_STFDX(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||
|
||||
bool PPCRecompilerImlGen_STFIWX(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||
{
|
||||
if( hasSSE2Support == false )
|
||||
return false;
|
||||
sint32 rA, frS, rB;
|
||||
PPC_OPC_TEMPL_X(opcode, frS, rA, rB);
|
||||
// get memory gpr registers
|
||||
@@ -959,10 +919,6 @@ bool PPCRecompilerImlGen_FCMPO(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||
sint32 crfD, frA, frB;
|
||||
PPC_OPC_TEMPL_X(opcode, crfD, frA, frB);
|
||||
crfD >>= 2;
|
||||
if( hasSSE2Support == false )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
uint32 fprRegisterA = PPCRecompilerImlGen_loadFPRRegister(ppcImlGenContext, PPCREC_NAME_FPR0+frA);
|
||||
uint32 fprRegisterB = PPCRecompilerImlGen_loadFPRRegister(ppcImlGenContext, PPCREC_NAME_FPR0+frB);
|
||||
PPCRecompilerImlGen_generateNewInstruction_fpr_r_r(ppcImlGenContext, PPCREC_IML_OP_FPR_FCMPO_BOTTOM, fprRegisterA, fprRegisterB, crfD);
|
||||
@@ -974,10 +930,6 @@ bool PPCRecompilerImlGen_FCMPU(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||
sint32 crfD, frA, frB;
|
||||
PPC_OPC_TEMPL_X(opcode, crfD, frA, frB);
|
||||
crfD >>= 2;
|
||||
if( hasSSE2Support == false )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
uint32 fprRegisterA = PPCRecompilerImlGen_loadFPRRegister(ppcImlGenContext, PPCREC_NAME_FPR0+frA);
|
||||
uint32 fprRegisterB = PPCRecompilerImlGen_loadFPRRegister(ppcImlGenContext, PPCREC_NAME_FPR0+frB);
|
||||
PPCRecompilerImlGen_generateNewInstruction_fpr_r_r(ppcImlGenContext, PPCREC_IML_OP_FPR_FCMPU_BOTTOM, fprRegisterA, fprRegisterB, crfD);
|
||||
@@ -1120,8 +1072,6 @@ bool PPCRecompilerImlGen_FCTIWZ(ppcImlGenContext_t* ppcImlGenContext, uint32 opc
|
||||
|
||||
bool PPCRecompilerImlGen_PSQ_L(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||
{
|
||||
if (hasSSE2Support == false)
|
||||
return false;
|
||||
int rA, frD;
|
||||
uint32 immUnused;
|
||||
PPC_OPC_TEMPL_D_SImm(opcode, frD, rA, immUnused);
|
||||
@@ -1146,8 +1096,6 @@ bool PPCRecompilerImlGen_PSQ_L(ppcImlGenContext_t* ppcImlGenContext, uint32 opco
|
||||
|
||||
bool PPCRecompilerImlGen_PSQ_LU(ppcImlGenContext_t* ppcImlGenContext, uint32 opcode)
|
||||
{
|
||||
if (hasSSE2Support == false)
|
||||
return false;
|
||||
int rA, frD;
|
||||
uint32 immUnused;
|
||||
PPC_OPC_TEMPL_D_SImm(opcode, frD, rA, immUnused);
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
#include "PPCRecompilerIml.h"
|
||||
#include "PPCRecompilerX64.h"
|
||||
#include "Cafe/OS/libs/coreinit/coreinit_Time.h"
|
||||
|
||||
#include "util/MemMapper/MemMapper.h"
|
||||
#include "Common/cpu_features.h"
|
||||
|
||||
sint32 x64Gen_registerMap[12] = // virtual GPR to x64 register mapping
|
||||
{
|
||||
@@ -381,7 +381,7 @@ bool PPCRecompilerX64Gen_imlInstruction_load(PPCRecFunction_t* PPCRecFunction, p
|
||||
{
|
||||
x64Gen_lea_reg64Low32_reg64Low32PlusReg64Low32(x64GenContext, REG_RESV_TEMP, realRegisterMem, realRegisterMem2);
|
||||
}
|
||||
if( hasMOVBESupport && switchEndian )
|
||||
if( g_CPUFeatures.x86.movbe && switchEndian )
|
||||
{
|
||||
if (indexed)
|
||||
{
|
||||
@@ -419,7 +419,7 @@ bool PPCRecompilerX64Gen_imlInstruction_load(PPCRecFunction_t* PPCRecFunction, p
|
||||
{
|
||||
x64Gen_add_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2);
|
||||
}
|
||||
if( hasMOVBESupport && switchEndian )
|
||||
if( g_CPUFeatures.x86.movbe && switchEndian )
|
||||
{
|
||||
x64Gen_movBEZeroExtend_reg64Low16_mem16Reg64PlusReg64(x64GenContext, realRegisterData, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32);
|
||||
if( indexed && realRegisterMem != realRegisterData )
|
||||
@@ -477,7 +477,7 @@ bool PPCRecompilerX64Gen_imlInstruction_load(PPCRecFunction_t* PPCRecFunction, p
|
||||
assert_dbg();
|
||||
if( indexed )
|
||||
x64Gen_add_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2); // can be replaced with LEA temp, [memReg1+memReg2] (this way we can avoid the SUB instruction after the move)
|
||||
if( hasMOVBESupport )
|
||||
if( g_CPUFeatures.x86.movbe )
|
||||
{
|
||||
x64Gen_movBEZeroExtend_reg64_mem32Reg64PlusReg64(x64GenContext, realRegisterData, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32);
|
||||
if( indexed && realRegisterMem != realRegisterData )
|
||||
@@ -537,7 +537,7 @@ bool PPCRecompilerX64Gen_imlInstruction_store(PPCRecFunction_t* PPCRecFunction,
|
||||
if (indexed)
|
||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
||||
uint32 valueRegister;
|
||||
if ((swapEndian == false || hasMOVBESupport) && realRegisterMem != realRegisterData)
|
||||
if ((swapEndian == false || g_CPUFeatures.x86.movbe) && realRegisterMem != realRegisterData)
|
||||
{
|
||||
valueRegister = realRegisterData;
|
||||
}
|
||||
@@ -546,11 +546,11 @@ bool PPCRecompilerX64Gen_imlInstruction_store(PPCRecFunction_t* PPCRecFunction,
|
||||
x64Gen_mov_reg64_reg64(x64GenContext, REG_RESV_TEMP, realRegisterData);
|
||||
valueRegister = REG_RESV_TEMP;
|
||||
}
|
||||
if (hasMOVBESupport == false && swapEndian)
|
||||
if (g_CPUFeatures.x86.movbe == false && swapEndian)
|
||||
x64Gen_bswap_reg64Lower32bit(x64GenContext, valueRegister);
|
||||
if (indexed)
|
||||
x64Gen_add_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2);
|
||||
if (hasMOVBESupport && swapEndian)
|
||||
if (g_CPUFeatures.x86.movbe && swapEndian)
|
||||
x64Gen_movBETruncate_mem32Reg64PlusReg64_reg64(x64GenContext, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32, valueRegister);
|
||||
else
|
||||
x64Gen_movTruncate_mem32Reg64PlusReg64_reg64(x64GenContext, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32, valueRegister);
|
||||
@@ -802,8 +802,7 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r(PPCRecFunction_t* PPCRecFunction, pp
|
||||
// count leading zeros
|
||||
PPCRecompilerX64Gen_crConditionFlags_forget(PPCRecFunction, ppcImlGenContext, x64GenContext);
|
||||
cemu_assert_debug(imlInstruction->crRegister == PPC_REC_INVALID_REGISTER);
|
||||
// LZCNT instruction (part of SSE4, CPUID.80000001H:ECX.ABM[Bit 5])
|
||||
if( hasLZCNTSupport )
|
||||
if( g_CPUFeatures.x86.lzcnt )
|
||||
{
|
||||
x64Gen_lzcnt_reg64Low32_reg64Low32(x64GenContext, tempToRealRegister(imlInstruction->op_r_r.registerResult), tempToRealRegister(imlInstruction->op_r_r.registerA));
|
||||
}
|
||||
@@ -1521,12 +1520,12 @@ bool PPCRecompilerX64Gen_imlInstruction_r_r_r(PPCRecFunction_t* PPCRecFunction,
|
||||
sint32 rRegOperand1 = tempToRealRegister(imlInstruction->op_r_r_r.registerA);
|
||||
sint32 rRegOperand2 = tempToRealRegister(imlInstruction->op_r_r_r.registerB);
|
||||
|
||||
if (hasBMI2Support && imlInstruction->operation == PPCREC_IML_OP_SRW)
|
||||
if (g_CPUFeatures.x86.bmi2 && imlInstruction->operation == PPCREC_IML_OP_SRW)
|
||||
{
|
||||
// use BMI2 SHRX if available
|
||||
x64Gen_shrx_reg64_reg64_reg64(x64GenContext, rRegResult, rRegOperand1, rRegOperand2);
|
||||
}
|
||||
else if (hasBMI2Support && imlInstruction->operation == PPCREC_IML_OP_SLW)
|
||||
else if (g_CPUFeatures.x86.bmi2 && imlInstruction->operation == PPCREC_IML_OP_SLW)
|
||||
{
|
||||
// use BMI2 SHLX if available
|
||||
x64Gen_shlx_reg64_reg64_reg64(x64GenContext, rRegResult, rRegOperand1, rRegOperand2);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "PPCRecompilerIml.h"
|
||||
#include "PPCRecompilerX64.h"
|
||||
#include "asm/x64util.h"
|
||||
#include "Common/cpu_features.h"
|
||||
|
||||
void PPCRecompilerX64Gen_imlInstruction_fpr_r_name(PPCRecFunction_t* PPCRecFunction, ppcImlGenContext_t* ppcImlGenContext, x64GenContext_t* x64GenContext, PPCRecImlInstruction_t* imlInstruction)
|
||||
{
|
||||
@@ -86,7 +87,7 @@ void PPCRecompilerX64Gen_imlInstr_psq_load(ppcImlGenContext_t* ppcImlGenContext,
|
||||
{
|
||||
x64Gen_mov_reg64Low32_reg64Low32(x64GenContext, REG_RESV_TEMP, memRegEx);
|
||||
x64Gen_add_reg64Low32_reg64Low32(x64GenContext, REG_RESV_TEMP, memReg);
|
||||
if (hasMOVBESupport)
|
||||
if (g_CPUFeatures.x86.movbe)
|
||||
{
|
||||
x64Gen_movBEZeroExtend_reg64_mem32Reg64PlusReg64(x64GenContext, REG_RESV_TEMP, REG_RESV_MEMBASE, REG_RESV_TEMP, memImmS32);
|
||||
}
|
||||
@@ -98,7 +99,7 @@ void PPCRecompilerX64Gen_imlInstr_psq_load(ppcImlGenContext_t* ppcImlGenContext,
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hasMOVBESupport)
|
||||
if (g_CPUFeatures.x86.movbe)
|
||||
{
|
||||
x64Gen_movBEZeroExtend_reg64_mem32Reg64PlusReg64(x64GenContext, REG_RESV_TEMP, REG_RESV_MEMBASE, memReg, memImmS32);
|
||||
}
|
||||
@@ -108,7 +109,7 @@ void PPCRecompilerX64Gen_imlInstr_psq_load(ppcImlGenContext_t* ppcImlGenContext,
|
||||
x64Gen_bswap_reg64Lower32bit(x64GenContext, REG_RESV_TEMP);
|
||||
}
|
||||
}
|
||||
if (hasAVXSupport)
|
||||
if (g_CPUFeatures.x86.avx)
|
||||
{
|
||||
x64Gen_movd_xmmReg_reg64Low32(x64GenContext, REG_RESV_FPR_TEMP, REG_RESV_TEMP);
|
||||
}
|
||||
@@ -280,21 +281,21 @@ bool PPCRecompilerX64Gen_imlInstruction_fpr_load(PPCRecFunction_t* PPCRecFunctio
|
||||
{
|
||||
x64Gen_mov_reg64Low32_reg64Low32(x64GenContext, REG_RESV_TEMP, realRegisterMem2);
|
||||
x64Gen_add_reg64Low32_reg64Low32(x64GenContext, REG_RESV_TEMP, realRegisterMem);
|
||||
if( hasMOVBESupport )
|
||||
if( g_CPUFeatures.x86.movbe )
|
||||
x64Gen_movBEZeroExtend_reg64_mem32Reg64PlusReg64(x64GenContext, REG_RESV_TEMP, REG_RESV_MEMBASE, REG_RESV_TEMP, imlInstruction->op_storeLoad.immS32);
|
||||
else
|
||||
x64Emit_mov_reg32_mem32(x64GenContext, REG_RESV_TEMP, REG_RESV_MEMBASE, REG_RESV_TEMP, imlInstruction->op_storeLoad.immS32);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( hasMOVBESupport )
|
||||
if( g_CPUFeatures.x86.movbe )
|
||||
x64Gen_movBEZeroExtend_reg64_mem32Reg64PlusReg64(x64GenContext, REG_RESV_TEMP, REG_RESV_MEMBASE, realRegisterMem, imlInstruction->op_storeLoad.immS32);
|
||||
else
|
||||
x64Emit_mov_reg32_mem32(x64GenContext, REG_RESV_TEMP, REG_RESV_MEMBASE, realRegisterMem, imlInstruction->op_storeLoad.immS32);
|
||||
}
|
||||
if( hasMOVBESupport == false )
|
||||
if( g_CPUFeatures.x86.movbe == false )
|
||||
x64Gen_bswap_reg64Lower32bit(x64GenContext, REG_RESV_TEMP);
|
||||
if( hasAVXSupport )
|
||||
if( g_CPUFeatures.x86.avx )
|
||||
{
|
||||
x64Gen_movd_xmmReg_reg64Low32(x64GenContext, realRegisterXMM, REG_RESV_TEMP);
|
||||
}
|
||||
@@ -316,7 +317,7 @@ bool PPCRecompilerX64Gen_imlInstruction_fpr_load(PPCRecFunction_t* PPCRecFunctio
|
||||
}
|
||||
else if( mode == PPCREC_FPR_LD_MODE_DOUBLE_INTO_PS0 )
|
||||
{
|
||||
if( hasAVXSupport )
|
||||
if( g_CPUFeatures.x86.avx )
|
||||
{
|
||||
if( indexed )
|
||||
{
|
||||
@@ -419,7 +420,7 @@ void PPCRecompilerX64Gen_imlInstr_psq_store(ppcImlGenContext_t* ppcImlGenContext
|
||||
if (mode == PPCREC_FPR_ST_MODE_PSQ_FLOAT_PS0)
|
||||
{
|
||||
x64Gen_cvtsd2ss_xmmReg_xmmReg(x64GenContext, REG_RESV_FPR_TEMP, registerXMM);
|
||||
if (hasAVXSupport)
|
||||
if (g_CPUFeatures.x86.avx)
|
||||
{
|
||||
x64Gen_movd_reg64Low32_xmmReg(x64GenContext, REG_RESV_TEMP, REG_RESV_FPR_TEMP);
|
||||
}
|
||||
@@ -428,14 +429,14 @@ void PPCRecompilerX64Gen_imlInstr_psq_store(ppcImlGenContext_t* ppcImlGenContext
|
||||
x64Gen_movsd_memReg64_xmmReg(x64GenContext, REG_RESV_FPR_TEMP, REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR));
|
||||
x64Emit_mov_reg64_mem32(x64GenContext, REG_RESV_TEMP, REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR));
|
||||
}
|
||||
if (hasMOVBESupport == false)
|
||||
if (g_CPUFeatures.x86.movbe == false)
|
||||
x64Gen_bswap_reg64Lower32bit(x64GenContext, REG_RESV_TEMP);
|
||||
if (indexed)
|
||||
{
|
||||
cemu_assert_debug(memReg != memRegEx);
|
||||
x64Gen_add_reg64Low32_reg64Low32(x64GenContext, memReg, memRegEx);
|
||||
}
|
||||
if (hasMOVBESupport)
|
||||
if (g_CPUFeatures.x86.movbe)
|
||||
x64Gen_movBETruncate_mem32Reg64PlusReg64_reg64(x64GenContext, REG_R13, memReg, memImmS32, REG_RESV_TEMP);
|
||||
else
|
||||
x64Gen_movTruncate_mem32Reg64PlusReg64_reg64(x64GenContext, REG_R13, memReg, memImmS32, REG_RESV_TEMP);
|
||||
@@ -604,7 +605,7 @@ bool PPCRecompilerX64Gen_imlInstruction_fpr_store(PPCRecFunction_t* PPCRecFuncti
|
||||
if (imlInstruction->op_storeLoad.flags2.notExpanded)
|
||||
{
|
||||
// value is already in single format
|
||||
if (hasAVXSupport)
|
||||
if (g_CPUFeatures.x86.avx)
|
||||
{
|
||||
x64Gen_movd_reg64Low32_xmmReg(x64GenContext, REG_RESV_TEMP, realRegisterXMM);
|
||||
}
|
||||
@@ -617,7 +618,7 @@ bool PPCRecompilerX64Gen_imlInstruction_fpr_store(PPCRecFunction_t* PPCRecFuncti
|
||||
else
|
||||
{
|
||||
x64Gen_cvtsd2ss_xmmReg_xmmReg(x64GenContext, REG_RESV_FPR_TEMP, realRegisterXMM);
|
||||
if (hasAVXSupport)
|
||||
if (g_CPUFeatures.x86.avx)
|
||||
{
|
||||
x64Gen_movd_reg64Low32_xmmReg(x64GenContext, REG_RESV_TEMP, REG_RESV_FPR_TEMP);
|
||||
}
|
||||
@@ -627,7 +628,7 @@ bool PPCRecompilerX64Gen_imlInstruction_fpr_store(PPCRecFunction_t* PPCRecFuncti
|
||||
x64Emit_mov_reg64_mem32(x64GenContext, REG_RESV_TEMP, REG_RSP, offsetof(PPCInterpreter_t, temporaryFPR));
|
||||
}
|
||||
}
|
||||
if( hasMOVBESupport == false )
|
||||
if( g_CPUFeatures.x86.movbe == false )
|
||||
x64Gen_bswap_reg64Lower32bit(x64GenContext, REG_RESV_TEMP);
|
||||
if( indexed )
|
||||
{
|
||||
@@ -635,7 +636,7 @@ bool PPCRecompilerX64Gen_imlInstruction_fpr_store(PPCRecFunction_t* PPCRecFuncti
|
||||
assert_dbg();
|
||||
x64Gen_add_reg64Low32_reg64Low32(x64GenContext, realRegisterMem, realRegisterMem2);
|
||||
}
|
||||
if( hasMOVBESupport )
|
||||
if( g_CPUFeatures.x86.movbe )
|
||||
x64Gen_movBETruncate_mem32Reg64PlusReg64_reg64(x64GenContext, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32, REG_RESV_TEMP);
|
||||
else
|
||||
x64Gen_movTruncate_mem32Reg64PlusReg64_reg64(x64GenContext, REG_R13, realRegisterMem, imlInstruction->op_storeLoad.immS32, REG_RESV_TEMP);
|
||||
@@ -668,7 +669,7 @@ bool PPCRecompilerX64Gen_imlInstruction_fpr_store(PPCRecFunction_t* PPCRecFuncti
|
||||
}
|
||||
else if( mode == PPCREC_FPR_ST_MODE_UI32_FROM_PS0 )
|
||||
{
|
||||
if( hasAVXSupport )
|
||||
if( g_CPUFeatures.x86.avx )
|
||||
{
|
||||
x64Gen_movd_reg64Low32_xmmReg(x64GenContext, REG_RESV_TEMP, realRegisterXMM);
|
||||
}
|
||||
@@ -749,7 +750,7 @@ void PPCRecompilerX64Gen_imlInstruction_fpr_r_r(PPCRecFunction_t* PPCRecFunction
|
||||
// unpack top to bottom and top
|
||||
x64Gen_unpckhpd_xmmReg_xmmReg(x64GenContext, imlInstruction->op_fpr_r_r.registerResult, imlInstruction->op_fpr_r_r.registerOperand);
|
||||
}
|
||||
//else if ( hasAVXSupport )
|
||||
//else if ( g_CPUFeatures.x86.avx )
|
||||
//{
|
||||
// // unpack top to bottom and top with non-destructive destination
|
||||
// // update: On Ivy Bridge this causes weird stalls?
|
||||
@@ -1056,7 +1057,7 @@ void PPCRecompilerX64Gen_imlInstruction_fpr_r_r_r(PPCRecFunction_t* PPCRecFuncti
|
||||
{
|
||||
x64Gen_subpd_xmmReg_xmmReg(x64GenContext, imlInstruction->op_fpr_r_r_r.registerResult, imlInstruction->op_fpr_r_r_r.registerOperandB);
|
||||
}
|
||||
else if (hasAVXSupport)
|
||||
else if (g_CPUFeatures.x86.avx)
|
||||
{
|
||||
x64Gen_avx_VSUBPD_xmm_xmm_xmm(x64GenContext, imlInstruction->op_fpr_r_r_r.registerResult, imlInstruction->op_fpr_r_r_r.registerOperandA, imlInstruction->op_fpr_r_r_r.registerOperandB);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#include "Cafe/HW/Latte/Core/LatteConst.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Renderer.h"
|
||||
|
||||
#include "Cafe/HW/Latte/ISA/RegDefines.h"
|
||||
#include "Common/cpu_features.h"
|
||||
|
||||
#if defined(ARCH_X86_64)
|
||||
#if __GNUC__
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
@@ -14,6 +15,7 @@
|
||||
#define ATTRIBUTE_AVX2
|
||||
#define ATTRIBUTE_SSE41
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct
|
||||
{
|
||||
@@ -292,6 +294,7 @@ void LatteIndices_generateAutoLineLoopIndices(void* indexDataOutput, uint32 coun
|
||||
indexMax = std::max(count, 1u) - 1;
|
||||
}
|
||||
|
||||
#if defined(ARCH_X86_64)
|
||||
ATTRIBUTE_AVX2
|
||||
void LatteIndices_fastConvertU16_AVX2(const void* indexDataInput, void* indexDataOutput, uint32 count, uint32& indexMin, uint32& indexMax)
|
||||
{
|
||||
@@ -487,6 +490,7 @@ void LatteIndices_fastConvertU32_AVX2(const void* indexDataInput, void* indexDat
|
||||
indexMax = std::max(indexMax, _maxIndex);
|
||||
indexMin = std::min(indexMin, _minIndex);
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename T>
|
||||
void _LatteIndices_alternativeCalculateIndexMinMax(const void* indexData, uint32 count, uint32 primitiveRestartIndex, uint32& indexMin, uint32& indexMax)
|
||||
@@ -669,19 +673,27 @@ void LatteIndices_decode(const void* indexData, LatteIndexType indexType, uint32
|
||||
{
|
||||
if (indexType == LatteIndexType::U16_BE)
|
||||
{
|
||||
if (_cpuExtension_AVX2)
|
||||
#if defined(ARCH_X86_64)
|
||||
if (g_CPUFeatures.x86.avx2)
|
||||
LatteIndices_fastConvertU16_AVX2(indexData, indexOutputPtr, count, indexMin, indexMax);
|
||||
else if (_cpuExtension_SSE4_1 && _cpuExtension_SSSE3)
|
||||
else if (g_CPUFeatures.x86.sse4_1 && g_CPUFeatures.x86.ssse3)
|
||||
LatteIndices_fastConvertU16_SSE41(indexData, indexOutputPtr, count, indexMin, indexMax);
|
||||
else
|
||||
LatteIndices_convertBE<uint16>(indexData, indexOutputPtr, count, indexMin, indexMax);
|
||||
#else
|
||||
LatteIndices_convertBE<uint16>(indexData, indexOutputPtr, count, indexMin, indexMax);
|
||||
#endif
|
||||
}
|
||||
else if (indexType == LatteIndexType::U32_BE)
|
||||
{
|
||||
if (_cpuExtension_AVX2)
|
||||
#if defined(ARCH_X86_64)
|
||||
if (g_CPUFeatures.x86.avx2)
|
||||
LatteIndices_fastConvertU32_AVX2(indexData, indexOutputPtr, count, indexMin, indexMax);
|
||||
else
|
||||
LatteIndices_convertBE<uint32>(indexData, indexOutputPtr, count, indexMin, indexMax);
|
||||
#else
|
||||
LatteIndices_convertBE<uint32>(indexData, indexOutputPtr, count, indexMin, indexMax);
|
||||
#endif
|
||||
}
|
||||
else if (indexType == LatteIndexType::U16_LE)
|
||||
{
|
||||
@@ -714,4 +726,4 @@ void LatteIndices_decode(const void* indexData, LatteIndexType indexType, uint32
|
||||
LatteIndexCache.outputCount = outputCount;
|
||||
LatteIndexCache.indexBufferOffset = indexBufferOffset;
|
||||
LatteIndexCache.indexBufferIndex = indexBufferIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "Cafe/HW/Latte/Core/LatteDraw.h"
|
||||
#include "Cafe/HW/Latte/Core/LatteTexture.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Renderer.h"
|
||||
#include "Common/cpu_features.h"
|
||||
|
||||
std::unordered_set<LatteTexture*> g_allTextures;
|
||||
|
||||
@@ -146,7 +147,7 @@ uint32 LatteTexture_CalculateTextureDataHash(LatteTexture* hostTexture)
|
||||
if( isCompressedFormat == false )
|
||||
{
|
||||
#if BOOST_OS_WINDOWS
|
||||
if (_cpuExtension_AVX2)
|
||||
if (g_CPUFeatures.x86.avx2)
|
||||
{
|
||||
__m256i h256 = { 0 };
|
||||
__m256i* readPtr = (__m256i*)texDataU32;
|
||||
|
||||
@@ -1075,7 +1075,9 @@ namespace coreinit
|
||||
{
|
||||
OSHostThread* hostThread = (OSHostThread*)_thread;
|
||||
|
||||
#if defined(ARCH_X86_64)
|
||||
_mm_setcsr(_mm_getcsr() | 0x8000); // flush denormals to zero
|
||||
#endif
|
||||
|
||||
uint32 lehmer_lcg = 12345;
|
||||
|
||||
@@ -1116,7 +1118,9 @@ namespace coreinit
|
||||
{
|
||||
SetThreadName(fmt::format("OSSchedulerThread[core={}]", (uintptr_t)_assignedCoreIndex).c_str());
|
||||
t_assignedCoreIndex = (sint32)(uintptr_t)_assignedCoreIndex;
|
||||
#if defined(ARCH_X86_64)
|
||||
_mm_setcsr(_mm_getcsr() | 0x8000); // flush denormals to zero
|
||||
#endif
|
||||
t_schedulerFiber = Fiber::PrepareCurrentThread();
|
||||
|
||||
// create scheduler idle fiber and switch to it
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
add_library(CemuCommon
|
||||
betype.h
|
||||
cpu_features.cpp
|
||||
cpu_features.h
|
||||
enumFlags.h
|
||||
ExceptionHandler/ExceptionHandler.h
|
||||
FileStream.h
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
#include "cpu_features.h"
|
||||
|
||||
// wrappers with uniform prototype for implementation-specific x86 CPU id
|
||||
#if defined(ARCH_X86_64)
|
||||
#ifdef __GNUC__
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
|
||||
inline void cpuid(int cpuInfo[4], int functionId) {
|
||||
#if defined(_MSC_VER)
|
||||
__cpuid(cpuInfo, functionId);
|
||||
#elif defined(__GNUC__)
|
||||
__cpuid(functionId, cpuInfo[0], cpuInfo[1], cpuInfo[2], cpuInfo[3]);
|
||||
#else
|
||||
#error No definition for cpuid
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void cpuidex(int cpuInfo[4], int functionId, int subFunctionId) {
|
||||
#if defined(_MSC_VER)
|
||||
__cpuidex(cpuInfo, functionId, subFunctionId);
|
||||
#elif defined(__GNUC__)
|
||||
__cpuid_count(functionId, subFunctionId, cpuInfo[0], cpuInfo[1], cpuInfo[2], cpuInfo[3]);
|
||||
#else
|
||||
#error No definition for cpuidex
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
CPUFeaturesImpl::CPUFeaturesImpl()
|
||||
{
|
||||
#if defined(ARCH_X86_64)
|
||||
int cpuInfo[4];
|
||||
cpuid(cpuInfo, 0x80000001);
|
||||
x86.lzcnt = ((cpuInfo[2] >> 5) & 1) != 0;
|
||||
cpuid(cpuInfo, 0x1);
|
||||
x86.movbe = ((cpuInfo[2] >> 22) & 1) != 0;
|
||||
x86.avx = ((cpuInfo[2] >> 28) & 1) != 0;
|
||||
x86.aesni = ((cpuInfo[2] >> 25) & 1) != 0;
|
||||
x86.ssse3 = ((cpuInfo[2] >> 9) & 1) != 0;
|
||||
x86.sse4_1 = ((cpuInfo[2] >> 19) & 1) != 0;
|
||||
cpuidex(cpuInfo, 0x7, 0);
|
||||
x86.avx2 = ((cpuInfo[1] >> 5) & 1) != 0;
|
||||
x86.bmi2 = ((cpuInfo[1] >> 8) & 1) != 0;
|
||||
cpuid(cpuInfo, 0x80000007);
|
||||
x86.invariant_tsc = ((cpuInfo[3] >> 8) & 1);
|
||||
// get CPU brand name
|
||||
uint32_t nExIds, i = 0;
|
||||
memset(m_cpuBrandName, 0, sizeof(m_cpuBrandName));
|
||||
cpuid(cpuInfo, 0x80000000);
|
||||
nExIds = (uint32_t)cpuInfo[0];
|
||||
for (uint32_t i = 0x80000000; i <= nExIds; ++i)
|
||||
{
|
||||
cpuid(cpuInfo, i);
|
||||
if (i == 0x80000002)
|
||||
memcpy(m_cpuBrandName, cpuInfo, sizeof(cpuInfo));
|
||||
else if (i == 0x80000003)
|
||||
memcpy(m_cpuBrandName + 16, cpuInfo, sizeof(cpuInfo));
|
||||
else if (i == 0x80000004)
|
||||
memcpy(m_cpuBrandName + 32, cpuInfo, sizeof(cpuInfo));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string CPUFeaturesImpl::GetCPUName()
|
||||
{
|
||||
return { m_cpuBrandName };
|
||||
}
|
||||
|
||||
std::string CPUFeaturesImpl::GetCommaSeparatedExtensionList()
|
||||
{
|
||||
std::string tmp;
|
||||
auto appendExt = [&tmp](const char* str)
|
||||
{
|
||||
if (!tmp.empty())
|
||||
tmp.append(", ");
|
||||
tmp.append(str);
|
||||
};
|
||||
if (x86.ssse3)
|
||||
appendExt("SSSE3");
|
||||
if (x86.sse4_1)
|
||||
appendExt("SSE4.1");
|
||||
if (x86.avx)
|
||||
appendExt("AVX");
|
||||
if (x86.avx2)
|
||||
appendExt("AVX2");
|
||||
if (x86.lzcnt)
|
||||
appendExt("LZCNT");
|
||||
if (x86.movbe)
|
||||
appendExt("MOVBE");
|
||||
if (x86.bmi2)
|
||||
appendExt("BMI2");
|
||||
if (x86.aesni)
|
||||
appendExt("AES-NI");
|
||||
if(x86.invariant_tsc)
|
||||
appendExt("INVARIANT-TSC");
|
||||
return tmp;
|
||||
}
|
||||
|
||||
CPUFeaturesImpl g_CPUFeatures;
|
||||
@@ -0,0 +1,26 @@
|
||||
|
||||
class CPUFeaturesImpl
|
||||
{
|
||||
public:
|
||||
CPUFeaturesImpl();
|
||||
|
||||
std::string GetCPUName(); // empty if not available
|
||||
std::string GetCommaSeparatedExtensionList();
|
||||
|
||||
struct
|
||||
{
|
||||
bool ssse3{ false };
|
||||
bool sse4_1{ false };
|
||||
bool avx{ false };
|
||||
bool avx2{ false };
|
||||
bool lzcnt{ false };
|
||||
bool movbe{ false };
|
||||
bool bmi2{ false };
|
||||
bool aesni{ false };
|
||||
bool invariant_tsc{ false };
|
||||
}x86;
|
||||
private:
|
||||
char m_cpuBrandName[0x40]{ 0 };
|
||||
};
|
||||
|
||||
extern CPUFeaturesImpl g_CPUFeatures;
|
||||
+33
-24
@@ -24,13 +24,22 @@
|
||||
// }
|
||||
// #endif
|
||||
|
||||
// arch defines
|
||||
|
||||
#if defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64)
|
||||
#define ARCH_X86_64
|
||||
#endif
|
||||
|
||||
// c includes
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
#include <cassert>
|
||||
|
||||
#if defined(ARCH_X86_64)
|
||||
#include <immintrin.h>
|
||||
#endif
|
||||
|
||||
// c++ includes
|
||||
#include <string>
|
||||
@@ -106,11 +115,6 @@ using uint8le = uint8_t;
|
||||
#include "Cemu/Logging/CemuDebugLogging.h"
|
||||
#include "Cemu/Logging/CemuLogging.h"
|
||||
|
||||
// CPU extensions
|
||||
extern bool _cpuExtension_SSSE3;
|
||||
extern bool _cpuExtension_SSE4_1;
|
||||
extern bool _cpuExtension_AVX2;
|
||||
|
||||
// manual endian-swapping
|
||||
|
||||
#if _MSC_VER
|
||||
@@ -251,30 +255,35 @@ inline uint64 _udiv128(uint64 highDividend, uint64 lowDividend, uint64 divisor,
|
||||
#define NOEXPORT __attribute__ ((visibility ("hidden")))
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#include <cpuid.h>
|
||||
#endif
|
||||
// On aarch64 we handle some of the x86 intrinsics by implementing them as wrappers
|
||||
#if defined(__aarch64__)
|
||||
|
||||
inline void cpuid(int cpuInfo[4], int functionId) {
|
||||
#if defined(_MSC_VER)
|
||||
__cpuid(cpuInfo, functionId);
|
||||
#elif defined(__GNUC__)
|
||||
__cpuid(functionId, cpuInfo[0], cpuInfo[1], cpuInfo[2], cpuInfo[3]);
|
||||
#else
|
||||
#error No definition for cpuid
|
||||
#endif
|
||||
inline void _mm_pause()
|
||||
{
|
||||
asm volatile("yield");
|
||||
}
|
||||
|
||||
inline void cpuidex(int cpuInfo[4], int functionId, int subFunctionId) {
|
||||
#if defined(_MSC_VER)
|
||||
__cpuidex(cpuInfo, functionId, subFunctionId);
|
||||
#elif defined(__GNUC__)
|
||||
__cpuid_count(functionId, subFunctionId, cpuInfo[0], cpuInfo[1], cpuInfo[2], cpuInfo[3]);
|
||||
#else
|
||||
#error No definition for cpuidex
|
||||
#endif
|
||||
inline uint64 __rdtsc()
|
||||
{
|
||||
uint64 t;
|
||||
asm volatile("mrs %0, cntvct_el0" : "=r" (t));
|
||||
return t;
|
||||
}
|
||||
|
||||
inline void _mm_mfence()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
inline unsigned char _addcarry_u64(unsigned char carry, unsigned long long a, unsigned long long b, unsigned long long *result)
|
||||
{
|
||||
*result = a + b + (unsigned long long)carry;
|
||||
if (*result < a)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// MEMPTR
|
||||
#include "Common/MemPtr.h"
|
||||
|
||||
+39
-31
@@ -1,39 +1,47 @@
|
||||
project(CemuAsm C)
|
||||
|
||||
if (WIN32)
|
||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "(x86)|(X86)|(amd64)|(AMD64)")
|
||||
|
||||
enable_language(C ASM_MASM)
|
||||
if (WIN32)
|
||||
|
||||
add_library(CemuAsm x64util_masm.asm)
|
||||
set_source_files_properties(x64util_masm.asm PROPERTIES LANGUAGE ASM_MASM)
|
||||
enable_language(C ASM_MASM)
|
||||
|
||||
# workaround for cr flag being passed to LINK.exe which considers it an input file and thus fails
|
||||
# doesn't always seem to happen. The Windows CI builds were fine, but locally I would run into this problem
|
||||
# possibly related to https://gitlab.kitware.com/cmake/cmake/-/issues/18889
|
||||
set(CMAKE_ASM_MASM_CREATE_STATIC_LIBRARY "<CMAKE_AR> /OUT:<TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
add_library(CemuAsm x64util_masm.asm)
|
||||
set_source_files_properties(x64util_masm.asm PROPERTIES LANGUAGE ASM_MASM)
|
||||
|
||||
# workaround for cr flag being passed to LINK.exe which considers it an input file and thus fails
|
||||
# doesn't always seem to happen. The Windows CI builds were fine, but locally I would run into this problem
|
||||
# possibly related to https://gitlab.kitware.com/cmake/cmake/-/issues/18889
|
||||
set(CMAKE_ASM_MASM_CREATE_STATIC_LIBRARY "<CMAKE_AR> /OUT:<TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
|
||||
set_property(TARGET CemuAsm PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
|
||||
else()
|
||||
|
||||
# NASM
|
||||
if (APPLE)
|
||||
set(CMAKE_ASM_NASM_COMPILE_OBJECT "<CMAKE_ASM_NASM_COMPILER> -g -Fdwarf -f macho64 --prefix _ -o <OBJECT> <SOURCE>")
|
||||
else()
|
||||
set(CMAKE_ASM_NASM_COMPILE_OBJECT "<CMAKE_ASM_NASM_COMPILER> -g -Fdwarf -f elf64 -o <OBJECT> <SOURCE>")
|
||||
endif()
|
||||
set(CMAKE_ASM_NASM_LINK_EXECUTABLE "ld <FLAGS> <CMAKE_ASM_NASM_LINK_FLAGS> <LINK_FLAGS> -fPIC <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
|
||||
|
||||
enable_language(C ASM_NASM)
|
||||
|
||||
add_library(CemuAsm x64util_nasm.asm)
|
||||
set_source_files_properties(x64util_nasm.asm PROPERTIES LANGUAGE ASM_NASM)
|
||||
|
||||
if (APPLE)
|
||||
set_target_properties(CemuAsm PROPERTIES NASM_OBJ_FORMAT macho64)
|
||||
else()
|
||||
set_target_properties(CemuAsm PROPERTIES NASM_OBJ_FORMAT elf64)
|
||||
endif()
|
||||
set_target_properties(CemuAsm PROPERTIES LINKER_LANGUAGE C)
|
||||
|
||||
endif()
|
||||
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "(aarch64)|(AARCH64)")
|
||||
add_library(CemuAsm stub.cpp)
|
||||
else()
|
||||
|
||||
# NASM
|
||||
if (APPLE)
|
||||
set(CMAKE_ASM_NASM_COMPILE_OBJECT "<CMAKE_ASM_NASM_COMPILER> -g -Fdwarf -f macho64 --prefix _ -o <OBJECT> <SOURCE>")
|
||||
else()
|
||||
set(CMAKE_ASM_NASM_COMPILE_OBJECT "<CMAKE_ASM_NASM_COMPILER> -g -Fdwarf -f elf64 -o <OBJECT> <SOURCE>")
|
||||
endif()
|
||||
set(CMAKE_ASM_NASM_LINK_EXECUTABLE "ld <FLAGS> <CMAKE_ASM_NASM_LINK_FLAGS> <LINK_FLAGS> -fPIC <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
|
||||
|
||||
enable_language(C ASM_NASM)
|
||||
|
||||
add_library(CemuAsm x64util_nasm.asm)
|
||||
set_source_files_properties(x64util_nasm.asm PROPERTIES LANGUAGE ASM_NASM)
|
||||
|
||||
if (APPLE)
|
||||
set_target_properties(CemuAsm PROPERTIES NASM_OBJ_FORMAT macho64)
|
||||
else()
|
||||
set_target_properties(CemuAsm PROPERTIES NASM_OBJ_FORMAT elf64)
|
||||
endif()
|
||||
set_target_properties(CemuAsm PROPERTIES LINKER_LANGUAGE C)
|
||||
|
||||
message(STATUS "CemuAsm - Unsupported arch: ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
endif()
|
||||
|
||||
set_property(TARGET CemuAsm PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
|
||||
@@ -1,4 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#if defined(ARCH_X86_64)
|
||||
|
||||
extern "C" void recompiler_fres();
|
||||
extern "C" void recompiler_frsqrte();
|
||||
|
||||
#else
|
||||
|
||||
// stubbed on non-x86 for now
|
||||
static void recompiler_fres()
|
||||
{
|
||||
cemu_assert_unimplemented();
|
||||
}
|
||||
static void recompiler_frsqrte()
|
||||
{
|
||||
cemu_assert_unimplemented();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -64,6 +64,7 @@ void CemuConfig::Load(XMLConfigParser& parser)
|
||||
save_screenshot = parser.get("save_screenshot", save_screenshot);
|
||||
did_show_vulkan_warning = parser.get("vk_warning", did_show_vulkan_warning);
|
||||
did_show_graphic_pack_download = parser.get("gp_download", did_show_graphic_pack_download);
|
||||
did_show_macos_disclaimer = parser.get("macos_disclaimer", did_show_macos_disclaimer);
|
||||
fullscreen = parser.get("fullscreen", fullscreen);
|
||||
proxy_server = parser.get("proxy_server", "");
|
||||
|
||||
@@ -365,6 +366,7 @@ void CemuConfig::Save(XMLConfigParser& parser)
|
||||
config.set<bool>("save_screenshot", save_screenshot);
|
||||
config.set<bool>("vk_warning", did_show_vulkan_warning);
|
||||
config.set<bool>("gp_download", did_show_graphic_pack_download);
|
||||
config.set<bool>("macos_disclaimer", did_show_macos_disclaimer);
|
||||
config.set<bool>("fullscreen", fullscreen);
|
||||
config.set("proxy_server", proxy_server.GetValue().c_str());
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user