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