Skip to content

Add Fallback for FASTFLOAT_XXBIT #76

@Alexhuszagh

Description

@Alexhuszagh

The main motivation for this is RISCV, Sparc, and MIPS architectures, which are still in active use, as well as esoteric, proprietary architectures where we cannot possibly enumerate all compiler architecture defines.

Issue

Currently, the size of the architecture is determine via:

#if (defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)   \
       || defined(__amd64) || defined(__aarch64__) || defined(_M_ARM64) \
       || defined(__MINGW64__)                                          \
       || defined(__s390x__)                                            \
       || (defined(__ppc64__) || defined(__PPC64__) || defined(__ppc64le__) || defined(__PPC64LE__)) \
       || defined(__EMSCRIPTEN__))
#define FASTFLOAT_64BIT
#elif (defined(__i386) || defined(__i386__) || defined(_M_IX86)   \
     || defined(__arm__)                                        \
     || defined(__MINGW32__))
#define FASTFLOAT_32BIT
#else
#error Unknown platform (not 32-bit, not 64-bit?)
#endif

This unfortunately hard-codes supported architectures, which means that architectures like the MIPS family, 32-bit PowerPC, and other architectures are not supported (such as RISCV). Other than adding hard-coded support for other architectures, there is a suitable alternative for most cases (there is no way to determine the exact, preferred register size, but size_t is generally a good barometer).

Solution

We can probe SIZE_MAX to attempt to determine the system architecture, which is guaranteed to be defined on all C++11 systems (unlike UINTPTR_MAX or INTPTR_MAX, which may or may not be defined).

A simple check as follows fixes the issue:

  // Need to check incrementally, since SIZE_MAX is a size_t, avoid overflow.
  // We can never tell the register width, but the SIZE_MAX is a good approximation.
  // UINTPTR_MAX and INTPTR_MAX are optional, so avoid them for max portability.
  #if SIZE_MAX == 0xffff
    #error Unknown platform (16-bit, unsupported)
  #elif SIZE_MAX == 0xffffffff
    #define FASTFLOAT_32BIT
  #elif SIZE_MAX == 0xffffffffffffffff
    #define FASTFLOAT_64BIT
  #else
    #error Unknown platform (not 32-bit, not 64-bit?)
  #endif

We need to check in order, from 16-bit to 64-bit, since SIZE_MAX is of type size_t, and therefore on a 16-bit system we'll get an overflow (which should never happen, since who uses 16-bit systems anymore?).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions