@@ -74,11 +74,14 @@ size_t mp_binary_get_size(char struct_type, char val_type, size_t *palign) {
7474 case 'S' :
7575 size = sizeof (void * );
7676 break ;
77+ case 'e' :
78+ size = 2 ;
79+ break ;
7780 case 'f' :
78- size = sizeof ( float ) ;
81+ size = 4 ;
7982 break ;
8083 case 'd' :
81- size = sizeof ( double ) ;
84+ size = 8 ;
8285 break ;
8386 }
8487 break ;
@@ -122,6 +125,10 @@ size_t mp_binary_get_size(char struct_type, char val_type, size_t *palign) {
122125 align = alignof(void * );
123126 size = sizeof (void * );
124127 break ;
128+ case 'e' :
129+ align = 2 ;
130+ size = 2 ;
131+ break ;
125132 case 'f' :
126133 align = alignof(float );
127134 size = sizeof (float );
@@ -144,6 +151,99 @@ size_t mp_binary_get_size(char struct_type, char val_type, size_t *palign) {
144151 return size ;
145152}
146153
154+ #if MICROPY_PY_BUILTINS_FLOAT && MICROPY_FLOAT_USE_NATIVE_FLT16
155+
156+ static inline float mp_decode_half_float (uint16_t hf ) {
157+ union {
158+ uint16_t i ;
159+ _Float16 f ;
160+ } fpu = { .i = hf };
161+ return fpu .f ;
162+ }
163+
164+ static inline uint16_t mp_encode_half_float (float x ) {
165+ union {
166+ uint16_t i ;
167+ _Float16 f ;
168+ } fp_sp = { .f = (_Float16 )x };
169+ return fp_sp .i ;
170+ }
171+
172+ #elif MICROPY_PY_BUILTINS_FLOAT
173+
174+ static float mp_decode_half_float (uint16_t hf ) {
175+ union {
176+ uint32_t i ;
177+ float f ;
178+ } fpu ;
179+
180+ uint16_t m = hf & 0x3ff ;
181+ int e = (hf >> 10 ) & 0x1f ;
182+ if (e == 0x1f ) {
183+ // Half-float is infinity.
184+ e = 0xff ;
185+ } else if (e ) {
186+ // Half-float is normal.
187+ e += 127 - 15 ;
188+ } else if (m ) {
189+ // Half-float is subnormal, make it normal.
190+ e = 127 - 15 ;
191+ while (!(m & 0x400 )) {
192+ m <<= 1 ;
193+ -- e ;
194+ }
195+ m -= 0x400 ;
196+ ++ e ;
197+ }
198+
199+ fpu .i = ((hf & 0x8000 ) << 16 ) | (e << 23 ) | (m << 13 );
200+ return fpu .f ;
201+ }
202+
203+ static uint16_t mp_encode_half_float (float x ) {
204+ union {
205+ uint32_t i ;
206+ float f ;
207+ } fpu = { .f = x };
208+
209+ uint16_t m = (fpu .i >> 13 ) & 0x3ff ;
210+ if (fpu .i & (1 << 12 )) {
211+ // Round up.
212+ ++ m ;
213+ }
214+ int e = (fpu .i >> 23 ) & 0xff ;
215+
216+ if (e == 0xff ) {
217+ // Infinity.
218+ e = 0x1f ;
219+ } else if (e != 0 ) {
220+ e -= 127 - 15 ;
221+ if (e < 0 ) {
222+ // Underflow: denormalized, or zero.
223+ if (e >= -11 ) {
224+ m = (m | 0x400 ) >> - e ;
225+ if (m & 1 ) {
226+ m = (m >> 1 ) + 1 ;
227+ } else {
228+ m >>= 1 ;
229+ }
230+ } else {
231+ m = 0 ;
232+ }
233+ e = 0 ;
234+ } else if (e > 0x3f ) {
235+ // Overflow: infinity.
236+ e = 0x1f ;
237+ m = 0 ;
238+ }
239+ }
240+
241+ uint16_t bits = ((fpu .i >> 16 ) & 0x8000 ) | (e << 10 ) | m ;
242+ return bits ;
243+ }
244+
245+ #endif
246+
147247mp_obj_t mp_binary_get_val_array (char typecode , void * p , size_t index ) {
148248 mp_int_t val = 0 ;
149249 switch (typecode ) {
@@ -240,6 +340,8 @@ mp_obj_t mp_binary_get_val(char struct_type, char val_type, byte *p_base, byte *
240340 const char * s_val = (const char * )(uintptr_t )(mp_uint_t )val ;
241341 return mp_obj_new_str (s_val , strlen (s_val ));
242342 #if MICROPY_PY_BUILTINS_FLOAT
343+ } else if (val_type == 'e' ) {
344+ return mp_obj_new_float_from_f (mp_decode_half_float (val ));
243345 } else if (val_type == 'f' ) {
244346 union {
245347 uint32_t i ;
@@ -309,6 +411,9 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte *p
309411 val = (mp_uint_t )val_in ;
310412 break ;
311413 #if MICROPY_PY_BUILTINS_FLOAT
414+ case 'e' :
415+ val = mp_encode_half_float (mp_obj_get_float_to_f (val_in ));
416+ break ;
312417 case 'f' : {
313418 union {
314419 uint32_t i ;
0 commit comments