diff options
Diffstat (limited to 'target.c')
| -rw-r--r-- | target.c | 262 |
1 files changed, 131 insertions, 131 deletions
@@ -1,13 +1,14 @@ #include <stdio.h> +#include <string.h> #include "symbol.h" #include "target.h" #include "machine.h" -struct symbol *size_t_ctype = &uint_ctype; -struct symbol *ssize_t_ctype = &int_ctype; -struct symbol *intmax_ctype = &llong_ctype; -struct symbol *uintmax_ctype = &ullong_ctype; +struct symbol *size_t_ctype = &ulong_ctype; +struct symbol *ssize_t_ctype = &long_ctype; +struct symbol *intmax_ctype = &long_ctype; +struct symbol *uintmax_ctype = &ulong_ctype; struct symbol *int64_ctype = &long_ctype; struct symbol *uint64_ctype = &ulong_ctype; struct symbol *int32_ctype = &int_ctype; @@ -27,11 +28,11 @@ int bits_in_bool = 1; int bits_in_char = 8; int bits_in_short = 16; int bits_in_int = 32; -int bits_in_long = 32; +int bits_in_long = 64; int bits_in_longlong = 64; int bits_in_longlonglong = 128; -int max_int_alignment = 4; +int max_int_alignment = 8; /* * Floating point data types @@ -45,8 +46,8 @@ int max_fp_alignment = 16; /* * Pointer data type */ -int bits_in_pointer = 32; -int pointer_alignment = 4; +int bits_in_pointer = 64; +int pointer_alignment = 8; /* * Enum data types @@ -55,149 +56,148 @@ int bits_in_enum = 32; int enum_alignment = 4; -void init_target(void) +static const struct target *targets[] = { + [MACH_ARM] = &target_arm, + [MACH_ARM64] = &target_arm64, + [MACH_I386] = &target_i386, + [MACH_X86_64] = &target_x86_64, + [MACH_MIPS32] = &target_mips32, + [MACH_MIPS64] = &target_mips64, + [MACH_PPC32] = &target_ppc32, + [MACH_PPC64] = &target_ppc64, + [MACH_RISCV32] = &target_riscv32, + [MACH_RISCV64] = &target_riscv64, + [MACH_S390] = &target_s390, + [MACH_S390X] = &target_s390x, + [MACH_SPARC32] = &target_sparc32, + [MACH_SPARC64] = &target_sparc64, + [MACH_M68K] = &target_m68k, + [MACH_UNKNOWN] = &target_default, +}; +const struct target *arch_target = &target_default; + +enum machine target_parse(const char *name) { - switch (arch_mach) { - case MACH_I386: - case MACH_MIPS32: - case MACH_PPC32: - case MACH_RISCV32: - case MACH_SPARC32: - case MACH_S390: - if (arch_m64 == ARCH_LP64) - arch_mach++; - break; - case MACH_X86_64: - case MACH_MIPS64: - case MACH_PPC64: - case MACH_RISCV64: - case MACH_SPARC64: - case MACH_S390X: - if (arch_m64 == ARCH_LP32) - arch_mach--; - break; - } + static const struct arch { + const char *name; + enum machine mach; + char bits; + } archs[] = { + { "aarch64", MACH_ARM64, 64, }, + { "arm64", MACH_ARM64, 64, }, + { "arm", MACH_ARM, 32, }, + { "i386", MACH_I386, 32, }, + { "m68k", MACH_M68K, 32, }, + { "mips", MACH_MIPS32, 0, }, + { "powerpc", MACH_PPC32, 0, }, + { "ppc", MACH_PPC32, 0, }, + { "riscv", MACH_RISCV32, 0, }, + { "s390x", MACH_S390X, 64, }, + { "s390", MACH_S390, 32, }, + { "sparc", MACH_SPARC32, 0, }, + { "x86_64", MACH_X86_64, 64, }, + { "x86-64", MACH_X86_64, 64, }, + { NULL }, + }; + const struct arch *p; - switch (arch_mach) { - case MACH_I386: - wchar_ctype = &long_ctype; - /* fall through */ - case MACH_X86_64: - switch (arch_os) { - case OS_CYGWIN: - wchar_ctype = &ushort_ctype; - break; - case OS_DARWIN: - int64_ctype = &llong_ctype; - uint64_ctype = &ullong_ctype; - wint_ctype = &int_ctype; - break; - case OS_FREEBSD: - wint_ctype = &int_ctype; - break; - case OS_OPENBSD: - wchar_ctype = &int_ctype; - wint_ctype = &int_ctype; - break; - } - break; - case MACH_M68K: - case MACH_PPC32: - wchar_ctype = &long_ctype; - break; - case MACH_ARM: - case MACH_ARM64: - wchar_ctype = &uint_ctype; - break; - case MACH_SPARC32: - if (arch_os == OS_SUNOS) { - wint_ctype = &long_ctype; - wchar_ctype = &long_ctype; + for (p = &archs[0]; p->name; p++) { + size_t len = strlen(p->name); + if (strncmp(p->name, name, len) == 0) { + enum machine mach = p->mach; + const char *suf = name + len; + int bits = p->bits; + + if (bits == 0) { + if (!strcmp(suf, "") || !strcmp(suf, "32")) { + ; + } else if (!strcmp(suf, "64")) { + mach += 1; + } else { + die("invalid architecture: %s", name); + } + } else { + if (strcmp(suf, "")) + die("invalid architecture: %s", name); + } + + return mach; } - break; - default: - break; } - if (fshort_wchar) - wchar_ctype = &ushort_ctype; - switch (arch_mach) { - case MACH_SPARC32: - if (arch_os == OS_SUNOS) - break; - /* fall through */ - case MACH_ARM: - case MACH_MIPS64: - // FIXME: ABI n32 & (n)64 have 128-bit ldouble - case MACH_MIPS32: - case MACH_S390: - case MACH_S390X: - bits_in_longdouble = 64; - max_fp_alignment = 8; - break; - case MACH_X86_64: - if (arch_m64 == ARCH_LP64 || arch_m64 == ARCH_X32) - break; - /* fall through */ - case MACH_I386: - case MACH_M68K: - bits_in_longdouble = 96; - max_fp_alignment = 4; - break; - default: - break; - } + return MACH_UNKNOWN; +} - switch (arch_mach) { - case MACH_ARM: - case MACH_ARM64: - case MACH_PPC32: - case MACH_PPC64: - case MACH_RISCV32: - case MACH_RISCV64: - case MACH_S390: - case MACH_S390X: - if (funsigned_char == -1) - funsigned_char = 1; - break; - default: - if (funsigned_char == -1) - funsigned_char = 0; - break; - } + +void target_config(enum machine mach) +{ + const struct target *target = targets[mach]; + + arch_target = target; + arch_m64 = target->bitness; + arch_big_endian = target->big_endian; + + funsigned_char = target->unsigned_char; +} + + +void target_init(void) +{ + const struct target *target = arch_target; switch (arch_m64) { - case ARCH_X32: - max_int_alignment = 8; - int64_ctype = &llong_ctype; - uint64_ctype = &ullong_ctype; - break; case ARCH_LP32: - /* default values */ + max_int_alignment = 4; + /* fallthrough */ + case ARCH_X32: + bits_in_long = 32; + bits_in_pointer = 32; + pointer_alignment = 4; + size_t_ctype = &uint_ctype; + ssize_t_ctype = &int_ctype; int64_ctype = &llong_ctype; uint64_ctype = &ullong_ctype; intmax_ctype = &llong_ctype; uintmax_ctype = &ullong_ctype; + if (target->target_32bit) + target = target->target_32bit; break; - case ARCH_LP64: - bits_in_long = 64; - max_int_alignment = 8; - size_t_ctype = &ulong_ctype; - ssize_t_ctype = &long_ctype; - intmax_ctype = &long_ctype; - uintmax_ctype = &ulong_ctype; - goto case_64bit_common; + case ARCH_LLP64: bits_in_long = 32; - max_int_alignment = 8; size_t_ctype = &ullong_ctype; ssize_t_ctype = &llong_ctype; int64_ctype = &llong_ctype; uint64_ctype = &ullong_ctype; - goto case_64bit_common; - case_64bit_common: - bits_in_pointer = 64; - pointer_alignment = 8; + intmax_ctype = &llong_ctype; + uintmax_ctype = &ullong_ctype; + /* fallthrough */ + case ARCH_LP64: + if (target->target_64bit) + target = target->target_64bit; break; } + arch_target = target; + + if (fpie > fpic) + fpic = fpie; + + if (target->wchar) + wchar_ctype = target->wchar; + if (target->wint) + wint_ctype = target->wint; + if (target->bits_in_longdouble) + bits_in_longdouble = target->bits_in_longdouble; + if (target->max_fp_alignment) + max_fp_alignment = target->max_fp_alignment; + + if (target->init) + target->init(target); + + if (arch_msize_long || target->size_t_long) { + size_t_ctype = &ulong_ctype; + ssize_t_ctype = &long_ctype; + } + if (fshort_wchar) + wchar_ctype = &ushort_ctype; } |
