summaryrefslogtreecommitdiff
path: root/Source/Core/Common
diff options
context:
space:
mode:
authorNeoBrainX <NeoBrainX@gmail.com>2011-08-27 20:42:11 +0200
committerNeoBrainX <NeoBrainX@gmail.com>2011-08-27 20:42:11 +0200
commit06e640532aa093902e81f09aa18de1b084fcc5ce (patch)
treec9c375c37e5adecfb7e2dd7b53f2aa5e049aebf2 /Source/Core/Common
parentc0dd84cf7d0410d5f247f8641208f43fabe8c420 (diff)
Various changes which improve FreeBSD support.
Patches by martymac, all credits go to him ;)
Diffstat (limited to 'Source/Core/Common')
-rw-r--r--Source/Core/Common/Src/CPUDetect.cpp9
-rw-r--r--Source/Core/Common/Src/CommonFuncs.h6
-rw-r--r--Source/Core/Common/Src/MemoryUtil.cpp48
3 files changed, 57 insertions, 6 deletions
diff --git a/Source/Core/Common/Src/CPUDetect.cpp b/Source/Core/Common/Src/CPUDetect.cpp
index 810c5d2a59..7c231b0a69 100644
--- a/Source/Core/Common/Src/CPUDetect.cpp
+++ b/Source/Core/Common/Src/CPUDetect.cpp
@@ -32,6 +32,10 @@
//#include <config/i386/cpuid.h>
#include <xmmintrin.h>
+#if defined __FreeBSD__
+#include <sys/types.h>
+#include <machine/cpufunc.h>
+#else
static inline void do_cpuid(unsigned int *eax, unsigned int *ebx,
unsigned int *ecx, unsigned int *edx)
{
@@ -65,15 +69,20 @@ static inline void do_cpuid(unsigned int *eax, unsigned int *ebx,
);
#endif
}
+#endif /* defined __FreeBSD__ */
static void __cpuid(int info[4], int x)
{
+#if defined __FreeBSD__
+ do_cpuid((unsigned int)x, (unsigned int*)info);
+#else
unsigned int eax = x, ebx = 0, ecx = 0, edx = 0;
do_cpuid(&eax, &ebx, &ecx, &edx);
info[0] = eax;
info[1] = ebx;
info[2] = ecx;
info[3] = edx;
+#endif
}
#endif
diff --git a/Source/Core/Common/Src/CommonFuncs.h b/Source/Core/Common/Src/CommonFuncs.h
index 7dd156f42e..c79137780d 100644
--- a/Source/Core/Common/Src/CommonFuncs.h
+++ b/Source/Core/Common/Src/CommonFuncs.h
@@ -45,6 +45,8 @@ _mm_shuffle_epi8(__m128i a, __m128i mask)
#include <errno.h>
#ifdef __linux__
#include <byteswap.h>
+#elif defined __FreeBSD__
+#include <sys/endian.h>
#endif
// go to debugger mode
@@ -137,6 +139,10 @@ inline __attribute__((always_inline)) u32 swap32(u32 _data)
{return __builtin_bswap32(_data);}
inline __attribute__((always_inline)) u64 swap64(u64 _data)
{return __builtin_bswap64(_data);}
+#elif __FreeBSD__
+inline u16 swap16(u16 _data) {return bswap16(_data);}
+inline u32 swap32(u32 _data) {return bswap32(_data);}
+inline u64 swap64(u64 _data) {return bswap64(_data);}
#else
// Slow generic implementation.
inline u16 swap16(u16 data) {return (data >> 8) | (data << 8);}
diff --git a/Source/Core/Common/Src/MemoryUtil.cpp b/Source/Core/Common/Src/MemoryUtil.cpp
index bc65f856f4..65c70e0c5e 100644
--- a/Source/Core/Common/Src/MemoryUtil.cpp
+++ b/Source/Core/Common/Src/MemoryUtil.cpp
@@ -27,28 +27,64 @@
#include <stdio.h>
#endif
+#if !defined(MAP_32BIT)
+#include <unistd.h>
+#define PAGE_MASK (getpagesize() - 1)
+#define round_page(x) ((((unsigned long)(x)) + PAGE_MASK) & ~(PAGE_MASK))
+#endif
+
// This is purposely not a full wrapper for virtualalloc/mmap, but it
// provides exactly the primitive operations that Dolphin needs.
void* AllocateExecutableMemory(size_t size, bool low)
{
-#ifdef _WIN32
+ static char *map_hint = 0;
+#if defined(__x86_64__) && !defined(MAP_32BIT)
+ if (low && (!map_hint))
+ map_hint = (char*)round_page(512*1024*1024); /* 0.5 GB rounded up to the next page */
+#endif
+
+#if defined(_WIN32)
void* ptr = VirtualAlloc(0, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#else
- void* ptr = mmap(0, size, PROT_READ | PROT_WRITE | PROT_EXEC,
+ void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_ANON | MAP_PRIVATE
-#if defined __linux__ && defined __x86_64__
+#if defined(__x86_64__)
+#if defined(MAP_32BIT)
| (low ? MAP_32BIT : 0)
-#endif
+#else
+ | (low ? MAP_FIXED : 0)
+#endif /* defined(MAP_32BIT) */
+#endif /* defined(__x86_64__) */
, -1, 0);
-#endif
+#endif /* defined(_WIN32) */
// printf("Mapped executable memory at %p (size %ld)\n", ptr,
// (unsigned long)size);
+#if defined(__FreeBSD__)
+ if (ptr == MAP_FAILED)
+ {
+ ptr = NULL;
+#else
if (ptr == NULL)
+ {
+#endif
PanicAlert("Failed to allocate executable memory");
-#ifdef _M_X64
+ }
+#if defined(__x86_64__) && !defined(MAP_32BIT)
+ else
+ {
+ if (low)
+ {
+ map_hint += size;
+ map_hint = (char*)round_page(map_hint); /* round up to the next page */
+ // printf("Next map will (hopefully) be at %p\n", map_hint);
+ }
+ }
+#endif
+
+#if defined(_M_X64)
if ((u64)ptr >= 0x80000000 && low == true)
PanicAlert("Executable memory ended up above 2GB!");
#endif