xref: /titanic_51/usr/src/lib/libast/common/features/align.c (revision 19d61fc7991644175873937566d932d8cf52912a)
1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *           Copyright (c) 1985-2007 AT&T Knowledge Ventures            *
5 *                      and is licensed under the                       *
6 *                  Common Public License, Version 1.0                  *
7 *                      by AT&T Knowledge Ventures                      *
8 *                                                                      *
9 *                A copy of the License is available at                 *
10 *            http://www.opensource.org/licenses/cpl1.0.txt             *
11 *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12 *                                                                      *
13 *              Information and Software Systems Research               *
14 *                            AT&T Research                             *
15 *                           Florham Park NJ                            *
16 *                                                                      *
17 *                 Glenn Fowler <gsf@research.att.com>                  *
18 *                  David Korn <dgk@research.att.com>                   *
19 *                   Phong Vo <kpv@research.att.com>                    *
20 *                                                                      *
21 ***********************************************************************/
22 #pragma prototyped
23 /*
24  * Glenn Fowler
25  * AT&T Bell Laboratories
26  *
27  * generate align features
28  *
29  * NOTE: two's complement binary integral representation assumed
30  */
31 
32 #include "FEATURE/common"
33 
34 #include <setjmp.h>
35 
36 union _u_
37 {
38 	long			u1;
39 	char*			u2;
40 	double			u3;
41 	char			u4[1024];
42 	intmax_t		u5;
43 	uintmax_t		u6;
44 	_ast_fltmax_t		u7;
45 	void*			u8;
46 	char*			(*u9)();
47 	jmp_buf			u10;
48 };
49 
50 struct _s_
51 {
52 	char		s1;
53 	union _u_	s2;
54 };
55 
56 #define roundof(x,y)	(((x)+((y)-1))&~((y)-1))
57 
58 static union _u_	u;
59 static union _u_	v;
60 
61 int
62 main()
63 {
64 	register int	i;
65 	register int	j;
66 	register int	k;
67 
68 	int		align0;
69 	int		align1;
70 	int		align2;
71 	unsigned long	bit1;
72 	unsigned long	bit2;
73 	unsigned long	bits0;
74 	unsigned long	bits1;
75 	unsigned long	bits2;
76 
77 	u.u2 = u.u4;
78 	v.u2 = u.u2 + 1;
79 	bit1 = u.u1 ^ v.u1;
80 	v.u2 = u.u2 + 2;
81 	bit2 = u.u1 ^ v.u1;
82 	align0 = sizeof(struct _s_) - sizeof(union _u_);
83 	bits0 = 0;
84 	k = 0;
85 	for (j = 0; j < align0; j++)
86 	{
87 		u.u2 = u.u4 + j;
88 		bits1 = 0;
89 		for (i = 0; i < align0; i++)
90 		{
91 			v.u2 = u.u2 + i;
92 			bits1 |= u.u1 ^ v.u1;
93 		}
94 		if (!bits0 || bits1 < bits0)
95 		{
96 			bits0 = bits1;
97 			k = j;
98 		}
99 	}
100 	align1 = roundof(align0, 2);
101 	u.u2 = u.u4 + k;
102 	for (bits1 = bits0; i < align1; i++)
103 	{
104 		v.u2 = u.u2 + i;
105 		bits1 |= u.u1 ^ v.u1;
106 	}
107 	align2 = roundof(align0, 4);
108 	for (bits2 = bits1; i < align2; i++)
109 	{
110 		v.u2 = u.u2 + i;
111 		bits2 |= u.u1 ^ v.u1;
112 	}
113 	printf("typedef unsigned %s ALIGN_INTEGRAL;\n", sizeof(char*) >= sizeof(long) ? "long" : sizeof(char*) >= sizeof(int) ? "int" : "short");
114 	printf("\n");
115 	printf("#define ALIGN_CHUNK		%d\n", sizeof(char*) >= 4 ? 8192 : 1024);
116 	printf("#define ALIGN_INTEGRAL		%s\n", sizeof(char*) >= sizeof(long) ? "long" : sizeof(char*) >= sizeof(int) ? "int" : "short");
117 	printf("#define ALIGN_INTEGER(x)	((ALIGN_INTEGRAL)(x))\n");
118 	printf("#define ALIGN_POINTER(x)	((char*)(x))\n");
119 	if (bits2 == (align2 - 1)) printf("#define ALIGN_ROUND(x,y)	ALIGN_POINTER(ALIGN_INTEGER((x)+(y)-1)&~((y)-1))\n");
120 	else printf("#define ALIGN_ROUND(x,y)	ALIGN_POINTER(ALIGN_INTEGER(ALIGN_ALIGN(x)+(((y)+%d)/%d)-1)&~((((y)+%d)/%d)-1))\n", align0, align0, align0, align0);
121 	printf("\n");
122 	if (align0 == align2)
123 	{
124 		printf("#define ALIGN_BOUND		ALIGN_BOUND2\n");
125 		printf("#define ALIGN_ALIGN(x)		ALIGN_ALIGN2(x)\n");
126 		printf("#define ALIGN_TRUNC(x)		ALIGN_TRUNC2(x)\n");
127 	}
128 	else if (align0 == align1)
129 	{
130 		printf("#define ALIGN_BOUND		ALIGN_BOUND1\n");
131 		printf("#define ALIGN_ALIGN(x)		ALIGN_ALIGN1(x)\n");
132 		printf("#define ALIGN_TRUNC(x)		ALIGN_TRUNC1(x)\n");
133 	}
134 	else
135 	{
136 		printf("#define ALIGN_BOUND		1\n");
137 		printf("#define ALIGN_ALIGN(x)		ALIGN_POINTER(x)\n");
138 		printf("#define ALIGN_TRUNC(x)		ALIGN_POINTER(x)\n");
139 	}
140 	printf("\n");
141 	printf("#define ALIGN_BIT1		0x%lx\n", bit1);
142 	if (align1 == align2)
143 	{
144 		printf("#define ALIGN_BOUND1		ALIGN_BOUND2\n");
145 		printf("#define ALIGN_ALIGN1(x)		ALIGN_ALIGN2(x)\n");
146 		printf("#define ALIGN_TRUNC1(x)		ALIGN_TRUNC2(x)\n");
147 	}
148 	else
149 	{
150 		printf("#define ALIGN_BOUND1		%d\n", align1);
151 		printf("#define ALIGN_ALIGN1(x)		ALIGN_TRUNC1((x)+%d)\n", align1 - 1);
152 		printf("#define ALIGN_TRUNC1(x)		ALIGN_POINTER(ALIGN_INTEGER((x)+%d)&0x%lx)\n", align1 - 1, ~(bits0|bits1));
153 	}
154 	printf("#define ALIGN_CLRBIT1(x)	ALIGN_POINTER(ALIGN_INTEGER(x)&0x%lx)\n", ~bit1);
155 	printf("#define ALIGN_SETBIT1(x)	ALIGN_POINTER(ALIGN_INTEGER(x)|0x%lx)\n", bit1);
156 	printf("#define ALIGN_TSTBIT1(x)	ALIGN_POINTER(ALIGN_INTEGER(x)&0x%lx)\n", bit1);
157 	printf("\n");
158 	printf("#define ALIGN_BIT2		0x%lx\n", bit2);
159 	printf("#define ALIGN_BOUND2		%d\n", align2);
160 	printf("#define ALIGN_ALIGN2(x)		ALIGN_TRUNC2((x)+%d)\n", align2 - 1);
161 	printf("#define ALIGN_TRUNC2(x)		ALIGN_POINTER(ALIGN_INTEGER(x)&0x%lx)\n", ~(bits0|bits1|bits2));
162 	printf("#define ALIGN_CLRBIT2(x)	ALIGN_POINTER(ALIGN_INTEGER(x)&0x%lx)\n", ~bit2);
163 	printf("#define ALIGN_SETBIT2(x)	ALIGN_POINTER(ALIGN_INTEGER(x)|0x%lx)\n", bit2);
164 	printf("#define ALIGN_TSTBIT2(x)	ALIGN_POINTER(ALIGN_INTEGER(x)&0x%lx)\n", bit2);
165 	printf("\n");
166 	return 0;
167 }
168