OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [newlib-1.17.0/] [newlib/] [libc/] [machine/] [hppa/] [strlen.S] - Blame information for rev 816

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 148 jeremybenn
/*
2
 *  (c) Copyright 1986 HEWLETT-PACKARD COMPANY
3
 *
4
 *  To anyone who acknowledges that this file is provided "AS IS"
5
 *  without any express or implied warranty:
6
 *      permission to use, copy, modify, and distribute this file
7
 *  for any purpose is hereby granted without fee, provided that
8
 *  the above copyright notice and this notice appears in all
9
 *  copies, and that the name of Hewlett-Packard Company not be
10
 *  used in advertising or publicity pertaining to distribution
11
 *  of the software without specific, written prior permission.
12
 *  Hewlett-Packard Company makes no representations about the
13
 *  suitability of this software for any purpose.
14
 */
15
 
16
/* HPUX_ID = "@(#) $Revision: 1.1 $" */
17
/* strlen(s): Return length of string s */
18
 
19
#define start   arg0
20
#define end     ret0
21
#define tmp1    arg1
22
#define tmp2    arg2
23
 
24
#include "DEFS.h"
25
 
26
ENTRY(strlen)
27
        movb,=,n        start,end,$null_ptr
28
        depi            0,31,2,end
29
        comb,<>         start,end,$not_aligned
30
        ldws,ma         4(end),tmp1
31
        comib,tr        0,0,$loop       /* avoid INDIGO two register interlock */
32
        uxor,nbz        0,tmp1,0
33
$not_aligned:
34
        /*
35
        ;       Tricky code.  The problem is that the value of of the word
36
        ;       including the start of the string has some garbage bytes that
37
        ;       may be 0.  We don't want them to stop the string scan.  So
38
        ;       we make those bytes non-zero (and any old non-zero value
39
        ;       will do).  Notice that the end pointer has been rounded
40
        ;       down to a word boundary, and then incremented to the next
41
        ;       word by the time we get here.  Therefore, (start-end) has
42
        ;       one of the values (-3, -2, or -1).  Use uaddcm to do the
43
        ;       subtraction (instead of sub), and the result will be
44
        ;       (-4, -3, or -2).  Multiply this by 8, and put into the
45
        ;       shift register (which truncates to the last 5 bits) and
46
        ;       the value will be (0, 8, or 16).  Use this as a bit position,
47
        ;       and drop a mask down into tmp1.  All the garbage bytes will
48
        ;       have at least 1 bit affected by the vdepi, so all the garbage
49
        ;       in this first word will be non-zero garbage.
50
        */
51
        uaddcm          start,end,tmp2  /*  tmp2 <- {  -4,  -3,  -2 } */
52
        sh3add          tmp2,0,tmp2     /*  tmp2 <- { -32, -24, -16 } */
53
        mtsar           tmp2            /*  sar  <- {   0,   8,  16 } */
54
        vdepi           -1,32,tmp1
55
        uxor,nbz        0,tmp1,0
56
$loop:
57
        b,n             $end_loop
58
        ldws,ma         4(end),tmp1
59
        comib,tr        0,0,$loop       /* avoid INDIGO two register interlock */
60
        uxor,nbz        0,tmp1,0
61
$end_loop:
62
        /*       adjust the end pointer to one past the end of the string */
63
        extru,<>        tmp1,7,8,0
64
        addib,tr,n      -3,end,$out
65
        extru,<>        tmp1,15,8,0
66
        addib,tr,n      -2,end,$out
67
        extru,<>        tmp1,23,8,0
68
        addi            -1,end,end
69
$out:
70
        bv              0(rp)
71
        /*
72
        ;       tricky code.  the end pointer is just beyond the terminating
73
        ;       null byte, so the length is (end-start-1).  use uaddcm
74
        ;       to do this in 1 instruction
75
        */
76
        uaddcm          end,start,ret0
77
 
78
$null_ptr:
79
EXIT(strlen)

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.