diff --git a/CMakeLists.txt b/CMakeLists.txt index 1000e8de9..82c050394 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) - 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) diff --git a/include/mgba-util/common.h b/include/mgba-util/common.h index 63e3dd30d..45961ddbb 100644 --- a/include/mgba-util/common.h +++ b/include/mgba-util/common.h @@ -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)) diff --git a/include/mgba-util/platform/posix/threading.h b/include/mgba-util/platform/posix/threading.h index f79d97b10..468e1460c 100644 --- a/include/mgba-util/platform/posix/threading.h +++ b/include/mgba-util/platform/posix/threading.h @@ -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; diff --git a/include/mgba-util/vector.h b/include/mgba-util/vector.h index ae542d41b..c18b6c8b5 100644 --- a/include/mgba-util/vector.h +++ b/include/mgba-util/vector.h @@ -10,6 +10,10 @@ CXX_GUARD_START +#ifdef vector +#undef vector +#endif + #define DECLARE_VECTOR(NAME, TYPE) \ struct NAME { \ TYPE* vector; \ diff --git a/include/mgba/debugger/debugger.h b/include/mgba/debugger/debugger.h index bef61c208..cb31d6e11 100644 --- a/include/mgba/debugger/debugger.h +++ b/include/mgba/debugger/debugger.h @@ -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; diff --git a/include/mgba/internal/debugger/cli-debugger.h b/include/mgba/internal/debugger/cli-debugger.h index 6eb28b1dc..f8acc7bf0 100644 --- a/include/mgba/internal/debugger/cli-debugger.h +++ b/include/mgba/internal/debugger/cli-debugger.h @@ -24,13 +24,9 @@ struct CLIDebugVector { 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*); diff --git a/src/arm/debugger/debugger.c b/src/arm/debugger/debugger.c index fde61a8a8..e6f39687a 100644 --- a/src/arm/debugger/debugger.c +++ b/src/arm/debugger/debugger.c @@ -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); } diff --git a/src/arm/debugger/memory-debugger.c b/src/arm/debugger/memory-debugger.c index faa8651f4..88a8518b6 100644 --- a/src/arm/debugger/memory-debugger.c +++ b/src/arm/debugger/memory-debugger.c @@ -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; } } diff --git a/src/debugger/cli-debugger.c b/src/debugger/cli-debugger.c index cc911d8c7..8b91e9f71 100644 --- a/src/debugger/cli-debugger.c +++ b/src/debugger/cli-debugger.c @@ -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"); } diff --git a/src/debugger/gdb-stub.c b/src/debugger/gdb-stub.c index 3c149c9fc..de0de32f7 100644 --- a/src/debugger/gdb-stub.c +++ b/src/debugger/gdb-stub.c @@ -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) { diff --git a/src/gb/gb.c b/src/gb/gb.c index fcf262696..89f40886e 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -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); } diff --git a/src/gba/gba.c b/src/gba/gba.c index 184548763..f5bd195f3 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -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); } diff --git a/src/lr35902/debugger/memory-debugger.c b/src/lr35902/debugger/memory-debugger.c index 3b9f66343..f9918a1f7 100644 --- a/src/lr35902/debugger/memory-debugger.c +++ b/src/lr35902/debugger/memory-debugger.c @@ -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; } } diff --git a/src/platform/opengl/gl.c b/src/platform/opengl/gl.c index 87b679c6b..cfa05bea9 100644 --- a/src/platform/opengl/gl.c +++ b/src/platform/opengl/gl.c @@ -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 diff --git a/src/platform/opengl/gles2.c b/src/platform/opengl/gles2.c index 2dfa7448b..1401fa238 100644 --- a/src/platform/opengl/gles2.c +++ b/src/platform/opengl/gles2.c @@ -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 diff --git a/src/platform/sdl/sdl-audio.h b/src/platform/sdl/sdl-audio.h index dc21cb86c..2ae920af4 100644 --- a/src/platform/sdl/sdl-audio.h +++ b/src/platform/sdl/sdl-audio.h @@ -13,6 +13,14 @@ CXX_GUARD_START #include #include +// Altivec sometimes defines this +#ifdef vector +#undef vector +#endif +#ifdef bool +#undef bool +#define bool _Bool +#endif mLOG_DECLARE_CATEGORY(SDL_AUDIO); diff --git a/src/platform/sdl/sdl-events.h b/src/platform/sdl/sdl-events.h index 3c67222cd..c9d7b386f 100644 --- a/src/platform/sdl/sdl-events.h +++ b/src/platform/sdl/sdl-events.h @@ -16,6 +16,14 @@ CXX_GUARD_START #include #include +// Altivec sometimes defines this +#ifdef vector +#undef vector +#endif +#ifdef bool +#undef bool +#define bool _Bool +#endif mLOG_DECLARE_CATEGORY(SDL_EVENTS);