1f08c3bdfSopenharmony_ci#include <stdio.h>
2f08c3bdfSopenharmony_ci#include <string.h>
3f08c3bdfSopenharmony_ci
4f08c3bdfSopenharmony_ci#include "symbol.h"
5f08c3bdfSopenharmony_ci#include "target.h"
6f08c3bdfSopenharmony_ci#include "machine.h"
7f08c3bdfSopenharmony_ci
8f08c3bdfSopenharmony_cistruct symbol *ptrdiff_ctype;
9f08c3bdfSopenharmony_cistruct symbol *intptr_ctype;
10f08c3bdfSopenharmony_cistruct symbol *uintptr_ctype;
11f08c3bdfSopenharmony_cistruct symbol *size_t_ctype = &ulong_ctype;
12f08c3bdfSopenharmony_cistruct symbol *ssize_t_ctype = &long_ctype;
13f08c3bdfSopenharmony_cistruct symbol *intmax_ctype = &long_ctype;
14f08c3bdfSopenharmony_cistruct symbol *uintmax_ctype = &ulong_ctype;
15f08c3bdfSopenharmony_cistruct symbol *int64_ctype = &long_ctype;
16f08c3bdfSopenharmony_cistruct symbol *uint64_ctype = &ulong_ctype;
17f08c3bdfSopenharmony_cistruct symbol *int32_ctype = &int_ctype;
18f08c3bdfSopenharmony_cistruct symbol *uint32_ctype = &uint_ctype;
19f08c3bdfSopenharmony_cistruct symbol *wchar_ctype = &int_ctype;
20f08c3bdfSopenharmony_cistruct symbol *wint_ctype = &uint_ctype;
21f08c3bdfSopenharmony_cistruct symbol *least8_ctype = &schar_ctype;
22f08c3bdfSopenharmony_cistruct symbol *uleast8_ctype = &uchar_ctype;
23f08c3bdfSopenharmony_cistruct symbol *least16_ctype = &short_ctype;
24f08c3bdfSopenharmony_cistruct symbol *uleast16_ctype = &ushort_ctype;
25f08c3bdfSopenharmony_cistruct symbol *least32_ctype = &int_ctype;
26f08c3bdfSopenharmony_cistruct symbol *uleast32_ctype = &uint_ctype;
27f08c3bdfSopenharmony_cistruct symbol *least64_ctype = &llong_ctype;
28f08c3bdfSopenharmony_cistruct symbol *uleast64_ctype = &ullong_ctype;
29f08c3bdfSopenharmony_cistruct symbol *fast8_ctype = &schar_ctype;
30f08c3bdfSopenharmony_cistruct symbol *ufast8_ctype = &uchar_ctype;
31f08c3bdfSopenharmony_cistruct symbol *fast16_ctype = &long_ctype;
32f08c3bdfSopenharmony_cistruct symbol *ufast16_ctype = &ulong_ctype;
33f08c3bdfSopenharmony_cistruct symbol *fast32_ctype = &long_ctype;
34f08c3bdfSopenharmony_cistruct symbol *ufast32_ctype = &ulong_ctype;
35f08c3bdfSopenharmony_cistruct symbol *fast64_ctype = &long_ctype;
36f08c3bdfSopenharmony_cistruct symbol *ufast64_ctype = &ulong_ctype;
37f08c3bdfSopenharmony_cistruct symbol *sig_atomic_ctype = &int_ctype;
38f08c3bdfSopenharmony_ci
39f08c3bdfSopenharmony_ci/*
40f08c3bdfSopenharmony_ci * For "__attribute__((aligned))"
41f08c3bdfSopenharmony_ci */
42f08c3bdfSopenharmony_ciint max_alignment = 16;
43f08c3bdfSopenharmony_ci
44f08c3bdfSopenharmony_ci/*
45f08c3bdfSopenharmony_ci * Integer data types
46f08c3bdfSopenharmony_ci */
47f08c3bdfSopenharmony_ciint bits_in_bool = 1;
48f08c3bdfSopenharmony_ciint bits_in_char = 8;
49f08c3bdfSopenharmony_ciint bits_in_short = 16;
50f08c3bdfSopenharmony_ciint bits_in_int = 32;
51f08c3bdfSopenharmony_ciint bits_in_long = 64;
52f08c3bdfSopenharmony_ciint bits_in_longlong = 64;
53f08c3bdfSopenharmony_ciint bits_in_longlonglong = 128;
54f08c3bdfSopenharmony_ci
55f08c3bdfSopenharmony_ciint max_int_alignment = 8;
56f08c3bdfSopenharmony_ci
57f08c3bdfSopenharmony_ci/*
58f08c3bdfSopenharmony_ci * Floating point data types
59f08c3bdfSopenharmony_ci */
60f08c3bdfSopenharmony_ciint bits_in_float = 32;
61f08c3bdfSopenharmony_ciint bits_in_double = 64;
62f08c3bdfSopenharmony_ciint bits_in_longdouble = 128;
63f08c3bdfSopenharmony_ci
64f08c3bdfSopenharmony_ciint max_fp_alignment = 16;
65f08c3bdfSopenharmony_ci
66f08c3bdfSopenharmony_ci/*
67f08c3bdfSopenharmony_ci * Pointer data type
68f08c3bdfSopenharmony_ci */
69f08c3bdfSopenharmony_ciint bits_in_pointer = 64;
70f08c3bdfSopenharmony_ciint pointer_alignment = 8;
71f08c3bdfSopenharmony_ci
72f08c3bdfSopenharmony_ci/*
73f08c3bdfSopenharmony_ci * Enum data types
74f08c3bdfSopenharmony_ci */
75f08c3bdfSopenharmony_ciint bits_in_enum = 32;
76f08c3bdfSopenharmony_ciint enum_alignment = 4;
77f08c3bdfSopenharmony_ci
78f08c3bdfSopenharmony_ci
79f08c3bdfSopenharmony_cistatic const struct target *targets[] = {
80f08c3bdfSopenharmony_ci	[MACH_ALPHA] =		&target_alpha,
81f08c3bdfSopenharmony_ci	[MACH_ARM] =		&target_arm,
82f08c3bdfSopenharmony_ci	[MACH_ARM64] =		&target_arm64,
83f08c3bdfSopenharmony_ci	[MACH_BFIN] =		&target_bfin,
84f08c3bdfSopenharmony_ci	[MACH_H8300] =		&target_h8300,
85f08c3bdfSopenharmony_ci	[MACH_I386] =		&target_i386,
86f08c3bdfSopenharmony_ci	[MACH_M68K] =		&target_m68k,
87f08c3bdfSopenharmony_ci	[MACH_MICROBLAZE] =	&target_microblaze,
88f08c3bdfSopenharmony_ci	[MACH_MIPS32] =		&target_mips32,
89f08c3bdfSopenharmony_ci	[MACH_MIPS64] =		&target_mips64,
90f08c3bdfSopenharmony_ci	[MACH_NDS32] =		&target_nds32,
91f08c3bdfSopenharmony_ci	[MACH_NIOS2] =		&target_nios2,
92f08c3bdfSopenharmony_ci	[MACH_OPENRISC] =	&target_openrisc,
93f08c3bdfSopenharmony_ci	[MACH_PPC32] =		&target_ppc32,
94f08c3bdfSopenharmony_ci	[MACH_PPC64] =		&target_ppc64,
95f08c3bdfSopenharmony_ci	[MACH_RISCV32] =	&target_riscv32,
96f08c3bdfSopenharmony_ci	[MACH_RISCV64] =	&target_riscv64,
97f08c3bdfSopenharmony_ci	[MACH_S390] =		&target_s390,
98f08c3bdfSopenharmony_ci	[MACH_S390X] =		&target_s390x,
99f08c3bdfSopenharmony_ci	[MACH_SH] =		&target_sh,
100f08c3bdfSopenharmony_ci	[MACH_SPARC32] =	&target_sparc32,
101f08c3bdfSopenharmony_ci	[MACH_SPARC64] =	&target_sparc64,
102f08c3bdfSopenharmony_ci	[MACH_X86_64] =		&target_x86_64,
103f08c3bdfSopenharmony_ci	[MACH_XTENSA] =		&target_xtensa,
104f08c3bdfSopenharmony_ci	[MACH_UNKNOWN] =	&target_default,
105f08c3bdfSopenharmony_ci};
106f08c3bdfSopenharmony_ciconst struct target *arch_target = &target_default;
107f08c3bdfSopenharmony_ci
108f08c3bdfSopenharmony_cienum machine target_parse(const char *name)
109f08c3bdfSopenharmony_ci{
110f08c3bdfSopenharmony_ci	static const struct arch {
111f08c3bdfSopenharmony_ci		const char *name;
112f08c3bdfSopenharmony_ci		enum machine mach;
113f08c3bdfSopenharmony_ci		char bits;
114f08c3bdfSopenharmony_ci	} archs[] = {
115f08c3bdfSopenharmony_ci		{ "alpha",	MACH_ALPHA,	64, },
116f08c3bdfSopenharmony_ci		{ "aarch64",	MACH_ARM64,	64, },
117f08c3bdfSopenharmony_ci		{ "arm64",	MACH_ARM64,	64, },
118f08c3bdfSopenharmony_ci		{ "arm",	MACH_ARM,	32, },
119f08c3bdfSopenharmony_ci		{ "bfin",	MACH_BFIN,	32, },
120f08c3bdfSopenharmony_ci		{ "h8300",	MACH_H8300,	32, },
121f08c3bdfSopenharmony_ci		{ "i386",	MACH_I386,	32, },
122f08c3bdfSopenharmony_ci		{ "m68k",	MACH_M68K,	32, },
123f08c3bdfSopenharmony_ci		{ "microblaze",	MACH_MICROBLAZE,32, },
124f08c3bdfSopenharmony_ci		{ "mips",	MACH_MIPS32,	0,  },
125f08c3bdfSopenharmony_ci		{ "nds32",	MACH_NDS32,	32, },
126f08c3bdfSopenharmony_ci		{ "nios2",	MACH_NIOS2,	32, },
127f08c3bdfSopenharmony_ci		{ "openrisc",	MACH_OPENRISC,	32, },
128f08c3bdfSopenharmony_ci		{ "powerpc",	MACH_PPC32,	0,  },
129f08c3bdfSopenharmony_ci		{ "ppc",	MACH_PPC32,	0,  },
130f08c3bdfSopenharmony_ci		{ "riscv",	MACH_RISCV32,	0,  },
131f08c3bdfSopenharmony_ci		{ "s390x",	MACH_S390X,	64, },
132f08c3bdfSopenharmony_ci		{ "s390",	MACH_S390,	32, },
133f08c3bdfSopenharmony_ci		{ "sparc",	MACH_SPARC32,	0,  },
134f08c3bdfSopenharmony_ci		{ "x86_64",	MACH_X86_64,	64, },
135f08c3bdfSopenharmony_ci		{ "x86-64",	MACH_X86_64,	64, },
136f08c3bdfSopenharmony_ci		{ "sh",		MACH_SH,	32, },
137f08c3bdfSopenharmony_ci		{ "xtensa",	MACH_XTENSA,	32, },
138f08c3bdfSopenharmony_ci		{ NULL },
139f08c3bdfSopenharmony_ci	};
140f08c3bdfSopenharmony_ci	const struct arch *p;
141f08c3bdfSopenharmony_ci
142f08c3bdfSopenharmony_ci	for (p = &archs[0]; p->name; p++) {
143f08c3bdfSopenharmony_ci		size_t len = strlen(p->name);
144f08c3bdfSopenharmony_ci		if (strncmp(p->name, name, len) == 0) {
145f08c3bdfSopenharmony_ci			enum machine mach = p->mach;
146f08c3bdfSopenharmony_ci			const char *suf = name + len;
147f08c3bdfSopenharmony_ci			int bits = p->bits;
148f08c3bdfSopenharmony_ci
149f08c3bdfSopenharmony_ci			if (bits == 0) {
150f08c3bdfSopenharmony_ci				if (!strcmp(suf, "") || !strcmp(suf, "32")) {
151f08c3bdfSopenharmony_ci					;
152f08c3bdfSopenharmony_ci				} else if (!strcmp(suf, "64")) {
153f08c3bdfSopenharmony_ci					mach += 1;
154f08c3bdfSopenharmony_ci				} else {
155f08c3bdfSopenharmony_ci					die("invalid architecture: %s", name);
156f08c3bdfSopenharmony_ci				}
157f08c3bdfSopenharmony_ci			} else {
158f08c3bdfSopenharmony_ci				if (strcmp(suf, ""))
159f08c3bdfSopenharmony_ci					die("invalid architecture: %s", name);
160f08c3bdfSopenharmony_ci			}
161f08c3bdfSopenharmony_ci
162f08c3bdfSopenharmony_ci			return mach;
163f08c3bdfSopenharmony_ci		}
164f08c3bdfSopenharmony_ci	}
165f08c3bdfSopenharmony_ci
166f08c3bdfSopenharmony_ci	return MACH_UNKNOWN;
167f08c3bdfSopenharmony_ci}
168f08c3bdfSopenharmony_ci
169f08c3bdfSopenharmony_civoid target_os(const char *name)
170f08c3bdfSopenharmony_ci{
171f08c3bdfSopenharmony_ci	static const struct os {
172f08c3bdfSopenharmony_ci		const char *name;
173f08c3bdfSopenharmony_ci		int os;
174f08c3bdfSopenharmony_ci	} oses[] = {
175f08c3bdfSopenharmony_ci		{ "cygwin",	OS_CYGWIN },
176f08c3bdfSopenharmony_ci		{ "darwin",	OS_DARWIN },
177f08c3bdfSopenharmony_ci		{ "freebsd",	OS_FREEBSD },
178f08c3bdfSopenharmony_ci		{ "linux",	OS_LINUX },
179f08c3bdfSopenharmony_ci		{ "native",	OS_NATIVE, },
180f08c3bdfSopenharmony_ci		{ "netbsd",	OS_NETBSD },
181f08c3bdfSopenharmony_ci		{ "none",	OS_NONE },
182f08c3bdfSopenharmony_ci		{ "openbsd",	OS_OPENBSD },
183f08c3bdfSopenharmony_ci		{ "sunos",	OS_SUNOS },
184f08c3bdfSopenharmony_ci		{ "unix",	OS_UNIX },
185f08c3bdfSopenharmony_ci		{ NULL },
186f08c3bdfSopenharmony_ci	}, *p;
187f08c3bdfSopenharmony_ci
188f08c3bdfSopenharmony_ci	for (p = &oses[0]; p->name; p++) {
189f08c3bdfSopenharmony_ci		if (!strcmp(p->name, name)) {
190f08c3bdfSopenharmony_ci			arch_os = p->os;
191f08c3bdfSopenharmony_ci			return;
192f08c3bdfSopenharmony_ci		}
193f08c3bdfSopenharmony_ci	}
194f08c3bdfSopenharmony_ci
195f08c3bdfSopenharmony_ci	die("invalid os: %s", name);
196f08c3bdfSopenharmony_ci}
197f08c3bdfSopenharmony_ci
198f08c3bdfSopenharmony_ci
199f08c3bdfSopenharmony_civoid target_config(enum machine mach)
200f08c3bdfSopenharmony_ci{
201f08c3bdfSopenharmony_ci	const struct target *target = targets[mach];
202f08c3bdfSopenharmony_ci
203f08c3bdfSopenharmony_ci	arch_target = target;
204f08c3bdfSopenharmony_ci	arch_m64 = target->bitness;
205f08c3bdfSopenharmony_ci	arch_big_endian = target->big_endian;
206f08c3bdfSopenharmony_ci
207f08c3bdfSopenharmony_ci	funsigned_char = target->unsigned_char;
208f08c3bdfSopenharmony_ci}
209f08c3bdfSopenharmony_ci
210f08c3bdfSopenharmony_ci
211f08c3bdfSopenharmony_civoid target_init(void)
212f08c3bdfSopenharmony_ci{
213f08c3bdfSopenharmony_ci	const struct target *target = arch_target;
214f08c3bdfSopenharmony_ci
215f08c3bdfSopenharmony_ci	switch (arch_m64) {
216f08c3bdfSopenharmony_ci	case ARCH_X32:
217f08c3bdfSopenharmony_ci		if (target->target_x32bit)
218f08c3bdfSopenharmony_ci			target = target->target_x32bit;
219f08c3bdfSopenharmony_ci		goto case_32bit;
220f08c3bdfSopenharmony_ci
221f08c3bdfSopenharmony_ci	case ARCH_LP32:
222f08c3bdfSopenharmony_ci		max_int_alignment = 4;
223f08c3bdfSopenharmony_ci		if (target->target_32bit)
224f08c3bdfSopenharmony_ci			target = target->target_32bit;
225f08c3bdfSopenharmony_ci		/* fallthrough */
226f08c3bdfSopenharmony_ci	case_32bit:
227f08c3bdfSopenharmony_ci		bits_in_long = 32;
228f08c3bdfSopenharmony_ci		bits_in_pointer = 32;
229f08c3bdfSopenharmony_ci		pointer_alignment = 4;
230f08c3bdfSopenharmony_ci		size_t_ctype = &uint_ctype;
231f08c3bdfSopenharmony_ci		ssize_t_ctype = &int_ctype;
232f08c3bdfSopenharmony_ci		int64_ctype = &llong_ctype;
233f08c3bdfSopenharmony_ci		uint64_ctype = &ullong_ctype;
234f08c3bdfSopenharmony_ci		intmax_ctype = &llong_ctype;
235f08c3bdfSopenharmony_ci		uintmax_ctype = &ullong_ctype;
236f08c3bdfSopenharmony_ci		fast64_ctype = &llong_ctype;
237f08c3bdfSopenharmony_ci		ufast64_ctype = &ullong_ctype;
238f08c3bdfSopenharmony_ci		break;
239f08c3bdfSopenharmony_ci
240f08c3bdfSopenharmony_ci	case ARCH_LLP64:
241f08c3bdfSopenharmony_ci		bits_in_long = 32;
242f08c3bdfSopenharmony_ci		size_t_ctype = &ullong_ctype;
243f08c3bdfSopenharmony_ci		ssize_t_ctype = &llong_ctype;
244f08c3bdfSopenharmony_ci		int64_ctype = &llong_ctype;
245f08c3bdfSopenharmony_ci		uint64_ctype = &ullong_ctype;
246f08c3bdfSopenharmony_ci		intmax_ctype = &llong_ctype;
247f08c3bdfSopenharmony_ci		uintmax_ctype = &ullong_ctype;
248f08c3bdfSopenharmony_ci		/* fallthrough */
249f08c3bdfSopenharmony_ci	case ARCH_LP64:
250f08c3bdfSopenharmony_ci		if (target->target_64bit)
251f08c3bdfSopenharmony_ci			target = target->target_64bit;
252f08c3bdfSopenharmony_ci		break;
253f08c3bdfSopenharmony_ci	}
254f08c3bdfSopenharmony_ci	arch_target = target;
255f08c3bdfSopenharmony_ci
256f08c3bdfSopenharmony_ci	if (fpie > fpic)
257f08c3bdfSopenharmony_ci		fpic = fpie;
258f08c3bdfSopenharmony_ci
259f08c3bdfSopenharmony_ci	if (target->wchar)
260f08c3bdfSopenharmony_ci		wchar_ctype = target->wchar;
261f08c3bdfSopenharmony_ci	if (target->wint)
262f08c3bdfSopenharmony_ci		wint_ctype = target->wint;
263f08c3bdfSopenharmony_ci	if (target->bits_in_longdouble)
264f08c3bdfSopenharmony_ci		bits_in_longdouble = target->bits_in_longdouble;
265f08c3bdfSopenharmony_ci	if (target->max_fp_alignment)
266f08c3bdfSopenharmony_ci		max_fp_alignment = target->max_fp_alignment;
267f08c3bdfSopenharmony_ci
268f08c3bdfSopenharmony_ci	if (target->init)
269f08c3bdfSopenharmony_ci		target->init(target);
270f08c3bdfSopenharmony_ci
271f08c3bdfSopenharmony_ci	if (arch_msize_long || target->size_t_long) {
272f08c3bdfSopenharmony_ci		size_t_ctype = &ulong_ctype;
273f08c3bdfSopenharmony_ci		ssize_t_ctype = &long_ctype;
274f08c3bdfSopenharmony_ci	}
275f08c3bdfSopenharmony_ci	if (fshort_wchar)
276f08c3bdfSopenharmony_ci		wchar_ctype = &ushort_ctype;
277f08c3bdfSopenharmony_ci}
278