diff --git a/py/mpconfig.h b/py/mpconfig.h index 2c4169070d..d4a9f3c50c 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -70,25 +70,28 @@ // A MicroPython object is a machine word having the following form: // - xxxx...xxx1 : a small int, bits 1 and above are the value -// - xxxx...xx10 : a qstr, bits 2 and above are the value +// - xxxx...x010 : a qstr, bits 3 and above are the value +// - xxxx...x110 : an immediate object, bits 3 and above are the value // - xxxx...xx00 : a pointer to an mp_obj_base_t (unless a fake object) #define MICROPY_OBJ_REPR_A (0) // A MicroPython object is a machine word having the following form: // - xxxx...xx01 : a small int, bits 2 and above are the value -// - xxxx...xx11 : a qstr, bits 2 and above are the value +// - xxxx...x011 : a qstr, bits 3 and above are the value +// - xxxx...x111 : an immediate object, bits 3 and above are the value // - 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 (called R): // - iiiiiiii iiiiiiii iiiiiiii iiiiiii1 small int with 31-bit signed value -// - 01111111 1qqqqqqq qqqqqqqq qqqqq110 str with 20-bit qstr value +// - 01111111 1qqqqqqq qqqqqqqq qqqq0110 str with 19-bit qstr value +// - 01111111 10000000 00000000 ssss1110 immediate object with 4-bit 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) -// Str and float stored as O = R + 0x80800000, retrieved as R = O - 0x80800000. -// This makes strs easier to encode/decode as they have zeros in the top 9 bits. +// Str, immediate and float stored as O = R + 0x80800000, retrieved as R = O - 0x80800000. +// This makes strs/immediates easier to encode/decode as they have zeros in the top 9 bits. // This scheme only works with 32-bit word size and float enabled. #define MICROPY_OBJ_REPR_C (2) @@ -98,6 +101,7 @@ // - 01111111 11111000 00000000 00000000 00000000 00000000 00000000 00000000 normalised nan // - 01111111 11111101 iiiiiiii iiiiiiii iiiiiiii iiiiiiii iiiiiiii iiiiiii1 small int // - 01111111 11111110 00000000 00000000 qqqqqqqq qqqqqqqq qqqqqqqq qqqqqqq1 str +// - 01111111 11111111 ss000000 00000000 00000000 00000000 00000000 00000000 immediate object // - 01111111 11111100 00000000 00000000 pppppppp pppppppp pppppppp pppppp00 ptr (4 byte alignment) // Stored as O = R + 0x8004000000000000, retrieved as R = O - 0x8004000000000000. // This makes pointers have all zeros in the top 32 bits. diff --git a/py/obj.h b/py/obj.h index d98a0470da..f0bb44a403 100644 --- a/py/obj.h +++ b/py/obj.h @@ -87,9 +87,14 @@ static inline bool mp_obj_is_small_int(mp_const_obj_t o) #define MP_OBJ_NEW_SMALL_INT(small_int) ((mp_obj_t)((((mp_uint_t)(small_int)) << 1) | 1)) static inline bool mp_obj_is_qstr(mp_const_obj_t o) - { return ((((mp_int_t)(o)) & 3) == 2); } -#define MP_OBJ_QSTR_VALUE(o) (((mp_uint_t)(o)) >> 2) -#define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 2) | 2)) + { return ((((mp_int_t)(o)) & 7) == 2); } +#define MP_OBJ_QSTR_VALUE(o) (((mp_uint_t)(o)) >> 3) +#define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 3) | 2)) + +static inline bool mp_obj_is_immediate_obj(mp_const_obj_t o) + { return ((((mp_int_t)(o)) & 7) == 6); } +#define MP_OBJ_IMMEDIATE_OBJ_VALUE(o) (((mp_uint_t)(o)) >> 3) +#define MP_OBJ_NEW_IMMEDIATE_OBJ(val) ((mp_obj_t)(((val) << 3) | 6)) #if MICROPY_PY_BUILTINS_FLOAT #define mp_const_float_e MP_ROM_PTR(&mp_const_float_e_obj) @@ -113,9 +118,14 @@ static inline bool mp_obj_is_small_int(mp_const_obj_t o) #define MP_OBJ_NEW_SMALL_INT(small_int) ((mp_obj_t)((((mp_uint_t)(small_int)) << 2) | 1)) static inline bool mp_obj_is_qstr(mp_const_obj_t o) - { return ((((mp_int_t)(o)) & 3) == 3); } -#define MP_OBJ_QSTR_VALUE(o) (((mp_uint_t)(o)) >> 2) -#define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 2) | 3)) + { return ((((mp_int_t)(o)) & 7) == 3); } +#define MP_OBJ_QSTR_VALUE(o) (((mp_uint_t)(o)) >> 3) +#define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 3) | 3)) + +static inline bool mp_obj_is_immediate_obj(mp_const_obj_t o) + { return ((((mp_int_t)(o)) & 7) == 7); } +#define MP_OBJ_IMMEDIATE_OBJ_VALUE(o) (((mp_uint_t)(o)) >> 3) +#define MP_OBJ_NEW_IMMEDIATE_OBJ(val) ((mp_obj_t)(((val) << 3) | 7)) #if MICROPY_PY_BUILTINS_FLOAT #define mp_const_float_e MP_ROM_PTR(&mp_const_float_e_obj) @@ -161,9 +171,14 @@ static inline mp_obj_t mp_obj_new_float(mp_float_t f) { #endif static inline bool mp_obj_is_qstr(mp_const_obj_t o) - { return (((mp_uint_t)(o)) & 0xff800007) == 0x00000006; } -#define MP_OBJ_QSTR_VALUE(o) (((mp_uint_t)(o)) >> 3) -#define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 3) | 0x00000006)) + { return (((mp_uint_t)(o)) & 0xff80000f) == 0x00000006; } +#define MP_OBJ_QSTR_VALUE(o) (((mp_uint_t)(o)) >> 4) +#define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 4) | 0x00000006)) + +static inline bool mp_obj_is_immediate_obj(mp_const_obj_t o) + { return (((mp_uint_t)(o)) & 0xff80000f) == 0x0000000e; } +#define MP_OBJ_IMMEDIATE_OBJ_VALUE(o) (((mp_uint_t)(o)) >> 4) +#define MP_OBJ_NEW_IMMEDIATE_OBJ(val) ((mp_obj_t)(((val) << 4) | 0xe)) static inline bool mp_obj_is_obj(mp_const_obj_t o) { return ((((mp_int_t)(o)) & 3) == 0); } @@ -180,6 +195,11 @@ static inline bool mp_obj_is_qstr(mp_const_obj_t o) #define MP_OBJ_QSTR_VALUE(o) ((((uint32_t)(o)) >> 1) & 0xffffffff) #define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)(((uint64_t)(((uint32_t)(qst)) << 1)) | 0x0002000000000001)) +static inline bool mp_obj_is_immediate_obj(mp_const_obj_t o) + { return ((((uint64_t)(o)) & 0xffff000000000000) == 0x0003000000000000); } +#define MP_OBJ_IMMEDIATE_OBJ_VALUE(o) ((((uint32_t)(o)) >> 46) & 3) +#define MP_OBJ_NEW_IMMEDIATE_OBJ(val) (((uint64_t)(val) << 46) | 0x0003000000000000) + #if MICROPY_PY_BUILTINS_FLOAT #if MICROPY_FLOAT_IMPL != MICROPY_FLOAT_IMPL_DOUBLE