/avr-libc-1.6.2.orig/libc/stdlib/atoi.S

https://bitbucket.org/ldauvergne/cubeled4x4x5 · Assembly · 128 lines · 51 code · 15 blank · 62 comment · 0 complexity · 205d0c15aa260a660f8f03701795a9f5 MD5 · raw file

  1. /* Copyright (c) 2002, 2007 Reiner Patommel
  2. All rights reserved.
  3. Redistribution and use in source and binary forms, with or without
  4. modification, are permitted provided that the following conditions are met:
  5. * Redistributions of source code must retain the above copyright
  6. notice, this list of conditions and the following disclaimer.
  7. * Redistributions in binary form must reproduce the above copyright
  8. notice, this list of conditions and the following disclaimer in
  9. the documentation and/or other materials provided with the
  10. distribution.
  11. * Neither the name of the copyright holders nor the names of
  12. contributors may be used to endorse or promote products derived
  13. from this software without specific prior written permission.
  14. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  15. AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  16. IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  17. ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  18. LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  19. CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  20. SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  21. INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  22. CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  23. ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  24. POSSIBILITY OF SUCH DAMAGE. */
  25. /* $Id: atoi.S,v 1.14 2007/12/01 06:03:30 dmix Exp $ */
  26. /*
  27. Contributors:
  28. Created by Reiner Patommel
  29. Changes: Jochen Pernsteiner, Marek Michalkiewicz
  30. Changes: Reiner Patommel, 8 Feb 2003
  31. Changes: Reiner Patommel, 13 May 2003 (DOXYGEN)
  32. TODO: this implementation uses an inline isspace(). If Avr-libc will
  33. use locales other than C/POSIX it is needed to call an external isspace().
  34. ATTENTION: an external __mulhi_const_10() function is used: nonstandart
  35. call conventions: some registers and bit T must be nochanged.
  36. */
  37. /** \file */
  38. /** \ingroup avr_stdlib
  39. \fn int atoi(const char *s)
  40. \brief Convert a string to an integer.
  41. The atoi() function converts the initial portion of the string
  42. pointed to by \p s to integer representation. In contrast to
  43. \code (int)strtol(s, (char **)NULL, 10); \endcode
  44. this function does not detect overflow (\c errno is not changed and
  45. the result value is not predictable), uses smaller memory (flash and
  46. stack) and works more quickly.
  47. */
  48. #if !defined(__DOXYGEN__)
  49. #include "macros.inc"
  50. #define str_hi r25
  51. #define str_lo r24
  52. #define num_hi r25
  53. #define num_lo r24
  54. #define tmp r18
  55. .text
  56. .global _U(atoi)
  57. .type _U(atoi), @function
  58. /*
  59. Skip leading spaces and tabs. Process optional sign. Stop conversion
  60. on detection of a non-numeric character. Return 0 if string contains
  61. no numeric characters. No check is performed whether the value is within
  62. the range of an 'int' i.e. 32768 becomes -32768.
  63. */
  64. /* This fact is used below. */
  65. .if ('\t'-9) | ('\n'-10) | ('\f'-12) | ('\r'-13) ; '\v' is 11
  66. .err
  67. .endif
  68. _U(atoi):
  69. X_movw ZL, str_lo ; set pointer to string
  70. CLR num_lo
  71. CLR num_hi ; clear number
  72. CLT ; clear sign flag
  73. .L_atoi_loop:
  74. LD tmp, Z+ ; get (next) character
  75. CPI tmp, ' ' ; skip whitespace
  76. BREQ .L_atoi_loop
  77. CPI tmp, '\t' ; ASCII sequence is: \t,\n,\v,\f,\r
  78. BRLO 1f
  79. CPI tmp, '\r'+1
  80. BRLO .L_atoi_loop
  81. 1:
  82. CPI tmp, '+' ; if '+' convert
  83. BREQ .L_atoi_loop2
  84. CPI tmp, '-' ; if '-' remember sign
  85. BRNE .L_atoi_digit
  86. SET ; remember number is negative
  87. RJMP .L_atoi_loop2
  88. 2: XCALL __mulhi_const_10 ; r25:r24 *= 10
  89. ADD num_lo, tmp ; num = (num * 10) + (tmp - '0')
  90. ADC num_hi, __zero_reg__
  91. .L_atoi_loop2:
  92. LD tmp, Z+
  93. .L_atoi_digit:
  94. SUBI tmp, '0'
  95. CPI tmp, 10
  96. BRLO 2b
  97. BRTC .L_atoi_done ; positive number? -> return
  98. COM num_hi
  99. NEG num_lo
  100. SBCI num_hi, -1 ; make number negative
  101. .L_atoi_done:
  102. RET
  103. .L_atoi_end:
  104. .size _U(atoi), .L_atoi_end - _U(atoi)
  105. #endif /* not __DOXYGEN__ */