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
36union _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
50struct _s_
51{
52	char		s1;
53	union _u_	s2;
54};
55
56#define roundof(x,y)	(((x)+((y)-1))&~((y)-1))
57
58static union _u_	u;
59static union _u_	v;
60
61int
62main()
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