diff --git a/CMakeLists.txt b/CMakeLists.txt index 7d7f99e5b..45719707d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) 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 0a9bb67c1..3dc813334 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 a6d623df3..eabb3bcf1 100644 --- a/include/mgba/internal/debugger/cli-debugger.h +++ b/include/mgba/internal/debugger/cli-debugger.h @@ -25,13 +25,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 4033f4a13..1d646208e 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 8b98d8a7b..f00a000d1 100644 --- a/src/debugger/cli-debugger.c +++ b/src/debugger/cli-debugger.c @@ -848,10 +848,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"); @@ -859,7 +859,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 6e2d287fa..73dd978d6 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 6ecaaf74f..617161851 100644 --- a/src/gb/gb.c +++ b/src/gb/gb.c @@ -701,7 +701,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); } @@ -720,7 +720,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 a2385954e..a08c6d73f 100644 --- a/src/gba/gba.c +++ b/src/gba/gba.c @@ -662,7 +662,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); } @@ -685,7 +685,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 @@ -706,7 +706,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 84343e35f..94d0856ca 100644 --- a/src/platform/opengl/gles2.c +++ b/src/platform/opengl/gles2.c @@ -149,6 +149,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 @@ -324,6 +326,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);