~ubuntu-branches/ubuntu/hardy/avr-libc/hardy

« back to all changes in this revision

Viewing changes to libc/string/strncasecmp.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
   Copyright (c) 2007  Dmitry Xmelkov
2
3
   All rights reserved.
3
4
 
4
5
   Redistribution and use in source and binary forms, with or without
26
27
  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
28
  POSSIBILITY OF SUCH DAMAGE. */
28
29
 
29
 
/* $Id: strncasecmp.S,v 1.5 2005/11/05 16:49:46 aesok Exp $ */
 
30
/* $Id: strncasecmp.S,v 1.5.2.3 2007/03/31 13:31:03 dmix Exp $ */
30
31
 
31
32
/*
32
33
   strncasecmp.S
35
36
   Contributors:
36
37
     Created by Reiner Patommel
37
38
*/
38
 
#include "macros.inc"
39
 
 
40
 
#define s1_hi r25
41
 
#define s1_lo r24
42
 
#define s2_hi r23
43
 
#define s2_lo r22
44
 
#define len_hi r21
45
 
#define len_lo r20
46
 
#define tmp r19
47
 
#define cht r18
48
 
 
49
 
#define ret_hi r25
50
 
#define ret_lo r24
 
39
/** \file */
51
40
 
52
41
/** \ingroup avr_string
53
42
    \fn int strncasecmp(const char *s1, const char *s2, size_t len)
54
43
    \brief Compare two strings ignoring case.
55
44
 
56
 
    The strncasecmp() function is similar to strcasecmp(), except it only
57
 
    compares the first n characters of s1.
 
45
    The strncasecmp() function is similar to strcasecmp(), except it
 
46
    only compares the first \p len characters of \p s1.
58
47
 
59
 
    \returns The strncasecmp() function returns an integer less than, equal to,
60
 
    or greater than zero if s1 (or the first n bytes thereof) is found,
61
 
    respectively, to be less than, to match, or be greater than s2.  */
 
48
    \returns The strncasecmp() function returns an integer less than,
 
49
    equal to, or greater than zero if \p s1 (or the first \p len bytes
 
50
    thereof) is found, respectively, to be less than, to match, or be
 
51
    greater than \p s2. A consequence of the ordering used by
 
52
    strncasecmp() is that if \p s1 is an initial substring of \p s2,
 
53
    then \p s1 is considered to be "less than" \p s2.  */
62
54
 
63
55
#if !defined(__DOXYGEN__)
64
56
 
 
57
#include "macros.inc"
 
58
 
 
59
#define s1_hi   r25
 
60
#define s1_lo   r24
 
61
#define s2_hi   r23
 
62
#define s2_lo   r22
 
63
#define len_hi  r21
 
64
#define len_lo  r20
 
65
 
 
66
#define tmp     r22
 
67
#define ret_hi  r25
 
68
#define ret_lo  r24
 
69
 
65
70
        .text
66
71
        .global _U(strncasecmp)
67
72
        .type   _U(strncasecmp), @function
69
74
_U(strncasecmp):
70
75
        X_movw  ZL, s2_lo
71
76
        X_movw  XL, s1_lo
72
 
.L_strncasecmp_loop:
73
 
        SUBI    len_lo, lo8(1)
74
 
        SBCI    len_hi, hi8(1)
75
 
        BRCS    .L_strncasecmp_equal
76
 
        LD      ret_lo, X+              ; load *s1
77
 
        LD      tmp, Z+                 ; load *s2
78
 
        MOV     cht, tmp                ; copy of *s2 to cht
79
 
        ORI     cht, 0x20               ; make it lower case
80
 
        CPI     cht, 'a'                ; test on [a .. z]
81
 
        BRLT    .L_strncasecmp_tst
82
 
        CPI     cht, 'z'+1
83
 
        BRGE    .L_strncasecmp_tst
84
 
        ORI     tmp, 0x20               ; we got an alpha in s2
85
 
        ORI     ret_lo, 0x20            ; make *s1, *s2 lower case
86
 
.L_strncasecmp_tst:
87
 
        SUB     ret_lo, tmp             ; compare chars
88
 
        BRNE    .L_strncasecmp_done
89
 
        TST     tmp                     ; end of s2?
90
 
        BRNE    .L_strncasecmp_loop
91
 
.L_strncasecmp_equal:
92
 
        SUB     ret_lo, ret_lo          ; clear ret_lo and C flag
93
 
.L_strncasecmp_done:
94
 
; ret_hi = SREG.C ? 0xFF : 0
95
 
        SBC     ret_hi, ret_hi
96
 
        RET
97
 
.L_strncasecmp_end:
98
 
        .size   _U(strncasecmp), .L_strncasecmp_end - _U(strncasecmp)
 
77
 
 
78
1:      subi    len_lo, lo8(1)          ; if (--len == -1) return 0
 
79
        sbci    len_hi, hi8(1)
 
80
        brlo    5f
 
81
 
 
82
        ld      ret_lo, X+              ; *s1++
 
83
        cpi     ret_lo, 'A'             ; if in [A-Z] then tolower()
 
84
        brlt    2f
 
85
        cpi     ret_lo, 'Z'+1
 
86
        brge    2f
 
87
        subi    ret_lo, 'A'-'a'
 
88
 
 
89
2:      ld      tmp, Z+                 ; *s2++
 
90
        cpi     tmp, 'A'                ; if in [A-Z] then tolower()
 
91
        brlt    3f
 
92
        cpi     tmp, 'Z'+1
 
93
        brge    3f
 
94
        subi    tmp, 'A'-'a'
 
95
 
 
96
3:      sub     ret_lo, tmp             ; compare
 
97
        cpse    tmp, __zero_reg__       ; break, if end of string
 
98
        breq    1b
 
99
4:      sbc     ret_hi, ret_hi          ; sign extension
 
100
        ret
 
101
 
 
102
5:      sub     ret_lo, ret_lo          ; length limit, return 0
 
103
        rjmp    4b
 
104
 
 
105
        .size   _U(strncasecmp), . - _U(strncasecmp)
99
106
 
100
107
#endif /* not __DOXYGEN__ */