diff options
Diffstat (limited to 'private/crt32/misc/alpha/strlen_.s')
-rw-r--r-- | private/crt32/misc/alpha/strlen_.s | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/private/crt32/misc/alpha/strlen_.s b/private/crt32/misc/alpha/strlen_.s new file mode 100644 index 000000000..2a7979387 --- /dev/null +++ b/private/crt32/misc/alpha/strlen_.s @@ -0,0 +1,95 @@ + #**************************************************************************** + #* * + #* Copyright (c) 1991 by * + #* DIGITAL EQUIPMENT CORPORATION, Maynard, Massachusetts. * + #* All rights reserved. * + #* * + #* This software is furnished under a license and may be used and copied * + #* only in accordance with the terms of such license and with the * + #* inclusion of the above copyright notice. This software or any other * + #* copies thereof may not be provided or otherwise made available to any * + #* other person. No title to and ownership of the software is hereby * + #* transferred. * + #* * + #* The information in this software is subject to change without notice * + #* and should not be construed as a commitment by Digital Equipment * + #* Corporation. * + #* * + #* Digital assumes no responsibility for the use or reliability of its * + #* software on equipment which is not supplied by Digital. * + #* * + #* * + #**************************************************************************** + # + #++ + # Facility: + # DEC C Run Time Library on the Alpha/WNT Platform + # + # Abstract: + # + # Implements the C RTL function strlen() for the compiler intrinsic. + # + # Author: + # Bill Noyce 9-Aug-1991 + # + # Modified by: + # + # 001 Kevin Routley 10-Sep-1991 + # Modified to C RTL Coding standards. + # + # 002 Chris Bord 30 September 1991 + # + # 003 Chris Bord 24 January 1992 + # Add second parameter to .procedure_descriptor directive + # + # 004 John Parks 22 January 1993 + # Ported to Alpha/NT. + #-- + + .globl _Otsstrlen + .ent _Otsstrlen + + # r16 = src pointer + # Returns r0 = length + # Destroys r16,r27-r28 + +_Otsstrlen: + .set noat + .set noreorder + + ldq_u $27, ($16) # Get QW containing start of string + lda $28, -1($31) # Mask of all ones + mskql $28, $16, $28 # Nonzeros in low bytes to be ignored + and $16, 7, $0 # Alignment = bytes not to be counted + or $27, $28, $27 # Fill ignored bytes with nonzeros + cmpbge $31, $27, $27 # Any null bytes in this QW? + subq $31, $0, $0 # Initialize count to -alignment + bne $27, bottom # Skip if null byte seen + +loop: ldq_u $27, 8($16) # Load next QW of string + addq $16, 8, $16 # Advance pointer + addq $0, 8, $0 # Increment length + cmpbge $31, $27, $27 # Any nulls in this QW? + beq $27, loop # Repeat if not + +bottom: and $27, 0xF, $28 # Null in low longword? + subq $27, 1, $16 # Complement the lowest 1-bit in mask + blbs $27, done # Exit if null appears in first byte + andnot $27, $16, $27 # Make single-bit mask of null location + beq $28, geq_4 # Skip if null is in high longword + srl $27, 2, $27 # Map 2/4/8 --> 0/1/2 + addq $0, 1, $0 # Bump length by one... + addq $0, $27, $0 # ... and then by null location + +done: ret $31, ($26) + +geq_4: srl $27, 5, $28 # Map 10/20/40/80 --> 0/1/2/4 + srl $27, 7, $27 # Map 10/20/40/80 --> 0/0/0/1 + addq $0, 4, $0 # Bump length by four + subq $28, $27, $28 # Compute location within high LW... + addq $0, $28, $0 # ... and add to length + ret $31, ($26) + + .set at + .set reorder + .end _Otsstrlen |