@@ -87,23 +87,31 @@ int vsnprintf_P(char *str, size_t strSize, PGM_P formatP, va_list ap) __attribut
87
87
// w1, w0
88
88
89
89
#ifdef __ets__
90
- #define pgm_read_byte (addr ) \
91
- (__extension__({ \
92
- PGM_P __local = (PGM_P)(addr); /* isolate varible for macro expansion */ \
93
- ptrdiff_t __offset = ((uint32_t )__local & 0x00000003 ); /* byte aligned mask */ \
94
- const uint32_t * __addr32 = (const uint32_t * )((const uint8_t * )(__local )- __offset ); \
95
- uint8_t __result = ((* __addr32 ) >> (__offset * 8 )); \
96
- __result ; \
97
- }))
98
-
99
- #define pgm_read_word (addr ) \
100
- (__extension__({ \
101
- PGM_P __local = (PGM_P)(addr); /* isolate varible for macro expansion */ \
102
- ptrdiff_t __offset = ((uint32_t )__local & 0x00000002 ); /* word aligned mask */ \
103
- const uint32_t * __addr32 = (const uint32_t * )((const uint8_t * )(__local ) - __offset ); \
104
- uint16_t __result = ((* __addr32 ) >> (__offset * 8 )); \
105
- __result ; \
106
- }))
90
+
91
+ #define pgm_read_with_offset (addr , res ) \
92
+ asm("extui %0, %1, 0, 2\n" /* Extract offset within word (in bytes) */ \
93
+ "sub %1, %1, %0\n" /* Subtract offset from addr, yielding an aligned address */ \
94
+ "l32i.n %1, %1, 0x0\n" /* Load word from aligned address */ \
95
+ "slli %0, %0, 3\n" /* Mulitiply offset by 8, yielding an offset in bits */ \
96
+ "ssr %0\n" /* Prepare to shift by offset (in bits) */ \
97
+ "srl %0, %1\n" /* Shift right; now the requested byte is the first one */ \
98
+ :"=r" (res ), "=r" (addr ) \
99
+ :"1" (addr ) \
100
+ :);
101
+
102
+ static inline uint8_t pgm_read_byte (const void * addr ) {
103
+ register uint32_t res ;
104
+ pgm_read_with_offset (addr , res );
105
+ return (uint8_t ) res ; /* This masks the lower byte from the returned word */
106
+ }
107
+
108
+ /* Although this says "word", it's actually 16 bit, i.e. half word on Xtensa */
109
+ static inline uint16_t pgm_read_word (const void * addr ) {
110
+ register uint32_t res ;
111
+ pgm_read_with_offset (addr , res );
112
+ return (uint16_t ) res ; /* This masks the lower half-word from the returned word */
113
+ }
114
+
107
115
#else //__ets__
108
116
#define pgm_read_byte (addr ) (*reinterpret_cast<const uint8_t*>(addr))
109
117
#define pgm_read_word (addr ) (*reinterpret_cast<const uint16_t*>(addr))
0 commit comments