36a37
>      Wolfgang Haidinger <wh@vmars.tuwien.ac.at> (pgm_read_long())
170a172,211
> #define __LPM_long_classic__(addr)          \
> ({                                          \
>     uint16_t __addr16 = (uint16_t)(addr);   \
>     uint32_t __result;                      \
>     __asm__                                 \
>     (                                       \
>         "lpm"           "\n\t"              \
>         "mov %A0, r0"   "\n\t"              \
>         "adiw r30, 1"   "\n\t"              \
>         "lpm"           "\n\t"              \
>         "mov %B0, r0"   "\n\t"              \
>         "adiw r30, 1"   "\n\t"              \
>         "lpm"           "\n\t"              \
>         "mov %C0, r0"   "\n\t"              \
>         "adiw r30, 1"   "\n\t"              \
>         "lpm"           "\n\t"              \
>         "mov %D0, r0"   "\n\t"              \
>         : "=r" (__result), "=z" (__addr16)  \
>         : "1" (__addr16)                    \
>         : "r0"                              \
>     );                                      \
>     __result;                               \
> })
> 
> #define __LPM_long_enhanced__(addr)         \
> ({                                          \
>     uint16_t __addr16 = (uint16_t)(addr);   \
>     uint32_t __result;                      \
>     __asm__                                 \
>     (                                       \
>         "lpm %A0, Z+"   "\n\t"              \
>         "lpm %B0, Z+"   "\n\t"              \
>         "lpm %C0, Z+"   "\n\t"              \
>         "lpm %D0, Z"    "\n\t"              \
>         : "=r" (__result), "=z" (__addr16)  \
>         : "1" (__addr16)                    \
>     );                                      \
>     __result;                               \
> })
> 
173a215
> #define __LPM_long(addr)    __LPM_long_enhanced__(addr)
176a219
> #define __LPM_long(addr)    __LPM_long_classic__(addr)
194a238,245
> /** \ingroup avr_pgmspace
>     \def pgm_read_word_near(address_short)
>     Read a word from the program space with a 16-bit (near) address. 
>     \note The address is a byte address. 
>     The address is in the program space. */
> 
> #define pgm_read_long_near(address_short) __LPM_long((uint16_t)(address_short))
> 
283a335,391
> #define __ELPM_long_classic__(addr)     \
> ({                                      \
>     uint32_t __addr32 = (uint32_t)(addr); \
>     uint32_t __result;                  \
>     __asm__                             \
>     (                                   \
>         "out %2, %C1"   "\n\t"          \
>         "mov r31, %B1"  "\n\t"          \
>         "mov r30, %A1"  "\n\t"          \
>         "elpm"          "\n\t"          \
>         "mov %A0, r0"   "\n\t"          \
>         "in r0, %2"     "\n\t"          \
>         "adiw r30, 1"   "\n\t"          \
>         "adc r0, __zero_reg__" "\n\t"   \
>         "out %2, r0"    "\n\t"          \
>         "elpm"          "\n\t"          \
>         "mov %B0, r0"   "\n\t"          \
>         "in r0, %2"     "\n\t"          \
>         "adiw r30, 1"   "\n\t"          \
>         "adc r0, __zero_reg__" "\n\t"   \
>         "out %2, r0"    "\n\t"          \
>         "elpm"          "\n\t"          \
>         "mov %C0, r0"   "\n\t"          \
>         "in r0, %2"     "\n\t"          \
>         "adiw r30, 1"   "\n\t"          \
>         "adc r0, __zero_reg__" "\n\t"   \
>         "out %2, r0"    "\n\t"          \
>         "elpm"          "\n\t"          \
>         "mov %D0, r0"   "\n\t"          \
>         : "=r" (__result)               \
>         : "r" (__addr32),               \
>           "I" (_SFR_IO_ADDR(RAMPZ))     \
>         : "r0", "r30", "r31"            \
>     );                                  \
>     __result;                           \
> })
> 
> #define __ELPM_long_enhanced__(addr)    \
> ({                                      \
>     uint32_t __addr32 = (uint32_t)(addr); \
>     uint32_t __result;                  \
>     __asm__                             \
>     (                                   \
>         "out %2, %C1"   "\n\t"          \
>         "movw r30, %1"  "\n\t"          \
>         "elpm %A0, Z+"  "\n\t"          \
>         "elpm %B0, Z+"  "\n\t"          \
>         "elpm %C0, Z+"  "\n\t"          \
>         "elpm %D0, Z"   "\n\t"          \
>         : "=r" (__result)               \
>         : "r" (__addr32),               \
>           "I" (_SFR_IO_ADDR(RAMPZ))     \
>         : "r30", "r31"                  \
>     );                                  \
>     __result;                           \
> })
> 
286a395
> #define __ELPM_long(addr)   __ELPM_word_enhanced__(addr)
289a399
> #define __ELPM_long(addr)   __ELPM_word_classic__(addr)
309a420,428
> /** \ingroup avr_pgmspace
>     \def pgm_read_long_far(address_long)
>     Read a long from the program space with a 32-bit (far) address. 
> 
>     \note The address is a byte address.
>     The address is in the program space. */
> 
> #define pgm_read_long_far(address_long)  __ELPM_long((uint32_t)(address_long))
> 
328a448,456
> 
> /** \ingroup avr_pgmspace
>     \def pgm_long_word(address_short)
>     Read a long from the program space with a 16-bit (near) address. 
> 
>     \note The address is a byte address. 
>     The address is in the program space. */
> 
> #define pgm_read_long(address_short)    pgm_read_long_near(address_short)
