/* 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;