1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 1985-2011 AT&T Intellectual Property          *
5 *                      and is licensed under the                       *
6 *                 Eclipse Public License, Version 1.0                  *
7 *                    by AT&T Intellectual Property                     *
8 *                                                                      *
9 *                A copy of the License is available at                 *
10 *          http://www.eclipse.org/org/documents/epl-v10.html           *
11 *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
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
main()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("\n");
114 	printf("#define ALIGN_CHUNK		%d\n", sizeof(char*) >= 4 ? 8192 : 1024);
115 	printf("#define ALIGN_INTEGRAL		uintptr_t\n");
116 	printf("#define ALIGN_INTEGER(x)	((char*)(x)-(char*)0)\n");
117 	printf("#define ALIGN_POINTER(x)	((char*)(x))\n");
118 	if (bits2 == (align2 - 1))
119 		printf("#define ALIGN_ROUND(x,y)	ALIGN_POINTER(ALIGN_INTEGER((x)+(y)-1)&~((y)-1))\n");
120 	else
121 		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);
122 	printf("\n");
123 	if (align0 == align2)
124 	{
125 		printf("#define ALIGN_BOUND		ALIGN_BOUND2\n");
126 		printf("#define ALIGN_ALIGN(x)		ALIGN_ALIGN2(x)\n");
127 		printf("#define ALIGN_TRUNC(x)		ALIGN_TRUNC2(x)\n");
128 	}
129 	else if (align0 == align1)
130 	{
131 		printf("#define ALIGN_BOUND		ALIGN_BOUND1\n");
132 		printf("#define ALIGN_ALIGN(x)		ALIGN_ALIGN1(x)\n");
133 		printf("#define ALIGN_TRUNC(x)		ALIGN_TRUNC1(x)\n");
134 	}
135 	else
136 	{
137 		printf("#define ALIGN_BOUND		1\n");
138 		printf("#define ALIGN_ALIGN(x)		ALIGN_POINTER(x)\n");
139 		printf("#define ALIGN_TRUNC(x)		ALIGN_POINTER(x)\n");
140 	}
141 	printf("\n");
142 	printf("#define ALIGN_BIT1		0x%lx\n", bit1);
143 	if (align1 == align2)
144 	{
145 		printf("#define ALIGN_BOUND1		ALIGN_BOUND2\n");
146 		printf("#define ALIGN_ALIGN1(x)		ALIGN_ALIGN2(x)\n");
147 		printf("#define ALIGN_TRUNC1(x)		ALIGN_TRUNC2(x)\n");
148 	}
149 	else
150 	{
151 		printf("#define ALIGN_BOUND1		%d\n", align1);
152 		printf("#define ALIGN_ALIGN1(x)		ALIGN_TRUNC1((x)+%d)\n", align1 - 1);
153 		printf("#define ALIGN_TRUNC1(x)		ALIGN_POINTER(ALIGN_INTEGER((x)+%d)&0x%lx)\n", align1 - 1, ~(bits0|bits1));
154 	}
155 #if _X86_ || _X64_
156 	printf("#if _X64_\n");
157 	printf("#define ALIGN_CLRBIT1(x)	ALIGN_POINTER(ALIGN_INTEGER(x)&0xfffffffffffffffeULL)\n");
158 	printf("#else\n");
159 	printf("#define ALIGN_CLRBIT1(x)	ALIGN_POINTER(ALIGN_INTEGER(x)&0xfffffffe)\n");
160 	printf("#endif\n");
161 #else
162 	printf("#define ALIGN_CLRBIT1(x)	ALIGN_POINTER(ALIGN_INTEGER(x)&0x%lx)\n", ~bit1);
163 #endif
164 	printf("#define ALIGN_SETBIT1(x)	ALIGN_POINTER(ALIGN_INTEGER(x)|0x%lx)\n", bit1);
165 	printf("#define ALIGN_TSTBIT1(x)	ALIGN_POINTER(ALIGN_INTEGER(x)&0x%lx)\n", bit1);
166 	printf("\n");
167 	printf("#define ALIGN_BIT2		0x%lx\n", bit2);
168 #if _X86_ || _X64_
169 	printf("#if _X64_\n");
170 	printf("#define ALIGN_BOUND2		16\n");
171 	printf("#define ALIGN_ALIGN2(x)		ALIGN_TRUNC2((x)+15)\n");
172 	printf("#define ALIGN_TRUNC2(x)		ALIGN_POINTER(ALIGN_INTEGER(x)&0xfffffffffffffffeULL)\n");
173 	printf("#else\n");
174 	printf("#define ALIGN_BOUND2		8\n");
175 	printf("#define ALIGN_ALIGN2(x)		ALIGN_TRUNC2((x)+7)\n");
176 	printf("#define ALIGN_TRUNC2(x)		ALIGN_POINTER(ALIGN_INTEGER(x)&0xfffffff8)\n");
177 	printf("#endif\n");
178 #else
179 	printf("#define ALIGN_BOUND2		%d\n", align2);
180 	printf("#define ALIGN_ALIGN2(x)		ALIGN_TRUNC2((x)+%d)\n", align2 - 1);
181 	printf("#define ALIGN_TRUNC2(x)		ALIGN_POINTER(ALIGN_INTEGER(x)&0x%lx)\n", ~(bits0|bits1|bits2));
182 #endif
183 	printf("#define ALIGN_CLRBIT2(x)	ALIGN_POINTER(ALIGN_INTEGER(x)&0x%lx)\n", ~bit2);
184 	printf("#define ALIGN_SETBIT2(x)	ALIGN_POINTER(ALIGN_INTEGER(x)|0x%lx)\n", bit2);
185 	printf("#define ALIGN_TSTBIT2(x)	ALIGN_POINTER(ALIGN_INTEGER(x)&0x%lx)\n", bit2);
186 	printf("\n");
187 	return 0;
188 }
189