Fix 64 bit alignment errors

This commit is contained in:
Carsten Larsen 2017-02-04 12:55:27 +01:00
parent af7bf8a97a
commit e988bbbd9f
9 changed files with 80 additions and 41 deletions

View File

@ -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");

4
configure vendored
View File

@ -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"

View File

@ -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;

View File

@ -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

View File

@ -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;

45
lib/clib/memoo.cpp Normal file
View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2015-2017 Carsten Sonne Larsen <cs@innolan.dk>
* 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 <new>
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

View File

@ -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 {

View File

@ -34,5 +34,5 @@ int StrLen(const char *string)
char *s = i;
while (*i)
i++;
return i - s;
return (int)(i - s);
}

View File

@ -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 <new>
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 */