Merge remote-tracking branch 'origin/master' into Android-trash

This commit is contained in:
Ryan Houdek
2013-04-13 00:58:37 -05:00
417 changed files with 23059 additions and 19251 deletions

View File

@ -83,6 +83,40 @@ bool TryMakeOperand2_AllowNegation(s32 imm, Operand2 &op2, bool *negated)
}
}
Operand2 AssumeMakeOperand2(u32 imm) {
Operand2 op2;
bool result = TryMakeOperand2(imm, op2);
_dbg_assert_msg_(JIT, result, "Could not make assumed Operand2.");
return op2;
}
bool ARMXEmitter::TrySetValue_TwoOp(ARMReg reg, u32 val)
{
int ops = 0;
for (int i = 0; i < 16; i++)
{
if ((val >> (i*2)) & 0x3)
{
ops++;
i+=3;
}
}
if (ops > 2)
return false;
bool first = true;
for (int i = 0; i < 16; i++, val >>=2) {
if (val & 0x3) {
first ? MOV(reg, Operand2((u8)val, (u8)((16-i) & 0xF)))
: ORR(reg, reg, Operand2((u8)val, (u8)((16-i) & 0xF)));
first = false;
i+=3;
val >>= 6;
}
}
return true;
}
void ARMXEmitter::MOVI2F(ARMReg dest, float val, ARMReg tempReg)
{
union {float f; u32 u;} conv;
@ -93,6 +127,21 @@ void ARMXEmitter::MOVI2F(ARMReg dest, float val, ARMReg tempReg)
// Otherwise, use a literal pool and VLDR directly (+- 1020)
}
void ARMXEmitter::ADDI2R(ARMReg rd, ARMReg rs, u32 val, ARMReg scratch)
{
Operand2 op2;
bool negated;
if (TryMakeOperand2_AllowNegation(val, op2, &negated)) {
if (!negated)
ADD(rd, rs, op2);
else
SUB(rd, rs, op2);
} else {
MOVI2R(scratch, val);
ADD(rd, rs, scratch);
}
}
void ARMXEmitter::ANDI2R(ARMReg rd, ARMReg rs, u32 val, ARMReg scratch)
{
Operand2 op2;
@ -109,6 +158,21 @@ void ARMXEmitter::ANDI2R(ARMReg rd, ARMReg rs, u32 val, ARMReg scratch)
}
}
void ARMXEmitter::CMPI2R(ARMReg rs, u32 val, ARMReg scratch)
{
Operand2 op2;
bool negated;
if (TryMakeOperand2_AllowNegation(val, op2, &negated)) {
if (!negated)
CMP(rs, op2);
else
CMN(rs, op2);
} else {
MOVI2R(scratch, val);
CMP(rs, scratch);
}
}
void ARMXEmitter::ORI2R(ARMReg rd, ARMReg rs, u32 val, ARMReg scratch)
{
Operand2 op2;
@ -173,7 +237,7 @@ void ARMXEmitter::MOVI2R(ARMReg reg, u32 val, bool optimize)
MOVW(reg, val & 0xFFFF);
if(val & 0xFFFF0000)
MOVT(reg, val, true);
} else {
} else if (!TrySetValue_TwoOp(reg,val)) {
// Use literal pool for ARMv6.
AddNewLit(val);
LDR(reg, _PC); // To be backpatched later
@ -190,9 +254,7 @@ void ARMXEmitter::SetCodePtr(u8 *ptr)
{
code = ptr;
startcode = code;
#ifdef IOS
lastCacheFlushEnd = ptr;
#endif
}
const u8 *ARMXEmitter::GetCodePtr() const
@ -236,12 +298,9 @@ void ARMXEmitter::FlushIcacheSection(u8 *start, u8 *end)
#elif defined(BLACKBERRY)
msync(start, end - start, MS_SYNC | MS_INVALIDATE_ICACHE);
#elif defined(IOS)
if (start != NULL)
sys_cache_control(kCacheFunctionPrepareForExecution, start, end - start);
// Header file says this is equivalent to: sys_icache_invalidate(start, end - start);
sys_cache_control(kCacheFunctionPrepareForExecution, start, end - start);
#elif !defined(_WIN32)
#ifndef ANDROID
start = startcode; // Should be Linux Only
#endif
__builtin___clear_cache(start, end);
#endif
}
@ -628,38 +687,40 @@ void ARMXEmitter::SVC(Operand2 op)
// IMM, REG, IMMSREG, RSR
// -1 for invalid if the instruction doesn't support that
const s32 LoadStoreOps[][4] = { {0x40, 0x60, 0x60, -1}, // STR
{0x41, 0x61, 0x61, -1}, // LDR
{0x44, 0x64, 0x64, -1}, // STRB
{0x45, 0x65, 0x65, -1}, // LDRB
// Special encodings
{ 0x4, 0x0, -1, -1}, // STRH
{ 0x5, 0x1, -1, -1}, // LDRH
{ 0x5, 0x1, -1, -1}, // LDRSB
{ 0x5, 0x1, -1, -1}, // LDRSH
};
const char *LoadStoreNames[] = { "STR",
"LDR",
"STRB",
"LDRB",
"STRH",
"LDRH",
"LDRSB",
"LDRSH",
};
const s32 LoadStoreOps[][4] = {
{0x40, 0x60, 0x60, -1}, // STR
{0x41, 0x61, 0x61, -1}, // LDR
{0x44, 0x64, 0x64, -1}, // STRB
{0x45, 0x65, 0x65, -1}, // LDRB
// Special encodings
{ 0x4, 0x0, -1, -1}, // STRH
{ 0x5, 0x1, -1, -1}, // LDRH
{ 0x5, 0x1, -1, -1}, // LDRSB
{ 0x5, 0x1, -1, -1}, // LDRSH
};
const char *LoadStoreNames[] = {
"STR",
"LDR",
"STRB",
"LDRB",
"STRH",
"LDRH",
"LDRSB",
"LDRSH",
};
void ARMXEmitter::WriteStoreOp(u32 Op, ARMReg Rt, ARMReg Rn, Operand2 Rm, bool RegAdd)
{
s32 op = LoadStoreOps[Op][Rm.GetType()]; // Type always decided by last operand
u32 Data;
// Qualcomm chipsets get /really/ angry if you don't use index, even if the offset is zero.
// Some of these encodings require Index at all times anyway. Doesn't really matter.
// bool Index = op2 != 0 ? true : false;
bool Index = true;
bool Add = false;
bool Add = false;
// Special Encoding
// Special Encoding (misc addressing mode)
bool SpecialOp = false;
bool Half = false;
bool SignedLoad = false;
@ -699,10 +760,13 @@ void ARMXEmitter::WriteStoreOp(u32 Op, ARMReg Rt, ARMReg Rn, Operand2 Rm, bool R
// The offset is encoded differently on this one.
if (SpecialOp)
Data = (Data & 0xF0 << 4) | (Data & 0xF);
if (Temp >= 0) Add = true;
if (Temp >= 0) Add = true;
}
break;
case TYPE_REG:
Data = Rm.GetData();
Add = RegAdd;
break;
case TYPE_IMMSREG:
if (!SpecialOp)
{
@ -710,17 +774,18 @@ void ARMXEmitter::WriteStoreOp(u32 Op, ARMReg Rt, ARMReg Rn, Operand2 Rm, bool R
Add = RegAdd;
break;
}
// Intentional fallthrough: TYPE_IMMSREG not supported for misc addressing.
default:
// RSR not supported for any of these
// We already have the warning above
BKPT(0x2);
return;
break;
break;
}
if (SpecialOp)
{
// Add SpecialOp things
Data = (0x5 << 4) | (SignedLoad << 6) | (Half << 5) | Data;
Data = (0x9 << 4) | (SignedLoad << 6) | (Half << 5) | Data;
}
Write32(condition | (op << 20) | (Index << 24) | (Add << 23) | (Rn << 16) | (Rt << 12) | Data);
}
@ -947,7 +1012,6 @@ void ARMXEmitter::VLDR(ARMReg Dest, ARMReg Base, s16 offset)
{
Write32(condition | (0xD << 24) | (Add << 23) | ((Dest & 0x1) << 22) | (1 << 20) | (Base << 16) \
| ((Dest & 0x1E) << 11) | (10 << 8) | (imm >> 2));
}
else
{

View File

@ -320,6 +320,9 @@ bool TryMakeOperand2(u32 imm, Operand2 &op2);
bool TryMakeOperand2_AllowInverse(u32 imm, Operand2 &op2, bool *inverse);
bool TryMakeOperand2_AllowNegation(s32 imm, Operand2 &op2, bool *negated);
// Use this only when you know imm can be made into an Operand2.
Operand2 AssumeMakeOperand2(u32 imm);
inline Operand2 R(ARMReg Reg) { return Operand2(Reg, TYPE_REG); }
inline Operand2 IMM(u32 Imm) { return Operand2(Imm, TYPE_IMM); }
inline Operand2 Mem(void *ptr) { return Operand2((u32)ptr, TYPE_IMM); }
@ -394,6 +397,7 @@ public:
void FlushLitPool();
void AddNewLit(u32 val);
bool TrySetValue_TwoOp(ARMReg reg, u32 val);
CCFlags GetCC() { return CCFlags(condition >> 28); }
void SetCC(CCFlags cond = CC_AL);
@ -562,7 +566,9 @@ public:
void MOVI2R(ARMReg reg, u32 val, bool optimize = true);
void MOVI2F(ARMReg dest, float val, ARMReg tempReg);
void ADDI2R(ARMReg rd, ARMReg rs, u32 val, ARMReg scratch);
void ANDI2R(ARMReg rd, ARMReg rs, u32 val, ARMReg scratch);
void CMPI2R(ARMReg rs, u32 val, ARMReg scratch);
void ORI2R(ARMReg rd, ARMReg rs, u32 val, ARMReg scratch);

View File

@ -32,6 +32,7 @@
#include <list>
#include <deque>
#include <string>
#include <type_traits>
#include "Common.h"
#include "FileUtil.h"
@ -139,11 +140,17 @@ public:
template <typename T>
void Do(T& x)
{
// TODO: Bad, Do(some_non_POD) will compile and fail at runtime
// type_traits are not fully supported everywhere yet
// Ideally this would be std::is_trivially_copyable, but not enough support yet
static_assert(std::is_pod<T>::value, "Only sane for POD types");
DoVoid((void*)&x, sizeof(x));
}
template <typename T>
void DoPOD(T& x)
{
DoVoid((void*)&x, sizeof(x));
}
template <typename T>
void DoPointer(T*& x, T* const base)

View File

@ -66,23 +66,26 @@ _mm_shuffle_epi8(__m128i a, __m128i mask)
#define Crash() {asm ("int $3");}
#endif
#define ARRAYSIZE(A) (sizeof(A)/sizeof((A)[0]))
// GCC 4.8 defines all the rotate functions now
// Small issue with GCC's lrotl/lrotr intrinsics is they are still 32bit while we require 64bit
#ifndef _rotl
inline u32 _rotl(u32 x, int shift) {
shift &= 31;
if (!shift) return x;
return (x << shift) | (x >> (32 - shift));
}
inline u64 _rotl64(u64 x, unsigned int shift){
unsigned int n = shift % 64;
return (x << n) | (x >> (64 - n));
}
inline u32 _rotr(u32 x, int shift) {
shift &= 31;
if (!shift) return x;
return (x >> shift) | (x << (32 - shift));
}
#endif
inline u64 _rotl64(u64 x, unsigned int shift){
unsigned int n = shift % 64;
return (x << n) | (x >> (64 - n));
}
inline u64 _rotr64(u64 x, unsigned int shift){
unsigned int n = shift % 64;

View File

@ -36,15 +36,16 @@ public:
return (0 == m_size);
}
const T& Front() const
T& Front() const
{
return *m_read_ptr->current;
}
void Push(const T& t)
template <typename Arg>
void Push(Arg&& t)
{
// create the element, add it to the queue
m_write_ptr->current = new T(t);
m_write_ptr->current = new T(std::forward<Arg>(t));
// set the next pointer to a new element ptr
// then advance the write pointer
m_write_ptr = m_write_ptr->next = new ElementPtr();
@ -67,7 +68,7 @@ public:
if (Empty())
return false;
t = Front();
t = std::move(Front());
Pop();
return true;

View File

@ -124,7 +124,7 @@ bool Delete(const std::string &filename)
// being there, not the actual delete.
if (!Exists(filename))
{
WARN_LOG(COMMON, "Delete: %s does not exists", filename.c_str());
WARN_LOG(COMMON, "Delete: %s does not exist", filename.c_str());
return true;
}
@ -216,7 +216,7 @@ bool CreateFullPath(const std::string &fullPath)
panicCounter--;
if (panicCounter <= 0)
{
ERROR_LOG(COMMON, "CreateFullPath: directory structure too deep");
ERROR_LOG(COMMON, "CreateFullPath: directory structure is too deep");
return false;
}
position++;
@ -324,7 +324,7 @@ bool Copy(const std::string &srcFilename, const std::string &destFilename)
goto bail;
}
}
// close flushs
// close files
fclose(input);
fclose(output);
return true;
@ -669,7 +669,7 @@ std::string GetSysDirectory()
// Returns a string with a Dolphin data dir or file in the user's home
// directory. To be used in "multi-user" mode (that is, installed).
std::string &GetUserPath(const unsigned int DirIDX, const std::string &newPath)
const std::string& GetUserPath(const unsigned int DirIDX, const std::string &newPath)
{
static std::string paths[NUM_PATH_INDICES];
@ -723,11 +723,11 @@ std::string &GetUserPath(const unsigned int DirIDX, const std::string &newPath)
if (!newPath.empty())
{
if(DirIDX != D_WIIROOT_IDX)
PanicAlert("trying to change user path other than wii root");
PanicAlert("Trying to change user path other than Wii root");
if (!File::IsDirectory(newPath))
{
WARN_LOG(COMMON, "Invalid path specified %s, wii user path will be set to default", newPath.c_str());
WARN_LOG(COMMON, "Invalid path specified %s, Wii user path will be set to default", newPath.c_str());
paths[D_WIIROOT_IDX] = paths[D_USER_IDX] + WII_USER_DIR;
}
else
@ -742,6 +742,19 @@ std::string &GetUserPath(const unsigned int DirIDX, const std::string &newPath)
return paths[DirIDX];
}
std::string GetThemeDir(const std::string& theme_name)
{
std::string dir = File::GetUserPath(D_THEMES_IDX) + theme_name + "/";
#if !defined(_WIN32)
// If theme does not exist in user's dir load from shared directory
if (!File::Exists(dir))
dir = SHARED_USER_DIR THEMES_DIR "/" + theme_name + "/";
#endif
return dir;
}
bool WriteStringToFile(bool text_file, const std::string &str, const char *filename)
{
return File::IOFile(filename, text_file ? "w" : "wb").WriteBytes(str.data(), str.size());

View File

@ -132,7 +132,10 @@ bool SetCurrentDir(const std::string &directory);
// Returns a pointer to a string with a Dolphin data dir in the user's home
// directory. To be used in "multi-user" mode (that is, installed).
std::string &GetUserPath(const unsigned int DirIDX, const std::string &newPath="");
const std::string& GetUserPath(const unsigned int DirIDX, const std::string &newPath="");
// probably doesn't belong here
std::string GetThemeDir(const std::string& theme_name);
// Returns the path to where the sys file are
std::string GetSysDirectory();

View File

@ -116,6 +116,7 @@ LogManager::~LogManager()
delete m_fileLog;
delete m_consoleLog;
delete m_debuggerLog;
}
void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type,

View File

@ -46,7 +46,7 @@ public:
void Log(LogTypes::LOG_LEVELS, const char *msg);
bool IsValid() { return (m_logfile != NULL); }
bool IsValid() { return (bool)m_logfile; }
bool IsEnabled() const { return m_enable; }
void SetEnable(bool enable) { m_enable = enable; }

View File

@ -5,9 +5,26 @@
#define GCC_VER(x,y,z) ((x) * 10000 + (y) * 100 + (z))
#define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
#ifndef __has_include
#define __has_include(s) 0
#endif
#if GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__ && !ANDROID
// GCC 4.4 provides <condition_variable>
#include <condition_variable>
#elif __has_include(<condition_variable>)
// clang and libc++ provide <condition_variable> on OSX. However, the version
// of libc++ bundled with OSX 10.7 and 10.8 is buggy: it uses _ as a variable.
//
// We work around this issue by undefining and redefining _.
#undef _
#include <condition_variable>
#define _(s) wxGetTranslation((s))
#else
// partial std::condition_variable implementation for win32/pthread

View File

@ -5,9 +5,16 @@
#define GCC_VER(x,y,z) ((x) * 10000 + (y) * 100 + (z))
#define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
#ifndef __has_include
#define __has_include(s) 0
#endif
#if GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__ && !ANDROID
// GCC 4.4 provides <mutex>
#include <mutex>
#elif __has_include(<mutex>)
// Clang + libc++
#include <mutex>
#else
// partial <mutex> implementation for win32/pthread

View File

@ -5,12 +5,19 @@
#define GCC_VER(x,y,z) ((x) * 10000 + (y) * 100 + (z))
#define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
#ifndef __has_include
#define __has_include(s) 0
#endif
#if GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__ && !ANDROID
// GCC 4.4 provides <thread>
#ifndef _GLIBCXX_USE_SCHED_YIELD
#define _GLIBCXX_USE_SCHED_YIELD
#endif
#include <thread>
#elif __has_include(<thread>)
// Clang + libc++
#include <thread>
#else
// partial std::thread implementation for win32/pthread

View File

@ -18,9 +18,9 @@
#ifndef _THREAD_H_
#define _THREAD_H_
#include "StdThread.h"
#include "StdMutex.h"
#include "StdConditionVariable.h"
#include "StdMutex.h"
#include "StdThread.h"
// Don't include common.h here as it will break LogManager
#include "CommonTypes.h"

View File

@ -29,6 +29,7 @@
std::vector<VideoBackend*> g_available_video_backends;
VideoBackend* g_video_backend = NULL;
static VideoBackend* s_default_backend = NULL;
#ifdef _WIN32
// http://msdn.microsoft.com/en-us/library/ms725491.aspx
@ -49,17 +50,27 @@ static bool IsGteVista()
void VideoBackend::PopulateList()
{
VideoBackend* backends[4] = { NULL };
// D3D11 > OGL > D3D9 > SW
#ifdef _WIN32
g_available_video_backends.push_back(new DX9::VideoBackend);
g_available_video_backends.push_back(backends[2] = new DX9::VideoBackend);
if (IsGteVista())
g_available_video_backends.push_back(new DX11::VideoBackend);
g_available_video_backends.push_back(backends[0] = new DX11::VideoBackend);
#endif
#ifndef USE_GLES
g_available_video_backends.push_back(new OGL::VideoBackend);
g_available_video_backends.push_back(backends[1] = new OGL::VideoBackend);
#endif
g_available_video_backends.push_back(new SW::VideoSoftware);
g_available_video_backends.push_back(backends[3] = new SW::VideoSoftware);
g_video_backend = g_available_video_backends.front();
for (int i = 0; i < 4; ++i)
{
if (backends[i])
{
s_default_backend = g_video_backend = backends[i];
break;
}
}
}
void VideoBackend::ClearList()
@ -73,8 +84,8 @@ void VideoBackend::ClearList()
void VideoBackend::ActivateBackend(const std::string& name)
{
if (name.length() == 0) // If NULL, set it to the first one in the list. Expected behavior
g_video_backend = g_available_video_backends.front();
if (name.length() == 0) // If NULL, set it to the default backend (expected behavior)
g_video_backend = s_default_backend;
for (std::vector<VideoBackend*>::const_iterator it = g_available_video_backends.begin(); it != g_available_video_backends.end(); ++it)
if (name == (*it)->GetName())

View File

@ -97,6 +97,7 @@ public:
virtual void RunLoop(bool enable) = 0;
virtual std::string GetName() = 0;
virtual std::string GetDisplayName() { return GetName(); }
virtual void ShowConfig(void*) {}