mirror of
https://github.com/esp8266/Arduino.git
synced 2025-04-21 10:26:06 +03:00
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.
This commit is contained in:
parent
76cda9bdbc
commit
d2a487dfd9
@ -256,6 +256,7 @@ const int TIM_DIV265 __attribute__((deprecated, weak)) = TIM_DIV256;
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cmath>
|
||||||
#include <pgmspace.h>
|
#include <pgmspace.h>
|
||||||
|
|
||||||
#include "WCharacter.h"
|
#include "WCharacter.h"
|
||||||
|
@ -27,7 +27,7 @@ extern "C" void call_user_start();
|
|||||||
/* this is the default NONOS-SDK user's heap location */
|
/* this is the default NONOS-SDK user's heap location */
|
||||||
static cont_t g_cont __attribute__ ((aligned (16)));
|
static cont_t g_cont __attribute__ ((aligned (16)));
|
||||||
|
|
||||||
extern "C" void ICACHE_RAM_ATTR app_entry_redefinable(void)
|
extern "C" void app_entry_redefinable(void)
|
||||||
{
|
{
|
||||||
g_pcont = &g_cont;
|
g_pcont = &g_cont;
|
||||||
|
|
||||||
|
@ -236,8 +236,8 @@ void init_done() {
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern "C" void ICACHE_RAM_ATTR app_entry_redefinable(void) __attribute__((weak));
|
extern "C" void app_entry_redefinable(void) __attribute__((weak));
|
||||||
extern "C" void ICACHE_RAM_ATTR app_entry_redefinable(void)
|
extern "C" void app_entry_redefinable(void)
|
||||||
{
|
{
|
||||||
/* Allocate continuation context on this SYS stack,
|
/* Allocate continuation context on this SYS stack,
|
||||||
and save pointer to it. */
|
and save pointer to it. */
|
||||||
@ -248,9 +248,9 @@ extern "C" void ICACHE_RAM_ATTR app_entry_redefinable(void)
|
|||||||
call_user_start();
|
call_user_start();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ICACHE_RAM_ATTR app_entry_custom (void) __attribute__((weakref("app_entry_redefinable")));
|
static void app_entry_custom (void) __attribute__((weakref("app_entry_redefinable")));
|
||||||
|
|
||||||
extern "C" void ICACHE_RAM_ATTR app_entry (void)
|
extern "C" void app_entry (void)
|
||||||
{
|
{
|
||||||
return app_entry_custom();
|
return app_entry_custom();
|
||||||
}
|
}
|
||||||
|
@ -84,11 +84,9 @@ public:
|
|||||||
|
|
||||||
void unref()
|
void unref()
|
||||||
{
|
{
|
||||||
if(this != 0) {
|
DEBUGV(":ur %d\r\n", _refcnt);
|
||||||
DEBUGV(":ur %d\r\n", _refcnt);
|
if(--_refcnt == 0) {
|
||||||
if(--_refcnt == 0) {
|
delete this;
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,6 +127,8 @@ SECTIONS
|
|||||||
*(.init.literal)
|
*(.init.literal)
|
||||||
*(.init)
|
*(.init)
|
||||||
|
|
||||||
|
*(.text.app_entry*) /* The main startup code */
|
||||||
|
|
||||||
/* all functional callers are placed in IRAM (including SPI/IRQ callbacks/etc) here */
|
/* all functional callers are placed in IRAM (including SPI/IRQ callbacks/etc) here */
|
||||||
*(.text._ZNKSt8functionIF*EE*) /* std::function<any(...)>::operator()() const */
|
*(.text._ZNKSt8functionIF*EE*) /* std::function<any(...)>::operator()() const */
|
||||||
} >iram1_0_seg :iram1_0_phdr
|
} >iram1_0_seg :iram1_0_phdr
|
||||||
|
@ -48,13 +48,23 @@ extern "C" {
|
|||||||
asm("extui %0, %1, 0, 2\n" /* Extract offset within word (in bytes) */ \
|
asm("extui %0, %1, 0, 2\n" /* Extract offset within word (in bytes) */ \
|
||||||
"sub %1, %1, %0\n" /* Subtract offset from addr, yielding an aligned address */ \
|
"sub %1, %1, %0\n" /* Subtract offset from addr, yielding an aligned address */ \
|
||||||
"l32i.n %1, %1, 0x0\n" /* Load word from aligned address */ \
|
"l32i.n %1, %1, 0x0\n" /* Load word from aligned address */ \
|
||||||
"slli %0, %0, 3\n" /* Mulitiply offset by 8, yielding an offset in bits */ \
|
"ssa8l %0\n" /* Prepare to shift by offset (in bits) */ \
|
||||||
"ssr %0\n" /* Prepare to shift by offset (in bits) */ \
|
"src %0, %1, %1\n" /* Shift right; now the requested byte is the first one */ \
|
||||||
"srl %0, %1\n" /* Shift right; now the requested byte is the first one */ \
|
|
||||||
:"=r"(res), "=r"(addr) \
|
:"=r"(res), "=r"(addr) \
|
||||||
:"1"(addr) \
|
:"1"(addr) \
|
||||||
:);
|
:);
|
||||||
|
|
||||||
|
#define pgm_read_dword_with_offset(addr, res) \
|
||||||
|
asm("extui %0, %1, 0, 2\n" /* Extract offset within word (in bytes) */ \
|
||||||
|
"sub %1, %1, %0\n" /* Subtract offset from addr, yielding an aligned address */ \
|
||||||
|
"l32i a15, %1, 0\n" \
|
||||||
|
"l32i %1, %1, 4\n" \
|
||||||
|
"ssa8l %0\n" \
|
||||||
|
"src %0, %1, a15\n" \
|
||||||
|
:"=r"(res), "=r"(addr) \
|
||||||
|
:"1"(addr) \
|
||||||
|
:"a15");
|
||||||
|
|
||||||
static inline uint8_t pgm_read_byte_inlined(const void* addr) {
|
static inline uint8_t pgm_read_byte_inlined(const void* addr) {
|
||||||
register uint32_t res;
|
register uint32_t res;
|
||||||
pgm_read_with_offset(addr, res);
|
pgm_read_with_offset(addr, res);
|
||||||
@ -68,8 +78,6 @@ static inline uint16_t pgm_read_word_inlined(const void* addr) {
|
|||||||
return (uint16_t) res; /* This masks the lower half-word from the returned word */
|
return (uint16_t) res; /* This masks the lower half-word from the returned word */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define pgm_read_byte(addr) pgm_read_byte_inlined(addr)
|
#define pgm_read_byte(addr) pgm_read_byte_inlined(addr)
|
||||||
#define pgm_read_word_aligned(addr) pgm_read_word_inlined(addr)
|
#define pgm_read_word_aligned(addr) pgm_read_word_inlined(addr)
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -82,26 +90,16 @@ static inline uint16_t pgm_read_word_inlined(const void* addr) {
|
|||||||
#define pgm_read_ptr_aligned(addr) (*(const void* const*)(addr))
|
#define pgm_read_ptr_aligned(addr) (*(const void* const*)(addr))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__attribute__((optimize("-O3"), always_inline)) static inline uint32_t pgm_read_dword_unaligned(const void *addr) {
|
static inline uint32_t pgm_read_dword_unaligned(const void *addr) {
|
||||||
if (!(((int)addr)&3)) return *(const uint32_t *)addr;
|
uint32_t res;
|
||||||
int off = (((int)addr) & 3) << 3;
|
pgm_read_dword_with_offset(addr, res);
|
||||||
const uint32_t *p = (const uint32_t *)((int)addr & (~3));
|
return res;
|
||||||
uint32_t a = *p++;
|
|
||||||
uint32_t b = *p;
|
|
||||||
return (a>>off) | (b <<(32-off));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((optimize("-O3"), always_inline)) static inline float pgm_read_float_unaligned(const void *addr) {
|
#define pgm_read_float_unaligned(addr) ((float)pgm_read_dword_unaligned(addr))
|
||||||
return (float)pgm_read_dword_unaligned(addr);
|
#define pgm_read_ptr_unaligned(addr) ((void*)pgm_read_dword_unaligned(addr))
|
||||||
}
|
#define pgm_read_word_unaligned(addr) ((uint16_t)(pgm_read_dword_unaligned(addr) & 0xffff))
|
||||||
|
|
||||||
__attribute__((optimize("-O3"), always_inline)) static inline void *pgm_read_ptr_unaligned(const void *addr) {
|
|
||||||
return (void *)pgm_read_dword_unaligned(addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((optimize("-O3"), always_inline)) static inline uint16_t pgm_read_word_unaligned(const void *addr) {
|
|
||||||
return pgm_read_dword_unaligned(addr) & 0xffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow selection of _aligned or _unaligned, but default to _unaligned for Arduino compatibility
|
// Allow selection of _aligned or _unaligned, but default to _unaligned for Arduino compatibility
|
||||||
// Add -DPGM_READ_UNALIGNED=0 or "#define PGM_READ_UNALIGNED 0" to code to use aligned-only (faster) macros by default
|
// Add -DPGM_READ_UNALIGNED=0 or "#define PGM_READ_UNALIGNED 0" to code to use aligned-only (faster) macros by default
|
||||||
|
Loading…
x
Reference in New Issue
Block a user