1*0Sstevel@tonic-gate/* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate/* 23*0Sstevel@tonic-gate * Copyright (c) 1989-1995,1998 by Sun Microsystems, Inc. 24*0Sstevel@tonic-gate * All rights reserved. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate.ident "%Z%%M% %I% %E% SMI" /* SunOS 4.1 1.2 */ 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate .file "%M%" 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gate/* 32*0Sstevel@tonic-gate * memcmp(s1, s2, len) 33*0Sstevel@tonic-gate * 34*0Sstevel@tonic-gate * Compare n bytes: s1>s2: >0 s1==s2: 0 s1<s2: <0 35*0Sstevel@tonic-gate * 36*0Sstevel@tonic-gate * Fast assembler language version of the following C-program for memcmp 37*0Sstevel@tonic-gate * which represents the `standard' for the C-library. 38*0Sstevel@tonic-gate * 39*0Sstevel@tonic-gate * int 40*0Sstevel@tonic-gate * memcmp(const void *s1, const void *s2, size_t n) 41*0Sstevel@tonic-gate * { 42*0Sstevel@tonic-gate * if (s1 != s2 && n != 0) { 43*0Sstevel@tonic-gate * const char *ps1 = s1; 44*0Sstevel@tonic-gate * const char *ps2 = s2; 45*0Sstevel@tonic-gate * do { 46*0Sstevel@tonic-gate * if (*ps1++ != *ps2++) 47*0Sstevel@tonic-gate * return (ps1[-1] - ps2[-1]); 48*0Sstevel@tonic-gate * } while (--n != 0); 49*0Sstevel@tonic-gate * } 50*0Sstevel@tonic-gate * return (NULL); 51*0Sstevel@tonic-gate * } 52*0Sstevel@tonic-gate */ 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gate#include <sys/asm_linkage.h> 55*0Sstevel@tonic-gate 56*0Sstevel@tonic-gate ANSI_PRAGMA_WEAK(memcmp,function) 57*0Sstevel@tonic-gate 58*0Sstevel@tonic-gate#include "synonyms.h" 59*0Sstevel@tonic-gate 60*0Sstevel@tonic-gate ENTRY(memcmp) 61*0Sstevel@tonic-gate st %g2, [%sp + 68] ! g2 must be restored before retl 62*0Sstevel@tonic-gate cmp %o0, %o1 ! s1 == s2? 63*0Sstevel@tonic-gate be .cmpeq 64*0Sstevel@tonic-gate cmp %o2, 17 65*0Sstevel@tonic-gate bleu,a .cmpbyt ! for small counts go do bytes 66*0Sstevel@tonic-gate sub %o1, %o0, %o1 67*0Sstevel@tonic-gate 68*0Sstevel@tonic-gate andcc %o0, 3, %o3 ! is s1 aligned? 69*0Sstevel@tonic-gate bz,a .iss2 ! if so go check s2 70*0Sstevel@tonic-gate andcc %o1, 3, %o4 ! is s2 aligned? 71*0Sstevel@tonic-gate cmp %o3, 2 72*0Sstevel@tonic-gate be .algn2 73*0Sstevel@tonic-gate cmp %o3, 3 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate.algn1: ldub [%o0], %o4 ! cmp one byte 76*0Sstevel@tonic-gate inc %o0 77*0Sstevel@tonic-gate ldub [%o1], %o5 78*0Sstevel@tonic-gate inc %o1 79*0Sstevel@tonic-gate dec %o2 80*0Sstevel@tonic-gate be .algn3 81*0Sstevel@tonic-gate cmp %o4, %o5 82*0Sstevel@tonic-gate be .algn2 83*0Sstevel@tonic-gate nop 84*0Sstevel@tonic-gate b,a .noteq 85*0Sstevel@tonic-gate 86*0Sstevel@tonic-gate.algn2: lduh [%o0], %o4 87*0Sstevel@tonic-gate inc 2, %o0 88*0Sstevel@tonic-gate ldub [%o1], %o5 89*0Sstevel@tonic-gate inc 1, %o1 90*0Sstevel@tonic-gate srl %o4, 8, %o3 91*0Sstevel@tonic-gate cmp %o3, %o5 92*0Sstevel@tonic-gate be,a 1f 93*0Sstevel@tonic-gate ldub [%o1], %o5 ! delay slot, get next byte from s2 94*0Sstevel@tonic-gate b .noteq 95*0Sstevel@tonic-gate mov %o3, %o4 ! delay slot, move *s1 to %o4 96*0Sstevel@tonic-gate1: inc %o1 97*0Sstevel@tonic-gate dec 2, %o2 98*0Sstevel@tonic-gate and %o4, 0xff, %o4 99*0Sstevel@tonic-gate cmp %o4, %o5 100*0Sstevel@tonic-gate.algn3: be,a .iss2 101*0Sstevel@tonic-gate andcc %o1, 3, %o4 ! delay slot, is s2 aligned? 102*0Sstevel@tonic-gate b,a .noteq 103*0Sstevel@tonic-gate 104*0Sstevel@tonic-gate.cmpbyt:b .bytcmp 105*0Sstevel@tonic-gate deccc %o2 106*0Sstevel@tonic-gate1: ldub [%o0 + %o1], %o5 ! byte compare loop 107*0Sstevel@tonic-gate inc %o0 108*0Sstevel@tonic-gate cmp %o4, %o5 109*0Sstevel@tonic-gate be,a .bytcmp 110*0Sstevel@tonic-gate deccc %o2 ! delay slot, compare count (len) 111*0Sstevel@tonic-gate b,a .noteq 112*0Sstevel@tonic-gate.bytcmp:bgeu,a 1b 113*0Sstevel@tonic-gate ldub [%o0], %o4 114*0Sstevel@tonic-gate.cmpeq: ld [%sp + 68], %g2 115*0Sstevel@tonic-gate retl ! strings compare equal 116*0Sstevel@tonic-gate clr %o0 117*0Sstevel@tonic-gate 118*0Sstevel@tonic-gate.noteq_word: ! words aren't equal. find unequal byte 119*0Sstevel@tonic-gate srl %o4, 24, %o1 ! first byte 120*0Sstevel@tonic-gate srl %o5, 24, %o2 121*0Sstevel@tonic-gate cmp %o1, %o2 122*0Sstevel@tonic-gate bne 1f 123*0Sstevel@tonic-gate sll %o4, 8, %o4 124*0Sstevel@tonic-gate sll %o5, 8, %o5 125*0Sstevel@tonic-gate srl %o4, 24, %o1 126*0Sstevel@tonic-gate srl %o5, 24, %o2 127*0Sstevel@tonic-gate cmp %o1, %o2 128*0Sstevel@tonic-gate bne 1f 129*0Sstevel@tonic-gate sll %o4, 8, %o4 130*0Sstevel@tonic-gate sll %o5, 8, %o5 131*0Sstevel@tonic-gate srl %o4, 24, %o1 132*0Sstevel@tonic-gate srl %o5, 24, %o2 133*0Sstevel@tonic-gate cmp %o1, %o2 134*0Sstevel@tonic-gate bne 1f 135*0Sstevel@tonic-gate sll %o4, 8, %o4 136*0Sstevel@tonic-gate sll %o5, 8, %o5 137*0Sstevel@tonic-gate srl %o4, 24, %o1 138*0Sstevel@tonic-gate srl %o5, 24, %o2 139*0Sstevel@tonic-gate1: 140*0Sstevel@tonic-gate ld [%sp + 68], %g2 141*0Sstevel@tonic-gate retl 142*0Sstevel@tonic-gate sub %o1, %o2, %o0 ! delay slot 143*0Sstevel@tonic-gate 144*0Sstevel@tonic-gate.noteq: 145*0Sstevel@tonic-gate ld [%sp + 68], %g2 146*0Sstevel@tonic-gate retl ! strings aren't equal 147*0Sstevel@tonic-gate sub %o4, %o5, %o0 ! delay slot, return(*s1 - *s2) 148*0Sstevel@tonic-gate 149*0Sstevel@tonic-gate.iss2: andn %o2, 3, %o3 ! count of aligned bytes 150*0Sstevel@tonic-gate and %o2, 3, %o2 ! remaining bytes 151*0Sstevel@tonic-gate bz .w4cmp ! if s2 word aligned, compare words 152*0Sstevel@tonic-gate cmp %o4, 2 153*0Sstevel@tonic-gate be .w2cmp ! s2 half aligned 154*0Sstevel@tonic-gate cmp %o4, 1 155*0Sstevel@tonic-gate 156*0Sstevel@tonic-gate.w3cmp: 157*0Sstevel@tonic-gate dec 4, %o3 ! avoid reading beyond the last byte 158*0Sstevel@tonic-gate inc 4, %o2 159*0Sstevel@tonic-gate ldub [%o1], %g1 ! read a byte to align for word reads 160*0Sstevel@tonic-gate inc 1, %o1 161*0Sstevel@tonic-gate be .w1cmp ! aligned to 1 or 3 bytes 162*0Sstevel@tonic-gate sll %g1, 24, %o5 163*0Sstevel@tonic-gate 164*0Sstevel@tonic-gate sub %o1, %o0, %o1 165*0Sstevel@tonic-gate2: ld [%o0 + %o1], %g1 166*0Sstevel@tonic-gate ld [%o0], %o4 167*0Sstevel@tonic-gate inc 4, %o0 168*0Sstevel@tonic-gate srl %g1, 8, %g2 ! merge with the other half 169*0Sstevel@tonic-gate or %g2, %o5, %o5 170*0Sstevel@tonic-gate cmp %o4, %o5 171*0Sstevel@tonic-gate bne .noteq_word 172*0Sstevel@tonic-gate deccc 4, %o3 173*0Sstevel@tonic-gate bnz 2b 174*0Sstevel@tonic-gate sll %g1, 24, %o5 175*0Sstevel@tonic-gate sub %o1, 1, %o1 ! used 3 bytes of the last word read 176*0Sstevel@tonic-gate b .bytcmp 177*0Sstevel@tonic-gate deccc %o2 178*0Sstevel@tonic-gate 179*0Sstevel@tonic-gate.w1cmp: 180*0Sstevel@tonic-gate dec 4, %o3 ! avoid reading beyond the last byte 181*0Sstevel@tonic-gate inc 4, %o2 182*0Sstevel@tonic-gate lduh [%o1], %g1 ! read 3 bytes to word align 183*0Sstevel@tonic-gate inc 2, %o1 184*0Sstevel@tonic-gate sll %g1, 8, %g2 185*0Sstevel@tonic-gate or %o5, %g2, %o5 186*0Sstevel@tonic-gate 187*0Sstevel@tonic-gate sub %o1, %o0, %o1 188*0Sstevel@tonic-gate3: ld [%o0 + %o1], %g1 189*0Sstevel@tonic-gate ld [%o0], %o4 190*0Sstevel@tonic-gate inc 4, %o0 191*0Sstevel@tonic-gate srl %g1, 24, %g2 ! merge with the other half 192*0Sstevel@tonic-gate or %g2, %o5, %o5 193*0Sstevel@tonic-gate cmp %o4, %o5 194*0Sstevel@tonic-gate bne .noteq_word 195*0Sstevel@tonic-gate deccc 4, %o3 196*0Sstevel@tonic-gate bnz 3b 197*0Sstevel@tonic-gate sll %g1, 8, %o5 198*0Sstevel@tonic-gate sub %o1, 3, %o1 ! used 1 byte of the last word read 199*0Sstevel@tonic-gate b .bytcmp 200*0Sstevel@tonic-gate deccc %o2 201*0Sstevel@tonic-gate 202*0Sstevel@tonic-gate.w2cmp: 203*0Sstevel@tonic-gate dec 4, %o3 ! avoid reading beyond the last byte 204*0Sstevel@tonic-gate inc 4, %o2 205*0Sstevel@tonic-gate lduh [%o1], %g1 ! read a halfword to align s2 206*0Sstevel@tonic-gate inc 2, %o1 207*0Sstevel@tonic-gate sll %g1, 16, %o5 208*0Sstevel@tonic-gate 209*0Sstevel@tonic-gate sub %o1, %o0, %o1 210*0Sstevel@tonic-gate4: ld [%o0 + %o1], %g1 ! read a word from s2 211*0Sstevel@tonic-gate ld [%o0], %o4 ! read a word from s1 212*0Sstevel@tonic-gate inc 4, %o0 213*0Sstevel@tonic-gate srl %g1, 16, %g2 ! merge with the other half 214*0Sstevel@tonic-gate or %g2, %o5, %o5 215*0Sstevel@tonic-gate cmp %o4, %o5 216*0Sstevel@tonic-gate bne .noteq_word 217*0Sstevel@tonic-gate deccc 4, %o3 218*0Sstevel@tonic-gate bnz 4b 219*0Sstevel@tonic-gate sll %g1, 16, %o5 220*0Sstevel@tonic-gate sub %o1, 2, %o1 ! only used half of the last read word 221*0Sstevel@tonic-gate b .bytcmp 222*0Sstevel@tonic-gate deccc %o2 223*0Sstevel@tonic-gate 224*0Sstevel@tonic-gate.w4cmp: 225*0Sstevel@tonic-gate sub %o1, %o0, %o1 226*0Sstevel@tonic-gate ld [%o0 + %o1], %o5 227*0Sstevel@tonic-gate5: ld [%o0], %o4 228*0Sstevel@tonic-gate inc 4, %o0 229*0Sstevel@tonic-gate cmp %o4, %o5 230*0Sstevel@tonic-gate bne .noteq_word 231*0Sstevel@tonic-gate deccc 4, %o3 232*0Sstevel@tonic-gate bnz,a 5b 233*0Sstevel@tonic-gate ld [%o0 + %o1], %o5 234*0Sstevel@tonic-gate b .bytcmp ! compare remaining bytes, if any 235*0Sstevel@tonic-gate deccc %o2 236*0Sstevel@tonic-gate 237*0Sstevel@tonic-gate SET_SIZE(memcmp) 238