mirror of
https://github.com/libretro/beetle-gba-libretro.git
synced 2025-02-22 09:34:17 +00:00
Reimplement cputest.c for libretro
This commit is contained in:
parent
2011ba7926
commit
87abd627d6
1
Makefile
1
Makefile
@ -605,7 +605,6 @@ FLAGS += $(ENDIANNESS_DEFINES) -DSIZEOF_DOUBLE=8 $(WARNINGS) -DMEDNAFEN_VERSION=
|
||||
|
||||
ifeq ($(IS_X86), 1)
|
||||
FLAGS += -DARCH_X86
|
||||
CORE_SOURCES += $(MEDNAFEN_DIR)/cputest/x86_cpu.c
|
||||
endif
|
||||
|
||||
ifeq ($(CACHE_CD), 1)
|
||||
|
10
libretro.cpp
10
libretro.cpp
@ -9,6 +9,9 @@
|
||||
#include "libretro.h"
|
||||
|
||||
static MDFNGI *game;
|
||||
|
||||
struct retro_perf_callback perf_cb;
|
||||
retro_get_cpu_features_t perf_get_cpu_features_cb = NULL;
|
||||
retro_log_printf_t log_cb;
|
||||
static retro_video_refresh_t video_cb;
|
||||
static retro_audio_sample_t audio_cb;
|
||||
@ -363,7 +366,7 @@ static struct retro_disk_control_callback disk_interface = {
|
||||
};
|
||||
#endif
|
||||
|
||||
void retro_init()
|
||||
void retro_init(void)
|
||||
{
|
||||
struct retro_log_callback log;
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_LOG_INTERFACE, &log))
|
||||
@ -427,6 +430,11 @@ void retro_init()
|
||||
environ_cb(RETRO_ENVIRONMENT_SET_DISK_CONTROL_INTERFACE, &disk_interface);
|
||||
#endif
|
||||
|
||||
if (environ_cb(RETRO_ENVIRONMENT_GET_PERF_INTERFACE, &perf_cb))
|
||||
perf_get_cpu_features_cb = perf_cb.get_cpu_features;
|
||||
else
|
||||
perf_get_cpu_features_cb = NULL;
|
||||
|
||||
check_system_specs();
|
||||
}
|
||||
|
||||
|
215
libretro.h
215
libretro.h
@ -27,11 +27,13 @@
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
|
||||
// Hack applied for MSVC when compiling in C89 mode as it isn't C99 compliant.
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#else
|
||||
#if defined(_MSC_VER) && !defined(SN_TARGET_PS3) && !defined(__cplusplus)
|
||||
#endif
|
||||
|
||||
#ifndef __cplusplus
|
||||
#if defined(_MSC_VER) && !defined(SN_TARGET_PS3)
|
||||
/* Hack applied for MSVC when compiling in C89 mode as it isn't C99 compliant. */
|
||||
#define bool unsigned char
|
||||
#define true 1
|
||||
#define false 0
|
||||
@ -44,8 +46,22 @@ extern "C" {
|
||||
// It is not incremented for compatible changes to the API.
|
||||
#define RETRO_API_VERSION 1
|
||||
|
||||
// Libretro's fundamental device abstractions.
|
||||
#define RETRO_DEVICE_MASK 0xff
|
||||
//
|
||||
// Libretros fundamental device abstractions.
|
||||
/////////
|
||||
//
|
||||
// Libretros input system consists of some standardized device types such as a joypad (with/without analog),
|
||||
// mouse, keyboard, lightgun and a pointer. The functionality of these devices are fixed, and individual cores map
|
||||
// their own concept of a controller to libretros abstractions.
|
||||
// This makes it possible for frontends to map the abstract types to a real input device,
|
||||
// and not having to worry about binding input correctly to arbitrary controller layouts.
|
||||
|
||||
|
||||
#define RETRO_DEVICE_TYPE_SHIFT 8
|
||||
#define RETRO_DEVICE_MASK ((1 << RETRO_DEVICE_TYPE_SHIFT) - 1)
|
||||
#define RETRO_DEVICE_SUBCLASS(base, id) (((id + 1) << RETRO_DEVICE_TYPE_SHIFT) | base)
|
||||
|
||||
// Input disabled.
|
||||
#define RETRO_DEVICE_NONE 0
|
||||
|
||||
// The JOYPAD is called RetroPad. It is essentially a Super Nintendo controller,
|
||||
@ -60,6 +76,7 @@ extern "C" {
|
||||
|
||||
// KEYBOARD device lets one poll for raw key pressed.
|
||||
// It is poll based, so input callback will return with the current pressed state.
|
||||
// For event/text based keyboard input, see RETRO_ENVIRONMENT_SET_KEYBOARD_CALLBACK.
|
||||
#define RETRO_DEVICE_KEYBOARD 3
|
||||
|
||||
// Lightgun X/Y coordinates are reported relatively to last poll, similar to mouse.
|
||||
@ -85,7 +102,7 @@ extern "C" {
|
||||
//
|
||||
// To check if the pointer coordinates are valid (e.g. a touch display actually being touched),
|
||||
// PRESSED returns 1 or 0.
|
||||
// If using a mouse, PRESSED will usually correspond to the left mouse button.
|
||||
// If using a mouse on a desktop, PRESSED will usually correspond to the left mouse button, but this is a frontend decision.
|
||||
// PRESSED will only return 1 if the pointer is inside the game screen.
|
||||
//
|
||||
// For multi-touch, the index variable can be used to successively query more presses.
|
||||
@ -94,16 +111,6 @@ extern "C" {
|
||||
// Eventually _PRESSED will return false for an index. No further presses are registered at this point.
|
||||
#define RETRO_DEVICE_POINTER 6
|
||||
|
||||
// These device types are specializations of the base types above.
|
||||
// They should only be used in retro_set_controller_type() to inform libretro implementations
|
||||
// about use of a very specific device type.
|
||||
//
|
||||
// In input state callback, however, only the base type should be used in the 'device' field.
|
||||
#define RETRO_DEVICE_JOYPAD_MULTITAP ((1 << 8) | RETRO_DEVICE_JOYPAD)
|
||||
#define RETRO_DEVICE_LIGHTGUN_SUPER_SCOPE ((1 << 8) | RETRO_DEVICE_LIGHTGUN)
|
||||
#define RETRO_DEVICE_LIGHTGUN_JUSTIFIER ((2 << 8) | RETRO_DEVICE_LIGHTGUN)
|
||||
#define RETRO_DEVICE_LIGHTGUN_JUSTIFIERS ((3 << 8) | RETRO_DEVICE_LIGHTGUN)
|
||||
|
||||
// Buttons for the RetroPad (JOYPAD).
|
||||
// The placement of these is equivalent to placements on the Super Nintendo controller.
|
||||
// L2/R2/L3/R3 buttons correspond to the PS1 DualShock.
|
||||
@ -160,7 +167,7 @@ extern "C" {
|
||||
|
||||
// Regular save ram. This ram is usually found on a game cartridge, backed up by a battery.
|
||||
// If save game data is too complex for a single memory buffer,
|
||||
// the SYSTEM_DIRECTORY environment callback can be used.
|
||||
// the SAVE_DIRECTORY (preferably) or SYSTEM_DIRECTORY environment callback can be used.
|
||||
#define RETRO_MEMORY_SAVE_RAM 0
|
||||
|
||||
// Some games have a built-in clock to keep track of time.
|
||||
@ -173,21 +180,6 @@ extern "C" {
|
||||
// Video ram lets a frontend peek into a game systems video RAM (VRAM).
|
||||
#define RETRO_MEMORY_VIDEO_RAM 3
|
||||
|
||||
// Special memory types.
|
||||
#define RETRO_MEMORY_SNES_BSX_RAM ((1 << 8) | RETRO_MEMORY_SAVE_RAM)
|
||||
#define RETRO_MEMORY_SNES_BSX_PRAM ((2 << 8) | RETRO_MEMORY_SAVE_RAM)
|
||||
#define RETRO_MEMORY_SNES_SUFAMI_TURBO_A_RAM ((3 << 8) | RETRO_MEMORY_SAVE_RAM)
|
||||
#define RETRO_MEMORY_SNES_SUFAMI_TURBO_B_RAM ((4 << 8) | RETRO_MEMORY_SAVE_RAM)
|
||||
#define RETRO_MEMORY_SNES_GAME_BOY_RAM ((5 << 8) | RETRO_MEMORY_SAVE_RAM)
|
||||
#define RETRO_MEMORY_SNES_GAME_BOY_RTC ((6 << 8) | RETRO_MEMORY_RTC)
|
||||
|
||||
// Special game types passed into retro_load_game_special().
|
||||
// Only used when multiple ROMs are required.
|
||||
#define RETRO_GAME_TYPE_BSX 0x101
|
||||
#define RETRO_GAME_TYPE_BSX_SLOTTED 0x102
|
||||
#define RETRO_GAME_TYPE_SUFAMI_TURBO 0x103
|
||||
#define RETRO_GAME_TYPE_SUPER_GAME_BOY 0x104
|
||||
|
||||
// Keysyms used for ID in input state callback when polling RETRO_KEYBOARD.
|
||||
enum retro_key
|
||||
{
|
||||
@ -413,6 +405,9 @@ enum retro_mod
|
||||
// If so, no such directory is defined,
|
||||
// and it's up to the implementation to find a suitable directory.
|
||||
//
|
||||
// NOTE: Some cores used this folder also for "save" data such as memory cards, etc, for lack of a better place to put it.
|
||||
// This is now discouraged, and if possible, cores should try to use the new GET_SAVE_DIRECTORY.
|
||||
//
|
||||
#define RETRO_ENVIRONMENT_SET_PIXEL_FORMAT 10
|
||||
// const enum retro_pixel_format * --
|
||||
// Sets the internal pixel format used by the implementation.
|
||||
@ -558,12 +553,12 @@ enum retro_mod
|
||||
// If this interface is not used, libretro cores should log to stderr as desired.
|
||||
#define RETRO_ENVIRONMENT_GET_PERF_INTERFACE 28
|
||||
// struct retro_perf_callback * --
|
||||
// Gets an interface for performance counters. This is useful for performance logging in a
|
||||
// Gets an interface for performance counters. This is useful for performance logging in a
|
||||
// cross-platform way and for detecting architecture-specific features, such as SIMD support.
|
||||
#define RETRO_ENVIRONMENT_GET_LOCATION_INTERFACE 29
|
||||
// struct retro_location_callback * --
|
||||
// Gets access to the location interface.
|
||||
// The purpose of this interface is to be able to retrieve location-based information from the host device,
|
||||
// The purpose of this interface is to be able to retrieve location-based information from the host device,
|
||||
// such as current latitude / longitude.
|
||||
//
|
||||
#define RETRO_ENVIRONMENT_GET_CONTENT_DIRECTORY 30
|
||||
@ -578,7 +573,140 @@ enum retro_mod
|
||||
#define RETRO_ENVIRONMENT_GET_SAVE_DIRECTORY 31
|
||||
// const char ** --
|
||||
// Returns the "save" directory of the frontend.
|
||||
// This directory can be used to store SRAM, memory cards, high scores, etc
|
||||
// This directory can be used to store SRAM, memory cards, high scores, etc, if the libretro core
|
||||
// cannot use the regular memory interface (retro_get_memory_data()).
|
||||
//
|
||||
// NOTE: libretro cores used to check GET_SYSTEM_DIRECTORY for similar things before.
|
||||
// They should still check GET_SYSTEM_DIRECTORY if they want to be backwards compatible.
|
||||
// The path here can be NULL. It should only be non-NULL if the frontend user has set a specific save path.
|
||||
//
|
||||
#define RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO 32
|
||||
// const struct retro_system_av_info * --
|
||||
// Sets a new av_info structure. This can only be called from within retro_run().
|
||||
// This should *only* be used if the core is completely altering the internal resolutions, aspect ratios, timings, sampling rate, etc.
|
||||
// Calling this can require a full reinitialization of video/audio drivers in the frontend,
|
||||
// so it is important to call it very sparingly, and usually only with the users explicit consent.
|
||||
// An eventual driver reinit will happen so that video and audio callbacks
|
||||
// happening after this call within the same retro_run() call will target the newly initialized driver.
|
||||
//
|
||||
// This callback makes it possible to support configurable resolutions in games, which can be useful to
|
||||
// avoid setting the "worst case" in max_width/max_height.
|
||||
//
|
||||
// ***HIGHLY RECOMMENDED*** Do not call this callback every time resolution changes in an emulator core if it's
|
||||
// expected to be a temporary change, for the reasons of possible driver reinit.
|
||||
// This call is not a free pass for not trying to provide correct values in retro_get_system_av_info().
|
||||
//
|
||||
// If this returns false, the frontend does not acknowledge a changed av_info struct.
|
||||
#define RETRO_ENVIRONMENT_SET_PROC_ADDRESS_CALLBACK 33
|
||||
// const struct retro_get_proc_address_interface * --
|
||||
// Allows a libretro core to announce support for the get_proc_address() interface.
|
||||
// This interface allows for a standard way to extend libretro where use of environment calls are too indirect,
|
||||
// e.g. for cases where the frontend wants to call directly into the core.
|
||||
//
|
||||
// If a core wants to expose this interface, SET_PROC_ADDRESS_CALLBACK **MUST** be called from within retro_set_environment().
|
||||
//
|
||||
#define RETRO_ENVIRONMENT_SET_SUBSYSTEM_INFO 34
|
||||
// const struct retro_subsystem_info * --
|
||||
// This environment call introduces the concept of libretro "subsystems".
|
||||
// A subsystem is a variant of a libretro core which supports different kinds of games.
|
||||
// The purpose of this is to support e.g. emulators which might have special needs, e.g. Super Nintendos Super GameBoy, Sufami Turbo.
|
||||
// It can also be used to pick among subsystems in an explicit way if the libretro implementation is a multi-system emulator itself.
|
||||
//
|
||||
// Loading a game via a subsystem is done with retro_load_game_special(),
|
||||
// and this environment call allows a libretro core to expose which subsystems are supported for use with retro_load_game_special().
|
||||
// A core passes an array of retro_game_special_info which is terminated with a zeroed out retro_game_special_info struct.
|
||||
//
|
||||
// If a core wants to use this functionality, SET_SUBSYSTEM_INFO **MUST** be called from within retro_set_environment().
|
||||
//
|
||||
#define RETRO_ENVIRONMENT_SET_CONTROLLER_INFO 35
|
||||
// const struct retro_controller_info * --
|
||||
// This environment call lets a libretro core tell the frontend which
|
||||
// controller types are recognized in calls to retro_set_controller_port_device().
|
||||
//
|
||||
// Some emulators such as Super Nintendo
|
||||
// support multiple lightgun types which must be specifically selected from.
|
||||
// It is therefore sometimes necessary for a frontend to be able to tell
|
||||
// the core about a special kind of input device which is not covered by the
|
||||
// libretro input API.
|
||||
//
|
||||
// In order for a frontend to understand the workings of an input device,
|
||||
// it must be a specialized type
|
||||
// of the generic device types already defined in the libretro API.
|
||||
//
|
||||
// Which devices are supported can vary per input port.
|
||||
// The core must pass an array of const struct retro_controller_info which is terminated with
|
||||
// a blanked out struct. Each element of the struct corresponds to an ascending port index to retro_set_controller_port_device().
|
||||
// Even if special device types are set in the libretro core, libretro should only poll input based on the base input device types.
|
||||
|
||||
struct retro_controller_description
|
||||
{
|
||||
// Human-readable description of the controller. Even if using a generic input device type, this can be
|
||||
// set to the particular device type the core uses.
|
||||
const char *desc;
|
||||
|
||||
// Device type passed to retro_set_controller_port_device(). If the device type is a sub-class of a generic input device type,
|
||||
// use the RETRO_DEVICE_SUBCLASS macro to create an ID. E.g. RETRO_DEVICE_SUBCLASS(RETRO_DEVICE_JOYPAD, 1).
|
||||
unsigned id;
|
||||
};
|
||||
|
||||
struct retro_controller_info
|
||||
{
|
||||
const struct retro_controller_description *types;
|
||||
unsigned num_types;
|
||||
};
|
||||
|
||||
struct retro_subsystem_memory_info
|
||||
{
|
||||
const char *extension; // The extension associated with a memory type, e.g. "psram".
|
||||
unsigned type; // The memory type for retro_get_memory(). This should be at least 0x100 to avoid conflict with standardized libretro memory types.
|
||||
};
|
||||
|
||||
struct retro_subsystem_rom_info
|
||||
{
|
||||
const char *desc; // Describes what the ROM is (SGB bios, GB rom, etc).
|
||||
const char *valid_extensions; // Same definition as retro_get_system_info().
|
||||
bool need_fullpath; // Same definition as retro_get_system_info().
|
||||
bool block_extract; // Same definition as retro_get_system_info().
|
||||
bool required; // This is set if the ROM is required to load a game. If this is set to false, a zeroed-out retro_game_info can be passed.
|
||||
|
||||
// ROMs can have multiple associated persistent memory types (retro_get_memory()).
|
||||
const struct retro_subsystem_memory_info *memory;
|
||||
unsigned num_memory;
|
||||
};
|
||||
|
||||
struct retro_subsystem_info
|
||||
{
|
||||
const char *desc; // Human-readable string of the subsystem type, e.g. "Super GameBoy"
|
||||
// A computer friendly short string identifier for the subsystem type.
|
||||
// This name must be [a-z].
|
||||
// E.g. if desc is "Super GameBoy", this can be "sgb".
|
||||
// This identifier can be used for command-line interfaces, etc.
|
||||
const char *ident;
|
||||
|
||||
// Infos for each ROM. The first entry is assumed to be the "most significant" ROM for frontend purposes.
|
||||
// E.g. with Super GameBoy, the first ROM should be the GameBoy ROM, as it is the most "significant" ROM to a user.
|
||||
// If a frontend creates new file paths based on the ROM used (e.g. savestates), it should use the path for the first ROM to do so.
|
||||
const struct retro_subsystem_rom_info *roms;
|
||||
|
||||
unsigned num_roms; // Number of ROMs associated with a subsystem.
|
||||
unsigned id; // The type passed to retro_load_game_special().
|
||||
};
|
||||
|
||||
typedef void (*retro_proc_address_t)(void);
|
||||
// libretro API extension functions:
|
||||
// (None here so far).
|
||||
//////
|
||||
|
||||
// Get a symbol from a libretro core.
|
||||
// Cores should only return symbols which are actual extensions to the libretro API.
|
||||
// Frontends should not use this to obtain symbols to standard libretro entry points (static linking or dlsym).
|
||||
// The symbol name must be equal to the function name, e.g. if void retro_foo(void); exists, the symbol must be called "retro_foo".
|
||||
// The returned function pointer must be cast to the corresponding type.
|
||||
typedef retro_proc_address_t (*retro_get_proc_address_t)(const char *sym);
|
||||
struct retro_get_proc_address_interface
|
||||
{
|
||||
retro_get_proc_address_t get_proc_address;
|
||||
};
|
||||
|
||||
enum retro_log_level
|
||||
{
|
||||
@ -610,6 +738,12 @@ struct retro_log_callback
|
||||
#define RETRO_SIMD_SSE3 (1 << 6)
|
||||
#define RETRO_SIMD_SSSE3 (1 << 7)
|
||||
#define RETRO_SIMD_MMX (1 << 8)
|
||||
#define RETRO_SIMD_MMXEXT (1 << 9)
|
||||
#define RETRO_SIMD_SSE4 (1 << 10)
|
||||
#define RETRO_SIMD_SSE42 (1 << 11)
|
||||
#define RETRO_SIMD_AVX2 (1 << 12)
|
||||
#define RETRO_SIMD_VFPU (1 << 13)
|
||||
#define RETRO_SIMD_PS (1 << 14)
|
||||
|
||||
typedef uint64_t retro_perf_tick_t;
|
||||
typedef int64_t retro_time_t;
|
||||
@ -735,7 +869,7 @@ typedef void (*retro_camera_frame_raw_framebuffer_t)(const uint32_t *buffer, uns
|
||||
//
|
||||
// texture_target is the texture target for the GL texture.
|
||||
// These can include e.g. GL_TEXTURE_2D, GL_TEXTURE_RECTANGLE, and possibly more depending on extensions.
|
||||
//
|
||||
//
|
||||
// affine points to a packed 3x3 column-major matrix used to apply an affine transform to texture coordinates. (affine_matrix * vec3(coord_x, coord_y, 1.0))
|
||||
// After transform, normalized texture coord (0, 0) should be bottom-left and (1, 1) should be top-right (or (width, height) for RECTANGLE).
|
||||
//
|
||||
@ -763,7 +897,7 @@ struct retro_camera_callback
|
||||
};
|
||||
|
||||
// Sets the interval of time and/or distance at which to update/poll location-based data.
|
||||
// To ensure compatibility with all location-based implementations, values for both
|
||||
// To ensure compatibility with all location-based implementations, values for both
|
||||
// interval_ms and interval_distance should be provided.
|
||||
// interval_ms is the interval expressed in milliseconds.
|
||||
// interval_distance is the distance interval expressed in meters.
|
||||
@ -791,7 +925,7 @@ struct retro_location_callback
|
||||
retro_location_start_t start;
|
||||
retro_location_stop_t stop;
|
||||
retro_location_get_position_t get_position;
|
||||
retro_location_set_interval_t set_interval;
|
||||
retro_location_set_interval_t set_interval;
|
||||
|
||||
retro_location_lifetime_status_t initialized;
|
||||
retro_location_lifetime_status_t deinitialized;
|
||||
@ -856,7 +990,6 @@ typedef void (*retro_hw_context_reset_t)(void);
|
||||
typedef uintptr_t (*retro_hw_get_current_framebuffer_t)(void);
|
||||
|
||||
// Get a symbol from HW context.
|
||||
typedef void (*retro_proc_address_t)(void);
|
||||
typedef retro_proc_address_t (*retro_hw_get_proc_address_t)(const char *sym);
|
||||
|
||||
enum retro_hw_context_type
|
||||
@ -884,7 +1017,7 @@ struct retro_hw_render_callback
|
||||
unsigned version_minor; // Minor version number for core GL context.
|
||||
|
||||
bool cache_context; // If this is true, the frontend will go very far to avoid resetting context in scenarios like toggling fullscreen, etc.
|
||||
// The reset callback might still be called in extreme situations such as if the context is lost beyond recovery.
|
||||
// The reset callback might still be called in extreme situations such as if the context is lost beyond recovery.
|
||||
// For optimal stability, set this to false, and allow context to be reset at any time.
|
||||
retro_hw_context_reset_t context_destroy; // A callback to be called before the context is destroyed. Resources can be deinitialized at this step. This can be set to NULL, in which resources will just be destroyed without any notification.
|
||||
bool debug_context; // Creates a debug context.
|
||||
@ -1117,6 +1250,8 @@ void retro_get_system_info(struct retro_system_info *info);
|
||||
void retro_get_system_av_info(struct retro_system_av_info *info);
|
||||
|
||||
// Sets device to be used for player 'port'.
|
||||
// By default, RETRO_DEVICE_JOYPAD is assumed to be plugged into all available ports.
|
||||
// Setting a particular device type is not a guarantee that libretro cores will only poll input based on that particular device type. It is only a hint to the libretro core when a core cannot automatically detect the appropriate input device type on its own. It is also relevant when a core can change its behavior depending on device type.
|
||||
void retro_set_controller_port_device(unsigned port, unsigned device);
|
||||
|
||||
// Resets the current game.
|
||||
|
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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 Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "cputest.h"
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
int ff_get_cpu_flags_arm(void)
|
||||
{
|
||||
|
||||
return 0;
|
||||
// return HAVE_IWMMXT * CPUTEST_FLAG_IWMMXT;
|
||||
}
|
@ -17,32 +17,41 @@
|
||||
*/
|
||||
|
||||
#include "cputest.h"
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include "../libretro.h"
|
||||
|
||||
extern retro_get_cpu_features_t perf_get_cpu_features_cb;
|
||||
|
||||
static int flags, checked = 0;
|
||||
|
||||
|
||||
void cputest_force_flags(int arg)
|
||||
{
|
||||
flags = arg;
|
||||
checked = 1;
|
||||
}
|
||||
|
||||
int cputest_get_flags(void)
|
||||
{
|
||||
if (checked)
|
||||
return flags;
|
||||
unsigned cpu = 0;
|
||||
flags = 0;
|
||||
if (perf_get_cpu_features_cb)
|
||||
cpu = perf_get_cpu_features_cb();
|
||||
|
||||
// if (ARCH_ARM) flags = ff_get_cpu_flags_arm();
|
||||
#if ARCH_POWERPC
|
||||
flags = ff_get_cpu_flags_ppc();
|
||||
#endif
|
||||
|
||||
#if ARCH_X86
|
||||
flags = ff_get_cpu_flags_x86();
|
||||
#endif
|
||||
if (cpu & RETRO_SIMD_MMX)
|
||||
flags |= CPUTEST_FLAG_MMX;
|
||||
if (cpu & RETRO_SIMD_SSE)
|
||||
flags |= CPUTEST_FLAG_SSE;
|
||||
if (cpu & RETRO_SIMD_SSE2)
|
||||
flags |= CPUTEST_FLAG_SSE2;
|
||||
if (cpu & RETRO_SIMD_SSE3)
|
||||
flags |= CPUTEST_FLAG_SSE3;
|
||||
if (cpu & RETRO_SIMD_SSSE3)
|
||||
flags |= CPUTEST_FLAG_SSSE3;
|
||||
if (cpu & RETRO_SIMD_SSE4)
|
||||
flags |= CPUTEST_FLAG_SSE4;
|
||||
if (cpu & RETRO_SIMD_SSE42)
|
||||
flags |= CPUTEST_FLAG_SSE42;
|
||||
if (cpu & RETRO_SIMD_AVX)
|
||||
flags |= CPUTEST_FLAG_AVX;
|
||||
if (cpu & RETRO_SIMD_VMX)
|
||||
flags |= CPUTEST_FLAG_ALTIVEC;
|
||||
|
||||
checked = 1;
|
||||
return flags;
|
||||
|
@ -1,87 +0,0 @@
|
||||
/*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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 Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <sys/sysctl.h>
|
||||
#elif defined(__OpenBSD__)
|
||||
#include <sys/param.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <machine/cpu.h>
|
||||
#elif defined(__AMIGAOS4__)
|
||||
#include <exec/exec.h>
|
||||
#include <interfaces/exec.h>
|
||||
#include <proto/exec.h>
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
#include "cputest.h"
|
||||
|
||||
/**
|
||||
* This function MAY rely on signal() or fork() in order to make sure AltiVec
|
||||
* is present.
|
||||
*/
|
||||
int ff_get_cpu_flags_ppc(void)
|
||||
{
|
||||
//#if HAVE_ALTIVEC
|
||||
#if ARCH_POWERPC_ALTIVEC
|
||||
#ifdef __AMIGAOS4__
|
||||
ULONG result = 0;
|
||||
extern struct ExecIFace *IExec;
|
||||
|
||||
IExec->GetCPUInfoTags(GCIT_VectorUnit, &result, TAG_DONE);
|
||||
if (result == VECTORTYPE_ALTIVEC)
|
||||
return CPUTEST_FLAG_ALTIVEC;
|
||||
return 0;
|
||||
#elif defined(__APPLE__) || defined(__OpenBSD__)
|
||||
#ifdef __OpenBSD__
|
||||
int sels[2] = {CTL_MACHDEP, CPU_ALTIVEC};
|
||||
#else
|
||||
int sels[2] = {CTL_HW, HW_VECTORUNIT};
|
||||
#endif
|
||||
int has_vu = 0;
|
||||
size_t len = sizeof(has_vu);
|
||||
int err;
|
||||
|
||||
err = sysctl(sels, 2, &has_vu, &len, NULL, 0);
|
||||
|
||||
if (err == 0)
|
||||
return has_vu ? CPUTEST_FLAG_ALTIVEC : 0;
|
||||
return 0;
|
||||
#elif CONFIG_RUNTIME_CPUDETECT
|
||||
int proc_ver;
|
||||
// Support of mfspr PVR emulation added in Linux 2.6.17.
|
||||
__asm__ volatile("mfspr %0, 287" : "=r" (proc_ver));
|
||||
proc_ver >>= 16;
|
||||
if (proc_ver & 0x8000 ||
|
||||
proc_ver == 0x000c ||
|
||||
proc_ver == 0x0039 || proc_ver == 0x003c ||
|
||||
proc_ver == 0x0044 || proc_ver == 0x0045 ||
|
||||
proc_ver == 0x0070)
|
||||
return CPUTEST_FLAG_ALTIVEC;
|
||||
return 0;
|
||||
#else
|
||||
// Since we were compiled for AltiVec, just assume we have it
|
||||
// until someone comes up with a proper way (not involving signal hacks).
|
||||
return CPUTEST_FLAG_ALTIVEC;
|
||||
#endif /* __AMIGAOS4__ */
|
||||
#endif /* HAVE_ALTIVEC */
|
||||
return 0;
|
||||
}
|
@ -1,164 +0,0 @@
|
||||
/*
|
||||
* CPU detection code, extracted from mmx.h
|
||||
* (c)1997-99 by H. Dietz and R. Fisher
|
||||
* Converted to C and improved by Fabrice Bellard.
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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 Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "x86_cpu.h"
|
||||
#include "cputest.h"
|
||||
|
||||
/* ebx saving is necessary for PIC. gcc seems unable to see it alone */
|
||||
#define cpuid(index,eax,ebx,ecx,edx)\
|
||||
__asm__ volatile\
|
||||
("mov %%"REG_b", %%"REG_S"\n\t"\
|
||||
"cpuid\n\t"\
|
||||
"xchg %%"REG_b", %%"REG_S\
|
||||
: "=a" (eax), "=S" (ebx),\
|
||||
"=c" (ecx), "=d" (edx)\
|
||||
: "0" (index));
|
||||
|
||||
#define xgetbv(index,eax,edx) \
|
||||
__asm__ (".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c" (index))
|
||||
|
||||
/* Function to test if multimedia instructions are supported... */
|
||||
int ff_get_cpu_flags_x86(void)
|
||||
{
|
||||
int rval = 0;
|
||||
int eax, ebx, ecx, edx;
|
||||
int max_std_level, max_ext_level, std_caps=0, ext_caps=0;
|
||||
int family=0, model=0;
|
||||
union { int i[3]; char c[12]; } vendor;
|
||||
|
||||
#if ARCH_X86_32
|
||||
x86_reg a, c;
|
||||
__asm__ volatile (
|
||||
/* See if CPUID instruction is supported ... */
|
||||
/* ... Get copies of EFLAGS into eax and ecx */
|
||||
"pushfl\n\t"
|
||||
"pop %0\n\t"
|
||||
"mov %0, %1\n\t"
|
||||
|
||||
/* ... Toggle the ID bit in one copy and store */
|
||||
/* to the EFLAGS reg */
|
||||
"xor $0x200000, %0\n\t"
|
||||
"push %0\n\t"
|
||||
"popfl\n\t"
|
||||
|
||||
/* ... Get the (hopefully modified) EFLAGS */
|
||||
"pushfl\n\t"
|
||||
"pop %0\n\t"
|
||||
: "=a" (a), "=c" (c)
|
||||
:
|
||||
: "cc"
|
||||
);
|
||||
|
||||
if (a == c)
|
||||
return 0; /* CPUID not supported */
|
||||
#endif
|
||||
|
||||
cpuid(0, max_std_level, vendor.i[0], vendor.i[2], vendor.i[1]);
|
||||
|
||||
if(max_std_level >= 1){
|
||||
cpuid(1, eax, ebx, ecx, std_caps);
|
||||
family = ((eax>>8)&0xf) + ((eax>>20)&0xff);
|
||||
model = ((eax>>4)&0xf) + ((eax>>12)&0xf0);
|
||||
|
||||
// Mednafen addition(cmov):
|
||||
if (std_caps & (1<<15))
|
||||
rval |= CPUTEST_FLAG_CMOV;
|
||||
|
||||
if (std_caps & (1<<23))
|
||||
rval |= CPUTEST_FLAG_MMX;
|
||||
if (std_caps & (1<<25))
|
||||
rval |= CPUTEST_FLAG_MMX2
|
||||
//#if HAVE_SSE
|
||||
| CPUTEST_FLAG_SSE;
|
||||
if (std_caps & (1<<26))
|
||||
rval |= CPUTEST_FLAG_SSE2;
|
||||
if (ecx & 1)
|
||||
rval |= CPUTEST_FLAG_SSE3;
|
||||
if (ecx & 0x00000200 )
|
||||
rval |= CPUTEST_FLAG_SSSE3;
|
||||
if (ecx & 0x00080000 )
|
||||
rval |= CPUTEST_FLAG_SSE4;
|
||||
if (ecx & 0x00100000 )
|
||||
rval |= CPUTEST_FLAG_SSE42;
|
||||
//#if HAVE_AVX
|
||||
/* Check OXSAVE and AVX bits */
|
||||
if ((ecx & 0x18000000) == 0x18000000) {
|
||||
/* Check for OS support */
|
||||
xgetbv(0, eax, edx);
|
||||
if ((eax & 0x6) == 0x6)
|
||||
rval |= CPUTEST_FLAG_AVX;
|
||||
}
|
||||
//#endif
|
||||
//#endif
|
||||
;
|
||||
}
|
||||
|
||||
cpuid(0x80000000, max_ext_level, ebx, ecx, edx);
|
||||
|
||||
if(max_ext_level >= 0x80000001){
|
||||
cpuid(0x80000001, eax, ebx, ecx, ext_caps);
|
||||
if (ext_caps & (1<<31))
|
||||
rval |= CPUTEST_FLAG_3DNOW;
|
||||
if (ext_caps & (1<<30))
|
||||
rval |= CPUTEST_FLAG_3DNOWEXT;
|
||||
if (ext_caps & (1<<23))
|
||||
rval |= CPUTEST_FLAG_MMX;
|
||||
if (ext_caps & (1<<22))
|
||||
rval |= CPUTEST_FLAG_MMX2;
|
||||
|
||||
/* Allow for selectively disabling SSE2 functions on AMD processors
|
||||
with SSE2 support but not SSE4a. This includes Athlon64, some
|
||||
Opteron, and some Sempron processors. MMX, SSE, or 3DNow! are faster
|
||||
than SSE2 often enough to utilize this special-case flag.
|
||||
CPUTEST_FLAG_SSE2 and CPUTEST_FLAG_SSE2SLOW are both set in this case
|
||||
so that SSE2 is used unless explicitly disabled by checking
|
||||
CPUTEST_FLAG_SSE2SLOW. */
|
||||
if (!strncmp(vendor.c, "AuthenticAMD", 12) &&
|
||||
rval & CPUTEST_FLAG_SSE2 && !(ecx & 0x00000040)) {
|
||||
rval |= CPUTEST_FLAG_SSE2SLOW;
|
||||
}
|
||||
}
|
||||
|
||||
if (!strncmp(vendor.c, "GenuineIntel", 12)) {
|
||||
if (family == 6 && (model == 9 || model == 13 || model == 14)) {
|
||||
/* 6/9 (pentium-m "banias"), 6/13 (pentium-m "dothan"), and 6/14 (core1 "yonah")
|
||||
* theoretically support sse2, but it's usually slower than mmx,
|
||||
* so let's just pretend they don't. CPUTEST_FLAG_SSE2 is disabled and
|
||||
* CPUTEST_FLAG_SSE2SLOW is enabled so that SSE2 is not used unless
|
||||
* explicitly enabled by checking CPUTEST_FLAG_SSE2SLOW. The same
|
||||
* situation applies for CPUTEST_FLAG_SSE3 and CPUTEST_FLAG_SSE3SLOW. */
|
||||
if (rval & CPUTEST_FLAG_SSE2) rval ^= CPUTEST_FLAG_SSE2SLOW|CPUTEST_FLAG_SSE2;
|
||||
if (rval & CPUTEST_FLAG_SSE3) rval ^= CPUTEST_FLAG_SSE3SLOW|CPUTEST_FLAG_SSE3;
|
||||
}
|
||||
/* The Atom processor has SSSE3 support, which is useful in many cases,
|
||||
* but sometimes the SSSE3 version is slower than the SSE2 equivalent
|
||||
* on the Atom, but is generally faster on other processors supporting
|
||||
* SSSE3. This flag allows for selectively disabling certain SSSE3
|
||||
* functions on the Atom. */
|
||||
if (family == 6 && model == 28)
|
||||
rval |= CPUTEST_FLAG_ATOM;
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
@ -1,101 +0,0 @@
|
||||
/*
|
||||
* copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg 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 Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef AVUTIL_X86_CPU_H
|
||||
#define AVUTIL_X86_CPU_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if ARCH_X86_64
|
||||
# define OPSIZE "q"
|
||||
# define REG_a "rax"
|
||||
# define REG_b "rbx"
|
||||
# define REG_c "rcx"
|
||||
# define REG_d "rdx"
|
||||
# define REG_D "rdi"
|
||||
# define REG_S "rsi"
|
||||
# define PTR_SIZE "8"
|
||||
typedef int64_t x86_reg;
|
||||
|
||||
# define REG_SP "rsp"
|
||||
# define REG_BP "rbp"
|
||||
# define REGBP rbp
|
||||
# define REGa rax
|
||||
# define REGb rbx
|
||||
# define REGc rcx
|
||||
# define REGd rdx
|
||||
# define REGSP rsp
|
||||
|
||||
#elif ARCH_X86_32
|
||||
|
||||
# define OPSIZE "l"
|
||||
# define REG_a "eax"
|
||||
# define REG_b "ebx"
|
||||
# define REG_c "ecx"
|
||||
# define REG_d "edx"
|
||||
# define REG_D "edi"
|
||||
# define REG_S "esi"
|
||||
# define PTR_SIZE "4"
|
||||
typedef int32_t x86_reg;
|
||||
|
||||
# define REG_SP "esp"
|
||||
# define REG_BP "ebp"
|
||||
# define REGBP ebp
|
||||
# define REGa eax
|
||||
# define REGb ebx
|
||||
# define REGc ecx
|
||||
# define REGd edx
|
||||
# define REGSP esp
|
||||
#else
|
||||
typedef int x86_reg;
|
||||
#endif
|
||||
|
||||
#define HAVE_7REGS (ARCH_X86_64 || (HAVE_EBX_AVAILABLE && HAVE_EBP_AVAILABLE))
|
||||
#define HAVE_6REGS (ARCH_X86_64 || (HAVE_EBX_AVAILABLE || HAVE_EBP_AVAILABLE))
|
||||
|
||||
#if ARCH_X86_64 && defined(PIC)
|
||||
# define BROKEN_RELOCATIONS 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If gcc is not set to support sse (-msse) it will not accept xmm registers
|
||||
* in the clobber list for inline asm. XMM_CLOBBERS takes a list of xmm
|
||||
* registers to be marked as clobbered and evaluates to nothing if they are
|
||||
* not supported, or to the list itself if they are supported. Since a clobber
|
||||
* list may not be empty, XMM_CLOBBERS_ONLY should be used if the xmm
|
||||
* registers are the only in the clobber list.
|
||||
* For example a list with "eax" and "xmm0" as clobbers should become:
|
||||
* : XMM_CLOBBERS("xmm0",) "eax"
|
||||
* and a list with only "xmm0" should become:
|
||||
* XMM_CLOBBERS_ONLY("xmm0")
|
||||
*/
|
||||
#if HAVE_XMM_CLOBBERS
|
||||
# define XMM_CLOBBERS(...) __VA_ARGS__
|
||||
# define XMM_CLOBBERS_ONLY(...) : __VA_ARGS__
|
||||
#else
|
||||
# define XMM_CLOBBERS(...)
|
||||
# define XMM_CLOBBERS_ONLY(...)
|
||||
#endif
|
||||
|
||||
#endif /* AVUTIL_X86_CPU_H */
|
Loading…
x
Reference in New Issue
Block a user