summaryrefslogtreecommitdiff
path: root/py
diff options
context:
space:
mode:
Diffstat (limited to 'py')
-rw-r--r--py/misc.h18
-rw-r--r--py/mpconfig.h103
-rw-r--r--py/mpprint.c4
-rw-r--r--py/runtime_utils.c4
4 files changed, 92 insertions, 37 deletions
diff --git a/py/misc.h b/py/misc.h
index 67248ac2f..5188b8030 100644
--- a/py/misc.h
+++ b/py/misc.h
@@ -456,15 +456,15 @@ static inline uint32_t mp_clz_mpi(mp_int_t x) {
}
return zeroes;
#else
- MP_STATIC_ASSERT(sizeof(mp_int_t) == sizeof(long long)
- || sizeof(mp_int_t) == sizeof(long));
-
- // ugly, but should compile to single intrinsic unless O0 is set
- if (mp_check(sizeof(mp_int_t) == sizeof(long))) {
- return mp_clzl((unsigned long)x);
- } else {
- return mp_clzll((unsigned long long)x);
- }
+ #if MP_INT_MAX == INT_MAX
+ return mp_clz((unsigned)x);
+ #elif MP_INT_MAX == LONG_MAX
+ return mp_clzl((unsigned long)x);
+ #elif MP_INT_MAX == LLONG_MAX
+ return mp_clzll((unsigned long long)x);
+ #else
+ #error Unexpected MP_INT_MAX value
+ #endif
#endif
}
diff --git a/py/mpconfig.h b/py/mpconfig.h
index 6da872c56..6ad27c51f 100644
--- a/py/mpconfig.h
+++ b/py/mpconfig.h
@@ -26,6 +26,15 @@
#ifndef MICROPY_INCLUDED_PY_MPCONFIG_H
#define MICROPY_INCLUDED_PY_MPCONFIG_H
+#include <stdint.h>
+
+#if defined(__cplusplus) // Required on at least one compiler to get ULLONG_MAX
+#include <climits>
+#else
+#include <limits.h>
+#endif
+
+
// Current version of MicroPython. This is used by sys.implementation.version
// as well as a fallback to generate MICROPY_GIT_TAG if the git repo or tags
// are unavailable.
@@ -161,6 +170,78 @@
#define MICROPY_OBJ_IMMEDIATE_OBJS (MICROPY_OBJ_REPR != MICROPY_OBJ_REPR_D)
#endif
+// Definition of the `mp_int_t` and `mp_uint_t` types and associated macros.
+// Normally, it suffices for the platform to do nothing: A type as wide
+// as a pointer is chosen, unless nanboxing (REPR_D) is selected, in
+// which case a 64-bit type is chosen to match the assumed size of
+// double-precision floats.
+//
+// In the case of exceptions, the port, board, or variant must define
+// MP_INT_TYPE as MP_INT_TYPE_OTHER and provide all the typedefs and
+// defines.
+#define MP_INT_TYPE_INTPTR (0)
+#define MP_INT_TYPE_INT64 (1)
+#define MP_INT_TYPE_OTHER (2)
+
+#if !defined(MP_INT_TYPE)
+#if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D
+#define MP_INT_TYPE (MP_INT_TYPE_INT64)
+#else
+#define MP_INT_TYPE (MP_INT_TYPE_INTPTR)
+#endif
+#endif
+
+#if MP_INT_TYPE == MP_INT_TYPE_INTPTR
+typedef intptr_t mp_int_t;
+typedef uintptr_t mp_uint_t;
+#define MP_INT_MAX INTPTR_MAX
+#define MP_INT_MIN INTPTR_MIN
+#define MP_UINT_MAX INTPTR_UMAX
+#elif MP_INT_TYPE == MP_INT_TYPE_INT64
+typedef int64_t mp_int_t;
+typedef uint64_t mp_uint_t;
+#define MP_INT_MAX INT64_MAX
+#define MP_INT_MIN INT64_MIN
+#define MP_UINT_MAX INT64_UMAX
+#endif
+
+// mp_printf format support for mp_int_t. In the unusual case that MP_INT_MAX doesn't
+// match any of the standard C types (int/long/long long), provide all 3
+// macros. Otherwise, rely on these automatic definitions.
+#if !defined(INT_FMT)
+#if MP_INT_MAX == INT_MAX
+#define INT_FMT "%d"
+#define UINT_FMT "%u"
+#define HEX_FMT "%x"
+#elif MP_INT_MAX == LONG_MAX
+#define INT_FMT "%ld"
+#define UINT_FMT "%lu"
+#define HEX_FMT "%lx"
+#elif MP_INT_MAX == LLONG_MAX
+#define INT_FMT "%lld"
+#define UINT_FMT "%llu"
+#define HEX_FMT "%llx"
+#else
+#error Unexpected MP_INT_MAX value
+#endif
+#endif
+
+// mp_printf format support for size_t. In the unusual case that SIZE_MAX doesn't
+// match any of the standard C types (int/long/long long), provide a
+// macro. Otherwise, rely on these automatic definitions.
+#if !defined(SIZE_FMT)
+#if SIZE_MAX == UINT_MAX
+#define SIZE_FMT "%u"
+#elif SIZE_MAX == ULONG_MAX
+#define SIZE_FMT "%lu"
+#elif SIZE_MAX == ULLONG_MAX
+#define SIZE_FMT "%llu"
+#else
+#error Unexpected SIZE_MAX value
+#endif
+#endif
+
+
/*****************************************************************************/
/* Memory allocation policy */
@@ -2237,28 +2318,6 @@ typedef time_t mp_timestamp_t;
#define MP_SSIZE_MAX SSIZE_MAX
#endif
-// printf format spec to use for mp_int_t and friends
-#ifndef INT_FMT
-#if defined(__LP64__)
-// Archs where mp_int_t == long, long != int
-#define UINT_FMT "%lu"
-#define INT_FMT "%ld"
-#define HEX_FMT "%lx"
-#define SIZE_FMT "%lu"
-#elif defined(_WIN64)
-#define UINT_FMT "%llu"
-#define INT_FMT "%lld"
-#define HEX_FMT "%llx"
-#define SIZE_FMT "%llu"
-#else
-// Archs where mp_int_t == int
-#define UINT_FMT "%u"
-#define INT_FMT "%d"
-#define HEX_FMT "%x"
-#define SIZE_FMT "%u"
-#endif
-#endif // INT_FMT
-
// Modifier for function which doesn't return
#ifndef MP_NORETURN
#define MP_NORETURN __attribute__((noreturn))
diff --git a/py/mpprint.c b/py/mpprint.c
index 89b3dbd76..fa37a4d07 100644
--- a/py/mpprint.c
+++ b/py/mpprint.c
@@ -482,7 +482,7 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) {
}
// parse long and long long specifiers (only where they make a difference)
- #if defined(MICROPY_UNIX_COVERAGE) || (LONG_MAX > INT_MAX)
+ #if (MP_INT_MAX > INT_MAX && MP_INT_MAX == LONG_MAX) || defined(MICROPY_UNIX_COVERAGE)
#define SUPPORT_L_FORMAT (1)
#else
#define SUPPORT_L_FORMAT (0)
@@ -491,7 +491,7 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) {
bool long_arg = false;
#endif
- #if (MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_D) || defined(_WIN64) || defined(MICROPY_UNIX_COVERAGE)
+ #if (MP_INT_MAX > LONG_MAX) || defined(MICROPY_UNIX_COVERAGE)
#define SUPPORT_LL_FORMAT (1)
#else
#define SUPPORT_LL_FORMAT (0)
diff --git a/py/runtime_utils.c b/py/runtime_utils.c
index 50526b210..3b0ae279a 100644
--- a/py/runtime_utils.c
+++ b/py/runtime_utils.c
@@ -77,10 +77,6 @@ bool mp_mul_ll_overflow(long long int x, long long int y, long long int *res) {
return overflow;
}
-#define MP_UINT_MAX (~(mp_uint_t)0)
-#define MP_INT_MAX ((mp_int_t)(MP_UINT_MAX >> 1))
-#define MP_INT_MIN (-MP_INT_MAX - 1)
-
bool mp_mul_mp_int_t_overflow(mp_int_t x, mp_int_t y, mp_int_t *res) {
// Check for multiply overflow; see CERT INT32-C
if (x > 0) { // x is positive