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,1998 by Sun Microsystems, Inc. 24*0Sstevel@tonic-gate * All rights reserved. 25*0Sstevel@tonic-gate * 26*0Sstevel@tonic-gate * .seg "data" 27*0Sstevel@tonic-gate * .asciz "@(#)strncmp.s 1.2 89/08/16" 28*0Sstevel@tonic-gate */ 29*0Sstevel@tonic-gate 30*0Sstevel@tonic-gate.ident "%Z%%M% %I% %E% SMI" /* SunOS 4.1 1.4 */ 31*0Sstevel@tonic-gate 32*0Sstevel@tonic-gate .file "strncmp.s" 33*0Sstevel@tonic-gate 34*0Sstevel@tonic-gate/* 35*0Sstevel@tonic-gate * strncmp(s1, s2, n) 36*0Sstevel@tonic-gate * 37*0Sstevel@tonic-gate * Compare strings (at most n bytes): s1>s2: >0 s1==s2: 0 s1<s2: <0 38*0Sstevel@tonic-gate * 39*0Sstevel@tonic-gate * Fast assembler language version of the following C-program for strncmp 40*0Sstevel@tonic-gate * which represents the `standard' for the C-library. 41*0Sstevel@tonic-gate * 42*0Sstevel@tonic-gate * int 43*0Sstevel@tonic-gate * strncmp(const char *s1, const char *s2, size_t n) 44*0Sstevel@tonic-gate * { 45*0Sstevel@tonic-gate * n++; 46*0Sstevel@tonic-gate * if (s1 == s2) 47*0Sstevel@tonic-gate * return (0); 48*0Sstevel@tonic-gate * while (--n != 0 && *s1 == *s2++) 49*0Sstevel@tonic-gate * if (*s1++ == '\0') 50*0Sstevel@tonic-gate * return (0); 51*0Sstevel@tonic-gate * return ((n == 0) ? 0 : (*s1 - s2[-1])); 52*0Sstevel@tonic-gate * } 53*0Sstevel@tonic-gate */ 54*0Sstevel@tonic-gate 55*0Sstevel@tonic-gate#include <sys/asm_linkage.h> 56*0Sstevel@tonic-gate#include "synonyms.h" 57*0Sstevel@tonic-gate 58*0Sstevel@tonic-gate ENTRY(strncmp) 59*0Sstevel@tonic-gate save %sp, -SA(WINDOWSIZE), %sp 60*0Sstevel@tonic-gate cmp %i2, 8 61*0Sstevel@tonic-gate blu,a .cmp_bytes ! for small counts go do bytes 62*0Sstevel@tonic-gate sub %i0, %i1, %i0 ! delay slot, get diff from s1 - s2 63*0Sstevel@tonic-gate andcc %i0, 3, %g0 ! is s1 aligned 64*0Sstevel@tonic-gate1: bz .iss2 ! if so go check s2 65*0Sstevel@tonic-gate andcc %i1, 3, %i3 ! is s2 aligned 66*0Sstevel@tonic-gate 67*0Sstevel@tonic-gate deccc %i2 ! --n >= 0 ? 68*0Sstevel@tonic-gate bcs .doneq 69*0Sstevel@tonic-gate nop ! delay slot 70*0Sstevel@tonic-gate 71*0Sstevel@tonic-gate ldub [%i0], %i4 ! else cmp one byte 72*0Sstevel@tonic-gate ldub [%i1], %i5 73*0Sstevel@tonic-gate inc %i0 74*0Sstevel@tonic-gate cmp %i4, %i5 75*0Sstevel@tonic-gate bne .noteqb 76*0Sstevel@tonic-gate inc %i1 77*0Sstevel@tonic-gate tst %i4 ! terminating zero 78*0Sstevel@tonic-gate bnz 1b 79*0Sstevel@tonic-gate andcc %i0, 3, %g0 80*0Sstevel@tonic-gate b,a .doneq 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate.iss2: 83*0Sstevel@tonic-gate set 0x7efefeff, %l6 84*0Sstevel@tonic-gate set 0x81010100, %l7 85*0Sstevel@tonic-gate sethi %hi(0xff000000), %l0 ! masks to test for terminating null 86*0Sstevel@tonic-gate sethi %hi(0x00ff0000), %l1 87*0Sstevel@tonic-gate srl %l1, 8, %l2 ! generate 0x0000ff00 mask 88*0Sstevel@tonic-gate 89*0Sstevel@tonic-gate bz .w4cmp ! if s2 word aligned, compare words 90*0Sstevel@tonic-gate cmp %i3, 2 ! check if s2 half aligned 91*0Sstevel@tonic-gate be .w2cmp 92*0Sstevel@tonic-gate cmp %i3, 1 ! check if aligned to 1 or 3 bytes 93*0Sstevel@tonic-gate.w3cmp: ldub [%i1], %i5 94*0Sstevel@tonic-gate inc 1, %i1 95*0Sstevel@tonic-gate be .w1cmp 96*0Sstevel@tonic-gate sll %i5, 24, %i5 97*0Sstevel@tonic-gate sub %i0, %i1, %i0 98*0Sstevel@tonic-gate2: 99*0Sstevel@tonic-gate deccc 4, %i2 ! n >= 4 ? 100*0Sstevel@tonic-gate bgeu,a 3f 101*0Sstevel@tonic-gate ld [%i1], %i3 ! delay slot 102*0Sstevel@tonic-gate dec %i1 ! reset s2 103*0Sstevel@tonic-gate inc %i0 ! reset s1 diff 104*0Sstevel@tonic-gate b .cmp_bytes ! do a byte at a time if n < 4 105*0Sstevel@tonic-gate inc 4, %i2 106*0Sstevel@tonic-gate3: 107*0Sstevel@tonic-gate ld [%i0 + %i1], %i4 108*0Sstevel@tonic-gate inc 4, %i1 109*0Sstevel@tonic-gate srl %i3, 8, %l4 ! merge with the other half 110*0Sstevel@tonic-gate or %l4, %i5, %i5 111*0Sstevel@tonic-gate cmp %i4, %i5 112*0Sstevel@tonic-gate be 1f 113*0Sstevel@tonic-gate 114*0Sstevel@tonic-gate add %i4, %l6, %l3 115*0Sstevel@tonic-gate b,a .noteq 116*0Sstevel@tonic-gate1: xor %l3, %i4, %l3 117*0Sstevel@tonic-gate and %l3, %l7, %l3 118*0Sstevel@tonic-gate cmp %l3, %l7 119*0Sstevel@tonic-gate be,a 2b 120*0Sstevel@tonic-gate sll %i3, 24, %i5 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gate ! 123*0Sstevel@tonic-gate ! For 7-bit characters, we know one of the bytes is zero, but for 124*0Sstevel@tonic-gate ! 8-bit characters, the zero detection algorithm gives some false 125*0Sstevel@tonic-gate ! triggers ... check every byte individually. 126*0Sstevel@tonic-gate ! 127*0Sstevel@tonic-gate andcc %i4, %l0, %g0 ! check if first byte was zero 128*0Sstevel@tonic-gate bnz 1f 129*0Sstevel@tonic-gate andcc %i4, %l1, %g0 ! check if second byte was zero 130*0Sstevel@tonic-gate b,a .doneq 131*0Sstevel@tonic-gate1: bnz 1f 132*0Sstevel@tonic-gate andcc %i4, %l2, %g0 ! check if third byte was zero 133*0Sstevel@tonic-gate b,a .doneq 134*0Sstevel@tonic-gate1: bnz 1f 135*0Sstevel@tonic-gate andcc %i4, 0xff, %g0 ! check if last byte is zero 136*0Sstevel@tonic-gate b,a .doneq 137*0Sstevel@tonic-gate1: bnz 2b 138*0Sstevel@tonic-gate sll %i3, 24, %i5 139*0Sstevel@tonic-gate b,a .doneq 140*0Sstevel@tonic-gate 141*0Sstevel@tonic-gate.w1cmp: clr %l4 142*0Sstevel@tonic-gate lduh [%i1], %l4 143*0Sstevel@tonic-gate inc 2, %i1 144*0Sstevel@tonic-gate sll %l4, 8, %l4 145*0Sstevel@tonic-gate or %i5, %l4, %i5 146*0Sstevel@tonic-gate 147*0Sstevel@tonic-gate sub %i0, %i1, %i0 148*0Sstevel@tonic-gate3: 149*0Sstevel@tonic-gate deccc 4, %i2 ! n >= 4 ? 150*0Sstevel@tonic-gate bgeu,a 4f 151*0Sstevel@tonic-gate ld [%i1], %i3 ! delay slot 152*0Sstevel@tonic-gate dec 3, %i1 ! reset s2 153*0Sstevel@tonic-gate inc 3, %i0 ! reset s1 diff 154*0Sstevel@tonic-gate b .cmp_bytes ! do a byte at a time if n < 4 155*0Sstevel@tonic-gate inc 4, %i2 156*0Sstevel@tonic-gate4: 157*0Sstevel@tonic-gate ld [%i0 + %i1], %i4 158*0Sstevel@tonic-gate inc 4, %i1 159*0Sstevel@tonic-gate srl %i3, 24, %l4 ! merge with the other half 160*0Sstevel@tonic-gate or %l4, %i5, %i5 161*0Sstevel@tonic-gate cmp %i4, %i5 162*0Sstevel@tonic-gate be 1f 163*0Sstevel@tonic-gate 164*0Sstevel@tonic-gate add %i4, %l6, %l3 165*0Sstevel@tonic-gate b,a .noteq 166*0Sstevel@tonic-gate1: xor %l3, %i4, %l3 167*0Sstevel@tonic-gate and %l3, %l7, %l3 168*0Sstevel@tonic-gate cmp %l3, %l7 169*0Sstevel@tonic-gate be,a 3b 170*0Sstevel@tonic-gate sll %i3, 8, %i5 171*0Sstevel@tonic-gate 172*0Sstevel@tonic-gate andcc %i4, %l0, %g0 ! check if first byte was zero 173*0Sstevel@tonic-gate bnz 1f 174*0Sstevel@tonic-gate andcc %i4, %l1, %g0 ! check if second byte was zero 175*0Sstevel@tonic-gate b,a .doneq 176*0Sstevel@tonic-gate1: bnz 1f 177*0Sstevel@tonic-gate andcc %i4, %l2, %g0 ! check if third byte was zero 178*0Sstevel@tonic-gate b,a .doneq 179*0Sstevel@tonic-gate1: bnz 1f 180*0Sstevel@tonic-gate andcc %i4, 0xff, %g0 ! check if last byte is zero 181*0Sstevel@tonic-gate b,a .doneq 182*0Sstevel@tonic-gate1: bnz 3b 183*0Sstevel@tonic-gate sll %i3, 8, %i5 184*0Sstevel@tonic-gate b,a .doneq 185*0Sstevel@tonic-gate 186*0Sstevel@tonic-gate.w2cmp: 187*0Sstevel@tonic-gate lduh [%i1], %i5 ! read a halfword to align s2 188*0Sstevel@tonic-gate inc 2, %i1 189*0Sstevel@tonic-gate sll %i5, 16, %i5 190*0Sstevel@tonic-gate 191*0Sstevel@tonic-gate sub %i0, %i1, %i0 192*0Sstevel@tonic-gate4: 193*0Sstevel@tonic-gate deccc 4, %i2 ! n >= 4 ? 194*0Sstevel@tonic-gate bgeu,a 5f 195*0Sstevel@tonic-gate ld [%i1], %i3 ! delay slot 196*0Sstevel@tonic-gate dec 2, %i1 ! reset s2 197*0Sstevel@tonic-gate inc 2, %i0 ! reset s1 diff 198*0Sstevel@tonic-gate b .cmp_bytes ! do a byte at a time if n < 4 199*0Sstevel@tonic-gate inc 4, %i2 ! delay slot 200*0Sstevel@tonic-gate5: 201*0Sstevel@tonic-gate ld [%i1 + %i0], %i4 ! read a word from s2 202*0Sstevel@tonic-gate inc 4, %i1 203*0Sstevel@tonic-gate srl %i3, 16, %l4 ! merge with the other half 204*0Sstevel@tonic-gate or %l4, %i5, %i5 205*0Sstevel@tonic-gate cmp %i4, %i5 206*0Sstevel@tonic-gate be 1f 207*0Sstevel@tonic-gate 208*0Sstevel@tonic-gate add %i4, %l6, %l3 209*0Sstevel@tonic-gate b,a .noteq 210*0Sstevel@tonic-gate1: xor %l3, %i4, %l3 ! are any bytes 0? 211*0Sstevel@tonic-gate and %l3, %l7, %l3 212*0Sstevel@tonic-gate cmp %l3, %l7 213*0Sstevel@tonic-gate be,a 4b 214*0Sstevel@tonic-gate sll %i3, 16, %i5 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gate andcc %i4, %l0, %g0 ! check if first byte was zero 217*0Sstevel@tonic-gate bnz 1f 218*0Sstevel@tonic-gate andcc %i4, %l1, %g0 ! check if second byte was zero 219*0Sstevel@tonic-gate b,a .doneq 220*0Sstevel@tonic-gate1: bnz 1f 221*0Sstevel@tonic-gate andcc %i4, %l2, %g0 ! check if third byte was zero 222*0Sstevel@tonic-gate b,a .doneq 223*0Sstevel@tonic-gate1: bnz 1f 224*0Sstevel@tonic-gate andcc %i4, 0xff, %g0 ! check if last byte is zero 225*0Sstevel@tonic-gate b,a .doneq 226*0Sstevel@tonic-gate1: bnz 4b 227*0Sstevel@tonic-gate sll %i3, 16, %i5 228*0Sstevel@tonic-gate b,a .doneq 229*0Sstevel@tonic-gate 230*0Sstevel@tonic-gate.w4cmp: sub %i0, %i1, %i0 231*0Sstevel@tonic-gate ld [%i1], %i5 ! read a word from s1 232*0Sstevel@tonic-gate5: cmp %i2,0 233*0Sstevel@tonic-gate be,a .doneq 234*0Sstevel@tonic-gate nop 235*0Sstevel@tonic-gate ld [%i1], %i5 ! read a word from s1 236*0Sstevel@tonic-gate deccc 4, %i2 ! n >= 4 ? 237*0Sstevel@tonic-gate bcs,a .cmp_bytes ! do a byte at a time if n < 4 238*0Sstevel@tonic-gate inc 4, %i2 239*0Sstevel@tonic-gate 240*0Sstevel@tonic-gate ld [%i1 + %i0], %i4 ! read a word from s2 241*0Sstevel@tonic-gate cmp %i4, %i5 242*0Sstevel@tonic-gate inc 4, %i1 243*0Sstevel@tonic-gate be 1f 244*0Sstevel@tonic-gate 245*0Sstevel@tonic-gate add %i4, %l6, %l3 246*0Sstevel@tonic-gate b,a .noteq 247*0Sstevel@tonic-gate1: xor %l3, %i4, %l3 248*0Sstevel@tonic-gate and %l3, %l7, %l3 249*0Sstevel@tonic-gate cmp %l3, %l7 250*0Sstevel@tonic-gate be,a 5b 251*0Sstevel@tonic-gate nop 252*0Sstevel@tonic-gate 253*0Sstevel@tonic-gate andcc %i4, %l0, %g0 ! check if first byte was zero 254*0Sstevel@tonic-gate bnz 1f 255*0Sstevel@tonic-gate andcc %i4, %l1, %g0 ! check if second byte was zero 256*0Sstevel@tonic-gate b,a .doneq 257*0Sstevel@tonic-gate1: bnz 1f 258*0Sstevel@tonic-gate andcc %i4, %l2, %g0 ! check if third byte was zero 259*0Sstevel@tonic-gate b,a .doneq 260*0Sstevel@tonic-gate1: bnz 1f 261*0Sstevel@tonic-gate andcc %i4, 0xff, %g0 ! check if last byte is zero 262*0Sstevel@tonic-gate b,a .doneq 263*0Sstevel@tonic-gate1: bnz,a 5b 264*0Sstevel@tonic-gate ld [%i1], %i5 265*0Sstevel@tonic-gate.doneq: ret 266*0Sstevel@tonic-gate restore %g0, %g0, %o0 ! equal return zero 267*0Sstevel@tonic-gate 268*0Sstevel@tonic-gate.noteq: srl %i4, 24, %l4 269*0Sstevel@tonic-gate srl %i5, 24, %l5 270*0Sstevel@tonic-gate subcc %l4, %l5, %i0 271*0Sstevel@tonic-gate bne 6f 272*0Sstevel@tonic-gate andcc %l4, 0xff, %g0 273*0Sstevel@tonic-gate bz .doneq 274*0Sstevel@tonic-gate sll %i4, 8, %l4 275*0Sstevel@tonic-gate sll %i5, 8, %l5 276*0Sstevel@tonic-gate srl %l4, 24, %l4 277*0Sstevel@tonic-gate srl %l5, 24, %l5 278*0Sstevel@tonic-gate subcc %l4, %l5, %i0 279*0Sstevel@tonic-gate bne 6f 280*0Sstevel@tonic-gate andcc %l4, 0xff, %g0 281*0Sstevel@tonic-gate bz .doneq 282*0Sstevel@tonic-gate sll %i4, 16, %l4 283*0Sstevel@tonic-gate sll %i5, 16, %l5 284*0Sstevel@tonic-gate srl %l4, 24, %l4 285*0Sstevel@tonic-gate srl %l5, 24, %l5 286*0Sstevel@tonic-gate subcc %l4, %l5, %i0 287*0Sstevel@tonic-gate bne 6f 288*0Sstevel@tonic-gate andcc %l4, 0xff, %g0 289*0Sstevel@tonic-gate bz .doneq 290*0Sstevel@tonic-gate nop 291*0Sstevel@tonic-gate.noteqb: 292*0Sstevel@tonic-gate and %i4, 0xff, %l4 293*0Sstevel@tonic-gate and %i5, 0xff, %l5 294*0Sstevel@tonic-gate subcc %l4, %l5, %i0 295*0Sstevel@tonic-gate6: ret 296*0Sstevel@tonic-gate restore %i0, %g0, %o0 297*0Sstevel@tonic-gate 298*0Sstevel@tonic-gate ! Do a byte by byte comparison, disregarding alignments 299*0Sstevel@tonic-gate.cmp_bytes: 300*0Sstevel@tonic-gate deccc %i2 ! --n >= 0 ? 301*0Sstevel@tonic-gate1: 302*0Sstevel@tonic-gate bcs .doneq 303*0Sstevel@tonic-gate nop ! delay slot 304*0Sstevel@tonic-gate ldub [%i1 + %i0], %i4 ! read a word from s1 305*0Sstevel@tonic-gate ldub [%i1], %i5 ! read a word from s2 306*0Sstevel@tonic-gate 307*0Sstevel@tonic-gate inc %i1 308*0Sstevel@tonic-gate cmp %i4, %i5 309*0Sstevel@tonic-gate bne .noteqb 310*0Sstevel@tonic-gate tst %i4 ! terminating zero 311*0Sstevel@tonic-gate bnz 1b 312*0Sstevel@tonic-gate deccc %i2 ! --n >= 0 313*0Sstevel@tonic-gate b,a .doneq 314*0Sstevel@tonic-gate 315*0Sstevel@tonic-gate SET_SIZE(strncmp) 316