1 /* @(#)align_test.c	1.31 15/11/30 Copyright 1995-2015 J. Schilling */
2 #include <schily/mconfig.h>
3 #ifndef	lint
4 static	UConst char sccsid[] =
5 	"@(#)align_test.c	1.31 15/11/30 Copyright 1995-2015 J. Schilling";
6 #endif
7 /*
8  *	Generate machine dependant align.h
9  *
10  *	Copyright (c) 1995-2015 J. Schilling
11  */
12 /*
13  * The contents of this file are subject to the terms of the
14  * Common Development and Distribution License, Version 1.0 only
15  * (the "License").  You may not use this file except in compliance
16  * with the License.
17  *
18  * See the file CDDL.Schily.txt in this distribution for details.
19  * A copy of the CDDL is also available via the Internet at
20  * http://www.opensource.org/licenses/cddl1.txt
21  *
22  * When distributing Covered Code, include this CDDL HEADER in each
23  * file and include the License file CDDL.Schily.txt from this distribution.
24  */
25 
26 #include <schily/stdio.h>
27 #include <schily/standard.h>
28 #undef	NO_LONGLONG	/* Make sure that Llong will be long long */
29 #include <schily/utypes.h>
30 #include <schily/libport.h>	/* Define missing prototypes */
31 
32 /*
33  * Be very careful here as MSVC does not implement long long but rather __int64
34  * and once someone makes 'long long' 128 bits on a 64 bit machine, we need to
35  * check for a MSVC __int128 type.
36  */
37 
38 /*
39  * CHECK_ALIGN needs SIGBUS, but DJGPP has no SIGBUS
40  */
41 /*#define	FORCE_ALIGN*/
42 /*#define	OFF_ALIGN*/
43 /*#define	CHECK_ALIGN*/
44 
45 EXPORT	int	main	__PR((int ac, char **av));
46 
47 #if	!defined(FORCE_ALIGN) && !defined(OFF_ALIGN) &&	!defined(CHECK_ALIGN)
48 #define	OFF_ALIGN
49 #endif
50 
51 char	buf[8192+1024];
52 char	*buf_aligned;
53 
54 #ifdef	FORCE_ALIGN
55 #	undef	CHECK_ALIGN
56 #	undef	OFF_ALIGN
57 #endif
58 
59 #ifdef	CHECK_ALIGN
60 #	undef	FORCE_ALIGN
61 #	undef	OFF_ALIGN
62 #endif
63 
64 #ifdef	OFF_ALIGN
65 #	undef	FORCE_ALIGN
66 #	undef	CHECK_ALIGN
67 #endif
68 
69 
70 #ifdef	FORCE_ALIGN
71 
72 #define	ALIGN_short	sizeof (short)
73 #define	ALIGN_int	sizeof (int)
74 #define	ALIGN_long	sizeof (long)
75 #define	ALIGN_longlong	sizeof (Llong)
76 #define	ALIGN_float	sizeof (float)
77 #define	ALIGN_double	sizeof (double)
78 #define	ALIGN_ldouble	sizeof (long double)
79 #define	ALIGN_ptr	sizeof (char *)
80 
81 #endif
82 
83 #ifdef	CHECK_ALIGN
84 
85 #include <schily/signal.h>
86 #include <schily/setjmp.h>
87 LOCAL	jmp_buf	jb;
88 
89 LOCAL	int	check_align	__PR((int (*)(char *, int),
90 					void (*)(char *, int), int));
91 LOCAL	int	check_short	__PR((char *, int));
92 LOCAL	int	check_int	__PR((char *, int));
93 LOCAL	int	check_long	__PR((char *, int));
94 LOCAL	int	check_longlong	__PR((char *, int));
95 LOCAL	int	check_float	__PR((char *, int));
96 LOCAL	int	check_double	__PR((char *, int));
97 #ifdef	HAVE_LONGDOUBLE
98 LOCAL	int	check_ldouble	__PR((char *, int));
99 #endif
100 LOCAL	int	check_ptr	__PR((char *, int));
101 
102 LOCAL	int	speed_check	__PR((char *,
103 					void (*)(char *, int), int));
104 LOCAL	void	speed_short	__PR((char *, int));
105 LOCAL	void	speed_int	__PR((char *, int));
106 LOCAL	void	speed_long	__PR((char *, int));
107 LOCAL	void	speed_longlong	__PR((char *, int));
108 LOCAL	void	speed_float	__PR((char *, int));
109 LOCAL	void	speed_double	__PR((char *, int));
110 #ifdef	HAVE_LONGDOUBLE
111 LOCAL	void	speed_ldouble	__PR((char *, int));
112 #endif
113 LOCAL	void	speed_ptr	__PR((char *, int));
114 
115 #define	ALIGN_short	check_align(check_short, speed_short, sizeof (short))
116 #define	ALIGN_int	check_align(check_int, speed_int, sizeof (int))
117 #define	ALIGN_long	check_align(check_long, speed_long, sizeof (long))
118 #define	ALIGN_longlong	check_align(check_longlong, speed_longlong, sizeof (Llong))
119 #define	ALIGN_float	check_align(check_float, speed_float, sizeof (float))
120 #define	ALIGN_double	check_align(check_double, speed_double, sizeof (double))
121 #define	ALIGN_ldouble	check_align(check_ldouble, speed_ldouble, sizeof (long double))
122 #define	ALIGN_ptr	check_align(check_ptr, speed_ptr, sizeof (char *))
123 
124 #endif
125 
126 #ifdef	OFF_ALIGN
127 
128 #define	sm_off(s, m)	((size_t)&((s)0)->m)
129 
130 LOCAL	void	used		__PR((int i));
131 LOCAL	int	off_short	__PR((void));
132 LOCAL	int	off_int		__PR((void));
133 LOCAL	int	off_long	__PR((void));
134 LOCAL	int	off_longlong	__PR((void));
135 LOCAL	int	off_float	__PR((void));
136 LOCAL	int	off_double	__PR((void));
137 #ifdef	HAVE_LONGDOUBLE
138 LOCAL	int	off_ldouble	__PR((void));
139 #endif
140 LOCAL	int	off_ptr		__PR((void));
141 
142 #define	ALIGN_short	off_short()
143 #define	ALIGN_int	off_int()
144 #define	ALIGN_long	off_long()
145 #define	ALIGN_longlong	off_longlong()
146 #define	ALIGN_float	off_float()
147 #define	ALIGN_double	off_double()
148 #define	ALIGN_ldouble	off_ldouble()
149 #define	ALIGN_ptr	off_ptr()
150 
151 #endif
152 
153 LOCAL	void	printmacs	__PR((void));
154 
155 #ifdef	CHECK_ALIGN
156 LOCAL	void	sig		__PR((int));
157 
158 LOCAL void
sig(signo)159 sig(signo)
160 	int	signo;
161 {
162 	signal(signo, sig);
163 	longjmp(jb, 1);
164 }
165 #endif
166 
167 #if defined(mc68000) || defined(mc68020)
168 #define	MIN_ALIGN	2
169 #else
170 #define	MIN_ALIGN	2
171 #endif
172 
173 
174 #define	min_align(i)	(((i) < MIN_ALIGN) ? MIN_ALIGN : (i))
175 
176 /*
177  * Make it LOCAL MacOS-X by default links against libcurses and
178  * so we totherwise have a double defined "al".
179  */
180 LOCAL	char	al[] = "alignment value for ";
181 LOCAL	char	ms[] = "alignment mask  for ";
182 LOCAL	char	so[] = "sizeof ";
183 LOCAL	char	sh[] = "short";
184 LOCAL	char	in[] = "int";
185 LOCAL	char	lo[] = "long";
186 LOCAL	char	ll[] = "long long";
187 LOCAL	char	fl[] = "float";
188 LOCAL	char	db[] = "double";
189 LOCAL	char	ld[] = "long double";
190 LOCAL	char	pt[] = "pointer";
191 LOCAL	char	mt[] = "max type";
192 
193 #define	xalign(x, a, m)		(((char *)(x)) + ((a) - (((UIntptr_t)(x))&(m))))
194 
195 EXPORT int
main(ac,av)196 main(ac, av)
197 	int	ac;
198 	char	**av;
199 {
200 	char	*p;
201 	int	i;
202 	int	s;
203 	int	amax = 0;
204 	int	smax = 0;
205 
206 #ifdef	CHECK_ALIGN
207 #ifdef	SIGBUS
208 	signal(SIGBUS, sig);
209 #endif
210 #endif
211 
212 	i = ((size_t)buf) % 1024;
213 	i = 1024 - i;
214 	p = &buf[i];
215 	buf_aligned = p;
216 
217 #ifdef	DEBUG
218 	fprintf(stderr, "buf: 0x%lX 0x%lX\n",
219 		(unsigned long)buf, (unsigned long)xalign(buf, 1024, 1023));
220 #endif
221 
222 	printf("/*\n");
223 	printf(" * This file has been generated automatically\n");
224 	printf(" * by %s\n", sccsid);
225 	printf(" * do not edit by hand.\n");
226 	printf(" */\n");
227 	printf("#ifndef	__ALIGN_H\n");
228 	printf("#define	__ALIGN_H\n\n");
229 
230 	s = sizeof (short);
231 	i  = ALIGN_short;
232 	i = min_align(i);
233 	if (i > amax)
234 		amax = i;
235 	if (s > smax)
236 		smax = s;
237 	printf("\n");
238 	printf("#define	ALIGN_SHORT	%d\t/* %s(%s *)\t*/\n", i, al, sh);
239 	printf("#define	ALIGN_SMASK	%d\t/* %s(%s *)\t*/\n", i-1, ms, sh);
240 	printf("#define	SIZE_SHORT	%d\t/* %s(%s)\t\t\t*/\n", s, so, sh);
241 
242 	s = sizeof (int);
243 	i  = ALIGN_int;
244 	i = min_align(i);
245 	if (i > amax)
246 		amax = i;
247 	if (s > smax)
248 		smax = s;
249 	printf("\n");
250 	printf("#define	ALIGN_INT	%d\t/* %s(%s *)\t\t*/\n", i, al, in);
251 	printf("#define	ALIGN_IMASK	%d\t/* %s(%s *)\t\t*/\n", i-1, ms, in);
252 	printf("#define	SIZE_INT	%d\t/* %s(%s)\t\t\t\t*/\n", s, so, in);
253 
254 	s = sizeof (long);
255 	i  = ALIGN_long;
256 	i = min_align(i);
257 	if (i > amax)
258 		amax = i;
259 	if (s > smax)
260 		smax = s;
261 	printf("\n");
262 	printf("#define	ALIGN_LONG	%d\t/* %s(%s *)\t\t*/\n", i, al, lo);
263 	printf("#define	ALIGN_LMASK	%d\t/* %s(%s *)\t\t*/\n", i-1, ms, lo);
264 	printf("#define	SIZE_LONG	%d\t/* %s(%s)\t\t\t*/\n", s, so, lo);
265 
266 #ifdef	HAVE_LONGLONG
267 	s = sizeof (Llong);
268 	i  = ALIGN_longlong;
269 	i = min_align(i);
270 	if (i > amax)
271 		amax = i;
272 	if (s > smax)
273 		smax = s;
274 #endif
275 	printf("\n");
276 	printf("#define	ALIGN_LLONG	%d\t/* %s(%s *)\t*/\n", i, al, ll);
277 	printf("#define	ALIGN_LLMASK	%d\t/* %s(%s *)\t*/\n", i-1, ms, ll);
278 	printf("#define	SIZE_LLONG	%d\t/* %s(%s)\t\t\t*/\n", s, so, ll);
279 
280 	s = sizeof (float);
281 	i  = ALIGN_float;
282 	i = min_align(i);
283 	if (i > amax)
284 		amax = i;
285 	if (s > smax)
286 		smax = s;
287 	printf("\n");
288 	printf("#define	ALIGN_FLOAT	%d\t/* %s(%s *)\t*/\n", i, al, fl);
289 	printf("#define	ALIGN_FMASK	%d\t/* %s(%s *)\t*/\n", i-1, ms, fl);
290 	printf("#define	SIZE_FLOAT	%d\t/* %s(%s)\t\t\t*/\n", s, so, fl);
291 
292 	s = sizeof (double);
293 	i  = ALIGN_double;
294 	i = min_align(i);
295 	if (i > amax)
296 		amax = i;
297 	if (s > smax)
298 		smax = s;
299 	printf("\n");
300 	printf("#define	ALIGN_DOUBLE	%d\t/* %s(%s *)\t*/\n", i, al, db);
301 	printf("#define	ALIGN_DMASK	%d\t/* %s(%s *)\t*/\n", i-1, ms, db);
302 	printf("#define	SIZE_DOUBLE	%d\t/* %s(%s)\t\t\t*/\n", s, so, db);
303 
304 #ifdef	HAVE_LONGDOUBLE
305 	s = sizeof (long double);
306 	i  = ALIGN_ldouble;
307 	i = min_align(i);
308 	if (i > amax)
309 		amax = i;
310 	if (s > smax)
311 		smax = s;
312 #endif
313 	printf("\n");
314 	printf("#define	ALIGN_LDOUBLE	%d\t/* %s(%s *)\t*/\n", i, al, ld);
315 	printf("#define	ALIGN_LDMASK	%d\t/* %s(%s *)\t*/\n", i-1, ms, ld);
316 	printf("#define	SIZE_LDOUBLE	%d\t/* %s(%s)\t\t\t*/\n", s, so, ld);
317 
318 	s = sizeof (char *);
319 	i  = ALIGN_ptr;
320 	i = min_align(i);
321 	if (i > amax)
322 		amax = i;
323 	if (s > smax)
324 		smax = s;
325 	printf("\n");
326 	printf("#define	ALIGN_PTR	%d\t/* %s(%s *)\t*/\n", i, al, pt);
327 	printf("#define	ALIGN_PMASK	%d\t/* %s(%s *)\t*/\n", i-1, ms, pt);
328 	printf("#define	SIZE_PTR	%d\t/* %s(%s)\t\t\t*/\n", s, so, pt);
329 
330 	printf("\n");
331 	printf("#define	ALIGN_TMAX	%d\t/* %s(%s *)\t*/\n", amax, al, mt);
332 	printf("#define	ALIGN_TMMASK	%d\t/* %s(%s *)\t*/\n", amax-1, ms, mt);
333 	printf("#define	SIZE_TMAX	%d\t/* %s(%s)\t\t\t*/\n", smax, so, mt);
334 
335 	printmacs();
336 	printf("\n#endif	/* __ALIGN_H */\n");
337 	fflush(stdout);
338 	return (0);
339 }
340 
341 LOCAL void
printmacs()342 printmacs()
343 {
344 printf("\n\n");
345 printf("/*\n * There used to be a cast to an int but we get a warning from GCC.\n");
346 printf(" * This warning message from GCC is wrong.\n");
347 printf(" * Believe me that this macro would even be usable if I would cast to short.\n");
348 printf(" * In order to avoid this warning, we are now using UIntptr_t\n */\n");
349 /*printf("\n");*/
350 /*printf("\n");*/
351 printf("#define	xaligned(a, s)		((((UIntptr_t)(a)) & (s)) == 0)\n");
352 printf("#define	x2aligned(a, b, s)	(((((UIntptr_t)(a)) | ((UIntptr_t)(b))) & (s)) == 0)\n");
353 printf("\n");
354 printf("#define	saligned(a)		xaligned(a, ALIGN_SMASK)\n");
355 printf("#define	s2aligned(a, b)		x2aligned(a, b, ALIGN_SMASK)\n");
356 printf("\n");
357 printf("#define	ialigned(a)		xaligned(a, ALIGN_IMASK)\n");
358 printf("#define	i2aligned(a, b)		x2aligned(a, b, ALIGN_IMASK)\n");
359 printf("\n");
360 printf("#define	laligned(a)		xaligned(a, ALIGN_LMASK)\n");
361 printf("#define	l2aligned(a, b)		x2aligned(a, b, ALIGN_LMASK)\n");
362 printf("\n");
363 printf("#define	llaligned(a)		xaligned(a, ALIGN_LLMASK)\n");
364 printf("#define	ll2aligned(a, b)	x2aligned(a, b, ALIGN_LLMASK)\n");
365 printf("\n");
366 printf("#define	faligned(a)		xaligned(a, ALIGN_FMASK)\n");
367 printf("#define	f2aligned(a, b)		x2aligned(a, b, ALIGN_FMASK)\n");
368 printf("\n");
369 printf("#define	daligned(a)		xaligned(a, ALIGN_DMASK)\n");
370 printf("#define	d2aligned(a, b)		x2aligned(a, b, ALIGN_DMASK)\n");
371 printf("\n");
372 printf("#define	ldaligned(a)		xaligned(a, ALIGN_LDMASK)\n");
373 printf("#define	ld2aligned(a, b)	x2aligned(a, b, ALIGN_LDMASK)\n");
374 printf("\n");
375 printf("#define	paligned(a)		xaligned(a, ALIGN_PMASK)\n");
376 printf("#define	p2aligned(a, b)		x2aligned(a, b, ALIGN_PMASK)\n");
377 printf("\n");
378 printf("#define	maligned(a)		xaligned(a, ALIGN_TMMASK)\n");
379 printf("#define	m2aligned(a, b)		x2aligned(a, b, ALIGN_TMMASK)\n");
380 
381 printf("\n\n");
382 printf("/*\n * There used to be a cast to an int but we get a warning from GCC.\n");
383 printf(" * This warning message from GCC is wrong.\n");
384 printf(" * Believe me that this macro would even be usable if I would cast to short.\n");
385 printf(" * In order to avoid this warning, we are now using UIntptr_t\n */\n");
386 printf("#define	xalign(x, a, m)		(((char *)(x)) + ((a) - 1 - ((((UIntptr_t)(x))-1)&(m))))\n");
387 printf("\n");
388 printf("#define	salign(x)		xalign((x), ALIGN_SHORT, ALIGN_SMASK)\n");
389 printf("#define	ialign(x)		xalign((x), ALIGN_INT, ALIGN_IMASK)\n");
390 printf("#define	lalign(x)		xalign((x), ALIGN_LONG, ALIGN_LMASK)\n");
391 printf("#define	llalign(x)		xalign((x), ALIGN_LLONG, ALIGN_LLMASK)\n");
392 printf("#define	falign(x)		xalign((x), ALIGN_FLOAT, ALIGN_FMASK)\n");
393 printf("#define	dalign(x)		xalign((x), ALIGN_DOUBLE, ALIGN_DMASK)\n");
394 printf("#define	ldalign(x)		xalign((x), ALIGN_LDOUBLE, ALIGN_LDMASK)\n");
395 printf("#define	palign(x)		xalign((x), ALIGN_PTR, ALIGN_PMASK)\n");
396 printf("#define	malign(x)		xalign((x), ALIGN_TMAX, ALIGN_TMMASK)\n");
397 }
398 
399 #ifdef	CHECK_ALIGN
400 /*
401  * Routines to compute the alignement by checking if the assignement
402  * causes a bus error.
403  * Some systems (e.g. Linux on DEC Aplha) will allow to fetch any
404  * type from any address. On these systems we must check the speed
405  * because unaligned fetches will take more time.
406  */
407 LOCAL int
408 check_align(cfunc, sfunc, tsize)
409 	int	(*cfunc)();
410 	void	(*sfunc)();
411 	int	tsize;
412 {
413 		int	calign;
414 		int	align;
415 		int	tcheck;
416 		int	t;
417 	register int	i;
418 	register char	*p = buf_aligned;
419 
420 	for (i = 1; i < 128; i++) {
421 		if (!setjmp(jb)) {
422 			(cfunc)(p, i);
423 			break;
424 		}
425 	}
426 #ifdef	DEBUG
427 	fprintf(stderr, "i: %d tsize: %d\n", i, tsize);
428 #endif
429 	if (i == tsize)
430 		return (i);
431 
432 	align = calign = i;
433 	tcheck = speed_check(p, sfunc, i);
434 #ifdef	DEBUG
435 	fprintf(stderr, "tcheck: %d\n", tcheck);
436 #endif
437 
438 	for (i = calign*2; i <= tsize; i *= 2) {
439 		t = speed_check(p, sfunc, i);
440 #ifdef	DEBUG
441 		fprintf(stderr, "tcheck: %d t: %d i: %d\n", tcheck, t, i);
442 		fprintf(stderr, "tcheck - t: %d ... * 3: %d\n",  (tcheck - t), (tcheck - t) * 3);
443 #endif
444 		if (((tcheck - t) > 0) && ((tcheck - t) * 3) > tcheck) {
445 #ifdef	DEBUG
446 			fprintf(stderr, "kleiner\n");
447 #endif
448 			align = i;
449 			tcheck = t;
450 		}
451 	}
452 	return (align);
453 }
454 
455 LOCAL int
check_short(p,i)456 check_short(p, i)
457 	char	*p;
458 	int	i;
459 {
460 	short	*sp;
461 
462 	sp = (short *)&p[i];
463 	*sp = 1;
464 	return (0);
465 }
466 
467 LOCAL int
check_int(p,i)468 check_int(p, i)
469 	char	*p;
470 	int	i;
471 {
472 	int	*ip;
473 
474 	ip = (int *)&p[i];
475 	*ip = 1;
476 	return (0);
477 }
478 
479 LOCAL int
check_long(p,i)480 check_long(p, i)
481 	char	*p;
482 	int	i;
483 {
484 	long	*lp;
485 
486 	lp = (long *)&p[i];
487 	*lp = 1;
488 	return (0);
489 }
490 
491 #ifdef	HAVE_LONGLONG
492 LOCAL int
check_longlong(p,i)493 check_longlong(p, i)
494 	char	*p;
495 	int	i;
496 {
497 	Llong	*llp;
498 
499 	llp = (Llong *)&p[i];
500 	*llp = 1;
501 	return (0);
502 }
503 #endif
504 
505 LOCAL int
check_float(p,i)506 check_float(p, i)
507 	char	*p;
508 	int	i;
509 {
510 	float	*fp;
511 
512 	fp = (float *)&p[i];
513 	*fp = 1.0;
514 	return (0);
515 }
516 
517 LOCAL int
check_double(p,i)518 check_double(p, i)
519 	char	*p;
520 	int	i;
521 {
522 	double	*dp;
523 
524 	dp = (double *)&p[i];
525 	*dp = 1.0;
526 	return (0);
527 }
528 
529 #ifdef	HAVE_LONGDOUBLE
530 LOCAL int
check_ldouble(p,i)531 check_ldouble(p, i)
532 	char	*p;
533 	int	i;
534 {
535 	long double	*dp;
536 
537 	dp = (long double *)&p[i];
538 	*dp = 1.0;
539 	return (0);
540 }
541 #endif
542 
543 LOCAL int
check_ptr(p,i)544 check_ptr(p, i)
545 	char	*p;
546 	int	i;
547 {
548 	char	**pp;
549 
550 	pp = (char  **)&p[i];
551 	*pp = (char *)1;
552 	return (0);
553 }
554 
555 /*
556  * Routines to compute the alignement by checking the speed of the
557  * assignement.
558  * Some systems (e.g. Linux on DEC Aplha) will allow to fetch any
559  * type from any address. On these systems we must check the speed
560  * because unaligned fetches will take more time.
561  */
562 LOCAL void
speed_short(p,n)563 speed_short(p, n)
564 	char	*p;
565 	int	n;
566 {
567 	short	*sp;
568 	int	i;
569 
570 	sp = (short *)&p[n];
571 
572 	for (i = 1000000; --i >= 0; )
573 		*sp = i;
574 }
575 
576 LOCAL void
speed_int(p,n)577 speed_int(p, n)
578 	char	*p;
579 	int	n;
580 {
581 	int	*ip;
582 	int	i;
583 
584 	ip = (int *)&p[n];
585 
586 	for (i = 1000000; --i >= 0; )
587 		*ip = i;
588 }
589 
590 LOCAL void
speed_long(p,n)591 speed_long(p, n)
592 	char	*p;
593 	int	n;
594 {
595 	long	*lp;
596 	int	i;
597 
598 	lp = (long *)&p[n];
599 
600 	for (i = 1000000; --i >= 0; )
601 		*lp = i;
602 }
603 
604 #ifdef	HAVE_LONGLONG
605 LOCAL void
speed_longlong(p,n)606 speed_longlong(p, n)
607 	char	*p;
608 	int	n;
609 {
610 	Llong *llp;
611 	int	i;
612 
613 	llp = (Llong *)&p[n];
614 
615 	for (i = 1000000; --i >= 0; )
616 		*llp = i;
617 }
618 #endif
619 
620 LOCAL void
speed_float(p,n)621 speed_float(p, n)
622 	char	*p;
623 	int	n;
624 {
625 	float	*fp;
626 	int	i;
627 
628 	fp = (float *)&p[n];
629 
630 	for (i = 1000000; --i >= 0; )
631 		*fp = i;
632 }
633 
634 LOCAL void
speed_double(p,n)635 speed_double(p, n)
636 	char	*p;
637 	int	n;
638 {
639 	double	*dp;
640 	int	i;
641 
642 	dp = (double *)&p[n];
643 
644 	for (i = 1000000; --i >= 0; )
645 		*dp = i;
646 }
647 
648 #ifdef	HAVE_LONGDOUBLE
649 LOCAL void
speed_ldouble(p,n)650 speed_ldouble(p, n)
651 	char	*p;
652 	int	n;
653 {
654 	long double	*dp;
655 	int	i;
656 
657 	dp = (long double *)&p[n];
658 
659 	for (i = 1000000; --i >= 0; )
660 		*dp = i;
661 }
662 #endif
663 
664 LOCAL void
speed_ptr(p,n)665 speed_ptr(p, n)
666 	char	*p;
667 	int	n;
668 {
669 	char	**pp;
670 	int	i;
671 
672 	pp = (char **)&p[n];
673 
674 	for (i = 1000000; --i >= 0; )
675 		*pp = (char *)i;
676 }
677 
678 #include <schily/time.h>
679 #include <schily/times.h>
680 LOCAL int
speed_check(p,sfunc,n)681 speed_check(p, sfunc, n)
682 	char	*p;
683 	void	(*sfunc)();
684 	int	n;
685 {
686 	struct tms tm1;
687 	struct tms tm2;
688 
689 	times(&tm1);
690 	(*sfunc)(p, n);
691 	times(&tm2);
692 
693 #ifdef	DEBUG
694 	fprintf(stderr, "t1: %ld\n", (long)tm2.tms_utime-tm1.tms_utime);
695 #endif
696 
697 	return ((int)tm2.tms_utime-tm1.tms_utime);
698 }
699 
700 #endif	/* CHECK_ALIGN */
701 
702 #ifdef	OFF_ALIGN
703 /*
704  * Routines to compute the alignement by using the knowledge
705  * of the C-compiler.
706  * We define a structure and check the padding that has been inserted
707  * by the compiler to keep the apropriate type on a properly aligned
708  * address.
709  */
710 LOCAL	int	used_var;
711 LOCAL void
used(i)712 used(i)
713 	int	i;
714 {
715 	used_var = i;
716 }
717 
718 LOCAL int
off_short()719 off_short()
720 {
721 	struct ss {
722 		char	c;
723 		short	s;
724 	} ss;
725 	ss.c = 0;		/* fool C-compiler */
726 	used(ss.c);
727 
728 	return (sm_off(struct ss *, s));
729 }
730 
731 LOCAL int
off_int()732 off_int()
733 {
734 	struct si {
735 		char	c;
736 		int	i;
737 	} si;
738 	si.c = 0;		/* fool C-compiler */
739 	used(si.c);
740 
741 	return (sm_off(struct si *, i));
742 }
743 
744 LOCAL int
off_long()745 off_long()
746 {
747 	struct sl {
748 		char	c;
749 		long	l;
750 	} sl;
751 	sl.c = 0;		/* fool C-compiler */
752 	used(sl.c);
753 
754 	return (sm_off(struct sl *, l));
755 }
756 
757 #ifdef	HAVE_LONGLONG
758 LOCAL int
off_longlong()759 off_longlong()
760 {
761 	struct sll {
762 		char	c;
763 		Llong	ll;
764 	} sll;
765 	sll.c = 0;		/* fool C-compiler */
766 	used(sll.c);
767 
768 	return (sm_off(struct sll *, ll));
769 }
770 #endif
771 
772 LOCAL int
off_float()773 off_float()
774 {
775 	struct sf {
776 		char	c;
777 		float	f;
778 	} sf;
779 	sf.c = 0;		/* fool C-compiler */
780 	used(sf.c);
781 
782 	return (sm_off(struct sf *, f));
783 }
784 
785 LOCAL int
off_double()786 off_double()
787 {
788 	struct sd {
789 		char	c;
790 		double	d;
791 	} sd;
792 	sd.c = 0;		/* fool C-compiler */
793 	used(sd.c);
794 
795 	return (sm_off(struct sd *, d));
796 }
797 
798 #ifdef	HAVE_LONGDOUBLE
799 LOCAL int
off_ldouble()800 off_ldouble()
801 {
802 	struct sd {
803 		char		c;
804 		long double	ld;
805 	} sd;
806 	sd.c = 0;		/* fool C-compiler */
807 	used(sd.c);
808 
809 	return (sm_off(struct sd *, ld));
810 }
811 #endif
812 
813 LOCAL int
off_ptr()814 off_ptr()
815 {
816 	struct sp {
817 		char	c;
818 		char	*p;
819 	} sp;
820 	sp.c = 0;		/* fool C-compiler */
821 	used(sp.c);
822 
823 	return (sm_off(struct sp *, p));
824 }
825 
826 #endif	/* OFF_ALIGN */
827