All: Support building on PPC Mac
jump to
@@ -2,7 +2,11 @@ cmake_minimum_required(VERSION 3.1)
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()@@ -218,7 +222,9 @@ endif()
if(APPLE) add_definitions(-D_DARWIN_C_SOURCE) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=10.6") + 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 @@ #ifndef M_PI
#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 @@ #else
#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 @@ void* _ptr = (ARR); \
__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 @@ #define LOAD_16LE(DEST, ADDR, ARR) DEST = *(uint16_t*) ((uintptr_t) (ARR) + (size_t) (ADDR))
#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 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 @@ #include <mgba-util/common.h>
CXX_GUARD_START +#ifdef vector +#undef vector +#endif + #define DECLARE_VECTOR(NAME, TYPE) \ struct NAME { \ TYPE* vector; \
@@ -60,13 +60,13 @@ uint32_t oldValue;
uint32_t newValue; enum mWatchpointType watchType; enum mWatchpointType accessType; - }; + } wp; struct { uint32_t opcode; enum mBreakpointType breakType; - }; - }; + } bp; + } type; }; struct mDebugger;
@@ -25,13 +25,9 @@ CLIDV_ERROR_TYPE,
CLIDV_INT_TYPE, CLIDV_CHAR_TYPE, } type; - union { - char* charValue; - struct { - int32_t intValue; - int segmentValue; - }; - }; + char* charValue; + int32_t intValue; + int segmentValue; }; typedef void (*CLIDebuggerCommand)(struct CLIDebugger*, struct CLIDebugVector*);
@@ -39,7 +39,7 @@ return;
} 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 @@ watchpoint = ARMDebugWatchpointListGetPointer(&debugger->watchpoints, i);
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; } }
@@ -848,10 +848,10 @@ }
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");@@ -859,7 +859,7 @@ }
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 @@ snprintf(stub->outgoing, GDB_STUB_MAX_LINE - 4, "S%02x", SIGINT);
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 @@ break;
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 @@
#ifdef _MSC_VER value = _byteswap_ulong(value); #else - value = __builtin_bswap32(value); + LOAD_32BE(value, 0, &value); #endif if (reg <= ARM_PC) {
@@ -701,7 +701,7 @@ #ifdef USE_DEBUGGERS
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); }@@ -720,7 +720,7 @@ #ifdef USE_DEBUGGERS
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); }
@@ -662,7 +662,7 @@ #ifdef USE_DEBUGGERS
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); }@@ -685,7 +685,7 @@ #ifdef USE_DEBUGGERS
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@@ -706,7 +706,7 @@ case CPU_COMPONENT_DEBUGGER:
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 @@ size_t i;
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 @@ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, toPow2(width), toPow2(height), 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0);
#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 @@ glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, v->width, v->height, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 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
@@ -149,6 +149,8 @@ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0);
#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@@ -324,6 +326,8 @@ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, v->width, v->height, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 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 @@
#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 @@ #include <mgba-util/circle-buffer.h>
#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);