mirror of https://github.com/mgba-emu/mgba.git
All: Support building on PPC Mac
This commit is contained in:
parent
c93d03eca8
commit
e456798712
|
@ -2,7 +2,11 @@ cmake_minimum_required(VERSION 2.8.11)
|
|||
project(mGBA)
|
||||
set(BINARY_NAME mgba CACHE INTERNAL "Name of output binaries")
|
||||
if(NOT MSVC)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-missing-field-initializers -std=c99")
|
||||
set(GCC_STD "c99")
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_COMPILER_VERSION VERSION_LESS "4.3")
|
||||
set(GCC_STD "gnu99")
|
||||
endif()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-missing-field-initializers -std=${GCC_STD}")
|
||||
else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_CRT_SECURE_NO_WARNINGS /wd4003 /wd4244 /wd4146")
|
||||
endif()
|
||||
|
@ -216,7 +220,9 @@ endif()
|
|||
|
||||
if(APPLE)
|
||||
add_definitions(-D_DARWIN_C_SOURCE)
|
||||
if(CMAKE_SYSTEM_VERSION VERSION_GREATER "10.5.8")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=10.6")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT HAIKU AND NOT MSVC AND NOT PSP2)
|
||||
|
|
|
@ -73,7 +73,7 @@ typedef intptr_t ssize_t;
|
|||
#define M_PI 3.141592654f
|
||||
#endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#if !defined(_MSC_VER) && (defined(__llvm__) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))
|
||||
#define ATOMIC_STORE(DST, SRC) __atomic_store_n(&DST, SRC, __ATOMIC_RELEASE)
|
||||
#define ATOMIC_LOAD(DST, SRC) DST = __atomic_load_n(&SRC, __ATOMIC_ACQUIRE)
|
||||
#define ATOMIC_ADD(DST, OP) __atomic_add_fetch(&DST, OP, __ATOMIC_RELEASE)
|
||||
|
@ -101,6 +101,8 @@ typedef intptr_t ssize_t;
|
|||
#define PRIz "z"
|
||||
#endif
|
||||
|
||||
#if defined __BIG_ENDIAN__
|
||||
#define LOAD_32BE(DEST, ADDR, ARR) DEST = *(uint32_t*) ((uintptr_t) (ARR) + (size_t) (ADDR))
|
||||
#if defined(__PPC__) || defined(__POWERPC__)
|
||||
#define LOAD_32LE(DEST, ADDR, ARR) { \
|
||||
uint32_t _addr = (ADDR); \
|
||||
|
@ -126,10 +128,39 @@ typedef intptr_t ssize_t;
|
|||
__asm__("sthbrx %0, %1, %2" : : "r"(SRC), "b"(_ptr), "r"(_addr)); \
|
||||
}
|
||||
|
||||
#define LOAD_64LE(DEST, ADDR, ARR) DEST = __builtin_bswap64(((uint64_t*) ARR)[(ADDR) >> 3])
|
||||
#define STORE_64LE(SRC, ADDR, ARR) ((uint64_t*) ARR)[(ADDR) >> 3] = __builtin_bswap64(SRC)
|
||||
#elif defined __BIG_ENDIAN__
|
||||
#if defined(__llvm__) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
#define LOAD_64LE(DEST, ADDR, ARR) { \
|
||||
uint32_t _addr = (ADDR); \
|
||||
union { \
|
||||
struct { \
|
||||
uint32_t hi; \
|
||||
uint32_t lo; \
|
||||
}; \
|
||||
uint64_t b64; \
|
||||
} *bswap = (void*) &DEST; \
|
||||
const void* _ptr = (ARR); \
|
||||
__asm__( \
|
||||
"lwbrx %0, %2, %3 \n" \
|
||||
"lwbrx %1, %2, %4 \n" \
|
||||
: "=r"(bswap->lo), "=r"(bswap->hi) : "b"(_ptr), "r"(_addr), "r"(_addr + 4)); \
|
||||
}
|
||||
|
||||
#define STORE_64LE(SRC, ADDR, ARR) { \
|
||||
uint32_t _addr = (ADDR); \
|
||||
union { \
|
||||
struct { \
|
||||
uint32_t hi; \
|
||||
uint32_t lo; \
|
||||
}; \
|
||||
uint64_t b64; \
|
||||
} *bswap = (void*) &SRC; \
|
||||
const void* _ptr = (ARR); \
|
||||
__asm__( \
|
||||
"stwbrx %0, %2, %3 \n" \
|
||||
"stwbrx %1, %2, %4 \n" \
|
||||
: : "r"(bswap->hi), "r"(bswap->lo), "b"(_ptr), "r"(_addr), "r"(_addr + 4)); \
|
||||
}
|
||||
|
||||
#elif defined(__llvm__) || (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
#define LOAD_64LE(DEST, ADDR, ARR) DEST = __builtin_bswap64(((uint64_t*) ARR)[(ADDR) >> 3])
|
||||
#define LOAD_32LE(DEST, ADDR, ARR) DEST = __builtin_bswap32(((uint32_t*) ARR)[(ADDR) >> 2])
|
||||
#define LOAD_16LE(DEST, ADDR, ARR) DEST = __builtin_bswap16(((uint16_t*) ARR)[(ADDR) >> 1])
|
||||
|
@ -146,6 +177,7 @@ typedef intptr_t ssize_t;
|
|||
#define STORE_64LE(SRC, ADDR, ARR) *(uint64_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)) = SRC
|
||||
#define STORE_32LE(SRC, ADDR, ARR) *(uint32_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)) = SRC
|
||||
#define STORE_16LE(SRC, ADDR, ARR) *(uint16_t*) ((uintptr_t) (ARR) + (size_t) (ADDR)) = SRC
|
||||
#define LOAD_32BE(DEST, ADDR, ARR) DEST = __builtin_bswap32(((uint32_t*) ARR)[(ADDR) >> 2])
|
||||
#endif
|
||||
|
||||
#define MAKE_MASK(START, END) (((1 << ((END) - (START))) - 1) << (START))
|
||||
|
|
|
@ -86,7 +86,12 @@ static inline int ThreadJoin(Thread thread) {
|
|||
|
||||
static inline int ThreadSetName(const char* name) {
|
||||
#ifdef __APPLE__
|
||||
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1060
|
||||
return pthread_setname_np(name);
|
||||
#else
|
||||
UNUSED(name);
|
||||
return 0;
|
||||
#endif
|
||||
#elif defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
pthread_set_name_np(pthread_self(), name);
|
||||
return 0;
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
|
||||
CXX_GUARD_START
|
||||
|
||||
#ifdef vector
|
||||
#undef vector
|
||||
#endif
|
||||
|
||||
#define DECLARE_VECTOR(NAME, TYPE) \
|
||||
struct NAME { \
|
||||
TYPE* vector; \
|
||||
|
|
|
@ -60,13 +60,13 @@ struct mDebuggerEntryInfo {
|
|||
uint32_t newValue;
|
||||
enum mWatchpointType watchType;
|
||||
enum mWatchpointType accessType;
|
||||
};
|
||||
} wp;
|
||||
|
||||
struct {
|
||||
uint32_t opcode;
|
||||
enum mBreakpointType breakType;
|
||||
};
|
||||
};
|
||||
} bp;
|
||||
} type;
|
||||
};
|
||||
|
||||
struct mDebugger;
|
||||
|
|
|
@ -24,13 +24,9 @@ struct CLIDebugVector {
|
|||
CLIDV_INT_TYPE,
|
||||
CLIDV_CHAR_TYPE,
|
||||
} type;
|
||||
union {
|
||||
char* charValue;
|
||||
struct {
|
||||
int32_t intValue;
|
||||
int segmentValue;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
typedef void (*CLIDebuggerCommand)(struct CLIDebugger*, struct CLIDebugVector*);
|
||||
|
|
|
@ -39,7 +39,7 @@ static void ARMDebuggerCheckBreakpoints(struct mDebuggerPlatform* d) {
|
|||
}
|
||||
struct mDebuggerEntryInfo info = {
|
||||
.address = breakpoint->address,
|
||||
.breakType = BREAKPOINT_HARDWARE
|
||||
.type.bp.breakType = BREAKPOINT_HARDWARE
|
||||
};
|
||||
mDebuggerEnter(d->p, DEBUGGER_ENTER_BREAKPOINT, &info);
|
||||
}
|
||||
|
|
|
@ -99,19 +99,19 @@ static bool _checkWatchpoints(struct ARMDebugger* debugger, uint32_t address, st
|
|||
if (!((watchpoint->address ^ address) & ~width) && watchpoint->type & type) {
|
||||
switch (width + 1) {
|
||||
case 1:
|
||||
info->oldValue = debugger->originalMemory.load8(debugger->cpu, address, 0);
|
||||
info->type.wp.oldValue = debugger->originalMemory.load8(debugger->cpu, address, 0);
|
||||
break;
|
||||
case 2:
|
||||
info->oldValue = debugger->originalMemory.load16(debugger->cpu, address, 0);
|
||||
info->type.wp.oldValue = debugger->originalMemory.load16(debugger->cpu, address, 0);
|
||||
break;
|
||||
case 4:
|
||||
info->oldValue = debugger->originalMemory.load32(debugger->cpu, address, 0);
|
||||
info->type.wp.oldValue = debugger->originalMemory.load32(debugger->cpu, address, 0);
|
||||
break;
|
||||
}
|
||||
info->newValue = newValue;
|
||||
info->type.wp.newValue = newValue;
|
||||
info->address = address;
|
||||
info->watchType = watchpoint->type;
|
||||
info->accessType = type;
|
||||
info->type.wp.watchType = watchpoint->type;
|
||||
info->type.wp.accessType = type;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -752,10 +752,10 @@ static void _reportEntry(struct mDebugger* debugger, enum mDebuggerEntryReason r
|
|||
break;
|
||||
case DEBUGGER_ENTER_WATCHPOINT:
|
||||
if (info) {
|
||||
if (info->accessType & WATCHPOINT_WRITE) {
|
||||
cliDebugger->backend->printf(cliDebugger->backend, "Hit watchpoint at 0x%08X: (new value = 0x%08x, old value = 0x%08X)\n", info->address, info->newValue, info->oldValue);
|
||||
if (info->type.wp.accessType & WATCHPOINT_WRITE) {
|
||||
cliDebugger->backend->printf(cliDebugger->backend, "Hit watchpoint at 0x%08X: (new value = 0x%08x, old value = 0x%08X)\n", info->address, info->type.wp.newValue, info->type.wp.oldValue);
|
||||
} else {
|
||||
cliDebugger->backend->printf(cliDebugger->backend, "Hit watchpoint at 0x%08X: (value = 0x%08x)\n", info->address, info->oldValue);
|
||||
cliDebugger->backend->printf(cliDebugger->backend, "Hit watchpoint at 0x%08X: (value = 0x%08x)\n", info->address, info->type.wp.oldValue);
|
||||
}
|
||||
} else {
|
||||
cliDebugger->backend->printf(cliDebugger->backend, "Hit watchpoint\n");
|
||||
|
@ -763,7 +763,7 @@ static void _reportEntry(struct mDebugger* debugger, enum mDebuggerEntryReason r
|
|||
break;
|
||||
case DEBUGGER_ENTER_ILLEGAL_OP:
|
||||
if (info) {
|
||||
cliDebugger->backend->printf(cliDebugger->backend, "Hit illegal opcode at 0x%08X: 0x%08X\n", info->address, info->opcode);
|
||||
cliDebugger->backend->printf(cliDebugger->backend, "Hit illegal opcode at 0x%08X: 0x%08X\n", info->address, info->type.bp.opcode);
|
||||
} else {
|
||||
cliDebugger->backend->printf(cliDebugger->backend, "Hit illegal opcode\n");
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ static void _gdbStubEntered(struct mDebugger* debugger, enum mDebuggerEntryReaso
|
|||
break;
|
||||
case DEBUGGER_ENTER_BREAKPOINT:
|
||||
if (stub->supportsHwbreak && stub->supportsSwbreak && info) {
|
||||
snprintf(stub->outgoing, GDB_STUB_MAX_LINE - 4, "T%02x%cwbreak:;", SIGTRAP, info->breakType == BREAKPOINT_SOFTWARE ? 's' : 'h');
|
||||
snprintf(stub->outgoing, GDB_STUB_MAX_LINE - 4, "T%02x%cwbreak:;", SIGTRAP, info->type.bp.breakType == BREAKPOINT_SOFTWARE ? 's' : 'h');
|
||||
} else {
|
||||
snprintf(stub->outgoing, GDB_STUB_MAX_LINE - 4, "S%02xk", SIGTRAP);
|
||||
}
|
||||
|
@ -54,9 +54,9 @@ static void _gdbStubEntered(struct mDebugger* debugger, enum mDebuggerEntryReaso
|
|||
case DEBUGGER_ENTER_WATCHPOINT:
|
||||
if (info) {
|
||||
const char* type = 0;
|
||||
switch (info->watchType) {
|
||||
switch (info->type.wp.watchType) {
|
||||
case WATCHPOINT_WRITE:
|
||||
if (info->newValue == info->oldValue) {
|
||||
if (info->type.wp.newValue == info->type.wp.oldValue) {
|
||||
if (stub->d.state == DEBUGGER_PAUSED) {
|
||||
stub->d.state = DEBUGGER_RUNNING;
|
||||
}
|
||||
|
@ -363,7 +363,7 @@ static void _writeRegister(struct GDBStub* stub, const char* message) {
|
|||
#ifdef _MSC_VER
|
||||
value = _byteswap_ulong(value);
|
||||
#else
|
||||
value = __builtin_bswap32(value);
|
||||
LOAD_32BE(value, 0, &value);
|
||||
#endif
|
||||
|
||||
if (reg <= ARM_PC) {
|
||||
|
|
|
@ -630,7 +630,7 @@ void GBStop(struct LR35902Core* cpu) {
|
|||
if (cpu->components && cpu->components[CPU_COMPONENT_DEBUGGER]) {
|
||||
struct mDebuggerEntryInfo info = {
|
||||
.address = cpu->pc - 1,
|
||||
.opcode = 0x1000 | cpu->bus
|
||||
.type.bp.opcode = 0x1000 | cpu->bus
|
||||
};
|
||||
mDebuggerEnter((struct mDebugger*) cpu->components[CPU_COMPONENT_DEBUGGER], DEBUGGER_ENTER_ILLEGAL_OP, &info);
|
||||
}
|
||||
|
@ -649,7 +649,7 @@ void GBIllegal(struct LR35902Core* cpu) {
|
|||
if (cpu->components && cpu->components[CPU_COMPONENT_DEBUGGER]) {
|
||||
struct mDebuggerEntryInfo info = {
|
||||
.address = cpu->pc,
|
||||
.opcode = cpu->bus
|
||||
.type.bp.opcode = cpu->bus
|
||||
};
|
||||
mDebuggerEnter((struct mDebugger*) cpu->components[CPU_COMPONENT_DEBUGGER], DEBUGGER_ENTER_ILLEGAL_OP, &info);
|
||||
}
|
||||
|
|
|
@ -602,7 +602,7 @@ void GBAHitStub(struct ARMCore* cpu, uint32_t opcode) {
|
|||
if (gba->debugger) {
|
||||
struct mDebuggerEntryInfo info = {
|
||||
.address = _ARMPCAddress(cpu),
|
||||
.opcode = opcode
|
||||
.type.bp.opcode = opcode
|
||||
};
|
||||
mDebuggerEnter(gba->debugger->d.p, DEBUGGER_ENTER_ILLEGAL_OP, &info);
|
||||
}
|
||||
|
@ -625,7 +625,7 @@ void GBAIllegal(struct ARMCore* cpu, uint32_t opcode) {
|
|||
if (gba->debugger) {
|
||||
struct mDebuggerEntryInfo info = {
|
||||
.address = _ARMPCAddress(cpu),
|
||||
.opcode = opcode
|
||||
.type.bp.opcode = opcode
|
||||
};
|
||||
mDebuggerEnter(gba->debugger->d.p, DEBUGGER_ENTER_ILLEGAL_OP, &info);
|
||||
} else
|
||||
|
@ -646,7 +646,7 @@ void GBABreakpoint(struct ARMCore* cpu, int immediate) {
|
|||
if (gba->debugger) {
|
||||
struct mDebuggerEntryInfo info = {
|
||||
.address = _ARMPCAddress(cpu),
|
||||
.breakType = BREAKPOINT_SOFTWARE
|
||||
.type.bp.breakType = BREAKPOINT_SOFTWARE
|
||||
};
|
||||
mDebuggerEnter(gba->debugger->d.p, DEBUGGER_ENTER_BREAKPOINT, &info);
|
||||
}
|
||||
|
|
|
@ -47,11 +47,11 @@ static bool _checkWatchpoints(struct LR35902Debugger* debugger, uint16_t address
|
|||
for (i = 0; i < LR35902DebugWatchpointListSize(&debugger->watchpoints); ++i) {
|
||||
watchpoint = LR35902DebugWatchpointListGetPointer(&debugger->watchpoints, i);
|
||||
if (watchpoint->address == address && (watchpoint->segment < 0 || watchpoint->segment == debugger->originalMemory.currentSegment(debugger->cpu, address)) && watchpoint->type & type) {
|
||||
info->oldValue = debugger->originalMemory.load8(debugger->cpu, address);
|
||||
info->newValue = newValue;
|
||||
info->type.wp.oldValue = debugger->originalMemory.load8(debugger->cpu, address);
|
||||
info->type.wp.newValue = newValue;
|
||||
info->address = address;
|
||||
info->watchType = watchpoint->type;
|
||||
info->accessType = type;
|
||||
info->type.wp.watchType = watchpoint->type;
|
||||
info->type.wp.accessType = type;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -45,6 +45,8 @@ static void mGLContextSetDimensions(struct VideoBackend* v, unsigned width, unsi
|
|||
#else
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, toPow2(width), toPow2(height), 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0);
|
||||
#endif
|
||||
#elif defined(__BIG_ENDIAN__)
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, toPow2(width), toPow2(height), 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
|
||||
#else
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, toPow2(width), toPow2(height), 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
#endif
|
||||
|
@ -114,6 +116,8 @@ void mGLContextPostFrame(struct VideoBackend* v, const void* frame) {
|
|||
#else
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, v->width, v->height, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, frame);
|
||||
#endif
|
||||
#elif defined(__BIG_ENDIAN__)
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, v->width, v->height, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, frame);
|
||||
#else
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, v->width, v->height, GL_RGBA, GL_UNSIGNED_BYTE, frame);
|
||||
#endif
|
||||
|
|
|
@ -148,6 +148,8 @@ static void mGLES2ContextSetDimensions(struct VideoBackend* v, unsigned width, u
|
|||
#else
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 0);
|
||||
#endif
|
||||
#elif defined(__BIG_ENDIAN__)
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, 0);
|
||||
#else
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
|
||||
#endif
|
||||
|
@ -322,6 +324,8 @@ void mGLES2ContextPostFrame(struct VideoBackend* v, const void* frame) {
|
|||
#else
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, v->width, v->height, 0, GL_RGBA, GL_UNSIGNED_SHORT_1_5_5_5_REV, frame);
|
||||
#endif
|
||||
#elif defined(__BIG_ENDIAN__)
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, v->width, v->height, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, frame);
|
||||
#else
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, v->width, v->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, frame);
|
||||
#endif
|
||||
|
|
|
@ -13,6 +13,14 @@ CXX_GUARD_START
|
|||
#include <mgba/core/log.h>
|
||||
|
||||
#include <SDL.h>
|
||||
// Altivec sometimes defines this
|
||||
#ifdef vector
|
||||
#undef vector
|
||||
#endif
|
||||
#ifdef bool
|
||||
#undef bool
|
||||
#define bool _Bool
|
||||
#endif
|
||||
|
||||
mLOG_DECLARE_CATEGORY(SDL_AUDIO);
|
||||
|
||||
|
|
|
@ -16,6 +16,14 @@ CXX_GUARD_START
|
|||
#include <mgba-util/vector.h>
|
||||
|
||||
#include <SDL.h>
|
||||
// Altivec sometimes defines this
|
||||
#ifdef vector
|
||||
#undef vector
|
||||
#endif
|
||||
#ifdef bool
|
||||
#undef bool
|
||||
#define bool _Bool
|
||||
#endif
|
||||
|
||||
mLOG_DECLARE_CATEGORY(SDL_EVENTS);
|
||||
|
||||
|
|
Loading…
Reference in New Issue