*** pgmspace.h	Wed Apr 30 18:26:16 2008
--- pgmspace.h	Wed May 21 22:34:52 2008
***************
*** 37 ****
--- 38 ----
+      Ivanov Anton <anton@arc.com.ru> (pgm_read_float())
***************
*** 350 ****
--- 352,391 ----
+ #define __LPM_float_classic__(addr)         \
+ (__extension__({                            \
+     uint16_t __addr16 = (uint16_t)(addr);   \
+     float __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_float_enhanced__(addr)        \
+ (__extension__({                            \
+     uint16_t __addr16 = (uint16_t)(addr);   \
+     float __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;                               \
+ }))
+ 
***************
*** 354 ****
--- 396 ----
+ #define __LPM_float(addr)   __LPM_float_enhanced__(addr)
***************
*** 358 ****
--- 401 ----
+ #define __LPM_float(addr)   __LPM_float_classic__(addr)
***************
*** 385 ****
--- 429,437 ----
+ /** \ingroup avr_pgmspace
+     \def pgm_read_float_near(address_short)
+     Read a float 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_float_near(address_short) \
+     __LPM_float((uint16_t)(address_short))
+ 
***************
*** 529 ****
--- 582,638 ----
+ #define __ELPM_float_classic__(addr)      \
+ (__extension__({                          \
+     uint32_t __addr32 = (uint32_t)(addr); \
+     float __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_float_enhanced__(addr)     \
+ (__extension__({                          \
+     uint32_t __addr32 = (uint32_t)(addr); \
+     float __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;                             \
+ }))
+ 
***************
*** 533 ****
--- 643 ----
+ #define __ELPM_float(addr)  __ELPM_float_enhanced__(addr)
***************
*** 537 ****
--- 648 ----
+ #define __ELPM_float(addr)  __ELPM_float_classic__(addr)
***************
*** 566 ****
--- 678,686 ----
+ /** \ingroup avr_pgmspace
+     \def pgm_read_float_far(address_long)
+     Read a float 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_float_far(address_long) __ELPM_float((uint32_t)(address_long))
+ 
***************
*** 594 ****
--- 715,723 ----
+ 
+ /** \ingroup avr_pgmspace
+     \def pgm_read_float(address_short)
+     Read a float 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_float(address_short)   pgm_read_float_near(address_short)
