#**************************************************************************** #* * #* 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