aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/target.c
diff options
Diffstat (limited to 'target.c')
-rw-r--r--target.c262
1 files changed, 131 insertions, 131 deletions
diff --git a/target.c b/target.c
index 76cbb954..abfa9756 100644
--- a/target.c
+++ b/target.c
@@ -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;
}