summaryrefslogtreecommitdiffstatshomepage
path: root/py
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2015-11-06 23:25:10 +0000
committerDamien George <damien.p.george@gmail.com>2015-11-06 23:25:10 +0000
commit8b8d189bc09b050f9a66048736c7e990ac8c8335 (patch)
tree5d9d9c77f5a9d0b84724037ff74907cf9c565234 /py
parent8f7ff854b0e341aa49d198a93fea7e83dd4cc71c (diff)
downloadmicropython-8b8d189bc09b050f9a66048736c7e990ac8c8335.tar.gz
micropython-8b8d189bc09b050f9a66048736c7e990ac8c8335.zip
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.
Diffstat (limited to 'py')
-rw-r--r--py/mpconfig.h7
-rw-r--r--py/obj.h16
2 files changed, 13 insertions, 10 deletions
diff --git a/py/mpconfig.h b/py/mpconfig.h
index 98e9406c6b..4f023934e6 100644
--- a/py/mpconfig.h
+++ b/py/mpconfig.h
@@ -63,14 +63,17 @@
// - 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:
+// A MicroPython object is a machine word having the following form (called R):
// - iiiiiiii iiiiiiii iiiiiiii iiiiiii1 small int with 31-bit signed value
-// - x1111111 1qqqqqqq qqqqqqqq qqqqq110 str with 20-bit qstr value
+// - 01111111 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)
+// 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.
// This scheme only works with 32-bit word size and float enabled.
+
#define MICROPY_OBJ_REPR_C (2)
#ifndef MICROPY_OBJ_REPR
diff --git a/py/obj.h b/py/obj.h
index af5652c4ec..64395083af 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -130,16 +130,16 @@ static inline bool MP_OBJ_IS_SMALL_INT(mp_const_obj_t o)
#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))
+#define mp_const_float_e ((mp_obj_t)(((0x402df854 & ~3) | 2) + 0x80800000))
+#define mp_const_float_pi ((mp_obj_t)(((0x40490fdb & ~3) | 2) + 0x80800000))
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; }
+ { return (((mp_uint_t)(o)) & 3) == 2 && (((mp_uint_t)(o)) & 0xff800007) != 0x00000006; }
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};
+ } num = {.u = ((mp_uint_t)o - 0x80800000) & ~3};
return num.f;
}
static inline mp_obj_t mp_obj_new_float(mp_float_t f) {
@@ -147,13 +147,13 @@ static inline mp_obj_t mp_obj_new_float(mp_float_t f) {
mp_float_t f;
mp_uint_t u;
} num = {.f = f};
- return (mp_obj_t)((num.u & ~0x3) | 2);
+ return (mp_obj_t)(((num.u & ~0x3) | 2) + 0x80800000);
}
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))
+ { 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))
static inline bool MP_OBJ_IS_OBJ(mp_const_obj_t o)
{ return ((((mp_int_t)(o)) & 3) == 0); }