From e988bbbd9f87086bc5db55a32ee1a7e99e60be71 Mon Sep 17 00:00:00 2001 From: Carsten Larsen Date: Sat, 4 Feb 2017 12:55:27 +0100 Subject: [PATCH] Fix 64 bit alignment errors --- app/system/program_test.cpp | 4 ++-- configure | 4 +++- lib/clib/alloccpy.c | 2 +- lib/clib/mem.c | 12 +++++++--- lib/clib/memcpy.c | 22 +++++++++--------- lib/clib/memoo.cpp | 45 +++++++++++++++++++++++++++++++++++++ lib/clib/memset.c | 8 ++++++- lib/clib/strlen.c | 2 +- lib/platform.h | 22 ------------------ 9 files changed, 80 insertions(+), 41 deletions(-) create mode 100644 lib/clib/memoo.cpp diff --git a/app/system/program_test.cpp b/app/system/program_test.cpp index bba2ac7d..728a157d 100644 --- a/app/system/program_test.cpp +++ b/app/system/program_test.cpp @@ -357,7 +357,7 @@ void TestProgram::RunTestset6() TestExecution("help trigon"); TestExecution("help hyper"); TestExecution("help complex"); - TestExecution("help statements"); // Error + TestExecution("help statements"); TestExecution("help operators"); TestExecution("help sin"); TestExecution("help help"); @@ -382,7 +382,7 @@ void TestProgram::RunTestset6() TestExecution("eval 7+7"); TestExecution("delete x"); TestExecution("delete pi"); - TestExecution("eval pi/2"); // Error + TestExecution("eval pi/2"); TestExecution("list"); TestExecution("memory"); TestExecution("version"); diff --git a/configure b/configure index 918ce9cd..ec21187f 100755 --- a/configure +++ b/configure @@ -162,6 +162,7 @@ LIBC2SRCS=' lib/dconv/dragon4.cpp lib/dconv/dmath.cpp lib/dconv/dprint.cpp + lib/clib/memoo.cpp ' if make -v 2>&1 | grep GNU > /dev/null 2>&1 ; then @@ -243,7 +244,8 @@ if $VALID ; then echo "CFLAGS = ${ARCFLAG}$options ${CROSSCOMPILEFLAGS}" echo "CXXFLAGS = ${ARCFLAG}$options ${CROSSCOMPILEFLAGS}-I." # echo "CXXFLAGS = -Wno-inline-new-delete ${ARCFLAG}$options ${CROSSCOMPILEFLAGS}-I." - echo "LFLAGS = $gcclib -lamathapp${outext} -lcamath${outext} -lcomplex${outext} -lamath${outext}" +# echo "LFLAGS = $gcclib -lamathapp${outext} -lcamath${outext} -lcomplex${outext} -lamath${outext}" + echo "LFLAGS = -lamathapp${outext} -lcomplex${outext} -lamath${outext} -lcamath${outext} $gcclib" echo echo "FLXCAT = build/flexcat/flexcat" echo "MKDIR = mkdir" diff --git a/lib/clib/alloccpy.c b/lib/clib/alloccpy.c index fb82eb79..d60c01bb 100644 --- a/lib/clib/alloccpy.c +++ b/lib/clib/alloccpy.c @@ -46,7 +46,7 @@ unsigned int AllocAndCopy(char **destination, const char *source) while (*i) i++; - n = i - s + 1; + n = (unsigned int)(i - s + 1); size = n; *destination = AllocMemSafe(size); d = *destination; diff --git a/lib/clib/mem.c b/lib/clib/mem.c index 50b2bcac..173eaaed 100644 --- a/lib/clib/mem.c +++ b/lib/clib/mem.c @@ -43,6 +43,12 @@ # define Debug(x,y,z) #endif +#if defined(__x86_64__) || defined(__aarch64__) || \ + defined(_M_AMD64) || defined(_M_ARM64) || \ + defined(__powerpc64__) +#define P64BIT +#endif + /** * @brief Block of allocated memory. */ @@ -59,8 +65,8 @@ struct MemoryBlock struct MemoryList { struct MemoryBlock *first; - long peak; - long size; + size_t peak; + size_t size; long count; }; @@ -93,7 +99,7 @@ void* AllocMemSafe(size_t size) list->count = 0; } -#if defined(__x86_64__) || defined(__aarch64__) || defined(_M_AMD64) || defined(_M_ARM64) || defined(__powerpc64__) +#ifdef P64BIT // Align to bytes of 8 allocsize = (size + 7) & ~0x07; #else diff --git a/lib/clib/memcpy.c b/lib/clib/memcpy.c index 4e366966..b8d2ec57 100644 --- a/lib/clib/memcpy.c +++ b/lib/clib/memcpy.c @@ -52,10 +52,12 @@ * sizeof(word) MUST BE A POWER OF TWO * SO THAT wmask BELOW IS ALL ONES */ -#if defined(__x86_64__) || defined(__aarch64__) || defined(_M_AMD64) || defined(_M_ARM64) || defined(__powerpc64__) -typedef uint64_t word; -#else typedef uint32_t word; + +#ifdef _WIN32 +typedef unsigned long long mem_ptr; +#else +typedef unsigned long mem_ptr; #endif /** @@ -77,13 +79,13 @@ void MemCopy(void *destination, const void *source, unsigned int length) if (length == 0 || dst == src) // nothing to do return; - if ((unsigned long)dst < (unsigned long)src) { + if ((mem_ptr)dst < (mem_ptr)src) { // Copy forward - t = (unsigned long)src; // only need low bits - if ((t | (unsigned long)dst) & wmask) { + t = (mem_ptr)src; // only need low bits + if ((t | (mem_ptr)dst) & wmask) { // Try to align operands. This cannot be done unless the low bits match. - if ((t ^ (unsigned long)dst) & wmask || length < wsize) + if ((t ^ (mem_ptr)dst) & wmask || length < wsize) t = length; else t = wsize - (t & wmask); @@ -105,10 +107,10 @@ void MemCopy(void *destination, const void *source, unsigned int length) // (t&wmask) bytes to align, not wsize-(t&wmask). src += length; dst += length; - t = (unsigned long)src; - if ((t | (unsigned long)dst) & wmask) { + t = (mem_ptr)src; + if ((t | (mem_ptr)dst) & wmask) { - if ((t ^ (unsigned long)dst) & wmask || length <= wsize) + if ((t ^ (mem_ptr)dst) & wmask || length <= wsize) t = length; else t &= wmask; diff --git a/lib/clib/memoo.cpp b/lib/clib/memoo.cpp new file mode 100644 index 00000000..47407e6a --- /dev/null +++ b/lib/clib/memoo.cpp @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2015-2017 Carsten Sonne Larsen + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "mem.h" +#include "clib.h" + +/* GCC 2.95 */ +#if (__GNUC__ == 2 && __GNUC_MINOR__ == 95) +void* operator new (size_t size) { return AllocMemSafe(size); } +void* operator new[] (size_t size) { return AllocMemSafe(size); } +void operator delete (void* ptr) { FreeMemSafe(ptr); } +void operator delete[] (void* ptr) { FreeMemSafe(ptr); } +#endif + +/* GCC 3+ and Windows */ +#if (__GNUC__ > 2) || defined (_WIN32) +#include +void* operator new (size_t size) throw(std::bad_alloc) { return AllocMemSafe(size); } +void* operator new[] (size_t size) throw(std::bad_alloc) { return AllocMemSafe(size); } +void operator delete (void* ptr) throw() { FreeMemSafe(ptr); } +void operator delete[] (void* ptr) throw() { FreeMemSafe(ptr); } +#endif diff --git a/lib/clib/memset.c b/lib/clib/memset.c index 3b8f9461..3fa7a5c0 100644 --- a/lib/clib/memset.c +++ b/lib/clib/memset.c @@ -47,6 +47,12 @@ #pragma GCC diagnostic ignored "-Wcast-align" #endif +#ifdef _WIN32 +typedef unsigned long long mem_ptr; +#else +typedef unsigned long mem_ptr; +#endif + /** * @brief Fill block of memory with a constant value. */ @@ -87,7 +93,7 @@ void MemSet(void *dst0, int c0, unsigned int length) } /* Align destination by filling in bytes. */ - if ((t = (long)dst & wmask) != 0) { + if ((t = (mem_ptr)dst & wmask) != 0) { t = wsize - t; length -= t; do { diff --git a/lib/clib/strlen.c b/lib/clib/strlen.c index 71252b2b..92de58c4 100644 --- a/lib/clib/strlen.c +++ b/lib/clib/strlen.c @@ -34,5 +34,5 @@ int StrLen(const char *string) char *s = i; while (*i) i++; - return i - s; + return (int)(i - s); } diff --git a/lib/platform.h b/lib/platform.h index c3de92d5..3e544ce8 100644 --- a/lib/platform.h +++ b/lib/platform.h @@ -296,26 +296,4 @@ typedef u_int64_t uint64_t; #define CLEARWINDOW EMPTYSTRING #endif /* ANSICONSOLE */ -/* Memory allocation */ -#ifdef __cplusplus - -/* GCC 2.95 */ -#if (__GNUC__ == 2 && __GNUC_MINOR__ == 95) -inline void* operator new (size_t size) { return AllocMemSafe(size); } -inline void* operator new[] (size_t size) { return AllocMemSafe(size); } -inline void operator delete (void* ptr) { FreeMemSafe(ptr); } -inline void operator delete[] (void* ptr) { FreeMemSafe(ptr); } -#endif - -/* GCC 3+ and Windows */ -#if (__GNUC__ > 2) || defined (_WIN32) -#include -inline void* operator new (size_t size) throw(std::bad_alloc) { return AllocMemSafe(size); } -inline void* operator new[] (size_t size) throw(std::bad_alloc) { return AllocMemSafe(size); } -inline void operator delete (void* ptr) throw() { FreeMemSafe(ptr); } -inline void operator delete[] (void* ptr) throw() { FreeMemSafe(ptr); } -#endif - -#endif /* __cplusplus */ - #endif /* AMATH_LIB_PLATFORM_H */