darwin-xnu/libkern/ppc/memcmp.s
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2000-2001 Apple Computer, Inc. All rights reserved.
   3 *
   4 * @APPLE_LICENSE_HEADER_START@
   5 * 
   6 * The contents of this file constitute Original Code as defined in and
   7 * are subject to the Apple Public Source License Version 1.1 (the
   8 * "License").  You may not use this file except in compliance with the
   9 * License.  Please obtain a copy of the License at
  10 * http://www.apple.com/publicsource and read it before using this file.
  11 * 
  12 * This Original Code and all software distributed under the License are
  13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
  17 * License for the specific language governing rights and limitations
  18 * under the License.
  19 * 
  20 * @APPLE_LICENSE_HEADER_END@
  21 */
  22;
  23#include <ppc/asm.h>
  24#include <ppc/proc_reg.h>
  25;
  26; int   memcmp(const void *LHS, const void *RHS, size_t len);
  27;
  28; Memcmp returns the difference between the first two different bytes, 
  29; or 0 if the two strings are equal.  Because we compare a word at a
  30; time, this requires a little additional processing once we find a
  31; difference.
  32;       r3 - LHS
  33;       r4 - RHS
  34;       r5 - len
  35
  36        .align  5
  37        .globl  EXT(memcmp)
  38LEXT(memcmp)
  39
  40        cmpwi   cr1,r5,6                ; six is the most common length
  41        mr      r6,r3                   ; we want to use r3 for compare result
  42        mr.     r3,r5                   ; test length for 0
  43        bgt     cr1,Llong               ; handle long strings
  44        blt     cr1,Lshort              ; and short strings
  45
  46        ; six char strings are special cased because they are the most common
  47Lsix:
  48        lwz     r8,0(r6)                ; first 4 bytes of LHS
  49        lwz     r7,0(r4)                ; and RHS
  50        xor.    r3,r8,r7                ; compare first 4
  51        bne     Ldifferent              ; first 4 differed
  52        lhz     r8,4(r6)                ; last 2 of LHS
  53        lhz     r7,4(r4)                ; last 2 of RHS
  54        xor.    r3,r8,r7                ; compare last 2
  55        beqlr                           ; done if equal
  56
  57        ; strings differ, so we must compute difference between first two
  58        ; differing bytes.
  59        ;       r8 = LHS bytes
  60        ;       r7 = RHS bytes
  61        ;       r3 = r8 xor r7 (r3!=0)
  62Ldifferent:
  63        cntlzw  r9,r3                   ; count leading 0s in xor
  64        rlwinm  r10,r9,0,0,28           ; mask off low 3 bits, so r10 = 0, 8, 16, or 24
  65        subfic  r6,r10,24               ; r6 := (24 - r10)
  66        srw     r4,r8,r6                ; r4 = LHS differing byte
  67        srw     r5,r7,r6                ; r5 = RHS differing byte
  68        sub     r3,r4,r5                ; r3 = difference
  69        blr
  70
  71        ; handle long strings
  72Llong:
  73        srwi    r0,r5,2                 ; r0 = word length
  74        mtctr   r0                      ; set up for loop
  75Llongloop:
  76        lwz     r8,0(r6)                ; next 4 bytes from LHS
  77        addi    r6,r6,4
  78        lwz     r7,0(r4)                ; next 4 from RHS
  79        addi    r4,r4,4
  80        xor.    r3,r8,r7                ; compare next 4 bytes
  81        bdnzt+  eq,Llongloop            ; loop if ctr!=0 and cr0_eq
  82        bne     Ldifferent              ; these 4 bytes not equal
  83        
  84        andi.   r5,r5,3                 ; more to go?
  85
  86        ; compare short strings (0-5 bytes long)
  87        ;       r5 = length (0-5)
  88        ;       cr0= set on length
  89        ;       r3 = if r5=0, then r3=0
  90Lshort:
  91        beqlr                           ; 0-length strings are defined to be equal (r3=0)
  92        mtctr   r5
  93Lshortloop:
  94        lbz     r8,0(r6)                ; get next byte from LHS
  95        addi    r6,r6,1
  96        lbz     r7,0(r4)                ; and next byte from RHS
  97        addi    r4,r4,1
  98        sub.    r3,r8,r7                ; compare
  99        bdnzt+  eq,Lshortloop           ; lloop if ctr!=0 and cr0_eq
 100        blr                             ; done, r3 set correctly by the subtract
 101
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.