/* PCSX2 - PS2 Emulator for PCs * Copyright (C) 2002-2010 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 . */ #pragma once #include "x86emitter.h" enum x86VendorType { x86Vendor_Intel = 0, x86Vendor_AMD = 1, x86Vendor_Unknown = 2 }; // -------------------------------------------------------------------------------------- // x86capabilities // -------------------------------------------------------------------------------------- class x86capabilities { public: bool isIdentified; public: x86VendorType VendorID; uint FamilyID; // Processor Family uint Model; // Processor Model uint TypeID; // Processor Type uint StepID; // Stepping ID u32 Flags; // Feature Flags u32 Flags2; // More Feature Flags u32 EFlags; // Extended Feature Flags u32 EFlags2; // Extended Feature Flags pg2 u32 SEFlag; // Structured Extended Feature Flags Enumeration char VendorName[16]; // Vendor/Creator ID char FamilyName[50]; // the original cpu name // ---------------------------------------------------------------------------- // x86 CPU Capabilities Section (all boolean flags!) // ---------------------------------------------------------------------------- union { struct { u32 hasFloatingPointUnit :1; u32 hasVirtual8086ModeEnhancements :1; u32 hasDebuggingExtensions :1; u32 hasPageSizeExtensions :1; u32 hasTimeStampCounter :1; u32 hasModelSpecificRegisters :1; u32 hasPhysicalAddressExtension :1; u32 hasCOMPXCHG8BInstruction :1; u32 hasAdvancedProgrammableInterruptController :1; u32 hasSEPFastSystemCall :1; u32 hasMemoryTypeRangeRegisters :1; u32 hasPTEGlobalFlag :1; u32 hasMachineCheckArchitecture :1; u32 hasConditionalMoveAndCompareInstructions :1; u32 hasFGPageAttributeTable :1; u32 has36bitPageSizeExtension :1; u32 hasProcessorSerialNumber :1; u32 hasCFLUSHInstruction :1; u32 hasDebugStore :1; u32 hasACPIThermalMonitorAndClockControl :1; u32 hasFastStreamingSIMDExtensionsSaveRestore :1; u32 hasStreamingSIMDExtensions :1; u32 hasStreamingSIMD2Extensions :1; u32 hasSelfSnoop :1; // is TRUE for both multi-core and Hyperthreaded CPUs. u32 hasMultiThreading :1; u32 hasThermalMonitor :1; u32 hasIntel64BitArchitecture :1; u32 hasStreamingSIMD3Extensions :1; u32 hasSupplementalStreamingSIMD3Extensions :1; u32 hasStreamingSIMD4Extensions :1; u32 hasStreamingSIMD4Extensions2 :1; u32 hasAVX :1; u32 hasAVX2 :1; u32 hasBMI1 :1; u32 hasBMI2 :1; u32 hasFMA :1; // AMD-specific CPU Features u32 hasAMD64BitArchitecture :1; u32 hasStreamingSIMD4ExtensionsA :1; }; u64 AllCapabilities; }; // Core Counts! u32 PhysicalCores; u32 LogicalCores; public: x86capabilities(); void Identify(); void CountCores(); wxString GetTypeName() const; u32 CalculateMHz() const; void SIMD_EstablishMXCSRmask(); protected: s64 _CPUSpeedHz( u64 time ) const; void CountLogicalCores(); }; enum SSE_RoundMode { SSE_RoundMode_FIRST = 0, SSEround_Nearest = 0, SSEround_NegInf, SSEround_PosInf, SSEround_Chop, SSE_RoundMode_COUNT }; ImplementEnumOperators( SSE_RoundMode ); // -------------------------------------------------------------------------------------- // SSE_MXCSR - Control/Status Register (bitfield) // -------------------------------------------------------------------------------------- // Bits 0-5 are exception flags; used only if SSE exceptions have been enabled. // Bits in this field are "sticky" and, once an exception has occured, must be manually // cleared using LDMXCSR or FXRSTOR. // // Bits 7-12 are the masks for disabling the exceptions in bits 0-5. Cleared bits allow // exceptions, set bits mask exceptions from being raised. // union SSE_MXCSR { u32 bitmask; struct { u32 InvalidOpFlag :1, DenormalFlag :1, DivideByZeroFlag :1, OverflowFlag :1, UnderflowFlag :1, PrecisionFlag :1, // This bit is supported only on SSE2 or better CPUs. Setting it to 1 on // SSE1 cpus will result in an invalid instruction exception when executing // LDMXSCR. DenormalsAreZero :1, InvalidOpMask :1, DenormalMask :1, DivideByZeroMask :1, OverflowMask :1, UnderflowMask :1, PrecisionMask :1, RoundingControl :2, FlushToZero :1; }; SSE_RoundMode GetRoundMode() const; SSE_MXCSR& SetRoundMode( SSE_RoundMode mode ); SSE_MXCSR& ClearExceptionFlags(); SSE_MXCSR& EnableExceptions(); SSE_MXCSR& DisableExceptions(); SSE_MXCSR& ApplyReserveMask(); bool operator ==( const SSE_MXCSR& right ) const { return bitmask == right.bitmask; } bool operator !=( const SSE_MXCSR& right ) const { return bitmask != right.bitmask; } operator x86Emitter::xIndirect32() const; }; extern SSE_MXCSR MXCSR_Mask; extern __aligned16 x86capabilities x86caps;