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*                  Common Public License, Version 1.0                  *
7*                    by AT&T Intellectual Property                     *
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
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("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