harec

[hare] Hare compiler, written in C11 for POSIX OSs
Log | Files | Refs | README | LICENSE

commit bdc8b2fcfdcdaa42d89acd2ea77ca858c7929853
parent 090543b5f6f4c6b8afac7203ba40e2ba51a7895a
Author: Sebastian <sebastian@sebsite.pw>
Date:   Sat, 22 Oct 2022 20:20:38 -0400

Add -a flag to set target architecture

This is needed in harec since the size and alignment of types is used in
check, and some types have sizes and alignments which depend on the
target architecture.

Pre-existing installations need to rerun their configure script after
this change.

Signed-off-by: Sebastian <sebastian@sebsite.pw>

Diffstat:
Mconfig.sh | 28++++++++++++++++++++++++++++
Minclude/types.h | 2+-
Msrc/main.c | 9+++++++--
Msrc/type_store.c | 18++++++++++--------
Msrc/types.c | 130++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
Mtests/30-reduction.c | 6+++++-
6 files changed, 150 insertions(+), 43 deletions(-)

diff --git a/config.sh b/config.sh @@ -4,6 +4,7 @@ AR=${AR:-ar} AS=${AS:-as} CC=${CC:-cc} CFLAGS=${CFLAGS:-} +DEFAULT_TARGET= LDFLAGS=${LDFLAGS:-} LD=${LD:-ld} QBE=${QBE:-qbe} @@ -38,6 +39,9 @@ do --sysconfdir=*) SYSCONFDIR=${arg#*=} ;; + --target=*) + DEFAULT_TARGET=${arg#*=} + ;; --help) cat >&2 <<'EOF' Usage: configure [options...] @@ -56,6 +60,8 @@ Options: default: (prefix)/share --sysconfdir=<path> default: /etc if prefix is /usr, otherwise (prefix)/etc +--target=<arch> + default: (current arch) Environment variables: AR (default: "ar") @@ -177,6 +183,28 @@ run_configure() { fi done + if [ -z "$DEFAULT_TARGET" ] + then + printf "Detecting machine architecture... " + arch="$(uname -m)" + case "$arch" in + x86_64|amd64) + DEFAULT_TARGET=x86_64 + ;; + aarch64|arm64) + DEFAULT_TARGET=aarch64 + ;; + riscv64) + DEFAULT_TARGET=riscv64 + ;; + *) + printf "Error: unsupported or unrecognized architecture %s\n" "$arch" + ;; + esac + printf '%s\n' "$DEFAULT_TARGET" + fi + append_cflags -DDEFAULT_TARGET="\\\"$DEFAULT_TARGET\\\"" + printf "Checking for qbe... " if $QBE -h > /dev/null 2>&1 then diff --git a/include/types.h b/include/types.h @@ -194,7 +194,7 @@ const struct type *type_create_const(enum type_storage storage, const struct type *lower_const(const struct type *old, const struct type *new); void const_refer(const struct type *type, const struct type **ref); -void builtin_types_init(void); +void builtin_types_init(const char *target); // Built-in type singletons extern struct type diff --git a/src/main.c b/src/main.c @@ -19,7 +19,7 @@ static void usage(const char *argv_0) { fprintf(stderr, - "Usage: %s [-D ident:type=value] [-o output] [-T] [-t typedefs] [-N namespace] [input.ha...]\n", + "Usage: %s [-a arch] [-D ident:type=value] [-o output] [-T] [-t typedefs] [-N namespace] [input.ha...]\n", argv_0); } @@ -87,6 +87,7 @@ int main(int argc, char *argv[]) { char *output = NULL, *typedefs = NULL; + char *target = DEFAULT_TARGET; bool is_test = false; struct unit unit = {0}; struct lexer lexer; @@ -95,6 +96,9 @@ main(int argc, char *argv[]) int c; while ((c = getopt(argc, argv, "D:ho:Tt:N:")) != -1) { switch (c) { + case 'a': + target = optarg; + break; case 'D': def = parse_define(argv[0], optarg); def->next = defines; @@ -125,6 +129,8 @@ main(int argc, char *argv[]) } } + builtin_types_init(target); + size_t ninputs = argc - optind; if (ninputs == 0) { usage(argv[0]); @@ -176,7 +182,6 @@ main(int argc, char *argv[]) } static struct type_store ts = {0}; - builtin_types_init(); check(&ts, is_test, defines, &aunit, &unit); if (stage == STAGE_CHECK) { return EXIT_SUCCESS; diff --git a/src/type_store.c b/src/type_store.c @@ -8,6 +8,7 @@ #include "scope.h" #include "typedef.h" #include "type_store.h" +#include "types.h" #include "util.h" // XXX: This needs to be updated on updates to type_flags (types.h) @@ -795,8 +796,8 @@ type_init_from_atype(struct type_store *store, } break; case STORAGE_POINTER: - type->size = 8; // XXX: ARCH - type->align = 8; + type->size = builtin_type_uintptr.size; + type->align = builtin_type_uintptr.align; if (size_only) { break; } @@ -805,8 +806,9 @@ type_init_from_atype(struct type_store *store, store, atype->pointer.referent); break; case STORAGE_SLICE: - type->size = 24; // XXX: ARCH - type->align = 8; + type->size = builtin_type_uintptr.size + + 2 * builtin_type_size.size; + type->align = builtin_type_uintptr.align; if (size_only) { break; } @@ -979,8 +981,8 @@ type_store_lookup_pointer(struct type_store *store, struct location loc, .referent = referent, .flags = ptrflags, }, - .size = 8, // XXX: ARCH - .align = 8, + .size = builtin_type_uintptr.size, + .align = builtin_type_uintptr.align, }; return type_store_lookup_type(store, &ptr); } @@ -1054,8 +1056,8 @@ type_store_lookup_slice(struct type_store *store, struct location loc, .members = members, .length = SIZE_UNDEFINED, }, - .size = 24, // XXX: ARCH - .align = 8, + .size = builtin_type_uintptr.size + 2 * builtin_type_size.size, + .align = builtin_type_uintptr.align, }; return type_store_lookup_type(store, &slice); } diff --git a/src/types.c b/src/types.c @@ -1,6 +1,7 @@ #include <assert.h> #include <stdbool.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include "expr.h" #include "scope.h" @@ -982,8 +983,105 @@ type_is_castable(const struct type *to, const struct type *from) } void -builtin_types_init(void) +builtin_types_init(const char *target) { + if (strcmp(target, "aarch64") == 0) { + builtin_type_bool.size = 4; + builtin_type_bool.align = 4; + builtin_type_int.size = 4; + builtin_type_int.align = 4; + builtin_type_uint.size = 4; + builtin_type_uint.align = 4; + builtin_type_uintptr.size = 8; + builtin_type_uintptr.align = 8; + builtin_type_null.size = 8; + builtin_type_null.align = 8; + builtin_type_size.size = 8; + builtin_type_size.align = 8; + builtin_type_const_bool.size = 4; + builtin_type_const_bool.align = 4; + builtin_type_const_int.size = 4; + builtin_type_const_int.align = 4; + builtin_type_const_uint.size = 4; + builtin_type_const_uint.align = 4; + builtin_type_const_uintptr.size = 8; + builtin_type_const_uintptr.align = 8; + builtin_type_const_size.size = 8; + builtin_type_const_size.align = 8; + builtin_type_ptr_const_char.size = 8; + builtin_type_ptr_const_char.align = 8; + builtin_type_str.size = 24; + builtin_type_str.align = 8; + builtin_type_const_str.size = 24; + builtin_type_const_str.align = 8; + builtin_type_valist.size = 32; + builtin_type_valist.align = 8; + } else if (strcmp(target, "riscv64") == 0) { + builtin_type_bool.size = 4; + builtin_type_bool.align = 4; + builtin_type_int.size = 4; + builtin_type_int.align = 4; + builtin_type_uint.size = 4; + builtin_type_uint.align = 4; + builtin_type_uintptr.size = 8; + builtin_type_uintptr.align = 8; + builtin_type_null.size = 8; + builtin_type_null.align = 8; + builtin_type_size.size = 8; + builtin_type_size.align = 8; + builtin_type_const_bool.size = 4; + builtin_type_const_bool.align = 4; + builtin_type_const_int.size = 4; + builtin_type_const_int.align = 4; + builtin_type_const_uint.size = 4; + builtin_type_const_uint.align = 4; + builtin_type_const_uintptr.size = 8; + builtin_type_const_uintptr.align = 8; + builtin_type_const_size.size = 8; + builtin_type_const_size.align = 8; + builtin_type_ptr_const_char.size = 8; + builtin_type_ptr_const_char.align = 8; + builtin_type_str.size = 24; + builtin_type_str.align = 8; + builtin_type_const_str.size = 24; + builtin_type_const_str.align = 8; + builtin_type_valist.size = 8; + builtin_type_valist.align = 8; + } else if (strcmp(target, "x86_64") == 0) { + builtin_type_bool.size = 4; + builtin_type_bool.align = 4; + builtin_type_int.size = 4; + builtin_type_int.align = 4; + builtin_type_uint.size = 4; + builtin_type_uint.align = 4; + builtin_type_uintptr.size = 8; + builtin_type_uintptr.align = 8; + builtin_type_null.size = 8; + builtin_type_null.align = 8; + builtin_type_size.size = 8; + builtin_type_size.align = 8; + builtin_type_const_bool.size = 4; + builtin_type_const_bool.align = 4; + builtin_type_const_int.size = 4; + builtin_type_const_int.align = 4; + builtin_type_const_uint.size = 4; + builtin_type_const_uint.align = 4; + builtin_type_const_uintptr.size = 8; + builtin_type_const_uintptr.align = 8; + builtin_type_const_size.size = 8; + builtin_type_const_size.align = 8; + builtin_type_ptr_const_char.size = 8; + builtin_type_ptr_const_char.align = 8; + builtin_type_str.size = 24; + builtin_type_str.align = 8; + builtin_type_const_str.size = 24; + builtin_type_const_str.align = 8; + builtin_type_valist.size = 24; + builtin_type_valist.align = 8; + } else { + fprintf(stderr, "Unsupported or unrecognized target: %s", target); + exit(EXIT_FAILURE); + } struct type *builtins[] = { &builtin_type_bool, &builtin_type_char, &builtin_type_f32, &builtin_type_f64, &builtin_type_i8, &builtin_type_i16, @@ -1012,8 +1110,6 @@ builtin_types_init(void) // Built-in type singletons struct type builtin_type_bool = { .storage = STORAGE_BOOL, - .size = 4, // XXX: ARCH - .align = 4, }, builtin_type_char = { .storage = STORAGE_CHAR, @@ -1052,8 +1148,6 @@ builtin_type_i64 = { }, builtin_type_int = { .storage = STORAGE_INT, - .size = 4, // XXX: ARCH - .align = 4, }, builtin_type_u8 = { .storage = STORAGE_U8, @@ -1077,18 +1171,12 @@ builtin_type_u64 = { }, builtin_type_uint = { .storage = STORAGE_UINT, - .size = 4, - .align = 4, }, builtin_type_uintptr = { .storage = STORAGE_UINTPTR, - .size = 8, // XXX: ARCH - .align = 8, }, builtin_type_null = { .storage = STORAGE_NULL, - .size = 8, // XXX: ARCH - .align = 8, }, builtin_type_rune = { .storage = STORAGE_RUNE, @@ -1097,8 +1185,6 @@ builtin_type_rune = { }, builtin_type_size = { .storage = STORAGE_SIZE, - .size = 8, // XXX: ARCH - .align = 8, }, builtin_type_void = { .storage = STORAGE_VOID, @@ -1108,8 +1194,6 @@ builtin_type_void = { builtin_type_const_bool = { .storage = STORAGE_BOOL, .flags = TYPE_CONST, - .size = 4, // XXX: ARCH - .align = 4, }, builtin_type_const_char = { .storage = STORAGE_CHAR, @@ -1156,8 +1240,6 @@ builtin_type_const_i64 = { builtin_type_const_int = { .storage = STORAGE_INT, .flags = TYPE_CONST, - .size = 4, // XXX: ARCH - .align = 4, }, builtin_type_const_u8 = { .storage = STORAGE_U8, @@ -1186,14 +1268,10 @@ builtin_type_const_u64 = { builtin_type_const_uint = { .storage = STORAGE_UINT, .flags = TYPE_CONST, - .size = 4, - .align = 4, }, builtin_type_const_uintptr = { .storage = STORAGE_UINTPTR, .flags = TYPE_CONST, - .size = 8, // XXX: ARCH - .align = 8, }, builtin_type_const_rune = { .storage = STORAGE_RUNE, @@ -1204,8 +1282,6 @@ builtin_type_const_rune = { builtin_type_const_size = { .storage = STORAGE_SIZE, .flags = TYPE_CONST, - .size = 8, // XXX: ARCH - .align = 8, }, builtin_type_const_void = { .storage = STORAGE_VOID, @@ -1217,25 +1293,17 @@ builtin_type_const_void = { // Others struct type builtin_type_ptr_const_char = { .storage = STORAGE_POINTER, - .size = 8, // XXX: ARCH - .align = 8, .pointer = { .referent = &builtin_type_const_char, }, }, builtin_type_str = { .storage = STORAGE_STRING, - .size = 24, // XXX: ARCH - .align = 8, }, builtin_type_const_str = { .storage = STORAGE_STRING, .flags = TYPE_CONST, - .size = 24, // XXX: ARCH - .align = 8, }, builtin_type_valist = { .storage = STORAGE_VALIST, - .size = 32, // XXX: ARCH - .align = 8, }; diff --git a/tests/30-reduction.c b/tests/30-reduction.c @@ -11,10 +11,14 @@ #include "scope.h" #include "type_store.h" #include "typedef.h" +#include "types.h" #include "util.h" void test(struct context *ctx, const char *expected, const char *input) { - builtin_types_init(); + // The target is irrelevant here, since it's only used to compute the + // sizes of types, which isn't tested here or depended on. + builtin_types_init("x86_64"); + ctx->errors = NULL; ctx->next = &ctx->errors;