Skip to content

Commit 8b8d189

Browse files
committed
py: Adjust object repr C (30-bit stuffed float) to reduce code size.
This patch adds/subtracts a constant from the 30-bit float representation so that str/qstr representations are favoured: they now have all the high bits set to zero. This makes encoding/decoding qstr strings more efficient (and they are used more often than floats, which are now slightly less efficient to encode/decode). Saves about 300 bytes of code space on Thumb 2 arch.
1 parent 8f7ff85 commit 8b8d189

File tree

2 files changed

+13
-10
lines changed

2 files changed

+13
-10
lines changed

py/mpconfig.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,17 @@
6363
// - xxxx...xxx0 : a pointer to an mp_obj_base_t (unless a fake object)
6464
#define MICROPY_OBJ_REPR_B (1)
6565

66-
// A MicroPython object is a machine word having the following form:
66+
// A MicroPython object is a machine word having the following form (called R):
6767
// - iiiiiiii iiiiiiii iiiiiiii iiiiiii1 small int with 31-bit signed value
68-
// - x1111111 1qqqqqqq qqqqqqqq qqqqq110 str with 20-bit qstr value
68+
// - 01111111 1qqqqqqq qqqqqqqq qqqqq110 str with 20-bit qstr value
6969
// - s1111111 10000000 00000000 00000010 +/- inf
7070
// - s1111111 1xxxxxxx xxxxxxxx xxxxx010 nan, x != 0
7171
// - seeeeeee efffffff ffffffff ffffff10 30-bit fp, e != 0xff
7272
// - pppppppp pppppppp pppppppp pppppp00 ptr (4 byte alignment)
73+
// Str and float stored as O = R + 0x80800000, retrieved as R = O - 0x80800000.
74+
// This makes strs easier to encode/decode as they have zeros in the top 9 bits.
7375
// This scheme only works with 32-bit word size and float enabled.
76+
7477
#define MICROPY_OBJ_REPR_C (2)
7578

7679
#ifndef MICROPY_OBJ_REPR

py/obj.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -130,30 +130,30 @@ static inline bool MP_OBJ_IS_SMALL_INT(mp_const_obj_t o)
130130
#define MP_OBJ_SMALL_INT_VALUE(o) (((mp_int_t)(o)) >> 1)
131131
#define MP_OBJ_NEW_SMALL_INT(small_int) ((mp_obj_t)((((mp_int_t)(small_int)) << 1) | 1))
132132

133-
#define mp_const_float_e ((mp_obj_t)((0x402df854 & ~3) | 2))
134-
#define mp_const_float_pi ((mp_obj_t)((0x40490fdb & ~3) | 2))
133+
#define mp_const_float_e ((mp_obj_t)(((0x402df854 & ~3) | 2) + 0x80800000))
134+
#define mp_const_float_pi ((mp_obj_t)(((0x40490fdb & ~3) | 2) + 0x80800000))
135135

136136
static inline bool mp_obj_is_float(mp_const_obj_t o)
137-
{ return (((mp_uint_t)(o)) & 3) == 2 && (((mp_uint_t)(o)) & 0x7f800004) != 0x7f800004; }
137+
{ return (((mp_uint_t)(o)) & 3) == 2 && (((mp_uint_t)(o)) & 0xff800007) != 0x00000006; }
138138
static inline mp_float_t mp_obj_float_get(mp_const_obj_t o) {
139139
union {
140140
mp_float_t f;
141141
mp_uint_t u;
142-
} num = {.u = (mp_uint_t)o & ~3};
142+
} num = {.u = ((mp_uint_t)o - 0x80800000) & ~3};
143143
return num.f;
144144
}
145145
static inline mp_obj_t mp_obj_new_float(mp_float_t f) {
146146
union {
147147
mp_float_t f;
148148
mp_uint_t u;
149149
} num = {.f = f};
150-
return (mp_obj_t)((num.u & ~0x3) | 2);
150+
return (mp_obj_t)(((num.u & ~0x3) | 2) + 0x80800000);
151151
}
152152

153153
static inline bool MP_OBJ_IS_QSTR(mp_const_obj_t o)
154-
{ return (((mp_uint_t)(o)) & 0x7f800007) == 0x7f800006; }
155-
#define MP_OBJ_QSTR_VALUE(o) ((((mp_uint_t)(o)) >> 3) & 0xfffff)
156-
#define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 3) | 0x7f800006))
154+
{ return (((mp_uint_t)(o)) & 0xff800007) == 0x00000006; }
155+
#define MP_OBJ_QSTR_VALUE(o) (((mp_uint_t)(o)) >> 3)
156+
#define MP_OBJ_NEW_QSTR(qst) ((mp_obj_t)((((mp_uint_t)(qst)) << 3) | 0x00000006))
157157

158158
static inline bool MP_OBJ_IS_OBJ(mp_const_obj_t o)
159159
{ return ((((mp_int_t)(o)) & 3) == 0); }

0 commit comments

Comments
 (0)