/* 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
#ifdef __CYGWIN__
#define __linux__
#endif
// make sure __POSIX__ is defined for all systems where we assume POSIX
// compliance
#if defined(__linux__) || defined(__APPLE__) || defined(__unix__) || defined(__CYGWIN__) || defined(__LINUX__)
#if !defined(__POSIX__)
#define __POSIX__ 1
#endif
#endif
#include "Pcsx2Types.h"
#include "common/emitter/x86_intrin.h"
// The C++ standard doesn't allow `offsetof` to be used on non-constant values (e.g. `offsetof(class, field[i])`)
// Use this in those situations
#define OFFSETOF(a, b) (reinterpret_cast(&(static_cast(0)->b)))
// Renamed ARRAYSIZE to ArraySize -- looks nice and gets rid of Windows.h conflicts (air)
// Notes: I'd have used ARRAY_SIZE instead but ran into cross-platform lib conflicts with
// that as well. >_<
#ifndef ArraySize
#define ArraySize(x) (sizeof(x) / sizeof((x)[0]))
#endif
// --------------------------------------------------------------------------------------
// Dev / Debug conditionals - Consts for using if() statements instead of uglier #ifdef.
// --------------------------------------------------------------------------------------
// Note: Using if() optimizes nicely in Devel and Release builds, but will generate extra
// code overhead in debug builds (since debug neither inlines, nor optimizes out const-
// level conditionals). Normally not a concern, but if you stick if( IsDevbuild ) in
// some tight loops it will likely make debug builds unusably slow.
//
#ifdef PCSX2_DEVBUILD
static const bool IsDevBuild = true;
#else
static const bool IsDevBuild = false;
#endif
#ifdef PCSX2_DEBUG
static const bool IsDebugBuild = true;
#else
static const bool IsDebugBuild = false;
#endif
#ifdef PCSX2_DEBUG
#define pxDebugCode(code) code
#else
#define pxDebugCode(code)
#endif
#ifdef PCSX2_DEVBUILD
#define pxDevelCode(code) code
#else
#define pxDevelCode(code)
#endif
#if defined(PCSX2_DEBUG) || defined(PCSX2_DEVBUILD)
#define pxReleaseCode(code)
#define pxNonReleaseCode(code) code
#else
#define pxReleaseCode(code) code
#define pxNonReleaseCode(code)
#endif
// --------------------------------------------------------------------------------------
// __aligned / __aligned16 / __pagealigned
// --------------------------------------------------------------------------------------
// GCC Warning! The GCC linker (LD) typically fails to assure alignment of class members.
// If you want alignment to be assured, the variable must either be a member of a struct
// or a static global.
//
// __pagealigned is equivalent to __aligned(0x1000), and is used to align a dynarec code
// buffer to a page boundary (allows the use of execution-enabled mprotect).
//
// General Performance Warning: Any function that specifies alignment on a local (stack)
// variable will have to align the stack frame on enter, and restore it on exit (adds
// overhead). Furthermore, compilers cannot inline functions that have aligned local
// vars. So use local var alignment with much caution.
//
// Defines the memory page size for the target platform at compilation. All supported platforms
// (which means Intel only right now) have a 4k granularity.
#define PCSX2_PAGESIZE 0x1000
static const int __pagesize = PCSX2_PAGESIZE;
// --------------------------------------------------------------------------------------
// Microsoft Visual Studio
// --------------------------------------------------------------------------------------
#ifdef _MSC_VER
// Using these breaks compat with VC2005; so we're not using it yet.
//# define __pack_begin __pragma(pack(1))
//# define __pack_end __pragma(pack())
// This is the 2005/earlier compatible packing define, which must be used in conjunction
// with #ifdef _MSC_VER/#pragma pack() directives (ugly).
#define __packed
#define __aligned(alig) __declspec(align(alig))
#define __aligned16 __declspec(align(16))
#define __aligned32 __declspec(align(32))
#define __pagealigned __declspec(align(PCSX2_PAGESIZE))
#define __noinline __declspec(noinline)
#define __noreturn __declspec(noreturn)
// Don't know if there are Visual C++ equivalents of these.
#define likely(x) (!!(x))
#define unlikely(x) (!!(x))
#define CALLBACK __stdcall
#else
// --------------------------------------------------------------------------------------
// GCC / Intel Compilers Section
// --------------------------------------------------------------------------------------
#ifndef __packed
#define __packed __attribute__((packed))
#endif
#ifndef __aligned
#define __aligned(alig) __attribute__((aligned(alig)))
#endif
#define __aligned16 __attribute__((aligned(16)))
#define __aligned32 __attribute__((aligned(32)))
#define __pagealigned __attribute__((aligned(PCSX2_PAGESIZE)))
#define __assume(cond) ((void)0) // GCC has no equivalent for __assume
#define CALLBACK __attribute__((stdcall))
// Inlining note: GCC needs ((unused)) attributes defined on inlined functions to suppress
// warnings when a static inlined function isn't used in the scope of a single file (which
// happens *by design* like all the friggen time >_<)
#ifndef __fastcall
#define __fastcall __attribute__((fastcall))
#endif
#define __vectorcall __fastcall
#define _inline __inline__ __attribute__((unused))
#ifdef NDEBUG
#define __forceinline __attribute__((always_inline, unused))
#else
#define __forceinline __attribute__((unused))
#endif
#ifndef __noinline
#define __noinline __attribute__((noinline))
#endif
#ifndef __noreturn
#define __noreturn __attribute__((noreturn))
#endif
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#endif
// --------------------------------------------------------------------------------------
// __releaseinline / __ri -- a forceinline macro that is enabled for RELEASE/PUBLIC builds ONLY.
// --------------------------------------------------------------------------------------
// This is useful because forceinline can make certain types of debugging problematic since
// functions that look like they should be called won't breakpoint since their code is
// inlined, and it can make stack traces confusing or near useless.
//
// Use __releaseinline for things which are generally large functions where trace debugging
// from Devel builds is likely useful; but which should be inlined in an optimized Release
// environment.
//
#ifdef PCSX2_DEVBUILD
#define __releaseinline
#else
#define __releaseinline __forceinline
#endif
#define __ri __releaseinline
#define __fi __forceinline
#define __fc __fastcall