[444] | 1 | /* |
---|
| 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$" */ |
---|
| 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) |
---|