py: Add object repr "C", where 30-bit floats are stuffed in obj word.
This new object representation puts floats into the object word instead of on the heap, at the expense of reducing their precision to 30 bits. It only makes sense when the word size is 32-bits.
This commit is contained in:
parent
aedb859177
commit
183edefddd
@ -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
|
||||
|
35
py/obj.h
35
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.
|
||||
|
@ -39,6 +39,8 @@
|
||||
#include <math.h>
|
||||
#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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user