summaryrefslogtreecommitdiffstats
path: root/private/crt32/misc/alpha/strlen_.s
diff options
context:
space:
mode:
Diffstat (limited to 'private/crt32/misc/alpha/strlen_.s')
-rw-r--r--private/crt32/misc/alpha/strlen_.s95
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