URL
https://opencores.org/ocsvn/or1k/or1k/trunk
Subversion Repositories or1k
[/] [or1k/] [trunk/] [newlib-1.10.0/] [newlib/] [libc/] [machine/] [hppa/] [strcmp.S] - Rev 1765
Compare with Previous | Blame | View Log
/** (c) Copyright 1986 HEWLETT-PACKARD COMPANY** To anyone who acknowledges that this file is provided "AS IS"* without any express or implied warranty:* permission to use, copy, modify, and distribute this file* for any purpose is hereby granted without fee, provided that* the above copyright notice and this notice appears in all* copies, and that the name of Hewlett-Packard Company not be* used in advertising or publicity pertaining to distribution* of the software without specific, written prior permission.* Hewlett-Packard Company makes no representations about the* suitability of this software for any purpose.*//*strcmpJerry HuckEdgar Circenis*//** strcmp(s1, s2)** returns integer: < 0 iff s1 lexicographically less than s2* > 0 iff s1 lexicographically greater than s2* = 0 iff s1 lexicographically equal to s2*/#include "DEFS.h"#define s1 26#define s2 25#define tmp1 19#define s2word 20#define tmp3 21#define tmp7 22#define s1word 23#define save 1#define tmp6 24#define tmp5 28ENTRY(strcmp)comb,=,n s1,s2,samestringcomib,=,n 0,s1,s1isnullcomib,=,n 0,s2,s2isnull/* Hope for word alignment. Pick up low two bits of each adress */extru,<> s1,31,2,tmp1ldwm 4(s1),s1worddep,= s2,29,2,tmp1b,n case_analysis/* Start looping until null is found in s1 or they mis-compare */loop:ldwm 4(s2),s2wordloop_plus:uxor,nbz s1word,r0,r0 /* Null in this? */b,n nullins1comb,=,n s1word,s2word,loopldwm 4(s1),s1word/* The words do not compare equal and s1 does not have a null.Need to treat words as unsigned and generate either a positiveor negative return value */wordcomparereturn:comclr,>> s1word,s2word,ret0 /*Set ret0 to 0 and skip if greater*/ldi -2,ret0 /*Set ret0 to -2 when less */bv r0(rp)addi 1,ret0,ret0 /*Fix return value to be -1 or +1 *//* s1 has a null. s2 has not been checked. */nullins1:/*If s2 has no nulls this is simple, but assume that it mightand fix up s1 to allow the word comparision to work byscanning s1 and duplicating all the bytes in s2 below that byte intothe remainder of s1. A remainder only exists if the zero byteis found in the upper three bytes */extru,<> s1word,7,8,r0 /*in the first byte? */dep,tr s2word,31,24,s1word /*copy low 3 bytes of *s2 into *s1 */extru,<> s1word,15,8,r0 /*in the second byte? */dep,tr s2word,31,16,s1word /*copy low 2 bytes of *s2 into *s1 */extru,<> s1word,23,8,r0 /*in the third byte? */dep s2word,31,8,s1word /*copy low 1 byte of *s2 into *s1 *//* Do the normal unsigned compare and return */comclr,<> s1word,s2word,ret0 /*Set ret0 to 0 and skip if not equal */bv,n r0(rp)comclr,>> s1word,s2word,ret0 /*Set ret0 to 0 and skip if greater*/ldi -2,ret0 /*Set ret0 to -2 when less */bv r0(rp)addi 1,ret0,ret0 /*Fix return value to be -1 or +1 *//* s1 and s2 are the same string and therefore equal */samestring:bv r0(rp)copy r0,ret0/* s1 is null. Treat as string of nulls. Therefore returnthe negative of s2's first byte. s2 cannot be zero. */s1isnull:ldbs 0(0,s2),ret0bv r0(rp)sub 0,ret0,ret0/* s2 is null. Treat as string of nulls. Therefore returns1's first byte. s1 cannot be zero. */s2isnull:bv r0(rp)ldbs 0(0,s1),ret0case_analysis:blr tmp1,r0nop/*Case statement for non-aligned cases (we've alreadychecked the aligned case.NOTE: for non-aligned cases, the absolute shift valuegets loaded into tmp3.*//* S2 S1 */nop /* 00 00 can't happen */nopb shifts2 /* 00 01 */ldi 8,tmp3 /* load shift count (delay slot) */b shifts2 /* 00 10 */ldi 16,tmp3 /* load shift count (delay slot) */b shifts2 /* 00 11 */ldi 24,tmp3 /* load shift count (delay slot) */b shifts1_0 /* 01 00 */ldi 8,tmp3 /* load shift count (delay slot) */b eq_align1 /* 01 01 */ldbs,ma 1(s1),s1wordb shifts2 /* 01 10 */ldi 8,tmp3 /* load shift count (delay slot) */b shifts2 /* 01 11 */ldi 16,tmp3 /* load shift count (delay slot) */b shifts1_0 /* 10 00 */ldi 16,tmp3 /* load shift count (delay slot) */b shifts1 /* 10 01 */ldi 8,tmp3 /* load shift count (delay slot) */b eq_align2 /* 10 10 */ldhs,ma 2(s1),s1wordb shifts2 /* 10 11 */ldi 8,tmp3 /* load shift count (delay slot) */b shifts1_0 /* 11 00 */ldi 24,tmp3 /* load shift count (delay slot) */b shifts1 /* 11 01 */ldi 16,tmp3 /* load shift count (delay slot) */b shifts1 /* 11 10 */ldi 8,tmp3 /* load shift count (delay slot) */ldbs,ma 1(s1),s1word /* 11 11 */ldbs,ma 1(s2),s2wordsub,= s1word,s2word,ret0 /* if not equal, we can return now */bv,n r0(rp)comclr,<> s1word,r0,ret0bv,n r0(rp)b loop /* fall into main loop */ldwm 4(s1),s1wordeq_align1:ldbs,ma 1(s2),s2wordsub,= s1word,s2word,ret0 /* if not equal, we can return now */bv,n r0(rp)comclr,<> s1word,r0,ret0bv,n r0(rp)/* fall through to half-word aligned case */ldhs,ma 2(s1),s1word /* load next halfword */eq_align2:ldhs,ma 2(s2),s2word /* load next halfword *//* form the mask: 0xffff0000 and mask leading nulls in s1word and s2wordso that we can fall into the main loop with word aligned data */ldi 16,savemtctl save,r11zvdepi -2,32,saveor save,s1word,s1wordb loop_plus /* fall into main loop */or save,s2word,s2word/* s2's alignment is greater than s1's alignment, so we will shift s1 */shifts1_0:addi -4,s1,s1 /* fix up s1 due to earlier read */shifts1:extru s1,31,2,tmp1extru s2,31,2,tmp5dep r0,31,2,s1 /* Compute word address of s1 */dep r0,31,2,s2 /* Compute word address of s2 */ldwm 4(s1),s1word /* get first word of s1 */ldwm 4(s2),s2word /* get first word of s2 */combt,=,n r0,tmp1,masks2 /* Do we need to mask beginning of s1 */sh3add tmp1,r0,save /* save now has number of bits to mask */mtctl save,r11zvdepi -2,32,save /* load save with proper mask */or save,s1word,s1wordmasks2:sh3add tmp5,r0,save /* save now has number of bits to mask */mtctl save,r11zvdepi -2,32,save /* load save with proper mask */or save,s2word,s2wordldi -1,tmp7 /* load tmp7 with 0xffffffff */mtctl tmp3,r11 /* Move shift amount to CR11 */more: uxor,nbz s1word,r0,r0 /* Is there a null in s1? */b ends1vshd tmp7,s1word,savecombf,=,n save,s2word,cmps1ldwm 4(s1),tmp7ldwm 4(s2),s2worduxor,nbz tmp7,r0,r0 /* is there a null in s1? */b ends1_0vshd s1word,tmp7,savecombf,=,n save,s2word,cmps1ldwm 4(s1),s1wordb moreldwm 4(s2),s2wordcmps1: movb,tr save,s1word,wordcomparereturnnopends1_0:copy tmp7,s1word /* move tmp7 to s1word */ends1:combf,=,n save,s2word,nullins1 /* branch if no match */copy save,s1word /* delay slot *//* At this point, we know that we've read a null *//* from s1, so we can't read more from s1 */uxor,nbz save,r0,r0 /* are the strings equal? */b,n samestringvshd s1word,r0,s1wordb nullins1ldwm 4(s2),s2word/* s1's alignment is greater than s2's alignment, so we will shift s2 */shifts2:extru s1,31,2,tmp1extru s2,31,2,tmp5dep r0,31,2,s1 /* Compute word address of s1 */dep r0,31,2,s2 /* Compute word address of s2 */ldwm 4(s2),s2word /* get first word of s2 */ldwm 4(s1),s1word /* get first word of s1 */combt,=,n r0,tmp5,masks1 /* Do we need to mask beginning of s2 */sh3add tmp5,r0,save /* save now has number of bits to mask */mtctl save,r11zvdepi -2,32,save /* load save with proper mask */or save,s2word,s2wordmasks1:sh3add tmp1,r0,save /* save now has number of bits to mask */mtctl save,r11zvdepi -2,32,save /* load save with proper mask */or save,s1word,s1wordldi -1,tmp7 /* load tmp7 with 0xffffffff */mtctl tmp3,r11 /* Move shift amount to CR11 */more1: uxor,nbz s2word,r0,r0 /* is there a null in s2? */b ends2vshd tmp7,s2word,savecombf,=,n s1word,save,cmps2ldwm 4(s2),tmp7ldwm 4(s1),s1worduxor,nbz tmp7,r0,r0 /* is there a null in s2? */b ends2_0vshd s2word,tmp7,savecombf,=,n s1word,save,cmps2ldwm 4(s2),s2wordb more1ldwm 4(s1),s1wordcmps2: movb,tr save,s2word,wordcomparereturnnopends2_0:copy tmp7,s2word /* move tmp7 to s2word */ends2:combf,=,n s1word,save,nullins1 /* branch if no match */copy save,s2word /* delay slot *//* At this point, we know that we've read a null *//* from s2, so we can't read more from s2 */uxor,nbz save,r0,r0 /* are the strings equal? */b,n samestringvshd s2word,r0,s2wordb nullins1ldwm 4(s1),s1wordEXIT(strcmp)
