/* * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * The contents of this file constitute Original Code as defined in and * are subject to the Apple Public Source License Version 1.1 (the * "License"). You may not use this file except in compliance with the * License. Please obtain a copy of the License at * http://www.apple.com/publicsource and read it before using this file. * * This Original Code and all software distributed under the License are * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the * License for the specific language governing rights and limitations * under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* Copyright (c) 1992, 1997 NeXT Software, Inc. All rights reserved. * * File: libc/gen/ppc/strlen.s * * HISTORY * 24-Jan-1997 Umesh Vaishampayan (umeshv@NeXT.com) * Ported to PPC. * 12-Nov-92 Derek B Clegg (dclegg@next.com) * Created. * * size_t strlen(const char *s); * * Description: * * Returns: */ #import #import /* size_t strlen(const char *s); */ #define a8 ep #define a9 at .at_off #define check_for_zero(reg, tmp, found_zero, checked_all) \ extrwi. tmp,reg,8,0 @\ beq- found_zero @\ bdz- checked_all @\ extrwi. tmp,reg,8,8 @\ beq- found_zero @\ bdz- checked_all @\ extrwi. tmp,reg,8,16 @\ beq- found_zero @\ bdz- checked_all @\ extrwi. tmp,reg,8,24 @\ beq- found_zero @\ bdz- checked_all #define check_32(tmp, found_zero) \ check_for_zero(a2, tmp, found_zero, 1f) @\ check_for_zero(a3, tmp, found_zero, 1f) @\ check_for_zero(a4, tmp, found_zero, 1f) @\ check_for_zero(a5, tmp, found_zero, 1f) @\ check_for_zero(a6, tmp, found_zero, 1f) @\ check_for_zero(a7, tmp, found_zero, 1f) @\ check_for_zero(a8, tmp, found_zero, 1f) @\ check_for_zero(a9, tmp, found_zero, 1f) @\ 1: LEAF(_strlen) dcbt 0,a0 // Try to load the cache line. andi. a1,a0,31 // We want to be 32-byte aligned. subfic a1,a1,32 // Get the number of bytes to start with. mtxer a1 // Setup xer for load. lswx a2,0,a0 // Load the bytes. mtctr a1 // Setup ctr for zero check. check_32(zt, L_found_zero) /* Now check 32-byte blocks. At this point, ctr is zero, so we can * use it as our running count. */ dcbt a1,a0 // Try to load the cache line. li32 a2,32 mtxer a2 li32 a2,0 mtctr a2 2: lswx a2,a1,a0 // Load 32 bytes. check_32(zt, L_found_zero) addi a0,a0,32 // Increment the pointer. dcbt a1,a0 // Try to load the cache. b 2b // Loop L_found_zero: mfctr a0 sub a0,a1,a0 // Get the number of bytes before 0. blr // Return. END(_strlen)