10Sstevel@tonic-gate/* 2*10583SEdward.Gillett@Sun.COM * CDDL HEADER START 3*10583SEdward.Gillett@Sun.COM * 4*10583SEdward.Gillett@Sun.COM * The contents of this file are subject to the terms of the 5*10583SEdward.Gillett@Sun.COM * Common Development and Distribution License (the "License"). 6*10583SEdward.Gillett@Sun.COM * You may not use this file except in compliance with the License. 7*10583SEdward.Gillett@Sun.COM * 8*10583SEdward.Gillett@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*10583SEdward.Gillett@Sun.COM * or http://www.opensolaris.org/os/licensing. 10*10583SEdward.Gillett@Sun.COM * See the License for the specific language governing permissions 11*10583SEdward.Gillett@Sun.COM * and limitations under the License. 12*10583SEdward.Gillett@Sun.COM * 13*10583SEdward.Gillett@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each 14*10583SEdward.Gillett@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*10583SEdward.Gillett@Sun.COM * If applicable, add the following below this CDDL HEADER, with the 16*10583SEdward.Gillett@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying 17*10583SEdward.Gillett@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner] 18*10583SEdward.Gillett@Sun.COM * 19*10583SEdward.Gillett@Sun.COM * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate 220Sstevel@tonic-gate/* 23*10583SEdward.Gillett@Sun.COM * Copyright (c) 2009, Intel Corporation 240Sstevel@tonic-gate * All rights reserved. 250Sstevel@tonic-gate */ 260Sstevel@tonic-gate 27*10583SEdward.Gillett@Sun.COM/* 28*10583SEdward.Gillett@Sun.COM * str[n]cmp - compare chars between two string 29*10583SEdward.Gillett@Sun.COM */ 300Sstevel@tonic-gate 310Sstevel@tonic-gate#include "SYS.h" 32*10583SEdward.Gillett@Sun.COM#include "proc64_id.h" 330Sstevel@tonic-gate 340Sstevel@tonic-gate#define LABEL(s) .strcmp/**/s 350Sstevel@tonic-gate 360Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 37*10583SEdward.Gillett@Sun.COM /* 38*10583SEdward.Gillett@Sun.COM * Since the counter, %r11, is unsigned, we branch to strcmp_exitz 39*10583SEdward.Gillett@Sun.COM * if the new counter > the old one or is 0. 40*10583SEdward.Gillett@Sun.COM */ 41*10583SEdward.Gillett@Sun.COM#define UPDATE_STRNCMP_COUNTER \ 42*10583SEdward.Gillett@Sun.COM /* calculate left number to compare */ \ 43*10583SEdward.Gillett@Sun.COM lea -16(%rcx, %r11), %r9; \ 44*10583SEdward.Gillett@Sun.COM cmp %r9, %r11; \ 45*10583SEdward.Gillett@Sun.COM jb LABEL(strcmp_exitz); \ 46*10583SEdward.Gillett@Sun.COM test %r9, %r9; \ 47*10583SEdward.Gillett@Sun.COM je LABEL(strcmp_exitz); \ 48*10583SEdward.Gillett@Sun.COM mov %r9, %r11 49*10583SEdward.Gillett@Sun.COM#else 50*10583SEdward.Gillett@Sun.COM#define UPDATE_STRNCMP_COUNTER 51*10583SEdward.Gillett@Sun.COM#endif 52*10583SEdward.Gillett@Sun.COM 53*10583SEdward.Gillett@Sun.COM /* 54*10583SEdward.Gillett@Sun.COM * This implementation uses SSE to compare up to 16 bytes at a time. 55*10583SEdward.Gillett@Sun.COM */ 56*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 570Sstevel@tonic-gate ENTRY(strncmp) 58*10583SEdward.Gillett@Sun.COM test %rdx, %rdx 59*10583SEdward.Gillett@Sun.COM je LABEL(strcmp_exitz) 60*10583SEdward.Gillett@Sun.COM mov %rdx, %r11 610Sstevel@tonic-gate#else 620Sstevel@tonic-gate ENTRY(strcmp) /* (const char *, const char *) */ 630Sstevel@tonic-gate#endif 64*10583SEdward.Gillett@Sun.COM mov %esi, %ecx 65*10583SEdward.Gillett@Sun.COM mov %edi, %eax 66*10583SEdward.Gillett@Sun.COM and $0x3f, %rcx /* rsi alignment in cache line */ 67*10583SEdward.Gillett@Sun.COM and $0x3f, %rax /* rdi alignment in cache line */ 68*10583SEdward.Gillett@Sun.COM cmp $0x30, %ecx 69*10583SEdward.Gillett@Sun.COM ja LABEL(crosscache) /* rsi: 16-byte load will cross cache line */ 70*10583SEdward.Gillett@Sun.COM cmp $0x30, %eax 71*10583SEdward.Gillett@Sun.COM ja LABEL(crosscache) /* rdi: 16-byte load will cross cache line */ 72*10583SEdward.Gillett@Sun.COM movlpd (%rdi), %xmm1 73*10583SEdward.Gillett@Sun.COM movlpd (%rsi), %xmm2 74*10583SEdward.Gillett@Sun.COM movhpd 8(%rdi), %xmm1 75*10583SEdward.Gillett@Sun.COM movhpd 8(%rsi), %xmm2 76*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 /* clear %xmm0 for null char checks */ 77*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 /* Any null chars? */ 78*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 /* compare first 16 bytes for equality */ 79*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 /* packed sub of comparison results*/ 80*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 81*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx /* if first 16 bytes are same, edx == 0xffff */ 82*10583SEdward.Gillett@Sun.COM jnz LABEL(less16bytes) /* If not, found mismatch or null char */ 83*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 84*10583SEdward.Gillett@Sun.COM sub $16, %r11 85*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) /* finish comparision */ 86*10583SEdward.Gillett@Sun.COM#endif 87*10583SEdward.Gillett@Sun.COM add $16, %rsi /* prepare to search next 16 bytes */ 88*10583SEdward.Gillett@Sun.COM add $16, %rdi /* prepare to search next 16 bytes */ 89*10583SEdward.Gillett@Sun.COM 90*10583SEdward.Gillett@Sun.COM /* 91*10583SEdward.Gillett@Sun.COM * Determine rdi and rsi string offsets from 16-byte alignment. 92*10583SEdward.Gillett@Sun.COM * Use relative offset difference between the two to determine which case 93*10583SEdward.Gillett@Sun.COM * below to use. 94*10583SEdward.Gillett@Sun.COM */ 95*10583SEdward.Gillett@Sun.COM .p2align 4 96*10583SEdward.Gillett@Sun.COMLABEL(crosscache): 97*10583SEdward.Gillett@Sun.COM and $0xfffffffffffffff0, %rsi /* force %rsi to be 16 byte aligned */ 98*10583SEdward.Gillett@Sun.COM and $0xfffffffffffffff0, %rdi /* force %rdi to be 16 byte aligned */ 99*10583SEdward.Gillett@Sun.COM mov $0xffff, %edx /* for equivalent offset */ 100*10583SEdward.Gillett@Sun.COM xor %r8d, %r8d 101*10583SEdward.Gillett@Sun.COM and $0xf, %ecx /* offset of rsi */ 102*10583SEdward.Gillett@Sun.COM and $0xf, %eax /* offset of rdi */ 103*10583SEdward.Gillett@Sun.COM cmp %eax, %ecx 104*10583SEdward.Gillett@Sun.COM je LABEL(ashr_0) /* both strings have the same alignment */ 105*10583SEdward.Gillett@Sun.COM ja LABEL(bigger) 106*10583SEdward.Gillett@Sun.COM mov %edx, %r8d /* r8d is offset flag for exit tail */ 107*10583SEdward.Gillett@Sun.COM xchg %ecx, %eax 108*10583SEdward.Gillett@Sun.COM xchg %rsi, %rdi 109*10583SEdward.Gillett@Sun.COMLABEL(bigger): 110*10583SEdward.Gillett@Sun.COM mov %rcx, %r9 111*10583SEdward.Gillett@Sun.COM sub %rax, %r9 112*10583SEdward.Gillett@Sun.COM lea LABEL(unaligned_table)(%rip), %r10 113*10583SEdward.Gillett@Sun.COM movslq (%r10, %r9, 4), %r9 114*10583SEdward.Gillett@Sun.COM lea (%r10, %r9), %r10 115*10583SEdward.Gillett@Sun.COM jmp *%r10 /* jump to corresponding case */ 116*10583SEdward.Gillett@Sun.COM 117*10583SEdward.Gillett@Sun.COM/* 118*10583SEdward.Gillett@Sun.COM * ashr_0 handles the following cases: 119*10583SEdward.Gillett@Sun.COM * str1 offset = str2 offset 120*10583SEdward.Gillett@Sun.COM */ 121*10583SEdward.Gillett@Sun.COM .p2align 4 122*10583SEdward.Gillett@Sun.COMLABEL(ashr_0): 123*10583SEdward.Gillett@Sun.COM movdqa (%rsi), %xmm1 124*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 /* clear %xmm0 for null char check */ 125*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 /* Any null chars? */ 126*10583SEdward.Gillett@Sun.COM pcmpeqb (%rdi), %xmm1 /* compare 16 bytes for equality */ 127*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 /* packed sub of comparison results*/ 128*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %r9d 129*10583SEdward.Gillett@Sun.COM shr %cl, %edx /* adjust 0xffff for offset */ 130*10583SEdward.Gillett@Sun.COM shr %cl, %r9d /* adjust for 16-byte offset */ 131*10583SEdward.Gillett@Sun.COM sub %r9d, %edx 132*10583SEdward.Gillett@Sun.COM /* 133*10583SEdward.Gillett@Sun.COM * edx must be the same with r9d if in left byte (16-rcx) is equal to 134*10583SEdward.Gillett@Sun.COM * the start from (16-rax) and no null char was seen. 135*10583SEdward.Gillett@Sun.COM */ 136*10583SEdward.Gillett@Sun.COM jne LABEL(less32bytes) /* mismatch or null char */ 137*10583SEdward.Gillett@Sun.COM UPDATE_STRNCMP_COUNTER 138*10583SEdward.Gillett@Sun.COM mov $16, %rcx 139*10583SEdward.Gillett@Sun.COM mov $16, %r9 140*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 /* clear xmm0, may have changed above */ 141*10583SEdward.Gillett@Sun.COM 142*10583SEdward.Gillett@Sun.COM /* 143*10583SEdward.Gillett@Sun.COM * Now both strings are aligned at 16-byte boundary. Loop over strings 144*10583SEdward.Gillett@Sun.COM * checking 32-bytes per iteration. 145*10583SEdward.Gillett@Sun.COM */ 146*10583SEdward.Gillett@Sun.COM .p2align 4 147*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_0): 148*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 149*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 150*10583SEdward.Gillett@Sun.COM 151*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 152*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 153*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 154*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 155*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 156*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) /* mismatch or null char seen */ 1570Sstevel@tonic-gate 1580Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 159*10583SEdward.Gillett@Sun.COM sub $16, %r11 160*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 1610Sstevel@tonic-gate#endif 162*10583SEdward.Gillett@Sun.COM add $16, %rcx 163*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 164*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 165*10583SEdward.Gillett@Sun.COM 166*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 167*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 168*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 169*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 170*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 171*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 172*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 173*10583SEdward.Gillett@Sun.COM sub $16, %r11 174*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 175*10583SEdward.Gillett@Sun.COM#endif 176*10583SEdward.Gillett@Sun.COM add $16, %rcx 177*10583SEdward.Gillett@Sun.COM jmp LABEL(loop_ashr_0) 1780Sstevel@tonic-gate 179*10583SEdward.Gillett@Sun.COM/* 180*10583SEdward.Gillett@Sun.COM * ashr_1 handles the following cases: 181*10583SEdward.Gillett@Sun.COM * abs(str1 offset - str2 offset) = 15 182*10583SEdward.Gillett@Sun.COM */ 183*10583SEdward.Gillett@Sun.COM .p2align 4 184*10583SEdward.Gillett@Sun.COMLABEL(ashr_1): 185*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 186*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm2 187*10583SEdward.Gillett@Sun.COM movdqa (%rsi), %xmm1 188*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 /* Any null chars? */ 189*10583SEdward.Gillett@Sun.COM pslldq $15, %xmm2 /* shift first string to align with second */ 190*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm2 /* compare 16 bytes for equality */ 191*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm2 /* packed sub of comparison results*/ 192*10583SEdward.Gillett@Sun.COM pmovmskb %xmm2, %r9d 193*10583SEdward.Gillett@Sun.COM shr %cl, %edx /* adjust 0xffff for offset */ 194*10583SEdward.Gillett@Sun.COM shr %cl, %r9d /* adjust for 16-byte offset */ 195*10583SEdward.Gillett@Sun.COM sub %r9d, %edx 196*10583SEdward.Gillett@Sun.COM jnz LABEL(less32bytes) /* mismatch or null char seen */ 197*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm3 198*10583SEdward.Gillett@Sun.COM UPDATE_STRNCMP_COUNTER 1990Sstevel@tonic-gate 200*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 201*10583SEdward.Gillett@Sun.COM mov $16, %rcx /* index for loads */ 202*10583SEdward.Gillett@Sun.COM mov $1, %r9d /* rdi bytes already examined. Used in exit code */ 203*10583SEdward.Gillett@Sun.COM /* 204*10583SEdward.Gillett@Sun.COM * Setup %r10 value allows us to detect crossing a page boundary. 205*10583SEdward.Gillett@Sun.COM * When %r10 goes positive we are crossing a page boundary and 206*10583SEdward.Gillett@Sun.COM * need to do a nibble. 207*10583SEdward.Gillett@Sun.COM */ 208*10583SEdward.Gillett@Sun.COM lea 1(%rdi), %r10 209*10583SEdward.Gillett@Sun.COM and $0xfff, %r10 /* offset into 4K page */ 210*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K pagesize */ 211*10583SEdward.Gillett@Sun.COM movdqa %xmm3, %xmm4 2120Sstevel@tonic-gate 213*10583SEdward.Gillett@Sun.COM .p2align 4 214*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_1): 215*10583SEdward.Gillett@Sun.COM add $16, %r10 216*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_1) /* cross page boundary */ 217*10583SEdward.Gillett@Sun.COM 218*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_1): 219*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 220*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 221*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 /* store for next cycle */ 2220Sstevel@tonic-gate 223*10583SEdward.Gillett@Sun.COM psrldq $1, %xmm3 224*10583SEdward.Gillett@Sun.COM pslldq $15, %xmm2 225*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 /* merge into one 16byte value */ 226*10583SEdward.Gillett@Sun.COM 227*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 228*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 229*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 230*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 231*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 232*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 2330Sstevel@tonic-gate 2340Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 235*10583SEdward.Gillett@Sun.COM sub $16, %r11 236*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 2370Sstevel@tonic-gate#endif 238*10583SEdward.Gillett@Sun.COM add $16, %rcx 239*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 240*10583SEdward.Gillett@Sun.COM 241*10583SEdward.Gillett@Sun.COM add $16, %r10 242*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_1) /* cross page boundary */ 2430Sstevel@tonic-gate 244*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 245*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 246*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 /* store for next cycle */ 2470Sstevel@tonic-gate 248*10583SEdward.Gillett@Sun.COM psrldq $1, %xmm3 249*10583SEdward.Gillett@Sun.COM pslldq $15, %xmm2 250*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 /* merge into one 16byte value */ 2510Sstevel@tonic-gate 252*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 253*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 254*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 255*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 256*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 257*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 2580Sstevel@tonic-gate 2597953SNobutomo.Nakano@Sun.COM#ifdef USE_AS_STRNCMP 260*10583SEdward.Gillett@Sun.COM sub $16, %r11 261*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 262*10583SEdward.Gillett@Sun.COM#endif 263*10583SEdward.Gillett@Sun.COM add $16, %rcx 264*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 265*10583SEdward.Gillett@Sun.COM jmp LABEL(loop_ashr_1) 266*10583SEdward.Gillett@Sun.COM 267*10583SEdward.Gillett@Sun.COM /* 268*10583SEdward.Gillett@Sun.COM * Nibble avoids loads across page boundary. This is to avoid a potential 269*10583SEdward.Gillett@Sun.COM * access into unmapped memory. 270*10583SEdward.Gillett@Sun.COM */ 271*10583SEdward.Gillett@Sun.COM .p2align 4 272*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_1): 273*10583SEdward.Gillett@Sun.COM psrldq $1, %xmm4 274*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 275*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 276*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm4, %xmm1 277*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 278*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 279*10583SEdward.Gillett@Sun.COM sub $0x7fff, %edx 280*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 281*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 282*10583SEdward.Gillett@Sun.COM cmp $15, %r11 283*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 284*10583SEdward.Gillett@Sun.COM#endif 285*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 286*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K from %r10 */ 287*10583SEdward.Gillett@Sun.COM jmp LABEL(gobble_ashr_1) 288*10583SEdward.Gillett@Sun.COM 289*10583SEdward.Gillett@Sun.COM/* 290*10583SEdward.Gillett@Sun.COM * ashr_2 handles the following cases: 291*10583SEdward.Gillett@Sun.COM * abs(str1 offset - str2 offset) = 14 292*10583SEdward.Gillett@Sun.COM */ 293*10583SEdward.Gillett@Sun.COM .p2align 4 294*10583SEdward.Gillett@Sun.COMLABEL(ashr_2): 295*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 296*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm2 297*10583SEdward.Gillett@Sun.COM movdqa (%rsi), %xmm1 298*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 299*10583SEdward.Gillett@Sun.COM pslldq $14, %xmm2 300*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm2 301*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm2 302*10583SEdward.Gillett@Sun.COM pmovmskb %xmm2, %r9d 303*10583SEdward.Gillett@Sun.COM shr %cl, %edx 304*10583SEdward.Gillett@Sun.COM shr %cl, %r9d 305*10583SEdward.Gillett@Sun.COM sub %r9d, %edx 306*10583SEdward.Gillett@Sun.COM jnz LABEL(less32bytes) 307*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm3 308*10583SEdward.Gillett@Sun.COM UPDATE_STRNCMP_COUNTER 309*10583SEdward.Gillett@Sun.COM 310*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 311*10583SEdward.Gillett@Sun.COM mov $16, %rcx /* index for loads */ 312*10583SEdward.Gillett@Sun.COM mov $2, %r9d /* rdi bytes already examined. Used in exit code */ 313*10583SEdward.Gillett@Sun.COM /* 314*10583SEdward.Gillett@Sun.COM * Setup %r10 value allows us to detect crossing a page boundary. 315*10583SEdward.Gillett@Sun.COM * When %r10 goes positive we are crossing a page boundary and 316*10583SEdward.Gillett@Sun.COM * need to do a nibble. 317*10583SEdward.Gillett@Sun.COM */ 318*10583SEdward.Gillett@Sun.COM lea 2(%rdi), %r10 319*10583SEdward.Gillett@Sun.COM and $0xfff, %r10 /* offset into 4K page */ 320*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K pagesize */ 321*10583SEdward.Gillett@Sun.COM movdqa %xmm3, %xmm4 322*10583SEdward.Gillett@Sun.COM 323*10583SEdward.Gillett@Sun.COM .p2align 4 324*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_2): 325*10583SEdward.Gillett@Sun.COM add $16, %r10 326*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_2) 327*10583SEdward.Gillett@Sun.COM 328*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_2): 329*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 330*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 331*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 332*10583SEdward.Gillett@Sun.COM 333*10583SEdward.Gillett@Sun.COM psrldq $2, %xmm3 334*10583SEdward.Gillett@Sun.COM pslldq $14, %xmm2 335*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 336*10583SEdward.Gillett@Sun.COM 337*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 338*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 339*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 340*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 341*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 342*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 343*10583SEdward.Gillett@Sun.COM 344*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 345*10583SEdward.Gillett@Sun.COM sub $16, %r11 346*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 3477953SNobutomo.Nakano@Sun.COM#endif 3487953SNobutomo.Nakano@Sun.COM 349*10583SEdward.Gillett@Sun.COM add $16, %rcx 350*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 3510Sstevel@tonic-gate 352*10583SEdward.Gillett@Sun.COM add $16, %r10 353*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_2) /* cross page boundary */ 354*10583SEdward.Gillett@Sun.COM 355*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 356*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 357*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 3580Sstevel@tonic-gate 359*10583SEdward.Gillett@Sun.COM psrldq $2, %xmm3 360*10583SEdward.Gillett@Sun.COM pslldq $14, %xmm2 361*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 3620Sstevel@tonic-gate 363*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 364*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 365*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 366*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 367*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 368*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 3690Sstevel@tonic-gate 3700Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 371*10583SEdward.Gillett@Sun.COM sub $16, %r11 372*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 3730Sstevel@tonic-gate#endif 3740Sstevel@tonic-gate 375*10583SEdward.Gillett@Sun.COM add $16, %rcx 376*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 377*10583SEdward.Gillett@Sun.COM jmp LABEL(loop_ashr_2) 3780Sstevel@tonic-gate 379*10583SEdward.Gillett@Sun.COM .p2align 4 380*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_2): 381*10583SEdward.Gillett@Sun.COM psrldq $2, %xmm4 382*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 383*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 384*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm4, %xmm1 385*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 386*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 387*10583SEdward.Gillett@Sun.COM sub $0x3fff, %edx 388*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 389*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 390*10583SEdward.Gillett@Sun.COM cmp $14, %r11 391*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 392*10583SEdward.Gillett@Sun.COM#endif 393*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 394*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K from %r10 */ 395*10583SEdward.Gillett@Sun.COM jmp LABEL(gobble_ashr_2) 3960Sstevel@tonic-gate 397*10583SEdward.Gillett@Sun.COM/* 398*10583SEdward.Gillett@Sun.COM * ashr_3 handles the following cases: 399*10583SEdward.Gillett@Sun.COM * abs(str1 offset - str2 offset) = 13 400*10583SEdward.Gillett@Sun.COM */ 401*10583SEdward.Gillett@Sun.COM .p2align 4 402*10583SEdward.Gillett@Sun.COMLABEL(ashr_3): 403*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 404*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm2 405*10583SEdward.Gillett@Sun.COM movdqa (%rsi), %xmm1 406*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 407*10583SEdward.Gillett@Sun.COM pslldq $13, %xmm2 408*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm2 409*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm2 410*10583SEdward.Gillett@Sun.COM pmovmskb %xmm2, %r9d 411*10583SEdward.Gillett@Sun.COM shr %cl, %edx 412*10583SEdward.Gillett@Sun.COM shr %cl, %r9d 413*10583SEdward.Gillett@Sun.COM sub %r9d, %edx 414*10583SEdward.Gillett@Sun.COM jnz LABEL(less32bytes) 415*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm3 416*10583SEdward.Gillett@Sun.COM 417*10583SEdward.Gillett@Sun.COM UPDATE_STRNCMP_COUNTER 4180Sstevel@tonic-gate 419*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 420*10583SEdward.Gillett@Sun.COM mov $16, %rcx /* index for loads */ 421*10583SEdward.Gillett@Sun.COM mov $3, %r9d /* rdi bytes already examined. Used in exit code */ 422*10583SEdward.Gillett@Sun.COM /* 423*10583SEdward.Gillett@Sun.COM * Setup %r10 value allows us to detect crossing a page boundary. 424*10583SEdward.Gillett@Sun.COM * When %r10 goes positive we are crossing a page boundary and 425*10583SEdward.Gillett@Sun.COM * need to do a nibble. 426*10583SEdward.Gillett@Sun.COM */ 427*10583SEdward.Gillett@Sun.COM lea 3(%rdi), %r10 428*10583SEdward.Gillett@Sun.COM and $0xfff, %r10 /* offset into 4K page */ 429*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K pagesize */ 430*10583SEdward.Gillett@Sun.COM movdqa %xmm3, %xmm4 4310Sstevel@tonic-gate 432*10583SEdward.Gillett@Sun.COM .p2align 4 433*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_3): 434*10583SEdward.Gillett@Sun.COM add $16, %r10 435*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_3) 436*10583SEdward.Gillett@Sun.COM 437*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_3): 438*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 439*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 440*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 441*10583SEdward.Gillett@Sun.COM 442*10583SEdward.Gillett@Sun.COM psrldq $3, %xmm3 443*10583SEdward.Gillett@Sun.COM pslldq $13, %xmm2 444*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 445*10583SEdward.Gillett@Sun.COM 446*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 447*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 448*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 449*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 450*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 451*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 4520Sstevel@tonic-gate 4530Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 454*10583SEdward.Gillett@Sun.COM sub $16, %r11 455*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 456*10583SEdward.Gillett@Sun.COM#endif 457*10583SEdward.Gillett@Sun.COM 458*10583SEdward.Gillett@Sun.COM add $16, %rcx 459*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 460*10583SEdward.Gillett@Sun.COM 461*10583SEdward.Gillett@Sun.COM add $16, %r10 462*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_3) /* cross page boundary */ 463*10583SEdward.Gillett@Sun.COM 464*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 465*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 466*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 467*10583SEdward.Gillett@Sun.COM 468*10583SEdward.Gillett@Sun.COM psrldq $3, %xmm3 469*10583SEdward.Gillett@Sun.COM pslldq $13, %xmm2 470*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 471*10583SEdward.Gillett@Sun.COM 472*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 473*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 474*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 475*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 476*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 477*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 478*10583SEdward.Gillett@Sun.COM 479*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 480*10583SEdward.Gillett@Sun.COM sub $16, %r11 481*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 4820Sstevel@tonic-gate#endif 4830Sstevel@tonic-gate 484*10583SEdward.Gillett@Sun.COM add $16, %rcx 485*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 486*10583SEdward.Gillett@Sun.COM jmp LABEL(loop_ashr_3) 487*10583SEdward.Gillett@Sun.COM 488*10583SEdward.Gillett@Sun.COM .p2align 4 489*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_3): 490*10583SEdward.Gillett@Sun.COM psrldq $3, %xmm4 491*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 492*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 493*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm4, %xmm1 494*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 495*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 496*10583SEdward.Gillett@Sun.COM sub $0x1fff, %edx 497*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 498*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 499*10583SEdward.Gillett@Sun.COM cmp $13, %r11 500*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 501*10583SEdward.Gillett@Sun.COM#endif 502*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 503*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K from %r10 */ 504*10583SEdward.Gillett@Sun.COM jmp LABEL(gobble_ashr_3) 5050Sstevel@tonic-gate 506*10583SEdward.Gillett@Sun.COM/* 507*10583SEdward.Gillett@Sun.COM * ashr_4 handles the following cases: 508*10583SEdward.Gillett@Sun.COM * abs(str1 offset - str2 offset) = 12 509*10583SEdward.Gillett@Sun.COM */ 510*10583SEdward.Gillett@Sun.COM .p2align 4 511*10583SEdward.Gillett@Sun.COMLABEL(ashr_4): 512*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 513*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm2 514*10583SEdward.Gillett@Sun.COM movdqa (%rsi), %xmm1 515*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 516*10583SEdward.Gillett@Sun.COM pslldq $12, %xmm2 517*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm2 518*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm2 519*10583SEdward.Gillett@Sun.COM pmovmskb %xmm2, %r9d 520*10583SEdward.Gillett@Sun.COM shr %cl, %edx 521*10583SEdward.Gillett@Sun.COM shr %cl, %r9d 522*10583SEdward.Gillett@Sun.COM sub %r9d, %edx 523*10583SEdward.Gillett@Sun.COM jnz LABEL(less32bytes) 524*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm3 525*10583SEdward.Gillett@Sun.COM 526*10583SEdward.Gillett@Sun.COM UPDATE_STRNCMP_COUNTER 5270Sstevel@tonic-gate 528*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 529*10583SEdward.Gillett@Sun.COM mov $16, %rcx /* index for loads */ 530*10583SEdward.Gillett@Sun.COM mov $4, %r9d /* rdi bytes already examined. Used in exit code */ 531*10583SEdward.Gillett@Sun.COM /* 532*10583SEdward.Gillett@Sun.COM * Setup %r10 value allows us to detect crossing a page boundary. 533*10583SEdward.Gillett@Sun.COM * When %r10 goes positive we are crossing a page boundary and 534*10583SEdward.Gillett@Sun.COM * need to do a nibble. 535*10583SEdward.Gillett@Sun.COM */ 536*10583SEdward.Gillett@Sun.COM lea 4(%rdi), %r10 537*10583SEdward.Gillett@Sun.COM and $0xfff, %r10 /* offset into 4K page */ 538*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K pagesize */ 539*10583SEdward.Gillett@Sun.COM movdqa %xmm3, %xmm4 540*10583SEdward.Gillett@Sun.COM 541*10583SEdward.Gillett@Sun.COM .p2align 4 542*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_4): 543*10583SEdward.Gillett@Sun.COM add $16, %r10 544*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_4) 545*10583SEdward.Gillett@Sun.COM 546*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_4): 547*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 548*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 549*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 550*10583SEdward.Gillett@Sun.COM 551*10583SEdward.Gillett@Sun.COM psrldq $4, %xmm3 552*10583SEdward.Gillett@Sun.COM pslldq $12, %xmm2 553*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 5540Sstevel@tonic-gate 555*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 556*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 557*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 558*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 559*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 560*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 561*10583SEdward.Gillett@Sun.COM 562*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 563*10583SEdward.Gillett@Sun.COM sub $16, %r11 564*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 565*10583SEdward.Gillett@Sun.COM#endif 566*10583SEdward.Gillett@Sun.COM 567*10583SEdward.Gillett@Sun.COM add $16, %rcx 568*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 5690Sstevel@tonic-gate 570*10583SEdward.Gillett@Sun.COM add $16, %r10 571*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_4) /* cross page boundary */ 572*10583SEdward.Gillett@Sun.COM 573*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 574*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 575*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 5760Sstevel@tonic-gate 577*10583SEdward.Gillett@Sun.COM psrldq $4, %xmm3 578*10583SEdward.Gillett@Sun.COM pslldq $12, %xmm2 579*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 580*10583SEdward.Gillett@Sun.COM 581*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 582*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 583*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 584*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 585*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 586*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 5870Sstevel@tonic-gate 5880Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 589*10583SEdward.Gillett@Sun.COM sub $16, %r11 590*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 5910Sstevel@tonic-gate#endif 5920Sstevel@tonic-gate 593*10583SEdward.Gillett@Sun.COM add $16, %rcx 594*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 595*10583SEdward.Gillett@Sun.COM jmp LABEL(loop_ashr_4) 596*10583SEdward.Gillett@Sun.COM 597*10583SEdward.Gillett@Sun.COM .p2align 4 598*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_4): 599*10583SEdward.Gillett@Sun.COM psrldq $4, %xmm4 600*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 601*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 602*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm4, %xmm1 603*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 604*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 605*10583SEdward.Gillett@Sun.COM sub $0x0fff, %edx 606*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 607*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 608*10583SEdward.Gillett@Sun.COM cmp $12, %r11 609*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 610*10583SEdward.Gillett@Sun.COM#endif 611*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 612*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K from %r10 */ 613*10583SEdward.Gillett@Sun.COM jmp LABEL(gobble_ashr_4) 6140Sstevel@tonic-gate 615*10583SEdward.Gillett@Sun.COM/* 616*10583SEdward.Gillett@Sun.COM * ashr_5 handles the following cases: 617*10583SEdward.Gillett@Sun.COM * abs(str1 offset - str2 offset) = 11 618*10583SEdward.Gillett@Sun.COM */ 619*10583SEdward.Gillett@Sun.COM .p2align 4 620*10583SEdward.Gillett@Sun.COMLABEL(ashr_5): 621*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 622*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm2 623*10583SEdward.Gillett@Sun.COM movdqa (%rsi), %xmm1 624*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 625*10583SEdward.Gillett@Sun.COM pslldq $11, %xmm2 626*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm2 627*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm2 628*10583SEdward.Gillett@Sun.COM pmovmskb %xmm2, %r9d 629*10583SEdward.Gillett@Sun.COM shr %cl, %edx 630*10583SEdward.Gillett@Sun.COM shr %cl, %r9d 631*10583SEdward.Gillett@Sun.COM sub %r9d, %edx 632*10583SEdward.Gillett@Sun.COM jnz LABEL(less32bytes) 633*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm3 634*10583SEdward.Gillett@Sun.COM 635*10583SEdward.Gillett@Sun.COM UPDATE_STRNCMP_COUNTER 6360Sstevel@tonic-gate 637*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 638*10583SEdward.Gillett@Sun.COM mov $16, %rcx /* index for loads */ 639*10583SEdward.Gillett@Sun.COM mov $5, %r9d /* rdi bytes already examined. Used in exit code */ 640*10583SEdward.Gillett@Sun.COM /* 641*10583SEdward.Gillett@Sun.COM * Setup %r10 value allows us to detect crossing a page boundary. 642*10583SEdward.Gillett@Sun.COM * When %r10 goes positive we are crossing a page boundary and 643*10583SEdward.Gillett@Sun.COM * need to do a nibble. 644*10583SEdward.Gillett@Sun.COM */ 645*10583SEdward.Gillett@Sun.COM lea 5(%rdi), %r10 646*10583SEdward.Gillett@Sun.COM and $0xfff, %r10 /* offset into 4K page */ 647*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K pagesize */ 648*10583SEdward.Gillett@Sun.COM movdqa %xmm3, %xmm4 649*10583SEdward.Gillett@Sun.COM 650*10583SEdward.Gillett@Sun.COM .p2align 4 651*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_5): 652*10583SEdward.Gillett@Sun.COM add $16, %r10 653*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_5) 654*10583SEdward.Gillett@Sun.COM 655*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_5): 656*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 657*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 658*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 659*10583SEdward.Gillett@Sun.COM 660*10583SEdward.Gillett@Sun.COM psrldq $5, %xmm3 661*10583SEdward.Gillett@Sun.COM pslldq $11, %xmm2 662*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 6630Sstevel@tonic-gate 664*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 665*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 666*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 667*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 668*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 669*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 670*10583SEdward.Gillett@Sun.COM 671*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 672*10583SEdward.Gillett@Sun.COM sub $16, %r11 673*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 674*10583SEdward.Gillett@Sun.COM#endif 675*10583SEdward.Gillett@Sun.COM 676*10583SEdward.Gillett@Sun.COM add $16, %rcx 677*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 6780Sstevel@tonic-gate 679*10583SEdward.Gillett@Sun.COM add $16, %r10 680*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_5) /* cross page boundary */ 681*10583SEdward.Gillett@Sun.COM 682*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 683*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 684*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 6850Sstevel@tonic-gate 686*10583SEdward.Gillett@Sun.COM psrldq $5, %xmm3 687*10583SEdward.Gillett@Sun.COM pslldq $11, %xmm2 688*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 689*10583SEdward.Gillett@Sun.COM 690*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 691*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 692*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 693*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 694*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 695*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 6960Sstevel@tonic-gate 6970Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 698*10583SEdward.Gillett@Sun.COM sub $16, %r11 699*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 7000Sstevel@tonic-gate#endif 7010Sstevel@tonic-gate 702*10583SEdward.Gillett@Sun.COM add $16, %rcx 703*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 704*10583SEdward.Gillett@Sun.COM jmp LABEL(loop_ashr_5) 705*10583SEdward.Gillett@Sun.COM 706*10583SEdward.Gillett@Sun.COM .p2align 4 707*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_5): 708*10583SEdward.Gillett@Sun.COM psrldq $5, %xmm4 709*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 710*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 711*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm4, %xmm1 712*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 713*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 714*10583SEdward.Gillett@Sun.COM sub $0x07ff, %edx 715*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 716*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 717*10583SEdward.Gillett@Sun.COM cmp $11, %r11 718*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 719*10583SEdward.Gillett@Sun.COM#endif 720*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 721*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K from %r10 */ 722*10583SEdward.Gillett@Sun.COM jmp LABEL(gobble_ashr_5) 7230Sstevel@tonic-gate 724*10583SEdward.Gillett@Sun.COM/* 725*10583SEdward.Gillett@Sun.COM * ashr_6 handles the following cases: 726*10583SEdward.Gillett@Sun.COM * abs(str1 offset - str2 offset) = 10 727*10583SEdward.Gillett@Sun.COM */ 728*10583SEdward.Gillett@Sun.COM .p2align 4 729*10583SEdward.Gillett@Sun.COMLABEL(ashr_6): 730*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 731*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm2 732*10583SEdward.Gillett@Sun.COM movdqa (%rsi), %xmm1 733*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 734*10583SEdward.Gillett@Sun.COM pslldq $10, %xmm2 735*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm2 736*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm2 737*10583SEdward.Gillett@Sun.COM pmovmskb %xmm2, %r9d 738*10583SEdward.Gillett@Sun.COM shr %cl, %edx 739*10583SEdward.Gillett@Sun.COM shr %cl, %r9d 740*10583SEdward.Gillett@Sun.COM sub %r9d, %edx 741*10583SEdward.Gillett@Sun.COM jnz LABEL(less32bytes) 742*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm3 743*10583SEdward.Gillett@Sun.COM 744*10583SEdward.Gillett@Sun.COM UPDATE_STRNCMP_COUNTER 7450Sstevel@tonic-gate 746*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 747*10583SEdward.Gillett@Sun.COM mov $16, %rcx /* index for loads */ 748*10583SEdward.Gillett@Sun.COM mov $6, %r9d /* rdi bytes already examined. Used in exit code */ 749*10583SEdward.Gillett@Sun.COM /* 750*10583SEdward.Gillett@Sun.COM * Setup %r10 value allows us to detect crossing a page boundary. 751*10583SEdward.Gillett@Sun.COM * When %r10 goes positive we are crossing a page boundary and 752*10583SEdward.Gillett@Sun.COM * need to do a nibble. 753*10583SEdward.Gillett@Sun.COM */ 754*10583SEdward.Gillett@Sun.COM lea 6(%rdi), %r10 755*10583SEdward.Gillett@Sun.COM and $0xfff, %r10 /* offset into 4K page */ 756*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K pagesize */ 757*10583SEdward.Gillett@Sun.COM movdqa %xmm3, %xmm4 758*10583SEdward.Gillett@Sun.COM 759*10583SEdward.Gillett@Sun.COM .p2align 4 760*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_6): 761*10583SEdward.Gillett@Sun.COM add $16, %r10 762*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_6) 763*10583SEdward.Gillett@Sun.COM 764*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_6): 765*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 766*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 767*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 768*10583SEdward.Gillett@Sun.COM 769*10583SEdward.Gillett@Sun.COM psrldq $6, %xmm3 770*10583SEdward.Gillett@Sun.COM pslldq $10, %xmm2 771*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 7720Sstevel@tonic-gate 773*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 774*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 775*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 776*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 777*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 778*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 779*10583SEdward.Gillett@Sun.COM 780*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 781*10583SEdward.Gillett@Sun.COM sub $16, %r11 782*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 783*10583SEdward.Gillett@Sun.COM#endif 784*10583SEdward.Gillett@Sun.COM 785*10583SEdward.Gillett@Sun.COM add $16, %rcx 786*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 7870Sstevel@tonic-gate 788*10583SEdward.Gillett@Sun.COM add $16, %r10 789*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_6) /* cross page boundary */ 790*10583SEdward.Gillett@Sun.COM 791*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 792*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 793*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 7940Sstevel@tonic-gate 795*10583SEdward.Gillett@Sun.COM psrldq $6, %xmm3 796*10583SEdward.Gillett@Sun.COM pslldq $10, %xmm2 797*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 798*10583SEdward.Gillett@Sun.COM 799*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 800*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 801*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 802*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 803*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 804*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 8050Sstevel@tonic-gate 8060Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 807*10583SEdward.Gillett@Sun.COM sub $16, %r11 808*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 809*10583SEdward.Gillett@Sun.COM#endif 810*10583SEdward.Gillett@Sun.COM 811*10583SEdward.Gillett@Sun.COM add $16, %rcx 812*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 813*10583SEdward.Gillett@Sun.COM jmp LABEL(loop_ashr_6) 814*10583SEdward.Gillett@Sun.COM 815*10583SEdward.Gillett@Sun.COM .p2align 4 816*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_6): 817*10583SEdward.Gillett@Sun.COM psrldq $6, %xmm4 818*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 819*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 820*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm4, %xmm1 821*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 822*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 823*10583SEdward.Gillett@Sun.COM sub $0x03ff, %edx 824*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 825*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 826*10583SEdward.Gillett@Sun.COM cmp $10, %r11 827*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 828*10583SEdward.Gillett@Sun.COM#endif 829*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 830*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K from %r10 */ 831*10583SEdward.Gillett@Sun.COM jmp LABEL(gobble_ashr_6) 832*10583SEdward.Gillett@Sun.COM 833*10583SEdward.Gillett@Sun.COM/* 834*10583SEdward.Gillett@Sun.COM * ashr_7 handles the following cases: 835*10583SEdward.Gillett@Sun.COM * abs(str1 offset - str2 offset) = 9 836*10583SEdward.Gillett@Sun.COM */ 837*10583SEdward.Gillett@Sun.COM .p2align 4 838*10583SEdward.Gillett@Sun.COMLABEL(ashr_7): 839*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 840*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm2 841*10583SEdward.Gillett@Sun.COM movdqa (%rsi), %xmm1 842*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 843*10583SEdward.Gillett@Sun.COM pslldq $9, %xmm2 844*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm2 845*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm2 846*10583SEdward.Gillett@Sun.COM pmovmskb %xmm2, %r9d 847*10583SEdward.Gillett@Sun.COM shr %cl, %edx 848*10583SEdward.Gillett@Sun.COM shr %cl, %r9d 849*10583SEdward.Gillett@Sun.COM sub %r9d, %edx 850*10583SEdward.Gillett@Sun.COM jnz LABEL(less32bytes) 851*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm3 852*10583SEdward.Gillett@Sun.COM 853*10583SEdward.Gillett@Sun.COM UPDATE_STRNCMP_COUNTER 854*10583SEdward.Gillett@Sun.COM 855*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 856*10583SEdward.Gillett@Sun.COM mov $16, %rcx /* index for loads */ 857*10583SEdward.Gillett@Sun.COM mov $7, %r9d /* rdi bytes already examined. Used in exit code */ 858*10583SEdward.Gillett@Sun.COM /* 859*10583SEdward.Gillett@Sun.COM * Setup %r10 value allows us to detect crossing a page boundary. 860*10583SEdward.Gillett@Sun.COM * When %r10 goes positive we are crossing a page boundary and 861*10583SEdward.Gillett@Sun.COM * need to do a nibble. 862*10583SEdward.Gillett@Sun.COM */ 863*10583SEdward.Gillett@Sun.COM lea 7(%rdi), %r10 864*10583SEdward.Gillett@Sun.COM and $0xfff, %r10 /* offset into 4K page */ 865*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K pagesize */ 866*10583SEdward.Gillett@Sun.COM movdqa %xmm3, %xmm4 867*10583SEdward.Gillett@Sun.COM 868*10583SEdward.Gillett@Sun.COM .p2align 4 869*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_7): 870*10583SEdward.Gillett@Sun.COM add $16, %r10 871*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_7) 872*10583SEdward.Gillett@Sun.COM 873*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_7): 874*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 875*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 876*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 877*10583SEdward.Gillett@Sun.COM 878*10583SEdward.Gillett@Sun.COM psrldq $7, %xmm3 879*10583SEdward.Gillett@Sun.COM pslldq $9, %xmm2 880*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 881*10583SEdward.Gillett@Sun.COM 882*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 883*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 884*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 885*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 886*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 887*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 888*10583SEdward.Gillett@Sun.COM 889*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 890*10583SEdward.Gillett@Sun.COM sub $16, %r11 891*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 8920Sstevel@tonic-gate#endif 8930Sstevel@tonic-gate 894*10583SEdward.Gillett@Sun.COM add $16, %rcx 895*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 8960Sstevel@tonic-gate 897*10583SEdward.Gillett@Sun.COM add $16, %r10 898*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_7) /* cross page boundary */ 899*10583SEdward.Gillett@Sun.COM 900*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 901*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 902*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 9030Sstevel@tonic-gate 904*10583SEdward.Gillett@Sun.COM psrldq $7, %xmm3 905*10583SEdward.Gillett@Sun.COM pslldq $9, %xmm2 906*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 9070Sstevel@tonic-gate 908*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 909*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 910*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 911*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 912*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 913*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 9140Sstevel@tonic-gate 9150Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 916*10583SEdward.Gillett@Sun.COM sub $16, %r11 917*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 918*10583SEdward.Gillett@Sun.COM#endif 919*10583SEdward.Gillett@Sun.COM 920*10583SEdward.Gillett@Sun.COM add $16, %rcx 921*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 922*10583SEdward.Gillett@Sun.COM jmp LABEL(loop_ashr_7) 923*10583SEdward.Gillett@Sun.COM 924*10583SEdward.Gillett@Sun.COM .p2align 4 925*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_7): 926*10583SEdward.Gillett@Sun.COM psrldq $7, %xmm4 927*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 928*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 929*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm4, %xmm1 930*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 931*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 932*10583SEdward.Gillett@Sun.COM sub $0x01ff, %edx 933*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 934*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 935*10583SEdward.Gillett@Sun.COM cmp $9, %r11 936*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 937*10583SEdward.Gillett@Sun.COM#endif 938*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 939*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K from %r10 */ 940*10583SEdward.Gillett@Sun.COM jmp LABEL(gobble_ashr_7) 941*10583SEdward.Gillett@Sun.COM 942*10583SEdward.Gillett@Sun.COM/* 943*10583SEdward.Gillett@Sun.COM * ashr_8 handles the following cases: 944*10583SEdward.Gillett@Sun.COM * abs(str1 offset - str2 offset) = 8 945*10583SEdward.Gillett@Sun.COM */ 946*10583SEdward.Gillett@Sun.COM .p2align 4 947*10583SEdward.Gillett@Sun.COMLABEL(ashr_8): 948*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 949*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm2 950*10583SEdward.Gillett@Sun.COM movdqa (%rsi), %xmm1 951*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 952*10583SEdward.Gillett@Sun.COM pslldq $8, %xmm2 953*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm2 954*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm2 955*10583SEdward.Gillett@Sun.COM pmovmskb %xmm2, %r9d 956*10583SEdward.Gillett@Sun.COM shr %cl, %edx 957*10583SEdward.Gillett@Sun.COM shr %cl, %r9d 958*10583SEdward.Gillett@Sun.COM sub %r9d, %edx 959*10583SEdward.Gillett@Sun.COM jnz LABEL(less32bytes) 960*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm3 961*10583SEdward.Gillett@Sun.COM 962*10583SEdward.Gillett@Sun.COM UPDATE_STRNCMP_COUNTER 963*10583SEdward.Gillett@Sun.COM 964*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 965*10583SEdward.Gillett@Sun.COM mov $16, %rcx /* index for loads */ 966*10583SEdward.Gillett@Sun.COM mov $8, %r9d /* rdi bytes already examined. Used in exit code */ 967*10583SEdward.Gillett@Sun.COM /* 968*10583SEdward.Gillett@Sun.COM * Setup %r10 value allows us to detect crossing a page boundary. 969*10583SEdward.Gillett@Sun.COM * When %r10 goes positive we are crossing a page boundary and 970*10583SEdward.Gillett@Sun.COM * need to do a nibble. 971*10583SEdward.Gillett@Sun.COM */ 972*10583SEdward.Gillett@Sun.COM lea 8(%rdi), %r10 973*10583SEdward.Gillett@Sun.COM and $0xfff, %r10 /* offset into 4K page */ 974*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K pagesize */ 975*10583SEdward.Gillett@Sun.COM movdqa %xmm3, %xmm4 976*10583SEdward.Gillett@Sun.COM 977*10583SEdward.Gillett@Sun.COM .p2align 4 978*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_8): 979*10583SEdward.Gillett@Sun.COM add $16, %r10 980*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_8) 981*10583SEdward.Gillett@Sun.COM 982*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_8): 983*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 984*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 985*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 986*10583SEdward.Gillett@Sun.COM 987*10583SEdward.Gillett@Sun.COM psrldq $8, %xmm3 988*10583SEdward.Gillett@Sun.COM pslldq $8, %xmm2 989*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 990*10583SEdward.Gillett@Sun.COM 991*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 992*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 993*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 994*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 995*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 996*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 997*10583SEdward.Gillett@Sun.COM 998*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 999*10583SEdward.Gillett@Sun.COM sub $16, %r11 1000*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 1001*10583SEdward.Gillett@Sun.COM#endif 1002*10583SEdward.Gillett@Sun.COM 1003*10583SEdward.Gillett@Sun.COM add $16, %rcx 1004*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 1005*10583SEdward.Gillett@Sun.COM 1006*10583SEdward.Gillett@Sun.COM add $16, %r10 1007*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_8) /* cross page boundary */ 1008*10583SEdward.Gillett@Sun.COM 1009*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1010*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 1011*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 1012*10583SEdward.Gillett@Sun.COM 1013*10583SEdward.Gillett@Sun.COM psrldq $8, %xmm3 1014*10583SEdward.Gillett@Sun.COM pslldq $8, %xmm2 1015*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 1016*10583SEdward.Gillett@Sun.COM 1017*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1018*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 1019*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1020*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1021*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 1022*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 1023*10583SEdward.Gillett@Sun.COM 1024*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 1025*10583SEdward.Gillett@Sun.COM sub $16, %r11 1026*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 10270Sstevel@tonic-gate#endif 10280Sstevel@tonic-gate 1029*10583SEdward.Gillett@Sun.COM add $16, %rcx 1030*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 1031*10583SEdward.Gillett@Sun.COM jmp LABEL(loop_ashr_8) 10320Sstevel@tonic-gate 1033*10583SEdward.Gillett@Sun.COM .p2align 4 1034*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_8): 1035*10583SEdward.Gillett@Sun.COM psrldq $8, %xmm4 1036*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1037*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1038*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm4, %xmm1 1039*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1040*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1041*10583SEdward.Gillett@Sun.COM sub $0x00ff, %edx 1042*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 1043*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 1044*10583SEdward.Gillett@Sun.COM cmp $8, %r11 1045*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 1046*10583SEdward.Gillett@Sun.COM#endif 1047*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 1048*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K from %r10 */ 1049*10583SEdward.Gillett@Sun.COM jmp LABEL(gobble_ashr_8) 10500Sstevel@tonic-gate 1051*10583SEdward.Gillett@Sun.COM/* 1052*10583SEdward.Gillett@Sun.COM * ashr_9 handles the following cases: 1053*10583SEdward.Gillett@Sun.COM * abs(str1 offset - str2 offset) = 7 1054*10583SEdward.Gillett@Sun.COM */ 1055*10583SEdward.Gillett@Sun.COM .p2align 4 1056*10583SEdward.Gillett@Sun.COMLABEL(ashr_9): 1057*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 1058*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm2 1059*10583SEdward.Gillett@Sun.COM movdqa (%rsi), %xmm1 1060*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1061*10583SEdward.Gillett@Sun.COM pslldq $7, %xmm2 1062*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm2 1063*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm2 1064*10583SEdward.Gillett@Sun.COM pmovmskb %xmm2, %r9d 1065*10583SEdward.Gillett@Sun.COM shr %cl, %edx 1066*10583SEdward.Gillett@Sun.COM shr %cl, %r9d 1067*10583SEdward.Gillett@Sun.COM sub %r9d, %edx 1068*10583SEdward.Gillett@Sun.COM jnz LABEL(less32bytes) 1069*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm3 1070*10583SEdward.Gillett@Sun.COM 1071*10583SEdward.Gillett@Sun.COM UPDATE_STRNCMP_COUNTER 10720Sstevel@tonic-gate 1073*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 1074*10583SEdward.Gillett@Sun.COM mov $16, %rcx /* index for loads */ 1075*10583SEdward.Gillett@Sun.COM mov $9, %r9d /* rdi bytes already examined. Used in exit code */ 1076*10583SEdward.Gillett@Sun.COM /* 1077*10583SEdward.Gillett@Sun.COM * Setup %r10 value allows us to detect crossing a page boundary. 1078*10583SEdward.Gillett@Sun.COM * When %r10 goes positive we are crossing a page boundary and 1079*10583SEdward.Gillett@Sun.COM * need to do a nibble. 1080*10583SEdward.Gillett@Sun.COM */ 1081*10583SEdward.Gillett@Sun.COM lea 9(%rdi), %r10 1082*10583SEdward.Gillett@Sun.COM and $0xfff, %r10 /* offset into 4K page */ 1083*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K pagesize */ 1084*10583SEdward.Gillett@Sun.COM movdqa %xmm3, %xmm4 10850Sstevel@tonic-gate 1086*10583SEdward.Gillett@Sun.COM .p2align 4 1087*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_9): 1088*10583SEdward.Gillett@Sun.COM add $16, %r10 1089*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_9) 1090*10583SEdward.Gillett@Sun.COM 1091*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_9): 1092*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1093*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 1094*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 10950Sstevel@tonic-gate 1096*10583SEdward.Gillett@Sun.COM psrldq $9, %xmm3 1097*10583SEdward.Gillett@Sun.COM pslldq $7, %xmm2 1098*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 1099*10583SEdward.Gillett@Sun.COM 1100*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1101*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 1102*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1103*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1104*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 1105*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 11060Sstevel@tonic-gate 11070Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 1108*10583SEdward.Gillett@Sun.COM sub $16, %r11 1109*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 1110*10583SEdward.Gillett@Sun.COM#endif 1111*10583SEdward.Gillett@Sun.COM 1112*10583SEdward.Gillett@Sun.COM add $16, %rcx 1113*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 1114*10583SEdward.Gillett@Sun.COM 1115*10583SEdward.Gillett@Sun.COM add $16, %r10 1116*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_9) /* cross page boundary */ 1117*10583SEdward.Gillett@Sun.COM 1118*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1119*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 1120*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 1121*10583SEdward.Gillett@Sun.COM 1122*10583SEdward.Gillett@Sun.COM psrldq $9, %xmm3 1123*10583SEdward.Gillett@Sun.COM pslldq $7, %xmm2 1124*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 1125*10583SEdward.Gillett@Sun.COM 1126*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1127*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 1128*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1129*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1130*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 1131*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 1132*10583SEdward.Gillett@Sun.COM 1133*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 1134*10583SEdward.Gillett@Sun.COM sub $16, %r11 1135*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 1136*10583SEdward.Gillett@Sun.COM#endif 1137*10583SEdward.Gillett@Sun.COM 1138*10583SEdward.Gillett@Sun.COM add $16, %rcx 1139*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 /* store for next cycle */ 1140*10583SEdward.Gillett@Sun.COM jmp LABEL(loop_ashr_9) 1141*10583SEdward.Gillett@Sun.COM 1142*10583SEdward.Gillett@Sun.COM .p2align 4 1143*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_9): 1144*10583SEdward.Gillett@Sun.COM psrldq $9, %xmm4 1145*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1146*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1147*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm4, %xmm1 1148*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1149*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1150*10583SEdward.Gillett@Sun.COM sub $0x007f, %edx 1151*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 1152*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 1153*10583SEdward.Gillett@Sun.COM cmp $7, %r11 1154*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 1155*10583SEdward.Gillett@Sun.COM#endif 1156*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 1157*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K from %r10 */ 1158*10583SEdward.Gillett@Sun.COM jmp LABEL(gobble_ashr_9) 1159*10583SEdward.Gillett@Sun.COM 1160*10583SEdward.Gillett@Sun.COM/* 1161*10583SEdward.Gillett@Sun.COM * ashr_10 handles the following cases: 1162*10583SEdward.Gillett@Sun.COM * abs(str1 offset - str2 offset) = 6 1163*10583SEdward.Gillett@Sun.COM */ 1164*10583SEdward.Gillett@Sun.COM .p2align 4 1165*10583SEdward.Gillett@Sun.COMLABEL(ashr_10): 1166*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 1167*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm2 1168*10583SEdward.Gillett@Sun.COM movdqa (%rsi), %xmm1 1169*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1170*10583SEdward.Gillett@Sun.COM pslldq $6, %xmm2 1171*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm2 1172*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm2 1173*10583SEdward.Gillett@Sun.COM pmovmskb %xmm2, %r9d 1174*10583SEdward.Gillett@Sun.COM shr %cl, %edx 1175*10583SEdward.Gillett@Sun.COM shr %cl, %r9d 1176*10583SEdward.Gillett@Sun.COM sub %r9d, %edx 1177*10583SEdward.Gillett@Sun.COM jnz LABEL(less32bytes) 1178*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm3 1179*10583SEdward.Gillett@Sun.COM 1180*10583SEdward.Gillett@Sun.COM UPDATE_STRNCMP_COUNTER 1181*10583SEdward.Gillett@Sun.COM 1182*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 1183*10583SEdward.Gillett@Sun.COM mov $16, %rcx /* index for loads */ 1184*10583SEdward.Gillett@Sun.COM mov $10, %r9d /* rdi bytes already examined. Used in exit code */ 1185*10583SEdward.Gillett@Sun.COM /* 1186*10583SEdward.Gillett@Sun.COM * Setup %r10 value allows us to detect crossing a page boundary. 1187*10583SEdward.Gillett@Sun.COM * When %r10 goes positive we are crossing a page boundary and 1188*10583SEdward.Gillett@Sun.COM * need to do a nibble. 1189*10583SEdward.Gillett@Sun.COM */ 1190*10583SEdward.Gillett@Sun.COM lea 10(%rdi), %r10 1191*10583SEdward.Gillett@Sun.COM and $0xfff, %r10 /* offset into 4K page */ 1192*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K pagesize */ 1193*10583SEdward.Gillett@Sun.COM movdqa %xmm3, %xmm4 1194*10583SEdward.Gillett@Sun.COM 1195*10583SEdward.Gillett@Sun.COM .p2align 4 1196*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_10): 1197*10583SEdward.Gillett@Sun.COM add $16, %r10 1198*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_10) 1199*10583SEdward.Gillett@Sun.COM 1200*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_10): 1201*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1202*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 1203*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 1204*10583SEdward.Gillett@Sun.COM 1205*10583SEdward.Gillett@Sun.COM psrldq $10, %xmm3 1206*10583SEdward.Gillett@Sun.COM pslldq $6, %xmm2 1207*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 1208*10583SEdward.Gillett@Sun.COM 1209*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1210*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 1211*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1212*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1213*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 1214*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 1215*10583SEdward.Gillett@Sun.COM 1216*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 1217*10583SEdward.Gillett@Sun.COM sub $16, %r11 1218*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 12190Sstevel@tonic-gate#endif 12200Sstevel@tonic-gate 1221*10583SEdward.Gillett@Sun.COM add $16, %rcx 1222*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 1223*10583SEdward.Gillett@Sun.COM 1224*10583SEdward.Gillett@Sun.COM add $16, %r10 1225*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_10) /* cross page boundary */ 1226*10583SEdward.Gillett@Sun.COM 1227*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1228*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 1229*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 1230*10583SEdward.Gillett@Sun.COM 1231*10583SEdward.Gillett@Sun.COM psrldq $10, %xmm3 1232*10583SEdward.Gillett@Sun.COM pslldq $6, %xmm2 1233*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 1234*10583SEdward.Gillett@Sun.COM 1235*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1236*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 1237*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1238*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1239*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 1240*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 12410Sstevel@tonic-gate 1242*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 1243*10583SEdward.Gillett@Sun.COM sub $16, %r11 1244*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 1245*10583SEdward.Gillett@Sun.COM#endif 1246*10583SEdward.Gillett@Sun.COM 1247*10583SEdward.Gillett@Sun.COM add $16, %rcx 1248*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 1249*10583SEdward.Gillett@Sun.COM jmp LABEL(loop_ashr_10) 1250*10583SEdward.Gillett@Sun.COM 1251*10583SEdward.Gillett@Sun.COM .p2align 4 1252*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_10): 1253*10583SEdward.Gillett@Sun.COM psrldq $10, %xmm4 1254*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1255*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1256*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm4, %xmm1 1257*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1258*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1259*10583SEdward.Gillett@Sun.COM sub $0x003f, %edx 1260*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 1261*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 1262*10583SEdward.Gillett@Sun.COM cmp $6, %r11 1263*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 1264*10583SEdward.Gillett@Sun.COM#endif 1265*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 1266*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K from %r10 */ 1267*10583SEdward.Gillett@Sun.COM jmp LABEL(gobble_ashr_10) 12680Sstevel@tonic-gate 1269*10583SEdward.Gillett@Sun.COM/* 1270*10583SEdward.Gillett@Sun.COM * ashr_11 handles the following cases: 1271*10583SEdward.Gillett@Sun.COM * abs(str1 offset - str2 offset) = 5 1272*10583SEdward.Gillett@Sun.COM */ 1273*10583SEdward.Gillett@Sun.COM .p2align 4 1274*10583SEdward.Gillett@Sun.COMLABEL(ashr_11): 1275*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 1276*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm2 1277*10583SEdward.Gillett@Sun.COM movdqa (%rsi), %xmm1 1278*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1279*10583SEdward.Gillett@Sun.COM pslldq $5, %xmm2 1280*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm2 1281*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm2 1282*10583SEdward.Gillett@Sun.COM pmovmskb %xmm2, %r9d 1283*10583SEdward.Gillett@Sun.COM shr %cl, %edx 1284*10583SEdward.Gillett@Sun.COM shr %cl, %r9d 1285*10583SEdward.Gillett@Sun.COM sub %r9d, %edx 1286*10583SEdward.Gillett@Sun.COM jnz LABEL(less32bytes) 1287*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm3 1288*10583SEdward.Gillett@Sun.COM 1289*10583SEdward.Gillett@Sun.COM UPDATE_STRNCMP_COUNTER 12900Sstevel@tonic-gate 1291*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 1292*10583SEdward.Gillett@Sun.COM mov $16, %rcx /* index for loads */ 1293*10583SEdward.Gillett@Sun.COM mov $11, %r9d /* rdi bytes already examined. Used in exit code */ 1294*10583SEdward.Gillett@Sun.COM /* 1295*10583SEdward.Gillett@Sun.COM * Setup %r10 value allows us to detect crossing a page boundary. 1296*10583SEdward.Gillett@Sun.COM * When %r10 goes positive we are crossing a page boundary and 1297*10583SEdward.Gillett@Sun.COM * need to do a nibble. 1298*10583SEdward.Gillett@Sun.COM */ 1299*10583SEdward.Gillett@Sun.COM lea 11(%rdi), %r10 1300*10583SEdward.Gillett@Sun.COM and $0xfff, %r10 /* offset into 4K page */ 1301*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K pagesize */ 1302*10583SEdward.Gillett@Sun.COM movdqa %xmm3, %xmm4 13030Sstevel@tonic-gate 1304*10583SEdward.Gillett@Sun.COM .p2align 4 1305*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_11): 1306*10583SEdward.Gillett@Sun.COM add $16, %r10 1307*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_11) 1308*10583SEdward.Gillett@Sun.COM 1309*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_11): 1310*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1311*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 1312*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 13130Sstevel@tonic-gate 1314*10583SEdward.Gillett@Sun.COM psrldq $11, %xmm3 1315*10583SEdward.Gillett@Sun.COM pslldq $5, %xmm2 1316*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 1317*10583SEdward.Gillett@Sun.COM 1318*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1319*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 1320*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1321*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1322*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 1323*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 13240Sstevel@tonic-gate 13250Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 1326*10583SEdward.Gillett@Sun.COM sub $16, %r11 1327*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 1328*10583SEdward.Gillett@Sun.COM#endif 1329*10583SEdward.Gillett@Sun.COM 1330*10583SEdward.Gillett@Sun.COM add $16, %rcx 1331*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 1332*10583SEdward.Gillett@Sun.COM 1333*10583SEdward.Gillett@Sun.COM add $16, %r10 1334*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_11) /* cross page boundary */ 1335*10583SEdward.Gillett@Sun.COM 1336*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1337*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 1338*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 1339*10583SEdward.Gillett@Sun.COM 1340*10583SEdward.Gillett@Sun.COM psrldq $11, %xmm3 1341*10583SEdward.Gillett@Sun.COM pslldq $5, %xmm2 1342*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 1343*10583SEdward.Gillett@Sun.COM 1344*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1345*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 1346*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1347*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1348*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 1349*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 1350*10583SEdward.Gillett@Sun.COM 1351*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 1352*10583SEdward.Gillett@Sun.COM sub $16, %r11 1353*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 13540Sstevel@tonic-gate#endif 13550Sstevel@tonic-gate 1356*10583SEdward.Gillett@Sun.COM add $16, %rcx 1357*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 1358*10583SEdward.Gillett@Sun.COM jmp LABEL(loop_ashr_11) 13590Sstevel@tonic-gate 1360*10583SEdward.Gillett@Sun.COM .p2align 4 1361*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_11): 1362*10583SEdward.Gillett@Sun.COM psrldq $11, %xmm4 1363*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1364*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1365*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm4, %xmm1 1366*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1367*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1368*10583SEdward.Gillett@Sun.COM sub $0x001f, %edx 1369*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 1370*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 1371*10583SEdward.Gillett@Sun.COM cmp $5, %r11 1372*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 1373*10583SEdward.Gillett@Sun.COM#endif 1374*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 1375*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K from %r10 */ 1376*10583SEdward.Gillett@Sun.COM jmp LABEL(gobble_ashr_11) 13770Sstevel@tonic-gate 1378*10583SEdward.Gillett@Sun.COM/* 1379*10583SEdward.Gillett@Sun.COM * ashr_12 handles the following cases: 1380*10583SEdward.Gillett@Sun.COM * abs(str1 offset - str2 offset) = 4 1381*10583SEdward.Gillett@Sun.COM */ 1382*10583SEdward.Gillett@Sun.COM .p2align 4 1383*10583SEdward.Gillett@Sun.COMLABEL(ashr_12): 1384*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 1385*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm2 1386*10583SEdward.Gillett@Sun.COM movdqa (%rsi), %xmm1 1387*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1388*10583SEdward.Gillett@Sun.COM pslldq $4, %xmm2 1389*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm2 1390*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm2 1391*10583SEdward.Gillett@Sun.COM pmovmskb %xmm2, %r9d 1392*10583SEdward.Gillett@Sun.COM shr %cl, %edx 1393*10583SEdward.Gillett@Sun.COM shr %cl, %r9d 1394*10583SEdward.Gillett@Sun.COM sub %r9d, %edx 1395*10583SEdward.Gillett@Sun.COM jnz LABEL(less32bytes) 1396*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm3 1397*10583SEdward.Gillett@Sun.COM 1398*10583SEdward.Gillett@Sun.COM UPDATE_STRNCMP_COUNTER 13990Sstevel@tonic-gate 1400*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 1401*10583SEdward.Gillett@Sun.COM mov $16, %rcx /* index for loads */ 1402*10583SEdward.Gillett@Sun.COM mov $12, %r9d /* rdi bytes already examined. Used in exit code */ 1403*10583SEdward.Gillett@Sun.COM /* 1404*10583SEdward.Gillett@Sun.COM * Setup %r10 value allows us to detect crossing a page boundary. 1405*10583SEdward.Gillett@Sun.COM * When %r10 goes positive we are crossing a page boundary and 1406*10583SEdward.Gillett@Sun.COM * need to do a nibble. 1407*10583SEdward.Gillett@Sun.COM */ 1408*10583SEdward.Gillett@Sun.COM lea 12(%rdi), %r10 1409*10583SEdward.Gillett@Sun.COM and $0xfff, %r10 /* offset into 4K page */ 1410*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K pagesize */ 1411*10583SEdward.Gillett@Sun.COM movdqa %xmm3, %xmm4 14120Sstevel@tonic-gate 1413*10583SEdward.Gillett@Sun.COM .p2align 4 1414*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_12): 1415*10583SEdward.Gillett@Sun.COM add $16, %r10 1416*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_12) 1417*10583SEdward.Gillett@Sun.COM 1418*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_12): 1419*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1420*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 1421*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 14220Sstevel@tonic-gate 1423*10583SEdward.Gillett@Sun.COM psrldq $12, %xmm3 1424*10583SEdward.Gillett@Sun.COM pslldq $4, %xmm2 1425*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 1426*10583SEdward.Gillett@Sun.COM 1427*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1428*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 1429*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1430*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1431*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 1432*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 14330Sstevel@tonic-gate 14340Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 1435*10583SEdward.Gillett@Sun.COM sub $16, %r11 1436*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 1437*10583SEdward.Gillett@Sun.COM#endif 1438*10583SEdward.Gillett@Sun.COM 1439*10583SEdward.Gillett@Sun.COM add $16, %rcx 1440*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 1441*10583SEdward.Gillett@Sun.COM 1442*10583SEdward.Gillett@Sun.COM add $16, %r10 1443*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_12) /* cross page boundary */ 1444*10583SEdward.Gillett@Sun.COM 1445*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1446*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 1447*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 1448*10583SEdward.Gillett@Sun.COM 1449*10583SEdward.Gillett@Sun.COM psrldq $12, %xmm3 1450*10583SEdward.Gillett@Sun.COM pslldq $4, %xmm2 1451*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 1452*10583SEdward.Gillett@Sun.COM 1453*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1454*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 1455*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1456*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1457*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 1458*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 1459*10583SEdward.Gillett@Sun.COM 1460*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 1461*10583SEdward.Gillett@Sun.COM sub $16, %r11 1462*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 14630Sstevel@tonic-gate#endif 14640Sstevel@tonic-gate 1465*10583SEdward.Gillett@Sun.COM add $16, %rcx 1466*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 1467*10583SEdward.Gillett@Sun.COM jmp LABEL(loop_ashr_12) 14680Sstevel@tonic-gate 1469*10583SEdward.Gillett@Sun.COM .p2align 4 1470*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_12): 1471*10583SEdward.Gillett@Sun.COM psrldq $12, %xmm4 1472*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1473*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1474*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm4, %xmm1 1475*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1476*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1477*10583SEdward.Gillett@Sun.COM sub $0x000f, %edx 1478*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 1479*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 1480*10583SEdward.Gillett@Sun.COM cmp $4, %r11 1481*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 1482*10583SEdward.Gillett@Sun.COM#endif 1483*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 1484*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K from %r10 */ 1485*10583SEdward.Gillett@Sun.COM jmp LABEL(gobble_ashr_12) 14860Sstevel@tonic-gate 1487*10583SEdward.Gillett@Sun.COM/* 1488*10583SEdward.Gillett@Sun.COM * ashr_13 handles the following cases: 1489*10583SEdward.Gillett@Sun.COM * abs(str1 offset - str2 offset) = 3 1490*10583SEdward.Gillett@Sun.COM */ 1491*10583SEdward.Gillett@Sun.COM .p2align 4 1492*10583SEdward.Gillett@Sun.COMLABEL(ashr_13): 1493*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 1494*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm2 1495*10583SEdward.Gillett@Sun.COM movdqa (%rsi), %xmm1 1496*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1497*10583SEdward.Gillett@Sun.COM pslldq $3, %xmm2 1498*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm2 1499*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm2 1500*10583SEdward.Gillett@Sun.COM pmovmskb %xmm2, %r9d 1501*10583SEdward.Gillett@Sun.COM shr %cl, %edx 1502*10583SEdward.Gillett@Sun.COM shr %cl, %r9d 1503*10583SEdward.Gillett@Sun.COM sub %r9d, %edx 1504*10583SEdward.Gillett@Sun.COM jnz LABEL(less32bytes) 1505*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm3 15060Sstevel@tonic-gate 1507*10583SEdward.Gillett@Sun.COM UPDATE_STRNCMP_COUNTER 15080Sstevel@tonic-gate 1509*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 1510*10583SEdward.Gillett@Sun.COM mov $16, %rcx /* index for loads */ 1511*10583SEdward.Gillett@Sun.COM mov $13, %r9d /* rdi bytes already examined. Used in exit code */ 1512*10583SEdward.Gillett@Sun.COM /* 1513*10583SEdward.Gillett@Sun.COM * Setup %r10 value allows us to detect crossing a page boundary. 1514*10583SEdward.Gillett@Sun.COM * When %r10 goes positive we are crossing a page boundary and 1515*10583SEdward.Gillett@Sun.COM * need to do a nibble. 1516*10583SEdward.Gillett@Sun.COM */ 1517*10583SEdward.Gillett@Sun.COM lea 13(%rdi), %r10 1518*10583SEdward.Gillett@Sun.COM and $0xfff, %r10 /* offset into 4K page */ 1519*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K pagesize */ 1520*10583SEdward.Gillett@Sun.COM movdqa %xmm3, %xmm4 15210Sstevel@tonic-gate 1522*10583SEdward.Gillett@Sun.COM .p2align 4 1523*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_13): 1524*10583SEdward.Gillett@Sun.COM add $16, %r10 1525*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_13) 15260Sstevel@tonic-gate 1527*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_13): 1528*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1529*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 1530*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 1531*10583SEdward.Gillett@Sun.COM 1532*10583SEdward.Gillett@Sun.COM psrldq $13, %xmm3 1533*10583SEdward.Gillett@Sun.COM pslldq $3, %xmm2 1534*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 15350Sstevel@tonic-gate 1536*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1537*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 1538*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1539*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1540*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 1541*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 1542*10583SEdward.Gillett@Sun.COM 15430Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 1544*10583SEdward.Gillett@Sun.COM sub $16, %r11 1545*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 15460Sstevel@tonic-gate#endif 15470Sstevel@tonic-gate 1548*10583SEdward.Gillett@Sun.COM add $16, %rcx 1549*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 1550*10583SEdward.Gillett@Sun.COM 1551*10583SEdward.Gillett@Sun.COM add $16, %r10 1552*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_13) /* cross page boundary */ 1553*10583SEdward.Gillett@Sun.COM 1554*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1555*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 1556*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 15570Sstevel@tonic-gate 1558*10583SEdward.Gillett@Sun.COM psrldq $13, %xmm3 1559*10583SEdward.Gillett@Sun.COM pslldq $3, %xmm2 1560*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 1561*10583SEdward.Gillett@Sun.COM 1562*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1563*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 1564*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1565*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1566*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 1567*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 15680Sstevel@tonic-gate 15690Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 1570*10583SEdward.Gillett@Sun.COM sub $16, %r11 1571*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 15720Sstevel@tonic-gate#endif 15730Sstevel@tonic-gate 1574*10583SEdward.Gillett@Sun.COM add $16, %rcx 1575*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 1576*10583SEdward.Gillett@Sun.COM jmp LABEL(loop_ashr_13) 1577*10583SEdward.Gillett@Sun.COM 1578*10583SEdward.Gillett@Sun.COM .p2align 4 1579*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_13): 1580*10583SEdward.Gillett@Sun.COM psrldq $13, %xmm4 1581*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1582*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1583*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm4, %xmm1 1584*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1585*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1586*10583SEdward.Gillett@Sun.COM sub $0x0007, %edx 1587*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 1588*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 1589*10583SEdward.Gillett@Sun.COM cmp $3, %r11 1590*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 1591*10583SEdward.Gillett@Sun.COM#endif 1592*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 1593*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K from %r10 */ 1594*10583SEdward.Gillett@Sun.COM jmp LABEL(gobble_ashr_13) 15950Sstevel@tonic-gate 1596*10583SEdward.Gillett@Sun.COM/* 1597*10583SEdward.Gillett@Sun.COM * ashr_14 handles the following cases: 1598*10583SEdward.Gillett@Sun.COM * abs(str1 offset - str2 offset) = 2 1599*10583SEdward.Gillett@Sun.COM */ 1600*10583SEdward.Gillett@Sun.COM .p2align 4 1601*10583SEdward.Gillett@Sun.COMLABEL(ashr_14): 1602*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 1603*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm2 1604*10583SEdward.Gillett@Sun.COM movdqa (%rsi), %xmm1 1605*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1606*10583SEdward.Gillett@Sun.COM pslldq $2, %xmm2 1607*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm2 1608*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm2 1609*10583SEdward.Gillett@Sun.COM pmovmskb %xmm2, %r9d 1610*10583SEdward.Gillett@Sun.COM shr %cl, %edx 1611*10583SEdward.Gillett@Sun.COM shr %cl, %r9d 1612*10583SEdward.Gillett@Sun.COM sub %r9d, %edx 1613*10583SEdward.Gillett@Sun.COM jnz LABEL(less32bytes) 1614*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm3 1615*10583SEdward.Gillett@Sun.COM 1616*10583SEdward.Gillett@Sun.COM UPDATE_STRNCMP_COUNTER 1617*10583SEdward.Gillett@Sun.COM 1618*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 1619*10583SEdward.Gillett@Sun.COM mov $16, %rcx /* index for loads */ 1620*10583SEdward.Gillett@Sun.COM mov $14, %r9d /* rdi bytes already examined. Used in exit code */ 1621*10583SEdward.Gillett@Sun.COM /* 1622*10583SEdward.Gillett@Sun.COM * Setup %r10 value allows us to detect crossing a page boundary. 1623*10583SEdward.Gillett@Sun.COM * When %r10 goes positive we are crossing a page boundary and 1624*10583SEdward.Gillett@Sun.COM * need to do a nibble. 1625*10583SEdward.Gillett@Sun.COM */ 1626*10583SEdward.Gillett@Sun.COM lea 14(%rdi), %r10 1627*10583SEdward.Gillett@Sun.COM and $0xfff, %r10 /* offset into 4K page */ 1628*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K pagesize */ 1629*10583SEdward.Gillett@Sun.COM movdqa %xmm3, %xmm4 1630*10583SEdward.Gillett@Sun.COM 1631*10583SEdward.Gillett@Sun.COM .p2align 4 1632*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_14): 1633*10583SEdward.Gillett@Sun.COM add $16, %r10 1634*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_14) 1635*10583SEdward.Gillett@Sun.COM 1636*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_14): 1637*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1638*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 1639*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 1640*10583SEdward.Gillett@Sun.COM 1641*10583SEdward.Gillett@Sun.COM psrldq $14, %xmm3 1642*10583SEdward.Gillett@Sun.COM pslldq $2, %xmm2 1643*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 1644*10583SEdward.Gillett@Sun.COM 1645*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1646*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 1647*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1648*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1649*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 1650*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 16510Sstevel@tonic-gate 16520Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 1653*10583SEdward.Gillett@Sun.COM sub $16, %r11 1654*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 16550Sstevel@tonic-gate#endif 16560Sstevel@tonic-gate 1657*10583SEdward.Gillett@Sun.COM add $16, %rcx 1658*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 1659*10583SEdward.Gillett@Sun.COM 1660*10583SEdward.Gillett@Sun.COM add $16, %r10 1661*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_14) /* cross page boundary */ 1662*10583SEdward.Gillett@Sun.COM 1663*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1664*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 1665*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 16660Sstevel@tonic-gate 1667*10583SEdward.Gillett@Sun.COM psrldq $14, %xmm3 1668*10583SEdward.Gillett@Sun.COM pslldq $2, %xmm2 1669*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 1670*10583SEdward.Gillett@Sun.COM 1671*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1672*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 1673*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1674*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1675*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 1676*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 16770Sstevel@tonic-gate 16780Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 1679*10583SEdward.Gillett@Sun.COM sub $16, %r11 1680*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 16810Sstevel@tonic-gate#endif 16820Sstevel@tonic-gate 1683*10583SEdward.Gillett@Sun.COM add $16, %rcx 1684*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 1685*10583SEdward.Gillett@Sun.COM jmp LABEL(loop_ashr_14) 1686*10583SEdward.Gillett@Sun.COM 1687*10583SEdward.Gillett@Sun.COM .p2align 4 1688*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_14): 1689*10583SEdward.Gillett@Sun.COM psrldq $14, %xmm4 1690*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1691*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1692*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm4, %xmm1 1693*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1694*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1695*10583SEdward.Gillett@Sun.COM sub $0x0003, %edx 1696*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 1697*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 1698*10583SEdward.Gillett@Sun.COM cmp $2, %r11 1699*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 1700*10583SEdward.Gillett@Sun.COM#endif 1701*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 1702*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K from %r10 */ 1703*10583SEdward.Gillett@Sun.COM jmp LABEL(gobble_ashr_14) 17040Sstevel@tonic-gate 1705*10583SEdward.Gillett@Sun.COM/* 1706*10583SEdward.Gillett@Sun.COM * ashr_15 handles the following cases: 1707*10583SEdward.Gillett@Sun.COM * abs(str1 offset - str2 offset) = 1 1708*10583SEdward.Gillett@Sun.COM */ 1709*10583SEdward.Gillett@Sun.COM .p2align 4 1710*10583SEdward.Gillett@Sun.COMLABEL(ashr_15): 1711*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 1712*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm2 1713*10583SEdward.Gillett@Sun.COM movdqa (%rsi), %xmm1 1714*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1715*10583SEdward.Gillett@Sun.COM pslldq $1, %xmm2 1716*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm2 1717*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm2 1718*10583SEdward.Gillett@Sun.COM pmovmskb %xmm2, %r9d 1719*10583SEdward.Gillett@Sun.COM shr %cl, %edx 1720*10583SEdward.Gillett@Sun.COM shr %cl, %r9d 1721*10583SEdward.Gillett@Sun.COM sub %r9d, %edx 1722*10583SEdward.Gillett@Sun.COM jnz LABEL(less32bytes) 1723*10583SEdward.Gillett@Sun.COM 1724*10583SEdward.Gillett@Sun.COM movdqa (%rdi), %xmm3 1725*10583SEdward.Gillett@Sun.COM 1726*10583SEdward.Gillett@Sun.COM UPDATE_STRNCMP_COUNTER 1727*10583SEdward.Gillett@Sun.COM 1728*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 1729*10583SEdward.Gillett@Sun.COM mov $16, %rcx /* index for loads */ 1730*10583SEdward.Gillett@Sun.COM mov $15, %r9d /* rdi bytes already examined. Used in exit code */ 1731*10583SEdward.Gillett@Sun.COM /* 1732*10583SEdward.Gillett@Sun.COM * Setup %r10 value allows us to detect crossing a page boundary. 1733*10583SEdward.Gillett@Sun.COM * When %r10 goes positive we are crossing a page boundary and 1734*10583SEdward.Gillett@Sun.COM * need to do a nibble. 1735*10583SEdward.Gillett@Sun.COM */ 1736*10583SEdward.Gillett@Sun.COM lea 15(%rdi), %r10 1737*10583SEdward.Gillett@Sun.COM and $0xfff, %r10 /* offset into 4K page */ 1738*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K pagesize */ 1739*10583SEdward.Gillett@Sun.COM movdqa %xmm3, %xmm4 1740*10583SEdward.Gillett@Sun.COM 1741*10583SEdward.Gillett@Sun.COM .p2align 4 1742*10583SEdward.Gillett@Sun.COMLABEL(loop_ashr_15): 1743*10583SEdward.Gillett@Sun.COM add $16, %r10 1744*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_15) 1745*10583SEdward.Gillett@Sun.COM 1746*10583SEdward.Gillett@Sun.COMLABEL(gobble_ashr_15): 1747*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1748*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 1749*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 1750*10583SEdward.Gillett@Sun.COM 1751*10583SEdward.Gillett@Sun.COM psrldq $15, %xmm3 1752*10583SEdward.Gillett@Sun.COM pslldq $1, %xmm2 1753*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 1754*10583SEdward.Gillett@Sun.COM 1755*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1756*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 1757*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1758*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1759*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 1760*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 17610Sstevel@tonic-gate 17620Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 1763*10583SEdward.Gillett@Sun.COM sub $16, %r11 1764*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 17650Sstevel@tonic-gate#endif 17660Sstevel@tonic-gate 1767*10583SEdward.Gillett@Sun.COM add $16, %rcx 1768*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 1769*10583SEdward.Gillett@Sun.COM 1770*10583SEdward.Gillett@Sun.COM add $16, %r10 1771*10583SEdward.Gillett@Sun.COM jg LABEL(nibble_ashr_15) /* cross page boundary */ 1772*10583SEdward.Gillett@Sun.COM 1773*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1774*10583SEdward.Gillett@Sun.COM movdqa (%rdi, %rcx), %xmm2 1775*10583SEdward.Gillett@Sun.COM movdqa %xmm2, %xmm4 17760Sstevel@tonic-gate 1777*10583SEdward.Gillett@Sun.COM psrldq $15, %xmm3 1778*10583SEdward.Gillett@Sun.COM pslldq $1, %xmm2 1779*10583SEdward.Gillett@Sun.COM por %xmm3, %xmm2 1780*10583SEdward.Gillett@Sun.COM 1781*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1782*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm2, %xmm1 1783*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1784*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1785*10583SEdward.Gillett@Sun.COM sub $0xffff, %edx 1786*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 17870Sstevel@tonic-gate 17880Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 1789*10583SEdward.Gillett@Sun.COM sub $16, %r11 1790*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 17910Sstevel@tonic-gate#endif 17920Sstevel@tonic-gate 1793*10583SEdward.Gillett@Sun.COM add $16, %rcx 1794*10583SEdward.Gillett@Sun.COM movdqa %xmm4, %xmm3 1795*10583SEdward.Gillett@Sun.COM jmp LABEL(loop_ashr_15) 17960Sstevel@tonic-gate 1797*10583SEdward.Gillett@Sun.COM .p2align 4 1798*10583SEdward.Gillett@Sun.COMLABEL(nibble_ashr_15): 1799*10583SEdward.Gillett@Sun.COM psrldq $15, %xmm4 1800*10583SEdward.Gillett@Sun.COM movdqa (%rsi, %rcx), %xmm1 1801*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm1, %xmm0 1802*10583SEdward.Gillett@Sun.COM pcmpeqb %xmm4, %xmm1 1803*10583SEdward.Gillett@Sun.COM psubb %xmm0, %xmm1 1804*10583SEdward.Gillett@Sun.COM pmovmskb %xmm1, %edx 1805*10583SEdward.Gillett@Sun.COM sub $0x0001, %edx 1806*10583SEdward.Gillett@Sun.COM jnz LABEL(exit) 1807*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 1808*10583SEdward.Gillett@Sun.COM cmp $1, %r11 1809*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 1810*10583SEdward.Gillett@Sun.COM#endif 1811*10583SEdward.Gillett@Sun.COM pxor %xmm0, %xmm0 1812*10583SEdward.Gillett@Sun.COM sub $0x1000, %r10 /* subtract 4K from %r10 */ 1813*10583SEdward.Gillett@Sun.COM jmp LABEL(gobble_ashr_15) 1814*10583SEdward.Gillett@Sun.COM 1815*10583SEdward.Gillett@Sun.COM .p2align 4 1816*10583SEdward.Gillett@Sun.COMLABEL(exit): 1817*10583SEdward.Gillett@Sun.COM lea -16(%r9, %rcx), %rax /* locate the exact offset for rdi */ 1818*10583SEdward.Gillett@Sun.COMLABEL(less32bytes): 1819*10583SEdward.Gillett@Sun.COM lea (%rdi, %rax), %rdi /* locate the exact address for first operand(rdi) */ 1820*10583SEdward.Gillett@Sun.COM lea (%rsi, %rcx), %rsi /* locate the exact address for second operand(rsi) */ 1821*10583SEdward.Gillett@Sun.COM test %r8d, %r8d 1822*10583SEdward.Gillett@Sun.COM jz LABEL(ret) 1823*10583SEdward.Gillett@Sun.COM xchg %rsi, %rdi /* recover original order according to flag(%r8d) */ 1824*10583SEdward.Gillett@Sun.COM 1825*10583SEdward.Gillett@Sun.COM .p2align 4 1826*10583SEdward.Gillett@Sun.COMLABEL(ret): 1827*10583SEdward.Gillett@Sun.COMLABEL(less16bytes): 1828*10583SEdward.Gillett@Sun.COM /* 1829*10583SEdward.Gillett@Sun.COM * Check to see if BSF is fast on this processor. If not, use a different 1830*10583SEdward.Gillett@Sun.COM * exit tail. 1831*10583SEdward.Gillett@Sun.COM */ 1832*10583SEdward.Gillett@Sun.COM testl $USE_BSF,.memops_method(%rip) 1833*10583SEdward.Gillett@Sun.COM jz LABEL(AMD_exit) 1834*10583SEdward.Gillett@Sun.COM bsf %rdx, %rdx /* find and store bit index in %rdx */ 18350Sstevel@tonic-gate 18360Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 1837*10583SEdward.Gillett@Sun.COM sub %rdx, %r11 1838*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 1839*10583SEdward.Gillett@Sun.COM#endif 1840*10583SEdward.Gillett@Sun.COM xor %ecx, %ecx /* clear %ecx */ 1841*10583SEdward.Gillett@Sun.COM xor %eax, %eax /* clear %eax */ 1842*10583SEdward.Gillett@Sun.COM 1843*10583SEdward.Gillett@Sun.COM movb (%rsi, %rdx), %cl 1844*10583SEdward.Gillett@Sun.COM movb (%rdi, %rdx), %al 1845*10583SEdward.Gillett@Sun.COM 1846*10583SEdward.Gillett@Sun.COM sub %ecx, %eax 1847*10583SEdward.Gillett@Sun.COM ret 1848*10583SEdward.Gillett@Sun.COM 1849*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 1850*10583SEdward.Gillett@Sun.COMLABEL(strcmp_exitz): 1851*10583SEdward.Gillett@Sun.COM xor %eax, %eax 1852*10583SEdward.Gillett@Sun.COM ret 18530Sstevel@tonic-gate#endif 18540Sstevel@tonic-gate 1855*10583SEdward.Gillett@Sun.COM /* 1856*10583SEdward.Gillett@Sun.COM * This exit tail does not use the bsf instruction. 1857*10583SEdward.Gillett@Sun.COM */ 1858*10583SEdward.Gillett@Sun.COM .p2align 4 1859*10583SEdward.Gillett@Sun.COMLABEL(AMD_exit): 1860*10583SEdward.Gillett@Sun.COM test %dl, %dl 1861*10583SEdward.Gillett@Sun.COM jz LABEL(next_8_bytes) 1862*10583SEdward.Gillett@Sun.COM 1863*10583SEdward.Gillett@Sun.COM test $0x01, %dl 1864*10583SEdward.Gillett@Sun.COM jnz LABEL(Byte0) 1865*10583SEdward.Gillett@Sun.COM 1866*10583SEdward.Gillett@Sun.COM test $0x02, %dl 1867*10583SEdward.Gillett@Sun.COM jnz LABEL(Byte1) 1868*10583SEdward.Gillett@Sun.COM 1869*10583SEdward.Gillett@Sun.COM test $0x04, %dl 1870*10583SEdward.Gillett@Sun.COM jnz LABEL(Byte2) 1871*10583SEdward.Gillett@Sun.COM 1872*10583SEdward.Gillett@Sun.COM test $0x08, %dl 1873*10583SEdward.Gillett@Sun.COM jnz LABEL(Byte3) 1874*10583SEdward.Gillett@Sun.COM 1875*10583SEdward.Gillett@Sun.COM test $0x10, %dl 1876*10583SEdward.Gillett@Sun.COM jnz LABEL(Byte4) 1877*10583SEdward.Gillett@Sun.COM 1878*10583SEdward.Gillett@Sun.COM test $0x20, %dl 1879*10583SEdward.Gillett@Sun.COM jnz LABEL(Byte5) 1880*10583SEdward.Gillett@Sun.COM 1881*10583SEdward.Gillett@Sun.COM test $0x40, %dl 1882*10583SEdward.Gillett@Sun.COM jnz LABEL(Byte6) 1883*10583SEdward.Gillett@Sun.COM 1884*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 1885*10583SEdward.Gillett@Sun.COM sub $7, %r11 1886*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 1887*10583SEdward.Gillett@Sun.COM#endif 1888*10583SEdward.Gillett@Sun.COM movzx 7(%rsi), %ecx 1889*10583SEdward.Gillett@Sun.COM movzx 7(%rdi), %eax 1890*10583SEdward.Gillett@Sun.COM 1891*10583SEdward.Gillett@Sun.COM sub %ecx, %eax 1892*10583SEdward.Gillett@Sun.COM ret 18930Sstevel@tonic-gate 1894*10583SEdward.Gillett@Sun.COM .p2align 4 1895*10583SEdward.Gillett@Sun.COMLABEL(Byte0): 1896*10583SEdward.Gillett@Sun.COM /* 1897*10583SEdward.Gillett@Sun.COM * never need to handle byte 0 for strncmpy 1898*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 1899*10583SEdward.Gillett@Sun.COM sub $0, %r11 1900*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 1901*10583SEdward.Gillett@Sun.COM#endif 1902*10583SEdward.Gillett@Sun.COM */ 1903*10583SEdward.Gillett@Sun.COM movzx (%rsi), %ecx 1904*10583SEdward.Gillett@Sun.COM movzx (%rdi), %eax 1905*10583SEdward.Gillett@Sun.COM 1906*10583SEdward.Gillett@Sun.COM sub %ecx, %eax 1907*10583SEdward.Gillett@Sun.COM ret 1908*10583SEdward.Gillett@Sun.COM 1909*10583SEdward.Gillett@Sun.COM .p2align 4 1910*10583SEdward.Gillett@Sun.COMLABEL(Byte1): 1911*10583SEdward.Gillett@Sun.COM 1912*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 1913*10583SEdward.Gillett@Sun.COM sub $1, %r11 1914*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 1915*10583SEdward.Gillett@Sun.COM#endif 1916*10583SEdward.Gillett@Sun.COM movzx 1(%rsi), %ecx 1917*10583SEdward.Gillett@Sun.COM movzx 1(%rdi), %eax 1918*10583SEdward.Gillett@Sun.COM 1919*10583SEdward.Gillett@Sun.COM sub %ecx, %eax 1920*10583SEdward.Gillett@Sun.COM ret 1921*10583SEdward.Gillett@Sun.COM 1922*10583SEdward.Gillett@Sun.COM .p2align 4 1923*10583SEdward.Gillett@Sun.COMLABEL(Byte2): 1924*10583SEdward.Gillett@Sun.COM 1925*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 1926*10583SEdward.Gillett@Sun.COM sub $2, %r11 1927*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 1928*10583SEdward.Gillett@Sun.COM#endif 1929*10583SEdward.Gillett@Sun.COM movzx 2(%rsi), %ecx 1930*10583SEdward.Gillett@Sun.COM movzx 2(%rdi), %eax 1931*10583SEdward.Gillett@Sun.COM 1932*10583SEdward.Gillett@Sun.COM sub %ecx, %eax 1933*10583SEdward.Gillett@Sun.COM ret 1934*10583SEdward.Gillett@Sun.COM 1935*10583SEdward.Gillett@Sun.COM .p2align 4 1936*10583SEdward.Gillett@Sun.COMLABEL(Byte3): 19370Sstevel@tonic-gate 19380Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 1939*10583SEdward.Gillett@Sun.COM sub $3, %r11 1940*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 19410Sstevel@tonic-gate#endif 1942*10583SEdward.Gillett@Sun.COM movzx 3(%rsi), %ecx 1943*10583SEdward.Gillett@Sun.COM movzx 3(%rdi), %eax 1944*10583SEdward.Gillett@Sun.COM 1945*10583SEdward.Gillett@Sun.COM sub %ecx, %eax 1946*10583SEdward.Gillett@Sun.COM ret 19470Sstevel@tonic-gate 1948*10583SEdward.Gillett@Sun.COM .p2align 4 1949*10583SEdward.Gillett@Sun.COMLABEL(Byte4): 19500Sstevel@tonic-gate 1951*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 1952*10583SEdward.Gillett@Sun.COM sub $4, %r11 1953*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 1954*10583SEdward.Gillett@Sun.COM#endif 1955*10583SEdward.Gillett@Sun.COM movzx 4(%rsi), %ecx 1956*10583SEdward.Gillett@Sun.COM movzx 4(%rdi), %eax 19570Sstevel@tonic-gate 1958*10583SEdward.Gillett@Sun.COM sub %ecx, %eax 1959*10583SEdward.Gillett@Sun.COM ret 19600Sstevel@tonic-gate 1961*10583SEdward.Gillett@Sun.COM .p2align 4 1962*10583SEdward.Gillett@Sun.COMLABEL(Byte5): 19630Sstevel@tonic-gate 19640Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 1965*10583SEdward.Gillett@Sun.COM sub $5, %r11 1966*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 19670Sstevel@tonic-gate#endif 1968*10583SEdward.Gillett@Sun.COM movzx 5(%rsi), %ecx 1969*10583SEdward.Gillett@Sun.COM movzx 5(%rdi), %eax 19700Sstevel@tonic-gate 1971*10583SEdward.Gillett@Sun.COM sub %ecx, %eax 1972*10583SEdward.Gillett@Sun.COM ret 1973*10583SEdward.Gillett@Sun.COM 1974*10583SEdward.Gillett@Sun.COM .p2align 4 1975*10583SEdward.Gillett@Sun.COMLABEL(Byte6): 19760Sstevel@tonic-gate 19770Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 1978*10583SEdward.Gillett@Sun.COM sub $6, %r11 1979*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 1980*10583SEdward.Gillett@Sun.COM#endif 1981*10583SEdward.Gillett@Sun.COM movzx 6(%rsi), %ecx 1982*10583SEdward.Gillett@Sun.COM movzx 6(%rdi), %eax 1983*10583SEdward.Gillett@Sun.COM 1984*10583SEdward.Gillett@Sun.COM sub %ecx, %eax 1985*10583SEdward.Gillett@Sun.COM ret 1986*10583SEdward.Gillett@Sun.COM 1987*10583SEdward.Gillett@Sun.COM .p2align 4 1988*10583SEdward.Gillett@Sun.COMLABEL(next_8_bytes): 1989*10583SEdward.Gillett@Sun.COM add $8, %rdi 1990*10583SEdward.Gillett@Sun.COM add $8, %rsi 1991*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 1992*10583SEdward.Gillett@Sun.COM sub $8, %r11 1993*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 19940Sstevel@tonic-gate#endif 1995*10583SEdward.Gillett@Sun.COM test $0x01, %dh 1996*10583SEdward.Gillett@Sun.COM jnz LABEL(Byte0) 1997*10583SEdward.Gillett@Sun.COM 1998*10583SEdward.Gillett@Sun.COM test $0x02, %dh 1999*10583SEdward.Gillett@Sun.COM jnz LABEL(Byte1) 2000*10583SEdward.Gillett@Sun.COM 2001*10583SEdward.Gillett@Sun.COM test $0x04, %dh 2002*10583SEdward.Gillett@Sun.COM jnz LABEL(Byte2) 2003*10583SEdward.Gillett@Sun.COM 2004*10583SEdward.Gillett@Sun.COM test $0x08, %dh 2005*10583SEdward.Gillett@Sun.COM jnz LABEL(Byte3) 2006*10583SEdward.Gillett@Sun.COM 2007*10583SEdward.Gillett@Sun.COM test $0x10, %dh 2008*10583SEdward.Gillett@Sun.COM jnz LABEL(Byte4) 2009*10583SEdward.Gillett@Sun.COM 2010*10583SEdward.Gillett@Sun.COM test $0x20, %dh 2011*10583SEdward.Gillett@Sun.COM jnz LABEL(Byte5) 2012*10583SEdward.Gillett@Sun.COM 2013*10583SEdward.Gillett@Sun.COM test $0x40, %dh 2014*10583SEdward.Gillett@Sun.COM jnz LABEL(Byte6) 20150Sstevel@tonic-gate 20160Sstevel@tonic-gate#ifdef USE_AS_STRNCMP 2017*10583SEdward.Gillett@Sun.COM sub $7, %r11 2018*10583SEdward.Gillett@Sun.COM jbe LABEL(strcmp_exitz) 2019*10583SEdward.Gillett@Sun.COM#endif 2020*10583SEdward.Gillett@Sun.COM movzx 7(%rsi), %ecx 2021*10583SEdward.Gillett@Sun.COM movzx 7(%rdi), %eax 2022*10583SEdward.Gillett@Sun.COM 2023*10583SEdward.Gillett@Sun.COM sub %ecx, %eax 2024*10583SEdward.Gillett@Sun.COM ret 2025*10583SEdward.Gillett@Sun.COM 2026*10583SEdward.Gillett@Sun.COM .pushsection .rodata 2027*10583SEdward.Gillett@Sun.COM .p2align 4 2028*10583SEdward.Gillett@Sun.COMLABEL(unaligned_table): 2029*10583SEdward.Gillett@Sun.COM .int LABEL(ashr_0) - LABEL(unaligned_table) 2030*10583SEdward.Gillett@Sun.COM .int LABEL(ashr_15) - LABEL(unaligned_table) 2031*10583SEdward.Gillett@Sun.COM .int LABEL(ashr_14) - LABEL(unaligned_table) 2032*10583SEdward.Gillett@Sun.COM .int LABEL(ashr_13) - LABEL(unaligned_table) 2033*10583SEdward.Gillett@Sun.COM .int LABEL(ashr_12) - LABEL(unaligned_table) 2034*10583SEdward.Gillett@Sun.COM .int LABEL(ashr_11) - LABEL(unaligned_table) 2035*10583SEdward.Gillett@Sun.COM .int LABEL(ashr_10) - LABEL(unaligned_table) 2036*10583SEdward.Gillett@Sun.COM .int LABEL(ashr_9) - LABEL(unaligned_table) 2037*10583SEdward.Gillett@Sun.COM .int LABEL(ashr_8) - LABEL(unaligned_table) 2038*10583SEdward.Gillett@Sun.COM .int LABEL(ashr_7) - LABEL(unaligned_table) 2039*10583SEdward.Gillett@Sun.COM .int LABEL(ashr_6) - LABEL(unaligned_table) 2040*10583SEdward.Gillett@Sun.COM .int LABEL(ashr_5) - LABEL(unaligned_table) 2041*10583SEdward.Gillett@Sun.COM .int LABEL(ashr_4) - LABEL(unaligned_table) 2042*10583SEdward.Gillett@Sun.COM .int LABEL(ashr_3) - LABEL(unaligned_table) 2043*10583SEdward.Gillett@Sun.COM .int LABEL(ashr_2) - LABEL(unaligned_table) 2044*10583SEdward.Gillett@Sun.COM .int LABEL(ashr_1) - LABEL(unaligned_table) 2045*10583SEdward.Gillett@Sun.COM .popsection 2046*10583SEdward.Gillett@Sun.COM#ifdef USE_AS_STRNCMP 20470Sstevel@tonic-gate SET_SIZE(strncmp) 20480Sstevel@tonic-gate#else 20490Sstevel@tonic-gate SET_SIZE(strcmp) /* (const char *, const char *) */ 20500Sstevel@tonic-gate#endif 2051