avr-libc-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[avr-libc-commit] [2163] 2010-06-12 Eric B.


From: Eric Weddington
Subject: [avr-libc-commit] [2163] 2010-06-12 Eric B.
Date: Sun, 13 Jun 2010 05:13:31 +0000

Revision: 2163
          http://svn.sv.gnu.org/viewvc/?view=rev&root=avr-libc&revision=2163
Author:   arcanum
Date:     2010-06-13 05:13:31 +0000 (Sun, 13 Jun 2010)
Log Message:
-----------
2010-06-12  Eric B. Weddington  <address@hidden>

        Special thanks to Carlos Lamas and Jan Waclawek for contributing
        code in patch #6352 (that should've gotten in a long time ago).
        * libc/pmstring/Files.am: Add new files to list.
        * libc/pmstring/memcmp_PF.S: New file.
        * libc/pmstring/memcpy_PF.S: Same.
        * libc/pmstring/strcasecmp_PF.S: Same.
        * libc/pmstring/strcat_PF.S: Same.
        * libc/pmstring/strcmp_PF.S: Same.
        * libc/pmstring/strcpy_PF.S: Same.
        * libc/pmstring/strlcat_PF.S: Same.
        * libc/pmstring/strlcpy_PF.S: Same.
        * libc/pmstring/strlen_PF.S: Same.
        * libc/pmstring/strncasecmp_PF.S: Same.
        * libc/pmstring/strncat_PF.S: Same.
        * libc/pmstring/strncmp_PF.S: Same.
        * libc/pmstring/strncpy_PF.S: Same.
        * libc/pmstring/strnlen_PF.S: Same.
        * libc/pmstring/strstr_PF.S: Same.
        * include/avr/pgmspace.h: Add support for far program memory
        functions and macros.
        * NEWS: Add news items.

Ticket Links:
:-----------
    http://savannah.gnu.org/patch/?6352

Modified Paths:
--------------
    trunk/avr-libc/ChangeLog
    trunk/avr-libc/NEWS
    trunk/avr-libc/include/avr/pgmspace.h
    trunk/avr-libc/libc/pmstring/Files.am

Added Paths:
-----------
    trunk/avr-libc/libc/pmstring/memcmp_PF.S
    trunk/avr-libc/libc/pmstring/memcpy_PF.S
    trunk/avr-libc/libc/pmstring/strcasecmp_PF.S
    trunk/avr-libc/libc/pmstring/strcat_PF.S
    trunk/avr-libc/libc/pmstring/strcmp_PF.S
    trunk/avr-libc/libc/pmstring/strcpy_PF.S
    trunk/avr-libc/libc/pmstring/strlcat_PF.S
    trunk/avr-libc/libc/pmstring/strlcpy_PF.S
    trunk/avr-libc/libc/pmstring/strlen_PF.S
    trunk/avr-libc/libc/pmstring/strncasecmp_PF.S
    trunk/avr-libc/libc/pmstring/strncat_PF.S
    trunk/avr-libc/libc/pmstring/strncmp_PF.S
    trunk/avr-libc/libc/pmstring/strncpy_PF.S
    trunk/avr-libc/libc/pmstring/strnlen_PF.S
    trunk/avr-libc/libc/pmstring/strstr_PF.S

Modified: trunk/avr-libc/ChangeLog
===================================================================
--- trunk/avr-libc/ChangeLog    2010-06-11 17:26:12 UTC (rev 2162)
+++ trunk/avr-libc/ChangeLog    2010-06-13 05:13:31 UTC (rev 2163)
@@ -1,3 +1,27 @@
+2010-06-12  Eric B. Weddington  <address@hidden>
+
+       Special thanks to Carlos Lamas and Jan Waclawek for contributing
+       code in patch #6352 (that should've gotten in a long time ago).
+       * libc/pmstring/Files.am: Add new files to list.
+       * libc/pmstring/memcmp_PF.S: New file.
+       * libc/pmstring/memcpy_PF.S: Same.
+       * libc/pmstring/strcasecmp_PF.S: Same.
+       * libc/pmstring/strcat_PF.S: Same.
+       * libc/pmstring/strcmp_PF.S: Same.
+       * libc/pmstring/strcpy_PF.S: Same.
+       * libc/pmstring/strlcat_PF.S: Same.
+       * libc/pmstring/strlcpy_PF.S: Same.
+       * libc/pmstring/strlen_PF.S: Same.
+       * libc/pmstring/strncasecmp_PF.S: Same.
+       * libc/pmstring/strncat_PF.S: Same.
+       * libc/pmstring/strncmp_PF.S: Same.
+       * libc/pmstring/strncpy_PF.S: Same.
+       * libc/pmstring/strnlen_PF.S: Same.
+       * libc/pmstring/strstr_PF.S: Same.
+       * include/avr/pgmspace.h: Add support for far program memory
+       functions and macros.
+       * NEWS: Add news items.
+
 2010-06-11  Eric B. Weddington  <address@hidden>
 
        Atmel bug #11742.

Modified: trunk/avr-libc/NEWS
===================================================================
--- trunk/avr-libc/NEWS 2010-06-11 17:26:12 UTC (rev 2162)
+++ trunk/avr-libc/NEWS 2010-06-13 05:13:31 UTC (rev 2163)
@@ -1,4 +1,4 @@
-*** Changes since avr-libc-1.6.0:
+*** Changes in avr-libc-1.7.0:
 
 * Bugs fixed:
   [Atmel: #7159] the memory location of tccr0b is mixed with tccr0a for 
tiny48/88
@@ -293,6 +293,7 @@
 * Contributed Patches:
 
   [#6194] Twitest updated to handle larger EEPROM devices
+  [#6352] Far pointer library
   [#6500] Reentrant code faq
   [#6517] Pgmspace with float support
   [#6555] malloc improvement
@@ -321,7 +322,24 @@
    memccpy_P
    strdup
    strtok
-   strtok_P, strtok_rP
+   strtok_P
+   strtok_rP
+   strlen_PF
+   strnlen_PF
+   memcpy_PF
+   strcpy_PF
+   strncpy_PF
+   strcat_PF
+   strlcat_PF
+   strncat_PF
+   strcmp_PF
+   strncmp_PF
+   strcasecmp_PF
+   strncasecmp_PF
+   strstr_PF
+   strlcpy_PF
+   memcmp_PF
+   
 
 *** Changes in avr-libc-1.6.0:
 

Modified: trunk/avr-libc/include/avr/pgmspace.h
===================================================================
--- trunk/avr-libc/include/avr/pgmspace.h       2010-06-11 17:26:12 UTC (rev 
2162)
+++ trunk/avr-libc/include/avr/pgmspace.h       2010-06-13 05:13:31 UTC (rev 
2163)
@@ -1,4 +1,6 @@
-/* Copyright (c) 2002 - 2007  Marek Michalkiewicz
+/* Copyright (c) 2002-2007  Marek Michalkiewicz
+   Copyright (c) 2006, Carlos Lamas
+   Copyright (c) 2009-2010, Jan Waclawek
    All rights reserved.
 
    Redistribution and use in source and binary forms, with or without
@@ -849,6 +851,165 @@
 #define PGM_VOID_P const prog_void *
 #endif
 
+
+/* GET_FAR_ADDRESS() macro
+
+   This macro facilitates the obtention of a 32 bit "far" pointer (only 24 bits
+   used) to data even passed the 64KB limit for the 16 bit ordinary pointer. It
+   is similar to the '&' operator, with some limitations.
+
+   Comments:
+
+   - The overhead is minimal and it's mainly due to the 32 bit size operation.
+
+   - 24 bit sizes guarantees the code compatibility for use in future devices.
+
+   - hh8() is an undocumented feature but seems to give the third significant 
byte
+     of a 32 bit data and accepts symbols, complementing the functionality of 
hi8()
+     and lo8(). There is not an equivalent assembler function to get the high
+     significant byte.
+
+   - 'var' has to be resolved at linking time as an existing symbol, i.e, a 
simple
+     type variable name, an array name (not an indexed element of the array, 
if the
+     index is a constant the compiler does not complain but fails to get the 
address
+     if optimization is enabled), a struct name or a struct field name, a 
function
+     identifier, a linker defined identifier,...
+
+   - The returned value is the identifier's VMA (virtual memory address) 
determined
+     by the linker and falls in the corresponding memory region. The AVR 
Harvard
+     architecture requires non overlapping VMA areas for the multiple address 
spaces
+     in the processor: Flash ROM, RAM, and EEPROM. Typical offset for this are
+     0x00000000, 0x00800xx0, and 0x00810000 respectively, derived from the 
linker
+        script used and linker options. The value returned can be seen then as 
a
+     universal pointer.
+
+*/
+
+#define pgm_get_far_address(var)                          \
+({                                                    \
+       uint_farptr_t tmp;                                \
+                                                      \
+       __asm__ __volatile__(                             \
+                                                      \
+                       "ldi    %A0, lo8(%1)"           "\n\t"    \
+                       "ldi    %B0, hi8(%1)"           "\n\t"    \
+                       "ldi    %C0, hh8(%1)"           "\n\t"    \
+                       "clr    %D0"                    "\n\t"    \
+               :                                             \
+                       "=d" (tmp)                                \
+               :                                             \
+                       "p"  (&(var))                             \
+       );                                                \
+       tmp;                                              \
+})
+
+
+/* PROGMEM_FAR macro
+*/
+
+#ifndef PROGMEM_FAR
+#define PROGMEM_FAR __attribute__((__section__("._progmem_far")))
+#endif
+
+#ifndef PROGMEM_SEG1
+#define PROGMEM_SEG1 __attribute__((__section__("._progmem_segment1")))
+#endif
+
+#ifndef PROGMEM_SEG2
+#define PROGMEM_SEG2 __attribute__((__section__("._progmem_segment2")))
+#endif
+
+#ifndef PROGMEM_SEG3
+#define PROGMEM_SEG3 __attribute__((__section__("._progmem_segment3")))
+#endif
+
+#define PROGMEM_SEG1_BASE 0x10000UL
+#define PROGMEM_SEG2_BASE 0x20000UL
+#define PROGMEM_SEG3_BASE 0x30000UL
+
+/* PFSTR() macro
+
+
+*/
+
+# define PFSTR(s) (__extension__({static char __c[] PROGMEM_FAR = (s); 
pgm_get_far_address(__c[0]);}))
+# define PS1STR(s) (__extension__({static char __c[] PROGMEM_SEG1 = (s); 
PROGMEM_SEG1_BASE + (uint16_t)&__c[0];}))
+# define PS2STR(s) (__extension__({static char __c[] PROGMEM_SEG2 = (s); 
PROGMEM_SEG2_BASE + (uint16_t)&__c[0];}))
+# define PS3STR(s) (__extension__({static char __c[] PROGMEM_SEG3 = (s); 
PROGMEM_SEG3_BASE + (uint16_t)&__c[0];}))
+
+// for segmented access, pointers are 16-bit
+typedef uint16_t uint_segptr_t;
+
+
+#if defined (__AVR_HAVE_LPMX__)
+
+  #define pgm_read_byte_seg1(addr)          \
+  (__extension__({                          \
+      uint16_t __addr16 = (uint16_t)(addr); \
+      uint8_t __result;                     \
+      __asm__                               \
+      (                                     \
+          "ldi r30, 1"   "\n\t"             \
+          "out %2, r30"  "\n\t"             \
+          "movw r30, %1" "\n\t"             \
+          "elpm %0, Z+"  "\n\t"             \
+          : "=r" (__result)                 \
+          : "r" (__addr16),                 \
+            "I" (_SFR_IO_ADDR(RAMPZ))       \
+          : "r30", "r31"                    \
+      );                                    \
+      __result;                             \
+  }))
+
+
+  #define pgm_read_word_seg1(addr)          \
+  (__extension__({                          \
+      uint16_t __addr16 = (uint16_t)(addr); \
+      uint16_t __result;                    \
+      __asm__                               \
+      (                                     \
+          "ldi r30, 1"    "\n\t"            \
+          "out %2, r30"   "\n\t"            \
+          "movw r30, %1"  "\n\t"            \
+          "elpm %A0, Z+"  "\n\t"            \
+          "elpm %B0, Z"   "\n\t"            \
+          : "=r" (__result)                 \
+          : "r" (__addr16),                 \
+            "I" (_SFR_IO_ADDR(RAMPZ))       \
+          : "r30", "r31"                    \
+      );                                    \
+      __result;                             \
+  }))
+
+
+  #define pgm_read_dword_seg1(addr)         \
+  (__extension__({                          \
+      uint16_t __addr16 = (uint16_t)(addr); \
+      uint32_t __result;                    \
+      __asm__                               \
+      (                                     \
+          "ldi r30, 1"    "\n\t"            \
+          "out %2,  r30"  "\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" (__addr16),                 \
+            "I" (_SFR_IO_ADDR(RAMPZ))       \
+          : "r30", "r31"                    \
+      );                                    \
+      __result;                             \
+  }))
+
+
+#else
+  #error "No pgm_seg support for ATmega103."
+#endif
+
+
+
 extern PGM_VOID_P memchr_P(PGM_VOID_P, int __val, size_t __len) __ATTR_CONST__;
 extern int memcmp_P(const void *, PGM_VOID_P, size_t) __ATTR_PURE__;
 extern void *memccpy_P(void *, PGM_VOID_P, int __val, size_t);
@@ -879,6 +1040,23 @@
 extern char *strtok_P(char *__s, PGM_P __delim);
 extern char *strtok_rP(char *__s, PGM_P __delim, char **__last);
 
+extern size_t strlen_PF (uint_farptr_t src) __ATTR_CONST__; /* program memory 
can't change */
+extern size_t strnlen_PF (uint_farptr_t src, size_t len) __ATTR_CONST__; /* 
program memory can't change */
+extern void *memcpy_PF (void *dest, uint_farptr_t src, size_t len);
+extern char *strcpy_PF (char *dest, uint_farptr_t src);
+extern char *strncpy_PF (char *dest, uint_farptr_t src, size_t len);
+extern char *strcat_PF (char *dest, uint_farptr_t src);
+extern size_t strlcat_PF (char *dst, uint_farptr_t src, size_t siz);
+extern char *strncat_PF (char *dest, uint_farptr_t src, size_t len);
+extern int strcmp_PF (const char *s1, uint_farptr_t s2) __ATTR_PURE__;
+extern int strncmp_PF (const char *s1, uint_farptr_t s2, size_t n) 
__ATTR_PURE__;
+extern int strcasecmp_PF (const char *s1, uint_farptr_t s2) __ATTR_PURE__;
+extern int strncasecmp_PF (const char *s1, uint_farptr_t s2, size_t n) 
__ATTR_PURE__;
+extern char *strstr_PF (const char *s1, uint_farptr_t s2);
+extern size_t strlcpy_PF (char *dst, uint_farptr_t src, size_t siz);
+extern int memcmp_PF(const void *, uint_farptr_t, size_t) __ATTR_PURE__;
+
+
 #ifdef __cplusplus
 }
 #endif

Modified: trunk/avr-libc/libc/pmstring/Files.am
===================================================================
--- trunk/avr-libc/libc/pmstring/Files.am       2010-06-11 17:26:12 UTC (rev 
2162)
+++ trunk/avr-libc/libc/pmstring/Files.am       2010-06-13 05:13:31 UTC (rev 
2163)
@@ -58,6 +58,21 @@
        strsep_P.S \
        strspn_P.S \
        strstr_P.S \
-       strtok_rP.S
+       strtok_rP.S \
+       memcpy_PF.S \
+       strcasecmp_PF.S \
+       strcat_PF.S \
+       strcmp_PF.S \
+       strcpy_PF.S \
+       strlcat_PF.S \
+       strlcpy_PF.S \
+       strlen_PF.S \
+       strncasecmp_PF.S \
+       strncat_PF.S \
+       strncmp_PF.S \
+       strncpy_PF.S \
+       strnlen_PF.S \
+       strstr_PF.S \
+       memcmp_PF.S \
 
 # vim: set ft=make:

Added: trunk/avr-libc/libc/pmstring/memcmp_PF.S
===================================================================
--- trunk/avr-libc/libc/pmstring/memcmp_PF.S                            (rev 0)
+++ trunk/avr-libc/libc/pmstring/memcmp_PF.S    2010-06-13 05:13:31 UTC (rev 
2163)
@@ -0,0 +1,103 @@
+/* Copyright (c) 2010  Jan Waclawek
+
+   based on libc/pmstring/memcmp_P.S which is
+   Copyright (c) 2002, 2007 Marek Michalkiewicz
+   Copyright (c) 2007  Dmitry Xmelkov
+   and on exteded program memory routines, which are
+   Copyright (c) 2006, Carlos Lamas
+
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+   * Neither the name of the copyright holders nor the names of
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE. */
+
+/* $Id$ */
+
+/** \file */
+
+/** \ingroup avr_pgmspace
+    \fn int memcmp_PF(const void *s1, uint_farptr_t s2, size_t len)
+    \brief Compare memory areas
+
+    The memcmp_PF() function compares the first \p len bytes of the memory
+    areas \p s1 and flash \p s2. The comparision is performed using unsigned
+    char operations. It is an equivalent of memcmp_P() function, except
+    that it is capable working on all FLASH including the exteded area
+    above 64kB.
+
+    \returns The memcmp_PF() function returns an integer less than, equal
+    to, or greater than zero if the first \p len bytes of \p s1 is found,
+    respectively, to be less than, to match, or be greater than the first
+    \p len bytes of \p s2.  */
+
+#if !defined(__DOXYGEN__)
+
+#include "macros.inc"
+
+#define s1_b1 r25
+#define s1_b0 r24
+#define s2_b3 r23
+#define s2_b2 r22
+#define s2_b1 r21
+#define s2_b0 r20
+#define len_b1 r19
+#define len_b0 r18
+
+#define ret_b1 r25
+#define ret_b0 r24
+
+/* the conditional caters for pre-1.6.8 libc and standalone use */
+#ifdef ASSEMBLY_CLIB_SECTION
+  ASSEMBLY_CLIB_SECTION
+#else
+  .text
+#endif
+  .global _U(memcmp_PF)
+  .type _U(memcmp_PF), @function
+_U(memcmp_PF):
+  X_movw  ZL, s2_b0
+  LPM_R0_ZPLUS_INIT s2_b2
+  X_movw  XL, s1_b0
+
+  rjmp  2f
+
+1:
+  ld    ret_b0, X+
+  LPM_R0_ZPLUS_NEXT s2_b2
+  sub   ret_b0, r0
+  brne  3f
+2:
+  subi  len_b0, lo8(1)
+  sbci  len_b1, hi8(1)
+  brsh  1b
+
+  sub   ret_b0, ret_b0
+3:
+  sbc   ret_b1, ret_b1
+  ret
+
+  .size _U(memcmp_PF), . - _U(memcmp_PF)
+
+#endif /* not __DOXYGEN__ */

Added: trunk/avr-libc/libc/pmstring/memcpy_PF.S
===================================================================
--- trunk/avr-libc/libc/pmstring/memcpy_PF.S                            (rev 0)
+++ trunk/avr-libc/libc/pmstring/memcpy_PF.S    2010-06-13 05:13:31 UTC (rev 
2163)
@@ -0,0 +1,119 @@
+/* Copyright (c) 2006, Carlos Lamas
+
+   based on libc/pmstring/memcpy_P.S which is
+   Copyright (c) 2002, Marek Michalkiewicz
+
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+   * Neither the name of the copyright holders nor the names of
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE. */
+
+/* $Id$ */
+
+#include "macros.inc"
+
+#define dest_b1 r25
+#define dest_b0 r24
+#define src_b3 r23
+#define src_b2 r22
+#define src_b1 r21
+#define src_b0 r20
+#define len_b1 r19
+#define len_b0 r18
+
+/** \ingroup avr_pgmspace
+    \fn void *memcpy_PF (void *dest, uint_farptr_t src, size_t n)
+    \brief Copy a memory block from flash to SRAM
+
+    The memcpy_PF() function is similar to memcpy(), except the data
+    is copied from the program space and is addressed using a far pointer
+
+       \param dst A pointer to the destination buffer
+       \param src A far pointer to the origin of data in flash memory
+       \param n The number of bytes to be copied
+
+    \returns The memcpy_PF() function returns a pointer to \e dst. The contents
+    of RAMPZ SFR are undefined when the function returns */
+
+#if !defined(__DOXYGEN__)
+
+       .text
+       .global _U(memcpy_PF)
+       .type   _U(memcpy_PF), @function
+
+_U(memcpy_PF):
+
+       LPM_R0_ZPLUS_INIT src_b2
+       X_movw  ZL, src_b0
+       X_movw  XL, dest_b0
+
+#if OPTIMIZE_SPEED
+
+       sbrs    len_b0, 0
+       rjmp    .L_memcpy_PF_start
+       rjmp    .L_memcpy_PF_odd
+
+.L_memcpy_PF_loop:
+
+       LPM_R0_ZPLUS_NEXT src_b2
+       st      X+, r0
+
+.L_memcpy_PF_odd:
+
+       LPM_R0_ZPLUS_NEXT src_b2
+       st      X+, r0
+
+.L_memcpy_PF_start:
+
+       subi    len_b0, lo8(2)
+       sbci    len_b1, hi8(2)
+
+#else
+
+       rjmp    .L_memcpy_PF_start
+
+.L_memcpy_PF_loop:
+
+       LPM_R0_ZPLUS_NEXT src_b2
+       st      X+, r0
+
+.L_memcpy_PF_start:
+
+       subi    len_b0, lo8(1)
+       sbci    len_b1, hi8(1)
+
+#endif
+
+       brcc    .L_memcpy_PF_loop
+
+; return dest (unchanged)
+
+       ret
+
+.L_memcpy_PF_end:
+
+       .size   _U(memcpy_PF), .L_memcpy_PF_end - _U(memcpy_PF)
+
+#endif /* not __DOXYGEN__ */

Added: trunk/avr-libc/libc/pmstring/strcasecmp_PF.S
===================================================================
--- trunk/avr-libc/libc/pmstring/strcasecmp_PF.S                                
(rev 0)
+++ trunk/avr-libc/libc/pmstring/strcasecmp_PF.S        2010-06-13 05:13:31 UTC 
(rev 2163)
@@ -0,0 +1,108 @@
+/* Copyright (c) 2006, Carlos Lamas
+
+   based on libc/pmstring/strcasecmp_P.S which is
+   Copyright (c) 2002, Reiner Patommel
+
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+   * Neither the name of the copyright holders nor the names of
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE. */
+
+/* $Id$ */
+
+#include "macros.inc"
+
+#define s1_b1 r25
+#define s1_b0 r24
+#define s2_b3 r23
+#define s2_b2 r22
+#define s2_b1 r21
+#define s2_b0 r20
+
+#define ret_b1 r25
+#define ret_b0 r24
+
+#define tmp s2_b1      /* copied to Z pointer */
+#define cht s2_b0
+
+/** \ingroup avr_pgmspace
+    \fn int strcasecmp_PF (const char *s1, uint_farptr_t s2)
+    \brief Compare two strings ignoring case
+
+    The strcasecmp_PF() function compares the two strings \e s1 and \e s2, 
ignoring
+    the case of the characters
+
+    \param s1 A pointer to the first string in SRAM
+    \param s2 A far pointer to the second string in Flash
+
+    \returns The strcasecmp_PF() function returns an integer less than, equal
+    to, or greater than zero if \e s1 is found, respectively, to be less than, 
to
+    match, or be greater than \e s2. The contents of RAMPZ SFR are undefined
+    when the function returns */
+
+#if !defined(__DOXYGEN__)
+
+       .text
+       .global _U(strcasecmp_PF)
+       .type   _U(strcasecmp_PF), @function
+
+_U(strcasecmp_PF):
+
+       X_movw  ZL, s2_b0
+       LPM_R0_ZPLUS_INIT s2_b2
+       X_movw  XL, s1_b0
+
+.L_strcasecmp_PF_loop:
+
+       ld      ret_b0, X+              ; load *s1
+       LPM_R0_ZPLUS_NEXT s2_b2         ; load *s2
+       mov     tmp, r0                 ; copy of *s2 to tmp
+       mov     cht, r0                 ; copy of *s2 to cht
+       ori     cht, 0x20               ; make tmp lower case
+       cpi     cht, 'a'                ; test on [a .. z]
+       brlt    .L_strcasecmp_PF_tst
+       cpi     cht, 'z'+1
+       brge    .L_strcasecmp_PF_tst
+       ori     tmp, 0x20               ; we got an aplpha in s2
+       ori     ret_b0, 0x20
+
+.L_strcasecmp_PF_tst:                  ; compare
+
+       sub     ret_b0, tmp
+       brne    .L_strcasecmp_PF_done
+       tst     r0                      ; end of s2?
+       brne    .L_strcasecmp_PF_loop
+
+.L_strcasecmp_PF_done:
+; ret_hi = SREG.C ? 0xFF : 0
+
+       sbc     ret_b1, ret_b1
+       ret
+
+.L_strcasecmp_PF_end:
+
+       .size   _U(strcasecmp_PF), .L_strcasecmp_PF_end - _U(strcasecmp_PF)
+
+#endif /* not __DOXYGEN__ */

Added: trunk/avr-libc/libc/pmstring/strcat_PF.S
===================================================================
--- trunk/avr-libc/libc/pmstring/strcat_PF.S                            (rev 0)
+++ trunk/avr-libc/libc/pmstring/strcat_PF.S    2010-06-13 05:13:31 UTC (rev 
2163)
@@ -0,0 +1,94 @@
+/* Copyright (c) 2006, Carlos Lamas
+
+   based on libc/pmstring/strcat_P.S which is
+   Copyright (c) 2002, Reiner Patommel
+
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+   * Neither the name of the copyright holders nor the names of
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE. */
+
+
+/* $Id: strcat_PF.S,v 1.0 2006/01/04 12:00:00 ??????? Exp $ */
+
+#include "macros.inc"
+
+#define dest_b1 r25
+#define dest_b0 r24
+#define src_b3 r23
+#define src_b2 r22
+#define src_b1 r21
+#define src_b0 r20
+
+/** \ingroup avr_pgmspace
+    \fn char *strcat_PF (char *dst, uint_farptr_t src)
+       \brief Concatenates two strings
+
+    The strcat_PF() function is similar to strcat() except that the \e src
+    string must be located in program space (flash) and is addressed using
+    a far pointer
+
+    \param dst A pointer to the destination string in SRAM
+    \param src A far pointer to the string to be appended in Flash
+
+    \returns The strcat_PF() function returns a pointer to the resulting
+    string \e dst. The contents of RAMPZ SFR are undefined when the function
+    returns */
+
+#if !defined(__DOXYGEN__)
+
+       .text
+       .global _U(strcat_PF)
+       .type   _U(strcat_PF), @function
+
+_U(strcat_PF):
+
+       X_movw  ZL, src_b0
+       LPM_R0_ZPLUS_INIT src_b2
+       X_movw  XL, dest_b0
+
+.L_strcat_PF_skip:
+
+       ld      __tmp_reg__, X+
+       tst     __tmp_reg__
+       brne    .L_strcat_PF_skip
+       sbiw    XL, 1           ; undo post-increment
+
+.L_strcat_PF_loop:
+
+       LPM_R0_ZPLUS_NEXT src_b2
+       st      X+, r0
+       tst     r0
+       brne    .L_strcat_PF_loop
+
+; return dest (unchanged)
+
+       ret
+
+.L_strcat_PF_end:
+
+       .size   _U(strcat_PF), .L_strcat_PF_end - _U(strcat_PF)
+
+#endif /* not __DOXYGEN__ */

Added: trunk/avr-libc/libc/pmstring/strcmp_PF.S
===================================================================
--- trunk/avr-libc/libc/pmstring/strcmp_PF.S                            (rev 0)
+++ trunk/avr-libc/libc/pmstring/strcmp_PF.S    2010-06-13 05:13:31 UTC (rev 
2163)
@@ -0,0 +1,93 @@
+/* Copyright (c) 2006, Carlos Lamas
+
+   based on libc/pmstring/strcmp_P.S which is
+   Copyright (c) 2002, Marek Michalkiewicz
+
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+   * Neither the name of the copyright holders nor the names of
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE. */
+
+/* $Id$ */
+
+#include "macros.inc"
+
+#define s1_b1 r25
+#define s1_b0 r24
+#define s2_b3 r23
+#define s2_b2 r22
+#define s2_b1 r21
+#define s2_b0 r20
+
+#define ret_b1 r25
+#define ret_b0 r24
+
+/** \ingroup avr_pgmspace
+    \fn int strcmp_PF (const char *s1, uint_farptr_t s2)
+       \brief Compares two strings
+
+    The strcmp_PF() function is similar to strcmp() except that \e s2 is a far
+    pointer to a string in program space
+
+    \param s1 A pointer to the first string in SRAM
+    \param s2 A far pointer to the second string in Flash
+
+    \returns The strcmp_PF() function returns an integer less than, equal to,
+    or greater than zero if \e s1 is found, respectively, to be less than, to
+    match, or be greater than \e s2. The contents of RAMPZ SFR are undefined
+    when the function returns */
+
+#if !defined(__DOXYGEN__)
+
+       .text
+       .global _U(strcmp_PF)
+       .type   _U(strcmp_PF), @function
+
+_U(strcmp_PF):
+
+       X_movw  ZL, s2_b0
+       LPM_R0_ZPLUS_INIT s2_b2
+       X_movw  XL, s1_b0
+
+.L_strcmp_PF_loop:
+
+       ld      ret_b0, X+
+       LPM_R0_ZPLUS_NEXT s2_b2
+       sub     ret_b0, r0
+       brne    .L_strcmp_PF_done
+       tst     r0
+       brne    .L_strcmp_PF_loop
+
+.L_strcmp_PF_done:
+; ret_hi = SREG.C ? 0xFF : 0
+
+       sbc     ret_b1, ret_b1
+       ret
+
+.L_strcmp_PF_end:
+
+       .size   _U(strcmp_PF), .L_strcmp_PF_end - _U(strcmp_PF)
+
+#endif /* not __DOXYGEN__ */

Added: trunk/avr-libc/libc/pmstring/strcpy_PF.S
===================================================================
--- trunk/avr-libc/libc/pmstring/strcpy_PF.S                            (rev 0)
+++ trunk/avr-libc/libc/pmstring/strcpy_PF.S    2010-06-13 05:13:31 UTC (rev 
2163)
@@ -0,0 +1,85 @@
+/* Copyright (c) 2006, Carlos Lamas
+
+   based on libc/pmstring/strcpy_P.S which is
+   Copyright (c) 2002, Marek Michalkiewicz
+
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+   * Neither the name of the copyright holders nor the names of
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE. */
+
+/* $Id$ */
+
+#include "macros.inc"
+
+#define dest_b1 r25
+#define dest_b0 r24
+#define src_b3 r23
+#define src_b2 r22
+#define src_b1 r21
+#define src_b0 r20
+
+/** \ingroup avr_pgmspace
+    \fn char *strcpy_PF (char *dst, uint_farptr_t src)
+       \brief Duplicate a string
+
+    The strcpy_PF() function is similar to strcpy() except that \e src is a far
+    pointer to a string in program space
+
+    \param dst A pointer to the destination string in SRAM
+    \param src A far pointer to the source string in Flash
+
+    \returns The strcpy_PF() function returns a pointer to the destination
+    string \e dst. The contents of RAMPZ SFR are undefined when the funcion
+    returns */
+
+#if !defined(__DOXYGEN__)
+
+       .text
+       .global _U(strcpy_PF)
+       .type   _U(strcpy_PF), @function
+
+_U(strcpy_PF):
+
+       X_movw  ZL, src_b0
+       LPM_R0_ZPLUS_INIT src_b2
+       X_movw  XL, dest_b0
+
+.L_strcpy_PF_loop:
+
+       LPM_R0_ZPLUS_NEXT src_b2
+       st      X+, r0
+       tst     r0
+       brne    .L_strcpy_PF_loop
+
+; return dest (unchanged)
+
+       ret
+
+.L_strcpy_PF_end:
+
+       .size   _U(strcpy_PF), .L_strcpy_PF_end - _U(strcpy_PF)
+
+#endif /* not __DOXYGEN__ */

Added: trunk/avr-libc/libc/pmstring/strlcat_PF.S
===================================================================
--- trunk/avr-libc/libc/pmstring/strlcat_PF.S                           (rev 0)
+++ trunk/avr-libc/libc/pmstring/strlcat_PF.S   2010-06-13 05:13:31 UTC (rev 
2163)
@@ -0,0 +1,152 @@
+/* Copyright (c) 2006, Carlos Lamas
+
+   based on libc/pmstring/strlcat_P.S which is
+   Copyright (c) 2003, Eric B. Weddington, R. Patommel
+
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+   * Neither the name of the copyright holders nor the names of
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+/* $Id$ */
+
+/** \ingroup avr_pgmspace
+    \fn size_t strlcat_PF (char *dst, uint_farptr_t src, size_t n)
+    \brief Concatenate two strings
+
+    The strlcat_PF() function is similar to strlcat(), except that the \e src
+    string must be located in program space (flash) and is addressed using
+       a far pointer
+
+    Appends src to string dst of size \e n (unlike strncat(), \e n is the
+    full size of \e dst, not space left).  At most \e n-1 characters
+    will be copied.  Always NULL terminates (unless \e n <= strlen(\e dst))
+
+    \param dst A pointer to the destination string in SRAM
+    \param src A far pointer to the source string in Flash
+    \param n The total number of bytes allocated to the destination string
+
+    \returns The strlcat_PF() function returns strlen(\e src) + MIN(\e n,
+    strlen(initial \e dst)).  If retval >= \e n, truncation occurred. The
+    contents of RAMPZ SFR are undefined when the funcion returns */
+
+#if !defined(__DOXYGEN__)
+
+#include "macros.inc"
+
+#define dst_b1         r25
+#define dst_b0         r24
+#define src_b30                r23     /* ignored */
+#define src_b20                r22     /* moved to src_b2 in the code */
+#define src_b1         r21
+#define src_b0         r20
+#define siz_b1         r19
+#define siz_b0         r18
+
+#define src_b2         r28     /* must be preserved */
+#define dlen_b1                src_b30
+#define dlen_b0                src_b20
+#define rWord_b1       r25
+#define rWord_b0       r24
+
+       .text
+       .global _U(strlcat_PF)
+       .type   _U(strlcat_PF),@function
+
+_U(strlcat_PF):
+
+       push    src_b2
+       mov     src_b2, src_b20
+       X_movw  XL, dst_b0              ; X = dst
+       X_movw  ZL, src_b0              ; Z = src
+       LPM_R0_ZPLUS_INIT src_b2
+
+.L_strlcat_PF_dlen:                    ; Find end of dst string
+
+       ld      r0, X+                  ; get next char from dst
+       cp      siz_b0, __zero_reg__    ; and calc dlen = len of dst
+       cpc     siz_b1, __zero_reg__    ; size == 0 ?
+       breq     1f                     ; --> done
+       tst     r0                      ; end of dst ?
+       breq     1f                     ; --> done
+       subi    siz_b0, lo8(1)
+       sbci    siz_b1, hi8(1)          ; siz--
+       rjmp    .L_strlcat_PF_dlen      ; --> next char
+1:     sbiw    XL, 1                   ; undo post increment
+       X_movw  dlen_b0, XL
+       sub     dlen_b0, dst_b0
+       sbc     dlen_b1, dst_b1         ; dlen = X - dst
+       cp      siz_b0, __zero_reg__
+       cpc     siz_b1, __zero_reg__    ; size == 0 ?
+       breq    .L_strlcat_PF_slen      ; --> done
+       subi    siz_b0, lo8(1)
+       sbci    siz_b1, hi8(1)          ; siz--
+
+.L_strlcat_PF_concat:                  ; Concatenate
+
+       LPM_R0_ZPLUS_NEXT src_b2        ; get next char from src
+       cp      siz_b0, __zero_reg__
+       cpc     siz_b1, __zero_reg__    ; size == 0 ?
+       breq    1f                      ; --> done
+       tst     r0                      ; end of src ?
+       breq    1f                      ; --> done
+       st      X+, r0                  ; store in dest
+       subi    siz_b0, lo8(1)
+       sbci    siz_b1, hi8(1)          ; siz--
+       rjmp    .L_strlcat_PF_concat    ; --> next char
+1:     st      X, __zero_reg__         ; *X = '\0'
+       sbiw    ZL, 1                   ; undo post increment
+#ifdef RAMPZ
+       in      r0, _SFR_IO_ADDR(RAMPZ)
+       sbc     r0, __zero_reg__
+       out     _SFR_IO_ADDR(RAMPZ), r0
+#endif
+
+.L_strlcat_PF_slen:
+
+       LPM_R0_ZPLUS_NEXT src_b2        ; get next char from src
+       tst     r0                      ; end of src ?
+       brne    .L_strlcat_PF_slen      ; --> next char
+       sbiw    ZL, 1                   ; undo post increment
+#ifdef RAMPZ
+       in      r0, _SFR_IO_ADDR(RAMPZ)
+       sbc     r0, __zero_reg__
+       out     _SFR_IO_ADDR(RAMPZ), r0
+#endif
+       X_movw  rWord_b0, dlen_b0
+       add     rWord_b0, ZL
+       adc     rWord_b1, ZH
+       sub     rWord_b0, src_b0
+       sbc     rWord_b1, src_b1        ; return(dlen + (Z - src))
+       pop     src_b2
+       ret
+
+.L_strlcat_PF_end:
+
+       .size   _U(strlcat_PF), .L_strlcat_PF_end - _U(strlcat_PF)
+
+#endif /* not __DOXYGEN__ */

Added: trunk/avr-libc/libc/pmstring/strlcpy_PF.S
===================================================================
--- trunk/avr-libc/libc/pmstring/strlcpy_PF.S                           (rev 0)
+++ trunk/avr-libc/libc/pmstring/strlcpy_PF.S   2010-06-13 05:13:31 UTC (rev 
2163)
@@ -0,0 +1,107 @@
+/* Copyright (c) 2006, Carlos Lamas
+
+   based on libc/pmstring/strlcpy_P.S which is
+   Copyright (c) 2003, Eric B. Weddington
+
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+   * Neither the name of the copyright holders nor the names of
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE.
+
+*/
+
+/* $Id$ */
+
+/** \ingroup avr_pgmspace
+    \fn size_t strlcpy_PF (char *dst, uint_farptr_t src, size_t siz)
+    \brief Copy a string from progmem to RAM.
+
+    Copy src to string dst of size siz.  At most siz-1 characters will be
+    copied. Always NULL terminates (unless siz == 0).
+
+    \returns The strlcpy_PF() function returns strlen(src). If retval >= siz,
+    truncation occurred.  The contents of RAMPZ SFR are undefined when the
+    function returns */
+
+#if !defined(__DOXYGEN__)
+
+#include "macros.inc"
+
+#define dst_b1         r25
+#define dst_b0         r24
+#define src_b3         r23
+#define src_b2         r22
+#define src_b1         r21
+#define src_b0         r20
+#define siz_b1         r19
+#define siz_b0         r18
+
+#define rWord_b1       r25
+#define rWord_b0       r24
+
+       .text
+       .global _U(strlcpy_PF)
+       .type   _U(strlcpy_PF), @function
+
+_U(strlcpy_PF):
+
+       X_movw  ZL, src_b0              ; Z = src
+       LPM_R0_ZPLUS_INIT src_b2
+       X_movw  XL, dst_b0              ; X = dst
+       cp      siz_b0, __zero_reg__
+       cpc     siz_b0, __zero_reg__    ; size == 0 ?
+       breq    .L_strlcpy_PF_truncated
+
+.L_strlcpy_PF_copy_loop:               ; copy src to dst
+
+       subi    siz_b0, lo8(1)
+       sbci    siz_b1, hi8(1)          ; decrement siz
+       breq    1f                      ; --> siz chars copied
+       LPM_R0_ZPLUS_NEXT src_b2        ; get next src char
+       st      X+, r0                  ; copy char
+       tst     r0                      ; end of src string ?
+       breq    .L_strlcpy_PF_len       ; --> all src chars copied
+       rjmp    .L_strlcpy_PF_copy_loop ; next char
+1:     st      X, __zero_reg__         ; truncate dst string
+
+.L_strlcpy_PF_truncated:               ; find Z = end of src string
+
+       LPM_R0_ZPLUS_NEXT src_b2        ; get next char from src
+       tst     r0                      ; end of src string ?
+       brne    .L_strlcpy_PF_truncated ; next char
+
+.L_strlcpy_PF_len:                     ; calculate strlen(src)
+
+       sub     ZL, src_b0
+       sbc     ZH, src_b1              ; Z points past \0
+       sbiw    ZL, 1
+       X_movw  rWord_b0, ZL
+       ret
+
+.L_strlcpy_PF_end:
+
+       .size   _U(strlcpy_PF), .L_strlcpy_PF_end - _U(strlcpy_PF)
+
+#endif /* not __DOXYGEN__ */

Added: trunk/avr-libc/libc/pmstring/strlen_PF.S
===================================================================
--- trunk/avr-libc/libc/pmstring/strlen_PF.S                            (rev 0)
+++ trunk/avr-libc/libc/pmstring/strlen_PF.S    2010-06-13 05:13:31 UTC (rev 
2163)
@@ -0,0 +1,84 @@
+/* Copyright (c) 2006, Carlos Lamas
+
+   based on libc/pmstring/strlen_P.S which is
+   Copyright (c) 2002, Marek Michalkiewicz
+
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+   * Neither the name of the copyright holders nor the names of
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE. */
+
+/* $Id$ */
+
+#include "macros.inc"
+
+#define src_b3 r25     /* MSB, ignored */
+#define src_b2 r24
+#define src_b1 r23
+#define src_b0 r22
+
+/** \ingroup avr_pgmspace
+    \fn size_t strlen_PF (uint_farptr_t s)
+    \brief Obtain the length of a string
+
+    The strlen_PF() function is similar to strlen(), except that \e s is a
+    far pointer to a string in program space
+
+    \param s A far pointer to the string in flash
+
+    \returns The strlen_PF() function returns the number of characters in
+    \e s. The contents of RAMPZ SFR are undefined when the function returns */
+
+#if !defined(__DOXYGEN__)
+
+       .text
+       .global _U(strlen_PF)
+       .type   _U(strlen_PF), @function
+
+_U(strlen_PF):
+
+       LPM_R0_ZPLUS_INIT src_b2
+       X_movw  ZL, src_b0
+
+.L_strlen_PF_loop:
+
+       LPM_R0_ZPLUS_NEXT src_b2
+       tst     r0
+       brne    .L_strlen_PF_loop
+
+; return RAMPZ:Z - 1 - src = (-1 - src) + RAMPZ:Z = ~src + RAMPZ:Z
+
+       com     src_b0
+       com     src_b1
+       add     src_b0, ZL
+       adc     src_b1, ZH
+       X_movw  src_b2, src_b0  ; size_t is 16 bits
+       ret
+
+.L_strlen_PF_end:
+
+       .size   _U(strlen_PF), .L_strlen_PF_end - _U(strlen_PF)
+
+#endif /* not __DOXYGEN__ */

Added: trunk/avr-libc/libc/pmstring/strncasecmp_PF.S
===================================================================
--- trunk/avr-libc/libc/pmstring/strncasecmp_PF.S                               
(rev 0)
+++ trunk/avr-libc/libc/pmstring/strncasecmp_PF.S       2010-06-13 05:13:31 UTC 
(rev 2163)
@@ -0,0 +1,119 @@
+/* Copyright (c) 2006, Carlos Lamas
+
+   based on libc/pmstring/strncasecmp_P.S which is
+   Copyright (c) 2002, Reiner Patommel
+
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+   * Neither the name of the copyright holders nor the names of
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE. */
+
+/* $Id$ */
+
+#include "macros.inc"
+
+#define s1_b1 r25
+#define s1_b0 r24
+#define s2_b3 r23
+#define s2_b2 r22
+#define s2_b1 r21
+#define s2_b0 r20
+#define len_b1 r19
+#define len_b0 r18
+
+#define cht s2_b1
+#define tmp s2_b0
+
+#define ret_b1 r25
+#define ret_b0 r24
+
+/** \ingroup avr_pgmspace
+    \fn int strncasecmp_PF (const char *s1, uint_farptr_t s2, size_t n)
+    \brief Compare two strings ignoring case
+
+    The strncasecmp_PF() function is similar to strcasecmp_PF(), except it
+    only compares the first \e n characters of \e s1 and the string in flash is
+    addressed using a far pointer
+
+    \param s1 A pointer to a string in SRAM
+    \param s2 A far pointer to a string in Flash
+    \param n The maximum number of bytes to compare
+
+    \returns The strncasecmp_PF() function returns an integer less than, equal
+    to, or greater than zero if \e s1 (or the first \e n bytes thereof) is 
found,
+    respectively, to be less than, to match, or be greater than \e s2. The
+    contents of RAMPZ SFR are undefined when the function returns  */
+
+#if !defined(__DOXYGEN__)
+
+       .text
+       .global _U(strncasecmp_PF)
+       .type   _U(strncasecmp_PF), @function
+
+_U(strncasecmp_PF):
+
+       X_movw  ZL, s2_b0
+       LPM_R0_ZPLUS_INIT s2_b2
+       X_movw  XL, s1_b0
+
+.L_strncasecmp_PF_loop:
+
+       subi    len_b0, lo8(1)
+       sbci    len_b1, hi8(1)
+       brcs    .L_strncasecmp_PF_equal
+       ld      ret_b0, X+              ; load *s1
+       LPM_R0_ZPLUS_NEXT s2_b2         ; load *s2
+       mov     tmp, r0                 ; copy of *s2 to tmp
+       mov     cht, r0                 ; copy of *s2 to cht
+       ori     cht, 0x20               ; make it lower case
+       cpi     cht, 'a'                ; test on [a .. z]
+       brlt    .L_strncasecmp_PF_tst
+       cpi     cht, 'z'+1
+       brge    .L_strncasecmp_PF_tst
+       ori     tmp, 0x20               ; we got an alpha in s2
+       ori     ret_b0, 0x20            ; make *s1, *s2 lower case
+
+.L_strncasecmp_PF_tst:
+
+       sub     ret_b0, tmp
+       brne    .L_strncasecmp_PF_done
+       tst     r0
+       brne    .L_strncasecmp_PF_loop
+
+.L_strncasecmp_PF_equal:
+
+       sub     ret_b0, ret_b0
+
+.L_strncasecmp_PF_done:
+; ret_hi = SREG.C ? 0xFF : 0
+
+       sbc     ret_b1, ret_b1
+       ret
+
+.L_strncasecmp_PF_end:
+
+       .size   _U(strncasecmp_PF), .L_strncasecmp_PF_end - _U(strncasecmp_PF)
+
+#endif /* not __DOXYGEN__ */

Added: trunk/avr-libc/libc/pmstring/strncat_PF.S
===================================================================
--- trunk/avr-libc/libc/pmstring/strncat_PF.S                           (rev 0)
+++ trunk/avr-libc/libc/pmstring/strncat_PF.S   2010-06-13 05:13:31 UTC (rev 
2163)
@@ -0,0 +1,109 @@
+/* Copyright (c) 2006, Carlos Lamas
+
+   based on libc/pmstring/strncat_P.S which is
+   Copyright (c) 2003, Reiner Patommel
+
+   based on strncat by Marek Michalkiewicz
+
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+   * Neither the name of the copyright holders nor the names of
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE. */
+
+/* $Id$ */
+
+#include "macros.inc"
+
+#define dest_b1 r25
+#define dest_b0 r24
+#define src_b3 r23
+#define src_b2 r22
+#define src_b1 r21
+#define src_b0 r20
+#define len_b1 r19
+#define len_b0 r18
+
+/** \ingroup avr_pgmspace
+    \fn char *strncat_PF (char *dst, uint_farptr_t src, size_t n)
+    \brief Concatenate two strings
+
+    The strncat_PF() function is similar to strncat(), except that the \e src
+    string must be located in program space (flash) and is addressed using a
+    far pointer
+
+    \param dst A pointer to the destination string in SRAM
+    \param src A far pointer to the source string in Flash
+    \param n The maximum number of bytes to append
+
+    \returns The strncat_PF() function returns a pointer to the resulting
+    string \e dst. The contents of RAMPZ SFR are undefined when the function
+    returns */
+
+#if !defined(__DOXYGEN__)
+
+       .text
+       .global _U(strncat_PF)
+       .type   _U(strncat_PF), @function
+
+_U(strncat_PF):
+
+       X_movw  ZL, src_b0
+       LPM_R0_ZPLUS_INIT src_b2
+       X_movw  XL, dest_b0
+
+.L_strncat_PF_skip:
+
+       ld      r0, X+
+       tst     r0
+       brne    .L_strncat_PF_skip
+       sbiw    XL, 1           ; undo post-increment (point the the NUL)
+
+.L_strncat_PF_loop:
+
+       subi    len_b0, lo8(1)
+       sbci    len_b1, hi8(1)
+       brcs    .L_strncat_PF_done
+       LPM_R0_ZPLUS_NEXT src_b2
+       tst     r0
+       st      X+, r0
+       brne    .L_strncat_PF_loop
+
+; return dest (unchanged)
+
+       ret
+
+.L_strncat_PF_done:
+
+       st      X, __zero_reg__
+
+; return dest (unchanged)
+
+       ret
+
+.L_strncat_PF_end:
+
+       .size   _U(strncat_PF), .L_strncat_PF_end - _U(strncat_PF)
+
+#endif /* not __DOXYGEN__ */

Added: trunk/avr-libc/libc/pmstring/strncmp_PF.S
===================================================================
--- trunk/avr-libc/libc/pmstring/strncmp_PF.S                           (rev 0)
+++ trunk/avr-libc/libc/pmstring/strncmp_PF.S   2010-06-13 05:13:31 UTC (rev 
2163)
@@ -0,0 +1,103 @@
+/* Copyright (c) 2006, Carlos Lamas
+
+   based on libc/pmstring/strncmp_P.S which is
+   Copyright (c) 2002, Marek Michalkiewicz
+
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+   * Neither the name of the copyright holders nor the names of
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE. */
+
+/* $Id$ */
+
+#include "macros.inc"
+
+#define s1_b1 r25
+#define s1_b0 r24
+#define s2_b3 r23
+#define s2_b2 r22
+#define s2_b1 r21
+#define s2_b0 r20
+#define len_b1 r19
+#define len_b0 r18
+
+#define ret_b1 r25
+#define ret_b0 r24
+
+/** \ingroup avr_pgmspace
+    \fn int strncmp_PF (const char *s1, uint_farptr_t s2, size_t n)
+    \brief Compare two strings with limited length
+
+    The strncmp_PF() function is similar to strcmp_PF() except it only
+    compares the first (at most) \e n characters of \e s1 and \e s2
+
+    \param s1 A pointer to the first string in SRAM
+    \param s2 A far pointer to the second string in Flash
+    \param n The maximum number of bytes to compare
+
+    \returns The strncmp_PF() function returns an integer less than, equal
+    to, or greater than zero if \e s1 (or the first \e n bytes thereof) is 
found,
+    respectively, to be less than, to match, or be greater than \e s2. The
+    contents of RAMPZ SFR are undefined when the function returns */
+
+#if !defined(__DOXYGEN__)
+
+       .text
+       .global _U(strncmp_PF)
+       .type   _U(strncmp_PF), @function
+
+_U(strncmp_PF):
+
+       X_movw  ZL, s2_b0
+       LPM_R0_ZPLUS_INIT s2_b2
+       X_movw  XL, s1_b0
+
+.L_strncmp_PF_loop:
+
+       subi    len_b0, lo8(1)
+       sbci    len_b1, hi8(1)
+       brcs    .L_strncmp_PF_equal
+       ld      ret_b0, X+
+       LPM_R0_ZPLUS_NEXT s2_b2
+       sub     ret_b0, r0
+       brne    .L_strncmp_PF_done
+       tst     r0
+       brne    .L_strncmp_PF_loop
+
+.L_strncmp_PF_equal:
+
+       sub     ret_b0, ret_b0
+
+.L_strncmp_PF_done:
+; ret_hi = SREG.C ? 0xFF : 0
+
+       sbc     ret_b1, ret_b1
+       ret
+
+.L_strncmp_PF_end:
+
+       .size   _U(strncmp_PF), .L_strncmp_PF_end - _U(strncmp_PF)
+
+#endif /* not __DOXYGEN__ */

Added: trunk/avr-libc/libc/pmstring/strncpy_PF.S
===================================================================
--- trunk/avr-libc/libc/pmstring/strncpy_PF.S                           (rev 0)
+++ trunk/avr-libc/libc/pmstring/strncpy_PF.S   2010-06-13 05:13:31 UTC (rev 
2163)
@@ -0,0 +1,113 @@
+/* Copyright (c) 2006, Carlos Lamas
+
+   based on libc/pmstring/strncpy_P.S which is
+   Copyright (c) 2002, Marek Michalkiewicz
+
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+   * Neither the name of the copyright holders nor the names of
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE. */
+
+/* $Id$ */
+
+#include "macros.inc"
+
+#define dest_b1 r25
+#define dest_b0 r24
+#define src_b3 r23
+#define src_b2 r22
+#define src_b1 r21
+#define src_b0 r20
+#define len_b1 r19
+#define len_b0 r18
+
+
+/** \ingroup avr_pgmspace
+    \fn char *strncpy_PF (char *dst, uint_farptr_t src, size_t n)
+       \brief Duplicate a string until a limited length
+
+    The strncpy_PF() function is similar to strcpy_PF() except that not more
+    than \e n bytes of \e src are copied.  Thus, if there is no null byte among
+    the first \e n bytes of \e src, the result will not be null-terminated
+
+    In the case where the length of \e src is less than that of \e n, the
+    remainder of \e dst will be padded with nulls
+
+    \param dst A pointer to the destination string in SRAM
+    \param src A far pointer to the source string in Flash
+    \param n The maximum number of bytes to copy
+
+    \returns The strncpy_PF() function returns a pointer to the destination
+    string \e dst. The contents of RAMPZ SFR are undefined when the function
+    returns */
+
+#if !defined(__DOXYGEN__)
+
+       .text
+       .global _U(strncpy_PF)
+       .type   _U(strncpy_PF), @function
+
+_U(strncpy_PF):
+
+       X_movw  ZL, src_b0
+       LPM_R0_ZPLUS_INIT src_b2
+       X_movw  XL, dest_b0
+
+.L_strncpy_PF_loop:
+
+       subi    len_b0, lo8(1)
+       sbci    len_b1, hi8(1)
+       brcs    .L_strncpy_PF_done
+       LPM_R0_ZPLUS_NEXT src_b2
+       st      X+, r0
+       tst     r0
+       brne    .L_strncpy_PF_loop
+
+; store null characters up to the end of dest
+; as the glibc manual says:
+; This behavior is rarely useful, but it is specified by the ISO C standard.
+
+       rjmp    .L_strncpy_PF_clr_start
+
+.L_strncpy_PF_clr_loop:
+
+       st      X+, __zero_reg__
+
+.L_strncpy_PF_clr_start:
+
+       subi    len_b0, lo8(1)
+       sbci    len_b1, hi8(1)
+       brcc    .L_strncpy_PF_clr_loop
+
+.L_strncpy_PF_done:
+; return dest (unchanged)
+
+       ret
+
+.L_strncpy_PF_end:
+
+       .size   _U(strncpy_PF), .L_strncpy_PF_end - _U(strncpy_PF)
+
+#endif /* not __DOXYGEN__ */

Added: trunk/avr-libc/libc/pmstring/strnlen_PF.S
===================================================================
--- trunk/avr-libc/libc/pmstring/strnlen_PF.S                           (rev 0)
+++ trunk/avr-libc/libc/pmstring/strnlen_PF.S   2010-06-13 05:13:31 UTC (rev 
2163)
@@ -0,0 +1,95 @@
+/* Copyright (c) 2006, Carlos Lamas
+
+   based on libc/pmstring/strnlen_P.S which is
+   Copyright (c) 2005, Helmut Wallner
+
+   based on libc/pmstring/strnlen.S which is
+   Copyright (c) 2002, Marek Michalkiewicz
+
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+   * Neither the name of the copyright holders nor the names of
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE. */
+
+/* $Id$ */
+
+#include "macros.inc"
+
+#define src_b3 r25
+#define src_b2 r24
+#define src_b1 r23
+#define src_b0 r22
+#define len_b1 r21
+#define len_b0 r20
+
+/** \ingroup avr_pgmspace
+    \fn size_t strnlen_PF(uint_farptr_t s, size_t len)
+    \brief Determine the length of a fixed-size string
+
+    The strnlen_PF() function is similar to strnlen(), except that \e s is a
+    far pointer to a string in program space
+
+    \param s A far pointer to the string in Flash
+    \param len The maximum number of length to return
+
+    \returns The strnlen_PF function returns strlen_P(\e s), if that is less
+    than \e len, or \e len if there is no '\\0' character among the first \e
+    len characters pointed to by \e s. The contents of RAMPZ SFR are
+    undefined when the function returns */
+
+#if !defined(__DOXYGEN__)
+
+       .text
+       .global _U(strnlen_PF)
+       .type   _U(strnlen_PF), @function
+
+_U(strnlen_PF):
+
+       LPM_R0_ZPLUS_INIT src_b2
+       X_movw  ZL, src_b0
+
+.L_strnlen_PF_loop:
+
+       LPM_R0_ZPLUS_NEXT src_b2
+       subi    len_b0, lo8(1)
+       sbci    len_b1, hi8(1)
+       cpse    r0, __zero_reg__
+       brcc    .L_strnlen_PF_loop
+
+; RAMPZ:Z points one character past the terminating NUL
+; return RAMPZ:Z - 1 - src = (-1 - src) + RAMPZ:Z = ~src + RAMPZ:Z
+
+       com     src_b0
+       com     src_b1
+       add     src_b0, ZL
+       adc     src_b1, ZH
+       X_movw  src_b2, src_b0          ; size_t is 16 bits
+       ret
+
+.L_strnlen_PF_end:
+
+       .size   _U(strnlen_PF), .L_strnlen_PF_end - _U(strnlen_PF)
+
+#endif /* not __DOXYGEN__ */

Added: trunk/avr-libc/libc/pmstring/strstr_PF.S
===================================================================
--- trunk/avr-libc/libc/pmstring/strstr_PF.S                            (rev 0)
+++ trunk/avr-libc/libc/pmstring/strstr_PF.S    2010-06-13 05:13:31 UTC (rev 
2163)
@@ -0,0 +1,124 @@
+/* Copyright (c) 2006, Carlos Lamas
+
+   based on libc/pmstring/strstr_P.S which is
+   Copyright (c) 2005, Werner Boellmann
+   Copyright (c) 2002, Philip Soeberg
+
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions are met:
+
+   * Redistributions of source code must retain the above copyright
+     notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above copyright
+     notice, this list of conditions and the following disclaimer in
+     the documentation and/or other materials provided with the
+     distribution.
+   * Neither the name of the copyright holders nor the names of
+     contributors may be used to endorse or promote products derived
+     from this software without specific prior written permission.
+
+  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+  POSSIBILITY OF SUCH DAMAGE. */
+
+/* $Id$ */
+
+#include "macros.inc"
+
+/** \ingroup avr_pgmspace
+    \fn char *strstr_PF (const char *s1, uint_farptr_t s2)
+    \brief Locate a substring.
+
+    The strstr_PF() function finds the first occurrence of the substring \c s2
+    in the string \c s1.  The terminating '\\0' characters are not
+    compared.
+    The strstr_PF() function is similar to strstr() except that \c s2 is a
+    far pointer to a string in program space.
+
+    \returns The strstr_PF() function returns a pointer to the beginning of the
+    substring, or NULL if the substring is not found.
+    If \c s2 points to a string of zero length, the function returns \c s1. The
+    contents of RAMPZ SFR are undefined when the function returns */
+
+#if !defined(__DOXYGEN__)
+
+#define s1_b1 r25
+#define s1_b0 r24
+#define s2_b3 r23
+#define s2_b2 r22
+#define s2_b1 r21
+#define s2_b0 r20
+
+; first char of str1 (updated in loop)
+#define chr1 s2_b3     /* MSB not used */
+
+#define ret_b1 r25
+#define ret_b0 r24
+
+       .text
+       .global _U(strstr_PF)
+       .type _U(strstr_PF), @function
+
+_U(strstr_PF):
+
+       X_movw  ZL, s2_b0
+       LPM_R0_ZPLUS_INIT s2_b2
+       X_movw  XL, s1_b0
+       LPM_R0_ZPLUS_NEXT s2_b2
+       tst     r0              ; is str2 empty?
+       brne    .L_findstart_P
+       ret                     ; return original string (req'd by standard)
+
+.L_findstart_P:
+
+       X_movw  ZL, s2_b0       ; reset Z pointer
+       LPM_R0_ZPLUS_INIT s2_b2
+       LPM_R0_ZPLUS_NEXT s2_b2 ; fetch first char
+
+.L_findstart_loop_P:           ; Find first char
+
+       ld      chr1, X+
+       tst     chr1            ; Is str1 @ end?
+       breq    .L_no_match_P   ; then return
+       cp      chr1, r0        ; Is chr1 == r0?
+       X_movw  ret_b0, XL      ; store return value
+       brne    .L_findstart_loop_P     ; If, then start checking string
+
+.L_stringloop_P:
+
+       LPM_R0_ZPLUS_NEXT s2_b2
+       tst     r0
+       breq    .L_match_P
+       ld      chr1, X
+       tst     chr1
+       breq    .L_no_match_P
+       cp      chr1, r0
+       brne    .L_findstart_P
+       adiw    XL, 1           ; Increment X with one
+       rjmp    .L_stringloop_P
+
+.L_no_match_P:
+
+       clr     ret_b0
+       clr     ret_b1
+       ret
+
+.L_match_P:
+       sbiw    ret_b0, 1
+       ret
+
+.L_strstr_end_P:
+
+       .size _U(strstr_PF), .L_strstr_end_P - _U(strstr_PF)
+
+#endif /* not __DOXYGEN__ */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]