1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 .ident "%Z%%M% %I% %E% SMI" 28 29 .file "%M%" 30 31/ 32/ memcmp(s1, s2, n) 33/ 34/ Compares n bytes: s1>s2: >0 s1==s2: 0 s1<s2: <0 35/ 36/ Fast assembly language version of the following C-program strcat 37/ which represents the `standard' for the C-library. 38/ 39/ int 40/ memcmp(const void *s1, const void *s2, size_t n) 41/ { 42/ if (s1 != s2 && n != 0) { 43/ const unsigned char *ps1 = s1; 44/ const unsigned char *ps2 = s2; 45/ 46/ do { 47/ if (*ps1++ != *ps2++) 48/ return (ps1[-1] - ps2[-1]); 49/ } while (--n != 0); 50/ } 51/ return (NULL); 52/ } 53/ 54/ This implementation conforms to SVID but does not implement 55/ the same algorithm as the portable version because it is 56/ inconvenient to get the difference of the differing characters. 57 58#include <sys/asm_linkage.h> 59 60 ANSI_PRAGMA_WEAK(memcmp,function) 61 62#include "SYS.h" 63 64 ENTRY(memcmp) 65 pushl %edi / save register variable 66 movl 8(%esp), %eax / %eax = address of string 1 67 movl 12(%esp), %ecx / %ecx = address of string 2 68 cmpl %eax, %ecx / if the same string 69 je .equal / goto .equal 70 movl 16(%esp), %edi / %edi = length in bytes 71 cmpl $4, %edi / if %edi < 4 72 jb .byte_check / goto .byte_check 73 .align 4 74.word_loop: 75 movl (%ecx), %edx / move 1 word from (%ecx) to %edx 76 leal -4(%edi), %edi / %edi -= 4 77 cmpl (%eax), %edx / compare 1 word from (%eax) with %edx 78 jne .word_not_equal / if not equal, goto .word_not_equal 79 leal 4(%ecx), %ecx / %ecx += 4 (next word) 80 leal 4(%eax), %eax / %eax += 4 (next word) 81 cmpl $4, %edi / if %edi >= 4 82 jae .word_loop / goto .word_loop 83.byte_check: 84 cmpl $0, %edi / if %edi == 0 85 je .equal / goto .equal 86 jmp .byte_loop / goto .byte_loop (checks in bytes) 87.word_not_equal: 88 leal 4(%edi), %edi / %edi += 4 (post-decremented) 89 .align 4 90.byte_loop: 91 movb (%ecx), %dl / move 1 byte from (%ecx) to %dl 92 cmpb %dl, (%eax) / compare %dl with 1 byte from (%eax) 93 jne .not_equal / if not equal, goto .not_equal 94 incl %ecx / %ecx++ (next byte) 95 incl %eax / %eax++ (next byte) 96 decl %edi / %edi-- 97 jnz .byte_loop / if not zero, goto .byte_loop 98.equal: 99 xorl %eax, %eax / %eax = 0 100 popl %edi / restore register variable 101 ret / return (NULL) 102 .align 4 103.not_equal: 104 sbbl %eax, %eax / %eax = 0 if no carry, %eax = -1 if carry 105 orl $1, %eax / %eax = 1 if no carry, %eax = -1 if carry 106 popl %edi / restore register variable 107 ret / return (NULL) 108 SET_SIZE(memcmp) 109