@@ -61,42 +61,43 @@ extern "C" {
61
61
// w1, w0
62
62
63
63
#define pgm_read_with_offset (addr, res ) \
64
- __asm__ (" extui %0, %1, 0, 2\n " /* Extract offset within word (in bytes) */ \
65
- " sub %1, %1, %0\n " /* Subtract offset from addr, yielding an aligned address */ \
66
- " l32i.n %1, %1, 0x0\n " /* Load word from aligned address */ \
67
- " ssa8l %0\n " /* Prepare to shift by offset (in bits) */ \
68
- " src %0, %1, %1\n " /* Shift right; now the requested byte is the first one */ \
69
- :" =r" (res), "=r"(addr) \
70
- :"1"(addr) \
71
- :);
64
+ __asm__ ( \
65
+ " extui\t %0, %1, 0, 2\n\t " /* Extract offset within word (in bytes) */ \
66
+ " sub\t %1, %1, %0\n\t " /* Subtract offset from addr, yielding an aligned address */ \
67
+ " l32i.n\t %1, %1, 0\n\t " /* Load word from aligned address */ \
68
+ " ssa8l\t %0\n\t " /* Prepare to shift by offset (in bits) */ \
69
+ " src\t %0, %1, %1" /* Shift right; now the requested byte is the first one */ \
70
+ : " =r" (res), "+r"(addr))
72
71
73
72
#define pgm_read_dword_with_offset (addr, res ) \
74
- __asm__ (" extui %0, %1, 0, 2\n " /* Extract offset within word (in bytes) */ \
75
- " sub %1, %1, %0\n " /* Subtract offset from addr, yielding an aligned address */ \
76
- " l32i a14, %1, 0\n " \
77
- " l32i %1, %1, 4\n " \
78
- " ssa8l %0\n " \
79
- " src %0, %1, a14\n " \
80
- :" =r" (res), "=r"(addr) \
81
- :"1"(addr) \
82
- :"a14");
73
+ do { \
74
+ uint32_t temp; \
75
+ __asm__ ( \
76
+ " extui\t %0, %1, 0, 2\n\t " /* Extract offset within word (in bytes) */ \
77
+ " sub\t %1, %1, %0\n\t " /* Subtract offset from addr, yielding an aligned address */ \
78
+ " l32i.n\t %2, %1, 0\n\t " /* Load 2 words */ \
79
+ " l32i.n\t %1, %1, 4\n\t " /* from aligned address */ \
80
+ " ssa8l\t %0\n\t " /* Prepare to shift by offset (in bits) */ \
81
+ " src\t %0, %1, %2" /* Shift right in order to extract the requested dword */ \
82
+ : " =r" (res), " +r" (addr), " =r" (temp)); \
83
+ } while (0 )
83
84
84
85
static inline uint8_t pgm_read_byte_inlined (const void * addr) {
85
86
uint32_t res;
86
87
pgm_read_with_offset (addr, res);
87
- return ( uint8_t ) res; /* This masks the lower byte from the returned word */
88
+ return res; /* Implicit cast to uint8_t masks the lower byte from the returned word */
88
89
}
89
90
90
91
/* Although this says "word", it's actually 16 bit, i.e. half word on Xtensa */
91
92
static inline uint16_t pgm_read_word_inlined (const void * addr) {
92
93
uint32_t res;
93
94
pgm_read_with_offset (addr, res);
94
- return ( uint16_t ) res; /* This masks the lower half-word from the returned word */
95
+ return res; /* Implicit cast to uint16_t masks the lower half-word from the returned word */
95
96
}
96
97
97
98
/* Can't legally cast bits of uint32_t to a float w/o conversion or std::memcpy, which is inefficient. */
98
99
/* The ASM block doesn't care the type, so just pass in what C thinks is a float and return in custom fcn. */
99
- static inline float pgm_read_float_unaligned (const void * addr) {
100
+ static inline float pgm_read_float_unaligned (const void * addr) {
100
101
float res;
101
102
pgm_read_with_offset (addr, res);
102
103
return res;
@@ -121,7 +122,7 @@ static inline uint32_t pgm_read_dword_unaligned(const void *addr) {
121
122
}
122
123
123
124
#define pgm_read_ptr_unaligned (addr ) ((void *)pgm_read_dword_unaligned(addr))
124
- #define pgm_read_word_unaligned (addr ) ((uint16_t )( pgm_read_dword_unaligned(addr) & 0xffff ))
125
+ #define pgm_read_word_unaligned (addr ) ((uint16_t )pgm_read_dword_unaligned(addr))
125
126
126
127
127
128
// Allow selection of _aligned or _unaligned, but default to _unaligned for Arduino compatibility
0 commit comments