Skip to content

Commit ffa0a2b

Browse files
Fix pgm_read_float_unaligned macro
Fixes esp8266#6590 The ASM block that implements the read-uint32-unaligned returns a uint32_t. The old code was doing a cast like `(float)(uint32_t ret) which actually goes and creates a new float of the positive uint value (approx, of course due to exponent and sign bits) which is not correct. C and C++ don't have a concise way to convert the bits in a register from int to float interpretation, so avoid the whole issue by making a new function which uses the same ASM block as the read-uint32-unaligned, just make the destination and return values as floats.
1 parent 215459f commit ffa0a2b

File tree

1 file changed

+8
-1
lines changed
  • tools/sdk/libc/xtensa-lx106-elf/include/sys

1 file changed

+8
-1
lines changed

tools/sdk/libc/xtensa-lx106-elf/include/sys/pgmspace.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,14 @@ static inline uint16_t pgm_read_word_inlined(const void* addr) {
8080
return (uint16_t) res; /* This masks the lower half-word from the returned word */
8181
}
8282

83+
/* Can't legally cast bits of uint32_t to a float w/o conversion or std::memcpy, which is inefficient. */
84+
/* The ASM block doesn't care the type, so just pass in what C thinks is a float and return in custom fcn. */
85+
static inline float pgm_read_float_unaligned(const void *addr) {
86+
register float res;
87+
pgm_read_with_offset(addr, res);
88+
return res;
89+
}
90+
8391
#define pgm_read_byte(addr) pgm_read_byte_inlined(addr)
8492
#define pgm_read_word_aligned(addr) pgm_read_word_inlined(addr)
8593
#ifdef __cplusplus
@@ -98,7 +106,6 @@ static inline uint32_t pgm_read_dword_unaligned(const void *addr) {
98106
return res;
99107
}
100108

101-
#define pgm_read_float_unaligned(addr) ((float)pgm_read_dword_unaligned(addr))
102109
#define pgm_read_ptr_unaligned(addr) ((void*)pgm_read_dword_unaligned(addr))
103110
#define pgm_read_word_unaligned(addr) ((uint16_t)(pgm_read_dword_unaligned(addr) & 0xffff))
104111

0 commit comments

Comments
 (0)