Skip to content

Commit d2a487d

Browse files
earlephilhowerd-a-v
authored andcommitted
Clean up code to build under GCC7, fix pgm_read_unaligned (#6270)
Apply most compatible changes needed to get the core compiling under GCC 7.2 to the main gcc 4.8 tree to ease porting for 3.0.0. Update pgmspace.h with corrected and optimized unaligned pgm_read macros. Now pgm_read_dword in the unaligned case gives proper results even if optimization is enabled and is also written in assembly and only 1 instruction longer than the pgm_read_byte macro (which also has been optimized to reduce 1 instruction). These changes should marginally shrink code and speed up flash reads accordingly. The toolchain should/will be rebuilt at a later time with this optimization to ensure it's used in the libc.a/etc. files.
1 parent 76cda9b commit d2a487d

File tree

6 files changed

+31
-32
lines changed

6 files changed

+31
-32
lines changed

cores/esp8266/Arduino.h

+1
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,7 @@ const int TIM_DIV265 __attribute__((deprecated, weak)) = TIM_DIV256;
256256
#ifdef __cplusplus
257257

258258
#include <algorithm>
259+
#include <cmath>
259260
#include <pgmspace.h>
260261

261262
#include "WCharacter.h"

cores/esp8266/core_esp8266_app_entry_noextra4k.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ extern "C" void call_user_start();
2727
/* this is the default NONOS-SDK user's heap location */
2828
static cont_t g_cont __attribute__ ((aligned (16)));
2929

30-
extern "C" void ICACHE_RAM_ATTR app_entry_redefinable(void)
30+
extern "C" void app_entry_redefinable(void)
3131
{
3232
g_pcont = &g_cont;
3333

cores/esp8266/core_esp8266_main.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,8 @@ void init_done() {
236236
237237
*/
238238

239-
extern "C" void ICACHE_RAM_ATTR app_entry_redefinable(void) __attribute__((weak));
240-
extern "C" void ICACHE_RAM_ATTR app_entry_redefinable(void)
239+
extern "C" void app_entry_redefinable(void) __attribute__((weak));
240+
extern "C" void app_entry_redefinable(void)
241241
{
242242
/* Allocate continuation context on this SYS stack,
243243
and save pointer to it. */
@@ -248,9 +248,9 @@ extern "C" void ICACHE_RAM_ATTR app_entry_redefinable(void)
248248
call_user_start();
249249
}
250250

251-
static void ICACHE_RAM_ATTR app_entry_custom (void) __attribute__((weakref("app_entry_redefinable")));
251+
static void app_entry_custom (void) __attribute__((weakref("app_entry_redefinable")));
252252

253-
extern "C" void ICACHE_RAM_ATTR app_entry (void)
253+
extern "C" void app_entry (void)
254254
{
255255
return app_entry_custom();
256256
}

libraries/ESP8266WiFi/src/include/UdpContext.h

+3-5
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,9 @@ class UdpContext
8484

8585
void unref()
8686
{
87-
if(this != 0) {
88-
DEBUGV(":ur %d\r\n", _refcnt);
89-
if(--_refcnt == 0) {
90-
delete this;
91-
}
87+
DEBUGV(":ur %d\r\n", _refcnt);
88+
if(--_refcnt == 0) {
89+
delete this;
9290
}
9391
}
9492

tools/sdk/ld/eagle.app.v6.common.ld.h

+2
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ SECTIONS
127127
*(.init.literal)
128128
*(.init)
129129

130+
*(.text.app_entry*) /* The main startup code */
131+
130132
/* all functional callers are placed in IRAM (including SPI/IRQ callbacks/etc) here */
131133
*(.text._ZNKSt8functionIF*EE*) /* std::function<any(...)>::operator()() const */
132134
} >iram1_0_seg :iram1_0_phdr

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

+20-22
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,23 @@ extern "C" {
4848
asm("extui %0, %1, 0, 2\n" /* Extract offset within word (in bytes) */ \
4949
"sub %1, %1, %0\n" /* Subtract offset from addr, yielding an aligned address */ \
5050
"l32i.n %1, %1, 0x0\n" /* Load word from aligned address */ \
51-
"slli %0, %0, 3\n" /* Mulitiply offset by 8, yielding an offset in bits */ \
52-
"ssr %0\n" /* Prepare to shift by offset (in bits) */ \
53-
"srl %0, %1\n" /* Shift right; now the requested byte is the first one */ \
51+
"ssa8l %0\n" /* Prepare to shift by offset (in bits) */ \
52+
"src %0, %1, %1\n" /* Shift right; now the requested byte is the first one */ \
5453
:"=r"(res), "=r"(addr) \
5554
:"1"(addr) \
5655
:);
5756

57+
#define pgm_read_dword_with_offset(addr, res) \
58+
asm("extui %0, %1, 0, 2\n" /* Extract offset within word (in bytes) */ \
59+
"sub %1, %1, %0\n" /* Subtract offset from addr, yielding an aligned address */ \
60+
"l32i a15, %1, 0\n" \
61+
"l32i %1, %1, 4\n" \
62+
"ssa8l %0\n" \
63+
"src %0, %1, a15\n" \
64+
:"=r"(res), "=r"(addr) \
65+
:"1"(addr) \
66+
:"a15");
67+
5868
static inline uint8_t pgm_read_byte_inlined(const void* addr) {
5969
register uint32_t res;
6070
pgm_read_with_offset(addr, res);
@@ -68,8 +78,6 @@ static inline uint16_t pgm_read_word_inlined(const void* addr) {
6878
return (uint16_t) res; /* This masks the lower half-word from the returned word */
6979
}
7080

71-
72-
7381
#define pgm_read_byte(addr) pgm_read_byte_inlined(addr)
7482
#define pgm_read_word_aligned(addr) pgm_read_word_inlined(addr)
7583
#ifdef __cplusplus
@@ -82,26 +90,16 @@ static inline uint16_t pgm_read_word_inlined(const void* addr) {
8290
#define pgm_read_ptr_aligned(addr) (*(const void* const*)(addr))
8391
#endif
8492

85-
__attribute__((optimize("-O3"), always_inline)) static inline uint32_t pgm_read_dword_unaligned(const void *addr) {
86-
if (!(((int)addr)&3)) return *(const uint32_t *)addr;
87-
int off = (((int)addr) & 3) << 3;
88-
const uint32_t *p = (const uint32_t *)((int)addr & (~3));
89-
uint32_t a = *p++;
90-
uint32_t b = *p;
91-
return (a>>off) | (b <<(32-off));
93+
static inline uint32_t pgm_read_dword_unaligned(const void *addr) {
94+
uint32_t res;
95+
pgm_read_dword_with_offset(addr, res);
96+
return res;
9297
}
9398

94-
__attribute__((optimize("-O3"), always_inline)) static inline float pgm_read_float_unaligned(const void *addr) {
95-
return (float)pgm_read_dword_unaligned(addr);
96-
}
99+
#define pgm_read_float_unaligned(addr) ((float)pgm_read_dword_unaligned(addr))
100+
#define pgm_read_ptr_unaligned(addr) ((void*)pgm_read_dword_unaligned(addr))
101+
#define pgm_read_word_unaligned(addr) ((uint16_t)(pgm_read_dword_unaligned(addr) & 0xffff))
97102

98-
__attribute__((optimize("-O3"), always_inline)) static inline void *pgm_read_ptr_unaligned(const void *addr) {
99-
return (void *)pgm_read_dword_unaligned(addr);
100-
}
101-
102-
__attribute__((optimize("-O3"), always_inline)) static inline uint16_t pgm_read_word_unaligned(const void *addr) {
103-
return pgm_read_dword_unaligned(addr) & 0xffff;
104-
}
105103

106104
// Allow selection of _aligned or _unaligned, but default to _unaligned for Arduino compatibility
107105
// Add -DPGM_READ_UNALIGNED=0 or "#define PGM_READ_UNALIGNED 0" to code to use aligned-only (faster) macros by default

0 commit comments

Comments
 (0)