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

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

[avr-libc-commit] [2298] Apply patch #3729: Printf for integers speed up


From: Dmitry Xmelkov
Subject: [avr-libc-commit] [2298] Apply patch #3729: Printf for integers speed up
Date: Sun, 29 Jul 2012 15:30:35 +0000

Revision: 2298
          http://svn.sv.gnu.org/viewvc/?view=rev&root=avr-libc&revision=2298
Author:   dmix
Date:     2012-07-29 15:30:34 +0000 (Sun, 29 Jul 2012)
Log Message:
-----------
Apply patch #3729: Printf for integers speed up

* doc/api/bench-libc.dox: Regenerate with GCC 4.7.1 (and new integer
to ASCII functions).
* include/stdlib.h: Define *toa() as inline functions.
* libc/misc/Files.am: Add new files.
* libc/misc/itoa.S: Rewrite.
* libc/misc/itoa_ncheck.S: New file.
* libc/misc/ltoa.S: Rewrite.
* libc/misc/ltoa_ncheck.S: New file.
* libc/misc/ultoa.S: Rewrite.
* libc/misc/ultoa_ncheck.S: New file.
* libc/misc/utoa.S: Rewrite.
* libc/misc/utoa_ncheck.S: New file.
* tests/simulate/stdlib/itoa-1.c: New file.
* tests/simulate/stdlib/itoa-2.c: New file.
* tests/simulate/stdlib/ltoa-1.c: New file.
* tests/simulate/stdlib/ltoa-2.c: New file.
* tests/simulate/stdlib/ultoa-1.c: New file.
* tests/simulate/stdlib/ultoa-2.c: New file.
* tests/simulate/stdlib/ultoa-3.c: New file.
* tests/simulate/stdlib/utoa-1.c: New file.
* tests/simulate/stdlib/utoa-2.c: New file.
* tests/simulate/stdlib/utoa-3.c: New file.

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

Modified Paths:
--------------
    trunk/avr-libc/ChangeLog
    trunk/avr-libc/NEWS
    trunk/avr-libc/doc/api/bench-libc.dox
    trunk/avr-libc/include/stdlib.h
    trunk/avr-libc/libc/misc/Files.am
    trunk/avr-libc/libc/misc/itoa.S
    trunk/avr-libc/libc/misc/ltoa.S
    trunk/avr-libc/libc/misc/ultoa.S
    trunk/avr-libc/libc/misc/utoa.S

Added Paths:
-----------
    trunk/avr-libc/libc/misc/itoa_ncheck.S
    trunk/avr-libc/libc/misc/ltoa_ncheck.S
    trunk/avr-libc/libc/misc/ultoa_ncheck.S
    trunk/avr-libc/libc/misc/utoa_ncheck.S
    trunk/avr-libc/tests/simulate/stdlib/itoa-1.c
    trunk/avr-libc/tests/simulate/stdlib/itoa-2.c
    trunk/avr-libc/tests/simulate/stdlib/ltoa-1.c
    trunk/avr-libc/tests/simulate/stdlib/ltoa-2.c
    trunk/avr-libc/tests/simulate/stdlib/ultoa-1.c
    trunk/avr-libc/tests/simulate/stdlib/ultoa-2.c
    trunk/avr-libc/tests/simulate/stdlib/ultoa-3.c
    trunk/avr-libc/tests/simulate/stdlib/utoa-1.c
    trunk/avr-libc/tests/simulate/stdlib/utoa-2.c
    trunk/avr-libc/tests/simulate/stdlib/utoa-3.c

Modified: trunk/avr-libc/ChangeLog
===================================================================
--- trunk/avr-libc/ChangeLog    2012-06-19 06:56:49 UTC (rev 2297)
+++ trunk/avr-libc/ChangeLog    2012-07-29 15:30:34 UTC (rev 2298)
@@ -1,3 +1,30 @@
+2012-07-30  Dmitry Xmelkov  <address@hidden>
+
+       patch #3729: Printf for integers speed up
+       Thanks to Georg-Johann Lay.
+       * doc/api/bench-libc.dox: Regenerate with GCC 4.7.1 (and new integer
+       to ASCII functions).
+       * include/stdlib.h: Define *toa() as inline functions.
+       * libc/misc/Files.am: Add new files.
+       * libc/misc/itoa.S: Rewrite.
+       * libc/misc/itoa_ncheck.S: New file.
+       * libc/misc/ltoa.S: Rewrite.
+       * libc/misc/ltoa_ncheck.S: New file.
+       * libc/misc/ultoa.S: Rewrite.
+       * libc/misc/ultoa_ncheck.S: New file.
+       * libc/misc/utoa.S: Rewrite.
+       * libc/misc/utoa_ncheck.S: New file.
+       * tests/simulate/stdlib/itoa-1.c: New file.
+       * tests/simulate/stdlib/itoa-2.c: New file.
+       * tests/simulate/stdlib/ltoa-1.c: New file.
+       * tests/simulate/stdlib/ltoa-2.c: New file.
+       * tests/simulate/stdlib/ultoa-1.c: New file.
+       * tests/simulate/stdlib/ultoa-2.c: New file.
+       * tests/simulate/stdlib/ultoa-3.c: New file.
+       * tests/simulate/stdlib/utoa-1.c: New file.
+       * tests/simulate/stdlib/utoa-2.c: New file.
+       * tests/simulate/stdlib/utoa-3.c: New file.
+
 2012-06-19  Joerg Wunsch <address@hidden>
 
        * include/avr/signature.h (__signature): mark as "used"

Modified: trunk/avr-libc/NEWS
===================================================================
--- trunk/avr-libc/NEWS 2012-06-19 06:56:49 UTC (rev 2297)
+++ trunk/avr-libc/NEWS 2012-07-29 15:30:34 UTC (rev 2298)
@@ -14,6 +14,8 @@
 
 * Contributed Patches:
 
+  [#3729] Printf for integers speed up
+
 * Other changes:
 
 

Modified: trunk/avr-libc/doc/api/bench-libc.dox
===================================================================
--- trunk/avr-libc/doc/api/bench-libc.dox       2012-06-19 06:56:49 UTC (rev 
2297)
+++ trunk/avr-libc/doc/api/bench-libc.dox       2012-07-29 15:30:34 UTC (rev 
2298)
@@ -7,7 +7,7 @@
 
 \section bench_libc A few of libc functions.
 
-Avr-gcc version is 4.2.3
+Avr-gcc version is 4.7.1
 
 The size of function is given in view of all picked up functions. By default
 Avr-libc is compiled with \c -mcall-prologues option. In brackets the size
@@ -28,127 +28,127 @@
     <td> atoi ("12345")</td>
     <td>Flash bytes<br>Stack bytes<br>MCU clocks</td>
     <td>82 (82)<br>2<br>155</td>
-    <td>78 (78)<br><br></td>
+    <td>78 (78)<br>2<br>149</td>
     <td>74 (74)<br>2<br>149</td>
   </tr>
   <tr>
     <td> atol ("12345")</td>
     <td>Flash bytes<br>Stack bytes<br>MCU clocks</td>
     <td>122 (122)<br>2<br>221</td>
-    <td>118 (118)<br><br></td>
     <td>118 (118)<br>2<br>219</td>
+    <td>118 (118)<br>2<br>219</td>
   </tr>
   <tr>
     <td> dtostre (1.2345, s, 6, 0)</td>
     <td>Flash bytes<br>Stack bytes<br>MCU clocks</td>
-    <td>1184 (1072)<br>17<br>1313</td>
-    <td>1088 (978)<br><br></td>
-    <td>1088 (978)<br>17<br>1152</td>
+    <td>1116 (1004)<br>17<br>1247</td>
+    <td>1048 (938)<br>17<br>1105</td>
+    <td>1048 (938)<br>17<br>1105</td>
   </tr>
   <tr>
     <td> dtostrf (1.2345, 15, 6, s)</td>
     <td>Flash bytes<br>Stack bytes<br>MCU clocks</td>
-    <td>1676 (1564)<br>36<br>1608</td>
-    <td>1548 (1438)<br><br></td>
-    <td>1548 (1438)<br>36<br>1443</td>
+    <td>1616 (1616)<br>38<br>1634</td>
+    <td>1508 (1508)<br>38<br>1462</td>
+    <td>1508 (1508)<br>38<br>1462</td>
   </tr>
   <tr>
     <td> itoa (12345, s, 10)</td>
     <td>Flash bytes<br>Stack bytes<br>MCU clocks</td>
-    <td>150 (150)<br>4<br>1172</td>
-    <td>134 (134)<br><br></td>
-    <td>134 (134)<br>4<br>1152</td>
+    <td>110 (110)<br>2<br>879</td>
+    <td>102 (102)<br>2<br>875</td>
+    <td>102 (102)<br>2<br>875</td>
   </tr>
   <tr>
     <td> ltoa (12345L, s, 10)</td>
     <td>Flash bytes<br>Stack bytes<br>MCU clocks</td>
-    <td>220 (220)<br>9<br>3174</td>
-    <td>200 (200)<br><br></td>
-    <td>200 (200)<br>9<br>3136</td>
+    <td>134 (134)<br>2<br>1597</td>
+    <td>126 (126)<br>2<br>1593</td>
+    <td>126 (126)<br>2<br>1593</td>
   </tr>
   <tr>
     <td> malloc (1)</td>
     <td>Flash bytes<br>Stack bytes<br>MCU clocks</td>
-    <td>554 (554)<br>4<br>196</td>
-    <td>506 (506)<br><br></td>
-    <td>506 (506)<br>4<br>178</td>
+    <td>768 (712)<br>6<br>215</td>
+    <td>714 (660)<br>6<br>201</td>
+    <td>714 (660)<br>6<br>201</td>
   </tr>
   <tr>
     <td> realloc ((void *)0, 1)</td>
     <td>Flash bytes<br>Stack bytes<br>MCU clocks</td>
-    <td>1152 (1040)<br>20<br>303</td>
-    <td>1042 (932)<br><br></td>
-    <td>1042 (932)<br>20<br>280</td>
+    <td>1284 (1172)<br>18<br>305</td>
+    <td>1174 (1064)<br>18<br>286</td>
+    <td>1174 (1064)<br>18<br>286</td>
   </tr>
   <tr>
     <td> qsort (s, sizeof(s), 1, cmp)</td>
     <td>Flash bytes<br>Stack bytes<br>MCU clocks</td>
-    <td>1242 (1130)<br>38<br>20914</td>
-    <td>990 (880)<br><br></td>
-    <td>1008 (898)<br>38<br>16678</td>
+    <td>1252 (1140)<br>42<br>21996</td>
+    <td>1022 (912)<br>42<br>19905</td>
+    <td>1028 (918)<br>42<br>17541</td>
   </tr>
   <tr>
     <td> sprintf_min (s, "%d", 12345)</td>
     <td>Flash bytes<br>Stack bytes<br>MCU clocks</td>
-    <td>1216 (1104)<br>59<br>1846</td>
-    <td>1090 (980)<br><br></td>
-    <td>1086 (976)<br>59<br>1711</td>
+    <td>1224 (1112)<br>53<br>1841</td>
+    <td>1092 (982)<br>53<br>1694</td>
+    <td>1088 (978)<br>53<br>1689</td>
   </tr>
   <tr>
     <td> sprintf (s, "%d", 12345)</td>
     <td>Flash bytes<br>Stack bytes<br>MCU clocks</td>
-    <td>1674 (1562)<br>58<br>1610</td>
-    <td>1542 (1432)<br><br></td>
-    <td>1498 (1388)<br>58<br>1528</td>
+    <td>1614 (1502)<br>58<br>1647</td>
+    <td>1476 (1366)<br>58<br>1552</td>
+    <td>1454 (1344)<br>58<br>1547</td>
   </tr>
   <tr>
     <td> sprintf_flt (s, "%e", 1.2345)</td>
     <td>Flash bytes<br>Stack bytes<br>MCU clocks</td>
-    <td>3334 (3222)<br>66<br>2513</td>
-    <td>3084 (2974)<br><br></td>
-    <td>3040 (2930)<br>66<br>2297</td>
+    <td>3228 (3116)<br>67<br>2573</td>
+    <td>2990 (2880)<br>67<br>2311</td>
+    <td>2968 (2858)<br>67<br>2311</td>
   </tr>
   <tr>
     <td> sscanf_min ("12345", "%d", &i)</td>
     <td>Flash bytes<br>Stack bytes<br>MCU clocks</td>
-    <td>1540 (1428)<br>55<br>1339</td>
-    <td>1354 (1244)<br><br></td>
-    <td>1354 (1244)<br>55<br>1240</td>
+    <td>1532 (1420)<br>55<br>1607</td>
+    <td>1328 (1218)<br>55<br>1446</td>
+    <td>1328 (1218)<br>55<br>1446</td>
   </tr>
   <tr>
     <td> sscanf ("12345", "%d", &i)</td>
     <td>Flash bytes<br>Stack bytes<br>MCU clocks</td>
-    <td>1950 (1838)<br>53<br>1334</td>
-    <td>1704 (1594)<br><br></td>
-    <td>1704 (1594)<br>53<br>1235</td>
+    <td>2008 (1896)<br>55<br>1610</td>
+    <td>1748 (1638)<br>55<br>1449</td>
+    <td>1748 (1638)<br>55<br>1449</td>
   </tr>
   <tr>
     <td> sscanf ("point,color", "%[a-z]", s)</td>
     <td>Flash bytes<br>Stack bytes<br>MCU clocks</td>
-    <td>1950 (1838)<br>87<br>2878</td>
-    <td>1704 (1594)<br><br></td>
-    <td>1704 (1594)<br>87<br>2718</td>
+    <td>2008 (1896)<br>86<br>3067</td>
+    <td>1748 (1638)<br>86<br>2806</td>
+    <td>1748 (1638)<br>86<br>2806</td>
   </tr>
   <tr>
     <td> sscanf_flt ("1.2345", "%e", &x)</td>
     <td>Flash bytes<br>Stack bytes<br>MCU clocks</td>
-    <td>3298 (3186)<br>63<br>2187</td>
-    <td>2934 (2824)<br><br></td>
-    <td>2918 (2808)<br>63<br>1833</td>
+    <td>3464 (3352)<br>71<br>2497</td>
+    <td>3086 (2976)<br>71<br>2281</td>
+    <td>3070 (2960)<br>71<br>2078</td>
   </tr>
   <tr>
     <td> strtod ("1.2345", &p)</td>
     <td>Flash bytes<br>Stack bytes<br>MCU clocks</td>
-    <td>1570 (1458)<br>22<br>1237</td>
-    <td>1472 (1362)<br><br></td>
-    <td>1456 (1346)<br>22<br>971</td>
+    <td>1632 (1520)<br>20<br>1235</td>
+    <td>1536 (1426)<br>20<br>1177</td>
+    <td>1480 (1480)<br>21<br>1124</td>
   </tr>
   <tr>
     <td> strtol ("12345", &p, 0)</td>
     <td>Flash bytes<br>Stack bytes<br>MCU clocks</td>
-    <td>942 (830)<br>29<br>1074</td>
-    <td>874 (764)<br><br></td>
-    <td>808 (698)<br>21<br>722</td>
+    <td>918 (806)<br>22<br>956</td>
+    <td>834 (724)<br>22<br>891</td>
+    <td>792 (792)<br>28<br>794</td>
   </tr>
 </table>
 </small>

Modified: trunk/avr-libc/include/stdlib.h
===================================================================
--- trunk/avr-libc/include/stdlib.h     2012-06-19 06:56:49 UTC (rev 2297)
+++ trunk/avr-libc/include/stdlib.h     2012-07-29 15:30:34 UTC (rev 2298)
@@ -82,23 +82,31 @@
 #ifndef __DOXYGEN__
 
 #ifndef __ATTR_CONST__
-#define __ATTR_CONST__ __attribute__((__const__))
+# define __ATTR_CONST__ __attribute__((__const__))
 #endif
 
 #ifndef __ATTR_MALLOC__
-#define __ATTR_MALLOC__ __attribute__((__malloc__))
+# define __ATTR_MALLOC__ __attribute__((__malloc__))
 #endif
 
 #ifndef __ATTR_NORETURN__
-#define __ATTR_NORETURN__ __attribute__((__noreturn__))
+# define __ATTR_NORETURN__ __attribute__((__noreturn__))
 #endif
 
 #ifndef __ATTR_PURE__
-#define __ATTR_PURE__ __attribute__((__pure__))
+# define __ATTR_PURE__ __attribute__((__pure__))
 #endif
 
+#ifndef        __ATTR_GNU_INLINE__
+# ifdef  __GNUC_STDC_INLINE__
+#  define __ATTR_GNU_INLINE__   __attribute__((__gnu_inline__))
+# else
+#  define __ATTR_GNU_INLINE__
+# endif
 #endif
 
+#endif
+
 /** The abort() function causes abnormal program termination to occur.
     This realization disables interrupts and jumps to _exit() function
     with argument equal to 1. In the limited AVR environment, execution is
@@ -403,7 +411,24 @@
 
    The itoa() function returns the pointer passed as \c s.
 */
-extern char *itoa(int __val, char *__s, int __radix);
+#ifdef  __DOXYGEN__
+extern char *itoa(int val, char *s, int radix);
+#else
+extern __inline__ __ATTR_GNU_INLINE__
+char *itoa (int __val, char *__s, int __radix)
+{
+    if (!__builtin_constant_p (__radix)) {
+       extern char *__itoa (int, char *, int);
+       return __itoa (__val, __s, __radix);
+    } else if (__radix < 2 || __radix > 36) {
+       *__s = 0;
+       return __s;
+    } else {
+       extern char *__itoa_ncheck (int, char *, unsigned char);
+       return __itoa_ncheck (__val, __s, __radix);
+    }
+}
+#endif
 
 /**
  \ingroup avr_stdlib
@@ -431,7 +456,24 @@
 
    The ltoa() function returns the pointer passed as \c s.
 */
-extern char *ltoa(long int __val, char *__s, int __radix);
+#ifdef  __DOXYGEN__
+extern char *ltoa(long val, char *s, int radix);
+#else
+extern __inline__ __ATTR_GNU_INLINE__
+char *ltoa (long __val, char *__s, int __radix)
+{
+    if (!__builtin_constant_p (__radix)) {
+       extern char *__ltoa (long, char *, int);
+       return __ltoa (__val, __s, __radix);
+    } else if (__radix < 2 || __radix > 36) {
+       *__s = 0;
+       return __s;
+    } else {
+       extern char *__ltoa_ncheck (long, char *, unsigned char);
+       return __ltoa_ncheck (__val, __s, __radix);
+    }
+}
+#endif
 
 /**
  \ingroup avr_stdlib
@@ -457,16 +499,32 @@
 
    The utoa() function returns the pointer passed as \c s.
 */
-extern char *utoa(unsigned int __val, char *__s, int __radix);
+#ifdef  __DOXYGEN__
+extern char *utoa(unsigned int val, char *s, int radix);
+#else
+extern __inline__ __ATTR_GNU_INLINE__
+char *utoa (unsigned int __val, char *__s, int __radix)
+{
+    if (!__builtin_constant_p (__radix)) {
+       extern char *__utoa (unsigned int, char *, int);
+       return __utoa (__val, __s, __radix);
+    } else if (__radix < 2 || __radix > 36) {
+       *__s = 0;
+       return __s;
+    } else {
+       extern char *__utoa_ncheck (unsigned int, char *, unsigned char);
+       return __utoa_ncheck (__val, __s, __radix);
+    }
+}
+#endif
 
 /**
  \ingroup avr_stdlib
    \brief Convert an unsigned long integer to a string.
 
    The function ultoa() converts the unsigned long integer value from
-   \c val into an
-   ASCII representation that will be stored under \c s.  The caller
-   is responsible for providing sufficient storage in \c s.
+   \c val into an ASCII representation that will be stored under \c s.
+   The caller is responsible for providing sufficient storage in \c s.
 
    \note The minimal size of the buffer \c s depends on the choice of
    radix. For example, if the radix is 2 (binary), you need to supply a buffer
@@ -483,7 +541,24 @@
 
    The ultoa() function returns the pointer passed as \c s.
 */
-extern char *ultoa(unsigned long int __val, char *__s, int __radix);
+#ifdef  __DOXYGEN__
+extern char *ultoa(unsigned long val, char *s, int radix);
+#else
+extern __inline__ __ATTR_GNU_INLINE__
+char *ultoa (unsigned long __val, char *__s, int __radix)
+{
+    if (!__builtin_constant_p (__radix)) {
+       extern char *__ultoa (unsigned long, char *, int);
+       return __ultoa (__val, __s, __radix);
+    } else if (__radix < 2 || __radix > 36) {
+       *__s = 0;
+       return __s;
+    } else {
+       extern char *__ultoa_ncheck (unsigned long, char *, unsigned char);
+       return __ultoa_ncheck (__val, __s, __radix);
+    }
+}
+#endif
 
 /**  \ingroup avr_stdlib
 Highest number that can be generated by random(). */

Modified: trunk/avr-libc/libc/misc/Files.am
===================================================================
--- trunk/avr-libc/libc/misc/Files.am   2012-06-19 06:56:49 UTC (rev 2297)
+++ trunk/avr-libc/libc/misc/Files.am   2012-07-29 15:30:34 UTC (rev 2298)
@@ -47,11 +47,15 @@
 
 misc_a_asm_sources = \
        itoa.S \
+       itoa_ncheck.S \
        ltoa.S \
+       ltoa_ncheck.S \
        mulsi10.S \
        mul10.S \
        ultoa.S \
-       utoa.S
+       ultoa_ncheck.S \
+       utoa.S \
+       utoa_ncheck.S
 
 misc_a_extra_dist = \
        eedef.h \

Modified: trunk/avr-libc/libc/misc/itoa.S
===================================================================
--- trunk/avr-libc/libc/misc/itoa.S     2012-06-19 06:56:49 UTC (rev 2297)
+++ trunk/avr-libc/libc/misc/itoa.S     2012-07-29 15:30:34 UTC (rev 2298)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2001, 2002, Michael Rickmann
+/* Copyright (c) 2012  Georg-Johann Lay
    All rights reserved.
 
    Redistribution and use in source and binary forms, with or without
@@ -26,84 +26,39 @@
   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   POSSIBILITY OF SUCH DAMAGE. */
 
-/* $Id$ */
+/* $Id$        */
 
-/*
-   itoa.S
+#if    !defined (__DOXYGEN__)
+#if    !defined (__AVR_TINY)
 
-   Copyright (C) 2000 Michael Rickmann <address@hidden>
-   Changes: Reiner Patommel <address@hidden>
-       (no stack space used anymore)
-   Changes: Reiner Patommel <address@hidden> bug# 4010                         
        
+#include "asmdef.h"
 
-   #include <stdlib.h>
-   char *itoa(int value, char *string, int radix);
-  ----------------------------------------------------------------------
-*/
+/* char *itoa (int val, char *s, int radix)
+   Commonly this program is't used, as the 'stdlib.h' obtains the inline
+   version of itoa() where radix is checked at compile time.
+ */
 
-#if !defined(__AVR_TINY__)
+#define val_lo r24
+#define str_lo r22
+#define rdx_lo r20
+#define rdx_hi r21
 
-#if !defined(__DOXYGEN__)
+ENTRY  itoa
+ENTRY  __itoa
 
-#include "macros.inc"
-#include "ctoasm.inc"
+       cpi     rdx_lo, 37
+       cpc     rdx_hi, __zero_reg__
+       brsh    1f
+       cpi     rdx_lo, 2
+       brlo    1f
+       XJMP    _U(__itoa_ncheck)
 
-       ASSEMBLY_CLIB_SECTION
-    .global _U(itoa)
-       .func _U(itoa)
+1:     X_movw  ZL, str_lo
+       st      Z, __zero_reg__
+       X_movw  r24, str_lo
+       ret
 
-/* arguments */
-#define r_val_hi r25
-#define r_val_lo r24
-#define r_str_hi r23
-#define r_str_lo r22
-#define r_radix  r20
+ENDFUNC
 
-/* local variables */
-#define r_lstr_hi r19
-#define r_lstr_lo r18
-
-
-_U(itoa):
-       X_movw  ZL, r_str_lo    ; &string
-       X_movw  r_lstr_lo, ZL   ; save &string
-       clt                     ; make sure T flag is clear
-       cpi     r_radix, 2      ; no radix < 2
-       brlt    99f             ; return with \0
-       cpi     r_radix, 37     ; no radix > 36
-       brge    99f             ; return with \0
-       cpi     r_radix, 10     ; decimal number ?
-       brne    1f              ; no -> convert
-       bst     r_val_hi, 7     ; for decimal numbers remember sign of value
-       brtc    1f              ; positive number -> convert
-       com     r_val_hi        ; negative number -> make positive
-       neg     r_val_lo
-       sbci    r_val_hi, 0xff
-1:
-       mov     r22, r_radix    ; radix
-       clr     r23             ;  dividend in r25:r24, divisor in r23:r22
-       XCALL   _U(__udivmodhi4);  quotient in r23:r22, remainder in r25:r24
-                               ;  clobbered: r0, r21, r26, r27
-                               ;  call-used but preserved: r18, r19, r20, r30, 
r31
-       subi    r24, 0xd0       ; + '0'
-       cpi     r24, 0x3a       ; > '9' ?
-       brlt    10f
-       subi    r24, 0xd9       ; + 'a' - 10 - '0'
-10:
-       st      Z+, r24         ; write char to string in reverse order
-       X_movw  r_val_lo, r22   ; quotient -> dividend
-       sbiw    r_val_lo, 0     ; value == 0 ?
-       brne    1b
-       brtc    99f             ; T flag clear? -> positive number              
-       ldi     r21, '-'
-       st      Z+, r21         ; write minus sign to string
-99:    
-       st      Z, __zero_reg__ ; terminate string
-       X_movw  r_val_lo, r_lstr_lo     ; restore &string as return value
-       XJMP    _U(strrev)      ; reverse string
-
-       .endfunc
-
-#endif /* not __DOXYGEN__ */
-
-#endif /*!defined(__AVR_TINY__) */
+#endif /* !__AVR_TINY__ */
+#endif /* !__DOXYGEN__ */

Added: trunk/avr-libc/libc/misc/itoa_ncheck.S
===================================================================
--- trunk/avr-libc/libc/misc/itoa_ncheck.S                              (rev 0)
+++ trunk/avr-libc/libc/misc/itoa_ncheck.S      2012-07-29 15:30:34 UTC (rev 
2298)
@@ -0,0 +1,64 @@
+/* Copyright (c) 2012  Georg-Johann Lay
+   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$        */
+
+#if    !defined (__DOXYGEN__)
+#if    !defined (__AVR_TINY)
+
+#include "asmdef.h"
+
+/* char *__itoa_ncheck (int val, char *s, unsigned char radix) */
+
+#define val_lo r24
+#define val_hi r25
+#define str_lo r22
+#define radix  r20
+
+#define sign   r27     /* Argument for __utoa_common() */
+
+ENTRY  __itoa_ncheck
+
+       clr     sign
+       cpi     radix, 10
+       brne    1f
+       tst     val_hi
+       brpl    1f
+
+    ; radix == 10 && val < 0: sign = '-'
+       ldi     sign, '-'
+    ; val = -val to make val positive
+       com     val_hi
+       neg     val_lo
+       sbci    val_hi, -1
+1:     XJMP    _U(__utoa_common)
+
+ENDFUNC
+
+#endif /* !__AVR_TINY__ */
+#endif /* !__DOXYGEN__ */


Property changes on: trunk/avr-libc/libc/misc/itoa_ncheck.S
___________________________________________________________________
Added: svn:keywords
   + Author Id Date

Modified: trunk/avr-libc/libc/misc/ltoa.S
===================================================================
--- trunk/avr-libc/libc/misc/ltoa.S     2012-06-19 06:56:49 UTC (rev 2297)
+++ trunk/avr-libc/libc/misc/ltoa.S     2012-07-29 15:30:34 UTC (rev 2298)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002, Reiner Patommel
+/* Copyright (c) 2012  Georg-Johann Lay
    All rights reserved.
 
    Redistribution and use in source and binary forms, with or without
@@ -26,99 +26,37 @@
   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   POSSIBILITY OF SUCH DAMAGE. */
 
-/* $Id$ */
+/* $Id$        */
 
-/*
-   ltoa.S
+#if    !defined (__DOXYGEN__)
+#if    !defined (__AVR_TINY)
 
-   Contributors:
-     Created by Reiner Patommel based on
-        itoa.s by Michael Rickmann <address@hidden>
-     Changes: Reiner Patommel <address@hidden> bug# 4010       
+#include "asmdef.h"
 
-       #include <stdlib.h>
-       char *ltoa(long int value, char *string, int radix);
-  ----------------------------------------------------------------------
-*/
+/* char *ltoa (long val, char *s, int radix)   */
 
-#if !defined(__DOXYGEN__)
+#define val_lo r22
+#define str_lo r20
+#define rdx_lo r18
+#define rdx_hi r19
 
-#include "macros.inc"
-#include "ctoasm.inc"
 
-       ASSEMBLY_CLIB_SECTION
-    .global _U(ltoa)
-       .func _U(ltoa)
+ENTRY  ltoa
+ENTRY  __ltoa
 
-/* function arguments */
-#define a_val_hhi      r25
-#define a_val_hlo      r24
-#define a_val_hi       r23
-#define a_val_lo       r22
-#define a_str_hi       r21
-#define a_str_lo       r20
-#define a_radix_hi     r19
-#define a_radix        r18
+       cpi     rdx_lo, 37
+       cpc     rdx_hi, __zero_reg__
+       brsh    1f
+       cpi     rdx_lo, 2
+       brlo    1f
+       XJMP    _U(__ltoa_ncheck)
 
-/* local variables */
-#define r_radix                r28
+1:     X_movw  ZL, str_lo
+       st      Z, __zero_reg__
+       X_movw  r24, str_lo
+       ret
 
+ENDFUNC
 
-
-_U(ltoa):
-       X_movw  ZL, a_str_lo    ; Z = &string
-       push    r28             ; save r28
-       push    ZH              ; keep &string
-       push    ZL
-       cpi     a_radix, 2      ; no radix < 2
-       brlt    99f             ; return with \0
-       cpi     a_radix, 37     ; no radix > 36
-       brge    99f             ; return with \0
-       mov     r_radix, a_radix; save radix
-       clt                     ; make sure T flag is clear
-       cpi     r_radix, 10     ; decimal number?
-       brne    1f
-       bst     a_val_hhi, 7    ; remember sign of decimal number
-       brtc    1f              ; number positive? -> convert
-       com     a_val_hhi       ; make decimal number positive
-       com     a_val_hlo
-       com     a_val_hi
-       neg     a_val_lo
-       sbci    a_val_hi,  lo8(-1)
-       sbci    a_val_hlo, lo8(-1)
-       sbci    a_val_hhi, lo8(-1)
-1:
-       mov     r18, r_radix    ; radix is divisor
-       clr     r19             ; remainder of number is dividend
-       clr     r20
-       clr     r21
-       push    ZH              ; Z will be clobbered
-       push    ZL              ; dividend in r25:r22, divisor in r21:r18
-       XCALL   _U(__udivmodsi4); quotient in r21:r18, remainder in r25:r22
-       pop     ZL
-       pop     ZH
-       subi    r22, 0xd0       ; + '0'
-       cpi     r22, 0x3a       ; > '9' ?
-       brlt    10f
-       subi    r22, 0xd9       ; + 'a' - 10 - '0'
-10:
-       st      Z+, r22         ; write character to string in reverse order!
-       X_movw  a_val_lo, r18   ; quotient -> dividend
-       X_movw  a_val_hlo, r20
-       subi    a_val_lo, 0
-       sbci    a_val_hi, 0
-       sbci    a_val_hlo, 0
-       sbci    a_val_hhi,0     ; value == 0 ?
-       brne    1b
-       brtc    99f             ; decimal number positive -> finish
-       ldi     r28, '-'
-       st      Z+, r28         ; write minus sign to string
-99:
-       st      Z, __zero_reg__ ; terminate string
-       pop     a_val_hlo       ; restore &string as return value
-       pop     a_val_hhi
-       pop     r28             ; restore r28
-       XJMP    _U(strrev)      ; reverse string
-       .endfunc
-
-#endif /* not __DOXYGEN__ */
+#endif /* !__AVR_TINY__ */
+#endif /* !__DOXYGEN__ */

Added: trunk/avr-libc/libc/misc/ltoa_ncheck.S
===================================================================
--- trunk/avr-libc/libc/misc/ltoa_ncheck.S                              (rev 0)
+++ trunk/avr-libc/libc/misc/ltoa_ncheck.S      2012-07-29 15:30:34 UTC (rev 
2298)
@@ -0,0 +1,69 @@
+/* Copyright (c) 2012  Georg-Johann Lay
+   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$        */
+
+#if    !defined (__DOXYGEN__)
+#if    !defined (__AVR_TINY)
+
+#include "asmdef.h"
+
+/* char *__ltoa_ncheck (long val, char *s, unsigned char radix)        */
+
+#define val_lo r22
+#define val_hi r23
+#define val_hlo        r24
+#define val_hhi        r25
+#define str_lo r20
+#define rdx_lo r18
+
+#define sign   r27     /* Argument for __ultoa_common()        */
+
+ENTRY  __ltoa_ncheck
+
+       clr     sign
+       cpi     rdx_lo, 10
+       brne    1f
+       tst     val_hhi
+       brpl    1f
+
+    ; radix == 10 && val < 0: sign = '-' and val = -val
+       ldi     sign, '-'
+       com     val_hhi
+       com     val_hlo
+       com     val_hi
+       neg     val_lo
+       sbci    val_hi, -1
+       sbci    val_hlo, -1
+       sbci    val_hhi, -1
+1:     XJMP    _U(__ultoa_common)
+
+ENDFUNC
+
+#endif /* !__AVR_TINY__ */
+#endif /* !__DOXYGEN__ */


Property changes on: trunk/avr-libc/libc/misc/ltoa_ncheck.S
___________________________________________________________________
Added: svn:keywords
   + Author Id Date

Modified: trunk/avr-libc/libc/misc/ultoa.S
===================================================================
--- trunk/avr-libc/libc/misc/ultoa.S    2012-06-19 06:56:49 UTC (rev 2297)
+++ trunk/avr-libc/libc/misc/ultoa.S    2012-07-29 15:30:34 UTC (rev 2298)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002, Reiner Patommel
+/* Copyright (c) 2012  Georg-Johann Lay
    All rights reserved.
 
    Redistribution and use in source and binary forms, with or without
@@ -26,83 +26,38 @@
   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   POSSIBILITY OF SUCH DAMAGE. */
 
-/* $Id$ */
+/* $Id$        */
 
-/*
-   ultoa.S
+#if    !defined (__DOXYGEN__)
+#if    !defined (__AVR_TINY)
 
-   Contributors:
-     Created by Reiner Patommel based on
-     itoa.s by Michael Rickmann <address@hidden>
-     19 June 2003 changed by Reiner Patommel bug# 4010
+#include "asmdef.h"
 
-       #include <stdlib.h>
-       char *ultoa(unsigned long int value, char *string, int radix);
-  ----------------------------------------------------------------------
-*/
+/* char *ultoa (unsigned long val, char *s, int radix) */
 
-#if !defined(__DOXYGEN__)
+#define val_lo r22
+#define str_lo r20
+#define rdx_lo r18
+#define rdx_hi r19
 
-#include "macros.inc"
-#include "ctoasm.inc"
 
-    ASSEMBLY_CLIB_SECTION
-       .global _U(ultoa)
-       .func _U(ultoa)
+ENTRY  ultoa
+ENTRY  __ultoa
 
-/* function arguments */
-#define a_val_hhi      r25
-#define a_val_hlo      r24
-#define a_val_hi       r23
-#define a_val_lo       r22
-#define a_str_hi       r21
-#define a_str_lo       r20
-#define a_radix_hi     r19
-#define a_radix        r18
+    ; Check radix
+       cpi     rdx_lo, 37
+       cpc     rdx_hi, __zero_reg__
+       brsh    1f
+       cpi     rdx_lo, 2
+       brlo    1f
+       XJMP    _U(__ultoa_ncheck)
 
-/* local variables */
-#define r_radix                r28
+1:     X_movw  ZL, str_lo
+       st      Z, __zero_reg__
+       X_movw  r24, str_lo
+       ret
 
+ENDFUNC
 
-_U(ultoa):
-       X_movw  ZL, a_str_lo    ; Z = &string
-       push    r28             ; save r28
-       push    ZH              ; keep &string
-       push    ZL
-       cpi     a_radix, 2      ; no radix < 2
-       brlt    99f             ; return with \0
-       cpi     a_radix, 37     ; no radix > 36
-       brge    99f             ; return with \0
-       mov     r_radix, a_radix; save radix
-1:
-       mov     r18, r_radix    ; radix is divisor
-       clr     r19             ; remainder of number is dividend
-       clr     r20
-       clr     r21
-       push    ZH              ; Z will be clobbered
-       push    ZL              ; dividend in r25:r22, divisor in r21:r18
-       XCALL   _U(__udivmodsi4); quotient in r21:r18, remainder in r25:r22
-       pop     ZL
-       pop     ZH
-       subi    r22, 0xd0       ; + '0'
-       cpi     r22, 0x3a       ; > '9' ?
-       brlt    10f
-       subi    r22, 0xd9       ; + 'a' - 10 - '0'
-10:
-       st      Z+, r22         ; write character to string in reverse order!
-       X_movw  a_val_lo, r18   ; quotient -> dividend
-       X_movw  a_val_hlo, r20
-       subi    a_val_lo, 0
-       sbci    a_val_hi, 0
-       sbci    a_val_hlo, 0
-       sbci    a_val_hhi,0     ; value == 0 ?
-       brne    1b
-99:
-       st      Z, __zero_reg__ ; terminate string
-       pop     a_val_hlo       ; restore &string as return value
-       pop     a_val_hhi
-       pop     r28             ; restore r28
-       XJMP    _U(strrev)      ; reverse string
-       .endfunc
-
-#endif /* not __DOXYGEN__ */
+#endif /* !__AVR_TINY__ */
+#endif /* !__DOXYGEN__ */

Added: trunk/avr-libc/libc/misc/ultoa_ncheck.S
===================================================================
--- trunk/avr-libc/libc/misc/ultoa_ncheck.S                             (rev 0)
+++ trunk/avr-libc/libc/misc/ultoa_ncheck.S     2012-07-29 15:30:34 UTC (rev 
2298)
@@ -0,0 +1,116 @@
+/* Copyright (c) 2012  Georg-Johann Lay
+   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$        */
+
+#if    !defined (__DOXYGEN__)
+#if    !defined (__AVR_TINY)
+
+#include "asmdef.h"
+
+/* char *__ultoa_ncheck (unsigned long val, char *s, unsigned char radix)
+   This function is the utoa() without checking the radix for 2..36 margins.
+ */
+
+#define val_lo r22
+#define val_hi r23
+#define val_hlo        r24
+#define val_hhi        r25
+#define str_lo r20
+#define radix  r18
+
+#define counter        r19
+#define digit  r26
+#define sign   r27
+
+
+ENTRY  __ultoa_ncheck
+       clr     sign
+
+ENTRY  __ultoa_common
+       X_movw  ZL, str_lo
+
+1:  ; Saves one iteration of the digit-loop:
+    ; If val < radix we can use the low byte of val as digit
+       mov     digit, val_lo
+       cp      val_lo, radix
+       cpc     val_hi, __zero_reg__
+       cpc     val_hlo, __zero_reg__
+       cpc     val_hhi, __zero_reg__
+    ; now C is set, if val < radix
+       sbc     counter, counter
+       bst     counter, 0
+       brts    4f
+    ; counter == 0 here
+
+    ; If val >= radix, then pop one digit from val
+       clr     digit
+
+2:  ; Vanilla 32:8 quotient and remainder to pop the digit
+    ; digit <- val % radix
+    ; val   <- val / radix
+       lsl     val_lo
+       rol     val_hi
+       rol     val_hlo
+       rol     val_hhi
+       rol     digit
+       cp      digit, radix
+       brlo    3f
+       sub     digit, radix
+    ; val |= 1
+       inc     val_lo
+3:  ; Loop the 32 bits
+       subi    counter, 8              ; 256 / 8 == 32 loops
+       brne    2b
+
+4:  ; Convert the digit to ASCII...
+       subi    digit, -'0'
+       cpi     digit, '9'+1
+       brlo    5f
+       subi    digit, '0'-'a'+10
+5:  ; ... and store it to the reversed string
+       st      Z+, digit
+
+    ; Popped all digits?
+       brtc    1b
+
+    ; Yes:  Store the sign (if any)
+       cpse    sign, __zero_reg__
+       st      Z+, sign
+
+    ; Terminate the string with '\0'
+7:     st      Z, __zero_reg__
+
+    ; Reverse the string and return the original string pointer
+       X_movw  r24, str_lo
+       XJMP    _U(strrev)
+
+ENDFUNC
+
+#endif /* !__AVR_TINY__ */
+#endif /* !__DOXYGEN__ */


Property changes on: trunk/avr-libc/libc/misc/ultoa_ncheck.S
___________________________________________________________________
Added: svn:keywords
   + Author Id Date

Modified: trunk/avr-libc/libc/misc/utoa.S
===================================================================
--- trunk/avr-libc/libc/misc/utoa.S     2012-06-19 06:56:49 UTC (rev 2297)
+++ trunk/avr-libc/libc/misc/utoa.S     2012-07-29 15:30:34 UTC (rev 2298)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2002, Reiner Patommel
+/* Copyright (c) 2012  Georg-Johann Lay
    All rights reserved.
 
    Redistribution and use in source and binary forms, with or without
@@ -26,74 +26,39 @@
   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   POSSIBILITY OF SUCH DAMAGE. */
 
-/* $Id$ */
+/* $Id$        */
 
-/*
-   utoa.S
+#if    !defined (__DOXYGEN__)
+#if    !defined (__AVR_TINY)
 
-   Contributors:
-   Created by Reiner Patommel based on
-   itoa.s by Michael Rickmann <address@hidden>
-   19 June 2003 changed by Reiner Patommel bug# 4010
+#include "asmdef.h"
 
-       #include <stdlib.h>
-       char *utoa(unsigned int value, char *string, int radix);
-  ----------------------------------------------------------------------
-*/
+/* char *utoa (unsigned val, char *s, int radix)
+   Commonly this program is't used, as the 'stdlib.h' obtains the inline
+   version of utoa() where radix is checked at compile time.
+ */
 
-#if !defined(__AVR_TINY__)
+#define val_lo r24
+#define str_lo r22
+#define rdx_lo r20
+#define rdx_hi r21
 
-#if !defined(__DOXYGEN__)
+ENTRY  utoa
+ENTRY  __utoa
 
-#include "macros.inc"
-#include "ctoasm.inc"
+       cpi     rdx_lo, 37
+       cpc     rdx_hi, __zero_reg__
+       brsh    1f
+       cpi     rdx_lo, 2
+       brlo    1f
+       XJMP    _U(__utoa_ncheck)
 
-    ASSEMBLY_CLIB_SECTION
-    .global _U(utoa)
-    .func _U(utoa)
+1:     X_movw  ZL, str_lo
+       st      Z, __zero_reg__
+       X_movw  r24, str_lo
+       ret
 
-/* arguments */
-#define r_val_hi r25
-#define r_val_lo r24
-#define r_str_hi r23
-#define r_str_lo r22
-#define r_radix  r20
+ENDFUNC
 
-/* local variables */
-#define r_lstr_hi r19
-#define r_lstr_lo r18
-
-
-
-_U(utoa):
-       X_movw  ZL, r_str_lo    ; &string
-       X_movw  r_lstr_lo, ZL   ; save &string
-       cpi     r_radix, 2      ; no radix < 2
-       brlt    99f
-       cpi     r_radix, 37     ; no radix > 36
-       brge    99f     
-1:
-       mov     r22, r_radix    ; radix
-       clr     r23             ;  dividend in r25:r24,   divisor in r23:r22
-       XCALL   _U(__udivmodhi4);  quotient in r23:r22, remainder in r25:r24
-                               ;  clobbered: r0, r21, r26, r27
-                               ;  call-used but preserved: r18,r19,r20,r30,r31
-       subi    r24, 0xd0       ; + '0'
-       cpi     r24, 0x3a       ; > '9' ?
-       brlt    10f
-       subi    r24, 0xd9       ; + 'a' - 10 - '0'
-10:
-       st      Z+, r24         ; write char to string in reverse order!
-       X_movw  r_val_lo,r22    ; quotient -> dividend
-       sbiw    r_val_lo,0      ; value == 0 ?
-       brne    1b
-99:
-       st      Z, __zero_reg__ ; terminate string
-       X_movw  r_val_lo, r_lstr_lo     ; restore &string as return value
-       XJMP    _U(strrev)      ; reverse string
-
-       .endfunc
-
-#endif /* not __DOXYGEN__ */
-
-#endif /* !defined(__AVR_TINY__) */
+#endif /* !__AVR_TINY__ */
+#endif /* !__DOXYGEN__ */

Added: trunk/avr-libc/libc/misc/utoa_ncheck.S
===================================================================
--- trunk/avr-libc/libc/misc/utoa_ncheck.S                              (rev 0)
+++ trunk/avr-libc/libc/misc/utoa_ncheck.S      2012-07-29 15:30:34 UTC (rev 
2298)
@@ -0,0 +1,97 @@
+/* Copyright (c) 2012  Georg-Johann Lay
+   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$        */
+
+#if    !defined (__DOXYGEN__)
+#if    !defined (__AVR_TINY)
+
+#include "asmdef.h"
+
+/* char *__utoa_ncheck (unsigned val, char *s, unsigned char radix)
+   This function is the utoa() without checking the radix for 2..36 margins.
+ */
+
+#define val_lo r24
+#define val_hi r25
+#define str_lo r22
+#define radix  r20
+
+#define counter        r21
+#define digit  r26
+#define sign   r27
+
+ENTRY  __utoa_ncheck
+       clr     sign
+
+ENTRY  __utoa_common
+       X_movw  ZL, str_lo
+       clr     counter
+
+1:  ; Vanilla 16:8 quotient and remainder to pop the digit
+    ; digit <- val % radix
+    ; val   <- val / radix
+       clr     digit
+
+2:     lsl     val_lo
+       rol     val_hi
+       rol     digit
+       cp      digit, radix
+       brlo    3f
+       sub     digit, radix
+       inc     val_lo
+3:     subi    counter, 16             ; 256 / 16 == 16 loops
+       brne    2b
+
+    ; Convert the digit to ASCII...
+       subi    digit, -'0'
+       cpi     digit, '9'+1
+       brlo    4f
+       subi    digit, '0'-'a'+10
+4:  ; ... and store it to the reversed string
+       st      Z+, digit
+
+    ; Iterate until all digits are sucked out of VAL.
+       sbiw    val_lo, 0
+       brne    1b
+
+    ; Store the sign (if any)
+       cpse    sign, __zero_reg__
+       st      Z+, sign
+
+    ; Terminate the string with '\0'
+       st      Z+, __zero_reg__
+
+    ; Reverse the string and return the original string pointer
+       X_movw  r24, str_lo
+       XJMP    _U(strrev)
+
+ENDFUNC
+
+#endif /* !__AVR_TINY__ */
+#endif /* !__DOXYGEN__ */


Property changes on: trunk/avr-libc/libc/misc/utoa_ncheck.S
___________________________________________________________________
Added: svn:keywords
   + Author Id Date

Added: trunk/avr-libc/tests/simulate/stdlib/itoa-1.c
===================================================================
--- trunk/avr-libc/tests/simulate/stdlib/itoa-1.c                               
(rev 0)
+++ trunk/avr-libc/tests/simulate/stdlib/itoa-1.c       2012-07-29 15:30:34 UTC 
(rev 2298)
@@ -0,0 +1,154 @@
+/* Copyright (c) 2012  Dmitry Xmelkov
+   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.
+ */
+
+/* Test of itoa() with all possible inline variants.
+   $Id$        */
+
+#include <stdlib.h>
+#include <string.h>
+#include "progmem.h"
+
+#ifndef        __AVR__
+# include <stdio.h>
+# define PRINTFLN(line, fmt, ...)      \
+    printf ("\n%s:%d: " fmt "\n", __FILE__, line, ##__VA_ARGS__);
+# define EXIT(code)    exit ((code) < 255 ? (code) : 100 + (code) % 100)
+#else
+# define PRINTFLN(args...)
+# define EXIT(code)    exit (code)
+#endif
+
+#ifndef        __AVR__
+static char *utoa_recursive (unsigned val, char *s, unsigned radix)
+{
+    int c;
+
+    if (val >= radix)
+       s = utoa_recursive (val / radix, s, radix);
+    c = val % radix;
+    c += (c < 10 ? '0' : 'a' - 10);
+    *s++ = c;
+    return s;
+}
+
+static char *itoa (int val, char *s, int radix)
+{
+    if (radix < 2 || radix > 36) {
+       s[0] = 0;
+    } else {
+       char *p = s;
+       if (radix == 10 && val < 0) {
+           val = -val;
+           *p++ = '-';
+       }
+       *utoa_recursive (val, p, radix) = 0;
+    }
+    return s;
+}
+#endif
+
+
+int main ()
+{
+    char s[40];
+    char *(* volatile fun)(int, char *, int);
+    volatile int rdx;
+
+    /* Inline function, possible call of __itoa_ncheck().      */
+
+    itoa (-12345, s, 10);
+    if (strcmp_P (s, PSTR ("-12345")))
+       EXIT (__LINE__);
+    itoa (35, s, 2);
+    if (strcmp_P (s, PSTR ("100011")))
+       EXIT (__LINE__);
+    itoa (35, s, 36);
+    if (strcmp_P (s, PSTR ("z")))
+       EXIT (__LINE__);
+
+    if (itoa (2, s, 1) != s || s[0])
+       EXIT (__LINE__);
+    s[0] = '2';
+    if (itoa (2, s, 37) != s || s[0])
+       EXIT (__LINE__);
+    s[0] = '2';
+    if (itoa (2, s, 0x0108) != s || s[0])
+       EXIT (__LINE__);
+
+    /* Library function, call of itoa().       */
+
+    fun = itoa;
+    fun (-12345, s, 10);
+    if (strcmp_P (s, PSTR ("-12345")))
+       EXIT (__LINE__);
+    fun (35, s, 2);
+    if (strcmp_P (s, PSTR ("100011")))
+       EXIT (__LINE__);
+    fun (35, s, 36);
+    if (strcmp_P (s, PSTR ("z")))
+       EXIT (__LINE__);
+
+    if (fun (2, s, 1) != s || s[0])
+       EXIT (__LINE__);
+    s[0] = '2';
+    if (fun (2, s, 37) != s || s[0])
+       EXIT (__LINE__);
+    s[0] = '2';
+    if (fun (2, s, 0x0108) != s || s[0])
+       EXIT (__LINE__);
+
+    /* Unknown radix, call of __itoa().        */
+
+    rdx = 10;
+    itoa (-12345, s, rdx);
+    if (strcmp_P (s, PSTR ("-12345")))
+       EXIT (__LINE__);
+    rdx = 2;
+    itoa (35, s, rdx);
+    if (strcmp_P (s, PSTR ("100011")))
+       EXIT (__LINE__);
+    rdx = 36;
+    itoa (35, s, rdx);
+    if (strcmp_P (s, PSTR ("z")))
+       EXIT (__LINE__);
+
+    rdx = 1;
+    if (itoa (2, s, rdx) != s || s[0])
+       EXIT (__LINE__);
+    rdx = 37;
+    s[0] = '2';
+    if (itoa (2, s, rdx) != s || s[0])
+       EXIT (__LINE__);
+    rdx = 0x0108;
+    s[0] = '2';
+    if (itoa (2, s, rdx) != s || s[0])
+       EXIT (__LINE__);
+
+    return 0;
+}


Property changes on: trunk/avr-libc/tests/simulate/stdlib/itoa-1.c
___________________________________________________________________
Added: svn:keywords
   + Author Id Date

Added: trunk/avr-libc/tests/simulate/stdlib/itoa-2.c
===================================================================
--- trunk/avr-libc/tests/simulate/stdlib/itoa-2.c                               
(rev 0)
+++ trunk/avr-libc/tests/simulate/stdlib/itoa-2.c       2012-07-29 15:30:34 UTC 
(rev 2298)
@@ -0,0 +1,143 @@
+/* Copyright (c) 2012  Dmitry Xmelkov
+   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.
+ */
+
+/* Test of itoa() function with patterns.
+   $Id$        */
+
+#include <stdlib.h>
+#include <string.h>
+#include "progmem.h"
+
+#ifndef        __AVR__
+# include <stdio.h>
+# define PRINTFLN(line, fmt, ...)      \
+    printf ("\n%s:%d: " fmt "\n", __FILE__, line, ##__VA_ARGS__);
+# define EXIT(code)    exit ((code) < 255 ? (code) : 100 + (code) % 100)
+#else
+# define PRINTFLN(args...)
+# define EXIT(code)    exit (code)
+#endif
+
+#ifndef        __AVR__
+static char *utoa_recursive (unsigned val, char *s, unsigned radix)
+{
+    int c;
+
+    if (val >= radix)
+       s = utoa_recursive (val / radix, s, radix);
+    c = val % radix;
+    c += (c < 10 ? '0' : 'a' - 10);
+    *s++ = c;
+    return s;
+}
+
+static char *itoa (int val, char *s, int radix)
+{
+    if (radix < 2 || radix > 36) {
+       s[0] = 0;
+    } else {
+       char *p = s;
+       if (radix == 10 && val < 0) {
+           val = -val;
+           *p++ = '-';
+       }
+       *utoa_recursive (val, p, radix) = 0;
+    }
+    return s;
+}
+#endif
+
+static void
+Check (int line, int val, const char *rslt, int radix)
+{
+    char s[40];
+
+#ifndef        __AVR__
+    if (radix >= 2 && radix <= 36) {
+       long x = strtol (rslt, 0, radix);
+       if (x != val) {
+           PRINTFLN (line, "strtol(\"%s\",,%d)= %ld,  val= %d",
+                     rslt, radix, x, val);
+           EXIT (2000 + line);
+       }
+    }
+#endif
+
+    memset (s, 0xff, sizeof (s) - 1);
+    s[sizeof (s) - 1] = 0;
+    if (itoa (val, s, radix) != s) {
+       PRINTFLN (line, "Incorrect result");
+       EXIT (1000 + line);
+    }
+
+    if (strcmp_P (s, rslt)) {
+       PRINTFLN (line, "itoa(%d,,%d) puts: %s, must: %s",
+                 val, radix, s, rslt);
+       EXIT (line);
+    }
+}
+
+#define CHECK(val, rslt, base) \
+    Check (__LINE__, val, PSTR (rslt), base)
+
+
+int main ()
+{
+    int i;
+
+    /* Invalid radix.  */
+    CHECK (0, "", 0);
+    CHECK (0, "", 1);
+    CHECK (0, "", 37);
+    CHECK (10, "", 0x0102);
+    CHECK (-256, "", -10);
+
+    /* Decimal negative.       */
+    CHECK (-1, "-1", 10);
+    CHECK (-255, "-255", 10);
+    CHECK (-256, "-256", 10);
+    CHECK (-257, "-257", 10);
+    CHECK (-32767, "-32767", 10);
+    CHECK (-32768, "-32768", 10);
+
+    /* Only radix == 10 is signed.     */
+    for (i = 2; i <= 36; i++) {
+       char s[40];
+       itoa (-1, s, i);
+       if (i == 10) {
+           if (s[0] != '-') exit (__LINE__);
+       } else {
+           if (s[0] == '-') exit (__LINE__);
+       }
+    }
+
+    CHECK (-12345, "-12345", 10);
+
+    return 0;
+}


Property changes on: trunk/avr-libc/tests/simulate/stdlib/itoa-2.c
___________________________________________________________________
Added: svn:keywords
   + Author Id Date

Added: trunk/avr-libc/tests/simulate/stdlib/ltoa-1.c
===================================================================
--- trunk/avr-libc/tests/simulate/stdlib/ltoa-1.c                               
(rev 0)
+++ trunk/avr-libc/tests/simulate/stdlib/ltoa-1.c       2012-07-29 15:30:34 UTC 
(rev 2298)
@@ -0,0 +1,154 @@
+/* Copyright (c) 2012  Dmitry Xmelkov
+   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.
+ */
+
+/* Test of ltoa() with all possible inline variants.
+   $Id$        */
+
+#include <stdlib.h>
+#include <string.h>
+#include "progmem.h"
+
+#ifndef        __AVR__
+# include <stdio.h>
+# define PRINTFLN(line, fmt, ...)      \
+    printf ("\n%s:%d: " fmt "\n", __FILE__, line, ##__VA_ARGS__);
+# define EXIT(code)    exit ((code) < 255 ? (code) : 100 + (code) % 100)
+#else
+# define PRINTFLN(args...)
+# define EXIT(code)    exit (code)
+#endif
+
+#ifndef        __AVR__
+static char *ultoa_recursive (unsigned long val, char *s, unsigned radix)
+{
+    int c;
+
+    if (val >= radix)
+       s = ultoa_recursive (val / radix, s, radix);
+    c = val % radix;
+    c += (c < 10 ? '0' : 'a' - 10);
+    *s++ = c;
+    return s;
+}
+
+static char *ltoa (long val, char *s, int radix)
+{
+    if (radix < 2 || radix > 36) {
+       s[0] = 0;
+    } else {
+       char *p = s;
+       if (radix == 10 && val < 0) {
+           val = -val;
+           *p++ = '-';
+       }
+       *ultoa_recursive (val, p, radix) = 0;
+    }
+    return s;
+}
+#endif
+
+
+int main ()
+{
+    char s[40];
+    char *(* volatile fun)(long, char *, int);
+    volatile int rdx;
+
+    /* Inline function, possible call of __ltoa_ncheck().      */
+
+    ltoa (-12345678, s, 10);
+    if (strcmp_P (s, PSTR ("-12345678")))
+       EXIT (__LINE__);
+    ltoa (35, s, 2);
+    if (strcmp_P (s, PSTR ("100011")))
+       EXIT (__LINE__);
+    ltoa (35, s, 36);
+    if (strcmp_P (s, PSTR ("z")))
+       EXIT (__LINE__);
+
+    if (ltoa (2, s, 1) != s || s[0])
+       EXIT (__LINE__);
+    s[0] = '2';
+    if (ltoa (2, s, 37) != s || s[0])
+       EXIT (__LINE__);
+    s[0] = '2';
+    if (ltoa (2, s, 0x0108) != s || s[0])
+       EXIT (__LINE__);
+
+    /* Library function, call of ltoa().       */
+
+    fun = ltoa;
+    fun (-12345678, s, 10);
+    if (strcmp_P (s, PSTR ("-12345678")))
+       EXIT (__LINE__);
+    fun (35, s, 2);
+    if (strcmp_P (s, PSTR ("100011")))
+       EXIT (__LINE__);
+    fun (35, s, 36);
+    if (strcmp_P (s, PSTR ("z")))
+       EXIT (__LINE__);
+
+    if (fun (2, s, 1) != s || s[0])
+       EXIT (__LINE__);
+    s[0] = '2';
+    if (fun (2, s, 37) != s || s[0])
+       EXIT (__LINE__);
+    s[0] = '2';
+    if (fun (2, s, 0x0108) != s || s[0])
+       EXIT (__LINE__);
+
+    /* Unknown radix, call of __ltoa().        */
+
+    rdx = 10;
+    ltoa (-12345678, s, rdx);
+    if (strcmp_P (s, PSTR ("-12345678")))
+       EXIT (__LINE__);
+    rdx = 2;
+    ltoa (35, s, rdx);
+    if (strcmp_P (s, PSTR ("100011")))
+       EXIT (__LINE__);
+    rdx = 36;
+    ltoa (35, s, rdx);
+    if (strcmp_P (s, PSTR ("z")))
+       EXIT (__LINE__);
+
+    rdx = 1;
+    if (ltoa (2, s, rdx) != s || s[0])
+       EXIT (__LINE__);
+    rdx = 37;
+    s[0] = '2';
+    if (ltoa (2, s, rdx) != s || s[0])
+       EXIT (__LINE__);
+    rdx = 0x0108;
+    s[0] = '2';
+    if (ltoa (2, s, rdx) != s || s[0])
+       EXIT (__LINE__);
+
+    return 0;
+}


Property changes on: trunk/avr-libc/tests/simulate/stdlib/ltoa-1.c
___________________________________________________________________
Added: svn:keywords
   + Author Id Date

Added: trunk/avr-libc/tests/simulate/stdlib/ltoa-2.c
===================================================================
--- trunk/avr-libc/tests/simulate/stdlib/ltoa-2.c                               
(rev 0)
+++ trunk/avr-libc/tests/simulate/stdlib/ltoa-2.c       2012-07-29 15:30:34 UTC 
(rev 2298)
@@ -0,0 +1,149 @@
+/* Copyright (c) 2012  Dmitry Xmelkov
+   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.
+ */
+
+/* Test of ltoa() function with patterns.
+   $Id$        */
+
+#include <stdlib.h>
+#include <string.h>
+#include "progmem.h"
+
+#ifndef        __AVR__
+# include <stdio.h>
+# define PRINTFLN(line, fmt, ...)      \
+    printf ("\n%s:%d: " fmt "\n", __FILE__, line, ##__VA_ARGS__);
+# define EXIT(code)    exit ((code) < 255 ? (code) : 100 + (code) % 100)
+#else
+# define PRINTFLN(args...)
+# define EXIT(code)    exit (code)
+#endif
+
+#ifndef        __AVR__
+static char *ultoa_recursive (unsigned long val, char *s, unsigned radix)
+{
+    int c;
+
+    if (val >= radix)
+       s = ultoa_recursive (val / radix, s, radix);
+    c = val % radix;
+    c += (c < 10 ? '0' : 'a' - 10);
+    *s++ = c;
+    return s;
+}
+
+static char *ltoa (long val, char *s, int radix)
+{
+    if (radix < 2 || radix > 36) {
+       s[0] = 0;
+    } else {
+       char *p = s;
+       if (radix == 10 && val < 0) {
+           val = -val;
+           *p++ = '-';
+       }
+       *ultoa_recursive (val, p, radix) = 0;
+    }
+    return s;
+}
+#endif
+
+static void
+Check (int line, long val, const char *rslt, int radix)
+{
+    char s[40];
+
+#ifndef        __AVR__
+    if (radix >= 2 && radix <= 36) {
+       long x = strtol (rslt, 0, radix);
+       if (x != val) {
+           PRINTFLN (line, "strtol(\"%s\",,%d)= %ld,  val= %ld",
+                     rslt, radix, x, val);
+           EXIT (2000 + line);
+       }
+    }
+#endif
+
+    memset (s, 0xff, sizeof (s) - 1);
+    s[sizeof (s) - 1] = 0;
+    if (ltoa (val, s, radix) != s) {
+       PRINTFLN (line, "Incorrect result");
+       EXIT (1000 + line);
+    }
+
+    if (strcmp_P (s, rslt)) {
+       PRINTFLN (line, "ltoa(%ld,,%d) puts: %s, must: %s",
+                 val, radix, s, rslt);
+       EXIT (line);
+    }
+}
+
+#define CHECK(val, rslt, base) \
+    Check (__LINE__, val, PSTR (rslt), base)
+
+
+int main ()
+{
+    int i;
+
+    /* Invalid radix.  */
+    CHECK (0, "", 0);
+    CHECK (0, "", 1);
+    CHECK (0, "", 37);
+    CHECK (10, "", 0x0102);
+    CHECK (-256, "", -10);
+
+    /* Decimal negative.       */
+    CHECK (-1, "-1", 10);
+    CHECK (-255, "-255", 10);
+    CHECK (-256, "-256", 10);
+    CHECK (-257, "-257", 10);
+    CHECK (-65535, "-65535", 10);
+    CHECK (-65536, "-65536", 10);
+    CHECK (-65537, "-65537", 10);
+    CHECK (-16777215, "-16777215", 10);
+    CHECK (-16777216, "-16777216", 10);
+    CHECK (-16777217, "-16777217", 10);
+    CHECK (-2147483647, "-2147483647", 10);
+    CHECK (-2147483648, "-2147483648", 10);
+
+    /* Only radix == 10 is signed.     */
+    for (i = 2; i <= 36; i++) {
+       char s[40];
+       ltoa (-1, s, i);
+       if (i == 10) {
+           if (s[0] != '-') exit (__LINE__);
+       } else {
+           if (s[0] == '-') exit (__LINE__);
+       }
+    }
+
+    CHECK (-123456789, "-123456789", 10);
+
+    return 0;
+}


Property changes on: trunk/avr-libc/tests/simulate/stdlib/ltoa-2.c
___________________________________________________________________
Added: svn:keywords
   + Author Id Date

Added: trunk/avr-libc/tests/simulate/stdlib/ultoa-1.c
===================================================================
--- trunk/avr-libc/tests/simulate/stdlib/ultoa-1.c                              
(rev 0)
+++ trunk/avr-libc/tests/simulate/stdlib/ultoa-1.c      2012-07-29 15:30:34 UTC 
(rev 2298)
@@ -0,0 +1,148 @@
+/* Copyright (c) 2012  Dmitry Xmelkov
+   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.
+ */
+
+/* Test of ultoa() with all possible inline variants.
+   $Id$        */
+
+#include <stdlib.h>
+#include <string.h>
+#include "progmem.h"
+
+#ifndef        __AVR__
+# include <stdio.h>
+# define PRINTFLN(line, fmt, ...)      \
+    printf ("\n%s:%d: " fmt "\n", __FILE__, line, ##__VA_ARGS__);
+# define EXIT(code)    exit ((code) < 255 ? (code) : 100 + (code) % 100)
+#else
+# define PRINTFLN(args...)
+# define EXIT(code)    exit (code)
+#endif
+
+#ifndef        __AVR__
+static char *ultoa_recursive (unsigned long val, char *s, unsigned radix)
+{
+    int c;
+
+    if (val >= radix)
+       s = ultoa_recursive (val / radix, s, radix);
+    c = val % radix;
+    c += (c < 10 ? '0' : 'a' - 10);
+    *s++ = c;
+    return s;
+}
+
+static char *ultoa (unsigned long val, char *s, int radix)
+{
+    if (radix < 2 || radix > 36)
+       s[0] = 0;
+    else
+       *ultoa_recursive (val, s, radix) = 0;
+    return s;
+}
+#endif
+
+
+int main ()
+{
+    char s[40];
+    char *(* volatile fun)(unsigned long, char *, int);
+    volatile int rdx;
+
+    /* Inline function, possible call of __ltoa_ncheck().      */
+
+    ultoa (4000999000, s, 10);
+    if (strcmp_P (s, PSTR ("4000999000")))
+       EXIT (__LINE__);
+    ultoa (35, s, 2);
+    if (strcmp_P (s, PSTR ("100011")))
+       EXIT (__LINE__);
+    ultoa (35, s, 36);
+    if (strcmp_P (s, PSTR ("z")))
+       EXIT (__LINE__);
+
+    if (ultoa (2, s, 1) != s || s[0])
+       EXIT (__LINE__);
+    s[0] = '2';
+    if (ultoa (2, s, 37) != s || s[0])
+       EXIT (__LINE__);
+    s[0] = '2';
+    if (ultoa (2, s, 0x0108) != s || s[0])
+       EXIT (__LINE__);
+
+    /* Library function, call of ultoa().      */
+
+    fun = ultoa;
+    fun (4000999000, s, 10);
+    if (strcmp_P (s, PSTR ("4000999000")))
+       EXIT (__LINE__);
+    fun (35, s, 2);
+    if (strcmp_P (s, PSTR ("100011")))
+       EXIT (__LINE__);
+    fun (35, s, 36);
+    if (strcmp_P (s, PSTR ("z")))
+       EXIT (__LINE__);
+
+    if (fun (2, s, 1) != s || s[0])
+       EXIT (__LINE__);
+    s[0] = '2';
+    if (fun (2, s, 37) != s || s[0])
+       EXIT (__LINE__);
+    s[0] = '2';
+    if (fun (2, s, 0x0108) != s || s[0])
+       EXIT (__LINE__);
+
+    /* Unknown radix, call of __ultoa().       */
+
+    rdx = 10;
+    ultoa (4000999000, s, rdx);
+    if (strcmp_P (s, PSTR ("4000999000")))
+       EXIT (__LINE__);
+    rdx = 2;
+    ultoa (35, s, rdx);
+    if (strcmp_P (s, PSTR ("100011")))
+       EXIT (__LINE__);
+    rdx = 36;
+    ultoa (35, s, rdx);
+    if (strcmp_P (s, PSTR ("z")))
+       EXIT (__LINE__);
+
+    rdx = 1;
+    if (ultoa (2, s, rdx) != s || s[0])
+       EXIT (__LINE__);
+    rdx = 37;
+    s[0] = '2';
+    if (ultoa (2, s, rdx) != s || s[0])
+       EXIT (__LINE__);
+    rdx = 0x0108;
+    s[0] = '2';
+    if (ultoa (2, s, rdx) != s || s[0])
+       EXIT (__LINE__);
+
+    return 0;
+}


Property changes on: trunk/avr-libc/tests/simulate/stdlib/ultoa-1.c
___________________________________________________________________
Added: svn:keywords
   + Author Id Date

Added: trunk/avr-libc/tests/simulate/stdlib/ultoa-2.c
===================================================================
--- trunk/avr-libc/tests/simulate/stdlib/ultoa-2.c                              
(rev 0)
+++ trunk/avr-libc/tests/simulate/stdlib/ultoa-2.c      2012-07-29 15:30:34 UTC 
(rev 2298)
@@ -0,0 +1,224 @@
+/* Copyright (c) 2012  Dmitry Xmelkov
+   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.
+ */
+
+/* Test of ultoa() with patterns.
+   $Id$        */
+
+#include <stdlib.h>
+#include <string.h>
+#include "progmem.h"
+
+#ifndef        __AVR__
+# include <stdio.h>
+# define PRINTFLN(line, fmt, ...)      \
+    printf ("\n%s:%d: " fmt "\n", __FILE__, line, ##__VA_ARGS__);
+# define EXIT(code)    exit ((code) < 255 ? (code) : 100 + (code) % 100)
+#else
+# define PRINTFLN(args...)
+# define EXIT(code)    exit (code)
+#endif
+
+#ifndef        __AVR__
+static char *ultoa_recursive (unsigned long val, char *s, unsigned radix)
+{
+    int c;
+
+    if (val >= radix)
+       s = ultoa_recursive (val / radix, s, radix);
+    c = val % radix;
+    c += (c < 10 ? '0' : 'a' - 10);
+    *s++ = c;
+    return s;
+}
+
+static char *ultoa (unsigned long val, char *s, int radix)
+{
+    if (radix < 2 || radix > 36)
+       s[0] = 0;
+    else
+       *ultoa_recursive (val, s, radix) = 0;
+    return s;
+}
+#endif
+
+static void
+Check (int line, unsigned long val, const char *rslt, int radix)
+{
+    char s[40];
+
+#ifndef        __AVR__
+    if (radix >= 2 && radix <= 36) {
+       unsigned long x = strtoul (rslt, 0, radix);
+       if (x != val) {
+           PRINTFLN (line, "strtoul(\"%s\",,%d)= %lu,  val= %lu",
+                     rslt, radix, x, val);
+           EXIT (2000 + line);
+       }
+    }
+#endif
+
+    memset (s, 0xff, sizeof (s) - 1);
+    s[sizeof (s) - 1] = 0;
+    if (ultoa (val, s, radix) != s) {
+       PRINTFLN (line, "Incorrect result");
+       EXIT (1000 + line);
+    }
+
+    if (strcmp_P (s, rslt)) {
+       PRINTFLN (line, "ultoa(%lu,,%d) puts: %s, must: %s",
+                 val, radix, s, rslt);
+       EXIT (line);
+    }
+}
+
+#define CHECK(val, rslt, base) \
+    Check (__LINE__, val, PSTR (rslt), base)
+
+
+int main ()
+{
+    int i;
+
+    /* Invalid radix.  */
+    CHECK (0, "", 0);
+    CHECK (0, "", 1);
+    CHECK (0, "", 37);
+    CHECK (10, "", 0x0102);
+    CHECK (256, "", 0x8008);
+
+    /* Radix-independent results.      */
+    for (i = 2; i <= 36; i++) {
+       unsigned long x;
+
+       CHECK (0, "0", i);
+       CHECK (1, "1", i);
+
+       CHECK (i, "10", i);
+       CHECK (i + 1, "11", i);
+
+       x = i * i;
+       CHECK (x, "100", i);
+       CHECK (x + 1, "101", i);
+       CHECK (x + i, "110", i);
+       CHECK (x + i + 1, "111", i);
+
+       x *= i;
+       CHECK (x, "1000", i);
+       x *= i;
+       CHECK (x, "10000", i);
+       x *= i;
+       CHECK (x, "100000", i);
+    }
+
+    CHECK (0xfe, "11111110", 2);
+    CHECK (0xfe, "254", 10);
+    CHECK (0xfe, "211", 11);
+    CHECK (0xfe, "72", 36);
+
+    CHECK (0xff, "11111111", 2);
+    CHECK (0xff, "255", 10);
+    CHECK (0xff, "212", 11);
+    CHECK (0xff, "73", 36);
+
+    CHECK (0x100, "100000000", 2);
+    CHECK (0x100, "256", 10);
+    CHECK (0x100, "213", 11);
+    CHECK (0x100, "74", 36);
+
+    CHECK (0x101, "100000001", 2);
+    CHECK (0x101, "257", 10);
+    CHECK (0x101, "214", 11);
+    CHECK (0x101, "75", 36);
+
+    CHECK (0xfffe, "1111111111111110", 2);
+    CHECK (0xfffe, "65534", 10);
+    CHECK (0xfffe, "45267", 11);
+    CHECK (0xfffe, "1eke", 36);
+
+    CHECK (0xffff, "1111111111111111", 2);
+    CHECK (0xffff, "65535", 10);
+    CHECK (0xffff, "45268", 11);
+    CHECK (0xffff, "1ekf", 36);
+
+    CHECK (0x10000, "10000000000000000", 2);
+    CHECK (0x10000, "65536", 10);
+    CHECK (0x10000, "45269", 11);
+    CHECK (0x10000, "1ekg", 36);
+
+    CHECK (0x10001, "10000000000000001", 2);
+    CHECK (0x10001, "65537", 10);
+    CHECK (0x10001, "4526a", 11);
+    CHECK (0x10001, "1ekh", 36);
+
+    CHECK (0xfffffe, "111111111111111111111110", 2);
+    CHECK (0xfffffe, "16777214", 10);
+    CHECK (0xfffffe, "9519a73", 11);
+    CHECK (0xfffffe, "9zldq", 36);
+
+    CHECK (0xffffff, "111111111111111111111111", 2);
+    CHECK (0xffffff, "16777215", 10);
+    CHECK (0xffffff, "9519a74", 11);
+    CHECK (0xffffff, "9zldr", 36);
+
+    CHECK (0x1000000, "1000000000000000000000000", 2);
+    CHECK (0x1000000, "16777216", 10);
+    CHECK (0x1000000, "9519a75", 11);
+    CHECK (0x1000000, "9zlds", 36);
+
+    CHECK (0x1000001, "1000000000000000000000001", 2);
+    CHECK (0x1000001, "16777217", 10);
+    CHECK (0x1000001, "9519a76", 11);
+    CHECK (0x1000001, "9zldt", 36);
+
+    CHECK (0xfffffffe, "11111111111111111111111111111110", 2);
+    CHECK (0xfffffffe, "37777777776", 8);
+    CHECK (0xfffffffe, "4294967294", 10);
+    CHECK (0xfffffffe, "1904440552", 11);
+    CHECK (0xfffffffe, "fffffffe", 16);
+    CHECK (0xfffffffe, "1z141z2", 36);
+
+    CHECK (0xffffffff, "11111111111111111111111111111111", 2);
+    CHECK (0xffffffff, "37777777777", 8);
+    CHECK (0xffffffff, "4294967295", 10);
+    CHECK (0xffffffff, "1904440553", 11);
+    CHECK (0xffffffff, "ffffffff", 16);
+    CHECK (0xffffffff, "1z141z3", 36);
+
+    CHECK (10, "a", 11);
+    CHECK (35, "z", 36);
+
+    CHECK (01234567, "1234567", 8);
+    CHECK (07654321, "7654321", 8);
+    CHECK (123456789, "123456789", 10);
+    CHECK (987654321, "987654321", 10);
+    CHECK (0x89ABCDEF, "89abcdef", 16);
+    CHECK (0xFEDCBA98, "fedcba98", 16);
+
+    return 0;
+}


Property changes on: trunk/avr-libc/tests/simulate/stdlib/ultoa-2.c
___________________________________________________________________
Added: svn:keywords
   + Author Id Date

Added: trunk/avr-libc/tests/simulate/stdlib/ultoa-3.c
===================================================================
--- trunk/avr-libc/tests/simulate/stdlib/ultoa-3.c                              
(rev 0)
+++ trunk/avr-libc/tests/simulate/stdlib/ultoa-3.c      2012-07-29 15:30:34 UTC 
(rev 2298)
@@ -0,0 +1,157 @@
+/* Copyright (c) 2012  Dmitry Xmelkov
+   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.
+ */
+
+/* Test of ultoa() function with strtoul() usage.
+   $Id$        */
+
+#include <stdlib.h>
+#include <string.h>
+#include "progmem.h"
+
+#ifndef        __AVR__
+# include <stdio.h>
+# define PRINTFLN(line, fmt, ...)      \
+    printf ("\n%s:%d: " fmt "\n", __FILE__, line, ##__VA_ARGS__);
+# define EXIT(code)    exit ((code) < 255 ? (code) : 100 + (code) % 100)
+#else
+# define PRINTFLN(args...)
+# define EXIT(code)    exit (code)
+#endif
+
+#ifndef        __AVR__
+static char *ultoa_recursive (unsigned long val, char *s, unsigned radix)
+{
+    int c;
+
+    if (val >= radix)
+       s = ultoa_recursive (val / radix, s, radix);
+    c = val % radix;
+    c += (c < 10 ? '0' : 'a' - 10);
+    *s++ = c;
+    return s;
+}
+
+static char *ultoa (unsigned long val, char *s, int radix)
+{
+    if (radix < 2 || radix > 36)
+       s[0] = 0;
+    else
+       *ultoa_recursive (val, s, radix) = 0;
+    return s;
+}
+#endif
+
+static void
+Check (int line, unsigned long val, int radix)
+{
+    char s[40], *p;
+    unsigned long x;
+
+    memset (s, 0xff, sizeof (s) - 1);
+    s[sizeof (s) - 1] = 0;
+    if (ultoa (val, s, radix) != s) {
+       PRINTFLN (line, "Incorrect result");
+       EXIT (1000 + line);
+    }
+
+    x = strtoul (s, &p, radix);
+    if (x != val) {
+       PRINTFLN (line, "strtoul (ultoa (%lu,s,%d)) = %lu", val, radix, x);
+       EXIT (line);
+    }
+
+    if (p != s + strlen (s)) {
+       PRINTFLN (line, "Invalid character");
+       EXIT (line);
+    }
+}
+
+#define CHECK(val, base)       Check (__LINE__, val, base)
+
+
+int main ()
+{
+    int i;
+    int radix;
+
+    for (radix = 2; radix <= 36; radix++) {
+       int n;
+
+       CHECK (0x55555555, radix);
+       CHECK (0xaaaaaaaa, radix);
+
+       for (i = 0; i < 32; i++) {
+           CHECK (1uL << i, radix);
+           CHECK (~0uL << i, radix);
+       }
+
+       for (i = 0; i < 31; i++) {
+           CHECK (3uL << i, radix);
+           CHECK (~3uL << i, radix);
+       }
+
+       for (i = 0; i < 30; i++) {
+           CHECK (7uL << i, radix);
+           CHECK (~7uL << i, radix);
+       }
+
+       for (i = 0; i < 29; i++) {
+           CHECK (017uL << i, radix);
+           CHECK (~017uL << i, radix);
+       }
+
+       for (i = 0; i < 28; i++) {
+           CHECK (037uL << i, radix);
+           CHECK (~037uL << i, radix);
+       }
+
+       for (i = 0; i < 27; i++) {
+           CHECK (077uL << i, radix);
+           CHECK (~077uL << i, radix);
+       }
+
+       for (i = 0; i < 26; i++) {
+           CHECK (0177uL << i, radix);
+           CHECK (~0177uL << i, radix);
+       }
+
+       for (i = 0; i < 25; i++) {
+           CHECK (0377uL << i, radix);
+           CHECK (~0377uL << i, radix);
+       }
+
+       n = radix*radix;
+       for (i = 5; i <= n; i++) {
+           CHECK (i, radix);
+           CHECK (-i, radix);
+       }
+    }
+
+    return 0;
+}


Property changes on: trunk/avr-libc/tests/simulate/stdlib/ultoa-3.c
___________________________________________________________________
Added: svn:keywords
   + Author Id Date

Added: trunk/avr-libc/tests/simulate/stdlib/utoa-1.c
===================================================================
--- trunk/avr-libc/tests/simulate/stdlib/utoa-1.c                               
(rev 0)
+++ trunk/avr-libc/tests/simulate/stdlib/utoa-1.c       2012-07-29 15:30:34 UTC 
(rev 2298)
@@ -0,0 +1,148 @@
+/* Copyright (c) 2012  Dmitry Xmelkov
+   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.
+ */
+
+/* Test of utoa() with all possible inline variants.
+   $Id$        */
+
+#include <stdlib.h>
+#include <string.h>
+#include "progmem.h"
+
+#ifndef        __AVR__
+# include <stdio.h>
+# define PRINTFLN(line, fmt, ...)      \
+    printf ("\n%s:%d: " fmt "\n", __FILE__, line, ##__VA_ARGS__);
+# define EXIT(code)    exit ((code) < 255 ? (code) : 100 + (code) % 100)
+#else
+# define PRINTFLN(args...)
+# define EXIT(code)    exit (code)
+#endif
+
+#ifndef        __AVR__
+static char *utoa_recursive (unsigned val, char *s, unsigned radix)
+{
+    int c;
+
+    if (val >= radix)
+       s = utoa_recursive (val / radix, s, radix);
+    c = val % radix;
+    c += (c < 10 ? '0' : 'a' - 10);
+    *s++ = c;
+    return s;
+}
+
+static char *utoa (unsigned val, char *s, int radix)
+{
+    if (radix < 2 || radix > 36)
+       s[0] = 0;
+    else
+       *utoa_recursive (val, s, radix) = 0;
+    return s;
+}
+#endif
+
+
+int main ()
+{
+    char s[40];
+    char *(* volatile fun)(unsigned, char *, int);
+    volatile int rdx;
+
+    /* Inline function, possible call of __ltoa_ncheck().      */
+
+    utoa (60000, s, 10);
+    if (strcmp_P (s, PSTR ("60000")))
+       EXIT (__LINE__);
+    utoa (35, s, 2);
+    if (strcmp_P (s, PSTR ("100011")))
+       EXIT (__LINE__);
+    utoa (35, s, 36);
+    if (strcmp_P (s, PSTR ("z")))
+       EXIT (__LINE__);
+
+    if (utoa (2, s, 1) != s || s[0])
+       EXIT (__LINE__);
+    s[0] = '2';
+    if (utoa (2, s, 37) != s || s[0])
+       EXIT (__LINE__);
+    s[0] = '2';
+    if (utoa (2, s, 0x0108) != s || s[0])
+       EXIT (__LINE__);
+
+    /* Library function, call of utoa().       */
+
+    fun = utoa;
+    fun (60000, s, 10);
+    if (strcmp_P (s, PSTR ("60000")))
+       EXIT (__LINE__);
+    fun (35, s, 2);
+    if (strcmp_P (s, PSTR ("100011")))
+       EXIT (__LINE__);
+    fun (35, s, 36);
+    if (strcmp_P (s, PSTR ("z")))
+       EXIT (__LINE__);
+
+    if (fun (2, s, 1) != s || s[0])
+       EXIT (__LINE__);
+    s[0] = '2';
+    if (fun (2, s, 37) != s || s[0])
+       EXIT (__LINE__);
+    s[0] = '2';
+    if (fun (2, s, 0x0108) != s || s[0])
+       EXIT (__LINE__);
+
+    /* Unknown radix, call of __utoa().        */
+
+    rdx = 10;
+    utoa (60000, s, rdx);
+    if (strcmp_P (s, PSTR ("60000")))
+       EXIT (__LINE__);
+    rdx = 2;
+    utoa (35, s, rdx);
+    if (strcmp_P (s, PSTR ("100011")))
+       EXIT (__LINE__);
+    rdx = 36;
+    utoa (35, s, rdx);
+    if (strcmp_P (s, PSTR ("z")))
+       EXIT (__LINE__);
+
+    rdx = 1;
+    if (utoa (2, s, rdx) != s || s[0])
+       EXIT (__LINE__);
+    rdx = 37;
+    s[0] = '2';
+    if (utoa (2, s, rdx) != s || s[0])
+       EXIT (__LINE__);
+    rdx = 0x0108;
+    s[0] = '2';
+    if (utoa (2, s, rdx) != s || s[0])
+       EXIT (__LINE__);
+
+    return 0;
+}


Property changes on: trunk/avr-libc/tests/simulate/stdlib/utoa-1.c
___________________________________________________________________
Added: svn:keywords
   + Author Id Date

Added: trunk/avr-libc/tests/simulate/stdlib/utoa-2.c
===================================================================
--- trunk/avr-libc/tests/simulate/stdlib/utoa-2.c                               
(rev 0)
+++ trunk/avr-libc/tests/simulate/stdlib/utoa-2.c       2012-07-29 15:30:34 UTC 
(rev 2298)
@@ -0,0 +1,180 @@
+/* Copyright (c) 2012  Dmitry Xmelkov
+   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.
+ */
+
+/* Test of utoa() with patterns.
+   $Id$        */
+
+#include <stdlib.h>
+#include <string.h>
+#include "progmem.h"
+
+#ifndef        __AVR__
+# include <stdio.h>
+# define PRINTFLN(line, fmt, ...)      \
+    printf ("\n%s:%d: " fmt "\n", __FILE__, line, ##__VA_ARGS__);
+# define EXIT(code)    exit ((code) < 255 ? (code) : 100 + (code) % 100)
+#else
+# define PRINTFLN(args...)
+# define EXIT(code)    exit (code)
+#endif
+
+#ifndef        __AVR__
+static char *utoa_recursive (unsigned val, char *s, unsigned radix)
+{
+    int c;
+
+    if (val >= radix)
+       s = utoa_recursive (val / radix, s, radix);
+    c = val % radix;
+    c += (c < 10 ? '0' : 'a' - 10);
+    *s++ = c;
+    return s;
+}
+
+static char *utoa (unsigned val, char *s, int radix)
+{
+    if (radix < 2 || radix > 36)
+       s[0] = 0;
+    else
+       *utoa_recursive (val, s, radix) = 0;
+    return s;
+}
+#endif
+
+static void
+Check (int line, unsigned val, const char *rslt, int radix)
+{
+    char s[40];
+
+#ifndef        __AVR__
+    if (radix >= 2 && radix <= 36) {
+       unsigned long x = strtoul (rslt, 0, radix);
+       if (x != val) {
+           PRINTFLN (line, "strtoul(\"%s\",,%d)= %lu,  val= %u",
+                     rslt, radix, x, val);
+           EXIT (2000 + line);
+       }
+    }
+#endif
+
+    memset (s, 0xff, sizeof (s) - 1);
+    s[sizeof (s) - 1] = 0;
+    if (utoa (val, s, radix) != s) {
+       PRINTFLN (line, "Incorrect result");
+       EXIT (1000 + line);
+    }
+
+    if (strcmp_P (s, rslt)) {
+       PRINTFLN (line, "utoa(%u,,%d) puts: %s, must: %s",
+                 val, radix, s, rslt);
+       EXIT (line);
+    }
+}
+
+#define CHECK(val, rslt, base) \
+    Check (__LINE__, val, PSTR (rslt), base)
+
+
+int main ()
+{
+    int i;
+
+    /* Invalid radix.  */
+    CHECK (0, "", 0);
+    CHECK (0, "", 1);
+    CHECK (0, "", 37);
+    CHECK (10, "", 0x0102);
+    CHECK (256, "", 0x8008);
+
+    /* Radix-independent results.      */
+    for (i = 2; i <= 36; i++) {
+       unsigned long x;
+
+       CHECK (0, "0", i);
+       CHECK (1, "1", i);
+
+       CHECK (i, "10", i);
+       CHECK (i + 1, "11", i);
+
+       x = i * i;
+       CHECK (x, "100", i);
+       CHECK (x + 1, "101", i);
+       CHECK (x + i, "110", i);
+       CHECK (x + i + 1, "111", i);
+
+       x *= i;
+       CHECK (x, "1000", i);
+       CHECK (x + 1, "1001", i);
+       CHECK (x + i, "1010", i);
+       CHECK (x + i + 1, "1011", i);
+       CHECK (x + i*i + i + 1, "1111", i);
+    }
+
+    CHECK (0xfe, "11111110", 2);
+    CHECK (0xfe, "254", 10);
+    CHECK (0xfe, "211", 11);
+    CHECK (0xfe, "72", 36);
+
+    CHECK (0xff, "11111111", 2);
+    CHECK (0xff, "255", 10);
+    CHECK (0xff, "212", 11);
+    CHECK (0xff, "73", 36);
+
+    CHECK (0x100, "100000000", 2);
+    CHECK (0x100, "256", 10);
+    CHECK (0x100, "213", 11);
+    CHECK (0x100, "74", 36);
+
+    CHECK (0x101, "100000001", 2);
+    CHECK (0x101, "257", 10);
+    CHECK (0x101, "214", 11);
+    CHECK (0x101, "75", 36);
+
+    CHECK (0xfffe, "1111111111111110", 2);
+    CHECK (0xfffe, "65534", 10);
+    CHECK (0xfffe, "45267", 11);
+    CHECK (0xfffe, "1eke", 36);
+
+    CHECK (0xffff, "1111111111111111", 2);
+    CHECK (0xffff, "65535", 10);
+    CHECK (0xffff, "45268", 11);
+    CHECK (0xffff, "1ekf", 36);
+
+    CHECK (10, "a", 11);
+    CHECK (35, "z", 36);
+
+    CHECK (0123456, "123456", 8);
+    CHECK (076543, "76543", 8);
+    CHECK (12345, "12345", 10);
+    CHECK (9876, "9876", 10);
+    CHECK (0x89AB, "89ab", 16);
+    CHECK (0xFEDC, "fedc", 16);
+
+    return 0;
+}


Property changes on: trunk/avr-libc/tests/simulate/stdlib/utoa-2.c
___________________________________________________________________
Added: svn:keywords
   + Author Id Date

Added: trunk/avr-libc/tests/simulate/stdlib/utoa-3.c
===================================================================
--- trunk/avr-libc/tests/simulate/stdlib/utoa-3.c                               
(rev 0)
+++ trunk/avr-libc/tests/simulate/stdlib/utoa-3.c       2012-07-29 15:30:34 UTC 
(rev 2298)
@@ -0,0 +1,157 @@
+/* Copyright (c) 2012  Dmitry Xmelkov
+   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.
+ */
+
+/* Test of utoa() function with strtoul() usage.
+   $Id$        */
+
+#include <stdlib.h>
+#include <string.h>
+#include "progmem.h"
+
+#ifndef        __AVR__
+# include <stdio.h>
+# define PRINTFLN(line, fmt, ...)      \
+    printf ("\n%s:%d: " fmt "\n", __FILE__, line, ##__VA_ARGS__);
+# define EXIT(code)    exit ((code) < 255 ? (code) : 100 + (code) % 100)
+#else
+# define PRINTFLN(args...)
+# define EXIT(code)    exit (code)
+#endif
+
+#ifndef        __AVR__
+static char *utoa_recursive (unsigned val, char *s, unsigned radix)
+{
+    int c;
+
+    if (val >= radix)
+       s = utoa_recursive (val / radix, s, radix);
+    c = val % radix;
+    c += (c < 10 ? '0' : 'a' - 10);
+    *s++ = c;
+    return s;
+}
+
+static char *utoa (unsigned val, char *s, int radix)
+{
+    if (radix < 2 || radix > 36)
+       s[0] = 0;
+    else
+       *utoa_recursive (val, s, radix) = 0;
+    return s;
+}
+#endif
+
+static void
+Check (int line, unsigned val, int radix)
+{
+    char s[40], *p;
+    unsigned long x;
+
+    memset (s, 0xff, sizeof (s) - 1);
+    s[sizeof (s) - 1] = 0;
+    if (utoa (val, s, radix) != s) {
+       PRINTFLN (line, "Incorrect result");
+       EXIT (1000 + line);
+    }
+
+    x = strtoul (s, &p, radix);
+    if (x != val) {
+       PRINTFLN (line, "strtoul (utoa (%u,s,%d)) = %lu", val, radix, x);
+       EXIT (line);
+    }
+
+    if (p != s + strlen (s)) {
+       PRINTFLN (line, "Invalid character");
+       EXIT (line);
+    }
+}
+
+#define CHECK(val, base)       Check (__LINE__, val, base)
+
+
+int main ()
+{
+    int i;
+    int radix;
+
+    for (radix = 2; radix <= 36; radix++) {
+       int n;
+
+       CHECK (0x5555, radix);
+       CHECK (0xaaaa, radix);
+
+       for (i = 0; i < 16; i++) {
+           CHECK (1 << i, radix);
+           CHECK (~0 << i, radix);
+       }
+
+       for (i = 0; i < 15; i++) {
+           CHECK (3 << i, radix);
+           CHECK (~3 << i, radix);
+       }
+
+       for (i = 0; i < 14; i++) {
+           CHECK (7 << i, radix);
+           CHECK (~7 << i, radix);
+       }
+
+       for (i = 0; i < 13; i++) {
+           CHECK (017 << i, radix);
+           CHECK (~017 << i, radix);
+       }
+
+       for (i = 0; i < 12; i++) {
+           CHECK (037 << i, radix);
+           CHECK (~037 << i, radix);
+       }
+
+       for (i = 0; i < 11; i++) {
+           CHECK (077 << i, radix);
+           CHECK (~077 << i, radix);
+       }
+
+       for (i = 0; i < 10; i++) {
+           CHECK (0177 << i, radix);
+           CHECK (~0177 << i, radix);
+       }
+
+       for (i = 0; i < 9; i++) {
+           CHECK (0377 << i, radix);
+           CHECK (~0377 << i, radix);
+       }
+
+       n = radix*radix;
+       for (i = 5; i <= n; i++) {
+           CHECK (i, radix);
+           CHECK (-i, radix);
+       }
+    }
+
+    return 0;
+}


Property changes on: trunk/avr-libc/tests/simulate/stdlib/utoa-3.c
___________________________________________________________________
Added: svn:keywords
   + Author Id Date




reply via email to

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