xref: /onnv-gate/usr/src/lib/libsum/common/sum-att.c (revision 12068:08a39a083754)
18462SApril.Chin@Sun.COM /***********************************************************************
28462SApril.Chin@Sun.COM *                                                                      *
38462SApril.Chin@Sun.COM *               This software is part of the ast package               *
4*12068SRoger.Faulkner@Oracle.COM *          Copyright (c) 1996-2010 AT&T Intellectual Property          *
58462SApril.Chin@Sun.COM *                      and is licensed under the                       *
68462SApril.Chin@Sun.COM *                  Common Public License, Version 1.0                  *
78462SApril.Chin@Sun.COM *                    by AT&T Intellectual Property                     *
88462SApril.Chin@Sun.COM *                                                                      *
98462SApril.Chin@Sun.COM *                A copy of the License is available at                 *
108462SApril.Chin@Sun.COM *            http://www.opensource.org/licenses/cpl1.0.txt             *
118462SApril.Chin@Sun.COM *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
128462SApril.Chin@Sun.COM *                                                                      *
138462SApril.Chin@Sun.COM *              Information and Software Systems Research               *
148462SApril.Chin@Sun.COM *                            AT&T Research                             *
158462SApril.Chin@Sun.COM *                           Florham Park NJ                            *
168462SApril.Chin@Sun.COM *                                                                      *
178462SApril.Chin@Sun.COM *                 Glenn Fowler <gsf@research.att.com>                  *
188462SApril.Chin@Sun.COM *                                                                      *
198462SApril.Chin@Sun.COM ***********************************************************************/
208462SApril.Chin@Sun.COM #pragma prototyped
218462SApril.Chin@Sun.COM 
228462SApril.Chin@Sun.COM /*
238462SApril.Chin@Sun.COM  * att
248462SApril.Chin@Sun.COM  */
258462SApril.Chin@Sun.COM 
268462SApril.Chin@Sun.COM #define att_description	\
278462SApril.Chin@Sun.COM 	"The system 5 release 4 checksum. This is the default for \bsum\b \
288462SApril.Chin@Sun.COM 	when \bgetconf UNIVERSE\b is \batt\b. This is the only true sum; \
298462SApril.Chin@Sun.COM 	all of the other methods are order dependent."
308462SApril.Chin@Sun.COM #define att_options	0
318462SApril.Chin@Sun.COM #define att_match	"att|sys5|s5|default"
328462SApril.Chin@Sun.COM #define att_open	long_open
338462SApril.Chin@Sun.COM #define att_init	long_init
348462SApril.Chin@Sun.COM #define att_print	long_print
358462SApril.Chin@Sun.COM #define att_data	long_data
368462SApril.Chin@Sun.COM #define att_scale	512
378462SApril.Chin@Sun.COM 
3810898Sroland.mainz@nrubsig.org #if defined(__SUNPRO_C) || defined(__GNUC__)
3910898Sroland.mainz@nrubsig.org 
4010898Sroland.mainz@nrubsig.org #if defined(__SUNPRO_C)
4110898Sroland.mainz@nrubsig.org #    include <sun_prefetch.h>
4210898Sroland.mainz@nrubsig.org #    define sum_prefetch(addr) sun_prefetch_read_many((void *)(addr))
4310898Sroland.mainz@nrubsig.org #elif defined(__GNUC__)
4410898Sroland.mainz@nrubsig.org #    define sum_prefetch(addr) __builtin_prefetch((addr), 0, 3)
4510898Sroland.mainz@nrubsig.org #else
4610898Sroland.mainz@nrubsig.org #    error Unknown compiler
4710898Sroland.mainz@nrubsig.org #endif
4810898Sroland.mainz@nrubsig.org 
4910898Sroland.mainz@nrubsig.org #define CBLOCK_SIZE (64)
5010898Sroland.mainz@nrubsig.org #pragma unroll(16)
5110898Sroland.mainz@nrubsig.org 
5210898Sroland.mainz@nrubsig.org /* Inmos transputer would love this algorithm */
5310898Sroland.mainz@nrubsig.org static int
att_block(register Sum_t * p,const void * s,size_t n)5410898Sroland.mainz@nrubsig.org att_block(register Sum_t* p, const void* s, size_t n)
5510898Sroland.mainz@nrubsig.org {
5610898Sroland.mainz@nrubsig.org 	register uint32_t	c = ((Integral_t*)p)->sum;
5710898Sroland.mainz@nrubsig.org 	register const unsigned char*	b = (const unsigned char*)s;
5810898Sroland.mainz@nrubsig.org 	register const unsigned char*	e = b + n;
5910898Sroland.mainz@nrubsig.org 	register uint32_t s0, s1, s2, s3, s4, s5, s6, s7;
6010898Sroland.mainz@nrubsig.org 	register unsigned int i;
6110898Sroland.mainz@nrubsig.org 
6210898Sroland.mainz@nrubsig.org 	s0=s1=s2=s3=s4=s5=s6=s7=0U;
6310898Sroland.mainz@nrubsig.org 
6410898Sroland.mainz@nrubsig.org 	sum_prefetch((void *)b);
6510898Sroland.mainz@nrubsig.org 
6610898Sroland.mainz@nrubsig.org 	while (n > CBLOCK_SIZE)
6710898Sroland.mainz@nrubsig.org 	{
6810898Sroland.mainz@nrubsig.org 		sum_prefetch((b+CBLOCK_SIZE));
6910898Sroland.mainz@nrubsig.org 
7010898Sroland.mainz@nrubsig.org 		/* Compiler will unroll for() loops per #pragma unroll */
7110898Sroland.mainz@nrubsig.org 		for (i=0 ; i < (CBLOCK_SIZE/8) ; i++)
7210898Sroland.mainz@nrubsig.org 		{
7310898Sroland.mainz@nrubsig.org 			/*
7410898Sroland.mainz@nrubsig.org 			 * use s0-s7 to decouple calculations (this improves pipelining)
7510898Sroland.mainz@nrubsig.org 			 * because each operation is completely independent from it's
7610898Sroland.mainz@nrubsig.org 			 * siblings
7710898Sroland.mainz@nrubsig.org 			 */
7810898Sroland.mainz@nrubsig.org 			s0+=b[0];
7910898Sroland.mainz@nrubsig.org 			s1+=b[1];
8010898Sroland.mainz@nrubsig.org 			s2+=b[2];
8110898Sroland.mainz@nrubsig.org 			s3+=b[3];
8210898Sroland.mainz@nrubsig.org 			s4+=b[4];
8310898Sroland.mainz@nrubsig.org 			s5+=b[5];
8410898Sroland.mainz@nrubsig.org 			s6+=b[6];
8510898Sroland.mainz@nrubsig.org 			s7+=b[7];
8610898Sroland.mainz@nrubsig.org 
8710898Sroland.mainz@nrubsig.org 			b+=8;
8810898Sroland.mainz@nrubsig.org 			n-=8;
8910898Sroland.mainz@nrubsig.org 		}
9010898Sroland.mainz@nrubsig.org 	}
9110898Sroland.mainz@nrubsig.org 
9210898Sroland.mainz@nrubsig.org 	c+=s0+s1+s2+s3+s4+s5+s6+s7;
9310898Sroland.mainz@nrubsig.org 
9410898Sroland.mainz@nrubsig.org 	while (b < e)
9510898Sroland.mainz@nrubsig.org 		c += *b++;
9610898Sroland.mainz@nrubsig.org 	((Integral_t*)p)->sum = c;
9710898Sroland.mainz@nrubsig.org 	return 0;
9810898Sroland.mainz@nrubsig.org }
9910898Sroland.mainz@nrubsig.org 
10010898Sroland.mainz@nrubsig.org #else
1018462SApril.Chin@Sun.COM static int
att_block(register Sum_t * p,const void * s,size_t n)1028462SApril.Chin@Sun.COM att_block(register Sum_t* p, const void* s, size_t n)
1038462SApril.Chin@Sun.COM {
1048462SApril.Chin@Sun.COM 	register uint32_t	c = ((Integral_t*)p)->sum;
1058462SApril.Chin@Sun.COM 	register unsigned char*	b = (unsigned char*)s;
1068462SApril.Chin@Sun.COM 	register unsigned char*	e = b + n;
1078462SApril.Chin@Sun.COM 
1088462SApril.Chin@Sun.COM 	while (b < e)
1098462SApril.Chin@Sun.COM 		c += *b++;
1108462SApril.Chin@Sun.COM 	((Integral_t*)p)->sum = c;
1118462SApril.Chin@Sun.COM 	return 0;
1128462SApril.Chin@Sun.COM }
11310898Sroland.mainz@nrubsig.org #endif /* defined(__SUNPRO_C) || defined(__GNUC__) */
1148462SApril.Chin@Sun.COM 
1158462SApril.Chin@Sun.COM static int
att_done(Sum_t * p)1168462SApril.Chin@Sun.COM att_done(Sum_t* p)
1178462SApril.Chin@Sun.COM {
1188462SApril.Chin@Sun.COM 	register uint32_t	c = ((Integral_t*)p)->sum;
1198462SApril.Chin@Sun.COM 
1208462SApril.Chin@Sun.COM 	c = (c & 0xffff) + ((c >> 16) & 0xffff);
1218462SApril.Chin@Sun.COM 	c = (c & 0xffff) + (c >> 16);
1228462SApril.Chin@Sun.COM 	((Integral_t*)p)->sum = c & 0xffff;
1238462SApril.Chin@Sun.COM 	return short_done(p);
1248462SApril.Chin@Sun.COM }
125