diff --git a/py/mpconfig.h b/py/mpconfig.h index 7ab179304c..98e9406c6b 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -63,6 +63,16 @@ // - xxxx...xxx0 : a pointer to an mp_obj_base_t (unless a fake object) #define MICROPY_OBJ_REPR_B (1) +// A MicroPython object is a machine word having the following form: +// - iiiiiiii iiiiiiii iiiiiiii iiiiiii1 small int with 31-bit signed value +// - x1111111 1qqqqqqq qqqqqqqq qqqqq110 str with 20-bit qstr value +// - s1111111 10000000 00000000 00000010 +/- inf +// - s1111111 1xxxxxxx xxxxxxxx xxxxx010 nan, x != 0 +// - seeeeeee efffffff ffffffff ffffff10 30-bit fp, e != 0xff +// - pppppppp pppppppp pppppppp pppppp00 ptr (4 byte alignment) +// This scheme only works with 32-bit word size and float enabled. +#define MICROPY_OBJ_REPR_C (2) + #ifndef MICROPY_OBJ_REPR #define MICROPY_OBJ_REPR (MICROPY_OBJ_REPR_A) #endif diff --git a/py/obj.h b/py/obj.h index faf7e096af..af5652c4ec 100644 --- a/py/obj.h +++ b/py/obj.h @@ -123,6 +123,41 @@ mp_obj_t mp_obj_new_float(mp_float_t value); static inline bool MP_OBJ_IS_OBJ(mp_const_obj_t o) { return ((((mp_int_t)(o)) & 1) == 0); } +#elif MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_C + +static inline bool MP_OBJ_IS_SMALL_INT(mp_const_obj_t o) + { return ((((mp_int_t)(o)) & 1) != 0); } +#define MP_OBJ_SMALL_INT_VALUE(o) (((mp_int_t)(o)) >> 1) +#define MP_OBJ_NEW_SMALL_INT(small_int) ((mp_obj_t)((((mp_int_t)(small_int)) << 1) | 1)) + +#define mp_const_float_e ((mp_obj_t)((0x402df854 & ~3) | 2)) +#define mp_const_float_pi ((mp_obj_t)((0x40490fdb & ~3) | 2)) + +static inline bool mp_obj_is_float(mp_const_obj_t o) + { return (((mp_uint_t)(o)) & 3) == 2 && (((mp_uint_t)(o)) & 0x7f800004) != 0x7f800004; } +static inline mp_float_t mp_obj_float_get(mp_const_obj_t o) { + union { + mp_float_t f; + mp_uint_t u; + } num = {.u = (mp_uint_t)o & ~3}; + return num.f; +} +static inline mp_obj_t mp_obj_new_float(mp_float_t f) { + union { + mp_float_t f; + mp_uint_t u; + } num = {.f = f}; + return (mp_obj_t)((num.u & ~0x3) | 2); +} + +static inline bool MP_OBJ_IS_QSTR(mp_const_obj_t o) + { return (((mp_uint_t)(o)) & 0x7f800007) == 0x7f800006; } +#define MP_OBJ_QSTR_VALUE(o) ((((mp_uint_t)(o)) >> 3) & 0xfffff) +#define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 3) | 0x7f800006)) + +static inline bool MP_OBJ_IS_OBJ(mp_const_obj_t o) + { return ((((mp_int_t)(o)) & 3) == 0); } + #endif // Macros to convert between mp_obj_t and concrete object types. diff --git a/py/objfloat.c b/py/objfloat.c index 7c58f320db..81eac99bd1 100644 --- a/py/objfloat.c +++ b/py/objfloat.c @@ -39,6 +39,8 @@ #include #include "py/formatfloat.h" +#if MICROPY_OBJ_REPR != MICROPY_OBJ_REPR_C + typedef struct _mp_obj_float_t { mp_obj_base_t base; mp_float_t value; @@ -47,6 +49,8 @@ typedef struct _mp_obj_float_t { const mp_obj_float_t mp_const_float_e_obj = {{&mp_type_float}, M_E}; const mp_obj_float_t mp_const_float_pi_obj = {{&mp_type_float}, M_PI}; +#endif + STATIC void float_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind) { (void)kind; mp_float_t o_val = mp_obj_float_get(o_in); @@ -121,6 +125,8 @@ const mp_obj_type_t mp_type_float = { .binary_op = float_binary_op, }; +#if MICROPY_OBJ_REPR != MICROPY_OBJ_REPR_C + mp_obj_t mp_obj_new_float(mp_float_t value) { mp_obj_float_t *o = m_new(mp_obj_float_t, 1); o->base.type = &mp_type_float; @@ -134,6 +140,8 @@ mp_float_t mp_obj_float_get(mp_obj_t self_in) { return self->value; } +#endif + STATIC void mp_obj_float_divmod(mp_float_t *x, mp_float_t *y) { // logic here follows that of CPython // https://docs.python.org/3/reference/expressions.html#binary-arithmetic-operations diff --git a/py/smallint.h b/py/smallint.h index 19b5209ec7..d9e53ee361 100644 --- a/py/smallint.h +++ b/py/smallint.h @@ -32,7 +32,7 @@ // Functions for small integer arithmetic // In SMALL_INT, next-to-highest bits is used as sign, so both must match for value in range -#if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_A +#if MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_A || MICROPY_OBJ_REPR == MICROPY_OBJ_REPR_C #define MP_SMALL_INT_MIN ((mp_int_t)(((mp_int_t)WORD_MSBIT_HIGH) >> 1)) #define MP_SMALL_INT_FITS(n) ((((n) ^ ((n) << 1)) & WORD_MSBIT_HIGH) == 0)