~ubuntu-branches/ubuntu/maverick/avr-libc/maverick

« back to all changes in this revision

Viewing changes to libc/stdlib/atol.S

  • Committer: Bazaar Package Importer
  • Author(s): Hakan Ardo
  • Date: 2007-08-09 11:28:01 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070809112801-ps7wognnynio9kz7
Tags: 1:1.4.6-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (c) 2002, Reiner Patommel
 
1
/* Copyright (c) 2002, 2007 Reiner Patommel
2
2
   All rights reserved.
3
3
 
4
4
   Redistribution and use in source and binary forms, with or without
26
26
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
27
  POSSIBILITY OF SUCH DAMAGE. */
28
28
 
29
 
/* $Id: atol.S,v 1.9 2005/11/09 23:51:43 aesok Exp $ */
 
29
/* $Id: atol.S,v 1.9.2.2 2007/03/25 14:35:00 dmix Exp $ */
30
30
 
31
31
/*
32
32
   atol.S
35
35
     Created by Reiner Patommel
36
36
     Modified by Reiner Patommel 8 Feb 2003, Bug #2481
37
37
     Modified by Reiner Patommel 13 May 2003, (DOXYGEN)
 
38
 
 
39
   TODO: this implementation uses an inline isspace(). If Avr-libc will
 
40
   use locales other than C/POSIX it is needed to call an external isspace().
 
41
   
 
42
   ATTENTION: an external __mulsi_const_10() function is used: nonstandart
 
43
   call conventions: some registers and bit T must be nochanged.
38
44
 */
39
45
 
40
46
#include "macros.inc"
48
54
#define tmp             r17
49
55
 
50
56
 
 
57
/** \file */
 
58
 
51
59
/** \ingroup avr_stdlib
52
 
    \fn long int atol(const char *string)
 
60
    \fn long atol(const char *s)
53
61
    \brief Convert a string to a long integer.
54
62
 
55
63
    The atol() function converts the initial portion of the string
56
 
    pointed to by \c stringp to integer representation.
57
 
 
58
 
    It is equivalent to:
59
 
 
60
 
           \code strtol(nptr, (char **)NULL, 10); \endcode
61
 
           except that atol() does not detect errors.
 
64
    pointed to by \p s to long integer representation. In contrast to
 
65
 
 
66
        \code strtol(s, (char **)NULL, 10); \endcode
 
67
 
 
68
    this function does not detect overflow (\c errno is not changed and
 
69
    the result value is not predictable), uses smaller memory (flash and
 
70
    stack) and works more quickly.
62
71
*/
63
72
 
64
73
#if !defined(__DOXYGEN__)
73
82
   no numeric characters.
74
83
 */
75
84
 
 
85
/* This fact is used below.     */
 
86
.if     ('\t'-9) | ('\n'-10) | ('\f'-12) | ('\r'-13)    ; '\v' is 11
 
87
  .err
 
88
.endif
 
89
 
76
90
_U(atol):
77
 
        PUSH    r17
 
91
        PUSH    tmp
78
92
        X_movw  ZL, str_lo              ; set pointer to string
79
93
        CLR     num_hi_hi
80
94
        CLR     num_hi_lo
81
 
        CLR     num_lo_hi
82
 
        CLR     num_lo_lo               ; clear number
 
95
        X_movw  num_lo_lo, num_hi_lo    ; clear number
83
96
        CLT                             ; clear sign
84
97
 
85
98
.L_atol_loop:
86
99
        LD      tmp, Z+                 ; get (next) character
87
 
        TST     tmp                     ; is it end of string?
88
 
        BREQ    .L_atol_sig
89
100
        CPI     tmp, ' '                ; skip whitespace
90
101
        BREQ    .L_atol_loop
91
102
        CPI     tmp, '\t'
92
 
        BREQ    .L_atol_loop
93
 
        CPI     tmp, '\n'
94
 
        BREQ    .L_atol_loop
95
 
        CPI     tmp, '\f'
96
 
        BREQ    .L_atol_loop
97
 
        CPI     tmp, '\r'
98
 
        BREQ    .L_atol_loop
99
 
        CPI     tmp, '\v'
100
 
        BREQ    .L_atol_loop
 
103
        BRLO    1f
 
104
        CPI     tmp, '\r'+1
 
105
        BRLO    .L_atol_loop
 
106
1:
101
107
        CPI     tmp, '+'                ; if '+' go on
102
108
        BREQ    .L_atol_loop2
103
109
        CPI     tmp, '-'                ; if '-' remember sign
104
110
        BRNE    .L_atol_digit
105
 
 
106
 
.L_atol_neg:
107
111
        SET                             ; remember number is negative
 
112
        RJMP    .L_atol_loop2
108
113
 
 
114
2:      XCALL   __mulsi_const_10        ; r25:r24:r23:r22 *= 10
 
115
        ADD     num_lo_lo, tmp          ; num = (num * 10) + (tmp - '0')
 
116
        ADC     num_lo_hi, __zero_reg__
 
117
        ADC     num_hi_lo, __zero_reg__
 
118
        ADC     num_hi_hi, __zero_reg__
109
119
.L_atol_loop2:
110
120
        LD      tmp, Z+
111
 
        TST     tmp
112
 
        BREQ    .L_atol_sig
113
 
 
114
121
.L_atol_digit:
115
 
        CPI     tmp, '0'                ; test on [0 .. 9]
116
 
        BRLT    .L_atol_sig
117
 
        CPI     tmp, '9'+1
118
 
        BRGE    .L_atol_sig
119
122
        SUBI    tmp, '0'                ; make figure a number
120
 
        XCALL   __mulsi_const_10        ; r25:r24:r23:r22 *= 10
121
 
        ADD     num_lo_lo, tmp          ; num = (num * 10) + (tmp - '0')
122
 
        ADC     num_lo_hi, __zero_reg__
123
 
        ADC     num_hi_lo, __zero_reg__
124
 
        ADC     num_hi_hi, __zero_reg__
125
 
        RJMP    .L_atol_loop2           ; next figure
 
123
        CPI     tmp, 10
 
124
        BRLO    2b
126
125
 
127
 
.L_atol_sig:
128
 
        CP      num_lo_lo, __zero_reg__
129
 
        CPC     num_lo_hi, __zero_reg__
130
 
        CPC     num_hi_lo, __zero_reg__
131
 
        CPC     num_hi_hi, __zero_reg__ ; did we get a number?
132
 
        BREQ    .L_atol_done            ; no, drop sign and return
133
126
        BRTC    .L_atol_done            ; positive number? -> return
134
127
        COM     num_hi_hi
135
128
        COM     num_hi_lo
140
133
        SBCI    num_hi_hi, 0xff         ; make number negative
141
134
 
142
135
.L_atol_done:
143
 
        POP     r17
 
136
        POP     tmp
144
137
        RET
145
138
 
146
139
.L_atol_end: