commit f04946c4b6ed13d4d6dc4364e2ae512b6f6e77a8 parent d49b364900f22f9bdc60b32ebc598c59efe64e53 Author: Ryan Sepassi <rsepassi@gmail.com> Date: Mon, 25 May 2026 18:33:48 -0700 format Diffstat:
660 files changed, 12334 insertions(+), 10258 deletions(-)
diff --git a/driver/addr2line.c b/driver/addr2line.c @@ -1,35 +1,34 @@ -#include "driver.h" - +#include <cfree/core.h> +#include <cfree/dwarf.h> +#include <cfree/object.h> #include <stdint.h> #include <stdlib.h> #include <string.h> -#include <cfree/core.h> -#include <cfree/dwarf.h> -#include <cfree/object.h> +#include "driver.h" #define A2L_TOOL "addr2line" typedef struct A2lOpts { - const char *exe_path; - int functions; /* -f */ - int pretty; /* -p */ - int basenames; /* --basenames */ - int show_addr; /* -a */ + const char* exe_path; + int functions; /* -f */ + int pretty; /* -p */ + int basenames; /* --basenames */ + int show_addr; /* -a */ } A2lOpts; -static void a2l_strip_basename(const char **path_ptr) { - const char *s = *path_ptr; - const char *slash = NULL; - const char *p; +static void a2l_strip_basename(const char** path_ptr) { + const char* s = *path_ptr; + const char* slash = NULL; + const char* p; if (!s) return; for (p = s; *p; ++p) if (*p == '/') slash = p; if (slash) *path_ptr = slash + 1; } -static void a2l_translate(CfreeDebugInfo *dwarf, uint64_t addr, - const A2lOpts *opts) { +static void a2l_translate(CfreeDebugInfo* dwarf, uint64_t addr, + const A2lOpts* opts) { CfreeSlice file; uint32_t line = 0, col = 0; CfreeSlice func; @@ -38,13 +37,11 @@ static void a2l_translate(CfreeDebugInfo *dwarf, uint64_t addr, int have_func = 0; if (opts->functions) { - if (cfree_dwarf_func_at(dwarf, addr, &func, &func_lo, &func_hi) == - CFREE_OK) + if (cfree_dwarf_func_at(dwarf, addr, &func, &func_lo, &func_hi) == CFREE_OK) have_func = 1; } - if (opts->show_addr) - driver_printf("0x%llx", (unsigned long long)addr); + if (opts->show_addr) driver_printf("0x%llx", (unsigned long long)addr); if (opts->pretty) { if (opts->show_addr) driver_printf(": "); @@ -53,7 +50,7 @@ static void a2l_translate(CfreeDebugInfo *dwarf, uint64_t addr, else if (opts->functions) driver_printf("?? at "); if (st == CFREE_OK) { - const char *f = file.s; + const char* f = file.s; if (opts->basenames) a2l_strip_basename(&f); driver_printf("%s:%u", f, line); if (col) driver_printf(":%u", col); @@ -75,7 +72,7 @@ static void a2l_translate(CfreeDebugInfo *dwarf, uint64_t addr, } if (st == CFREE_OK) { - const char *f = file.s; + const char* f = file.s; if (opts->basenames) a2l_strip_basename(&f); driver_printf("%s:%u", f, line); if (col) driver_printf(":%u", col); @@ -89,29 +86,30 @@ void driver_help_addr2line(void) { driver_printf( "%.*s", CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "cfree addr2line — translate addresses to file:line using debug info\n" - "\n" - "USAGE\n" - " cfree addr2line [OPTIONS] -e FILE [ADDR...]\n" - "\n" - "OPTIONS\n" - " -e FILE object file with debug info (required)\n" - " -a, --addresses print the address before each line\n" - " -f, --functions print function names\n" - " -p, --pretty-print compact single-line output\n" - " --basenames strip directory from file paths\n" - " -h, --help show this help\n" - "\n" - "If no addresses are given on the command line, addresses are read\n" - "from standard input, one per line (hex).\n"))); + "cfree addr2line — translate addresses to file:line using debug " + "info\n" + "\n" + "USAGE\n" + " cfree addr2line [OPTIONS] -e FILE [ADDR...]\n" + "\n" + "OPTIONS\n" + " -e FILE object file with debug info (required)\n" + " -a, --addresses print the address before each line\n" + " -f, --functions print function names\n" + " -p, --pretty-print compact single-line output\n" + " --basenames strip directory from file paths\n" + " -h, --help show this help\n" + "\n" + "If no addresses are given on the command line, addresses are read\n" + "from standard input, one per line (hex).\n"))); } -int driver_addr2line(int argc, char **argv) { +int driver_addr2line(int argc, char** argv) { DriverEnv env; CfreeContext ctx; A2lOpts opts; - CfreeObjFile *of = NULL; - CfreeDebugInfo *dwarf = NULL; + CfreeObjFile* of = NULL; + CfreeDebugInfo* dwarf = NULL; DriverLoad ld = {0}; CfreeSlice input; int i, rc = 1; @@ -127,7 +125,7 @@ int driver_addr2line(int argc, char **argv) { ctx = driver_env_to_context(&env); for (i = 1; i < argc; ++i) { - const char *a = argv[i]; + const char* a = argv[i]; if (driver_streq(a, "-e")) { if (i + 1 >= argc) { driver_errf(A2L_TOOL, "-e requires a path"); @@ -138,16 +136,20 @@ int driver_addr2line(int argc, char **argv) { continue; } if (driver_streq(a, "-a") || driver_streq(a, "--addresses")) { - opts.show_addr = 1; continue; + opts.show_addr = 1; + continue; } if (driver_streq(a, "-f") || driver_streq(a, "--functions")) { - opts.functions = 1; continue; + opts.functions = 1; + continue; } if (driver_streq(a, "-p") || driver_streq(a, "--pretty-print")) { - opts.pretty = 1; continue; + opts.pretty = 1; + continue; } if (driver_streq(a, "--basenames")) { - opts.basenames = 1; continue; + opts.basenames = 1; + continue; } if (a[0] == '-' && a[1] != '\0') { driver_errf(A2L_TOOL, "unknown option: %s", a); @@ -162,8 +164,8 @@ int driver_addr2line(int argc, char **argv) { goto done; } - if (driver_load_bytes(&env.file_io, A2L_TOOL, opts.exe_path, &ld, - &input) != 0) { + if (driver_load_bytes(&env.file_io, A2L_TOOL, opts.exe_path, &ld, &input) != + 0) { rc = 1; goto done; } @@ -171,8 +173,7 @@ int driver_addr2line(int argc, char **argv) { { CfreeSlice name_slice = cfree_slice_cstr(opts.exe_path); if (cfree_obj_open(&ctx, name_slice, &input, &of) != CFREE_OK) { - driver_errf(A2L_TOOL, "%s: not a recognized object file", - opts.exe_path); + driver_errf(A2L_TOOL, "%s: not a recognized object file", opts.exe_path); rc = 1; goto done; } @@ -186,9 +187,12 @@ int driver_addr2line(int argc, char **argv) { /* scan for positional addresses */ for (i = 1; i < argc; ++i) { - const char *a = argv[i]; + const char* a = argv[i]; if (a[0] == '-' && a[1] != '\0') { - if (driver_streq(a, "-e")) { ++i; continue; } + if (driver_streq(a, "-e")) { + ++i; + continue; + } continue; } { diff --git a/driver/ar.c b/driver/ar.c @@ -1,9 +1,8 @@ -#include "driver.h" - #include <cfree/archive.h> #include <cfree/core.h> #include <cfree/object.h> +#include "driver.h" #include "inputs.h" /* `cfree ar` — POSIX ar archive front-end. @@ -49,69 +48,79 @@ static void ar_usage(void) { driver_errf(AR_TOOL, "%.*s", CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "usage: cfree ar {rc|r|c|t|x|p}[s] archive.a [members...]\n" - " cfree ar --help for full operation reference"))); + "usage: cfree ar {rc|r|c|t|x|p}[s] archive.a [members...]\n" + " cfree ar --help for full operation reference"))); } void driver_help_ar(void) { driver_printf( "%.*s", CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "cfree ar — POSIX `ar` archive front-end\n" - "\n" - "USAGE\n" - " cfree ar MODE archive.a [members...]\n" - "\n" - "MODE is a string of one or more letters; exactly one operation must\n" - "be selected and any number of modifiers may follow. The archive\n" - "path and (optional) member list follow the mode.\n" - "\n" - "OPERATIONS (mutually exclusive)\n" - " r Replace listed members in place; preserve unlisted; append\n" - " new ones. Warns when the archive must be created.\n" - " c Create / overwrite the archive with exactly the listed\n" - " members. Suppresses the create warning.\n" - " rc, cr `r` semantics with the create warning suppressed.\n" - " t List member names.\n" - " x Extract members to the current working directory. With no\n" - " member list, extract everything.\n" - " p Print members to stdout. With no list, print all members;\n" - " with two or more members each is preceded by a header.\n" - "\n" - "MODIFIERS\n" - " s Emit a System-V `/` symbol-index member at the head of\n" - " the archive. Valid only combined with r and/or c (rs, cs,\n" - " rcs, crs). Globally-defined symbols (CFREE_SB_GLOBAL with\n" - " a defined section) of each object member are indexed; non-\n" - " object members contribute no symbols.\n" - " u Update-if-newer compatibility modifier; accepted as a\n" - " no-op.\n" - " v Verbose. With t list <size>\\t<name>; with x/r/c print one\n" - " line per affected member (\"x - name\", \"a - name\", or\n" - " \"r - name\" for replacements); with p force the per-member\n" - " \"archive(name):\" header even on a single match.\n" - "\n" - "REPRODUCIBILITY\n" - " When SOURCE_DATE_EPOCH is set to a positive integer, that value is\n" - " written to ar_date for every member on write. Long member names\n" - " are routed through a `//` extended-name table.\n" - "\n" - "NOT YET IMPLEMENTED\n" - " d (delete), q (quick append), and standalone `s` without r/c.\n" - " Encountering any of those yields a usage error with exit code 2.\n" - "\n" - "EXAMPLES\n" - " cfree ar rcs libfoo.a a.o b.o c.o\n" - " cfree ar t libfoo.a\n" - " cfree ar x libfoo.a a.o\n" - " cfree ar p libfoo.a a.o > a.o.copy\n" - "\n" - "GETTING HELP\n" - " -h, --help Show this help and exit\n" - "\n" - "EXIT CODES\n" - " 0 success 1 archive I/O error 2 bad " - "usage\n"))); + "cfree ar — POSIX `ar` archive front-end\n" + "\n" + "USAGE\n" + " cfree ar MODE archive.a [members...]\n" + "\n" + "MODE is a string of one or more letters; exactly one operation " + "must\n" + "be selected and any number of modifiers may follow. The archive\n" + "path and (optional) member list follow the mode.\n" + "\n" + "OPERATIONS (mutually exclusive)\n" + " r Replace listed members in place; preserve unlisted; " + "append\n" + " new ones. Warns when the archive must be created.\n" + " c Create / overwrite the archive with exactly the listed\n" + " members. Suppresses the create warning.\n" + " rc, cr `r` semantics with the create warning suppressed.\n" + " t List member names.\n" + " x Extract members to the current working directory. With " + "no\n" + " member list, extract everything.\n" + " p Print members to stdout. With no list, print all " + "members;\n" + " with two or more members each is preceded by a header.\n" + "\n" + "MODIFIERS\n" + " s Emit a System-V `/` symbol-index member at the head of\n" + " the archive. Valid only combined with r and/or c (rs, " + "cs,\n" + " rcs, crs). Globally-defined symbols (CFREE_SB_GLOBAL " + "with\n" + " a defined section) of each object member are indexed; " + "non-\n" + " object members contribute no symbols.\n" + " u Update-if-newer compatibility modifier; accepted as a\n" + " no-op.\n" + " v Verbose. With t list <size>\\t<name>; with x/r/c print " + "one\n" + " line per affected member (\"x - name\", \"a - name\", or\n" + " \"r - name\" for replacements); with p force the " + "per-member\n" + " \"archive(name):\" header even on a single match.\n" + "\n" + "REPRODUCIBILITY\n" + " When SOURCE_DATE_EPOCH is set to a positive integer, that value " + "is\n" + " written to ar_date for every member on write. Long member names\n" + " are routed through a `//` extended-name table.\n" + "\n" + "NOT YET IMPLEMENTED\n" + " d (delete), q (quick append), and standalone `s` without r/c.\n" + " Encountering any of those yields a usage error with exit code 2.\n" + "\n" + "EXAMPLES\n" + " cfree ar rcs libfoo.a a.o b.o c.o\n" + " cfree ar t libfoo.a\n" + " cfree ar x libfoo.a a.o\n" + " cfree ar p libfoo.a a.o > a.o.copy\n" + "\n" + "GETTING HELP\n" + " -h, --help Show this help and exit\n" + "\n" + "EXIT CODES\n" + " 0 success 1 archive I/O error 2 bad " + "usage\n"))); } /* Parse SOURCE_DATE_EPOCH into a u64; 0 (or unset/invalid) means "no epoch". */ @@ -128,8 +137,7 @@ static uint64_t ar_epoch_from_env(void) { /* Return 1 iff `name` matches any of the names in argv[start..argc) — or if * there are no filters, in which case every member matches. */ -static int ar_name_selected(CfreeSlice name, int argc, char** argv, - int start) { +static int ar_name_selected(CfreeSlice name, int argc, char** argv, int start) { int i; if (start >= argc) return 1; for (i = start; i < argc; ++i) { @@ -185,7 +193,7 @@ static int ar_do_list(DriverEnv* env, const char* archive_path, int verbose) { CfreeArMember m; if (cfree_ar_iter_new(&ctx, &input, &it) != CFREE_OK) { driver_errf(AR_TOOL, "not an archive: %.*s", - CFREE_SLICE_ARG(cfree_slice_cstr(archive_path))); + CFREE_SLICE_ARG(cfree_slice_cstr(archive_path))); cfree_writer_close(out); ctx.file_io->release(ctx.file_io->user, &fd); return 1; @@ -193,8 +201,7 @@ static int ar_do_list(DriverEnv* env, const char* archive_path, int verbose) { for (;;) { CfreeIterResult r = cfree_ar_iter_next(it, &m); if (r != CFREE_ITER_ITEM) break; - driver_printf("%zu\t%.*s\n", m.size, - CFREE_SLICE_ARG(m.name)); + driver_printf("%zu\t%.*s\n", m.size, CFREE_SLICE_ARG(m.name)); } cfree_ar_iter_free(it); rc = cfree_writer_status(out) == CFREE_OK ? 0 : 1; @@ -234,20 +241,17 @@ static int ar_do_extract(DriverEnv* env, const char* archive_path, int argc, if (ctx.file_io->open_writer(ctx.file_io->user, m.name.s, &out) != CFREE_OK) { - driver_errf(AR_TOOL, "failed to open: %.*s", - CFREE_SLICE_ARG(m.name)); + driver_errf(AR_TOOL, "failed to open: %.*s", CFREE_SLICE_ARG(m.name)); rc = 1; continue; } if (m.size) cfree_writer_write(out, m.data, m.size); if (cfree_writer_status(out) != CFREE_OK) { - driver_errf(AR_TOOL, "write failed: %.*s", - CFREE_SLICE_ARG(m.name)); + driver_errf(AR_TOOL, "write failed: %.*s", CFREE_SLICE_ARG(m.name)); rc = 1; } cfree_writer_close(out); - if (verbose) - driver_printf("x - %.*s\n", CFREE_SLICE_ARG(m.name)); + if (verbose) driver_printf("x - %.*s\n", CFREE_SLICE_ARG(m.name)); } cfree_ar_iter_free(it); @@ -356,7 +360,7 @@ static int ar_do_write(DriverEnv* env, const char* archive_path, int nmembers, input.len = old_fd.size; if (cfree_ar_iter_new(&ctx, &input, &it) != CFREE_OK) { driver_errf(AR_TOOL, "not an archive: %.*s", - CFREE_SLICE_ARG(cfree_slice_cstr(archive_path))); + CFREE_SLICE_ARG(cfree_slice_cstr(archive_path))); rc = 1; goto done; } @@ -536,8 +540,7 @@ done: if (msyms) driver_free(env, msyms, (size_t)nm * sizeof(*msyms)); if (new_fds) { for (i = 0; i < nnew; ++i) { - if (new_fds[i].data) - ctx.file_io->release(ctx.file_io->user, &new_fds[i]); + if (new_fds[i].data) ctx.file_io->release(ctx.file_io->user, &new_fds[i]); } driver_free(env, new_fds, (size_t)nnew * sizeof(*new_fds)); } diff --git a/driver/as.c b/driver/as.c @@ -24,42 +24,49 @@ typedef struct AsOptions { static void as_usage(void) { driver_errf(AS_TOOL, "%.*s", CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "usage: cfree as [-g] [-target TRIPLE] -o out.o input.{s,S}\n" - " cfree as --help for full option reference"))); + "usage: cfree as [-g] [-target TRIPLE] -o out.o input.{s,S}\n" + " cfree as --help for full option reference"))); } void driver_help_as(void) { driver_printf( "%.*s", CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "cfree as — standalone assembler\n" - "\n" - "USAGE\n" - " cfree as [options] -o OUT.o INPUT.s\n" - " cfree as [options] -o OUT.o INPUT.S\n" - "\n" - "DESCRIPTION\n" - " Reads a single text source written in a GAS subset (AT&T syntax on\n" - " x86, standard mnemonics on aarch64/riscv64) and writes a relocatable\n" - " object via the same back-end the C compiler emits to. INPUT.S is run\n" - " through the C preprocessor first; INPUT.s is assembled directly.\n" - " Exactly one positional input is required; -o is required.\n" - "\n" - "OPTIONS\n" - " -o PATH Output object path (required)\n" - " -g Emit DWARF debug info from .file/.loc directives\n" - " -I DIR, -IDIR Add a user include directory for INPUT.S\n" - " -isystem DIR Add a system include directory for INPUT.S\n" - " -D NAME[=VALUE] Define a preprocessor macro for INPUT.S\n" - " -U NAME Undefine a preprocessor macro for INPUT.S\n" - " -target TRIPLE Cross-assemble target. See `cfree cc --help` for " - "the\n" - " full list of recognized arches and OSes. Default:\n" - " the host target.\n" - " -h, --help Show this help and exit\n" - "\n" - "EXIT CODES\n" - " 0 success 1 assemble error 2 bad usage\n"))); + "cfree as — standalone assembler\n" + "\n" + "USAGE\n" + " cfree as [options] -o OUT.o INPUT.s\n" + " cfree as [options] -o OUT.o INPUT.S\n" + "\n" + "DESCRIPTION\n" + " Reads a single text source written in a GAS subset (AT&T syntax " + "on\n" + " x86, standard mnemonics on aarch64/riscv64) and writes a " + "relocatable\n" + " object via the same back-end the C compiler emits to. INPUT.S is " + "run\n" + " through the C preprocessor first; INPUT.s is assembled directly.\n" + " Exactly one positional input is required; -o is required.\n" + "\n" + "OPTIONS\n" + " -o PATH Output object path (required)\n" + " -g Emit DWARF debug info from .file/.loc " + "directives\n" + " -I DIR, -IDIR Add a user include directory for INPUT.S\n" + " -isystem DIR Add a system include directory for INPUT.S\n" + " -D NAME[=VALUE] Define a preprocessor macro for INPUT.S\n" + " -U NAME Undefine a preprocessor macro for INPUT.S\n" + " -target TRIPLE Cross-assemble target. See `cfree cc --help` " + "for " + "the\n" + " full list of recognized arches and OSes. " + "Default:\n" + " the host target.\n" + " -h, --help Show this help and exit\n" + "\n" + "EXIT CODES\n" + " 0 success 1 assemble error 2 bad " + "usage\n"))); } /* Returns 0 on success; non-zero on bad args (already reported). */ diff --git a/driver/cc.c b/driver/cc.c @@ -129,16 +129,16 @@ typedef struct CcOptions { int output_path_set; char* owned_output_path; size_t owned_output_path_size; - const char* entry; /* -e */ - const char* linker_script; /* -T path */ - uint16_t pe_subsystem; /* CfreePeSubsystem */ - const char* sysroot; /* --sysroot / -isysroot */ - int freestanding; /* -ffreestanding (suppresses sysroot headers) */ + const char* entry; /* -e */ + const char* linker_script; /* -T path */ + uint16_t pe_subsystem; /* CfreePeSubsystem */ + const char* sysroot; /* --sysroot / -isysroot */ + int freestanding; /* -ffreestanding (suppresses sysroot headers) */ uint8_t default_visibility; /* CfreeSymVis; -fvisibility=... */ - int nostdinc; /* -nostdinc (suppresses sysroot headers) */ - const char* support_dir; /* --support-dir */ - int probe_kind; /* CcProbeKind */ - const char* probe_arg; /* -print-file-name= / -print-prog-name= */ + int nostdinc; /* -nostdinc (suppresses sysroot headers) */ + const char* support_dir; /* --support-dir */ + int probe_kind; /* CcProbeKind */ + const char* probe_arg; /* -print-file-name= / -print-prog-name= */ /* -ffile-prefix-map=old=new entries; old is heap-owned (split out), new * aliases argv. */ @@ -220,44 +220,51 @@ typedef struct CcOptions { static void cc_usage(void) { driver_errf(CC_TOOL, "%.*s", CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "usage: cfree cc [-c|-E|-shared] [-o out] " - "[options...] inputs...\n" - " cfree cc --help for full option reference"))); + "usage: cfree cc [-c|-E|-shared] [-o out] " + "[options...] inputs...\n" + " cfree cc --help for full option reference"))); } void driver_help_cc(void) { driver_printf( "%.*s", CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "cfree cc — C compiler driver\n" - "\n" - "USAGE\n" - " cfree cc [options] inputs... compile and link to " - "exe\n" - " cfree cc -c [options] input.c compile one source to " - ".o\n" - " cfree cc -E [options] input.c preprocess to -o\n" - " cfree cc -fsyntax-only [options] inputs... check only\n" - " cfree cc -shared [options] inputs... link a shared library\n" - " cfree cc -M|-MM [options] input.c print header deps; no " - "compile\n" - " --sysroot DIR / -isysroot DIR hosted SDK/sysroot\n" - " --support-dir DIR cfree support root\n" - "\n" - "(see source for the full GCC-subset flag reference)\n"))); + "cfree cc — C compiler driver\n" + "\n" + "USAGE\n" + " cfree cc [options] inputs... compile and link " + "to " + "exe\n" + " cfree cc -c [options] input.c compile one source " + "to " + ".o\n" + " cfree cc -E [options] input.c preprocess to -o\n" + " cfree cc -fsyntax-only [options] inputs... check only\n" + " cfree cc -shared [options] inputs... link a shared " + "library\n" + " cfree cc -M|-MM [options] input.c print header deps; " + "no " + "compile\n" + " --sysroot DIR / -isysroot DIR hosted " + "SDK/sysroot\n" + " --support-dir DIR cfree support " + "root\n" + "\n" + "(see source for the full GCC-subset flag reference)\n"))); } void driver_help_check(void) { - driver_printf( - "%.*s", - CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "cfree check — run frontend checks without emitting code\n" - "\n" - "USAGE\n" - " cfree check [cc-options] inputs...\n" - "\n" - "Runs the same C frontend path as `cfree cc -fsyntax-only`, including " - "preprocessing and diagnostics, but does not write objects or link.\n"))); + driver_printf("%.*s", + CFREE_SLICE_ARG(CFREE_SLICE_LIT( + "cfree check — run frontend checks without emitting code\n" + "\n" + "USAGE\n" + " cfree check [cc-options] inputs...\n" + "\n" + "Runs the same C frontend path as `cfree cc " + "-fsyntax-only`, including " + "preprocessing and diagnostics, but does not write objects " + "or link.\n"))); } static int cc_alloc_arrays(CcOptions* o, int argc) { @@ -363,8 +370,7 @@ static char* cc_dup_span(DriverEnv* env, const char* s, size_t n) { static int cc_record_build_id(CcOptions* o, const char* val); static int cc_apply_hosted_profile(CcOptions* o); -static int cc_subsystem_value_eq(const char* val, size_t n, - const char* want) { +static int cc_subsystem_value_eq(const char* val, size_t n, const char* want) { size_t i; for (i = 0; want[i]; ++i) { char a; @@ -761,21 +767,25 @@ static int cc_run_probe(CcOptions* o) { switch (o->probe_kind) { case CC_PROBE_PRINT_SEARCH_DIRS: - driver_printf("install: %.*s\n", CFREE_SLICE_ARG(cfree_slice_cstr( - o->support_dir ? o->support_dir : ""))); + driver_printf("install: %.*s\n", + CFREE_SLICE_ARG(cfree_slice_cstr( + o->support_dir ? o->support_dir : ""))); driver_printf("programs: =\n"); driver_printf("libraries: ="); if (o->sysroot) - driver_printf("%.*s/lib", CFREE_SLICE_ARG(cfree_slice_cstr(o->sysroot))); + driver_printf("%.*s/lib", + CFREE_SLICE_ARG(cfree_slice_cstr(o->sysroot))); driver_printf("\n"); return 0; case CC_PROBE_PRINT_FILE_NAME: - driver_printf("%.*s\n", CFREE_SLICE_ARG(cfree_slice_cstr( - o->probe_arg ? o->probe_arg : ""))); + driver_printf( + "%.*s\n", + CFREE_SLICE_ARG(cfree_slice_cstr(o->probe_arg ? o->probe_arg : ""))); return 0; case CC_PROBE_PRINT_PROG_NAME: - driver_printf("%.*s\n", CFREE_SLICE_ARG(cfree_slice_cstr( - o->probe_arg ? o->probe_arg : ""))); + driver_printf( + "%.*s\n", + CFREE_SLICE_ARG(cfree_slice_cstr(o->probe_arg ? o->probe_arg : ""))); return 0; case CC_PROBE_PRINT_LIBGCC_FILE_NAME: driver_printf("libcfree_rt.a\n"); @@ -883,8 +893,8 @@ static int cc_resolve_pending_libs(CcOptions* o) { ? LIB_RESOLVE_OS_WINDOWS : LIB_RESOLVE_OS_POSIX; if (driver_lib_resolve_for_os(o->env, pl->name, mode, resolve_os, - o->lib_search_paths, o->nlib_search_paths, - &p, &sz, &kind) != 0) { + o->lib_search_paths, o->nlib_search_paths, &p, + &sz, &kind) != 0) { driver_errf(CC_TOOL, "library not found: -l%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(pl->name))); return 1; @@ -1025,8 +1035,8 @@ static int cc_append_windows_lib_dirs(CcOptions* o) { } static int cc_has_link_action(const CcOptions* o) { - return !o->compile_only && !o->preprocess_only && - o->dep_mode != CC_DEP_M && o->dep_mode != CC_DEP_MM; + return !o->compile_only && !o->preprocess_only && o->dep_mode != CC_DEP_M && + o->dep_mode != CC_DEP_MM; } /* A sysroot on its own means "compile/link hosted against that root" — the @@ -1612,14 +1622,16 @@ static int cc_parse(int argc, char** argv, CcOptions* o) { } if ((o->compile_only && o->preprocess_only) || (o->emit_asm_source && o->preprocess_only) || - (o->syntax_only && (o->compile_only || o->preprocess_only || - o->emit_asm_source))) { - driver_errf(CC_TOOL, "-c, -S, -E, and -fsyntax-only are mutually exclusive"); + (o->syntax_only && + (o->compile_only || o->preprocess_only || o->emit_asm_source))) { + driver_errf(CC_TOOL, + "-c, -S, -E, and -fsyntax-only are mutually exclusive"); return 1; } if (o->shared && (o->compile_only || o->emit_asm_source || - o->preprocess_only || o->syntax_only)) { - driver_errf(CC_TOOL, "-shared is incompatible with -c/-S/-E/-fsyntax-only"); + o->preprocess_only || o->syntax_only)) { + driver_errf(CC_TOOL, + "-shared is incompatible with -c/-S/-E/-fsyntax-only"); return 1; } if (o->syntax_only) { @@ -1921,9 +1933,8 @@ static char* cc_dep_default_target(DriverEnv* env, const CcOptions* o, } } -static char* cc_default_obj_path_for_name(DriverEnv* env, - const CcOptions* o, const char* src, - size_t* out_size) { +static char* cc_default_obj_path_for_name(DriverEnv* env, const CcOptions* o, + const char* src, size_t* out_size) { /* Windows targets default to a `.obj` suffix; everyone else `.o`. * Drivers accept both spellings as inputs (driver/inputs.c), but * tooling that scrapes default outputs expects the canonical @@ -2106,10 +2117,10 @@ static int cc_dep_finish(DriverEnv* env, const CfreeContext* ctx, dep_w = cc_dep_open_writer(env, ctx, o, &owned_path, &owned_size); if (!dep_w) { - driver_errf( - CC_TOOL, "failed to open dep output: %.*s", - CFREE_SLICE_ARG(cfree_slice_cstr( - o->dep_file ? o->dep_file : (owned_path ? owned_path : "<stdout>")))); + driver_errf(CC_TOOL, "failed to open dep output: %.*s", + CFREE_SLICE_ARG(cfree_slice_cstr( + o->dep_file ? o->dep_file + : (owned_path ? owned_path : "<stdout>")))); goto out; } @@ -2284,11 +2295,10 @@ static int cc_run_compile_one(DriverEnv* env, const CcOptions* o, copts.code.c_source_writer = obj_w; } { - CfreeLanguage lang = - is_memory - ? o->source_memory[index].lang - : cc_resolve_lang(compiler, o->source_files[index], - o->source_langs[index]); + CfreeLanguage lang = is_memory + ? o->source_memory[index].lang + : cc_resolve_lang(compiler, o->source_files[index], + o->source_langs[index]); CfreeSlice in_name = is_memory ? o->source_memory[index].name : cfree_slice_cstr(o->source_files[index]); CfreeStatus st; @@ -2331,8 +2341,7 @@ static int cc_run_compile_objs(DriverEnv* env, const CcOptions* o, if (rc != 0) return rc; } for (i = 0; i < o->nsource_memory; ++i) { - const char* out = - o->emit_asm_source ? "<stdin>.s" : "<stdin>.o"; + const char* out = o->emit_asm_source ? "<stdin>.s" : "<stdin>.o"; if (cc_run_compile_one(env, o, pp, 1, i, out) != 0) return 1; } return 0; @@ -2379,19 +2388,17 @@ static int cc_run_check(DriverEnv* env, const CcOptions* o, CfreeObjBuilder* ob = NULL; CfreeLanguage lang = cc_resolve_lang(compiler, o->source_files[i], o->source_langs[i]); - CfreeStatus st = - cc_compile_source_obj(compiler, lang, &copts, - cfree_slice_cstr(o->source_files[i]), - &src_bytes[i], &ob); + CfreeStatus st = cc_compile_source_obj(compiler, lang, &copts, + cfree_slice_cstr(o->source_files[i]), + &src_bytes[i], &ob); cfree_obj_builder_free(ob); if (st != CFREE_OK) goto out; } for (i = 0; i < o->nsource_memory; ++i) { CfreeObjBuilder* ob = NULL; - CfreeStatus st = - cc_compile_source_obj(compiler, o->source_memory[i].lang, &copts, - o->source_memory[i].name, - &o->source_memory[i].bytes, &ob); + CfreeStatus st = cc_compile_source_obj(compiler, o->source_memory[i].lang, + &copts, o->source_memory[i].name, + &o->source_memory[i].bytes, &ob); cfree_obj_builder_free(ob); if (st != CFREE_OK) goto out; } @@ -2545,10 +2552,9 @@ static int cc_run_link_exe(DriverEnv* env, const CcOptions* o, } for (i = 0; i < o->nsource_memory; ++i) { CfreeStatus st; - st = cc_compile_source_obj(compiler, o->source_memory[i].lang, &copts, - o->source_memory[i].name, - &o->source_memory[i].bytes, - &objs[o->nsource_files + i]); + st = cc_compile_source_obj( + compiler, o->source_memory[i].lang, &copts, o->source_memory[i].name, + &o->source_memory[i].bytes, &objs[o->nsource_files + i]); if (st != CFREE_OK) goto out; } @@ -2563,7 +2569,8 @@ static int cc_run_link_exe(DriverEnv* env, const CcOptions* o, CfreeStatus st; CfreeSlice* rpath_slices = NULL; if (o->nrpaths) { - rpath_slices = driver_alloc_zeroed(env, o->nrpaths * sizeof(*rpath_slices)); + rpath_slices = + driver_alloc_zeroed(env, o->nrpaths * sizeof(*rpath_slices)); if (!rpath_slices) { driver_errf(CC_TOOL, "out of memory"); goto out; diff --git a/driver/cflags.c b/driver/cflags.c @@ -62,7 +62,7 @@ static int cflags_record_define(DriverCflags* cf, DriverEnv* env, name[n] = '\0'; cf->_owned_define_names[cf->ndefines] = name; cf->_owned_define_name_sizes[cf->ndefines] = bytes; - d->name = (CfreeSlice){ .s = name, .len = n }; + d->name = (CfreeSlice){.s = name, .len = n}; d->body = cfree_slice_cstr(eq + 1); } else { d->name = cfree_slice_cstr(arg); @@ -119,8 +119,7 @@ int driver_cflags_try_consume(DriverCflags* cf, DriverEnv* env, } if (driver_strneq(a, "-idirafter", 10)) { - const char* dir = - cflags_pull_value(tool, argc, argv, i, 10, "-idirafter"); + const char* dir = cflags_pull_value(tool, argc, argv, i, 10, "-idirafter"); if (!dir) return -1; cf->system_include_dirs[cf->nsystem_include_dirs++] = dir; return 1; diff --git a/driver/cflags.h b/driver/cflags.h @@ -1,10 +1,10 @@ #ifndef CFREE_DRIVER_CFLAGS_H #define CFREE_DRIVER_CFLAGS_H -#include "driver.h" - #include <cfree/compile.h> +#include "driver.h" + /* Shared parsing of the C-preprocessor flag family used by both `cc` and * `run`: -I, -isystem, -D, -U. Owns a back-store sized to the worst-case * argv slot count so callers can hold borrowed pointers into argv without diff --git a/driver/cpp.c b/driver/cpp.c @@ -1,8 +1,7 @@ -#include <stdint.h> - #include <cfree/compile.h> #include <cfree/core.h> #include <cfree/preprocess.h> +#include <stdint.h> #include "cflags.h" #include "driver.h" @@ -37,38 +36,40 @@ void driver_help_cpp(void) { driver_printf( "%.*s", CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "cfree cpp — standalone C preprocessor\n" - "\n" - "USAGE\n" - " cfree cpp [options] INPUT.c\n" - " cfree cpp [options] - (read from stdin)\n" - "\n" - "DESCRIPTION\n" - " Runs the C preprocessor on a single input and writes the resulting\n" - " token stream to -o (or stdout when -o is absent). Functionally\n" - " equivalent to `cfree cc -E` but without cc's link/source-input\n" - " classification.\n" - "\n" - "OPTIONS\n" - " -o PATH Output path (default: stdout)\n" - " -I DIR, -IDIR Add a user include directory\n" - " -isystem DIR Add a system include directory\n" - " -D NAME[=BODY] Define a preprocessor macro\n" - " -U NAME Undefine a preprocessor macro\n" - " -target TRIPLE Cross-target. See `cfree cc --help` for the\n" - " accepted arches/OSes. Default: host.\n" - " -h, --help Show this help and exit\n" - "\n" - "EXIT CODES\n" - " 0 success 1 preprocess / I/O error 2 bad " - "usage\n"))); + "cfree cpp — standalone C preprocessor\n" + "\n" + "USAGE\n" + " cfree cpp [options] INPUT.c\n" + " cfree cpp [options] - (read from stdin)\n" + "\n" + "DESCRIPTION\n" + " Runs the C preprocessor on a single input and writes the " + "resulting\n" + " token stream to -o (or stdout when -o is absent). Functionally\n" + " equivalent to `cfree cc -E` but without cc's link/source-input\n" + " classification.\n" + "\n" + "OPTIONS\n" + " -o PATH Output path (default: stdout)\n" + " -I DIR, -IDIR Add a user include directory\n" + " -isystem DIR Add a system include directory\n" + " -D NAME[=BODY] Define a preprocessor macro\n" + " -U NAME Undefine a preprocessor macro\n" + " -target TRIPLE Cross-target. See `cfree cc --help` for the\n" + " accepted arches/OSes. Default: host.\n" + " -h, --help Show this help and exit\n" + "\n" + "EXIT CODES\n" + " 0 success 1 preprocess / I/O error 2 " + "bad " + "usage\n"))); } static void cpp_usage(void) { driver_errf(CPP_TOOL, "%.*s", CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "usage: cfree cpp [options] INPUT.c\n" - " cfree cpp --help for full option reference"))); + "usage: cfree cpp [options] INPUT.c\n" + " cfree cpp --help for full option reference"))); } static int cpp_parse(int argc, char** argv, CppOptions* o, DriverEnv* env, @@ -216,11 +217,10 @@ int driver_cpp(int argc, char** argv) { goto out; } - rc = - cfree_cpp_preprocess(compiler, &pp, input_name, &input, writer) == - CFREE_OK - ? 0 - : 1; + rc = cfree_cpp_preprocess(compiler, &pp, input_name, &input, writer) == + CFREE_OK + ? 0 + : 1; out: if (compiler) driver_compiler_free(compiler); diff --git a/driver/dbg.c b/driver/dbg.c @@ -68,79 +68,90 @@ void driver_help_dbg(void) { driver_printf( "%.*s", CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "cfree dbg — interactive JIT debugger\n" - "\n" - "USAGE\n" - " cfree dbg [options] [input.{c,toy,s} ...] [-- prog-arg ...]\n" - "\n" - "DESCRIPTION\n" - " Mirrors `cfree run` for compile flags and argv shape, but instead\n" - " of calling the entry directly drops into a REPL that drives the\n" - " JIT session: breakpoints, single-step (insn / source line / over),\n" - " finish, backtrace, registers, locals/args, variable read/write,\n" - " and raw memory examine. -g is forced on so source lines and\n" - " variable locations are available at runtime.\n" - "\n" - " Anything after `--` is passed to the JITed program as argv.\n" - " With no input files, dbg starts an empty JIT session; append code\n" - " with `jit` or evaluate expressions directly from the REPL.\n" - "\n" - "COMPILE OPTIONS\n" - " -O0 -O1 -O2 Optimization level (default -O0)\n" - " -g Emit DWARF (forced on)\n" - " -e SYMBOL Entry symbol (default `main`)\n" - " -x LANG Default REPL language: c, toy, asm, wasm/wat\n" - " --language LANG Same as -x\n" - " -I DIR Add quoted-include search path\n" - " -isystem DIR Add system-include search path\n" - " -D NAME[=BODY] Define a macro\n" - " -U NAME Undefine a builtin/predefined macro\n" - "\n" - "REPL COMMANDS (also shown by `h` at the prompt)\n" - " h, help show REPL help\n" - " q, quit exit (Ctrl-D also works)\n" - " r, run start fresh execution at entry\n" - " c, cont continue after a stop\n" - " s, step single-step one instruction\n" - " sl step to next source line (into calls)\n" - " n, next step to next source line (over calls)\n" - " finish run until current frame returns\n" - " jit [LANG|NAME] { ... } compile and append a language snippet\n" - " { ... } same as jit { ... }\n" - " edit [LANG|NAME] edit and append a language snippet\n" - " expr EXPR | expr { ... } compile and call an expression thunk\n" - " EXPR same as expr EXPR\n" - " LANG defaults to the selected language\n" - " call SYMBOL [INT_OR_ADDR...] call function, returns uint64_t\n" - " jump ADDR set PC to ADDR (no resume)\n" - " bt, backtrace print stack trace with arguments\n" - " b LOC set breakpoint at LOC:\n" - " 0xADDR | sym[+off] | file.c:line\n" - " ignore N COUNT skip the next COUNT hits of bp N\n" - " d N, delete N delete breakpoint N\n" - " enable N | disable N toggle breakpoint N\n" - " p NAME print variable / global\n" - " set NAME VALUE write VALUE into NAME\n" - " x ADDR [count] examine memory (default 16 bytes)\n" - " list FILE:LINE | l FILE:LINE source listing around FILE:LINE\n" - " info b list breakpoints\n" - " info reg, info registers dump registers\n" - " info locals | info args list locals / args at current PC\n" - " info functions [PATTERN] list JIT functions matching PATTERN\n" - " info variables [PATTERN] list JIT globals matching PATTERN\n" - "\n" - "SIGNALS\n" - " Ctrl-C is forwarded into the running session as an interrupt; at\n" - " the REPL prompt it terminates the program normally.\n" - "\n" - "GETTING HELP\n" - " -h, --help Show this help and exit (this is the\n" - " command-line help; once the REPL is\n" - " running, type `h` for REPL commands)\n" - "\n" - "EXIT CODES\n" - " 0 clean exit 1 compile/link or session error 2 bad " - "usage\n"))); + "cfree dbg — interactive JIT debugger\n" + "\n" + "USAGE\n" + " cfree dbg [options] [input.{c,toy,s} ...] [-- prog-arg ...]\n" + "\n" + "DESCRIPTION\n" + " Mirrors `cfree run` for compile flags and argv shape, but " + "instead\n" + " of calling the entry directly drops into a REPL that drives the\n" + " JIT session: breakpoints, single-step (insn / source line / " + "over),\n" + " finish, backtrace, registers, locals/args, variable read/write,\n" + " and raw memory examine. -g is forced on so source lines and\n" + " variable locations are available at runtime.\n" + "\n" + " Anything after `--` is passed to the JITed program as argv.\n" + " With no input files, dbg starts an empty JIT session; append " + "code\n" + " with `jit` or evaluate expressions directly from the REPL.\n" + "\n" + "COMPILE OPTIONS\n" + " -O0 -O1 -O2 Optimization level (default -O0)\n" + " -g Emit DWARF (forced on)\n" + " -e SYMBOL Entry symbol (default `main`)\n" + " -x LANG Default REPL language: c, toy, asm, wasm/wat\n" + " --language LANG Same as -x\n" + " -I DIR Add quoted-include search path\n" + " -isystem DIR Add system-include search path\n" + " -D NAME[=BODY] Define a macro\n" + " -U NAME Undefine a builtin/predefined macro\n" + "\n" + "REPL COMMANDS (also shown by `h` at the prompt)\n" + " h, help show REPL help\n" + " q, quit exit (Ctrl-D also works)\n" + " r, run start fresh execution at entry\n" + " c, cont continue after a stop\n" + " s, step single-step one instruction\n" + " sl step to next source line (into " + "calls)\n" + " n, next step to next source line (over " + "calls)\n" + " finish run until current frame returns\n" + " jit [LANG|NAME] { ... } compile and append a language " + "snippet\n" + " { ... } same as jit { ... }\n" + " edit [LANG|NAME] edit and append a language snippet\n" + " expr EXPR | expr { ... } compile and call an expression " + "thunk\n" + " EXPR same as expr EXPR\n" + " LANG defaults to the selected " + "language\n" + " call SYMBOL [INT_OR_ADDR...] call function, returns uint64_t\n" + " jump ADDR set PC to ADDR (no resume)\n" + " bt, backtrace print stack trace with arguments\n" + " b LOC set breakpoint at LOC:\n" + " 0xADDR | sym[+off] | file.c:line\n" + " ignore N COUNT skip the next COUNT hits of bp N\n" + " d N, delete N delete breakpoint N\n" + " enable N | disable N toggle breakpoint N\n" + " p NAME print variable / global\n" + " set NAME VALUE write VALUE into NAME\n" + " x ADDR [count] examine memory (default 16 bytes)\n" + " list FILE:LINE | l FILE:LINE source listing around FILE:LINE\n" + " info b list breakpoints\n" + " info reg, info registers dump registers\n" + " info locals | info args list locals / args at current PC\n" + " info functions [PATTERN] list JIT functions matching PATTERN\n" + " info variables [PATTERN] list JIT globals matching PATTERN\n" + "\n" + "SIGNALS\n" + " Ctrl-C is forwarded into the running session as an interrupt; at\n" + " the REPL prompt it terminates the program normally.\n" + "\n" + "GETTING HELP\n" + " -h, --help Show this help and exit (this is " + "the\n" + " command-line help; once the REPL is\n" + " running, type `h` for REPL " + "commands)\n" + "\n" + "EXIT CODES\n" + " 0 clean exit 1 compile/link or session error 2 " + "bad " + "usage\n"))); } static int dbg_alloc_arrays(DbgOpts* o, int argc) { @@ -883,8 +894,8 @@ static int dbg_drive(DbgState* s, DbgRunMode mode) { driver_errf(DBG_TOOL, "session %.*s failed (st=%d) — " "JIT session implementation pending", - CFREE_SLICE_ARG(cfree_slice_cstr(mode == RUN_FRESH ? "call" - : "resume")), + CFREE_SLICE_ARG( + cfree_slice_cstr(mode == RUN_FRESH ? "call" : "resume")), (int)rc); return 1; } @@ -970,8 +981,8 @@ static void dbg_cmd_bt(DbgState* s) { r = cfree_dwarf_param_iter_next(it, &p); if (r != CFREE_ITER_ITEM) break; if (!first) driver_printf(", "); - driver_printf("%.*s=", CFREE_SLICE_ARG(p.name.s ? p.name - : CFREE_SLICE_LIT("?"))); + driver_printf("%.*s=", CFREE_SLICE_ARG( + p.name.s ? p.name : CFREE_SLICE_LIT("?"))); dbg_translate_loc(s, &p.loc); if (dbg_read_value(s, &p.loc, &frame, stack_buf, sizeof(stack_buf), &buf, &alloc, &got) == 0) { @@ -1178,9 +1189,9 @@ static void dbg_print_value(DbgState* s, const CfreeDwarfType* type, if (r != CFREE_ITER_ITEM) break; size_t fsz = 0; dbg_indent(depth + 1); - driver_printf(".%.*s = ", - CFREE_SLICE_ARG(f.name.len ? f.name - : CFREE_SLICE_LIT("<anon>"))); + driver_printf( + ".%.*s = ", + CFREE_SLICE_ARG(f.name.len ? f.name : CFREE_SLICE_LIT("<anon>"))); if (f.bit_size) { /* Bitfield: read up to 8 bytes spanning the storage * unit at byte_offset, shift, mask. */ @@ -1694,8 +1705,8 @@ static int dbg_jit_compile_append_ex(DbgState* s, CfreeLanguage lang, s->jit_counter++; memset(&sin, 0, sizeof(sin)); - sin.name = cfree_slice_cstr(input_name ? input_name - : dbg_jit_default_name(lang)); + sin.name = + cfree_slice_cstr(input_name ? input_name : dbg_jit_default_name(lang)); sin.bytes.data = (const uint8_t*)src; sin.bytes.len = len; sin.lang = lang; @@ -2193,8 +2204,8 @@ static void dbg_cmd_list(DbgState* s, const char* spec) { /* Validate via DWARF first. */ { - CfreeStatus st = cfree_dwarf_line_to_addr( - s->dwarf, cfree_slice_cstr(path), (uint32_t)line_u, &pc); + CfreeStatus st = cfree_dwarf_line_to_addr(s->dwarf, cfree_slice_cstr(path), + (uint32_t)line_u, &pc); if (st == CFREE_NOT_FOUND) { driver_errf(DBG_TOOL, "no line %u in %.*s", (uint32_t)line_u, CFREE_SLICE_ARG(cfree_slice_cstr(path))); @@ -2241,10 +2252,10 @@ static void dbg_cmd_list(DbgState* s, const char* spec) { if (eol) { if (cur >= lo && cur <= hi) { size_t len = (size_t)(p - line_start); - driver_printf("%6u%.*s %.*s\n", cur, - CFREE_SLICE_ARG( - cfree_slice_cstr(cur == target ? " >" : " ")), - (int)len, (const char*)line_start); + driver_printf( + "%6u%.*s %.*s\n", cur, + CFREE_SLICE_ARG(cfree_slice_cstr(cur == target ? " >" : " ")), + (int)len, (const char*)line_start); } ++cur; if (p == end) break; @@ -2322,11 +2333,10 @@ static void dbg_cmd_break(DbgState* s, const char* spec) { } s->nbps++; - driver_printf("Breakpoint %d at 0x%llx (%.*s)%.*s\n", b->id, - (unsigned long long)addr, - CFREE_SLICE_ARG(cfree_slice_cstr(spec)), - CFREE_SLICE_ARG( - cfree_slice_cstr(b->session_id ? "" : " [disarmed]"))); + driver_printf( + "Breakpoint %d at 0x%llx (%.*s)%.*s\n", b->id, (unsigned long long)addr, + CFREE_SLICE_ARG(cfree_slice_cstr(spec)), + CFREE_SLICE_ARG(cfree_slice_cstr(b->session_id ? "" : " [disarmed]"))); } static void dbg_cmd_info_b(DbgState* s) { @@ -2338,13 +2348,12 @@ static void dbg_cmd_info_b(DbgState* s) { driver_printf("Num Enb Address Skip Max Spec\n"); for (i = 0; i < s->nbps; ++i) { Bp* b = &s->bps[i]; - driver_printf("%-4d %-4s 0x%-18llx %-6llu %-6llu %.*s%.*s\n", b->id, - b->enabled ? "y" : "n", (unsigned long long)b->addr, - (unsigned long long)b->skip_count, - (unsigned long long)b->max_hits, - CFREE_SLICE_ARG(cfree_slice_cstr(b->spec)), - CFREE_SLICE_ARG( - cfree_slice_cstr(b->session_id ? "" : " [disarmed]"))); + driver_printf( + "%-4d %-4s 0x%-18llx %-6llu %-6llu %.*s%.*s\n", b->id, + b->enabled ? "y" : "n", (unsigned long long)b->addr, + (unsigned long long)b->skip_count, (unsigned long long)b->max_hits, + CFREE_SLICE_ARG(cfree_slice_cstr(b->spec)), + CFREE_SLICE_ARG(cfree_slice_cstr(b->session_id ? "" : " [disarmed]"))); } } @@ -2404,40 +2413,46 @@ static void dbg_cmd_help(void) { driver_printf( "%.*s", CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "Commands (abbrev. shown):\n" - " h, help show this help\n" - " q, quit exit (Ctrl-D also works)\n" - " :language c|toy|asm|wasm select language for jit/expr input\n" - " r, run start fresh execution at entry\n" - " c, cont continue after a stop\n" - " s, step single-step one instruction\n" - " sl step to next source line (into calls)\n" - " n, next step to next source line (over calls)\n" - " finish run until current frame returns\n" - " jit [LANG|NAME] { ... } compile and append a language snippet\n" - " { ... } same as jit { ... }\n" - " edit [LANG|NAME], e [...] edit and append a language snippet\n" - " expr EXPR | expr { ... } compile and call an expression thunk\n" - " EXPR same as expr EXPR\n" - " LANG defaults to the selected language\n" - " call SYMBOL [INT_OR_ADDR...] call function, returns uint64_t\n" - " jump ADDR set PC to ADDR (no resume)\n" - " bt, backtrace print stack trace with arguments\n" - " b LOC set breakpoint at LOC:\n" - " 0xADDR | sym[+off] | file.c:line\n" - " ignore N COUNT skip the next COUNT hits of bp N\n" - " d N, delete N delete breakpoint N\n" - " enable N | disable N toggle breakpoint N\n" - " p NAME print variable / global\n" - " set NAME VALUE write VALUE into NAME\n" - " x ADDR [count] examine memory (count bytes, default 16)\n" - " list FILE:LINE, l FILE:LINE source listing around FILE:LINE\n" - " info b list breakpoints\n" - " info reg, info registers dump registers\n" - " info locals list locals at current PC\n" - " info args list args at current PC\n" - " info functions [PATTERN] list JIT functions matching PATTERN\n" - " info variables [PATTERN] list JIT globals matching PATTERN\n"))); + "Commands (abbrev. shown):\n" + " h, help show this help\n" + " q, quit exit (Ctrl-D also works)\n" + " :language c|toy|asm|wasm select language for jit/expr input\n" + " r, run start fresh execution at entry\n" + " c, cont continue after a stop\n" + " s, step single-step one instruction\n" + " sl step to next source line (into " + "calls)\n" + " n, next step to next source line (over " + "calls)\n" + " finish run until current frame returns\n" + " jit [LANG|NAME] { ... } compile and append a language " + "snippet\n" + " { ... } same as jit { ... }\n" + " edit [LANG|NAME], e [...] edit and append a language snippet\n" + " expr EXPR | expr { ... } compile and call an expression thunk\n" + " EXPR same as expr EXPR\n" + " LANG defaults to the selected " + "language\n" + " call SYMBOL [INT_OR_ADDR...] call function, returns uint64_t\n" + " jump ADDR set PC to ADDR (no resume)\n" + " bt, backtrace print stack trace with arguments\n" + " b LOC set breakpoint at LOC:\n" + " 0xADDR | sym[+off] | file.c:line\n" + " ignore N COUNT skip the next COUNT hits of bp N\n" + " d N, delete N delete breakpoint N\n" + " enable N | disable N toggle breakpoint N\n" + " p NAME print variable / global\n" + " set NAME VALUE write VALUE into NAME\n" + " x ADDR [count] examine memory (count bytes, default " + "16)\n" + " list FILE:LINE, l FILE:LINE source listing around FILE:LINE\n" + " info b list breakpoints\n" + " info reg, info registers dump registers\n" + " info locals list locals at current PC\n" + " info args list args at current PC\n" + " info functions [PATTERN] list JIT functions matching PATTERN\n" + " info variables [PATTERN] list JIT globals matching " + "PATTERN\n"))); } static CfreeLanguage dbg_default_language_from_inputs(CfreeCompiler* c, diff --git a/driver/driver.h b/driver/driver.h @@ -1,10 +1,10 @@ #ifndef CFREE_DRIVER_H #define CFREE_DRIVER_H -#include <cfree/core.h> #include <cfree/compile.h> -#include <cfree/jit.h> +#include <cfree/core.h> #include <cfree/dbg.h> +#include <cfree/jit.h> #include "env.h" @@ -33,25 +33,25 @@ typedef enum DriverTool { } DriverTool; /* Multi-call entry: dispatches by argv[0] basename (or argv[1] fallback). */ -int driver_main(int argc, char **argv); +int driver_main(int argc, char** argv); /* Direct entry per tool. Each lives in driver/<tool>.c. */ -int driver_cc(int argc, char **argv); -int driver_check(int argc, char **argv); -int driver_cpp(int argc, char **argv); -int driver_as(int argc, char **argv); -int driver_ld(int argc, char **argv); -int driver_ar(int argc, char **argv); -int driver_ranlib(int argc, char **argv); -int driver_strip(int argc, char **argv); -int driver_objcopy(int argc, char **argv); -int driver_objdump(int argc, char **argv); -int driver_dbg(int argc, char **argv); -int driver_run(int argc, char **argv); -int driver_emu(int argc, char **argv); -int driver_nm(int argc, char **argv); -int driver_size(int argc, char **argv); -int driver_addr2line(int argc, char **argv); +int driver_cc(int argc, char** argv); +int driver_check(int argc, char** argv); +int driver_cpp(int argc, char** argv); +int driver_as(int argc, char** argv); +int driver_ld(int argc, char** argv); +int driver_ar(int argc, char** argv); +int driver_ranlib(int argc, char** argv); +int driver_strip(int argc, char** argv); +int driver_objcopy(int argc, char** argv); +int driver_objdump(int argc, char** argv); +int driver_dbg(int argc, char** argv); +int driver_run(int argc, char** argv); +int driver_emu(int argc, char** argv); +int driver_nm(int argc, char** argv); +int driver_size(int argc, char** argv); +int driver_addr2line(int argc, char** argv); /* Per-tool help printers. Write a multi-section help text to stdout and * return. The tool entry-points call these when invoked with no args, -h, @@ -83,13 +83,13 @@ void driver_help_top(void); * as a help request by every tool except objdump (where it means * "section headers"); callers that want to honour it should test it * explicitly via driver_argv_wants_help(..., 1). */ -int driver_is_help_flag(const char *arg); +int driver_is_help_flag(const char* arg); /* Scan argv[1..argc-1] for a help request, returning 1 on a hit. Triggers * on "--help" / "-help" always, and on "-h" when accept_short_h is set. * Tool entries also treat argc < 2 (no positional or option args) as a * help request — the convention is "no args means show help". */ -int driver_argv_wants_help(int argc, char **argv, int accept_short_h); +int driver_argv_wants_help(int argc, char** argv, int accept_short_h); /* Parse a target triple string (`<arch>[-<vendor>]-<os>[-<env>]`) into a * CfreeTarget. Recognized arches: x86_64/amd64, i386/i486/i586/i686, aarch64/ @@ -99,10 +99,10 @@ int driver_argv_wants_help(int argc, char **argv, int accept_short_h); * freestanding. Sets arch/os/obj/ptr_size/ptr_align/big_endian; pic and * code_model are left at their defaults. Returns 0 on success, nonzero on * unrecognized arch or NULL inputs. */ -int driver_target_from_triple(const char *triple, CfreeTarget *out); +int driver_target_from_triple(const char* triple, CfreeTarget* out); /* Render a canonical driver target triple into `buf`. Returns 0 on success, * nonzero when `buf` is too small. */ -int driver_target_to_triple(CfreeTarget target, char *buf, size_t cap); +int driver_target_to_triple(CfreeTarget target, char* buf, size_t cap); #endif diff --git a/driver/emu.c b/driver/emu.c @@ -1,12 +1,11 @@ +#include <cfree/core.h> +#include <cfree/emu.h> +#include <cfree/object.h> #include <stddef.h> #include <stdint.h> #include "driver.h" -#include <cfree/core.h> -#include <cfree/emu.h> -#include <cfree/object.h> - /* `cfree emu` — run a guest user-mode executable on the host via libcfree's * per-basic-block JIT translator. * @@ -52,39 +51,43 @@ void driver_help_emu(void) { driver_printf( "%.*s", CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "cfree emu — run a guest user-mode executable on the host\n" - "\n" - "USAGE\n" - " cfree emu [options] guest-exe [-- guest-arg...]\n" - "\n" - "DESCRIPTION\n" - " Loads a static guest user-mode executable and runs it on the host via\n" - " the per-basic-block JIT translator. The host code generated by the\n" - " translator runs natively on the host arch.\n" - "\n" - " The driver returns the guest's exit code on a clean exit, or 1 on\n" - " internal failure. Argv shape mirrors `cfree run`: anything after\n" - " `--` is forwarded as the guest argv. With no `--`, argv[0] defaults\n" - " to the guest executable path.\n" - "\n" - "OPTIONS\n" - " -O0 -O1 -O2 Translator optimization level (default -O0)\n" - " -arch ARCH Force guest arch: aarch64 (alias arm64) or\n" - " riscv64 (alias rv64). When omitted the arch is\n" - " auto-detected from the executable.\n" - " -tracepc Trace each translated PC\n" - " -traceinsn Trace each guest instruction\n" - " -traceblock Trace each translated basic block\n" - " -h, --help Show this help and exit\n" - "\n" - "EXAMPLES\n" - " cfree emu hello\n" - " cfree emu -arch riscv64 hello -- foo bar\n" - " cfree emu -O2 -tracepc prog\n" - "\n" - "EXIT CODES\n" - " Returns the guest's exit code on clean exit, or 1 on internal\n" - " failure. 2 on bad command-line usage.\n"))); + "cfree emu — run a guest user-mode executable on the host\n" + "\n" + "USAGE\n" + " cfree emu [options] guest-exe [-- guest-arg...]\n" + "\n" + "DESCRIPTION\n" + " Loads a static guest user-mode executable and runs it on the host " + "via\n" + " the per-basic-block JIT translator. The host code generated by " + "the\n" + " translator runs natively on the host arch.\n" + "\n" + " The driver returns the guest's exit code on a clean exit, or 1 " + "on\n" + " internal failure. Argv shape mirrors `cfree run`: anything after\n" + " `--` is forwarded as the guest argv. With no `--`, argv[0] " + "defaults\n" + " to the guest executable path.\n" + "\n" + "OPTIONS\n" + " -O0 -O1 -O2 Translator optimization level (default -O0)\n" + " -arch ARCH Force guest arch: aarch64 (alias arm64) or\n" + " riscv64 (alias rv64). When omitted the arch is\n" + " auto-detected from the executable.\n" + " -tracepc Trace each translated PC\n" + " -traceinsn Trace each guest instruction\n" + " -traceblock Trace each translated basic block\n" + " -h, --help Show this help and exit\n" + "\n" + "EXAMPLES\n" + " cfree emu hello\n" + " cfree emu -arch riscv64 hello -- foo bar\n" + " cfree emu -O2 -tracepc prog\n" + "\n" + "EXIT CODES\n" + " Returns the guest's exit code on clean exit, or 1 on internal\n" + " failure. 2 on bad command-line usage.\n"))); } static int emu_alloc_arrays(EmuOptions* o, int argc) { @@ -311,10 +314,10 @@ int driver_emu(int argc, char** argv) { opts.envp = 0; if (cfree_emu_run(compiler, &opts, &exit_code) != CFREE_OK) { - driver_errf(EMU_TOOL, "emulation of %.*s (%.*s) failed", - CFREE_SLICE_ARG(cfree_slice_cstr(eo.guest_path)), - CFREE_SLICE_ARG( - cfree_slice_cstr(emu_arch_name(eo.guest_target.arch)))); + driver_errf( + EMU_TOOL, "emulation of %.*s (%.*s) failed", + CFREE_SLICE_ARG(cfree_slice_cstr(eo.guest_path)), + CFREE_SLICE_ARG(cfree_slice_cstr(emu_arch_name(eo.guest_target.arch)))); goto out; } diff --git a/driver/env.c b/driver/env.c @@ -36,9 +36,8 @@ #include <libkern/OSCacheControl.h> #endif -#include "env.h" - #include "driver.h" +#include "env.h" /* Dual-mapping back-ends for strict W^X. Picks per-platform: * @@ -71,19 +70,18 @@ #if defined(__x86_64__) && defined(MAP_32BIT) #define DRIVER_MAP_32BIT MAP_32BIT static uintptr_t g_execmem_low_runtime_hint = 0x40000000u; -static void *execmem_low_runtime_hint(size_t size) { +static void* execmem_low_runtime_hint(size_t size) { uintptr_t p = g_execmem_low_runtime_hint; uintptr_t step = (uintptr_t)((size + 0xffffu) & ~(size_t)0xffffu); - if (step < 0x10000u) - step = 0x10000u; + if (step < 0x10000u) step = 0x10000u; g_execmem_low_runtime_hint = p + step + 0x10000u; if (g_execmem_low_runtime_hint > 0x78000000u) g_execmem_low_runtime_hint = 0x40000000u; - return (void *)p; + return (void*)p; } #else #define DRIVER_MAP_32BIT 0 -static void *execmem_low_runtime_hint(size_t size) { +static void* execmem_low_runtime_hint(size_t size) { (void)size; return NULL; } @@ -104,13 +102,13 @@ static void *execmem_low_runtime_hint(size_t size) { /* ---------------- heap (libc-backed) ---------------- */ -static void *heap_libc_alloc(CfreeHeap *h, size_t size, size_t align) { +static void* heap_libc_alloc(CfreeHeap* h, size_t size, size_t align) { (void)h; (void)align; /* malloc satisfies all max_align_t alignments */ return size ? malloc(size) : NULL; } -static void *heap_libc_realloc(CfreeHeap *h, void *p, size_t old_size, +static void* heap_libc_realloc(CfreeHeap* h, void* p, size_t old_size, size_t new_size, size_t align) { (void)h; (void)old_size; @@ -118,7 +116,7 @@ static void *heap_libc_realloc(CfreeHeap *h, void *p, size_t old_size, return realloc(p, new_size); } -static void heap_libc_free(CfreeHeap *h, void *p, size_t size) { +static void heap_libc_free(CfreeHeap* h, void* p, size_t size) { (void)h; (void)size; free(p); @@ -133,16 +131,16 @@ static CfreeHeap g_heap_libc = { /* ---------------- diag sink (stderr) ---------------- */ -static const char *diag_label(CfreeDiagKind k) { +static const char* diag_label(CfreeDiagKind k) { switch (k) { - case CFREE_DIAG_NOTE: - return "note"; - case CFREE_DIAG_WARN: - return "warning"; - case CFREE_DIAG_ERROR: - return "error"; - case CFREE_DIAG_FATAL: - return "fatal"; + case CFREE_DIAG_NOTE: + return "note"; + case CFREE_DIAG_WARN: + return "warning"; + case CFREE_DIAG_ERROR: + return "error"; + case CFREE_DIAG_FATAL: + return "fatal"; } return "diag"; } @@ -151,18 +149,18 @@ static const char *diag_label(CfreeDiagKind k) { * diag sink can resolve loc.file_id to the source's spelling (path or * memory-input label). NULL falls back to the numeric `<file:%u>` form, * which is what callers see before they've registered a compiler. */ -static CfreeCompiler *g_diag_active_compiler; +static CfreeCompiler* g_diag_active_compiler; -void driver_diag_set_compiler(CfreeCompiler *c) { g_diag_active_compiler = c; } +void driver_diag_set_compiler(CfreeCompiler* c) { g_diag_active_compiler = c; } /* driver_compiler_{new,free}: thin wrappers around the libcfree * lifecycle entries that register the active compiler with the diag sink * and clear it on free. Driver tools call these instead of the raw * cfree_* calls so a fatal diagnostic from libcfree prints the source * file name rather than a bare numeric file_id. */ -CfreeStatus driver_compiler_new(CfreeTarget t, const CfreeContext *ctx, - CfreeCompiler **out) { - CfreeCompiler *c = NULL; +CfreeStatus driver_compiler_new(CfreeTarget t, const CfreeContext* ctx, + CfreeCompiler** out) { + CfreeCompiler* c = NULL; CfreeStatus st = cfree_compiler_new(t, ctx, &c); if (st != CFREE_OK) { if (out) *out = NULL; @@ -173,24 +171,21 @@ CfreeStatus driver_compiler_new(CfreeTarget t, const CfreeContext *ctx, return CFREE_OK; } -void driver_compiler_free(CfreeCompiler *c) { - if (!c) - return; - if (g_diag_active_compiler == c) - driver_diag_set_compiler(NULL); +void driver_compiler_free(CfreeCompiler* c) { + if (!c) return; + if (g_diag_active_compiler == c) driver_diag_set_compiler(NULL); cfree_compiler_free(c); } -static void diag_stderr_emit(CfreeDiagSink *s, CfreeDiagKind k, CfreeSrcLoc loc, - const char *fmt, va_list ap) { +static void diag_stderr_emit(CfreeDiagSink* s, CfreeDiagKind k, CfreeSrcLoc loc, + const char* fmt, va_list ap) { (void)s; if (loc.file_id || loc.line) { CfreeSlice name = cfree_compiler_file_name(g_diag_active_compiler, loc.file_id); if (name.len) { - fprintf(stderr, "%.*s:%u:%u: %.*s: ", - CFREE_SLICE_ARG(name), loc.line, loc.col, - CFREE_SLICE_ARG(cfree_slice_cstr(diag_label(k)))); + fprintf(stderr, "%.*s:%u:%u: %.*s: ", CFREE_SLICE_ARG(name), loc.line, + loc.col, CFREE_SLICE_ARG(cfree_slice_cstr(diag_label(k)))); } else { fprintf(stderr, "<file:%u>:%u:%u: %.*s: ", loc.file_id, loc.line, loc.col, CFREE_SLICE_ARG(cfree_slice_cstr(diag_label(k)))); @@ -213,12 +208,9 @@ static CfreeDiagSink g_diag_stderr = { static int cfree_to_posix_prot(int prot) { int p = 0; - if (prot & CFREE_PROT_READ) - p |= PROT_READ; - if (prot & CFREE_PROT_WRITE) - p |= PROT_WRITE; - if (prot & CFREE_PROT_EXEC) - p |= PROT_EXEC; + if (prot & CFREE_PROT_READ) p |= PROT_READ; + if (prot & CFREE_PROT_WRITE) p |= PROT_WRITE; + if (prot & CFREE_PROT_EXEC) p |= PROT_EXEC; return p; } @@ -227,8 +219,8 @@ static int cfree_to_posix_prot(int prot) { * Apple stores nothing extra; Linux stores the memfd-backed write alias * size so munmap can release the runtime alias separately. */ typedef struct ExecMemToken { - void *write_addr; - void *runtime_addr; + void* write_addr; + void* runtime_addr; size_t size; } ExecMemToken; @@ -238,23 +230,21 @@ typedef struct ExecMemToken { * reservations (write == runtime) are not registered. JITs typically hold * 1-2 reservations live so a linked list keeps the lookup trivial. */ typedef struct ExecDualNode { - void *write_base; - void *runtime_base; + void* write_base; + void* runtime_base; size_t size; - struct ExecDualNode *next; + struct ExecDualNode* next; } ExecDualNode; -static ExecDualNode *g_jit_dual_map; +static ExecDualNode* g_jit_dual_map; static pthread_mutex_t g_jit_dual_map_mu = PTHREAD_MUTEX_INITIALIZER; -static void exec_dual_register(void *write_base, void *runtime_base, +static void exec_dual_register(void* write_base, void* runtime_base, size_t size) { - ExecDualNode *n; - if (write_base == runtime_base) - return; - n = (ExecDualNode *)malloc(sizeof(*n)); - if (!n) - return; /* registry is best-effort; lookup will fail open */ + ExecDualNode* n; + if (write_base == runtime_base) return; + n = (ExecDualNode*)malloc(sizeof(*n)); + if (!n) return; /* registry is best-effort; lookup will fail open */ n->write_base = write_base; n->runtime_base = runtime_base; n->size = size; @@ -264,12 +254,12 @@ static void exec_dual_register(void *write_base, void *runtime_base, pthread_mutex_unlock(&g_jit_dual_map_mu); } -static void exec_dual_unregister(void *runtime_base) { - ExecDualNode **pp; +static void exec_dual_unregister(void* runtime_base) { + ExecDualNode** pp; pthread_mutex_lock(&g_jit_dual_map_mu); for (pp = &g_jit_dual_map; *pp; pp = &(*pp)->next) { if ((*pp)->runtime_base == runtime_base) { - ExecDualNode *dead = *pp; + ExecDualNode* dead = *pp; *pp = dead->next; free(dead); break; @@ -278,14 +268,14 @@ static void exec_dual_unregister(void *runtime_base) { pthread_mutex_unlock(&g_jit_dual_map_mu); } -static int exec_dual_lookup(void *runtime_addr, size_t n, void **write_out) { - ExecDualNode *cur; +static int exec_dual_lookup(void* runtime_addr, size_t n, void** write_out) { + ExecDualNode* cur; uintptr_t a = (uintptr_t)runtime_addr; pthread_mutex_lock(&g_jit_dual_map_mu); for (cur = g_jit_dual_map; cur; cur = cur->next) { uintptr_t base = (uintptr_t)cur->runtime_base; if (a >= base && a + n <= base + cur->size) { - *write_out = (void *)((uintptr_t)cur->write_base + (a - base)); + *write_out = (void*)((uintptr_t)cur->write_base + (a - base)); pthread_mutex_unlock(&g_jit_dual_map_mu); return 0; } @@ -295,11 +285,10 @@ static int exec_dual_lookup(void *runtime_addr, size_t n, void **write_out) { } static CfreeStatus execmem_reserve_single(size_t size, - CfreeExecMemRegion *out) { - void *p = + CfreeExecMemRegion* out) { + void* p = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); - if (p == MAP_FAILED) - return CFREE_NOMEM; + if (p == MAP_FAILED) return CFREE_NOMEM; out->write = p; out->runtime = p; out->size = size; @@ -309,16 +298,15 @@ static CfreeStatus execmem_reserve_single(size_t size, #if DRIVER_DUAL_APPLE static CfreeStatus execmem_reserve_dual_apple(size_t size, - CfreeExecMemRegion *out) { + CfreeExecMemRegion* out) { /* 1) Allocate the writable backing via mmap. */ - void *w = + void* w = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); mach_vm_address_t r_addr = 0; vm_prot_t cur = 0, max = 0; kern_return_t kr; - ExecMemToken *tok; - if (w == MAP_FAILED) - return CFREE_NOMEM; + ExecMemToken* tok; + if (w == MAP_FAILED) return CFREE_NOMEM; /* 2) Create an alias mapping. copy=FALSE makes the new VA share the * same physical pages. We request VM_INHERIT_NONE so child @@ -335,26 +323,26 @@ static CfreeStatus execmem_reserve_dual_apple(size_t size, /* 3) Drop the runtime alias to PROT_READ until protect() flips it. * No window of writable+executable: the write alias has W (no X), * the runtime alias has R only (no W, no X yet). */ - if (mprotect((void *)(uintptr_t)r_addr, size, PROT_READ) != 0) { - munmap((void *)(uintptr_t)r_addr, size); + if (mprotect((void*)(uintptr_t)r_addr, size, PROT_READ) != 0) { + munmap((void*)(uintptr_t)r_addr, size); munmap(w, size); return CFREE_ERR; } - tok = (ExecMemToken *)malloc(sizeof(*tok)); + tok = (ExecMemToken*)malloc(sizeof(*tok)); if (!tok) { - munmap((void *)(uintptr_t)r_addr, size); + munmap((void*)(uintptr_t)r_addr, size); munmap(w, size); return CFREE_NOMEM; } tok->write_addr = w; - tok->runtime_addr = (void *)(uintptr_t)r_addr; + tok->runtime_addr = (void*)(uintptr_t)r_addr; tok->size = size; - exec_dual_register(w, (void *)(uintptr_t)r_addr, size); + exec_dual_register(w, (void*)(uintptr_t)r_addr, size); out->write = w; - out->runtime = (void *)(uintptr_t)r_addr; + out->runtime = (void*)(uintptr_t)r_addr; out->size = size; out->token = tok; return CFREE_OK; @@ -363,22 +351,21 @@ static CfreeStatus execmem_reserve_dual_apple(size_t size, #if DRIVER_DUAL_LINUX static CfreeStatus execmem_reserve_dual_linux(size_t size, - CfreeExecMemRegion *out) { + CfreeExecMemRegion* out) { /* memfd_create gives us an anonymous fd; two mmaps of that fd alias * the same physical pages at distinct VAs. */ int fd = (int)syscall(SYS_memfd_create, "cfree-jit", 0u); - void *w; - void *r; - ExecMemToken *tok; - if (fd < 0) - return CFREE_ERR; + void* w; + void* r; + ExecMemToken* tok; + if (fd < 0) return CFREE_ERR; if (ftruncate(fd, (off_t)size) != 0) { close(fd); return CFREE_ERR; } - w = mmap(NULL, size, PROT_READ | PROT_WRITE, - MAP_SHARED | DRIVER_MAP_32BIT, fd, 0); + w = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED | DRIVER_MAP_32BIT, + fd, 0); if (w == MAP_FAILED) { close(fd); return CFREE_NOMEM; @@ -393,7 +380,7 @@ static CfreeStatus execmem_reserve_dual_linux(size_t size, /* The fd is no longer needed once both aliases are mapped. */ close(fd); - tok = (ExecMemToken *)malloc(sizeof(*tok)); + tok = (ExecMemToken*)malloc(sizeof(*tok)); if (!tok) { munmap(r, size); munmap(w, size); @@ -413,11 +400,10 @@ static CfreeStatus execmem_reserve_dual_linux(size_t size, } #endif -static CfreeStatus execmem_reserve(void *user, size_t size, int prot, - CfreeExecMemRegion *out) { +static CfreeStatus execmem_reserve(void* user, size_t size, int prot, + CfreeExecMemRegion* out) { (void)user; - if (!out || !size) - return CFREE_INVALID; + if (!out || !size) return CFREE_INVALID; if (prot & CFREE_PROT_EXEC) { #if DRIVER_DUAL_APPLE return execmem_reserve_dual_apple(size, out); @@ -432,25 +418,23 @@ static CfreeStatus execmem_reserve(void *user, size_t size, int prot, return execmem_reserve_single(size, out); } -static CfreeStatus execmem_protect(void *user, void *addr, size_t size, +static CfreeStatus execmem_protect(void* user, void* addr, size_t size, int prot) { (void)user; return mprotect(addr, size, cfree_to_posix_prot(prot)) == 0 ? CFREE_OK : CFREE_ERR; } -static void execmem_release(void *user, CfreeExecMemRegion *region) { +static void execmem_release(void* user, CfreeExecMemRegion* region) { (void)user; - if (!region || !region->size) - return; + if (!region || !region->size) return; if (region->token) { - ExecMemToken *tok = (ExecMemToken *)region->token; + ExecMemToken* tok = (ExecMemToken*)region->token; if (tok->runtime_addr && tok->runtime_addr != tok->write_addr) { exec_dual_unregister(tok->runtime_addr); munmap(tok->runtime_addr, tok->size); } - if (tok->write_addr) - munmap(tok->write_addr, tok->size); + if (tok->write_addr) munmap(tok->write_addr, tok->size); free(tok); } else if (region->write) { munmap(region->write, region->size); @@ -461,7 +445,7 @@ static void execmem_release(void *user, CfreeExecMemRegion *region) { region->token = NULL; } -static void execmem_flush_icache(void *user, void *addr, size_t size) { +static void execmem_flush_icache(void* user, void* addr, size_t size) { (void)user; #if defined(__aarch64__) || defined(__arm__) || defined(__riscv) /* __builtin___clear_cache lowers to the right thing per arch: @@ -472,7 +456,7 @@ static void execmem_flush_icache(void *user, void *addr, size_t size) { #if defined(__riscv) __asm__ __volatile__("fence.i" ::: "memory"); #endif - __builtin___clear_cache((char *)addr, (char *)addr + size); + __builtin___clear_cache((char*)addr, (char*)addr + size); #else (void)addr; (void)size; @@ -500,7 +484,7 @@ static CfreeExecMem g_execmem_posix; /* page_size set in driver_env_init */ * signals_uninstall after restoring SIG_DFL. */ static CfreeDbgSignalOps g_dbg_ops; static int g_dbg_ops_set; -static void *g_dbg_session; +static void* g_dbg_session; static pthread_t g_dbg_worker_tid; static int g_dbg_worker_tid_valid; @@ -521,23 +505,22 @@ static __thread int g_guard_armed; typedef struct DbgThread { pthread_t tid; - void (*fn)(void *); - void *arg; + void (*fn)(void*); + void* arg; } DbgThread; -static void *dbg_thread_trampoline(void *p) { - DbgThread *t = (DbgThread *)p; +static void* dbg_thread_trampoline(void* p) { + DbgThread* t = (DbgThread*)p; t->fn(t->arg); return NULL; } -static CfreeStatus dbg_thread_start(void *user, void (*fn)(void *), void *arg, - void **thread_out) { - DbgThread *t; +static CfreeStatus dbg_thread_start(void* user, void (*fn)(void*), void* arg, + void** thread_out) { + DbgThread* t; (void)user; - t = (DbgThread *)malloc(sizeof(*t)); - if (!t) - return CFREE_NOMEM; + t = (DbgThread*)malloc(sizeof(*t)); + if (!t) return CFREE_NOMEM; t->fn = fn; t->arg = arg; if (pthread_create(&t->tid, NULL, dbg_thread_trampoline, t) != 0) { @@ -550,21 +533,19 @@ static CfreeStatus dbg_thread_start(void *user, void (*fn)(void *), void *arg, return CFREE_OK; } -static void dbg_thread_join(void *user, void *thread) { - DbgThread *t = (DbgThread *)thread; +static void dbg_thread_join(void* user, void* thread) { + DbgThread* t = (DbgThread*)thread; (void)user; - if (!t) - return; + if (!t) return; pthread_join(t->tid, NULL); g_dbg_worker_tid_valid = 0; free(t); } -static CfreeStatus dbg_thread_interrupt(void *user, void *thread) { - DbgThread *t = (DbgThread *)thread; +static CfreeStatus dbg_thread_interrupt(void* user, void* thread) { + DbgThread* t = (DbgThread*)thread; (void)user; - if (!t) - return CFREE_INVALID; + if (!t) return CFREE_INVALID; return pthread_kill(t->tid, DBG_INTERRUPT_SIGNO) == 0 ? CFREE_OK : CFREE_ERR; } @@ -576,12 +557,11 @@ typedef struct DbgEvent { int signaled; } DbgEvent; -static CfreeStatus dbg_event_new(void *user, void **event_out) { - DbgEvent *e; +static CfreeStatus dbg_event_new(void* user, void** event_out) { + DbgEvent* e; (void)user; - e = (DbgEvent *)malloc(sizeof(*e)); - if (!e) - return CFREE_NOMEM; + e = (DbgEvent*)malloc(sizeof(*e)); + if (!e) return CFREE_NOMEM; if (pthread_mutex_init(&e->mu, NULL) != 0) { free(e); return CFREE_ERR; @@ -596,22 +576,20 @@ static CfreeStatus dbg_event_new(void *user, void **event_out) { return CFREE_OK; } -static void dbg_event_free(void *user, void *ev) { - DbgEvent *e = (DbgEvent *)ev; +static void dbg_event_free(void* user, void* ev) { + DbgEvent* e = (DbgEvent*)ev; (void)user; - if (!e) - return; + if (!e) return; pthread_cond_destroy(&e->cv); pthread_mutex_destroy(&e->mu); free(e); } -static CfreeStatus dbg_event_wait(void *user, void *ev) { - DbgEvent *e = (DbgEvent *)ev; +static CfreeStatus dbg_event_wait(void* user, void* ev) { + DbgEvent* e = (DbgEvent*)ev; (void)user; pthread_mutex_lock(&e->mu); - while (!e->signaled) - pthread_cond_wait(&e->cv, &e->mu); + while (!e->signaled) pthread_cond_wait(&e->cv, &e->mu); e->signaled = 0; pthread_mutex_unlock(&e->mu); return CFREE_OK; @@ -620,8 +598,8 @@ static CfreeStatus dbg_event_wait(void *user, void *ev) { /* pthread_cond_signal is not formally async-signal-safe per POSIX, but * it is in practice on glibc and Apple libc when callers manage the * signal mask carefully. LLDB and rr rely on the same pattern. */ -static CfreeStatus dbg_event_signal(void *user, void *ev) { - DbgEvent *e = (DbgEvent *)ev; +static CfreeStatus dbg_event_signal(void* user, void* ev) { + DbgEvent* e = (DbgEvent*)ev; (void)user; pthread_mutex_lock(&e->mu); e->signaled = 1; @@ -630,8 +608,8 @@ static CfreeStatus dbg_event_signal(void *user, void *ev) { return CFREE_OK; } -static CfreeStatus dbg_event_reset(void *user, void *ev) { - DbgEvent *e = (DbgEvent *)ev; +static CfreeStatus dbg_event_reset(void* user, void* ev) { + DbgEvent* e = (DbgEvent*)ev; (void)user; pthread_mutex_lock(&e->mu); e->signaled = 0; @@ -644,42 +622,38 @@ static CfreeStatus dbg_event_reset(void *user, void *ev) { /* Marshal ucontext_t <-> CfreeUnwindFrame. Register slots use each * architecture's DWARF numbering. */ #if defined(__aarch64__) && defined(__APPLE__) -static void dbg_ucontext_to_frame(const ucontext_t *uc, CfreeUnwindFrame *f) { - const struct __darwin_arm_thread_state64 *ss = &uc->uc_mcontext->__ss; +static void dbg_ucontext_to_frame(const ucontext_t* uc, CfreeUnwindFrame* f) { + const struct __darwin_arm_thread_state64* ss = &uc->uc_mcontext->__ss; int i; - for (i = 0; i < 29; ++i) - f->regs[i] = ss->__x[i]; + for (i = 0; i < 29; ++i) f->regs[i] = ss->__x[i]; f->regs[29] = (uint64_t)ss->__fp; f->regs[30] = (uint64_t)ss->__lr; f->regs[31] = (uint64_t)ss->__sp; f->pc = (uint64_t)ss->__pc; f->cfa = (uint64_t)ss->__fp; /* DWARF CFI refines this in the session */ } -static void dbg_frame_to_ucontext(const CfreeUnwindFrame *f, ucontext_t *uc) { - struct __darwin_arm_thread_state64 *ss = &uc->uc_mcontext->__ss; +static void dbg_frame_to_ucontext(const CfreeUnwindFrame* f, ucontext_t* uc) { + struct __darwin_arm_thread_state64* ss = &uc->uc_mcontext->__ss; int i; - for (i = 0; i < 29; ++i) - ss->__x[i] = f->regs[i]; + for (i = 0; i < 29; ++i) ss->__x[i] = f->regs[i]; ss->__fp = f->regs[29]; ss->__lr = f->regs[30]; ss->__sp = f->regs[31]; ss->__pc = f->pc; } #elif defined(__aarch64__) && defined(__linux__) -static void dbg_ucontext_to_frame(const ucontext_t *uc, CfreeUnwindFrame *f) { - const mcontext_t *mc = &uc->uc_mcontext; +static void dbg_ucontext_to_frame(const ucontext_t* uc, CfreeUnwindFrame* f) { + const mcontext_t* mc = &uc->uc_mcontext; int i; - for (i = 0; i < 31; ++i) - f->regs[i] = mc->regs[i]; + for (i = 0; i < 31; ++i) f->regs[i] = mc->regs[i]; f->regs[31] = mc->sp; f->pc = mc->pc; f->cfa = mc->regs[29]; /* fp; CFI refines */ } -static void dbg_frame_to_ucontext(const CfreeUnwindFrame *f, ucontext_t *uc) { - mcontext_t *mc = &uc->uc_mcontext; +static void dbg_frame_to_ucontext(const CfreeUnwindFrame* f, ucontext_t* uc) { + mcontext_t* mc = &uc->uc_mcontext; int i; - for (i = 0; i < 31; ++i) - mc->regs[i] = f->regs[i]; + for (i = 0; i < 31; ++i) mc->regs[i] = f->regs[i]; mc->sp = f->regs[31]; mc->pc = f->pc; } @@ -689,25 +663,23 @@ static void dbg_frame_to_ucontext(const CfreeUnwindFrame *f, ucontext_t *uc) { * tp, t0..t2, s0/fp, s1, a0..a7, s2..s11, t3..t6). DWARF numbering * assigns 0..31 to x0..x31, so we marshal pc separately and fold x1..x31 * into f->regs[1..31], leaving f->regs[0] as the constant zero. */ -static void dbg_ucontext_to_frame(const ucontext_t *uc, CfreeUnwindFrame *f) { - const mcontext_t *mc = &uc->uc_mcontext; +static void dbg_ucontext_to_frame(const ucontext_t* uc, CfreeUnwindFrame* f) { + const mcontext_t* mc = &uc->uc_mcontext; int i; f->regs[0] = 0; - for (i = 1; i < 32; ++i) - f->regs[i] = (uint64_t)mc->__gregs[i]; + for (i = 1; i < 32; ++i) f->regs[i] = (uint64_t)mc->__gregs[i]; f->pc = (uint64_t)mc->__gregs[0]; f->cfa = (uint64_t)mc->__gregs[8]; /* s0/fp; CFI refines */ } -static void dbg_frame_to_ucontext(const CfreeUnwindFrame *f, ucontext_t *uc) { - mcontext_t *mc = &uc->uc_mcontext; +static void dbg_frame_to_ucontext(const CfreeUnwindFrame* f, ucontext_t* uc) { + mcontext_t* mc = &uc->uc_mcontext; int i; - for (i = 1; i < 32; ++i) - mc->__gregs[i] = (unsigned long)f->regs[i]; + for (i = 1; i < 32; ++i) mc->__gregs[i] = (unsigned long)f->regs[i]; mc->__gregs[0] = (unsigned long)f->pc; } #elif defined(__x86_64__) && defined(__linux__) -static void dbg_ucontext_to_frame(const ucontext_t *uc, CfreeUnwindFrame *f) { - const greg_t *g = uc->uc_mcontext.gregs; +static void dbg_ucontext_to_frame(const ucontext_t* uc, CfreeUnwindFrame* f) { + const greg_t* g = uc->uc_mcontext.gregs; memset(f, 0, sizeof(*f)); f->regs[0] = (uint64_t)g[REG_RAX]; f->regs[1] = (uint64_t)g[REG_RDX]; @@ -729,8 +701,8 @@ static void dbg_ucontext_to_frame(const ucontext_t *uc, CfreeUnwindFrame *f) { f->pc = (uint64_t)g[REG_RIP]; f->cfa = (uint64_t)g[REG_RSP]; } -static void dbg_frame_to_ucontext(const CfreeUnwindFrame *f, ucontext_t *uc) { - greg_t *g = uc->uc_mcontext.gregs; +static void dbg_frame_to_ucontext(const CfreeUnwindFrame* f, ucontext_t* uc) { + greg_t* g = uc->uc_mcontext.gregs; g[REG_RAX] = (greg_t)f->regs[0]; g[REG_RDX] = (greg_t)f->regs[1]; g[REG_RCX] = (greg_t)f->regs[2]; @@ -750,11 +722,12 @@ static void dbg_frame_to_ucontext(const CfreeUnwindFrame *f, ucontext_t *uc) { g[REG_RIP] = (greg_t)f->pc; } #else -#error "cfree dbg v1 supports only aarch64 on macOS/Linux, riscv64 on Linux, or x86_64 on Linux" +#error \ + "cfree dbg v1 supports only aarch64 on macOS/Linux, riscv64 on Linux, or x86_64 on Linux" #endif -static void dbg_signal_handler(int signo, siginfo_t *si, void *ucv) { - ucontext_t *uc = (ucontext_t *)ucv; +static void dbg_signal_handler(int signo, siginfo_t* si, void* ucv) { + ucontext_t* uc = (ucontext_t*)ucv; CfreeUnwindFrame frame; CfreeStatus rc; (void)si; @@ -800,14 +773,12 @@ static void dbg_signal_handler(int signo, siginfo_t *si, void *ucv) { dbg_frame_to_ucontext(&frame, uc); } -static CfreeStatus dbg_signals_install(void *user, - const CfreeDbgSignalOps *ops, - void *session) { +static CfreeStatus dbg_signals_install(void* user, const CfreeDbgSignalOps* ops, + void* session) { struct sigaction sa; int i; (void)user; - if (g_dbg_installed) - return CFREE_ERR; + if (g_dbg_installed) return CFREE_ERR; g_dbg_ops = *ops; g_dbg_ops_set = 1; g_dbg_session = session; @@ -818,8 +789,7 @@ static CfreeStatus dbg_signals_install(void *user, sigemptyset(&sa.sa_mask); /* Block our signal cohort during the handler so nested faults from * the cond-wait critical region don't recurse. */ - for (i = 0; i < DBG_NSIGS; ++i) - sigaddset(&sa.sa_mask, g_dbg_signos[i]); + for (i = 0; i < DBG_NSIGS; ++i) sigaddset(&sa.sa_mask, g_dbg_signos[i]); for (i = 0; i < DBG_NSIGS; ++i) { if (sigaction(g_dbg_signos[i], &sa, &g_dbg_prev_sa[i]) != 0) { @@ -837,11 +807,10 @@ static CfreeStatus dbg_signals_install(void *user, return CFREE_OK; } -static void dbg_signals_uninstall(void *user) { +static void dbg_signals_uninstall(void* user) { int i; (void)user; - if (!g_dbg_installed) - return; + if (!g_dbg_installed) return; for (i = 0; i < DBG_NSIGS; ++i) sigaction(g_dbg_signos[i], &g_dbg_prev_sa[i], NULL); g_dbg_installed = 0; @@ -859,11 +828,10 @@ static size_t dbg_page_ceil(size_t v, size_t pg) { } #endif -static CfreeStatus dbg_code_write_begin(void *user, void *runtime_addr, - size_t n, void **write_out) { +static CfreeStatus dbg_code_write_begin(void* user, void* runtime_addr, + size_t n, void** write_out) { (void)user; - if (!runtime_addr || !n || !write_out) - return CFREE_INVALID; + if (!runtime_addr || !n || !write_out) return CFREE_INVALID; #if defined(__APPLE__) /* Dual-mapped reservation (mach_vm_remap): the write alias is a * separate VA already RW. Translate via the registry; no protect flip @@ -879,9 +847,8 @@ static CfreeStatus dbg_code_write_begin(void *user, void *runtime_addr, /* Linux dual-mapping uses memfd: write alias and runtime alias have * distinct VAs. Prefer the alias lookup; fall back to a transient * mprotect of the runtime alias for single-mapping reservations. */ - if (exec_dual_lookup(runtime_addr, n, write_out) == 0) - return CFREE_OK; - if (mprotect((void *)base, span, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) + if (exec_dual_lookup(runtime_addr, n, write_out) == 0) return CFREE_OK; + if (mprotect((void*)base, span, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) return CFREE_ERR; *write_out = runtime_addr; return CFREE_OK; @@ -891,37 +858,37 @@ static CfreeStatus dbg_code_write_begin(void *user, void *runtime_addr, #endif } -static void dbg_code_write_end(void *user, void *runtime_addr, size_t n) { +static void dbg_code_write_end(void* user, void* runtime_addr, size_t n) { (void)user; #if defined(__APPLE__) (void)runtime_addr; (void)n; #elif defined(__linux__) { - void *w; + void* w; size_t pg = driver_host_page_size(); uintptr_t a = (uintptr_t)runtime_addr; uintptr_t base = dbg_page_floor(a, pg); size_t span = dbg_page_ceil((a - base) + n, pg); if (exec_dual_lookup(runtime_addr, n, &w) == 0) return; /* dual: nothing to flip back */ - mprotect((void *)base, span, PROT_READ | PROT_EXEC); + mprotect((void*)base, span, PROT_READ | PROT_EXEC); } #endif } -static void dbg_flush_icache(void *user, void *runtime_addr, size_t n) { +static void dbg_flush_icache(void* user, void* runtime_addr, size_t n) { (void)user; #if defined(__APPLE__) && defined(__aarch64__) sys_icache_invalidate(runtime_addr, n); #else - __builtin___clear_cache((char *)runtime_addr, (char *)runtime_addr + n); + __builtin___clear_cache((char*)runtime_addr, (char*)runtime_addr + n); #endif } /* --- guarded copy --- */ -static CfreeStatus dbg_guarded_copy(void *user, void *dst, const void *src, +static CfreeStatus dbg_guarded_copy(void* user, void* dst, const void* src, size_t n) { (void)user; if (sigsetjmp(g_guard_buf, 1) != 0) { @@ -936,7 +903,7 @@ static CfreeStatus dbg_guarded_copy(void *user, void *dst, const void *src, static __thread sigjmp_buf g_dbg_abort_buf; -static int dbg_call_with_catch(void *user, void (*fn)(void *), void *arg) { +static int dbg_call_with_catch(void* user, void (*fn)(void*), void* arg) { (void)user; if (sigsetjmp(g_dbg_abort_buf, 1) == 0) { fn(arg); @@ -945,7 +912,7 @@ static int dbg_call_with_catch(void *user, void (*fn)(void *), void *arg) { return 1; } -static void dbg_thread_abort(void *user) { +static void dbg_thread_abort(void* user) { (void)user; siglongjmp(g_dbg_abort_buf, 1); } @@ -963,49 +930,45 @@ static CfreeDbgOs g_dbg_os_posix; * x0 = ctx and expects back an x0 = TLS block. We satisfy this by * making `get_block` the first field. */ typedef struct JitTlsCtx { - void *(*get_block)(void *ctx); /* first; matches tlv_thunk's expectation */ + void* (*get_block)(void* ctx); /* first; matches tlv_thunk's expectation */ pthread_key_t key; size_t image_size; size_t image_filesz; size_t align; - void *init_bytes; /* heap-owned copy of init bytes, or NULL if all BSS */ + void* init_bytes; /* heap-owned copy of init bytes, or NULL if all BSS */ } JitTlsCtx; -static void jit_tls_thread_dtor(void *block) { +static void jit_tls_thread_dtor(void* block) { /* POSIX pthread_key destructor: called when a thread that touched the * TLV exits. `block` is the void* set by pthread_setspecific, never * NULL (POSIX skips the destructor if it was NULL). */ free(block); } -static void *jit_tls_alloc_block(JitTlsCtx *ctx) { +static void* jit_tls_alloc_block(JitTlsCtx* ctx) { /* macOS aligned_alloc requires alignment >= sizeof(void*); bump * smaller request alignments up. Size must be a multiple of * alignment too. */ - size_t a = ctx->align ? ctx->align : sizeof(void *); - if (a < sizeof(void *)) - a = sizeof(void *); + size_t a = ctx->align ? ctx->align : sizeof(void*); + if (a < sizeof(void*)) a = sizeof(void*); size_t sz = (ctx->image_size + a - 1u) & ~(a - 1u); - if (sz == 0) - sz = a; /* zero-size TLS image still needs a non-NULL block */ - void *block = aligned_alloc(a, sz); - if (!block) - return NULL; + if (sz == 0) sz = a; /* zero-size TLS image still needs a non-NULL block */ + void* block = aligned_alloc(a, sz); + if (!block) return NULL; if (ctx->image_filesz && ctx->init_bytes) memcpy(block, ctx->init_bytes, ctx->image_filesz); if (ctx->image_size > ctx->image_filesz) - memset((char *)block + ctx->image_filesz, 0, + memset((char*)block + ctx->image_filesz, 0, ctx->image_size - ctx->image_filesz); return block; } /* The thunk-callable entry; the asm trampoline calls this with x0=ctx * and expects x0 back = TLS block base. */ -static void *jit_tls_get_block(void *ctx_v) { - JitTlsCtx *ctx = (JitTlsCtx *)ctx_v; - void *block = pthread_getspecific(ctx->key); - if (block) - return block; +static void* jit_tls_get_block(void* ctx_v) { + JitTlsCtx* ctx = (JitTlsCtx*)ctx_v; + void* block = pthread_getspecific(ctx->key); + if (block) return block; block = jit_tls_alloc_block(ctx); if (!block) { /* OOM inside a TLV access has no clean recovery: the thunk's caller @@ -1022,17 +985,16 @@ static void *jit_tls_get_block(void *ctx_v) { return block; } -static void *jit_tls_ctx_new(void *user, const void *init_bytes, +static void* jit_tls_ctx_new(void* user, const void* init_bytes, size_t image_filesz, size_t image_size, size_t align) { (void)user; - JitTlsCtx *ctx = (JitTlsCtx *)malloc(sizeof(*ctx)); - if (!ctx) - return NULL; + JitTlsCtx* ctx = (JitTlsCtx*)malloc(sizeof(*ctx)); + if (!ctx) return NULL; ctx->get_block = jit_tls_get_block; ctx->image_size = image_size; ctx->image_filesz = image_filesz; - ctx->align = align ? align : sizeof(void *); + ctx->align = align ? align : sizeof(void*); ctx->init_bytes = NULL; if (image_filesz && init_bytes) { ctx->init_bytes = malloc(image_filesz); @@ -1050,17 +1012,16 @@ static void *jit_tls_ctx_new(void *user, const void *init_bytes, return ctx; } -static void jit_tls_ctx_destroy(void *user, void *ctx_v) { - JitTlsCtx *ctx = (JitTlsCtx *)ctx_v; +static void jit_tls_ctx_destroy(void* user, void* ctx_v) { + JitTlsCtx* ctx = (JitTlsCtx*)ctx_v; (void)user; - if (!ctx) - return; + if (!ctx) return; /* Free the calling thread's block (POSIX won't run our destructor for * it; pthread_key_delete also doesn't fire destructors for live * threads). Other threads' blocks are reaped when those threads * exit, since their stored pointers remain reachable via the key * value already snapshotted into TSD before delete. */ - void *my_block = pthread_getspecific(ctx->key); + void* my_block = pthread_getspecific(ctx->key); if (my_block) { pthread_setspecific(ctx->key, NULL); free(my_block); @@ -1076,17 +1037,16 @@ static CfreeJitTls g_jit_tls_posix; typedef struct DriverFdWriter { CfreeWriter base; /* must be first; libcfree reads via this */ - CfreeHeap *heap; + CfreeHeap* heap; int fd; CfreeStatus status; uint64_t pos; } DriverFdWriter; -static CfreeStatus fdw_write(CfreeWriter *w, const void *data, size_t n) { - DriverFdWriter *fw = (DriverFdWriter *)w; - const unsigned char *p = (const unsigned char *)data; - if (fw->status != CFREE_OK) - return fw->status; +static CfreeStatus fdw_write(CfreeWriter* w, const void* data, size_t n) { + DriverFdWriter* fw = (DriverFdWriter*)w; + const unsigned char* p = (const unsigned char*)data; + if (fw->status != CFREE_OK) return fw->status; while (n > 0) { ssize_t k = write(fw->fd, p, n); if (k < 0) { @@ -1100,10 +1060,9 @@ static CfreeStatus fdw_write(CfreeWriter *w, const void *data, size_t n) { return CFREE_OK; } -static CfreeStatus fdw_seek(CfreeWriter *w, uint64_t off) { - DriverFdWriter *fw = (DriverFdWriter *)w; - if (fw->status != CFREE_OK) - return fw->status; +static CfreeStatus fdw_seek(CfreeWriter* w, uint64_t off) { + DriverFdWriter* fw = (DriverFdWriter*)w; + if (fw->status != CFREE_OK) return fw->status; if (lseek(fw->fd, (off_t)off, SEEK_SET) < 0) { fw->status = CFREE_IO; return CFREE_IO; @@ -1112,23 +1071,21 @@ static CfreeStatus fdw_seek(CfreeWriter *w, uint64_t off) { return CFREE_OK; } -static uint64_t fdw_tell(CfreeWriter *w) { return ((DriverFdWriter *)w)->pos; } -static CfreeStatus fdw_status(CfreeWriter *w) { - return ((DriverFdWriter *)w)->status; +static uint64_t fdw_tell(CfreeWriter* w) { return ((DriverFdWriter*)w)->pos; } +static CfreeStatus fdw_status(CfreeWriter* w) { + return ((DriverFdWriter*)w)->status; } -static void fdw_close(CfreeWriter *w) { - DriverFdWriter *fw = (DriverFdWriter *)w; - if (fw->fd >= 0) - close(fw->fd); +static void fdw_close(CfreeWriter* w) { + DriverFdWriter* fw = (DriverFdWriter*)w; + if (fw->fd >= 0) close(fw->fd); fw->heap->free(fw->heap, fw, sizeof(*fw)); } -static CfreeWriter *driver_writer_fd(CfreeHeap *h, int fd) { - DriverFdWriter *fw = - (DriverFdWriter *)h->alloc(h, sizeof(*fw), _Alignof(DriverFdWriter)); - if (!fw) - return NULL; +static CfreeWriter* driver_writer_fd(CfreeHeap* h, int fd) { + DriverFdWriter* fw = + (DriverFdWriter*)h->alloc(h, sizeof(*fw), _Alignof(DriverFdWriter)); + if (!fw) return NULL; fw->base.write = fdw_write; fw->base.seek = fdw_seek; fw->base.tell = fdw_tell; @@ -1147,13 +1104,13 @@ static CfreeWriter *driver_writer_fd(CfreeHeap *h, int fd) { * to fd 1 bypasses that buffer entirely). */ typedef struct DriverStdioWriter { CfreeWriter base; - CfreeHeap *heap; - FILE *fp; + CfreeHeap* heap; + FILE* fp; CfreeStatus status; } DriverStdioWriter; -static CfreeStatus stdio_w_write(CfreeWriter *w, const void *data, size_t n) { - DriverStdioWriter *sw = (DriverStdioWriter *)w; +static CfreeStatus stdio_w_write(CfreeWriter* w, const void* data, size_t n) { + DriverStdioWriter* sw = (DriverStdioWriter*)w; if (n) { size_t got = fwrite(data, 1, n, sw->fp); if (got != n) { @@ -1163,31 +1120,29 @@ static CfreeStatus stdio_w_write(CfreeWriter *w, const void *data, size_t n) { } return CFREE_OK; } -static CfreeStatus stdio_w_seek(CfreeWriter *w, uint64_t off) { - DriverStdioWriter *sw = (DriverStdioWriter *)w; +static CfreeStatus stdio_w_seek(CfreeWriter* w, uint64_t off) { + DriverStdioWriter* sw = (DriverStdioWriter*)w; return fseek(sw->fp, (long)off, SEEK_SET) == 0 ? CFREE_OK : CFREE_IO; } -static uint64_t stdio_w_tell(CfreeWriter *w) { - long t = ftell(((DriverStdioWriter *)w)->fp); +static uint64_t stdio_w_tell(CfreeWriter* w) { + long t = ftell(((DriverStdioWriter*)w)->fp); return t < 0 ? 0u : (uint64_t)t; } -static CfreeStatus stdio_w_status(CfreeWriter *w) { - DriverStdioWriter *sw = (DriverStdioWriter *)w; - if (sw->status != CFREE_OK) - return sw->status; +static CfreeStatus stdio_w_status(CfreeWriter* w) { + DriverStdioWriter* sw = (DriverStdioWriter*)w; + if (sw->status != CFREE_OK) return sw->status; return ferror(sw->fp) ? CFREE_IO : CFREE_OK; } -static void stdio_w_close(CfreeWriter *w) { - DriverStdioWriter *sw = (DriverStdioWriter *)w; +static void stdio_w_close(CfreeWriter* w) { + DriverStdioWriter* sw = (DriverStdioWriter*)w; fflush(sw->fp); /* flush but do not close stdout */ sw->heap->free(sw->heap, sw, sizeof(*sw)); } -CfreeWriter *driver_stdout_writer(DriverEnv *e) { - DriverStdioWriter *sw = (DriverStdioWriter *)e->heap->alloc( +CfreeWriter* driver_stdout_writer(DriverEnv* e) { + DriverStdioWriter* sw = (DriverStdioWriter*)e->heap->alloc( e->heap, sizeof(*sw), _Alignof(DriverStdioWriter)); - if (!sw) - return NULL; + if (!sw) return NULL; sw->base.write = stdio_w_write; sw->base.seek = stdio_w_seek; sw->base.tell = stdio_w_tell; @@ -1201,18 +1156,17 @@ CfreeWriter *driver_stdout_writer(DriverEnv *e) { /* ---------------- file_io (POSIX) ---------------- */ -static CfreeStatus posix_read_all(void *user, const char *path, - CfreeFileData *out) { - DriverEnv *env = (DriverEnv *)user; +static CfreeStatus posix_read_all(void* user, const char* path, + CfreeFileData* out) { + DriverEnv* env = (DriverEnv*)user; int fd; struct stat sb; size_t size; size_t got; - void *buf; + void* buf; fd = open(path, O_RDONLY); - if (fd < 0) - return CFREE_NOT_FOUND; + if (fd < 0) return CFREE_NOT_FOUND; if (fstat(fd, &sb) < 0) { close(fd); return CFREE_IO; @@ -1226,7 +1180,7 @@ static CfreeStatus posix_read_all(void *user, const char *path, got = 0; while (got < size) { - ssize_t n = read(fd, (unsigned char *)buf + got, size - got); + ssize_t n = read(fd, (unsigned char*)buf + got, size - got); if (n <= 0) { env->heap->free(env->heap, buf, size); close(fd); @@ -1236,28 +1190,26 @@ static CfreeStatus posix_read_all(void *user, const char *path, } close(fd); - out->data = (const uint8_t *)buf; + out->data = (const uint8_t*)buf; out->size = size; out->token = buf; return CFREE_OK; } -static void posix_release(void *user, CfreeFileData *d) { - DriverEnv *env = (DriverEnv *)user; - if (d->token) - env->heap->free(env->heap, d->token, d->size); +static void posix_release(void* user, CfreeFileData* d) { + DriverEnv* env = (DriverEnv*)user; + if (d->token) env->heap->free(env->heap, d->token, d->size); d->data = NULL; d->size = 0; d->token = NULL; } -static CfreeStatus posix_open_writer(void *user, const char *path, - CfreeWriter **out) { - DriverEnv *env = (DriverEnv *)user; +static CfreeStatus posix_open_writer(void* user, const char* path, + CfreeWriter** out) { + DriverEnv* env = (DriverEnv*)user; int fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0644); - CfreeWriter *w; - if (fd < 0) - return CFREE_IO; + CfreeWriter* w; + if (fd < 0) return CFREE_IO; w = driver_writer_fd(env->heap, fd); if (!w) { close(fd); @@ -1269,7 +1221,7 @@ static CfreeStatus posix_open_writer(void *user, const char *path, /* ---------------- env wiring ---------------- */ -void driver_env_init(DriverEnv *e) { +void driver_env_init(DriverEnv* e) { e->heap = &g_heap_libc; e->diag = &g_diag_stderr; e->file_io.read_all = posix_read_all; @@ -1316,9 +1268,9 @@ void driver_env_init(DriverEnv *e) { * If neither is set or the env value doesn't parse, advertise -1 ("no * clock") and pp falls back to C11 placeholders. */ { - const char *sde = getenv("SOURCE_DATE_EPOCH"); + const char* sde = getenv("SOURCE_DATE_EPOCH"); if (sde && *sde) { - char *endp = NULL; + char* endp = NULL; long long v = strtoll(sde, &endp, 10); e->now = (endp != sde && v >= 0) ? (int64_t)v : (int64_t)-1; } else { @@ -1328,12 +1280,12 @@ void driver_env_init(DriverEnv *e) { } } -void driver_env_fini(DriverEnv *e) { +void driver_env_fini(DriverEnv* e) { /* Singletons; nothing to release. */ (void)e; } -CfreeContext driver_env_to_context(const DriverEnv *e) { +CfreeContext driver_env_to_context(const DriverEnv* e) { CfreeContext c; c.heap = e->heap; c.file_io = &e->file_io; @@ -1343,14 +1295,14 @@ CfreeContext driver_env_to_context(const DriverEnv *e) { return c; } -CfreeJitHost driver_env_to_jit_host(const DriverEnv *e) { +CfreeJitHost driver_env_to_jit_host(const DriverEnv* e) { CfreeJitHost h; h.execmem = e->execmem; h.tls = e->jit_tls; return h; } -CfreeDbgHost driver_env_to_dbg_host(const DriverEnv *e) { +CfreeDbgHost driver_env_to_dbg_host(const DriverEnv* e) { CfreeDbgHost h; h.os = e->dbg_os; return h; @@ -1362,11 +1314,11 @@ CfreeDbgHost driver_env_to_dbg_host(const DriverEnv *e) { * route every length scan through cfree_slice_cstr and otherwise use the * length-based mem* primitives. No libc str* is used. */ -int driver_streq(const char *a, const char *b) { +int driver_streq(const char* a, const char* b) { return cfree_slice_eq(cfree_slice_cstr(a), cfree_slice_cstr(b)); } -int driver_strneq(const char *a, const char *b, size_t n) { +int driver_strneq(const char* a, const char* b, size_t n) { size_t i; for (i = 0; i < n; ++i) { unsigned char ca = (unsigned char)a[i], cb = (unsigned char)b[i]; @@ -1376,14 +1328,14 @@ int driver_strneq(const char *a, const char *b, size_t n) { return 1; } -size_t driver_strlen(const char *s) { return cfree_slice_cstr(s).len; } +size_t driver_strlen(const char* s) { return cfree_slice_cstr(s).len; } -const char *driver_strchr(const char *s, int c) { +const char* driver_strchr(const char* s, int c) { /* search includes the terminator so driver_strchr(s, 0) works like strchr */ - return (const char *)memchr(s, c, cfree_slice_cstr(s).len + 1u); + return (const char*)memchr(s, c, cfree_slice_cstr(s).len + 1u); } -const char *driver_basename(const char *path) { +const char* driver_basename(const char* path) { size_t i = cfree_slice_cstr(path).len; while (i > 0) { if (path[i - 1] == '/') return path + i; @@ -1392,28 +1344,25 @@ const char *driver_basename(const char *path) { return path; } -int driver_has_suffix(const char *s, const char *suffix) { +int driver_has_suffix(const char* s, const char* suffix) { size_t ls = cfree_slice_cstr(s).len; size_t lf = cfree_slice_cstr(suffix).len; return ls >= lf && memcmp(s + ls - lf, suffix, lf) == 0; } -int driver_path_exists(const char *path) { +int driver_path_exists(const char* path) { struct stat sb; - if (!path) - return 0; + if (!path) return 0; return stat(path, &sb) == 0; } -int driver_path_mtime_ns(const char *path, int64_t *out) { +int driver_path_mtime_ns(const char* path, int64_t* out) { struct stat sb; int64_t sec; int64_t nsec; - if (!path || !out) - return 1; - if (stat(path, &sb) != 0) - return 1; + if (!path || !out) return 1; + if (stat(path, &sb) != 0) return 1; #if defined(__APPLE__) sec = (int64_t)sb.st_mtimespec.tv_sec; nsec = (int64_t)sb.st_mtimespec.tv_nsec; @@ -1428,26 +1377,22 @@ int driver_path_mtime_ns(const char *path, int64_t *out) { return 0; } -int driver_mkdir_p(DriverEnv *env, const char *path) { +int driver_mkdir_p(DriverEnv* env, const char* path) { size_t len; - char *buf; + char* buf; size_t i; struct stat sb; - if (!path || !path[0]) - return 1; + if (!path || !path[0]) return 1; len = cfree_slice_cstr(path).len; - buf = (char *)driver_alloc(env, len + 1); - if (!buf) - return 1; + buf = (char*)driver_alloc(env, len + 1); + if (!buf) return 1; memcpy(buf, path, len + 1); for (i = 1; i <= len; ++i) { int at_end = (i == len); - if (!at_end && buf[i] != '/') - continue; - if (!at_end) - buf[i] = '\0'; + if (!at_end && buf[i] != '/') continue; + if (!at_end) buf[i] = '\0'; if (buf[0] != '\0' && !driver_streq(buf, ".")) { if (mkdir(buf, 0755) != 0 && errno != EEXIST) { driver_free(env, buf, len + 1); @@ -1458,47 +1403,43 @@ int driver_mkdir_p(DriverEnv *env, const char *path) { return 1; } } - if (!at_end) - buf[i] = '/'; + if (!at_end) buf[i] = '/'; } driver_free(env, buf, len + 1); return 0; } -int driver_mark_executable_output(const char *path) { +int driver_mark_executable_output(const char* path) { mode_t mask; mode_t mode; - if (!path) - return 1; + if (!path) return 1; mask = umask(0); (void)umask(mask); mode = (mode_t)(0777 & ~mask); return chmod(path, mode) == 0 ? 0 : 1; } -void *driver_alloc(DriverEnv *e, size_t n) { +void* driver_alloc(DriverEnv* e, size_t n) { return e->heap->alloc(e->heap, n, _Alignof(max_align_t)); } -void *driver_alloc_zeroed(DriverEnv *e, size_t n) { - void *p = driver_alloc(e, n); - if (p) - memset(p, 0, n); +void* driver_alloc_zeroed(DriverEnv* e, size_t n) { + void* p = driver_alloc(e, n); + if (p) memset(p, 0, n); return p; } -void driver_free(DriverEnv *e, void *p, size_t n) { - if (p) - e->heap->free(e->heap, p, n); +void driver_free(DriverEnv* e, void* p, size_t n) { + if (p) e->heap->free(e->heap, p, n); } -void driver_memcpy(void *dst, const void *src, size_t n) { +void driver_memcpy(void* dst, const void* src, size_t n) { memcpy(dst, src, n); } -void driver_errf(const char *tool, const char *fmt, ...) { +void driver_errf(const char* tool, const char* fmt, ...) { va_list ap; fprintf(stderr, "%.*s: ", CFREE_SLICE_ARG(cfree_slice_cstr(tool))); va_start(ap, fmt); @@ -1507,7 +1448,7 @@ void driver_errf(const char *tool, const char *fmt, ...) { fputc('\n', stderr); } -void driver_logf(const char *fmt, ...) { +void driver_logf(const char* fmt, ...) { va_list ap; va_start(ap, fmt); vfprintf(stderr, fmt, ap); @@ -1515,7 +1456,7 @@ void driver_logf(const char *fmt, ...) { fputc('\n', stderr); } -void driver_printf(const char *fmt, ...) { +void driver_printf(const char* fmt, ...) { va_list ap; va_start(ap, fmt); vprintf(fmt, ap); @@ -1531,10 +1472,10 @@ uint64_t driver_now_ns(void) { return 0; } -const char *driver_getenv(const char *name) { return getenv(name); } +const char* driver_getenv(const char* name) { return getenv(name); } -int driver_load_bytes(const CfreeFileIO *io, const char *tool, const char *path, - DriverLoad *out, CfreeSlice *in) { +int driver_load_bytes(const CfreeFileIO* io, const char* tool, const char* path, + DriverLoad* out, CfreeSlice* in) { out->loaded = 0; out->fd.data = NULL; out->fd.size = 0; @@ -1554,28 +1495,25 @@ int driver_load_bytes(const CfreeFileIO *io, const char *tool, const char *path, return 0; } -void driver_release_bytes(const CfreeFileIO *io, DriverLoad *lf) { - if (!lf || !lf->loaded) - return; - if (io && io->release) - io->release(io->user, &lf->fd); +void driver_release_bytes(const CfreeFileIO* io, DriverLoad* lf) { + if (!lf || !lf->loaded) return; + if (io && io->release) io->release(io->user, &lf->fd); lf->loaded = 0; } -int driver_read_stdin(DriverEnv *e, uint8_t **out_data, size_t *out_size) { +int driver_read_stdin(DriverEnv* e, uint8_t** out_data, size_t* out_size) { /* stdin is unseekable in the general case (pipes, ttys), so grow a buffer * geometrically as we read, then shrink to the exact byte count so * out_size is a valid argument to driver_free. */ size_t cap = 4096; size_t len = 0; - uint8_t *buf = e->heap->alloc(e->heap, cap, 1); - if (!buf) - return 0; + uint8_t* buf = e->heap->alloc(e->heap, cap, 1); + if (!buf) return 0; for (;;) { ssize_t n; if (len == cap) { size_t newcap = cap * 2; - uint8_t *nb = e->heap->realloc(e->heap, buf, cap, newcap, 1); + uint8_t* nb = e->heap->realloc(e->heap, buf, cap, newcap, 1); if (!nb) { e->heap->free(e->heap, buf, cap); return 0; @@ -1584,8 +1522,7 @@ int driver_read_stdin(DriverEnv *e, uint8_t **out_data, size_t *out_size) { cap = newcap; } n = read(STDIN_FILENO, buf + len, cap - len); - if (n == 0) - break; + if (n == 0) break; if (n < 0) { e->heap->free(e->heap, buf, cap); return 0; @@ -1593,7 +1530,7 @@ int driver_read_stdin(DriverEnv *e, uint8_t **out_data, size_t *out_size) { len += (size_t)n; } if (len < cap) { - uint8_t *shrunk = len ? e->heap->realloc(e->heap, buf, cap, len, 1) : NULL; + uint8_t* shrunk = len ? e->heap->realloc(e->heap, buf, cap, len, 1) : NULL; if (len && !shrunk) { /* Shrink failed: keep the larger buffer. The release size below * tracks `cap`, so this remains free-correct. */ @@ -1613,33 +1550,29 @@ int driver_read_stdin(DriverEnv *e, uint8_t **out_data, size_t *out_size) { return 1; } -static int driver_write_fd_all(int fd, const uint8_t *data, size_t n) { +static int driver_write_fd_all(int fd, const uint8_t* data, size_t n) { size_t off = 0; while (off < n) { ssize_t wr = write(fd, data + off, n - off); if (wr < 0) { - if (errno == EINTR) - continue; + if (errno == EINTR) continue; return 0; } - if (wr == 0) - return 0; + if (wr == 0) return 0; off += (size_t)wr; } return 1; } -static char *driver_shell_quote_path(DriverEnv *e, const char *path, - size_t path_len, size_t *quoted_len_out) { +static char* driver_shell_quote_path(DriverEnv* e, const char* path, + size_t path_len, size_t* quoted_len_out) { size_t i; size_t quoted_len = 2u; - char *out; - char *q; - for (i = 0; i < path_len; ++i) - quoted_len += path[i] == '\'' ? 4u : 1u; + char* out; + char* q; + for (i = 0; i < path_len; ++i) quoted_len += path[i] == '\'' ? 4u : 1u; out = e->heap->alloc(e->heap, quoted_len + 1u, 1); - if (!out) - return NULL; + if (!out) return NULL; q = out; *q++ = '\''; for (i = 0; i < path_len; ++i) { @@ -1654,51 +1587,45 @@ static char *driver_shell_quote_path(DriverEnv *e, const char *path, } *q++ = '\''; *q = '\0'; - if (quoted_len_out) - *quoted_len_out = quoted_len; + if (quoted_len_out) *quoted_len_out = quoted_len; return out; } -int driver_edit_temp(DriverEnv *e, const char *suffix, const uint8_t *initial, - size_t initial_size, uint8_t **out_data, - size_t *out_size) { - const char *editor; - const char *tmpdir; - const char *base = "/cfree-dbg-XXXXXX"; +int driver_edit_temp(DriverEnv* e, const char* suffix, const uint8_t* initial, + size_t initial_size, uint8_t** out_data, + size_t* out_size) { + const char* editor; + const char* tmpdir; + const char* base = "/cfree-dbg-XXXXXX"; size_t tmpdir_len; size_t base_len; size_t suffix_len; size_t path_len; - char *path; + char* path; int fd = -1; int ok = 0; CfreeFileData fd_data; - if (!out_data || !out_size) - return 0; + if (!out_data || !out_size) return 0; *out_data = NULL; *out_size = 0; suffix_len = suffix ? cfree_slice_cstr(suffix).len : 0u; tmpdir = getenv("TMPDIR"); - if (!tmpdir || !*tmpdir) - tmpdir = "/tmp"; + if (!tmpdir || !*tmpdir) tmpdir = "/tmp"; tmpdir_len = cfree_slice_cstr(tmpdir).len; base_len = cfree_slice_cstr(base).len; path_len = tmpdir_len + base_len + suffix_len; path = e->heap->alloc(e->heap, path_len + 1u, 1); - if (!path) - return 0; + if (!path) return 0; memcpy(path, tmpdir, tmpdir_len); memcpy(path + tmpdir_len, base, base_len); - if (suffix_len) - memcpy(path + tmpdir_len + base_len, suffix, suffix_len); + if (suffix_len) memcpy(path + tmpdir_len + base_len, suffix, suffix_len); path[path_len] = '\0'; fd = mkstemps(path, (int)suffix_len); - if (fd < 0) - goto out; + if (fd < 0) goto out; if (initial_size && - !driver_write_fd_all(fd, initial ? initial : (const uint8_t *)"", + !driver_write_fd_all(fd, initial ? initial : (const uint8_t*)"", initial_size)) goto out; if (close(fd) != 0) { @@ -1708,19 +1635,16 @@ int driver_edit_temp(DriverEnv *e, const char *suffix, const uint8_t *initial, fd = -1; editor = getenv("VISUAL"); - if (!editor || !*editor) - editor = getenv("EDITOR"); - if (!editor || !*editor) - editor = "vi"; + if (!editor || !*editor) editor = getenv("EDITOR"); + if (!editor || !*editor) editor = "vi"; { size_t editor_len = cfree_slice_cstr(editor).len; size_t quoted_len = 0; - char *quoted = driver_shell_quote_path(e, path, path_len, "ed_len); - char *cmd; + char* quoted = driver_shell_quote_path(e, path, path_len, "ed_len); + char* cmd; int status; pid_t pid; - if (!quoted) - goto out; + if (!quoted) goto out; cmd = e->heap->alloc(e->heap, editor_len + 1u + quoted_len + 1u, 1); if (!cmd) { e->heap->free(e->heap, quoted, quoted_len + 1u); @@ -1732,36 +1656,31 @@ int driver_edit_temp(DriverEnv *e, const char *suffix, const uint8_t *initial, e->heap->free(e->heap, quoted, quoted_len + 1u); pid = fork(); if (pid == 0) { - execl("/bin/sh", "sh", "-c", cmd, (char *)NULL); + execl("/bin/sh", "sh", "-c", cmd, (char*)NULL); _exit(127); } e->heap->free(e->heap, cmd, editor_len + 1u + quoted_len + 1u); - if (pid < 0) - goto out; + if (pid < 0) goto out; do { if (waitpid(pid, &status, 0) < 0) { - if (errno == EINTR) - continue; + if (errno == EINTR) continue; goto out; } break; } while (1); - if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) - goto out; + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) goto out; } fd_data.data = NULL; fd_data.size = 0; fd_data.token = NULL; - if (posix_read_all(e, path, &fd_data) != CFREE_OK) - goto out; - *out_data = (uint8_t *)fd_data.data; + if (posix_read_all(e, path, &fd_data) != CFREE_OK) goto out; + *out_data = (uint8_t*)fd_data.data; *out_size = fd_data.size; ok = 1; out: - if (fd >= 0) - close(fd); + if (fd >= 0) close(fd); if (path) { unlink(path); e->heap->free(e->heap, path, path_len + 1u); @@ -1769,14 +1688,13 @@ out: return ok; } -void *driver_dlsym_resolver(void *user, CfreeSlice name_s) { +void* driver_dlsym_resolver(void* user, CfreeSlice name_s) { /* The linker hands us interned/pool slices that are NUL-terminated, so * we can pass .s straight to dlsym (a host libc boundary). */ - const char *name = name_s.s; - void *p; + const char* name = name_s.s; + void* p; (void)user; - if (!name || name_s.len == 0) - return NULL; + if (!name || name_s.len == 0) return NULL; /* On Mach-O hosts the linker hands us C names with a leading underscore * (obj_format_c_mangle), but dlsym(RTLD_DEFAULT) expects the * source-level name. Try the stripped form first to avoid a wasted @@ -1795,7 +1713,7 @@ void *driver_dlsym_resolver(void *user, CfreeSlice name_s) { #endif } -int driver_read_line(char *buf, size_t cap) { +int driver_read_line(char* buf, size_t cap) { /* Reads one line from stdin into `buf` (cap >= 2 required). The trailing * newline is stripped; the result is NUL-terminated. Returns the number * of characters in the line on success, 0 at EOF (with buf[0]='\0'), @@ -1803,8 +1721,7 @@ int driver_read_line(char *buf, size_t cap) { * (errno == EINTR). Lines longer than cap-1 bytes are truncated to * cap-1 and the remainder up to the next newline is consumed. */ size_t len = 0; - if (!buf || cap < 2) - return -1; + if (!buf || cap < 2) return -1; for (;;) { int c; errno = 0; @@ -1815,18 +1732,15 @@ int driver_read_line(char *buf, size_t cap) { clearerr(stdin); return -2; } - if (ferror(stdin)) - return -1; - if (len == 0) - return 0; + if (ferror(stdin)) return -1; + if (len == 0) return 0; return (int)len; } if (c == '\n') { buf[len] = '\0'; return (int)len; } - if (len + 1 < cap) - buf[len++] = (char)c; + if (len + 1 < cap) buf[len++] = (char)c; /* else: drop overflow; keep consuming until the newline. */ } } @@ -1838,16 +1752,15 @@ void driver_flush_stdout(void) { fflush(stdout); } * call cfree_jit_session_interrupt). The handler is short and async-signal * safe by construction; the cb is the caller's responsibility. */ -static void (*s_sigint_cb)(void *); -static void *s_sigint_cb_user; +static void (*s_sigint_cb)(void*); +static void* s_sigint_cb_user; static void sigint_trampoline(int sig) { (void)sig; - if (s_sigint_cb) - s_sigint_cb(s_sigint_cb_user); + if (s_sigint_cb) s_sigint_cb(s_sigint_cb_user); } -int driver_install_sigint(void (*cb)(void *), void *user) { +int driver_install_sigint(void (*cb)(void*), void* user) { struct sigaction sa; s_sigint_cb = cb; s_sigint_cb_user = user; @@ -1904,8 +1817,8 @@ CfreeTarget driver_host_target(void) { t.obj = CFREE_OBJ_ELF; #endif - t.ptr_size = (uint8_t)sizeof(void *); - t.ptr_align = (uint8_t)sizeof(void *); + t.ptr_size = (uint8_t)sizeof(void*); + t.ptr_align = (uint8_t)sizeof(void*); t.big_endian = 0; t.pic = CFREE_PIC_NONE; t.code_model = CFREE_CM_DEFAULT; diff --git a/driver/env.h b/driver/env.h @@ -1,13 +1,12 @@ #ifndef CFREE_DRIVER_ENV_H #define CFREE_DRIVER_ENV_H -#include <stddef.h> -#include <stdint.h> - #include <cfree/compile.h> #include <cfree/core.h> #include <cfree/dbg.h> #include <cfree/jit.h> +#include <stddef.h> +#include <stdint.h> /* Shared host environment used by every tool that calls into libcfree. * driver_env_init wires up the libc-backed heap, the stderr diag sink, and @@ -19,45 +18,45 @@ * that one DriverEnv covers every libcfree-using tool, but they're handed * to libcfree per-call via the appropriate host struct. */ typedef struct DriverEnv { - CfreeHeap *heap; - CfreeDiagSink *diag; + CfreeHeap* heap; + CfreeDiagSink* diag; CfreeFileIO file_io; - const CfreeExecMem *execmem; - const CfreeDbgOs *dbg_os; /* NULL unless `cfree dbg` paths run */ - const CfreeJitTls *jit_tls; /* NULL unless `cfree run` w/ TLV paths run */ - const CfreeMetrics *metrics; /* optional scoped metrics sink */ + const CfreeExecMem* execmem; + const CfreeDbgOs* dbg_os; /* NULL unless `cfree dbg` paths run */ + const CfreeJitTls* jit_tls; /* NULL unless `cfree run` w/ TLV paths run */ + const CfreeMetrics* metrics; /* optional scoped metrics sink */ int64_t now; /* unix seconds; -1 = unknown */ } DriverEnv; -void driver_env_init(DriverEnv *); -void driver_env_fini(DriverEnv *); +void driver_env_init(DriverEnv*); +void driver_env_fini(DriverEnv*); /* Build a CfreeContext value pointing at the DriverEnv's heap/diag/file_io * vtables. The returned value can be passed by const-pointer to any * libcfree entry that takes `const CfreeContext *`. */ -CfreeContext driver_env_to_context(const DriverEnv *); +CfreeContext driver_env_to_context(const DriverEnv*); /* Build a CfreeJitHost from the DriverEnv (execmem + tls). The returned * struct holds borrowed pointers to vtables owned by g_execmem_posix / * g_jit_tls_posix; callers must not outlive driver_env_fini. */ -CfreeJitHost driver_env_to_jit_host(const DriverEnv *); +CfreeJitHost driver_env_to_jit_host(const DriverEnv*); /* Build a CfreeDbgHost from the DriverEnv (dbg_os). */ -CfreeDbgHost driver_env_to_dbg_host(const DriverEnv *); +CfreeDbgHost driver_env_to_dbg_host(const DriverEnv*); /* Tells the stderr diag sink which compiler to use when resolving * SrcLoc.file_id to a path. The driver_compiler_{new,free} helpers * below already manage this; call this directly only when you hand a * CfreeCompiler from outside those helpers (none today). */ -void driver_diag_set_compiler(CfreeCompiler *); +void driver_diag_set_compiler(CfreeCompiler*); /* Lifecycle helpers around cfree_compiler_{new,free}. Identical to the * raw entries except they register the active compiler with the stderr * diag sink so diagnostics resolve loc.file_id to its registered path. * Returns CFREE_OK on success; on failure *out is NULL. */ -CfreeStatus driver_compiler_new(CfreeTarget, const CfreeContext *, - CfreeCompiler **out); -void driver_compiler_free(CfreeCompiler *); +CfreeStatus driver_compiler_new(CfreeTarget, const CfreeContext*, + CfreeCompiler** out); +void driver_compiler_free(CfreeCompiler*); /* Default target used by tools that don't expose a target-selection flag * yet. v1: native-looking host target (chosen at compile time). */ @@ -77,50 +76,50 @@ CfreeTarget driver_host_target(void); /* String predicates and lookups. driver_streq / driver_strneq return * non-zero when the strings (or first n bytes) match -- sense-flipped * from libc's strcmp so call sites read naturally. */ -int driver_streq(const char *a, const char *b); -int driver_strneq(const char *a, const char *b, size_t n); -size_t driver_strlen(const char *s); -const char *driver_strchr(const char *s, int c); -const char *driver_basename(const char *path); -int driver_has_suffix(const char *s, const char *suffix); +int driver_streq(const char* a, const char* b); +int driver_strneq(const char* a, const char* b, size_t n); +size_t driver_strlen(const char* s); +const char* driver_strchr(const char* s, int c); +const char* driver_basename(const char* path); +int driver_has_suffix(const char* s, const char* suffix); /* Memory. Allocations route through DriverEnv.heap; release returns the * size used at allocation (so the heap implementation can track usage). */ -void *driver_alloc(DriverEnv *, size_t); -void *driver_alloc_zeroed(DriverEnv *, size_t); -void driver_free(DriverEnv *, void *p, size_t); -void driver_memcpy(void *dst, const void *src, size_t n); +void* driver_alloc(DriverEnv*, size_t); +void* driver_alloc_zeroed(DriverEnv*, size_t); +void driver_free(DriverEnv*, void* p, size_t); +void driver_memcpy(void* dst, const void* src, size_t n); /* Opens a Writer that writes to stdout. close frees the struct but does * not close stdout. */ -CfreeWriter *driver_stdout_writer(DriverEnv *); +CfreeWriter* driver_stdout_writer(DriverEnv*); /* Test whether `path` names an existing filesystem entry (any type). * Returns nonzero on existence, zero otherwise. Used by library-path * resolution; intentionally distinct from read_all so candidate-search * loops don't slurp file contents on a hit. */ -int driver_path_exists(const char *path); +int driver_path_exists(const char* path); /* Read a path's last modification time in nanoseconds since the Unix epoch. * Returns 0 on success, nonzero on stat failure. */ -int driver_path_mtime_ns(const char *path, int64_t *out); +int driver_path_mtime_ns(const char* path, int64_t* out); /* Create a directory and any missing parents. Returns 0 on success. */ -int driver_mkdir_p(DriverEnv *, const char *path); +int driver_mkdir_p(DriverEnv*, const char* path); /* Set a linked binary output's final mode according to the active umask. * Returns 0 on success, nonzero on chmod failure. */ -int driver_mark_executable_output(const char *path); +int driver_mark_executable_output(const char* path); /* Diagnostic printing to host stderr. Format is `"<tool>: <fmt>\n"`. */ -void driver_errf(const char *tool, const char *fmt, ...); +void driver_errf(const char* tool, const char* fmt, ...); /* Raw hosted stderr log. Used by optional metrics so libcfree stays callback- * only and freestanding. */ -void driver_logf(const char *fmt, ...); +void driver_logf(const char* fmt, ...); /* Formatted output to stdout. */ -void driver_printf(const char *fmt, ...); +void driver_printf(const char* fmt, ...); /* Monotonic host time in nanoseconds, or 0 if unavailable. */ uint64_t driver_now_ns(void); @@ -128,20 +127,20 @@ uint64_t driver_now_ns(void); /* Lookup a process environment variable; returns NULL if unset. The returned * pointer aliases libc-owned storage and is valid until the next setenv/ * putenv from any caller. */ -const char *driver_getenv(const char *name); +const char* driver_getenv(const char* name); /* Read all of stdin into a freshly-allocated buffer. On success returns 1 * and stores the buffer/size in out_data/out_size; the caller frees via * driver_free(env, *out_data, *out_size). Returns 0 on read failure or * allocation failure. */ -int driver_read_stdin(DriverEnv *, uint8_t **out_data, size_t *out_size); +int driver_read_stdin(DriverEnv*, uint8_t** out_data, size_t* out_size); /* Open a temporary file in $VISUAL, then $EDITOR, then vi. `suffix` should * include the leading dot when a language-specific extension is useful. * On success, returns the edited bytes in a freshly allocated buffer that the * caller frees with driver_free(env, *out_data, *out_size). */ -int driver_edit_temp(DriverEnv *, const char *suffix, const uint8_t *initial, - size_t initial_size, uint8_t **out_data, size_t *out_size); +int driver_edit_temp(DriverEnv*, const char* suffix, const uint8_t* initial, + size_t initial_size, uint8_t** out_data, size_t* out_size); /* Path-shaped input loader. Wraps env.file_io.read_all so each tool can * convert a list of paths to a list of CfreeSlice without re-implementing @@ -155,9 +154,9 @@ typedef struct DriverLoad { int loaded; } DriverLoad; -int driver_load_bytes(const CfreeFileIO *, const char *tool, const char *path, - DriverLoad *out, CfreeSlice *in); -void driver_release_bytes(const CfreeFileIO *, DriverLoad *); +int driver_load_bytes(const CfreeFileIO*, const char* tool, const char* path, + DriverLoad* out, CfreeSlice* in); +void driver_release_bytes(const CfreeFileIO*, DriverLoad*); /* Read one line from stdin into `buf` (cap >= 2). Strips the trailing * newline and NUL-terminates. Returns the line length on success, 0 at @@ -165,7 +164,7 @@ void driver_release_bytes(const CfreeFileIO *, DriverLoad *); * interrupted by a signal (caller should print a fresh prompt and * retry). Over-long lines are truncated to cap-1 bytes; the remainder * up to the next newline is consumed silently. */ -int driver_read_line(char *buf, size_t cap); +int driver_read_line(char* buf, size_t cap); /* Flush the host stdout. The dbg REPL prompt has no trailing newline, so * without an explicit flush the prompt stays buffered until the next @@ -177,7 +176,7 @@ void driver_flush_stdout(void); * forward Ctrl-C into cfree_jit_session_interrupt while the worker is * running, and to restore SIG_DFL while sitting at the REPL prompt so * Ctrl-C terminates the program normally. Returns 0 on success. */ -int driver_install_sigint(void (*cb)(void *), void *user); +int driver_install_sigint(void (*cb)(void*), void* user); void driver_restore_sigint(void); /* Host-symbol resolver for JIT extern_resolver. Looks up `name` via @@ -185,6 +184,6 @@ void driver_restore_sigint(void); * `user` is ignored and may be NULL. Wired into `cfree run` so JITed code * can call libc symbols (printf, malloc, ...) without an explicit linker * step. */ -void *driver_dlsym_resolver(void *user, CfreeSlice name); +void* driver_dlsym_resolver(void* user, CfreeSlice name); #endif diff --git a/driver/hosted.h b/driver/hosted.h @@ -1,9 +1,8 @@ #ifndef CFREE_DRIVER_HOSTED_H #define CFREE_DRIVER_HOSTED_H -#include <stdint.h> - #include <cfree/compile.h> +#include <stdint.h> #include "driver.h" diff --git a/driver/inputs.c b/driver/inputs.c @@ -1,11 +1,10 @@ #include "inputs.h" +#include <cfree/frontend.h> #include <stddef.h> #include <stdint.h> #include <string.h> -#include <cfree/frontend.h> - int driver_inputs_init(DriverInputs* in, DriverEnv* env, const char* tool, int argc) { size_t bound = (size_t)argc; diff --git a/driver/inputs.h b/driver/inputs.h @@ -1,12 +1,12 @@ #ifndef CFREE_DRIVER_INPUTS_H #define CFREE_DRIVER_INPUTS_H -#include "driver.h" - #include <cfree/compile.h> #include <cfree/link.h> #include <cfree/object.h> +#include "driver.h" + /* Shared input handling for tools that take a mixed list of C sources, * stdin source, object files, and static archives — `cfree run` and * `cfree dbg` today. Owns parallel arrays sized to the worst-case argv @@ -29,19 +29,19 @@ * Path strings (`.c`, `.o`, `.a`) are borrowed from argv. The stdin * buffer is heap-owned and freed by driver_inputs_release. */ typedef struct DriverInputs { - DriverEnv *env; - const char *tool; + DriverEnv* env; + const char* tool; size_t bound; - const char **sources; /* .c .cc .cpp paths (borrowed) */ + const char** sources; /* .c .cc .cpp paths (borrowed) */ uint32_t nsources; - CfreeSourceInput *source_memory; /* "-" stdin slurp; at most one entry */ + CfreeSourceInput* source_memory; /* "-" stdin slurp; at most one entry */ uint32_t nsource_memory; - uint8_t *stdin_buf; /* owning storage for the one stdin slurp */ + uint8_t* stdin_buf; /* owning storage for the one stdin slurp */ size_t stdin_size; - const char **object_files; /* .o .obj paths (borrowed) */ + const char** object_files; /* .o .obj paths (borrowed) */ uint32_t nobject_files; - const char **archives; /* .a paths (borrowed) */ + const char** archives; /* .a paths (borrowed) */ uint32_t narchives; } DriverInputs; @@ -49,11 +49,11 @@ typedef struct DriverInputs { * (typically the program's argc). `tool` is the short name used in * driver_errf messages. Returns 0 on success, 1 on allocation failure * (already reported). */ -int driver_inputs_init(DriverInputs *, DriverEnv *, const char *tool, int argc); +int driver_inputs_init(DriverInputs*, DriverEnv*, const char* tool, int argc); /* Release every allocation held by *in, including the stdin buffer. * Safe to call even after a failed init. */ -void driver_inputs_release(DriverInputs *); +void driver_inputs_release(DriverInputs*); /* Try to consume one positional input at `arg`. Recognized: * "-" read C source from stdin (at most once) @@ -69,29 +69,29 @@ void driver_inputs_release(DriverInputs *); * -1 arg matched a recognized shape but recording failed (duplicate * stdin, stdin read failure, allocation failure); the error has * already been reported via driver_errf. */ -int driver_inputs_classify(DriverInputs *, const char *arg); +int driver_inputs_classify(DriverInputs*, const char* arg); /* Total recorded inputs across every kind. */ -uint32_t driver_inputs_count(const DriverInputs *); +uint32_t driver_inputs_count(const DriverInputs*); /* Display name of the first recorded input (sources, then source_memory, * then object_files, then archives — matches the order used by the * link/compile loop). Used by callers to synthesize argv[0] for the * JITed program. Returns NULL when no inputs are recorded. */ -const char *driver_inputs_first_name(const DriverInputs *); +const char* driver_inputs_first_name(const DriverInputs*); /* Load every input through env.file_io, compile sources via `compiler` * with `copts`, and JIT-link the result. `host` carries execmem/tls; * `extern_resolver` populates the JIT link options. On success *out_jit * owns the JIT image; on failure an error has already been reported. * Returns 0 on success, 1 otherwise. */ -int driver_inputs_compile_and_jit(DriverInputs *, CfreeCompiler *, - const CfreeJitHost *, - const CfreeCCompileOptions *copts, - const char *entry, - void *(*extern_resolver)(void *, CfreeSlice), - void *extern_resolver_user, - CfreeJit **out_jit); +int driver_inputs_compile_and_jit(DriverInputs*, CfreeCompiler*, + const CfreeJitHost*, + const CfreeCCompileOptions* copts, + const char* entry, + void* (*extern_resolver)(void*, CfreeSlice), + void* extern_resolver_user, + CfreeJit** out_jit); /* ---------------------------------------------------------------------- * Per-object global-symbol collection @@ -114,14 +114,13 @@ int driver_inputs_compile_and_jit(DriverInputs *, CfreeCompiler *, * 1 fatal failure (out of memory, etc.); an error has been reported * via driver_errf using the supplied tool tag. */ -int driver_collect_obj_global_syms(DriverEnv *env, const CfreeContext *ctx, - const char *tool, - const CfreeSlice *member, void **blob_out, - size_t *blob_size_out, - const CfreeSlice **names_out, - uint32_t *count_out); +int driver_collect_obj_global_syms(DriverEnv* env, const CfreeContext* ctx, + const char* tool, const CfreeSlice* member, + void** blob_out, size_t* blob_size_out, + const CfreeSlice** names_out, + uint32_t* count_out); -void driver_collect_obj_global_syms_free(DriverEnv *env, void *blob, +void driver_collect_obj_global_syms_free(DriverEnv* env, void* blob, size_t blob_size); #endif diff --git a/driver/ld.c b/driver/ld.c @@ -131,88 +131,95 @@ typedef struct LdOptions { static void ld_usage(void) { driver_errf(LD_TOOL, "%.*s", CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "usage: cfree ld -o out [options...] inputs.o|inputs.a...\n" - " cfree ld --help for full option reference"))); + "usage: cfree ld -o out [options...] inputs.o|inputs.a...\n" + " cfree ld --help for full option reference"))); } void driver_help_ld(void) { driver_printf( "%.*s", CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "cfree ld — link objects/archives into an executable or shared library\n" - "\n" - "USAGE\n" - " cfree ld -o OUT [options] inputs.o ... inputs.a ...\n" - " cfree ld -shared -o libfoo.so [options] inputs.o ...\n" - " cfree ld -r -o partial.o inputs.o ...\n" - "\n" - "DESCRIPTION\n" - " Loads each input via host file I/O, optionally parses a -T linker\n" - " script, and emits an executable (default) or shared library\n" - " (-shared). The full link surface is exposed: per-archive flags,\n" - " cyclic-resolution groups, build-id, soname/rpath/exports.\n" - "\n" - "OUTPUT\n" - " -o PATH Output path (required, exactly one)\n" - " -shared Emit a position-independent shared library " - "/\n" - " dylib instead of an executable\n" - " -r, --relocatable Emit a relocatable partial-link object\n" - "\n" - "ENTRY / SCRIPT\n" - " -e SYMBOL Entry symbol\n" - " --subsystem NAME PE subsystem: console or windows\n" - " -T SCRIPT.ld Use a linker script (parsed, not raw)\n" - "\n" - "TARGET\n" - " -static Non-PIC, non-PIE\n" - " -pie Position-independent executable\n" - " -no-pie Disable PIE\n" - " (target is otherwise auto-detected from the first object input)\n" - "\n" - "LIBRARY RESOLUTION\n" - " -L DIR Add library search path\n" - " -l NAME Resolve to lib<NAME>.a via -L\n" - "\n" - "POSITIONAL ARCHIVE STATE (apply to following .a inputs)\n" - " --whole-archive Pull every member of following archives\n" - " --no-whole-archive Reset (default behaviour)\n" - " -Bstatic Force static link mode\n" - " -Bdynamic Force dynamic link mode\n" - " --as-needed Link only if a real reference exists\n" - " --no-as-needed Reset to dynamic\n" - " --start-group ...\n" - " --end-group Cyclic-resolution archive group\n" - "\n" - "SHARED-LIBRARY OPTIONS (require -shared)\n" - " -soname NAME DT_SONAME / LC_ID_DYLIB\n" - " -soname=NAME equivalent attached form\n" - " -rpath DIR DT_RPATH/DT_RUNPATH entry (repeatable)\n" - " -rpath=DIR attached form\n" - " -rpath-link DIR Link-time-only search path (advisory)\n" - " --enable-new-dtags rpaths land in DT_RUNPATH (default)\n" - " --disable-new-dtags rpaths land in DT_RPATH\n" - "\n" - "SECTION GC\n" - " --gc-sections Drop sections unreferenced from the entry\n" - " symbol, init/fini arrays, SHF_GNU_RETAIN,\n" - " and __start_/__stop_ section references\n" - " --no-gc-sections Disable section GC (default)\n" - " -E, --export-dynamic Promote defined globals into dynsym\n" - " (no-op for -shared; recorded for exe)\n" - " --no-undefined Reject unresolved symbols in -shared " - "output\n" - " -z defs Same as --no-undefined\n" - "\n" - "BUILD ID\n" - " --build-id Same as --build-id=sha256\n" - " --build-id=MODE none | sha256 | uuid | 0xHEX\n" - "\n" - "GETTING HELP\n" - " -h, --help Show this help and exit\n" - "\n" - "EXIT CODES\n" - " 0 success 1 link error 2 bad usage\n"))); + "cfree ld — link objects/archives into an executable or shared " + "library\n" + "\n" + "USAGE\n" + " cfree ld -o OUT [options] inputs.o ... inputs.a ...\n" + " cfree ld -shared -o libfoo.so [options] inputs.o ...\n" + " cfree ld -r -o partial.o inputs.o ...\n" + "\n" + "DESCRIPTION\n" + " Loads each input via host file I/O, optionally parses a -T " + "linker\n" + " script, and emits an executable (default) or shared library\n" + " (-shared). The full link surface is exposed: per-archive flags,\n" + " cyclic-resolution groups, build-id, soname/rpath/exports.\n" + "\n" + "OUTPUT\n" + " -o PATH Output path (required, exactly one)\n" + " -shared Emit a position-independent shared " + "library " + "/\n" + " dylib instead of an executable\n" + " -r, --relocatable Emit a relocatable partial-link object\n" + "\n" + "ENTRY / SCRIPT\n" + " -e SYMBOL Entry symbol\n" + " --subsystem NAME PE subsystem: console or windows\n" + " -T SCRIPT.ld Use a linker script (parsed, not raw)\n" + "\n" + "TARGET\n" + " -static Non-PIC, non-PIE\n" + " -pie Position-independent executable\n" + " -no-pie Disable PIE\n" + " (target is otherwise auto-detected from the first object input)\n" + "\n" + "LIBRARY RESOLUTION\n" + " -L DIR Add library search path\n" + " -l NAME Resolve to lib<NAME>.a via -L\n" + "\n" + "POSITIONAL ARCHIVE STATE (apply to following .a inputs)\n" + " --whole-archive Pull every member of following " + "archives\n" + " --no-whole-archive Reset (default behaviour)\n" + " -Bstatic Force static link mode\n" + " -Bdynamic Force dynamic link mode\n" + " --as-needed Link only if a real reference exists\n" + " --no-as-needed Reset to dynamic\n" + " --start-group ...\n" + " --end-group Cyclic-resolution archive group\n" + "\n" + "SHARED-LIBRARY OPTIONS (require -shared)\n" + " -soname NAME DT_SONAME / LC_ID_DYLIB\n" + " -soname=NAME equivalent attached form\n" + " -rpath DIR DT_RPATH/DT_RUNPATH entry (repeatable)\n" + " -rpath=DIR attached form\n" + " -rpath-link DIR Link-time-only search path (advisory)\n" + " --enable-new-dtags rpaths land in DT_RUNPATH (default)\n" + " --disable-new-dtags rpaths land in DT_RPATH\n" + "\n" + "SECTION GC\n" + " --gc-sections Drop sections unreferenced from the " + "entry\n" + " symbol, init/fini arrays, " + "SHF_GNU_RETAIN,\n" + " and __start_/__stop_ section " + "references\n" + " --no-gc-sections Disable section GC (default)\n" + " -E, --export-dynamic Promote defined globals into dynsym\n" + " (no-op for -shared; recorded for exe)\n" + " --no-undefined Reject unresolved symbols in -shared " + "output\n" + " -z defs Same as --no-undefined\n" + "\n" + "BUILD ID\n" + " --build-id Same as --build-id=sha256\n" + " --build-id=MODE none | sha256 | uuid | 0xHEX\n" + "\n" + "GETTING HELP\n" + " -h, --help Show this help and exit\n" + "\n" + "EXIT CODES\n" + " 0 success 1 link error 2 bad usage\n"))); } /* ---------- argv-sized scratch arrays ---------- */ diff --git a/driver/lib_resolve.c b/driver/lib_resolve.c @@ -118,8 +118,7 @@ static int resolve_posix(DriverEnv* env, const char* name, LibResolveMode mode, } static int resolve_windows(DriverEnv* env, const char* name, - LibResolveMode mode, - const char* const* search_dirs, + LibResolveMode mode, const char* const* search_dirs, uint32_t nsearch_dirs, char** out_path, size_t* out_size, LibResolveKind* out_kind) { /* Windows / mingw layout. Try the mingw-canonical names first diff --git a/driver/nm.c b/driver/nm.c @@ -1,13 +1,12 @@ -#include "driver.h" - +#include <cfree/archive.h> +#include <cfree/core.h> +#include <cfree/object.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <cfree/archive.h> -#include <cfree/core.h> -#include <cfree/object.h> +#include "driver.h" #define NM_TOOL "nm" @@ -17,7 +16,7 @@ typedef struct NmSym { CfreeSymBind bind; CfreeSymKind kind; int defined; /* 1 = has a section, 0 = undef/abs/common */ - const char *file_prefix; + const char* file_prefix; } NmSym; typedef struct NmOpts { @@ -31,16 +30,16 @@ typedef struct NmOpts { int print_file; /* -A */ } NmOpts; -static int nm_symbol_visible(const CfreeObjSymInfo *si, const NmOpts *opts) { +static int nm_symbol_visible(const CfreeObjSymInfo* si, const NmOpts* opts) { if (!si->name.len) return 0; - if (opts->undef_only && - si->section != CFREE_SECTION_NONE && si->kind != CFREE_SK_ABS) + if (opts->undef_only && si->section != CFREE_SECTION_NONE && + si->kind != CFREE_SK_ABS) return 0; if (opts->defined_only && si->section == CFREE_SECTION_NONE && si->kind != CFREE_SK_ABS) return 0; - if (opts->extern_only && - si->bind != CFREE_SB_GLOBAL && si->bind != CFREE_SB_WEAK) + if (opts->extern_only && si->bind != CFREE_SB_GLOBAL && + si->bind != CFREE_SB_WEAK) return 0; if (!opts->debug_syms) { if (si->kind == CFREE_SK_FILE) return 0; @@ -49,9 +48,8 @@ static int nm_symbol_visible(const CfreeObjSymInfo *si, const NmOpts *opts) { return 1; } -static char nm_type_char(const NmSym *s) { - if (s->kind == CFREE_SK_ABS) - return (s->bind == CFREE_SB_LOCAL) ? 'a' : 'A'; +static char nm_type_char(const NmSym* s) { + if (s->kind == CFREE_SK_ABS) return (s->bind == CFREE_SB_LOCAL) ? 'a' : 'A'; if (!s->defined) { if (s->kind == CFREE_SK_COMMON) { if (s->bind == CFREE_SB_WEAK) return 'v'; @@ -78,9 +76,9 @@ static char nm_type_char(const NmSym *s) { } } -static int nm_name_cmp(const void *a, const void *b) { - const NmSym *sa = (const NmSym *)a; - const NmSym *sb = (const NmSym *)b; +static int nm_name_cmp(const void* a, const void* b) { + const NmSym* sa = (const NmSym*)a; + const NmSym* sb = (const NmSym*)b; size_t la = sa->name.len, lb = sb->name.len; size_t n = la < lb ? la : lb; int c = memcmp(sa->name.s, sb->name.s, n); @@ -88,24 +86,24 @@ static int nm_name_cmp(const void *a, const void *b) { return la < lb ? -1 : (la > lb ? 1 : 0); } -static int nm_value_cmp(const void *a, const void *b) { - const NmSym *sa = (const NmSym *)a; - const NmSym *sb = (const NmSym *)b; +static int nm_value_cmp(const void* a, const void* b) { + const NmSym* sa = (const NmSym*)a; + const NmSym* sb = (const NmSym*)b; if (sa->value < sb->value) return -1; if (sa->value > sb->value) return 1; return nm_name_cmp(a, b); } -static int nm_append_sym(DriverEnv *env, NmSym **syms, uint32_t *n, - uint32_t *cap, const CfreeObjSymInfo *si, - const char *file_prefix, int *ptr_digits, +static int nm_append_sym(DriverEnv* env, NmSym** syms, uint32_t* n, + uint32_t* cap, const CfreeObjSymInfo* si, + const char* file_prefix, int* ptr_digits, CfreeTarget t) { int d = (t.ptr_size == 4) ? 8 : 16; - char *name; + char* name; if (d > *ptr_digits) *ptr_digits = d; if (*n >= *cap) { uint32_t nc = *cap ? *cap * 2u : 64u; - NmSym *ns = (NmSym *)driver_alloc_zeroed(env, (size_t)nc * sizeof(NmSym)); + NmSym* ns = (NmSym*)driver_alloc_zeroed(env, (size_t)nc * sizeof(NmSym)); if (!ns) return 1; if (*syms) { memcpy(ns, *syms, (size_t)(*n) * sizeof(NmSym)); @@ -114,10 +112,10 @@ static int nm_append_sym(DriverEnv *env, NmSym **syms, uint32_t *n, *syms = ns; *cap = nc; } - name = (char *)driver_alloc(env, si->name.len); + name = (char*)driver_alloc(env, si->name.len); if (!name) return 1; driver_memcpy(name, si->name.s, si->name.len); - NmSym *ds = &(*syms)[*n]; + NmSym* ds = &(*syms)[*n]; ds->name.s = name; ds->name.len = si->name.len; ds->value = si->value; @@ -129,11 +127,11 @@ static int nm_append_sym(DriverEnv *env, NmSym **syms, uint32_t *n, return 0; } -static int nm_collect_obj(CfreeObjFile *of, const NmOpts *opts, - const char *file_prefix, NmSym **syms, uint32_t *n, - uint32_t *cap, int *ptr_digits, DriverEnv *env) { +static int nm_collect_obj(CfreeObjFile* of, const NmOpts* opts, + const char* file_prefix, NmSym** syms, uint32_t* n, + uint32_t* cap, int* ptr_digits, DriverEnv* env) { CfreeTarget t = cfree_obj_target(of); - CfreeObjSymIter *it = NULL; + CfreeObjSymIter* it = NULL; int rc = 0; if (cfree_obj_symiter_new(of, &it) != CFREE_OK) return 1; for (;;) { @@ -150,13 +148,13 @@ static int nm_collect_obj(CfreeObjFile *of, const NmOpts *opts, return rc; } -static int nm_process_file(const CfreeContext *ctx, const CfreeSlice *input, - const char *path, const NmOpts *opts, NmSym **syms, - uint32_t *n, uint32_t *cap, int *ptr_digits, - DriverEnv *env) { +static int nm_process_file(const CfreeContext* ctx, const CfreeSlice* input, + const char* path, const NmOpts* opts, NmSym** syms, + uint32_t* n, uint32_t* cap, int* ptr_digits, + DriverEnv* env) { CfreeBinFmt fmt = cfree_detect_fmt(input->data, input->len); if (fmt == CFREE_BIN_AR) { - CfreeArIter *it = NULL; + CfreeArIter* it = NULL; if (cfree_ar_iter_new(ctx, input, &it) != CFREE_OK) { driver_errf(NM_TOOL, "%s: not a recognized archive", path); return 1; @@ -164,7 +162,7 @@ static int nm_process_file(const CfreeContext *ctx, const CfreeSlice *input, for (;;) { CfreeArMember m; if (cfree_ar_iter_next(it, &m) != CFREE_ITER_ITEM) break; - CfreeObjFile *of = NULL; + CfreeObjFile* of = NULL; CfreeSlice mb; mb.data = m.data; mb.len = m.size; @@ -181,7 +179,7 @@ static int nm_process_file(const CfreeContext *ctx, const CfreeSlice *input, } cfree_ar_iter_free(it); } else { - CfreeObjFile *of = NULL; + CfreeObjFile* of = NULL; if (cfree_obj_open(ctx, cfree_slice_cstr(path), input, &of) != CFREE_OK && cfree_obj_open(ctx, CFREE_SLICE_NULL, input, &of) != CFREE_OK) { driver_errf(NM_TOOL, "%s: not a recognized object file", path); @@ -197,18 +195,18 @@ static int nm_process_file(const CfreeContext *ctx, const CfreeSlice *input, return 0; } -static void nm_free_syms(DriverEnv *env, NmSym *syms, uint32_t nsyms, +static void nm_free_syms(DriverEnv* env, NmSym* syms, uint32_t nsyms, uint32_t cap) { uint32_t i; if (!syms) return; for (i = 0; i < nsyms; ++i) { if (syms[i].name.s) - driver_free(env, (void *)syms[i].name.s, syms[i].name.len); + driver_free(env, (void*)syms[i].name.s, syms[i].name.len); } driver_free(env, syms, (size_t)cap * sizeof(NmSym)); } -static void nm_sort_syms(NmSym *syms, uint32_t nsyms, const NmOpts *opts) { +static void nm_sort_syms(NmSym* syms, uint32_t nsyms, const NmOpts* opts) { uint32_t i, j; if (opts->no_sort) return; qsort(syms, (size_t)nsyms, sizeof(NmSym), @@ -221,26 +219,24 @@ static void nm_sort_syms(NmSym *syms, uint32_t nsyms, const NmOpts *opts) { } } -static void nm_print_syms(const NmSym *syms, uint32_t nsyms, - const NmOpts *opts, int ptr_digits) { +static void nm_print_syms(const NmSym* syms, uint32_t nsyms, const NmOpts* opts, + int ptr_digits) { uint32_t i; for (i = 0; i < nsyms; ++i) { - const NmSym *s = &syms[i]; + const NmSym* s = &syms[i]; char tc = nm_type_char(s); - const char *pfx = ""; + const char* pfx = ""; char pbuf[256]; if (opts->print_file && s->file_prefix) { snprintf(pbuf, sizeof pbuf, "%s:", s->file_prefix); pfx = pbuf; } if (ptr_digits == 8) { - driver_printf("%s%08llx %c %.*s\n", pfx, - (unsigned long long)s->value, tc, + driver_printf("%s%08llx %c %.*s\n", pfx, (unsigned long long)s->value, tc, (int)s->name.len, s->name.s); } else { - driver_printf("%s%016llx %c %.*s\n", pfx, - (unsigned long long)s->value, tc, - (int)s->name.len, s->name.s); + driver_printf("%s%016llx %c %.*s\n", pfx, (unsigned long long)s->value, + tc, (int)s->name.len, s->name.s); } } } @@ -249,28 +245,28 @@ void driver_help_nm(void) { driver_printf( "%.*s", CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "cfree nm — list symbols from object files\n" - "\n" - "USAGE\n" - " cfree nm [OPTIONS] FILE...\n" - "\n" - "OPTIONS\n" - " -a, --debug-syms include debug symbols\n" - " -g, --extern-only show only external (global) symbols\n" - " -u, --undefined-only show only undefined symbols\n" - " --defined-only show only defined symbols\n" - " -n, --numeric-sort sort by address\n" - " -r, --reverse-sort reverse the sort order\n" - " --no-sort, -p do not sort; print in file order\n" - " -A, --print-file-name prefix each line with the input file name\n" - " -h, --help show this help\n"))); + "cfree nm — list symbols from object files\n" + "\n" + "USAGE\n" + " cfree nm [OPTIONS] FILE...\n" + "\n" + "OPTIONS\n" + " -a, --debug-syms include debug symbols\n" + " -g, --extern-only show only external (global) symbols\n" + " -u, --undefined-only show only undefined symbols\n" + " --defined-only show only defined symbols\n" + " -n, --numeric-sort sort by address\n" + " -r, --reverse-sort reverse the sort order\n" + " --no-sort, -p do not sort; print in file order\n" + " -A, --print-file-name prefix each line with the input file name\n" + " -h, --help show this help\n"))); } -int driver_nm(int argc, char **argv) { +int driver_nm(int argc, char** argv) { DriverEnv env; CfreeContext ctx; NmOpts opts; - NmSym *syms = NULL; + NmSym* syms = NULL; uint32_t nsyms = 0, cap = 0; int ptr_digits = 8; int i, rc = 1, any_input = 0; @@ -285,30 +281,38 @@ int driver_nm(int argc, char **argv) { ctx = driver_env_to_context(&env); for (i = 1; i < argc; ++i) { - const char *a = argv[i]; + const char* a = argv[i]; if (driver_streq(a, "-a") || driver_streq(a, "--debug-syms")) { - opts.debug_syms = 1; continue; + opts.debug_syms = 1; + continue; } if (driver_streq(a, "-g") || driver_streq(a, "--extern-only")) { - opts.extern_only = 1; continue; + opts.extern_only = 1; + continue; } if (driver_streq(a, "-u") || driver_streq(a, "--undefined-only")) { - opts.undef_only = 1; continue; + opts.undef_only = 1; + continue; } if (driver_streq(a, "--defined-only")) { - opts.defined_only = 1; continue; + opts.defined_only = 1; + continue; } if (driver_streq(a, "-n") || driver_streq(a, "--numeric-sort")) { - opts.numeric_sort = 1; continue; + opts.numeric_sort = 1; + continue; } if (driver_streq(a, "-r") || driver_streq(a, "--reverse-sort")) { - opts.reverse_sort = 1; continue; + opts.reverse_sort = 1; + continue; } if (driver_streq(a, "--no-sort") || driver_streq(a, "-p")) { - opts.no_sort = 1; continue; + opts.no_sort = 1; + continue; } if (driver_streq(a, "-A") || driver_streq(a, "--print-file-name")) { - opts.print_file = 1; continue; + opts.print_file = 1; + continue; } if (a[0] == '-') { driver_errf(NM_TOOL, "unknown option: %s", a); @@ -316,7 +320,7 @@ int driver_nm(int argc, char **argv) { goto done; } { - const char *path = a; + const char* path = a; DriverLoad ld = {0}; CfreeSlice input; if (driver_load_bytes(&env.file_io, NM_TOOL, path, &ld, &input) != 0) { diff --git a/driver/objcopy.c b/driver/objcopy.c @@ -1,12 +1,10 @@ -#include "driver.h" - -#include <stdint.h> -#include <string.h> - #include <cfree/archive.h> #include <cfree/core.h> #include <cfree/object.h> +#include <stdint.h> +#include <string.h> +#include "driver.h" #include "inputs.h" /* `cfree objcopy` — copy + transform an object file. v1 scope is the @@ -37,34 +35,39 @@ void driver_help_objcopy(void) { driver_printf( "%.*s", CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "cfree objcopy — copy and transform an object file\n" - "\n" - "USAGE\n" - " cfree objcopy [OPTIONS] INPUT [OUTPUT]\n" - "\n" - "SECTION OPS\n" - " --remove-section=NAME drop section NAME (may repeat)\n" - " --only-section=NAME keep only section NAME (may repeat)\n" - " --rename-section=OLD=NEW rename section OLD to NEW\n" - " --add-section=NAME=FILE append a new section with FILE's bytes\n" - " --update-section=NAME=FILE replace NAME's bytes with FILE's bytes\n" - "\n" - "SYMBOL OPS\n" - " --redefine-sym=OLD=NEW rename a symbol (may repeat)\n" - " --globalize-symbol=NAME set NAME's binding to global\n" - " --localize-symbol=NAME set NAME's binding to local\n" - " --weaken-symbol=NAME set NAME's binding to weak\n" - "\n" - "STRIP OPS\n" - " --strip-debug, --strip-unneeded, --strip-all\n" - " same semantics as `cfree strip`\n" - "\n" - "FORMAT\n" - " -O BFDNAME emit as a different format. Recognized\n" - " names: elf*, mach-o / macho*, coff*, wasm*\n" - "\n" - "EXIT CODES\n" - " 0 success 1 I/O or strip error 2 bad usage\n"))); + "cfree objcopy — copy and transform an object file\n" + "\n" + "USAGE\n" + " cfree objcopy [OPTIONS] INPUT [OUTPUT]\n" + "\n" + "SECTION OPS\n" + " --remove-section=NAME drop section NAME (may repeat)\n" + " --only-section=NAME keep only section NAME (may repeat)\n" + " --rename-section=OLD=NEW rename section OLD to NEW\n" + " --add-section=NAME=FILE append a new section with FILE's " + "bytes\n" + " --update-section=NAME=FILE replace NAME's bytes with FILE's " + "bytes\n" + "\n" + "SYMBOL OPS\n" + " --redefine-sym=OLD=NEW rename a symbol (may repeat)\n" + " --globalize-symbol=NAME set NAME's binding to global\n" + " --localize-symbol=NAME set NAME's binding to local\n" + " --weaken-symbol=NAME set NAME's binding to weak\n" + "\n" + "STRIP OPS\n" + " --strip-debug, --strip-unneeded, --strip-all\n" + " same semantics as `cfree strip`\n" + "\n" + "FORMAT\n" + " -O BFDNAME emit as a different format. " + "Recognized\n" + " names: elf*, mach-o / macho*, coff*, " + "wasm*\n" + "\n" + "EXIT CODES\n" + " 0 success 1 I/O or strip error 2 bad " + "usage\n"))); } typedef enum CopyOp { @@ -131,8 +134,8 @@ static int push_str(DriverEnv* env, const char*** arr, uint32_t* n, uint32_t* cap, const char* s) { if (*n >= *cap) { uint32_t newcap = *cap ? *cap * 2u : 4u; - const char** nb = (const char**)driver_alloc_zeroed( - env, (size_t)newcap * sizeof(*nb)); + const char** nb = + (const char**)driver_alloc_zeroed(env, (size_t)newcap * sizeof(*nb)); if (!nb) return -1; if (*arr) { memcpy(nb, *arr, (size_t)(*n) * sizeof(*nb)); @@ -245,8 +248,8 @@ static int apply_strip_pass(DriverEnv* env, CfreeObjFile* of, CfreeObjSymbol* needed = NULL; uint32_t nneeded = 0, cap_needed = 0; CfreeObjSymIter* sit = NULL; - int filter_syms = (opts->op == COPY_OP_STRIP_UNNEEDED || - opts->op == COPY_OP_STRIP_ALL); + int filter_syms = + (opts->op == COPY_OP_STRIP_UNNEEDED || opts->op == COPY_OP_STRIP_ALL); int rc = 1; if (opts->op == COPY_OP_NONE) return 0; @@ -370,8 +373,7 @@ static int run_transforms(DriverEnv* env, const CfreeContext* ctx, } else if (opts->nremove) { for (i = 0; i < opts->nremove; ++i) { CfreeObjSection sid = find_sec_id(of, opts->remove_sections[i]); - if (sid != CFREE_SECTION_NONE) - cfree_obj_builder_remove_section(b, sid); + if (sid != CFREE_SECTION_NONE) cfree_obj_builder_remove_section(b, sid); } } @@ -379,14 +381,14 @@ static int run_transforms(DriverEnv* env, const CfreeContext* ctx, for (i = 0; i < opts->nrename_sec; ++i) { CfreeObjSection sid = find_sec_id(of, opts->rename_sections[i].old_name); if (sid == CFREE_SECTION_NONE) { - driver_errf(OBJCOPY_TOOL, "rename-section: '%.*s' not found", - CFREE_SLICE_ARG( - cfree_slice_cstr(opts->rename_sections[i].old_name))); + driver_errf( + OBJCOPY_TOOL, "rename-section: '%.*s' not found", + CFREE_SLICE_ARG(cfree_slice_cstr(opts->rename_sections[i].old_name))); return 1; } - CfreeSym ns = cfree_sym_intern( - cfree_obj_builder_compiler(b), - cfree_slice_cstr(opts->rename_sections[i].new_name)); + CfreeSym ns = + cfree_sym_intern(cfree_obj_builder_compiler(b), + cfree_slice_cstr(opts->rename_sections[i].new_name)); cfree_obj_builder_rename_section(b, sid, ns); } @@ -395,17 +397,17 @@ static int run_transforms(DriverEnv* env, const CfreeContext* ctx, CfreeObjSection sid = find_sec_id(of, opts->update_sections[i].old_name); CfreeFileData fd = {0}; if (sid == CFREE_SECTION_NONE) { - driver_errf(OBJCOPY_TOOL, "update-section: '%.*s' not found", - CFREE_SLICE_ARG( - cfree_slice_cstr(opts->update_sections[i].old_name))); + driver_errf( + OBJCOPY_TOOL, "update-section: '%.*s' not found", + CFREE_SLICE_ARG(cfree_slice_cstr(opts->update_sections[i].old_name))); return 1; } if (ctx->file_io->read_all(ctx->file_io->user, opts->update_sections[i].new_name, &fd) != CFREE_OK) { - driver_errf(OBJCOPY_TOOL, "update-section: cannot read %.*s", - CFREE_SLICE_ARG( - cfree_slice_cstr(opts->update_sections[i].new_name))); + driver_errf( + OBJCOPY_TOOL, "update-section: cannot read %.*s", + CFREE_SLICE_ARG(cfree_slice_cstr(opts->update_sections[i].new_name))); return 1; } cfree_obj_builder_section_replace_bytes(b, sid, fd.data, fd.size); @@ -419,25 +421,25 @@ static int run_transforms(DriverEnv* env, const CfreeContext* ctx, CfreeObjSection nsid; CfreeFileData fd = {0}; if (ctx->file_io->read_all(ctx->file_io->user, - opts->add_sections[i].new_name, &fd) != - CFREE_OK) { - driver_errf(OBJCOPY_TOOL, "add-section: cannot read %.*s", - CFREE_SLICE_ARG( - cfree_slice_cstr(opts->add_sections[i].new_name))); + opts->add_sections[i].new_name, + &fd) != CFREE_OK) { + driver_errf( + OBJCOPY_TOOL, "add-section: cannot read %.*s", + CFREE_SLICE_ARG(cfree_slice_cstr(opts->add_sections[i].new_name))); return 1; } memset(&desc, 0, sizeof desc); - desc.name = cfree_sym_intern( - cfree_obj_builder_compiler(b), - cfree_slice_cstr(opts->add_sections[i].old_name)); + desc.name = + cfree_sym_intern(cfree_obj_builder_compiler(b), + cfree_slice_cstr(opts->add_sections[i].old_name)); desc.kind = CFREE_SEC_OTHER; desc.flags = 0; desc.align = 1; desc.entsize = 0; if (cfree_obj_builder_section(b, &desc, &nsid) != CFREE_OK) { - driver_errf(OBJCOPY_TOOL, "add-section: failed to create '%.*s'", - CFREE_SLICE_ARG( - cfree_slice_cstr(opts->add_sections[i].old_name))); + driver_errf( + OBJCOPY_TOOL, "add-section: failed to create '%.*s'", + CFREE_SLICE_ARG(cfree_slice_cstr(opts->add_sections[i].old_name))); ctx->file_io->release(ctx->file_io->user, &fd); return 1; } @@ -628,7 +630,8 @@ int driver_objcopy(int argc, char** argv) { if (matched) { const char *left, *right; if (split_pair(&env, val, &left, &right) != 0) { - driver_errf(OBJCOPY_TOOL, "update-section: expected NAME=FILE (got %.*s)", + driver_errf(OBJCOPY_TOOL, + "update-section: expected NAME=FILE (got %.*s)", CFREE_SLICE_ARG(cfree_slice_cstr(val))); rc = 2; goto done; diff --git a/driver/objdump.c b/driver/objdump.c @@ -1,11 +1,10 @@ -#include "driver.h" - -#include <stdio.h> - #include <cfree/archive.h> #include <cfree/core.h> #include <cfree/disasm.h> #include <cfree/object.h> +#include <stdio.h> + +#include "driver.h" /* `cfree objdump` — print section/symbol info, disassembly, hex contents, * and relocations for object files and archives. Archives are auto-detected @@ -32,71 +31,77 @@ typedef struct ObjdumpOpts { static void objdump_usage(void) { driver_errf(OBJDUMP_TOOL, "%.*s", CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "usage: cfree objdump [-h] [-t] [-d] [-D] [-r] [-s] [-j NAME " - "...] input...\n" - " cfree objdump --help for full option reference"))); + "usage: cfree objdump [-h] [-t] [-d] [-D] [-r] [-s] [-j NAME " + "...] input...\n" + " cfree objdump --help for full option reference"))); } void driver_help_objdump(void) { driver_printf( "%.*s", CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "cfree objdump — print info about object files and archives\n" - "\n" - "USAGE\n" - " cfree objdump [options] input ...\n" - "\n" - "DESCRIPTION\n" - " Prints section/symbol info, disassembly, hex contents, and\n" - " relocations for object files (ELF / COFF / Mach-O / Wasm) and `ar`\n" - " archives. Archives are auto-detected by magic; each member is\n" - " dumped in turn with an `archive(member)` label.\n" - "\n" - " With no operation flags the default is `-h -t` (section headers +\n" - " symbol table), matching GNU objdump's default-ish behaviour.\n" - "\n" - "OPERATIONS (any combination)\n" - " -f Print the file header: architecture, format,\n" - " section / symbol counts, HAS_RELOC / HAS_SYMS\n" - " flags, and (for PE images) image base,\n" - " entry point, and subsystem.\n" - " -h Print section headers (idx, name, size, align,\n" - " flags). For COFF inputs the raw\n" - " IMAGE_SCN_* Characteristics value is appended\n" - " on a continuation line and COMDAT groups are\n" - " printed after the section table. NOTE: this is\n" - " the GNU objdump meaning of -h — it does NOT\n" - " print this help; use --help.\n" - " -t Print the symbol table\n" - " -d Disassemble executable sections\n" - " -D Disassemble all sections\n" - " -r Print relocation records\n" - " -s Print section contents as a hex+ASCII dump\n" - " -p, --private-headers\n" - " Print PE optional header, data directories,\n" - " and per-DLL import lists (PE images only)\n" - " -x Aggregate: -f -h -r -t\n" - "\n" - "FILTERS\n" - " -j NAME Restrict output to the named section. Repeatable;\n" - " affects -h / -t / -d / -D / -r / -s.\n" - "\n" - "SUPPORTED INPUTS\n" - " *.o / *.obj Single object file (ELF / COFF / Mach-O / Wasm)\n" - " *.a POSIX `ar` archive — every object member is dumped\n" - " in turn with an `<archive>(<member>)` label\n" - "\n" - "GETTING HELP\n" - " --help Show this help and exit (-h is `section headers`)\n" - "\n" - "EXAMPLES\n" - " cfree objdump -d a.o\n" - " cfree objdump -h -j .text -j .rodata a.o\n" - " cfree objdump -t libfoo.a\n" - "\n" - "EXIT CODES\n" - " 0 success 1 parse / I/O error 2 bad " - "usage\n"))); + "cfree objdump — print info about object files and archives\n" + "\n" + "USAGE\n" + " cfree objdump [options] input ...\n" + "\n" + "DESCRIPTION\n" + " Prints section/symbol info, disassembly, hex contents, and\n" + " relocations for object files (ELF / COFF / Mach-O / Wasm) and " + "`ar`\n" + " archives. Archives are auto-detected by magic; each member is\n" + " dumped in turn with an `archive(member)` label.\n" + "\n" + " With no operation flags the default is `-h -t` (section headers " + "+\n" + " symbol table), matching GNU objdump's default-ish behaviour.\n" + "\n" + "OPERATIONS (any combination)\n" + " -f Print the file header: architecture, format,\n" + " section / symbol counts, HAS_RELOC / HAS_SYMS\n" + " flags, and (for PE images) image base,\n" + " entry point, and subsystem.\n" + " -h Print section headers (idx, name, size, align,\n" + " flags). For COFF inputs the raw\n" + " IMAGE_SCN_* Characteristics value is appended\n" + " on a continuation line and COMDAT groups are\n" + " printed after the section table. NOTE: this is\n" + " the GNU objdump meaning of -h — it does NOT\n" + " print this help; use --help.\n" + " -t Print the symbol table\n" + " -d Disassemble executable sections\n" + " -D Disassemble all sections\n" + " -r Print relocation records\n" + " -s Print section contents as a hex+ASCII dump\n" + " -p, --private-headers\n" + " Print PE optional header, data directories,\n" + " and per-DLL import lists (PE images only)\n" + " -x Aggregate: -f -h -r -t\n" + "\n" + "FILTERS\n" + " -j NAME Restrict output to the named section. " + "Repeatable;\n" + " affects -h / -t / -d / -D / -r / -s.\n" + "\n" + "SUPPORTED INPUTS\n" + " *.o / *.obj Single object file (ELF / COFF / Mach-O / " + "Wasm)\n" + " *.a POSIX `ar` archive — every object member is " + "dumped\n" + " in turn with an `<archive>(<member>)` label\n" + "\n" + "GETTING HELP\n" + " --help Show this help and exit (-h is `section " + "headers`)\n" + "\n" + "EXAMPLES\n" + " cfree objdump -d a.o\n" + " cfree objdump -h -j .text -j .rodata a.o\n" + " cfree objdump -t libfoo.a\n" + "\n" + "EXIT CODES\n" + " 0 success 1 parse / I/O error 2 bad " + "usage\n"))); } /* ---- PE/COFF private-header walker (used by `-p`) ---- @@ -304,9 +309,9 @@ static void pe_dump_imports(const uint8_t* buf, size_t buf_len, size_t sec_off, dll[0] = '\0'; } } - driver_printf(" DLL Name: %.*s\n", - CFREE_SLICE_ARG(cfree_slice_cstr(dll[0] ? dll - : "(unreadable)"))); + driver_printf( + " DLL Name: %.*s\n", + CFREE_SLICE_ARG(cfree_slice_cstr(dll[0] ? dll : "(unreadable)"))); driver_printf(" ILT RVA: 0x%x IAT RVA: 0x%x\n", ilt_rva, iat_rva); /* Prefer walking the original first thunk (ILT) for names. Some * mingw-emitted images zero the ILT and only ship the IAT; fall @@ -329,9 +334,8 @@ static void pe_dump_imports(const uint8_t* buf, size_t buf_len, size_t sec_off, long hint_off = pe_rva_to_file(buf, buf_len, sec_off, nsec, (uint32_t)t); char name[256]; - if (hint_off < 0 || - pe_read_cstr(buf, buf_len, (size_t)hint_off + 2u, name, - sizeof name) != 0) { + if (hint_off < 0 || pe_read_cstr(buf, buf_len, (size_t)hint_off + 2u, + name, sizeof name) != 0) { continue; } driver_printf(" Name: %.*s\n", @@ -399,15 +403,24 @@ static int pe_parse_image(const uint8_t* buf, size_t buf_len, PeImage* out) { static const char* pe_machine_name(uint16_t m) { switch (m) { - case 0x8664u: return "x86_64 (AMD64)"; - case 0xAA64u: return "aarch64 (ARM64)"; - case 0xA641u: return "aarch64 (ARM64EC)"; - case 0x014Cu: return "i386"; - case 0x01C0u: return "arm"; - case 0x01C4u: return "armnt"; - case 0x0200u: return "ia64"; - case 0x5064u: return "riscv64"; - default: return "unknown"; + case 0x8664u: + return "x86_64 (AMD64)"; + case 0xAA64u: + return "aarch64 (ARM64)"; + case 0xA641u: + return "aarch64 (ARM64EC)"; + case 0x014Cu: + return "i386"; + case 0x01C0u: + return "arm"; + case 0x01C4u: + return "armnt"; + case 0x0200u: + return "ia64"; + case 0x5064u: + return "riscv64"; + default: + return "unknown"; } } @@ -415,9 +428,10 @@ static const char* pe_machine_name(uint16_t m) { * Counterpart to dump_file_header for inputs that cfree_obj_open can't * parse yet (PE executables / DLLs vs .obj). */ static void dump_pe_file_header(const char* label, const PeImage* pe) { - driver_printf("%.*s:\tfile format pei-%.*s\n\n", - CFREE_SLICE_ARG(cfree_slice_cstr(label)), - CFREE_SLICE_ARG(cfree_slice_cstr(pe_machine_name(pe->machine)))); + driver_printf( + "%.*s:\tfile format pei-%.*s\n\n", + CFREE_SLICE_ARG(cfree_slice_cstr(label)), + CFREE_SLICE_ARG(cfree_slice_cstr(pe_machine_name(pe->machine)))); driver_printf("architecture: %.*s, flags 0x%04x\n", CFREE_SLICE_ARG(cfree_slice_cstr(pe_machine_name(pe->machine))), (unsigned)pe->file_chars); @@ -430,8 +444,9 @@ static void dump_pe_file_header(const char* label, const PeImage* pe) { (unsigned)pe->subsystem, CFREE_SLICE_ARG(cfree_slice_cstr(pe_subsystem_name(pe->subsystem)))); } else { - driver_printf("PE32 (magic 0x%x) — only PE32+ inspection is implemented\n\n", - (unsigned)pe->opt_magic); + driver_printf( + "PE32 (magic 0x%x) — only PE32+ inspection is implemented\n\n", + (unsigned)pe->opt_magic); } } @@ -478,8 +493,9 @@ static void dump_pe_sections(const char* label, const PeImage* pe, char name[9]; driver_printf("%.*s:\tSections (PE image):\n", CFREE_SLICE_ARG(cfree_slice_cstr(label))); - driver_printf("Idx Name VMA Size " - "FileOff Align Flags\n"); + driver_printf( + "Idx Name VMA Size " + "FileOff Align Flags\n"); for (i = 0; i < pe->nsec; ++i) { size_t sh = pe->sec_off + (size_t)i * PE_SECTION_HEADER_SIZE; uint32_t vsize; @@ -506,8 +522,10 @@ static void dump_pe_sections(const char* label, const PeImage* pe, name, (unsigned long long)(pe->image_base + va), vsize ? vsize : raw_size, raw_off, align_log2, CFREE_SLICE_ARG(cfree_slice_cstr(flagbuf))); - driver_printf(" Characteristics: 0x%08x\n", - ch); + driver_printf( + " " + "Characteristics: 0x%08x\n", + ch); } driver_printf("\n"); } @@ -539,9 +557,9 @@ static void dump_pe_private(const char* label, const uint8_t* buf, driver_printf(" ImageBase: 0x%llx\n", (unsigned long long)pe.image_base); driver_printf(" AddressOfEntryPoint: 0x%x\n", pe.entry_rva); - driver_printf(" Subsystem: %u (%.*s)\n", (unsigned)pe.subsystem, - CFREE_SLICE_ARG( - cfree_slice_cstr(pe_subsystem_name(pe.subsystem)))); + driver_printf( + " Subsystem: %u (%.*s)\n", (unsigned)pe.subsystem, + CFREE_SLICE_ARG(cfree_slice_cstr(pe_subsystem_name(pe.subsystem)))); driver_printf(" DllCharacteristics: 0x%04x\n", (unsigned)pe.dllchars); driver_printf(" NumberOfSections: %u\n", (unsigned)pe.nsec); @@ -549,10 +567,8 @@ static void dump_pe_private(const char* label, const uint8_t* buf, driver_printf("\nData Directories:\n"); driver_printf(" Idx Name RVA Size\n"); for (i = 0; i < PE_NUM_DATA_DIRS; ++i) { - uint32_t rva = - pe_rd_u32(buf + pe.dir_off + i * PE_DATA_DIRECTORY_SIZE); - uint32_t sz = - pe_rd_u32(buf + pe.dir_off + i * PE_DATA_DIRECTORY_SIZE + 4); + uint32_t rva = pe_rd_u32(buf + pe.dir_off + i * PE_DATA_DIRECTORY_SIZE); + uint32_t sz = pe_rd_u32(buf + pe.dir_off + i * PE_DATA_DIRECTORY_SIZE + 4); if (rva == 0 && sz == 0) continue; driver_printf(" %2u %-14s 0x%08x 0x%08x\n", i, pe_dir_name(i), rva, sz); if (i == PE_DIR_IMPORT) { @@ -562,8 +578,7 @@ static void dump_pe_private(const char* label, const uint8_t* buf, } if (import_rva && import_size) { - pe_dump_imports(buf, buf_len, pe.sec_off, pe.nsec, import_rva, - import_size); + pe_dump_imports(buf, buf_len, pe.sec_off, pe.nsec, import_rva, import_size); } } @@ -690,12 +705,11 @@ static void render_sec_flags(const CfreeObjSecInfo* sec, CfreeObjFmt fmt, } if (sec->entsize && n + 1 < cap) { char tmp[32]; - int k = snprintf(tmp, sizeof tmp, "%.*sentsize=%u", - CFREE_SLICE_ARG(cfree_slice_cstr(n ? "," : "")), - sec->entsize); + int k = + snprintf(tmp, sizeof tmp, "%.*sentsize=%u", + CFREE_SLICE_ARG(cfree_slice_cstr(n ? "," : "")), sec->entsize); size_t j; - for (j = 0; k > 0 && j < (size_t)k && n + 1 < cap; ++j) - buf[n++] = tmp[j]; + for (j = 0; k > 0 && j < (size_t)k && n + 1 < cap; ++j) buf[n++] = tmp[j]; } buf[n] = '\0'; } @@ -726,8 +740,10 @@ static void dump_sections(CfreeObjFile* f, const ObjdumpOpts* opts) { * by name, and the tag list above already covers the bits that * change behaviour at link time. */ if (fmt == CFREE_OBJ_COFF && raw_type) { - driver_printf(" Characteristics: 0x%08x\n", - raw_type); + driver_printf( + " Characteristics: " + "0x%08x\n", + raw_type); } } driver_printf("\n"); @@ -750,19 +766,19 @@ static void dump_groups(CfreeObjFile* f, const ObjdumpOpts* opts) { driver_printf("COMDAT groups:\n"); printed_header = 1; } - driver_printf(" group %.*s (signature sym #%u, %u section%.*s)\n", - CFREE_SLICE_ARG(g.name.len ? g.name - : CFREE_SLICE_LIT("(anon)")), - (unsigned)g.signature, (unsigned)g.nsections, - CFREE_SLICE_ARG(cfree_slice_cstr(g.nsections == 1 ? "" : "s"))); + driver_printf( + " group %.*s (signature sym #%u, %u section%.*s)\n", + CFREE_SLICE_ARG(g.name.len ? g.name : CFREE_SLICE_LIT("(anon)")), + (unsigned)g.signature, (unsigned)g.nsections, + CFREE_SLICE_ARG(cfree_slice_cstr(g.nsections == 1 ? "" : "s"))); for (k = 0; k < g.nsections; ++k) { CfreeObjSection sid = g.sections[k]; CfreeObjSecInfo si; if (sid == CFREE_SECTION_NONE) continue; if (cfree_obj_section(f, sid, &si) != CFREE_OK) continue; - driver_printf(" [%3u] %.*s\n", (unsigned)sid, - CFREE_SLICE_ARG(si.name.len ? si.name - : CFREE_SLICE_LIT("(anon)"))); + driver_printf( + " [%3u] %.*s\n", (unsigned)sid, + CFREE_SLICE_ARG(si.name.len ? si.name : CFREE_SLICE_LIT("(anon)"))); } } cfree_obj_groupiter_free(it); @@ -812,9 +828,9 @@ static void dump_hex(CfreeObjFile* f, const ObjdumpOpts* opts) { if (cfree_obj_section_data(f, i, &data, &len) != CFREE_OK) continue; if (!data || len == 0) continue; - driver_printf("Contents of section %.*s:\n", - CFREE_SLICE_ARG(sec.name.len ? sec.name - : CFREE_SLICE_LIT("(anon)"))); + driver_printf( + "Contents of section %.*s:\n", + CFREE_SLICE_ARG(sec.name.len ? sec.name : CFREE_SLICE_LIT("(anon)"))); for (ofs = 0; ofs < len; ofs += 16) { size_t j; char ascii[17]; @@ -855,9 +871,9 @@ static void dump_relocs(CfreeObjFile* f, const ObjdumpOpts* opts) { if (r.section != cur_sec) { if (printed_header) driver_printf("\n"); - driver_printf("RELOCATION RECORDS FOR [%.*s]:\n", - CFREE_SLICE_ARG(sec.name.len ? sec.name - : CFREE_SLICE_LIT("(anon)"))); + driver_printf( + "RELOCATION RECORDS FOR [%.*s]:\n", + CFREE_SLICE_ARG(sec.name.len ? sec.name : CFREE_SLICE_LIT("(anon)"))); driver_printf("OFFSET TYPE VALUE\n"); cur_sec = r.section; printed_header = 1; @@ -929,9 +945,9 @@ static void dump_disasm(const CfreeDisasmContext* dctx, CfreeObjFile* f, if (cfree_obj_section_data(f, i, &data, &len) != CFREE_OK) continue; if (!data || len == 0) continue; - driver_printf("Disassembly of section %.*s:\n\n", - CFREE_SLICE_ARG(sec.name.len ? sec.name - : CFREE_SLICE_LIT("(anon)"))); + driver_printf( + "Disassembly of section %.*s:\n\n", + CFREE_SLICE_ARG(sec.name.len ? sec.name : CFREE_SLICE_LIT("(anon)"))); if (cfree_disasm_iter_new(&file_dctx, data, len, 0, f, &dis) != CFREE_OK) continue; @@ -993,14 +1009,16 @@ static void dump_file_header(CfreeObjFile* f, const char* label) { if (nsym) flags |= 0x0010u; driver_printf("architecture: %.*s, flags 0x%08x:\n", - CFREE_SLICE_ARG(cfree_slice_cstr(arch_str(target.arch))), flags); + CFREE_SLICE_ARG(cfree_slice_cstr(arch_str(target.arch))), + flags); if (has_relocs) driver_printf("HAS_RELOC, "); if (nsym) driver_printf("HAS_SYMS"); if (has_relocs || nsym) driver_printf("\n"); driver_printf("start address 0x%016llx\n", 0ull); - driver_printf("format: %.*s, sections: %u, symbols: %u\n\n", - CFREE_SLICE_ARG(cfree_slice_cstr(fmt_str(fmt, target.ptr_size))), - nsec, nsym); + driver_printf( + "format: %.*s, sections: %u, symbols: %u\n\n", + CFREE_SLICE_ARG(cfree_slice_cstr(fmt_str(fmt, target.ptr_size))), nsec, + nsym); (void)label; } @@ -1009,10 +1027,11 @@ static void dump_obj(const CfreeDisasmContext* dctx, const char* label, CfreeTarget target = cfree_obj_target(f); CfreeObjFmt fmt = cfree_obj_fmt(f); - driver_printf("%.*s:\tfile format %.*s-%.*s\n\n", - CFREE_SLICE_ARG(cfree_slice_cstr(label)), - CFREE_SLICE_ARG(cfree_slice_cstr(fmt_str(fmt, target.ptr_size))), - CFREE_SLICE_ARG(cfree_slice_cstr(arch_str(target.arch)))); + driver_printf( + "%.*s:\tfile format %.*s-%.*s\n\n", + CFREE_SLICE_ARG(cfree_slice_cstr(label)), + CFREE_SLICE_ARG(cfree_slice_cstr(fmt_str(fmt, target.ptr_size))), + CFREE_SLICE_ARG(cfree_slice_cstr(arch_str(target.arch)))); if (opts->f) dump_file_header(f, label); if (opts->h) dump_sections(f, opts); @@ -1024,8 +1043,7 @@ static void dump_obj(const CfreeDisasmContext* dctx, const char* label, } static int dump_archive(const char* path, const CfreeSlice* input, - const CfreeContext* ctx, - const CfreeDisasmContext* dctx, + const CfreeContext* ctx, const CfreeDisasmContext* dctx, const ObjdumpOpts* opts) { CfreeArIter* it = NULL; CfreeArMember member; @@ -1180,8 +1198,9 @@ int driver_objdump(int argc, char** argv) { if (a[0] != '-' || a[1] == '\0') continue; if (driver_streq(a, "-j")) { if (i + 1 >= argc) { - driver_errf(OBJDUMP_TOOL, "%.*s", - CFREE_SLICE_ARG(CFREE_SLICE_LIT("-j requires a section name"))); + driver_errf( + OBJDUMP_TOOL, "%.*s", + CFREE_SLICE_ARG(CFREE_SLICE_LIT("-j requires a section name"))); rc = 2; goto done; } diff --git a/driver/ranlib.c b/driver/ranlib.c @@ -1,8 +1,7 @@ -#include <stdint.h> - #include <cfree/archive.h> #include <cfree/core.h> #include <cfree/object.h> +#include <stdint.h> #include "driver.h" #include "inputs.h" @@ -26,27 +25,28 @@ void driver_help_ranlib(void) { driver_printf( "%.*s", CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "cfree ranlib — refresh the symbol index of an `ar` archive\n" - "\n" - "USAGE\n" - " cfree ranlib ARCHIVE.a\n" - "\n" - "DESCRIPTION\n" - " Reads every member of ARCHIVE.a, rebuilds the archive in place\n" - " with a System-V `/` symbol-index member at the head. Member names,\n" - " contents, and order are preserved. Reproducible: when\n" - " SOURCE_DATE_EPOCH is set to a positive integer, that value is\n" - " written to ar_date for every member.\n" - "\n" - " Equivalent to `cfree ar s ARCHIVE.a` (the bare `s` modifier is\n" - " reserved by the POSIX ar grammar but not yet implemented).\n" - "\n" - "OPTIONS\n" - " -h, --help Show this help and exit\n" - "\n" - "EXIT CODES\n" - " 0 success 1 archive I/O error 2 bad " - "usage\n"))); + "cfree ranlib — refresh the symbol index of an `ar` archive\n" + "\n" + "USAGE\n" + " cfree ranlib ARCHIVE.a\n" + "\n" + "DESCRIPTION\n" + " Reads every member of ARCHIVE.a, rebuilds the archive in place\n" + " with a System-V `/` symbol-index member at the head. Member " + "names,\n" + " contents, and order are preserved. Reproducible: when\n" + " SOURCE_DATE_EPOCH is set to a positive integer, that value is\n" + " written to ar_date for every member.\n" + "\n" + " Equivalent to `cfree ar s ARCHIVE.a` (the bare `s` modifier is\n" + " reserved by the POSIX ar grammar but not yet implemented).\n" + "\n" + "OPTIONS\n" + " -h, --help Show this help and exit\n" + "\n" + "EXIT CODES\n" + " 0 success 1 archive I/O error 2 bad " + "usage\n"))); } static uint64_t ranlib_epoch_from_env(void) { @@ -181,8 +181,8 @@ int driver_ranlib(int argc, char** argv) { /* Pass 3: collect per-member global symbols. */ msyms = (CfreeArMemberSymbols*)driver_alloc_zeroed( &env, (size_t)nmembers * sizeof(*msyms)); - sym_allocs = (void**)driver_alloc_zeroed( - &env, (size_t)nmembers * sizeof(*sym_allocs)); + sym_allocs = + (void**)driver_alloc_zeroed(&env, (size_t)nmembers * sizeof(*sym_allocs)); sym_alloc_szs = (size_t*)driver_alloc_zeroed( &env, (size_t)nmembers * sizeof(*sym_alloc_szs)); if (!msyms || !sym_allocs || !sym_alloc_szs) { @@ -194,9 +194,9 @@ int driver_ranlib(int argc, char** argv) { size_t blob_size = 0; const CfreeSlice* names = NULL; uint32_t count = 0; - if (driver_collect_obj_global_syms(&env, &ctx, RANLIB_TOOL, &members[i].bytes, - &blob, &blob_size, &names, - &count) != 0) { + if (driver_collect_obj_global_syms(&env, &ctx, RANLIB_TOOL, + &members[i].bytes, &blob, &blob_size, + &names, &count) != 0) { goto out; } sym_allocs[i] = blob; @@ -228,8 +228,7 @@ out: driver_free(&env, sym_allocs, (size_t)nmembers * sizeof(*sym_allocs)); } if (sym_alloc_szs) - driver_free(&env, sym_alloc_szs, - (size_t)nmembers * sizeof(*sym_alloc_szs)); + driver_free(&env, sym_alloc_szs, (size_t)nmembers * sizeof(*sym_alloc_szs)); if (msyms) driver_free(&env, msyms, (size_t)nmembers * sizeof(*msyms)); if (name_storage) driver_free(&env, name_storage, name_bytes_total); if (members) driver_free(&env, members, (size_t)nmembers * sizeof(*members)); diff --git a/driver/run.c b/driver/run.c @@ -2,6 +2,7 @@ #include <cfree/core.h> #include <cfree/jit.h> #include <cfree/link.h> +#include <cfree/wasm.h> #include <stdint.h> #include <stdlib.h> @@ -10,12 +11,6 @@ #include "hosted.h" #include "inputs.h" -#include <cfree/compile.h> -#include <cfree/core.h> -#include <cfree/jit.h> -#include <cfree/link.h> -#include <cfree/wasm.h> - /* `cfree run` — JIT-compile one or more inputs and invoke the entry symbol * (default `main`) in-process. Args after `--` are passed to the JITed * program as argv. Mirrors the cc front-end for input shape (.c / - sources, @@ -73,9 +68,9 @@ typedef enum RunMetricEventKind { } RunMetricEventKind; typedef struct RunMetricEvent { - const char* name; /* aliased; callers pass string literals */ - uint64_t value; /* SCOPE: elapsed_ns; COUNT: count value */ - uint16_t depth; /* nesting depth at emit time (0-based) */ + const char* name; /* aliased; callers pass string literals */ + uint64_t value; /* SCOPE: elapsed_ns; COUNT: count value */ + uint16_t depth; /* nesting depth at emit time (0-based) */ uint16_t kind; } RunMetricEvent; @@ -241,73 +236,81 @@ void driver_help_run(void) { driver_printf( "%.*s", CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "cfree run — JIT-compile inputs and invoke the entry symbol in-process\n" - "\n" - "USAGE\n" - " cfree run [options] inputs... [-- prog-arg...]\n" - "\n" - "DESCRIPTION\n" - " Compiles and JIT-links every input, looks up the entry symbol\n" - " (default `main`), and calls it as `int(*)(int, char**)`. Args\n" - " after `--` are passed to the JITed program as argv. The driver\n" - " returns the entry's exit code, or 1 on a compile/link/lookup\n" - " error.\n" - "\n" - " Inputs are classified by suffix:\n" - " .c .cc .cpp C source\n" - " .wat .wasm WebAssembly source module\n" - " .o .obj object file\n" - " .a static archive\n" - " - read C source from stdin (single source only)\n" - "\n" - " JITed code may call any host symbol resolvable via " - "dlsym(RTLD_DEFAULT)\n" - " — typically libc. The JIT path forces PIC; -fPIC / -fPIE / -mcmodel\n" - " are accepted but have no observable effect.\n" - "\n" - "COMPILE OPTIONS\n" - " -O0 -O1 -O2 Optimization level (default -O0)\n" - " -g Emit DWARF debug info\n" - " --time, --metrics Emit scoped compile/link/JIT timing to stderr\n" - " --bench-time Emit parseable compile/JIT/execution timings\n" - " -e SYMBOL Entry symbol (default `main`)\n" - " -target TRIPLE Cross-compile target (see `cfree cc --help`)\n" - " --sysroot DIR Hosted libc sysroot for headers/defines with -lc\n" - " -lc Enable hosted libc headers/defines; calls resolve " - "via host dlsym\n" - " -fPIC -fpic Position-independent code (no-op for the JIT)\n" - " -fPIE -fpie Position-independent executable (no-op for the " - "JIT)\n" - " -mcmodel=MODEL small | medium | large (no-op for the JIT)\n" - " -Werror Treat warnings as errors\n" - " -fmax-errors=N Stop after N errors (0 = unlimited)\n" - "\n" - "PREPROCESSOR\n" - " -I DIR Add quoted-include search path\n" - " -isystem DIR Add system-include search path\n" - " -D NAME[=BODY] Define a macro\n" - " -U NAME Undefine a builtin/predefined macro\n" - "\n" - "ARGV PASSTHROUGH\n" - " -- End of `cfree run` options. Tokens after `--` are\n" - " passed to the JITed program's main(argc, argv)\n" - " starting at argv[1]. argv[0] is synthesized from\n" - " the first input (path, `<stdin>`, .o, or .a) so\n" - " JITed code can index argv[0] like a hosted\n" - " program. Without `--` the program receives\n" - " argc==1 with argv[0] set and argv[1]==NULL.\n" - "\n" - "GETTING HELP\n" - " -h, --help Show this help and exit\n" - "\n" - "EXAMPLES\n" - " cfree run hello.c\n" - " cfree run -O2 -DNDEBUG main.c util.c\n" - " cfree run main.c -- arg1 arg2\n" - "\n" - "EXIT CODES\n" - " Returns the exit code of the JITed entry, or 1 on internal failure.\n" - " 2 on bad command-line usage.\n"))); + "cfree run — JIT-compile inputs and invoke the entry symbol " + "in-process\n" + "\n" + "USAGE\n" + " cfree run [options] inputs... [-- prog-arg...]\n" + "\n" + "DESCRIPTION\n" + " Compiles and JIT-links every input, looks up the entry symbol\n" + " (default `main`), and calls it as `int(*)(int, char**)`. Args\n" + " after `--` are passed to the JITed program as argv. The driver\n" + " returns the entry's exit code, or 1 on a compile/link/lookup\n" + " error.\n" + "\n" + " Inputs are classified by suffix:\n" + " .c .cc .cpp C source\n" + " .wat .wasm WebAssembly source module\n" + " .o .obj object file\n" + " .a static archive\n" + " - read C source from stdin (single source only)\n" + "\n" + " JITed code may call any host symbol resolvable via " + "dlsym(RTLD_DEFAULT)\n" + " — typically libc. The JIT path forces PIC; -fPIC / -fPIE / " + "-mcmodel\n" + " are accepted but have no observable effect.\n" + "\n" + "COMPILE OPTIONS\n" + " -O0 -O1 -O2 Optimization level (default -O0)\n" + " -g Emit DWARF debug info\n" + " --time, --metrics Emit scoped compile/link/JIT timing to stderr\n" + " --bench-time Emit parseable compile/JIT/execution timings\n" + " -e SYMBOL Entry symbol (default `main`)\n" + " -target TRIPLE Cross-compile target (see `cfree cc --help`)\n" + " --sysroot DIR Hosted libc sysroot for headers/defines with " + "-lc\n" + " -lc Enable hosted libc headers/defines; calls " + "resolve " + "via host dlsym\n" + " -fPIC -fpic Position-independent code (no-op for the JIT)\n" + " -fPIE -fpie Position-independent executable (no-op for the " + "JIT)\n" + " -mcmodel=MODEL small | medium | large (no-op for the JIT)\n" + " -Werror Treat warnings as errors\n" + " -fmax-errors=N Stop after N errors (0 = unlimited)\n" + "\n" + "PREPROCESSOR\n" + " -I DIR Add quoted-include search path\n" + " -isystem DIR Add system-include search path\n" + " -D NAME[=BODY] Define a macro\n" + " -U NAME Undefine a builtin/predefined macro\n" + "\n" + "ARGV PASSTHROUGH\n" + " -- End of `cfree run` options. Tokens after `--` " + "are\n" + " passed to the JITed program's main(argc, argv)\n" + " starting at argv[1]. argv[0] is synthesized " + "from\n" + " the first input (path, `<stdin>`, .o, or .a) " + "so\n" + " JITed code can index argv[0] like a hosted\n" + " program. Without `--` the program receives\n" + " argc==1 with argv[0] set and argv[1]==NULL.\n" + "\n" + "GETTING HELP\n" + " -h, --help Show this help and exit\n" + "\n" + "EXAMPLES\n" + " cfree run hello.c\n" + " cfree run -O2 -DNDEBUG main.c util.c\n" + " cfree run main.c -- arg1 arg2\n" + "\n" + "EXIT CODES\n" + " Returns the exit code of the JITed entry, or 1 on internal " + "failure.\n" + " 2 on bad command-line usage.\n"))); } static int run_alloc_arrays(RunOptions* o, int argc) { @@ -681,10 +684,9 @@ static int run_call_wasm_entry(RunOptions* ro, CfreeCompiler* compiler, h_imports = canned; h_nimports = ncanned; } - if (cfree_wasm_bind_host_imports(compiler, jit, - (CfreeWasmInstance*)instance, h_imports, - h_nimports, h_resolve, h_user) != - CFREE_OK) { + if (cfree_wasm_bind_host_imports( + compiler, jit, (CfreeWasmInstance*)instance, h_imports, h_nimports, + h_resolve, h_user) != CFREE_OK) { driver_errf(RUN_TOOL, "wasm host import bind failed"); driver_free(ro->env, memory, 16u * 1024u * 1024u); driver_free(ro->env, instance, 64u * 1024u); diff --git a/driver/runtime.c b/driver/runtime.c @@ -24,13 +24,13 @@ typedef struct RuntimeVariant { } RuntimeVariant; static const char* const kRtSrcX64[] = { - "assert/assert.c", "int/int.c", - "int/si_div.c", "fp/fp.c", - "mem/mem.c", "string/string.c", - "stdlib/stdlib.c", "stdlib/qsort.c", - "stdio/printf.c", "atomic/atomic_freestanding.c", + "assert/assert.c", "int/int.c", + "int/si_div.c", "fp/fp.c", + "mem/mem.c", "string/string.c", + "stdlib/stdlib.c", "stdlib/qsort.c", + "stdio/printf.c", "atomic/atomic_freestanding.c", "cache/clear_cache.c", "cfree/ifunc_init.c", - "int64/int64.c", "coro/x86_64.c", + "int64/int64.c", "coro/x86_64.c", "coro/coro.c", }; diff --git a/driver/size.c b/driver/size.c @@ -1,13 +1,12 @@ -#include "driver.h" - +#include <cfree/archive.h> +#include <cfree/core.h> +#include <cfree/object.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <cfree/archive.h> -#include <cfree/core.h> -#include <cfree/object.h> +#include "driver.h" #define SIZE_TOOL "size" @@ -23,10 +22,10 @@ typedef enum SizeRadix { } SizeRadix; typedef struct SizeOpts { - SizeFmt fmt; /* -A => SYSV, default BERKELEY */ - SizeRadix radix; /* default hex; -d => DEC, -o => OCT */ - int common; /* --common */ - int totals; /* -t / --totals (berkeley only) */ + SizeFmt fmt; /* -A => SYSV, default BERKELEY */ + SizeRadix radix; /* default hex; -d => DEC, -o => OCT */ + int common; /* --common */ + int totals; /* -t / --totals (berkeley only) */ } SizeOpts; typedef struct SizeAgg { @@ -36,8 +35,8 @@ typedef struct SizeAgg { uint64_t total; } SizeAgg; -static void size_classify_section(const CfreeObjSecInfo *sec, int *is_text, - int *is_data, int *is_bss) { +static void size_classify_section(const CfreeObjSecInfo* sec, int* is_text, + int* is_data, int* is_bss) { int alloc = (sec->flags & CFREE_SF_ALLOC) != 0; int exec = (sec->flags & CFREE_SF_EXEC) != 0; int write = (sec->flags & CFREE_SF_WRITE) != 0; @@ -68,7 +67,7 @@ static void size_classify_section(const CfreeObjSecInfo *sec, int *is_text, *is_data = 1; } -static SizeAgg size_compute_obj(CfreeObjFile *of, const SizeOpts *opts) { +static SizeAgg size_compute_obj(CfreeObjFile* of, const SizeOpts* opts) { SizeAgg a; uint32_t ns, i; memset(&a, 0, sizeof a); @@ -80,10 +79,10 @@ static SizeAgg size_compute_obj(CfreeObjFile *of, const SizeOpts *opts) { size_classify_section(&sec, &is_text, &is_data, &is_bss); if (is_text) a.text += sec.size; if (is_data) a.data += sec.size; - if (is_bss) a.bss += sec.size; + if (is_bss) a.bss += sec.size; } if (opts->common) { - CfreeObjSymIter *it = NULL; + CfreeObjSymIter* it = NULL; if (cfree_obj_symiter_new(of, &it) == CFREE_OK) { for (;;) { CfreeObjSymInfo si; @@ -97,8 +96,8 @@ static SizeAgg size_compute_obj(CfreeObjFile *of, const SizeOpts *opts) { return a; } -static void size_print_val(uint64_t v, SizeRadix radix, int width, - char *buf, size_t buf_size) { +static void size_print_val(uint64_t v, SizeRadix radix, int width, char* buf, + size_t buf_size) { switch (radix) { case SIZE_RAD_DEC: snprintf(buf, buf_size, "%*llu", width, (unsigned long long)v); @@ -116,27 +115,27 @@ static int size_width(SizeRadix radix) { return (radix == SIZE_RAD_OCT) ? 10 : (radix == SIZE_RAD_DEC) ? 8 : 7; } -static void size_print_berkeley_header(const SizeOpts *opts) { +static void size_print_berkeley_header(const SizeOpts* opts) { int w = size_width(opts->radix); - driver_printf(" %-*s %-*s %-*s %8s %7s filename\n", - w, "text", w, "data", w, "bss", "dec", "hex"); + driver_printf(" %-*s %-*s %-*s %8s %7s filename\n", w, "text", w, + "data", w, "bss", "dec", "hex"); } -static void size_print_berkeley_sums(const SizeAgg *a, const char *name, - const SizeOpts *opts) { +static void size_print_berkeley_sums(const SizeAgg* a, const char* name, + const SizeOpts* opts) { int w = size_width(opts->radix); char text_buf[32], data_buf[32], bss_buf[32], dec_buf[32], hex_buf[32]; size_print_val(a->text, opts->radix, w, text_buf, sizeof text_buf); size_print_val(a->data, opts->radix, w, data_buf, sizeof data_buf); - size_print_val(a->bss, opts->radix, w, bss_buf, sizeof bss_buf); + size_print_val(a->bss, opts->radix, w, bss_buf, sizeof bss_buf); size_print_val(a->total, SIZE_RAD_DEC, 8, dec_buf, sizeof dec_buf); size_print_val(a->total, SIZE_RAD_HEX, 7, hex_buf, sizeof hex_buf); - driver_printf(" %s %s %s %s %s %s\n", - text_buf, data_buf, bss_buf, dec_buf, hex_buf, name); + driver_printf(" %s %s %s %s %s %s\n", text_buf, data_buf, bss_buf, + dec_buf, hex_buf, name); } -static void size_print_sysv(CfreeObjFile *of, const char *name, - const SizeOpts *opts) { +static void size_print_sysv(CfreeObjFile* of, const char* name, + const SizeOpts* opts) { uint32_t ns, i; driver_printf("%s :\n", name); driver_printf("section size addr\n"); @@ -152,8 +151,7 @@ static void size_print_sysv(CfreeObjFile *of, const char *name, } driver_printf("%-16.16s %08llx %08llx\n", sec.name.len ? sec.name.s : "(anon)", - (unsigned long long)sec.size, - (unsigned long long)addr); + (unsigned long long)sec.size, (unsigned long long)addr); } { SizeAgg a = size_compute_obj(of, opts); @@ -161,12 +159,12 @@ static void size_print_sysv(CfreeObjFile *of, const char *name, } } -static int size_process_file(const CfreeContext *ctx, const CfreeSlice *input, - const char *path, const SizeOpts *opts, - SizeAgg *total_out, int *any_out) { +static int size_process_file(const CfreeContext* ctx, const CfreeSlice* input, + const char* path, const SizeOpts* opts, + SizeAgg* total_out, int* any_out) { CfreeBinFmt fmt = cfree_detect_fmt(input->data, input->len); if (fmt == CFREE_BIN_AR) { - CfreeArIter *it = NULL; + CfreeArIter* it = NULL; if (cfree_ar_iter_new(ctx, input, &it) != CFREE_OK) { driver_errf(SIZE_TOOL, "%s: not a recognized archive", path); return 1; @@ -174,7 +172,7 @@ static int size_process_file(const CfreeContext *ctx, const CfreeSlice *input, for (;;) { CfreeArMember m; if (cfree_ar_iter_next(it, &m) != CFREE_ITER_ITEM) break; - CfreeObjFile *of = NULL; + CfreeObjFile* of = NULL; CfreeSlice mb; mb.data = m.data; mb.len = m.size; @@ -188,13 +186,13 @@ static int size_process_file(const CfreeContext *ctx, const CfreeSlice *input, size_print_berkeley_sums(&a, nmbuf, opts); } else { char nmbuf[512]; - snprintf(nmbuf, sizeof nmbuf, "%s(%.*s)", path, - (int)m.name.len, m.name.s); + snprintf(nmbuf, sizeof nmbuf, "%s(%.*s)", path, (int)m.name.len, + m.name.s); size_print_sysv(of, nmbuf, opts); } - total_out->text += a.text; - total_out->data += a.data; - total_out->bss += a.bss; + total_out->text += a.text; + total_out->data += a.data; + total_out->bss += a.bss; total_out->total += a.total; *any_out = 1; cfree_obj_free(of); @@ -202,7 +200,7 @@ static int size_process_file(const CfreeContext *ctx, const CfreeSlice *input, } cfree_ar_iter_free(it); } else { - CfreeObjFile *of = NULL; + CfreeObjFile* of = NULL; if (cfree_obj_open(ctx, cfree_slice_cstr(path), input, &of) != CFREE_OK) { driver_errf(SIZE_TOOL, "%s: not a recognized object file", path); return 1; @@ -214,9 +212,9 @@ static int size_process_file(const CfreeContext *ctx, const CfreeSlice *input, } else { size_print_sysv(of, path, opts); } - total_out->text += a.text; - total_out->data += a.data; - total_out->bss += a.bss; + total_out->text += a.text; + total_out->data += a.data; + total_out->bss += a.bss; total_out->total += a.total; } *any_out = 1; @@ -229,23 +227,23 @@ void driver_help_size(void) { driver_printf( "%.*s", CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "cfree size — display section sizes of object files\n" - "\n" - "USAGE\n" - " cfree size [OPTIONS] FILE...\n" - "\n" - "OPTIONS\n" - " -A, --format sysv SysV output (section-by-section)\n" - " -B, --format berkeley Berkeley output (default)\n" - " -d sizes in decimal\n" - " -o sizes in octal\n" - " -x sizes in hexadecimal\n" - " --common include COMMON symbols in bss total\n" - " -t, --totals print a totals line (Berkeley only)\n" - " -h, --help show this help\n"))); + "cfree size — display section sizes of object files\n" + "\n" + "USAGE\n" + " cfree size [OPTIONS] FILE...\n" + "\n" + "OPTIONS\n" + " -A, --format sysv SysV output (section-by-section)\n" + " -B, --format berkeley Berkeley output (default)\n" + " -d sizes in decimal\n" + " -o sizes in octal\n" + " -x sizes in hexadecimal\n" + " --common include COMMON symbols in bss total\n" + " -t, --totals print a totals line (Berkeley only)\n" + " -h, --help show this help\n"))); } -int driver_size(int argc, char **argv) { +int driver_size(int argc, char** argv) { DriverEnv env; CfreeContext ctx; SizeOpts opts; @@ -264,27 +262,34 @@ int driver_size(int argc, char **argv) { ctx = driver_env_to_context(&env); for (i = 1; i < argc; ++i) { - const char *a = argv[i]; + const char* a = argv[i]; if (driver_streq(a, "-A") || driver_streq(a, "--format=sysv")) { - opts.fmt = SIZE_FMT_SYSV; continue; + opts.fmt = SIZE_FMT_SYSV; + continue; } if (driver_streq(a, "-B") || driver_streq(a, "--format=berkeley")) { - opts.fmt = SIZE_FMT_BERKELEY; continue; + opts.fmt = SIZE_FMT_BERKELEY; + continue; } if (driver_streq(a, "-d")) { - opts.radix = SIZE_RAD_DEC; continue; + opts.radix = SIZE_RAD_DEC; + continue; } if (driver_streq(a, "-o")) { - opts.radix = SIZE_RAD_OCT; continue; + opts.radix = SIZE_RAD_OCT; + continue; } if (driver_streq(a, "-x")) { - opts.radix = SIZE_RAD_HEX; continue; + opts.radix = SIZE_RAD_HEX; + continue; } if (driver_streq(a, "--common")) { - opts.common = 1; continue; + opts.common = 1; + continue; } if (driver_streq(a, "-t") || driver_streq(a, "--totals")) { - opts.totals = 1; continue; + opts.totals = 1; + continue; } if (a[0] == '-') { driver_errf(SIZE_TOOL, "unknown option: %s", a); @@ -300,11 +305,10 @@ int driver_size(int argc, char **argv) { goto done; } - if (opts.fmt == SIZE_FMT_BERKELEY) - size_print_berkeley_header(&opts); + if (opts.fmt == SIZE_FMT_BERKELEY) size_print_berkeley_header(&opts); for (i = 1; i < argc; ++i) { - const char *a = argv[i]; + const char* a = argv[i]; if (driver_streq(a, "-A") || driver_streq(a, "--format=sysv") || driver_streq(a, "-B") || driver_streq(a, "--format=berkeley") || driver_streq(a, "-d") || driver_streq(a, "-o") || @@ -313,15 +317,15 @@ int driver_size(int argc, char **argv) { continue; } { - const char *path = a; + const char* path = a; DriverLoad ld = {0}; CfreeSlice input; if (driver_load_bytes(&env.file_io, SIZE_TOOL, path, &ld, &input) != 0) { rc = 1; goto done; } - if (size_process_file(&ctx, &input, path, &opts, &totals, - &any_output) != 0) { + if (size_process_file(&ctx, &input, path, &opts, &totals, &any_output) != + 0) { driver_release_bytes(&env.file_io, &ld); rc = 1; goto done; @@ -341,11 +345,11 @@ int driver_size(int argc, char **argv) { char text_buf[32], data_buf[32], bss_buf[32], dec_buf[32], hex_buf[32]; size_print_val(totals.text, opts.radix, w, text_buf, sizeof text_buf); size_print_val(totals.data, opts.radix, w, data_buf, sizeof data_buf); - size_print_val(totals.bss, opts.radix, w, bss_buf, sizeof bss_buf); + size_print_val(totals.bss, opts.radix, w, bss_buf, sizeof bss_buf); size_print_val(totals.total, SIZE_RAD_DEC, 8, dec_buf, sizeof dec_buf); size_print_val(totals.total, SIZE_RAD_HEX, 7, hex_buf, sizeof hex_buf); - driver_printf(" %s %s %s %s %s (TOTALS)\n", - text_buf, data_buf, bss_buf, dec_buf, hex_buf); + driver_printf(" %s %s %s %s %s (TOTALS)\n", text_buf, data_buf, bss_buf, + dec_buf, hex_buf); } rc = 0; diff --git a/driver/strip.c b/driver/strip.c @@ -1,12 +1,10 @@ -#include "driver.h" - -#include <stdint.h> -#include <string.h> - #include <cfree/archive.h> #include <cfree/core.h> #include <cfree/object.h> +#include <stdint.h> +#include <string.h> +#include "driver.h" #include "inputs.h" /* `cfree strip` — drop debug sections and / or unwanted symbols from a @@ -20,7 +18,8 @@ * --strip-all drop debug + every non-essential symbol (default) * * Filters applied on top of the operation: - * --keep-symbol=NAME, -K NAME keep NAME even if the operation would drop it + * --keep-symbol=NAME, -K NAME keep NAME even if the operation would drop + * it * --strip-symbol=NAME, -N NAME always drop NAME * * I/O: @@ -33,30 +32,33 @@ void driver_help_strip(void) { driver_printf( "%.*s", CFREE_SLICE_ARG(CFREE_SLICE_LIT( - "cfree strip — drop debug sections and/or symbols\n" - "\n" - "USAGE\n" - " cfree strip [OPTIONS] FILE\n" - "\n" - "OPERATIONS (last one wins; default is --strip-all)\n" - " --strip-debug remove debug-info sections\n" - " --strip-unneeded remove debug + symbols not needed by relocs\n" - " --strip-all remove debug + all non-essential symbols\n" - "\n" - "SYMBOL FILTERS (may repeat)\n" - " --keep-symbol=NAME, -K NAME keep NAME even when the operation\n" - " would otherwise drop it\n" - " --strip-symbol=NAME, -N NAME always drop NAME\n" - "\n" - "OUTPUT\n" - " -o PATH write to PATH (default: rewrite FILE in place)\n" - "\n" - "INPUTS\n" - " FILE may be a relocatable .o or a static .a archive. Linked\n" - " executables / shared libraries are not supported yet.\n" - "\n" - "EXIT CODES\n" - " 0 success 1 I/O or strip error 2 bad usage\n"))); + "cfree strip — drop debug sections and/or symbols\n" + "\n" + "USAGE\n" + " cfree strip [OPTIONS] FILE\n" + "\n" + "OPERATIONS (last one wins; default is --strip-all)\n" + " --strip-debug remove debug-info sections\n" + " --strip-unneeded remove debug + symbols not needed by " + "relocs\n" + " --strip-all remove debug + all non-essential symbols\n" + "\n" + "SYMBOL FILTERS (may repeat)\n" + " --keep-symbol=NAME, -K NAME keep NAME even when the operation\n" + " would otherwise drop it\n" + " --strip-symbol=NAME, -N NAME always drop NAME\n" + "\n" + "OUTPUT\n" + " -o PATH write to PATH (default: rewrite FILE in " + "place)\n" + "\n" + "INPUTS\n" + " FILE may be a relocatable .o or a static .a archive. Linked\n" + " executables / shared libraries are not supported yet.\n" + "\n" + "EXIT CODES\n" + " 0 success 1 I/O or strip error 2 bad " + "usage\n"))); } typedef enum StripOp { @@ -90,8 +92,8 @@ static int push_name(DriverEnv* env, const char*** arr, uint32_t* n, uint32_t* cap, const char* name) { if (*n >= *cap) { uint32_t newcap = *cap ? *cap * 2u : 8u; - const char** nb = (const char**)driver_alloc_zeroed( - env, (size_t)newcap * sizeof(*nb)); + const char** nb = + (const char**)driver_alloc_zeroed(env, (size_t)newcap * sizeof(*nb)); if (!nb) { driver_errf(STRIP_TOOL, "out of memory"); return -1; @@ -213,8 +215,7 @@ static int id_in_set(CfreeObjSymbol id, const CfreeObjSymbol* arr, uint32_t n) { static int strip_one_builder(DriverEnv* env, CfreeObjFile* of, CfreeObjBuilder* b, const StripOpts* opts) { uint32_t i, nsec; - int filter_syms = (opts->op == STRIP_OP_UNNEEDED || - opts->op == STRIP_OP_ALL); + int filter_syms = (opts->op == STRIP_OP_UNNEEDED || opts->op == STRIP_OP_ALL); CfreeObjSymbol* needed = NULL; uint32_t nneeded = 0, cap_needed = 0; CfreeObjSymIter* sit = NULL; @@ -468,9 +469,9 @@ static int strip_archive(DriverEnv* env, const CfreeContext* ctx, size_t blob_size = 0; const CfreeSlice* names = NULL; uint32_t count = 0; - if (driver_collect_obj_global_syms(env, ctx, STRIP_TOOL, &members[k].bytes, - &blob, &blob_size, &names, - &count) != 0) { + if (driver_collect_obj_global_syms(env, ctx, STRIP_TOOL, + &members[k].bytes, &blob, &blob_size, + &names, &count) != 0) { goto done; } sym_allocs[k] = blob; @@ -505,8 +506,7 @@ done: driver_free(env, sym_allocs, (size_t)nmembers * sizeof(*sym_allocs)); } if (sym_alloc_szs) - driver_free(env, sym_alloc_szs, - (size_t)nmembers * sizeof(*sym_alloc_szs)); + driver_free(env, sym_alloc_szs, (size_t)nmembers * sizeof(*sym_alloc_szs)); if (msyms) driver_free(env, msyms, (size_t)nmembers * sizeof(*msyms)); if (owned_data) { for (k = 0; k < nmembers; ++k) { @@ -639,8 +639,7 @@ int driver_strip(int argc, char** argv) { 0) { goto done; } - if (ctx.file_io->open_writer(ctx.file_io->user, out_path, &w) != - CFREE_OK) { + if (ctx.file_io->open_writer(ctx.file_io->user, out_path, &w) != CFREE_OK) { driver_errf(STRIP_TOOL, "failed to open: %.*s", CFREE_SLICE_ARG(cfree_slice_cstr(out_path))); goto done; @@ -659,7 +658,8 @@ done: if (out_data) driver_free(&env, out_data, out_size); if (have_input) ctx.file_io->release(ctx.file_io->user, &input_fd); if (opts.keep) - driver_free(&env, (void*)opts.keep, (size_t)opts.cap_keep * sizeof(*opts.keep)); + driver_free(&env, (void*)opts.keep, + (size_t)opts.cap_keep * sizeof(*opts.keep)); if (opts.strip) driver_free(&env, (void*)opts.strip, (size_t)opts.cap_strip * sizeof(*opts.strip)); diff --git a/include/cfree/arch.h b/include/cfree/arch.h @@ -19,11 +19,12 @@ typedef struct CfreeArchReg { CfreeSlice name; } CfreeArchReg; -CFREE_API CfreeSlice cfree_arch_register_name(CfreeArchKind, uint32_t dwarf_idx); +CFREE_API CfreeSlice cfree_arch_register_name(CfreeArchKind, + uint32_t dwarf_idx); CFREE_API CfreeStatus cfree_arch_register_index(CfreeArchKind, CfreeSlice name, - uint32_t *idx_out); + uint32_t* idx_out); CFREE_API uint32_t cfree_arch_register_count(CfreeArchKind); CFREE_API CfreeStatus cfree_arch_register_at(CfreeArchKind, uint32_t idx, - CfreeArchReg *out); + CfreeArchReg* out); #endif diff --git a/include/cfree/archive.h b/include/cfree/archive.h @@ -11,7 +11,7 @@ */ typedef struct CfreeArMemberSymbols { - const CfreeSlice *names; + const CfreeSlice* names; uint32_t count; } CfreeArMemberSymbols; @@ -19,7 +19,7 @@ typedef struct CfreeArWriteOptions { uint64_t epoch; int symbol_index; int long_names; - const CfreeArMemberSymbols *member_symbols; + const CfreeArMemberSymbols* member_symbols; } CfreeArWriteOptions; /* One member to be written into an archive: its name (e.g. "foo.o") and its @@ -29,22 +29,25 @@ typedef struct CfreeArInput { CfreeSlice bytes; } CfreeArInput; -CFREE_API CfreeStatus cfree_ar_write(CfreeWriter *out, const CfreeArInput *members, - uint32_t nmembers, - const CfreeArWriteOptions *opts); -CFREE_API CfreeStatus cfree_ar_list(const CfreeSlice *archive, CfreeWriter *out); +CFREE_API CfreeStatus cfree_ar_write(CfreeWriter* out, + const CfreeArInput* members, + uint32_t nmembers, + const CfreeArWriteOptions* opts); +CFREE_API CfreeStatus cfree_ar_list(const CfreeSlice* archive, + CfreeWriter* out); typedef struct CfreeArIter CfreeArIter; typedef struct CfreeArMember { CfreeSlice name; - const uint8_t *data; + const uint8_t* data; size_t size; } CfreeArMember; -CFREE_API CfreeStatus cfree_ar_iter_new(const CfreeContext *, const CfreeSlice *archive, - CfreeArIter **out); -CFREE_API CfreeIterResult cfree_ar_iter_next(CfreeArIter *, CfreeArMember *out); -CFREE_API void cfree_ar_iter_free(CfreeArIter *); +CFREE_API CfreeStatus cfree_ar_iter_new(const CfreeContext*, + const CfreeSlice* archive, + CfreeArIter** out); +CFREE_API CfreeIterResult cfree_ar_iter_next(CfreeArIter*, CfreeArMember* out); +CFREE_API void cfree_ar_iter_free(CfreeArIter*); #endif diff --git a/include/cfree/asm_emit.h b/include/cfree/asm_emit.h @@ -4,6 +4,7 @@ #include <cfree/core.h> #include <cfree/object.h> -CFREE_API CfreeStatus cfree_obj_builder_emit_asm(CfreeObjBuilder *, CfreeWriter *); +CFREE_API CfreeStatus cfree_obj_builder_emit_asm(CfreeObjBuilder*, + CfreeWriter*); #endif diff --git a/include/cfree/cg.h b/include/cfree/cg.h @@ -149,21 +149,22 @@ CFREE_API CfreeCgBuiltinTypes cfree_cg_builtin_types(CfreeCompiler*); * address space. */ CFREE_API CfreeCgTypeId cfree_cg_type_func(CfreeCompiler*, CfreeCgFuncSig sig); CFREE_API CfreeCgTypeId cfree_cg_type_ptr(CfreeCompiler*, CfreeCgTypeId pointee, - uint32_t address_space); + uint32_t address_space); CFREE_API CfreeCgTypeId cfree_cg_type_array(CfreeCompiler*, CfreeCgTypeId elem, - uint64_t count); + uint64_t count); /* Fresh nominal/source-facing types. Enums use a width-only integer base. */ CFREE_API CfreeCgTypeId cfree_cg_type_alias(CfreeCompiler*, CfreeSym name, - CfreeCgTypeId base); + CfreeCgTypeId base); CFREE_API CfreeCgTypeId cfree_cg_type_record(CfreeCompiler*, CfreeSym tag, - const CfreeCgField* fields, - uint32_t nfields); -CFREE_API CfreeCgTypeId cfree_cg_type_record_ex(CfreeCompiler*, const CfreeCgRecordDesc*); + const CfreeCgField* fields, + uint32_t nfields); +CFREE_API CfreeCgTypeId cfree_cg_type_record_ex(CfreeCompiler*, + const CfreeCgRecordDesc*); CFREE_API CfreeCgTypeId cfree_cg_type_enum(CfreeCompiler*, CfreeSym tag, - CfreeCgTypeId base, - const CfreeCgEnumValue* values, - uint32_t nvalues); + CfreeCgTypeId base, + const CfreeCgEnumValue* values, + uint32_t nvalues); /* Type queries. These report codegen storage, ABI, and target layout facts. */ CFREE_API CfreeCgTypeKind cfree_cg_type_kind(CfreeCompiler*, CfreeCgTypeId); @@ -172,24 +173,30 @@ CFREE_API uint32_t cfree_cg_type_align(CfreeCompiler*, CfreeCgTypeId); CFREE_API uint32_t cfree_cg_type_int_width(CfreeCompiler*, CfreeCgTypeId); CFREE_API uint32_t cfree_cg_type_float_width(CfreeCompiler*, CfreeCgTypeId); -CFREE_API CfreeCgTypeId cfree_cg_type_ptr_pointee(CfreeCompiler*, CfreeCgTypeId); -CFREE_API uint32_t cfree_cg_type_ptr_address_space(CfreeCompiler*, CfreeCgTypeId); +CFREE_API CfreeCgTypeId cfree_cg_type_ptr_pointee(CfreeCompiler*, + CfreeCgTypeId); +CFREE_API uint32_t cfree_cg_type_ptr_address_space(CfreeCompiler*, + CfreeCgTypeId); CFREE_API CfreeCgTypeId cfree_cg_type_array_elem(CfreeCompiler*, CfreeCgTypeId); CFREE_API uint64_t cfree_cg_type_array_count(CfreeCompiler*, CfreeCgTypeId); CFREE_API CfreeCgTypeId cfree_cg_type_func_ret(CfreeCompiler*, CfreeCgTypeId); -CFREE_API CfreeCgAbiAttrs cfree_cg_type_func_ret_attrs(CfreeCompiler*, CfreeCgTypeId); +CFREE_API CfreeCgAbiAttrs cfree_cg_type_func_ret_attrs(CfreeCompiler*, + CfreeCgTypeId); CFREE_API uint32_t cfree_cg_type_func_nparams(CfreeCompiler*, CfreeCgTypeId); -CFREE_API CfreeCgFuncParam cfree_cg_type_func_param(CfreeCompiler*, CfreeCgTypeId, - uint32_t index); -CFREE_API CfreeCgCallConv cfree_cg_type_func_call_conv(CfreeCompiler*, CfreeCgTypeId); +CFREE_API CfreeCgFuncParam cfree_cg_type_func_param(CfreeCompiler*, + CfreeCgTypeId, + uint32_t index); +CFREE_API CfreeCgCallConv cfree_cg_type_func_call_conv(CfreeCompiler*, + CfreeCgTypeId); CFREE_API int cfree_cg_type_func_is_variadic(CfreeCompiler*, CfreeCgTypeId); CFREE_API uint32_t cfree_cg_type_record_nfields(CfreeCompiler*, CfreeCgTypeId); /* Returns CFREE_OK and fills any non-NULL out parameters on success. */ CFREE_API CfreeStatus cfree_cg_type_record_field(CfreeCompiler*, CfreeCgTypeId, - uint32_t index, CfreeCgField* out, - uint64_t* offset_out); + uint32_t index, + CfreeCgField* out, + uint64_t* offset_out); typedef enum CfreeCgSymbolFeature { CFREE_CG_SYMFEAT_WEAK, @@ -219,9 +226,10 @@ typedef enum CfreeCgBackendFeatureFlag { * requested feature correctly, not whether it is fast. These are target * facts, not knobs: frontends use them to choose a legal lowering or to emit * an unsupported-feature diagnostic before asking CG to produce output. */ -CFREE_API int cfree_cg_target_supports_call_conv(CfreeCompiler*, CfreeCgCallConv); +CFREE_API int cfree_cg_target_supports_call_conv(CfreeCompiler*, + CfreeCgCallConv); CFREE_API int cfree_cg_target_supports_symbol_feature(CfreeCompiler*, - CfreeCgSymbolFeature); + CfreeCgSymbolFeature); CFREE_API uint64_t cfree_cg_target_backend_features(CfreeCompiler*); /* ============================================================ @@ -400,7 +408,8 @@ CFREE_API CfreeCgSym cfree_cg_alias(CfreeCg*, CfreeCgAlias alias); * remains the frontend's responsibility. Use this when filling * CfreeCgDecl.linkage_name for symbols that should interoperate with C entry * names, libc symbols, and linker entry lookup. */ -CFREE_API CfreeSym cfree_cg_c_linkage_name(CfreeCompiler*, CfreeSym source_name); +CFREE_API CfreeSym cfree_cg_c_linkage_name(CfreeCompiler*, + CfreeSym source_name); /* ============================================================ * Lifecycle and Source Locations @@ -408,7 +417,7 @@ CFREE_API CfreeSym cfree_cg_c_linkage_name(CfreeCompiler*, CfreeSym source_name) CFREE_API CfreeStatus cfree_cg_new(CfreeCompiler*, CfreeCg** cg_out); CFREE_API CfreeStatus cfree_cg_begin_obj(CfreeCg*, CfreeObjBuilder* out, - const CfreeCodeOptions*); + const CfreeCodeOptions*); CFREE_API CfreeStatus cfree_cg_end_obj(CfreeCg*); CFREE_API void cfree_cg_free(CfreeCg*); @@ -422,7 +431,7 @@ CFREE_API void cfree_cg_set_loc(CfreeCg*, CfreeSrcLoc); CFREE_API void cfree_cg_func_begin(CfreeCg*, CfreeCgSym sym); CFREE_API void cfree_cg_func_begin_attrs(CfreeCg*, CfreeCgSym sym, - CfreeCgFuncAttrs attrs); + CfreeCgFuncAttrs attrs); CFREE_API void cfree_cg_func_end(CfreeCg*); typedef enum CfreeCgLocalFlag { @@ -439,16 +448,18 @@ typedef struct CfreeCgLocalAttrs { } CfreeCgLocalAttrs; CFREE_API CfreeCgLocal cfree_cg_local(CfreeCg*, CfreeCgTypeId type, - CfreeCgLocalAttrs attrs); + CfreeCgLocalAttrs attrs); /* Declares a source parameter as a local handle. Parameters must be declared * in order before ordinary locals; therefore the first n parameter handles in * a function are also the first n local ids. */ -CFREE_API CfreeCgLocal cfree_cg_param(CfreeCg*, uint32_t index, CfreeCgTypeId type, - CfreeCgLocalAttrs attrs); +CFREE_API CfreeCgLocal cfree_cg_param(CfreeCg*, uint32_t index, + CfreeCgTypeId type, + CfreeCgLocalAttrs attrs); /* Pops a byte size and pushes a pointer to stack storage with at least align * alignment. The allocation lifetime is the current function activation. */ -CFREE_API void cfree_cg_alloca(CfreeCg*, uint32_t align, CfreeCgTypeId result_ptr_type); +CFREE_API void cfree_cg_alloca(CfreeCg*, uint32_t align, + CfreeCgTypeId result_ptr_type); /* ============================================================ * Control flow @@ -469,14 +480,16 @@ CFREE_API void cfree_cg_alloca(CfreeCg*, uint32_t align, CfreeCgTypeId result_pt * * continue/continue_true/continue_false never carry a result; they jump to * the loop header, not the scope exit. */ -CFREE_API CfreeCgScope cfree_cg_scope_begin(CfreeCg*, CfreeCgTypeId result_type); +CFREE_API CfreeCgScope cfree_cg_scope_begin(CfreeCg*, + CfreeCgTypeId result_type); /* Like cfree_cg_scope_begin but opens a forward-only block: break exits past * the scope; continue is not legal. This is the natural shape for `if`/ * `if-else` (a wrapping block whose break is "skip the rest"), and lets * backends with structured control flow (Wasm) emit `block`/`end` directly * instead of recognizing arbitrary forward-only label-and-jump patterns. */ -CFREE_API CfreeCgScope cfree_cg_block_begin(CfreeCg*, CfreeCgTypeId result_type); +CFREE_API CfreeCgScope cfree_cg_block_begin(CfreeCg*, + CfreeCgTypeId result_type); CFREE_API void cfree_cg_scope_end(CfreeCg*, CfreeCgScope); /* Expose the labels CG minted for this scope. Frontends that emit * unstructured `jump`/`branch` ops (rather than going through the @@ -533,13 +546,15 @@ CFREE_API void cfree_cg_switch(CfreeCg*, CfreeCgSwitch sw); * stored, loaded, selected from tables, compared for equality, and consumed by * cfree_cg_computed_goto. They are only valid within the defining function's * dynamic activation and must not be called or dereferenced as data. */ -CFREE_API void cfree_cg_push_label_addr(CfreeCg*, CfreeCgLabel, CfreeCgTypeId ptr_type); +CFREE_API void cfree_cg_push_label_addr(CfreeCg*, CfreeCgLabel, + CfreeCgTypeId ptr_type); /* Pops a label address and branches to it. valid_targets must name the * non-empty closed set of labels the target may resolve to; targets use it * for validation, CFG construction, and branch-protection lowering. */ -CFREE_API void cfree_cg_computed_goto(CfreeCg*, const CfreeCgLabel* valid_targets, - uint32_t ntargets); +CFREE_API void cfree_cg_computed_goto(CfreeCg*, + const CfreeCgLabel* valid_targets, + uint32_t ntargets); /* Terminates the current block with unreachable code. This is a real * terminator, not a side-effect intrinsic. */ @@ -569,13 +584,15 @@ CFREE_API void cfree_cg_push_local_addr(CfreeCg*, CfreeCgLocal local); * can materialize its address with push_symbol_addr. pointee_type describes * the logical value at that address, enabling const_data + indirect + load to * materialize arbitrary-width constants. */ -CFREE_API CfreeCgSym cfree_cg_const_data(CfreeCg*, const uint8_t* data, size_t len, - uint32_t align, CfreeCgTypeId pointee_type); +CFREE_API CfreeCgSym cfree_cg_const_data(CfreeCg*, const uint8_t* data, + size_t len, uint32_t align, + CfreeCgTypeId pointee_type); /* Pushes &sym + addend as a pointer rvalue. For TLS objects this means the * address of the current thread's instance; the target chooses LE/IE/GD/TLVP * or equivalent lowering from the symbol attrs and output mode. */ -CFREE_API void cfree_cg_push_symbol_addr(CfreeCg*, CfreeCgSym sym, int64_t addend); +CFREE_API void cfree_cg_push_symbol_addr(CfreeCg*, CfreeCgSym sym, + int64_t addend); /* Projects an lvalue TOS back to a pointer rvalue (e.g. for `&x`, passing to * a call, escape). */ @@ -601,8 +618,10 @@ CFREE_API void cfree_cg_field(CfreeCg*, uint32_t field_index); * scale > 0: * load: [base, index] -> [value] * store: [base, index, value] -> [] */ -CFREE_API void cfree_cg_load(CfreeCg*, CfreeCgMemAccess access, CfreeCgEffAddr ea); -CFREE_API void cfree_cg_store(CfreeCg*, CfreeCgMemAccess access, CfreeCgEffAddr ea); +CFREE_API void cfree_cg_load(CfreeCg*, CfreeCgMemAccess access, + CfreeCgEffAddr ea); +CFREE_API void cfree_cg_store(CfreeCg*, CfreeCgMemAccess access, + CfreeCgEffAddr ea); /* ============================================================ * ABI variadic argument access @@ -615,10 +634,10 @@ CFREE_API void cfree_cg_store(CfreeCg*, CfreeCgMemAccess access, CfreeCgEffAddr * that local's address before each operation. The implementation reads and * writes the state in memory according to the target ABI. */ CFREE_API void cfree_cg_vararg_start(CfreeCg*); /* pop &state */ -CFREE_API void cfree_cg_vararg_next(CfreeCg*, - CfreeCgTypeId type); /* pop &state; push value */ -CFREE_API void cfree_cg_vararg_end(CfreeCg*); /* pop &state */ -CFREE_API void cfree_cg_vararg_copy(CfreeCg*); /* pop &dst, &src */ +CFREE_API void cfree_cg_vararg_next( + CfreeCg*, CfreeCgTypeId type); /* pop &state; push value */ +CFREE_API void cfree_cg_vararg_end(CfreeCg*); /* pop &state */ +CFREE_API void cfree_cg_vararg_copy(CfreeCg*); /* pop &dst, &src */ /* ============================================================ * Integer Operations @@ -742,13 +761,13 @@ CFREE_API void cfree_cg_bitcast(CfreeCg*, CfreeCgTypeId dst); CFREE_API void cfree_cg_fpext(CfreeCg*, CfreeCgTypeId dst); CFREE_API void cfree_cg_fptrunc(CfreeCg*, CfreeCgTypeId dst); CFREE_API void cfree_cg_sint_to_float(CfreeCg*, CfreeCgTypeId dst, - CfreeCgRounding rounding); + CfreeCgRounding rounding); CFREE_API void cfree_cg_uint_to_float(CfreeCg*, CfreeCgTypeId dst, - CfreeCgRounding rounding); + CfreeCgRounding rounding); CFREE_API void cfree_cg_float_to_sint(CfreeCg*, CfreeCgTypeId dst, - CfreeCgRounding rounding); + CfreeCgRounding rounding); CFREE_API void cfree_cg_float_to_uint(CfreeCg*, CfreeCgTypeId dst, - CfreeCgRounding rounding); + CfreeCgRounding rounding); /* ============================================================ * Calls and Returns @@ -816,9 +835,9 @@ typedef struct CfreeCgCallAttrs { * tail call whose callee return type is incompatible with the enclosing * function's return type is a frontend bug and aborts under any policy. */ CFREE_API void cfree_cg_call(CfreeCg*, uint32_t nargs, CfreeCgTypeId fn_type, - CfreeCgCallAttrs attrs); + CfreeCgCallAttrs attrs); CFREE_API void cfree_cg_call_symbol(CfreeCg*, CfreeCgSym sym, uint32_t nargs, - CfreeCgCallAttrs attrs); + CfreeCgCallAttrs attrs); CFREE_API void cfree_cg_ret(CfreeCg*); CFREE_API void cfree_cg_ret_void(CfreeCg*); @@ -880,7 +899,7 @@ typedef enum CfreeCgBarrierScope { * mirror rt/include/cfree/{syscall,baremetal,coro}.h and must diagnose targets * where the primitive has no legal lowering. */ CFREE_API void cfree_cg_intrinsic(CfreeCg*, CfreeCgIntrinsic, uint32_t nargs, - CfreeCgTypeId result_type); + CfreeCgTypeId result_type); /* ============================================================ * Fixed-Sized Memory Operations @@ -890,11 +909,11 @@ CFREE_API void cfree_cg_intrinsic(CfreeCg*, CfreeCgIntrinsic, uint32_t nargs, * memcpy/memmove: [dst, src] -> [] * memset: [dst] -> [] */ CFREE_API void cfree_cg_memcpy(CfreeCg*, uint64_t size, CfreeCgMemAccess dst, - CfreeCgMemAccess src); + CfreeCgMemAccess src); CFREE_API void cfree_cg_memmove(CfreeCg*, uint64_t size, CfreeCgMemAccess dst, - CfreeCgMemAccess src); + CfreeCgMemAccess src); CFREE_API void cfree_cg_memset(CfreeCg*, uint8_t val, uint64_t size, - CfreeCgMemAccess dst); + CfreeCgMemAccess dst); /* ============================================================ * Atomics @@ -920,18 +939,19 @@ typedef enum CfreeCgMemOrder { } CfreeCgMemOrder; CFREE_API int cfree_cg_atomic_is_legal(CfreeCompiler*, CfreeCgMemAccess access, - CfreeCgMemOrder order); -CFREE_API int cfree_cg_atomic_is_lock_free(CfreeCompiler*, CfreeCgMemAccess access); + CfreeCgMemOrder order); +CFREE_API int cfree_cg_atomic_is_lock_free(CfreeCompiler*, + CfreeCgMemAccess access); CFREE_API void cfree_cg_atomic_load(CfreeCg*, CfreeCgMemAccess access, - CfreeCgMemOrder order); + CfreeCgMemOrder order); CFREE_API void cfree_cg_atomic_store(CfreeCg*, CfreeCgMemAccess access, - CfreeCgMemOrder order); -CFREE_API void cfree_cg_atomic_rmw(CfreeCg*, CfreeCgMemAccess access, CfreeCgAtomicOp, - CfreeCgMemOrder order); + CfreeCgMemOrder order); +CFREE_API void cfree_cg_atomic_rmw(CfreeCg*, CfreeCgMemAccess access, + CfreeCgAtomicOp, CfreeCgMemOrder order); /* Stack: [ptr, expected, desired] -> [prior, ok_bool]. */ CFREE_API void cfree_cg_atomic_cmpxchg(CfreeCg*, CfreeCgMemAccess access, - CfreeCgMemOrder success, CfreeCgMemOrder failure, - int weak); + CfreeCgMemOrder success, + CfreeCgMemOrder failure, int weak); CFREE_API void cfree_cg_atomic_fence(CfreeCg*, CfreeCgMemOrder); /* ============================================================ @@ -1022,9 +1042,10 @@ typedef struct CfreeCgDataDefAttrs { * function remains open across data_begin/data_end so frontends can define * block-scope statics and computed-goto dispatch tables that need function * label context. */ -CFREE_API void cfree_cg_data_begin(CfreeCg*, CfreeCgSym sym, CfreeCgDataDefAttrs attrs); +CFREE_API void cfree_cg_data_begin(CfreeCg*, CfreeCgSym sym, + CfreeCgDataDefAttrs attrs); CFREE_API void cfree_cg_data_common(CfreeCg*, CfreeCgSym sym, uint64_t size, - uint32_t align); + uint32_t align); CFREE_API void cfree_cg_data_end(CfreeCg*); /* Appends to the currently open data definition. */ @@ -1041,7 +1062,7 @@ CFREE_API void cfree_cg_data_zero(CfreeCg*, uint64_t size); * is the pointer address space of address constants; use 0 for the target data * address space. */ CFREE_API void cfree_cg_data_addr(CfreeCg*, CfreeCgSym target, int64_t addend, - uint32_t width, uint32_t address_space); + uint32_t width, uint32_t address_space); /* Encodes a function-local label address for direct-threaded dispatch tables. * The target label must have been created by cfree_cg_label_new; it does not * need to be placed yet, and the containing function must still be open so the @@ -1053,12 +1074,13 @@ CFREE_API void cfree_cg_data_addr(CfreeCg*, CfreeCgSym target, int64_t addend, * selected from tables, and consumed by cfree_cg_computed_goto in the label's * defining function. It must not be called, dereferenced as data, or used by * another function's computed goto. */ -CFREE_API void cfree_cg_data_label_addr(CfreeCg*, CfreeCgLabel target, int64_t addend, - uint32_t width, uint32_t address_space); +CFREE_API void cfree_cg_data_label_addr(CfreeCg*, CfreeCgLabel target, + int64_t addend, uint32_t width, + uint32_t address_space); CFREE_API void cfree_cg_data_pcrel(CfreeCg*, CfreeCgSym target, int64_t addend, - uint32_t width); + uint32_t width); CFREE_API void cfree_cg_data_symdiff(CfreeCg*, CfreeCgSym lhs, CfreeCgSym rhs, - int64_t addend, uint32_t width); + int64_t addend, uint32_t width); /* ============================================================ * Static Inline Convenience Operations @@ -1151,19 +1173,19 @@ static inline void cfree_cg_inc_dec(CfreeCg* cg, CfreeCgIntBinOp op, int post, cfree_cg_dup(cg); /* [lv, lv] */ cfree_cg_load(cg, access, ea); /* [lv, old] */ if (post) { - cfree_cg_dup(cg); /* [lv, old, old] */ - cfree_cg_push_int(cg, 1, ty); /* [lv, old, old, 1] */ - cfree_cg_int_binop(cg, op, 0); /* [lv, old, new] */ - cfree_cg_rot3(cg); /* [old, new, lv] */ - cfree_cg_swap(cg); /* [old, lv, new] */ - cfree_cg_store(cg, access, ea); /* [old] */ + cfree_cg_dup(cg); /* [lv, old, old] */ + cfree_cg_push_int(cg, 1, ty); /* [lv, old, old, 1] */ + cfree_cg_int_binop(cg, op, 0); /* [lv, old, new] */ + cfree_cg_rot3(cg); /* [old, new, lv] */ + cfree_cg_swap(cg); /* [old, lv, new] */ + cfree_cg_store(cg, access, ea); /* [old] */ } else { - cfree_cg_push_int(cg, 1, ty); /* [lv, old, 1] */ - cfree_cg_int_binop(cg, op, 0); /* [lv, new] */ - cfree_cg_dup(cg); /* [lv, new, new] */ - cfree_cg_rot3(cg); /* [new, new, lv] */ - cfree_cg_swap(cg); /* [new, lv, new] */ - cfree_cg_store(cg, access, ea); /* [new] */ + cfree_cg_push_int(cg, 1, ty); /* [lv, old, 1] */ + cfree_cg_int_binop(cg, op, 0); /* [lv, new] */ + cfree_cg_dup(cg); /* [lv, new, new] */ + cfree_cg_rot3(cg); /* [new, new, lv] */ + cfree_cg_swap(cg); /* [new, lv, new] */ + cfree_cg_store(cg, access, ea); /* [new] */ } } diff --git a/include/cfree/compile.h b/include/cfree/compile.h @@ -85,24 +85,25 @@ typedef struct CfreeFrontendVTable { uint32_t nextensions; } CfreeFrontendVTable; -CFREE_API CfreeLanguage cfree_language_for_path(CfreeCompiler*, const char* path); +CFREE_API CfreeLanguage cfree_language_for_path(CfreeCompiler*, + const char* path); CFREE_API CfreeStatus cfree_register_frontend(CfreeCompiler*, CfreeLanguage, - const CfreeFrontendVTable*); + const CfreeFrontendVTable*); -CFREE_API uint32_t cfree_compiler_arch_predefines(CfreeCompiler*, - const CfreePredefinedMacro** out); +CFREE_API uint32_t cfree_compiler_arch_predefines( + CfreeCompiler*, const CfreePredefinedMacro** out); typedef struct CfreeCompileSessionOptions { CfreeLanguage lang; CfreeFrontendCompileOptions compile; } CfreeCompileSessionOptions; -CFREE_API CfreeStatus cfree_compile_session_new(CfreeCompiler*, - const CfreeCompileSessionOptions*, - CfreeCompileSession** out); +CFREE_API CfreeStatus +cfree_compile_session_new(CfreeCompiler*, const CfreeCompileSessionOptions*, + CfreeCompileSession** out); CFREE_API CfreeStatus cfree_compile_session_compile(CfreeCompileSession*, - const CfreeSourceInput*, - CfreeObjBuilder** out); + const CfreeSourceInput*, + CfreeObjBuilder** out); CFREE_API void cfree_compile_session_free(CfreeCompileSession*); typedef struct CfreeDepIter CfreeDepIter; diff --git a/include/cfree/config.h b/include/cfree/config.h @@ -24,18 +24,18 @@ */ /* Backend architectures. */ -#define CFREE_ARCH_AA64_ENABLED 1 -#define CFREE_ARCH_X64_ENABLED 1 -#define CFREE_ARCH_RV64_ENABLED 1 -#define CFREE_ARCH_WASM_ENABLED 1 +#define CFREE_ARCH_AA64_ENABLED 1 +#define CFREE_ARCH_X64_ENABLED 1 +#define CFREE_ARCH_RV64_ENABLED 1 +#define CFREE_ARCH_WASM_ENABLED 1 #define CFREE_ARCH_C_TARGET_ENABLED 1 /* Object/image formats. Each gates emit + read + link-image paths and * the matching arch-side reloc tables. */ -#define CFREE_OBJ_ELF_ENABLED 1 +#define CFREE_OBJ_ELF_ENABLED 1 #define CFREE_OBJ_MACHO_ENABLED 1 -#define CFREE_OBJ_COFF_ENABLED 1 -#define CFREE_OBJ_WASM_ENABLED 1 +#define CFREE_OBJ_COFF_ENABLED 1 +#define CFREE_OBJ_WASM_ENABLED 1 /* Language frontends. * @@ -46,10 +46,10 @@ * CFREE_LANG_CPP_ENABLED gates the C preprocessor (lang/cpp/). The C frontend * depends on it; enabling CFREE_LANG_C_ENABLED without CFREE_LANG_CPP_ENABLED * is a build-time error. The preprocessor can be enabled standalone. */ -#define CFREE_LANG_ASM_ENABLED 1 -#define CFREE_LANG_CPP_ENABLED 1 -#define CFREE_LANG_C_ENABLED 1 -#define CFREE_LANG_TOY_ENABLED 1 +#define CFREE_LANG_ASM_ENABLED 1 +#define CFREE_LANG_CPP_ENABLED 1 +#define CFREE_LANG_C_ENABLED 1 +#define CFREE_LANG_TOY_ENABLED 1 #define CFREE_LANG_WASM_ENABLED 1 /* Optimizer pipeline. -O0/direct codegen is always available; -O1 and above @@ -64,31 +64,31 @@ * Some implementation directories are still shared by historically coupled * subsystems. The build asserts the dependencies that are required by the * current layout. */ -#define CFREE_AR_ENABLED 1 +#define CFREE_AR_ENABLED 1 #define CFREE_DISASM_ENABLED 1 -#define CFREE_DWARF_ENABLED 1 -#define CFREE_LINK_ENABLED 1 -#define CFREE_JIT_ENABLED 1 -#define CFREE_DBG_ENABLED 1 -#define CFREE_EMU_ENABLED 1 +#define CFREE_DWARF_ENABLED 1 +#define CFREE_LINK_ENABLED 1 +#define CFREE_JIT_ENABLED 1 +#define CFREE_DBG_ENABLED 1 +#define CFREE_EMU_ENABLED 1 /* cfree multi-call driver tools. These flags control both dispatch/help and * the driver/<tool>.c objects included in the cfree binary. */ -#define CFREE_TOOL_CC_ENABLED 1 -#define CFREE_TOOL_CHECK_ENABLED 1 -#define CFREE_TOOL_CPP_ENABLED 1 -#define CFREE_TOOL_AS_ENABLED 1 -#define CFREE_TOOL_LD_ENABLED 1 -#define CFREE_TOOL_AR_ENABLED 1 -#define CFREE_TOOL_RANLIB_ENABLED 1 -#define CFREE_TOOL_STRIP_ENABLED 1 -#define CFREE_TOOL_OBJCOPY_ENABLED 1 -#define CFREE_TOOL_OBJDUMP_ENABLED 1 -#define CFREE_TOOL_DBG_ENABLED 1 -#define CFREE_TOOL_RUN_ENABLED 1 -#define CFREE_TOOL_EMU_ENABLED 1 -#define CFREE_TOOL_NM_ENABLED 1 -#define CFREE_TOOL_SIZE_ENABLED 1 +#define CFREE_TOOL_CC_ENABLED 1 +#define CFREE_TOOL_CHECK_ENABLED 1 +#define CFREE_TOOL_CPP_ENABLED 1 +#define CFREE_TOOL_AS_ENABLED 1 +#define CFREE_TOOL_LD_ENABLED 1 +#define CFREE_TOOL_AR_ENABLED 1 +#define CFREE_TOOL_RANLIB_ENABLED 1 +#define CFREE_TOOL_STRIP_ENABLED 1 +#define CFREE_TOOL_OBJCOPY_ENABLED 1 +#define CFREE_TOOL_OBJDUMP_ENABLED 1 +#define CFREE_TOOL_DBG_ENABLED 1 +#define CFREE_TOOL_RUN_ENABLED 1 +#define CFREE_TOOL_EMU_ENABLED 1 +#define CFREE_TOOL_NM_ENABLED 1 +#define CFREE_TOOL_SIZE_ENABLED 1 #define CFREE_TOOL_ADDR2LINE_ENABLED 1 #endif /* CFREE_CONFIG_H */ diff --git a/include/cfree/core.h b/include/cfree/core.h @@ -75,11 +75,11 @@ typedef struct CfreeSlice { } CfreeSlice; /* Build a slice from a string literal (length is compile-time, no strlen). */ -#define CFREE_SLICE_LIT(lit) \ - ((CfreeSlice){ .s = (lit), .len = sizeof(lit) - 1 }) +#define CFREE_SLICE_LIT(lit) ((CfreeSlice){.s = (lit), .len = sizeof(lit) - 1}) /* The empty slice. */ -#define CFREE_SLICE_NULL ((CfreeSlice){ .s = NULL, .len = 0 }) -/* Spread a slice into printf "%.*s" arguments: printf("%.*s", CFREE_SLICE_ARG(x)). */ +#define CFREE_SLICE_NULL ((CfreeSlice){.s = NULL, .len = 0}) +/* Spread a slice into printf "%.*s" arguments: printf("%.*s", + * CFREE_SLICE_ARG(x)). */ #define CFREE_SLICE_ARG(x) (int)(x).len, (x).s /* Lift a NUL-terminated C string into a slice. The sanctioned boundary helper @@ -108,7 +108,8 @@ static inline bool cfree_slice_eq(CfreeSlice a, CfreeSlice b) { return true; } -/* Equality against a NUL-terminated string (compares bytes, ignores z's NUL). */ +/* Equality against a NUL-terminated string (compares bytes, ignores z's NUL). + */ static inline bool cfree_slice_eq_cstr(CfreeSlice a, const char* z) { size_t i; if (!z) return a.len == 0; @@ -309,7 +310,7 @@ typedef struct CfreeContext { } CfreeContext; CFREE_API CfreeStatus cfree_compiler_new(CfreeTarget, const CfreeContext*, - CfreeCompiler** out); + CfreeCompiler** out); CFREE_API void cfree_compiler_free(CfreeCompiler*); CFREE_API CfreeTarget cfree_compiler_target(CfreeCompiler*); diff --git a/include/cfree/dbg.h b/include/cfree/dbg.h @@ -13,42 +13,41 @@ */ typedef struct CfreeDbgSignalOps { - CfreeStatus (*on_fault)(void *session, int signo, CfreeUnwindFrame *regs); + CfreeStatus (*on_fault)(void* session, int signo, CfreeUnwindFrame* regs); } CfreeDbgSignalOps; typedef struct CfreeDbgOs { - CfreeStatus (*thread_start)(void *user, void (*fn)(void *), void *arg, - void **thread_out); - void (*thread_join)(void *user, void *thread); - CfreeStatus (*thread_interrupt)(void *user, void *thread); - - CfreeStatus (*event_new)(void *user, void **event_out); - void (*event_free)(void *user, void *ev); - CfreeStatus (*event_wait)(void *user, void *ev); - CfreeStatus (*event_signal)(void *user, void *ev); - CfreeStatus (*event_reset)(void *user, void *ev); - - CfreeStatus (*signals_install)(void *user, const CfreeDbgSignalOps *ops, - void *session); - void (*signals_uninstall)(void *user); + CfreeStatus (*thread_start)(void* user, void (*fn)(void*), void* arg, + void** thread_out); + void (*thread_join)(void* user, void* thread); + CfreeStatus (*thread_interrupt)(void* user, void* thread); + + CfreeStatus (*event_new)(void* user, void** event_out); + void (*event_free)(void* user, void* ev); + CfreeStatus (*event_wait)(void* user, void* ev); + CfreeStatus (*event_signal)(void* user, void* ev); + CfreeStatus (*event_reset)(void* user, void* ev); + + CfreeStatus (*signals_install)(void* user, const CfreeDbgSignalOps* ops, + void* session); + void (*signals_uninstall)(void* user); int interrupt_signo; - CfreeStatus (*code_write_begin)(void *user, void *runtime_addr, size_t n, - void **write_out); - void (*code_write_end)(void *user, void *runtime_addr, size_t n); - void (*flush_icache)(void *user, void *runtime_addr, size_t n); + CfreeStatus (*code_write_begin)(void* user, void* runtime_addr, size_t n, + void** write_out); + void (*code_write_end)(void* user, void* runtime_addr, size_t n); + void (*flush_icache)(void* user, void* runtime_addr, size_t n); - CfreeStatus (*guarded_copy)(void *user, void *dst, const void *src, - size_t n); + CfreeStatus (*guarded_copy)(void* user, void* dst, const void* src, size_t n); - int (*call_with_catch)(void *user, void (*fn)(void *), void *arg); - void (*thread_abort)(void *user); + int (*call_with_catch)(void* user, void (*fn)(void*), void* arg); + void (*thread_abort)(void* user); - void *user; + void* user; } CfreeDbgOs; typedef struct CfreeDbgHost { - const CfreeDbgOs *os; + const CfreeDbgOs* os; } CfreeDbgHost; typedef enum CfreeStopKind { @@ -84,42 +83,47 @@ typedef struct CfreeBreakpointSpec { uint64_t addr; uint64_t skip_count; uint64_t max_hits; - int (*condition)(void *user, const CfreeUnwindFrame *regs); - void *condition_user; + int (*condition)(void* user, const CfreeUnwindFrame* regs); + void* condition_user; } CfreeBreakpointSpec; -CFREE_API CfreeStatus cfree_jit_session_new(CfreeJit *, const CfreeDbgHost *, - CfreeJitSession **out); -CFREE_API void cfree_jit_session_free(CfreeJitSession *); -CFREE_API CfreeStatus cfree_jit_session_attach_dwarf(CfreeJitSession *, - CfreeDebugInfo *); - -CFREE_API CfreeStatus cfree_jit_session_call(CfreeJitSession *, void *entry, - CfreeEntryKind, int argc, char **argv, - CfreeStopInfo *stop_out); -CFREE_API CfreeStatus cfree_jit_session_call_u64(CfreeJitSession *, void *entry, - const uint64_t *args, uint32_t nargs, - uint64_t *ret_out, - CfreeStopInfo *stop_out); -CFREE_API CfreeStatus cfree_jit_session_resume(CfreeJitSession *, CfreeResumeMode, - CfreeStopInfo *stop_out); -CFREE_API CfreeStatus cfree_jit_session_interrupt(CfreeJitSession *); - -CFREE_API CfreeStatus cfree_jit_session_read_mem(CfreeJitSession *, uint64_t addr, - void *dst, size_t n); -CFREE_API CfreeStatus cfree_jit_session_write_mem(CfreeJitSession *, uint64_t addr, - const void *src, size_t n); -CFREE_API CfreeStatus cfree_jit_session_get_regs(CfreeJitSession *, - CfreeUnwindFrame *out); -CFREE_API CfreeStatus cfree_jit_session_set_regs(CfreeJitSession *, - const CfreeUnwindFrame *); - -CFREE_API CfreeStatus cfree_jit_session_breakpoint_set(CfreeJitSession *, uint64_t addr, - uint32_t *bp_id_out); -CFREE_API CfreeStatus cfree_jit_session_breakpoint_clear(CfreeJitSession *, - uint32_t bp_id); -CFREE_API CfreeStatus cfree_jit_session_breakpoint_set_spec(CfreeJitSession *, - const CfreeBreakpointSpec *, - uint32_t *bp_id_out); +CFREE_API CfreeStatus cfree_jit_session_new(CfreeJit*, const CfreeDbgHost*, + CfreeJitSession** out); +CFREE_API void cfree_jit_session_free(CfreeJitSession*); +CFREE_API CfreeStatus cfree_jit_session_attach_dwarf(CfreeJitSession*, + CfreeDebugInfo*); + +CFREE_API CfreeStatus cfree_jit_session_call(CfreeJitSession*, void* entry, + CfreeEntryKind, int argc, + char** argv, + CfreeStopInfo* stop_out); +CFREE_API CfreeStatus cfree_jit_session_call_u64(CfreeJitSession*, void* entry, + const uint64_t* args, + uint32_t nargs, + uint64_t* ret_out, + CfreeStopInfo* stop_out); +CFREE_API CfreeStatus cfree_jit_session_resume(CfreeJitSession*, + CfreeResumeMode, + CfreeStopInfo* stop_out); +CFREE_API CfreeStatus cfree_jit_session_interrupt(CfreeJitSession*); + +CFREE_API CfreeStatus cfree_jit_session_read_mem(CfreeJitSession*, + uint64_t addr, void* dst, + size_t n); +CFREE_API CfreeStatus cfree_jit_session_write_mem(CfreeJitSession*, + uint64_t addr, + const void* src, size_t n); +CFREE_API CfreeStatus cfree_jit_session_get_regs(CfreeJitSession*, + CfreeUnwindFrame* out); +CFREE_API CfreeStatus cfree_jit_session_set_regs(CfreeJitSession*, + const CfreeUnwindFrame*); + +CFREE_API CfreeStatus cfree_jit_session_breakpoint_set(CfreeJitSession*, + uint64_t addr, + uint32_t* bp_id_out); +CFREE_API CfreeStatus cfree_jit_session_breakpoint_clear(CfreeJitSession*, + uint32_t bp_id); +CFREE_API CfreeStatus cfree_jit_session_breakpoint_set_spec( + CfreeJitSession*, const CfreeBreakpointSpec*, uint32_t* bp_id_out); #endif diff --git a/include/cfree/disasm.h b/include/cfree/disasm.h @@ -12,7 +12,7 @@ typedef struct CfreeInsn { uint64_t vaddr; - const uint8_t *bytes; + const uint8_t* bytes; uint32_t nbytes; CfreeSlice mnemonic; CfreeSlice operands; @@ -26,17 +26,19 @@ typedef struct CfreeDisasmContext { CfreeContext context; } CfreeDisasmContext; -CFREE_API CfreeStatus cfree_disasm_iter_new(const CfreeDisasmContext *, - const uint8_t *bytes, size_t len, - uint64_t vaddr, - const CfreeObjFile *annotations, - CfreeDisasmIter **out); -CFREE_API CfreeIterResult cfree_disasm_iter_next(CfreeDisasmIter *, CfreeInsn *out); -CFREE_API void cfree_disasm_iter_free(CfreeDisasmIter *); - -CFREE_API CfreeStatus cfree_disasm_obj(const CfreeContext *, const CfreeObjFile *, - CfreeWriter *out); -CFREE_API CfreeStatus cfree_disasm_obj_bytes(const CfreeContext *, const CfreeSlice *, - CfreeWriter *out); +CFREE_API CfreeStatus cfree_disasm_iter_new(const CfreeDisasmContext*, + const uint8_t* bytes, size_t len, + uint64_t vaddr, + const CfreeObjFile* annotations, + CfreeDisasmIter** out); +CFREE_API CfreeIterResult cfree_disasm_iter_next(CfreeDisasmIter*, + CfreeInsn* out); +CFREE_API void cfree_disasm_iter_free(CfreeDisasmIter*); + +CFREE_API CfreeStatus cfree_disasm_obj(const CfreeContext*, const CfreeObjFile*, + CfreeWriter* out); +CFREE_API CfreeStatus cfree_disasm_obj_bytes(const CfreeContext*, + const CfreeSlice*, + CfreeWriter* out); #endif diff --git a/include/cfree/dwarf.h b/include/cfree/dwarf.h @@ -14,28 +14,29 @@ typedef struct CfreeDwarfType CfreeDwarfType; -CFREE_API CfreeStatus cfree_dwarf_open(const CfreeContext *, const CfreeObjFile *, - CfreeDebugInfo **out); -CFREE_API void cfree_dwarf_free(CfreeDebugInfo *); +CFREE_API CfreeStatus cfree_dwarf_open(const CfreeContext*, const CfreeObjFile*, + CfreeDebugInfo** out); +CFREE_API void cfree_dwarf_free(CfreeDebugInfo*); -CFREE_API CfreeStatus cfree_dwarf_addr_to_line(CfreeDebugInfo *, uint64_t pc, - CfreeSlice *file_out, - uint32_t *line_out, uint32_t *col_out); -CFREE_API CfreeStatus cfree_dwarf_line_to_addr(CfreeDebugInfo *, CfreeSlice file, - uint32_t line, uint64_t *pc_out); +CFREE_API CfreeStatus cfree_dwarf_addr_to_line(CfreeDebugInfo*, uint64_t pc, + CfreeSlice* file_out, + uint32_t* line_out, + uint32_t* col_out); +CFREE_API CfreeStatus cfree_dwarf_line_to_addr(CfreeDebugInfo*, CfreeSlice file, + uint32_t line, uint64_t* pc_out); typedef struct CfreeDwarfLineMatch { uint64_t pc; CfreeSlice file; } CfreeDwarfLineMatch; -CFREE_API CfreeStatus cfree_dwarf_line_to_addr_all(CfreeDebugInfo *, CfreeSlice file, - uint32_t line, - CfreeDwarfLineMatch *out, - uint32_t cap, uint32_t *n_out); -CFREE_API CfreeStatus cfree_dwarf_func_at(CfreeDebugInfo *, uint64_t pc, - CfreeSlice *name_out, uint64_t *low_pc_out, - uint64_t *high_pc_out); +CFREE_API CfreeStatus cfree_dwarf_line_to_addr_all( + CfreeDebugInfo*, CfreeSlice file, uint32_t line, CfreeDwarfLineMatch* out, + uint32_t cap, uint32_t* n_out); +CFREE_API CfreeStatus cfree_dwarf_func_at(CfreeDebugInfo*, uint64_t pc, + CfreeSlice* name_out, + uint64_t* low_pc_out, + uint64_t* high_pc_out); typedef struct CfreeDwarfSubprogram { CfreeSlice name; @@ -43,15 +44,17 @@ typedef struct CfreeDwarfSubprogram { uint64_t high_pc; CfreeSlice decl_file; uint32_t decl_line; - const CfreeDwarfType *return_type; + const CfreeDwarfType* return_type; bool inlined; } CfreeDwarfSubprogram; -CFREE_API CfreeStatus cfree_dwarf_subprogram_at(CfreeDebugInfo *, uint64_t pc, - CfreeDwarfSubprogram *out); -CFREE_API CfreeStatus cfree_dwarf_subprogram_named(CfreeDebugInfo *, CfreeSlice name, - CfreeDwarfSubprogram *out); -CFREE_API CfreeStatus cfree_dwarf_unwind_step(CfreeDebugInfo *, CfreeUnwindFrame *); +CFREE_API CfreeStatus cfree_dwarf_subprogram_at(CfreeDebugInfo*, uint64_t pc, + CfreeDwarfSubprogram* out); +CFREE_API CfreeStatus cfree_dwarf_subprogram_named(CfreeDebugInfo*, + CfreeSlice name, + CfreeDwarfSubprogram* out); +CFREE_API CfreeStatus cfree_dwarf_unwind_step(CfreeDebugInfo*, + CfreeUnwindFrame*); typedef enum CfreeDwarfTypeKind { CFREE_DT_VOID, @@ -74,10 +77,10 @@ typedef struct CfreeDwarfTypeInfo { uint32_t byte_size; CfreeSlice name; uint32_t element_count; - const CfreeDwarfType *inner; + const CfreeDwarfType* inner; } CfreeDwarfTypeInfo; -CFREE_API CfreeDwarfTypeInfo cfree_dwarf_type_info(const CfreeDwarfType *); +CFREE_API CfreeDwarfTypeInfo cfree_dwarf_type_info(const CfreeDwarfType*); typedef struct CfreeDwarfFieldIter CfreeDwarfFieldIter; typedef struct CfreeDwarfField { @@ -85,15 +88,15 @@ typedef struct CfreeDwarfField { uint32_t byte_offset; uint32_t bit_offset; uint32_t bit_size; - const CfreeDwarfType *type; + const CfreeDwarfType* type; } CfreeDwarfField; -CFREE_API CfreeStatus cfree_dwarf_field_iter_new(CfreeDebugInfo *, - const CfreeDwarfType *, - CfreeDwarfFieldIter **out); -CFREE_API CfreeIterResult cfree_dwarf_field_iter_next(CfreeDwarfFieldIter *, - CfreeDwarfField *out); -CFREE_API void cfree_dwarf_field_iter_free(CfreeDwarfFieldIter *); +CFREE_API CfreeStatus cfree_dwarf_field_iter_new(CfreeDebugInfo*, + const CfreeDwarfType*, + CfreeDwarfFieldIter** out); +CFREE_API CfreeIterResult cfree_dwarf_field_iter_next(CfreeDwarfFieldIter*, + CfreeDwarfField* out); +CFREE_API void cfree_dwarf_field_iter_free(CfreeDwarfFieldIter*); typedef struct CfreeDwarfEnumIter CfreeDwarfEnumIter; typedef struct CfreeDwarfEnumVal { @@ -101,12 +104,12 @@ typedef struct CfreeDwarfEnumVal { int64_t value; } CfreeDwarfEnumVal; -CFREE_API CfreeStatus cfree_dwarf_enum_iter_new(CfreeDebugInfo *, - const CfreeDwarfType *, - CfreeDwarfEnumIter **out); -CFREE_API CfreeIterResult cfree_dwarf_enum_iter_next(CfreeDwarfEnumIter *, - CfreeDwarfEnumVal *out); -CFREE_API void cfree_dwarf_enum_iter_free(CfreeDwarfEnumIter *); +CFREE_API CfreeStatus cfree_dwarf_enum_iter_new(CfreeDebugInfo*, + const CfreeDwarfType*, + CfreeDwarfEnumIter** out); +CFREE_API CfreeIterResult cfree_dwarf_enum_iter_next(CfreeDwarfEnumIter*, + CfreeDwarfEnumVal* out); +CFREE_API void cfree_dwarf_enum_iter_free(CfreeDwarfEnumIter*); typedef enum CfreeDwarfLocKind { CFREE_DLOC_REG, @@ -118,27 +121,30 @@ typedef enum CfreeDwarfLocKind { typedef struct CfreeDwarfVarLoc { CfreeDwarfLocKind kind; uint32_t byte_size; - const CfreeDwarfType *type; + const CfreeDwarfType* type; union { uint32_t reg; int32_t frame_ofs; uint64_t global; struct { - const uint8_t *bytes; + const uint8_t* bytes; size_t len; } expr; } v; } CfreeDwarfVarLoc; -typedef CfreeStatus (*CfreeDwarfReadMemFn)(void *user, uint64_t addr, - void *dst, size_t n); +typedef CfreeStatus (*CfreeDwarfReadMemFn)(void* user, uint64_t addr, void* dst, + size_t n); -CFREE_API CfreeStatus cfree_dwarf_var_at(CfreeDebugInfo *, uint64_t pc, - CfreeSlice name, CfreeDwarfVarLoc *out); -CFREE_API CfreeStatus cfree_dwarf_loc_read(CfreeDebugInfo *, const CfreeDwarfVarLoc *, - const CfreeUnwindFrame *, - CfreeDwarfReadMemFn read_mem, void *read_user, - void *dst, size_t cap, size_t *read_out); +CFREE_API CfreeStatus cfree_dwarf_var_at(CfreeDebugInfo*, uint64_t pc, + CfreeSlice name, + CfreeDwarfVarLoc* out); +CFREE_API CfreeStatus cfree_dwarf_loc_read(CfreeDebugInfo*, + const CfreeDwarfVarLoc*, + const CfreeUnwindFrame*, + CfreeDwarfReadMemFn read_mem, + void* read_user, void* dst, + size_t cap, size_t* read_out); typedef enum CfreeDwarfVarRole { CFREE_DVR_LOCAL, @@ -161,22 +167,21 @@ typedef struct CfreeDwarfVar { typedef struct CfreeDwarfVarIter CfreeDwarfVarIter; -CFREE_API CfreeStatus cfree_dwarf_vars_at_new(CfreeDebugInfo *, uint64_t pc, - uint32_t role_mask, - CfreeDwarfVarIter **out); -CFREE_API CfreeIterResult cfree_dwarf_vars_at_next(CfreeDwarfVarIter *, - CfreeDwarfVar *out); -CFREE_API void cfree_dwarf_vars_at_free(CfreeDwarfVarIter *); +CFREE_API CfreeStatus cfree_dwarf_vars_at_new(CfreeDebugInfo*, uint64_t pc, + uint32_t role_mask, + CfreeDwarfVarIter** out); +CFREE_API CfreeIterResult cfree_dwarf_vars_at_next(CfreeDwarfVarIter*, + CfreeDwarfVar* out); +CFREE_API void cfree_dwarf_vars_at_free(CfreeDwarfVarIter*); typedef struct CfreeDwarfParamIter CfreeDwarfParamIter; -CFREE_API CfreeStatus cfree_dwarf_param_iter_new(CfreeDebugInfo *, uint64_t pc, - CfreeDwarfParamIter **out); -CFREE_API CfreeStatus cfree_dwarf_param_iter_new_named(CfreeDebugInfo *, - CfreeSlice name, - CfreeDwarfParamIter **out); -CFREE_API CfreeIterResult cfree_dwarf_param_iter_next(CfreeDwarfParamIter *, - CfreeDwarfVar *out); -CFREE_API void cfree_dwarf_param_iter_free(CfreeDwarfParamIter *); +CFREE_API CfreeStatus cfree_dwarf_param_iter_new(CfreeDebugInfo*, uint64_t pc, + CfreeDwarfParamIter** out); +CFREE_API CfreeStatus cfree_dwarf_param_iter_new_named( + CfreeDebugInfo*, CfreeSlice name, CfreeDwarfParamIter** out); +CFREE_API CfreeIterResult cfree_dwarf_param_iter_next(CfreeDwarfParamIter*, + CfreeDwarfVar* out); +CFREE_API void cfree_dwarf_param_iter_free(CfreeDwarfParamIter*); #endif diff --git a/include/cfree/emu.h b/include/cfree/emu.h @@ -60,7 +60,7 @@ typedef struct CfreeEmuImportRequest { typedef struct CfreeEmuResolvedImport { uint64_t guest_addr; - void *host_fn; + void* host_fn; uint32_t flags; CfreeEmuImportSignature signature; } CfreeEmuResolvedImport; @@ -76,16 +76,15 @@ typedef struct CfreeEmuResolvedObject { } CfreeEmuResolvedObject; typedef struct CfreeEmuExternalBindings { - CfreeStatus (*syscall)(void *user, CfreeEmu *, - const CfreeEmuSyscallRequest *, - CfreeEmuSyscallResult *out); - CfreeStatus (*resolve_import)(void *user, CfreeEmu *, - const CfreeEmuImportRequest *, - CfreeEmuResolvedImport *out); - CfreeStatus (*resolve_object)(void *user, CfreeEmu *, - const CfreeEmuObjectRequest *, - CfreeEmuResolvedObject *out); - void *user; + CfreeStatus (*syscall)(void* user, CfreeEmu*, const CfreeEmuSyscallRequest*, + CfreeEmuSyscallResult* out); + CfreeStatus (*resolve_import)(void* user, CfreeEmu*, + const CfreeEmuImportRequest*, + CfreeEmuResolvedImport* out); + CfreeStatus (*resolve_object)(void* user, CfreeEmu*, + const CfreeEmuObjectRequest*, + CfreeEmuResolvedObject* out); + void* user; } CfreeEmuExternalBindings; typedef struct CfreeEmuOptions { @@ -93,20 +92,20 @@ typedef struct CfreeEmuOptions { CfreeSlice guest_bytes; CfreeTarget guest_target; bool has_guest_target; - const CfreeJitHost *jit_host; + const CfreeJitHost* jit_host; int optimize; CfreeEmuTraceFlags trace; CfreeEmuExternalBindings bindings; - const char *const *argv; - const char *const *envp; + const char* const* argv; + const char* const* envp; } CfreeEmuOptions; -CFREE_API CfreeStatus cfree_emu_run(CfreeCompiler *, const CfreeEmuOptions *, - int *out_exit_code); -CFREE_API CfreeStatus cfree_emu_new(CfreeCompiler *, const CfreeEmuOptions *, - CfreeEmu **out); -CFREE_API CfreeStatus cfree_emu_step(CfreeEmu *, uint32_t nblocks); -CFREE_API void *cfree_emu_lookup(CfreeEmu *, uint64_t guest_pc); -CFREE_API void cfree_emu_free(CfreeEmu *); +CFREE_API CfreeStatus cfree_emu_run(CfreeCompiler*, const CfreeEmuOptions*, + int* out_exit_code); +CFREE_API CfreeStatus cfree_emu_new(CfreeCompiler*, const CfreeEmuOptions*, + CfreeEmu** out); +CFREE_API CfreeStatus cfree_emu_step(CfreeEmu*, uint32_t nblocks); +CFREE_API void* cfree_emu_lookup(CfreeEmu*, uint64_t guest_pc); +CFREE_API void cfree_emu_free(CfreeEmu*); #endif diff --git a/include/cfree/frontend.h b/include/cfree/frontend.h @@ -24,20 +24,23 @@ * cfree_frontend_run to get the same behavior without exposing libcfree's * internal panic machinery. */ -typedef CfreeStatus (*CfreeFrontendRunFn)(CfreeCompiler *, void *user); -CFREE_API CfreeStatus cfree_frontend_run(CfreeCompiler *, CfreeFrontendRunFn, void *user); +typedef CfreeStatus (*CfreeFrontendRunFn)(CfreeCompiler*, void* user); +CFREE_API CfreeStatus cfree_frontend_run(CfreeCompiler*, CfreeFrontendRunFn, + void* user); /* Optional metrics bridge for frontends. These are no-ops unless the host * supplied CfreeContext.metrics. Frontends use this public shim instead of * depending on libcfree's internal core headers. */ -CFREE_API void cfree_frontend_metrics_scope_begin(CfreeCompiler *, const char *name); -CFREE_API void cfree_frontend_metrics_scope_end(CfreeCompiler *, const char *name); -CFREE_API void cfree_frontend_metrics_count(CfreeCompiler *, const char *name, - uint64_t value); +CFREE_API void cfree_frontend_metrics_scope_begin(CfreeCompiler*, + const char* name); +CFREE_API void cfree_frontend_metrics_scope_end(CfreeCompiler*, + const char* name); +CFREE_API void cfree_frontend_metrics_count(CfreeCompiler*, const char* name, + uint64_t value); -CFREE_API _Noreturn void cfree_frontend_fatal(CfreeCompiler *, CfreeSrcLoc, - const char *fmt, ...); -CFREE_API _Noreturn void cfree_frontend_vfatal(CfreeCompiler *, CfreeSrcLoc, - const char *fmt, va_list); +CFREE_API _Noreturn void cfree_frontend_fatal(CfreeCompiler*, CfreeSrcLoc, + const char* fmt, ...); +CFREE_API _Noreturn void cfree_frontend_vfatal(CfreeCompiler*, CfreeSrcLoc, + const char* fmt, va_list); #endif diff --git a/include/cfree/jit.h b/include/cfree/jit.h @@ -66,12 +66,14 @@ typedef struct CfreeJitPublishResult { uint64_t generation; } CfreeJitPublishResult; -CFREE_API CfreeStatus cfree_jit_publish(CfreeJit*, const CfreeJitPublishOptions*, - CfreeJitPublishResult*); +CFREE_API CfreeStatus cfree_jit_publish(CfreeJit*, + const CfreeJitPublishOptions*, + CfreeJitPublishResult*); CFREE_API const CfreeObjFile* cfree_jit_view(CfreeJit*); CFREE_API CfreeStatus cfree_jit_addr_to_sym(CfreeJit*, uint64_t addr, - CfreeSlice* name_out, uint64_t* off_out); + CfreeSlice* name_out, + uint64_t* off_out); CFREE_API uint64_t cfree_jit_runtime_to_image(CfreeJit*, uint64_t runtime_pc); CFREE_API uint64_t cfree_jit_image_to_runtime(CfreeJit*, uint64_t image_vaddr); @@ -85,7 +87,8 @@ typedef struct CfreeJitSym { } CfreeJitSym; CFREE_API CfreeStatus cfree_jit_sym_iter_new(CfreeJit*, CfreeJitSymIter** out); -CFREE_API CfreeIterResult cfree_jit_sym_iter_next(CfreeJitSymIter*, CfreeJitSym* out); +CFREE_API CfreeIterResult cfree_jit_sym_iter_next(CfreeJitSymIter*, + CfreeJitSym* out); CFREE_API void cfree_jit_sym_iter_free(CfreeJitSymIter*); #endif diff --git a/include/cfree/link.h b/include/cfree/link.h @@ -112,8 +112,9 @@ typedef struct CfreeLinkScript { uint32_t ntop_asns; } CfreeLinkScript; -CFREE_API CfreeStatus cfree_link_script_parse(const CfreeContext*, CfreeSlice text, - CfreeLinkScript** out); +CFREE_API CfreeStatus cfree_link_script_parse(const CfreeContext*, + CfreeSlice text, + CfreeLinkScript** out); CFREE_API void cfree_link_script_free(const CfreeContext*, CfreeLinkScript*); typedef enum CfreeLinkMode { @@ -185,18 +186,23 @@ typedef struct CfreeLinkSessionOptions { } CfreeLinkSessionOptions; CFREE_API CfreeStatus cfree_link_session_new(CfreeCompiler*, - const CfreeLinkSessionOptions*, - CfreeLinkSession** out); -CFREE_API CfreeStatus cfree_link_session_add_obj(CfreeLinkSession*, CfreeObjBuilder*); -CFREE_API CfreeStatus cfree_link_session_add_obj_bytes(CfreeLinkSession*, CfreeSlice name, - const CfreeSlice*); -CFREE_API CfreeStatus cfree_link_session_add_archive_bytes(CfreeLinkSession*, - const CfreeLinkArchiveInput*); -CFREE_API CfreeStatus cfree_link_session_add_dso_bytes(CfreeLinkSession*, CfreeSlice name, - const CfreeSlice*); + const CfreeLinkSessionOptions*, + CfreeLinkSession** out); +CFREE_API CfreeStatus cfree_link_session_add_obj(CfreeLinkSession*, + CfreeObjBuilder*); +CFREE_API CfreeStatus cfree_link_session_add_obj_bytes(CfreeLinkSession*, + CfreeSlice name, + const CfreeSlice*); +CFREE_API CfreeStatus cfree_link_session_add_archive_bytes( + CfreeLinkSession*, const CfreeLinkArchiveInput*); +CFREE_API CfreeStatus cfree_link_session_add_dso_bytes(CfreeLinkSession*, + CfreeSlice name, + const CfreeSlice*); CFREE_API CfreeStatus cfree_link_session_resolve(CfreeLinkSession*); -CFREE_API CfreeStatus cfree_link_session_emit(CfreeLinkSession*, CfreeWriter* out); -CFREE_API CfreeStatus cfree_link_session_jit(CfreeLinkSession*, CfreeJit** out_jit); +CFREE_API CfreeStatus cfree_link_session_emit(CfreeLinkSession*, + CfreeWriter* out); +CFREE_API CfreeStatus cfree_link_session_jit(CfreeLinkSession*, + CfreeJit** out_jit); CFREE_API void cfree_link_session_free(CfreeLinkSession*); #endif diff --git a/include/cfree/object.h b/include/cfree/object.h @@ -135,61 +135,70 @@ typedef struct CfreeObjRelocDesc { int64_t addend; } CfreeObjRelocDesc; -CFREE_API CfreeStatus cfree_obj_builder_new(CfreeCompiler *, CfreeObjBuilder **out); -CFREE_API void cfree_obj_builder_free(CfreeObjBuilder *); +CFREE_API CfreeStatus cfree_obj_builder_new(CfreeCompiler*, + CfreeObjBuilder** out); +CFREE_API void cfree_obj_builder_free(CfreeObjBuilder*); /* Returns the CfreeCompiler this builder is bound to. Used by callers * that hold a builder via cfree_obj_file_builder (the reader-side path) * and need to intern strings into the matching Sym pool before issuing * mutator calls. */ -CFREE_API CfreeCompiler *cfree_obj_builder_compiler(CfreeObjBuilder *); - -CFREE_API CfreeStatus cfree_obj_builder_section(CfreeObjBuilder *, - const CfreeObjSectionDesc *, - CfreeObjSection *out); -CFREE_API CfreeStatus cfree_obj_builder_section_group(CfreeObjBuilder *, CfreeObjSection, - CfreeObjGroup); - -CFREE_API CfreeStatus cfree_obj_builder_pos(CfreeObjBuilder *, CfreeObjSection, - uint64_t *out); -CFREE_API CfreeStatus cfree_obj_builder_align(CfreeObjBuilder *, CfreeObjSection, - uint32_t align, uint64_t *new_pos_out); -CFREE_API CfreeStatus cfree_obj_builder_write(CfreeObjBuilder *, CfreeObjSection, - const void *data, size_t n); -CFREE_API CfreeStatus cfree_obj_builder_reserve(CfreeObjBuilder *, CfreeObjSection, - size_t n, void **out); -CFREE_API CfreeStatus cfree_obj_builder_reserve_bss(CfreeObjBuilder *, CfreeObjSection, - uint64_t size, uint32_t align); -CFREE_API CfreeStatus cfree_obj_builder_patch(CfreeObjBuilder *, CfreeObjSection, - uint64_t offset, const void *data, - size_t n); - -CFREE_API CfreeStatus cfree_obj_builder_symbol(CfreeObjBuilder *, - const CfreeObjSymbolDesc *, - CfreeObjSymbol *out); -CFREE_API CfreeStatus cfree_obj_builder_symbol_define(CfreeObjBuilder *, CfreeObjSymbol, - CfreeObjSection, uint64_t value, - uint64_t size); -CFREE_API CfreeStatus cfree_obj_builder_reloc(CfreeObjBuilder *, - const CfreeObjRelocDesc *); - -CFREE_API CfreeStatus cfree_obj_builder_group(CfreeObjBuilder *, CfreeSym name, - CfreeObjSymbol signature, uint32_t flags, - CfreeObjGroup *out); -CFREE_API CfreeStatus cfree_obj_builder_group_add_section(CfreeObjBuilder *, - CfreeObjGroup, - CfreeObjSection); - -CFREE_API CfreeStatus cfree_obj_builder_finalize(CfreeObjBuilder *); -CFREE_API CfreeStatus cfree_obj_builder_emit(CfreeObjBuilder *, CfreeWriter *); +CFREE_API CfreeCompiler* cfree_obj_builder_compiler(CfreeObjBuilder*); + +CFREE_API CfreeStatus cfree_obj_builder_section(CfreeObjBuilder*, + const CfreeObjSectionDesc*, + CfreeObjSection* out); +CFREE_API CfreeStatus cfree_obj_builder_section_group(CfreeObjBuilder*, + CfreeObjSection, + CfreeObjGroup); + +CFREE_API CfreeStatus cfree_obj_builder_pos(CfreeObjBuilder*, CfreeObjSection, + uint64_t* out); +CFREE_API CfreeStatus cfree_obj_builder_align(CfreeObjBuilder*, CfreeObjSection, + uint32_t align, + uint64_t* new_pos_out); +CFREE_API CfreeStatus cfree_obj_builder_write(CfreeObjBuilder*, CfreeObjSection, + const void* data, size_t n); +CFREE_API CfreeStatus cfree_obj_builder_reserve(CfreeObjBuilder*, + CfreeObjSection, size_t n, + void** out); +CFREE_API CfreeStatus cfree_obj_builder_reserve_bss(CfreeObjBuilder*, + CfreeObjSection, + uint64_t size, + uint32_t align); +CFREE_API CfreeStatus cfree_obj_builder_patch(CfreeObjBuilder*, CfreeObjSection, + uint64_t offset, const void* data, + size_t n); + +CFREE_API CfreeStatus cfree_obj_builder_symbol(CfreeObjBuilder*, + const CfreeObjSymbolDesc*, + CfreeObjSymbol* out); +CFREE_API CfreeStatus cfree_obj_builder_symbol_define(CfreeObjBuilder*, + CfreeObjSymbol, + CfreeObjSection, + uint64_t value, + uint64_t size); +CFREE_API CfreeStatus cfree_obj_builder_reloc(CfreeObjBuilder*, + const CfreeObjRelocDesc*); + +CFREE_API CfreeStatus cfree_obj_builder_group(CfreeObjBuilder*, CfreeSym name, + CfreeObjSymbol signature, + uint32_t flags, + CfreeObjGroup* out); +CFREE_API CfreeStatus cfree_obj_builder_group_add_section(CfreeObjBuilder*, + CfreeObjGroup, + CfreeObjSection); + +CFREE_API CfreeStatus cfree_obj_builder_finalize(CfreeObjBuilder*); +CFREE_API CfreeStatus cfree_obj_builder_emit(CfreeObjBuilder*, CfreeWriter*); /* Emit using a caller-specified output format instead of the builder's * own target.obj. Used by `objcopy -O <bfdname>` to convert between * ELF / Mach-O / COFF / Wasm at the same arch. Returns * CFREE_UNSUPPORTED when the active arch doesn't have a backend for * the requested format (e.g. RISC-V → Mach-O). */ -CFREE_API CfreeStatus cfree_obj_builder_emit_as(CfreeObjBuilder *, CfreeObjFmt, - CfreeWriter *); +CFREE_API CfreeStatus cfree_obj_builder_emit_as(CfreeObjBuilder*, CfreeObjFmt, + CfreeWriter*); /* ============================================================ * Mutators (strip / objcopy support) @@ -204,22 +213,28 @@ CFREE_API CfreeStatus cfree_obj_builder_emit_as(CfreeObjBuilder *, CfreeObjFmt, * mutation targets — the reader produces an already-finalized builder * and mutators are legal on it. */ -CFREE_API CfreeStatus cfree_obj_builder_remove_section(CfreeObjBuilder *, - CfreeObjSection); -CFREE_API CfreeStatus cfree_obj_builder_remove_symbol(CfreeObjBuilder *, CfreeObjSymbol); -CFREE_API CfreeStatus cfree_obj_builder_remove_group(CfreeObjBuilder *, CfreeObjGroup); -CFREE_API CfreeStatus cfree_obj_builder_rename_section(CfreeObjBuilder *, - CfreeObjSection, CfreeSym new_name); -CFREE_API CfreeStatus cfree_obj_builder_rename_symbol(CfreeObjBuilder *, CfreeObjSymbol, - CfreeSym new_name); -CFREE_API CfreeStatus cfree_obj_builder_symbol_set_bind(CfreeObjBuilder *, - CfreeObjSymbol, CfreeSymBind); -CFREE_API CfreeStatus cfree_obj_builder_symbol_set_vis(CfreeObjBuilder *, CfreeObjSymbol, - CfreeSymVis); -CFREE_API CfreeStatus cfree_obj_builder_section_replace_bytes(CfreeObjBuilder *, - CfreeObjSection, - const void *data, - size_t n); +CFREE_API CfreeStatus cfree_obj_builder_remove_section(CfreeObjBuilder*, + CfreeObjSection); +CFREE_API CfreeStatus cfree_obj_builder_remove_symbol(CfreeObjBuilder*, + CfreeObjSymbol); +CFREE_API CfreeStatus cfree_obj_builder_remove_group(CfreeObjBuilder*, + CfreeObjGroup); +CFREE_API CfreeStatus cfree_obj_builder_rename_section(CfreeObjBuilder*, + CfreeObjSection, + CfreeSym new_name); +CFREE_API CfreeStatus cfree_obj_builder_rename_symbol(CfreeObjBuilder*, + CfreeObjSymbol, + CfreeSym new_name); +CFREE_API CfreeStatus cfree_obj_builder_symbol_set_bind(CfreeObjBuilder*, + CfreeObjSymbol, + CfreeSymBind); +CFREE_API CfreeStatus cfree_obj_builder_symbol_set_vis(CfreeObjBuilder*, + CfreeObjSymbol, + CfreeSymVis); +CFREE_API CfreeStatus cfree_obj_builder_section_replace_bytes(CfreeObjBuilder*, + CfreeObjSection, + const void* data, + size_t n); /* ============================================================ * Reader / inspection @@ -245,28 +260,33 @@ typedef struct CfreeObjGroupInfo { uint32_t flags; /* CfreeObjGroupFlag */ uint32_t nsections; /* Borrowed; valid until the next groupiter_next call or _free. Members - * pointing at the OBJ_SEC_NONE sentinel are reported as CFREE_SECTION_NONE. */ - const CfreeObjSection *sections; + * pointing at the OBJ_SEC_NONE sentinel are reported as CFREE_SECTION_NONE. + */ + const CfreeObjSection* sections; } CfreeObjGroupInfo; -CFREE_API CfreeBinFmt cfree_detect_fmt(const uint8_t *data, size_t len); -CFREE_API CfreeStatus cfree_detect_target(const uint8_t *data, size_t len, - CfreeTarget *out); - -CFREE_API CfreeStatus cfree_obj_open(const CfreeContext *, CfreeSlice name, - const CfreeSlice *, CfreeObjFile **out); -CFREE_API void cfree_obj_free(CfreeObjFile *); - -CFREE_API CfreeObjFmt cfree_obj_fmt(const CfreeObjFile *); -CFREE_API CfreeTarget cfree_obj_target(const CfreeObjFile *); - -CFREE_API uint32_t cfree_obj_nsections(const CfreeObjFile *); -CFREE_API CfreeStatus cfree_obj_section(const CfreeObjFile *, CfreeObjSection idx, - CfreeObjSecInfo *out); -CFREE_API CfreeStatus cfree_obj_section_data(const CfreeObjFile *, CfreeObjSection idx, - const uint8_t **data_out, size_t *len_out); -CFREE_API CfreeStatus cfree_obj_section_by_name(const CfreeObjFile *, CfreeSlice name, - CfreeObjSection *out); +CFREE_API CfreeBinFmt cfree_detect_fmt(const uint8_t* data, size_t len); +CFREE_API CfreeStatus cfree_detect_target(const uint8_t* data, size_t len, + CfreeTarget* out); + +CFREE_API CfreeStatus cfree_obj_open(const CfreeContext*, CfreeSlice name, + const CfreeSlice*, CfreeObjFile** out); +CFREE_API void cfree_obj_free(CfreeObjFile*); + +CFREE_API CfreeObjFmt cfree_obj_fmt(const CfreeObjFile*); +CFREE_API CfreeTarget cfree_obj_target(const CfreeObjFile*); + +CFREE_API uint32_t cfree_obj_nsections(const CfreeObjFile*); +CFREE_API CfreeStatus cfree_obj_section(const CfreeObjFile*, + CfreeObjSection idx, + CfreeObjSecInfo* out); +CFREE_API CfreeStatus cfree_obj_section_data(const CfreeObjFile*, + CfreeObjSection idx, + const uint8_t** data_out, + size_t* len_out); +CFREE_API CfreeStatus cfree_obj_section_by_name(const CfreeObjFile*, + CfreeSlice name, + CfreeObjSection* out); /* Format-specific raw section attributes preserved by the reader. * @@ -281,30 +301,34 @@ CFREE_API CfreeStatus cfree_obj_section_by_name(const CfreeObjFile *, CfreeSlice * Use when canonical SecFlag/SecKind isn't enough — e.g. objdump * decoding `IMAGE_SCN_LNK_COMDAT` / `_MEM_DISCARDABLE` for diagnostic * display. NULL output pointers are ignored. */ -CFREE_API CfreeStatus cfree_obj_section_format_flags(const CfreeObjFile *, - CfreeObjSection idx, - uint32_t *raw_type_out, - uint32_t *raw_flags_out); - -CFREE_API CfreeStatus cfree_obj_symbol_by_name(const CfreeObjFile *, CfreeSlice name, - CfreeObjSymInfo *out); - -CFREE_API CfreeStatus cfree_obj_symiter_new(CfreeObjFile *, CfreeObjSymIter **out); -CFREE_API CfreeIterResult cfree_obj_symiter_next(CfreeObjSymIter *, - CfreeObjSymInfo *out); -CFREE_API void cfree_obj_symiter_free(CfreeObjSymIter *); - -CFREE_API CfreeStatus cfree_obj_reliter_new(CfreeObjFile *, CfreeObjRelocIter **out); -CFREE_API CfreeIterResult cfree_obj_reliter_next(CfreeObjRelocIter *, - CfreeObjReloc *out); -CFREE_API void cfree_obj_reliter_free(CfreeObjRelocIter *); +CFREE_API CfreeStatus cfree_obj_section_format_flags(const CfreeObjFile*, + CfreeObjSection idx, + uint32_t* raw_type_out, + uint32_t* raw_flags_out); + +CFREE_API CfreeStatus cfree_obj_symbol_by_name(const CfreeObjFile*, + CfreeSlice name, + CfreeObjSymInfo* out); + +CFREE_API CfreeStatus cfree_obj_symiter_new(CfreeObjFile*, + CfreeObjSymIter** out); +CFREE_API CfreeIterResult cfree_obj_symiter_next(CfreeObjSymIter*, + CfreeObjSymInfo* out); +CFREE_API void cfree_obj_symiter_free(CfreeObjSymIter*); + +CFREE_API CfreeStatus cfree_obj_reliter_new(CfreeObjFile*, + CfreeObjRelocIter** out); +CFREE_API CfreeIterResult cfree_obj_reliter_next(CfreeObjRelocIter*, + CfreeObjReloc* out); +CFREE_API void cfree_obj_reliter_free(CfreeObjRelocIter*); /* Section-group iteration (ELF SHT_GROUP / COMDAT and friends). Empty * for formats / objects that carry no groups. */ -CFREE_API CfreeStatus cfree_obj_groupiter_new(CfreeObjFile *, CfreeObjGroupIter **out); -CFREE_API CfreeIterResult cfree_obj_groupiter_next(CfreeObjGroupIter *, - CfreeObjGroupInfo *out); -CFREE_API void cfree_obj_groupiter_free(CfreeObjGroupIter *); +CFREE_API CfreeStatus cfree_obj_groupiter_new(CfreeObjFile*, + CfreeObjGroupIter** out); +CFREE_API CfreeIterResult cfree_obj_groupiter_next(CfreeObjGroupIter*, + CfreeObjGroupInfo* out); +CFREE_API void cfree_obj_groupiter_free(CfreeObjGroupIter*); /* Roundtrip: open an object via cfree_obj_open, then hand its underlying * builder back. The builder is the same one the reader populated; it is @@ -317,6 +341,6 @@ CFREE_API void cfree_obj_groupiter_free(CfreeObjGroupIter *); * symbol_set_* / section_replace_bytes calls above. Drops and renames * are cheap field writes; emit applies the cascade (drop relocs against * removed sections, etc.) automatically. */ -CFREE_API CfreeObjBuilder *cfree_obj_file_builder(const CfreeObjFile *); +CFREE_API CfreeObjBuilder* cfree_obj_file_builder(const CfreeObjFile*); #endif diff --git a/include/cfree/preprocess.h b/include/cfree/preprocess.h @@ -31,8 +31,9 @@ typedef struct CfreePreprocessOptions { uint32_t nundefines; } CfreePreprocessOptions; -CFREE_API CfreeStatus cfree_cpp_preprocess(CfreeCompiler*, const CfreePreprocessOptions*, - CfreeSlice name, const CfreeSlice*, - CfreeWriter*); +CFREE_API CfreeStatus cfree_cpp_preprocess(CfreeCompiler*, + const CfreePreprocessOptions*, + CfreeSlice name, const CfreeSlice*, + CfreeWriter*); #endif diff --git a/include/cfree/source.h b/include/cfree/source.h @@ -11,15 +11,17 @@ * dependency reporting and diagnostics. */ -CFREE_API CfreeStatus cfree_source_add_file(CfreeCompiler *, const char *path, - int system_header, uint32_t *file_id_out); -CFREE_API CfreeStatus cfree_source_add_memory(CfreeCompiler *, CfreeSlice name, - uint32_t *file_id_out); -CFREE_API CfreeStatus cfree_source_add_builtin(CfreeCompiler *, CfreeSlice name, - uint32_t *file_id_out); -CFREE_API CfreeStatus cfree_source_add_include(CfreeCompiler *, uint32_t includer_file_id, - uint32_t included_file_id, - CfreeSrcLoc loc, int system); +CFREE_API CfreeStatus cfree_source_add_file(CfreeCompiler*, const char* path, + int system_header, + uint32_t* file_id_out); +CFREE_API CfreeStatus cfree_source_add_memory(CfreeCompiler*, CfreeSlice name, + uint32_t* file_id_out); +CFREE_API CfreeStatus cfree_source_add_builtin(CfreeCompiler*, CfreeSlice name, + uint32_t* file_id_out); +CFREE_API CfreeStatus cfree_source_add_include(CfreeCompiler*, + uint32_t includer_file_id, + uint32_t included_file_id, + CfreeSrcLoc loc, int system); typedef struct CfreeSourceFile { uint32_t id; @@ -30,7 +32,7 @@ typedef struct CfreeSourceFile { uint16_t pad; } CfreeSourceFile; -CFREE_API CfreeStatus cfree_source_file(CfreeCompiler *, uint32_t file_id, - CfreeSourceFile *out); +CFREE_API CfreeStatus cfree_source_file(CfreeCompiler*, uint32_t file_id, + CfreeSourceFile* out); #endif diff --git a/include/cfree/support/arena.h b/include/cfree/support/arena.h @@ -11,20 +11,21 @@ typedef struct CfreeArena CfreeArena; -CFREE_API CfreeStatus cfree_arena_new(CfreeHeap *, size_t block_size, CfreeArena **out); -CFREE_API void cfree_arena_free(CfreeArena *); -CFREE_API void cfree_arena_reset(CfreeArena *); -CFREE_API void *cfree_arena_alloc(CfreeArena *, size_t size, size_t align); -CFREE_API void *cfree_arena_zalloc(CfreeArena *, size_t size, size_t align); -CFREE_API char *cfree_arena_strdup(CfreeArena *, const char *s, size_t len); +CFREE_API CfreeStatus cfree_arena_new(CfreeHeap*, size_t block_size, + CfreeArena** out); +CFREE_API void cfree_arena_free(CfreeArena*); +CFREE_API void cfree_arena_reset(CfreeArena*); +CFREE_API void* cfree_arena_alloc(CfreeArena*, size_t size, size_t align); +CFREE_API void* cfree_arena_zalloc(CfreeArena*, size_t size, size_t align); +CFREE_API char* cfree_arena_strdup(CfreeArena*, const char* s, size_t len); #define cfree_arena_new_obj(a, T) \ - ((T *)cfree_arena_alloc((a), sizeof(T), _Alignof(T))) + ((T*)cfree_arena_alloc((a), sizeof(T), _Alignof(T))) #define cfree_arena_znew_obj(a, T) \ - ((T *)cfree_arena_zalloc((a), sizeof(T), _Alignof(T))) + ((T*)cfree_arena_zalloc((a), sizeof(T), _Alignof(T))) #define cfree_arena_array(a, T, n) \ - ((T *)cfree_arena_alloc((a), sizeof(T) * (size_t)(n), _Alignof(T))) + ((T*)cfree_arena_alloc((a), sizeof(T) * (size_t)(n), _Alignof(T))) #define cfree_arena_zarray(a, T, n) \ - ((T *)cfree_arena_zalloc((a), sizeof(T) * (size_t)(n), _Alignof(T))) + ((T*)cfree_arena_zalloc((a), sizeof(T) * (size_t)(n), _Alignof(T))) #endif diff --git a/include/cfree/support/hashmap.h b/include/cfree/support/hashmap.h @@ -34,143 +34,141 @@ static inline uint32_t cfree_hash_u64(uint64_t x) { #define CFREE_HASHMAP_UNUSED #endif -#define CFREE_HASHMAP_DEFINE(NAME, KT, VT, HASH_FN) \ - typedef struct NAME##Slot { \ - KT k; \ - VT v; \ - } NAME##Slot; \ - typedef struct NAME { \ - CfreeHeap* heap; \ - NAME##Slot* slots; \ - uint32_t cap; \ - uint32_t used; \ - } NAME; \ - \ - CFREE_HASHMAP_UNUSED static void NAME##_resize(NAME* m, \ - uint32_t new_cap) { \ - NAME##Slot* fresh; \ - uint32_t i, mask; \ - fresh = (NAME##Slot*)m->heap->alloc(m->heap, sizeof(*fresh) * new_cap, \ - _Alignof(NAME##Slot)); \ - if (!fresh) return; \ - memset(fresh, 0, sizeof(*fresh) * new_cap); \ - mask = new_cap - 1u; \ - for (i = 0; i < m->cap; ++i) { \ - KT k = m->slots[i].k; \ - uint32_t j; \ - if (!(k)) continue; \ - j = HASH_FN(k) & mask; \ - while (fresh[j].k) j = (j + 1u) & mask; \ - fresh[j] = m->slots[i]; \ - } \ - if (m->slots) \ - m->heap->free(m->heap, m->slots, sizeof(*m->slots) * m->cap); \ - m->slots = fresh; \ - m->cap = new_cap; \ - } \ - \ - CFREE_HASHMAP_UNUSED static inline void NAME##_init_cap( \ - NAME* m, CfreeHeap* h, uint32_t cap) { \ - m->heap = h; \ - m->slots = NULL; \ - m->cap = 0; \ - m->used = 0; \ - if (cap) NAME##_resize(m, cap); \ - } \ - \ - CFREE_HASHMAP_UNUSED static inline void NAME##_init(NAME* m, \ - CfreeHeap* h) { \ - NAME##_init_cap(m, h, CFREE_HASHMAP_INIT_CAP); \ - } \ - \ - CFREE_HASHMAP_UNUSED static inline void NAME##_fini(NAME* m) { \ - if (m->slots) \ - m->heap->free(m->heap, m->slots, sizeof(*m->slots) * m->cap); \ - m->slots = NULL; \ - m->cap = m->used = 0; \ - } \ - \ - CFREE_HASHMAP_UNUSED static inline VT* NAME##_get(const NAME* m, KT k) { \ - uint32_t mask, j; \ - if (m->cap == 0 || !(k)) return NULL; \ - mask = m->cap - 1u; \ - j = HASH_FN(k) & mask; \ - while (m->slots[j].k) { \ - if (m->slots[j].k == (k)) return &m->slots[j].v; \ - j = (j + 1u) & mask; \ - } \ - return NULL; \ - } \ - \ - CFREE_HASHMAP_UNUSED static inline int NAME##_set(NAME* m, KT k, VT v) { \ - uint32_t mask, j; \ - if (m->cap == 0 || \ - m->used * CFREE_HASHMAP_LOAD_DEN >= m->cap * CFREE_HASHMAP_LOAD_NUM) \ - NAME##_resize(m, m->cap ? m->cap * 2u : CFREE_HASHMAP_INIT_CAP); \ - mask = m->cap - 1u; \ - j = HASH_FN(k) & mask; \ - while (m->slots[j].k) { \ - if (m->slots[j].k == (k)) { \ - m->slots[j].v = (v); \ - return 0; \ - } \ - j = (j + 1u) & mask; \ - } \ - m->slots[j].k = (k); \ - m->slots[j].v = (v); \ - m->used++; \ - return 1; \ - } \ - \ - CFREE_HASHMAP_UNUSED static inline int NAME##_try_insert( \ - NAME* m, KT k, VT v, VT* existing_out) { \ - uint32_t mask, j; \ - if (m->cap == 0 || \ - m->used * CFREE_HASHMAP_LOAD_DEN >= m->cap * CFREE_HASHMAP_LOAD_NUM) \ - NAME##_resize(m, m->cap ? m->cap * 2u : CFREE_HASHMAP_INIT_CAP); \ - mask = m->cap - 1u; \ - j = HASH_FN(k) & mask; \ - while (m->slots[j].k) { \ - if (m->slots[j].k == (k)) { \ - if (existing_out) *existing_out = m->slots[j].v; \ - return 0; \ - } \ - j = (j + 1u) & mask; \ - } \ - m->slots[j].k = (k); \ - m->slots[j].v = (v); \ - m->used++; \ - return 1; \ - } \ - \ - CFREE_HASHMAP_UNUSED static inline void NAME##_del(NAME* m, KT k) { \ - uint32_t mask, j; \ - if (m->cap == 0 || !(k)) return; \ - mask = m->cap - 1u; \ - j = HASH_FN(k) & mask; \ - while (m->slots[j].k) { \ - if (m->slots[j].k == (k)) { \ - uint32_t i = (j + 1u) & mask; \ - m->slots[j].k = 0; \ - m->used--; \ - while (m->slots[i].k) { \ - KT rk = m->slots[i].k; \ - VT rv = m->slots[i].v; \ - uint32_t nh; \ - m->slots[i].k = 0; \ - m->used--; \ - nh = HASH_FN(rk) & mask; \ - while (m->slots[nh].k) nh = (nh + 1u) & mask; \ - m->slots[nh].k = rk; \ - m->slots[nh].v = rv; \ - m->used++; \ - i = (i + 1u) & mask; \ - } \ - return; \ - } \ - j = (j + 1u) & mask; \ - } \ - } \ +#define CFREE_HASHMAP_DEFINE(NAME, KT, VT, HASH_FN) \ + typedef struct NAME##Slot { \ + KT k; \ + VT v; \ + } NAME##Slot; \ + typedef struct NAME { \ + CfreeHeap* heap; \ + NAME##Slot* slots; \ + uint32_t cap; \ + uint32_t used; \ + } NAME; \ + \ + CFREE_HASHMAP_UNUSED static void NAME##_resize(NAME* m, uint32_t new_cap) { \ + NAME##Slot* fresh; \ + uint32_t i, mask; \ + fresh = (NAME##Slot*)m->heap->alloc(m->heap, sizeof(*fresh) * new_cap, \ + _Alignof(NAME##Slot)); \ + if (!fresh) return; \ + memset(fresh, 0, sizeof(*fresh) * new_cap); \ + mask = new_cap - 1u; \ + for (i = 0; i < m->cap; ++i) { \ + KT k = m->slots[i].k; \ + uint32_t j; \ + if (!(k)) continue; \ + j = HASH_FN(k) & mask; \ + while (fresh[j].k) j = (j + 1u) & mask; \ + fresh[j] = m->slots[i]; \ + } \ + if (m->slots) \ + m->heap->free(m->heap, m->slots, sizeof(*m->slots) * m->cap); \ + m->slots = fresh; \ + m->cap = new_cap; \ + } \ + \ + CFREE_HASHMAP_UNUSED static inline void NAME##_init_cap( \ + NAME* m, CfreeHeap* h, uint32_t cap) { \ + m->heap = h; \ + m->slots = NULL; \ + m->cap = 0; \ + m->used = 0; \ + if (cap) NAME##_resize(m, cap); \ + } \ + \ + CFREE_HASHMAP_UNUSED static inline void NAME##_init(NAME* m, CfreeHeap* h) { \ + NAME##_init_cap(m, h, CFREE_HASHMAP_INIT_CAP); \ + } \ + \ + CFREE_HASHMAP_UNUSED static inline void NAME##_fini(NAME* m) { \ + if (m->slots) \ + m->heap->free(m->heap, m->slots, sizeof(*m->slots) * m->cap); \ + m->slots = NULL; \ + m->cap = m->used = 0; \ + } \ + \ + CFREE_HASHMAP_UNUSED static inline VT* NAME##_get(const NAME* m, KT k) { \ + uint32_t mask, j; \ + if (m->cap == 0 || !(k)) return NULL; \ + mask = m->cap - 1u; \ + j = HASH_FN(k) & mask; \ + while (m->slots[j].k) { \ + if (m->slots[j].k == (k)) return &m->slots[j].v; \ + j = (j + 1u) & mask; \ + } \ + return NULL; \ + } \ + \ + CFREE_HASHMAP_UNUSED static inline int NAME##_set(NAME* m, KT k, VT v) { \ + uint32_t mask, j; \ + if (m->cap == 0 || \ + m->used * CFREE_HASHMAP_LOAD_DEN >= m->cap * CFREE_HASHMAP_LOAD_NUM) \ + NAME##_resize(m, m->cap ? m->cap * 2u : CFREE_HASHMAP_INIT_CAP); \ + mask = m->cap - 1u; \ + j = HASH_FN(k) & mask; \ + while (m->slots[j].k) { \ + if (m->slots[j].k == (k)) { \ + m->slots[j].v = (v); \ + return 0; \ + } \ + j = (j + 1u) & mask; \ + } \ + m->slots[j].k = (k); \ + m->slots[j].v = (v); \ + m->used++; \ + return 1; \ + } \ + \ + CFREE_HASHMAP_UNUSED static inline int NAME##_try_insert( \ + NAME* m, KT k, VT v, VT* existing_out) { \ + uint32_t mask, j; \ + if (m->cap == 0 || \ + m->used * CFREE_HASHMAP_LOAD_DEN >= m->cap * CFREE_HASHMAP_LOAD_NUM) \ + NAME##_resize(m, m->cap ? m->cap * 2u : CFREE_HASHMAP_INIT_CAP); \ + mask = m->cap - 1u; \ + j = HASH_FN(k) & mask; \ + while (m->slots[j].k) { \ + if (m->slots[j].k == (k)) { \ + if (existing_out) *existing_out = m->slots[j].v; \ + return 0; \ + } \ + j = (j + 1u) & mask; \ + } \ + m->slots[j].k = (k); \ + m->slots[j].v = (v); \ + m->used++; \ + return 1; \ + } \ + \ + CFREE_HASHMAP_UNUSED static inline void NAME##_del(NAME* m, KT k) { \ + uint32_t mask, j; \ + if (m->cap == 0 || !(k)) return; \ + mask = m->cap - 1u; \ + j = HASH_FN(k) & mask; \ + while (m->slots[j].k) { \ + if (m->slots[j].k == (k)) { \ + uint32_t i = (j + 1u) & mask; \ + m->slots[j].k = 0; \ + m->used--; \ + while (m->slots[i].k) { \ + KT rk = m->slots[i].k; \ + VT rv = m->slots[i].v; \ + uint32_t nh; \ + m->slots[i].k = 0; \ + m->used--; \ + nh = HASH_FN(rk) & mask; \ + while (m->slots[nh].k) nh = (nh + 1u) & mask; \ + m->slots[nh].k = rk; \ + m->slots[nh].v = rv; \ + m->used++; \ + i = (i + 1u) & mask; \ + } \ + return; \ + } \ + j = (j + 1u) & mask; \ + } \ + } \ struct NAME #endif diff --git a/include/cfree/wasm.h b/include/cfree/wasm.h @@ -99,11 +99,9 @@ CFREE_API void cfree_wasm_set_host_imports(CfreeCompiler*, * `cfree_wasm_set_host_imports`. The output pointer / count / resolver * remain owned by the compiler (do not free). Used by runners to feed the * bind step. Any out parameter may be NULL. */ -CFREE_API void cfree_wasm_get_host_imports(CfreeCompiler*, - const CfreeWasmHostImport** imports_out, - size_t* nimports_out, - CfreeWasmResolveFn* resolve_out, - void** user_out); +CFREE_API void cfree_wasm_get_host_imports( + CfreeCompiler*, const CfreeWasmHostImport** imports_out, + size_t* nimports_out, CfreeWasmResolveFn* resolve_out, void** user_out); /* Resolve every declared import in the module loaded into `jit` against * the supplied static table and/or resolver, and write the resolved diff --git a/lang/c/abi/c_abi.c b/lang/c/abi/c_abi.c @@ -79,8 +79,8 @@ const ABIRecordLayout* c_abi_record_layout(TargetABI* a, Pool* p, if (cfree_cg_type_record_field(a, id, i, &f, &off) != 0) return NULL; fl[i].offset = (u32)off; fl[i].storage_size = f.bit_storage_size - ? f.bit_storage_size - : (u32)cfree_cg_type_size(a, f.type); + ? f.bit_storage_size + : (u32)cfree_cg_type_size(a, f.type); if (t->rec.fields[i].flags & FIELD_BITFIELD) { fl[i].bit_width = t->rec.fields[i].bitfield_width; fl[i].bit_offset = f.bit_offset; @@ -142,15 +142,19 @@ const Type* c_abi_va_list_type(TargetABI* a, Pool* p) { SrcLoc nl = {0, 0, 0}; TagId tg = type_tag_new(p, TAG_STRUCT, name, nl); TypeRecordBuilder* b = type_record_begin(p, TY_STRUCT, tg, name); - type_record_field( - b, (Field){.name = cfree_sym_intern(p->c, CFREE_SLICE_LIT("gp_offset")), .type = uit}); - type_record_field( - b, (Field){.name = cfree_sym_intern(p->c, CFREE_SLICE_LIT("fp_offset")), .type = uit}); - type_record_field( - b, (Field){.name = cfree_sym_intern(p->c, CFREE_SLICE_LIT("overflow_arg_area")), - .type = vp}); - type_record_field( - b, (Field){.name = cfree_sym_intern(p->c, CFREE_SLICE_LIT("reg_save_area")), .type = vp}); + type_record_field(b, (Field){.name = cfree_sym_intern( + p->c, CFREE_SLICE_LIT("gp_offset")), + .type = uit}); + type_record_field(b, (Field){.name = cfree_sym_intern( + p->c, CFREE_SLICE_LIT("fp_offset")), + .type = uit}); + type_record_field(b, + (Field){.name = cfree_sym_intern( + p->c, CFREE_SLICE_LIT("overflow_arg_area")), + .type = vp}); + type_record_field(b, (Field){.name = cfree_sym_intern( + p->c, CFREE_SLICE_LIT("reg_save_area")), + .type = vp}); return type_record_end(p, b); } case CFREE_ARCH_ARM_64: @@ -163,16 +167,21 @@ const Type* c_abi_va_list_type(TargetABI* a, Pool* p) { SrcLoc nl = {0, 0, 0}; TagId tg = type_tag_new(p, TAG_STRUCT, name, nl); TypeRecordBuilder* b = type_record_begin(p, TY_STRUCT, tg, name); - type_record_field( - b, (Field){.name = cfree_sym_intern(p->c, CFREE_SLICE_LIT("__stack")), .type = vp}); - type_record_field( - b, (Field){.name = cfree_sym_intern(p->c, CFREE_SLICE_LIT("__gr_top")), .type = vp}); - type_record_field( - b, (Field){.name = cfree_sym_intern(p->c, CFREE_SLICE_LIT("__vr_top")), .type = vp}); - type_record_field( - b, (Field){.name = cfree_sym_intern(p->c, CFREE_SLICE_LIT("__gr_offs")), .type = it}); - type_record_field( - b, (Field){.name = cfree_sym_intern(p->c, CFREE_SLICE_LIT("__vr_offs")), .type = it}); + type_record_field(b, (Field){.name = cfree_sym_intern( + p->c, CFREE_SLICE_LIT("__stack")), + .type = vp}); + type_record_field(b, (Field){.name = cfree_sym_intern( + p->c, CFREE_SLICE_LIT("__gr_top")), + .type = vp}); + type_record_field(b, (Field){.name = cfree_sym_intern( + p->c, CFREE_SLICE_LIT("__vr_top")), + .type = vp}); + type_record_field(b, (Field){.name = cfree_sym_intern( + p->c, CFREE_SLICE_LIT("__gr_offs")), + .type = it}); + type_record_field(b, (Field){.name = cfree_sym_intern( + p->c, CFREE_SLICE_LIT("__vr_offs")), + .type = it}); return type_record_end(p, b); } case CFREE_ARCH_RV64: diff --git a/lang/c/c.c b/lang/c/c.c @@ -116,8 +116,7 @@ static CfreeStatus c_frontend_compile( cfree_frontend_metrics_scope_end(c, "compile.c.pp_push_input"); cfree_frontend_metrics_scope_begin(c, "compile.c.parse_codegen"); - parse_c(c, pool, pp, decls, cg, - (CfreeSymVis)opts->code.default_visibility); + parse_c(c, pool, pp, decls, cg, (CfreeSymVis)opts->code.default_visibility); cfree_frontend_metrics_scope_end(c, "compile.c.parse_codegen"); cfree_frontend_metrics_scope_begin(c, "compile.c.cleanup"); @@ -141,9 +140,5 @@ static void c_frontend_free(CfreeFrontendState* frontend) { * to CFREE_LANG_C as the default when nothing else matches, so listing * `c`/`h` here would only duplicate that fallback. */ const CfreeFrontendVTable cfree_c_frontend_vtable = { - c_frontend_new, - c_frontend_compile, - c_frontend_free, - NULL, - 0, + c_frontend_new, c_frontend_compile, c_frontend_free, NULL, 0, }; diff --git a/lang/c/parse/cg_adapter.c b/lang/c/parse/cg_adapter.c @@ -96,8 +96,10 @@ void pcg_dup_type(Parser* p) { const Type* ty = pcg_top_type(p); u8 flags = p->cg_type_sp ? p->cg_value_flags[p->cg_type_sp - 1u] : 0; PcgLvAux aux; - if (p->cg_type_sp) aux = p->cg_lv_aux[p->cg_type_sp - 1u]; - else pcg_aux_clear(&aux); + if (p->cg_type_sp) + aux = p->cg_lv_aux[p->cg_type_sp - 1u]; + else + pcg_aux_clear(&aux); pcg_push_type(p, ty); if (p->cg_type_sp) { p->cg_value_flags[p->cg_type_sp - 1u] = flags; @@ -473,17 +475,19 @@ void pcg_load(Parser* p) { * The materialization sequence depends on the aux: * base_kind == LOCAL: * - scale == 0, offset == 0: addr - * - scale == 0, offset != 0: addr ; ptr_to_int ; +offset ; int_to_ptr - * - scale != 0: addr ; ptr_to_int ; idx*scale + ofs ; int_to_ptr - * base_kind == POINTER_RV: + * - scale == 0, offset != 0: addr ; ptr_to_int ; +offset ; + * int_to_ptr + * - scale != 0: addr ; ptr_to_int ; idx*scale + ofs ; + * int_to_ptr base_kind == POINTER_RV: * - scale == 0, offset == 0: no-op * - scale == 0, offset != 0: ptr_to_int ; +offset ; int_to_ptr - * - scale != 0: ptr_to_int ; idx*scale + ofs ; int_to_ptr */ + * - scale != 0: ptr_to_int ; idx*scale + ofs ; + * int_to_ptr */ static void pcg_materialize_lv_to_ptr(Parser* p, const Type* result_ptr_ty) { PcgLvAux* lv = pcg_top_lv_aux(p); int emit = pcg_emit_enabled(p); - PcgLvBaseKind base_kind = lv ? (PcgLvBaseKind)lv->base_kind - : PCG_LV_BASE_LOCAL; + PcgLvBaseKind base_kind = + lv ? (PcgLvBaseKind)lv->base_kind : PCG_LV_BASE_LOCAL; i64 ofs = lv ? lv->offset : 0; u32 scale = lv ? lv->scale : 0u; const Type* idx_ty = c_abi_ptrdiff_type(p->abi, p->pool); @@ -586,14 +590,14 @@ void pcg_store(Parser* p) { zero_ea.offset = 0; zero_ea.scale = 0; /* [base, rv] */ - cfree_cg_push_local(p->cg, tmp); /* [base, rv, tmp] */ - cfree_cg_swap(p->cg); /* [base, tmp, rv] */ + cfree_cg_push_local(p->cg, tmp); /* [base, rv, tmp] */ + cfree_cg_swap(p->cg); /* [base, tmp, rv] */ cfree_cg_store(p->cg, rv_access, zero_ea); /* [base] */ cfree_cg_push_local(p->cg, tmp); - cfree_cg_load(p->cg, rv_access, zero_ea); /* [base, rv] */ - cfree_cg_store(p->cg, access, ea); /* [] */ + cfree_cg_load(p->cg, rv_access, zero_ea); /* [base, rv] */ + cfree_cg_store(p->cg, access, ea); /* [] */ cfree_cg_push_local(p->cg, tmp); - cfree_cg_load(p->cg, rv_access, zero_ea); /* [rv] */ + cfree_cg_load(p->cg, rv_access, zero_ea); /* [rv] */ } } else { /* Indexed lvalue: CG stack on entry is [base, idx, rv]. Stash rv into a @@ -613,14 +617,14 @@ void pcg_store(Parser* p) { zero_ea.offset = 0; zero_ea.scale = 0; /* [base, idx, rv] */ - cfree_cg_push_local(p->cg, tmp); /* [base, idx, rv, tmp] */ - cfree_cg_swap(p->cg); /* [base, idx, tmp, rv] */ + cfree_cg_push_local(p->cg, tmp); /* [base, idx, rv, tmp] */ + cfree_cg_swap(p->cg); /* [base, idx, tmp, rv] */ cfree_cg_store(p->cg, rv_access, zero_ea); /* [base, idx] */ cfree_cg_push_local(p->cg, tmp); - cfree_cg_load(p->cg, rv_access, zero_ea); /* [base, idx, rv] */ - cfree_cg_store(p->cg, access, ea); /* [] */ + cfree_cg_load(p->cg, rv_access, zero_ea); /* [base, idx, rv] */ + cfree_cg_store(p->cg, access, ea); /* [] */ cfree_cg_push_local(p->cg, tmp); - cfree_cg_load(p->cg, rv_access, zero_ea); /* [rv] */ + cfree_cg_load(p->cg, rv_access, zero_ea); /* [rv] */ } } pcg_drop_type(p); @@ -710,13 +714,12 @@ void pcg_lv_subscript(Parser* p, u32 elem_size, const Type* elem_ty) { (p->cg_value_flags[p->cg_type_sp - 2u] & PCG_VALUE_LVALUE) != 0); u8 saved_base_kind = !base_is_lvalue ? PCG_LV_BASE_POINTER_RV - : (base_lv ? base_lv->base_kind - : PCG_LV_BASE_LOCAL); + : (base_lv ? base_lv->base_kind : PCG_LV_BASE_LOCAL); if (base_lv && base_lv->scale != 0) { perr(p, "internal: nested subscript without materialization"); } - pcg_drop_type(p); /* drop index parser slot */ - pcg_retag_top(p, elem_ty); /* retag base parser slot as element */ + pcg_drop_type(p); /* drop index parser slot */ + pcg_retag_top(p, elem_ty); /* retag base parser slot as element */ pcg_set_top_lvalue(p); { PcgLvAux* lv = pcg_top_lv_aux(p); @@ -871,17 +874,18 @@ void pcg_inc_dec(Parser* p, BinOp op, int post) { cfree_cg_load(p->cg, access, ea); /* ..., lv-base[, idx], old */ if (post) { /* Stash old, compute new, store, then re-load old as result. */ - cfree_cg_dup(p->cg); /* ..., lv-base[, idx], old, old */ + cfree_cg_dup(p->cg); /* ..., lv-base[, idx], old, old */ cfree_cg_push_local(p->cg, tmp); cfree_cg_swap(p->cg); - cfree_cg_store(p->cg, r_access, zero_ea); /* ..., lv-base[, idx], old */ + cfree_cg_store(p->cg, r_access, + zero_ea); /* ..., lv-base[, idx], old */ if (ty && ty->kind == TY_PTR) { cfree_cg_push_int(p->cg, step, pcg_tid(p, step_ty)); } else { cfree_cg_push_int(p->cg, 1, pcg_tid(p, step_ty)); } - cfree_cg_int_binop(p->cg, cg_op, 0); /* ..., lv-base[, idx], new */ - cfree_cg_store(p->cg, access, ea); /* [] */ + cfree_cg_int_binop(p->cg, cg_op, 0); /* ..., lv-base[, idx], new */ + cfree_cg_store(p->cg, access, ea); /* [] */ cfree_cg_push_local(p->cg, tmp); cfree_cg_load(p->cg, r_access, zero_ea); /* [old] */ } else { @@ -891,14 +895,15 @@ void pcg_inc_dec(Parser* p, BinOp op, int post) { } else { cfree_cg_push_int(p->cg, 1, pcg_tid(p, step_ty)); } - cfree_cg_int_binop(p->cg, cg_op, 0); /* ..., lv-base[, idx], new */ - cfree_cg_dup(p->cg); /* ..., lv-base[, idx], new, new */ + cfree_cg_int_binop(p->cg, cg_op, 0); /* ..., lv-base[, idx], new */ + cfree_cg_dup(p->cg); /* ..., lv-base[, idx], new, new */ cfree_cg_push_local(p->cg, tmp); cfree_cg_swap(p->cg); - cfree_cg_store(p->cg, r_access, zero_ea); /* ..., lv-base[, idx], new */ - cfree_cg_store(p->cg, access, ea); /* [] */ + cfree_cg_store(p->cg, r_access, + zero_ea); /* ..., lv-base[, idx], new */ + cfree_cg_store(p->cg, access, ea); /* [] */ cfree_cg_push_local(p->cg, tmp); - cfree_cg_load(p->cg, r_access, zero_ea); /* [new] */ + cfree_cg_load(p->cg, r_access, zero_ea); /* [new] */ } (void)step; } @@ -1036,7 +1041,8 @@ void pcg_inline_asm(Parser* p, const char* tmpl, const AsmConstraint* outs, if (nout) { o = arena_zarray(p->pool->arena, CfreeCgAsmOperand, nout); for (u32 i = 0; i < nout; ++i) { - o[i].constraint = cfree_sym_intern(p->c, cfree_slice_cstr(outs[i].str ? outs[i].str : "")); + o[i].constraint = cfree_sym_intern( + p->c, cfree_slice_cstr(outs[i].str ? outs[i].str : "")); o[i].name = outs[i].name; o[i].type = pcg_tid(p, outs[i].type); o[i].dir = CFREE_CG_ASM_OUT; @@ -1045,7 +1051,8 @@ void pcg_inline_asm(Parser* p, const char* tmpl, const AsmConstraint* outs, if (nin) { in = arena_zarray(p->pool->arena, CfreeCgAsmOperand, nin); for (u32 i = 0; i < nin; ++i) { - in[i].constraint = cfree_sym_intern(p->c, cfree_slice_cstr(ins[i].str ? ins[i].str : "")); + in[i].constraint = cfree_sym_intern( + p->c, cfree_slice_cstr(ins[i].str ? ins[i].str : "")); in[i].name = ins[i].name; in[i].type = pcg_tid(p, ins[i].type); in[i].dir = diff --git a/lang/c/parse/cg_public_compat.h b/lang/c/parse/cg_public_compat.h @@ -46,8 +46,8 @@ typedef struct PcgLvAux { u16 bit_width; u32 storage_size; u8 bit_signed; - u8 base_kind; /* PcgLvBaseKind */ - u8 is_subobject; /* lvalue is a member/element of a larger CG object */ + u8 base_kind; /* PcgLvBaseKind */ + u8 is_subobject; /* lvalue is a member/element of a larger CG object */ u8 pad[5]; } PcgLvAux; @@ -307,15 +307,15 @@ void pcg_intrinsic_void(Parser*, IntrinKind); void pcg_inline_asm(Parser*, const char*, const AsmConstraint*, u32, const AsmConstraint*, u32, const Sym*, u32); -#define cg_set_loc(g, loc) \ - do { \ +#define cg_set_loc(g, loc) \ + do { \ if (pcg_emit_enabled(p)) cfree_cg_set_loc((g), (loc)); \ } while (0) #define cg_local(g, fsd) pcg_local(p, (fsd)) #define cg_param(g, pd) pcg_param(p, (pd)) #define cg_func_begin(g, fd) pcg_func_begin(p, (fd)) -#define cg_func_end(g) \ - do { \ +#define cg_func_end(g) \ + do { \ if (pcg_emit_enabled(p)) cfree_cg_func_end((g)); \ } while (0) #define cg_push_int(g, v, ty) pcg_push_int(p, (v), (ty)) @@ -324,20 +324,20 @@ void pcg_inline_asm(Parser*, const char*, const AsmConstraint*, u32, #define cg_push_global(g, sym, ty) pcg_push_global(p, (sym), (ty)) #define cg_load(g) pcg_load(p) #define cg_addr(g) pcg_addr(p) -#define cg_dup(g) \ - do { \ +#define cg_dup(g) \ + do { \ if (pcg_emit_enabled(p)) cfree_cg_dup((g)); \ - pcg_dup_type(p); \ + pcg_dup_type(p); \ } while (0) -#define cg_swap(g) \ - do { \ +#define cg_swap(g) \ + do { \ if (pcg_emit_enabled(p)) cfree_cg_swap((g)); \ - pcg_swap_type(p); \ + pcg_swap_type(p); \ } while (0) -#define cg_drop(g) \ - do { \ +#define cg_drop(g) \ + do { \ if (pcg_emit_enabled(p)) cfree_cg_drop((g)); \ - pcg_drop_type(p); \ + pcg_drop_type(p); \ } while (0) #define cg_store(g) pcg_store(p) #define cg_deref(g, ty) pcg_deref(p, (ty)) @@ -352,16 +352,16 @@ void pcg_inline_asm(Parser*, const char*, const AsmConstraint*, u32, #define cg_call(g, nargs, fn_type) pcg_call(p, (nargs), (fn_type)) #define cg_ret(g, has_value) pcg_ret(p, (has_value)) #define cg_alloca(g) pcg_alloca(p) -#define cg_va_start_(g) \ - do { \ +#define cg_va_start_(g) \ + do { \ if (pcg_emit_enabled(p)) cfree_cg_vararg_start((g)); \ } while (0) -#define cg_va_end_(g) \ - do { \ +#define cg_va_end_(g) \ + do { \ if (pcg_emit_enabled(p)) cfree_cg_vararg_end((g)); \ } while (0) -#define cg_va_copy_(g) \ - do { \ +#define cg_va_copy_(g) \ + do { \ if (pcg_emit_enabled(p)) cfree_cg_vararg_copy((g)); \ } while (0) #define cg_va_arg_(g, ty) pcg_va_arg(p, (ty)) @@ -373,23 +373,23 @@ void pcg_inline_asm(Parser*, const char*, const AsmConstraint*, u32, #define cg_intrinsic_unary_to_int(g, k) pcg_intrinsic_unary_to_int(p, (k)) #define cg_intrinsic_void(g, k) pcg_intrinsic_void(p, (k)) #define cg_label_new(g) cfree_cg_label_new((g)) -#define cg_label_place(g, l) \ - do { \ +#define cg_label_place(g, l) \ + do { \ if (pcg_emit_enabled(p)) cfree_cg_label_place((g), (l)); \ } while (0) -#define cg_jump(g, l) \ - do { \ +#define cg_jump(g, l) \ + do { \ if (pcg_emit_enabled(p)) cfree_cg_jump((g), (l)); \ } while (0) -#define cg_branch_true(g, l) \ - do { \ +#define cg_branch_true(g, l) \ + do { \ if (pcg_emit_enabled(p)) cfree_cg_branch_true((g), (l)); \ - pcg_drop_type(p); \ + pcg_drop_type(p); \ } while (0) -#define cg_branch_false(g, l) \ - do { \ +#define cg_branch_false(g, l) \ + do { \ if (pcg_emit_enabled(p)) cfree_cg_branch_false((g), (l)); \ - pcg_drop_type(p); \ + pcg_drop_type(p); \ } while (0) #define cg_inline_asm(g, tmpl, outs, nout, ins, nin, clob, nclob) \ pcg_inline_asm(p, (tmpl), (outs), (nout), (ins), (nin), (clob), (nclob)) diff --git a/lang/c/parse/parse.c b/lang/c/parse/parse.c @@ -155,7 +155,7 @@ static Tok fuse_string_lits(Parser* p, Tok a, Tok b) { } buf[k++] = '"'; out = a; - out.spelling = cfree_sym_intern(p->pool->c, (CfreeSlice){ .s = buf, .len = k }); + out.spelling = cfree_sym_intern(p->pool->c, (CfreeSlice){.s = buf, .len = k}); out.flags = (u16)((a.flags & ~STR_ENC_MASK) | fused_enc); out.lit = LIT_NONE; h->free(h, buf, 0); @@ -487,9 +487,8 @@ static void reset_vla_pending(Parser* p) { p->vla_pending_count_len = 0; } -static VLABound* add_vla_bound(Parser* p, VLABound* head, - const Type* array_ty, FrameSlot byte_slot, - FrameSlot count_slot) { +static VLABound* add_vla_bound(Parser* p, VLABound* head, const Type* array_ty, + FrameSlot byte_slot, FrameSlot count_slot) { VLABound* b = arena_znew(p->pool->arena, VLABound); b->array_ty = array_ty; b->byte_slot = byte_slot; @@ -519,9 +518,8 @@ static int build_vla_size(Parser* p, const Type* ty, u32* count_idx, FrameSlot elem_slot = FRAME_SLOT_NONE; u32 elem_static_size = 0; - int elem_dynamic = - build_vla_size(p, ty->arr.elem, count_idx, bounds, &elem_slot, - &elem_static_size, loc); + int elem_dynamic = build_vla_size(p, ty->arr.elem, count_idx, bounds, + &elem_slot, &elem_static_size, loc); if (count_dynamic || elem_dynamic) { FrameSlot byte_slot = make_vla_size_slot(p); @@ -682,7 +680,7 @@ Sym mint_static_local_sym(Parser* p, Sym orig) { } while (dn && wlen < sizeof buf - 1) buf[wlen++] = digits[--dn]; } - return cfree_sym_intern(p->pool->c, (CfreeSlice){ .s = buf, .len = wlen }); + return cfree_sym_intern(p->pool->c, (CfreeSlice){.s = buf, .len = wlen}); } /* ============================================================ @@ -699,8 +697,8 @@ static void parse_init_declarator(Parser* p, const DeclSpecs* specs) { SrcLoc loc; Sym name; const Type* var_ty = parse_declarator(p, specs->type, &name, &loc); - if ((specs->flags & DF_THREAD) && - specs->storage != DS_STATIC && specs->storage != DS_EXTERN) { + if ((specs->flags & DF_THREAD) && specs->storage != DS_STATIC && + specs->storage != DS_EXTERN) { perr(p, "block-scope _Thread_local requires static or extern"); } validate_decl_type_constraints(p, specs, var_ty, @@ -736,8 +734,9 @@ static void parse_init_declarator(Parser* p, const DeclSpecs* specs) { Sym alias_target; if ((specs->storage == DS_AUTO && specs->storage_explicit) || specs->storage == DS_REGISTER || specs->storage == DS_STATIC) { - perr(p, "invalid storage-class specifier for block-scope function " - "declaration"); + perr(p, + "invalid storage-class specifier for block-scope function " + "declaration"); } if (is_punct(&p->cur, '=')) { perr(p, "function declarator cannot have initializer"); @@ -803,7 +802,8 @@ static void parse_init_declarator(Parser* p, const DeclSpecs* specs) { const Type* composite = NULL; CSemCheck chk = c_sem_check_redeclaration(p->pool, prior->type, var_ty, &composite); - if (!chk.ok) perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message))); + if (!chk.ok) + perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message))); if (cur && cur->kind != SEK_GLOBAL) { perr(p, "redefinition of identifier"); } @@ -906,7 +906,8 @@ static void parse_init_declarator(Parser* p, const DeclSpecs* specs) { const Type* rhs = cg_top_type(p->cg); CSemCheck chk = c_sem_check_assignment(p->pool, var_ty, rhs, C_SEM_ASSIGN_INIT); - if (!chk.ok) perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message))); + if (!chk.ok) + perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message))); } coerce_top_to_lvalue(p); cg_store(p->cg); @@ -1001,8 +1002,7 @@ void parse_param_list(Parser* p, ParamInfo** infos_out, u16* nparams_out, infos[n].vla_bounds = NULL; infos[n].vla_bound_len = p->param_vla_bound_len; if (p->param_vla_bound_len) { - ParamVLABoundExpr* bounds = arena_array(p->pool->arena, - ParamVLABoundExpr, + ParamVLABoundExpr* bounds = arena_array(p->pool->arena, ParamVLABoundExpr, p->param_vla_bound_len); memcpy(bounds, p->param_vla_bounds, sizeof(ParamVLABoundExpr) * p->param_vla_bound_len); @@ -1031,7 +1031,8 @@ static SymEntry* declare_function(Parser* p, Sym fname, const Type* fn_ty, const Type* composite = NULL; CSemCheck chk = c_sem_check_redeclaration(p->pool, existing->type, fn_ty, &composite); - if (!chk.ok) perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message))); + if (!chk.ok) + perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message))); if (specs->storage == DS_STATIC && existing->linkage == DL_EXTERNAL) { perr(p, "static declaration follows non-static declaration"); } @@ -1057,7 +1058,8 @@ static SymEntry* declare_function(Parser* p, Sym fname, const Type* fn_ty, const Type* composite = NULL; CSemCheck chk = c_sem_check_redeclaration(p->pool, existing->type, fn_ty, &composite); - if (!chk.ok) perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message))); + if (!chk.ok) + perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message))); if (specs->storage == DS_STATIC && existing->linkage == DL_EXTERNAL) { perr(p, "static declaration follows non-static declaration"); } @@ -1278,9 +1280,8 @@ static void parse_external_decl(Parser* p) { attr_list_append(&fent->attrs, dattrs); if (is_punct(&p->cur, '{')) { - int suppress_body_codegen = - specs.storage == DS_EXTERN && - ((specs.flags | fn_decl_flags) & DF_INLINE); + int suppress_body_codegen = specs.storage == DS_EXTERN && + ((specs.flags | fn_decl_flags) & DF_INLINE); if (fent->defined) perr(p, "redefinition of function"); fent->defined = 1; fent->decl_state = DSTATE_FUNC_DEFINED; @@ -1348,7 +1349,8 @@ static void parse_external_decl(Parser* p) { const Type* composite = NULL; CSemCheck chk = c_sem_check_redeclaration(p->pool, existing->type, base_ty, &composite); - if (!chk.ok) perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message))); + if (!chk.ok) + perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message))); if (specs.storage == DS_STATIC && existing->linkage == DL_EXTERNAL) { perr(p, "static declaration follows non-static declaration"); } @@ -1513,65 +1515,105 @@ void parse_c(Compiler* c, Pool* pool, Pp* pp, DeclTable* decls, CG* cg, p.kw_sym[i] = cfree_sym_intern(p.pool->c, cfree_slice_cstr(kw_names[i])); } - p.sym_b_alloca = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_alloca")); + p.sym_b_alloca = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_alloca")); p.sym_b_ctz = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_ctz")); p.sym_b_ctzl = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_ctzl")); - p.sym_b_ctzll = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_ctzll")); + p.sym_b_ctzll = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_ctzll")); p.sym_b_clz = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_clz")); p.sym_b_clzl = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_clzl")); - p.sym_b_clzll = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_clzll")); + p.sym_b_clzll = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_clzll")); p.sym_b_trap = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_trap")); - p.sym_b_unreachable = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_unreachable")); - p.sym_b_memcpy = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_memcpy")); - p.sym_b_memmove = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_memmove")); - p.sym_b_memcmp = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_memcmp")); - p.sym_b_memset = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_memset")); - p.sym_b_clear_cache = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin___clear_cache")); - p.sym_b_isnan = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_isnan")); + p.sym_b_unreachable = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_unreachable")); + p.sym_b_memcpy = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_memcpy")); + p.sym_b_memmove = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_memmove")); + p.sym_b_memcmp = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_memcmp")); + p.sym_b_memset = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_memset")); + p.sym_b_clear_cache = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin___clear_cache")); + p.sym_b_isnan = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_isnan")); p.sym_b_fabs = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_fabs")); - p.sym_b_fabsf = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_fabsf")); - p.sym_b_fabsl = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_fabsl")); + p.sym_b_fabsf = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_fabsf")); + p.sym_b_fabsl = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_fabsl")); p.sym_b_inf = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_inf")); p.sym_b_inff = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_inff")); p.sym_b_infl = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_infl")); - p.sym_b_huge_val = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_huge_val")); - p.sym_b_huge_valf = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_huge_valf")); - p.sym_b_huge_vall = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_huge_vall")); + p.sym_b_huge_val = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_huge_val")); + p.sym_b_huge_valf = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_huge_valf")); + p.sym_b_huge_vall = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_huge_vall")); p.sym_func = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__func__")); p.sym_func_gcc = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__FUNCTION__")); - p.sym_pretty_func_gcc = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__PRETTY_FUNCTION__")); - p.sym_b_expect = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_expect")); - p.sym_b_offsetof = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_offsetof")); - p.sym_b_va_list = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_va_list")); - p.sym_b_va_start = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_va_start")); - p.sym_b_va_arg = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_va_arg")); - p.sym_b_va_end = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_va_end")); - p.sym_b_va_copy = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_va_copy")); - p.sym_attribute = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__attribute__")); - p.sym_volatile_alias = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__volatile__")); - p.sym_alignof_alias = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__alignof__")); + p.sym_pretty_func_gcc = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__PRETTY_FUNCTION__")); + p.sym_b_expect = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_expect")); + p.sym_b_offsetof = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_offsetof")); + p.sym_b_va_list = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_va_list")); + p.sym_b_va_start = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_va_start")); + p.sym_b_va_arg = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_va_arg")); + p.sym_b_va_end = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_va_end")); + p.sym_b_va_copy = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__builtin_va_copy")); + p.sym_attribute = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__attribute__")); + p.sym_volatile_alias = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__volatile__")); + p.sym_alignof_alias = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__alignof__")); p.sym_asm_alias = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__asm")); p.sym_inline_alias = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__inline")); - p.sym_inline_alias2 = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__inline__")); + p.sym_inline_alias2 = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__inline__")); p.sym_thread_alias = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__thread")); p.sym_int128 = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__int128")); p.sym_int128_t = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__int128_t")); p.sym_uint128_t = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__uint128_t")); - p.sym_a_load_n = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_load_n")); - p.sym_a_store_n = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_store_n")); - p.sym_a_exchange_n = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_exchange_n")); - p.sym_a_fetch_add = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_fetch_add")); - p.sym_a_fetch_sub = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_fetch_sub")); - p.sym_a_fetch_and = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_fetch_and")); - p.sym_a_fetch_or = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_fetch_or")); - p.sym_a_fetch_xor = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_fetch_xor")); - p.sym_a_fetch_nand = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_fetch_nand")); - p.sym_a_cas_n = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_compare_exchange_n")); + p.sym_a_load_n = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_load_n")); + p.sym_a_store_n = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_store_n")); + p.sym_a_exchange_n = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_exchange_n")); + p.sym_a_fetch_add = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_fetch_add")); + p.sym_a_fetch_sub = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_fetch_sub")); + p.sym_a_fetch_and = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_fetch_and")); + p.sym_a_fetch_or = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_fetch_or")); + p.sym_a_fetch_xor = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_fetch_xor")); + p.sym_a_fetch_nand = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_fetch_nand")); + p.sym_a_cas_n = cfree_sym_intern( + p.pool->c, CFREE_SLICE_LIT("__atomic_compare_exchange_n")); p.sym_a_always_lock_free = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_always_lock_free")); - p.sym_a_is_lock_free = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_is_lock_free")); - p.sym_a_thread_fence = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_thread_fence")); - p.sym_a_signal_fence = cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_signal_fence")); + p.sym_a_is_lock_free = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_is_lock_free")); + p.sym_a_thread_fence = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_thread_fence")); + p.sym_a_signal_fence = + cfree_sym_intern(p.pool->c, CFREE_SLICE_LIT("__atomic_signal_fence")); p.scope = scope_new(&p, NULL); diff --git a/lang/c/parse/parse_expr.c b/lang/c/parse/parse_expr.c @@ -389,12 +389,14 @@ i64 decode_char_literal(Parser* p, const Tok* t) { i++; if (i >= len || s[i] == '\'') perr(p, "empty character literal"); if (!c_lit_decode_unit(s, len, &i, &unit, &err)) { - compiler_panic(p->c, t->loc, "%.*s", - CFREE_SLICE_ARG(cfree_slice_cstr(err ? err : "bad character literal"))); + compiler_panic( + p->c, t->loc, "%.*s", + CFREE_SLICE_ARG(cfree_slice_cstr(err ? err : "bad character literal"))); } if (!c_lit_encode_char_unit(enc, bits, unit, &v, &err)) { - compiler_panic(p->c, t->loc, "%.*s", - CFREE_SLICE_ARG(cfree_slice_cstr(err ? err : "bad character literal"))); + compiler_panic( + p->c, t->loc, "%.*s", + CFREE_SLICE_ARG(cfree_slice_cstr(err ? err : "bad character literal"))); } if (i >= len || s[i] != '\'') { perr(p, "multi-character constants are not supported"); @@ -428,12 +430,14 @@ u8* decode_string_literal(Parser* p, const Tok* t, size_t* nlen_out) { while (i < len && s[i] != '"') { CLitUnit unit; if (!c_lit_decode_unit(s, len, &i, &unit, &err)) { - compiler_panic(p->c, t->loc, "%.*s", - CFREE_SLICE_ARG(cfree_slice_cstr(err ? err : "bad string literal"))); + compiler_panic( + p->c, t->loc, "%.*s", + CFREE_SLICE_ARG(cfree_slice_cstr(err ? err : "bad string literal"))); } if (!c_lit_append_string_unit(buf, &k, enc, elem_size, unit, &err)) { - compiler_panic(p->c, t->loc, "%.*s", - CFREE_SLICE_ARG(cfree_slice_cstr(err ? err : "bad string literal"))); + compiler_panic( + p->c, t->loc, "%.*s", + CFREE_SLICE_ARG(cfree_slice_cstr(err ? err : "bad string literal"))); } } c_lit_encode_uint_le(buf + k, elem_size, 0); @@ -1521,9 +1525,9 @@ static const Type* builtin_math_fp_type(Parser* p, Sym name) { static int parse_builtin_inf_call(Parser* p, Sym name, SrcLoc loc) { const Type* ty; - if (name != p->sym_b_inf && name != p->sym_b_inff && - name != p->sym_b_infl && name != p->sym_b_huge_val && - name != p->sym_b_huge_valf && name != p->sym_b_huge_vall) { + if (name != p->sym_b_inf && name != p->sym_b_inff && name != p->sym_b_infl && + name != p->sym_b_huge_val && name != p->sym_b_huge_valf && + name != p->sym_b_huge_vall) { return 0; } @@ -2003,11 +2007,12 @@ static void parse_primary(Parser* p) { if (t.v.ident == p->sym_func || t.v.ident == p->sym_func_gcc || t.v.ident == p->sym_pretty_func_gcc) { if (p->cur_func_name == 0) { - compiler_panic(p->c, t.loc, "'%.*s' used outside a function", - CFREE_SLICE_ARG(cfree_slice_cstr( - t.v.ident == p->sym_func ? "__func__" - : t.v.ident == p->sym_func_gcc ? "__FUNCTION__" - : "__PRETTY_FUNCTION__"))); + compiler_panic( + p->c, t.loc, "'%.*s' used outside a function", + CFREE_SLICE_ARG(cfree_slice_cstr( + t.v.ident == p->sym_func ? "__func__" + : t.v.ident == p->sym_func_gcc ? "__FUNCTION__" + : "__PRETTY_FUNCTION__"))); } CfreeSlice fn_name_sl = cfree_sym_str(p->pool->c, p->cur_func_name); size_t nlen = fn_name_sl.len; @@ -2209,7 +2214,8 @@ static void parse_postfix(Parser* p) { if (param_ty) { CSemCheck chk = c_sem_check_assignment( p->pool, param_ty, cg_top_type(p->cg), C_SEM_ASSIGN_EXPR); - if (!chk.ok) perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message))); + if (!chk.ok) + perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message))); coerce_top_to_type(p, param_ty); } ++nargs; @@ -3226,8 +3232,8 @@ static void parse_ternary(Parser* p) { result_ty = type_promoted(p->pool, result_ty); if (cg_top_type(p->cg) != result_ty) cg_convert(p->cg, result_ty); } - then_store_ty = then_null ? type_ptr(p->pool, type_prim(p->pool, TY_VOID)) - : result_ty; + then_store_ty = + then_null ? type_ptr(p->pool, type_prim(p->pool, TY_VOID)) : result_ty; memset(&fsd, 0, sizeof fsd); fsd.type = then_store_ty; fsd.size = c_abi_sizeof(p->abi, then_store_ty); @@ -3350,7 +3356,8 @@ void parse_assign_expr(Parser* p) { * to_rvalue) so the aggregate copy lands at the right address. */ if (lhs && (lhs->kind == TY_STRUCT || lhs->kind == TY_UNION)) { PcgLvAux* dlv = pcg_top_lv_aux(p); - if (pcg_top_is_lvalue(p) && dlv && (dlv->offset != 0 || dlv->scale != 0)) { + if (pcg_top_is_lvalue(p) && dlv && + (dlv->offset != 0 || dlv->scale != 0)) { const Type* uty = type_unqual(p->pool, lhs); pcg_addr(p); pcg_deref(p, uty); @@ -3362,7 +3369,8 @@ void parse_assign_expr(Parser* p) { const Type* rhs = cg_top_type(p->cg); CSemCheck chk = c_sem_check_assignment(p->pool, lhs, rhs, C_SEM_ASSIGN_EXPR); - if (!chk.ok) perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message))); + if (!chk.ok) + perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message))); } coerce_top_to_lvalue(p); cg_store(p->cg); @@ -3423,7 +3431,8 @@ void parse_assign_expr(Parser* p) { break; } CSemCheck chk = c_sem_check_compound_assignment(p->pool, lhs, rhs, op); - if (!chk.ok) perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message))); + if (!chk.ok) + perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message))); } if (compound == BO_IADD || compound == BO_ISUB) { emit_add_or_sub(p, compound); diff --git a/lang/c/parse/parse_init.c b/lang/c/parse/parse_init.c @@ -343,7 +343,8 @@ static void init_field_at(Parser* p, FrameSlot slot, const Type* arr_ty, const Type* rhs = cg_top_type(p->cg); CSemCheck chk = c_sem_check_assignment(p->pool, f->type, rhs, C_SEM_ASSIGN_INIT); - if (!chk.ok) perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message))); + if (!chk.ok) + perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message))); } coerce_top_to_lvalue(p); cg_store(p->cg); @@ -766,7 +767,8 @@ void init_at(Parser* p, FrameSlot slot, const Type* arr_ty, u32 offset, { const Type* rhs = cg_top_type(p->cg); CSemCheck chk = c_sem_check_assignment(p->pool, ty, rhs, C_SEM_ASSIGN_INIT); - if (!chk.ok) perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message))); + if (!chk.ok) + perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message))); } coerce_top_to_lvalue(p); cg_store(p->cg); @@ -963,8 +965,7 @@ static void parse_static_string_at(Parser* p, u8* buf, u32 buflen, u32 offset, void srl_push(Parser* p, u32 offset, u32 size, ObjSymId target, i64 addend) { if (p->static_relocs_len == p->static_relocs_cap) { u32 nc = p->static_relocs_cap ? p->static_relocs_cap * 2u : 4u; - void* nb = - arena_array(p->pool->arena, StaticReloc, nc); + void* nb = arena_array(p->pool->arena, StaticReloc, nc); if (!nb) perr(p, "out of memory recording static relocs"); if (p->static_relocs && p->static_relocs_len) { memcpy(nb, p->static_relocs, @@ -1017,7 +1018,7 @@ static Sym mint_compound_literal_sym(Parser* p) { } while (dn) buf[wlen++] = digits[--dn]; } - return cfree_sym_intern(p->pool->c, (CfreeSlice){ .s = buf, .len = wlen }); + return cfree_sym_intern(p->pool->c, (CfreeSlice){.s = buf, .len = wlen}); } static void static_relocs_swap_empty(Parser* p, StaticRelocSave* save) { diff --git a/lang/c/parse/parse_priv.h b/lang/c/parse/parse_priv.h @@ -37,7 +37,7 @@ typedef enum CKw { KW_ENUM, KW_EXTERN, KW_FLOAT, - KW_FLOAT16, /* _Float16 */ + KW_FLOAT16, /* _Float16 */ KW_FOR, KW_GOTO, KW_IF, @@ -519,15 +519,13 @@ double parse_float_literal(Parser* p, const Tok* t); i64 decode_char_literal(Parser* p, const Tok* t); const Type* char_literal_type(Parser* p, const Tok* t); const Type* string_literal_elem_type(Parser* p, const Tok* t); -int string_literal_initializes_array(Parser* p, const Type* elem, - const Tok* t); +int string_literal_initializes_array(Parser* p, const Type* elem, const Tok* t); u8* decode_string_literal(Parser* p, const Tok* t, size_t* nlen_out); void to_rvalue(Parser* p); void coerce_top_to_lvalue(Parser* p); CfreeCgSym emit_string_to_rodata(Parser* p, const u8* bytes, size_t n); CfreeCgSym emit_string_literal_to_rodata(Parser* p, const u8* bytes, - size_t nbytes, - const Type* elem_ty); + size_t nbytes, const Type* elem_ty); /* parse_init.c */ void init_at(Parser* p, FrameSlot slot, const Type* arr_ty, u32 offset, diff --git a/lang/c/parse/parse_stmt.c b/lang/c/parse/parse_stmt.c @@ -177,7 +177,8 @@ static void parse_return_stmt(Parser* p) { const Type* rhs = cg_top_type(p->cg); CSemCheck chk = c_sem_check_assignment(p->pool, p->cur_func_ret, rhs, C_SEM_ASSIGN_RETURN); - if (!chk.ok) perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message))); + if (!chk.ok) + perr(p, "%.*s", CFREE_SLICE_ARG(cfree_slice_cstr(chk.message))); } expect_punct(p, ';', "';' after return value"); cg_ret(p->cg, 1); @@ -346,8 +347,10 @@ static void parse_switch_stmt(Parser* p) { * sign bit and miscomparing against negative case constants. */ { const Type* prom = type_unqual(p->pool, vty); - if (prom && prom->kind == TY_ENUM) prom = type_prim(p->pool, TY_INT); - else prom = type_promoted(p->pool, prom); + if (prom && prom->kind == TY_ENUM) + prom = type_prim(p->pool, TY_INT); + else + prom = type_promoted(p->pool, prom); if (prom && prom != vty) { cg_convert(p->cg, prom); vty = prom; @@ -417,9 +420,8 @@ static void parse_switch_stmt(Parser* p) { CfreeCgSwitch sw; memset(&sw, 0, sizeof sw); sw.selector_type = pcg_tid(p, vty); - sw.default_label = - ctx.default_label ? (CfreeCgLabel)ctx.default_label - : (CfreeCgLabel)L_end; + sw.default_label = ctx.default_label ? (CfreeCgLabel)ctx.default_label + : (CfreeCgLabel)L_end; sw.cases = cases; sw.ncases = ncases; sw.hint = CFREE_CG_SWITCH_TARGET_DEFAULT; @@ -491,8 +493,10 @@ static const char* parse_asm_str(Parser* p, const char* what) { advance(p); bytes = decode_string_literal(p, &t, &nlen); if (nlen > 0) nlen -= 1; - s = cfree_sym_intern(p->pool->c, (CfreeSlice){ .s = (const char*)bytes, .len = nlen }); - cfree_compiler_context(p->c)->heap->free(cfree_compiler_context(p->c)->heap, bytes, 0); + s = cfree_sym_intern(p->pool->c, + (CfreeSlice){.s = (const char*)bytes, .len = nlen}); + cfree_compiler_context(p->c)->heap->free(cfree_compiler_context(p->c)->heap, + bytes, 0); return cfree_sym_str(p->pool->c, s).s; } diff --git a/lang/c/parse/parse_type.c b/lang/c/parse/parse_type.c @@ -80,7 +80,7 @@ static int attr_sym_canon_eq(Parser* p, Sym sym, const char* want) { size_t clen; if (!s) return 0; attr_canon_range(s, len, &cs, &clen); - return cfree_slice_eq_cstr((CfreeSlice){ .s = cs, .len = clen }, want); + return cfree_slice_eq_cstr((CfreeSlice){.s = cs, .len = clen}, want); } static const Type* attrs_apply_type_mode(Parser* p, const Type* base, @@ -89,7 +89,8 @@ static const Type* attrs_apply_type_mode(Parser* p, const Type* base, if (a->kind != ATTR_MODE || a->nargs == 0) continue; if (attr_sym_canon_eq(p, a->v.sym, "TI")) { const Type* u = type_unqual(p->pool, base); - int is_unsigned = u && type_is_int(u) && c_abi_type_info(p->abi, u).signed_ == 0; + int is_unsigned = + u && type_is_int(u) && c_abi_type_info(p->abi, u).signed_ == 0; return type_prim(p->pool, is_unsigned ? TY_UINT128 : TY_INT128); } } @@ -178,7 +179,7 @@ static AttrKind classify_attr(Parser* p, Sym name, AttrArgShape* shape_out) { attr_canon_range(s, len, &cs, &clen); for (i = 0; i < sizeof(kAttrTable) / sizeof(kAttrTable[0]); ++i) { const char* tn = kAttrTable[i].name; - if (cfree_slice_eq_cstr((CfreeSlice){ .s = cs, .len = clen }, tn)) { + if (cfree_slice_eq_cstr((CfreeSlice){.s = cs, .len = clen}, tn)) { *shape_out = kAttrTable[i].shape; return kAttrTable[i].kind; } @@ -265,8 +266,10 @@ static void parse_attr_args(Parser* p, Attr* a, AttrArgShape shape, size_t nlen = 0; u8* bytes = decode_string_literal(p, &t, &nlen); u32 ilen = (nlen > 0) ? (u32)(nlen - 1) : 0; - a->v.sym = cfree_sym_intern(p->pool->c, (CfreeSlice){ .s = (const char*)bytes, .len = ilen }); - cfree_compiler_context(p->c)->heap->free(cfree_compiler_context(p->c)->heap, bytes, 0); + a->v.sym = cfree_sym_intern( + p->pool->c, (CfreeSlice){.s = (const char*)bytes, .len = ilen}); + cfree_compiler_context(p->c)->heap->free( + cfree_compiler_context(p->c)->heap, bytes, 0); } a->nargs = 1; advance(p); @@ -425,9 +428,7 @@ u32 attrs_pick_aligned(const Attr* a) { return best; } -static int is_power_of_two_u32(u32 v) { - return v != 0 && (v & (v - 1u)) == 0; -} +static int is_power_of_two_u32(u32 v) { return v != 0 && (v & (v - 1u)) == 0; } static void validate_atomic_operand(Parser* p, const Type* ty) { if (!ty) perr(p, "_Atomic requires an object type"); @@ -452,7 +453,8 @@ void validate_decl_type_constraints(Parser* p, const DeclSpecs* specs, if (specs->storage != DS_AUTO || specs->storage_explicit) { perr(p, "storage-class specifier is invalid for struct member"); } - if (specs->flags & DF_INLINE) perr(p, "inline is invalid for struct member"); + if (specs->flags & DF_INLINE) + perr(p, "inline is invalid for struct member"); if (specs->flags & DF_NORETURN) perr(p, "_Noreturn is invalid for struct member"); if (specs->flags & DF_THREAD) @@ -467,7 +469,8 @@ void validate_decl_type_constraints(Parser* p, const DeclSpecs* specs, if ((specs->flags & DF_NORETURN) && !is_function) { perr(p, "_Noreturn may only appear on a function declaration"); } - if ((specs->flags & DF_THREAD) && (is_function || specs->storage == DS_TYPEDEF)) { + if ((specs->flags & DF_THREAD) && + (is_function || specs->storage == DS_TYPEDEF)) { perr(p, "_Thread_local may only appear on object declarations"); } if (specs->align) { @@ -886,7 +889,8 @@ static void validate_and_add_field(Parser* p, TypeRecordBuilder* b, const DeclSpecs* specs, Field* f, MemberNameSeen** names, u32* field_count, int* saw_flexible) { - int is_flexible = f->type && f->type->kind == TY_ARRAY && f->type->arr.incomplete; + int is_flexible = + f->type && f->type->kind == TY_ARRAY && f->type->arr.incomplete; validate_decl_type_constraints(p, specs, f->type, /*is_function=*/0, /*is_member=*/1); if ((f->flags & FIELD_BITFIELD) && specs->align) { @@ -897,7 +901,8 @@ static void validate_and_add_field(Parser* p, TypeRecordBuilder* b, } if (*saw_flexible) perr(p, "flexible array member must be last"); if (is_flexible) { - if (*field_count == 0) perr(p, "flexible array member cannot be only member"); + if (*field_count == 0) + perr(p, "flexible array member cannot be only member"); f->flags |= FIELD_FLEXIBLE_ARRAY; *saw_flexible = 1; } @@ -1060,9 +1065,8 @@ const Type* parse_struct_or_union(Parser* p, TypeKind kind, begin_opts.max_align = (u16)pack_align; } attrs_to_record_opts(rec_attrs, &begin_opts); - TypeRecordBuilder* b = - type_record_begin_ex(p->pool, kind, target->rec.tag_id, tag_name, - begin_opts); + TypeRecordBuilder* b = type_record_begin_ex(p->pool, kind, target->rec.tag_id, + tag_name, begin_opts); parse_member_decls(p, b); expect_punct(p, '}', "'}' after aggregate body"); TypeRecordOpts trailing_opts; @@ -1556,7 +1560,8 @@ const Type* parse_declarator_full_info(Parser* p, const Type* base, } nested_quals[nptrs_nested++] = q; } - if (p->cur.kind == TOK_IDENT && ident_kw(p, p->cur.v.ident) == KW_NONE) { + if (p->cur.kind == TOK_IDENT && + ident_kw(p, p->cur.v.ident) == KW_NONE) { name = p->cur.v.ident; nloc = tok_loc(&p->cur); advance(p); @@ -1568,7 +1573,7 @@ const Type* parse_declarator_full_info(Parser* p, const Type* base, } else if (!allow_abstract) { perr(p, "expected declarator name"); } -after_inner_name: + after_inner_name: parse_and_discard_attrs_or_asm(p); while (n_inner_suffs < 8) { if (!parse_decl_suffix(p, &inner_suffs[n_inner_suffs])) break; @@ -1662,7 +1667,8 @@ const Type* complete_incomplete_array(Parser* p, const Type* ty) { size_t n = 0; u8* bytes = decode_string_literal(p, &t, &n); u32 elem_size = c_abi_sizeof(p->abi, elem); - cfree_compiler_context(p->c)->heap->free(cfree_compiler_context(p->c)->heap, bytes, 0); + cfree_compiler_context(p->c)->heap->free(cfree_compiler_context(p->c)->heap, + bytes, 0); return type_array(p->pool, elem, elem_size ? (u32)(n / elem_size) : 0, /*incomplete=*/0); } @@ -1676,7 +1682,8 @@ const Type* complete_incomplete_array(Parser* p, const Type* ty) { size_t n = 0; u8* bytes = decode_string_literal(p, &t, &n); u32 elem_size = c_abi_sizeof(p->abi, elem); - cfree_compiler_context(p->c)->heap->free(cfree_compiler_context(p->c)->heap, bytes, 0); + cfree_compiler_context(p->c)->heap->free( + cfree_compiler_context(p->c)->heap, bytes, 0); cnt = elem_size ? (u32)(n / elem_size) : 0; } replay_rewind(p); diff --git a/lang/cpp/lex/lex.c b/lang/cpp/lex/lex.c @@ -177,7 +177,7 @@ static Sym intern_spliced(Lexer* l, size_t start, size_t end) { } if (!has_splice) return cfree_sym_intern( - l->pool->c, (CfreeSlice){ .s = l->src + start, .len = end - start }); + l->pool->c, (CfreeSlice){.s = l->src + start, .len = end - start}); buf = (char*)l->heap->alloc(l->heap, end - start, 1); k = 0; @@ -188,7 +188,7 @@ static Sym intern_spliced(Lexer* l, size_t start, size_t end) { } buf[k++] = l->src[i++]; } - sym = cfree_sym_intern(l->pool->c, (CfreeSlice){ .s = buf, .len = k }); + sym = cfree_sym_intern(l->pool->c, (CfreeSlice){.s = buf, .len = k}); l->heap->free(l->heap, buf, end - start); return sym; } @@ -526,7 +526,8 @@ Tok lex_next(Lexer* l) { break; } } - t.spelling = cfree_sym_intern(l->pool->c, (CfreeSlice){ .s = pbuf, .len = k }); + t.spelling = + cfree_sym_intern(l->pool->c, (CfreeSlice){.s = pbuf, .len = k}); l->heap->free(l->heap, pbuf, plen ? plen : 1); l->dstate = 0; return t; diff --git a/lang/cpp/pp/pp.c b/lang/cpp/pp/pp.c @@ -12,10 +12,10 @@ * Residual module: source stack, pp_next / pp_next_raw (public streaming), * pp_new/free, predefined macros, lifecycle, keyword interning. */ -#include "pp/pp_priv.h" - #include <cfree/compile.h> +#include "pp/pp_priv.h" + /* ============================================================ * Source stack * ============================================================ */ @@ -216,8 +216,10 @@ static void pp_intern_keywords(Pp* pp) { pp->sym_date__ = cfree_sym_intern(p->c, CFREE_SLICE_LIT("__DATE__")); pp->sym_time__ = cfree_sym_intern(p->c, CFREE_SLICE_LIT("__TIME__")); pp->sym_stdc__ = cfree_sym_intern(p->c, CFREE_SLICE_LIT("__STDC__")); - pp->sym_stdc_hosted__ = cfree_sym_intern(p->c, CFREE_SLICE_LIT("__STDC_HOSTED__")); - pp->sym_stdc_version__ = cfree_sym_intern(p->c, CFREE_SLICE_LIT("__STDC_VERSION__")); + pp->sym_stdc_hosted__ = + cfree_sym_intern(p->c, CFREE_SLICE_LIT("__STDC_HOSTED__")); + pp->sym_stdc_version__ = + cfree_sym_intern(p->c, CFREE_SLICE_LIT("__STDC_VERSION__")); pp->sym__pragma = cfree_sym_intern(p->c, CFREE_SLICE_LIT("_Pragma")); } @@ -296,8 +298,8 @@ static void compute_date_time(Pp* pp) { date[p++] = (char)('0' + (yyyy / 10) % 10); date[p++] = (char)('0' + (yyyy) % 10); date[p++] = '"'; - pp->val_date_str = - cfree_sym_intern(pp->pool->c, (CfreeSlice){ .s = date, .len = (size_t)p }); + pp->val_date_str = cfree_sym_intern( + pp->pool->c, (CfreeSlice){.s = date, .len = (size_t)p}); } { int hh = ymd.h, mm = ymd.m, ss = ymd.s; @@ -313,7 +315,7 @@ static void compute_date_time(Pp* pp) { tm[p++] = (char)('0' + ss % 10); tm[p++] = '"'; pp->val_time_str = - cfree_sym_intern(pp->pool->c, (CfreeSlice){ .s = tm, .len = (size_t)p }); + cfree_sym_intern(pp->pool->c, (CfreeSlice){.s = tm, .len = (size_t)p}); } } @@ -487,8 +489,8 @@ static void pp_register_target_predefined(Pp* pp) { pp_define(pp, "_stdcall", ""); pp_define(pp, "_fastcall", ""); /* __forceinline / __inline / __w64: mingw's _mingw.h redefines - * them itself when __GNUC__ is set, so we leave them alone here - * to avoid a redefinition-with-different-replacement error. */ + * them itself when __GNUC__ is set, so we leave them alone here + * to avoid a redefinition-with-different-replacement error. */ } /* stddef.h base aliases */ @@ -679,8 +681,7 @@ static void pp_register_target_predefined(Pp* pp) { pp_define(pp, "__LDBL_MIN_10_EXP__", "(-4931)"); pp_define(pp, "__LDBL_MAX_EXP__", "16384"); pp_define(pp, "__LDBL_MAX_10_EXP__", "4932"); - pp_define(pp, "__LDBL_MAX__", - "0x1.ffffffffffffffffffffffffffffp+16383L"); + pp_define(pp, "__LDBL_MAX__", "0x1.ffffffffffffffffffffffffffffp+16383L"); pp_define(pp, "__LDBL_EPSILON__", "0x1p-112L"); pp_define(pp, "__LDBL_MIN__", "0x1p-16382L"); pp_define(pp, "__LDBL_DENORM_MIN__", "0x1p-16494L"); @@ -817,9 +818,7 @@ void pp_undef(Pp* pp, const char* name) { mt_del(pp, s); } -uint32_t pp_pack_alignment(const Pp* pp) { - return pp ? pp->pack_align : 0; -} +uint32_t pp_pack_alignment(const Pp* pp) { return pp ? pp->pack_align : 0; } void pp_add_include_edge(Pp* pp, u32 includer, u32 included, SrcLoc include_loc, int system) { diff --git a/lang/cpp/pp/pp_directive.c b/lang/cpp/pp/pp_directive.c @@ -120,9 +120,9 @@ static void prepass_defined(Pp* pp, const Tok* in, u32 nin, TokVec* out) { t.kind = TOK_NUM; t.flags = in[i].flags & (TF_AT_BOL | TF_HAS_SPACE); t.loc = in[i].loc; - t.spelling = cfree_sym_intern( - pp->pool->c, mt_get(pp, ident) ? CFREE_SLICE_LIT("1") - : CFREE_SLICE_LIT("0")); + t.spelling = cfree_sym_intern(pp->pool->c, mt_get(pp, ident) + ? CFREE_SLICE_LIT("1") + : CFREE_SLICE_LIT("0")); tv_push(pp, out, t); } i = j - 1; @@ -879,7 +879,7 @@ static void do_line(Pp* pp, const Tok* line, u32 n, SrcLoc loc) { CfreeSlice s = cfree_sym_str(pp->pool->c, exp.data[1].spelling); if (s.len >= 2 && s.s[0] == '"' && s.s[s.len - 1] == '"') { target_file = cfree_sym_intern( - pp->pool->c, (CfreeSlice){ .s = s.s + 1, .len = s.len - 2 }); + pp->pool->c, (CfreeSlice){.s = s.s + 1, .len = s.len - 2}); } } } @@ -1287,7 +1287,7 @@ static void do_embed(Pp* pp, const Tok* line, u32 n, SrcLoc loc) { t.kind = TOK_NUM; t.loc = loc; t.spelling = cfree_sym_intern( - pp->pool->c, (CfreeSlice){ .s = numbuf, .len = (size_t)nl }); + pp->pool->c, (CfreeSlice){.s = numbuf, .len = (size_t)nl}); if (i == 0) t.flags = TF_AT_BOL; /* Bytes after a comma get a leading space to match * clang's `, ` separator format. */ diff --git a/lang/cpp/pp/pp_expand.c b/lang/cpp/pp/pp_expand.c @@ -639,8 +639,8 @@ static void preexpand_args(Pp* pp, ArgList* a) { * own it without aliasing. */ Tok* slice = arena_array(pp->arena, Tok, hi - lo); memcpy(slice, &a->raw[lo], sizeof(Tok) * (hi - lo)); - expand_arg_to_eof(pp, slice, a->raw_hs ? &a->raw_hs[lo] : NULL, - hi - lo, &exp); + expand_arg_to_eof(pp, slice, a->raw_hs ? &a->raw_hs[lo] : NULL, hi - lo, + &exp); } exp_start[i + 1] = exp.n; } @@ -662,8 +662,8 @@ static Tok make_stringize(Pp* pp, const Tok* arg, u32 lo, u32 hi, SrcLoc loc) { cb_putc(pp, &b, '"'); for (i = lo; i < hi; ++i) { const Tok* at = &arg[i]; - CfreeSlice sl = - at->spelling ? cfree_sym_str(pp->pool->c, at->spelling) : CFREE_SLICE_NULL; + CfreeSlice sl = at->spelling ? cfree_sym_str(pp->pool->c, at->spelling) + : CFREE_SLICE_NULL; const char* s = sl.s; size_t slen = sl.len; if (i > lo && (at->flags & TF_HAS_SPACE)) cb_putc(pp, &b, ' '); @@ -679,7 +679,7 @@ static Tok make_stringize(Pp* pp, const Tok* arg, u32 lo, u32 hi, SrcLoc loc) { } cb_putc(pp, &b, '"'); - sp = cfree_sym_intern(pp->pool->c, (CfreeSlice){ .s = b.data, .len = b.len }); + sp = cfree_sym_intern(pp->pool->c, (CfreeSlice){.s = b.data, .len = b.len}); memset(&t, 0, sizeof(t)); t.kind = TOK_STR; t.loc = loc; @@ -1000,8 +1000,8 @@ Tok pp_next_raw(Pp* pp) { while (j > 0) buf[k++] = tmp[--j]; } t.kind = TOK_NUM; - t.spelling = - cfree_sym_intern(pp->pool->c, (CfreeSlice){ .s = buf, .len = (size_t)k }); + t.spelling = cfree_sym_intern(pp->pool->c, + (CfreeSlice){.s = buf, .len = (size_t)k}); return t; } if (id == pp->sym_file__) { @@ -1029,8 +1029,8 @@ Tok pp_next_raw(Pp* pp) { if (nlen) memcpy(buf + 1, nstr, nlen); buf[nlen + 1] = '"'; t.kind = TOK_STR; - t.spelling = - cfree_sym_intern(pp->pool->c, (CfreeSlice){ .s = buf, .len = nlen + 2 }); + t.spelling = cfree_sym_intern(pp->pool->c, + (CfreeSlice){.s = buf, .len = nlen + 2}); t.v.str = t.spelling; return t; } diff --git a/lang/cpp/pp/pp_priv.h b/lang/cpp/pp/pp_priv.h @@ -191,7 +191,9 @@ struct Pp { * Allocation helpers (defined in pp.c, used everywhere) * ============================================================ */ -static inline Heap* pp_heap(Pp* pp) { return cfree_compiler_context(pp->c)->heap; } +static inline Heap* pp_heap(Pp* pp) { + return cfree_compiler_context(pp->c)->heap; +} static inline void* pp_xrealloc(Pp* pp, void* p, size_t old_n, size_t new_n, size_t align) { diff --git a/lang/toy/asm.c b/lang/toy/asm.c @@ -1,7 +1,7 @@ -#include "internal.h" - #include <string.h> +#include "internal.h" + typedef struct ToyAsmOperandList { CfreeCgAsmOperand* items; uint32_t count; @@ -80,8 +80,7 @@ static int toy_validate_asm_output_constraint(ToyParser* p, static int toy_validate_asm_input_constraint(ToyParser* p, const CfreeCgAsmOperand* op) { const char* s = cfree_sym_str(p->c, op->constraint).s; - if ((s && s[0] && !s[1] && - (s[0] == 'r' || s[0] == 'i' || s[0] == 'm')) || + if ((s && s[0] && !s[1] && (s[0] == 'r' || s[0] == 'i' || s[0] == 'm')) || toy_asm_is_decimal_constraint(s)) { return 1; } @@ -314,8 +313,7 @@ static int toy_parse_asm_flags(ToyParser* p, uint32_t* flags) { return 1; } -static int toy_parse_asm_clobber_abi(ToyParser* p, - uint32_t* clobber_abi_sets) { +static int toy_parse_asm_clobber_abi(ToyParser* p, uint32_t* clobber_abi_sets) { if (!toy_expect_ident(p, "clobber_abi") || !toy_parser_expect(p, TOK_LPAREN)) { toy_error(p, p->cur.loc, "expected clobber_abi(...)"); @@ -440,8 +438,8 @@ int toy_parse_typed_asm_tail(ToyParser* p, CfreeCgTypeId result_ty, toy_error(p, p->cur.loc, "asm record result output mismatch"); goto done; } - } else if (cfree_cg_type_record_field(p->c, result_ty, i, &field, - NULL) != 0) { + } else if (cfree_cg_type_record_field(p->c, result_ty, i, &field, NULL) != + 0) { toy_parser_free_mem(p, seen, nfields * sizeof *seen); goto done; } @@ -493,7 +491,6 @@ done: record_field_count * sizeof *record_field_indexes); toy_parser_free_mem(p, outputs.items, outputs.cap * sizeof *outputs.items); toy_parser_free_mem(p, inputs.items, inputs.cap * sizeof *inputs.items); - toy_parser_free_mem(p, clobbers.items, - clobbers.cap * sizeof *clobbers.items); + toy_parser_free_mem(p, clobbers.items, clobbers.cap * sizeof *clobbers.items); return ok; } diff --git a/lang/toy/attrs.c b/lang/toy/attrs.c @@ -1,7 +1,7 @@ -#include "internal.h" - #include <string.h> +#include "internal.h" + static void toy_attr_set_init(ToyAttrSet* attrs, CfreeSymBind default_bind) { memset(attrs, 0, sizeof *attrs); attrs->sym.bind = default_bind; @@ -23,8 +23,7 @@ int toy_parse_attr_dot_name(ToyParser* p, CfreeSym* out) { } static int toy_parse_attr_dot_arg(ToyParser* p, CfreeSym* out) { - if (!toy_parser_expect(p, TOK_LPAREN) || - !toy_parse_attr_dot_name(p, out) || + if (!toy_parser_expect(p, TOK_LPAREN) || !toy_parse_attr_dot_name(p, out) || !toy_parser_expect(p, TOK_RPAREN)) { toy_error(p, p->cur.loc, "expected dot attribute argument"); return 0; @@ -59,12 +58,18 @@ int toy_parse_callconv_const(ToyParser* p, CfreeCgCallConv* out) { } name = toy_tok_sym(p, p->cur); toy_parser_advance(p); - if (toy_sym_is(p, name, "target_c")) *out = CFREE_CG_CC_TARGET_C; - else if (toy_sym_is(p, name, "sysv")) *out = CFREE_CG_CC_SYSV; - else if (toy_sym_is(p, name, "win64")) *out = CFREE_CG_CC_WIN64; - else if (toy_sym_is(p, name, "aapcs")) *out = CFREE_CG_CC_AAPCS; - else if (toy_sym_is(p, name, "wasm")) *out = CFREE_CG_CC_WASM; - else if (toy_sym_is(p, name, "interrupt")) *out = CFREE_CG_CC_INTERRUPT; + if (toy_sym_is(p, name, "target_c")) + *out = CFREE_CG_CC_TARGET_C; + else if (toy_sym_is(p, name, "sysv")) + *out = CFREE_CG_CC_SYSV; + else if (toy_sym_is(p, name, "win64")) + *out = CFREE_CG_CC_WIN64; + else if (toy_sym_is(p, name, "aapcs")) + *out = CFREE_CG_CC_AAPCS; + else if (toy_sym_is(p, name, "wasm")) + *out = CFREE_CG_CC_WASM; + else if (toy_sym_is(p, name, "interrupt")) + *out = CFREE_CG_CC_INTERRUPT; else { toy_error(p, p->cur.loc, "unknown call convention"); return 0; @@ -81,9 +86,12 @@ static int toy_parse_attr_one(ToyParser* p, ToyAttrSet* attrs) { if (toy_sym_is(p, name, "bind")) { attrs->attr_kinds |= TOY_ATTR_SYMBOL; if (!toy_parse_attr_dot_arg(p, &arg)) return 0; - if (toy_sym_is(p, arg, "local")) attrs->sym.bind = CFREE_SB_LOCAL; - else if (toy_sym_is(p, arg, "global")) attrs->sym.bind = CFREE_SB_GLOBAL; - else if (toy_sym_is(p, arg, "weak")) attrs->sym.bind = CFREE_SB_WEAK; + if (toy_sym_is(p, arg, "local")) + attrs->sym.bind = CFREE_SB_LOCAL; + else if (toy_sym_is(p, arg, "global")) + attrs->sym.bind = CFREE_SB_GLOBAL; + else if (toy_sym_is(p, arg, "weak")) + attrs->sym.bind = CFREE_SB_WEAK; else { toy_error(p, p->cur.loc, "unknown bind attribute"); return 0; @@ -222,7 +230,8 @@ static int toy_parse_attr_one(ToyParser* p, ToyAttrSet* attrs) { if (toy_sym_is(p, name, "tls_model")) { attrs->attr_kinds |= TOY_ATTR_OBJECT; if (!toy_parse_attr_dot_arg(p, &arg)) return 0; - if (toy_sym_is(p, arg, "auto")) attrs->object.tls_model = CFREE_CG_TLS_AUTO; + if (toy_sym_is(p, arg, "auto")) + attrs->object.tls_model = CFREE_CG_TLS_AUTO; else if (toy_sym_is(p, arg, "local_exec")) attrs->object.tls_model = CFREE_CG_TLS_LOCAL_EXEC; else if (toy_sym_is(p, arg, "initial_exec")) @@ -305,13 +314,18 @@ static int toy_parse_abi_attr_one(ToyParser* p, CfreeCgAbiAttrs* attrs) { CfreeSym name; int64_t int_arg; if (!toy_parse_attr_dot_name(p, &name)) return 0; - if (toy_sym_is(p, name, "signext")) attrs->flags |= CFREE_CG_ABI_SIGNEXT; + if (toy_sym_is(p, name, "signext")) + attrs->flags |= CFREE_CG_ABI_SIGNEXT; else if (toy_sym_is(p, name, "zeroext")) attrs->flags |= CFREE_CG_ABI_ZEROEXT; - else if (toy_sym_is(p, name, "sret")) attrs->flags |= CFREE_CG_ABI_SRET; - else if (toy_sym_is(p, name, "byval")) attrs->flags |= CFREE_CG_ABI_BYVAL; - else if (toy_sym_is(p, name, "byref")) attrs->flags |= CFREE_CG_ABI_BYREF; - else if (toy_sym_is(p, name, "inreg")) attrs->flags |= CFREE_CG_ABI_INREG; + else if (toy_sym_is(p, name, "sret")) + attrs->flags |= CFREE_CG_ABI_SRET; + else if (toy_sym_is(p, name, "byval")) + attrs->flags |= CFREE_CG_ABI_BYVAL; + else if (toy_sym_is(p, name, "byref")) + attrs->flags |= CFREE_CG_ABI_BYREF; + else if (toy_sym_is(p, name, "inreg")) + attrs->flags |= CFREE_CG_ABI_INREG; else if (toy_sym_is(p, name, "noalias")) attrs->flags |= CFREE_CG_ABI_NOALIAS; else if (toy_sym_is(p, name, "readonly")) @@ -320,7 +334,8 @@ static int toy_parse_abi_attr_one(ToyParser* p, CfreeCgAbiAttrs* attrs) { attrs->flags |= CFREE_CG_ABI_WRITEONLY; else if (toy_sym_is(p, name, "nonnull")) attrs->flags |= CFREE_CG_ABI_NONNULL; - else if (toy_sym_is(p, name, "nest")) attrs->flags |= CFREE_CG_ABI_NEST; + else if (toy_sym_is(p, name, "nest")) + attrs->flags |= CFREE_CG_ABI_NEST; else if (toy_sym_is(p, name, "align")) { if (!toy_parse_attr_int_arg(p, &int_arg) || int_arg < 0) return 0; attrs->align = (uint32_t)int_arg; diff --git a/lang/toy/builtins.c b/lang/toy/builtins.c @@ -1,7 +1,7 @@ -#include "internal.h" - #include <string.h> +#include "internal.h" + static CfreeCgMemAccess toy_mem_access_align(ToyParser* p, CfreeCgTypeId type, uint32_t align) { CfreeCgMemAccess access = toy_mem_access(p, type); @@ -49,8 +49,8 @@ static void toy_push_loaded_local(ToyParser* p, CfreeCgLocal local, static void toy_emit_dynamic_memory_loop(ToyParser* p, CfreeCgLocal dst_local, CfreeCgLocal src_local, - CfreeCgLocal size_local, - int is_memset, uint8_t set_value) { + CfreeCgLocal size_local, int is_memset, + uint8_t set_value) { CfreeCgTypeId u8_ty = toy_builtin_type(p, CFREE_CG_BUILTIN_I8); CfreeCgTypeId u8_ptr_ty = cfree_cg_type_ptr(p->c, u8_ty, 0); CfreeCgLocal index_local = @@ -75,11 +75,9 @@ static void toy_emit_dynamic_memory_loop(ToyParser* p, CfreeCgLocal dst_local, } else { toy_push_loaded_local(p, src_local, u8_ptr_ty); toy_push_loaded_local(p, index_local, p->int_type); - cfree_cg_load(p->cg, toy_mem_access(p, u8_ty), - (CfreeCgEffAddr){0, 1}); + cfree_cg_load(p->cg, toy_mem_access(p, u8_ty), (CfreeCgEffAddr){0, 1}); } - cfree_cg_store(p->cg, toy_mem_access(p, u8_ty), - (CfreeCgEffAddr){0, 1}); + cfree_cg_store(p->cg, toy_mem_access(p, u8_ty), (CfreeCgEffAddr){0, 1}); cfree_cg_push_local(p->cg, index_local); toy_push_loaded_local(p, index_local, p->int_type); @@ -173,12 +171,18 @@ static int toy_parse_mem_order(ToyParser* p, CfreeCgMemOrder* out) { } name = toy_tok_sym(p, p->cur); toy_parser_advance(p); - if (toy_sym_is(p, name, "relaxed")) *out = CFREE_CG_MO_RELAXED; - else if (toy_sym_is(p, name, "consume")) *out = CFREE_CG_MO_CONSUME; - else if (toy_sym_is(p, name, "acquire")) *out = CFREE_CG_MO_ACQUIRE; - else if (toy_sym_is(p, name, "release")) *out = CFREE_CG_MO_RELEASE; - else if (toy_sym_is(p, name, "acq_rel")) *out = CFREE_CG_MO_ACQ_REL; - else if (toy_sym_is(p, name, "seq_cst")) *out = CFREE_CG_MO_SEQ_CST; + if (toy_sym_is(p, name, "relaxed")) + *out = CFREE_CG_MO_RELAXED; + else if (toy_sym_is(p, name, "consume")) + *out = CFREE_CG_MO_CONSUME; + else if (toy_sym_is(p, name, "acquire")) + *out = CFREE_CG_MO_ACQUIRE; + else if (toy_sym_is(p, name, "release")) + *out = CFREE_CG_MO_RELEASE; + else if (toy_sym_is(p, name, "acq_rel")) + *out = CFREE_CG_MO_ACQ_REL; + else if (toy_sym_is(p, name, "seq_cst")) + *out = CFREE_CG_MO_SEQ_CST; else { toy_error(p, p->cur.loc, "unknown memory order"); return 0; @@ -189,13 +193,20 @@ static int toy_parse_mem_order(ToyParser* p, CfreeCgMemOrder* out) { static int toy_parse_atomic_op(ToyParser* p, CfreeCgAtomicOp* out) { CfreeSym name; if (!toy_parse_attr_dot_name(p, &name)) return 0; - if (toy_sym_is(p, name, "xchg")) *out = CFREE_CG_ATOMIC_XCHG; - else if (toy_sym_is(p, name, "add")) *out = CFREE_CG_ATOMIC_ADD; - else if (toy_sym_is(p, name, "sub")) *out = CFREE_CG_ATOMIC_SUB; - else if (toy_sym_is(p, name, "and")) *out = CFREE_CG_ATOMIC_AND; - else if (toy_sym_is(p, name, "or")) *out = CFREE_CG_ATOMIC_OR; - else if (toy_sym_is(p, name, "xor")) *out = CFREE_CG_ATOMIC_XOR; - else if (toy_sym_is(p, name, "nand")) *out = CFREE_CG_ATOMIC_NAND; + if (toy_sym_is(p, name, "xchg")) + *out = CFREE_CG_ATOMIC_XCHG; + else if (toy_sym_is(p, name, "add")) + *out = CFREE_CG_ATOMIC_ADD; + else if (toy_sym_is(p, name, "sub")) + *out = CFREE_CG_ATOMIC_SUB; + else if (toy_sym_is(p, name, "and")) + *out = CFREE_CG_ATOMIC_AND; + else if (toy_sym_is(p, name, "or")) + *out = CFREE_CG_ATOMIC_OR; + else if (toy_sym_is(p, name, "xor")) + *out = CFREE_CG_ATOMIC_XOR; + else if (toy_sym_is(p, name, "nand")) + *out = CFREE_CG_ATOMIC_NAND; else { toy_error(p, p->cur.loc, "unknown atomic op"); return 0; @@ -211,8 +222,10 @@ static int toy_parse_cmpxchg_strength(ToyParser* p, int* weak_out) { } name = toy_tok_sym(p, p->cur); toy_parser_advance(p); - if (toy_sym_is(p, name, "strong")) *weak_out = 0; - else if (toy_sym_is(p, name, "weak")) *weak_out = 1; + if (toy_sym_is(p, name, "strong")) + *weak_out = 0; + else if (toy_sym_is(p, name, "weak")) + *weak_out = 1; else { toy_error(p, p->cur.loc, "unknown compare-exchange strength"); return 0; @@ -266,8 +279,7 @@ static int toy_reject_tail_call_operand(ToyParser* p) { static int toy_parse_call_braced_args(ToyParser* p, ToyToken call_tok, CfreeCgTypeId fn_ty, const ToyTypeId* toy_params, - size_t toy_nparams, - size_t* out_nargs) { + size_t toy_nparams, size_t* out_nargs) { uint32_t nparams = cfree_cg_type_func_nparams(p->c, fn_ty); int variadic = cfree_cg_type_func_is_variadic(p->c, fn_ty); size_t nargs = 0; @@ -283,9 +295,9 @@ static int toy_parse_call_braced_args(ToyParser* p, ToyToken call_tok, if (nargs < nparams) { CfreeCgFuncParam param = cfree_cg_type_func_param(p->c, fn_ty, (uint32_t)nargs); - ToyTypeId expected = - (toy_params && nargs < toy_nparams) ? toy_params[nargs] - : TOY_TYPE_NONE; + ToyTypeId expected = (toy_params && nargs < toy_nparams) + ? toy_params[nargs] + : TOY_TYPE_NONE; ToyTypeId actual = p->last_type; if (expected != TOY_TYPE_NONE && !toy_type_accepts_type(p, expected, actual)) { @@ -361,8 +373,7 @@ static CfreeCgTypeId toy_parse_call_builtin(ToyParser* p) { p, call_tok, fn_ty, direct ? fn->toy_params : (source_fn_type ? source_fn_type->params : NULL), - direct ? fn->nparams - : (source_fn_type ? source_fn_type->nparams : 0), + direct ? fn->nparams : (source_fn_type ? source_fn_type->nparams : 0), &nargs)) { return CFREE_CG_TYPE_NONE; } @@ -370,8 +381,8 @@ static CfreeCgTypeId toy_parse_call_builtin(ToyParser* p) { if (!toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; ret_ty = cfree_cg_type_func_ret(p->c, fn_ty); - tail = attrs.tail == CFREE_CG_TAIL_ALLOWED || - attrs.tail == CFREE_CG_TAIL_MUST; + tail = + attrs.tail == CFREE_CG_TAIL_ALLOWED || attrs.tail == CFREE_CG_TAIL_MUST; if (tail && !p->allow_tail_call_expr) { toy_error(p, call_tok.loc, "tail @call requires return"); return CFREE_CG_TYPE_NONE; @@ -381,8 +392,7 @@ static CfreeCgTypeId toy_parse_call_builtin(ToyParser* p) { if (tail) { p->tail_call_expr = 1; p->tail_call_ret_toy = ret_toy_type; - if (p->cur_fn_ret_toy != TOY_TYPE_NONE && - ret_toy_type != TOY_TYPE_NONE && + if (p->cur_fn_ret_toy != TOY_TYPE_NONE && ret_toy_type != TOY_TYPE_NONE && !toy_type_accepts_type(p, p->cur_fn_ret_toy, ret_toy_type)) { p->last_type = ret_toy_type; return ret_ty; @@ -400,11 +410,14 @@ static CfreeCgTypeId toy_parse_call_builtin(ToyParser* p) { static int toy_parse_barrier_scope(ToyParser* p, CfreeCgBarrierScope* out) { CfreeSym name; if (!toy_parse_attr_dot_name(p, &name)) return 0; - if (toy_sym_is(p, name, "full")) *out = CFREE_CG_BARRIER_FULL; - else if (toy_sym_is(p, name, "inner")) *out = CFREE_CG_BARRIER_INNER; + if (toy_sym_is(p, name, "full")) + *out = CFREE_CG_BARRIER_FULL; + else if (toy_sym_is(p, name, "inner")) + *out = CFREE_CG_BARRIER_INNER; else if (toy_sym_is(p, name, "inner_store")) *out = CFREE_CG_BARRIER_INNER_STORE; - else if (toy_sym_is(p, name, "outer")) *out = CFREE_CG_BARRIER_OUTER; + else if (toy_sym_is(p, name, "outer")) + *out = CFREE_CG_BARRIER_OUTER; else if (toy_sym_is(p, name, "outer_store")) *out = CFREE_CG_BARRIER_OUTER_STORE; else if (toy_sym_is(p, name, "non_share")) @@ -431,9 +444,12 @@ CfreeCgTypeId toy_parse_builtin_call(ToyParser* p, CfreeSym name, toy_sym_is(p, name, "clz") || toy_sym_is(p, name, "bswap")) { CfreeCgIntrinsic intrin = CFREE_CG_INTRIN_POPCOUNT; CfreeCgTypeId ty; - if (toy_sym_is(p, name, "ctz")) intrin = CFREE_CG_INTRIN_CTZ; - else if (toy_sym_is(p, name, "clz")) intrin = CFREE_CG_INTRIN_CLZ; - else if (toy_sym_is(p, name, "bswap")) intrin = CFREE_CG_INTRIN_BSWAP; + if (toy_sym_is(p, name, "ctz")) + intrin = CFREE_CG_INTRIN_CTZ; + else if (toy_sym_is(p, name, "clz")) + intrin = CFREE_CG_INTRIN_CLZ; + else if (toy_sym_is(p, name, "bswap")) + intrin = CFREE_CG_INTRIN_BSWAP; toy_parser_advance(p); /* ( */ ty = toy_parse_expr(p); if (ty == CFREE_CG_TYPE_NONE) return CFREE_CG_TYPE_NONE; @@ -467,8 +483,8 @@ CfreeCgTypeId toy_parse_builtin_call(ToyParser* p, CfreeSym name, } if (toy_sym_is(p, name, "trap")) { - if (!toy_parser_expect(p, TOK_LPAREN) || - !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; + if (!toy_parser_expect(p, TOK_LPAREN) || !toy_parser_expect(p, TOK_RPAREN)) + return CFREE_CG_TYPE_NONE; cfree_cg_intrinsic(p->cg, CFREE_CG_INTRIN_TRAP, 0, toy_builtin_type(p, CFREE_CG_BUILTIN_VOID)); return toy_builtin_type(p, CFREE_CG_BUILTIN_VOID); @@ -478,15 +494,16 @@ CfreeCgTypeId toy_parse_builtin_call(ToyParser* p, CfreeSym name, toy_sym_is(p, name, "irq_disable") || toy_sym_is(p, name, "irq_enable") || toy_sym_is(p, name, "isb")) { CfreeCgIntrinsic intrin = CFREE_CG_INTRIN_CPU_NOP; - if (toy_sym_is(p, name, "cpu_yield")) intrin = CFREE_CG_INTRIN_CPU_YIELD; + if (toy_sym_is(p, name, "cpu_yield")) + intrin = CFREE_CG_INTRIN_CPU_YIELD; else if (toy_sym_is(p, name, "irq_disable")) intrin = CFREE_CG_INTRIN_IRQ_DISABLE; else if (toy_sym_is(p, name, "irq_enable")) intrin = CFREE_CG_INTRIN_IRQ_ENABLE; else if (toy_sym_is(p, name, "isb")) intrin = CFREE_CG_INTRIN_ISB; - if (!toy_parser_expect(p, TOK_LPAREN) || - !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; + if (!toy_parser_expect(p, TOK_LPAREN) || !toy_parser_expect(p, TOK_RPAREN)) + return CFREE_CG_TYPE_NONE; cfree_cg_intrinsic(p->cg, intrin, 0, toy_builtin_type(p, CFREE_CG_BUILTIN_VOID)); return toy_builtin_type(p, CFREE_CG_BUILTIN_VOID); @@ -505,17 +522,17 @@ CfreeCgTypeId toy_parse_builtin_call(ToyParser* p, CfreeSym name, CfreeSlice text; if (!toy_parser_expect(p, TOK_LPAREN) || !toy_parse_string_sym(p, &msg, &msg_len) || - !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_RPAREN)) + return CFREE_CG_TYPE_NONE; text = cfree_sym_str(p->c, msg); - toy_error(p, p->cur.loc, "compile_error: %.*s", - CFREE_SLICE_ARG(text)); + toy_error(p, p->cur.loc, "compile_error: %.*s", CFREE_SLICE_ARG(text)); cfree_cg_push_int(p->cg, 0, p->int_type); return p->int_type; } if (toy_sym_is(p, name, "unreachable")) { - if (!toy_parser_expect(p, TOK_LPAREN) || - !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; + if (!toy_parser_expect(p, TOK_LPAREN) || !toy_parser_expect(p, TOK_RPAREN)) + return CFREE_CG_TYPE_NONE; cfree_cg_unreachable(p->cg); return toy_builtin_type(p, CFREE_CG_BUILTIN_VOID); } @@ -527,8 +544,8 @@ CfreeCgTypeId toy_parse_builtin_call(ToyParser* p, CfreeSym name, ty = toy_parse_expr(p); if (ty == CFREE_CG_TYPE_NONE || !toy_expect_comma(p) || !toy_parse_number_arg(p, &lo) || !toy_expect_comma(p) || - !toy_parse_number_arg(p, &width) || - !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parse_number_arg(p, &width) || !toy_parser_expect(p, TOK_RPAREN)) + return CFREE_CG_TYPE_NONE; if (!toy_validate_bit_range(p, ty, lo, width, 1)) { toy_error(p, p->cur.loc, "invalid bitget arguments"); return CFREE_CG_TYPE_NONE; @@ -549,8 +566,8 @@ CfreeCgTypeId toy_parse_builtin_call(ToyParser* p, CfreeSym name, src_ty = toy_parse_expr(p); if (src_ty == CFREE_CG_TYPE_NONE || !toy_expect_comma(p) || !toy_parse_number_arg(p, &lo) || !toy_expect_comma(p) || - !toy_parse_number_arg(p, &width) || - !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parse_number_arg(p, &width) || !toy_parser_expect(p, TOK_RPAREN)) + return CFREE_CG_TYPE_NONE; if (dst_ty != src_ty || !toy_validate_bit_range(p, dst_ty, lo, width, 0)) { toy_error(p, p->cur.loc, "invalid bitset arguments"); return CFREE_CG_TYPE_NONE; @@ -651,8 +668,8 @@ CfreeCgTypeId toy_parse_builtin_call(ToyParser* p, CfreeSym name, } if (toy_sym_is(p, name, "target_arch")) { - if (!toy_parser_expect(p, TOK_LPAREN) || - !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; + if (!toy_parser_expect(p, TOK_LPAREN) || !toy_parser_expect(p, TOK_RPAREN)) + return CFREE_CG_TYPE_NONE; cfree_cg_push_int(p->cg, (uint64_t)toy_target_code(p), p->int_type); return p->int_type; } @@ -660,8 +677,8 @@ CfreeCgTypeId toy_parse_builtin_call(ToyParser* p, CfreeSym name, if (toy_sym_is(p, name, "supports_callconv")) { CfreeCgCallConv cc; if (!toy_parser_expect(p, TOK_LPAREN) || - !toy_parse_callconv_const(p, &cc) || - !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parse_callconv_const(p, &cc) || !toy_parser_expect(p, TOK_RPAREN)) + return CFREE_CG_TYPE_NONE; cfree_cg_push_int(p->cg, cfree_cg_target_supports_call_conv(p->c, cc) ? 1u : 0u, toy_builtin_type(p, CFREE_CG_BUILTIN_BOOL)); @@ -672,10 +689,10 @@ CfreeCgTypeId toy_parse_builtin_call(ToyParser* p, CfreeSym name, CfreeCgSymbolFeature feature; if (!toy_parser_expect(p, TOK_LPAREN) || !toy_parse_symbol_feature_const(p, &feature) || - !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_RPAREN)) + return CFREE_CG_TYPE_NONE; cfree_cg_push_int( - p->cg, - cfree_cg_target_supports_symbol_feature(p->c, feature) ? 1u : 0u, + p->cg, cfree_cg_target_supports_symbol_feature(p->c, feature) ? 1u : 0u, toy_builtin_type(p, CFREE_CG_BUILTIN_BOOL)); return toy_builtin_type(p, CFREE_CG_BUILTIN_BOOL); } @@ -684,17 +701,18 @@ CfreeCgTypeId toy_parse_builtin_call(ToyParser* p, CfreeSym name, uint64_t feature; if (!toy_parser_expect(p, TOK_LPAREN) || !toy_parse_backend_feature_const(p, &feature) || - !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_RPAREN)) + return CFREE_CG_TYPE_NONE; cfree_cg_push_int( - p->cg, - (cfree_cg_target_backend_features(p->c) & feature) ? 1u : 0u, + p->cg, (cfree_cg_target_backend_features(p->c) & feature) ? 1u : 0u, toy_builtin_type(p, CFREE_CG_BUILTIN_BOOL)); return toy_builtin_type(p, CFREE_CG_BUILTIN_BOOL); } if (toy_sym_is(p, name, "va_start")) { if (!toy_parser_expect(p, TOK_LPAREN) || !toy_parse_va_list_addr_arg(p) || - !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_RPAREN)) + return CFREE_CG_TYPE_NONE; cfree_cg_vararg_start(p->cg); cfree_cg_push_int(p->cg, 0, p->int_type); return p->int_type; @@ -702,7 +720,8 @@ CfreeCgTypeId toy_parse_builtin_call(ToyParser* p, CfreeSym name, if (toy_sym_is(p, name, "va_end")) { if (!toy_parser_expect(p, TOK_LPAREN) || !toy_parse_va_list_addr_arg(p) || - !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_RPAREN)) + return CFREE_CG_TYPE_NONE; cfree_cg_vararg_end(p->cg); cfree_cg_push_int(p->cg, 0, p->int_type); return p->int_type; @@ -711,7 +730,8 @@ CfreeCgTypeId toy_parse_builtin_call(ToyParser* p, CfreeSym name, if (toy_sym_is(p, name, "va_copy")) { if (!toy_parser_expect(p, TOK_LPAREN) || !toy_parse_va_list_addr_arg(p) || !toy_expect_comma(p) || !toy_parse_va_list_addr_arg(p) || - !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_RPAREN)) + return CFREE_CG_TYPE_NONE; cfree_cg_vararg_copy(p->cg); cfree_cg_push_int(p->cg, 0, p->int_type); return p->int_type; @@ -735,7 +755,8 @@ CfreeCgTypeId toy_parse_generic_builtin(ToyParser* p, CfreeSym name, ty = toy_parse_type(p); elem_toy_type = p->last_type; if (ty == CFREE_CG_TYPE_NONE || !toy_parser_expect(p, TOK_GT) || - !toy_parser_expect(p, TOK_LPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_LPAREN)) + return CFREE_CG_TYPE_NONE; count_ty = toy_parse_expr(p); if (count_ty == CFREE_CG_TYPE_NONE || !toy_expect_comma(p) || !toy_parse_number_arg(p, &align) || !toy_parser_expect(p, TOK_RPAREN)) @@ -787,19 +808,28 @@ CfreeCgTypeId toy_parse_generic_builtin(ToyParser* p, CfreeSym name, ty = toy_parse_type(p); result_toy_type = p->last_type; if (ty == CFREE_CG_TYPE_NONE || !toy_parser_expect(p, TOK_GT) || - !toy_parser_expect(p, TOK_LPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_LPAREN)) + return CFREE_CG_TYPE_NONE; src_ty = toy_parse_expr(p); if (src_ty == CFREE_CG_TYPE_NONE || !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; (void)src_ty; - if (toy_sym_is(p, name, "sext")) cfree_cg_sext(p->cg, ty); - else if (toy_sym_is(p, name, "zext")) cfree_cg_zext(p->cg, ty); - else if (toy_sym_is(p, name, "trunc")) cfree_cg_trunc(p->cg, ty); - else if (toy_sym_is(p, name, "ptr_to_int")) cfree_cg_ptr_to_int(p->cg, ty); - else if (toy_sym_is(p, name, "int_to_ptr")) cfree_cg_int_to_ptr(p->cg, ty); - else if (toy_sym_is(p, name, "bitcast")) cfree_cg_bitcast(p->cg, ty); - else if (toy_sym_is(p, name, "fpext")) cfree_cg_fpext(p->cg, ty); - else if (toy_sym_is(p, name, "fptrunc")) cfree_cg_fptrunc(p->cg, ty); + if (toy_sym_is(p, name, "sext")) + cfree_cg_sext(p->cg, ty); + else if (toy_sym_is(p, name, "zext")) + cfree_cg_zext(p->cg, ty); + else if (toy_sym_is(p, name, "trunc")) + cfree_cg_trunc(p->cg, ty); + else if (toy_sym_is(p, name, "ptr_to_int")) + cfree_cg_ptr_to_int(p->cg, ty); + else if (toy_sym_is(p, name, "int_to_ptr")) + cfree_cg_int_to_ptr(p->cg, ty); + else if (toy_sym_is(p, name, "bitcast")) + cfree_cg_bitcast(p->cg, ty); + else if (toy_sym_is(p, name, "fpext")) + cfree_cg_fpext(p->cg, ty); + else if (toy_sym_is(p, name, "fptrunc")) + cfree_cg_fptrunc(p->cg, ty); p->last_type = result_toy_type; return ty; } @@ -813,7 +843,8 @@ CfreeCgTypeId toy_parse_generic_builtin(ToyParser* p, CfreeSym name, if (!toy_parser_expect(p, TOK_LT)) return CFREE_CG_TYPE_NONE; ty = toy_parse_type(p); if (ty == CFREE_CG_TYPE_NONE || !toy_parser_expect(p, TOK_GT) || - !toy_parser_expect(p, TOK_LPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_LPAREN)) + return CFREE_CG_TYPE_NONE; src_ty = toy_parse_expr(p); if (src_ty == CFREE_CG_TYPE_NONE || !toy_expect_comma(p) || !toy_parse_rounding_const(p, &rounding) || @@ -838,7 +869,8 @@ CfreeCgTypeId toy_parse_generic_builtin(ToyParser* p, CfreeSym name, if (!toy_parser_expect(p, TOK_LT)) return CFREE_CG_TYPE_NONE; ty = toy_parse_type(p); if (ty == CFREE_CG_TYPE_NONE || !toy_parser_expect(p, TOK_GT) || - !toy_parser_expect(p, TOK_LPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_LPAREN)) + return CFREE_CG_TYPE_NONE; ptr_ty = toy_parse_expr(p); if (ptr_ty == CFREE_CG_TYPE_NONE || !toy_expect_comma(p) || !toy_parse_number_arg(p, &align) || !toy_parser_expect(p, TOK_RPAREN)) @@ -862,10 +894,10 @@ CfreeCgTypeId toy_parse_generic_builtin(ToyParser* p, CfreeSym name, toy_error(p, p->cur.loc, "expected type query form"); return CFREE_CG_TYPE_NONE; } - cfree_cg_push_int(p->cg, - is_align ? cfree_cg_type_align(p->c, ty) - : cfree_cg_type_size(p->c, ty), - p->int_type); + cfree_cg_push_int( + p->cg, + is_align ? cfree_cg_type_align(p->c, ty) : cfree_cg_type_size(p->c, ty), + p->int_type); return p->int_type; } @@ -928,7 +960,8 @@ CfreeCgTypeId toy_parse_generic_builtin(ToyParser* p, CfreeSym name, ty = toy_parse_type(p); if (ty == CFREE_CG_TYPE_NONE || !toy_parser_expect(p, TOK_GT) || !toy_parser_expect(p, TOK_LPAREN) || !toy_parse_va_list_addr_arg(p) || - !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_RPAREN)) + return CFREE_CG_TYPE_NONE; cfree_cg_vararg_next(p->cg, ty); return ty; } @@ -954,7 +987,8 @@ CfreeCgTypeId toy_parse_generic_builtin(ToyParser* p, CfreeSym name, if (!toy_parser_expect(p, TOK_LT)) return CFREE_CG_TYPE_NONE; ty = toy_parse_type(p); if (ty == CFREE_CG_TYPE_NONE || !toy_parser_expect(p, TOK_GT) || - !toy_parser_expect(p, TOK_LPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_LPAREN)) + return CFREE_CG_TYPE_NONE; lhs_ty = toy_parse_expr(p); if (lhs_ty == CFREE_CG_TYPE_NONE || !toy_expect_comma(p)) return CFREE_CG_TYPE_NONE; @@ -1158,9 +1192,9 @@ CfreeCgTypeId toy_parse_memory_builtin_call(ToyParser* p, CfreeSym name, if (toy_sym_is(p, name, "atomic_fence")) { CfreeCgMemOrder order; - if (!toy_parser_expect(p, TOK_LPAREN) || - !toy_parse_mem_order(p, &order) || - !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; + if (!toy_parser_expect(p, TOK_LPAREN) || !toy_parse_mem_order(p, &order) || + !toy_parser_expect(p, TOK_RPAREN)) + return CFREE_CG_TYPE_NONE; cfree_cg_atomic_fence(p->cg, order); return toy_builtin_type(p, CFREE_CG_BUILTIN_VOID); } @@ -1181,14 +1215,16 @@ CfreeCgTypeId toy_parse_atomic_generic_builtin(ToyParser* p, CfreeSym name, if (!toy_parser_expect(p, TOK_LT)) return CFREE_CG_TYPE_NONE; ty = toy_parse_type(p); if (ty == CFREE_CG_TYPE_NONE || !toy_parser_expect(p, TOK_GT) || - !toy_parser_expect(p, TOK_LPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_LPAREN)) + return CFREE_CG_TYPE_NONE; ptr_ty = toy_parse_expr(p); if (ptr_ty == CFREE_CG_TYPE_NONE || !toy_expect_comma(p) || !toy_parse_mem_order(p, &order)) return CFREE_CG_TYPE_NONE; access = toy_mem_access(p, ty); if (!toy_parse_optional_access_arg(p, &access) || - !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_RPAREN)) + return CFREE_CG_TYPE_NONE; if (!toy_type_is_ptr(p, ptr_ty) || cfree_cg_type_ptr_pointee(p->c, ptr_ty) != ty) { toy_error(p, p->cur.loc, "atomic_load pointer type mismatch"); @@ -1205,7 +1241,8 @@ CfreeCgTypeId toy_parse_atomic_generic_builtin(ToyParser* p, CfreeSym name, if (!toy_parser_expect(p, TOK_LT)) return CFREE_CG_TYPE_NONE; ty = toy_parse_type(p); if (ty == CFREE_CG_TYPE_NONE || !toy_parser_expect(p, TOK_GT) || - !toy_parser_expect(p, TOK_LPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_LPAREN)) + return CFREE_CG_TYPE_NONE; ptr_ty = toy_parse_expr(p); if (ptr_ty == CFREE_CG_TYPE_NONE || !toy_expect_comma(p)) return CFREE_CG_TYPE_NONE; @@ -1215,7 +1252,8 @@ CfreeCgTypeId toy_parse_atomic_generic_builtin(ToyParser* p, CfreeSym name, return CFREE_CG_TYPE_NONE; access = toy_mem_access(p, ty); if (!toy_parse_optional_access_arg(p, &access) || - !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_RPAREN)) + return CFREE_CG_TYPE_NONE; if (!toy_type_is_ptr(p, ptr_ty) || cfree_cg_type_ptr_pointee(p->c, ptr_ty) != ty || val_ty != ty) { toy_error(p, p->cur.loc, "atomic_store type mismatch"); @@ -1234,7 +1272,8 @@ CfreeCgTypeId toy_parse_atomic_generic_builtin(ToyParser* p, CfreeSym name, ty = toy_parse_type(p); if (ty == CFREE_CG_TYPE_NONE || !toy_parser_expect(p, TOK_GT) || !toy_parser_expect(p, TOK_LPAREN) || !toy_parse_atomic_op(p, &op) || - !toy_expect_comma(p)) return CFREE_CG_TYPE_NONE; + !toy_expect_comma(p)) + return CFREE_CG_TYPE_NONE; ptr_ty = toy_parse_expr(p); if (ptr_ty == CFREE_CG_TYPE_NONE || !toy_expect_comma(p)) return CFREE_CG_TYPE_NONE; @@ -1244,7 +1283,8 @@ CfreeCgTypeId toy_parse_atomic_generic_builtin(ToyParser* p, CfreeSym name, return CFREE_CG_TYPE_NONE; access = toy_mem_access(p, ty); if (!toy_parse_optional_access_arg(p, &access) || - !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_RPAREN)) + return CFREE_CG_TYPE_NONE; if (!toy_type_is_ptr(p, ptr_ty) || cfree_cg_type_ptr_pointee(p->c, ptr_ty) != ty || val_ty != ty) { toy_error(p, p->cur.loc, "atomic_rmw type mismatch"); @@ -1264,7 +1304,8 @@ CfreeCgTypeId toy_parse_atomic_generic_builtin(ToyParser* p, CfreeSym name, if (!toy_parser_expect(p, TOK_LT)) return CFREE_CG_TYPE_NONE; ty = toy_parse_type(p); if (ty == CFREE_CG_TYPE_NONE || !toy_parser_expect(p, TOK_GT) || - !toy_parser_expect(p, TOK_LPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_LPAREN)) + return CFREE_CG_TYPE_NONE; ptr_ty = toy_parse_expr(p); if (ptr_ty == CFREE_CG_TYPE_NONE || !toy_expect_comma(p)) return CFREE_CG_TYPE_NONE; @@ -1275,13 +1316,15 @@ CfreeCgTypeId toy_parse_atomic_generic_builtin(ToyParser* p, CfreeSym name, if (desired_ty == CFREE_CG_TYPE_NONE || !toy_expect_comma(p) || !toy_parse_mem_order(p, &success_order) || !toy_expect_comma(p) || !toy_parse_mem_order(p, &failure_order) || !toy_expect_comma(p) || - !toy_parse_cmpxchg_strength(p, &weak)) return CFREE_CG_TYPE_NONE; + !toy_parse_cmpxchg_strength(p, &weak)) + return CFREE_CG_TYPE_NONE; access = toy_mem_access(p, ty); if (!toy_parse_optional_access_arg(p, &access) || - !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_RPAREN)) + return CFREE_CG_TYPE_NONE; if (!toy_type_is_ptr(p, ptr_ty) || - cfree_cg_type_ptr_pointee(p->c, ptr_ty) != ty || - expected_ty != ty || desired_ty != ty) { + cfree_cg_type_ptr_pointee(p->c, ptr_ty) != ty || expected_ty != ty || + desired_ty != ty) { toy_error(p, p->cur.loc, "atomic_cmpxchg type mismatch"); return CFREE_CG_TYPE_NONE; } @@ -1316,15 +1359,14 @@ CfreeCgTypeId toy_parse_atomic_generic_builtin(ToyParser* p, CfreeSym name, if (!toy_parser_expect(p, TOK_LT)) return CFREE_CG_TYPE_NONE; ty = toy_parse_type(p); if (ty == CFREE_CG_TYPE_NONE || !toy_parser_expect(p, TOK_GT) || - !toy_parser_expect(p, TOK_LPAREN) || - !toy_parse_mem_order(p, &order)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_LPAREN) || !toy_parse_mem_order(p, &order)) + return CFREE_CG_TYPE_NONE; access = toy_mem_access(p, ty); if (!toy_parse_optional_access_arg(p, &access) || - !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_RPAREN)) + return CFREE_CG_TYPE_NONE; cfree_cg_push_int(p->cg, - cfree_cg_atomic_is_legal(p->c, access, order) - ? 1u - : 0u, + cfree_cg_atomic_is_legal(p->c, access, order) ? 1u : 0u, toy_builtin_type(p, CFREE_CG_BUILTIN_BOOL)); return toy_builtin_type(p, CFREE_CG_BUILTIN_BOOL); } @@ -1334,14 +1376,15 @@ CfreeCgTypeId toy_parse_atomic_generic_builtin(ToyParser* p, CfreeSym name, if (!toy_parser_expect(p, TOK_LT)) return CFREE_CG_TYPE_NONE; ty = toy_parse_type(p); if (ty == CFREE_CG_TYPE_NONE || !toy_parser_expect(p, TOK_GT) || - !toy_parser_expect(p, TOK_LPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_LPAREN)) + return CFREE_CG_TYPE_NONE; access = toy_mem_access(p, ty); if (p->cur.kind != TOK_RPAREN && !toy_parse_access_group(p, &access)) return CFREE_CG_TYPE_NONE; if (!toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; - cfree_cg_push_int( - p->cg, cfree_cg_atomic_is_lock_free(p->c, access) ? 1u : 0u, - toy_builtin_type(p, CFREE_CG_BUILTIN_BOOL)); + cfree_cg_push_int(p->cg, + cfree_cg_atomic_is_lock_free(p->c, access) ? 1u : 0u, + toy_builtin_type(p, CFREE_CG_BUILTIN_BOOL)); return toy_builtin_type(p, CFREE_CG_BUILTIN_BOOL); } @@ -1413,8 +1456,8 @@ CfreeCgTypeId toy_parse_low_level_builtin_call(ToyParser* p, CfreeSym name, if (toy_sym_is(p, name, "irq_save") || toy_sym_is(p, name, "wfi") || toy_sym_is(p, name, "wfe") || toy_sym_is(p, name, "sev")) { - if (!toy_parser_expect(p, TOK_LPAREN) || - !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; + if (!toy_parser_expect(p, TOK_LPAREN) || !toy_parser_expect(p, TOK_RPAREN)) + return CFREE_CG_TYPE_NONE; return toy_unsupported_intrinsic(p); } @@ -1435,7 +1478,8 @@ CfreeCgTypeId toy_parse_low_level_builtin_call(ToyParser* p, CfreeSym name, CfreeCgBarrierScope scope; if (!toy_parser_expect(p, TOK_LPAREN) || !toy_parse_barrier_scope(p, &scope) || - !toy_parser_expect(p, TOK_RPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_RPAREN)) + return CFREE_CG_TYPE_NONE; (void)scope; return toy_unsupported_intrinsic(p); } @@ -1474,7 +1518,8 @@ CfreeCgTypeId toy_parse_low_level_generic_builtin(ToyParser* p, CfreeSym name, if (!toy_parser_expect(p, TOK_LT)) return CFREE_CG_TYPE_NONE; ty = toy_parse_type(p); if (ty == CFREE_CG_TYPE_NONE || !toy_parser_expect(p, TOK_GT) || - !toy_parser_expect(p, TOK_LPAREN)) return CFREE_CG_TYPE_NONE; + !toy_parser_expect(p, TOK_LPAREN)) + return CFREE_CG_TYPE_NONE; from_ty = toy_parse_expr(p); if (from_ty == CFREE_CG_TYPE_NONE || !toy_expect_comma(p)) return CFREE_CG_TYPE_NONE; diff --git a/lang/toy/data.c b/lang/toy/data.c @@ -1,7 +1,7 @@ -#include "internal.h" - #include <string.h> +#include "internal.h" + int toy_parse_data_array_builtin(ToyParser* p, CfreeCgTypeId elem_ty, uint64_t total_size, uint64_t* pos); @@ -28,12 +28,12 @@ int toy_parse_global_var(ToyParser* p, int is_extern, int is_pub) { toy_parser_advance(p); /* let */ } if (!toy_parse_attr_list(p, &attrs, default_bind)) return 0; - if (!toy_validate_attr_placement( - p, &attrs, - TOY_ATTR_SYMBOL | TOY_ATTR_OBJECT | TOY_ATTR_SECTION | - TOY_ATTR_OBJECT_DATA | (is_extern ? 0u : TOY_ATTR_DATA), - is_extern ? "invalid extern data attribute" - : "invalid object attribute")) { + if (!toy_validate_attr_placement(p, &attrs, + TOY_ATTR_SYMBOL | TOY_ATTR_OBJECT | + TOY_ATTR_SECTION | TOY_ATTR_OBJECT_DATA | + (is_extern ? 0u : TOY_ATTR_DATA), + is_extern ? "invalid extern data attribute" + : "invalid object attribute")) { return 0; } @@ -200,8 +200,8 @@ int toy_parse_global_var(ToyParser* p, int is_extern, int is_pub) { return 0; } } else if (attrs.is_common) { - uint32_t align = data_attrs.align ? data_attrs.align - : cfree_cg_type_align(p->c, ty); + uint32_t align = + data_attrs.align ? data_attrs.align : cfree_cg_type_align(p->c, ty); cfree_cg_data_common(p->cg, sym, cfree_cg_type_size(p->c, ty), align); } else { cfree_cg_data_begin(p->cg, sym, data_attrs); @@ -368,7 +368,8 @@ int toy_parse_data_array_builtin(ToyParser* p, CfreeCgTypeId elem_ty, CfreeSym target_name; CfreeCgSym target_sym; int64_t addend; - if (!toy_type_is_intlike(p, elem_ty) || (elem_size != 4 && elem_size != 8)) { + if (!toy_type_is_intlike(p, elem_ty) || + (elem_size != 4 && elem_size != 8)) { toy_error(p, p->cur.loc, "pcrel requires i32/i64 initializer slot"); return 0; } @@ -382,8 +383,7 @@ int toy_parse_data_array_builtin(ToyParser* p, CfreeCgTypeId elem_ty, } target_name = toy_tok_sym(p, p->cur); toy_parser_advance(p); - if (!toy_parser_expect(p, TOK_COMMA) || - !toy_parse_number_arg(p, &addend) || + if (!toy_parser_expect(p, TOK_COMMA) || !toy_parse_number_arg(p, &addend) || !toy_parser_expect(p, TOK_RPAREN)) { toy_error(p, p->cur.loc, "invalid pcrel initializer"); return 0; @@ -423,8 +423,7 @@ int toy_parse_data_array_builtin(ToyParser* p, CfreeCgTypeId elem_ty, } rhs_name = toy_tok_sym(p, p->cur); toy_parser_advance(p); - if (!toy_parser_expect(p, TOK_COMMA) || - !toy_parse_number_arg(p, &addend) || + if (!toy_parser_expect(p, TOK_COMMA) || !toy_parse_number_arg(p, &addend) || !toy_parser_expect(p, TOK_RPAREN)) { toy_error(p, p->cur.loc, "invalid symdiff initializer"); return 0; @@ -435,8 +434,7 @@ int toy_parse_data_array_builtin(ToyParser* p, CfreeCgTypeId elem_ty, toy_error(p, p->cur.loc, "undefined symdiff symbol"); return 0; } - cfree_cg_data_symdiff(p->cg, lhs_sym, rhs_sym, addend, - (uint32_t)elem_size); + cfree_cg_data_symdiff(p->cg, lhs_sym, rhs_sym, addend, (uint32_t)elem_size); *pos += elem_size; return 1; } @@ -475,10 +473,8 @@ int toy_parse_data_array_builtin(ToyParser* p, CfreeCgTypeId elem_ty, if (toy_sym_is(p, name, "pad")) { int64_t size; int64_t value; - if (!toy_parser_expect(p, TOK_LPAREN) || - !toy_parse_number_arg(p, &size) || - !toy_parser_expect(p, TOK_COMMA) || - !toy_parse_number_arg(p, &value) || + if (!toy_parser_expect(p, TOK_LPAREN) || !toy_parse_number_arg(p, &size) || + !toy_parser_expect(p, TOK_COMMA) || !toy_parse_number_arg(p, &value) || !toy_parser_expect(p, TOK_RPAREN)) { return 0; } @@ -494,8 +490,7 @@ int toy_parse_data_array_builtin(ToyParser* p, CfreeCgTypeId elem_ty, if (toy_sym_is(p, name, "align")) { int64_t align; uint64_t aligned; - if (!toy_parser_expect(p, TOK_LPAREN) || - !toy_parse_number_arg(p, &align) || + if (!toy_parser_expect(p, TOK_LPAREN) || !toy_parse_number_arg(p, &align) || !toy_parser_expect(p, TOK_RPAREN)) { return 0; } diff --git a/lang/toy/decls.c b/lang/toy/decls.c @@ -1,8 +1,8 @@ -#include "internal.h" - #include <stdio.h> #include <string.h> +#include "internal.h" + int toy_parse_type_alias_decl(ToyParser* p) { CfreeSym name; CfreeCgTypeId base; @@ -119,8 +119,7 @@ int toy_parse_record_decl(ToyParser* p) { done: toy_parser_free_mem(p, fields, cap_fields * sizeof *fields); - toy_parser_free_mem(p, field_infos, - cap_field_infos * sizeof *field_infos); + toy_parser_free_mem(p, field_infos, cap_field_infos * sizeof *field_infos); return ok; } @@ -157,7 +156,8 @@ int toy_parse_tuple_decl(ToyParser* p) { goto done; } snprintf(field_name_buf, sizeof field_name_buf, "%u", (uint32_t)nfields); - fields[nfields].name = cfree_sym_intern(p->c, cfree_slice_cstr(field_name_buf)); + fields[nfields].name = + cfree_sym_intern(p->c, cfree_slice_cstr(field_name_buf)); fields[nfields].type = toy_parse_type(p); if (fields[nfields].type == CFREE_CG_TYPE_NONE) goto done; field_infos[nfields].name = fields[nfields].name; @@ -181,8 +181,7 @@ int toy_parse_tuple_decl(ToyParser* p) { done: toy_parser_free_mem(p, fields, cap_fields * sizeof *fields); - toy_parser_free_mem(p, field_infos, - cap_field_infos * sizeof *field_infos); + toy_parser_free_mem(p, field_infos, cap_field_infos * sizeof *field_infos); return ok; } @@ -374,9 +373,8 @@ int toy_parse_fn(ToyParser* p, int is_extern, int is_pub) { !toy_parser_reserve(p, (void**)¶m_attrs, &cap_param_attrs, nparams + 1u, sizeof *param_attrs, "function parameter attrs") || - !toy_parser_reserve(p, (void**)¶m_toy_types, - &cap_param_toy_types, nparams + 1u, - sizeof *param_toy_types, + !toy_parser_reserve(p, (void**)¶m_toy_types, &cap_param_toy_types, + nparams + 1u, sizeof *param_toy_types, "function parameter source types") || !toy_parser_reserve(p, (void**)&sig_params, &cap_sig_params, nparams + 1u, sizeof *sig_params, @@ -441,8 +439,8 @@ int toy_parse_fn(ToyParser* p, int is_extern, int is_pub) { toy_error(p, p->cur.loc, "failed to create function type"); return -1; } - fn_toy_type = toy_type_register_func(p, fn_ty, ret_toy_type, - param_toy_types, nparams, variadic); + fn_toy_type = toy_type_register_func(p, fn_ty, ret_toy_type, param_toy_types, + nparams, variadic); memset(&decl, 0, sizeof(decl)); decl.kind = CFREE_CG_DECL_FUNC; @@ -476,15 +474,12 @@ int toy_parse_fn(ToyParser* p, int is_extern, int is_pub) { toy_error(p, p->cur.loc, "expected ';' after extern function"); return -1; } - toy_parser_free_mem(p, param_types, - cap_param_types * sizeof *param_types); + toy_parser_free_mem(p, param_types, cap_param_types * sizeof *param_types); toy_parser_free_mem(p, param_toy_types, cap_param_toy_types * sizeof *param_toy_types); - toy_parser_free_mem(p, param_attrs, - cap_param_attrs * sizeof *param_attrs); + toy_parser_free_mem(p, param_attrs, cap_param_attrs * sizeof *param_attrs); toy_parser_free_mem(p, sig_params, cap_sig_params * sizeof *sig_params); - toy_parser_free_mem(p, param_names, - cap_param_names * sizeof *param_names); + toy_parser_free_mem(p, param_names, cap_param_names * sizeof *param_names); return 1; } @@ -495,10 +490,11 @@ int toy_parse_fn(ToyParser* p, int is_extern, int is_pub) { p->cur_fn_ret = ret_type; p->cur_fn_ret_toy = ret_toy_type; for (i = 0; i < nparams; i++) { - CfreeCgLocal param = cfree_cg_param( - p->cg, (uint32_t)i, param_types[i], toy_slot_attrs(param_names[i])); + CfreeCgLocal param = cfree_cg_param(p->cg, (uint32_t)i, param_types[i], + toy_slot_attrs(param_names[i])); if (!toy_add_local_typed(p, param_names[i], param_types[i], - param_toy_types[i], param, 1)) return -1; + param_toy_types[i], param, 1)) + return -1; } if (!toy_parse_block(p)) return -1; diff --git a/lang/toy/expr.c b/lang/toy/expr.c @@ -1,11 +1,11 @@ -#include "internal.h" - #include <cfree/cg.h> #include <stddef.h> #include <stdint.h> #include <stdio.h> #include <string.h> +#include "internal.h" + /* Public CG API coverage goals for this frontend are tracked in * doc/toy-todo.md. Keep this file aligned with include/cfree/cg.h rather than * private CG implementation details. */ @@ -51,7 +51,8 @@ CfreeCgTypeId toy_push_named_rvalue(ToyParser* p, CfreeSym name) { if (g) { cfree_cg_push_symbol_addr(p->cg, g->sym, 0); if (cfree_cg_type_kind(p->c, g->type) != CFREE_CG_TYPE_RECORD) - cfree_cg_load(p->cg, toy_mem_access(p, g->type), (CfreeCgEffAddr){0, 0}); + cfree_cg_load(p->cg, toy_mem_access(p, g->type), + (CfreeCgEffAddr){0, 0}); p->last_type = g->toy_type; return g->type; } @@ -68,9 +69,9 @@ CfreeCgTypeId toy_push_named_rvalue(ToyParser* p, CfreeSym name) { return CFREE_CG_TYPE_NONE; } -int toy_parse_call_args(ToyParser* p, ToyToken call_tok, - CfreeCgTypeId fn_ty, const ToyTypeId* toy_params, - size_t toy_nparams, size_t* out_nargs) { +int toy_parse_call_args(ToyParser* p, ToyToken call_tok, CfreeCgTypeId fn_ty, + const ToyTypeId* toy_params, size_t toy_nparams, + size_t* out_nargs) { uint32_t nparams = cfree_cg_type_func_nparams(p->c, fn_ty); int variadic = cfree_cg_type_func_is_variadic(p->c, fn_ty); size_t nargs = 0; @@ -109,9 +110,9 @@ int toy_parse_call_args(ToyParser* p, ToyToken call_tok, } cfree_cg_push_int(p->cg, (uint64_t)value, param.type); arg_ty = param.type; - p->last_type = - (toy_params && nargs < toy_nparams) ? toy_params[nargs] - : toy_type_from_cg(p, arg_ty); + p->last_type = (toy_params && nargs < toy_nparams) + ? toy_params[nargs] + : toy_type_from_cg(p, arg_ty); } else { arg_ty = toy_parse_expr(p); } @@ -120,9 +121,9 @@ int toy_parse_call_args(ToyParser* p, ToyToken call_tok, if (nargs < nparams) { CfreeCgFuncParam param = cfree_cg_type_func_param(p->c, fn_ty, (uint32_t)nargs); - ToyTypeId expected = - (toy_params && nargs < toy_nparams) ? toy_params[nargs] - : TOY_TYPE_NONE; + ToyTypeId expected = (toy_params && nargs < toy_nparams) + ? toy_params[nargs] + : TOY_TYPE_NONE; ToyTypeId actual = p->last_type; if (expected != TOY_TYPE_NONE && !toy_type_accepts_type(p, expected, actual)) { @@ -175,9 +176,12 @@ static int toy_emit_cast(ToyParser* p, CfreeCgTypeId src, CfreeCgTypeId dst) { if (toy_type_is_intlike(p, src) && toy_type_is_intlike(p, dst)) { uint32_t sw = toy_type_int_width(p, src); uint32_t dw = toy_type_int_width(p, dst); - if (dw > sw && sk == CFREE_CG_TYPE_BOOL) cfree_cg_zext(p->cg, dst); - else if (dw > sw) cfree_cg_sext(p->cg, dst); - else if (dw < sw) cfree_cg_trunc(p->cg, dst); + if (dw > sw && sk == CFREE_CG_TYPE_BOOL) + cfree_cg_zext(p->cg, dst); + else if (dw > sw) + cfree_cg_sext(p->cg, dst); + else if (dw < sw) + cfree_cg_trunc(p->cg, dst); return 1; } if (toy_type_is_intlike(p, src) && dk == CFREE_CG_TYPE_FLOAT) { @@ -191,8 +195,10 @@ static int toy_emit_cast(ToyParser* p, CfreeCgTypeId src, CfreeCgTypeId dst) { if (sk == CFREE_CG_TYPE_FLOAT && dk == CFREE_CG_TYPE_FLOAT) { uint32_t sw = cfree_cg_type_float_width(p->c, src); uint32_t dw = cfree_cg_type_float_width(p->c, dst); - if (dw > sw) cfree_cg_fpext(p->cg, dst); - else if (dw < sw) cfree_cg_fptrunc(p->cg, dst); + if (dw > sw) + cfree_cg_fpext(p->cg, dst); + else if (dw < sw) + cfree_cg_fptrunc(p->cg, dst); return 1; } if (sk == CFREE_CG_TYPE_PTR && toy_type_is_intlike(p, dst)) { @@ -282,13 +288,20 @@ static int toy_parse_dot_constant_value(ToyParser* p, int64_t* out) { } name = toy_tok_sym(p, p->cur); toy_parser_advance(p); - if (toy_sym_is(p, name, "arm64")) *out = 1; - else if (toy_sym_is(p, name, "x64")) *out = 2; - else if (toy_sym_is(p, name, "rv64")) *out = 3; - else if (toy_sym_is(p, name, "x86")) *out = 4; - else if (toy_sym_is(p, name, "arm32")) *out = 5; - else if (toy_sym_is(p, name, "rv32")) *out = 6; - else if (toy_sym_is(p, name, "wasm")) *out = 7; + if (toy_sym_is(p, name, "arm64")) + *out = 1; + else if (toy_sym_is(p, name, "x64")) + *out = 2; + else if (toy_sym_is(p, name, "rv64")) + *out = 3; + else if (toy_sym_is(p, name, "x86")) + *out = 4; + else if (toy_sym_is(p, name, "arm32")) + *out = 5; + else if (toy_sym_is(p, name, "rv32")) + *out = 6; + else if (toy_sym_is(p, name, "wasm")) + *out = 7; else { toy_error(p, p->cur.loc, "unknown dot constant"); return 0; @@ -297,7 +310,7 @@ static int toy_parse_dot_constant_value(ToyParser* p, int64_t* out) { } int toy_parse_switch_label_value(ToyParser* p, CfreeCgTypeId selector_ty, - int64_t* out) { + int64_t* out) { ToyNamedType* named; CfreeSym value_name; size_t i; @@ -330,15 +343,18 @@ int toy_parse_symbol_feature_const(ToyParser* p, CfreeCgSymbolFeature* out) { } name = toy_tok_sym(p, p->cur); toy_parser_advance(p); - if (toy_sym_is(p, name, "weak")) *out = CFREE_CG_SYMFEAT_WEAK; + if (toy_sym_is(p, name, "weak")) + *out = CFREE_CG_SYMFEAT_WEAK; else if (toy_sym_is(p, name, "protected_visibility")) *out = CFREE_CG_SYMFEAT_PROTECTED_VISIBILITY; else if (toy_sym_is(p, name, "dllimport")) *out = CFREE_CG_SYMFEAT_DLLIMPORT; else if (toy_sym_is(p, name, "dllexport")) *out = CFREE_CG_SYMFEAT_DLLEXPORT; - else if (toy_sym_is(p, name, "comdat")) *out = CFREE_CG_SYMFEAT_COMDAT; - else if (toy_sym_is(p, name, "common")) *out = CFREE_CG_SYMFEAT_COMMON; + else if (toy_sym_is(p, name, "comdat")) + *out = CFREE_CG_SYMFEAT_COMDAT; + else if (toy_sym_is(p, name, "common")) + *out = CFREE_CG_SYMFEAT_COMMON; else if (toy_sym_is(p, name, "merge_sections")) *out = CFREE_CG_SYMFEAT_MERGE_SECTIONS; else if (toy_sym_is(p, name, "constructor_priority")) @@ -388,13 +404,16 @@ int toy_parse_backend_feature_const(ToyParser* p, uint64_t* out) { int toy_parse_rounding_const(ToyParser* p, CfreeCgRounding* out) { CfreeSym name; if (!toy_parse_attr_dot_name(p, &name)) return 0; - if (toy_sym_is(p, name, "default")) *out = CFREE_CG_ROUND_DEFAULT; + if (toy_sym_is(p, name, "default")) + *out = CFREE_CG_ROUND_DEFAULT; else if (toy_sym_is(p, name, "nearest_even")) *out = CFREE_CG_ROUND_NEAREST_EVEN; else if (toy_sym_is(p, name, "toward_zero")) *out = CFREE_CG_ROUND_TOWARD_ZERO; - else if (toy_sym_is(p, name, "down")) *out = CFREE_CG_ROUND_DOWN; - else if (toy_sym_is(p, name, "up")) *out = CFREE_CG_ROUND_UP; + else if (toy_sym_is(p, name, "down")) + *out = CFREE_CG_ROUND_DOWN; + else if (toy_sym_is(p, name, "up")) + *out = CFREE_CG_ROUND_UP; else { toy_error(p, p->cur.loc, "unknown rounding mode"); return 0; @@ -503,8 +522,7 @@ CfreeCgTypeId toy_emit_slice_index_lvalue(ToyParser* p, CfreeCgTypeId slice_ty, cfree_cg_load(p->cg, toy_mem_access(p, ptr_field.type), (CfreeCgEffAddr){(int64_t)ptr_field_off, 0}); cfree_cg_push_local(p->cg, idx_slot); - cfree_cg_load(p->cg, toy_mem_access(p, p->int_type), - (CfreeCgEffAddr){0, 0}); + cfree_cg_load(p->cg, toy_mem_access(p, p->int_type), (CfreeCgEffAddr){0, 0}); toy_addr_index(p, cfree_cg_type_size(p->c, elem_ty), cfree_cg_type_ptr(p->c, elem_ty, 0)); if (elem_toy_out) *elem_toy_out = elem_toy; @@ -513,8 +531,7 @@ CfreeCgTypeId toy_emit_slice_index_lvalue(ToyParser* p, CfreeCgTypeId slice_ty, CfreeCgTypeId toy_emit_slice_value(ToyParser* p, CfreeCgTypeId base_ty, ToyTypeId base_toy_type, - CfreeCgTypeId start_ty, - CfreeCgTypeId end_ty, + CfreeCgTypeId start_ty, CfreeCgTypeId end_ty, ToyTypeId* slice_toy_out) { ToyTypeId elem_toy = TOY_TYPE_NONE; CfreeCgTypeId elem_ty = CFREE_CG_TYPE_NONE; @@ -552,8 +569,10 @@ CfreeCgTypeId toy_emit_slice_value(ToyParser* p, CfreeCgTypeId base_ty, CfreeCgField len_field; (void)len_field; if (slice_ty == CFREE_CG_TYPE_NONE || - cfree_cg_type_record_field(p->c, slice_ty, 0, &ptr_field, &ptr_off) != 0 || - cfree_cg_type_record_field(p->c, slice_ty, 1, &len_field, &len_off) != 0) { + cfree_cg_type_record_field(p->c, slice_ty, 0, &ptr_field, &ptr_off) != + 0 || + cfree_cg_type_record_field(p->c, slice_ty, 1, &len_field, &len_off) != + 0) { toy_error(p, p->cur.loc, "failed to create slice type"); return CFREE_CG_TYPE_NONE; } @@ -684,8 +703,8 @@ static CfreeCgTypeId toy_parse_expr_primary(ToyParser* p) { if (toy_sym_is(p, name, "true") || toy_sym_is(p, name, "false")) { cfree_cg_push_int(p->cg, toy_sym_is(p, name, "true") ? 1u : 0u, toy_builtin_type(p, CFREE_CG_BUILTIN_BOOL)); - p->last_type = toy_type_from_cg( - p, toy_builtin_type(p, CFREE_CG_BUILTIN_BOOL)); + p->last_type = + toy_type_from_cg(p, toy_builtin_type(p, CFREE_CG_BUILTIN_BOOL)); return toy_builtin_type(p, CFREE_CG_BUILTIN_BOOL); } @@ -749,9 +768,9 @@ static CfreeCgTypeId toy_parse_expr_primary(ToyParser* p) { return CFREE_CG_TYPE_NONE; cfree_cg_call_default(p->cg, (uint32_t)nargs, fn_ty); p->last_type = - source_fn_type ? source_fn_type->ret - : toy_type_from_cg(p, - cfree_cg_type_func_ret(p->c, fn_ty)); + source_fn_type + ? source_fn_type->ret + : toy_type_from_cg(p, cfree_cg_type_func_ret(p->c, fn_ty)); return cfree_cg_type_func_ret(p->c, fn_ty); } @@ -770,9 +789,8 @@ static CfreeCgTypeId toy_parse_expr_primary(ToyParser* p) { } { ToyGlobal* g = toy_find_global(p, name); - if (g && - (cfree_cg_type_kind(p->c, g->type) == CFREE_CG_TYPE_ARRAY || - cfree_cg_type_kind(p->c, g->type) == CFREE_CG_TYPE_RECORD)) { + if (g && (cfree_cg_type_kind(p->c, g->type) == CFREE_CG_TYPE_ARRAY || + cfree_cg_type_kind(p->c, g->type) == CFREE_CG_TYPE_RECORD)) { cfree_cg_push_symbol_addr(p->cg, g->sym, 0); p->last_type = g->toy_type; return g->type; @@ -888,15 +906,17 @@ static CfreeCgTypeId toy_parse_expr_postfix(ToyParser* p) { ty = toy_emit_slice_index_lvalue(p, ty, toy_ty, &toy_ty); if (ty == CFREE_CG_TYPE_NONE) return CFREE_CG_TYPE_NONE; cfree_cg_load(p->cg, toy_mem_access(p, ty), (CfreeCgEffAddr){0, 0}); - p->last_type = toy_ty != TOY_TYPE_NONE ? toy_ty : toy_type_from_cg(p, ty); + p->last_type = + toy_ty != TOY_TYPE_NONE ? toy_ty : toy_type_from_cg(p, ty); continue; } else { toy_error(p, p->cur.loc, "cannot index non-array/non-pointer"); return CFREE_CG_TYPE_NONE; } /* TOS = [base, idx]; load with element-size scale. */ - cfree_cg_load(p->cg, toy_mem_access(p, ty), - (CfreeCgEffAddr){0, (uint32_t)cfree_cg_type_size(p->c, ty)}); + cfree_cg_load( + p->cg, toy_mem_access(p, ty), + (CfreeCgEffAddr){0, (uint32_t)cfree_cg_type_size(p->c, ty)}); p->last_type = toy_ty != TOY_TYPE_NONE ? toy_ty : toy_type_from_cg(p, ty); continue; } @@ -984,19 +1004,19 @@ static CfreeCgTypeId toy_parse_expr_postfix(ToyParser* p) { ty = found_field.type; cfree_cg_load(p->cg, toy_mem_access(p, ty), (CfreeCgEffAddr){(int64_t)found_off, 0}); - if (field_toy_type != TOY_TYPE_NONE) { - CfreeCgTypeId resolved = toy_type_resolved_cg(p, field_toy_type); - p->last_type = field_toy_type; - toy_ty = field_toy_type; - if (resolved != CFREE_CG_TYPE_NONE && resolved != ty) { - cfree_cg_bitcast(p->cg, resolved); - ty = resolved; - } - } else { - p->last_type = toy_type_from_cg(p, ty); - toy_ty = p->last_type; + if (field_toy_type != TOY_TYPE_NONE) { + CfreeCgTypeId resolved = toy_type_resolved_cg(p, field_toy_type); + p->last_type = field_toy_type; + toy_ty = field_toy_type; + if (resolved != CFREE_CG_TYPE_NONE && resolved != ty) { + cfree_cg_bitcast(p->cg, resolved); + ty = resolved; } - continue; + } else { + p->last_type = toy_type_from_cg(p, ty); + toy_ty = p->last_type; + } + continue; } break; @@ -1153,8 +1173,7 @@ static CfreeCgTypeId toy_parse_expr_unary(ToyParser* p) { return CFREE_CG_TYPE_NONE; } /* TOS = **T; load to TOS = *T. */ - cfree_cg_load(p->cg, toy_mem_access(p, ty), - (CfreeCgEffAddr){0, 0}); + cfree_cg_load(p->cg, toy_mem_access(p, ty), (CfreeCgEffAddr){0, 0}); ty = cfree_cg_type_ptr_pointee(p->c, ty); ty_toy = toy_type_pointee(p, ty_toy); continue; @@ -1165,12 +1184,10 @@ static CfreeCgTypeId toy_parse_expr_unary(ToyParser* p) { uint64_t foff = 0; ToyNamedType* named; if (cfree_cg_type_kind(p->c, ty) == CFREE_CG_TYPE_PTR && - cfree_cg_type_kind(p->c, - cfree_cg_type_ptr_pointee(p->c, ty)) == + cfree_cg_type_kind(p->c, cfree_cg_type_ptr_pointee(p->c, ty)) == CFREE_CG_TYPE_RECORD) { /* TOS = **Rec; load to *Rec. */ - cfree_cg_load(p->cg, toy_mem_access(p, ty), - (CfreeCgEffAddr){0, 0}); + cfree_cg_load(p->cg, toy_mem_access(p, ty), (CfreeCgEffAddr){0, 0}); ty = cfree_cg_type_ptr_pointee(p->c, ty); ty_toy = toy_type_pointee(p, ty_toy); } @@ -1212,8 +1229,7 @@ static CfreeCgTypeId toy_parse_expr_unary(ToyParser* p) { ty_toy = (named && field_index < named->nfields) ? named->fields[field_index].toy_type : toy_type_from_cg(p, ty); - toy_addr_offset(p, (int64_t)foff, - cfree_cg_type_ptr(p->c, ty, 0)); + toy_addr_offset(p, (int64_t)foff, cfree_cg_type_ptr(p->c, ty, 0)); continue; } break; @@ -1286,8 +1302,10 @@ static CfreeCgTypeId toy_parse_expr_mul(ToyParser* p) { CfreeCgTypeId ty2 = toy_parse_expr_cast(p); if (ty2 == CFREE_CG_TYPE_NONE) return CFREE_CG_TYPE_NONE; if (toy_reject_tail_call_operand(p)) return CFREE_CG_TYPE_NONE; - if (ty != ty2 || (!toy_type_is_intlike(p, ty) && !toy_type_is_float(p, ty))) { - toy_error(p, p->cur.loc, "arithmetic operands must have same numeric type"); + if (ty != ty2 || + (!toy_type_is_intlike(p, ty) && !toy_type_is_float(p, ty))) { + toy_error(p, p->cur.loc, + "arithmetic operands must have same numeric type"); return CFREE_CG_TYPE_NONE; } if (toy_type_is_float(p, ty)) { @@ -1344,14 +1362,15 @@ static CfreeCgTypeId toy_parse_expr_add(ToyParser* p) { CfreeCgTypeId ty2 = toy_parse_expr_mul(p); if (ty2 == CFREE_CG_TYPE_NONE) return CFREE_CG_TYPE_NONE; if (toy_reject_tail_call_operand(p)) return CFREE_CG_TYPE_NONE; - if (ty != ty2 || (!toy_type_is_intlike(p, ty) && !toy_type_is_float(p, ty))) { - toy_error(p, p->cur.loc, "arithmetic operands must have same numeric type"); + if (ty != ty2 || + (!toy_type_is_intlike(p, ty) && !toy_type_is_float(p, ty))) { + toy_error(p, p->cur.loc, + "arithmetic operands must have same numeric type"); return CFREE_CG_TYPE_NONE; } if (toy_type_is_float(p, ty)) { cfree_cg_fp_binop(p->cg, - op == TOK_PLUS ? CFREE_CG_FP_ADD : CFREE_CG_FP_SUB, - 0); + op == TOK_PLUS ? CFREE_CG_FP_ADD : CFREE_CG_FP_SUB, 0); } else { cfree_cg_int_binop(p->cg, binop, 0); } @@ -1362,10 +1381,9 @@ static CfreeCgTypeId toy_parse_expr_add(ToyParser* p) { static CfreeCgTypeId toy_parse_expr_cmp(ToyParser* p) { CfreeCgTypeId ty = toy_parse_expr_add(p); if (ty == CFREE_CG_TYPE_NONE) return CFREE_CG_TYPE_NONE; - if (!p->tail_call_expr && - (p->cur.kind == TOK_EQEQ || p->cur.kind == TOK_NE || - p->cur.kind == TOK_LT || p->cur.kind == TOK_GT || - p->cur.kind == TOK_LE || p->cur.kind == TOK_GE)) { + if (!p->tail_call_expr && (p->cur.kind == TOK_EQEQ || p->cur.kind == TOK_NE || + p->cur.kind == TOK_LT || p->cur.kind == TOK_GT || + p->cur.kind == TOK_LE || p->cur.kind == TOK_GE)) { ToyTokenKind op = p->cur.kind; CfreeCgIntCmpOp cmp; if (!toy_note_expr_island(p, TOY_EXPR_ISLAND_CMP)) diff --git a/lang/toy/internal.h b/lang/toy/internal.h @@ -1,14 +1,14 @@ #ifndef CFREE_TOY_INTERNAL_H #define CFREE_TOY_INTERNAL_H -#include "lexer.h" - -#include <cfree/compile.h> #include <cfree/cg.h> +#include <cfree/compile.h> #include <cfree/frontend.h> #include <stddef.h> #include <stdint.h> +#include "lexer.h" + typedef uint32_t ToyTypeId; #define TOY_TYPE_NONE ((ToyTypeId)0) @@ -228,11 +228,9 @@ typedef struct ToyParser { CfreeCgTypeId toy_builtin_type(ToyParser* p, CfreeCgBuiltinType ty); void toy_parser_init(ToyParser* p, CfreeCompiler* c, CfreeCg* cg, - const uint8_t* data, size_t len, - const char* input_name); + const uint8_t* data, size_t len, const char* input_name); void toy_parser_reinit(ToyParser* p, CfreeCompiler* c, CfreeCg* cg, - const uint8_t* data, size_t len, - const char* input_name, + const uint8_t* data, size_t len, const char* input_name, CfreeFrontendInputKind input_kind); void toy_parser_dispose(ToyParser* p); void* toy_parser_zalloc(ToyParser* p, size_t count, size_t elem_size, @@ -328,21 +326,21 @@ void toy_type_register_builtins(ToyParser* p); const ToyType* toy_type_get(ToyParser* p, ToyTypeId id); CfreeCgTypeId toy_type_cg(ToyParser* p, ToyTypeId id); ToyTypeId toy_type_from_cg(ToyParser* p, CfreeCgTypeId cg); -ToyTypeId toy_type_register_alias(ToyParser* p, CfreeSym name, - CfreeCgTypeId cg, CfreeCgTypeId base); +ToyTypeId toy_type_register_alias(ToyParser* p, CfreeSym name, CfreeCgTypeId cg, + CfreeCgTypeId base); ToyTypeId toy_type_register_named_record(ToyParser* p, CfreeSym name, CfreeCgTypeId cg, int is_tuple); -ToyTypeId toy_type_register_enum(ToyParser* p, CfreeSym name, - CfreeCgTypeId cg, CfreeCgTypeId base); +ToyTypeId toy_type_register_enum(ToyParser* p, CfreeSym name, CfreeCgTypeId cg, + CfreeCgTypeId base); ToyTypeId toy_type_register_qualified(ToyParser* p, CfreeCgTypeId cg, CfreeCgTypeId base, uint32_t quals); ToyTypeId toy_type_register_ptr(ToyParser* p, CfreeCgTypeId cg, ToyTypeId pointee, uint32_t address_space); ToyTypeId toy_type_register_slice(ToyParser* p, CfreeCgTypeId elem_cg, ToyTypeId elem); -ToyTypeId toy_type_register_func(ToyParser* p, CfreeCgTypeId cg, - ToyTypeId ret, const ToyTypeId* params, - size_t nparams, int variadic); +ToyTypeId toy_type_register_func(ToyParser* p, CfreeCgTypeId cg, ToyTypeId ret, + const ToyTypeId* params, size_t nparams, + int variadic); int toy_type_accepts_type(ToyParser* p, ToyTypeId expected, ToyTypeId actual); CfreeCgTypeId toy_type_resolved_cg(ToyParser* p, ToyTypeId id); ToyTypeId toy_type_pointee(ToyParser* p, ToyTypeId id); @@ -354,8 +352,7 @@ CfreeCgTypeId toy_emit_slice_index_lvalue(ToyParser* p, CfreeCgTypeId slice_ty, ToyTypeId* elem_toy_out); CfreeCgTypeId toy_emit_slice_value(ToyParser* p, CfreeCgTypeId base_ty, ToyTypeId base_toy_type, - CfreeCgTypeId start_ty, - CfreeCgTypeId end_ty, + CfreeCgTypeId start_ty, CfreeCgTypeId end_ty, ToyTypeId* slice_toy_out); int toy_record_field_index(ToyParser* p, CfreeCgTypeId record_ty, CfreeSym field_name, uint32_t* index_out, @@ -363,11 +360,9 @@ int toy_record_field_index(ToyParser* p, CfreeCgTypeId record_ty, int toy_add_named_type(ToyParser* p, CfreeSym name, CfreeCgTypeId type, ToyNamedTypeKind kind, CfreeCgTypeId base_type); int toy_set_named_type_fields(ToyParser* p, ToyNamedType* named, - const ToyRecordFieldInfo* fields, - size_t nfields); + const ToyRecordFieldInfo* fields, size_t nfields); int toy_set_named_type_enum_values(ToyParser* p, ToyNamedType* named, - const ToyEnumConst* values, - size_t nvalues); + const ToyEnumConst* values, size_t nvalues); ToyVar* toy_find_var(ToyParser* p, CfreeSym name); int toy_add_local(ToyParser* p, CfreeSym name, CfreeCgTypeId ty, @@ -377,8 +372,7 @@ int toy_add_local_typed(ToyParser* p, CfreeSym name, CfreeCgTypeId ty, int toy_add_static_local(ToyParser* p, CfreeSym name, CfreeCgTypeId ty, CfreeCgSym sym, int mutable); int toy_add_static_local_typed(ToyParser* p, CfreeSym name, CfreeCgTypeId ty, - ToyTypeId toy_type, CfreeCgSym sym, - int mutable); + ToyTypeId toy_type, CfreeCgSym sym, int mutable); ToyFn* toy_find_fn(ToyParser* p, CfreeSym name); ToyFn* toy_add_fn(ToyParser* p, CfreeSym name, CfreeCgSym sym, CfreeCgTypeId type, CfreeCgTypeId ret, @@ -393,8 +387,7 @@ ToyGlobal* toy_find_global(ToyParser* p, CfreeSym name); int toy_add_global(ToyParser* p, CfreeSym name, CfreeCgSym sym, CfreeCgTypeId type, int mutable); int toy_add_global_typed(ToyParser* p, CfreeSym name, CfreeCgSym sym, - CfreeCgTypeId type, ToyTypeId toy_type, - int mutable); + CfreeCgTypeId type, ToyTypeId toy_type, int mutable); ToyNamedType* toy_find_named_type(ToyParser* p, CfreeSym name); ToyNamedType* toy_find_named_type_by_type(ToyParser* p, CfreeCgTypeId type); ToyLabel* toy_find_label(ToyParser* p, CfreeSym name); diff --git a/lang/toy/lexer.c b/lang/toy/lexer.c @@ -161,8 +161,7 @@ ToyToken toy_lexer_next(ToyLexer* lex) { case '-': return toy_lexer_emit(lex, TOK_MINUS, start); case '.': - if (lex->cur + 1 < lex->end && lex->cur[0] == '.' && - lex->cur[1] == '.') { + if (lex->cur + 1 < lex->end && lex->cur[0] == '.' && lex->cur[1] == '.') { lex->cur += 2; return toy_lexer_emit(lex, TOK_DOTDOTDOT, start); } @@ -182,8 +181,8 @@ ToyToken toy_lexer_next(ToyLexer* lex) { v = v * 10 + (int64_t)(*lex->cur - '0'); lex->cur++; } - if (lex->cur < lex->end && *lex->cur == '.' && - lex->cur + 1 < lex->end && toy_is_digit(lex->cur[1])) { + if (lex->cur < lex->end && *lex->cur == '.' && lex->cur + 1 < lex->end && + toy_is_digit(lex->cur[1])) { is_float = 1; lex->cur++; while (lex->cur < lex->end && toy_is_digit(*lex->cur)) lex->cur++; diff --git a/lang/toy/literals.c b/lang/toy/literals.c @@ -1,7 +1,7 @@ -#include "internal.h" - #include <string.h> +#include "internal.h" + void toy_emit_int_bytes(ToyParser* p, uint64_t v, uint8_t* buf, size_t n) { size_t i; (void)p; @@ -32,7 +32,7 @@ int toy_parse_string_sym(ToyParser* p, CfreeSym* out, size_t* len_out) { } memcpy(buf, p->cur.text + 1, len); buf[len] = '\0'; - *out = cfree_sym_intern(p->c, (CfreeSlice){ .s = buf, .len = len }); + *out = cfree_sym_intern(p->c, (CfreeSlice){.s = buf, .len = len}); if (len_out) *len_out = len; toy_parser_advance(p); return 1; @@ -53,20 +53,24 @@ int toy_parse_string_bytes(ToyParser* p, uint8_t* out, size_t cap, uint8_t c = *cur++; if (c == '\\' && cur < end) { uint8_t esc = *cur++; - if (esc == '0') c = 0; - else if (esc == 'n') c = '\n'; - else if (esc == 't') c = '\t'; - else if (esc == '"' || esc == '\\') c = esc; + if (esc == '0') + c = 0; + else if (esc == 'n') + c = '\n'; + else if (esc == 't') + c = '\t'; + else if (esc == '"' || esc == '\\') + c = esc; else if (esc == 'x' && cur + 1 < end) { uint8_t hi = *cur++; uint8_t lo = *cur++; - uint8_t hv = (hi >= '0' && hi <= '9') ? (uint8_t)(hi - '0') - : (hi >= 'a' && hi <= 'f') ? (uint8_t)(hi - 'a' + 10) - : (hi >= 'A' && hi <= 'F') ? (uint8_t)(hi - 'A' + 10) + uint8_t hv = (hi >= '0' && hi <= '9') ? (uint8_t)(hi - '0') + : (hi >= 'a' && hi <= 'f') ? (uint8_t)(hi - 'a' + 10) + : (hi >= 'A' && hi <= 'F') ? (uint8_t)(hi - 'A' + 10) : 255; - uint8_t lv = (lo >= '0' && lo <= '9') ? (uint8_t)(lo - '0') - : (lo >= 'a' && lo <= 'f') ? (uint8_t)(lo - 'a' + 10) - : (lo >= 'A' && lo <= 'F') ? (uint8_t)(lo - 'A' + 10) + uint8_t lv = (lo >= '0' && lo <= '9') ? (uint8_t)(lo - '0') + : (lo >= 'a' && lo <= 'f') ? (uint8_t)(lo - 'a' + 10) + : (lo >= 'A' && lo <= 'F') ? (uint8_t)(lo - 'A' + 10) : 255; if (hv == 255 || lv == 255) { toy_error(p, p->cur.loc, "invalid hex escape"); diff --git a/lang/toy/parser.c b/lang/toy/parser.c @@ -1,11 +1,11 @@ -#include "internal.h" - #include <cfree/cg.h> #include <stddef.h> #include <stdint.h> #include <stdio.h> #include <string.h> +#include "internal.h" + /* Public CG API coverage goals for this frontend are tracked in * doc/toy-todo.md. Keep this file aligned with include/cfree/cg.h rather than * private CG implementation details. */ @@ -43,8 +43,7 @@ static void toy_push_local_indexed(ToyParser* p, CfreeCgLocal slot, static int toy_check_source_value(ToyParser* p, CfreeCgTypeId expected_cg, ToyTypeId expected_toy, - CfreeCgTypeId actual_cg, - ToyTypeId actual_toy, + CfreeCgTypeId actual_cg, ToyTypeId actual_toy, const char* message) { if (expected_toy != TOY_TYPE_NONE) { if (!toy_type_accepts_type(p, expected_toy, actual_toy)) { @@ -169,8 +168,9 @@ static int toy_parse_array_initializer(ToyParser* p, CfreeCgLocal slot, return 0; } if (expr_ty != elem_ty) cfree_cg_bitcast(p->cg, elem_ty); - cfree_cg_store(p->cg, toy_mem_access(p, elem_ty), - (CfreeCgEffAddr){0, (uint32_t)cfree_cg_type_size(p->c, elem_ty)}); + cfree_cg_store( + p->cg, toy_mem_access(p, elem_ty), + (CfreeCgEffAddr){0, (uint32_t)cfree_cg_type_size(p->c, elem_ty)}); index++; if (!toy_parser_match(p, TOK_COMMA)) break; } @@ -181,8 +181,9 @@ static int toy_parse_array_initializer(ToyParser* p, CfreeCgLocal slot, while (index < count) { toy_push_local_indexed(p, slot, index); cfree_cg_push_int(p->cg, 0, elem_ty); - cfree_cg_store(p->cg, toy_mem_access(p, elem_ty), - (CfreeCgEffAddr){0, (uint32_t)cfree_cg_type_size(p->c, elem_ty)}); + cfree_cg_store( + p->cg, toy_mem_access(p, elem_ty), + (CfreeCgEffAddr){0, (uint32_t)cfree_cg_type_size(p->c, elem_ty)}); index++; } return 1; @@ -229,10 +230,9 @@ static int toy_parse_record_initializer(ToyParser* p, CfreeCgLocal slot, expr_ty = toy_parse_expr(p); if (expr_ty == CFREE_CG_TYPE_NONE) return 0; { - ToyTypeId expected = - (named && field_index < named->nfields) - ? named->fields[field_index].toy_type - : TOY_TYPE_NONE; + ToyTypeId expected = (named && field_index < named->nfields) + ? named->fields[field_index].toy_type + : TOY_TYPE_NONE; if (!toy_check_source_value(p, field.type, expected, expr_ty, p->last_type, "tuple field type mismatch")) { @@ -268,23 +268,23 @@ static int toy_parse_record_initializer(ToyParser* p, CfreeCgLocal slot, toy_error(p, p->cur.loc, "expected ':' in record literal"); return 0; } - if (!toy_record_field_index(p, record_ty, field_name, &field_index, &field)) { + if (!toy_record_field_index(p, record_ty, field_name, &field_index, + &field)) { toy_error(p, p->cur.loc, "unknown record field"); return 0; } - if (cfree_cg_type_record_field(p->c, record_ty, field_index, NULL, &foff) != 0) + if (cfree_cg_type_record_field(p->c, record_ty, field_index, NULL, &foff) != + 0) return 0; cfree_cg_push_local(p->cg, slot); expr_ty = toy_parse_expr(p); if (expr_ty == CFREE_CG_TYPE_NONE) return 0; { - ToyTypeId expected = - (named && field_index < named->nfields) - ? named->fields[field_index].toy_type - : TOY_TYPE_NONE; + ToyTypeId expected = (named && field_index < named->nfields) + ? named->fields[field_index].toy_type + : TOY_TYPE_NONE; if (!toy_check_source_value(p, field.type, expected, expr_ty, - p->last_type, - "record field type mismatch")) { + p->last_type, "record field type mismatch")) { return 0; } } @@ -319,18 +319,17 @@ static int toy_parse_if_initializer(ToyParser* p, CfreeCgLocal slot, toy_error(p, p->cur.loc, "expected '{' in if expression"); return 0; } - if (!toy_parse_value_block_body_to_local(p, slot, result_ty, - result_toy_type)) return 0; + if (!toy_parse_value_block_body_to_local(p, slot, result_ty, result_toy_type)) + return 0; cfree_cg_if_else(p->cg, it); - if (!toy_parser_expect(p, TOK_ELSE) || - !toy_parser_expect(p, TOK_LBRACE)) { + if (!toy_parser_expect(p, TOK_ELSE) || !toy_parser_expect(p, TOK_LBRACE)) { toy_error(p, p->cur.loc, "expected else block in if expression"); return 0; } - if (!toy_parse_value_block_body_to_local(p, slot, result_ty, - result_toy_type)) return 0; + if (!toy_parse_value_block_body_to_local(p, slot, result_ty, result_toy_type)) + return 0; cfree_cg_if_end(p->cg, it); return 1; @@ -585,7 +584,8 @@ static int toy_parse_while_initializer_named(ToyParser* p, CfreeCgLocal slot, return 0; explicit_toy_type = p->last_type; if (!toy_check_source_value(p, result_ty, result_toy_type, explicit_ty, - explicit_toy_type, "while result type mismatch")) { + explicit_toy_type, + "while result type mismatch")) { return 0; } if (!toy_parser_reserve(p, (void**)&p->scopes, &p->cap_scopes, @@ -750,8 +750,7 @@ static int toy_parse_let_stmt(ToyParser* p) { toy_error(p, p->cur.loc, "failed to declare static local"); return 0; } - if (!toy_add_static_local_typed(p, name, ty, toy_ty, sym, is_var)) - return 0; + if (!toy_add_static_local_typed(p, name, ty, toy_ty, sym, is_var)) return 0; memset(&data_attrs, 0, sizeof data_attrs); data_attrs.flags |= CFREE_CG_DATADEF_FUNCTION_LOCAL; if (!is_var) data_attrs.flags |= CFREE_CG_DATADEF_READONLY; @@ -1128,9 +1127,8 @@ static int toy_parse_switch_stmt_named(ToyParser* p, CfreeSym label_name) { cfree_cg_push_local(p->cg, selector_slot); cfree_cg_load(p->cg, toy_mem_access(p, selector_ty), (CfreeCgEffAddr){0, 0}); sw.selector_type = selector_ty; - sw.default_label = default_arm_label != CFREE_CG_LABEL_NONE - ? default_arm_label - : end_label; + sw.default_label = + default_arm_label != CFREE_CG_LABEL_NONE ? default_arm_label : end_label; sw.cases = cases; sw.ncases = (uint32_t)ncases; sw.hint = hint; @@ -1148,9 +1146,9 @@ static int toy_parse_switch_stmt(ToyParser* p) { static int toy_add_goto_target(ToyParser* p, uint32_t* ntargets, CfreeCgLabel label) { - if (!toy_parser_reserve(p, (void**)&p->goto_targets, - &p->cap_goto_targets, (size_t)*ntargets + 1u, - sizeof *p->goto_targets, "goto targets")) { + if (!toy_parser_reserve(p, (void**)&p->goto_targets, &p->cap_goto_targets, + (size_t)*ntargets + 1u, sizeof *p->goto_targets, + "goto targets")) { return 0; } p->goto_targets[*ntargets] = label; @@ -1211,8 +1209,7 @@ static int toy_parse_goto_stmt(ToyParser* p) { toy_error(p, p->cur.loc, "unknown label in target list"); return 0; } - if (!toy_add_goto_target(p, &ntargets, label->label)) - return 0; + if (!toy_add_goto_target(p, &ntargets, label->label)) return 0; if (!toy_parser_match(p, TOK_COMMA)) break; } if (!toy_parser_expect(p, TOK_RPAREN)) { @@ -1222,8 +1219,7 @@ static int toy_parse_goto_stmt(ToyParser* p) { } if (ntargets == 0) { for (i = 0; i < p->nlabels; ++i) { - if (!toy_add_goto_target(p, &ntargets, p->labels[i].label)) - return 0; + if (!toy_add_goto_target(p, &ntargets, p->labels[i].label)) return 0; } } cfree_cg_computed_goto(p->cg, p->goto_targets, ntargets); @@ -1359,7 +1355,8 @@ static int toy_parse_return_stmt(ToyParser* p) { * (e.g. native fits varargs in the caller's incoming area; wasm cannot, * since its vararg buffer lives in the frame a sibling call tears down). */ if (!toy_parse_call_args(p, call_tok, fn_ty, fn ? fn->toy_params : NULL, - fn ? fn->nparams : 0, &nargs)) return 0; + fn ? fn->nparams : 0, &nargs)) + return 0; if (fn && !toy_type_accepts_type(p, p->cur_fn_ret_toy, fn->toy_ret)) { toy_error(p, p->cur.loc, "tail call signature mismatch"); return 0; @@ -1409,13 +1406,16 @@ static int toy_parse_return_stmt(ToyParser* p) { cfree_cg_local(p->cg, p->cur_fn_ret, toy_slot_attrs(0)); if (p->cur.kind == TOK_IF) { if (!toy_parse_if_initializer(p, slot, p->cur_fn_ret, - p->cur_fn_ret_toy)) return 0; + p->cur_fn_ret_toy)) + return 0; } else if (p->cur.kind == TOK_SWITCH) { if (!toy_parse_switch_initializer(p, slot, p->cur_fn_ret, - p->cur_fn_ret_toy)) return 0; + p->cur_fn_ret_toy)) + return 0; } else if (p->cur.kind == TOK_WHILE) { if (!toy_parse_while_initializer(p, slot, p->cur_fn_ret, - p->cur_fn_ret_toy)) return 0; + p->cur_fn_ret_toy)) + return 0; } else { toy_parser_advance(p); /* label */ if (!toy_parser_expect(p, TOK_COLON)) { @@ -1423,13 +1423,13 @@ static int toy_parse_return_stmt(ToyParser* p) { return 0; } if (!toy_parse_while_initializer_named(p, slot, p->cur_fn_ret, - p->cur_fn_ret_toy, - loop_label)) { + p->cur_fn_ret_toy, loop_label)) { return 0; } } cfree_cg_push_local(p->cg, slot); - cfree_cg_load(p->cg, toy_mem_access(p, p->cur_fn_ret), (CfreeCgEffAddr){0, 0}); + cfree_cg_load(p->cg, toy_mem_access(p, p->cur_fn_ret), + (CfreeCgEffAddr){0, 0}); cfree_cg_ret(p->cg); if (!toy_parser_expect(p, TOK_SEMI)) { toy_error(p, p->cur.loc, "expected ';' after return"); @@ -1500,8 +1500,7 @@ static int toy_parse_stmt(ToyParser* p) { if (p->cur.kind == TOK_LBRACE) return toy_parse_block(p); /* Assignment or expression statement */ - if (p->cur.kind == TOK_IDENT && - toy_lexer_peek(&p->lex).kind == TOK_COLON) { + if (p->cur.kind == TOK_IDENT && toy_lexer_peek(&p->lex).kind == TOK_COLON) { CfreeSym name = toy_tok_sym(p, p->cur); toy_parser_advance(p); /* ident */ toy_parser_advance(p); /* : */ @@ -1624,8 +1623,7 @@ static int toy_parse_stmt(ToyParser* p) { return 0; } /* TOS = `**T`; load to TOS = `*T`. */ - cfree_cg_load(p->cg, toy_mem_access(p, lhs_ty), - (CfreeCgEffAddr){0, 0}); + cfree_cg_load(p->cg, toy_mem_access(p, lhs_ty), (CfreeCgEffAddr){0, 0}); lhs_ty = cfree_cg_type_ptr_pointee(p->c, lhs_ty); lhs_toy_type = toy_type_pointee(p, lhs_toy_type); continue; @@ -1636,8 +1634,7 @@ static int toy_parse_stmt(ToyParser* p) { ToyNamedType* named; uint64_t foff = 0; if (cfree_cg_type_kind(p->c, lhs_ty) == CFREE_CG_TYPE_PTR && - cfree_cg_type_kind(p->c, - cfree_cg_type_ptr_pointee(p->c, lhs_ty)) == + cfree_cg_type_kind(p->c, cfree_cg_type_ptr_pointee(p->c, lhs_ty)) == CFREE_CG_TYPE_RECORD) { /* `p.field`: load the pointer value to address the record. */ cfree_cg_load(p->cg, toy_mem_access(p, lhs_ty), @@ -1675,7 +1672,8 @@ static int toy_parse_stmt(ToyParser* p) { toy_error(p, p->cur.loc, "unknown record field"); return 0; } - if (cfree_cg_type_record_field(p->c, lhs_ty, field_index, NULL, &foff) != 0) + if (cfree_cg_type_record_field(p->c, lhs_ty, field_index, NULL, + &foff) != 0) return 0; } lhs_slice_metadata = toy_type_is_slice(p, lhs_toy_type) && @@ -1684,8 +1682,7 @@ static int toy_parse_stmt(ToyParser* p) { lhs_toy_type = (named && field_index < named->nfields) ? named->fields[field_index].toy_type : TOY_TYPE_NONE; - toy_addr_offset(p, (int64_t)foff, - cfree_cg_type_ptr(p->c, lhs_ty, 0)); + toy_addr_offset(p, (int64_t)foff, cfree_cg_type_ptr(p->c, lhs_ty, 0)); continue; } break; @@ -1727,8 +1724,7 @@ static int toy_parse_stmt(ToyParser* p) { return 1; } - if (p->cur.kind == TOK_IDENT && - toy_lexer_peek(&p->lex).kind == TOK_EQ) { + if (p->cur.kind == TOK_IDENT && toy_lexer_peek(&p->lex).kind == TOK_EQ) { CfreeSym name = toy_tok_sym(p, p->cur); toy_parser_advance(p); /* ident */ toy_parser_advance(p); /* = */ @@ -1758,7 +1754,8 @@ static int toy_parse_stmt(ToyParser* p) { toy_push_var_lvalue(p, v); cfree_cg_swap(p->cg); if (expr_ty != v->type) cfree_cg_bitcast(p->cg, v->type); - cfree_cg_store(p->cg, toy_mem_access(p, v->type), (CfreeCgEffAddr){0, 0}); + cfree_cg_store(p->cg, toy_mem_access(p, v->type), + (CfreeCgEffAddr){0, 0}); } else { ToyGlobal* g = toy_find_global(p, name); if (!g) { @@ -1785,7 +1782,8 @@ static int toy_parse_stmt(ToyParser* p) { cfree_cg_push_symbol_addr(p->cg, g->sym, 0); cfree_cg_swap(p->cg); if (expr_ty != g->type) cfree_cg_bitcast(p->cg, g->type); - cfree_cg_store(p->cg, toy_mem_access(p, g->type), (CfreeCgEffAddr){0, 0}); + cfree_cg_store(p->cg, toy_mem_access(p, g->type), + (CfreeCgEffAddr){0, 0}); } } if (!toy_parser_expect(p, TOK_SEMI)) { diff --git a/lang/toy/parser_core.c b/lang/toy/parser_core.c @@ -1,10 +1,10 @@ -#include "internal.h" - #include <cfree/source.h> #include <stdarg.h> #include <stdio.h> #include <string.h> +#include "internal.h" + CfreeCgTypeId toy_builtin_type(ToyParser* p, CfreeCgBuiltinType ty) { return p->types.id[ty]; } @@ -44,8 +44,7 @@ static uint32_t toy_source_file_id(CfreeCompiler* c, const char* name) { } void toy_parser_init(ToyParser* p, CfreeCompiler* c, CfreeCg* cg, - const uint8_t* data, size_t len, - const char* input_name) { + const uint8_t* data, size_t len, const char* input_name) { memset(p, 0, sizeof *p); p->file_id = toy_source_file_id(c, input_name); p->input_name = input_name; @@ -97,8 +96,7 @@ void toy_parser_init(ToyParser* p, CfreeCompiler* c, CfreeCg* cg, } void toy_parser_reinit(ToyParser* p, CfreeCompiler* c, CfreeCg* cg, - const uint8_t* data, size_t len, - const char* input_name, + const uint8_t* data, size_t len, const char* input_name, CfreeFrontendInputKind input_kind) { p->file_id = toy_source_file_id(c, input_name); p->input_name = input_name; @@ -274,7 +272,7 @@ CfreeSym toy_tok_sym(ToyParser* p, ToyToken tok) { } memcpy(buf, tok.text, tok.text_len); buf[tok.text_len] = '\0'; - return cfree_sym_intern(p->c, (CfreeSlice){ .s = buf, .len = tok.text_len }); + return cfree_sym_intern(p->c, (CfreeSlice){.s = buf, .len = tok.text_len}); } int toy_sym_is(ToyParser* p, CfreeSym sym, const char* name) { @@ -317,6 +315,4 @@ int toy_skip_attr_list_ex(ToyParser* p, int* has_static) { return 1; } -int toy_skip_attr_list(ToyParser* p) { - return toy_skip_attr_list_ex(p, NULL); -} +int toy_skip_attr_list(ToyParser* p) { return toy_skip_attr_list_ex(p, NULL); } diff --git a/lang/toy/symbols.c b/lang/toy/symbols.c @@ -95,8 +95,7 @@ ToyFn* toy_add_fn_typed(ToyParser* p, CfreeSym name, CfreeCgSym sym, p, nparams, sizeof *fn->toy_params, "function parameters"); if (!fn->params || !fn->toy_params) { toy_parser_free_mem(p, fn->params, nparams * sizeof *fn->params); - toy_parser_free_mem(p, fn->toy_params, - nparams * sizeof *fn->toy_params); + toy_parser_free_mem(p, fn->toy_params, nparams * sizeof *fn->toy_params); fn->params = NULL; fn->toy_params = NULL; return NULL; @@ -113,10 +112,9 @@ ToyFn* toy_add_fn_typed(ToyParser* p, CfreeSym name, CfreeCgSym sym, fn->variadic = variadic; for (i = 0; i < nparams; ++i) { fn->params[i] = params[i]; - fn->toy_params[i] = - (toy_params && toy_params[i] != TOY_TYPE_NONE) - ? toy_params[i] - : toy_type_from_cg(p, params[i]); + fn->toy_params[i] = (toy_params && toy_params[i] != TOY_TYPE_NONE) + ? toy_params[i] + : toy_type_from_cg(p, params[i]); } p->nfns++; return fn; @@ -137,8 +135,7 @@ int toy_add_global(ToyParser* p, CfreeSym name, CfreeCgSym sym, } int toy_add_global_typed(ToyParser* p, CfreeSym name, CfreeCgSym sym, - CfreeCgTypeId type, ToyTypeId toy_type, - int mutable) { + CfreeCgTypeId type, ToyTypeId toy_type, int mutable) { if (!toy_parser_reserve(p, (void**)&p->globals, &p->cap_globals, p->nglobals + 1u, sizeof *p->globals, "globals")) { return 0; @@ -185,8 +182,7 @@ ToyScope* toy_find_scope(ToyParser* p, CfreeSym name) { ToyScope* toy_find_innermost_loop_scope(ToyParser* p) { size_t i; for (i = p->nscopes; i > 0; --i) { - if (p->scopes[i - 1].kind == TOY_SCOPE_LOOP) - return &p->scopes[i - 1]; + if (p->scopes[i - 1].kind == TOY_SCOPE_LOOP) return &p->scopes[i - 1]; } return NULL; } @@ -222,7 +218,8 @@ void toy_push_var_addr(ToyParser* p, const ToyVar* v) { * `cfree_cg_push_symbol_addr` (or `cfree_cg_addr` after `push_local`). */ /* TOS: [base_ptr]. After: [base_ptr + offset] as `result_ptr_ty`. */ -void toy_addr_offset(ToyParser* p, int64_t offset, CfreeCgTypeId result_ptr_ty) { +void toy_addr_offset(ToyParser* p, int64_t offset, + CfreeCgTypeId result_ptr_ty) { if (offset != 0) { cfree_cg_ptr_to_int(p->cg, p->int_type); cfree_cg_push_int(p->cg, (uint64_t)offset, p->int_type); diff --git a/lang/toy/types.c b/lang/toy/types.c @@ -1,7 +1,7 @@ -#include "internal.h" - #include <string.h> +#include "internal.h" + static ToyType* toy_type_slot(ToyParser* p, ToyTypeId id) { if (id == TOY_TYPE_NONE || id > p->type_table.ntypes) return NULL; return &p->type_table.types[id - 1u]; @@ -11,12 +11,12 @@ static ToyTypeId toy_type_find(ToyParser* p, const ToyType* key) { size_t i; for (i = 0; i < p->type_table.ntypes; ++i) { ToyType* ty = &p->type_table.types[i]; - if (ty->kind == key->kind && ty->cg == key->cg && - ty->name == key->name && ty->base == key->base && - ty->elem == key->elem && ty->pointee == key->pointee && - ty->ret == key->ret && ty->count == key->count && - ty->address_space == key->address_space && ty->quals == key->quals && - ty->nparams == key->nparams && ty->variadic == key->variadic) { + if (ty->kind == key->kind && ty->cg == key->cg && ty->name == key->name && + ty->base == key->base && ty->elem == key->elem && + ty->pointee == key->pointee && ty->ret == key->ret && + ty->count == key->count && ty->address_space == key->address_space && + ty->quals == key->quals && ty->nparams == key->nparams && + ty->variadic == key->variadic) { size_t j; for (j = 0; j < key->nparams; ++j) { if (ty->params[j] != key->params[j]) break; @@ -31,8 +31,7 @@ static ToyTypeId toy_type_add(ToyParser* p, const ToyType* type) { ToyTypeId existing = toy_type_find(p, type); if (existing != TOY_TYPE_NONE) return existing; if (!toy_parser_reserve(p, (void**)&p->type_table.types, - &p->type_table.cap_types, - p->type_table.ntypes + 1u, + &p->type_table.cap_types, p->type_table.ntypes + 1u, sizeof *p->type_table.types, "toy types")) { return TOY_TYPE_NONE; } @@ -77,7 +76,7 @@ CfreeCgTypeId toy_parse_type(ToyParser* p) { (p->cur.text_len == 8 && memcmp(p->cur.text, "restrict", 8) == 0))) { int is_restrict = p->cur.text_len == 8 && memcmp(p->cur.text, "restrict", 8) == 0; - uint32_t qual = is_restrict ? TOY_TYPE_QUAL_RESTRICT + uint32_t qual = is_restrict ? TOY_TYPE_QUAL_RESTRICT : (p->cur.text_len == 5) ? TOY_TYPE_QUAL_CONST : TOY_TYPE_QUAL_VOLATILE; CfreeCgTypeId qualified_ty; @@ -121,18 +120,16 @@ CfreeCgTypeId toy_parse_type(ToyParser* p) { if (!toy_parser_reserve(p, (void**)¶m_types, &cap_param_types, nparams + 1u, sizeof *param_types, "function type parameters") || - !toy_parser_reserve(p, (void**)¶m_toy_types, - &cap_param_toy_types, nparams + 1u, - sizeof *param_toy_types, - "function type source parameters") || + !toy_parser_reserve( + p, (void**)¶m_toy_types, &cap_param_toy_types, nparams + 1u, + sizeof *param_toy_types, "function type source parameters") || !toy_parser_reserve(p, (void**)&sig_params, &cap_sig_params, nparams + 1u, sizeof *sig_params, "function type signature parameters")) { goto fn_done; } param_types[nparams] = toy_parse_type(p); - if (param_types[nparams] == CFREE_CG_TYPE_NONE) - goto fn_done; + if (param_types[nparams] == CFREE_CG_TYPE_NONE) goto fn_done; param_toy_types[nparams] = p->last_type; nparams++; if (p->cur.kind == TOK_COMMA) { @@ -173,9 +170,8 @@ CfreeCgTypeId toy_parse_type(ToyParser* p) { toy_type_register_func(p, fn_ty, ret_toy_type, param_toy_types, nparams, variadic)); } -fn_done: - toy_parser_free_mem(p, param_types, - cap_param_types * sizeof *param_types); + fn_done: + toy_parser_free_mem(p, param_types, cap_param_types * sizeof *param_types); toy_parser_free_mem(p, param_toy_types, cap_param_toy_types * sizeof *param_toy_types); toy_parser_free_mem(p, sig_params, cap_sig_params * sizeof *sig_params); @@ -191,11 +187,9 @@ fn_done: if (elem == CFREE_CG_TYPE_NONE) return CFREE_CG_TYPE_NONE; elem_toy_type = p->last_type; slice_toy_type = toy_type_register_slice(p, elem, elem_toy_type); - return toy_type_finish(p, toy_type_cg(p, slice_toy_type), - slice_toy_type); + return toy_type_finish(p, toy_type_cg(p, slice_toy_type), slice_toy_type); } - if (p->cur.kind != TOK_NUMBER || p->cur.is_float || - p->cur.int_value < 0) { + if (p->cur.kind != TOK_NUMBER || p->cur.is_float || p->cur.int_value < 0) { toy_error(p, p->cur.loc, "expected array count"); return CFREE_CG_TYPE_NONE; } @@ -210,9 +204,9 @@ fn_done: elem_toy_type = p->last_type; { CfreeCgTypeId array_ty = cfree_cg_type_array(p->c, elem, count); - return toy_type_finish(p, array_ty, - toy_type_register_array(p, array_ty, - elem_toy_type, count)); + return toy_type_finish( + p, array_ty, + toy_type_register_array(p, array_ty, elem_toy_type, count)); } } if (toy_parser_match(p, TOK_RECORD)) { @@ -239,15 +233,13 @@ fn_done: } fields[nfields].name = toy_tok_sym(p, p->cur); toy_parser_advance(p); - if (!toy_parse_field_attr_list(p, &fields[nfields])) - goto record_done; + if (!toy_parse_field_attr_list(p, &fields[nfields])) goto record_done; if (!toy_parser_expect(p, TOK_COLON)) { toy_error(p, p->cur.loc, "expected ':' after record field name"); goto record_done; } fields[nfields].type = toy_parse_type(p); - if (fields[nfields].type == CFREE_CG_TYPE_NONE) - goto record_done; + if (fields[nfields].type == CFREE_CG_TYPE_NONE) goto record_done; nfields++; if (!toy_parser_match(p, TOK_COMMA)) break; } @@ -277,7 +269,7 @@ fn_done: cfree_cg_type_record(p->c, 0, fields, (uint32_t)nfields); result = toy_type_finish(p, record_ty, toy_type_from_cg(p, record_ty)); } -record_done: + record_done: toy_parser_free_mem(p, fields, cap_fields * sizeof *fields); return result; } @@ -346,8 +338,9 @@ record_done: } if (ty != CFREE_CG_TYPE_NONE) { ToyTypeId toy_type = toy_type_from_cg(p, ty); - ToyNamedType* named = - (p->cur.kind == TOK_IDENT) ? toy_find_named_type(p, toy_tok_sym(p, p->cur)) : NULL; + ToyNamedType* named = (p->cur.kind == TOK_IDENT) + ? toy_find_named_type(p, toy_tok_sym(p, p->cur)) + : NULL; if (named && named->type == ty && named->toy_type != TOY_TYPE_NONE) toy_type = named->toy_type; toy_parser_advance(p); @@ -455,10 +448,9 @@ ToyTypeId toy_type_from_cg(ToyParser* p, CfreeCgTypeId cg) { if (cg == CFREE_CG_TYPE_NONE) return TOY_TYPE_NONE; for (i = 0; i < p->type_table.ntypes; ++i) { ToyType* existing = &p->type_table.types[i]; - if (existing->cg == cg && - (existing->kind == TOY_TYPE_NOMINAL_RECORD || - existing->kind == TOY_TYPE_TUPLE_RECORD || - existing->kind == TOY_TYPE_ENUM)) { + if (existing->cg == cg && (existing->kind == TOY_TYPE_NOMINAL_RECORD || + existing->kind == TOY_TYPE_TUPLE_RECORD || + existing->kind == TOY_TYPE_ENUM)) { return (ToyTypeId)(i + 1u); } if (existing->cg == cg && existing->name == 0 && @@ -510,8 +502,8 @@ ToyTypeId toy_type_from_cg(ToyParser* p, CfreeCgTypeId cg) { return toy_type_add(p, &type); } -ToyTypeId toy_type_register_alias(ToyParser* p, CfreeSym name, - CfreeCgTypeId cg, CfreeCgTypeId base) { +ToyTypeId toy_type_register_alias(ToyParser* p, CfreeSym name, CfreeCgTypeId cg, + CfreeCgTypeId base) { ToyType type; memset(&type, 0, sizeof type); type.kind = TOY_TYPE_ALIAS; @@ -536,8 +528,8 @@ ToyTypeId toy_type_register_named_record(ToyParser* p, CfreeSym name, return toy_type_register(p, kind, cg, name, TOY_TYPE_NONE); } -ToyTypeId toy_type_register_enum(ToyParser* p, CfreeSym name, - CfreeCgTypeId cg, CfreeCgTypeId base) { +ToyTypeId toy_type_register_enum(ToyParser* p, CfreeSym name, CfreeCgTypeId cg, + CfreeCgTypeId base) { ToyType type; memset(&type, 0, sizeof type); type.kind = TOY_TYPE_ENUM; @@ -595,9 +587,9 @@ ToyTypeId toy_type_register_slice(ToyParser* p, CfreeCgTypeId elem_cg, return toy_type_add(p, &type); } -ToyTypeId toy_type_register_func(ToyParser* p, CfreeCgTypeId cg, - ToyTypeId ret, const ToyTypeId* params, - size_t nparams, int variadic) { +ToyTypeId toy_type_register_func(ToyParser* p, CfreeCgTypeId cg, ToyTypeId ret, + const ToyTypeId* params, size_t nparams, + int variadic) { ToyType type; ToyTypeId id; memset(&type, 0, sizeof type); @@ -608,8 +600,7 @@ ToyTypeId toy_type_register_func(ToyParser* p, CfreeCgTypeId cg, type.nparams = nparams; type.variadic = variadic; if (nparams) { - type.params = (ToyTypeId*)toy_parser_zalloc(p, nparams, - sizeof *type.params, + type.params = (ToyTypeId*)toy_parser_zalloc(p, nparams, sizeof *type.params, "function type parameters"); if (!type.params) return TOY_TYPE_NONE; memcpy(type.params, params, nparams * sizeof *type.params); @@ -776,8 +767,8 @@ int toy_add_named_type(ToyParser* p, CfreeSym name, CfreeCgTypeId type, else if (kind == TOY_NAMED_ENUM) toy_type = toy_type_register_enum(p, name, type, base_type); else - toy_type = toy_type_register_named_record( - p, name, type, kind == TOY_NAMED_TUPLE); + toy_type = + toy_type_register_named_record(p, name, type, kind == TOY_NAMED_TUPLE); if (toy_type == TOY_TYPE_NONE && type != CFREE_CG_TYPE_NONE) return 0; if (existing && existing->type == CFREE_CG_TYPE_NONE) { existing->type = type; @@ -786,9 +777,8 @@ int toy_add_named_type(ToyParser* p, CfreeSym name, CfreeCgTypeId type, existing->base_type = base_type; return 1; } - if (!toy_parser_reserve(p, (void**)&p->type_table.named, - &p->type_table.cap, p->type_table.count + 1u, - sizeof *p->type_table.named, + if (!toy_parser_reserve(p, (void**)&p->type_table.named, &p->type_table.cap, + p->type_table.count + 1u, sizeof *p->type_table.named, "named types")) { return 0; } @@ -810,23 +800,20 @@ int toy_set_named_type_fields(ToyParser* p, ToyNamedType* named, nfields, sizeof *named->fields, "record fields")) { return 0; } - if (nfields) - memcpy(named->fields, fields, sizeof *named->fields * nfields); + if (nfields) memcpy(named->fields, fields, sizeof *named->fields * nfields); named->nfields = nfields; return 1; } int toy_set_named_type_enum_values(ToyParser* p, ToyNamedType* named, - const ToyEnumConst* values, - size_t nvalues) { + const ToyEnumConst* values, size_t nvalues) { if (!named) return 0; if (!toy_parser_reserve(p, (void**)&named->enum_values, &named->cap_enum_values, nvalues, sizeof *named->enum_values, "enum values")) { return 0; } - if (nvalues) - memcpy(named->enum_values, values, sizeof values[0] * nvalues); + if (nvalues) memcpy(named->enum_values, values, sizeof values[0] * nvalues); named->nenum_values = nvalues; return 1; } diff --git a/lang/wasm/cg.c b/lang/wasm/cg.c @@ -1,7 +1,6 @@ -#include "wasm/wasm.h" - #include "core/arena.h" #include "core/heap.h" +#include "wasm/wasm.h" static CfreeCgTypeId wasm_cg_type(CfreeCompiler* c, CfreeCgBuiltinTypes b, WasmValType vt) { @@ -273,9 +272,8 @@ static void wasm_cg_build_runtime(CfreeCompiler* c, CfreeCgBuiltinTypes b, * func_ref entry per func) + nglobals + 2*ntables + ndata + nelems. * Allocate the upper bound from the arena so nfields can grow with the * module. */ - uint32_t instance_cap = m->nmemories + m->nfuncs + m->nfuncs + - m->nglobals + 2u * m->ntables + m->ndata + - 2u * m->nelems; + uint32_t instance_cap = m->nmemories + m->nfuncs + m->nfuncs + m->nglobals + + 2u * m->ntables + m->ndata + 2u * m->nelems; CfreeCgField* instance_fields = instance_cap ? arena_zarray(arena, CfreeCgField, instance_cap) : NULL; uint32_t nfields = 0; @@ -316,7 +314,8 @@ static void wasm_cg_build_runtime(CfreeCompiler* c, CfreeCgBuiltinTypes b, memory_fields[3].name = cfree_sym_intern(c, CFREE_SLICE_LIT("flags")); memory_fields[3].type = b.id[CFREE_CG_BUILTIN_I32]; rt->memory_ty = cfree_cg_type_record( - c, cfree_sym_intern(c, CFREE_SLICE_LIT("CfreeWasmMemory")), memory_fields, 4); + c, cfree_sym_intern(c, CFREE_SLICE_LIT("CfreeWasmMemory")), memory_fields, + 4); rt->memory_data_offset = wasm_cg_field_offset(c, rt->memory_ty, 0); rt->memory_pages_offset = wasm_cg_field_offset(c, rt->memory_ty, 1); rt->memory_max_pages_offset = wasm_cg_field_offset(c, rt->memory_ty, 2); @@ -329,13 +328,15 @@ static void wasm_cg_build_runtime(CfreeCompiler* c, CfreeCgBuiltinTypes b, func_import_fields[0].name = cfree_sym_intern(c, CFREE_SLICE_LIT("fn")); func_import_fields[0].type = rt->void_ptr_ty; rt->func_import_ty = cfree_cg_type_record( - c, cfree_sym_intern(c, CFREE_SLICE_LIT("CfreeWasmFuncImport")), func_import_fields, 1); + c, cfree_sym_intern(c, CFREE_SLICE_LIT("CfreeWasmFuncImport")), + func_import_fields, 1); rt->func_import_fn_offset = wasm_cg_field_offset(c, rt->func_import_ty, 0); memset(global_import_fields, 0, sizeof global_import_fields); global_import_fields[0].name = cfree_sym_intern(c, CFREE_SLICE_LIT("addr")); global_import_fields[0].type = rt->void_ptr_ty; rt->global_import_ty = cfree_cg_type_record( - c, cfree_sym_intern(c, CFREE_SLICE_LIT("CfreeWasmGlobalImport")), global_import_fields, 1); + c, cfree_sym_intern(c, CFREE_SLICE_LIT("CfreeWasmGlobalImport")), + global_import_fields, 1); rt->global_import_addr_offset = wasm_cg_field_offset(c, rt->global_import_ty, 0); memset(table_entry_fields, 0, sizeof table_entry_fields); @@ -344,7 +345,8 @@ static void wasm_cg_build_runtime(CfreeCompiler* c, CfreeCgBuiltinTypes b, table_entry_fields[1].name = cfree_sym_intern(c, CFREE_SLICE_LIT("typeidx")); table_entry_fields[1].type = b.id[CFREE_CG_BUILTIN_I32]; rt->table_entry_ty = cfree_cg_type_record( - c, cfree_sym_intern(c, CFREE_SLICE_LIT("CfreeWasmTableEntry")), table_entry_fields, 2); + c, cfree_sym_intern(c, CFREE_SLICE_LIT("CfreeWasmTableEntry")), + table_entry_fields, 2); rt->table_entry_ptr_ty = cfree_cg_type_ptr(c, rt->table_entry_ty, 0); rt->table_entry_fn_offset = wasm_cg_field_offset(c, rt->table_entry_ty, 0); rt->table_entry_typeidx_offset = @@ -359,8 +361,9 @@ static void wasm_cg_build_runtime(CfreeCompiler* c, CfreeCgBuiltinTypes b, table_fields[1].type = b.id[CFREE_CG_BUILTIN_I32]; table_fields[2].name = cfree_sym_intern(c, CFREE_SLICE_LIT("max")); table_fields[2].type = b.id[CFREE_CG_BUILTIN_I32]; - rt->table_ty = cfree_cg_type_record(c, cfree_sym_intern(c, CFREE_SLICE_LIT("CfreeWasmTable")), - table_fields, 3); + rt->table_ty = cfree_cg_type_record( + c, cfree_sym_intern(c, CFREE_SLICE_LIT("CfreeWasmTable")), table_fields, + 3); rt->table_entries_ptr_offset = wasm_cg_field_offset(c, rt->table_ty, 0); rt->table_len_offset = wasm_cg_field_offset(c, rt->table_ty, 1); rt->table_max_offset = wasm_cg_field_offset(c, rt->table_ty, 2); @@ -472,7 +475,8 @@ static void wasm_cg_build_runtime(CfreeCompiler* c, CfreeCgBuiltinTypes b, nfields++; } rt->instance_ty = cfree_cg_type_record( - c, cfree_sym_intern(c, CFREE_SLICE_LIT("CfreeWasmInstance")), instance_fields, nfields); + c, cfree_sym_intern(c, CFREE_SLICE_LIT("CfreeWasmInstance")), + instance_fields, nfields); rt->instance_ptr_ty = cfree_cg_type_ptr(c, rt->instance_ty, 0); for (uint32_t i = 0; i < m->nmemories; ++i) rt->memory_offset[i] = @@ -530,8 +534,7 @@ static void wasm_cg_push_memory_data_ptr(CfreeCg* cg, const WasmCgRuntime* rt, CfreeCgLocal instance_local, uint32_t memidx) { CfreeCgEffAddr ea; - ea.offset = - (int64_t)(rt->memory_offset[memidx] + rt->memory_data_offset); + ea.offset = (int64_t)(rt->memory_offset[memidx] + rt->memory_data_offset); ea.scale = 0; wasm_cg_push_instance_ptr(cg, rt, instance_local); cfree_cg_load(cg, wasm_cg_mem_type(rt->i8_ptr_ty), ea); @@ -551,8 +554,8 @@ static void wasm_cg_push_import_func_ptr(CfreeCg* cg, const WasmCgRuntime* rt, CfreeCgLocal instance_local, uint32_t func_index) { CfreeCgEffAddr ea; - ea.offset = (int64_t)(rt->func_import_offset[func_index] + - rt->func_import_fn_offset); + ea.offset = + (int64_t)(rt->func_import_offset[func_index] + rt->func_import_fn_offset); ea.scale = 0; wasm_cg_push_instance_ptr(cg, rt, instance_local); cfree_cg_load(cg, wasm_cg_mem_type(rt->void_ptr_ty), ea); @@ -626,8 +629,8 @@ static void wasm_cg_push_table_entry_ptr(CfreeCg* cg, CfreeCgBuiltinTypes b, CfreeCgEffAddr ea_idx = {0, 0}; CfreeCgTypeId i64_ty = b.id[CFREE_CG_BUILTIN_I64]; /* Load entries pointer from instance->tables[i].entries. */ - ea.offset = (int64_t)(rt->table_offset[table_index] + - rt->table_entries_ptr_offset); + ea.offset = + (int64_t)(rt->table_offset[table_index] + rt->table_entries_ptr_offset); ea.scale = 0; wasm_cg_push_instance_ptr(cg, rt, instance_local); cfree_cg_load(cg, wasm_cg_mem_type(rt->table_entry_ptr_ty), ea); @@ -1126,7 +1129,8 @@ static void wasm_cg_emit_host_import_metadata(CfreeCompiler* c, CfreeCg* cg, uint32_t slot_offset; } WasmImportEmit; WasmImportEmit* descs = arena_zarray(arena, WasmImportEmit, nimports); - uint32_t* type_remap = arena_zarray(arena, uint32_t, m->ntypes ? m->ntypes : 1u); + uint32_t* type_remap = + arena_zarray(arena, uint32_t, m->ntypes ? m->ntypes : 1u); uint32_t* local_to_module = arena_zarray(arena, uint32_t, nimports); uint32_t ntypes = 0; uint32_t d = 0; @@ -1146,14 +1150,13 @@ static void wasm_cg_emit_host_import_metadata(CfreeCompiler* c, CfreeCg* cg, local_to_module[ntypes] = module_typeidx; ntypes++; } - descs[d].module_sym = wasm_cg_intern_cstr( - cg, b, f->import_module ? f->import_module : ""); - descs[d].field_sym = wasm_cg_intern_cstr( - cg, b, f->import_name ? f->import_name : ""); + descs[d].module_sym = + wasm_cg_intern_cstr(cg, b, f->import_module ? f->import_module : ""); + descs[d].field_sym = + wasm_cg_intern_cstr(cg, b, f->import_name ? f->import_name : ""); descs[d].local_typeidx = type_remap[module_typeidx]; - if (cfree_cg_type_record_field(c, rt->instance_ty, - rt->func_import_field[i], NULL, - &slot_off) != CFREE_OK) { + if (cfree_cg_type_record_field(c, rt->instance_ty, rt->func_import_field[i], + NULL, &slot_off) != CFREE_OK) { wasm_error(c, f->loc, "wasm: failed to query import slot offset"); return; } @@ -1177,24 +1180,24 @@ static void wasm_cg_emit_host_import_metadata(CfreeCompiler* c, CfreeCg* cg, c, u8_ty, (uint64_t)type_desc_size * (ntypes ? ntypes : 1u)); for (uint32_t k = 0; k < ntypes; ++k) { const WasmFuncType* t = &m->types[local_to_module[k]]; - uint8_t* pbuf = t->nparams ? arena_array(arena, uint8_t, t->nparams) - : NULL; - uint8_t* rbuf = t->nresults ? arena_array(arena, uint8_t, t->nresults) - : NULL; + uint8_t* pbuf = + t->nparams ? arena_array(arena, uint8_t, t->nparams) : NULL; + uint8_t* rbuf = + t->nresults ? arena_array(arena, uint8_t, t->nresults) : NULL; for (uint32_t p = 0; p < t->nparams; ++p) pbuf[p] = (uint8_t)t->params[p]; for (uint32_t r = 0; r < t->nresults; ++r) rbuf[r] = (uint8_t)t->results[r]; param_syms[k] = t->nparams ? cfree_cg_const_data(cg, pbuf, t->nparams, 1, u8_ty) : (CfreeCgSym)0; - result_syms[k] = t->nresults - ? cfree_cg_const_data(cg, rbuf, t->nresults, 1, u8_ty) - : (CfreeCgSym)0; + result_syms[k] = + t->nresults ? cfree_cg_const_data(cg, rbuf, t->nresults, 1, u8_ty) + : (CfreeCgSym)0; } memset(&decl, 0, sizeof decl); decl.kind = CFREE_CG_DECL_OBJECT; - decl.linkage_name = - cfree_cg_c_linkage_name(c, cfree_sym_intern(c, CFREE_SLICE_LIT("__cfree_wasm_types"))); + decl.linkage_name = cfree_cg_c_linkage_name( + c, cfree_sym_intern(c, CFREE_SLICE_LIT("__cfree_wasm_types"))); decl.display_name = decl.linkage_name; decl.type = types_array_ty; decl.sym.bind = CFREE_SB_GLOBAL; @@ -1229,12 +1232,12 @@ static void wasm_cg_emit_host_import_metadata(CfreeCompiler* c, CfreeCg* cg, /* __cfree_wasm_imports: array of CfreeWasmImportDesc. */ { - CfreeCgTypeId imports_array_ty = cfree_cg_type_array( - c, u8_ty, (uint64_t)desc_size * nimports); + CfreeCgTypeId imports_array_ty = + cfree_cg_type_array(c, u8_ty, (uint64_t)desc_size * nimports); memset(&decl, 0, sizeof decl); decl.kind = CFREE_CG_DECL_OBJECT; - decl.linkage_name = - cfree_cg_c_linkage_name(c, cfree_sym_intern(c, CFREE_SLICE_LIT("__cfree_wasm_imports"))); + decl.linkage_name = cfree_cg_c_linkage_name( + c, cfree_sym_intern(c, CFREE_SLICE_LIT("__cfree_wasm_imports"))); decl.display_name = decl.linkage_name; decl.type = imports_array_ty; decl.sym.bind = CFREE_SB_GLOBAL; @@ -1337,9 +1340,11 @@ static void wasm_cg_emit_byte_copy_loop(CfreeCg* cg, CfreeCgBuiltinTypes b, cfree_cg_push_local(cg, src_base_local); cfree_cg_load(cg, ptr_mem, wasm_cg_ea0()); cfree_cg_int_cmp(cg, CFREE_CG_INT_EQ); - cfree_cg_store(cg, wasm_cg_mem_type(b.id[CFREE_CG_BUILTIN_I32]), wasm_cg_ea0()); + cfree_cg_store(cg, wasm_cg_mem_type(b.id[CFREE_CG_BUILTIN_I32]), + wasm_cg_ea0()); cfree_cg_push_local(cg, dir); - cfree_cg_load(cg, wasm_cg_mem_type(b.id[CFREE_CG_BUILTIN_I32]), wasm_cg_ea0()); + cfree_cg_load(cg, wasm_cg_mem_type(b.id[CFREE_CG_BUILTIN_I32]), + wasm_cg_ea0()); cfree_cg_branch_false(cg, forward); cfree_cg_push_local(cg, dst_addr_local); cfree_cg_load(cg, i64_mem, wasm_cg_ea0()); @@ -1482,14 +1487,11 @@ static void wasm_cg_emit_byte_fill_loop(CfreeCg* cg, CfreeCgBuiltinTypes b, } /* Like wasm_cg_emit_byte_copy_loop but for table entries (struct-sized). */ -static void wasm_cg_emit_table_copy_loop(CfreeCompiler* c, CfreeCg* cg, - CfreeCgBuiltinTypes b, - const WasmCgRuntime* rt, - CfreeCgLocal dst_base_local, - CfreeCgLocal src_base_local, - CfreeCgLocal dst_idx_local, - CfreeCgLocal src_idx_local, - CfreeCgLocal n_local) { +static void wasm_cg_emit_table_copy_loop( + CfreeCompiler* c, CfreeCg* cg, CfreeCgBuiltinTypes b, + const WasmCgRuntime* rt, CfreeCgLocal dst_base_local, + CfreeCgLocal src_base_local, CfreeCgLocal dst_idx_local, + CfreeCgLocal src_idx_local, CfreeCgLocal n_local) { CfreeCgMemAccess i64_mem = wasm_cg_mem_type(b.id[CFREE_CG_BUILTIN_I64]); CfreeCgMemAccess ptr_mem = wasm_cg_mem_type(rt->table_entry_ptr_ty); CfreeCgMemAccess fn_mem = wasm_cg_mem_type(rt->void_ptr_ty); @@ -1666,8 +1668,8 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, uint32_t i, j; arena_init(&arena, (Heap*)cfree_compiler_context(c)->heap, 8192); if (!cg) wasm_error(c, wasm_loc(0, 0), "wasm: failed to initialize codegen"); - CfreeCgSym* syms = m->nfuncs ? arena_zarray(&arena, CfreeCgSym, m->nfuncs) - : NULL; + CfreeCgSym* syms = + m->nfuncs ? arena_zarray(&arena, CfreeCgSym, m->nfuncs) : NULL; CfreeCgTypeId* func_types = m->nfuncs ? arena_zarray(&arena, CfreeCgTypeId, m->nfuncs) : NULL; wasm_cg_build_runtime(c, b, m, &rt, &arena); @@ -1681,7 +1683,8 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, if (!rt.trap_func_ty) wasm_error(c, wasm_loc(0, 0), "wasm: failed to create trap type"); for (uint32_t k = 0; k < WASM_TRAP_COUNT; ++k) { - CfreeSym source_name = cfree_sym_intern(c, cfree_slice_cstr(wasm_trap_name(k))); + CfreeSym source_name = + cfree_sym_intern(c, cfree_slice_cstr(wasm_trap_name(k))); memset(&decl, 0, sizeof decl); decl.kind = CFREE_CG_DECL_FUNC; decl.linkage_name = cfree_cg_c_linkage_name(c, source_name); @@ -1707,8 +1710,8 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, sig.call_conv = CFREE_CG_CC_TARGET_C; memset(&decl, 0, sizeof decl); decl.kind = CFREE_CG_DECL_FUNC; - decl.linkage_name = - cfree_cg_c_linkage_name(c, cfree_sym_intern(c, CFREE_SLICE_LIT("__cfree_wasm_init"))); + decl.linkage_name = cfree_cg_c_linkage_name( + c, cfree_sym_intern(c, CFREE_SLICE_LIT("__cfree_wasm_init"))); decl.display_name = decl.linkage_name; decl.type = cfree_cg_type_func(c, sig); decl.sym.bind = CFREE_SB_GLOBAL; @@ -1763,8 +1766,7 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, decl.type = func_types[i]; decl.sym.bind = f->export_name ? CFREE_SB_GLOBAL : CFREE_SB_LOCAL; syms[i] = cfree_cg_decl(cg, decl); - if (!syms[i]) - wasm_error(c, f->loc, "wasm: failed to declare function"); + if (!syms[i]) wasm_error(c, f->loc, "wasm: failed to declare function"); } for (uint32_t k = 0; k < WASM_TRAP_COUNT; ++k) { cfree_cg_func_begin(cg, rt.trap_syms[k]); @@ -1805,12 +1807,12 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, if (d->memidx != i) continue; if (!d->nbytes) continue; { - CfreeCgSym data_sym = cfree_cg_const_data( - cg, d->bytes, d->nbytes, 16, b.id[CFREE_CG_BUILTIN_I8]); - CfreeCgMemAccess byte_mem = wasm_cg_mem_type(b.id[CFREE_CG_BUILTIN_I8]); + CfreeCgSym data_sym = cfree_cg_const_data(cg, d->bytes, d->nbytes, 16, + b.id[CFREE_CG_BUILTIN_I8]); + CfreeCgMemAccess byte_mem = + wasm_cg_mem_type(b.id[CFREE_CG_BUILTIN_I8]); wasm_cg_push_memory_data_ptr(cg, &rt, instance_local, i); - if (d->offset) - wasm_cg_ptr_add_offset(cg, b, d->offset, rt.i8_ptr_ty); + if (d->offset) wasm_cg_ptr_add_offset(cg, b, d->offset, rt.i8_ptr_ty); cfree_cg_push_symbol_addr(cg, data_sym, 0); cfree_cg_memcpy(cg, d->nbytes, byte_mem, byte_mem); } @@ -1827,8 +1829,8 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, wasm_cg_push_passive_data_lvalue(cg, &rt, instance_local, di); cfree_cg_field(cg, rt.passive_data_base_field); if (d->mode == WASM_SEG_PASSIVE && d->nbytes) { - CfreeCgSym data_sym = cfree_cg_const_data( - cg, d->bytes, d->nbytes, 16, b.id[CFREE_CG_BUILTIN_I8]); + CfreeCgSym data_sym = cfree_cg_const_data(cg, d->bytes, d->nbytes, 16, + b.id[CFREE_CG_BUILTIN_I8]); cfree_cg_push_symbol_addr(cg, data_sym, 0); } else { cfree_cg_push_null(cg, rt.i8_ptr_ty); @@ -1836,8 +1838,7 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, cfree_cg_store(cg, wasm_cg_mem_type(rt.i8_ptr_ty), wasm_cg_ea0()); wasm_cg_push_passive_data_lvalue(cg, &rt, instance_local, di); cfree_cg_field(cg, rt.passive_data_len_field); - cfree_cg_push_int(cg, - (d->mode == WASM_SEG_PASSIVE) ? d->nbytes : 0u, + cfree_cg_push_int(cg, (d->mode == WASM_SEG_PASSIVE) ? d->nbytes : 0u, b.id[CFREE_CG_BUILTIN_I64]); cfree_cg_store(cg, wasm_cg_mem(c, b, WASM_VAL_I64), wasm_cg_ea0()); } @@ -1906,7 +1907,7 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, * later table.init. */ if (is_passive) { wasm_cg_push_passive_elem_storage_array_lvalue(cg, &rt, - instance_local, i); + instance_local, i); cfree_cg_push_local(cg, slot_local); cfree_cg_load(cg, wasm_cg_mem(c, b, WASM_VAL_I32), wasm_cg_ea0()); cfree_cg_index(cg, 0); @@ -1925,7 +1926,7 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, cfree_cg_store(cg, wasm_cg_mem_type(rt.void_ptr_ty), wasm_cg_ea0()); if (is_passive) { wasm_cg_push_passive_elem_storage_array_lvalue(cg, &rt, - instance_local, i); + instance_local, i); cfree_cg_push_local(cg, slot_local); cfree_cg_load(cg, wasm_cg_mem(c, b, WASM_VAL_I32), wasm_cg_ea0()); cfree_cg_index(cg, 0); @@ -1953,7 +1954,8 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, } else { cfree_cg_push_null(cg, rt.table_entry_ptr_ty); } - cfree_cg_store(cg, wasm_cg_mem_type(rt.table_entry_ptr_ty), wasm_cg_ea0()); + cfree_cg_store(cg, wasm_cg_mem_type(rt.table_entry_ptr_ty), + wasm_cg_ea0()); wasm_cg_push_passive_elem_lvalue(cg, &rt, instance_local, i); cfree_cg_field(cg, rt.passive_elem_length_field); cfree_cg_push_int(cg, is_passive ? seg->nfuncs : 0u, @@ -1977,8 +1979,8 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, if (m->has_start) wasm_cg_call_func(c, cg, b, &m->funcs[m->start_func], &rt, syms[m->start_func], func_types[m->start_func], - instance_local, m->start_func, 0, - m->start_field_loc, &arena); + instance_local, m->start_func, 0, m->start_field_loc, + &arena); cfree_cg_ret_void(cg); cfree_cg_func_end(cg); } @@ -2005,13 +2007,11 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, : NULL; Heap* heap = (Heap*)cfree_compiler_context(c)->heap; uint32_t control_cap = 16u; - WasmCgControl* control = - (WasmCgControl*)heap->alloc(heap, sizeof(WasmCgControl) * control_cap, - _Alignof(WasmCgControl)); + WasmCgControl* control = (WasmCgControl*)heap->alloc( + heap, sizeof(WasmCgControl) * control_cap, _Alignof(WasmCgControl)); uint32_t ncontrol = 0; CfreeCgLocal instance_local; - if (!control) - wasm_error(c, f->loc, "wasm: out of memory"); + if (!control) wasm_error(c, f->loc, "wasm: out of memory"); if (f->is_import) { heap->free(heap, control, sizeof(WasmCgControl) * control_cap); continue; @@ -2051,10 +2051,9 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, case WASM_INSN_BLOCK: if (ncontrol == control_cap) { uint32_t new_cap = control_cap * 2u; - void* p = heap->realloc(heap, control, - sizeof(WasmCgControl) * control_cap, - sizeof(WasmCgControl) * new_cap, - _Alignof(WasmCgControl)); + void* p = heap->realloc( + heap, control, sizeof(WasmCgControl) * control_cap, + sizeof(WasmCgControl) * new_cap, _Alignof(WasmCgControl)); if (!p) wasm_error(c, in.loc, "wasm: out of memory"); control = (WasmCgControl*)p; control_cap = new_cap; @@ -2067,10 +2066,9 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, case WASM_INSN_LOOP: if (ncontrol == control_cap) { uint32_t new_cap = control_cap * 2u; - void* p = heap->realloc(heap, control, - sizeof(WasmCgControl) * control_cap, - sizeof(WasmCgControl) * new_cap, - _Alignof(WasmCgControl)); + void* p = heap->realloc( + heap, control, sizeof(WasmCgControl) * control_cap, + sizeof(WasmCgControl) * new_cap, _Alignof(WasmCgControl)); if (!p) wasm_error(c, in.loc, "wasm: out of memory"); control = (WasmCgControl*)p; control_cap = new_cap; @@ -2085,10 +2083,9 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, case WASM_INSN_IF: if (ncontrol == control_cap) { uint32_t new_cap = control_cap * 2u; - void* p = heap->realloc(heap, control, - sizeof(WasmCgControl) * control_cap, - sizeof(WasmCgControl) * new_cap, - _Alignof(WasmCgControl)); + void* p = heap->realloc( + heap, control, sizeof(WasmCgControl) * control_cap, + sizeof(WasmCgControl) * new_cap, _Alignof(WasmCgControl)); if (!p) wasm_error(c, in.loc, "wasm: out of memory"); control = (WasmCgControl*)p; control_cap = new_cap; @@ -2108,8 +2105,7 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, control[ncontrol - 1u].seen_else = 1; break; case WASM_INSN_END: - if (!ncontrol) - wasm_error(c, in.loc, "wasm: end without block"); + if (!ncontrol) wasm_error(c, in.loc, "wasm: end without block"); ncontrol--; if (control[ncontrol].kind == WASM_INSN_IF && !control[ncontrol].seen_else) @@ -2230,14 +2226,16 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, case WASM_INSN_LOCAL_GET: { uint32_t index = (uint32_t)in.imm; cfree_cg_push_local(cg, locals[index]); - cfree_cg_load(cg, wasm_cg_mem(c, b, wasm_func_local_type(f, index)), wasm_cg_ea0()); + cfree_cg_load(cg, wasm_cg_mem(c, b, wasm_func_local_type(f, index)), + wasm_cg_ea0()); break; } case WASM_INSN_LOCAL_SET: { uint32_t index = (uint32_t)in.imm; cfree_cg_push_local(cg, locals[index]); cfree_cg_swap(cg); - cfree_cg_store(cg, wasm_cg_mem(c, b, wasm_func_local_type(f, index)), wasm_cg_ea0()); + cfree_cg_store(cg, wasm_cg_mem(c, b, wasm_func_local_type(f, index)), + wasm_cg_ea0()); break; } case WASM_INSN_LOCAL_TEE: { @@ -2245,15 +2243,16 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, cfree_cg_dup(cg); cfree_cg_push_local(cg, locals[index]); cfree_cg_swap(cg); - cfree_cg_store(cg, wasm_cg_mem(c, b, wasm_func_local_type(f, index)), wasm_cg_ea0()); + cfree_cg_store(cg, wasm_cg_mem(c, b, wasm_func_local_type(f, index)), + wasm_cg_ea0()); break; } case WASM_INSN_CALL: case WASM_INSN_RETURN_CALL: wasm_cg_call_func(c, cg, b, &m->funcs[in.imm], &rt, syms[in.imm], func_types[in.imm], instance_local, - (uint32_t)in.imm, - in.kind == WASM_INSN_RETURN_CALL, in.loc, &arena); + (uint32_t)in.imm, in.kind == WASM_INSN_RETURN_CALL, + in.loc, &arena); break; case WASM_INSN_CALL_INDIRECT: case WASM_INSN_RETURN_CALL_INDIRECT: { @@ -2261,8 +2260,7 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, CfreeCgLocalAttrs attrs; CfreeCgLocal selector, callee, result = CFREE_CG_LOCAL_NONE; CfreeCgLocal* args = - t->nparams ? arena_array(&arena, CfreeCgLocal, t->nparams) - : NULL; + t->nparams ? arena_array(&arena, CfreeCgLocal, t->nparams) : NULL; CfreeCgLabel ok; CfreeCgMemAccess i32_mem = wasm_cg_mem(c, b, WASM_VAL_I32); CfreeCgFuncParam* indirect_params = @@ -2295,7 +2293,8 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, cfree_cg_local(cg, wasm_cg_type(c, b, t->params[param]), attrs); cfree_cg_push_local(cg, args[param]); cfree_cg_swap(cg); - cfree_cg_store(cg, wasm_cg_mem(c, b, t->params[param]), wasm_cg_ea0()); + cfree_cg_store(cg, wasm_cg_mem(c, b, t->params[param]), + wasm_cg_ea0()); } ok = cfree_cg_label_new(cg); @@ -2352,7 +2351,8 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, cfree_cg_load(cg, wasm_cg_mem_type(rt.void_ptr_ty), wasm_cg_ea0()); cfree_cg_bitcast(cg, cfree_cg_type_ptr(c, indirect_func_type, 0)); cfree_cg_push_local(cg, instance_local); - cfree_cg_load(cg, wasm_cg_mem_type(rt.instance_ptr_ty), wasm_cg_ea0()); + cfree_cg_load(cg, wasm_cg_mem_type(rt.instance_ptr_ty), + wasm_cg_ea0()); for (uint32_t p = 0; p < t->nparams; ++p) { cfree_cg_push_local(cg, args[p]); cfree_cg_load(cg, wasm_cg_mem(c, b, t->params[p]), wasm_cg_ea0()); @@ -2393,8 +2393,7 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, CfreeCgLocalAttrs attrs; CfreeCgLocal callee_ref, callee, result = CFREE_CG_LOCAL_NONE; CfreeCgLocal* args = - t->nparams ? arena_array(&arena, CfreeCgLocal, t->nparams) - : NULL; + t->nparams ? arena_array(&arena, CfreeCgLocal, t->nparams) : NULL; CfreeCgLabel ok; CfreeCgMemAccess ref_mem = wasm_cg_mem_type(rt.void_ptr_ty); CfreeCgMemAccess i32_mem = wasm_cg_mem(c, b, WASM_VAL_I32); @@ -2415,7 +2414,8 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, cfree_cg_local(cg, wasm_cg_type(c, b, t->params[param]), attrs); cfree_cg_push_local(cg, args[param]); cfree_cg_swap(cg); - cfree_cg_store(cg, wasm_cg_mem(c, b, t->params[param]), wasm_cg_ea0()); + cfree_cg_store(cg, wasm_cg_mem(c, b, t->params[param]), + wasm_cg_ea0()); } ok = cfree_cg_label_new(cg); cfree_cg_push_local(cg, callee_ref); @@ -2471,7 +2471,8 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, cfree_cg_load(cg, ref_mem, wasm_cg_ea0()); cfree_cg_bitcast(cg, cfree_cg_type_ptr(c, ref_func_type, 0)); cfree_cg_push_local(cg, instance_local); - cfree_cg_load(cg, wasm_cg_mem_type(rt.instance_ptr_ty), wasm_cg_ea0()); + cfree_cg_load(cg, wasm_cg_mem_type(rt.instance_ptr_ty), + wasm_cg_ea0()); for (uint32_t p = 0; p < t->nparams; ++p) { cfree_cg_push_local(cg, args[p]); cfree_cg_load(cg, wasm_cg_mem(c, b, t->params[p]), wasm_cg_ea0()); @@ -2604,7 +2605,8 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, CfreeCgLocalAttrs attrs; CfreeCgLocal n_l, src_addr_l, dst_addr_l, src_base_l, dst_base_l; CfreeCgLocal src_size_l, dst_size_l; - CfreeCgMemAccess i64_mem = wasm_cg_mem_type(b.id[CFREE_CG_BUILTIN_I64]); + CfreeCgMemAccess i64_mem = + wasm_cg_mem_type(b.id[CFREE_CG_BUILTIN_I64]); CfreeCgMemAccess ptr_mem = wasm_cg_mem_type(rt.i8_ptr_ty); memset(&attrs, 0, sizeof attrs); attrs.flags = CFREE_CG_LOCAL_COMPILER_TEMP; @@ -2650,7 +2652,7 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, wasm_cg_bulk_bounds_check(cg, b, &rt, src_addr_l, n_l, src_size_l); wasm_cg_bulk_bounds_check(cg, b, &rt, dst_addr_l, n_l, dst_size_l); wasm_cg_emit_byte_copy_loop(cg, b, &rt, dst_base_l, src_base_l, - dst_addr_l, src_addr_l, n_l); + dst_addr_l, src_addr_l, n_l); break; } case WASM_INSN_MEMORY_FILL: { @@ -2659,8 +2661,10 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, int is64 = m->memories[memidx].is64; CfreeCgLocalAttrs attrs; CfreeCgLocal n_l, val_l, dst_addr_l, dst_base_l, dst_size_l; - CfreeCgMemAccess i64_mem = wasm_cg_mem_type(b.id[CFREE_CG_BUILTIN_I64]); - CfreeCgMemAccess i32_mem = wasm_cg_mem_type(b.id[CFREE_CG_BUILTIN_I32]); + CfreeCgMemAccess i64_mem = + wasm_cg_mem_type(b.id[CFREE_CG_BUILTIN_I64]); + CfreeCgMemAccess i32_mem = + wasm_cg_mem_type(b.id[CFREE_CG_BUILTIN_I32]); CfreeCgMemAccess ptr_mem = wasm_cg_mem_type(rt.i8_ptr_ty); memset(&attrs, 0, sizeof attrs); attrs.flags = CFREE_CG_LOCAL_COMPILER_TEMP; @@ -2691,18 +2695,20 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, cfree_cg_store(cg, i64_mem, wasm_cg_ea0()); wasm_cg_bulk_bounds_check(cg, b, &rt, dst_addr_l, n_l, dst_size_l); wasm_cg_emit_byte_fill_loop(cg, b, &rt, dst_base_l, dst_addr_l, val_l, - n_l); + n_l); break; } case WASM_INSN_MEMORY_INIT: { - /* Stack: [dst_addr, src_addr, n]; in.imm = dataidx; in.memidx = memidx */ + /* Stack: [dst_addr, src_addr, n]; in.imm = dataidx; in.memidx = + * memidx */ uint32_t dataidx = (uint32_t)in.imm; uint32_t memidx = in.memidx; int is64 = m->memories[memidx].is64; CfreeCgLocalAttrs attrs; CfreeCgLocal n_l, src_addr_l, dst_addr_l, src_base_l, dst_base_l; CfreeCgLocal src_size_l, dst_size_l; - CfreeCgMemAccess i64_mem = wasm_cg_mem_type(b.id[CFREE_CG_BUILTIN_I64]); + CfreeCgMemAccess i64_mem = + wasm_cg_mem_type(b.id[CFREE_CG_BUILTIN_I64]); CfreeCgMemAccess ptr_mem = wasm_cg_mem_type(rt.i8_ptr_ty); memset(&attrs, 0, sizeof attrs); attrs.flags = CFREE_CG_LOCAL_COMPILER_TEMP; @@ -2749,7 +2755,7 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, wasm_cg_bulk_bounds_check(cg, b, &rt, src_addr_l, n_l, src_size_l); wasm_cg_bulk_bounds_check(cg, b, &rt, dst_addr_l, n_l, dst_size_l); wasm_cg_emit_byte_copy_loop(cg, b, &rt, dst_base_l, src_base_l, - dst_addr_l, src_addr_l, n_l); + dst_addr_l, src_addr_l, n_l); break; } case WASM_INSN_DATA_DROP: { @@ -2899,7 +2905,8 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, cfree_cg_jump(cg, done); cfree_cg_label_place(cg, fail); cfree_cg_push_local(cg, result_l); - cfree_cg_push_int(cg, UINT32_C(0xffffffff), b.id[CFREE_CG_BUILTIN_I32]); + cfree_cg_push_int(cg, UINT32_C(0xffffffff), + b.id[CFREE_CG_BUILTIN_I32]); cfree_cg_store(cg, i32_mem, wasm_cg_ea0()); cfree_cg_label_place(cg, done); cfree_cg_push_local(cg, result_l); @@ -3031,13 +3038,15 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, break; } case WASM_INSN_TABLE_COPY: { - /* Stack: [dst_idx, src_idx, n]; in.imm = dst_tableidx; in.aux_idx = src */ + /* Stack: [dst_idx, src_idx, n]; in.imm = dst_tableidx; in.aux_idx = + * src */ uint32_t dst_tbl = (uint32_t)in.imm; uint32_t src_tbl = in.aux_idx; CfreeCgLocalAttrs attrs; CfreeCgLocal n_l, src_idx_l, dst_idx_l, src_base_l, dst_base_l; CfreeCgLocal src_len_l, dst_len_l; - CfreeCgMemAccess i64_mem = wasm_cg_mem_type(b.id[CFREE_CG_BUILTIN_I64]); + CfreeCgMemAccess i64_mem = + wasm_cg_mem_type(b.id[CFREE_CG_BUILTIN_I64]); CfreeCgMemAccess i32_mem = wasm_cg_mem(c, b, WASM_VAL_I32); CfreeCgMemAccess ptr_mem = wasm_cg_mem_type(rt.table_entry_ptr_ty); memset(&attrs, 0, sizeof attrs); @@ -3086,17 +3095,19 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, wasm_cg_bulk_bounds_check(cg, b, &rt, src_idx_l, n_l, src_len_l); wasm_cg_bulk_bounds_check(cg, b, &rt, dst_idx_l, n_l, dst_len_l); wasm_cg_emit_table_copy_loop(c, cg, b, &rt, dst_base_l, src_base_l, - dst_idx_l, src_idx_l, n_l); + dst_idx_l, src_idx_l, n_l); break; } case WASM_INSN_TABLE_INIT: { - /* Stack: [dst_idx, src_idx, n]; in.imm = elemidx; in.aux_idx = tableidx */ + /* Stack: [dst_idx, src_idx, n]; in.imm = elemidx; in.aux_idx = + * tableidx */ uint32_t elemidx = (uint32_t)in.imm; uint32_t tableidx = in.aux_idx; CfreeCgLocalAttrs attrs; CfreeCgLocal n_l, src_idx_l, dst_idx_l, src_base_l, dst_base_l; CfreeCgLocal src_len_l, dst_len_l; - CfreeCgMemAccess i64_mem = wasm_cg_mem_type(b.id[CFREE_CG_BUILTIN_I64]); + CfreeCgMemAccess i64_mem = + wasm_cg_mem_type(b.id[CFREE_CG_BUILTIN_I64]); CfreeCgMemAccess i32_mem = wasm_cg_mem(c, b, WASM_VAL_I32); CfreeCgMemAccess ptr_mem = wasm_cg_mem_type(rt.table_entry_ptr_ty); memset(&attrs, 0, sizeof attrs); @@ -3145,31 +3156,27 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, wasm_cg_bulk_bounds_check(cg, b, &rt, src_idx_l, n_l, src_len_l); wasm_cg_bulk_bounds_check(cg, b, &rt, dst_idx_l, n_l, dst_len_l); wasm_cg_emit_table_copy_loop(c, cg, b, &rt, dst_base_l, src_base_l, - dst_idx_l, src_idx_l, n_l); + dst_idx_l, src_idx_l, n_l); break; } case WASM_INSN_I32_TRUNC_SAT_F32_S: case WASM_INSN_I32_TRUNC_SAT_F64_S: - cfree_cg_float_to_sint(cg, - b.id[CFREE_CG_BUILTIN_I32], + cfree_cg_float_to_sint(cg, b.id[CFREE_CG_BUILTIN_I32], CFREE_CG_ROUND_TOWARD_ZERO); break; case WASM_INSN_I32_TRUNC_SAT_F32_U: case WASM_INSN_I32_TRUNC_SAT_F64_U: - cfree_cg_float_to_uint(cg, - b.id[CFREE_CG_BUILTIN_I32], + cfree_cg_float_to_uint(cg, b.id[CFREE_CG_BUILTIN_I32], CFREE_CG_ROUND_TOWARD_ZERO); break; case WASM_INSN_I64_TRUNC_SAT_F32_S: case WASM_INSN_I64_TRUNC_SAT_F64_S: - cfree_cg_float_to_sint(cg, - b.id[CFREE_CG_BUILTIN_I64], + cfree_cg_float_to_sint(cg, b.id[CFREE_CG_BUILTIN_I64], CFREE_CG_ROUND_TOWARD_ZERO); break; case WASM_INSN_I64_TRUNC_SAT_F32_U: case WASM_INSN_I64_TRUNC_SAT_F64_U: - cfree_cg_float_to_uint(cg, - b.id[CFREE_CG_BUILTIN_I64], + cfree_cg_float_to_uint(cg, b.id[CFREE_CG_BUILTIN_I64], CFREE_CG_ROUND_TOWARD_ZERO); break; case WASM_INSN_ATOMIC_FENCE: @@ -3187,7 +3194,8 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, CfreeCgMemAccess mem = wasm_cg_mem_type(ty); mem.align = in.align; wasm_cg_memory_check(c, cg, b, m, &rt, instance_local, &in); - wasm_cg_memory_addr_from_tos(cg, b, &rt, m, instance_local, in.memidx, in.offset64); + wasm_cg_memory_addr_from_tos(cg, b, &rt, m, instance_local, in.memidx, + in.offset64); cfree_cg_atomic_load(cg, mem, CFREE_CG_MO_SEQ_CST); break; } @@ -3211,7 +3219,8 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, cfree_cg_swap(cg); cfree_cg_store(cg, mem, wasm_cg_ea0()); wasm_cg_memory_check(c, cg, b, m, &rt, instance_local, &in); - wasm_cg_memory_addr_from_tos(cg, b, &rt, m, instance_local, in.memidx, in.offset64); + wasm_cg_memory_addr_from_tos(cg, b, &rt, m, instance_local, in.memidx, + in.offset64); cfree_cg_push_local(cg, value_tmp); cfree_cg_load(cg, mem, wasm_cg_ea0()); cfree_cg_atomic_store(cg, mem, CFREE_CG_MO_SEQ_CST); @@ -3242,7 +3251,8 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, cfree_cg_swap(cg); cfree_cg_store(cg, mem, wasm_cg_ea0()); wasm_cg_memory_check(c, cg, b, m, &rt, instance_local, &in); - wasm_cg_memory_addr_from_tos(cg, b, &rt, m, instance_local, in.memidx, in.offset64); + wasm_cg_memory_addr_from_tos(cg, b, &rt, m, instance_local, in.memidx, + in.offset64); cfree_cg_push_local(cg, value_tmp); cfree_cg_load(cg, mem, wasm_cg_ea0()); cfree_cg_atomic_rmw(cg, mem, wasm_atomic_rmw_op(in.kind), @@ -3268,7 +3278,8 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, cfree_cg_swap(cg); cfree_cg_store(cg, mem, wasm_cg_ea0()); wasm_cg_memory_check(c, cg, b, m, &rt, instance_local, &in); - wasm_cg_memory_addr_from_tos(cg, b, &rt, m, instance_local, in.memidx, in.offset64); + wasm_cg_memory_addr_from_tos(cg, b, &rt, m, instance_local, in.memidx, + in.offset64); cfree_cg_push_local(cg, expected_tmp); cfree_cg_load(cg, mem, wasm_cg_ea0()); cfree_cg_push_local(cg, desired_tmp); @@ -3300,7 +3311,8 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, cfree_cg_swap(cg); cfree_cg_store(cg, mem, wasm_cg_ea0()); wasm_cg_memory_check(c, cg, b, m, &rt, instance_local, &in); - wasm_cg_memory_addr_from_tos(cg, b, &rt, m, instance_local, in.memidx, in.offset64); + wasm_cg_memory_addr_from_tos(cg, b, &rt, m, instance_local, in.memidx, + in.offset64); cfree_cg_atomic_load(cg, mem, CFREE_CG_MO_SEQ_CST); cfree_cg_push_local(cg, expected_tmp); cfree_cg_load(cg, mem, wasm_cg_ea0()); @@ -3357,7 +3369,8 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, mem.type = storage; mem.align = in.align; wasm_cg_memory_check(c, cg, b, m, &rt, instance_local, &in); - wasm_cg_memory_addr_from_tos(cg, b, &rt, m, instance_local, in.memidx, in.offset64); + wasm_cg_memory_addr_from_tos(cg, b, &rt, m, instance_local, in.memidx, + in.offset64); cfree_cg_load(cg, mem, wasm_cg_ea0()); if (storage != result) { if (in.kind == WASM_INSN_I32_LOAD8_S || @@ -3405,7 +3418,8 @@ void wasm_emit_cg(CfreeCompiler* c, const CfreeCodeOptions* code_opts, cfree_cg_store(cg, wasm_cg_mem(c, b, addr_vt), wasm_cg_ea0()); cfree_cg_push_local(cg, addr_tmp); cfree_cg_load(cg, wasm_cg_mem(c, b, addr_vt), wasm_cg_ea0()); - wasm_cg_memory_addr_from_tos(cg, b, &rt, m, instance_local, in.memidx, in.offset64); + wasm_cg_memory_addr_from_tos(cg, b, &rt, m, instance_local, in.memidx, + in.offset64); cfree_cg_push_local(cg, value_tmp); cfree_cg_load(cg, mem, wasm_cg_ea0()); cfree_cg_store(cg, mem, wasm_cg_ea0()); diff --git a/lang/wasm/host_imports.c b/lang/wasm/host_imports.c @@ -6,15 +6,14 @@ * the rest of the cfree-instance ABI. The public-API surface is in * include/cfree/wasm.h. */ -#include "runtime_abi.h" - #include <cfree/core.h> #include <cfree/jit.h> #include <cfree/wasm.h> - #include <stdint.h> #include <string.h> +#include "runtime_abi.h" + /* Raw wasm WasmValType byte encoding (mirrored from src/wasm/wasm.h so this * module stays free of internal wasm-core dependencies; if either side * changes these, the binder/metadata pair breaks together). */ @@ -97,8 +96,8 @@ CFREE_API CfreeStatus cfree_wasm_bind_host_imports( (void)compiler; if (!jit || !inst) return CFREE_INVALID; - nimports_meta = - (const uint32_t*)cfree_jit_lookup(jit, CFREE_SLICE_LIT("__cfree_wasm_nimports")); + nimports_meta = (const uint32_t*)cfree_jit_lookup( + jit, CFREE_SLICE_LIT("__cfree_wasm_nimports")); if (!nimports_meta) { /* Module wasn't built through cfree's wasm frontend, or it has no * imports at all. Nothing to bind. */ @@ -106,10 +105,10 @@ CFREE_API CfreeStatus cfree_wasm_bind_host_imports( } n = *nimports_meta; if (n == 0) return CFREE_OK; - import_descs = - (const CfreeWasmImportDesc*)cfree_jit_lookup(jit, CFREE_SLICE_LIT("__cfree_wasm_imports")); - type_descs = - (const CfreeWasmTypeDesc*)cfree_jit_lookup(jit, CFREE_SLICE_LIT("__cfree_wasm_types")); + import_descs = (const CfreeWasmImportDesc*)cfree_jit_lookup( + jit, CFREE_SLICE_LIT("__cfree_wasm_imports")); + type_descs = (const CfreeWasmTypeDesc*)cfree_jit_lookup( + jit, CFREE_SLICE_LIT("__cfree_wasm_types")); if (!import_descs || !type_descs) return CFREE_MALFORMED; for (i = 0; i < n; ++i) { @@ -129,9 +128,8 @@ CFREE_API CfreeStatus cfree_wasm_bind_host_imports( /* Resolver fallback. */ if (!fn && resolve) { const CfreeWasmTypeDesc* td = &type_descs[d->typeidx]; - if (!host_imports_build_type(td, pbuf, CFREE_WASM_BIND_MAX_VALTYPES, - rbuf, CFREE_WASM_BIND_MAX_VALTYPES, - &type)) + if (!host_imports_build_type(td, pbuf, CFREE_WASM_BIND_MAX_VALTYPES, rbuf, + CFREE_WASM_BIND_MAX_VALTYPES, &type)) return CFREE_MALFORMED; fn = resolve(user, d->module, d->field, &type); } diff --git a/lang/wasm/runtime_abi.h b/lang/wasm/runtime_abi.h @@ -82,15 +82,15 @@ typedef void (*CfreeWasmInitFn)(CfreeWasmInstance*); * the public CfreeWasmValType enum when invoking host resolvers. */ typedef struct CfreeWasmImportDesc { - const char* module; /* image-owned, NUL-terminated */ - const char* field; /* image-owned, NUL-terminated */ - uint32_t typeidx; /* index into __cfree_wasm_types */ - uint32_t slot_offset; /* byte offset of the void* slot inside the - CfreeWasmInstance for this import */ + const char* module; /* image-owned, NUL-terminated */ + const char* field; /* image-owned, NUL-terminated */ + uint32_t typeidx; /* index into __cfree_wasm_types */ + uint32_t slot_offset; /* byte offset of the void* slot inside the + CfreeWasmInstance for this import */ } CfreeWasmImportDesc; typedef struct CfreeWasmTypeDesc { - const uint8_t* params; /* nparams WasmValType bytes */ + const uint8_t* params; /* nparams WasmValType bytes */ uint32_t nparams; const uint8_t* results; /* nresults WasmValType bytes */ uint32_t nresults; diff --git a/lang/wasm/wasm.c b/lang/wasm/wasm.c @@ -59,8 +59,7 @@ const CfreeFrontendVTable cfree_wasm_frontend_vtable = { (uint32_t)(sizeof wasm_extensions / sizeof wasm_extensions[0]), }; -CFREE_API int cfree_wasm_wat_to_wasm(CfreeCompiler* c, - const CfreeSlice* input, +CFREE_API int cfree_wasm_wat_to_wasm(CfreeCompiler* c, const CfreeSlice* input, CfreeWriter* out) { WasmModule m; wasm_module_init(&m, cfree_compiler_context(c)->heap); diff --git a/rt/include/stdio.h b/rt/include/stdio.h @@ -11,7 +11,6 @@ int snprintf(char* s, size_t n, const char* fmt, ...); int vsnprintf(char* s, size_t n, const char* fmt, va_list ap); int sprintf(char* s, const char* fmt, ...); int vsprintf(char* s, const char* fmt, va_list ap); -int fctprintf(void (*out)(char ch, void* arg), void* arg, - const char* fmt, ...); +int fctprintf(void (*out)(char ch, void* arg), void* arg, const char* fmt, ...); #endif diff --git a/rt/lib/atomic/atomic_freestanding.c b/rt/lib/atomic/atomic_freestanding.c @@ -27,8 +27,7 @@ static inline void unlock(Lock* l) { } static inline void lock(Lock* l) { - while (__atomic_exchange_n((uintptr_t*)l, 1, __ATOMIC_ACQUIRE)) - ; + while (__atomic_exchange_n((uintptr_t*)l, 1, __ATOMIC_ACQUIRE)); } #pragma clang diagnostic pop diff --git a/rt/lib/fp_tf/fp_tf.c b/rt/lib/fp_tf/fp_tf.c @@ -95,8 +95,7 @@ static void cfree_tf_u256_add_shifted_sig(cfree_tf_u256* product, rep_t sig, cfree_tf_u256_add_limb( product, index + 1, (lo >> (unsigned)(64 - bits)) | (hi << (unsigned)bits)); - cfree_tf_u256_add_limb(product, index + 2, - hi >> (unsigned)(64 - bits)); + cfree_tf_u256_add_limb(product, index + 2, hi >> (unsigned)(64 - bits)); } } @@ -239,18 +238,14 @@ COMPILER_RT_ABI fp_t __divtf3(fp_t a, fp_t b) { quotient |= 1; remainder -= bSignificand; } - if (i != significandBits + 3) - remainder <<= 1; + if (i != significandBits + 3) remainder <<= 1; } - if (remainder) - quotient |= 1; + if (remainder) quotient |= 1; - if (writtenExponent >= maxExponent) - return fromRep(infRep | quotientSign); + if (writtenExponent >= maxExponent) return fromRep(infRep | quotientSign); if (writtenExponent <= 0) { const int shift = 1 - writtenExponent; - if (shift >= typeWidth) - return fromRep(quotientSign); + if (shift >= typeWidth) return fromRep(quotientSign); if (shift > 0) { const bool sticky = (quotient << (typeWidth - shift)) != 0; quotient = (quotient >> shift) | sticky; @@ -263,23 +258,20 @@ COMPILER_RT_ABI fp_t __divtf3(fp_t a, fp_t b) { absResult |= (rep_t)writtenExponent << significandBits; switch (__fe_getround()) { - case CRT_FE_TONEAREST: - if (roundGuardSticky > 0x4) - absResult++; - if (roundGuardSticky == 0x4) - absResult += absResult & 1; - break; - case CRT_FE_DOWNWARD: - if (quotientSign && roundGuardSticky) absResult++; - break; - case CRT_FE_UPWARD: - if (!quotientSign && roundGuardSticky) absResult++; - break; - case CRT_FE_TOWARDZERO: - break; + case CRT_FE_TONEAREST: + if (roundGuardSticky > 0x4) absResult++; + if (roundGuardSticky == 0x4) absResult += absResult & 1; + break; + case CRT_FE_DOWNWARD: + if (quotientSign && roundGuardSticky) absResult++; + break; + case CRT_FE_UPWARD: + if (!quotientSign && roundGuardSticky) absResult++; + break; + case CRT_FE_TOWARDZERO: + break; } - if (roundGuardSticky) - __fe_raise_inexact(); + if (roundGuardSticky) __fe_raise_inexact(); return fromRep(absResult | quotientSign); } @@ -322,9 +314,8 @@ static int cfree_clz_u64(du_int x) { static fp_t cfree_tf_from_u64(du_int mag, rep_t sign, int width) { if (!mag) return fromRep(0); - int exponent = (width - 1) - - (width == 32 ? cfree_clz_u32((su_int)mag) - : cfree_clz_u64(mag)); + int exponent = (width - 1) - (width == 32 ? cfree_clz_u32((su_int)mag) + : cfree_clz_u64(mag)); int shift = significandBits - exponent; rep_t result = ((rep_t)mag << shift) ^ implicitBit; result |= (rep_t)(exponent + exponentBias) << significandBits; diff --git a/rt/lib/include/common/fp_lib.h b/rt/lib/include/common/fp_lib.h @@ -284,7 +284,7 @@ static inline void wideLeftShift(rep_t* hi, rep_t* lo, int count) { } static inline void wideRightShiftWithSticky(rep_t* hi, rep_t* lo, - unsigned int count) { + unsigned int count) { if (count < typeWidth) { const bool sticky = (*lo << (typeWidth - count)) != 0; *lo = *hi << (typeWidth - count) | *lo >> count | sticky; @@ -367,9 +367,7 @@ static inline fp_t __compiler_rt_fmaxf(fp_t x, fp_t y) { return __compiler_rt_fmaxX(x, y); } #elif defined(DOUBLE_PRECISION) -static inline fp_t __compiler_rt_logb(fp_t x) { - return __compiler_rt_logbX(x); -} +static inline fp_t __compiler_rt_logb(fp_t x) { return __compiler_rt_logbX(x); } static inline fp_t __compiler_rt_scalbn(fp_t x, int y) { return __compiler_rt_scalbnX(x, y); } diff --git a/rt/lib/int64/int64.c b/rt/lib/int64/int64.c @@ -210,9 +210,8 @@ static inline void ut_udivmod(utwords n, utwords d, utwords* q, utwords* rem) { return; } for (int i = 127; i >= 0; --i) { - du_int bit = - i < 64 ? ((n.s.low >> (unsigned)i) & 1u) - : ((n.s.high >> (unsigned)(i - 64)) & 1u); + du_int bit = i < 64 ? ((n.s.low >> (unsigned)i) & 1u) + : ((n.s.high >> (unsigned)(i - 64)) & 1u); remainder = ut_shl1(remainder); remainder.s.low |= bit; if (ut_cmp(remainder, d) >= 0) { diff --git a/rt/lib/stdio/printf.c b/rt/lib/stdio/printf.c @@ -34,8 +34,7 @@ static void cfree_out_repeat(CfreePrintfOut* out, char ch, unsigned count) { while (count-- > 0) cfree_out_ch(out, ch); } -static unsigned cfree_strlen_prec(const char* s, int has_prec, - unsigned prec) { +static unsigned cfree_strlen_prec(const char* s, int has_prec, unsigned prec) { unsigned n = 0; if (!s) s = "(null)"; while (s[n] != '\0' && (!has_prec || n < prec)) n++; @@ -81,9 +80,8 @@ static void cfree_out_uint(CfreePrintfOut* out, unsigned long long value, } static void cfree_out_padded_string(CfreePrintfOut* out, const char* s, - unsigned len, int neg, int plus, - int space, int left, int zero, - unsigned width) { + unsigned len, int neg, int plus, int space, + int left, int zero, unsigned width) { unsigned prefix = (neg || plus || space) ? 1U : 0U; char sign = neg ? '-' : (plus ? '+' : ' '); char pad = (zero && !left) ? '0' : ' '; @@ -254,9 +252,8 @@ static void cfree_trim_float(char* s, unsigned* len, int alt) { } static void cfree_format_float(CfreePrintfOut* out, double value, char spec, - int left, int zero, int plus, int space, - int alt, unsigned width, int has_prec, - unsigned prec) { + int left, int zero, int plus, int space, int alt, + unsigned width, int has_prec, unsigned prec) { char tmp[384]; CfreePrintfOut tmp_out; unsigned len; @@ -271,12 +268,12 @@ static void cfree_format_float(CfreePrintfOut* out, double value, char spec, tmp_out.arg = NULL; if (value != value) { - cfree_out_string(&tmp_out, (spec >= 'A' && spec <= 'Z') ? "NAN" : "nan", - 0, 0, 0, 0); + cfree_out_string(&tmp_out, (spec >= 'A' && spec <= 'Z') ? "NAN" : "nan", 0, + 0, 0, 0); neg = 0; } else if (mag > 1.7976931348623157e308) { - cfree_out_string(&tmp_out, (spec >= 'A' && spec <= 'Z') ? "INF" : "inf", - 0, 0, 0, 0); + cfree_out_string(&tmp_out, (spec >= 'A' && spec <= 'Z') ? "INF" : "inf", 0, + 0, 0, 0); } else if (spec == 'e' || spec == 'E') { cfree_format_exp_abs(&tmp_out, mag, prec, spec == 'E', alt); } else if (spec == 'g' || spec == 'G') { @@ -285,8 +282,8 @@ static void cfree_format_float(CfreePrintfOut* out, double value, char spec, if (exp < -4 || exp >= (int)prec) { cfree_format_exp_abs(&tmp_out, mag, prec - 1U, spec == 'G', alt); } else { - unsigned fprec = exp >= 0 ? prec - (unsigned)exp - 1U - : prec + (unsigned)(-exp) - 1U; + unsigned fprec = + exp >= 0 ? prec - (unsigned)exp - 1U : prec + (unsigned)(-exp) - 1U; cfree_format_fixed_abs(&tmp_out, mag, fprec, alt); } } else { @@ -298,8 +295,8 @@ static void cfree_format_float(CfreePrintfOut* out, double value, char spec, tmp[len] = '\0'; if (spec == 'g' || spec == 'G') cfree_trim_float(tmp, &len, alt); if (value != value) neg = 0; - cfree_out_padded_string(out, tmp, len, neg, plus && !neg, space && !neg, - left, zero, width); + cfree_out_padded_string(out, tmp, len, neg, plus && !neg, space && !neg, left, + zero, width); } static int cfree_is_digit(char ch) { return ch >= '0' && ch <= '9'; } @@ -314,7 +311,6 @@ static unsigned cfree_parse_uint(const char** p) { static int cfree_vprintf_impl(CfreePrintfOut* out, const char* fmt, va_list ap) { - while (*fmt) { int left = 0; int zero = 0; @@ -514,8 +510,8 @@ int sprintf(char* s, const char* fmt, ...) { return rc; } -int fctprintf(void (*out_fct)(char ch, void* arg), void* arg, - const char* fmt, ...) { +int fctprintf(void (*out_fct)(char ch, void* arg), void* arg, const char* fmt, + ...) { CfreePrintfOut out; va_list ap; int rc; diff --git a/rt/lib/stdlib/qsort.c b/rt/lib/stdlib/qsort.c @@ -24,211 +24,206 @@ /* Smoothsort, an adaptive variant of Heapsort. Memory usage: O(1). Run time: Worst case O(n log n), close to O(n) in the mostly-sorted case. */ -#include <stdint.h> #include <stddef.h> +#include <stdint.h> -void *memcpy(void *dest, const void *src, size_t n); +void* memcpy(void* dest, const void* src, size_t n); -typedef int (*cmpfun)(const void *, const void *); +typedef int (*cmpfun)(const void*, const void*); -static int ntz(size_t x) -{ - int n = 0; - while ((x & 1) == 0) { - x >>= 1; - n++; - } - return n; +static int ntz(size_t x) { + int n = 0; + while ((x & 1) == 0) { + x >>= 1; + n++; + } + return n; } /* returns index of first bit set, excluding the low bit assumed to always * be set, starting from low bit of p[0] up through high bit of p[1] */ static inline int pntz(size_t p[2]) { - if (p[0] != 1) return ntz(p[0] - 1); - if (p[1]) return 8*sizeof(size_t) + ntz(p[1]); - return 0; + if (p[0] != 1) return ntz(p[0] - 1); + if (p[1]) return 8 * sizeof(size_t) + ntz(p[1]); + return 0; } -static void cycle(size_t width, unsigned char* ar[], int n) -{ - unsigned char tmp[256]; - size_t l; - int i; - - if(n < 2) { - return; - } - - ar[n] = tmp; - while(width) { - l = sizeof(tmp) < width ? sizeof(tmp) : width; - memcpy(ar[n], ar[0], l); - for(i = 0; i < n; i++) { - memcpy(ar[i], ar[i + 1], l); - ar[i] += l; - } - width -= l; - } +static void cycle(size_t width, unsigned char* ar[], int n) { + unsigned char tmp[256]; + size_t l; + int i; + + if (n < 2) { + return; + } + + ar[n] = tmp; + while (width) { + l = sizeof(tmp) < width ? sizeof(tmp) : width; + memcpy(ar[n], ar[0], l); + for (i = 0; i < n; i++) { + memcpy(ar[i], ar[i + 1], l); + ar[i] += l; + } + width -= l; + } } /* shl() and shr() need n > 0 */ -static inline void shl(size_t p[2], int n) -{ - if(n >= 8 * sizeof(size_t)) { - n -= 8 * sizeof(size_t); - p[1] = p[0]; - p[0] = 0; - if (!n) return; - } - p[1] <<= n; - p[1] |= p[0] >> (sizeof(size_t) * 8 - n); - p[0] <<= n; +static inline void shl(size_t p[2], int n) { + if (n >= 8 * sizeof(size_t)) { + n -= 8 * sizeof(size_t); + p[1] = p[0]; + p[0] = 0; + if (!n) return; + } + p[1] <<= n; + p[1] |= p[0] >> (sizeof(size_t) * 8 - n); + p[0] <<= n; } -static inline void shr(size_t p[2], int n) -{ - if(n >= 8 * sizeof(size_t)) { - n -= 8 * sizeof(size_t); - p[0] = p[1]; - p[1] = 0; - if (!n) return; - } - p[0] >>= n; - p[0] |= p[1] << (sizeof(size_t) * 8 - n); - p[1] >>= n; +static inline void shr(size_t p[2], int n) { + if (n >= 8 * sizeof(size_t)) { + n -= 8 * sizeof(size_t); + p[0] = p[1]; + p[1] = 0; + if (!n) return; + } + p[0] >>= n; + p[0] |= p[1] << (sizeof(size_t) * 8 - n); + p[1] >>= n; } /* power-of-two length for working array so that we can mask indices and * not depend on any invariant of the algorithm for spatial memory safety. * the original size was just 14*sizeof(size_t)+1 */ -#define AR_LEN (16 * sizeof(size_t)) +#define AR_LEN (16 * sizeof(size_t)) #define AR_MASK (AR_LEN - 1) -static void sift(unsigned char *head, size_t width, cmpfun cmp, int pshift, size_t lp[]) -{ - unsigned char *rt, *lf; - unsigned char *ar[AR_LEN]; - int i = 1; - - ar[0] = head; - while(pshift > 1) { - rt = head - width; - lf = head - width - lp[pshift - 2]; - - if(cmp(ar[0], lf) >= 0 && cmp(ar[0], rt) >= 0) { - break; - } - if(cmp(lf, rt) >= 0) { - ar[i++ & AR_MASK] = lf; - head = lf; - pshift -= 1; - } else { - ar[i++ & AR_MASK] = rt; - head = rt; - pshift -= 2; - } - } - cycle(width, ar, i & AR_MASK); +static void sift(unsigned char* head, size_t width, cmpfun cmp, int pshift, + size_t lp[]) { + unsigned char *rt, *lf; + unsigned char* ar[AR_LEN]; + int i = 1; + + ar[0] = head; + while (pshift > 1) { + rt = head - width; + lf = head - width - lp[pshift - 2]; + + if (cmp(ar[0], lf) >= 0 && cmp(ar[0], rt) >= 0) { + break; + } + if (cmp(lf, rt) >= 0) { + ar[i++ & AR_MASK] = lf; + head = lf; + pshift -= 1; + } else { + ar[i++ & AR_MASK] = rt; + head = rt; + pshift -= 2; + } + } + cycle(width, ar, i & AR_MASK); } -static void trinkle(unsigned char *head, size_t width, cmpfun cmp, size_t pp[2], int pshift, int trusty, size_t lp[]) -{ - unsigned char *stepson, - *rt, *lf; - size_t p[2]; - unsigned char *ar[AR_LEN]; - int i = 1; - int trail; - - p[0] = pp[0]; - p[1] = pp[1]; - - ar[0] = head; - while(p[0] != 1 || p[1] != 0) { - stepson = head - lp[pshift]; - if(cmp(stepson, ar[0]) <= 0) { - break; - } - if(!trusty && pshift > 1) { - rt = head - width; - lf = head - width - lp[pshift - 2]; - if(cmp(rt, stepson) >= 0 || cmp(lf, stepson) >= 0) { - break; - } - } - - ar[i++ & AR_MASK] = stepson; - head = stepson; - trail = pntz(p); - shr(p, trail); - pshift += trail; - trusty = 0; - } - if(!trusty) { - cycle(width, ar, i & AR_MASK); - sift(head, width, cmp, pshift, lp); - } +static void trinkle(unsigned char* head, size_t width, cmpfun cmp, size_t pp[2], + int pshift, int trusty, size_t lp[]) { + unsigned char *stepson, *rt, *lf; + size_t p[2]; + unsigned char* ar[AR_LEN]; + int i = 1; + int trail; + + p[0] = pp[0]; + p[1] = pp[1]; + + ar[0] = head; + while (p[0] != 1 || p[1] != 0) { + stepson = head - lp[pshift]; + if (cmp(stepson, ar[0]) <= 0) { + break; + } + if (!trusty && pshift > 1) { + rt = head - width; + lf = head - width - lp[pshift - 2]; + if (cmp(rt, stepson) >= 0 || cmp(lf, stepson) >= 0) { + break; + } + } + + ar[i++ & AR_MASK] = stepson; + head = stepson; + trail = pntz(p); + shr(p, trail); + pshift += trail; + trusty = 0; + } + if (!trusty) { + cycle(width, ar, i & AR_MASK); + sift(head, width, cmp, pshift, lp); + } } -void qsort(void *base, size_t nel, size_t width, cmpfun cmp) -{ - size_t lp[12*sizeof(size_t)]; - size_t i, size = width * nel; - unsigned char *head, *high; - size_t p[2] = {1, 0}; - int pshift = 1; - int trail; - - if (!size) return; - - head = base; - high = head + size - width; - - /* Precompute Leonardo numbers, scaled by element width */ - for(lp[0]=lp[1]=width, i=2; (lp[i]=lp[i-2]+lp[i-1]+width) < size; i++); - - while(head < high) { - if((p[0] & 3) == 3) { - sift(head, width, cmp, pshift, lp); - shr(p, 2); - pshift += 2; - } else { - if(lp[pshift - 1] >= high - head) { - trinkle(head, width, cmp, p, pshift, 0, lp); - } else { - sift(head, width, cmp, pshift, lp); - } - - if(pshift == 1) { - shl(p, 1); - pshift = 0; - } else { - shl(p, pshift - 1); - pshift = 1; - } - } - - p[0] |= 1; - head += width; - } - - trinkle(head, width, cmp, p, pshift, 0, lp); - - while(pshift != 1 || p[0] != 1 || p[1] != 0) { - if(pshift <= 1) { - trail = pntz(p); - shr(p, trail); - pshift += trail; - } else { - shl(p, 2); - pshift -= 2; - p[0] ^= 7; - shr(p, 1); - trinkle(head - lp[pshift] - width, width, cmp, p, pshift + 1, 1, lp); - shl(p, 1); - p[0] |= 1; - trinkle(head - width, width, cmp, p, pshift, 1, lp); - } - head -= width; - } +void qsort(void* base, size_t nel, size_t width, cmpfun cmp) { + size_t lp[12 * sizeof(size_t)]; + size_t i, size = width * nel; + unsigned char *head, *high; + size_t p[2] = {1, 0}; + int pshift = 1; + int trail; + + if (!size) return; + + head = base; + high = head + size - width; + + /* Precompute Leonardo numbers, scaled by element width */ + for (lp[0] = lp[1] = width, i = 2; + (lp[i] = lp[i - 2] + lp[i - 1] + width) < size; i++); + + while (head < high) { + if ((p[0] & 3) == 3) { + sift(head, width, cmp, pshift, lp); + shr(p, 2); + pshift += 2; + } else { + if (lp[pshift - 1] >= high - head) { + trinkle(head, width, cmp, p, pshift, 0, lp); + } else { + sift(head, width, cmp, pshift, lp); + } + + if (pshift == 1) { + shl(p, 1); + pshift = 0; + } else { + shl(p, pshift - 1); + pshift = 1; + } + } + + p[0] |= 1; + head += width; + } + + trinkle(head, width, cmp, p, pshift, 0, lp); + + while (pshift != 1 || p[0] != 1 || p[1] != 0) { + if (pshift <= 1) { + trail = pntz(p); + shr(p, trail); + pshift += trail; + } else { + shl(p, 2); + pshift -= 2; + p[0] ^= 7; + shr(p, 1); + trinkle(head - lp[pshift] - width, width, cmp, p, pshift + 1, 1, lp); + shl(p, 1); + p[0] |= 1; + trinkle(head - width, width, cmp, p, pshift, 1, lp); + } + head -= width; + } } diff --git a/src/abi/abi.c b/src/abi/abi.c @@ -121,11 +121,9 @@ static ABIRecordLayout* compute_record_layout(TargetABI* a, CfreeCgTypeId id) { const CgTypeField* f = &t->record.fields[i]; fl[i].offset = (u32)f->offset; fl[i].bit_offset = f->bit_offset; - fl[i].bit_width = - (f->flags & CFREE_CG_FIELD_BITFIELD) ? f->bit_width : 0; - fl[i].storage_size = f->bit_storage_size - ? f->bit_storage_size - : (u32)abi_cg_sizeof(a, f->type); + fl[i].bit_width = (f->flags & CFREE_CG_FIELD_BITFIELD) ? f->bit_width : 0; + fl[i].storage_size = f->bit_storage_size ? f->bit_storage_size + : (u32)abi_cg_sizeof(a, f->type); } L->size = (u32)t->size; L->align = t->align; diff --git a/src/abi/abi_aapcs64_windows.c b/src/abi/abi_aapcs64_windows.c @@ -19,9 +19,8 @@ #include <string.h> #include "abi/abi_internal.h" -#include "core/core.h" - #include "core/arena.h" +#include "core/core.h" extern ABIFuncInfo* aapcs64_compute_func_info(TargetABI*, CfreeCgTypeId); @@ -45,7 +44,7 @@ static void remap_fp_parts_to_int(TargetABI* a, ABIArgInfo* ai) { } static ABIFuncInfo* aapcs64_windows_compute_func_info(TargetABI* a, - CfreeCgTypeId fn) { + CfreeCgTypeId fn) { ABIFuncInfo* info = aapcs64_compute_func_info(a, fn); /* vararg_on_stack stays 0 — Windows-ARM64 variadics use registers, * unlike Apple. diff --git a/src/abi/abi_rv64.c b/src/abi/abi_rv64.c @@ -35,9 +35,9 @@ enum { RV64_ABI_AGGREGATE_GPR_BYTES = 16, RV64_ABI_GPR_BYTES = 8 }; * bitfields). Returns the number of leaves collected, or > cap if the * record has too many leaves to inspect (caller falls back to GPR pair). */ typedef struct AbiLeaf { - u32 offset; /* byte offset within the outermost aggregate */ - u32 size; /* leaf scalar size in bytes */ - u8 scalar_kind; /* ABIScalarKind */ + u32 offset; /* byte offset within the outermost aggregate */ + u32 size; /* leaf scalar size in bytes */ + u8 scalar_kind; /* ABIScalarKind */ } AbiLeaf; static u32 rv64_collect_leaves(TargetABI* a, CfreeCgTypeId tid, u32 base_off, @@ -150,8 +150,8 @@ static int rv64_classify_fp_aggregate(TargetABI* a, CfreeCgTypeId t, parts[i].size = leaves[i].size; parts[i].align = leaves[i].size ? leaves[i].size : 1u; parts[i].src_offset = leaves[i].offset; - parts[i].cls = (leaves[i].scalar_kind == ABI_SC_FLOAT) ? ABI_CLASS_FP - : ABI_CLASS_INT; + parts[i].cls = + (leaves[i].scalar_kind == ABI_SC_FLOAT) ? ABI_CLASS_FP : ABI_CLASS_INT; } out->kind = ABI_ARG_DIRECT; out->flags = ABI_AF_NONE; diff --git a/src/abi/abi_sysv_x64.c b/src/abi/abi_sysv_x64.c @@ -123,8 +123,7 @@ static int classify_range(TargetABI* a, CfreeCgTypeId t, u32 base, if (i > UINT32_MAX || ei.size > UINT32_MAX || base > UINT32_MAX - (u32)(i * ei.size)) return 0; - if (!classify_range(a, ty->array.elem, base + (u32)(i * ei.size), - cls)) + if (!classify_range(a, ty->array.elem, base + (u32)(i * ei.size), cls)) return 0; } return 1; @@ -234,8 +233,7 @@ static void classify_one(TargetABI* a, CfreeCgTypeId t, ABIArgInfo* out, #define SYSV_X64_FP_MAX_OFFSET \ (SYSV_X64_FP_BASE_OFFSET + SYSV_X64_FP_REG_COUNT * SYSV_X64_FP_SLOT_SIZE) -static ABIFuncInfo* sysv_x64_compute_func_info(TargetABI* a, - CfreeCgTypeId fn) { +static ABIFuncInfo* sysv_x64_compute_func_info(TargetABI* a, CfreeCgTypeId fn) { ABIFuncInfo* info = arena_new(a->c->tu, ABIFuncInfo); const CgType* fnty = cg_type_get(a->c, fn); memset(info, 0, sizeof *info); diff --git a/src/api/archive.c b/src/api/archive.c @@ -52,7 +52,7 @@ static Slice ar_name_basename(Slice in) { for (i = 0; i < in.len; ++i) { if (in.s[i] == '/') start = i + 1; } - return (Slice){ .s = in.s + start, .len = in.len - start }; + return (Slice){.s = in.s + start, .len = in.len - start}; } static int ar_name_needs_longtable(const char* name, size_t len) { diff --git a/src/api/asm_emit.c b/src/api/asm_emit.c @@ -1,5 +1,7 @@ #include <cfree/asm_emit.h> #include <cfree/disasm.h> +#include <stdlib.h> +#include <string.h> #include "arch/arch.h" #include "core/arena.h" @@ -10,9 +12,6 @@ #include "core/slice.h" #include "obj/obj.h" -#include <stdlib.h> -#include <string.h> - #define ASM_BYTES_PER_LINE 16u static CfreeStatus w_str(Writer* w, const char* s) { @@ -131,7 +130,7 @@ static CfreeStatus emit_label(Writer* w, Compiler* c, const SymLabel* lbl) { } static CfreeStatus emit_size_directives(Writer* w, Compiler* c, ObjBuilder* ob, - ObjSecId sec_id) { + ObjSecId sec_id) { ObjSymIter* it = obj_symiter_new(ob); CfreeStatus st = CFREE_OK; if (!it) return CFREE_NOMEM; @@ -180,7 +179,7 @@ static const char* sec_directive(const Section* sec) { } static CfreeStatus emit_data_range(Writer* w, const u8* data, u32 start, - u32 end) { + u32 end) { u32 off; for (off = start; off < end; off += ASM_BYTES_PER_LINE) { u32 rem = end - off; @@ -214,7 +213,7 @@ static CfreeStatus emit_zero_range(Writer* w, u32 size) { } static CfreeStatus emit_disasm_range(Writer* w, ArchDisasm* dasm, - const u8* data, u32 start, u32 end) { + const u8* data, u32 start, u32 end) { u32 off = start; CfreeStatus st; @@ -255,7 +254,7 @@ static CfreeStatus emit_disasm_range(Writer* w, ArchDisasm* dasm, } CfreeStatus cfree_obj_builder_emit_asm(CfreeObjBuilder* builder, - CfreeWriter* out_w) { + CfreeWriter* out_w) { ObjBuilder* ob = (ObjBuilder*)builder; Compiler* c; Writer* w; diff --git a/src/api/core.c b/src/api/core.c @@ -82,7 +82,7 @@ CfreeSym cfree_cg_c_linkage_name(CfreeCompiler* c, CfreeSym source_name) { buf[0] = '_'; if (len) memcpy(buf + 1, name, len); buf[len + 1u] = '\0'; - out = pool_intern_slice(c->global, (Slice){ .s = buf, .len = (u32)(len + 1u) }); + out = pool_intern_slice(c->global, (Slice){.s = buf, .len = (u32)(len + 1u)}); h->free(h, buf, len + 2u); return out; } diff --git a/src/api/disasm.c b/src/api/disasm.c @@ -1,7 +1,6 @@ /* Public disassembler API. */ #include <cfree/disasm.h> - #include <stdint.h> #include <string.h> @@ -51,9 +50,8 @@ static Slice dasm_overlay(CfreeDisasmIter* it, uint64_t vaddr, r->section_id != (ObjSecId)(it->annot_section + 1)) continue; if ((u64)r->offset < want || (u64)r->offset >= end) continue; - const ObjSym* sym = (r->sym != OBJ_SYM_NONE) - ? obj_symbol_get(obj, r->sym) - : NULL; + const ObjSym* sym = + (r->sym != OBJ_SYM_NONE) ? obj_symbol_get(obj, r->sym) : NULL; if (sym && sym->name) { Compiler* oc = obj_compiler(obj); Slice nm = oc ? pool_slice(oc->global, sym->name) : SLICE_NULL; @@ -214,7 +212,8 @@ static Slice dasm_sym_at(const CfreeObjFile* f, uint32_t section_idx, CfreeObjSymIter* si = NULL; Slice found = SLICE_NULL; CfreeObjSymInfo s; - if (cfree_obj_symiter_new((CfreeObjFile*)f, &si) != CFREE_OK) return SLICE_NULL; + if (cfree_obj_symiter_new((CfreeObjFile*)f, &si) != CFREE_OK) + return SLICE_NULL; for (;;) { CfreeIterResult r = cfree_obj_symiter_next(si, &s); if (r != CFREE_ITER_ITEM) break; diff --git a/src/api/object_file.c b/src/api/object_file.c @@ -101,8 +101,8 @@ CfreeStatus cfree_obj_section(const CfreeObjFile* f, CfreeObjSection idx, if (idx >= obj_section_count(f->ob)) return CFREE_NOT_FOUND; sec = obj_section_get(f->ob, (ObjSecId)(idx + 1)); if (!sec) return CFREE_NOT_FOUND; - out->name = sec->name ? pool_slice(f->compiler.global, sec->name) - : SLICE_LIT(""); + out->name = + sec->name ? pool_slice(f->compiler.global, sec->name) : SLICE_LIT(""); out->kind = (CfreeSecKind)sec->kind; out->flags = (uint32_t)sec->flags; out->size = sec->bss_size ? sec->bss_size : sec->bytes.total; @@ -201,8 +201,8 @@ CfreeStatus cfree_obj_section_by_name(const CfreeObjFile* f, CfreeSlice name, static void fill_syminfo(const CfreeObjFile* f, ObjSymId id, const ObjSym* sym, CfreeObjSymInfo* out) { - out->name = sym->name ? pool_slice(f->compiler.global, sym->name) - : SLICE_LIT(""); + out->name = + sym->name ? pool_slice(f->compiler.global, sym->name) : SLICE_LIT(""); out->id = (id != OBJ_SYM_NONE) ? (CfreeObjSymbol)id : CFREE_OBJ_SYMBOL_NONE; out->bind = (CfreeSymBind)sym->bind; out->kind = (CfreeSymKind)sym->kind; @@ -414,8 +414,8 @@ CfreeStatus cfree_obj_groupiter_new(CfreeObjFile* f, CfreeObjGroupIter** out) { CfreeObjGroupIter* it; if (!f || !out) return CFREE_INVALID; h = f->ctx->heap; - it = (CfreeObjGroupIter*)h->alloc(h, sizeof(*it), - _Alignof(CfreeObjGroupIter)); + it = + (CfreeObjGroupIter*)h->alloc(h, sizeof(*it), _Alignof(CfreeObjGroupIter)); if (!it) return CFREE_NOMEM; memset(it, 0, sizeof(*it)); it->file = f; @@ -438,8 +438,8 @@ CfreeIterResult cfree_obj_groupiter_next(CfreeObjGroupIter* it, h = it->file->ctx->heap; if (entry.group->nsections > it->seccap) { CfreeObjSection* nb; - nb = (CfreeObjSection*)h->alloc( - h, sizeof(*nb) * entry.group->nsections, _Alignof(CfreeObjSection)); + nb = (CfreeObjSection*)h->alloc(h, sizeof(*nb) * entry.group->nsections, + _Alignof(CfreeObjSection)); if (!nb) return CFREE_ITER_ERROR; if (it->secbuf) h->free(h, it->secbuf, sizeof(*it->secbuf) * it->seccap); it->secbuf = nb; @@ -447,8 +447,8 @@ CfreeIterResult cfree_obj_groupiter_next(CfreeObjGroupIter* it, } for (i = 0; i < entry.group->nsections; ++i) { ObjSecId sid = entry.group->sections[i]; - it->secbuf[i] = (sid != OBJ_SEC_NONE) ? (CfreeObjSection)(sid - 1) - : CFREE_SECTION_NONE; + it->secbuf[i] = + (sid != OBJ_SEC_NONE) ? (CfreeObjSection)(sid - 1) : CFREE_SECTION_NONE; } out->name = entry.group->name ? pool_slice(it->file->compiler.global, entry.group->name) diff --git a/src/api/wasm.c b/src/api/wasm.c @@ -5,10 +5,10 @@ * into instance slots) lives in lang/wasm/host_imports.c so the wasm * frontend owns the metadata wire format. */ -#include "core/core.h" - #include <cfree/wasm.h> +#include "core/core.h" + CFREE_API void cfree_wasm_set_host_imports(CfreeCompiler* c, const CfreeWasmHostImport* imports, size_t nimports, diff --git a/src/arch/aa64/alloc.c b/src/arch/aa64/alloc.c @@ -105,8 +105,7 @@ static void aa_load_label_addr(CGTarget* t, Operand dst, Label l) { MCEmitter* mc = t->mc; u32 rd; if (dst.kind != OPK_REG) { - compiler_panic(t->c, mc->loc, - "aa64: load_label_addr dst must be REG"); + compiler_panic(t->c, mc->loc, "aa64: load_label_addr dst must be REG"); } rd = reg_num(dst); aa64_emit32(mc, aa64_adr(rd, 0u, 0u)); @@ -115,44 +114,61 @@ static void aa_load_label_addr(CGTarget* t, Operand dst, Label l) { mc->emit_label_ref(mc, (MCLabel)l, R_AARCH64_INTRA_LABEL_ADDR, 16, 0); } -static void aa_indirect_branch(CGTarget* t, Operand addr, - const Label* targets, u32 ntargets) { +static void aa_indirect_branch(CGTarget* t, Operand addr, const Label* targets, + u32 ntargets) { /* BR Xn — register-indirect branch (no fixup needed). */ MCEmitter* mc = t->mc; (void)targets; (void)ntargets; if (addr.kind != OPK_REG) { - compiler_panic(t->c, mc->loc, - "aa64: indirect_branch expects REG operand"); + compiler_panic(t->c, mc->loc, "aa64: indirect_branch expects REG operand"); } aa64_emit32(mc, aa64_br(reg_num(addr))); } static u32 cmp_to_cond(CmpOp op) { switch (op) { - case CMP_EQ: return 0x0u; - case CMP_NE: return 0x1u; - case CMP_LT_U: return 0x3u; - case CMP_LE_U: return 0x9u; - case CMP_GT_U: return 0x8u; - case CMP_GE_U: return 0x2u; - case CMP_LT_S: return 0xbu; - case CMP_LE_S: return 0xdu; - case CMP_GT_S: return 0xcu; - case CMP_GE_S: return 0xau; - default: return 0x0u; + case CMP_EQ: + return 0x0u; + case CMP_NE: + return 0x1u; + case CMP_LT_U: + return 0x3u; + case CMP_LE_U: + return 0x9u; + case CMP_GT_U: + return 0x8u; + case CMP_GE_U: + return 0x2u; + case CMP_LT_S: + return 0xbu; + case CMP_LE_S: + return 0xdu; + case CMP_GT_S: + return 0xcu; + case CMP_GE_S: + return 0xau; + default: + return 0x0u; } } static u32 fp_cmp_to_cond(CmpOp op) { switch (op) { - case CMP_EQ: return 0x0u; /* equal; unordered is false */ - case CMP_NE: return 0x1u; /* not equal; unordered is true */ - case CMP_LT_F: return 0x4u; /* MI: less-than only */ - case CMP_LE_F: return 0x9u; /* LS: less-or-equal only */ - case CMP_GT_F: return 0xcu; /* GT excludes unordered */ - case CMP_GE_F: return 0xau; /* GE excludes unordered */ - default: return cmp_to_cond(op); + case CMP_EQ: + return 0x0u; /* equal; unordered is false */ + case CMP_NE: + return 0x1u; /* not equal; unordered is true */ + case CMP_LT_F: + return 0x4u; /* MI: less-than only */ + case CMP_LE_F: + return 0x9u; /* LS: less-or-equal only */ + case CMP_GT_F: + return 0xcu; /* GT excludes unordered */ + case CMP_GE_F: + return 0xau; /* GE excludes unordered */ + default: + return cmp_to_cond(op); } } @@ -168,8 +184,7 @@ void emit_cmp_ab(CGTarget* t, Operand a_op, Operand b_op) { } } u32 rn = aa64_force_reg_int(t, a_op, sf, AA_TMP0); - u32 rm = - aa64_force_reg_int(t, b_op, sf, (rn == AA_TMP0) ? AA_TMP1 : AA_TMP0); + u32 rm = aa64_force_reg_int(t, b_op, sf, (rn == AA_TMP0) ? AA_TMP1 : AA_TMP0); aa64_emit32(mc, aa64_subs_reg(sf, /*Rd=ZR*/ 31u, rn, rm)); } diff --git a/src/arch/aa64/asm.c b/src/arch/aa64/asm.c @@ -20,13 +20,13 @@ #include "arch/aa64/isa.h" #include "arch/aa64/regs.h" #include "arch/arch.h" +#include "asm/asm_helpers.h" +#include "asm/asm_lex.h" #include "core/arena.h" #include "core/pool.h" #include "core/slice.h" #include "core/strbuf.h" -#include "asm/asm_lex.h" #include "obj/obj.h" -#include "asm/asm_helpers.h" /* ---- public handle ---- */ @@ -64,9 +64,7 @@ AA64Asm* aa64_asm_open(Compiler* c) { void aa64_asm_close(AA64Asm* a) { (void)a; } -ArchAsm* aa64_arch_asm_new(Compiler* c) { - return &aa64_asm_open(c)->base; -} +ArchAsm* aa64_arch_asm_new(Compiler* c) { return &aa64_asm_open(c)->base; } static void aa64_arch_asm_insn(ArchAsm* base, AsmDriver* d, Sym mnemonic) { aa64_asm_insn((AA64Asm*)base, d, mnemonic); @@ -76,10 +74,9 @@ static void aa64_arch_asm_destroy(ArchAsm* base) { aa64_asm_close((AA64Asm*)base); } -void aa64_inline_bind(AA64Asm* a, - const AsmConstraint* outs, u32 nout, Operand* out_ops, - const AsmConstraint* ins, u32 nin, const Operand* in_ops, - const Sym* clobbers, u32 nclob) { +void aa64_inline_bind(AA64Asm* a, const AsmConstraint* outs, u32 nout, + Operand* out_ops, const AsmConstraint* ins, u32 nin, + const Operand* in_ops, const Sym* clobbers, u32 nclob) { a->outs = outs; a->out_ops = out_ops; a->ins = ins; @@ -118,9 +115,9 @@ static int icase_eq(const char* a, size_t an, const char* b) { typedef struct AA64Reg { u32 num; u8 is64; - u8 is_sp; /* 1 if the spelling was "sp" / "wsp" */ - u8 is_fp; /* 1 for SIMD/FP register spellings accepted in FP forms */ - u8 fp_bytes; /* 8 for Dn, 16 for Qn */ + u8 is_sp; /* 1 if the spelling was "sp" / "wsp" */ + u8 is_fp; /* 1 for SIMD/FP register spellings accepted in FP forms */ + u8 fp_bytes; /* 8 for Dn, 16 for Qn */ } AA64Reg; static int parse_reg_from_ident(AsmDriver* d, Sym ident, AA64Reg* out) { @@ -204,13 +201,11 @@ static int parse_reg_from_ident(AsmDriver* d, Sym ident, AA64Reg* out) { return 0; } -static int parse_fp_pair_reg_from_ident(AsmDriver* d, Sym ident, - AA64Reg* out) { +static int parse_fp_pair_reg_from_ident(AsmDriver* d, Sym ident, AA64Reg* out) { Slice sl = pool_slice(asm_driver_pool(d), ident); const char* p = sl.s; size_t n = sl.len; - if (!p || n < 2 || - (p[0] != 'd' && p[0] != 'D' && p[0] != 'q' && p[0] != 'Q')) + if (!p || n < 2 || (p[0] != 'd' && p[0] != 'D' && p[0] != 'q' && p[0] != 'Q')) return 0; u32 r = 0; for (size_t i = 1; i < n; ++i) { @@ -289,22 +284,38 @@ static int parse_cond_from_ident(AsmDriver* d, Sym ident, u32* out) { const char* s = sl.s; size_t n = sl.len; if (!s) return 0; - if (icase_eq(s, n, "eq")) *out = 0; - else if (icase_eq(s, n, "ne")) *out = 1; - else if (icase_eq(s, n, "cs") || icase_eq(s, n, "hs")) *out = 2; - else if (icase_eq(s, n, "cc") || icase_eq(s, n, "lo")) *out = 3; - else if (icase_eq(s, n, "mi")) *out = 4; - else if (icase_eq(s, n, "pl")) *out = 5; - else if (icase_eq(s, n, "vs")) *out = 6; - else if (icase_eq(s, n, "vc")) *out = 7; - else if (icase_eq(s, n, "hi")) *out = 8; - else if (icase_eq(s, n, "ls")) *out = 9; - else if (icase_eq(s, n, "ge")) *out = 10; - else if (icase_eq(s, n, "lt")) *out = 11; - else if (icase_eq(s, n, "gt")) *out = 12; - else if (icase_eq(s, n, "le")) *out = 13; - else if (icase_eq(s, n, "al")) *out = 14; - else return 0; + if (icase_eq(s, n, "eq")) + *out = 0; + else if (icase_eq(s, n, "ne")) + *out = 1; + else if (icase_eq(s, n, "cs") || icase_eq(s, n, "hs")) + *out = 2; + else if (icase_eq(s, n, "cc") || icase_eq(s, n, "lo")) + *out = 3; + else if (icase_eq(s, n, "mi")) + *out = 4; + else if (icase_eq(s, n, "pl")) + *out = 5; + else if (icase_eq(s, n, "vs")) + *out = 6; + else if (icase_eq(s, n, "vc")) + *out = 7; + else if (icase_eq(s, n, "hi")) + *out = 8; + else if (icase_eq(s, n, "ls")) + *out = 9; + else if (icase_eq(s, n, "ge")) + *out = 10; + else if (icase_eq(s, n, "lt")) + *out = 11; + else if (icase_eq(s, n, "gt")) + *out = 12; + else if (icase_eq(s, n, "le")) + *out = 13; + else if (icase_eq(s, n, "al")) + *out = 14; + else + return 0; return 1; } @@ -369,14 +380,14 @@ static u32 parse_barrier_option(AsmDriver* d, int allow_dmb_ld_st) { Slice sl = pool_slice(asm_driver_pool(d), t.v.ident); const char* s = sl.s; size_t n = sl.len; - if (icase_eq(s, n, "sy")) return AA64_BARRIER_OPT_SY; - if (icase_eq(s, n, "ish")) return AA64_BARRIER_OPT_ISH; + if (icase_eq(s, n, "sy")) return AA64_BARRIER_OPT_SY; + if (icase_eq(s, n, "ish")) return AA64_BARRIER_OPT_ISH; if (icase_eq(s, n, "ishld")) return AA64_BARRIER_OPT_ISHLD; if (icase_eq(s, n, "ishst")) return AA64_BARRIER_OPT_ISHST; - if (icase_eq(s, n, "nsh")) return AA64_BARRIER_OPT_NSH; + if (icase_eq(s, n, "nsh")) return AA64_BARRIER_OPT_NSH; if (icase_eq(s, n, "nshld")) return AA64_BARRIER_OPT_NSHLD; if (icase_eq(s, n, "nshst")) return AA64_BARRIER_OPT_NSHST; - if (icase_eq(s, n, "osh")) return AA64_BARRIER_OPT_OSH; + if (icase_eq(s, n, "osh")) return AA64_BARRIER_OPT_OSH; if (icase_eq(s, n, "oshld")) return AA64_BARRIER_OPT_OSHLD; if (icase_eq(s, n, "oshst")) return AA64_BARRIER_OPT_OSHST; if (allow_dmb_ld_st) { @@ -387,8 +398,7 @@ static u32 parse_barrier_option(AsmDriver* d, int allow_dmb_ld_st) { } /* Numeric form: '#imm4'. */ i64 imm = parse_imm_const(d); - if (imm < 0 || imm > 15) - asm_driver_panic(d, "asm: barrier imm out of range"); + if (imm < 0 || imm > 15) asm_driver_panic(d, "asm: barrier imm out of range"); return (u32)imm; } @@ -487,8 +497,7 @@ static void p_movwide(AsmDriver* d, u32 opc) { if (asm_driver_eat_comma(d)) { /* lsl #N (N is 0/16/32/48). */ AsmTok lid = asm_driver_next(d); - if (lid.kind != ASM_TOK_IDENT) - asm_driver_panic(d, "asm: expected 'lsl'"); + if (lid.kind != ASM_TOK_IDENT) asm_driver_panic(d, "asm: expected 'lsl'"); Slice lsl = pool_slice(asm_driver_pool(d), lid.v.ident); const char* lp = lsl.s; size_t ln = lsl.len; @@ -509,8 +518,12 @@ static void p_movwide(AsmDriver* d, u32 opc) { static void p_except(AsmDriver* d, u32 form) { i64 imm = parse_imm_const(d); switch (form) { - case 0: emit32(d, aa64_svc((u32)imm)); break; - case 1: emit32(d, aa64_brk((u32)imm)); break; + case 0: + emit32(d, aa64_svc((u32)imm)); + break; + case 1: + emit32(d, aa64_brk((u32)imm)); + break; case 2: { /* HLT */ u32 word = AA64_EXCEPT_FAMILY_MATCH | ((u32)2 << 21) | @@ -518,7 +531,8 @@ static void p_except(AsmDriver* d, u32 form) { emit32(d, word); break; } - default: asm_driver_panic(d, "asm: bad exception form"); + default: + asm_driver_panic(d, "asm: bad exception form"); } } @@ -531,11 +545,16 @@ static int parse_shift_mod(AsmDriver* d, u32* shift_out, u32* imm6_out) { const char* p = sl.s; size_t n = sl.len; u32 sh; - if (icase_eq(p, n, "lsl")) sh = 0; - else if (icase_eq(p, n, "lsr")) sh = 1; - else if (icase_eq(p, n, "asr")) sh = 2; - else if (icase_eq(p, n, "ror")) sh = 3; - else return 0; + if (icase_eq(p, n, "lsl")) + sh = 0; + else if (icase_eq(p, n, "lsr")) + sh = 1; + else if (icase_eq(p, n, "asr")) + sh = 2; + else if (icase_eq(p, n, "ror")) + sh = 3; + else + return 0; (void)asm_driver_next(d); i64 imm = parse_imm_const(d); if (imm < 0 || imm > 63) @@ -580,15 +599,22 @@ static void p_addsub(AsmDriver* d, int is_sub, int set_flags) { if (!lp || !icase_eq(lp, ln, "lsl")) asm_driver_panic(d, "asm: expected 'lsl'"); i64 s = parse_imm_const(d); - if (s == 12) sh = 1; - else if (s == 0) sh = 0; - else asm_driver_panic(d, "asm: add/sub imm: lsl must be 0 or 12"); + if (s == 12) + sh = 1; + else if (s == 0) + sh = 0; + else + asm_driver_panic(d, "asm: add/sub imm: lsl must be 0 or 12"); } if (imm < 0 || imm > 0xfff) asm_driver_panic(d, "asm: add/sub imm out of range"); - u32 word = aa64_addsubimm_pack((AA64AddSubImm){ - .sf = rd.is64, .op = (u32)is_sub, .S = (u32)set_flags, .sh = sh, - .imm12 = (u32)imm, .Rn = rn.num, .Rd = rd.num}); + u32 word = aa64_addsubimm_pack((AA64AddSubImm){.sf = rd.is64, + .op = (u32)is_sub, + .S = (u32)set_flags, + .sh = sh, + .imm12 = (u32)imm, + .Rn = rn.num, + .Rd = rd.num}); emit32(d, word); return; } @@ -604,10 +630,14 @@ static void p_addsub(AsmDriver* d, int is_sub, int set_flags) { if (!parse_shift_mod(d, &shift, &imm6)) asm_driver_panic(d, "asm: add/sub reg: expected shift modifier"); } - u32 word = aa64_addsubsr_pack((AA64AddSubSR){ - .sf = rd.is64, .op = (u32)is_sub, .S = (u32)set_flags, - .shift = shift, .Rm = rm.num, .imm6 = imm6, .Rn = rn.num, - .Rd = rd.num}); + u32 word = aa64_addsubsr_pack((AA64AddSubSR){.sf = rd.is64, + .op = (u32)is_sub, + .S = (u32)set_flags, + .shift = shift, + .Rm = rm.num, + .imm6 = imm6, + .Rn = rn.num, + .Rd = rd.num}); emit32(d, word); } @@ -631,16 +661,20 @@ static void p_cmp(AsmDriver* d, int is_neg /* cmn flips op */) { if (!lp || !icase_eq(lp, ln, "lsl")) asm_driver_panic(d, "asm: cmp imm: expected 'lsl'"); i64 s = parse_imm_const(d); - if (s == 12) sh = 1; + if (s == 12) + sh = 1; else if (s != 0) asm_driver_panic(d, "asm: cmp imm: lsl must be 0 or 12"); } if (imm < 0 || imm > 0xfff) asm_driver_panic(d, "asm: cmp imm out of range"); - u32 word = aa64_addsubimm_pack( - (AA64AddSubImm){.sf = rn.is64, .op = (u32)(!is_neg), .S = 1, - .sh = sh, .imm12 = (u32)imm, .Rn = rn.num, - .Rd = AA64_ZR}); + u32 word = aa64_addsubimm_pack((AA64AddSubImm){.sf = rn.is64, + .op = (u32)(!is_neg), + .S = 1, + .sh = sh, + .imm12 = (u32)imm, + .Rn = rn.num, + .Rd = AA64_ZR}); emit32(d, word); return; } @@ -650,9 +684,14 @@ static void p_cmp(AsmDriver* d, int is_neg /* cmn flips op */) { if (rm.is64 != rn.is64) asm_driver_panic(d, "asm: cmp: width mismatch"); u32 shift = 0, imm6 = 0; if (asm_driver_eat_comma(d)) parse_shift_mod(d, &shift, &imm6); - u32 word = aa64_addsubsr_pack((AA64AddSubSR){ - .sf = rn.is64, .op = (u32)(!is_neg), .S = 1, .shift = shift, - .Rm = rm.num, .imm6 = imm6, .Rn = rn.num, .Rd = AA64_ZR}); + u32 word = aa64_addsubsr_pack((AA64AddSubSR){.sf = rn.is64, + .op = (u32)(!is_neg), + .S = 1, + .shift = shift, + .Rm = rm.num, + .imm6 = imm6, + .Rn = rn.num, + .Rd = AA64_ZR}); emit32(d, word); } @@ -709,9 +748,14 @@ static void p_neg(AsmDriver* d, int set_flags) { if (rd.is64 != rm.is64) asm_driver_panic(d, "asm: neg: width mismatch"); u32 shift = 0, imm6 = 0; if (asm_driver_eat_comma(d)) parse_shift_mod(d, &shift, &imm6); - u32 word = aa64_addsubsr_pack((AA64AddSubSR){ - .sf = rd.is64, .op = 1, .S = (u32)set_flags, .shift = shift, - .Rm = rm.num, .imm6 = imm6, .Rn = AA64_ZR, .Rd = rd.num}); + u32 word = aa64_addsubsr_pack((AA64AddSubSR){.sf = rd.is64, + .op = 1, + .S = (u32)set_flags, + .shift = shift, + .Rm = rm.num, + .imm6 = imm6, + .Rn = AA64_ZR, + .Rd = rd.num}); emit32(d, word); } @@ -726,9 +770,14 @@ static void p_log_sr(AsmDriver* d, u32 opc, u32 N) { asm_driver_panic(d, "asm: logical: width mismatch"); u32 shift = 0, imm6 = 0; if (asm_driver_eat_comma(d)) parse_shift_mod(d, &shift, &imm6); - u32 word = aa64_logsr_pack((AA64LogSR){ - .sf = rd.is64, .opc = opc, .shift = shift, .N = N, .Rm = rm.num, - .imm6 = imm6, .Rn = rn.num, .Rd = rd.num}); + u32 word = aa64_logsr_pack((AA64LogSR){.sf = rd.is64, + .opc = opc, + .shift = shift, + .N = N, + .Rm = rm.num, + .imm6 = imm6, + .Rn = rn.num, + .Rd = rd.num}); emit32(d, word); } @@ -743,9 +792,13 @@ static void p_dp3(AsmDriver* d, u32 o0) { AA64Reg ra = parse_reg(d); if (rd.is64 != rn.is64 || rd.is64 != rm.is64 || rd.is64 != ra.is64) asm_driver_panic(d, "asm: dp3: width mismatch"); - u32 word = aa64_dp3_pack((AA64DP3){ - .sf = rd.is64, .op31 = 0, .o0 = o0, .Rm = rm.num, .Ra = ra.num, - .Rn = rn.num, .Rd = rd.num}); + u32 word = aa64_dp3_pack((AA64DP3){.sf = rd.is64, + .op31 = 0, + .o0 = o0, + .Rm = rm.num, + .Ra = ra.num, + .Rn = rn.num, + .Rd = rd.num}); emit32(d, word); } @@ -758,9 +811,13 @@ static void p_mul(AsmDriver* d, u32 o0) { AA64Reg rm = parse_reg(d); if (rd.is64 != rn.is64 || rd.is64 != rm.is64) asm_driver_panic(d, "asm: mul: width mismatch"); - u32 word = aa64_dp3_pack((AA64DP3){ - .sf = rd.is64, .op31 = 0, .o0 = o0, .Rm = rm.num, .Ra = AA64_ZR, - .Rn = rn.num, .Rd = rd.num}); + u32 word = aa64_dp3_pack((AA64DP3){.sf = rd.is64, + .op31 = 0, + .o0 = o0, + .Rm = rm.num, + .Ra = AA64_ZR, + .Rn = rn.num, + .Rd = rd.num}); emit32(d, word); } @@ -773,8 +830,10 @@ static void p_dp2(AsmDriver* d, u32 opcode) { AA64Reg rm = parse_reg(d); if (rd.is64 != rn.is64 || rd.is64 != rm.is64) asm_driver_panic(d, "asm: dp2: width mismatch"); - u32 word = aa64_dp2_pack((AA64DP2){.sf = rd.is64, .opcode = opcode, - .Rm = rm.num, .Rn = rn.num, + u32 word = aa64_dp2_pack((AA64DP2){.sf = rd.is64, + .opcode = opcode, + .Rm = rm.num, + .Rn = rn.num, .Rd = rd.num}); emit32(d, word); } @@ -791,8 +850,8 @@ static void emit_branch_imm(AsmDriver* d, u32 op_bl, ObjSymId target, u32 ofs = mc->pos(mc) - 4; RelocKind k = op_bl ? R_AARCH64_CALL26 : R_AARCH64_JUMP26; if (target != OBJ_SYM_NONE) { - mc->emit_reloc_at(mc, asm_driver_cur_section(d), ofs, k, target, - addend, 1, 0); + mc->emit_reloc_at(mc, asm_driver_cur_section(d), ofs, k, target, addend, 1, + 0); } else { /* Pure constant displacement is rare in real .s; reject it now. * The recommended form is to use a label and let the assembler @@ -823,8 +882,8 @@ static void p_b_cond(AsmDriver* d, u32 cond) { emit32(d, word); MCEmitter* mc = asm_driver_mc(d); u32 ofs = mc->pos(mc) - 4; - mc->emit_reloc_at(mc, asm_driver_cur_section(d), ofs, - R_AARCH64_CONDBR19, sym, off, 1, 0); + mc->emit_reloc_at(mc, asm_driver_cur_section(d), ofs, R_AARCH64_CONDBR19, sym, + off, 1, 0); } static void p_cbz(AsmDriver* d, u32 op) { @@ -835,13 +894,13 @@ static void p_cbz(AsmDriver* d, u32 op) { parse_imm_sym(d, &sym, &off); if (sym == OBJ_SYM_NONE) asm_driver_panic(d, "asm: cbz: symbolic target required"); - u32 word = aa64_cb_pack((AA64CB){.sf = rt.is64, .op = op, .imm19 = 0, - .Rt = rt.num}); + u32 word = + aa64_cb_pack((AA64CB){.sf = rt.is64, .op = op, .imm19 = 0, .Rt = rt.num}); emit32(d, word); MCEmitter* mc = asm_driver_mc(d); u32 ofs = mc->pos(mc) - 4; - mc->emit_reloc_at(mc, asm_driver_cur_section(d), ofs, - R_AARCH64_CONDBR19, sym, off, 1, 0); + mc->emit_reloc_at(mc, asm_driver_cur_section(d), ofs, R_AARCH64_CONDBR19, sym, + off, 1, 0); } /* Memory-operand parser for [Xn], [Xn, #imm], [Xn, #imm]!. @@ -850,7 +909,7 @@ static void p_cbz(AsmDriver* d, u32 op) { * imm is the literal byte offset (no scaling). */ typedef struct AA64Mem { AA64Reg base; - i64 imm; /* byte offset (literal as written) */ + i64 imm; /* byte offset (literal as written) */ u8 pre_index; u8 has_offset; u8 pad[2]; @@ -859,8 +918,7 @@ typedef struct AA64Mem { static AA64Mem parse_mem(AsmDriver* d) { AA64Mem m; memset(&m, 0, sizeof m); - if (!asm_driver_eat_punct(d, '[')) - asm_driver_panic(d, "asm: expected '['"); + if (!asm_driver_eat_punct(d, '[')) asm_driver_panic(d, "asm: expected '['"); m.base = parse_reg(d); if (!m.base.is64) asm_driver_panic(d, "asm: ldr/str: base register must be 64-bit"); @@ -869,8 +927,7 @@ static AA64Mem parse_mem(AsmDriver* d) { m.imm = parse_imm_const(d); m.has_offset = 1; } - if (!asm_driver_eat_punct(d, ']')) - asm_driver_panic(d, "asm: expected ']'"); + if (!asm_driver_eat_punct(d, ']')) asm_driver_panic(d, "asm: expected ']'"); if (asm_driver_eat_punct(d, '!')) m.pre_index = 1; return m; } @@ -890,18 +947,24 @@ static void p_ldr_str(AsmDriver* d, int is_load) { if (m.imm >= 0 && (i64)((u64)m.imm % scale) == 0 && (u64)m.imm / scale <= 0xfff) { u32 imm12 = (u32)((u64)m.imm / scale); - u32 word = aa64_ldst_uimm_pack((AA64LdStUimm){ - .size = size, .V = 0, .opc = opc, .imm12 = imm12, - .Rn = m.base.num, .Rt = rt.num}); + u32 word = aa64_ldst_uimm_pack((AA64LdStUimm){.size = size, + .V = 0, + .opc = opc, + .imm12 = imm12, + .Rn = m.base.num, + .Rt = rt.num}); emit32(d, word); return; } /* Fall back to unscaled signed-imm9 (LDUR/STUR). */ if (m.imm >= -256 && m.imm <= 255) { u32 imm9 = (u32)((u64)m.imm & 0x1ffu); - u32 word = aa64_ldst_simm9_pack((AA64LdStSimm9){ - .size = size, .V = 0, .opc = opc, .imm9 = imm9, - .Rn = m.base.num, .Rt = rt.num}); + u32 word = aa64_ldst_simm9_pack((AA64LdStSimm9){.size = size, + .V = 0, + .opc = opc, + .imm9 = imm9, + .Rn = m.base.num, + .Rt = rt.num}); emit32(d, word); return; } @@ -920,10 +983,13 @@ static void p_ldur_stur(AsmDriver* d, int is_load) { if (m.imm < -256 || m.imm > 255) asm_driver_panic(d, "asm: ldur/stur: imm9 out of range"); u32 imm9 = (u32)((u64)m.imm & 0x1ffu); - u32 word = aa64_ldst_simm9_pack((AA64LdStSimm9){ - .size = size, .V = 0, - .opc = is_load ? AA64_LDST_OPC_LDR : AA64_LDST_OPC_STR, - .imm9 = imm9, .Rn = m.base.num, .Rt = rt.num}); + u32 word = aa64_ldst_simm9_pack( + (AA64LdStSimm9){.size = size, + .V = 0, + .opc = is_load ? AA64_LDST_OPC_LDR : AA64_LDST_OPC_STR, + .imm9 = imm9, + .Rn = m.base.num, + .Rt = rt.num}); emit32(d, word); } @@ -945,14 +1011,14 @@ static void p_ldp_stp(AsmDriver* d, int is_load) { i64 imm7 = m.imm / (i64)scale; if (imm7 < -64 || imm7 > 63) asm_driver_panic(d, "asm: ldp/stp: imm7 out of range"); - AA64LdStPPre f = {.opc = rt.is_fp ? (rt.fp_bytes == 16u ? 2u : 1u) - : (rt.is64 ? 2u : 0u), - .V = rt.is_fp ? 1u : 0u, - .L = is_load ? 1u : 0u, - .imm7 = (u32)imm7 & 0x7fu, - .Rt2 = rt2.num, - .Rn = m.base.num, - .Rt = rt.num}; + AA64LdStPPre f = { + .opc = rt.is_fp ? (rt.fp_bytes == 16u ? 2u : 1u) : (rt.is64 ? 2u : 0u), + .V = rt.is_fp ? 1u : 0u, + .L = is_load ? 1u : 0u, + .imm7 = (u32)imm7 & 0x7fu, + .Rt2 = rt2.num, + .Rn = m.base.num, + .Rt = rt.num}; if (m.pre_index) emit32(d, aa64_ldstp_pre_pack(f)); else @@ -969,7 +1035,9 @@ static void p_adr(AsmDriver* d, int is_adrp) { if (sym == OBJ_SYM_NONE) asm_driver_panic(d, "asm: adr/adrp: symbol required"); AA64PCRelAdr f = {.op = is_adrp ? AA64_ADR_OP_ADRP : AA64_ADR_OP_ADR, - .immlo = 0, .immhi = 0, .Rd = rd.num}; + .immlo = 0, + .immhi = 0, + .Rd = rd.num}; emit32(d, aa64_pcrel_adr_pack(f)); MCEmitter* mc = asm_driver_mc(d); u32 ofs = mc->pos(mc) - 4; @@ -1121,14 +1189,22 @@ static const AA64Mn kTable[] = { {"stp", p_stp_, 0}, {"adr", p_adr_, 0}, {"adrp", p_adrp_, 0}, - {"b.eq", p_b_eq, 0}, {"b.ne", p_b_ne, 0}, - {"b.cs", p_b_cs, 0}, {"b.hs", p_b_hs, 0}, - {"b.cc", p_b_cc, 0}, {"b.lo", p_b_lo, 0}, - {"b.mi", p_b_mi, 0}, {"b.pl", p_b_pl, 0}, - {"b.vs", p_b_vs, 0}, {"b.vc", p_b_vc, 0}, - {"b.hi", p_b_hi, 0}, {"b.ls", p_b_ls, 0}, - {"b.ge", p_b_ge, 0}, {"b.lt", p_b_lt, 0}, - {"b.gt", p_b_gt, 0}, {"b.le", p_b_le, 0}, + {"b.eq", p_b_eq, 0}, + {"b.ne", p_b_ne, 0}, + {"b.cs", p_b_cs, 0}, + {"b.hs", p_b_hs, 0}, + {"b.cc", p_b_cc, 0}, + {"b.lo", p_b_lo, 0}, + {"b.mi", p_b_mi, 0}, + {"b.pl", p_b_pl, 0}, + {"b.vs", p_b_vs, 0}, + {"b.vc", p_b_vc, 0}, + {"b.hi", p_b_hi, 0}, + {"b.ls", p_b_ls, 0}, + {"b.ge", p_b_ge, 0}, + {"b.lt", p_b_lt, 0}, + {"b.gt", p_b_gt, 0}, + {"b.le", p_b_le, 0}, {"b.al", p_b_al, 0}, {NULL, NULL, 0}, }; @@ -1190,7 +1266,8 @@ static void render_indirect(StrBuf* sb, Reg base, i32 ofs) { _Noreturn static void inline_panic(AA64Asm* a, const char* msg) { SrcLoc loc = {0, 0, 0}; - compiler_panic(a->c, loc, "inline asm: %.*s", SLICE_ARG(slice_from_cstr(msg))); + compiler_panic(a->c, loc, "inline asm: %.*s", + SLICE_ARG(slice_from_cstr(msg))); } /* Resolve operand index N → (kind=0 forced default, 1=force-w, 2=force-x, @@ -1198,22 +1275,19 @@ _Noreturn static void inline_panic(AA64Asm* a, const char* msg) { static void render_operand(AA64Asm* a, StrBuf* sb, u32 idx, int form) { u32 ntot = a->nout + a->nin; if (idx >= ntot) inline_panic(a, "operand index out of range"); - const Operand* op = (idx < a->nout) ? &a->out_ops[idx] - : &a->in_ops[idx - a->nout]; + const Operand* op = + (idx < a->nout) ? &a->out_ops[idx] : &a->in_ops[idx - a->nout]; switch (form) { case 1: /* %wN — force 32-bit register form */ - if (op->kind != OPK_REG) - inline_panic(a, "%w on non-register operand"); + if (op->kind != OPK_REG) inline_panic(a, "%w on non-register operand"); render_reg(sb, (u32)op->v.reg, /*is64=*/0); return; case 2: /* %xN — force 64-bit register form */ - if (op->kind != OPK_REG) - inline_panic(a, "%x on non-register operand"); + if (op->kind != OPK_REG) inline_panic(a, "%x on non-register operand"); render_reg(sb, (u32)op->v.reg, /*is64=*/1); return; case 3: /* %aN — memory addressing form */ - if (op->kind != OPK_INDIRECT) - inline_panic(a, "%a on non-memory operand"); + if (op->kind != OPK_INDIRECT) inline_panic(a, "%a on non-memory operand"); /* Inline asm consumes a plain pointer-shaped address; the cg * contract guarantees no EA index here. */ if (op->v.ind.index != REG_NONE) @@ -1332,15 +1406,21 @@ static void render_and_run_line(AA64Asm* a, MCEmitter* mc, StrBuf* sb, while (nend < end && *nend != ']') ++nend; if (nend == end) inline_panic(a, "unterminated %[name]"); size_t nlen = (size_t)(nend - nbeg); - Sym needle = pool_intern_slice(a->c->global, - (Slice){.s = nbeg, .len = nlen}); + Sym needle = + pool_intern_slice(a->c->global, (Slice){.s = nbeg, .len = nlen}); u32 idx = (u32)-1; for (u32 k = 0; k < a->nout; ++k) { - if (a->outs[k].name == needle) { idx = k; break; } + if (a->outs[k].name == needle) { + idx = k; + break; + } } if (idx == (u32)-1) { for (u32 k = 0; k < a->nin; ++k) { - if (a->ins[k].name == needle) { idx = a->nout + k; break; } + if (a->ins[k].name == needle) { + idx = a->nout + k; + break; + } } } if (idx == (u32)-1) @@ -1349,7 +1429,7 @@ static void render_and_run_line(AA64Asm* a, MCEmitter* mc, StrBuf* sb, render_operand(a, sb, idx, 0); continue; } - int form = 0; /* 0=default, 1=w, 2=x, 3=a */ + int form = 0; /* 0=default, 1=w, 2=x, 3=a */ if (n == 'w' || n == 'x' || n == 'a') { form = (n == 'w') ? 1 : (n == 'x') ? 2 : 3; ++p; @@ -1365,15 +1445,21 @@ static void render_and_run_line(AA64Asm* a, MCEmitter* mc, StrBuf* sb, while (nend < end && *nend != ']') ++nend; if (nend == end) inline_panic(a, "unterminated %[name]"); size_t nlen = (size_t)(nend - nbeg); - Sym needle = pool_intern_slice(a->c->global, - (Slice){.s = nbeg, .len = nlen}); + Sym needle = + pool_intern_slice(a->c->global, (Slice){.s = nbeg, .len = nlen}); u32 idx = (u32)-1; for (u32 k = 0; k < a->nout; ++k) { - if (a->outs[k].name == needle) { idx = k; break; } + if (a->outs[k].name == needle) { + idx = k; + break; + } } if (idx == (u32)-1) { for (u32 k = 0; k < a->nin; ++k) { - if (a->ins[k].name == needle) { idx = a->nout + k; break; } + if (a->ins[k].name == needle) { + idx = a->nout + k; + break; + } } } if (idx == (u32)-1) @@ -1382,8 +1468,7 @@ static void render_and_run_line(AA64Asm* a, MCEmitter* mc, StrBuf* sb, render_operand(a, sb, idx, form); continue; } - if (n < '0' || n > '9') - inline_panic(a, "expected digit after '%'"); + if (n < '0' || n > '9') inline_panic(a, "expected digit after '%'"); u32 idx = (u32)(n - '0'); ++p; /* GCC syntax permits up to two digits (%0..%99). */ diff --git a/src/arch/aa64/asm.h b/src/arch/aa64/asm.h @@ -12,8 +12,8 @@ * entry point (aa64_asm_insn) called for each mnemonic line. Symbol * resolution and label management live on the driver side. */ -#include "core/core.h" #include "asm/asm_lex.h" +#include "core/core.h" typedef struct AsmDriver AsmDriver; typedef struct ArchAsm ArchAsm; @@ -45,10 +45,9 @@ void aa64_asm_insn(AA64Asm*, AsmDriver*, Sym mnemonic); * Operand indexing follows the GCC convention: outputs are indexed * 0..nout-1, then inputs nout..nout+nin-1. Template placeholders %N * resolve into this combined list. */ -void aa64_inline_bind(AA64Asm*, - const AsmConstraint* outs, u32 nout, Operand* out_ops, - const AsmConstraint* ins, u32 nin, const Operand* in_ops, - const Sym* clobbers, u32 nclob); +void aa64_inline_bind(AA64Asm*, const AsmConstraint* outs, u32 nout, + Operand* out_ops, const AsmConstraint* ins, u32 nin, + const Operand* in_ops, const Sym* clobbers, u32 nclob); /* Walk the inline-asm template, substituting placeholders into per-line * source text and re-lexing each line through aa64_asm_insn. Must be diff --git a/src/arch/aa64/dbg.c b/src/arch/aa64/dbg.c @@ -27,20 +27,17 @@ * stale internal_bp is cleared by the next prepare; finalize gates on * PC == return_pc so it stays a no-op when control left the slot. */ -#include "arch/arch.h" - #include <string.h> #include "arch/aa64/isa.h" +#include "arch/arch.h" -#define SHIM_X16 16u /* IP0; safe to clobber inside a shim */ +#define SHIM_X16 16u /* IP0; safe to clobber inside a shim */ #define AA64_DBG_INSN_LEN 4u #define AA64_DBG_BL_MASK 0xFC000000u -#define AA64_DBG_BL_OP 0x94000000u +#define AA64_DBG_BL_OP 0x94000000u -static uint32_t aa64_dbg_brk_word(void) { - return aa64_brk(0); -} +static uint32_t aa64_dbg_brk_word(void) { return aa64_brk(0); } static int fits_signed(int64_t v, int bits) { int64_t lim = (int64_t)1 << (bits - 1); @@ -58,9 +55,12 @@ static uint32_t enc_ldr64_reg(uint32_t Rt, uint32_t Rn) { return aa64_ldr64_uimm12(Rt, Rn, 0); } static uint32_t enc_ldr32_reg(uint32_t Rt, uint32_t Rn) { - return aa64_ldst_uimm_pack((AA64LdStUimm){ - .size = 2, .V = 0, .opc = AA64_LDST_OPC_LDR, .imm12 = 0, .Rn = Rn, - .Rt = Rt}); + return aa64_ldst_uimm_pack((AA64LdStUimm){.size = 2, + .V = 0, + .opc = AA64_LDST_OPC_LDR, + .imm12 = 0, + .Rn = Rn, + .Rt = Rt}); } static uint32_t enc_ldrsw_reg(uint32_t Rt, uint32_t Rn) { return aa64_ldst_uimm_pack((AA64LdStUimm){ @@ -122,7 +122,8 @@ static int aa64_dbg_build_shim_word(uint32_t orig_insn, uint64_t orig_pc, nf.imm19 = 2u; /* +8 bytes from slot[0] → slot[8] */ put_u32(w, 0, aa64_brcond_pack(nf)); put_u32(w, 4, brk); - put_u32(w, 8, enc_ldr_lit_x(SHIM_X16, 2)); /* LDR x16, [pc+8] = slot[16] */ + put_u32(w, 8, + enc_ldr_lit_x(SHIM_X16, 2)); /* LDR x16, [pc+8] = slot[16] */ put_u32(w, 12, aa64_br(SHIM_X16)); put_u64(w, 16, target); *shim_len = 4; @@ -163,9 +164,8 @@ static int aa64_dbg_build_shim_word(uint32_t orig_insn, uint64_t orig_pc, int64_t imm = sign_extend(imm14_raw, 14); uint64_t target = orig_pc + (uint64_t)(imm * 4); uint32_t new_imm14 = 2u; /* +8 → slot[8] */ - uint32_t new_word = - (b5 << 31) | 0x36000000u | (op << 24) | (b40 << 19) | - ((new_imm14 & 0x3fffu) << 5) | (Rt & 0x1fu); + uint32_t new_word = (b5 << 31) | 0x36000000u | (op << 24) | (b40 << 19) | + ((new_imm14 & 0x3fffu) << 5) | (Rt & 0x1fu); put_u32(w, 0, new_word); put_u32(w, 4, brk); put_u32(w, 8, enc_ldr_lit_x(SHIM_X16, 2)); @@ -205,10 +205,17 @@ static int aa64_dbg_build_shim_word(uint32_t orig_insn, uint64_t orig_pc, uint32_t load_insn; if (V) return 1; /* vector forms (S/D/Q): not supported in v1 */ switch (opc) { - case 0: load_insn = enc_ldr32_reg(Rt, SHIM_X16); break; /* LDR Wt */ - case 1: load_insn = enc_ldr64_reg(Rt, SHIM_X16); break; /* LDR Xt */ - case 2: load_insn = enc_ldrsw_reg(Rt, SHIM_X16); break; /* LDRSW */ - default: return 1; /* PRFM (literal): not meaningful here */ + case 0: + load_insn = enc_ldr32_reg(Rt, SHIM_X16); + break; /* LDR Wt */ + case 1: + load_insn = enc_ldr64_reg(Rt, SHIM_X16); + break; /* LDR Xt */ + case 2: + load_insn = enc_ldrsw_reg(Rt, SHIM_X16); + break; /* LDRSW */ + default: + return 1; /* PRFM (literal): not meaningful here */ } /* LDR x16, [pc + 12] — literal at slot[12]. */ put_u32(w, 0, enc_ldr_lit_x(SHIM_X16, 3)); @@ -261,12 +268,9 @@ static CfreeStatus aa64_dbg_decode_insn(const u8* bytes, u32 len, u64 pc, return CFREE_OK; } -static CfreeStatus aa64_dbg_build_displaced_shim(const ArchDbgInsn* insn, - void* scratch_write, - u64 scratch_runtime, - u32 scratch_cap, - u32* sentinel_off, - u64* fallthrough_pc) { +static CfreeStatus aa64_dbg_build_displaced_shim( + const ArchDbgInsn* insn, void* scratch_write, u64 scratch_runtime, + u32 scratch_cap, u32* sentinel_off, u64* fallthrough_pc) { uint32_t word = 0; if (!insn || !scratch_write || !sentinel_off || !fallthrough_pc) return CFREE_INVALID; diff --git a/src/arch/aa64/emit.c b/src/arch/aa64/emit.c @@ -3,15 +3,15 @@ #include "arch/aa64/internal.h" -extern void debug_emit_row(Debug *, ObjSecId text_section, u32 offset, SrcLoc); -extern void debug_func_pc_range(Debug *, ObjSecId text_section, u32 begin_ofs, +extern void debug_emit_row(Debug*, ObjSecId text_section, u32 offset, SrcLoc); +extern void debug_func_pc_range(Debug*, ObjSecId text_section, u32 begin_ofs, u32 end_ofs); -static void aa_emit_cfi_frame(CGTarget *t, u32 post_prologue_off, u32 fp_lr_off, - u32 int_save_off, u32 fp_save_off, - u32 frame_size, const u32 *int_regs, - u32 n_int_saves, const u32 *fp_regs, - u32 n_fp_saves, int omit_frame); +static void aa_emit_cfi_frame(CGTarget* t, u32 post_prologue_off, u32 fp_lr_off, + u32 int_save_off, u32 fp_save_off, u32 frame_size, + const u32* int_regs, u32 n_int_saves, + const u32* fp_regs, u32 n_fp_saves, + int omit_frame); /* ============================================================ * Shared type / operand helpers @@ -36,40 +36,37 @@ u32 type_byte_size(CfreeCgTypeId t) { if (t == CG_BUILTIN_ID(CFREE_CG_BUILTIN_I8) || t == CG_BUILTIN_ID(CFREE_CG_BUILTIN_BOOL)) return 1; - if (t == CG_BUILTIN_ID(CFREE_CG_BUILTIN_I16)) - return 2; + if (t == CG_BUILTIN_ID(CFREE_CG_BUILTIN_I16)) return 2; if (t == CG_BUILTIN_ID(CFREE_CG_BUILTIN_I32) || t == CG_BUILTIN_ID(CFREE_CG_BUILTIN_F32)) return 4; - if (t == CG_BUILTIN_ID(CFREE_CG_BUILTIN_F128)) - return 16; + if (t == CG_BUILTIN_ID(CFREE_CG_BUILTIN_F128)) return 16; return 8; } u32 size_idx_for_bytes(u32 nbytes) { switch (nbytes) { - case 1: - return 0; - case 2: - return 1; - case 4: - return 2; - case 8: - return 3; - case 16: - return 4; - default: - return 3; + case 1: + return 0; + case 2: + return 1; + case 4: + return 2; + case 8: + return 3; + case 16: + return 4; + default: + return 3; } } u32 reg_num(Operand op) { return op.v.reg & 0x1fu; } -static u32 collect_mask_regs(u32 mask, u32 first, u32 last, u32 *out) { +static u32 collect_mask_regs(u32 mask, u32 first, u32 last, u32* out) { u32 n = 0; for (u32 r = first; r <= last; ++r) { - if (mask & (1u << r)) - out[n++] = r; + if (mask & (1u << r)) out[n++] = r; } return n; } @@ -82,7 +79,7 @@ static u32 count_mask_regs(u32 mask, u32 first, u32 last) { return n; } -static u32 aa_planned_prologue_words(const AAImpl *a) { +static u32 aa_planned_prologue_words(const AAImpl* a) { u32 n = AA_PROLOGUE_FRAME_WORDS; if (a->has_sret) ++n; n += count_mask_regs(a->planned_cs_int_mask, 19u, 28u); @@ -90,9 +87,9 @@ static u32 aa_planned_prologue_words(const AAImpl *a) { return n ? n : 1u; } -static void aa_func_begin_init(CGTarget *t, const CGFuncDesc *fd) { - AAImpl *a = impl_of(t); - MCEmitter *mc = t->mc; +static void aa_func_begin_init(CGTarget* t, const CGFuncDesc* fd) { + AAImpl* a = impl_of(t); + MCEmitter* mc = t->mc; mc->set_section(mc, fd->text_section_id); mc->emit_align(mc, 4, 0); @@ -108,8 +105,8 @@ static void aa_func_begin_init(CGTarget *t, const CGFuncDesc *fd) { a->max_outgoing = 0; a->used_cs_int_mask = a->has_planned_regs ? a->planned_cs_int_mask : 0; a->used_cs_fp_mask = a->has_planned_regs ? a->planned_cs_fp_mask : 0; - a->prologue_words = a->has_planned_regs ? aa_planned_prologue_words(a) - : AA_PROLOGUE_WORDS; + a->prologue_words = + a->has_planned_regs ? aa_planned_prologue_words(a) : AA_PROLOGUE_WORDS; a->post_prologue_off = 0; a->planned_cs_int_mask = 0; a->planned_cs_fp_mask = 0; @@ -129,8 +126,8 @@ static void aa_func_begin_init(CGTarget *t, const CGFuncDesc *fd) { mc->cfi_startproc(mc); } -static void aa_add_entry_frame_slots(CGTarget *t) { - AAImpl *a = impl_of(t); +static void aa_add_entry_frame_slots(CGTarget* t) { + AAImpl* a = impl_of(t); if (a->has_sret) { FrameSlotDesc fsd = { @@ -169,13 +166,13 @@ static void aa_add_entry_frame_slots(CGTarget *t) { } } -static void aa_emit_variadic_reg_saves(CGTarget *t) { - AAImpl *a = impl_of(t); - MCEmitter *mc = t->mc; +static void aa_emit_variadic_reg_saves(CGTarget* t) { + AAImpl* a = impl_of(t); + MCEmitter* mc = t->mc; if (!a->is_variadic) return; - AASlot *gs = aa64_slot_get(a, a->gp_save_slot); - AASlot *fs = aa64_slot_get(a, a->fp_save_slot); + AASlot* gs = aa64_slot_get(a, a->gp_save_slot); + AASlot* fs = aa64_slot_get(a, a->fp_save_slot); for (u32 i = 0; i < 8; ++i) aa64_emit32(mc, aa64_stur(3, i, 29, -(i32)gs->off + (i32)i * 8)); for (u32 i = 0; i < 8; ++i) @@ -186,7 +183,7 @@ static void aa_emit_variadic_reg_saves(CGTarget *t) { * Low-level emission * ============================================================ */ -void aa64_emit32(MCEmitter *mc, u32 word) { +void aa64_emit32(MCEmitter* mc, u32 word) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 b[4]; b[0] = (u8)(word & 0xff); @@ -199,7 +196,7 @@ void aa64_emit32(MCEmitter *mc, u32 word) { } } -void aa64_patch32(ObjBuilder *obj, u32 sec_id, u32 ofs, u32 word) { +void aa64_patch32(ObjBuilder* obj, u32 sec_id, u32 ofs, u32 word) { u8 b[4]; b[0] = (u8)(word & 0xff); b[1] = (u8)((word >> 8) & 0xff); @@ -212,7 +209,7 @@ void aa64_patch32(ObjBuilder *obj, u32 sec_id, u32 ofs, u32 word) { * Immediate encoding helpers * ============================================================ */ -void aa64_emit_load_imm(MCEmitter *mc, u32 sf, u32 Rd, i64 imm) { +void aa64_emit_load_imm(MCEmitter* mc, u32 sf, u32 Rd, i64 imm) { const u32 nslots = sf ? 4u : 2u; u64 v = sf ? (u64)imm : ((u64)imm & 0xffffffffu); @@ -241,19 +238,17 @@ void aa64_emit_load_imm(MCEmitter *mc, u32 sf, u32 Rd, i64 imm) { for (u32 i = 0; i < nslots; ++i) { u32 slot = (u32)((v >> (i * 16)) & 0xffffu); if (!placed) { - if (slot == 0) - continue; + if (slot == 0) continue; aa64_emit32(mc, aa64_movz(sf, Rd, slot, i)); placed = 1; } else if (slot != 0) { aa64_emit32(mc, aa64_movk(sf, Rd, slot, i)); } } - if (!placed) - aa64_emit32(mc, aa64_movz(sf, Rd, 0, 0)); + if (!placed) aa64_emit32(mc, aa64_movz(sf, Rd, 0, 0)); } -void emit_sp_add(MCEmitter *mc, u32 imm) { +void emit_sp_add(MCEmitter* mc, u32 imm) { if (imm <= 0xfff) { aa64_emit32(mc, aa64_add_imm(1, 31, 31, imm, 0)); } else if ((imm & 0xfff) == 0 && (imm >> 12) <= 0xfff) { @@ -268,15 +263,14 @@ void emit_sp_add(MCEmitter *mc, u32 imm) { * Function lifecycle * ============================================================ */ -void aa_func_begin(CGTarget *t, const CGFuncDesc *fd) { - AAImpl *a = impl_of(t); - MCEmitter *mc = t->mc; +void aa_func_begin(CGTarget* t, const CGFuncDesc* fd) { + AAImpl* a = impl_of(t); + MCEmitter* mc = t->mc; aa_func_begin_init(t, fd); a->prologue_pos = mc->pos(mc); - for (u32 i = 0; i < a->prologue_words; ++i) - aa64_emit32(mc, AA64_NOP); + for (u32 i = 0; i < a->prologue_words; ++i) aa64_emit32(mc, AA64_NOP); aa_add_entry_frame_slots(t); aa_emit_variadic_reg_saves(t); @@ -284,11 +278,11 @@ void aa_func_begin(CGTarget *t, const CGFuncDesc *fd) { a->post_prologue_off = mc->pos(mc) - a->func_start; } -static u32 aa_build_prologue(CGTarget *t, u32 *words, u32 cap, u32 frame_size, +static u32 aa_build_prologue(CGTarget* t, u32* words, u32 cap, u32 frame_size, u32 fp_lr_off, u32 int_save_off, u32 fp_save_off, - const u32 *int_regs, u32 n_int_saves, - const u32 *fp_regs, u32 n_fp_saves) { - AAImpl *a = impl_of(t); + const u32* int_regs, u32 n_int_saves, + const u32* fp_regs, u32 n_fp_saves) { + AAImpl* a = impl_of(t); u32 wi = 0; if (frame_size <= 0xfff) { @@ -327,11 +321,10 @@ static u32 aa_build_prologue(CGTarget *t, u32 *words, u32 cap, u32 frame_size, } } else { compiler_panic(t->c, a->loc, - "aarch64: fp/lr offset %u out of prologue range", - fp_lr_off); + "aarch64: fp/lr offset %u out of prologue range", fp_lr_off); } if (a->has_sret && a->sret_ptr_slot != FRAME_SLOT_NONE) { - AASlot *s = aa64_slot_get(a, a->sret_ptr_slot); + AASlot* s = aa64_slot_get(a, a->sret_ptr_slot); if (s) { if (wi >= cap) goto overflow; words[wi++] = aa64_stur(3, 8, 29, -(i32)s->off); @@ -353,9 +346,9 @@ overflow: return 0; } -static void aa_compute_frame(const AAImpl *a, u32 n_int_saves, u32 n_fp_saves, - u32 *int_save_off, u32 *fp_save_off, - u32 *fp_lr_off, u32 *frame_size) { +static void aa_compute_frame(const AAImpl* a, u32 n_int_saves, u32 n_fp_saves, + u32* int_save_off, u32* fp_save_off, + u32* fp_lr_off, u32* frame_size) { *int_save_off = a->max_outgoing; *fp_save_off = *int_save_off + n_int_saves * 8u; u32 locals_off = *fp_save_off + n_fp_saves * 8u; @@ -365,10 +358,10 @@ static void aa_compute_frame(const AAImpl *a, u32 n_int_saves, u32 n_fp_saves, *fp_lr_off = *frame_size - 16; } -void aa_func_begin_known_frame(CGTarget *t, const CGFuncDesc *fd, - const CGKnownFrameDesc *frame, - FrameSlot *out_slots) { - AAImpl *a = impl_of(t); +void aa_func_begin_known_frame(CGTarget* t, const CGFuncDesc* fd, + const CGKnownFrameDesc* frame, + FrameSlot* out_slots) { + AAImpl* a = impl_of(t); u32 int_regs[10]; u32 fp_regs[8]; u32 int_save_off, fp_save_off, fp_lr_off, frame_size; @@ -390,8 +383,7 @@ void aa_func_begin_known_frame(CGTarget *t, const CGFuncDesc *fd, u32 n_fp_saves = collect_mask_regs(a->used_cs_fp_mask, 8u, 15u, fp_regs); if (frame && frame->may_omit_frame && frame->nslots == 0 && frame->max_outgoing == 0 && !frame->has_alloca && !frame->has_call && - !a->has_sret && !a->is_variadic && n_int_saves == 0 && - n_fp_saves == 0) { + !a->has_sret && !a->is_variadic && n_int_saves == 0 && n_fp_saves == 0) { a->omit_frame = 1; return; } @@ -400,15 +392,14 @@ void aa_func_begin_known_frame(CGTarget *t, const CGFuncDesc *fd, a->prologue_pos = t->mc->pos(t->mc); u32 nwords = aa_build_prologue(t, words, AA_PROLOGUE_WORDS, frame_size, - fp_lr_off, int_save_off, fp_save_off, - int_regs, n_int_saves, fp_regs, n_fp_saves); - for (u32 i = 0; i < nwords; ++i) - aa64_emit32(t->mc, words[i]); + fp_lr_off, int_save_off, fp_save_off, int_regs, + n_int_saves, fp_regs, n_fp_saves); + for (u32 i = 0; i < nwords; ++i) aa64_emit32(t->mc, words[i]); aa_emit_variadic_reg_saves(t); { u32 post = t->mc->pos(t->mc) - a->func_start; - aa_emit_cfi_frame(t, post, fp_lr_off, int_save_off, fp_save_off, - frame_size, int_regs, n_int_saves, fp_regs, n_fp_saves, + aa_emit_cfi_frame(t, post, fp_lr_off, int_save_off, fp_save_off, frame_size, + int_regs, n_int_saves, fp_regs, n_fp_saves, /*omit_frame=*/0); } } @@ -418,12 +409,12 @@ void aa_func_begin_known_frame(CGTarget *t, const CGFuncDesc *fd, * x29 saved at CFA-16, x30 (LR) at CFA-8 * callee-saved ints/fps at their slot offsets * pc_offset = end-of-prologue offset within the function. */ -static void aa_emit_cfi_frame(CGTarget *t, u32 post_prologue_off, u32 fp_lr_off, - u32 int_save_off, u32 fp_save_off, - u32 frame_size, const u32 *int_regs, - u32 n_int_saves, const u32 *fp_regs, - u32 n_fp_saves, int omit_frame) { - MCEmitter *mc = t->mc; +static void aa_emit_cfi_frame(CGTarget* t, u32 post_prologue_off, u32 fp_lr_off, + u32 int_save_off, u32 fp_save_off, u32 frame_size, + const u32* int_regs, u32 n_int_saves, + const u32* fp_regs, u32 n_fp_saves, + int omit_frame) { + MCEmitter* mc = t->mc; if (omit_frame) return; (void)fp_lr_off; mc->cfi_set_next_pc_offset(mc, post_prologue_off); @@ -446,10 +437,10 @@ static void aa_emit_cfi_frame(CGTarget *t, u32 post_prologue_off, u32 fp_lr_off, } } -void aa_func_end(CGTarget *t) { - AAImpl *a = impl_of(t); - MCEmitter *mc = t->mc; - ObjBuilder *obj = t->obj; +void aa_func_end(CGTarget* t) { + AAImpl* a = impl_of(t); + MCEmitter* mc = t->mc; + ObjBuilder* obj = t->obj; u32 sec = a->fd->text_section_id; u32 int_regs[10]; @@ -463,8 +454,8 @@ void aa_func_end(CGTarget *t) { if (!a->known_frame) { aa_emit_cfi_frame(t, a->post_prologue_off, fp_lr_off, int_save_off, - fp_save_off, frame_size, int_regs, n_int_saves, - fp_regs, n_fp_saves, /*omit_frame=*/a->omit_frame); + fp_save_off, frame_size, int_regs, n_int_saves, fp_regs, + n_fp_saves, /*omit_frame=*/a->omit_frame); } if (a->omit_frame) goto finish; @@ -501,10 +492,9 @@ void aa_func_end(CGTarget *t) { if (!a->known_frame) { u32 pos = a->prologue_pos; u32 words[AA_PROLOGUE_WORDS]; - u32 prologue_words = a->prologue_words ? a->prologue_words - : AA_PROLOGUE_WORDS; - for (u32 i = 0; i < prologue_words; ++i) - words[i] = AA64_NOP; + u32 prologue_words = + a->prologue_words ? a->prologue_words : AA_PROLOGUE_WORDS; + for (u32 i = 0; i < prologue_words; ++i) words[i] = AA64_NOP; (void)aa_build_prologue(t, words, prologue_words, frame_size, fp_lr_off, int_save_off, fp_save_off, int_regs, n_int_saves, fp_regs, n_fp_saves); @@ -524,8 +514,7 @@ void aa_func_end(CGTarget *t) { aa64_patch32(obj, sec, a->add_patches[i].pos, word); } -finish: - ; +finish:; u32 end = mc->pos(mc); obj_symbol_define(obj, a->fd->sym, sec, (u64)a->func_start, (u64)(end - a->func_start)); @@ -533,8 +522,7 @@ finish: obj_atom_define(obj, sec, a->func_start, end - a->func_start, a->fd->sym, 0); } - if (t->debug) - debug_func_pc_range(t->debug, sec, a->func_start, end); + if (t->debug) debug_func_pc_range(t->debug, sec, a->func_start, end); mc->cfi_endproc(mc); mc_end_function(mc); @@ -545,13 +533,12 @@ finish: * Frame slots * ============================================================ */ -FrameSlot aa_frame_slot(CGTarget *t, const FrameSlotDesc *d) { - AAImpl *a = impl_of(t); +FrameSlot aa_frame_slot(CGTarget* t, const FrameSlotDesc* d) { + AAImpl* a = impl_of(t); if (a->nslots == a->slots_cap) { u32 ncap = a->slots_cap ? a->slots_cap * 2 : 8; - AASlot *nbuf = arena_array(t->c->tu, AASlot, ncap); - if (a->slots) - memcpy(nbuf, a->slots, sizeof(AASlot) * a->nslots); + AASlot* nbuf = arena_array(t->c->tu, AASlot, ncap); + if (a->slots) memcpy(nbuf, a->slots, sizeof(AASlot) * a->nslots); a->slots = nbuf; a->slots_cap = ncap; } @@ -561,7 +548,7 @@ FrameSlot aa_frame_slot(CGTarget *t, const FrameSlotDesc *d) { u32 mask = align - 1; next = (next + mask) & ~mask; - AASlot *s = &a->slots[a->nslots]; + AASlot* s = &a->slots[a->nslots]; s->off = next; s->size = size; s->align = align; @@ -576,7 +563,7 @@ FrameSlot aa_frame_slot(CGTarget *t, const FrameSlotDesc *d) { * Parameters * ============================================================ */ -static void aa_consume_param_location(AAImpl *a, const ABIArgInfo *ai) { +static void aa_consume_param_location(AAImpl* a, const ABIArgInfo* ai) { if (!ai || ai->kind == ABI_ARG_IGNORE) return; if (ai->kind == ABI_ARG_INDIRECT) { if (a->next_param_int < 8) @@ -587,7 +574,7 @@ static void aa_consume_param_location(AAImpl *a, const ABIArgInfo *ai) { return; } for (u16 i = 0; i < ai->nparts; ++i) { - const ABIArgPart *pt = &ai->parts[i]; + const ABIArgPart* pt = &ai->parts[i]; if (pt->cls == ABI_CLASS_INT) { if (a->next_param_int < 8) ++a->next_param_int; @@ -602,8 +589,8 @@ static void aa_consume_param_location(AAImpl *a, const ABIArgInfo *ai) { } } -CGLocalStorage aa_param(CGTarget *t, const CGParamDesc *p) { - AAImpl *a = impl_of(t); +CGLocalStorage aa_param(CGTarget* t, const CGParamDesc* p) { + AAImpl* a = impl_of(t); CGLocalStorage st = p->storage; if (st.kind == CG_LOCAL_STORAGE_FRAME && st.v.frame_slot == FRAME_SLOT_NONE) { FrameSlotDesc fsd = {0}; @@ -616,28 +603,28 @@ CGLocalStorage aa_param(CGTarget *t, const CGParamDesc *p) { if (p->flags & CG_LOCAL_ADDR_TAKEN) fsd.flags |= FSF_ADDR_TAKEN; st.v.frame_slot = aa_frame_slot(t, &fsd); } - AASlot *s = st.kind == CG_LOCAL_STORAGE_FRAME + AASlot* s = st.kind == CG_LOCAL_STORAGE_FRAME ? aa64_slot_get(a, st.v.frame_slot) : NULL; if (st.kind == CG_LOCAL_STORAGE_FRAME && !s) { compiler_panic(t->c, a->loc, "aarch64 param: bad slot"); } - const ABIArgInfo *ai = p->abi; + const ABIArgInfo* ai = p->abi; u32 incoming_stack_base = a->omit_frame ? 31u : 29u; i32 incoming_stack_bias = a->omit_frame ? 0 : 16; - if (ai->kind == ABI_ARG_IGNORE) - return st; + if (ai->kind == ABI_ARG_IGNORE) return st; if (st.kind == CG_LOCAL_STORAGE_REG && st.v.reg == (Reg)REG_NONE) { aa_consume_param_location(a, ai); return st; } if (st.kind == CG_LOCAL_STORAGE_REG) { if (ai->kind != ABI_ARG_DIRECT || ai->nparts != 1) { - compiler_panic(t->c, a->loc, - "aarch64 param: register storage requires one direct part"); + compiler_panic( + t->c, a->loc, + "aarch64 param: register storage requires one direct part"); } - const ABIArgPart *pt = &ai->parts[0]; + const ABIArgPart* pt = &ai->parts[0]; u32 sz = pt->size; u32 sidx = size_idx_for_bytes(sz); if (pt->cls == ABI_CLASS_INT) { @@ -658,8 +645,7 @@ CGLocalStorage aa_param(CGTarget *t, const CGParamDesc *p) { if (p->type == CG_BUILTIN_ID(CFREE_CG_BUILTIN_F64) || p->type == CG_BUILTIN_ID(CFREE_CG_BUILTIN_F32)) { aa64_emit_ldur_fp_off(t->mc, sidx, dst, incoming_stack_base, - incoming_stack_bias + (i32)caller_off, - AA_TMP0); + incoming_stack_bias + (i32)caller_off, AA_TMP0); } else { aa64_emit_ldur_off(t->mc, sidx, dst, incoming_stack_base, incoming_stack_bias + (i32)caller_off, AA_TMP0); @@ -679,13 +665,12 @@ CGLocalStorage aa_param(CGTarget *t, const CGParamDesc *p) { u32 caller_off = a->next_param_stack; a->next_param_stack += sz > 8 ? sz : 8; if (sz == 16) - aa64_emit32(t->mc, aa64_ldur_q(dst, incoming_stack_base, - incoming_stack_bias + - (i32)caller_off)); + aa64_emit32(t->mc, + aa64_ldur_q(dst, incoming_stack_base, + incoming_stack_bias + (i32)caller_off)); else aa64_emit_ldur_fp_off(t->mc, sidx, dst, incoming_stack_base, - incoming_stack_bias + (i32)caller_off, - AA_TMP0); + incoming_stack_bias + (i32)caller_off, AA_TMP0); } } else { compiler_panic(t->c, a->loc, "aarch64 param: ABI class %d unimpl", @@ -708,32 +693,28 @@ CGLocalStorage aa_param(CGTarget *t, const CGParamDesc *p) { u32 i = 0; while (i + 8 <= nbytes) { aa64_emit_ldur_off(t->mc, 3, AA_TMP1, ptr_reg, (i32)i, AA_TMP2); - aa64_emit_stur_off(t->mc, 3, AA_TMP1, 29, -(i32)s->off + (i32)i, - AA_TMP2); + aa64_emit_stur_off(t->mc, 3, AA_TMP1, 29, -(i32)s->off + (i32)i, AA_TMP2); i += 8; } while (i + 4 <= nbytes) { aa64_emit_ldur_off(t->mc, 2, AA_TMP1, ptr_reg, (i32)i, AA_TMP2); - aa64_emit_stur_off(t->mc, 2, AA_TMP1, 29, -(i32)s->off + (i32)i, - AA_TMP2); + aa64_emit_stur_off(t->mc, 2, AA_TMP1, 29, -(i32)s->off + (i32)i, AA_TMP2); i += 4; } while (i + 2 <= nbytes) { aa64_emit_ldur_off(t->mc, 1, AA_TMP1, ptr_reg, (i32)i, AA_TMP2); - aa64_emit_stur_off(t->mc, 1, AA_TMP1, 29, -(i32)s->off + (i32)i, - AA_TMP2); + aa64_emit_stur_off(t->mc, 1, AA_TMP1, 29, -(i32)s->off + (i32)i, AA_TMP2); i += 2; } while (i < nbytes) { aa64_emit_ldur_off(t->mc, 0, AA_TMP1, ptr_reg, (i32)i, AA_TMP2); - aa64_emit_stur_off(t->mc, 0, AA_TMP1, 29, -(i32)s->off + (i32)i, - AA_TMP2); + aa64_emit_stur_off(t->mc, 0, AA_TMP1, 29, -(i32)s->off + (i32)i, AA_TMP2); i += 1; } return st; } for (u16 i = 0; i < ai->nparts; ++i) { - const ABIArgPart *pt = &ai->parts[i]; + const ABIArgPart* pt = &ai->parts[i]; u32 part_off = pt->src_offset; u32 sz = pt->size; u32 sidx = size_idx_for_bytes(sz); @@ -741,8 +722,8 @@ CGLocalStorage aa_param(CGTarget *t, const CGParamDesc *p) { if (pt->cls == ABI_CLASS_INT) { if (a->next_param_int < 8) { u32 reg = a->next_param_int++; - aa64_emit_stur_off(t->mc, sidx, reg, 29, - -(i32)s->off + (i32)part_off, AA_TMP0); + aa64_emit_stur_off(t->mc, sidx, reg, 29, -(i32)s->off + (i32)part_off, + AA_TMP0); } else { u32 caller_off = a->next_param_stack; a->next_param_stack += 8; @@ -755,8 +736,8 @@ CGLocalStorage aa_param(CGTarget *t, const CGParamDesc *p) { if (a->next_param_fp < 8) { u32 reg = a->next_param_fp++; if (sz == 16) - aa64_emit32(t->mc, aa64_stur_q(reg, 29, - -(i32)s->off + (i32)part_off)); + aa64_emit32(t->mc, + aa64_stur_q(reg, 29, -(i32)s->off + (i32)part_off)); else aa64_emit_stur_fp_off(t->mc, sidx, reg, 29, -(i32)s->off + (i32)part_off, AA_TMP0); @@ -764,15 +745,14 @@ CGLocalStorage aa_param(CGTarget *t, const CGParamDesc *p) { u32 caller_off = a->next_param_stack; a->next_param_stack += sz > 8 ? sz : 8; if (sz == 16) { - aa64_emit32(t->mc, aa64_ldur_q(AA_FP_TMP0, incoming_stack_base, - incoming_stack_bias + - (i32)caller_off)); - aa64_emit32(t->mc, aa64_stur_q(AA_FP_TMP0, 29, - -(i32)s->off + (i32)part_off)); + aa64_emit32(t->mc, + aa64_ldur_q(AA_FP_TMP0, incoming_stack_base, + incoming_stack_bias + (i32)caller_off)); + aa64_emit32( + t->mc, aa64_stur_q(AA_FP_TMP0, 29, -(i32)s->off + (i32)part_off)); } else { aa64_emit_ldur_fp_off(t->mc, sidx, AA_FP_TMP0, incoming_stack_base, - incoming_stack_bias + (i32)caller_off, - AA_TMP0); + incoming_stack_bias + (i32)caller_off, AA_TMP0); aa64_emit_stur_fp_off(t->mc, sidx, AA_FP_TMP0, 29, -(i32)s->off + (i32)part_off, AA_TMP0); } @@ -789,12 +769,12 @@ CGLocalStorage aa_param(CGTarget *t, const CGParamDesc *p) { * Address materialization helpers * ============================================================ */ -static int use_got_for_sym(CGTarget *t, ObjSymId sym) { +static int use_got_for_sym(CGTarget* t, ObjSymId sym) { return obj_symbol_extern_via_got(t->c, t->obj, sym); } -void aa64_emit_got_load_addr(CGTarget *t, u32 dst_reg, ObjSymId sym) { - MCEmitter *mc = t->mc; +void aa64_emit_got_load_addr(CGTarget* t, u32 dst_reg, ObjSymId sym) { + MCEmitter* mc = t->mc; u32 sec = mc->section_id; u32 adrp_pos = mc->pos(mc); aa64_emit32(mc, aa64_adrp_base(dst_reg)); @@ -804,12 +784,11 @@ void aa64_emit_got_load_addr(CGTarget *t, u32 dst_reg, ObjSymId sym) { mc->emit_reloc_at(mc, sec, ldr_pos, R_AARCH64_LD64_GOT_LO12_NC, sym, 0, 0, 0); } -void emit_global_addr(CGTarget *t, u32 dst_reg, ObjSymId sym, i64 addend) { - MCEmitter *mc = t->mc; +void emit_global_addr(CGTarget* t, u32 dst_reg, ObjSymId sym, i64 addend) { + MCEmitter* mc = t->mc; if (use_got_for_sym(t, sym)) { aa64_emit_got_load_addr(t, dst_reg, sym); - if (addend) - aa64_emit_addr_adjust(mc, dst_reg, dst_reg, (i32)addend); + if (addend) aa64_emit_addr_adjust(mc, dst_reg, dst_reg, (i32)addend); return; } u32 sec = mc->section_id; @@ -823,7 +802,7 @@ void emit_global_addr(CGTarget *t, u32 dst_reg, ObjSymId sym, i64 addend) { 0); } -void aa64_emit_addr_adjust(MCEmitter *mc, u32 Rd, u32 base, i32 off) { +void aa64_emit_addr_adjust(MCEmitter* mc, u32 Rd, u32 base, i32 off) { if (off == 0) { aa64_emit32(mc, aa64_mov_reg(1, Rd, base)); return; @@ -840,15 +819,11 @@ void aa64_emit_addr_adjust(MCEmitter *mc, u32 Rd, u32 base, i32 off) { u32 hi = (abs_off >> 12) & 0xfff; u32 lo = abs_off & 0xfff; if (off < 0) { - if (hi) - aa64_emit32(mc, aa64_sub_imm(1, Rd, base, hi, 1)); - if (lo) - aa64_emit32(mc, aa64_sub_imm(1, Rd, hi ? Rd : base, lo, 0)); + if (hi) aa64_emit32(mc, aa64_sub_imm(1, Rd, base, hi, 1)); + if (lo) aa64_emit32(mc, aa64_sub_imm(1, Rd, hi ? Rd : base, lo, 0)); } else { - if (hi) - aa64_emit32(mc, aa64_add_imm(1, Rd, base, hi, 1)); - if (lo) - aa64_emit32(mc, aa64_add_imm(1, Rd, hi ? Rd : base, lo, 0)); + if (hi) aa64_emit32(mc, aa64_add_imm(1, Rd, base, hi, 1)); + if (lo) aa64_emit32(mc, aa64_add_imm(1, Rd, hi ? Rd : base, lo, 0)); } return; } @@ -856,9 +831,7 @@ void aa64_emit_addr_adjust(MCEmitter *mc, u32 Rd, u32 base, i32 off) { aa64_emit32(mc, aa64_add(1, Rd, base, Rd)); } -static int aa64_simm9_fits(i32 off) { - return off >= -256 && off <= 255; -} +static int aa64_simm9_fits(i32 off) { return off >= -256 && off <= 255; } void aa64_emit_ldur_off(MCEmitter* mc, u32 size, u32 Rt, u32 Rn, i32 off, u32 tmp) { diff --git a/src/arch/aa64/internal.h b/src/arch/aa64/internal.h @@ -67,12 +67,12 @@ static inline u32 aa64_ldur_fp(u32 size, u32 Rt, u32 Rn, i32 simm9) { ((Rn & 0x1f) << 5) | (Rt & 0x1f); } static inline u32 aa64_stur_q(u32 Rt, u32 Rn, i32 simm9) { - return 0x3C800000u | (((u32)simm9 & 0x1ffu) << 12) | - ((Rn & 0x1f) << 5) | (Rt & 0x1f); + return 0x3C800000u | (((u32)simm9 & 0x1ffu) << 12) | ((Rn & 0x1f) << 5) | + (Rt & 0x1f); } static inline u32 aa64_ldur_q(u32 Rt, u32 Rn, i32 simm9) { - return 0x3CC00000u | (((u32)simm9 & 0x1ffu) << 12) | - ((Rn & 0x1f) << 5) | (Rt & 0x1f); + return 0x3CC00000u | (((u32)simm9 & 0x1ffu) << 12) | ((Rn & 0x1f) << 5) | + (Rt & 0x1f); } static inline u32 aa64_str_uimm(u32 size, u32 Rt, u32 Rn, u32 byte_off) { @@ -92,8 +92,7 @@ static inline u32 aa64_str_fp_uimm(u32 size, u32 Rt, u32 Rn, u32 byte_off) { } static inline u32 aa64_str_q_uimm(u32 Rt, u32 Rn, u32 byte_off) { u32 sc = byte_off >> 4; - return 0x3D800000u | ((sc & 0xfffu) << 10) | - ((Rn & 0x1f) << 5) | (Rt & 0x1f); + return 0x3D800000u | ((sc & 0xfffu) << 10) | ((Rn & 0x1f) << 5) | (Rt & 0x1f); } static inline u32 aa64_mrs_tpidr_el0(u32 Rt) { @@ -111,16 +110,14 @@ static inline u32 aa64_ldr_fp_uimm(u32 size, u32 Rt, u32 Rn, u32 byte_off) { } static inline u32 aa64_ldr_q_uimm(u32 Rt, u32 Rn, u32 byte_off) { u32 sc = byte_off >> 4; - return 0x3DC00000u | ((sc & 0xfffu) << 10) | - ((Rn & 0x1f) << 5) | (Rt & 0x1f); + return 0x3DC00000u | ((sc & 0xfffu) << 10) | ((Rn & 0x1f) << 5) | (Rt & 0x1f); } static inline u32 aa64_fmov_reg(u32 type, u32 Rd, u32 Rn) { return 0x1E204000u | ((type & 3) << 22) | ((Rn & 0x1f) << 5) | (Rd & 0x1f); } static inline u32 aa64_mov_v16b(u32 Rd, u32 Rn) { - return 0x4EA01C00u | ((Rn & 0x1f) << 16) | ((Rn & 0x1f) << 5) | - (Rd & 0x1f); + return 0x4EA01C00u | ((Rn & 0x1f) << 16) | ((Rn & 0x1f) << 5) | (Rd & 0x1f); } static inline u32 aa64_subs_imm(u32 sf, u32 Rd, u32 Rn, u32 imm12) { @@ -206,8 +203,7 @@ static inline u32 aa64_fdiv(u32 type, u32 Rd, u32 Rn, u32 Rm) { ((Rn & 0x1f) << 5) | (Rd & 0x1f); } static inline u32 aa64_fneg(u32 type, u32 Rd, u32 Rn) { - return 0x1E214000u | ((type & 3) << 22) | ((Rn & 0x1f) << 5) | - (Rd & 0x1f); + return 0x1E214000u | ((type & 3) << 22) | ((Rn & 0x1f) << 5) | (Rd & 0x1f); } static inline u32 aa64_fcmp(u32 type, u32 Rn, u32 Rm) { diff --git a/src/arch/aa64/isa.c b/src/arch/aa64/isa.c @@ -35,10 +35,18 @@ const AA64InsnDesc aa64_insn_table[] = { * Alias MOV Rd, Rm is ORR Rd, ZR, Rm with shift=0, imm6=0. The mask * pins Rn (bits 9:5) to 11111 (ZR) and shift/imm6 to 0 so only the * MOV spelling matches; broader ORR rows below catch the rest. */ - {MN("mov"), 0x2A0003E0u, 0x7FE0FFE0u, AA64_FMT_LOG_SR, AA64_ASMFL_ALIAS, + {MN("mov"), + 0x2A0003E0u, + 0x7FE0FFE0u, + AA64_FMT_LOG_SR, + AA64_ASMFL_ALIAS, {0, 0}}, /* MVN Rd, Rm ≡ ORN Rd, ZR, Rm (logical N=1, Rn=ZR, no shift) */ - {MN("mvn"), 0x2A2003E0u, 0x7FE0FFE0u, AA64_FMT_LOG_SR, AA64_ASMFL_ALIAS, + {MN("mvn"), + 0x2A2003E0u, + 0x7FE0FFE0u, + AA64_FMT_LOG_SR, + AA64_ASMFL_ALIAS, {0, 0}}, {MN("and"), 0x0A000000u, 0x7F200000u, AA64_FMT_LOG_SR, 0, {0, 0}}, {MN("bic"), 0x0A200000u, 0x7F200000u, AA64_FMT_LOG_SR, 0, {0, 0}}, @@ -51,15 +59,31 @@ const AA64InsnDesc aa64_insn_table[] = { /* ----- Add/Sub, shifted register ----- * NEG Rd, Rm ≡ SUB Rd, ZR, Rm (Rn=ZR, shift=0, imm6=0). */ - {MN("neg"), 0x4B0003E0u, 0x7FE0FFE0u, AA64_FMT_ADDSUB_SR, AA64_ASMFL_ALIAS, + {MN("neg"), + 0x4B0003E0u, + 0x7FE0FFE0u, + AA64_FMT_ADDSUB_SR, + AA64_ASMFL_ALIAS, {0, 0}}, - {MN("negs"), 0x6B0003E0u, 0x7FE0FFE0u, AA64_FMT_ADDSUB_SR, AA64_ASMFL_ALIAS, + {MN("negs"), + 0x6B0003E0u, + 0x7FE0FFE0u, + AA64_FMT_ADDSUB_SR, + AA64_ASMFL_ALIAS, {0, 0}}, /* CMP Rn, Rm ≡ SUBS ZR, Rn, Rm. */ - {MN("cmp"), 0x6B00001Fu, 0x7F20001Fu, AA64_FMT_ADDSUB_SR, AA64_ASMFL_ALIAS, + {MN("cmp"), + 0x6B00001Fu, + 0x7F20001Fu, + AA64_FMT_ADDSUB_SR, + AA64_ASMFL_ALIAS, {0, 0}}, /* CMN Rn, Rm ≡ ADDS ZR, Rn, Rm. */ - {MN("cmn"), 0x2B00001Fu, 0x7F20001Fu, AA64_FMT_ADDSUB_SR, AA64_ASMFL_ALIAS, + {MN("cmn"), + 0x2B00001Fu, + 0x7F20001Fu, + AA64_FMT_ADDSUB_SR, + AA64_ASMFL_ALIAS, {0, 0}}, {MN("add"), 0x0B000000u, 0x7F200000u, AA64_FMT_ADDSUB_SR, 0, {0, 0}}, {MN("adds"), 0x2B000000u, 0x7F200000u, AA64_FMT_ADDSUB_SR, 0, {0, 0}}, @@ -68,9 +92,19 @@ const AA64InsnDesc aa64_insn_table[] = { /* ----- Data-processing 3-source ----- * MUL Rd, Rn, Rm ≡ MADD Rd, Rn, Rm, ZR (Ra=ZR, op31=0, o0=0). */ - {MN("mul"), 0x1B007C00u, 0x7FE0FC00u, AA64_FMT_DP3, AA64_ASMFL_ALIAS, {0, 0}}, + {MN("mul"), + 0x1B007C00u, + 0x7FE0FC00u, + AA64_FMT_DP3, + AA64_ASMFL_ALIAS, + {0, 0}}, /* MNEG Rd, Rn, Rm ≡ MSUB Rd, Rn, Rm, ZR. */ - {MN("mneg"), 0x1B00FC00u, 0x7FE0FC00u, AA64_FMT_DP3, AA64_ASMFL_ALIAS, {0, 0}}, + {MN("mneg"), + 0x1B00FC00u, + 0x7FE0FC00u, + AA64_FMT_DP3, + AA64_ASMFL_ALIAS, + {0, 0}}, {MN("madd"), 0x1B000000u, 0x7FE08000u, AA64_FMT_DP3, 0, {0, 0}}, {MN("msub"), 0x1B008000u, 0x7FE08000u, AA64_FMT_DP3, 0, {0, 0}}, @@ -87,10 +121,18 @@ const AA64InsnDesc aa64_insn_table[] = { * CSETM Rd, cond ≡ CSINV Rd, ZR, ZR, invert(cond). * These aliases are expressible as fixed Rn/Rm=ZR masks, so put them * before the canonical conditional-select rows. */ - {MN("cset"), 0x1A9F07E0u, 0x7FE00C00u | (0x1Fu << 16) | (0x1Fu << 5), - AA64_FMT_CONDSEL, AA64_ASMFL_ALIAS, {0, 0}}, - {MN("csetm"), 0x5A9F03E0u, 0x7FE00C00u | (0x1Fu << 16) | (0x1Fu << 5), - AA64_FMT_CONDSEL, AA64_ASMFL_ALIAS, {0, 0}}, + {MN("cset"), + 0x1A9F07E0u, + 0x7FE00C00u | (0x1Fu << 16) | (0x1Fu << 5), + AA64_FMT_CONDSEL, + AA64_ASMFL_ALIAS, + {0, 0}}, + {MN("csetm"), + 0x5A9F03E0u, + 0x7FE00C00u | (0x1Fu << 16) | (0x1Fu << 5), + AA64_FMT_CONDSEL, + AA64_ASMFL_ALIAS, + {0, 0}}, {MN("csel"), 0x1A800000u, 0x7FE00C00u, AA64_FMT_CONDSEL, 0, {0, 0}}, {MN("csinc"), 0x1A800400u, 0x7FE00C00u, AA64_FMT_CONDSEL, 0, {0, 0}}, {MN("csinv"), 0x5A800000u, 0x7FE00C00u, AA64_FMT_CONDSEL, 0, {0, 0}}, @@ -100,8 +142,12 @@ const AA64InsnDesc aa64_insn_table[] = { * RET aliases its no-operand spelling to RET X30 (Rn=11110). The * tighter row matches when Rn=30 and prints "ret" without operands; * the looser row below catches RET Xn for other Rn. */ - {MN("ret"), 0xD65F03C0u, 0xFFFFFFFFu, AA64_FMT_BR_REG, - AA64_ASMFL_ALIAS | AA64_ASMFL_NORN, {0, 0}}, + {MN("ret"), + 0xD65F03C0u, + 0xFFFFFFFFu, + AA64_FMT_BR_REG, + AA64_ASMFL_ALIAS | AA64_ASMFL_NORN, + {0, 0}}, {MN("br"), 0xD61F0000u, 0xFFFFFC1Fu, AA64_FMT_BR_REG, 0, {0, 0}}, {MN("blr"), 0xD63F0000u, 0xFFFFFC1Fu, AA64_FMT_BR_REG, 0, {0, 0}}, {MN("ret"), 0xD65F0000u, 0xFFFFFC1Fu, AA64_FMT_BR_REG, 0, {0, 0}}, @@ -112,9 +158,17 @@ const AA64InsnDesc aa64_insn_table[] = { /* ----- Add/Sub immediate ----- * CMP/CMN immediate are the Rd=ZR aliases of SUBS/ADDS immediate. */ - {MN("cmn"), 0x3100001Fu, 0x7F00001Fu, AA64_FMT_ADDSUB_IMM, AA64_ASMFL_ALIAS, + {MN("cmn"), + 0x3100001Fu, + 0x7F00001Fu, + AA64_FMT_ADDSUB_IMM, + AA64_ASMFL_ALIAS, {0, 0}}, - {MN("cmp"), 0x7100001Fu, 0x7F00001Fu, AA64_FMT_ADDSUB_IMM, AA64_ASMFL_ALIAS, + {MN("cmp"), + 0x7100001Fu, + 0x7F00001Fu, + AA64_FMT_ADDSUB_IMM, + AA64_ASMFL_ALIAS, {0, 0}}, {MN("add"), 0x11000000u, 0x7F000000u, AA64_FMT_ADDSUB_IMM, 0, {0, 0}}, {MN("adds"), 0x31000000u, 0x7F000000u, AA64_FMT_ADDSUB_IMM, 0, {0, 0}}, @@ -127,24 +181,44 @@ const AA64InsnDesc aa64_insn_table[] = { {MN("ldrb"), 0x39400000u, 0xFFC00000u, AA64_FMT_LDST_UIMM, 0, {0, 0}}, {MN("strh"), 0x79000000u, 0xFFC00000u, AA64_FMT_LDST_UIMM, 0, {0, 0}}, {MN("ldrh"), 0x79400000u, 0xFFC00000u, AA64_FMT_LDST_UIMM, 0, {0, 0}}, - {MN("str"), 0xB9000000u, 0xFFC00000u, AA64_FMT_LDST_UIMM, 0, {0, 0}}, /* 32 */ + {MN("str"), 0xB9000000u, 0xFFC00000u, AA64_FMT_LDST_UIMM, 0, {0, 0}}, /* 32 + */ {MN("ldr"), 0xB9400000u, 0xFFC00000u, AA64_FMT_LDST_UIMM, 0, {0, 0}}, - {MN("str"), 0xF9000000u, 0xFFC00000u, AA64_FMT_LDST_UIMM, AA64_ASMFL_SF1, + {MN("str"), + 0xF9000000u, + 0xFFC00000u, + AA64_FMT_LDST_UIMM, + AA64_ASMFL_SF1, {0, 0}}, /* 64 */ - {MN("ldr"), 0xF9400000u, 0xFFC00000u, AA64_FMT_LDST_UIMM, AA64_ASMFL_SF1, + {MN("ldr"), + 0xF9400000u, + 0xFFC00000u, + AA64_FMT_LDST_UIMM, + AA64_ASMFL_SF1, {0, 0}}, /* SIMD/FP scaled loads/stores (V=1). size 0..2 select B/H/S; size=3 * selects D; the 128-bit Q form uses size=00 with opc bit 1 set and * is not yet emitted by codegen. */ - {MN("str"), 0x3D000000u, 0xFFC00000u, AA64_FMT_LDST_UIMM, 0, {0, 0}}, /* B */ + {MN("str"), 0x3D000000u, 0xFFC00000u, AA64_FMT_LDST_UIMM, 0, {0, 0}}, /* B + */ {MN("ldr"), 0x3D400000u, 0xFFC00000u, AA64_FMT_LDST_UIMM, 0, {0, 0}}, - {MN("str"), 0x7D000000u, 0xFFC00000u, AA64_FMT_LDST_UIMM, 0, {0, 0}}, /* H */ + {MN("str"), 0x7D000000u, 0xFFC00000u, AA64_FMT_LDST_UIMM, 0, {0, 0}}, /* H + */ {MN("ldr"), 0x7D400000u, 0xFFC00000u, AA64_FMT_LDST_UIMM, 0, {0, 0}}, - {MN("str"), 0xBD000000u, 0xFFC00000u, AA64_FMT_LDST_UIMM, 0, {0, 0}}, /* S */ + {MN("str"), 0xBD000000u, 0xFFC00000u, AA64_FMT_LDST_UIMM, 0, {0, 0}}, /* S + */ {MN("ldr"), 0xBD400000u, 0xFFC00000u, AA64_FMT_LDST_UIMM, 0, {0, 0}}, - {MN("str"), 0xFD000000u, 0xFFC00000u, AA64_FMT_LDST_UIMM, AA64_ASMFL_SF1, + {MN("str"), + 0xFD000000u, + 0xFFC00000u, + AA64_FMT_LDST_UIMM, + AA64_ASMFL_SF1, {0, 0}}, /* D */ - {MN("ldr"), 0xFD400000u, 0xFFC00000u, AA64_FMT_LDST_UIMM, AA64_ASMFL_SF1, + {MN("ldr"), + 0xFD400000u, + 0xFFC00000u, + AA64_FMT_LDST_UIMM, + AA64_ASMFL_SF1, {0, 0}}, /* ----- Load/store, unscaled signed 9-bit immediate (LDUR/STUR) ----- @@ -154,45 +228,115 @@ const AA64InsnDesc aa64_insn_table[] = { {MN("ldurb"), 0x38400000u, 0xFFE00C00u, AA64_FMT_LDST_SIMM9, 0, {0, 0}}, {MN("sturh"), 0x78000000u, 0xFFE00C00u, AA64_FMT_LDST_SIMM9, 0, {0, 0}}, {MN("ldurh"), 0x78400000u, 0xFFE00C00u, AA64_FMT_LDST_SIMM9, 0, {0, 0}}, - {MN("stur"), 0xB8000000u, 0xFFE00C00u, AA64_FMT_LDST_SIMM9, 0, {0, 0}}, /* 32 */ + {MN("stur"), + 0xB8000000u, + 0xFFE00C00u, + AA64_FMT_LDST_SIMM9, + 0, + {0, 0}}, /* 32 */ {MN("ldur"), 0xB8400000u, 0xFFE00C00u, AA64_FMT_LDST_SIMM9, 0, {0, 0}}, - {MN("stur"), 0xF8000000u, 0xFFE00C00u, AA64_FMT_LDST_SIMM9, AA64_ASMFL_SF1, + {MN("stur"), + 0xF8000000u, + 0xFFE00C00u, + AA64_FMT_LDST_SIMM9, + AA64_ASMFL_SF1, {0, 0}}, - {MN("ldur"), 0xF8400000u, 0xFFE00C00u, AA64_FMT_LDST_SIMM9, AA64_ASMFL_SF1, + {MN("ldur"), + 0xF8400000u, + 0xFFE00C00u, + AA64_FMT_LDST_SIMM9, + AA64_ASMFL_SF1, {0, 0}}, - {MN("stur"), 0x3C000000u, 0xFFE00C00u, AA64_FMT_LDST_SIMM9, 0, {0, 0}}, /* B */ + {MN("stur"), + 0x3C000000u, + 0xFFE00C00u, + AA64_FMT_LDST_SIMM9, + 0, + {0, 0}}, /* B */ {MN("ldur"), 0x3C400000u, 0xFFE00C00u, AA64_FMT_LDST_SIMM9, 0, {0, 0}}, - {MN("stur"), 0x7C000000u, 0xFFE00C00u, AA64_FMT_LDST_SIMM9, 0, {0, 0}}, /* H */ + {MN("stur"), + 0x7C000000u, + 0xFFE00C00u, + AA64_FMT_LDST_SIMM9, + 0, + {0, 0}}, /* H */ {MN("ldur"), 0x7C400000u, 0xFFE00C00u, AA64_FMT_LDST_SIMM9, 0, {0, 0}}, - {MN("stur"), 0xBC000000u, 0xFFE00C00u, AA64_FMT_LDST_SIMM9, 0, {0, 0}}, /* S */ + {MN("stur"), + 0xBC000000u, + 0xFFE00C00u, + AA64_FMT_LDST_SIMM9, + 0, + {0, 0}}, /* S */ {MN("ldur"), 0xBC400000u, 0xFFE00C00u, AA64_FMT_LDST_SIMM9, 0, {0, 0}}, - {MN("stur"), 0xFC000000u, 0xFFE00C00u, AA64_FMT_LDST_SIMM9, AA64_ASMFL_SF1, + {MN("stur"), + 0xFC000000u, + 0xFFE00C00u, + AA64_FMT_LDST_SIMM9, + AA64_ASMFL_SF1, {0, 0}}, /* D */ - {MN("ldur"), 0xFC400000u, 0xFFE00C00u, AA64_FMT_LDST_SIMM9, AA64_ASMFL_SF1, + {MN("ldur"), + 0xFC400000u, + 0xFFE00C00u, + AA64_FMT_LDST_SIMM9, + AA64_ASMFL_SF1, {0, 0}}, /* ----- Load/store pair, pre-indexed (opc=10 X / opc=01 D) ----- */ - {MN("stp"), 0xA9800000u, 0xFFC00000u, AA64_FMT_LDSTP_PRE, AA64_ASMFL_SF1, + {MN("stp"), + 0xA9800000u, + 0xFFC00000u, + AA64_FMT_LDSTP_PRE, + AA64_ASMFL_SF1, {0, 0}}, - {MN("ldp"), 0xA9C00000u, 0xFFC00000u, AA64_FMT_LDSTP_PRE, AA64_ASMFL_SF1, + {MN("ldp"), + 0xA9C00000u, + 0xFFC00000u, + AA64_FMT_LDSTP_PRE, + AA64_ASMFL_SF1, {0, 0}}, - {MN("stp"), 0x6D800000u, 0xFFC00000u, AA64_FMT_LDSTP_PRE, 0, {0, 0}}, /* D */ + {MN("stp"), 0x6D800000u, 0xFFC00000u, AA64_FMT_LDSTP_PRE, 0, {0, 0}}, /* D + */ {MN("ldp"), 0x6DC00000u, 0xFFC00000u, AA64_FMT_LDSTP_PRE, 0, {0, 0}}, - {MN("stp"), 0xAD800000u, 0xFFC00000u, AA64_FMT_LDSTP_PRE, AA64_ASMFL_SF1, + {MN("stp"), + 0xAD800000u, + 0xFFC00000u, + AA64_FMT_LDSTP_PRE, + AA64_ASMFL_SF1, {0, 0}}, /* Q */ - {MN("ldp"), 0xADC00000u, 0xFFC00000u, AA64_FMT_LDSTP_PRE, AA64_ASMFL_SF1, + {MN("ldp"), + 0xADC00000u, + 0xFFC00000u, + AA64_FMT_LDSTP_PRE, + AA64_ASMFL_SF1, {0, 0}}, /* ----- Load/store pair, signed-offset ----- */ - {MN("stp"), 0xA9000000u, 0xFFC00000u, AA64_FMT_LDSTP_SOFF, AA64_ASMFL_SF1, + {MN("stp"), + 0xA9000000u, + 0xFFC00000u, + AA64_FMT_LDSTP_SOFF, + AA64_ASMFL_SF1, {0, 0}}, - {MN("ldp"), 0xA9400000u, 0xFFC00000u, AA64_FMT_LDSTP_SOFF, AA64_ASMFL_SF1, + {MN("ldp"), + 0xA9400000u, + 0xFFC00000u, + AA64_FMT_LDSTP_SOFF, + AA64_ASMFL_SF1, {0, 0}}, - {MN("stp"), 0x6D000000u, 0xFFC00000u, AA64_FMT_LDSTP_SOFF, 0, {0, 0}}, /* D */ + {MN("stp"), 0x6D000000u, 0xFFC00000u, AA64_FMT_LDSTP_SOFF, 0, {0, 0}}, /* D + */ {MN("ldp"), 0x6D400000u, 0xFFC00000u, AA64_FMT_LDSTP_SOFF, 0, {0, 0}}, - {MN("stp"), 0xAD000000u, 0xFFC00000u, AA64_FMT_LDSTP_SOFF, AA64_ASMFL_SF1, + {MN("stp"), + 0xAD000000u, + 0xFFC00000u, + AA64_FMT_LDSTP_SOFF, + AA64_ASMFL_SF1, {0, 0}}, /* Q */ - {MN("ldp"), 0xAD400000u, 0xFFC00000u, AA64_FMT_LDSTP_SOFF, AA64_ASMFL_SF1, + {MN("ldp"), + 0xAD400000u, + 0xFFC00000u, + AA64_FMT_LDSTP_SOFF, + AA64_ASMFL_SF1, {0, 0}}, /* ----- Unconditional branch (immediate) ----- */ @@ -216,9 +360,9 @@ const AA64InsnDesc aa64_insn_table[] = { /* ----- Memory barriers (DMB / DSB / ISB / CLREX) ----- * Mask covers everything but CRm at bits[11:8]. */ - {MN("dmb"), 0xD50330BFu, 0xFFFFF0FFu, AA64_FMT_BARRIER, 0, {0, 0}}, - {MN("dsb"), 0xD503309Fu, 0xFFFFF0FFu, AA64_FMT_BARRIER, 0, {0, 0}}, - {MN("isb"), 0xD50330DFu, 0xFFFFF0FFu, AA64_FMT_BARRIER, 0, {0, 0}}, + {MN("dmb"), 0xD50330BFu, 0xFFFFF0FFu, AA64_FMT_BARRIER, 0, {0, 0}}, + {MN("dsb"), 0xD503309Fu, 0xFFFFF0FFu, AA64_FMT_BARRIER, 0, {0, 0}}, + {MN("isb"), 0xD50330DFu, 0xFFFFF0FFu, AA64_FMT_BARRIER, 0, {0, 0}}, {MN("clrex"), 0xD503305Fu, 0xFFFFF0FFu, AA64_FMT_BARRIER, 0, {0, 0}}, }; @@ -252,9 +396,12 @@ const AA64InsnDesc* aa64_disasm_find(u32 word) { static void emit_reg(StrBuf* sb, u32 r, int sf, int sp_means_sp) { if (r == 31u) { - if (sp_means_sp) strbuf_puts(sb, "sp"); - else if (sf) strbuf_puts(sb, "xzr"); - else strbuf_puts(sb, "wzr"); + if (sp_means_sp) + strbuf_puts(sb, "sp"); + else if (sf) + strbuf_puts(sb, "xzr"); + else + strbuf_puts(sb, "wzr"); return; } strbuf_putc(sb, sf ? 'x' : 'w'); @@ -539,8 +686,7 @@ static void print_br_imm(StrBuf* sb, u32 w, u64 vaddr) { } } -static void print_br_cond(StrBuf* sb, u32 w, u64 vaddr, - const AA64InsnDesc* d) { +static void print_br_cond(StrBuf* sb, u32 w, u64 vaddr, const AA64InsnDesc* d) { AA64BrCond f = aa64_brcond_unpack(w); (void)d; /* mnemonic is "b.cond"; we'll print cond as a suffix on the target. @@ -586,27 +732,50 @@ static void print_barrier(StrBuf* sb, u32 w, const AA64InsnDesc* desc) { if ((is_isb || is_clrex) && f.CRm == AA64_BARRIER_OPT_SY) return; const char* opt = NULL; switch (f.CRm) { - case AA64_BARRIER_OPT_OSHLD: opt = "oshld"; break; - case AA64_BARRIER_OPT_OSHST: opt = "oshst"; break; - case AA64_BARRIER_OPT_OSH: opt = "osh"; break; - case AA64_BARRIER_OPT_NSHLD: opt = "nshld"; break; - case AA64_BARRIER_OPT_NSHST: opt = "nshst"; break; - case AA64_BARRIER_OPT_NSH: opt = "nsh"; break; - case AA64_BARRIER_OPT_ISHLD: opt = "ishld"; break; - case AA64_BARRIER_OPT_ISHST: opt = "ishst"; break; - case AA64_BARRIER_OPT_ISH: opt = "ish"; break; - case AA64_BARRIER_OPT_LD: opt = (desc && desc->mnemonic.len >= 2 && - desc->mnemonic.s[0] == 'd' && - desc->mnemonic.s[1] == 'm') - ? "ld" - : NULL; break; - case AA64_BARRIER_OPT_ST: opt = (desc && desc->mnemonic.len >= 2 && - desc->mnemonic.s[0] == 'd' && - desc->mnemonic.s[1] == 'm') - ? "st" - : NULL; break; - case AA64_BARRIER_OPT_SY: opt = "sy"; break; - default: break; + case AA64_BARRIER_OPT_OSHLD: + opt = "oshld"; + break; + case AA64_BARRIER_OPT_OSHST: + opt = "oshst"; + break; + case AA64_BARRIER_OPT_OSH: + opt = "osh"; + break; + case AA64_BARRIER_OPT_NSHLD: + opt = "nshld"; + break; + case AA64_BARRIER_OPT_NSHST: + opt = "nshst"; + break; + case AA64_BARRIER_OPT_NSH: + opt = "nsh"; + break; + case AA64_BARRIER_OPT_ISHLD: + opt = "ishld"; + break; + case AA64_BARRIER_OPT_ISHST: + opt = "ishst"; + break; + case AA64_BARRIER_OPT_ISH: + opt = "ish"; + break; + case AA64_BARRIER_OPT_LD: + opt = (desc && desc->mnemonic.len >= 2 && desc->mnemonic.s[0] == 'd' && + desc->mnemonic.s[1] == 'm') + ? "ld" + : NULL; + break; + case AA64_BARRIER_OPT_ST: + opt = (desc && desc->mnemonic.len >= 2 && desc->mnemonic.s[0] == 'd' && + desc->mnemonic.s[1] == 'm') + ? "st" + : NULL; + break; + case AA64_BARRIER_OPT_SY: + opt = "sy"; + break; + default: + break; } strbuf_putc(sb, ' '); if (opt) { @@ -620,25 +789,62 @@ static void print_barrier(StrBuf* sb, u32 w, const AA64InsnDesc* desc) { void aa64_print_operands(StrBuf* sb, const AA64InsnDesc* desc, u32 word, u64 vaddr) { switch ((AA64Format)desc->fmt) { - case AA64_FMT_MOVEWIDE: print_movewide(sb, word); break; - case AA64_FMT_LOG_SR: print_logsr(sb, word, desc); break; - case AA64_FMT_ADDSUB_SR: print_addsubsr(sb, word, desc); break; - case AA64_FMT_DP3: print_dp3(sb, word, desc); break; - case AA64_FMT_DP2: print_dp2(sb, word); break; - case AA64_FMT_CONDSEL: print_condsel(sb, word, desc); break; - case AA64_FMT_BR_REG: print_brreg(sb, word, desc); break; - case AA64_FMT_PCREL_ADR: print_pcrel(sb, word, vaddr); break; - case AA64_FMT_ADDSUB_IMM: print_addsubimm(sb, word); break; - case AA64_FMT_LDST_UIMM: print_ldst_uimm(sb, word, desc); break; - case AA64_FMT_LDSTP_PRE: print_ldstp_pre(sb, word); break; - case AA64_FMT_LDSTP_SOFF: print_ldstp_soff(sb, word); break; - case AA64_FMT_LDST_SIMM9: print_ldst_simm9(sb, word, desc); break; - case AA64_FMT_BR_IMM: print_br_imm(sb, word, vaddr); break; - case AA64_FMT_BR_COND: print_br_cond(sb, word, vaddr, desc); break; - case AA64_FMT_CB: print_cb(sb, word, vaddr); break; - case AA64_FMT_EXCEPT: print_except(sb, word); break; - case AA64_FMT_HINT: break; /* no operands for NOP */ - case AA64_FMT_BARRIER: print_barrier(sb, word, desc); break; + case AA64_FMT_MOVEWIDE: + print_movewide(sb, word); + break; + case AA64_FMT_LOG_SR: + print_logsr(sb, word, desc); + break; + case AA64_FMT_ADDSUB_SR: + print_addsubsr(sb, word, desc); + break; + case AA64_FMT_DP3: + print_dp3(sb, word, desc); + break; + case AA64_FMT_DP2: + print_dp2(sb, word); + break; + case AA64_FMT_CONDSEL: + print_condsel(sb, word, desc); + break; + case AA64_FMT_BR_REG: + print_brreg(sb, word, desc); + break; + case AA64_FMT_PCREL_ADR: + print_pcrel(sb, word, vaddr); + break; + case AA64_FMT_ADDSUB_IMM: + print_addsubimm(sb, word); + break; + case AA64_FMT_LDST_UIMM: + print_ldst_uimm(sb, word, desc); + break; + case AA64_FMT_LDSTP_PRE: + print_ldstp_pre(sb, word); + break; + case AA64_FMT_LDSTP_SOFF: + print_ldstp_soff(sb, word); + break; + case AA64_FMT_LDST_SIMM9: + print_ldst_simm9(sb, word, desc); + break; + case AA64_FMT_BR_IMM: + print_br_imm(sb, word, vaddr); + break; + case AA64_FMT_BR_COND: + print_br_cond(sb, word, vaddr, desc); + break; + case AA64_FMT_CB: + print_cb(sb, word, vaddr); + break; + case AA64_FMT_EXCEPT: + print_except(sb, word); + break; + case AA64_FMT_HINT: + break; /* no operands for NOP */ + case AA64_FMT_BARRIER: + print_barrier(sb, word, desc); + break; } } diff --git a/src/arch/aa64/isa.h b/src/arch/aa64/isa.h @@ -64,9 +64,11 @@ typedef enum AA64Format { * carry 0. When the disassembler matches a row whose ALIAS bit is set, * that's the spelling it prints; the assembler also accepts both the * alias and the canonical form because both rows live in the table. */ -#define AA64_ASMFL_ALIAS 0x01u /* row is an alias (e.g. MOV → ORR Rd, ZR, Rm) */ -#define AA64_ASMFL_SF1 0x02u /* 64-bit form only (sf hard-wired) */ -#define AA64_ASMFL_NORN 0x04u /* hide Rn operand in print (e.g. RET when Rn=30) */ +#define AA64_ASMFL_ALIAS 0x01u /* row is an alias (e.g. MOV → ORR Rd, ZR, Rm) \ + */ +#define AA64_ASMFL_SF1 0x02u /* 64-bit form only (sf hard-wired) */ +#define AA64_ASMFL_NORN \ + 0x04u /* hide Rn operand in print (e.g. RET when Rn=30) */ /* ==================================================================== * Move-wide immediate (MOVN / MOVZ / MOVK) @@ -246,8 +248,8 @@ static inline u32 aa64_eor_imm(u32 sf, u32 Rd, u32 Rn, u32 N, u32 immr, * repeating period; find the rotation that places the 1-run at the * LSB; encode size and ones-count into imms per the standard scheme * (top bits of imms inverted-encode size, low bits are ones-count-1). */ -static inline int aa64_logimm_encode(u64 imm, u32 sf, u32 *N_out, - u32 *immr_out, u32 *imms_out) { +static inline int aa64_logimm_encode(u64 imm, u32 sf, u32* N_out, u32* immr_out, + u32* imms_out) { if (!sf) { u64 lo = imm & 0xFFFFFFFFu; u64 hi = imm >> 32; @@ -273,8 +275,12 @@ static inline int aa64_logimm_encode(u64 imm, u32 sf, u32 *N_out, u64 aligned = ((u64)1 << ones) - 1u; u32 rotation = 0xFFFFFFFFu; for (u32 r = 0; r < size; r++) { - u64 rotated = r == 0 ? elt : (((elt >> r) | (elt << (size - r))) & elt_mask); - if (rotated == aligned) { rotation = r; break; } + u64 rotated = + r == 0 ? elt : (((elt >> r) | (elt << (size - r))) & elt_mask); + if (rotated == aligned) { + rotation = r; + break; + } } if (rotation == 0xFFFFFFFFu) return 0; @@ -294,24 +300,24 @@ static inline int aa64_logimm_encode(u64 imm, u32 sf, u32 *N_out, * UBFM/SBFM). Predicate: shift < width. The aa64_ubfm / aa64_sbfm * encoders live in aarch64.c; callers pair these (immr, imms) with the * matching pack. */ -static inline int aa64_lsl_imm_fields(u32 shift, u32 sf, u32 *immr_out, - u32 *imms_out) { +static inline int aa64_lsl_imm_fields(u32 shift, u32 sf, u32* immr_out, + u32* imms_out) { u32 width = sf ? 64u : 32u; if (shift >= width) return 0; *immr_out = (width - shift) & (width - 1u); *imms_out = width - 1u - shift; return 1; } -static inline int aa64_lsr_imm_fields(u32 shift, u32 sf, u32 *immr_out, - u32 *imms_out) { +static inline int aa64_lsr_imm_fields(u32 shift, u32 sf, u32* immr_out, + u32* imms_out) { u32 width = sf ? 64u : 32u; if (shift >= width) return 0; *immr_out = shift; *imms_out = width - 1u; return 1; } -static inline int aa64_asr_imm_fields(u32 shift, u32 sf, u32 *immr_out, - u32 *imms_out) { +static inline int aa64_asr_imm_fields(u32 shift, u32 sf, u32* immr_out, + u32* imms_out) { u32 width = sf ? 64u : 32u; if (shift >= width) return 0; *immr_out = shift; @@ -489,11 +495,10 @@ typedef struct AA64CondSel { } AA64CondSel; static inline u32 aa64_condsel_pack(AA64CondSel f) { - return ((f.sf & 1u) << 31) | ((f.op & 1u) << 30) | - ((f.S & 1u) << 29) | AA64_CONDSEL_FAMILY_MATCH | - ((f.Rm & 0x1fu) << 16) | ((f.cond & 0xfu) << 12) | - ((f.op2 & 3u) << 10) | ((f.Rn & 0x1fu) << 5) | - (f.Rd & 0x1fu); + return ((f.sf & 1u) << 31) | ((f.op & 1u) << 30) | ((f.S & 1u) << 29) | + AA64_CONDSEL_FAMILY_MATCH | ((f.Rm & 0x1fu) << 16) | + ((f.cond & 0xfu) << 12) | ((f.op2 & 3u) << 10) | + ((f.Rn & 0x1fu) << 5) | (f.Rd & 0x1fu); } static inline AA64CondSel aa64_condsel_unpack(u32 w) { @@ -698,12 +703,18 @@ static inline u32 aa64_subs_imm12(u32 sf, u32 Rd, u32 Rn, u32 imm12, u32 sh) { * (e.g. opt's machinize, or a smarter cg) is free to swap ADD ↔ SUB and * retry with the negated literal; the bare predicate keeps the contract * narrow. */ -static inline int aa64_addsub_imm_fits(i64 imm, u32 *imm12_out, u32 *sh_out) { +static inline int aa64_addsub_imm_fits(i64 imm, u32* imm12_out, u32* sh_out) { if (imm < 0) return 0; u64 u = (u64)imm; - if (u <= 0xFFFu) { *imm12_out = (u32)u; *sh_out = 0; return 1; } + if (u <= 0xFFFu) { + *imm12_out = (u32)u; + *sh_out = 0; + return 1; + } if ((u & 0xFFFu) == 0 && (u >> 12) <= 0xFFFu) { - *imm12_out = (u32)(u >> 12); *sh_out = 1; return 1; + *imm12_out = (u32)(u >> 12); + *sh_out = 1; + return 1; } return 0; } @@ -877,23 +888,23 @@ static inline u32 aa64_nop(void) { #define AA64_BARRIER_FAMILY_MASK 0xFFFFF01Fu /* CRm + op2 vary */ #define AA64_BARRIER_OP2_CLREX 2u -#define AA64_BARRIER_OP2_DSB 4u -#define AA64_BARRIER_OP2_DMB 5u -#define AA64_BARRIER_OP2_ISB 6u +#define AA64_BARRIER_OP2_DSB 4u +#define AA64_BARRIER_OP2_DMB 5u +#define AA64_BARRIER_OP2_ISB 6u /* Common CRm option encodings (ARM ARM C5.1.42). */ #define AA64_BARRIER_OPT_OSHLD 1u #define AA64_BARRIER_OPT_OSHST 2u -#define AA64_BARRIER_OPT_OSH 3u +#define AA64_BARRIER_OPT_OSH 3u #define AA64_BARRIER_OPT_NSHLD 5u #define AA64_BARRIER_OPT_NSHST 6u -#define AA64_BARRIER_OPT_NSH 7u +#define AA64_BARRIER_OPT_NSH 7u #define AA64_BARRIER_OPT_ISHLD 9u #define AA64_BARRIER_OPT_ISHST 10u -#define AA64_BARRIER_OPT_ISH 11u -#define AA64_BARRIER_OPT_LD 13u -#define AA64_BARRIER_OPT_ST 14u -#define AA64_BARRIER_OPT_SY 15u +#define AA64_BARRIER_OPT_ISH 11u +#define AA64_BARRIER_OPT_LD 13u +#define AA64_BARRIER_OPT_ST 14u +#define AA64_BARRIER_OPT_SY 15u typedef struct AA64Barrier { u32 CRm, op2; @@ -912,13 +923,16 @@ static inline AA64Barrier aa64_barrier_unpack(u32 w) { } static inline u32 aa64_dmb(u32 opt) { - return aa64_barrier_pack((AA64Barrier){.CRm = opt, .op2 = AA64_BARRIER_OP2_DMB}); + return aa64_barrier_pack( + (AA64Barrier){.CRm = opt, .op2 = AA64_BARRIER_OP2_DMB}); } static inline u32 aa64_dsb(u32 opt) { - return aa64_barrier_pack((AA64Barrier){.CRm = opt, .op2 = AA64_BARRIER_OP2_DSB}); + return aa64_barrier_pack( + (AA64Barrier){.CRm = opt, .op2 = AA64_BARRIER_OP2_DSB}); } static inline u32 aa64_isb(u32 opt) { - return aa64_barrier_pack((AA64Barrier){.CRm = opt, .op2 = AA64_BARRIER_OP2_ISB}); + return aa64_barrier_pack( + (AA64Barrier){.CRm = opt, .op2 = AA64_BARRIER_OP2_ISB}); } static inline u32 aa64_clrex(u32 opt) { return aa64_barrier_pack( @@ -978,8 +992,8 @@ typedef struct AA64LdStSimm9 { static inline u32 aa64_ldst_simm9_pack(AA64LdStSimm9 f) { return ((f.size & 3u) << 30) | AA64_LDST_SIMM9_FAMILY_MATCH | - ((f.V & 1u) << 26) | ((f.opc & 3u) << 22) | - ((f.imm9 & 0x1ffu) << 12) | ((f.Rn & 0x1fu) << 5) | (f.Rt & 0x1fu); + ((f.V & 1u) << 26) | ((f.opc & 3u) << 22) | ((f.imm9 & 0x1ffu) << 12) | + ((f.Rn & 0x1fu) << 5) | (f.Rt & 0x1fu); } static inline AA64LdStSimm9 aa64_ldst_simm9_unpack(u32 w) { @@ -1010,7 +1024,8 @@ typedef struct AA64BrImm { } AA64BrImm; static inline u32 aa64_brimm_pack(AA64BrImm f) { - return ((f.op & 1u) << 31) | AA64_BR_IMM_FAMILY_MATCH | (f.imm26 & 0x3ffffffu); + return ((f.op & 1u) << 31) | AA64_BR_IMM_FAMILY_MATCH | + (f.imm26 & 0x3ffffffu); } static inline AA64BrImm aa64_brimm_unpack(u32 w) { @@ -1036,7 +1051,8 @@ static inline u32 aa64_bl(u32 imm26) { * condition code (EQ=0, NE=1, ...). */ #define AA64_BR_COND_FAMILY_MATCH 0x54000000u -#define AA64_BR_COND_FAMILY_MASK 0xFF000010u /* bits 31:24 fixed + bit 4 = 0 */ +#define AA64_BR_COND_FAMILY_MASK 0xFF000010u /* bits 31:24 fixed + bit 4 = 0 \ + */ typedef struct AA64BrCond { u32 imm19, cond; diff --git a/src/arch/aa64/ops.c b/src/arch/aa64/ops.c @@ -75,13 +75,13 @@ static void aa_copy(CGTarget* t, Operand dst, Operand src) { if (dst.cls == RC_FP && src.cls == RC_INT) { u32 sz = type_byte_size(dst.type); aa64_emit32(t->mc, sz == 8 ? aa64_fmov_d_x(reg_num(dst), reg_num(src)) - : aa64_fmov_s_w(reg_num(dst), reg_num(src))); + : aa64_fmov_s_w(reg_num(dst), reg_num(src))); return; } if (dst.cls == RC_INT && src.cls == RC_FP) { u32 sz = type_byte_size(src.type); aa64_emit32(t->mc, sz == 8 ? aa64_fmov_x_d(reg_num(dst), reg_num(src)) - : aa64_fmov_w_s(reg_num(dst), reg_num(src))); + : aa64_fmov_w_s(reg_num(dst), reg_num(src))); return; } if (dst.cls == RC_FP || src.cls == RC_FP) { @@ -103,12 +103,18 @@ static void aa_copy(CGTarget* t, Operand dst, Operand src) { static RelocKind ldst_lo12_reloc_for(u32 nbytes) { switch (nbytes) { - case 1: return R_AARCH64_LDST8_ABS_LO12_NC; - case 2: return R_AARCH64_LDST16_ABS_LO12_NC; - case 4: return R_AARCH64_LDST32_ABS_LO12_NC; - case 8: return R_AARCH64_LDST64_ABS_LO12_NC; - case 16: return R_AARCH64_LDST128_ABS_LO12_NC; - default: return R_AARCH64_LDST64_ABS_LO12_NC; + case 1: + return R_AARCH64_LDST8_ABS_LO12_NC; + case 2: + return R_AARCH64_LDST16_ABS_LO12_NC; + case 4: + return R_AARCH64_LDST32_ABS_LO12_NC; + case 8: + return R_AARCH64_LDST64_ABS_LO12_NC; + case 16: + return R_AARCH64_LDST128_ABS_LO12_NC; + default: + return R_AARCH64_LDST64_ABS_LO12_NC; } } @@ -260,20 +266,20 @@ static inline void aa_assert_no_index(CGTarget* t, Operand addr, * The aarch64 register-offset addressing mode supports only those two * shift amounts (other values must be lowered upstream). */ static inline u32 aa64_ldr_reg(u32 size, u32 Rt, u32 Rn, u32 Rm, u32 S) { - return 0x38606800u | (size << 30) | ((Rm & 0x1fu) << 16) | - ((S & 1u) << 12) | ((Rn & 0x1fu) << 5) | (Rt & 0x1fu); + return 0x38606800u | (size << 30) | ((Rm & 0x1fu) << 16) | ((S & 1u) << 12) | + ((Rn & 0x1fu) << 5) | (Rt & 0x1fu); } static inline u32 aa64_str_reg(u32 size, u32 Rt, u32 Rn, u32 Rm, u32 S) { - return 0x38206800u | (size << 30) | ((Rm & 0x1fu) << 16) | - ((S & 1u) << 12) | ((Rn & 0x1fu) << 5) | (Rt & 0x1fu); + return 0x38206800u | (size << 30) | ((Rm & 0x1fu) << 16) | ((S & 1u) << 12) | + ((Rn & 0x1fu) << 5) | (Rt & 0x1fu); } static inline u32 aa64_ldr_fp_reg(u32 size, u32 Rt, u32 Rn, u32 Rm, u32 S) { - return 0x3C606800u | (size << 30) | ((Rm & 0x1fu) << 16) | - ((S & 1u) << 12) | ((Rn & 0x1fu) << 5) | (Rt & 0x1fu); + return 0x3C606800u | (size << 30) | ((Rm & 0x1fu) << 16) | ((S & 1u) << 12) | + ((Rn & 0x1fu) << 5) | (Rt & 0x1fu); } static inline u32 aa64_str_fp_reg(u32 size, u32 Rt, u32 Rn, u32 Rm, u32 S) { - return 0x3C206800u | (size << 30) | ((Rm & 0x1fu) << 16) | - ((S & 1u) << 12) | ((Rn & 0x1fu) << 5) | (Rt & 0x1fu); + return 0x3C206800u | (size << 30) | ((Rm & 0x1fu) << 16) | ((S & 1u) << 12) | + ((Rn & 0x1fu) << 5) | (Rt & 0x1fu); } /* 128-bit Q register-offset variants (size encoded as size=00, opc bit * pattern 11 selects 128b). */ @@ -291,10 +297,15 @@ static inline u32 aa64_str_q_reg(u32 Rt, u32 Rn, u32 Rm, u32 S) { * and S=1 (LSL #sidx) — any other scale must be lowered by adding * `index << log2_scale` into the base via arch_lower_indexed before the * load/store. */ -static inline int aa_indexed_scale_legal(u32 sidx, u32 log2_scale, - u32* S_out) { - if (log2_scale == 0u) { *S_out = 0u; return 1; } - if (log2_scale == sidx) { *S_out = 1u; return 1; } +static inline int aa_indexed_scale_legal(u32 sidx, u32 log2_scale, u32* S_out) { + if (log2_scale == 0u) { + *S_out = 0u; + return 1; + } + if (log2_scale == sidx) { + *S_out = 1u; + return 1; + } return 0; } @@ -376,8 +387,8 @@ void aa_store(CGTarget* t, Operand addr, Operand src, MemAccess ma) { u32 src_is_fp = 0; /* Zero immediate stores use wzr/xzr directly (reg 31). Avoids a * separate `mov wN, #0` and frees AA_TMP0 for the address base. */ - int src_imm_zero = (src.kind == OPK_IMM && src.v.imm == 0 && - src.cls != RC_FP); + int src_imm_zero = + (src.kind == OPK_IMM && src.v.imm == 0 && src.cls != RC_FP); if (src_imm_zero) { src_reg = 31u; } else if (src.kind == OPK_IMM) { @@ -415,10 +426,9 @@ void aa_store(CGTarget* t, Operand addr, Operand src, MemAccess ma) { } /* Zero immediate stores use wzr/xzr directly (reg 31). */ - int src_imm_zero = (src.kind == OPK_IMM && src.v.imm == 0 && - src.cls != RC_FP); - u32 addr_tmp = - (src.kind == OPK_IMM && !src_imm_zero) ? AA_TMP1 : AA_TMP0; + int src_imm_zero = + (src.kind == OPK_IMM && src.v.imm == 0 && src.cls != RC_FP); + u32 addr_tmp = (src.kind == OPK_IMM && !src_imm_zero) ? AA_TMP1 : AA_TMP0; /* Indexed register-offset form for STR when the EA's scale is legal. * Falls back to arch_lower_indexed when LSL doesn't fit the @@ -444,8 +454,7 @@ void aa_store(CGTarget* t, Operand addr, Operand src, MemAccess ma) { aa64_emit32(t->mc, aa64_str_fp_reg(sidx, src_reg, m.base, m.index, S)); } else { - aa64_emit32(t->mc, - aa64_str_reg(sidx, src_reg, m.base, m.index, S)); + aa64_emit32(t->mc, aa64_str_reg(sidx, src_reg, m.base, m.index, S)); } return; } @@ -564,8 +573,8 @@ static void aa_tls_addr_of(CGTarget* t, Operand dst, ObjSymId sym, i64 addend) { Sym idx_name = pool_intern_slice(t->c->global, SLICE_LIT("_tls_index")); ObjSymId idx_sym = obj_symbol_find(t->obj, idx_name); if (idx_sym == 0) { - idx_sym = obj_symbol(t->obj, idx_name, SB_GLOBAL, SK_UNDEF, - OBJ_SEC_NONE, 0, 0); + idx_sym = + obj_symbol(t->obj, idx_name, SB_GLOBAL, SK_UNDEF, OBJ_SEC_NONE, 0, 0); } /* Windows ARM64 reserves x18 as the TEB pointer. Do not read * TPIDR_EL0 here; Wine and real Windows expose the TLS slots via @@ -575,32 +584,29 @@ static void aa_tls_addr_of(CGTarget* t, Operand dst, ObjSymId sym, i64 addend) { u32 adrp_pos = mc->pos(mc); aa64_emit32(mc, aa64_adrp_base(/*Rd=*/16)); - mc->emit_reloc_at(mc, sec, adrp_pos, R_AARCH64_ADR_PREL_PG_HI21, - idx_sym, 0, 0, 0); + mc->emit_reloc_at(mc, sec, adrp_pos, R_AARCH64_ADR_PREL_PG_HI21, idx_sym, 0, + 0, 0); u32 ldr_pos = mc->pos(mc); - aa64_emit32(mc, - aa64_ldr_uimm(/*size=*/2, /*Rt=*/16, /*Rn=*/16, /*byte_off=*/0)); - mc->emit_reloc_at(mc, sec, ldr_pos, R_AARCH64_LDST32_ABS_LO12_NC, - idx_sym, 0, 0, 0); + aa64_emit32( + mc, aa64_ldr_uimm(/*size=*/2, /*Rt=*/16, /*Rn=*/16, /*byte_off=*/0)); + mc->emit_reloc_at(mc, sec, ldr_pos, R_AARCH64_LDST32_ABS_LO12_NC, idx_sym, + 0, 0, 0); /* add xd, xd, x16, LSL #3: * 0x8B000000 | (Rm << 16) | (3 << 10) | (Rn << 5) | Rd * sf=1, shift=LSL (00), Rm=16. */ - u32 add_shr = - 0x8B000000u | (16u << 16) | (3u << 10) | ((rd & 0x1fu) << 5) | - (rd & 0x1fu); + u32 add_shr = 0x8B000000u | (16u << 16) | (3u << 10) | ((rd & 0x1fu) << 5) | + (rd & 0x1fu); aa64_emit32(mc, add_shr); aa64_emit32(mc, aa64_ldr_uimm(/*size=*/3, rd, rd, /*byte_off=*/0)); /* add xd, xd, #(0 << 12), then patch HIGH12A: sh=1 in the encoding. */ u32 hi_pos = mc->pos(mc); - aa64_emit32(mc, - aa64_add_imm(/*sf=*/1, rd, rd, /*imm12=*/0, /*sh=*/1)); + aa64_emit32(mc, aa64_add_imm(/*sf=*/1, rd, rd, /*imm12=*/0, /*sh=*/1)); mc->emit_reloc_at(mc, sec, hi_pos, R_COFF_AARCH64_SECREL_HIGH12A, sym, addend, 0, 0); u32 lo_pos = mc->pos(mc); - aa64_emit32(mc, - aa64_add_imm(/*sf=*/1, rd, rd, /*imm12=*/0, /*sh=*/0)); + aa64_emit32(mc, aa64_add_imm(/*sf=*/1, rd, rd, /*imm12=*/0, /*sh=*/0)); mc->emit_reloc_at(mc, sec, lo_pos, R_COFF_AARCH64_SECREL_LOW12A, sym, addend, 0, 0); return; @@ -668,8 +674,7 @@ static void aa_copy_bytes(CGTarget* t, Operand dst_addr, Operand src_addr, AggregateAccess agg) { MCEmitter* mc = t->mc; u32 dr = agg_addr_reg(t, dst_addr, AA_TMP0); - u32 sr = agg_addr_reg(t, src_addr, - (dr == AA_TMP1) ? AA_TMP2 : AA_TMP1); + u32 sr = agg_addr_reg(t, src_addr, (dr == AA_TMP1) ? AA_TMP2 : AA_TMP1); u32 nbytes = agg.size; u32 i = 0; while (i + 8 <= nbytes) { @@ -839,11 +844,21 @@ static void aa_binop(CGTarget* t, BinOp op, Operand dst, Operand a_op, u32 rm = reg_num(b_op); u32 w; switch (op) { - case BO_FADD: w = aa64_fadd(type, rd, rn, rm); break; - case BO_FSUB: w = aa64_fsub(type, rd, rn, rm); break; - case BO_FMUL: w = aa64_fmul(type, rd, rn, rm); break; - case BO_FDIV: w = aa64_fdiv(type, rd, rn, rm); break; - default: w = 0; break; + case BO_FADD: + w = aa64_fadd(type, rd, rn, rm); + break; + case BO_FSUB: + w = aa64_fsub(type, rd, rn, rm); + break; + case BO_FMUL: + w = aa64_fmul(type, rd, rn, rm); + break; + case BO_FDIV: + w = aa64_fdiv(type, rd, rn, rm); + break; + default: + w = 0; + break; } aa64_emit32(mc, w); return; @@ -858,11 +873,14 @@ static void aa_binop(CGTarget* t, BinOp op, Operand dst, Operand a_op, case BO_OR: case BO_XOR: { if (a_op.kind == OPK_IMM && b_op.kind != OPK_IMM) { - Operand t_op = a_op; a_op = b_op; b_op = t_op; + Operand t_op = a_op; + a_op = b_op; + b_op = t_op; } break; } - default: break; + default: + break; } if (b_op.kind == OPK_IMM && a_op.kind != OPK_IMM) { @@ -927,27 +945,49 @@ static void aa_binop(CGTarget* t, BinOp op, Operand dst, Operand a_op, } break; } - default: break; + default: + break; } } u32 rn = aa64_force_reg_int(t, a_op, sf, AA_TMP0); - u32 rm = - aa64_force_reg_int(t, b_op, sf, (rn == AA_TMP0) ? AA_TMP1 : AA_TMP0); + u32 rm = aa64_force_reg_int(t, b_op, sf, (rn == AA_TMP0) ? AA_TMP1 : AA_TMP0); u32 word; switch (op) { - case BO_IADD: word = aa64_add(sf, rd, rn, rm); break; - case BO_ISUB: word = aa64_sub(sf, rd, rn, rm); break; - case BO_IMUL: word = aa64_mul(sf, rd, rn, rm); break; - case BO_AND: word = aa64_and(sf, rd, rn, rm); break; - case BO_OR: word = aa64_orr(sf, rd, rn, rm); break; - case BO_XOR: word = aa64_eor(sf, rd, rn, rm); break; - case BO_SHL: word = aa64_lslv(sf, rd, rn, rm); break; - case BO_SHR_U: word = aa64_lsrv(sf, rd, rn, rm); break; - case BO_SHR_S: word = aa64_asrv(sf, rd, rn, rm); break; - case BO_UDIV: word = aa64_udiv(sf, rd, rn, rm); break; - case BO_SDIV: word = aa64_sdiv(sf, rd, rn, rm); break; + case BO_IADD: + word = aa64_add(sf, rd, rn, rm); + break; + case BO_ISUB: + word = aa64_sub(sf, rd, rn, rm); + break; + case BO_IMUL: + word = aa64_mul(sf, rd, rn, rm); + break; + case BO_AND: + word = aa64_and(sf, rd, rn, rm); + break; + case BO_OR: + word = aa64_orr(sf, rd, rn, rm); + break; + case BO_XOR: + word = aa64_eor(sf, rd, rn, rm); + break; + case BO_SHL: + word = aa64_lslv(sf, rd, rn, rm); + break; + case BO_SHR_U: + word = aa64_lsrv(sf, rd, rn, rm); + break; + case BO_SHR_S: + word = aa64_asrv(sf, rd, rn, rm); + break; + case BO_UDIV: + word = aa64_udiv(sf, rd, rn, rm); + break; + case BO_SDIV: + word = aa64_sdiv(sf, rd, rn, rm); + break; case BO_SREM: aa64_emit32(mc, aa64_sdiv(sf, AA_TMP2, rn, rm)); word = aa64_msub(sf, rd, AA_TMP2, rm, rn); @@ -1020,7 +1060,8 @@ static void aa_convert(CGTarget* t, ConvKind k, Operand dst, Operand src) { aa64_emit32(mc, aa64_mov_reg(sf_dst, rd, rn)); return; } - aa64_emit32(mc, aa64_sbfm(sf_dst, rd, rn, /*immr=*/0, /*imms=*/src_bits - 1u)); + aa64_emit32( + mc, aa64_sbfm(sf_dst, rd, rn, /*immr=*/0, /*imms=*/src_bits - 1u)); return; } case CV_ZEXT: { @@ -1033,7 +1074,8 @@ static void aa_convert(CGTarget* t, ConvKind k, Operand dst, Operand src) { if (src_bits >= dst_bits || src_bits == 32u) { aa64_emit32(mc, aa64_mov_reg(src_bits == 32u ? 0u : sf_dst, rd, rn)); } else { - aa64_emit32(mc, aa64_ubfm(sf_dst, rd, rn, /*immr=*/0, /*imms=*/src_bits - 1u)); + aa64_emit32( + mc, aa64_ubfm(sf_dst, rd, rn, /*immr=*/0, /*imms=*/src_bits - 1u)); } return; } @@ -1082,10 +1124,12 @@ static void aa_convert(CGTarget* t, ConvKind k, Operand dst, Operand src) { case CV_BITCAST: { if (src.cls == RC_INT && dst.cls == RC_FP) { u32 sz = type_byte_size(dst.type); - aa64_emit32(mc, sz == 8 ? aa64_fmov_d_x(rd, rn) : aa64_fmov_s_w(rd, rn)); + aa64_emit32(mc, + sz == 8 ? aa64_fmov_d_x(rd, rn) : aa64_fmov_s_w(rd, rn)); } else if (src.cls == RC_FP && dst.cls == RC_INT) { u32 sz = type_byte_size(src.type); - aa64_emit32(mc, sz == 8 ? aa64_fmov_x_d(rd, rn) : aa64_fmov_w_s(rd, rn)); + aa64_emit32(mc, + sz == 8 ? aa64_fmov_x_d(rd, rn) : aa64_fmov_w_s(rd, rn)); } else { compiler_panic(t->c, a->loc, "aarch64 convert BITCAST: same-class not yet supported"); @@ -1101,8 +1145,7 @@ static void aa_convert(CGTarget* t, ConvKind k, Operand dst, Operand src) { * Calls * ============================================================ */ -static Operand aa_call_stack_arg_addr(CGTarget* t, u32 stack_offset, - int tail) { +static Operand aa_call_stack_arg_addr(CGTarget* t, u32 stack_offset, int tail) { AAImpl* a = impl_of(t); Operand addr; memset(&addr, 0, sizeof addr); @@ -1137,8 +1180,8 @@ static u32 aa_call_plan_stack_raw_size(const CGCallPlan* p) { } static void aa_store_stack_reg(CGTarget* t, u32 reg, RegClass cls, - CfreeCgTypeId type, u32 size, - u32 stack_offset, int tail) { + CfreeCgTypeId type, u32 size, u32 stack_offset, + int tail) { Operand addr = aa_call_stack_arg_addr(t, stack_offset, tail); Operand src; MemAccess ma; @@ -1182,10 +1225,10 @@ static void emit_arg_value(CGTarget* t, const ABIFuncInfo* fi, va_ai.kind = ABI_ARG_DIRECT; va_ai.parts = &va_pt; va_ai.nparts = 1; - va_pt.cls = aa_windows_fp_vararg(t, av) - ? ABI_CLASS_INT - : ((av->storage.cls == RC_FP) ? ABI_CLASS_FP - : ABI_CLASS_INT); + va_pt.cls = + aa_windows_fp_vararg(t, av) + ? ABI_CLASS_INT + : ((av->storage.cls == RC_FP) ? ABI_CLASS_FP : ABI_CLASS_INT); va_pt.size = sz; va_pt.align = sz; va_pt.src_offset = 0; @@ -1210,7 +1253,7 @@ static void emit_arg_value(CGTarget* t, const ABIFuncInfo* fi, aa64_emit_addr_adjust(t->mc, dst_reg, 29, -(i32)s->off); } else if (av->storage.kind == OPK_INDIRECT) { aa64_emit_addr_adjust(t->mc, dst_reg, av->storage.v.ind.base & 0x1f, - av->storage.v.ind.ofs); + av->storage.v.ind.ofs); } else if (av->storage.kind == OPK_GLOBAL) { emit_global_addr(t, dst_reg, av->storage.v.global.sym, av->storage.v.global.addend); @@ -1245,8 +1288,7 @@ static void emit_arg_value(CGTarget* t, const ABIFuncInfo* fi, if (av->storage.cls == RC_FP) aa_move_fp_to_int_reg(t->mc, dst_reg, av->storage, sz); else - aa64_emit32(t->mc, - aa64_mov_reg(sf, dst_reg, reg_num(av->storage))); + aa64_emit32(t->mc, aa64_mov_reg(sf, dst_reg, reg_num(av->storage))); break; } case OPK_LOCAL: { @@ -1287,14 +1329,15 @@ static void emit_arg_value(CGTarget* t, const ABIFuncInfo* fi, aa64_emit32(t->mc, aa64_mov_v16b(dst_reg, reg_num(av->storage))); else { u32 type = (sz == 8) ? 1u : 0u; - aa64_emit32(t->mc, aa64_fmov_reg(type, dst_reg, - reg_num(av->storage))); + aa64_emit32(t->mc, + aa64_fmov_reg(type, dst_reg, reg_num(av->storage))); } break; } case OPK_LOCAL: { AASlot* s = aa64_slot_get(a, av->storage.v.frame_slot); - if (!s) compiler_panic(t->c, a->loc, "aarch64 call: bad FP arg slot"); + if (!s) + compiler_panic(t->c, a->loc, "aarch64 call: bad FP arg slot"); i32 off = -(i32)s->off + (i32)pt->src_offset; aa_emit_ldr_fp_any(t->mc, sidx, dst_reg, 29, off); break; @@ -1324,11 +1367,12 @@ static void emit_arg_value(CGTarget* t, const ABIFuncInfo* fi, break; case OPK_LOCAL: { AASlot* s = aa64_slot_get(a, av->storage.v.frame_slot); - if (!s) compiler_panic(t->c, a->loc, "aarch64 call: bad FP arg slot"); + if (!s) + compiler_panic(t->c, a->loc, "aarch64 call: bad FP arg slot"); i32 off = -(i32)s->off + (i32)pt->src_offset; aa_emit_ldr_fp_any(t->mc, sidx, AA_FP_TMP0, 29, off); - aa_store_stack_reg(t, AA_FP_TMP0, RC_FP, av->type, sz, - *stack_off, tail); + aa_store_stack_reg(t, AA_FP_TMP0, RC_FP, av->type, sz, *stack_off, + tail); break; } case OPK_INDIRECT: { @@ -1341,8 +1385,8 @@ static void emit_arg_value(CGTarget* t, const ABIFuncInfo* fi, src.v.ind.ofs = av->storage.v.ind.ofs + (i32)pt->src_offset; AAAddrMode m = addr_mode(t, src, AA_TMP0); aa_emit_ldr_fp_any(t->mc, sidx, AA_FP_TMP0, m.base, m.ofs); - aa_store_stack_reg(t, AA_FP_TMP0, RC_FP, av->type, sz, - *stack_off, tail); + aa_store_stack_reg(t, AA_FP_TMP0, RC_FP, av->type, sz, *stack_off, + tail); break; } default: @@ -1361,8 +1405,8 @@ static void emit_arg_value(CGTarget* t, const ABIFuncInfo* fi, } static void count_arg_stack(CGTarget* t, const ABIFuncInfo* fi, - const CGABIValue* av, - u32* next_int, u32* next_fp, u32* stack_off) { + const CGABIValue* av, u32* next_int, u32* next_fp, + u32* stack_off) { ABIArgInfo va_ai; ABIArgPart va_pt; const ABIArgInfo* ai = av->abi; @@ -1373,10 +1417,10 @@ static void count_arg_stack(CGTarget* t, const ABIFuncInfo* fi, va_ai.kind = ABI_ARG_DIRECT; va_ai.parts = &va_pt; va_ai.nparts = 1; - va_pt.cls = aa_windows_fp_vararg(t, av) - ? ABI_CLASS_INT - : ((av->storage.cls == RC_FP) ? ABI_CLASS_FP - : ABI_CLASS_INT); + va_pt.cls = + aa_windows_fp_vararg(t, av) + ? ABI_CLASS_INT + : ((av->storage.cls == RC_FP) ? ABI_CLASS_FP : ABI_CLASS_INT); va_pt.size = sz; va_pt.align = sz; va_pt.src_offset = 0; @@ -1426,7 +1470,7 @@ static u32 aa_call_stack_size(CGTarget* t, const CGCallDesc* d) { * callees are realizable too: aa_call forwards this function's own incoming * sret pointer (the return-shape precondition guarantees it matches). */ static const char* aa_tail_call_unrealizable_reason(CGTarget* t, - const CGCallDesc* d) { + const CGCallDesc* d) { AAImpl* a = impl_of(t); u32 next_int = 0, next_fp = 0, stack_off = 0; for (u32 i = 0; i < d->nargs; ++i) @@ -1451,8 +1495,7 @@ static void aa_tail_restore_frame(CGTarget* t) { u32 fp_regs[8]; u32 n_int_saves = aa_collect_mask_regs(a->used_cs_int_mask, 19u, 28u, int_regs); - u32 n_fp_saves = - aa_collect_mask_regs(a->used_cs_fp_mask, 8u, 15u, fp_regs); + u32 n_fp_saves = aa_collect_mask_regs(a->used_cs_fp_mask, 8u, 15u, fp_regs); u32 int_save_off = a->max_outgoing; u32 fp_save_off = int_save_off + n_int_saves * 8u; u32 locals_off = fp_save_off + n_fp_saves * 8u; @@ -1465,8 +1508,7 @@ static void aa_tail_restore_frame(CGTarget* t) { if (fp_lr_off <= 0xfff) { aa64_emit32(mc, aa64_sub_imm(1, 31, 29, fp_lr_off, 0)); } else { - compiler_panic(t->c, a->loc, - "aarch64 tail call: fp/lr offset too large"); + compiler_panic(t->c, a->loc, "aarch64 tail call: fp/lr offset too large"); } } for (i32 i = (i32)n_fp_saves - 1; i >= 0; --i) { @@ -1629,7 +1671,8 @@ static void aa_call(CGTarget* t, const CGCallDesc* d) { } else { aa_emit_str_fp_any(mc, sidx, src_reg, base_reg, off); } - } else if (rs.kind == OPK_IMM && rs.type == CG_BUILTIN_ID(CFREE_CG_BUILTIN_VOID)) { + } else if (rs.kind == OPK_IMM && + rs.type == CG_BUILTIN_ID(CFREE_CG_BUILTIN_VOID)) { /* void return placeholder */ } else { compiler_panic(t->c, a->loc, @@ -1665,8 +1708,9 @@ static void aa_emit_call_plan(CGTarget* t, const CGCallPlan* p) { u32 needed = (aa_call_plan_stack_raw_size(p) + 15u) & ~15u; if (needed > a->max_outgoing) { if (a->known_frame) - compiler_panic(t->c, a->loc, - "aarch64 call plan: known frame outgoing area too small"); + compiler_panic( + t->c, a->loc, + "aarch64 call plan: known frame outgoing area too small"); a->max_outgoing = needed; } } @@ -1851,8 +1895,8 @@ static void aa_ret(CGTarget* t, const CGABIValue* val) { } else { u32 type = type_is_fp_double(val->storage.type) ? 1u : 0u; if (reg_num(val->storage) != 0) - aa64_emit32(mc, aa64_fmov_reg(type, /*Rd=*/0, - reg_num(val->storage))); + aa64_emit32(mc, + aa64_fmov_reg(type, /*Rd=*/0, reg_num(val->storage))); } } else { u32 sf = type_is_64(val->storage.type) ? 1u : 0u; @@ -1943,7 +1987,8 @@ static void aa_alloca_(CGTarget* t, Operand d, Operand sz, u32 align) { "aarch64 alloca: const size %llu too large for v1", (unsigned long long)aligned); } - aa64_emit32(mc, aa64_sub_imm(1, /*Rd=SP*/ 31, /*Rn=SP*/ 31, (u32)aligned, 0)); + aa64_emit32(mc, + aa64_sub_imm(1, /*Rd=SP*/ 31, /*Rn=SP*/ 31, (u32)aligned, 0)); } else if (sz.kind == OPK_REG) { u32 sz_reg = reg_num(sz); aa64_emit32(mc, aa64_add_imm(1, AA_TMP0, sz_reg, 15u, 0)); @@ -2010,8 +2055,7 @@ static void aa_va_start_(CGTarget* t, Operand ap_op) { if (t->c->target.os == CFREE_OS_WINDOWS) { if (a->next_param_int < 8) { AASlot* gs = aa64_slot_get(a, a->gp_save_slot); - emit_fp_off(mc, AA_TMP0, - -(i32)gs->off + (i32)(a->next_param_int * 8u)); + emit_fp_off(mc, AA_TMP0, -(i32)gs->off + (i32)(a->next_param_int * 8u)); } else { u32 ofs = 16u + a->next_param_stack; if (ofs <= 0xfff) @@ -2041,8 +2085,7 @@ static void aa_va_start_(CGTarget* t, Operand ap_op) { aa64_emit32(mc, aa64_str_uimm(3, AA_TMP0, ap, 8)); emit_fp_off(mc, AA_TMP0, -(i32)fs->off + (i32)fs->size); aa64_emit32(mc, aa64_str_uimm(3, AA_TMP0, ap, 16)); - aa64_emit_load_imm(mc, 0, AA_TMP0, - (i64)((i32)(a->next_param_int * 8u) - 64)); + aa64_emit_load_imm(mc, 0, AA_TMP0, (i64)((i32)(a->next_param_int * 8u) - 64)); aa64_emit32(mc, aa64_str_uimm(2, AA_TMP0, ap, 24)); aa64_emit_load_imm(mc, 0, AA_TMP0, (i64)((i32)(a->next_param_fp * 16u) - 128)); @@ -2278,12 +2321,24 @@ static void aa_atomic_store(CGTarget* t, Operand addr, Operand src, static void emit_rmw_combine(MCEmitter* mc, AtomicOp op, u32 sf, u32 dst_new, u32 prior, u32 val) { switch (op) { - case AO_XCHG: aa64_emit32(mc, aa64_mov_reg(sf, dst_new, val)); break; - case AO_ADD: aa64_emit32(mc, aa64_add(sf, dst_new, prior, val)); break; - case AO_SUB: aa64_emit32(mc, aa64_sub(sf, dst_new, prior, val)); break; - case AO_AND: aa64_emit32(mc, aa64_and(sf, dst_new, prior, val)); break; - case AO_OR: aa64_emit32(mc, aa64_orr(sf, dst_new, prior, val)); break; - case AO_XOR: aa64_emit32(mc, aa64_eor(sf, dst_new, prior, val)); break; + case AO_XCHG: + aa64_emit32(mc, aa64_mov_reg(sf, dst_new, val)); + break; + case AO_ADD: + aa64_emit32(mc, aa64_add(sf, dst_new, prior, val)); + break; + case AO_SUB: + aa64_emit32(mc, aa64_sub(sf, dst_new, prior, val)); + break; + case AO_AND: + aa64_emit32(mc, aa64_and(sf, dst_new, prior, val)); + break; + case AO_OR: + aa64_emit32(mc, aa64_orr(sf, dst_new, prior, val)); + break; + case AO_XOR: + aa64_emit32(mc, aa64_eor(sf, dst_new, prior, val)); + break; case AO_NAND: aa64_emit32(mc, aa64_and(sf, dst_new, prior, val)); aa64_emit32(mc, aa64_mvn(sf, dst_new, dst_new)); @@ -2474,12 +2529,10 @@ static inline u32 aa64_umull(u32 Rd, u32 Rn, u32 Rm) { return aa64_umaddl(Rd, Rn, Rm, AA64_ZR); } static inline u32 aa64_smulh(u32 Rd, u32 Rn, u32 Rm) { - return 0x9B407C00u | ((Rm & 0x1f) << 16) | ((Rn & 0x1f) << 5) | - (Rd & 0x1f); + return 0x9B407C00u | ((Rm & 0x1f) << 16) | ((Rn & 0x1f) << 5) | (Rd & 0x1f); } static inline u32 aa64_umulh(u32 Rd, u32 Rn, u32 Rm) { - return 0x9BC07C00u | ((Rm & 0x1f) << 16) | ((Rn & 0x1f) << 5) | - (Rd & 0x1f); + return 0x9BC07C00u | ((Rm & 0x1f) << 16) | ((Rn & 0x1f) << 5) | (Rd & 0x1f); } static inline u32 aa64_subs_extreg_x_sxtw(u32 Rd, u32 Rn, u32 Rm) { return 0xEB200000u | ((Rm & 0x1f) << 16) | (6u << 13) | ((Rn & 0x1f) << 5) | @@ -2537,10 +2590,11 @@ static void aa_intrinsic(CGTarget* t, IntrinKind kind, Operand* dsts, u32 nd, case INTRIN_MEMMOVE: { Operand da = args[0], sa = args[1], nb = args[2]; if (da.kind != OPK_REG || sa.kind != OPK_REG || nb.kind != OPK_IMM) { - compiler_panic(t->c, a->loc, - "aarch64 intrinsic: %.*s with non-const n or non-REG ptr", - SLICE_ARG(slice_from_cstr( - kind == INTRIN_MEMCPY ? "memcpy" : "memmove"))); + compiler_panic( + t->c, a->loc, + "aarch64 intrinsic: %.*s with non-const n or non-REG ptr", + SLICE_ARG( + slice_from_cstr(kind == INTRIN_MEMCPY ? "memcpy" : "memmove"))); } u32 dr = reg_num(da); u32 sr = reg_num(sa); @@ -2685,16 +2739,13 @@ static void aa_intrinsic(CGTarget* t, IntrinKind kind, Operand* dsts, u32 nd, u32 sf = type_is_64(dval.type) ? 1u : 0u; u32 ra = aa64_force_reg_int(t, a_op, sf, AA_TMP0); u32 rb = - aa64_force_reg_int(t, b_op, sf, - (ra == AA_TMP0) ? AA_TMP1 : AA_TMP0); - u32 word = (kind == INTRIN_SADD_OVERFLOW || - kind == INTRIN_UADD_OVERFLOW) + aa64_force_reg_int(t, b_op, sf, (ra == AA_TMP0) ? AA_TMP1 : AA_TMP0); + u32 word = (kind == INTRIN_SADD_OVERFLOW || kind == INTRIN_UADD_OVERFLOW) ? aa64_adds_reg(sf, reg_num(dval), ra, rb) : aa64_subs_reg(sf, reg_num(dval), ra, rb); - u32 cond = (kind == INTRIN_UADD_OVERFLOW) ? 0x2u /*CS*/ - : (kind == INTRIN_USUB_OVERFLOW) - ? 0x3u /*CC*/ - : 0x6u /*VS*/; + u32 cond = (kind == INTRIN_UADD_OVERFLOW) ? 0x2u /*CS*/ + : (kind == INTRIN_USUB_OVERFLOW) ? 0x3u /*CC*/ + : 0x6u /*VS*/; aa64_emit32(mc, word); aa64_emit32(mc, aa64_cset(0, reg_num(dovf), cond)); return; @@ -2705,8 +2756,7 @@ static void aa_intrinsic(CGTarget* t, IntrinKind kind, Operand* dsts, u32 nd, u32 sf = type_is_64(dval.type) ? 1u : 0u; u32 ra = aa64_force_reg_int(t, a_op, sf, AA_TMP0); u32 rb = - aa64_force_reg_int(t, b_op, sf, - (ra == AA_TMP0) ? AA_TMP1 : AA_TMP0); + aa64_force_reg_int(t, b_op, sf, (ra == AA_TMP0) ? AA_TMP1 : AA_TMP0); if (sf) { aa64_emit32(mc, aa64_mul(1, reg_num(dval), ra, rb)); aa64_emit32(mc, aa64_smulh(reg_num(dovf), ra, rb)); @@ -2726,8 +2776,7 @@ static void aa_intrinsic(CGTarget* t, IntrinKind kind, Operand* dsts, u32 nd, u32 sf = type_is_64(dval.type) ? 1u : 0u; u32 ra = aa64_force_reg_int(t, a_op, sf, AA_TMP0); u32 rb = - aa64_force_reg_int(t, b_op, sf, - (ra == AA_TMP0) ? AA_TMP1 : AA_TMP0); + aa64_force_reg_int(t, b_op, sf, (ra == AA_TMP0) ? AA_TMP1 : AA_TMP0); if (sf) { aa64_emit32(mc, aa64_mul(1, reg_num(dval), ra, rb)); aa64_emit32(mc, aa64_umulh(reg_num(dovf), ra, rb)); @@ -2760,11 +2809,9 @@ static void aa_asm_block(CGTarget* t, const char* tmpl, RegClass cls; if (t->resolve_reg_name(t, clobs[i], &phys, &cls) != 0) continue; if (cls == RC_INT) { - if (phys >= 19u && phys <= 28u) - a_impl->used_cs_int_mask |= 1u << phys; + if (phys >= 19u && phys <= 28u) a_impl->used_cs_int_mask |= 1u << phys; } else if (cls == RC_FP) { - if (phys >= 8u && phys <= 15u) - a_impl->used_cs_fp_mask |= 1u << phys; + if (phys >= 8u && phys <= 15u) a_impl->used_cs_fp_mask |= 1u << phys; } } AA64Asm* a = aa64_asm_open(t->c); diff --git a/src/arch/aa64/opt_coord.c b/src/arch/aa64/opt_coord.c @@ -7,41 +7,34 @@ /* ============================================================ * Static register tables reported to caller-owned allocators. */ -static const Reg aa_int_allocable[] = {19, 20, 21, 22, 23, - 24, 25, 26, 27, 28}; -static const Reg aa_fp_allocable[] = {8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23}; +static const Reg aa_int_allocable[] = {19, 20, 21, 22, 23, 24, 25, 26, 27, 28}; +static const Reg aa_fp_allocable[] = {8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, 19, 20, 21, 22, 23}; static const Reg aa_int_scratch[] = {16, 17}; -static const Reg aa_fp_scratch[] = {24, 25}; +static const Reg aa_fp_scratch[] = {24, 25}; static const CGPhysRegInfo aa_int_phys[] = { - {0, RC_INT, 0, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG | CG_REG_RET, 0, 0}, - {1, RC_INT, 1, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG | CG_REG_RET, 0, 0}, - {2, RC_INT, 2, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {3, RC_INT, 3, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {4, RC_INT, 4, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {5, RC_INT, 5, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {6, RC_INT, 6, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {7, RC_INT, 7, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {8, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {12, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_TEMP_PREFERRED, 0, 0}, - {13, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_TEMP_PREFERRED, 0, 0}, - {14, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_TEMP_PREFERRED, 0, 0}, - {15, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_TEMP_PREFERRED, 0, 0}, + {0, RC_INT, 0, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG | CG_REG_RET, 0, 0}, + {1, RC_INT, 1, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG | CG_REG_RET, 0, 0}, + {2, RC_INT, 2, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, 0}, + {3, RC_INT, 3, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, 0}, + {4, RC_INT, 4, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, 0}, + {5, RC_INT, 5, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, 0}, + {6, RC_INT, 6, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, 0}, + {7, RC_INT, 7, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, 0}, + {8, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, + 0}, + {12, RC_INT, 0xff, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_TEMP_PREFERRED, 0, 0}, + {13, RC_INT, 0xff, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_TEMP_PREFERRED, 0, 0}, + {14, RC_INT, 0xff, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_TEMP_PREFERRED, 0, 0}, + {15, RC_INT, 0xff, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_TEMP_PREFERRED, 0, 0}, {19, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLEE_SAVED, 50, 4}, {20, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLEE_SAVED, 50, 4}, {21, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLEE_SAVED, 50, 4}, @@ -54,22 +47,22 @@ static const CGPhysRegInfo aa_int_phys[] = { {28, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLEE_SAVED, 50, 4}, }; static const CGPhysRegInfo aa_fp_phys[] = { - {0, RC_FP, 0, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG | CG_REG_RET, 0, 0}, - {1, RC_FP, 1, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG | CG_REG_RET, 0, 0}, - {2, RC_FP, 2, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG | CG_REG_RET, 0, 0}, - {3, RC_FP, 3, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG | CG_REG_RET, 0, 0}, - {4, RC_FP, 4, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG | CG_REG_RET, 0, 0}, - {5, RC_FP, 5, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG | CG_REG_RET, 0, 0}, - {6, RC_FP, 6, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG | CG_REG_RET, 0, 0}, - {7, RC_FP, 7, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG | CG_REG_RET, 0, 0}, + {0, RC_FP, 0, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG | CG_REG_RET, 0, 0}, + {1, RC_FP, 1, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG | CG_REG_RET, 0, 0}, + {2, RC_FP, 2, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG | CG_REG_RET, 0, 0}, + {3, RC_FP, 3, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG | CG_REG_RET, 0, 0}, + {4, RC_FP, 4, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG | CG_REG_RET, 0, 0}, + {5, RC_FP, 5, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG | CG_REG_RET, 0, 0}, + {6, RC_FP, 6, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG | CG_REG_RET, 0, 0}, + {7, RC_FP, 7, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG | CG_REG_RET, 0, 0}, {8, RC_FP, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLEE_SAVED, 50, 4}, {9, RC_FP, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLEE_SAVED, 50, 4}, {10, RC_FP, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLEE_SAVED, 50, 4}, @@ -96,8 +89,8 @@ static const CGPhysRegInfo aa_fp_phys[] = { /* ============================================================ * Vtable methods */ -static void aa_get_allocable_regs(CGTarget* t, RegClass cls, - const Reg** out, u32* nregs) { +static void aa_get_allocable_regs(CGTarget* t, RegClass cls, const Reg** out, + u32* nregs) { (void)t; switch (cls) { case RC_INT: @@ -115,8 +108,8 @@ static void aa_get_allocable_regs(CGTarget* t, RegClass cls, } } -static void aa_get_scratch_regs(CGTarget* t, RegClass cls, - const Reg** out, u32* nregs) { +static void aa_get_scratch_regs(CGTarget* t, RegClass cls, const Reg** out, + u32* nregs) { (void)t; switch (cls) { case RC_INT: @@ -196,8 +189,10 @@ static u32 aa_return_reg_mask(CGTarget* t, const ABIFuncInfo* abi, u32 mask = 0, ni = 0, nf = 0; for (u16 i = 0; i < abi->ret.nparts; ++i) { const ABIArgPart* p = &abi->ret.parts[i]; - if (cls == RC_INT && p->cls == ABI_CLASS_INT) mask |= 1u << ni++; - else if (cls == RC_FP && p->cls == ABI_CLASS_FP) mask |= 1u << nf++; + if (cls == RC_INT && p->cls == ABI_CLASS_INT) + mask |= 1u << ni++; + else if (cls == RC_FP && p->cls == ABI_CLASS_FP) + mask |= 1u << nf++; } return mask; } @@ -246,8 +241,7 @@ static void aa_plan_call(CGTarget* t, const CGCallDesc* d, CGCallPlan* out) { memset(&vap, 0, sizeof vap); vap.cls = aa_windows_fp_vararg_plan(t, av) ? ABI_CLASS_INT - : (av->storage.cls == RC_FP ? ABI_CLASS_FP - : ABI_CLASS_INT); + : (av->storage.cls == RC_FP ? ABI_CLASS_FP : ABI_CLASS_INT); vap.size = type_byte_size(av->type); vai.kind = ABI_ARG_DIRECT; vai.nparts = 1; @@ -305,8 +299,8 @@ static void aa_plan_call(CGTarget* t, const CGCallDesc* d, CGCallPlan* out) { } } } - if ((d->flags & CG_CALL_TAIL) == 0 && - d->abi && d->abi->ret.kind != ABI_ARG_IGNORE && + if ((d->flags & CG_CALL_TAIL) == 0 && d->abi && + d->abi->ret.kind != ABI_ARG_IGNORE && d->abi->ret.kind != ABI_ARG_INDIRECT) { u32 ni = 0, nf = 0; for (u16 i = 0; i < d->abi->ret.nparts; ++i) { @@ -328,8 +322,8 @@ static void aa_plan_call(CGTarget* t, const CGCallDesc* d, CGCallPlan* out) { } } -static void aa_reserve_hard_regs(CGTarget* t, RegClass cls, - const Reg* regs, u32 n) { +static void aa_reserve_hard_regs(CGTarget* t, RegClass cls, const Reg* regs, + u32 n) { AAImpl* a = impl_of(t); for (u32 i = 0; i < n; ++i) { Reg r = regs[i]; @@ -367,13 +361,13 @@ static void aa_plan_hard_regs(CGTarget* t, RegClass cls, const Reg* regs, void aa_coord_vtable_init(CGTarget* t) { t->get_allocable_regs = aa_get_allocable_regs; - t->get_phys_regs = aa_get_phys_regs; - t->get_scratch_regs = aa_get_scratch_regs; - t->is_caller_saved = aa_is_caller_saved; - t->call_clobber_mask = aa_call_clobber_mask; - t->return_reg_mask = aa_return_reg_mask; - t->callee_save_mask = aa_callee_save_mask; - t->plan_call = aa_plan_call; - t->plan_hard_regs = aa_plan_hard_regs; - t->reserve_hard_regs = aa_reserve_hard_regs; + t->get_phys_regs = aa_get_phys_regs; + t->get_scratch_regs = aa_get_scratch_regs; + t->is_caller_saved = aa_is_caller_saved; + t->call_clobber_mask = aa_call_clobber_mask; + t->return_reg_mask = aa_return_reg_mask; + t->callee_save_mask = aa_callee_save_mask; + t->plan_call = aa_plan_call; + t->plan_hard_regs = aa_plan_hard_regs; + t->reserve_hard_regs = aa_reserve_hard_regs; } diff --git a/src/arch/aa64/regs.c b/src/arch/aa64/regs.c @@ -11,10 +11,11 @@ * disassembler output picks W/B/H/S/D based on instruction width * separately. */ +#include "arch/aa64/regs.h" + #include <stdint.h> #include <string.h> -#include "arch/aa64/regs.h" #include "core/core.h" #include "core/slice.h" @@ -30,18 +31,17 @@ static const AA64Reg AA64_REGS[] = { {15, "x15"}, {16, "x16"}, {17, "x17"}, {18, "x18"}, {19, "x19"}, {20, "x20"}, {21, "x21"}, {22, "x22"}, {23, "x23"}, {24, "x24"}, {25, "x25"}, {26, "x26"}, {27, "x27"}, {28, "x28"}, {29, "x29"}, - {30, "x30"}, {31, "sp"}, {32, "pc"}, - {64, "v0"}, {65, "v1"}, {66, "v2"}, {67, "v3"}, {68, "v4"}, - {69, "v5"}, {70, "v6"}, {71, "v7"}, {72, "v8"}, {73, "v9"}, - {74, "v10"}, {75, "v11"}, {76, "v12"}, {77, "v13"}, {78, "v14"}, - {79, "v15"}, {80, "v16"}, {81, "v17"}, {82, "v18"}, {83, "v19"}, - {84, "v20"}, {85, "v21"}, {86, "v22"}, {87, "v23"}, {88, "v24"}, - {89, "v25"}, {90, "v26"}, {91, "v27"}, {92, "v28"}, {93, "v29"}, - {94, "v30"}, {95, "v31"}, + {30, "x30"}, {31, "sp"}, {32, "pc"}, {64, "v0"}, {65, "v1"}, + {66, "v2"}, {67, "v3"}, {68, "v4"}, {69, "v5"}, {70, "v6"}, + {71, "v7"}, {72, "v8"}, {73, "v9"}, {74, "v10"}, {75, "v11"}, + {76, "v12"}, {77, "v13"}, {78, "v14"}, {79, "v15"}, {80, "v16"}, + {81, "v17"}, {82, "v18"}, {83, "v19"}, {84, "v20"}, {85, "v21"}, + {86, "v22"}, {87, "v23"}, {88, "v24"}, {89, "v25"}, {90, "v26"}, + {91, "v27"}, {92, "v28"}, {93, "v29"}, {94, "v30"}, {95, "v31"}, }; -static const uint32_t AA64_REGS_N = (uint32_t)(sizeof AA64_REGS / - sizeof AA64_REGS[0]); +static const uint32_t AA64_REGS_N = + (uint32_t)(sizeof AA64_REGS / sizeof AA64_REGS[0]); const char* aa64_register_name(uint32_t dwarf_idx) { uint32_t i; diff --git a/src/arch/arch.h b/src/arch/arch.h @@ -420,11 +420,11 @@ typedef struct CGCallDesc { Operand callee; const CGABIValue* args; u32 nargs; - u16 flags; /* CGCallFlag */ - u8 tail_policy; /* CfreeCgTailPolicy; meaningful when CG_CALL_TAIL is set. - * The opt recorder accepts every tail and preserves this so - * the replay can pick: emit tail (realizable), fall back to - * call+ret (ALLOWED), or diagnose (MUST). */ + u16 flags; /* CGCallFlag */ + u8 tail_policy; /* CfreeCgTailPolicy; meaningful when CG_CALL_TAIL is set. + * The opt recorder accepts every tail and preserves this so + * the replay can pick: emit tail (realizable), fall back to + * call+ret (ALLOWED), or diagnose (MUST). */ u8 pad; CfreeCgInlinePolicy inline_policy; CGABIValue ret; @@ -1194,8 +1194,8 @@ typedef struct ArchEmuOps { u64 (*signal_context_size)(EmuProcess*, EmuThread*); CfreeStatus (*save_signal_context)(EmuProcess*, EmuThread*, u8* dst, u64 size); - CfreeStatus (*restore_signal_context)(EmuProcess*, EmuThread*, - const u8* src, u64 size); + CfreeStatus (*restore_signal_context)(EmuProcess*, EmuThread*, const u8* src, + u64 size); CfreeStatus (*set_signal_handler_args)(EmuProcess*, EmuThread*, int signo, u64 siginfo, u64 ucontext); u64 (*signal_stack_align)(EmuProcess*, EmuThread*); diff --git a/src/arch/c_target/cbuf.c b/src/arch/c_target/cbuf.c @@ -4,7 +4,6 @@ * at func_end. */ #include "arch/c_target/internal.h" - #include "core/heap.h" enum { CBUF_MIN_CAP = 256 }; @@ -49,7 +48,8 @@ void cbuf_puts(CBuf* b, const char* s) { void cbuf_putn(CBuf* b, const char* s, size_t n) { if (b->len + n > b->cap) cbuf_grow(b, b->len + n); - for (size_t i = 0; i < n && b->len < b->cap; ++i) b->data[b->len++] = (u8)s[i]; + for (size_t i = 0; i < n && b->len < b->cap; ++i) + b->data[b->len++] = (u8)s[i]; } void cbuf_put_u64(CBuf* b, u64 v) { diff --git a/src/arch/c_target/emit.c b/src/arch/c_target/emit.c @@ -15,10 +15,9 @@ * on the Operand's source type. Frame slots are declared eagerly when CG * calls c_frame_slot. */ -#include "arch/c_target/internal.h" - #include <stdio.h> +#include "arch/c_target/internal.h" #include "cg/type.h" #include "core/core.h" #include "core/heap.h" @@ -130,8 +129,8 @@ static void c_ensure_typedef(CTarget* t, CfreeCgTypeId tid) { t->type_state[u] = 1; const CgType* ty = cg_type_get(t->c, u); SrcLoc loc = t->cur_fn ? t->cur_fn->loc : (SrcLoc){0, 0, 0}; - if (!ty) compiler_panic(t->c, loc, "C target: unknown type id %u", - (unsigned)u); + if (!ty) + compiler_panic(t->c, loc, "C target: unknown type id %u", (unsigned)u); switch (ty->kind) { case CFREE_CG_TYPE_FUNC: c_emit_typedef_for_func(t, u, ty); @@ -192,17 +191,17 @@ static void c_emit_typedef_for_func(CTarget* t, CfreeCgTypeId tid, /* Emit recursively for return and param types if they're composites. */ CfreeCgTypeId ret = api_unalias_type(t->c, ty->func.ret); const CgType* rty = cg_type_get(t->c, ret); - if (rty && (rty->kind == CFREE_CG_TYPE_RECORD || - rty->kind == CFREE_CG_TYPE_ARRAY || - rty->kind == CFREE_CG_TYPE_FUNC)) { + if (rty && + (rty->kind == CFREE_CG_TYPE_RECORD || rty->kind == CFREE_CG_TYPE_ARRAY || + rty->kind == CFREE_CG_TYPE_FUNC)) { c_ensure_typedef(t, ret); } for (u32 i = 0; i < ty->func.nparams; ++i) { CfreeCgTypeId pt = api_unalias_type(t->c, ty->func.params[i].type); const CgType* pty = cg_type_get(t->c, pt); - if (pty && (pty->kind == CFREE_CG_TYPE_RECORD || - pty->kind == CFREE_CG_TYPE_ARRAY || - pty->kind == CFREE_CG_TYPE_FUNC)) { + if (pty && + (pty->kind == CFREE_CG_TYPE_RECORD || + pty->kind == CFREE_CG_TYPE_ARRAY || pty->kind == CFREE_CG_TYPE_FUNC)) { c_ensure_typedef(t, pt); } } @@ -378,13 +377,11 @@ static void c_grow_slot_table(CTarget* t, u32 needed) { * type `ty`. Scalars get `= 0` (readable); aggregates get `= {0}` (which is * the only form that compiles for record/array). */ static void c_emit_zero_init(CTarget* t, CfreeCgTypeId ty) { - const CgType* cgt = ty ? cg_type_get(t->c, api_unalias_type(t->c, ty)) - : NULL; + const CgType* cgt = ty ? cg_type_get(t->c, api_unalias_type(t->c, ty)) : NULL; int is_aggregate = cgt && (cgt->kind == CFREE_CG_TYPE_RECORD || cgt->kind == CFREE_CG_TYPE_ARRAY); - cbuf_puts(&t->decls, is_aggregate - ? " __attribute__((unused)) = {0};\n" - : " __attribute__((unused)) = 0;\n"); + cbuf_puts(&t->decls, is_aggregate ? " __attribute__((unused)) = {0};\n" + : " __attribute__((unused)) = 0;\n"); } void c_ensure_reg(CTarget* t, Reg r, CfreeCgTypeId type, RegClass cls) { @@ -506,11 +503,10 @@ void c_emit_operand(CTarget* t, Operand op) { * actually wants. */ c_slot_name(op.v.frame_slot, buf, sizeof buf); u32 idx = (u32)op.v.frame_slot - 1u; - CfreeCgTypeId slot_ty = (idx < t->nslots) ? t->slot_type[idx] - : (CfreeCgTypeId)0; + CfreeCgTypeId slot_ty = + (idx < t->nslots) ? t->slot_type[idx] : (CfreeCgTypeId)0; if (op.type == 0 || slot_ty == 0 || - api_unalias_type(t->c, op.type) == - api_unalias_type(t->c, slot_ty)) { + api_unalias_type(t->c, op.type) == api_unalias_type(t->c, slot_ty)) { cbuf_puts(&t->body, buf); } else { cbuf_puts(&t->body, "(*("); @@ -543,10 +539,10 @@ void c_emit_operand(CTarget* t, Operand op) { * by-value via a global initialized buffer). */ obj_sym_mark_referenced(t->obj, op.v.global.sym); const char* nm = c_sym_name(t, op.v.global.sym); - const CgType* gty = (op.type != CFREE_CG_TYPE_NONE) - ? cg_type_get(t->c, - api_unalias_type(t->c, op.type)) - : NULL; + const CgType* gty = + (op.type != CFREE_CG_TYPE_NONE) + ? cg_type_get(t->c, api_unalias_type(t->c, op.type)) + : NULL; int is_aggregate = gty && (gty->kind == CFREE_CG_TYPE_RECORD || gty->kind == CFREE_CG_TYPE_ARRAY); if (is_aggregate) { @@ -618,9 +614,8 @@ static CfreeCgTypeId c_operand_emit_type(CTarget* t, Operand op) { if (idx < t->nslots) { /* c_emit_operand emits `slot_N` (slot_type) when op.type matches, * otherwise a deref-cast to op.type. */ - if (op.type == 0 || - api_unalias_type(t->c, op.type) == - api_unalias_type(t->c, t->slot_type[idx])) { + if (op.type == 0 || api_unalias_type(t->c, op.type) == + api_unalias_type(t->c, t->slot_type[idx])) { return t->slot_type[idx]; } } @@ -658,9 +653,7 @@ static void c_emit_reg_assign_open(CTarget* t, Reg r, CfreeCgTypeId rhs_ty) { cbuf_puts(&t->body, "("); } -static void c_emit_reg_assign_close(CTarget* t) { - cbuf_puts(&t->body, ");\n"); -} +static void c_emit_reg_assign_close(CTarget* t) { cbuf_puts(&t->body, ");\n"); } void c_emit_operand_signed(CTarget* t, Operand op, int signed_) { u32 w = c_int_width_for_signedness(t, op.type); @@ -785,7 +778,8 @@ static void c_emit_operand_arith_signed(CTarget* t, Operand op, int signed_) { * OPK_INDIRECT) using `access_type` as the access type. The result is the * full `*(T*)(...)` dereference (or the C variable directly when the access * type matches the underlying slot/symbol). */ -static void c_emit_addr_deref(CTarget* t, Operand addr, CfreeCgTypeId access_type) { +static void c_emit_addr_deref(CTarget* t, Operand addr, + CfreeCgTypeId access_type) { char buf[24]; SrcLoc loc = t->cur_fn ? t->cur_fn->loc : (SrcLoc){0, 0, 0}; switch (addr.kind) { @@ -944,9 +938,8 @@ const char* c_sym_name(CTarget* t, ObjSymId sym) { char buf[256]; size_t cap = sizeof(buf) - 1u; size_t out = 0; - int first_alpha = - (s[0] >= 'a' && s[0] <= 'z') || (s[0] >= 'A' && s[0] <= 'Z') || - s[0] == '_'; + int first_alpha = (s[0] >= 'a' && s[0] <= 'z') || + (s[0] >= 'A' && s[0] <= 'Z') || s[0] == '_'; if (!first_alpha && out < cap) buf[out++] = '_'; for (size_t i = 0; i < n && out < cap; ++i) { char ch = s[i]; @@ -1042,8 +1035,8 @@ void c_ensure_forward_decl(CTarget* t, ObjSymId sym, CfreeCgTypeId fn_type) { if ((u32)sym >= t->sym_forwarded_cap) { u32 newcap = t->sym_forwarded_cap ? t->sym_forwarded_cap : 16; while (newcap <= (u32)sym) newcap *= 2; - u8* nd = (u8*)h->realloc(h, t->sym_forwarded, t->sym_forwarded_cap, newcap, - 1); + u8* nd = + (u8*)h->realloc(h, t->sym_forwarded, t->sym_forwarded_cap, newcap, 1); if (!nd && newcap) { compiler_panic(t->c, (SrcLoc){0, 0, 0}, "C target: out of memory"); } @@ -1059,8 +1052,10 @@ void c_ensure_forward_decl(CTarget* t, ObjSymId sym, CfreeCgTypeId fn_type) { c_emit_func_signature(t, &t->forwards, name, fn_type); cbuf_puts(&t->forwards, ";\n"); } else { - if (os && os->bind == SB_LOCAL) cbuf_puts(&t->forwards, "static "); - else cbuf_puts(&t->forwards, "extern "); + if (os && os->bind == SB_LOCAL) + cbuf_puts(&t->forwards, "static "); + else + cbuf_puts(&t->forwards, "extern "); if (os && os->section_id != OBJ_SEC_NONE) { const Section* sec = obj_section_get(t->obj, os->section_id); if (sec->kind == SEC_RODATA) cbuf_puts(&t->forwards, "const "); @@ -1092,7 +1087,8 @@ void c_func_end(CGTarget* T) { } t->body.len = splice_at; - if (t->decls.len) cbuf_putn(&t->body, (const char*)t->decls.data, t->decls.len); + if (t->decls.len) + cbuf_putn(&t->body, (const char*)t->decls.data, t->decls.len); if (tmp) { cbuf_putn(&t->body, (const char*)tmp, fn_body_len); h->free(h, tmp, fn_body_len); @@ -1171,9 +1167,8 @@ void c_load_imm(CGTarget* T, Operand dst, i64 imm) { u32 w = c_int_width_for_signedness(t, dst.type); int can_drop_bridge; if (w > 0) { - can_drop_bridge = (w >= 64) || - (imm >= -((i64)1 << (w - 1)) && - imm <= (((i64)1 << (w - 1)) - 1)); + can_drop_bridge = (w >= 64) || (imm >= -((i64)1 << (w - 1)) && + imm <= (((i64)1 << (w - 1)) - 1)); } else if (c_type_is_ptr(t, dst.type)) { can_drop_bridge = (imm == 0); } else { @@ -1272,8 +1267,7 @@ void c_binop(CGTarget* T, BinOp op, Operand dst, Operand a, Operand b) { * the assignment back to a pointer dst doesn't trip -Wint-conversion. */ int has_ptr = c_operand_is_ptr_typed(t, dst) || c_operand_is_ptr_typed(t, a) || c_operand_is_ptr_typed(t, b); - c_emit_reg_assign_open(t, dst.v.reg, - has_ptr ? (CfreeCgTypeId)0 : dst.type); + c_emit_reg_assign_open(t, dst.v.reg, has_ptr ? (CfreeCgTypeId)0 : dst.type); int lhs_signed = 1; BinSignCast bsc = binop_sign_kind(op, &lhs_signed); switch (bsc) { @@ -1343,20 +1337,26 @@ void c_unop(CGTarget* T, UnOp op, Operand dst, Operand a) { static const char* cmp_to_c(CmpOp op) { switch (op) { - case CMP_EQ: return "=="; - case CMP_NE: return "!="; + case CMP_EQ: + return "=="; + case CMP_NE: + return "!="; case CMP_LT_S: case CMP_LT_U: - case CMP_LT_F: return "<"; + case CMP_LT_F: + return "<"; case CMP_LE_S: case CMP_LE_U: - case CMP_LE_F: return "<="; + case CMP_LE_F: + return "<="; case CMP_GT_S: case CMP_GT_U: - case CMP_GT_F: return ">"; + case CMP_GT_F: + return ">"; case CMP_GE_S: case CMP_GE_U: - case CMP_GE_F: return ">="; + case CMP_GE_F: + return ">="; } return NULL; } @@ -1738,8 +1738,7 @@ static void c_grow_local_static_entries(CTarget* t, u32 want) { u32 newcap = oldcap ? oldcap * 2u : 8u; while (newcap < want) newcap *= 2u; CLocalStaticLabelEntry* ne = (CLocalStaticLabelEntry*)h->realloc( - h, t->local_static_entries, - oldcap * sizeof(*t->local_static_entries), + h, t->local_static_entries, oldcap * sizeof(*t->local_static_entries), newcap * sizeof(*t->local_static_entries), _Alignof(CLocalStaticLabelEntry)); if (!ne) { @@ -1750,8 +1749,7 @@ static void c_grow_local_static_entries(CTarget* t, u32 want) { t->local_static_entries_cap = newcap; } -int c_local_static_data_begin(CGTarget* T, - const CGLocalStaticDataDesc* desc) { +int c_local_static_data_begin(CGTarget* T, const CGLocalStaticDataDesc* desc) { CTarget* t = (CTarget*)T; SrcLoc loc = t->cur_fn ? t->cur_fn->loc : (SrcLoc){0, 0, 0}; if (!t->cur_fn) { @@ -1781,8 +1779,7 @@ int c_local_static_data_begin(CGTarget* T, return 0; } if (count > UINT32_MAX) { - compiler_panic(t->c, loc, - "C target: local static pointer table too large"); + compiler_panic(t->c, loc, "C target: local static pointer table too large"); } c_grow_local_static_entries(t, (u32)count); @@ -1797,8 +1794,8 @@ int c_local_static_data_begin(CGTarget* T, t->local_static_count = count; t->local_static_offset = 0; t->local_static_ptr_width = (u32)cg_type_size(t->c, elem); - t->local_static_align = desc->align ? desc->align : cg_type_align(t->c, - desc->type); + t->local_static_align = + desc->align ? desc->align : cg_type_align(t->c, desc->type); t->local_static_active = 1; t->local_static_is_array = (u8)is_array; t->local_static_readonly = @@ -2098,8 +2095,7 @@ void c_call(CGTarget* T, const CGCallDesc* d) { cbuf_puts(&t->body, " "); c_emit_addr_deref(t, rs, ret_type); cbuf_puts(&t->body, " = "); - } else if (rs.kind == OPK_IMM && - cg_type_is_void(t->c, rs.type)) { + } else if (rs.kind == OPK_IMM && cg_type_is_void(t->c, rs.type)) { /* Result discarded by CG; emit a statement-only call. */ cbuf_puts(&t->body, " "); } else { @@ -2225,9 +2221,8 @@ void c_ret(CGTarget* T, const CGABIValue* val) { CfreeCgTypeId ret_type = t->cur_fn ? cg_type_func_ret_id(t->c, t->cur_fn->fn_type) : (CfreeCgTypeId)0; - const CgType* rty = ret_type ? cg_type_get(t->c, - api_unalias_type(t->c, ret_type)) - : NULL; + const CgType* rty = + ret_type ? cg_type_get(t->c, api_unalias_type(t->c, ret_type)) : NULL; int is_aggregate = rty && (rty->kind == CFREE_CG_TYPE_RECORD || rty->kind == CFREE_CG_TYPE_ARRAY); if (ret_type && !is_aggregate) { @@ -2262,8 +2257,8 @@ void c_alias(CGTarget* T, ObjSymId alias_sym, ObjSymId target_sym, if ((u32)alias_sym >= t->sym_forwarded_cap) { u32 newcap = t->sym_forwarded_cap ? t->sym_forwarded_cap : 16; while (newcap <= (u32)alias_sym) newcap *= 2; - u8* nd = (u8*)h->realloc(h, t->sym_forwarded, t->sym_forwarded_cap, newcap, - 1); + u8* nd = + (u8*)h->realloc(h, t->sym_forwarded, t->sym_forwarded_cap, newcap, 1); if (!nd && newcap) { compiler_panic(t->c, (SrcLoc){0, 0, 0}, "C target: out of memory"); } @@ -2453,9 +2448,9 @@ void c_intrinsic(CGTarget* T, IntrinKind k, Operand* dsts, u32 ndst, case INTRIN_MEMCPY: case INTRIN_MEMMOVE: case INTRIN_MEMSET: { - const char* fn = (k == INTRIN_MEMCPY) ? "__builtin_memcpy" : - (k == INTRIN_MEMMOVE) ? "__builtin_memmove" : - "__builtin_memset"; + const char* fn = (k == INTRIN_MEMCPY) ? "__builtin_memcpy" + : (k == INTRIN_MEMMOVE) ? "__builtin_memmove" + : "__builtin_memset"; cbuf_puts(&t->body, " "); cbuf_puts(&t->body, fn); cbuf_puts(&t->body, "("); @@ -2465,8 +2460,8 @@ void c_intrinsic(CGTarget* T, IntrinKind k, Operand* dsts, u32 ndst, * may be typed as a plain integer reg when they come from address * arithmetic, which the C target declares as int64_t. The builtins * take void*, so cast explicitly to avoid -Wint-conversion. */ - int is_ptr_arg = (i == 0) || - (i == 1 && (k == INTRIN_MEMCPY || k == INTRIN_MEMMOVE)); + int is_ptr_arg = + (i == 0) || (i == 1 && (k == INTRIN_MEMCPY || k == INTRIN_MEMMOVE)); if (is_ptr_arg) cbuf_puts(&t->body, "(void*)"); c_emit_operand(t, args[i]); } @@ -2490,12 +2485,11 @@ void c_intrinsic(CGTarget* T, IntrinKind k, Operand* dsts, u32 ndst, * of the right signedness and copy it back through the int/uint * bridge. */ if (ndst != 2 || narg != 2) { - compiler_panic(t->c, loc, - "C target: overflow-intrin: bad shape"); + compiler_panic(t->c, loc, "C target: overflow-intrin: bad shape"); } - int is_unsigned = (k == INTRIN_UADD_OVERFLOW || - k == INTRIN_USUB_OVERFLOW || - k == INTRIN_UMUL_OVERFLOW); + int is_unsigned = + (k == INTRIN_UADD_OVERFLOW || k == INTRIN_USUB_OVERFLOW || + k == INTRIN_UMUL_OVERFLOW); const char* fn = c_overflow_builtin(k); c_ensure_reg(t, dsts[0].v.reg, dsts[0].type, (RegClass)dsts[0].cls); c_ensure_reg(t, dsts[1].v.reg, dsts[1].type, (RegClass)dsts[1].cls); @@ -2723,16 +2717,22 @@ void c_tls_addr_of(CGTarget* T, Operand dst, ObjSymId sym, i64 addend) { * entirely. */ void c_bitfield_load(CGTarget* T, Operand dst, Operand addr, BitFieldAccess bf); -void c_bitfield_store(CGTarget* T, Operand addr, Operand src, BitFieldAccess bf); +void c_bitfield_store(CGTarget* T, Operand addr, Operand src, + BitFieldAccess bf); /* Returns the unsigned C integer type matching the storage-unit byte size. */ static const char* c_bf_storage_type(u32 size) { switch (size) { - case 1: return "uint8_t"; - case 2: return "uint16_t"; - case 4: return "uint32_t"; - case 8: return "uint64_t"; - default: return NULL; + case 1: + return "uint8_t"; + case 2: + return "uint16_t"; + case 4: + return "uint32_t"; + case 8: + return "uint64_t"; + default: + return NULL; } } @@ -2846,8 +2846,7 @@ void c_bitfield_load(CGTarget* T, Operand dst, Operand addr, cbuf_puts(&t->body, ")"); } else { /* ((storage >> bit_offset) & ((1u << bit_width) - 1)) */ - u64 mask = (bf.bit_width >= 64) ? ~(u64)0 - : (((u64)1 << bf.bit_width) - 1u); + u64 mask = (bf.bit_width >= 64) ? ~(u64)0 : (((u64)1 << bf.bit_width) - 1u); cbuf_puts(&t->body, "(("); c_bf_storage_lvalue(t, addr, bf, sty); cbuf_puts(&t->body, " >> "); @@ -2880,8 +2879,7 @@ void c_bitfield_store(CGTarget* T, Operand addr, Operand src, compiler_panic(t->c, loc, "C target: bitfield storage size %u unsupported", (unsigned)bf.storage.size); } - u64 mask = (bf.bit_width >= 64) ? ~(u64)0 - : (((u64)1 << bf.bit_width) - 1u); + u64 mask = (bf.bit_width >= 64) ? ~(u64)0 : (((u64)1 << bf.bit_width) - 1u); /* *(uintN_t*)p = (*(uintN_t*)p & ~(mask << bit_offset)) | * (((uintN_t)src & mask) << bit_offset); */ cbuf_puts(&t->body, " "); @@ -3018,18 +3016,17 @@ void c_asm_block(CGTarget* T, const char* tmpl, const AsmConstraint* outs, cbuf_puts(&t->body, " : "); for (u32 i = 0; i < nc; ++i) { if (i > 0) cbuf_puts(&t->body, ", "); - c_emit_c_string_literal(&t->body, - pool_slice(t->c->global, clobs[i]).s); + c_emit_c_string_literal(&t->body, pool_slice(t->c->global, clobs[i]).s); } cbuf_puts(&t->body, ");\n"); } /* === load_const === * - * Used by CG for non-integer literal pushes (mainly floats — `cfree_cg_push_float`). - * Bytes are the target's ABI encoding of the value; we copy them into the dst - * reg via a static const byte array and __builtin_memcpy so any host C - * compiler sees the same bit pattern. */ + * Used by CG for non-integer literal pushes (mainly floats — + * `cfree_cg_push_float`). Bytes are the target's ABI encoding of the value; we + * copy them into the dst reg via a static const byte array and __builtin_memcpy + * so any host C compiler sees the same bit pattern. */ void c_load_const(CGTarget* T, Operand dst, ConstBytes cb); @@ -3072,12 +3069,18 @@ void c_load_const(CGTarget* T, Operand dst, ConstBytes cb) { static const char* c_memorder_token(MemOrder o) { switch (o) { - case MO_RELAXED: return "__ATOMIC_RELAXED"; - case MO_CONSUME: return "__ATOMIC_CONSUME"; - case MO_ACQUIRE: return "__ATOMIC_ACQUIRE"; - case MO_RELEASE: return "__ATOMIC_RELEASE"; - case MO_ACQ_REL: return "__ATOMIC_ACQ_REL"; - case MO_SEQ_CST: return "__ATOMIC_SEQ_CST"; + case MO_RELAXED: + return "__ATOMIC_RELAXED"; + case MO_CONSUME: + return "__ATOMIC_CONSUME"; + case MO_ACQUIRE: + return "__ATOMIC_ACQUIRE"; + case MO_RELEASE: + return "__ATOMIC_RELEASE"; + case MO_ACQ_REL: + return "__ATOMIC_ACQ_REL"; + case MO_SEQ_CST: + return "__ATOMIC_SEQ_CST"; } return "__ATOMIC_SEQ_CST"; } @@ -3089,8 +3092,8 @@ void c_atomic_store(CGTarget* T, Operand addr, Operand src, MemAccess m, void c_atomic_rmw(CGTarget* T, AtomicOp op, Operand dst, Operand addr, Operand val, MemAccess m, MemOrder o); void c_atomic_cas(CGTarget* T, Operand prior, Operand ok, Operand addr, - Operand expected, Operand desired, MemAccess m, - MemOrder so, MemOrder fo); + Operand expected, Operand desired, MemAccess m, MemOrder so, + MemOrder fo); void c_fence(CGTarget* T, MemOrder o); void c_atomic_load(CGTarget* T, Operand dst, Operand addr, MemAccess m, @@ -3129,13 +3132,20 @@ void c_atomic_store(CGTarget* T, Operand addr, Operand src, MemAccess m, static const char* c_atomic_op_builtin(AtomicOp op) { switch (op) { - case AO_XCHG: return "__atomic_exchange_n"; - case AO_ADD: return "__atomic_fetch_add"; - case AO_SUB: return "__atomic_fetch_sub"; - case AO_AND: return "__atomic_fetch_and"; - case AO_OR: return "__atomic_fetch_or"; - case AO_XOR: return "__atomic_fetch_xor"; - case AO_NAND: return "__atomic_fetch_nand"; + case AO_XCHG: + return "__atomic_exchange_n"; + case AO_ADD: + return "__atomic_fetch_add"; + case AO_SUB: + return "__atomic_fetch_sub"; + case AO_AND: + return "__atomic_fetch_and"; + case AO_OR: + return "__atomic_fetch_or"; + case AO_XOR: + return "__atomic_fetch_xor"; + case AO_NAND: + return "__atomic_fetch_nand"; } return NULL; } @@ -3167,8 +3177,8 @@ void c_atomic_rmw(CGTarget* T, AtomicOp op, Operand dst, Operand addr, } void c_atomic_cas(CGTarget* T, Operand prior, Operand ok, Operand addr, - Operand expected, Operand desired, MemAccess m, - MemOrder so, MemOrder fo) { + Operand expected, Operand desired, MemAccess m, MemOrder so, + MemOrder fo) { CTarget* t = (CTarget*)T; (void)m; c_assert_no_index(t, addr, "atomic_cas"); @@ -3366,7 +3376,8 @@ static ObjSymId c_macho_tls_find_init(CTarget* t, ObjSecId desc_sec, * on Mach-O). Compared by interned Sym id. */ static int c_sec_name_is_macho_tvars(CTarget* t, const Section* sec) { if (!sec) return 0; - Sym tvars = pool_intern_slice(t->c->global, SLICE_LIT("__DATA,__thread_vars")); + Sym tvars = + pool_intern_slice(t->c->global, SLICE_LIT("__DATA,__thread_vars")); return sec->name == tvars; } @@ -3382,7 +3393,6 @@ static int c_sym_has_relocs(CTarget* t, ObjSecId sec_id, u32 base, u32 size) { return 0; } - /* Emit one data symbol: extern declaration if undef, otherwise the full * definition with bytes. Function symbols are skipped — those go through the * forwards path. */ @@ -3462,8 +3472,8 @@ static void c_emit_data_symbol(CTarget* t, ObjSymId id, const ObjSym* os) { * sym is skipped in its own iteration. */ const Section* desc_sec = obj_section_get(t->obj, os->section_id); if (c_sec_name_is_macho_tvars(t, desc_sec)) { - ObjSymId init_id = c_macho_tls_find_init(t, os->section_id, - (u32)os->value); + ObjSymId init_id = + c_macho_tls_find_init(t, os->section_id, (u32)os->value); if (init_id == OBJ_SYM_NONE) { compiler_panic(t->c, (SrcLoc){0, 0, 0}, "C target: Mach-O TLS descriptor missing init reloc"); @@ -3540,7 +3550,8 @@ static void c_emit_data_symbol(CTarget* t, ObjSymId id, const ObjSym* os) { u32 total_relocs = obj_reloc_total(t->obj); for (u32 i = 0; i < total_relocs; ++i) { const Reloc* r = obj_reloc_at(t->obj, i); - if (r->section_id == os->section_id && r->offset >= base && r->offset < base + size) { + if (r->section_id == os->section_id && r->offset >= base && + r->offset < base + size) { nrelocs++; } } @@ -3552,15 +3563,16 @@ static void c_emit_data_symbol(CTarget* t, ObjSymId id, const ObjSym* os) { u32 j = 0; for (u32 i = 0; i < total_relocs; ++i) { const Reloc* r = obj_reloc_at(t->obj, i); - if (r->section_id == os->section_id && r->offset >= base && r->offset < base + size) { + if (r->section_id == os->section_id && r->offset >= base && + r->offset < base + size) { rs[j++] = r; } } for (u32 i = 1; i < nrelocs; ++i) { const Reloc* tmp = rs[i]; u32 k = i; - while (k > 0 && rs[k-1]->offset > tmp->offset) { - rs[k] = rs[k-1]; + while (k > 0 && rs[k - 1]->offset > tmp->offset) { + rs[k] = rs[k - 1]; k--; } rs[k] = tmp; @@ -3746,12 +3758,10 @@ void c_destroy(CGTarget* T) { t->local_static_entries_cap * sizeof(*t->local_static_entries)); } if (t->reg_declared) h->free(h, t->reg_declared, t->reg_cap); - if (t->reg_type) - h->free(h, t->reg_type, t->reg_cap * sizeof(CfreeCgTypeId)); + if (t->reg_type) h->free(h, t->reg_type, t->reg_cap * sizeof(CfreeCgTypeId)); if (t->slot_type) h->free(h, t->slot_type, t->slot_cap * sizeof(CfreeCgTypeId)); - if (t->scopes) - h->free(h, t->scopes, t->scopes_cap * sizeof(CScopeInfo)); + if (t->scopes) h->free(h, t->scopes, t->scopes_cap * sizeof(CScopeInfo)); t->reg_declared = NULL; t->reg_type = NULL; t->slot_type = NULL; diff --git a/src/arch/c_target/internal.h b/src/arch/c_target/internal.h @@ -154,7 +154,7 @@ typedef struct CTarget { } CTarget; typedef struct CScopeInfo { - u8 kind; /* ScopeKind */ + u8 kind; /* ScopeKind */ /* Set when the C target emitted a `for (;;) { ... }` wrapper around * this scope. Drives jump/cmp_branch's translation of break/continue * labels into C `break;`/`continue;` and scope_end's `}`. */ diff --git a/src/arch/c_target/target.c b/src/arch/c_target/target.c @@ -4,10 +4,9 @@ * text to the CfreeWriter passed via CodeOptions.c_source_writer. CG operates * with virtual_regs=1, so we never run register allocation or spilling. */ -#include "arch/c_target/internal.h" - #include <string.h> +#include "arch/c_target/internal.h" #include "core/arena.h" #include "core/core.h" #include "core/heap.h" @@ -76,74 +75,99 @@ void c_fence(CGTarget*, MemOrder); /* Unimplemented stubs panic with the method name in the message — the toy * harness recognizes "C target: method <name> not implemented" as a graceful * SKIP rather than a hard FAIL. */ -#define C_UNIMPL(name) \ - compiler_panic(((CTarget*)t)->c, ((CTarget*)t)->cur_fn ? \ - ((CTarget*)t)->cur_fn->loc : (SrcLoc){0,0,0}, \ - "C target: method " name " not implemented") +#define C_UNIMPL(name) \ + compiler_panic( \ + ((CTarget*)t)->c, \ + ((CTarget*)t)->cur_fn ? ((CTarget*)t)->cur_fn->loc : (SrcLoc){0, 0, 0}, \ + "C target: method " name " not implemented") static void c_unimpl_spill_reg(CGTarget* t, Operand a, FrameSlot s, MemAccess m) { - (void)a; (void)s; (void)m; + (void)a; + (void)s; + (void)m; C_UNIMPL("spill_reg"); } static void c_unimpl_reload_reg(CGTarget* t, Operand a, FrameSlot s, MemAccess m) { - (void)a; (void)s; (void)m; + (void)a; + (void)s; + (void)m; C_UNIMPL("reload_reg"); } /* Register-pool descriptors: virtual_regs=1 means CG skips these, but the * non-null contract requires a callable. Return empty pools. */ static void c_no_regs(CGTarget* t, RegClass cls, const Reg** out, u32* n) { - (void)t; (void)cls; + (void)t; + (void)cls; *out = NULL; *n = 0; } -static void c_no_phys_regs(CGTarget* t, RegClass cls, - const CGPhysRegInfo** out, u32* n) { - (void)t; (void)cls; +static void c_no_phys_regs(CGTarget* t, RegClass cls, const CGPhysRegInfo** out, + u32* n) { + (void)t; + (void)cls; *out = NULL; *n = 0; } static int c_is_caller_saved(CGTarget* t, RegClass cls, Reg r) { - (void)t; (void)cls; (void)r; + (void)t; + (void)cls; + (void)r; return 0; } static u32 c_zero_mask(CGTarget* t, const CGCallDesc* d, RegClass cls) { - (void)t; (void)d; (void)cls; + (void)t; + (void)d; + (void)cls; return 0; } static u32 c_zero_ret_mask(CGTarget* t, const ABIFuncInfo* f, RegClass cls) { - (void)t; (void)f; (void)cls; + (void)t; + (void)f; + (void)cls; return 0; } static u32 c_zero_cs_mask(CGTarget* t, RegClass cls) { - (void)t; (void)cls; + (void)t; + (void)cls; return 0; } static void c_noop_plan_regs(CGTarget* t, RegClass cls, const Reg* r, u32 n) { - (void)t; (void)cls; (void)r; (void)n; + (void)t; + (void)cls; + (void)r; + (void)n; } -static void c_noop_reserve_regs(CGTarget* t, RegClass cls, const Reg* r, u32 n) { - (void)t; (void)cls; (void)r; (void)n; +static void c_noop_reserve_regs(CGTarget* t, RegClass cls, const Reg* r, + u32 n) { + (void)t; + (void)cls; + (void)r; + (void)n; } static u32 c_call_stack_size_zero(CGTarget* t, const CGCallDesc* d) { - (void)t; (void)d; + (void)t; + (void)d; return 0; } -static void c_unimpl_plan_call(CGTarget* t, const CGCallDesc* d, CGCallPlan* p) { - (void)d; (void)p; +static void c_unimpl_plan_call(CGTarget* t, const CGCallDesc* d, + CGCallPlan* p) { + (void)d; + (void)p; C_UNIMPL("plan_call"); } static void c_unimpl_load_call_arg(CGTarget* t, Operand d, const CGCallPlanMove* m) { - (void)d; (void)m; + (void)d; + (void)m; C_UNIMPL("load_call_arg"); } static void c_unimpl_store_call_arg(CGTarget* t, const CGCallPlanMove* m) { @@ -152,7 +176,8 @@ static void c_unimpl_store_call_arg(CGTarget* t, const CGCallPlanMove* m) { } static void c_unimpl_store_call_ret(CGTarget* t, const CGCallPlanRet* r, Operand s) { - (void)r; (void)s; + (void)r; + (void)s; C_UNIMPL("store_call_ret"); } static void c_unimpl_emit_call_plan(CGTarget* t, const CGCallPlan* p) { diff --git a/src/arch/check_target.c b/src/arch/check_target.c @@ -1,7 +1,6 @@ -#include "arch/arch.h" - #include <string.h> +#include "arch/arch.h" #include "core/arena.h" typedef struct CheckTarget { @@ -22,8 +21,7 @@ static void check_func_begin(CGTarget* t, const CGFuncDesc* d) { static void check_func_end(CGTarget* t) { (void)t; } -static void check_alias(CGTarget* t, ObjSymId a, ObjSymId b, - CfreeCgTypeId ty) { +static void check_alias(CGTarget* t, ObjSymId a, ObjSymId b, CfreeCgTypeId ty) { (void)t; (void)a; (void)b; @@ -129,8 +127,7 @@ static u32 check_zero_cs_mask(CGTarget* t, RegClass cls) { return 0; } -static void check_plan_regs(CGTarget* t, RegClass cls, const Reg* regs, - u32 n) { +static void check_plan_regs(CGTarget* t, RegClass cls, const Reg* regs, u32 n) { (void)t; (void)cls; (void)regs; @@ -405,9 +402,9 @@ static void check_intrinsic(CGTarget* t, IntrinKind k, Operand* dsts, u32 ndst, static void check_asm_block(CGTarget* t, const char* tmpl, const AsmConstraint* outs, u32 nout, - Operand* out_ops, const AsmConstraint* ins, - u32 nin, const Operand* in_ops, - const Sym* clobbers, u32 nclob) { + Operand* out_ops, const AsmConstraint* ins, u32 nin, + const Operand* in_ops, const Sym* clobbers, + u32 nclob) { (void)t; (void)tmpl; (void)outs; @@ -452,8 +449,7 @@ static void check_atomic_rmw(CGTarget* t, AtomicOp op, Operand dst, static void check_atomic_cas(CGTarget* t, Operand prior, Operand ok, Operand addr, Operand expected, Operand desired, - MemAccess m, MemOrder success, - MemOrder failure) { + MemAccess m, MemOrder success, MemOrder failure) { (void)t; (void)prior; (void)ok; diff --git a/src/arch/disasm.c b/src/arch/disasm.c @@ -52,7 +52,8 @@ ArchInsnFormatter* arch_insn_formatter_new(Compiler* c) { } { SrcLoc loc = {0, 0, 0}; - compiler_panic(c, loc, "arch_insn_formatter_new: unsupported target arch %d", + compiler_panic(c, loc, + "arch_insn_formatter_new: unsupported target arch %d", (int)c->target.arch); } } diff --git a/src/arch/mc.c b/src/arch/mc.c @@ -149,8 +149,7 @@ static void emit_label_data_reloc_now(MCImpl* mc, const MCDataLabelRef* r, compiler_panic(mc->base.c, mc->base.loc, "MCEmitter: label-data reloc resolved outside a function"); } - addend = - (i64)label_offset - (i64)mc->base.cur_func_start + r->extra_addend; + addend = (i64)label_offset - (i64)mc->base.cur_func_start + r->extra_addend; /* Patch the inline addend into the data bytes. Object formats that * carry the addend in the relocation record (ELF RELA) read both * inline and r->addend; static link adds them. Mach-O R_ABS64 @@ -370,8 +369,7 @@ static void fde_push(MCImpl* mc, u8 kind, u32 reg, i32 imm) { if (!nbuf) compiler_panic(mc->base.c, mc->base.loc, "MCEmitter: CFI OOM"); if (fde->directives) { memcpy(nbuf, fde->directives, sizeof(CfiDirective) * fde->ndir); - heap->free(heap, fde->directives, - sizeof(CfiDirective) * fde->dir_cap); + heap->free(heap, fde->directives, sizeof(CfiDirective) * fde->dir_cap); } fde->directives = nbuf; fde->dir_cap = new_cap; @@ -402,8 +400,8 @@ static void m_cfi_startproc(MCEmitter* m) { } if (mc->nfdes == mc->fdes_cap) { u32 new_cap = mc->fdes_cap ? mc->fdes_cap * 2u : 8u; - CfiFde* nbuf = (CfiFde*)heap->alloc(heap, sizeof(CfiFde) * new_cap, - _Alignof(CfiFde)); + CfiFde* nbuf = + (CfiFde*)heap->alloc(heap, sizeof(CfiFde) * new_cap, _Alignof(CfiFde)); if (!nbuf) compiler_panic(m->c, m->loc, "MCEmitter: CFI OOM"); if (mc->fdes) { memcpy(nbuf, mc->fdes, sizeof(CfiFde) * mc->nfdes); @@ -592,8 +590,7 @@ static void buf_sleb(Buf* b, i64 v) { while (more) { u8 byte = (u8)(v & 0x7fu); v >>= 7; - if ((v == 0 && (byte & 0x40u) == 0) || - (v == -1 && (byte & 0x40u) != 0)) { + if ((v == 0 && (byte & 0x40u) == 0) || (v == -1 && (byte & 0x40u) != 0)) { more = 0; } else { byte |= 0x80u; @@ -660,8 +657,10 @@ static void encode_cfi_directive(Buf* prog, const CfiDirective* d, u32* cur_loc, break; case CFI_OP_OFFSET: { i64 fac; - if (data_align == 0) fac = d->imm; - else fac = (i64)d->imm / (i64)data_align; + if (data_align == 0) + fac = d->imm; + else + fac = (i64)d->imm / (i64)data_align; if (d->reg < 0x40u && fac >= 0) { buf_u8(prog, DW_CFA_offset | (u8)d->reg); buf_uleb(prog, (u64)fac); @@ -673,8 +672,10 @@ static void encode_cfi_directive(Buf* prog, const CfiDirective* d, u32* cur_loc, } break; case CFI_OP_REL_OFFSET: { i64 fac; - if (data_align == 0) fac = d->imm; - else fac = (i64)d->imm / (i64)data_align; + if (data_align == 0) + fac = d->imm; + else + fac = (i64)d->imm / (i64)data_align; buf_u8(prog, DW_CFA_offset_extended_sf); buf_uleb(prog, d->reg); buf_sleb(prog, fac); @@ -735,9 +736,9 @@ void mc_emit_eh_frame(MCEmitter* m) { buf_u8(&body, fde_pe); buf_u8(&body, DW_CFA_def_cfa); buf_uleb(&body, (u64)arch->cfi_cfa_init_reg); - buf_uleb(&body, (u64)(arch->cfi_cfa_init_offset < 0 - ? 0 - : arch->cfi_cfa_init_offset)); + buf_uleb( + &body, + (u64)(arch->cfi_cfa_init_offset < 0 ? 0 : arch->cfi_cfa_init_offset)); buf_pad_to(&body, entry_start, 4u); cie_len = buf_pos(&body) - entry_start; { @@ -750,13 +751,12 @@ void mc_emit_eh_frame(MCEmitter* m) { } { - u32* pc_slot_rels = (u32*)heap->alloc( - heap, sizeof(u32) * mc->nfdes, _Alignof(u32)); + u32* pc_slot_rels = + (u32*)heap->alloc(heap, sizeof(u32) * mc->nfdes, _Alignof(u32)); ObjSymId* fde_syms = (ObjSymId*)heap->alloc( heap, sizeof(ObjSymId) * mc->nfdes, _Alignof(ObjSymId)); if (!pc_slot_rels || !fde_syms) { - if (pc_slot_rels) - heap->free(heap, pc_slot_rels, sizeof(u32) * mc->nfdes); + if (pc_slot_rels) heap->free(heap, pc_slot_rels, sizeof(u32) * mc->nfdes); if (fde_syms) heap->free(heap, fde_syms, sizeof(ObjSymId) * mc->nfdes); buf_fini(&body); compiler_panic(m->c, m->loc, "MCEmitter: CFI OOM"); @@ -777,9 +777,9 @@ void mc_emit_eh_frame(MCEmitter* m) { pc_slot = buf_pos(&body); pc_slot_rels[i] = pc_slot; fde_syms[i] = fde->func_sym; - buf_u32le(&body, 0); /* initial_location (reloc) */ + buf_u32le(&body, 0); /* initial_location (reloc) */ buf_u32le(&body, fde->func_end - fde->func_start); /* range */ - buf_uleb(&body, 0); /* aug_data_len = 0 */ + buf_uleb(&body, 0); /* aug_data_len = 0 */ for (j = 0; j < fde->ndir; ++j) { encode_cfi_directive(&body, &fde->directives[j], &cur_loc, arch->cfi_code_align_factor, @@ -803,7 +803,8 @@ void mc_emit_eh_frame(MCEmitter* m) { * ".eh_frame". The Mach-O emitter splits on comma; the ELF emitter * uses the literal as section name. */ if (m->c->target.obj == CFREE_OBJ_MACHO) { - sec_name = pool_intern_slice(m->c->global, SLICE_LIT("__TEXT,__eh_frame")); + sec_name = + pool_intern_slice(m->c->global, SLICE_LIT("__TEXT,__eh_frame")); } else { sec_name = pool_intern_slice(m->c->global, SLICE_LIT(".eh_frame")); } diff --git a/src/arch/regalloc.c b/src/arch/regalloc.c @@ -72,9 +72,7 @@ u32 cg_simple_regpool_used_regs(const CGSimpleRegPool* p, Reg* out, u32 cap) { return n; } -void cg_simple_regalloc_init(CGSimpleRegAlloc* a) { - memset(a, 0, sizeof *a); -} +void cg_simple_regalloc_init(CGSimpleRegAlloc* a) { memset(a, 0, sizeof *a); } void cg_simple_regalloc_init_virtual(CGSimpleRegAlloc* a) { memset(a, 0, sizeof *a); diff --git a/src/arch/regalloc.h b/src/arch/regalloc.h @@ -6,10 +6,10 @@ #define CG_SIMPLE_REGALLOC_MAX_REGS 32u typedef struct CGSimpleRegPool { - u32 free; /* bit i set iff reg_at(i) is free */ - u32 used; /* bit i set iff reg_at(i) was allocated/reserved */ + u32 free; /* bit i set iff reg_at(i) is free */ + u32 used; /* bit i set iff reg_at(i) was allocated/reserved */ const Reg* order; /* optional ordered hard-reg table */ - Reg base; /* used when order is NULL: reg_at(i) = base + i */ + Reg base; /* used when order is NULL: reg_at(i) = base + i */ u32 nregs; } CGSimpleRegPool; diff --git a/src/arch/rv64/alloc.c b/src/arch/rv64/alloc.c @@ -110,7 +110,7 @@ CGLocalStorage rv_param(CGTarget* t, const CGParamDesc* p) { u32 caller_off = a->next_param_stack; a->next_param_stack += 8; rv64_emit32(mc, enc_int_load(sz, 0, dst, incoming_stack_base, - caller_stack_base + (i32)caller_off)); + caller_stack_base + (i32)caller_off)); } } else if (pt->cls == ABI_CLASS_FP) { u32 dst = st.v.reg; @@ -187,15 +187,15 @@ CGLocalStorage rv_param(CGTarget* t, const CGParamDesc* p) { if (a->next_param_int < 8) { u32 reg = RV_A0 + a->next_param_int; a->next_param_int++; - rv64_emit32(mc, enc_int_store(sz, reg, RV_S0, - -(i32)s->off + (i32)part_off)); + rv64_emit32( + mc, enc_int_store(sz, reg, RV_S0, -(i32)s->off + (i32)part_off)); } else { u32 caller_off = a->next_param_stack; a->next_param_stack += 8; rv64_emit32(mc, enc_int_load(sz, 0, RV_T2, incoming_stack_base, - caller_stack_base + (i32)caller_off)); - rv64_emit32(mc, enc_int_store(sz, RV_T2, RV_S0, - -(i32)s->off + (i32)part_off)); + caller_stack_base + (i32)caller_off)); + rv64_emit32( + mc, enc_int_store(sz, RV_T2, RV_S0, -(i32)s->off + (i32)part_off)); } } else if (pt->cls == ABI_CLASS_FP) { if (a->next_param_fp < 8) { @@ -228,8 +228,7 @@ CGLocalStorage rv_param(CGTarget* t, const CGParamDesc* p) { return st; } -void rv_spill_reg(CGTarget* t, Operand src, FrameSlot slot, - MemAccess ma) { +void rv_spill_reg(CGTarget* t, Operand src, FrameSlot slot, MemAccess ma) { RImpl* a = impl_of(t); if (src.kind != OPK_REG) { compiler_panic(t->c, a->loc, "rv64 spill_reg: src is not OPK_REG"); @@ -243,8 +242,7 @@ void rv_spill_reg(CGTarget* t, Operand src, FrameSlot slot, rv_store(t, addr, src, ma); } -void rv_reload_reg(CGTarget* t, Operand dst, FrameSlot slot, - MemAccess ma) { +void rv_reload_reg(CGTarget* t, Operand dst, FrameSlot slot, MemAccess ma) { RImpl* a = impl_of(t); if (dst.kind != OPK_REG) { compiler_panic(t->c, a->loc, "rv64 reload_reg: dst is not OPK_REG"); @@ -260,9 +258,7 @@ void rv_reload_reg(CGTarget* t, Operand dst, FrameSlot slot, /* ---- labels / control flow ---- */ -Label rv_label_new(CGTarget* t) { - return (Label)t->mc->label_new(t->mc); -} +Label rv_label_new(CGTarget* t) { return (Label)t->mc->label_new(t->mc); } void rv_label_place(CGTarget* t, Label l) { t->mc->label_place(t->mc, (MCLabel)l); } @@ -316,35 +312,31 @@ u32 rv64_force_reg_int(CGTarget* t, Operand op, u32 scratch) { } static int signed_order_cmp_op(CmpOp op) { - return op == CMP_LT_S || op == CMP_LE_S || - op == CMP_GT_S || op == CMP_GE_S; + return op == CMP_LT_S || op == CMP_LE_S || op == CMP_GT_S || op == CMP_GE_S; } static int unsigned_order_cmp_op(CmpOp op) { - return op == CMP_LT_U || op == CMP_LE_U || - op == CMP_GT_U || op == CMP_GE_U; + return op == CMP_LT_U || op == CMP_LE_U || op == CMP_GT_U || op == CMP_GE_U; } static u32 sign_extend_i32_for_cmp(MCEmitter* mc, u32 src, u32 other) { - u32 dst = (src == RV_T0 || src == RV_T1) ? src - : ((other == RV_T0) ? RV_T1 - : RV_T0); + u32 dst = + (src == RV_T0 || src == RV_T1) ? src : ((other == RV_T0) ? RV_T1 : RV_T0); rv64_emit32(mc, rv_addiw(dst, src, 0)); return dst; } static u32 zero_extend_i32_for_cmp(MCEmitter* mc, u32 src, u32 other) { - u32 dst = (src == RV_T0 || src == RV_T1) ? src - : ((other == RV_T0) ? RV_T1 - : RV_T0); + u32 dst = + (src == RV_T0 || src == RV_T1) ? src : ((other == RV_T0) ? RV_T1 : RV_T0); rv64_emit32(mc, rv_slli(dst, src, 32)); rv64_emit32(mc, rv_srli(dst, dst, 32)); return dst; } static void canonicalize_i32_cmp_operands(MCEmitter* mc, CmpOp op, - CfreeCgTypeId type, - u32* ra, u32* rb) { + CfreeCgTypeId type, u32* ra, + u32* rb) { if (type_byte_size(type) != 4u) return; if (unsigned_order_cmp_op(op)) { @@ -360,8 +352,7 @@ static void canonicalize_i32_cmp_operands(MCEmitter* mc, CmpOp op, } /* Emit a conditional branch (a OP b) → label. Uses BEQ/BNE/BLT/BGE etc. */ -void rv_cmp_branch(CGTarget* t, CmpOp op, Operand a_op, Operand b_op, - Label l) { +void rv_cmp_branch(CGTarget* t, CmpOp op, Operand a_op, Operand b_op, Label l) { MCEmitter* mc = t->mc; RImpl* a = impl_of(t); /* FP compares: materialize the comparison into a GPR via FLT/FLE, @@ -385,7 +376,8 @@ void rv_cmp_branch(CGTarget* t, CmpOp op, Operand a_op, Operand b_op, case CMP_GE_F: rv64_emit32(mc, is_d ? rv_fle_d(rd, fb, fa) : rv_fle_s(rd, fb, fa)); break; - default: break; + default: + break; } rv64_emit32(mc, rv_bne(rd, RV_ZERO, 0)); mc->emit_label_ref(mc, (MCLabel)l, R_RV_BRANCH, 4, 0); @@ -396,18 +388,38 @@ void rv_cmp_branch(CGTarget* t, CmpOp op, Operand a_op, Operand b_op, canonicalize_i32_cmp_operands(mc, op, a_op.type, &ra, &rb); u32 word = 0; switch (op) { - case CMP_EQ: word = rv_beq(ra, rb, 0); break; - case CMP_NE: word = rv_bne(ra, rb, 0); break; - case CMP_LT_S: word = rv_blt(ra, rb, 0); break; - case CMP_GE_S: word = rv_bge(ra, rb, 0); break; - case CMP_LT_U: word = rv_bltu(ra, rb, 0); break; - case CMP_GE_U: word = rv_bgeu(ra, rb, 0); break; + case CMP_EQ: + word = rv_beq(ra, rb, 0); + break; + case CMP_NE: + word = rv_bne(ra, rb, 0); + break; + case CMP_LT_S: + word = rv_blt(ra, rb, 0); + break; + case CMP_GE_S: + word = rv_bge(ra, rb, 0); + break; + case CMP_LT_U: + word = rv_bltu(ra, rb, 0); + break; + case CMP_GE_U: + word = rv_bgeu(ra, rb, 0); + break; /* >= can become < with operands swapped: a > b ↔ b < a; * a <= b ↔ b >= a. */ - case CMP_GT_S: word = rv_blt(rb, ra, 0); break; - case CMP_LE_S: word = rv_bge(rb, ra, 0); break; - case CMP_GT_U: word = rv_bltu(rb, ra, 0); break; - case CMP_LE_U: word = rv_bgeu(rb, ra, 0); break; + case CMP_GT_S: + word = rv_blt(rb, ra, 0); + break; + case CMP_LE_S: + word = rv_bge(rb, ra, 0); + break; + case CMP_GT_U: + word = rv_bltu(rb, ra, 0); + break; + case CMP_LE_U: + word = rv_bgeu(rb, ra, 0); + break; default: compiler_panic(t->c, a->loc, "rv64 cmp_branch: op %d unimpl", (int)op); } @@ -416,8 +428,7 @@ void rv_cmp_branch(CGTarget* t, CmpOp op, Operand a_op, Operand b_op, } /* Materialize 0/1 into dst from a comparison. */ -void rv_cmp(CGTarget* t, CmpOp op, Operand dst, Operand a_op, - Operand b_op) { +void rv_cmp(CGTarget* t, CmpOp op, Operand dst, Operand a_op, Operand b_op) { MCEmitter* mc = t->mc; RImpl* a = impl_of(t); u32 rd = reg_num(dst); @@ -437,11 +448,20 @@ void rv_cmp(CGTarget* t, CmpOp op, Operand dst, Operand a_op, rv64_emit32(mc, is_d ? rv_feq_d(rd, fa, fb) : rv_feq_s(rd, fa, fb)); rv64_emit32(mc, rv_xori(rd, rd, 1)); return; - case CMP_LT_F: rv64_emit32(mc, is_d ? rv_flt_d(rd, fa, fb) : rv_flt_s(rd, fa, fb)); return; - case CMP_LE_F: rv64_emit32(mc, is_d ? rv_fle_d(rd, fa, fb) : rv_fle_s(rd, fa, fb)); return; - case CMP_GT_F: rv64_emit32(mc, is_d ? rv_flt_d(rd, fb, fa) : rv_flt_s(rd, fb, fa)); return; - case CMP_GE_F: rv64_emit32(mc, is_d ? rv_fle_d(rd, fb, fa) : rv_fle_s(rd, fb, fa)); return; - default: break; + case CMP_LT_F: + rv64_emit32(mc, is_d ? rv_flt_d(rd, fa, fb) : rv_flt_s(rd, fa, fb)); + return; + case CMP_LE_F: + rv64_emit32(mc, is_d ? rv_fle_d(rd, fa, fb) : rv_fle_s(rd, fa, fb)); + return; + case CMP_GT_F: + rv64_emit32(mc, is_d ? rv_flt_d(rd, fb, fa) : rv_flt_s(rd, fb, fa)); + return; + case CMP_GE_F: + rv64_emit32(mc, is_d ? rv_fle_d(rd, fb, fa) : rv_fle_s(rd, fb, fa)); + return; + default: + break; } } u32 ra = rv64_force_reg_int(t, a_op, RV_T0); @@ -457,10 +477,18 @@ void rv_cmp(CGTarget* t, CmpOp op, Operand dst, Operand a_op, rv64_emit32(mc, rv_sub(rd, ra, rb)); rv64_emit32(mc, rv_sltu(rd, RV_ZERO, rd)); return; - case CMP_LT_S: rv64_emit32(mc, rv_slt(rd, ra, rb)); return; - case CMP_LT_U: rv64_emit32(mc, rv_sltu(rd, ra, rb)); return; - case CMP_GT_S: rv64_emit32(mc, rv_slt(rd, rb, ra)); return; - case CMP_GT_U: rv64_emit32(mc, rv_sltu(rd, rb, ra)); return; + case CMP_LT_S: + rv64_emit32(mc, rv_slt(rd, ra, rb)); + return; + case CMP_LT_U: + rv64_emit32(mc, rv_sltu(rd, ra, rb)); + return; + case CMP_GT_S: + rv64_emit32(mc, rv_slt(rd, rb, ra)); + return; + case CMP_GT_U: + rv64_emit32(mc, rv_sltu(rd, rb, ra)); + return; case CMP_GE_S: rv64_emit32(mc, rv_slt(rd, ra, rb)); rv64_emit32(mc, rv_xori(rd, rd, 1)); diff --git a/src/arch/rv64/asm.c b/src/arch/rv64/asm.c @@ -57,7 +57,8 @@ static int sym_to_cstr(AsmDriver* d, Sym s, char* out, size_t cap) { return 1; } -/* True if `s` begins with the NUL-terminated literal `pfx` (length-explicit). */ +/* True if `s` begins with the NUL-terminated literal `pfx` (length-explicit). + */ static bool slice_has_prefix_cstr(Slice s, const char* pfx, size_t n) { return s.len >= n && memcmp(s.s, pfx, n) == 0; } @@ -124,11 +125,20 @@ static u32 parse_fence_mask(AsmDriver* d) { u32 mask = 0; for (const char* p = name; *p; ++p) { switch (*p) { - case 'i': mask |= 8u; break; - case 'o': mask |= 4u; break; - case 'r': mask |= 2u; break; - case 'w': mask |= 1u; break; - default: asm_driver_panic(d, "rv64 asm: bad fence char"); + case 'i': + mask |= 8u; + break; + case 'o': + mask |= 4u; + break; + case 'r': + mask |= 2u; + break; + case 'w': + mask |= 1u; + break; + default: + asm_driver_panic(d, "rv64 asm: bad fence char"); } } return mask; @@ -173,8 +183,7 @@ static u32 enc_j(u32 match, u32 rd, i32 imm21) { } static u32 enc_r4(u32 match, u32 rd, u32 rs1, u32 rs2, u32 rs3, u32 rm) { return match | ((rs3 & 0x1fu) << 27) | ((rs2 & 0x1fu) << 20) | - ((rs1 & 0x1fu) << 15) | ((rm & 0x7u) << 12) | - ((rd & 0x1fu) << 7); + ((rs1 & 0x1fu) << 15) | ((rm & 0x7u) << 12) | ((rd & 0x1fu) << 7); } /* RV64I shift-imm: shamt6 occupies bits 25:20; funct6 already in match. */ @@ -190,14 +199,14 @@ static u32 enc_ishiftw(u32 match, u32 rd, u32 rs1, u32 shamt) { /* AMO: aq/rl bits 26/25 — we accept them as optional .aq/.rl suffixes * on the mnemonic. For now mnemonics arrive bare. */ static u32 enc_amo(u32 match, u32 aq, u32 rl, u32 rd, u32 rs1, u32 rs2) { - return match | ((aq & 1u) << 26) | ((rl & 1u) << 25) | - ((rs2 & 0x1fu) << 20) | ((rs1 & 0x1fu) << 15) | - ((rd & 0x1fu) << 7); + return match | ((aq & 1u) << 26) | ((rl & 1u) << 25) | ((rs2 & 0x1fu) << 20) | + ((rs1 & 0x1fu) << 15) | ((rd & 0x1fu) << 7); } static u32 c_reg3(AsmDriver* d, u32 r) { if (r < 8u || r > 15u) - asm_driver_panic(d, "rv64 asm: compressed register must be x8..x15/f8..f15"); + asm_driver_panic(d, + "rv64 asm: compressed register must be x8..x15/f8..f15"); return r - 8u; } @@ -259,8 +268,8 @@ static u32 enc_c_swsp(u32 match, u32 rs2, u32 off, int wide64) { static u32 enc_c_cb_imm(u32 match, u32 rs1_3, i32 imm) { u32 u = (u32)imm & 0x1ffu; return match | (((u >> 8) & 1u) << 12) | (((u >> 3) & 3u) << 10) | - ((rs1_3 & 7u) << 7) | (((u >> 6) & 3u) << 5) | - (((u >> 1) & 3u) << 3) | (((u >> 5) & 1u) << 2); + ((rs1_3 & 7u) << 7) | (((u >> 6) & 3u) << 5) | (((u >> 1) & 3u) << 3) | + (((u >> 5) & 1u) << 2); } static u32 enc_c_cb_alu_imm(u32 match, u32 rd3, i32 imm) { @@ -289,20 +298,26 @@ static u32 assemble_one(AsmDriver* d, const Rv64InsnDesc* desc) { case RV64_FMT_R: /* Two-operand aliases: snez/neg/negw — rd, rs (rs1=x0). */ if (desc->flags & RV64_ASMFL_ALIAS) { - rd = parse_xreg(d); expect_comma(d); + rd = parse_xreg(d); + expect_comma(d); rs2 = parse_xreg(d); return enc_r(m, rd, 0u, rs2); } - rd = parse_xreg(d); expect_comma(d); - rs1 = parse_xreg(d); expect_comma(d); + rd = parse_xreg(d); + expect_comma(d); + rs1 = parse_xreg(d); + expect_comma(d); rs2 = parse_xreg(d); return enc_r(m, rd, rs1, rs2); case RV64_FMT_R4: { u32 rs3; - rd = parse_freg(d); expect_comma(d); - rs1 = parse_freg(d); expect_comma(d); - rs2 = parse_freg(d); expect_comma(d); + rd = parse_freg(d); + expect_comma(d); + rs1 = parse_freg(d); + expect_comma(d); + rs2 = parse_freg(d); + expect_comma(d); rs3 = parse_freg(d); return enc_r4(m, rd, rs1, rs2, rs3, 0x7u); } @@ -311,68 +326,84 @@ static u32 assemble_one(AsmDriver* d, const Rv64InsnDesc* desc) { /* Aliases first. */ if (desc->flags & RV64_ASMFL_ALIAS) { if (slice_eq_cstr(desc->mnemonic, "li")) { - rd = parse_xreg(d); expect_comma(d); + rd = parse_xreg(d); + expect_comma(d); imm = (i32)asm_driver_parse_const(d); return enc_i(m, rd, 0u, imm); } if (slice_eq_cstr(desc->mnemonic, "mv")) { - rd = parse_xreg(d); expect_comma(d); + rd = parse_xreg(d); + expect_comma(d); rs1 = parse_xreg(d); return enc_i(m, rd, rs1, 0); } if (slice_eq_cstr(desc->mnemonic, "sext.w")) { - rd = parse_xreg(d); expect_comma(d); + rd = parse_xreg(d); + expect_comma(d); rs1 = parse_xreg(d); return enc_i(m, rd, rs1, 0); } if (slice_eq_cstr(desc->mnemonic, "seqz") || slice_eq_cstr(desc->mnemonic, "not")) { - rd = parse_xreg(d); expect_comma(d); + rd = parse_xreg(d); + expect_comma(d); rs1 = parse_xreg(d); /* match already has imm12 + funct3 + op pinned. */ return m | ((rs1 & 0x1fu) << 15) | ((rd & 0x1fu) << 7); } } - rd = parse_xreg(d); expect_comma(d); - rs1 = parse_xreg(d); expect_comma(d); + rd = parse_xreg(d); + expect_comma(d); + rs1 = parse_xreg(d); + expect_comma(d); imm = (i32)asm_driver_parse_const(d); return enc_i(m, rd, rs1, imm); case RV64_FMT_I_SHIFT: - rd = parse_xreg(d); expect_comma(d); - rs1 = parse_xreg(d); expect_comma(d); + rd = parse_xreg(d); + expect_comma(d); + rs1 = parse_xreg(d); + expect_comma(d); return enc_ishift(m, rd, rs1, (u32)asm_driver_parse_const(d)); case RV64_FMT_I_SHIFTW: - rd = parse_xreg(d); expect_comma(d); - rs1 = parse_xreg(d); expect_comma(d); + rd = parse_xreg(d); + expect_comma(d); + rs1 = parse_xreg(d); + expect_comma(d); return enc_ishiftw(m, rd, rs1, (u32)asm_driver_parse_const(d)); case RV64_FMT_U: - rd = parse_xreg(d); expect_comma(d); + rd = parse_xreg(d); + expect_comma(d); imm = (i32)asm_driver_parse_const(d); /* LUI/AUIPC immediate is the upper-20 value: the input is interpreted * as the literal 20-bit value (already shifted-out form). */ return enc_u(m, rd, (u32)imm); case RV64_FMT_J: - if ((desc->flags & RV64_ASMFL_ALIAS) && slice_eq_cstr(desc->mnemonic, "j")) { + if ((desc->flags & RV64_ASMFL_ALIAS) && + slice_eq_cstr(desc->mnemonic, "j")) { imm = (i32)asm_driver_parse_const(d); return enc_j(m, 0u, imm); } - rd = parse_xreg(d); expect_comma(d); + rd = parse_xreg(d); + expect_comma(d); imm = (i32)asm_driver_parse_const(d); return enc_j(m, rd, imm); case RV64_FMT_B: if (desc->flags & RV64_ASMFL_ALIAS) { /* beqz / bnez: rs, off. */ - rs1 = parse_xreg(d); expect_comma(d); + rs1 = parse_xreg(d); + expect_comma(d); imm = (i32)asm_driver_parse_const(d); return enc_b(m, rs1, 0u, imm); } - rs1 = parse_xreg(d); expect_comma(d); - rs2 = parse_xreg(d); expect_comma(d); + rs1 = parse_xreg(d); + expect_comma(d); + rs2 = parse_xreg(d); + expect_comma(d); imm = (i32)asm_driver_parse_const(d); return enc_b(m, rs1, rs2, imm); @@ -383,7 +414,8 @@ static u32 assemble_one(AsmDriver* d, const Rv64InsnDesc* desc) { return enc_i(m, rd, mem.base, mem.disp); case RV64_FMT_FP_LOAD: - rd = parse_freg(d); expect_comma(d); + rd = parse_freg(d); + expect_comma(d); mem = parse_mem(d); return enc_i(m, rd, mem.base, mem.disp); @@ -394,12 +426,14 @@ static u32 assemble_one(AsmDriver* d, const Rv64InsnDesc* desc) { return enc_s(m, rs2, mem.base, mem.disp); case RV64_FMT_FP_STORE: - rs2 = parse_freg(d); expect_comma(d); + rs2 = parse_freg(d); + expect_comma(d); mem = parse_mem(d); return enc_s(m, rs2, mem.base, mem.disp); case RV64_FMT_JALR: - if ((desc->flags & RV64_ASMFL_ALIAS) && slice_eq_cstr(desc->mnemonic, "jr")) { + if ((desc->flags & RV64_ASMFL_ALIAS) && + slice_eq_cstr(desc->mnemonic, "jr")) { rs1 = parse_xreg(d); return enc_i(m, 0u, rs1, 0); } @@ -439,8 +473,10 @@ static u32 assemble_one(AsmDriver* d, const Rv64InsnDesc* desc) { return m; case RV64_FMT_FP_RM: - rd = parse_freg(d); expect_comma(d); - rs1 = parse_freg(d); expect_comma(d); + rd = parse_freg(d); + expect_comma(d); + rs1 = parse_freg(d); + expect_comma(d); rs2 = parse_freg(d); /* Use DYN(=7) rounding mode by default. */ return enc_r(m | (0x7u << 12), rd, rs1, rs2); @@ -452,13 +488,15 @@ static u32 assemble_one(AsmDriver* d, const Rv64InsnDesc* desc) { rd = parse_xreg(d); } expect_comma(d); - rs1 = parse_freg(d); expect_comma(d); + rs1 = parse_freg(d); + expect_comma(d); rs2 = parse_freg(d); return enc_r(m, rd, rs1, rs2); case RV64_FMT_FP_CVT: if (desc->flags & RV64_ASMFL_FP) { - rd = parse_freg(d); expect_comma(d); + rd = parse_freg(d); + expect_comma(d); /* Source: integer reg for fcvt.s.w etc (no FP flag would * indicate); but since we have ASMFL_FP set on dest, source may * be either. Disambiguate by mnemonic. */ @@ -475,22 +513,26 @@ static u32 assemble_one(AsmDriver* d, const Rv64InsnDesc* desc) { rs1 = parse_freg(d); } } else { - rd = parse_xreg(d); expect_comma(d); + rd = parse_xreg(d); + expect_comma(d); rs1 = parse_freg(d); } /* match already encodes rs2 (type selector); only OR rd/rs1. */ return m | ((rs1 & 0x1fu) << 15) | ((rd & 0x1fu) << 7); case RV64_FMT_AMO: - rd = parse_xreg(d); expect_comma(d); - rs2 = parse_xreg(d); expect_comma(d); + rd = parse_xreg(d); + expect_comma(d); + rs2 = parse_xreg(d); + expect_comma(d); asm_driver_expect_punct(d, '(', "'(' in rv64 amo operand"); rs1 = parse_xreg(d); asm_driver_expect_punct(d, ')', "')' in rv64 amo operand"); return enc_amo(m, 0u, 0u, rd, rs1, rs2); case RV64_FMT_LR: - rd = parse_xreg(d); expect_comma(d); + rd = parse_xreg(d); + expect_comma(d); asm_driver_expect_punct(d, '(', "'(' in rv64 lr operand"); rs1 = parse_xreg(d); asm_driver_expect_punct(d, ')', "')' in rv64 lr operand"); @@ -498,16 +540,20 @@ static u32 assemble_one(AsmDriver* d, const Rv64InsnDesc* desc) { case RV64_FMT_CSR: { i32 csr; - rd = parse_xreg(d); expect_comma(d); - csr = (i32)asm_driver_parse_const(d); expect_comma(d); + rd = parse_xreg(d); + expect_comma(d); + csr = (i32)asm_driver_parse_const(d); + expect_comma(d); rs1 = parse_xreg(d); return enc_i(m, rd, rs1, csr); } case RV64_FMT_CSRI: { i32 csr; - rd = parse_xreg(d); expect_comma(d); - csr = (i32)asm_driver_parse_const(d); expect_comma(d); + rd = parse_xreg(d); + expect_comma(d); + csr = (i32)asm_driver_parse_const(d); + expect_comma(d); u32 uimm = (u32)asm_driver_parse_const(d) & 0x1fu; return enc_i(m, rd, uimm, csr); } @@ -518,7 +564,8 @@ static u32 assemble_one(AsmDriver* d, const Rv64InsnDesc* desc) { rs1 = parse_xreg(d); return enc_c_cr(m, rs1, 0u); } - rd = parse_xreg(d); expect_comma(d); + rd = parse_xreg(d); + expect_comma(d); rs2 = parse_xreg(d); return enc_c_cr(m, rd, rs2); @@ -526,7 +573,8 @@ static u32 assemble_one(AsmDriver* d, const Rv64InsnDesc* desc) { if (slice_eq_cstr(desc->mnemonic, "c.lwsp") || slice_eq_cstr(desc->mnemonic, "c.ldsp") || slice_eq_cstr(desc->mnemonic, "c.fldsp")) { - rd = slice_eq_cstr(desc->mnemonic, "c.fldsp") ? parse_freg(d) : parse_xreg(d); + rd = slice_eq_cstr(desc->mnemonic, "c.fldsp") ? parse_freg(d) + : parse_xreg(d); expect_comma(d); mem = parse_mem(d); if (mem.base != RV_SP) @@ -534,7 +582,8 @@ static u32 assemble_one(AsmDriver* d, const Rv64InsnDesc* desc) { return enc_c_lwsp(m, rd, (u32)mem.disp, !slice_eq_cstr(desc->mnemonic, "c.lwsp")); } - rd = parse_xreg(d); expect_comma(d); + rd = parse_xreg(d); + expect_comma(d); imm = (i32)asm_driver_parse_const(d); if (slice_eq_cstr(desc->mnemonic, "c.lui") && ((u32)imm & 0xfffu) == 0) imm >>= 12; @@ -555,8 +604,10 @@ static u32 assemble_one(AsmDriver* d, const Rv64InsnDesc* desc) { !slice_eq_cstr(desc->mnemonic, "c.swsp")); case RV64_FMT_CIW: - rd = parse_xreg(d); expect_comma(d); - rs1 = parse_xreg(d); expect_comma(d); + rd = parse_xreg(d); + expect_comma(d); + rs1 = parse_xreg(d); + expect_comma(d); if (rs1 != RV_SP) asm_driver_panic(d, "rv64 asm: c.addi4spn needs sp source"); imm = (i32)asm_driver_parse_const(d); @@ -566,23 +617,25 @@ static u32 assemble_one(AsmDriver* d, const Rv64InsnDesc* desc) { rd = (desc->flags & RV64_ASMFL_FP) ? parse_freg(d) : parse_xreg(d); expect_comma(d); mem = parse_mem(d); - return enc_c_lwld(m, c_reg3(d, rd), c_reg3(d, mem.base), - (u32)mem.disp, !slice_eq_cstr(desc->mnemonic, "c.lw")); + return enc_c_lwld(m, c_reg3(d, rd), c_reg3(d, mem.base), (u32)mem.disp, + !slice_eq_cstr(desc->mnemonic, "c.lw")); case RV64_FMT_CS: rs2 = (desc->flags & RV64_ASMFL_FP) ? parse_freg(d) : parse_xreg(d); expect_comma(d); mem = parse_mem(d); - return enc_c_swld(m, c_reg3(d, rs2), c_reg3(d, mem.base), - (u32)mem.disp, !slice_eq_cstr(desc->mnemonic, "c.sw")); + return enc_c_swld(m, c_reg3(d, rs2), c_reg3(d, mem.base), (u32)mem.disp, + !slice_eq_cstr(desc->mnemonic, "c.sw")); case RV64_FMT_CA: - rd = parse_xreg(d); expect_comma(d); + rd = parse_xreg(d); + expect_comma(d); rs2 = parse_xreg(d); return m | (c_reg3(d, rd) << 7) | (c_reg3(d, rs2) << 2); case RV64_FMT_CB: - rs1 = parse_xreg(d); expect_comma(d); + rs1 = parse_xreg(d); + expect_comma(d); imm = (i32)asm_driver_parse_const(d); if (slice_eq_cstr(desc->mnemonic, "c.beqz") || slice_eq_cstr(desc->mnemonic, "c.bnez")) { @@ -645,10 +698,9 @@ Rv64Asm* rv64_asm_open(Compiler* c) { void rv64_asm_close(Rv64Asm* a) { (void)a; } -void rv64_inline_bind(Rv64Asm* a, - const AsmConstraint* outs, u32 nout, Operand* out_ops, - const AsmConstraint* ins, u32 nin, const Operand* in_ops, - const Sym* clobbers, u32 nclob) { +void rv64_inline_bind(Rv64Asm* a, const AsmConstraint* outs, u32 nout, + Operand* out_ops, const AsmConstraint* ins, u32 nin, + const Operand* in_ops, const Sym* clobbers, u32 nclob) { a->outs = outs; a->out_ops = out_ops; a->ins = ins; @@ -699,15 +751,15 @@ static void render_freg(StrBuf* sb, u32 reg) { /* Render a signed 64-bit integer. Inline asm immediates appear bare in * RISC-V (no '#' prefix), matching the standalone .s parser. */ -static void render_imm(StrBuf* sb, i64 v) { - strbuf_put_i64(sb, v); -} +static void render_imm(StrBuf* sb, i64 v) { strbuf_put_i64(sb, v); } /* Render addressing form `disp(base)`. */ static void render_indirect(Rv64Asm* a, StrBuf* sb, Reg base, i32 ofs) { (void)a; - if (ofs != 0) strbuf_put_i64(sb, (i64)ofs); - else strbuf_putc(sb, '0'); + if (ofs != 0) + strbuf_put_i64(sb, (i64)ofs); + else + strbuf_putc(sb, '0'); strbuf_putc(sb, '('); render_xreg(sb, (u32)base); strbuf_putc(sb, ')'); @@ -722,14 +774,16 @@ static void render_indirect(Rv64Asm* a, StrBuf* sb, Reg base, i32 ofs) { static void render_operand(Rv64Asm* a, StrBuf* sb, u32 idx, int form) { u32 ntot = a->nout + a->nin; if (idx >= ntot) inline_panic(a, "operand index out of range"); - const Operand* op = (idx < a->nout) ? &a->out_ops[idx] - : &a->in_ops[idx - a->nout]; + const Operand* op = + (idx < a->nout) ? &a->out_ops[idx] : &a->in_ops[idx - a->nout]; switch (form) { case 1: /* %wN — accept any reg/imm; rv64 has no narrower spelling. */ case 2: /* %xN — same. */ if (op->kind == OPK_REG) { - if (op->cls == RC_FP) render_freg(sb, (u32)op->v.reg); - else render_xreg(sb, (u32)op->v.reg); + if (op->cls == RC_FP) + render_freg(sb, (u32)op->v.reg); + else + render_xreg(sb, (u32)op->v.reg); return; } if (op->kind == OPK_IMM) { @@ -738,11 +792,11 @@ static void render_operand(Rv64Asm* a, StrBuf* sb, u32 idx, int form) { } inline_panic(a, "%w/%x on unsupported operand kind"); case 3: /* %aN — memory addressing form */ - if (op->kind != OPK_INDIRECT) - inline_panic(a, "%a on non-memory operand"); + if (op->kind != OPK_INDIRECT) inline_panic(a, "%a on non-memory operand"); if (op->v.ind.index != REG_NONE) - inline_panic(a, "%a on indexed memory operand: rv64 inline asm " - "requires base+disp only"); + inline_panic(a, + "%a on indexed memory operand: rv64 inline asm " + "requires base+disp only"); render_indirect(a, sb, op->v.ind.base, op->v.ind.ofs); return; case 4: /* %zN — zero-or-reg */ @@ -751,8 +805,10 @@ static void render_operand(Rv64Asm* a, StrBuf* sb, u32 idx, int form) { return; } if (op->kind == OPK_REG) { - if (op->cls == RC_FP) render_freg(sb, (u32)op->v.reg); - else render_xreg(sb, (u32)op->v.reg); + if (op->cls == RC_FP) + render_freg(sb, (u32)op->v.reg); + else + render_xreg(sb, (u32)op->v.reg); return; } inline_panic(a, "%z on unsupported operand kind"); @@ -761,16 +817,19 @@ static void render_operand(Rv64Asm* a, StrBuf* sb, u32 idx, int form) { } switch (op->kind) { case OPK_REG: - if (op->cls == RC_FP) render_freg(sb, (u32)op->v.reg); - else render_xreg(sb, (u32)op->v.reg); + if (op->cls == RC_FP) + render_freg(sb, (u32)op->v.reg); + else + render_xreg(sb, (u32)op->v.reg); return; case OPK_IMM: render_imm(sb, op->v.imm); return; case OPK_INDIRECT: if (op->v.ind.index != REG_NONE) - inline_panic(a, "indexed memory operand in inline asm: rv64 requires " - "base+disp only"); + inline_panic(a, + "indexed memory operand in inline asm: rv64 requires " + "base+disp only"); render_indirect(a, sb, op->v.ind.base, op->v.ind.ofs); return; default: @@ -870,8 +929,8 @@ static void render_and_run_line(Rv64Asm* a, MCEmitter* mc, StrBuf* sb, while (nend < end && *nend != ']') ++nend; if (nend == end) inline_panic(a, "unterminated %[name]"); size_t nlen = (size_t)(nend - nbeg); - Sym needle = pool_intern_slice(a->c->global, - (Slice){.s = nbeg, .len = nlen}); + Sym needle = + pool_intern_slice(a->c->global, (Slice){.s = nbeg, .len = nlen}); u32 idx = lookup_named(a, needle); if (idx == (u32)-1) inline_panic(a, "%[name] does not match any constraint"); @@ -892,8 +951,8 @@ static void render_and_run_line(Rv64Asm* a, MCEmitter* mc, StrBuf* sb, while (nend < end && *nend != ']') ++nend; if (nend == end) inline_panic(a, "unterminated %[name]"); size_t nlen = (size_t)(nend - nbeg); - Sym needle = pool_intern_slice(a->c->global, - (Slice){.s = nbeg, .len = nlen}); + Sym needle = + pool_intern_slice(a->c->global, (Slice){.s = nbeg, .len = nlen}); u32 idx = lookup_named(a, needle); if (idx == (u32)-1) inline_panic(a, "%[name] does not match any constraint"); @@ -901,8 +960,7 @@ static void render_and_run_line(Rv64Asm* a, MCEmitter* mc, StrBuf* sb, render_operand(a, sb, idx, form); continue; } - if (n < '0' || n > '9') - inline_panic(a, "expected digit after '%'"); + if (n < '0' || n > '9') inline_panic(a, "expected digit after '%'"); u32 idx = (u32)(n - '0'); ++p; /* GCC syntax permits up to two digits (%0..%99). */ diff --git a/src/arch/rv64/asm.h b/src/arch/rv64/asm.h @@ -24,10 +24,9 @@ void rv64_asm_close(Rv64Asm*); /* Bind the operand arrays + clobbers from the cg-side asm_block call onto * the Rv64Asm handle. Operand indexing per the GCC convention: outputs are * indexed 0..nout-1, then nout..nout+nin-1. */ -void rv64_inline_bind(Rv64Asm*, - const AsmConstraint* outs, u32 nout, Operand* out_ops, - const AsmConstraint* ins, u32 nin, const Operand* in_ops, - const Sym* clobbers, u32 nclob); +void rv64_inline_bind(Rv64Asm*, const AsmConstraint* outs, u32 nout, + Operand* out_ops, const AsmConstraint* ins, u32 nin, + const Operand* in_ops, const Sym* clobbers, u32 nclob); /* Walk the inline-asm template, substituting placeholders into per-line * source text and re-lexing each line through the standalone rv64 diff --git a/src/arch/rv64/dbg.c b/src/arch/rv64/dbg.c @@ -72,9 +72,7 @@ #define SHIM_T0 RV_T0 /* x5 — caller-saved temp, safe inside a shim */ -uint32_t dbg_rv64_brk_word(void) { - return rv_ebreak(); -} +uint32_t dbg_rv64_brk_word(void) { return rv_ebreak(); } static void put_u32(uint8_t* w, uint32_t off, uint32_t v) { memcpy(w + off, &v, sizeof(v)); @@ -95,34 +93,31 @@ static uint32_t rv_rs2(uint32_t insn) { return (insn >> 20) & 0x1fu; } /* J-type 20-bit immediate (sign-extended into 21-bit byte offset). */ static int64_t rv_j_imm(uint32_t insn) { - uint64_t imm = - ((uint64_t)((insn >> 31) & 1u) << 20) | - ((uint64_t)((insn >> 21) & 0x3ffu) << 1) | - ((uint64_t)((insn >> 20) & 1u) << 11) | - ((uint64_t)((insn >> 12) & 0xffu) << 12); + uint64_t imm = ((uint64_t)((insn >> 31) & 1u) << 20) | + ((uint64_t)((insn >> 21) & 0x3ffu) << 1) | + ((uint64_t)((insn >> 20) & 1u) << 11) | + ((uint64_t)((insn >> 12) & 0xffu) << 12); return sign_extend(imm, 21); } /* B-type 12-bit immediate (sign-extended 13-bit byte offset). */ static int64_t rv_b_imm(uint32_t insn) { - uint64_t imm = - ((uint64_t)((insn >> 31) & 1u) << 12) | - ((uint64_t)((insn >> 7) & 1u) << 11) | - ((uint64_t)((insn >> 25) & 0x3fu) << 5) | - ((uint64_t)((insn >> 8) & 0xfu) << 1); + uint64_t imm = ((uint64_t)((insn >> 31) & 1u) << 12) | + ((uint64_t)((insn >> 7) & 1u) << 11) | + ((uint64_t)((insn >> 25) & 0x3fu) << 5) | + ((uint64_t)((insn >> 8) & 0xfu) << 1); return sign_extend(imm, 13); } /* U-type 20-bit immediate, returned as the raw 20-bit field (consumer * shifts it left by 12). */ -static uint32_t rv_u_imm20(uint32_t insn) { - return (insn >> 12) & 0xfffffu; -} +static uint32_t rv_u_imm20(uint32_t insn) { return (insn >> 12) & 0xfffffu; } /* Decompose a 64-bit absolute target into a 32-bit AUIPC/LUI hi20 + * ADDI lo12 pair such that: * lui rd, hi20 -> rd = (sign_ext_32(hi20 << 12)) - * addi rd, rd, lo12 -> rd = (sign_ext_32(hi20 << 12) + sign_ext_12(lo12)) + * addi rd, rd, lo12 -> rd = (sign_ext_32(hi20 << 12) + + * sign_ext_12(lo12)) * == sign_ext_32(target_low32) * Returns 1 if the absolute target's low 32 bits cannot represent the * full target (i.e. the target lives outside the sign-extended 32-bit @@ -309,9 +304,8 @@ int dbg_rv64_build_shim(uint32_t orig_insn, uint64_t orig_pc, uint32_t rd = rv_rd(orig_insn); /* AUIPC computes rd = orig_pc + sign_ext_32(imm20 << 12). We * synthesize that absolute value into rd using LUI + ADDI. */ - uint64_t auipc_val = - (uint64_t)((int64_t)orig_pc + - (int64_t)(int32_t)((int32_t)(imm20 << 12))); + uint64_t auipc_val = (uint64_t)((int64_t)orig_pc + + (int64_t)(int32_t)((int32_t)(imm20 << 12))); uint32_t hi20; int32_t lo12; int sext32; @@ -354,12 +348,9 @@ static CfreeStatus rv64_dbg_decode_insn(const u8* bytes, u32 len, u64 pc, return CFREE_OK; } -static CfreeStatus rv64_dbg_build_displaced_shim(const ArchDbgInsn* insn, - void* scratch_write, - u64 scratch_runtime, - u32 scratch_cap, - u32* sentinel_off, - u64* fallthrough_pc) { +static CfreeStatus rv64_dbg_build_displaced_shim( + const ArchDbgInsn* insn, void* scratch_write, u64 scratch_runtime, + u32 scratch_cap, u32* sentinel_off, u64* fallthrough_pc) { uint32_t word = 0; if (!insn || !scratch_write || !sentinel_off || !fallthrough_pc) return CFREE_INVALID; diff --git a/src/arch/rv64/disasm.c b/src/arch/rv64/disasm.c @@ -37,18 +37,15 @@ typedef struct Rv64Disasm { Rv64InsnFormatter fmt; } Rv64Disasm; -static CfreeStatus rv64_format_insn(ArchInsnFormatter*, - const CfreeDecodedInsn*, CfreeInsn*); +static CfreeStatus rv64_format_insn(ArchInsnFormatter*, const CfreeDecodedInsn*, + CfreeInsn*); static void rv64_formatter_destroy(ArchInsnFormatter*); static u32 rv_read_u32_le(const u8* b) { - return (u32)b[0] | ((u32)b[1] << 8) | ((u32)b[2] << 16) | - ((u32)b[3] << 24); + return (u32)b[0] | ((u32)b[1] << 8) | ((u32)b[2] << 16) | ((u32)b[3] << 24); } -static u32 rv_read_u16_le(const u8* b) { - return (u32)b[0] | ((u32)b[1] << 8); -} +static u32 rv_read_u16_le(const u8* b) { return (u32)b[0] | ((u32)b[1] << 8); } static void rv_fmt_emit_fallback32(Rv64InsnFormatter* f, u32 word) { strbuf_reset(&f->mnem); @@ -233,9 +230,9 @@ static void rv64_decode_operands(const Rv64InsnDesc* desc, u32 word, u64 pc, out->noperands = 3; rv_decop_reg(&out->operands[0], i.rd, 64); rv_decop_reg(&out->operands[1], i.rs1, 64); - rv_decop_imm(&out->operands[2], - fmt == RV64_FMT_I_SHIFTW ? (i.imm12 & 0x1f) - : (i.imm12 & 0x3f)); + rv_decop_imm(&out->operands[2], fmt == RV64_FMT_I_SHIFTW + ? (i.imm12 & 0x1f) + : (i.imm12 & 0x3f)); break; } case RV64_FMT_LOAD: diff --git a/src/arch/rv64/emit.c b/src/arch/rv64/emit.c @@ -4,11 +4,10 @@ #include "arch/rv64/internal.h" #include "core/slice.h" -static u32 collect_mask_regs(u32 mask, u32 first, u32 last, u32 *out) { +static u32 collect_mask_regs(u32 mask, u32 first, u32 last, u32* out) { u32 n = 0; for (u32 r = first; r <= last; ++r) { - if (mask & (1u << r)) - out[n++] = r; + if (mask & (1u << r)) out[n++] = r; } return n; } @@ -21,7 +20,7 @@ static u32 count_mask_regs(u32 mask, u32 first, u32 last) { return n; } -static u32 rv_planned_prologue_words(const RImpl *a) { +static u32 rv_planned_prologue_words(const RImpl* a) { u32 n = RV_PROLOGUE_FRAME_WORDS; if (a->has_sret) ++n; if (a->is_variadic) n += 8u; @@ -30,7 +29,7 @@ static u32 rv_planned_prologue_words(const RImpl *a) { return n ? n : 1u; } -void rv64_emit32(MCEmitter *mc, u32 word) { +void rv64_emit32(MCEmitter* mc, u32 word) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 b[4]; b[0] = (u8)(word & 0xff); @@ -38,21 +37,19 @@ void rv64_emit32(MCEmitter *mc, u32 word) { b[2] = (u8)((word >> 16) & 0xff); b[3] = (u8)((word >> 24) & 0xff); mc->emit_bytes(mc, b, 4); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } -void rv64_emit16(MCEmitter *mc, u32 halfword) { +void rv64_emit16(MCEmitter* mc, u32 halfword) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 b[2]; b[0] = (u8)(halfword & 0xff); b[1] = (u8)((halfword >> 8) & 0xff); mc->emit_bytes(mc, b, 2); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } -void rv64_patch32(ObjBuilder *obj, u32 sec_id, u32 ofs, u32 word) { +void rv64_patch32(ObjBuilder* obj, u32 sec_id, u32 ofs, u32 word) { u8 b[4]; b[0] = (u8)(word & 0xff); b[1] = (u8)((word >> 8) & 0xff); @@ -61,7 +58,7 @@ void rv64_patch32(ObjBuilder *obj, u32 sec_id, u32 ofs, u32 word) { obj_patch(obj, sec_id, ofs, b, 4); } -_Noreturn void rv_panic(CGTarget *t, const char *what) { +_Noreturn void rv_panic(CGTarget* t, const char* what) { SrcLoc loc = impl_of(t)->loc; compiler_panic(t->c, loc, "rv64: %.*s not implemented", SLICE_ARG(slice_from_cstr(what))); @@ -76,7 +73,7 @@ static i64 floor_div_4096(i64 v) { return -((-v + 4095) / 4096); } -void emit_li_32(MCEmitter *mc, u32 rd, i32 imm) { +void emit_li_32(MCEmitter* mc, u32 rd, i32 imm) { if (imm >= -2048 && imm <= 2047) { rv64_emit32(mc, rv_addi(rd, RV_ZERO, imm)); return; @@ -87,8 +84,7 @@ void emit_li_32(MCEmitter *mc, u32 rd, i32 imm) { i32 hi = (i32)hi64; i32 lo = (i32)lo64; rv64_emit32(mc, rv_lui(rd, (u32)hi & 0xfffffu)); - if (lo) - rv64_emit32(mc, rv_addiw(rd, rd, lo)); + if (lo) rv64_emit32(mc, rv_addiw(rd, rd, lo)); } static i32 sign_extend_12(u32 v) { @@ -106,7 +102,7 @@ static i32 i32_from_bits(u32 v) { return -(i32)(~v + 1u); } -static void emit_li_64(MCEmitter *mc, u32 rd, u64 imm) { +static void emit_li_64(MCEmitter* mc, u32 rd, u64 imm) { if (fits_signed32_bits(imm)) { emit_li_32(mc, rd, i32_from_bits((u32)imm)); return; @@ -115,11 +111,10 @@ static void emit_li_64(MCEmitter *mc, u32 rd, u64 imm) { u64 hi = (imm - (u64)(i64)lo) >> 12; emit_li_64(mc, rd, hi); rv64_emit32(mc, rv_slli(rd, rd, 12)); - if (lo) - rv64_emit32(mc, rv_addi(rd, rd, lo)); + if (lo) rv64_emit32(mc, rv_addi(rd, rd, lo)); } -void rv64_emit_load_imm(MCEmitter *mc, u32 sf, u32 rd, i64 imm) { +void rv64_emit_load_imm(MCEmitter* mc, u32 sf, u32 rd, i64 imm) { if (!sf) { /* 32-bit destination: low 32 bits, sign-extended. */ emit_li_32(mc, rd, (i32)imm); @@ -134,7 +129,7 @@ void rv64_emit_load_imm(MCEmitter *mc, u32 sf, u32 rd, i64 imm) { /* sp += imm. imm can be any signed value the caller passes — we pick * the shortest sequence. */ -void emit_sp_addi(MCEmitter *mc, i64 imm) { +void emit_sp_addi(MCEmitter* mc, i64 imm) { if (imm >= -2048 && imm <= 2047) { rv64_emit32(mc, rv_addi(RV_SP, RV_SP, (i32)imm)); return; @@ -146,9 +141,9 @@ void emit_sp_addi(MCEmitter *mc, i64 imm) { /* ---- function lifecycle ---- */ typedef struct RvFrameLayout RvFrameLayout; -static void rv_emit_cfi_frame(CGTarget *t, u32 post_prologue_off, - const RvFrameLayout *fl, const u32 *int_regs, - u32 n_int_saves, const u32 *fp_regs, +static void rv_emit_cfi_frame(CGTarget* t, u32 post_prologue_off, + const RvFrameLayout* fl, const u32* int_regs, + u32 n_int_saves, const u32* fp_regs, u32 n_fp_saves, int omit_frame); struct RvFrameLayout { @@ -160,9 +155,9 @@ struct RvFrameLayout { i32 int_save_base; }; -static void rv_func_begin_init(CGTarget *t, const CGFuncDesc *fd) { - RImpl *a = impl_of(t); - MCEmitter *mc = t->mc; +static void rv_func_begin_init(CGTarget* t, const CGFuncDesc* fd) { + RImpl* a = impl_of(t); + MCEmitter* mc = t->mc; mc->set_section(mc, fd->text_section_id); mc->emit_align(mc, 4, 0); @@ -182,8 +177,8 @@ static void rv_func_begin_init(CGTarget *t, const CGFuncDesc *fd) { a->fp_pair_off = 0; a->used_cs_int_mask = a->has_planned_regs ? a->planned_cs_int_mask : 0; a->used_cs_fp_mask = a->has_planned_regs ? a->planned_cs_fp_mask : 0; - a->prologue_words = a->has_planned_regs ? rv_planned_prologue_words(a) - : RV_PROLOGUE_WORDS; + a->prologue_words = + a->has_planned_regs ? rv_planned_prologue_words(a) : RV_PROLOGUE_WORDS; a->post_prologue_off = 0; a->planned_cs_int_mask = 0; a->planned_cs_fp_mask = 0; @@ -199,8 +194,8 @@ static void rv_func_begin_init(CGTarget *t, const CGFuncDesc *fd) { mc->cfi_startproc(mc); } -static void rv_add_entry_frame_slots(CGTarget *t) { - RImpl *a = impl_of(t); +static void rv_add_entry_frame_slots(CGTarget* t) { + RImpl* a = impl_of(t); /* For an sret return, the caller passed the destination pointer in * a0; reserve a hidden slot to spill it into so the body can use a0 @@ -229,8 +224,8 @@ static void rv_add_entry_frame_slots(CGTarget *t) { * is_variadic is set. */ } -static void rv_compute_frame(const RImpl *a, u32 n_int_saves, u32 n_fp_saves, - RvFrameLayout *fl) { +static void rv_compute_frame(const RImpl* a, u32 n_int_saves, u32 n_fp_saves, + RvFrameLayout* fl) { fl->max_out = (a->max_outgoing + 15u) & ~15u; u32 int_saves_sz = n_int_saves * 8u; fl->fp_saves_sz = n_fp_saves * 8u; @@ -253,18 +248,18 @@ static void rv_compute_frame(const RImpl *a, u32 n_int_saves, u32 n_fp_saves, fl->int_save_base = fl->fp_save_base - (i32)fl->fp_saves_sz; } -static u32 rv_variadic_first_saved_int(const CGFuncDesc *fd) { +static u32 rv_variadic_first_saved_int(const CGFuncDesc* fd) { u32 next_int = (fd->abi && fd->abi->has_sret) ? 1u : 0u; u32 next_fp = 0; for (u32 pidx = 0; pidx < fd->nparams; ++pidx) { - const ABIArgInfo *ai = fd->params[pidx].abi; + const ABIArgInfo* ai = fd->params[pidx].abi; if (!ai || ai->kind == ABI_ARG_IGNORE) continue; if (ai->kind == ABI_ARG_INDIRECT) { if (next_int < 8) ++next_int; continue; } for (u16 i = 0; i < ai->nparts; ++i) { - const ABIArgPart *pt = &ai->parts[i]; + const ABIArgPart* pt = &ai->parts[i]; if (pt->cls == ABI_CLASS_INT) { if (next_int < 8) ++next_int; } else if (pt->cls == ABI_CLASS_FP) { @@ -275,7 +270,7 @@ static u32 rv_variadic_first_saved_int(const CGFuncDesc *fd) { return next_int; } -static void rv_words_addr_adjust(CGTarget *t, u32 *words, u32 cap, u32 *wi, +static void rv_words_addr_adjust(CGTarget* t, u32* words, u32 cap, u32* wi, u32 rd, u32 base, i32 off) { if (off == 0) { if (rd != base) { @@ -306,7 +301,7 @@ overflow: "rv64: prologue placeholder too small (cap %u)", cap); } -static void rv_words_store_int_s0(CGTarget *t, u32 *words, u32 cap, u32 *wi, +static void rv_words_store_int_s0(CGTarget* t, u32* words, u32 cap, u32* wi, u32 reg, i32 off) { if (off >= -2048 && off <= 2047) { if (*wi >= cap) goto overflow; @@ -323,7 +318,7 @@ overflow: "rv64: prologue placeholder too small (cap %u)", cap); } -static void rv_words_store_fp_s0(CGTarget *t, u32 *words, u32 cap, u32 *wi, +static void rv_words_store_fp_s0(CGTarget* t, u32* words, u32 cap, u32* wi, u32 reg, i32 off) { if (off >= -2048 && off <= 2047) { if (*wi >= cap) goto overflow; @@ -340,11 +335,11 @@ overflow: "rv64: prologue placeholder too small (cap %u)", cap); } -static u32 rv_build_prologue(CGTarget *t, u32 *words, u32 cap, - const RvFrameLayout *fl, const u32 *int_regs, - u32 n_int_saves, const u32 *fp_regs, +static u32 rv_build_prologue(CGTarget* t, u32* words, u32 cap, + const RvFrameLayout* fl, const u32* int_regs, + u32 n_int_saves, const u32* fp_regs, u32 n_fp_saves, u32 variadic_first_int) { - RImpl *a = impl_of(t); + RImpl* a = impl_of(t); u32 wi = 0; /* addi sp, sp, -frame_size (or multi-insn if too large) */ @@ -380,8 +375,7 @@ static u32 rv_build_prologue(CGTarget *t, u32 *words, u32 cap, compiler_panic(t->c, a->loc, "rv64: fp_pair_off too large"); if (wi + 6 > cap) goto overflow; words[wi++] = rv_lui(RV_T0, (u32)hi & 0xfffffu); - if (lo) - words[wi++] = rv_addiw(RV_T0, RV_T0, lo); + if (lo) words[wi++] = rv_addiw(RV_T0, RV_T0, lo); words[wi++] = rv_add(RV_T0, RV_SP, RV_T0); words[wi++] = rv_sd(RV_S0, RV_T0, 0); words[wi++] = rv_sd(RV_RA, RV_T0, 8); @@ -390,7 +384,7 @@ static u32 rv_build_prologue(CGTarget *t, u32 *words, u32 cap, /* If sret, spill incoming a0 into the hidden slot. */ if (a->has_sret && a->sret_ptr_slot != FRAME_SLOT_NONE) { - RvSlot *s = rv64_slot_get(a, a->sret_ptr_slot); + RvSlot* s = rv64_slot_get(a, a->sret_ptr_slot); if (s) { if (wi >= cap) goto overflow; words[wi++] = rv_sd(RV_A0, RV_S0, -(i32)s->off); @@ -416,31 +410,30 @@ static u32 rv_build_prologue(CGTarget *t, u32 *words, u32 cap, return wi; overflow: - compiler_panic(t->c, a->loc, - "rv64: prologue placeholder too small (cap %u)", cap); + compiler_panic(t->c, a->loc, "rv64: prologue placeholder too small (cap %u)", + cap); return 0; } -void rv_func_begin(CGTarget *t, const CGFuncDesc *fd) { - RImpl *a = impl_of(t); - MCEmitter *mc = t->mc; +void rv_func_begin(CGTarget* t, const CGFuncDesc* fd) { + RImpl* a = impl_of(t); + MCEmitter* mc = t->mc; rv_func_begin_init(t, fd); /* Reserve a NOP-filled prologue placeholder; func_end patches it. */ a->prologue_pos = mc->pos(mc); - for (u32 i = 0; i < a->prologue_words; ++i) - rv64_emit32(mc, RV_NOP); + for (u32 i = 0; i < a->prologue_words; ++i) rv64_emit32(mc, RV_NOP); rv_add_entry_frame_slots(t); /* Capture end-of-prologue position for CFI emission in func_end. */ a->post_prologue_off = mc->pos(mc) - a->func_start; } -void rv_func_begin_known_frame(CGTarget *t, const CGFuncDesc *fd, - const CGKnownFrameDesc *frame, - FrameSlot *out_slots) { - RImpl *a = impl_of(t); +void rv_func_begin_known_frame(CGTarget* t, const CGFuncDesc* fd, + const CGKnownFrameDesc* frame, + FrameSlot* out_slots) { + RImpl* a = impl_of(t); u32 int_regs[10]; u32 fp_regs[10]; u32 words[RV_PROLOGUE_WORDS]; @@ -462,23 +455,21 @@ void rv_func_begin_known_frame(CGTarget *t, const CGFuncDesc *fd, u32 n_fp_saves = collect_mask_regs(a->used_cs_fp_mask, 18u, 27u, fp_regs); if (frame && frame->may_omit_frame && frame->nslots == 0 && frame->max_outgoing == 0 && !frame->has_alloca && !frame->has_call && - !a->has_sret && !a->is_variadic && n_int_saves == 0 && - n_fp_saves == 0) { + !a->has_sret && !a->is_variadic && n_int_saves == 0 && n_fp_saves == 0) { a->omit_frame = 1; return; } rv_compute_frame(a, n_int_saves, n_fp_saves, &fl); a->fp_pair_off = fl.fp_pair_off; a->prologue_pos = t->mc->pos(t->mc); - u32 nwords = rv_build_prologue(t, words, RV_PROLOGUE_WORDS, &fl, int_regs, - n_int_saves, fp_regs, n_fp_saves, - rv_variadic_first_saved_int(fd)); - for (u32 i = 0; i < nwords; ++i) - rv64_emit32(t->mc, words[i]); + u32 nwords = + rv_build_prologue(t, words, RV_PROLOGUE_WORDS, &fl, int_regs, n_int_saves, + fp_regs, n_fp_saves, rv_variadic_first_saved_int(fd)); + for (u32 i = 0; i < nwords; ++i) rv64_emit32(t->mc, words[i]); { u32 post = t->mc->pos(t->mc) - a->func_start; - rv_emit_cfi_frame(t, post, &fl, int_regs, n_int_saves, fp_regs, - n_fp_saves, /*omit_frame=*/0); + rv_emit_cfi_frame(t, post, &fl, int_regs, n_int_saves, fp_regs, n_fp_saves, + /*omit_frame=*/0); } } @@ -489,18 +480,18 @@ void rv_func_begin_known_frame(CGTarget *t, const CGFuncDesc *fd, * saved ra at [s0+8] = saved-s0 offset + 8 * each callee-save at s0-relative offsets recorded in RvFrameLayout */ -static void rv_emit_cfi_frame(CGTarget *t, u32 post_prologue_off, - const RvFrameLayout *fl, const u32 *int_regs, - u32 n_int_saves, const u32 *fp_regs, +static void rv_emit_cfi_frame(CGTarget* t, u32 post_prologue_off, + const RvFrameLayout* fl, const u32* int_regs, + u32 n_int_saves, const u32* fp_regs, u32 n_fp_saves, int omit_frame) { - MCEmitter *mc = t->mc; + MCEmitter* mc = t->mc; i32 fp_dist; if (omit_frame) return; fp_dist = (i32)fl->frame_size - (i32)fl->fp_pair_off; mc->cfi_set_next_pc_offset(mc, post_prologue_off); mc->cfi_def_cfa(mc, 8u, fp_dist); - mc->cfi_offset(mc, 8u, -fp_dist); /* saved s0 at [s0+0] */ - mc->cfi_offset(mc, 1u, -fp_dist + 8); /* saved ra at [s0+8] */ + mc->cfi_offset(mc, 8u, -fp_dist); /* saved s0 at [s0+0] */ + mc->cfi_offset(mc, 1u, -fp_dist + 8); /* saved ra at [s0+8] */ { u32 i; for (i = 0; i < n_int_saves; ++i) { @@ -517,10 +508,10 @@ static void rv_emit_cfi_frame(CGTarget *t, u32 post_prologue_off, } } -void rv_func_end(CGTarget *t) { - RImpl *a = impl_of(t); - MCEmitter *mc = t->mc; - ObjBuilder *obj = t->obj; +void rv_func_end(CGTarget* t) { + RImpl* a = impl_of(t); + MCEmitter* mc = t->mc; + ObjBuilder* obj = t->obj; u32 sec = a->fd->text_section_id; u32 int_regs[10]; @@ -601,10 +592,9 @@ void rv_func_end(CGTarget *t) { if (!a->known_frame) { u32 pos = a->prologue_pos; u32 words[RV_PROLOGUE_WORDS]; - u32 prologue_words = a->prologue_words ? a->prologue_words - : RV_PROLOGUE_WORDS; - for (u32 i = 0; i < prologue_words; ++i) - words[i] = RV_NOP; + u32 prologue_words = + a->prologue_words ? a->prologue_words : RV_PROLOGUE_WORDS; + for (u32 i = 0; i < prologue_words; ++i) words[i] = RV_NOP; (void)rv_build_prologue(t, words, prologue_words, &fl, int_regs, n_int_saves, fp_regs, n_fp_saves, a->next_param_int); @@ -624,8 +614,7 @@ void rv_func_end(CGTarget *t) { rv64_patch32(obj, sec, a->add_patches[i].pos, word); } -finish: - ; +finish:; /* Define the function symbol. */ u32 end = mc->pos(mc); obj_symbol_define(obj, a->fd->sym, sec, (u64)a->func_start, @@ -634,8 +623,7 @@ finish: obj_atom_define(obj, sec, a->func_start, end - a->func_start, a->fd->sym, 0); } - if (t->debug) - debug_func_pc_range(t->debug, sec, a->func_start, end); + if (t->debug) debug_func_pc_range(t->debug, sec, a->func_start, end); mc->cfi_endproc(mc); mc_end_function(mc); diff --git a/src/arch/rv64/emu.c b/src/arch/rv64/emu.c @@ -134,8 +134,7 @@ static void rv64_emu_lift_syms_init(CfreeCompiler* c, CfreeCg* cg, out->load64 = rv64_emu_decl_helper(c, cg, EMU_SYM_LOAD64, out->load64_fn); out->load64_checked = rv64_emu_decl_helper(c, cg, EMU_SYM_LOAD64_CHECKED, out->load64_checked_fn); - out->store64 = - rv64_emu_decl_helper(c, cg, EMU_SYM_STORE64, out->store64_fn); + out->store64 = rv64_emu_decl_helper(c, cg, EMU_SYM_STORE64, out->store64_fn); out->jalr = rv64_emu_decl_helper(c, cg, RV64_EMU_SYM_JALR, out->jalr_fn); out->syscall = rv64_emu_decl_helper(c, cg, EMU_SYM_SYSCALL, out->syscall_fn); } @@ -275,8 +274,7 @@ static CfreeStatus rv64_emu_lift_block(Compiler* compiler, CfreeCg* cg, cfree_cg_push_int(cg, in->pc, syms.i64); cfree_cg_push_int(cg, next_pc, syms.i64); cfree_cg_push_local_addr(cg, tmp); - cfree_cg_call_symbol(cg, syms.load64_checked, 5, - (CfreeCgCallAttrs){0}); + cfree_cg_call_symbol(cg, syms.load64_checked, 5, (CfreeCgCallAttrs){0}); rv64_emu_store_local_from_stack(cg, &syms, fault_next); rv64_emu_push_local_value(cg, &syms, fault_next); cfree_cg_push_int(cg, 0, syms.i64); @@ -338,9 +336,9 @@ static CfreeStatus rv64_emu_lift_block(Compiler* compiler, CfreeCg* cg, static EmuCPUState* rv64_emu_cpu_new(Compiler* c, u64 initial_pc, u64 initial_sp) { - EmuCPUState* cpu = emu_cpu_new_with_arch_state( - c, CFREE_ARCH_RV64, initial_pc, sizeof(Rv64EmuCPUState), - _Alignof(Rv64EmuCPUState)); + EmuCPUState* cpu = emu_cpu_new_with_arch_state(c, CFREE_ARCH_RV64, initial_pc, + sizeof(Rv64EmuCPUState), + _Alignof(Rv64EmuCPUState)); Rv64EmuCPUState* rv = (Rv64EmuCPUState*)emu_cpu_arch_state(cpu); if (rv) rv->x[2] = initial_sp; return cpu; @@ -394,9 +392,9 @@ static void rv64_signal_wr64(u8* p, u64 v) { } static u64 rv64_signal_rd64(const u8* p) { - return (u64)p[0] | ((u64)p[1] << 8) | ((u64)p[2] << 16) | - ((u64)p[3] << 24) | ((u64)p[4] << 32) | ((u64)p[5] << 40) | - ((u64)p[6] << 48) | ((u64)p[7] << 56); + return (u64)p[0] | ((u64)p[1] << 8) | ((u64)p[2] << 16) | ((u64)p[3] << 24) | + ((u64)p[4] << 32) | ((u64)p[5] << 40) | ((u64)p[6] << 48) | + ((u64)p[7] << 56); } static u64 rv64_signal_context_size(EmuProcess* process, EmuThread* thread) { @@ -417,8 +415,8 @@ static CfreeStatus rv64_save_signal_context(EmuProcess* process, } static CfreeStatus rv64_restore_signal_context(EmuProcess* process, - EmuThread* thread, - const u8* src, u64 size) { + EmuThread* thread, const u8* src, + u64 size) { u32 i; (void)process; if (!thread || !src || size < 32u * 8u) return CFREE_INVALID; @@ -482,12 +480,10 @@ u64 emu_rv64_jalr(EmuThread* thread, u64 rd, u64 rs1, u64 imm, u64 next_pc) { static void* rv64_resolve_runtime_helper(void* emu, CfreeSlice name) { (void)emu; - if (cfree_slice_eq_cstr(name, RV64_EMU_SYM_XREG)) - return (void*)emu_rv64_xreg; + if (cfree_slice_eq_cstr(name, RV64_EMU_SYM_XREG)) return (void*)emu_rv64_xreg; if (cfree_slice_eq_cstr(name, RV64_EMU_SYM_SET_XREG)) return (void*)emu_rv64_set_xreg; - if (cfree_slice_eq_cstr(name, RV64_EMU_SYM_JALR)) - return (void*)emu_rv64_jalr; + if (cfree_slice_eq_cstr(name, RV64_EMU_SYM_JALR)) return (void*)emu_rv64_jalr; return NULL; } diff --git a/src/arch/rv64/internal.h b/src/arch/rv64/internal.h @@ -12,7 +12,8 @@ #include "obj/obj.h" #define RV_PROLOGUE_WORDS 128u -#define RV_PROLOGUE_FRAME_WORDS 10u /* sp adjust + far/near s0/ra save + set s0 */ +#define RV_PROLOGUE_FRAME_WORDS \ + 10u /* sp adjust + far/near s0/ra save + set s0 */ /* ---- RvSlot / RvScope ---- */ typedef struct RvSlot { @@ -37,7 +38,7 @@ typedef struct RvScope { typedef struct RImpl { CGTarget base; SrcLoc loc; - const CGFuncDesc *fd; + const CGFuncDesc* fd; u32 func_start; u32 prologue_pos; @@ -45,7 +46,7 @@ typedef struct RImpl { u32 post_prologue_off; /* end-of-prologue offset within function, for CFI */ MCLabel epilogue_label; - RvSlot *slots; + RvSlot* slots; u32 nslots; u32 slots_cap; u32 cum_off; @@ -68,7 +69,7 @@ typedef struct RImpl { u8 has_planned_regs; u8 pad1[3]; - RvScope *scopes; + RvScope* scopes; u32 nscopes; u32 scopes_cap; @@ -76,7 +77,7 @@ typedef struct RImpl { struct RvAllocaPatch { u32 pos; u32 dst_reg; - } *add_patches; + }* add_patches; u32 nadd_patches; u32 add_patches_cap; @@ -85,7 +86,7 @@ typedef struct RImpl { } RImpl; /* ---- impl_of ---- */ -static inline RImpl *impl_of(CGTarget *t) { return (RImpl *)t; } +static inline RImpl* impl_of(CGTarget* t) { return (RImpl*)t; } /* ---- type helpers ---- */ #define CG_BUILTIN_ID(k) ((CfreeCgTypeId)((1u << 6) | (u32)(k))) @@ -101,13 +102,11 @@ static inline u32 type_byte_size(CfreeCgTypeId t) { if (t == CG_BUILTIN_ID(CFREE_CG_BUILTIN_I8) || t == CG_BUILTIN_ID(CFREE_CG_BUILTIN_BOOL)) return 1; - if (t == CG_BUILTIN_ID(CFREE_CG_BUILTIN_I16)) - return 2; + if (t == CG_BUILTIN_ID(CFREE_CG_BUILTIN_I16)) return 2; if (t == CG_BUILTIN_ID(CFREE_CG_BUILTIN_I32) || t == CG_BUILTIN_ID(CFREE_CG_BUILTIN_F32)) return 4; - if (t == CG_BUILTIN_ID(CFREE_CG_BUILTIN_F128)) - return 16; + if (t == CG_BUILTIN_ID(CFREE_CG_BUILTIN_F128)) return 16; return 8; } static inline int type_is_signed(CfreeCgTypeId t) { @@ -118,52 +117,52 @@ static inline int type_is_signed(CfreeCgTypeId t) { static inline u32 reg_num(Operand op) { return op.v.reg & 0x1fu; } /* ---- emit.c: function lifecycle (referenced by ops.c vtable) ---- */ -void rv_func_begin(CGTarget *t, const CGFuncDesc *fd); -void rv_func_begin_known_frame(CGTarget *t, const CGFuncDesc *fd, - const CGKnownFrameDesc *frame, - FrameSlot *out_slots); -void rv_func_end(CGTarget *t); +void rv_func_begin(CGTarget* t, const CGFuncDesc* fd); +void rv_func_begin_known_frame(CGTarget* t, const CGFuncDesc* fd, + const CGKnownFrameDesc* frame, + FrameSlot* out_slots); +void rv_func_end(CGTarget* t); -void rv_coord_vtable_init(CGTarget *t); +void rv_coord_vtable_init(CGTarget* t); /* ---- emit helpers (defined in emit.c, used cross-file) ---- */ -extern void debug_emit_row(Debug *, ObjSecId text_section, u32 offset, SrcLoc); -extern void debug_func_pc_range(Debug *, ObjSecId text_section, u32 begin_ofs, +extern void debug_emit_row(Debug*, ObjSecId text_section, u32 offset, SrcLoc); +extern void debug_func_pc_range(Debug*, ObjSecId text_section, u32 begin_ofs, u32 end_ofs); -void rv64_emit32(MCEmitter *mc, u32 word); -void rv64_emit16(MCEmitter *mc, u32 halfword); -void rv64_patch32(ObjBuilder *obj, u32 sec_id, u32 ofs, u32 word); +void rv64_emit32(MCEmitter* mc, u32 word); +void rv64_emit16(MCEmitter* mc, u32 halfword); +void rv64_patch32(ObjBuilder* obj, u32 sec_id, u32 ofs, u32 word); int fits_signed32(i64 v); -void emit_li_32(MCEmitter *mc, u32 rd, i32 imm); -void rv64_emit_load_imm(MCEmitter *mc, u32 sf, u32 rd, i64 imm); -void emit_sp_addi(MCEmitter *mc, i64 imm); -_Noreturn void rv_panic(CGTarget *t, const char *what); +void emit_li_32(MCEmitter* mc, u32 rd, i32 imm); +void rv64_emit_load_imm(MCEmitter* mc, u32 sf, u32 rd, i64 imm); +void emit_sp_addi(MCEmitter* mc, i64 imm); +_Noreturn void rv_panic(CGTarget* t, const char* what); /* ---- alloc.c: all functions (non-static; referenced by ops.c vtable) ---- */ -FrameSlot rv_frame_slot(CGTarget *t, const FrameSlotDesc *d); -RvSlot *rv64_slot_get(RImpl *a, FrameSlot fs); -CGLocalStorage rv_param(CGTarget *t, const CGParamDesc *p); -void rv_spill_reg(CGTarget *t, Operand src, FrameSlot slot, MemAccess ma); -void rv_reload_reg(CGTarget *t, Operand dst, FrameSlot slot, MemAccess ma); -Label rv_label_new(CGTarget *t); -void rv_label_place(CGTarget *t, Label l); -void rv_jump(CGTarget *t, Label l); -void rv_load_label_addr(CGTarget *t, Operand dst, Label l); -void rv_indirect_branch(CGTarget *t, Operand addr, const Label *targets, +FrameSlot rv_frame_slot(CGTarget* t, const FrameSlotDesc* d); +RvSlot* rv64_slot_get(RImpl* a, FrameSlot fs); +CGLocalStorage rv_param(CGTarget* t, const CGParamDesc* p); +void rv_spill_reg(CGTarget* t, Operand src, FrameSlot slot, MemAccess ma); +void rv_reload_reg(CGTarget* t, Operand dst, FrameSlot slot, MemAccess ma); +Label rv_label_new(CGTarget* t); +void rv_label_place(CGTarget* t, Label l); +void rv_jump(CGTarget* t, Label l); +void rv_load_label_addr(CGTarget* t, Operand dst, Label l); +void rv_indirect_branch(CGTarget* t, Operand addr, const Label* targets, u32 ntargets); -u32 rv64_force_reg_int(CGTarget *t, Operand op, u32 scratch); -void rv_cmp_branch(CGTarget *t, CmpOp op, Operand a_op, Operand b_op, Label l); -void rv_cmp(CGTarget *t, CmpOp op, Operand dst, Operand a_op, Operand b_op); -CGScope rv_scope_begin(CGTarget *t, const CGScopeDesc *d); -void rv_scope_else(CGTarget *t, CGScope s); -void rv_scope_end(CGTarget *t, CGScope s); -void rv_break_to(CGTarget *t, CGScope s); -void rv_continue_to(CGTarget *t, CGScope s); +u32 rv64_force_reg_int(CGTarget* t, Operand op, u32 scratch); +void rv_cmp_branch(CGTarget* t, CmpOp op, Operand a_op, Operand b_op, Label l); +void rv_cmp(CGTarget* t, CmpOp op, Operand dst, Operand a_op, Operand b_op); +CGScope rv_scope_begin(CGTarget* t, const CGScopeDesc* d); +void rv_scope_else(CGTarget* t, CGScope s); +void rv_scope_end(CGTarget* t, CGScope s); +void rv_break_to(CGTarget* t, CGScope s); +void rv_continue_to(CGTarget* t, CGScope s); /* ---- ops.c: functions used cross-file ---- */ -void rv_load(CGTarget *t, Operand dst, Operand addr, MemAccess ma); -void rv_store(CGTarget *t, Operand addr, Operand src, MemAccess ma); +void rv_load(CGTarget* t, Operand dst, Operand addr, MemAccess ma); +void rv_store(CGTarget* t, Operand addr, Operand src, MemAccess ma); u32 enc_int_store(u32 nbytes, u32 src, u32 base, i32 off); u32 enc_int_load(u32 nbytes, int sign_ext, u32 rd, u32 base, i32 off); @@ -176,15 +175,15 @@ u32 enc_int_load(u32 nbytes, int sign_ext, u32 rd, u32 base, i32 off); typedef struct RvAddrMode { u32 base; u32 index; - u8 log2_scale; + u8 log2_scale; i32 ofs; } RvAddrMode; -RvAddrMode addr_mode(CGTarget *t, Operand addr, u32 tmp_reg); -void rv64_emit_addr_adjust(MCEmitter *mc, u32 rd, u32 base, i32 off); -ObjSymId emit_pcrel_anchor(CGTarget *t, u32 sec, u32 auipc_pos); -void rv64_emit_got_load_addr(CGTarget *t, u32 dst_reg, ObjSymId sym); -u32 agg_addr_reg(CGTarget *t, Operand op, u32 scratch); -int rv64_use_got_for_sym(CGTarget *t, ObjSymId sym); +RvAddrMode addr_mode(CGTarget* t, Operand addr, u32 tmp_reg); +void rv64_emit_addr_adjust(MCEmitter* mc, u32 rd, u32 base, i32 off); +ObjSymId emit_pcrel_anchor(CGTarget* t, u32 sec, u32 auipc_pos); +void rv64_emit_got_load_addr(CGTarget* t, u32 dst_reg, ObjSymId sym); +u32 agg_addr_reg(CGTarget* t, Operand op, u32 scratch); +int rv64_use_got_for_sym(CGTarget* t, ObjSymId sym); int mem_order_is_acquire(MemOrder o); int mem_order_is_release(MemOrder o); diff --git a/src/arch/rv64/isa.c b/src/arch/rv64/isa.c @@ -17,7 +17,8 @@ #include "core/slice.h" #include "core/strbuf.h" -/* True if `s` begins with the NUL-terminated literal `pfx` (length-explicit). */ +/* True if `s` begins with the NUL-terminated literal `pfx` (length-explicit). + */ static bool slice_has_prefix_cstr(Slice s, const char* pfx, size_t n) { return s.len >= n && memcmp(s.s, pfx, n) == 0; } @@ -29,8 +30,7 @@ static bool slice_has_prefix_cstr(Slice s, const char* pfx, size_t n) { /* Helper: build a 32-bit match for R-type with fixed funct7/funct3/op. */ #define MATCH_R(funct7, funct3, op) \ (((u32)(funct7) << 25) | ((u32)(funct3) << 12) | (u32)(op)) -#define MASK_R \ - (0xfe00707fu) /* funct7 + funct3 + opcode */ +#define MASK_R (0xfe00707fu) /* funct7 + funct3 + opcode */ #define MATCH_I(funct3, op) (((u32)(funct3) << 12) | (u32)(op)) #define MASK_I (0x0000707fu) /* funct3 + opcode */ @@ -67,7 +67,7 @@ static bool slice_has_prefix_cstr(Slice s, const char* pfx, size_t n) { #define MATCH_AMO(funct5, funct3, op) \ (((u32)(funct5) << 27) | ((u32)(funct3) << 12) | (u32)(op)) #define MASK_AMO (0xf800707fu) -#define MATCH_AMO_ORDER(funct5, aq, rl, funct3, op) \ +#define MATCH_AMO_ORDER(funct5, aq, rl, funct3, op) \ (((u32)(funct5) << 27) | ((u32)(aq) << 26) | ((u32)(rl) << 25) | \ ((u32)(funct3) << 12) | (u32)(op)) #define MASK_AMO_ORDER (MASK_AMO | (3u << 25)) @@ -107,16 +107,16 @@ const Rv64InsnDesc rv64_insn_table[] = { /* ================================================================= * RV64I base — integer register ops (R-type, OP=0x33) * ================================================================= */ - {MN("add"), MATCH_R(0x00, 0x0, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, - {MN("sub"), MATCH_R(0x20, 0x0, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, - {MN("sll"), MATCH_R(0x00, 0x1, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, - {MN("slt"), MATCH_R(0x00, 0x2, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, + {MN("add"), MATCH_R(0x00, 0x0, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, + {MN("sub"), MATCH_R(0x20, 0x0, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, + {MN("sll"), MATCH_R(0x00, 0x1, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, + {MN("slt"), MATCH_R(0x00, 0x2, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, {MN("sltu"), MATCH_R(0x00, 0x3, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, - {MN("xor"), MATCH_R(0x00, 0x4, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, - {MN("srl"), MATCH_R(0x00, 0x5, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, - {MN("sra"), MATCH_R(0x20, 0x5, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, - {MN("or"), MATCH_R(0x00, 0x6, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, - {MN("and"), MATCH_R(0x00, 0x7, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, + {MN("xor"), MATCH_R(0x00, 0x4, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, + {MN("srl"), MATCH_R(0x00, 0x5, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, + {MN("sra"), MATCH_R(0x20, 0x5, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, + {MN("or"), MATCH_R(0x00, 0x6, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, + {MN("and"), MATCH_R(0x00, 0x7, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, /* 32-bit (W) variants — OP_32 = 0x3b */ {MN("addw"), MATCH_R(0x00, 0x0, RV_OP_32), MASK_R, RV64_FMT_R, 0, {0, 0}}, @@ -129,56 +129,103 @@ const Rv64InsnDesc rv64_insn_table[] = { * Aliases: `li rd, imm` = ADDI rd, x0, imm (rs1=x0). * `mv rd, rs1` = ADDI rd, rs1, 0 (imm=0). * `nop` = ADDI x0, x0, 0 (full word fixed). */ - {MN("nop"), 0x00000013u, 0xffffffffu, RV64_FMT_SYSTEM, RV64_ASMFL_ALIAS, + {MN("nop"), + 0x00000013u, + 0xffffffffu, + RV64_FMT_SYSTEM, + RV64_ASMFL_ALIAS, {0, 0}}, {MN("li"), 0x00000013u, 0x000f807fu, RV64_FMT_I, RV64_ASMFL_ALIAS, {0, 0}}, /* mv: ADDI with imm=0. mask requires imm12=0 + funct3=0 + op. */ {MN("mv"), 0x00000013u, 0xfff0707fu, RV64_FMT_I, RV64_ASMFL_ALIAS, {0, 0}}, /* seqz: SLTIU rd, rs, 1 — funct3=3, imm12=1, op=OP_IMM. */ - {MN("seqz"), 0x00103013u, 0xfff0707fu, RV64_FMT_I, RV64_ASMFL_ALIAS, {0, 0}}, + {MN("seqz"), + 0x00103013u, + 0xfff0707fu, + RV64_FMT_I, + RV64_ASMFL_ALIAS, + {0, 0}}, /* snez: SLTU rd, x0, rs2 — rs1=x0, funct3=3, op=OP. */ - {MN("snez"), 0x00003033u, 0xfe0ff07fu, RV64_FMT_R, RV64_ASMFL_ALIAS, {0, 0}}, + {MN("snez"), + 0x00003033u, + 0xfe0ff07fu, + RV64_FMT_R, + RV64_ASMFL_ALIAS, + {0, 0}}, /* not: XORI rd, rs, -1 — imm12=0xfff, funct3=4, op=OP_IMM. */ {MN("not"), 0xfff04013u, 0xfff0707fu, RV64_FMT_I, RV64_ASMFL_ALIAS, {0, 0}}, /* neg: SUB rd, x0, rs2 — rs1=x0, funct7=0x20, funct3=0. */ {MN("neg"), 0x40000033u, 0xfe0ff07fu, RV64_FMT_R, RV64_ASMFL_ALIAS, {0, 0}}, /* negw: SUBW rd, x0, rs2. */ - {MN("negw"), 0x4000003bu, 0xfe0ff07fu, RV64_FMT_R, RV64_ASMFL_ALIAS, {0, 0}}, - {MN("addi"), MATCH_I(0x0, RV_OP_IMM), MASK_I, RV64_FMT_I, 0, {0, 0}}, - {MN("slti"), MATCH_I(0x2, RV_OP_IMM), MASK_I, RV64_FMT_I, 0, {0, 0}}, + {MN("negw"), + 0x4000003bu, + 0xfe0ff07fu, + RV64_FMT_R, + RV64_ASMFL_ALIAS, + {0, 0}}, + {MN("addi"), MATCH_I(0x0, RV_OP_IMM), MASK_I, RV64_FMT_I, 0, {0, 0}}, + {MN("slti"), MATCH_I(0x2, RV_OP_IMM), MASK_I, RV64_FMT_I, 0, {0, 0}}, {MN("sltiu"), MATCH_I(0x3, RV_OP_IMM), MASK_I, RV64_FMT_I, 0, {0, 0}}, - {MN("xori"), MATCH_I(0x4, RV_OP_IMM), MASK_I, RV64_FMT_I, 0, {0, 0}}, - {MN("ori"), MATCH_I(0x6, RV_OP_IMM), MASK_I, RV64_FMT_I, 0, {0, 0}}, - {MN("andi"), MATCH_I(0x7, RV_OP_IMM), MASK_I, RV64_FMT_I, 0, {0, 0}}, + {MN("xori"), MATCH_I(0x4, RV_OP_IMM), MASK_I, RV64_FMT_I, 0, {0, 0}}, + {MN("ori"), MATCH_I(0x6, RV_OP_IMM), MASK_I, RV64_FMT_I, 0, {0, 0}}, + {MN("andi"), MATCH_I(0x7, RV_OP_IMM), MASK_I, RV64_FMT_I, 0, {0, 0}}, /* RV64I shift-imm: funct6 in bits 31:26, shamt in 25:20. */ - {MN("slli"), MATCH_ISHIFT(0x00, 0x1, RV_OP_IMM), MASK_ISHIFT, - RV64_FMT_I_SHIFT, 0, {0, 0}}, - {MN("srli"), MATCH_ISHIFT(0x00, 0x5, RV_OP_IMM), MASK_ISHIFT, - RV64_FMT_I_SHIFT, 0, {0, 0}}, - {MN("srai"), MATCH_ISHIFT(0x10, 0x5, RV_OP_IMM), MASK_ISHIFT, - RV64_FMT_I_SHIFT, 0, {0, 0}}, + {MN("slli"), + MATCH_ISHIFT(0x00, 0x1, RV_OP_IMM), + MASK_ISHIFT, + RV64_FMT_I_SHIFT, + 0, + {0, 0}}, + {MN("srli"), + MATCH_ISHIFT(0x00, 0x5, RV_OP_IMM), + MASK_ISHIFT, + RV64_FMT_I_SHIFT, + 0, + {0, 0}}, + {MN("srai"), + MATCH_ISHIFT(0x10, 0x5, RV_OP_IMM), + MASK_ISHIFT, + RV64_FMT_I_SHIFT, + 0, + {0, 0}}, /* OP_IMM_32: ADDIW + word shifts. sext.w alias = ADDIW rd, rs, 0. */ - {MN("sext.w"), 0x0000001bu, 0xfff0707fu, RV64_FMT_I, RV64_ASMFL_ALIAS, + {MN("sext.w"), + 0x0000001bu, + 0xfff0707fu, + RV64_FMT_I, + RV64_ASMFL_ALIAS, {0, 0}}, {MN("addiw"), MATCH_I(0x0, RV_OP_IMM_32), MASK_I, RV64_FMT_I, 0, {0, 0}}, - {MN("slliw"), MATCH_ISHIFTW(0x00, 0x1, RV_OP_IMM_32), MASK_ISHIFTW, - RV64_FMT_I_SHIFTW, 0, {0, 0}}, - {MN("srliw"), MATCH_ISHIFTW(0x00, 0x5, RV_OP_IMM_32), MASK_ISHIFTW, - RV64_FMT_I_SHIFTW, 0, {0, 0}}, - {MN("sraiw"), MATCH_ISHIFTW(0x20, 0x5, RV_OP_IMM_32), MASK_ISHIFTW, - RV64_FMT_I_SHIFTW, 0, {0, 0}}, + {MN("slliw"), + MATCH_ISHIFTW(0x00, 0x1, RV_OP_IMM_32), + MASK_ISHIFTW, + RV64_FMT_I_SHIFTW, + 0, + {0, 0}}, + {MN("srliw"), + MATCH_ISHIFTW(0x00, 0x5, RV_OP_IMM_32), + MASK_ISHIFTW, + RV64_FMT_I_SHIFTW, + 0, + {0, 0}}, + {MN("sraiw"), + MATCH_ISHIFTW(0x20, 0x5, RV_OP_IMM_32), + MASK_ISHIFTW, + RV64_FMT_I_SHIFTW, + 0, + {0, 0}}, /* ---- LUI / AUIPC ---- */ - {MN("lui"), MATCH_U(RV_LUI), MASK_U, RV64_FMT_U, 0, {0, 0}}, + {MN("lui"), MATCH_U(RV_LUI), MASK_U, RV64_FMT_U, 0, {0, 0}}, {MN("auipc"), MATCH_U(RV_AUIPC), MASK_U, RV64_FMT_U, 0, {0, 0}}, /* ---- Loads (I-type, op=LOAD=0x03) ---- */ - {MN("lb"), MATCH_I(0x0, RV_LOAD), MASK_I, RV64_FMT_LOAD, 0, {0, 0}}, - {MN("lh"), MATCH_I(0x1, RV_LOAD), MASK_I, RV64_FMT_LOAD, 0, {0, 0}}, - {MN("lw"), MATCH_I(0x2, RV_LOAD), MASK_I, RV64_FMT_LOAD, 0, {0, 0}}, - {MN("ld"), MATCH_I(0x3, RV_LOAD), MASK_I, RV64_FMT_LOAD, 0, {0, 0}}, + {MN("lb"), MATCH_I(0x0, RV_LOAD), MASK_I, RV64_FMT_LOAD, 0, {0, 0}}, + {MN("lh"), MATCH_I(0x1, RV_LOAD), MASK_I, RV64_FMT_LOAD, 0, {0, 0}}, + {MN("lw"), MATCH_I(0x2, RV_LOAD), MASK_I, RV64_FMT_LOAD, 0, {0, 0}}, + {MN("ld"), MATCH_I(0x3, RV_LOAD), MASK_I, RV64_FMT_LOAD, 0, {0, 0}}, {MN("lbu"), MATCH_I(0x4, RV_LOAD), MASK_I, RV64_FMT_LOAD, 0, {0, 0}}, {MN("lhu"), MATCH_I(0x5, RV_LOAD), MASK_I, RV64_FMT_LOAD, 0, {0, 0}}, {MN("lwu"), MATCH_I(0x6, RV_LOAD), MASK_I, RV64_FMT_LOAD, 0, {0, 0}}, @@ -191,12 +238,22 @@ const Rv64InsnDesc rv64_insn_table[] = { /* ---- Branches (B-type, op=BRANCH=0x63) ---- * Aliases: `beqz rs, off` = BEQ rs, x0, off; `bnez rs, off` = BNE. */ - {MN("beqz"), 0x00000063u, 0x01f0707fu, RV64_FMT_B, RV64_ASMFL_ALIAS, {0, 0}}, - {MN("bnez"), 0x00001063u, 0x01f0707fu, RV64_FMT_B, RV64_ASMFL_ALIAS, {0, 0}}, - {MN("beq"), MATCH_B(0x0, RV_BRANCH), MASK_B, RV64_FMT_B, 0, {0, 0}}, - {MN("bne"), MATCH_B(0x1, RV_BRANCH), MASK_B, RV64_FMT_B, 0, {0, 0}}, - {MN("blt"), MATCH_B(0x4, RV_BRANCH), MASK_B, RV64_FMT_B, 0, {0, 0}}, - {MN("bge"), MATCH_B(0x5, RV_BRANCH), MASK_B, RV64_FMT_B, 0, {0, 0}}, + {MN("beqz"), + 0x00000063u, + 0x01f0707fu, + RV64_FMT_B, + RV64_ASMFL_ALIAS, + {0, 0}}, + {MN("bnez"), + 0x00001063u, + 0x01f0707fu, + RV64_FMT_B, + RV64_ASMFL_ALIAS, + {0, 0}}, + {MN("beq"), MATCH_B(0x0, RV_BRANCH), MASK_B, RV64_FMT_B, 0, {0, 0}}, + {MN("bne"), MATCH_B(0x1, RV_BRANCH), MASK_B, RV64_FMT_B, 0, {0, 0}}, + {MN("blt"), MATCH_B(0x4, RV_BRANCH), MASK_B, RV64_FMT_B, 0, {0, 0}}, + {MN("bge"), MATCH_B(0x5, RV_BRANCH), MASK_B, RV64_FMT_B, 0, {0, 0}}, {MN("bltu"), MATCH_B(0x6, RV_BRANCH), MASK_B, RV64_FMT_B, 0, {0, 0}}, {MN("bgeu"), MATCH_B(0x7, RV_BRANCH), MASK_B, RV64_FMT_B, 0, {0, 0}}, @@ -206,31 +263,51 @@ const Rv64InsnDesc rv64_insn_table[] = { * `ret` = JALR x0, 0(ra) (rd=x0 + rs1=ra + imm=0). * `jr rs` = JALR x0, 0(rs) (rd=x0, imm=0). * `jalr rs` = JALR ra, 0(rs) (rd=ra, imm=0). */ - {MN("ret"), 0x00008067u, 0xffffffffu, RV64_FMT_SYSTEM, RV64_ASMFL_ALIAS, + {MN("ret"), + 0x00008067u, + 0xffffffffu, + RV64_FMT_SYSTEM, + RV64_ASMFL_ALIAS, {0, 0}}, - {MN("jr"), 0x00000067u, 0xfff07fffu, RV64_FMT_JALR, RV64_ASMFL_ALIAS, + {MN("jr"), + 0x00000067u, + 0xfff07fffu, + RV64_FMT_JALR, + RV64_ASMFL_ALIAS, {0, 0}}, - {MN("j"), 0x0000006fu, 0x00000fffu, RV64_FMT_J, RV64_ASMFL_ALIAS, {0, 0}}, - {MN("jal"), MATCH_J(RV_JAL), MASK_J, RV64_FMT_J, 0, {0, 0}}, + {MN("j"), 0x0000006fu, 0x00000fffu, RV64_FMT_J, RV64_ASMFL_ALIAS, {0, 0}}, + {MN("jal"), MATCH_J(RV_JAL), MASK_J, RV64_FMT_J, 0, {0, 0}}, {MN("jalr"), MATCH_I(0x0, RV_JALR), MASK_I, RV64_FMT_JALR, 0, {0, 0}}, /* ---- FENCE ---- */ {MN("fence"), MATCH_I(0x0, RV_FENCE), MASK_I, RV64_FMT_FENCE, 0, {0, 0}}, - {MN("fence.i"), MATCH_FULL(0x0000100fu), MASK_FULL, RV64_FMT_SYSTEM, 0, + {MN("fence.i"), + MATCH_FULL(0x0000100fu), + MASK_FULL, + RV64_FMT_SYSTEM, + 0, {0, 0}}, /* ---- System (ECALL/EBREAK) ---- */ - {MN("ecall"), MATCH_FULL(0x00000073u), MASK_FULL, RV64_FMT_SYSTEM, 0, + {MN("ecall"), + MATCH_FULL(0x00000073u), + MASK_FULL, + RV64_FMT_SYSTEM, + 0, {0, 0}}, - {MN("ebreak"), MATCH_FULL(0x00100073u), MASK_FULL, RV64_FMT_SYSTEM, 0, + {MN("ebreak"), + MATCH_FULL(0x00100073u), + MASK_FULL, + RV64_FMT_SYSTEM, + 0, {0, 0}}, /* ================================================================= * Zicsr (CSR access) — RV_SYSTEM with funct3 ∈ {1..3, 5..7}. * ================================================================= */ - {MN("csrrw"), MATCH_CSR(0x1), MASK_CSR, RV64_FMT_CSR, 0, {0, 0}}, - {MN("csrrs"), MATCH_CSR(0x2), MASK_CSR, RV64_FMT_CSR, 0, {0, 0}}, - {MN("csrrc"), MATCH_CSR(0x3), MASK_CSR, RV64_FMT_CSR, 0, {0, 0}}, + {MN("csrrw"), MATCH_CSR(0x1), MASK_CSR, RV64_FMT_CSR, 0, {0, 0}}, + {MN("csrrs"), MATCH_CSR(0x2), MASK_CSR, RV64_FMT_CSR, 0, {0, 0}}, + {MN("csrrc"), MATCH_CSR(0x3), MASK_CSR, RV64_FMT_CSR, 0, {0, 0}}, {MN("csrrwi"), MATCH_CSR(0x5), MASK_CSR, RV64_FMT_CSRI, 0, {0, 0}}, {MN("csrrsi"), MATCH_CSR(0x6), MASK_CSR, RV64_FMT_CSRI, 0, {0, 0}}, {MN("csrrci"), MATCH_CSR(0x7), MASK_CSR, RV64_FMT_CSRI, 0, {0, 0}}, @@ -238,169 +315,417 @@ const Rv64InsnDesc rv64_insn_table[] = { /* ================================================================= * RV64M (multiply / divide) — funct7 = 0x01 * ================================================================= */ - {MN("mul"), MATCH_R(0x01, 0x0, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, - {MN("mulh"), MATCH_R(0x01, 0x1, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, + {MN("mul"), MATCH_R(0x01, 0x0, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, + {MN("mulh"), MATCH_R(0x01, 0x1, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, {MN("mulhsu"), MATCH_R(0x01, 0x2, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, - {MN("mulhu"), MATCH_R(0x01, 0x3, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, - {MN("div"), MATCH_R(0x01, 0x4, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, - {MN("divu"), MATCH_R(0x01, 0x5, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, - {MN("rem"), MATCH_R(0x01, 0x6, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, - {MN("remu"), MATCH_R(0x01, 0x7, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, - {MN("mulw"), MATCH_R(0x01, 0x0, RV_OP_32), MASK_R, RV64_FMT_R, 0, {0, 0}}, - {MN("divw"), MATCH_R(0x01, 0x4, RV_OP_32), MASK_R, RV64_FMT_R, 0, {0, 0}}, - {MN("divuw"), MATCH_R(0x01, 0x5, RV_OP_32), MASK_R, RV64_FMT_R, 0, {0, 0}}, - {MN("remw"), MATCH_R(0x01, 0x6, RV_OP_32), MASK_R, RV64_FMT_R, 0, {0, 0}}, - {MN("remuw"), MATCH_R(0x01, 0x7, RV_OP_32), MASK_R, RV64_FMT_R, 0, {0, 0}}, + {MN("mulhu"), MATCH_R(0x01, 0x3, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, + {MN("div"), MATCH_R(0x01, 0x4, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, + {MN("divu"), MATCH_R(0x01, 0x5, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, + {MN("rem"), MATCH_R(0x01, 0x6, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, + {MN("remu"), MATCH_R(0x01, 0x7, RV_OP), MASK_R, RV64_FMT_R, 0, {0, 0}}, + {MN("mulw"), MATCH_R(0x01, 0x0, RV_OP_32), MASK_R, RV64_FMT_R, 0, {0, 0}}, + {MN("divw"), MATCH_R(0x01, 0x4, RV_OP_32), MASK_R, RV64_FMT_R, 0, {0, 0}}, + {MN("divuw"), MATCH_R(0x01, 0x5, RV_OP_32), MASK_R, RV64_FMT_R, 0, {0, 0}}, + {MN("remw"), MATCH_R(0x01, 0x6, RV_OP_32), MASK_R, RV64_FMT_R, 0, {0, 0}}, + {MN("remuw"), MATCH_R(0x01, 0x7, RV_OP_32), MASK_R, RV64_FMT_R, 0, {0, 0}}, /* ================================================================= * RV32F / RV32D — single and double precision FP * ================================================================= */ /* FP fused multiply-add/subtract — rm defaults to dyn in the assembler. */ - {MN("fmadd.s"), MATCH_R4(RV_FMT_S, RV_MADD), MASK_R4, RV64_FMT_R4, - RV64_ASMFL_FP, {0, 0}}, - {MN("fmsub.s"), MATCH_R4(RV_FMT_S, RV_MSUB), MASK_R4, RV64_FMT_R4, - RV64_ASMFL_FP, {0, 0}}, - {MN("fnmsub.s"), MATCH_R4(RV_FMT_S, RV_NMSUB), MASK_R4, RV64_FMT_R4, - RV64_ASMFL_FP, {0, 0}}, - {MN("fnmadd.s"), MATCH_R4(RV_FMT_S, RV_NMADD), MASK_R4, RV64_FMT_R4, - RV64_ASMFL_FP, {0, 0}}, - {MN("fmadd.d"), MATCH_R4(RV_FMT_D, RV_MADD), MASK_R4, RV64_FMT_R4, - RV64_ASMFL_FP, {0, 0}}, - {MN("fmsub.d"), MATCH_R4(RV_FMT_D, RV_MSUB), MASK_R4, RV64_FMT_R4, - RV64_ASMFL_FP, {0, 0}}, - {MN("fnmsub.d"), MATCH_R4(RV_FMT_D, RV_NMSUB), MASK_R4, RV64_FMT_R4, - RV64_ASMFL_FP, {0, 0}}, - {MN("fnmadd.d"), MATCH_R4(RV_FMT_D, RV_NMADD), MASK_R4, RV64_FMT_R4, - RV64_ASMFL_FP, {0, 0}}, + {MN("fmadd.s"), + MATCH_R4(RV_FMT_S, RV_MADD), + MASK_R4, + RV64_FMT_R4, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fmsub.s"), + MATCH_R4(RV_FMT_S, RV_MSUB), + MASK_R4, + RV64_FMT_R4, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fnmsub.s"), + MATCH_R4(RV_FMT_S, RV_NMSUB), + MASK_R4, + RV64_FMT_R4, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fnmadd.s"), + MATCH_R4(RV_FMT_S, RV_NMADD), + MASK_R4, + RV64_FMT_R4, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fmadd.d"), + MATCH_R4(RV_FMT_D, RV_MADD), + MASK_R4, + RV64_FMT_R4, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fmsub.d"), + MATCH_R4(RV_FMT_D, RV_MSUB), + MASK_R4, + RV64_FMT_R4, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fnmsub.d"), + MATCH_R4(RV_FMT_D, RV_NMSUB), + MASK_R4, + RV64_FMT_R4, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fnmadd.d"), + MATCH_R4(RV_FMT_D, RV_NMADD), + MASK_R4, + RV64_FMT_R4, + RV64_ASMFL_FP, + {0, 0}}, /* FP arithmetic — rm field (funct3) is the rounding mode and prints * as the DYN(=7) default suppressed. funct7 low bits select fmt. */ - {MN("fadd.s"), MATCH_FP_RM(0x00, RV_OP_FP), MASK_FP_RM, RV64_FMT_FP_RM, - RV64_ASMFL_FP, {0, 0}}, - {MN("fsub.s"), MATCH_FP_RM(0x04, RV_OP_FP), MASK_FP_RM, RV64_FMT_FP_RM, - RV64_ASMFL_FP, {0, 0}}, - {MN("fmul.s"), MATCH_FP_RM(0x08, RV_OP_FP), MASK_FP_RM, RV64_FMT_FP_RM, - RV64_ASMFL_FP, {0, 0}}, - {MN("fdiv.s"), MATCH_FP_RM(0x0c, RV_OP_FP), MASK_FP_RM, RV64_FMT_FP_RM, - RV64_ASMFL_FP, {0, 0}}, - {MN("fadd.d"), MATCH_FP_RM(0x01, RV_OP_FP), MASK_FP_RM, RV64_FMT_FP_RM, - RV64_ASMFL_FP, {0, 0}}, - {MN("fsub.d"), MATCH_FP_RM(0x05, RV_OP_FP), MASK_FP_RM, RV64_FMT_FP_RM, - RV64_ASMFL_FP, {0, 0}}, - {MN("fmul.d"), MATCH_FP_RM(0x09, RV_OP_FP), MASK_FP_RM, RV64_FMT_FP_RM, - RV64_ASMFL_FP, {0, 0}}, - {MN("fdiv.d"), MATCH_FP_RM(0x0d, RV_OP_FP), MASK_FP_RM, RV64_FMT_FP_RM, - RV64_ASMFL_FP, {0, 0}}, + {MN("fadd.s"), + MATCH_FP_RM(0x00, RV_OP_FP), + MASK_FP_RM, + RV64_FMT_FP_RM, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fsub.s"), + MATCH_FP_RM(0x04, RV_OP_FP), + MASK_FP_RM, + RV64_FMT_FP_RM, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fmul.s"), + MATCH_FP_RM(0x08, RV_OP_FP), + MASK_FP_RM, + RV64_FMT_FP_RM, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fdiv.s"), + MATCH_FP_RM(0x0c, RV_OP_FP), + MASK_FP_RM, + RV64_FMT_FP_RM, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fadd.d"), + MATCH_FP_RM(0x01, RV_OP_FP), + MASK_FP_RM, + RV64_FMT_FP_RM, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fsub.d"), + MATCH_FP_RM(0x05, RV_OP_FP), + MASK_FP_RM, + RV64_FMT_FP_RM, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fmul.d"), + MATCH_FP_RM(0x09, RV_OP_FP), + MASK_FP_RM, + RV64_FMT_FP_RM, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fdiv.d"), + MATCH_FP_RM(0x0d, RV_OP_FP), + MASK_FP_RM, + RV64_FMT_FP_RM, + RV64_ASMFL_FP, + {0, 0}}, /* FP sqrt — funct7 = 0x2c (S) / 0x2d (D), rs2 must be 0. */ - {MN("fsqrt.s"), MATCH_FP_CVT(0x2c, 0x0, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, RV64_ASMFL_FP, {0, 0}}, - {MN("fsqrt.d"), MATCH_FP_CVT(0x2d, 0x0, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, RV64_ASMFL_FP, {0, 0}}, + {MN("fsqrt.s"), + MATCH_FP_CVT(0x2c, 0x0, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fsqrt.d"), + MATCH_FP_CVT(0x2d, 0x0, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + RV64_ASMFL_FP, + {0, 0}}, /* FP min/max — funct7 = 0x14/0x15, funct3 = 0 (min) / 1 (max). */ - {MN("fmin.s"), MATCH_FP_R(0x14, 0x0, RV_OP_FP), MASK_FP_R, RV64_FMT_FP_R, - RV64_ASMFL_FP | RV64_ASMFL_NORM, {0, 0}}, - {MN("fmax.s"), MATCH_FP_R(0x14, 0x1, RV_OP_FP), MASK_FP_R, RV64_FMT_FP_R, - RV64_ASMFL_FP | RV64_ASMFL_NORM, {0, 0}}, - {MN("fmin.d"), MATCH_FP_R(0x15, 0x0, RV_OP_FP), MASK_FP_R, RV64_FMT_FP_R, - RV64_ASMFL_FP | RV64_ASMFL_NORM, {0, 0}}, - {MN("fmax.d"), MATCH_FP_R(0x15, 0x1, RV_OP_FP), MASK_FP_R, RV64_FMT_FP_R, - RV64_ASMFL_FP | RV64_ASMFL_NORM, {0, 0}}, + {MN("fmin.s"), + MATCH_FP_R(0x14, 0x0, RV_OP_FP), + MASK_FP_R, + RV64_FMT_FP_R, + RV64_ASMFL_FP | RV64_ASMFL_NORM, + {0, 0}}, + {MN("fmax.s"), + MATCH_FP_R(0x14, 0x1, RV_OP_FP), + MASK_FP_R, + RV64_FMT_FP_R, + RV64_ASMFL_FP | RV64_ASMFL_NORM, + {0, 0}}, + {MN("fmin.d"), + MATCH_FP_R(0x15, 0x0, RV_OP_FP), + MASK_FP_R, + RV64_FMT_FP_R, + RV64_ASMFL_FP | RV64_ASMFL_NORM, + {0, 0}}, + {MN("fmax.d"), + MATCH_FP_R(0x15, 0x1, RV_OP_FP), + MASK_FP_R, + RV64_FMT_FP_R, + RV64_ASMFL_FP | RV64_ASMFL_NORM, + {0, 0}}, /* FP sign-injection — funct7 = 0x10/0x11, funct3 = 0/1/2 = J/JN/JX. */ - {MN("fsgnj.s"), MATCH_FP_R(0x10, 0x0, RV_OP_FP), MASK_FP_R, RV64_FMT_FP_R, - RV64_ASMFL_FP | RV64_ASMFL_NORM, {0, 0}}, - {MN("fsgnjn.s"), MATCH_FP_R(0x10, 0x1, RV_OP_FP), MASK_FP_R, RV64_FMT_FP_R, - RV64_ASMFL_FP | RV64_ASMFL_NORM, {0, 0}}, - {MN("fsgnjx.s"), MATCH_FP_R(0x10, 0x2, RV_OP_FP), MASK_FP_R, RV64_FMT_FP_R, - RV64_ASMFL_FP | RV64_ASMFL_NORM, {0, 0}}, - {MN("fsgnj.d"), MATCH_FP_R(0x11, 0x0, RV_OP_FP), MASK_FP_R, RV64_FMT_FP_R, - RV64_ASMFL_FP | RV64_ASMFL_NORM, {0, 0}}, - {MN("fsgnjn.d"), MATCH_FP_R(0x11, 0x1, RV_OP_FP), MASK_FP_R, RV64_FMT_FP_R, - RV64_ASMFL_FP | RV64_ASMFL_NORM, {0, 0}}, - {MN("fsgnjx.d"), MATCH_FP_R(0x11, 0x2, RV_OP_FP), MASK_FP_R, RV64_FMT_FP_R, - RV64_ASMFL_FP | RV64_ASMFL_NORM, {0, 0}}, + {MN("fsgnj.s"), + MATCH_FP_R(0x10, 0x0, RV_OP_FP), + MASK_FP_R, + RV64_FMT_FP_R, + RV64_ASMFL_FP | RV64_ASMFL_NORM, + {0, 0}}, + {MN("fsgnjn.s"), + MATCH_FP_R(0x10, 0x1, RV_OP_FP), + MASK_FP_R, + RV64_FMT_FP_R, + RV64_ASMFL_FP | RV64_ASMFL_NORM, + {0, 0}}, + {MN("fsgnjx.s"), + MATCH_FP_R(0x10, 0x2, RV_OP_FP), + MASK_FP_R, + RV64_FMT_FP_R, + RV64_ASMFL_FP | RV64_ASMFL_NORM, + {0, 0}}, + {MN("fsgnj.d"), + MATCH_FP_R(0x11, 0x0, RV_OP_FP), + MASK_FP_R, + RV64_FMT_FP_R, + RV64_ASMFL_FP | RV64_ASMFL_NORM, + {0, 0}}, + {MN("fsgnjn.d"), + MATCH_FP_R(0x11, 0x1, RV_OP_FP), + MASK_FP_R, + RV64_FMT_FP_R, + RV64_ASMFL_FP | RV64_ASMFL_NORM, + {0, 0}}, + {MN("fsgnjx.d"), + MATCH_FP_R(0x11, 0x2, RV_OP_FP), + MASK_FP_R, + RV64_FMT_FP_R, + RV64_ASMFL_FP | RV64_ASMFL_NORM, + {0, 0}}, /* FP compare — funct7 = 0x50 (S) / 0x51 (D), funct3 = 0/1/2 = LE/LT/EQ. * rd is integer GPR (not FP). */ - {MN("fle.s"), MATCH_FP_R(0x50, 0x0, RV_OP_FP), MASK_FP_R, RV64_FMT_FP_R, - RV64_ASMFL_NORM, {0, 0}}, - {MN("flt.s"), MATCH_FP_R(0x50, 0x1, RV_OP_FP), MASK_FP_R, RV64_FMT_FP_R, - RV64_ASMFL_NORM, {0, 0}}, - {MN("feq.s"), MATCH_FP_R(0x50, 0x2, RV_OP_FP), MASK_FP_R, RV64_FMT_FP_R, - RV64_ASMFL_NORM, {0, 0}}, - {MN("fle.d"), MATCH_FP_R(0x51, 0x0, RV_OP_FP), MASK_FP_R, RV64_FMT_FP_R, - RV64_ASMFL_NORM, {0, 0}}, - {MN("flt.d"), MATCH_FP_R(0x51, 0x1, RV_OP_FP), MASK_FP_R, RV64_FMT_FP_R, - RV64_ASMFL_NORM, {0, 0}}, - {MN("feq.d"), MATCH_FP_R(0x51, 0x2, RV_OP_FP), MASK_FP_R, RV64_FMT_FP_R, - RV64_ASMFL_NORM, {0, 0}}, + {MN("fle.s"), + MATCH_FP_R(0x50, 0x0, RV_OP_FP), + MASK_FP_R, + RV64_FMT_FP_R, + RV64_ASMFL_NORM, + {0, 0}}, + {MN("flt.s"), + MATCH_FP_R(0x50, 0x1, RV_OP_FP), + MASK_FP_R, + RV64_FMT_FP_R, + RV64_ASMFL_NORM, + {0, 0}}, + {MN("feq.s"), + MATCH_FP_R(0x50, 0x2, RV_OP_FP), + MASK_FP_R, + RV64_FMT_FP_R, + RV64_ASMFL_NORM, + {0, 0}}, + {MN("fle.d"), + MATCH_FP_R(0x51, 0x0, RV_OP_FP), + MASK_FP_R, + RV64_FMT_FP_R, + RV64_ASMFL_NORM, + {0, 0}}, + {MN("flt.d"), + MATCH_FP_R(0x51, 0x1, RV_OP_FP), + MASK_FP_R, + RV64_FMT_FP_R, + RV64_ASMFL_NORM, + {0, 0}}, + {MN("feq.d"), + MATCH_FP_R(0x51, 0x2, RV_OP_FP), + MASK_FP_R, + RV64_FMT_FP_R, + RV64_ASMFL_NORM, + {0, 0}}, /* FP classification — rd is GPR, rs1 is FPR, rs2=0, rm/funct3=1. */ - {MN("fclass.s"), MATCH_FP_R(0x70, 0x1, RV_OP_FP) | (0u << 20), - MASK_FP_CVT | (7u << 12), RV64_FMT_FP_CVT, 0, {0, 0}}, - {MN("fclass.d"), MATCH_FP_R(0x71, 0x1, RV_OP_FP) | (0u << 20), - MASK_FP_CVT | (7u << 12), RV64_FMT_FP_CVT, 0, {0, 0}}, + {MN("fclass.s"), + MATCH_FP_R(0x70, 0x1, RV_OP_FP) | (0u << 20), + MASK_FP_CVT | (7u << 12), + RV64_FMT_FP_CVT, + 0, + {0, 0}}, + {MN("fclass.d"), + MATCH_FP_R(0x71, 0x1, RV_OP_FP) | (0u << 20), + MASK_FP_CVT | (7u << 12), + RV64_FMT_FP_CVT, + 0, + {0, 0}}, /* FP conversions — funct7 selects {direction, fmt}, rs2 selects * integer width/signedness. */ - {MN("fcvt.w.s"), MATCH_FP_CVT(0x60, 0x0, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, 0, {0, 0}}, - {MN("fcvt.wu.s"), MATCH_FP_CVT(0x60, 0x1, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, 0, {0, 0}}, - {MN("fcvt.l.s"), MATCH_FP_CVT(0x60, 0x2, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, 0, {0, 0}}, - {MN("fcvt.lu.s"), MATCH_FP_CVT(0x60, 0x3, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, 0, {0, 0}}, - {MN("fcvt.w.d"), MATCH_FP_CVT(0x61, 0x0, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, 0, {0, 0}}, - {MN("fcvt.wu.d"), MATCH_FP_CVT(0x61, 0x1, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, 0, {0, 0}}, - {MN("fcvt.l.d"), MATCH_FP_CVT(0x61, 0x2, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, 0, {0, 0}}, - {MN("fcvt.lu.d"), MATCH_FP_CVT(0x61, 0x3, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, 0, {0, 0}}, - {MN("fcvt.s.w"), MATCH_FP_CVT(0x68, 0x0, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, RV64_ASMFL_FP, {0, 0}}, - {MN("fcvt.s.wu"), MATCH_FP_CVT(0x68, 0x1, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, RV64_ASMFL_FP, {0, 0}}, - {MN("fcvt.s.l"), MATCH_FP_CVT(0x68, 0x2, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, RV64_ASMFL_FP, {0, 0}}, - {MN("fcvt.s.lu"), MATCH_FP_CVT(0x68, 0x3, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, RV64_ASMFL_FP, {0, 0}}, - {MN("fcvt.d.w"), MATCH_FP_CVT(0x69, 0x0, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, RV64_ASMFL_FP, {0, 0}}, - {MN("fcvt.d.wu"), MATCH_FP_CVT(0x69, 0x1, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, RV64_ASMFL_FP, {0, 0}}, - {MN("fcvt.d.l"), MATCH_FP_CVT(0x69, 0x2, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, RV64_ASMFL_FP, {0, 0}}, - {MN("fcvt.d.lu"), MATCH_FP_CVT(0x69, 0x3, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, RV64_ASMFL_FP, {0, 0}}, - {MN("fcvt.s.d"), MATCH_FP_CVT(0x20, 0x1, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, RV64_ASMFL_FP, {0, 0}}, - {MN("fcvt.d.s"), MATCH_FP_CVT(0x21, 0x0, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, RV64_ASMFL_FP, {0, 0}}, + {MN("fcvt.w.s"), + MATCH_FP_CVT(0x60, 0x0, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + 0, + {0, 0}}, + {MN("fcvt.wu.s"), + MATCH_FP_CVT(0x60, 0x1, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + 0, + {0, 0}}, + {MN("fcvt.l.s"), + MATCH_FP_CVT(0x60, 0x2, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + 0, + {0, 0}}, + {MN("fcvt.lu.s"), + MATCH_FP_CVT(0x60, 0x3, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + 0, + {0, 0}}, + {MN("fcvt.w.d"), + MATCH_FP_CVT(0x61, 0x0, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + 0, + {0, 0}}, + {MN("fcvt.wu.d"), + MATCH_FP_CVT(0x61, 0x1, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + 0, + {0, 0}}, + {MN("fcvt.l.d"), + MATCH_FP_CVT(0x61, 0x2, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + 0, + {0, 0}}, + {MN("fcvt.lu.d"), + MATCH_FP_CVT(0x61, 0x3, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + 0, + {0, 0}}, + {MN("fcvt.s.w"), + MATCH_FP_CVT(0x68, 0x0, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fcvt.s.wu"), + MATCH_FP_CVT(0x68, 0x1, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fcvt.s.l"), + MATCH_FP_CVT(0x68, 0x2, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fcvt.s.lu"), + MATCH_FP_CVT(0x68, 0x3, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fcvt.d.w"), + MATCH_FP_CVT(0x69, 0x0, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fcvt.d.wu"), + MATCH_FP_CVT(0x69, 0x1, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fcvt.d.l"), + MATCH_FP_CVT(0x69, 0x2, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fcvt.d.lu"), + MATCH_FP_CVT(0x69, 0x3, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fcvt.s.d"), + MATCH_FP_CVT(0x20, 0x1, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fcvt.d.s"), + MATCH_FP_CVT(0x21, 0x0, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + RV64_ASMFL_FP, + {0, 0}}, /* FP bitcast moves — funct7 + rs2=0 + funct3=0 fixed. */ - {MN("fmv.x.w"), MATCH_FP_CVT(0x70, 0x0, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, 0, {0, 0}}, - {MN("fmv.w.x"), MATCH_FP_CVT(0x78, 0x0, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, RV64_ASMFL_FP, {0, 0}}, - {MN("fmv.x.d"), MATCH_FP_CVT(0x71, 0x0, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, 0, {0, 0}}, - {MN("fmv.d.x"), MATCH_FP_CVT(0x79, 0x0, RV_OP_FP), MASK_FP_CVT, - RV64_FMT_FP_CVT, RV64_ASMFL_FP, {0, 0}}, + {MN("fmv.x.w"), + MATCH_FP_CVT(0x70, 0x0, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + 0, + {0, 0}}, + {MN("fmv.w.x"), + MATCH_FP_CVT(0x78, 0x0, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fmv.x.d"), + MATCH_FP_CVT(0x71, 0x0, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + 0, + {0, 0}}, + {MN("fmv.d.x"), + MATCH_FP_CVT(0x79, 0x0, RV_OP_FP), + MASK_FP_CVT, + RV64_FMT_FP_CVT, + RV64_ASMFL_FP, + {0, 0}}, /* FP load/store */ - {MN("flw"), MATCH_I(0x2, RV_LOAD_FP), MASK_I, RV64_FMT_FP_LOAD, - RV64_ASMFL_FP, {0, 0}}, - {MN("fld"), MATCH_I(0x3, RV_LOAD_FP), MASK_I, RV64_FMT_FP_LOAD, - RV64_ASMFL_FP, {0, 0}}, - {MN("fsw"), MATCH_S(0x2, RV_STORE_FP), MASK_S, RV64_FMT_FP_STORE, - RV64_ASMFL_FP, {0, 0}}, - {MN("fsd"), MATCH_S(0x3, RV_STORE_FP), MASK_S, RV64_FMT_FP_STORE, - RV64_ASMFL_FP, {0, 0}}, + {MN("flw"), + MATCH_I(0x2, RV_LOAD_FP), + MASK_I, + RV64_FMT_FP_LOAD, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fld"), + MATCH_I(0x3, RV_LOAD_FP), + MASK_I, + RV64_FMT_FP_LOAD, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fsw"), + MATCH_S(0x2, RV_STORE_FP), + MASK_S, + RV64_FMT_FP_STORE, + RV64_ASMFL_FP, + {0, 0}}, + {MN("fsd"), + MATCH_S(0x3, RV_STORE_FP), + MASK_S, + RV64_FMT_FP_STORE, + RV64_ASMFL_FP, + {0, 0}}, /* ================================================================= * RV64A (atomic) — AMO funct5 + funct3 (W=2, D=3). aq/rl vary, so @@ -408,150 +733,307 @@ const Rv64InsnDesc rv64_insn_table[] = { * suffixes via the disassembler's annotation, but the row mnemonic * itself is the bare form (e.g. "amoadd.w"). * ================================================================= */ - {MN("lr.w.aq"), MATCH_AMO_ORDER(0x02, 1, 0, 0x2, RV_AMO), - MASK_AMO_ORDER | (0x1fu << 20), RV64_FMT_LR, 0, {0, 0}}, - {MN("lr.w.rl"), MATCH_AMO_ORDER(0x02, 0, 1, 0x2, RV_AMO), - MASK_AMO_ORDER | (0x1fu << 20), RV64_FMT_LR, 0, {0, 0}}, - {MN("lr.w.aqrl"), MATCH_AMO_ORDER(0x02, 1, 1, 0x2, RV_AMO), - MASK_AMO_ORDER | (0x1fu << 20), RV64_FMT_LR, 0, {0, 0}}, - {MN("lr.d.aq"), MATCH_AMO_ORDER(0x02, 1, 0, 0x3, RV_AMO), - MASK_AMO_ORDER | (0x1fu << 20), RV64_FMT_LR, 0, {0, 0}}, - {MN("lr.d.rl"), MATCH_AMO_ORDER(0x02, 0, 1, 0x3, RV_AMO), - MASK_AMO_ORDER | (0x1fu << 20), RV64_FMT_LR, 0, {0, 0}}, - {MN("lr.d.aqrl"), MATCH_AMO_ORDER(0x02, 1, 1, 0x3, RV_AMO), - MASK_AMO_ORDER | (0x1fu << 20), RV64_FMT_LR, 0, {0, 0}}, - {MN("sc.w.aq"), MATCH_AMO_ORDER(0x03, 1, 0, 0x2, RV_AMO), - MASK_AMO_ORDER, RV64_FMT_AMO, 0, {0, 0}}, - {MN("sc.w.rl"), MATCH_AMO_ORDER(0x03, 0, 1, 0x2, RV_AMO), - MASK_AMO_ORDER, RV64_FMT_AMO, 0, {0, 0}}, - {MN("sc.w.aqrl"), MATCH_AMO_ORDER(0x03, 1, 1, 0x2, RV_AMO), - MASK_AMO_ORDER, RV64_FMT_AMO, 0, {0, 0}}, - {MN("sc.d.aq"), MATCH_AMO_ORDER(0x03, 1, 0, 0x3, RV_AMO), - MASK_AMO_ORDER, RV64_FMT_AMO, 0, {0, 0}}, - {MN("sc.d.rl"), MATCH_AMO_ORDER(0x03, 0, 1, 0x3, RV_AMO), - MASK_AMO_ORDER, RV64_FMT_AMO, 0, {0, 0}}, - {MN("sc.d.aqrl"), MATCH_AMO_ORDER(0x03, 1, 1, 0x3, RV_AMO), - MASK_AMO_ORDER, RV64_FMT_AMO, 0, {0, 0}}, -#define RV64_AMO_ORDER_ROWS(mn, f5, f3) \ - {MN(mn ".aq"), MATCH_AMO_ORDER(f5, 1, 0, f3, RV_AMO), MASK_AMO_ORDER, \ - RV64_FMT_AMO, 0, {0, 0}}, \ - {MN(mn ".rl"), MATCH_AMO_ORDER(f5, 0, 1, f3, RV_AMO), MASK_AMO_ORDER, \ - RV64_FMT_AMO, 0, {0, 0}}, \ - {MN(mn ".aqrl"), MATCH_AMO_ORDER(f5, 1, 1, f3, RV_AMO), MASK_AMO_ORDER, \ - RV64_FMT_AMO, 0, {0, 0}} + {MN("lr.w.aq"), + MATCH_AMO_ORDER(0x02, 1, 0, 0x2, RV_AMO), + MASK_AMO_ORDER | (0x1fu << 20), + RV64_FMT_LR, + 0, + {0, 0}}, + {MN("lr.w.rl"), + MATCH_AMO_ORDER(0x02, 0, 1, 0x2, RV_AMO), + MASK_AMO_ORDER | (0x1fu << 20), + RV64_FMT_LR, + 0, + {0, 0}}, + {MN("lr.w.aqrl"), + MATCH_AMO_ORDER(0x02, 1, 1, 0x2, RV_AMO), + MASK_AMO_ORDER | (0x1fu << 20), + RV64_FMT_LR, + 0, + {0, 0}}, + {MN("lr.d.aq"), + MATCH_AMO_ORDER(0x02, 1, 0, 0x3, RV_AMO), + MASK_AMO_ORDER | (0x1fu << 20), + RV64_FMT_LR, + 0, + {0, 0}}, + {MN("lr.d.rl"), + MATCH_AMO_ORDER(0x02, 0, 1, 0x3, RV_AMO), + MASK_AMO_ORDER | (0x1fu << 20), + RV64_FMT_LR, + 0, + {0, 0}}, + {MN("lr.d.aqrl"), + MATCH_AMO_ORDER(0x02, 1, 1, 0x3, RV_AMO), + MASK_AMO_ORDER | (0x1fu << 20), + RV64_FMT_LR, + 0, + {0, 0}}, + {MN("sc.w.aq"), + MATCH_AMO_ORDER(0x03, 1, 0, 0x2, RV_AMO), + MASK_AMO_ORDER, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("sc.w.rl"), + MATCH_AMO_ORDER(0x03, 0, 1, 0x2, RV_AMO), + MASK_AMO_ORDER, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("sc.w.aqrl"), + MATCH_AMO_ORDER(0x03, 1, 1, 0x2, RV_AMO), + MASK_AMO_ORDER, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("sc.d.aq"), + MATCH_AMO_ORDER(0x03, 1, 0, 0x3, RV_AMO), + MASK_AMO_ORDER, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("sc.d.rl"), + MATCH_AMO_ORDER(0x03, 0, 1, 0x3, RV_AMO), + MASK_AMO_ORDER, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("sc.d.aqrl"), + MATCH_AMO_ORDER(0x03, 1, 1, 0x3, RV_AMO), + MASK_AMO_ORDER, + RV64_FMT_AMO, + 0, + {0, 0}}, +#define RV64_AMO_ORDER_ROWS(mn, f5, f3) \ + {MN(mn ".aq"), \ + MATCH_AMO_ORDER(f5, 1, 0, f3, RV_AMO), \ + MASK_AMO_ORDER, \ + RV64_FMT_AMO, \ + 0, \ + {0, 0}}, \ + {MN(mn ".rl"), \ + MATCH_AMO_ORDER(f5, 0, 1, f3, RV_AMO), \ + MASK_AMO_ORDER, \ + RV64_FMT_AMO, \ + 0, \ + {0, 0}}, \ + { \ + MN(mn ".aqrl"), MATCH_AMO_ORDER(f5, 1, 1, f3, RV_AMO), MASK_AMO_ORDER, \ + RV64_FMT_AMO, 0, {0, 0} \ + } RV64_AMO_ORDER_ROWS("amoswap.w", RV_AMO_SWAP, 0x2), - RV64_AMO_ORDER_ROWS("amoadd.w", RV_AMO_ADD, 0x2), - RV64_AMO_ORDER_ROWS("amoxor.w", RV_AMO_XOR, 0x2), - RV64_AMO_ORDER_ROWS("amoand.w", RV_AMO_AND, 0x2), - RV64_AMO_ORDER_ROWS("amoor.w", RV_AMO_OR, 0x2), - RV64_AMO_ORDER_ROWS("amomin.w", RV_AMO_MIN, 0x2), - RV64_AMO_ORDER_ROWS("amomax.w", RV_AMO_MAX, 0x2), + RV64_AMO_ORDER_ROWS("amoadd.w", RV_AMO_ADD, 0x2), + RV64_AMO_ORDER_ROWS("amoxor.w", RV_AMO_XOR, 0x2), + RV64_AMO_ORDER_ROWS("amoand.w", RV_AMO_AND, 0x2), + RV64_AMO_ORDER_ROWS("amoor.w", RV_AMO_OR, 0x2), + RV64_AMO_ORDER_ROWS("amomin.w", RV_AMO_MIN, 0x2), + RV64_AMO_ORDER_ROWS("amomax.w", RV_AMO_MAX, 0x2), RV64_AMO_ORDER_ROWS("amominu.w", RV_AMO_MINU, 0x2), RV64_AMO_ORDER_ROWS("amomaxu.w", RV_AMO_MAXU, 0x2), RV64_AMO_ORDER_ROWS("amoswap.d", RV_AMO_SWAP, 0x3), - RV64_AMO_ORDER_ROWS("amoadd.d", RV_AMO_ADD, 0x3), - RV64_AMO_ORDER_ROWS("amoxor.d", RV_AMO_XOR, 0x3), - RV64_AMO_ORDER_ROWS("amoand.d", RV_AMO_AND, 0x3), - RV64_AMO_ORDER_ROWS("amoor.d", RV_AMO_OR, 0x3), - RV64_AMO_ORDER_ROWS("amomin.d", RV_AMO_MIN, 0x3), - RV64_AMO_ORDER_ROWS("amomax.d", RV_AMO_MAX, 0x3), + RV64_AMO_ORDER_ROWS("amoadd.d", RV_AMO_ADD, 0x3), + RV64_AMO_ORDER_ROWS("amoxor.d", RV_AMO_XOR, 0x3), + RV64_AMO_ORDER_ROWS("amoand.d", RV_AMO_AND, 0x3), + RV64_AMO_ORDER_ROWS("amoor.d", RV_AMO_OR, 0x3), + RV64_AMO_ORDER_ROWS("amomin.d", RV_AMO_MIN, 0x3), + RV64_AMO_ORDER_ROWS("amomax.d", RV_AMO_MAX, 0x3), RV64_AMO_ORDER_ROWS("amominu.d", RV_AMO_MINU, 0x3), RV64_AMO_ORDER_ROWS("amomaxu.d", RV_AMO_MAXU, 0x3), - {MN("lr.w"), MATCH_AMO(0x02, 0x2, RV_AMO), MASK_AMO | (0x1fu << 20), - RV64_FMT_LR, 0, {0, 0}}, - {MN("lr.d"), MATCH_AMO(0x02, 0x3, RV_AMO), MASK_AMO | (0x1fu << 20), - RV64_FMT_LR, 0, {0, 0}}, - {MN("sc.w"), MATCH_AMO(0x03, 0x2, RV_AMO), MASK_AMO, RV64_FMT_AMO, 0, - {0, 0}}, - {MN("sc.d"), MATCH_AMO(0x03, 0x3, RV_AMO), MASK_AMO, RV64_FMT_AMO, 0, - {0, 0}}, - {MN("amoswap.w"), MATCH_AMO(RV_AMO_SWAP, 0x2, RV_AMO), MASK_AMO, - RV64_FMT_AMO, 0, {0, 0}}, - {MN("amoadd.w"), MATCH_AMO(RV_AMO_ADD, 0x2, RV_AMO), MASK_AMO, - RV64_FMT_AMO, 0, {0, 0}}, - {MN("amoxor.w"), MATCH_AMO(RV_AMO_XOR, 0x2, RV_AMO), MASK_AMO, - RV64_FMT_AMO, 0, {0, 0}}, - {MN("amoand.w"), MATCH_AMO(RV_AMO_AND, 0x2, RV_AMO), MASK_AMO, - RV64_FMT_AMO, 0, {0, 0}}, - {MN("amoor.w"), MATCH_AMO(RV_AMO_OR, 0x2, RV_AMO), MASK_AMO, - RV64_FMT_AMO, 0, {0, 0}}, - {MN("amomin.w"), MATCH_AMO(RV_AMO_MIN, 0x2, RV_AMO), MASK_AMO, - RV64_FMT_AMO, 0, {0, 0}}, - {MN("amomax.w"), MATCH_AMO(RV_AMO_MAX, 0x2, RV_AMO), MASK_AMO, - RV64_FMT_AMO, 0, {0, 0}}, - {MN("amominu.w"), MATCH_AMO(RV_AMO_MINU, 0x2, RV_AMO), MASK_AMO, - RV64_FMT_AMO, 0, {0, 0}}, - {MN("amomaxu.w"), MATCH_AMO(RV_AMO_MAXU, 0x2, RV_AMO), MASK_AMO, - RV64_FMT_AMO, 0, {0, 0}}, - {MN("amoswap.d"), MATCH_AMO(RV_AMO_SWAP, 0x3, RV_AMO), MASK_AMO, - RV64_FMT_AMO, 0, {0, 0}}, - {MN("amoadd.d"), MATCH_AMO(RV_AMO_ADD, 0x3, RV_AMO), MASK_AMO, - RV64_FMT_AMO, 0, {0, 0}}, - {MN("amoxor.d"), MATCH_AMO(RV_AMO_XOR, 0x3, RV_AMO), MASK_AMO, - RV64_FMT_AMO, 0, {0, 0}}, - {MN("amoand.d"), MATCH_AMO(RV_AMO_AND, 0x3, RV_AMO), MASK_AMO, - RV64_FMT_AMO, 0, {0, 0}}, - {MN("amoor.d"), MATCH_AMO(RV_AMO_OR, 0x3, RV_AMO), MASK_AMO, - RV64_FMT_AMO, 0, {0, 0}}, - {MN("amomin.d"), MATCH_AMO(RV_AMO_MIN, 0x3, RV_AMO), MASK_AMO, - RV64_FMT_AMO, 0, {0, 0}}, - {MN("amomax.d"), MATCH_AMO(RV_AMO_MAX, 0x3, RV_AMO), MASK_AMO, - RV64_FMT_AMO, 0, {0, 0}}, - {MN("amominu.d"), MATCH_AMO(RV_AMO_MINU, 0x3, RV_AMO), MASK_AMO, - RV64_FMT_AMO, 0, {0, 0}}, - {MN("amomaxu.d"), MATCH_AMO(RV_AMO_MAXU, 0x3, RV_AMO), MASK_AMO, - RV64_FMT_AMO, 0, {0, 0}}, + {MN("lr.w"), + MATCH_AMO(0x02, 0x2, RV_AMO), + MASK_AMO | (0x1fu << 20), + RV64_FMT_LR, + 0, + {0, 0}}, + {MN("lr.d"), + MATCH_AMO(0x02, 0x3, RV_AMO), + MASK_AMO | (0x1fu << 20), + RV64_FMT_LR, + 0, + {0, 0}}, + {MN("sc.w"), + MATCH_AMO(0x03, 0x2, RV_AMO), + MASK_AMO, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("sc.d"), + MATCH_AMO(0x03, 0x3, RV_AMO), + MASK_AMO, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("amoswap.w"), + MATCH_AMO(RV_AMO_SWAP, 0x2, RV_AMO), + MASK_AMO, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("amoadd.w"), + MATCH_AMO(RV_AMO_ADD, 0x2, RV_AMO), + MASK_AMO, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("amoxor.w"), + MATCH_AMO(RV_AMO_XOR, 0x2, RV_AMO), + MASK_AMO, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("amoand.w"), + MATCH_AMO(RV_AMO_AND, 0x2, RV_AMO), + MASK_AMO, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("amoor.w"), + MATCH_AMO(RV_AMO_OR, 0x2, RV_AMO), + MASK_AMO, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("amomin.w"), + MATCH_AMO(RV_AMO_MIN, 0x2, RV_AMO), + MASK_AMO, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("amomax.w"), + MATCH_AMO(RV_AMO_MAX, 0x2, RV_AMO), + MASK_AMO, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("amominu.w"), + MATCH_AMO(RV_AMO_MINU, 0x2, RV_AMO), + MASK_AMO, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("amomaxu.w"), + MATCH_AMO(RV_AMO_MAXU, 0x2, RV_AMO), + MASK_AMO, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("amoswap.d"), + MATCH_AMO(RV_AMO_SWAP, 0x3, RV_AMO), + MASK_AMO, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("amoadd.d"), + MATCH_AMO(RV_AMO_ADD, 0x3, RV_AMO), + MASK_AMO, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("amoxor.d"), + MATCH_AMO(RV_AMO_XOR, 0x3, RV_AMO), + MASK_AMO, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("amoand.d"), + MATCH_AMO(RV_AMO_AND, 0x3, RV_AMO), + MASK_AMO, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("amoor.d"), + MATCH_AMO(RV_AMO_OR, 0x3, RV_AMO), + MASK_AMO, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("amomin.d"), + MATCH_AMO(RV_AMO_MIN, 0x3, RV_AMO), + MASK_AMO, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("amomax.d"), + MATCH_AMO(RV_AMO_MAX, 0x3, RV_AMO), + MASK_AMO, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("amominu.d"), + MATCH_AMO(RV_AMO_MINU, 0x3, RV_AMO), + MASK_AMO, + RV64_FMT_AMO, + 0, + {0, 0}}, + {MN("amomaxu.d"), + MATCH_AMO(RV_AMO_MAXU, 0x3, RV_AMO), + MASK_AMO, + RV64_FMT_AMO, + 0, + {0, 0}}, /* ================================================================= * RV64C compressed — assembler rows. The disassembler uses the * dynamic C decoder below, so 32-bit decode skips these rows. * ================================================================= */ - {MN("c.nop"), 0x0001u, 0xffffu, RV64_FMT_C_NONE, RV64_ASMFL_C16, - {0, 0}}, - {MN("c.ebreak"), 0x9002u, 0xffffu, RV64_FMT_C_NONE, RV64_ASMFL_C16, - {0, 0}}, - {MN("c.jr"), 0x8002u, 0xf07fu, RV64_FMT_CR, RV64_ASMFL_C16, {0, 0}}, - {MN("c.jalr"), 0x9002u, 0xf07fu, RV64_FMT_CR, RV64_ASMFL_C16, {0, 0}}, - {MN("c.mv"), 0x8002u, 0xf003u, RV64_FMT_CR, RV64_ASMFL_C16, {0, 0}}, - {MN("c.add"), 0x9002u, 0xf003u, RV64_FMT_CR, RV64_ASMFL_C16, {0, 0}}, - {MN("c.li"), 0x4001u, 0xe003u, RV64_FMT_CI, RV64_ASMFL_C16, {0, 0}}, - {MN("c.addi"), 0x0001u, 0xe003u, RV64_FMT_CI, RV64_ASMFL_C16, {0, 0}}, - {MN("c.addiw"), 0x2001u, 0xe003u, RV64_FMT_CI, RV64_ASMFL_C16, {0, 0}}, - {MN("c.slli"), 0x0002u, 0xe003u, RV64_FMT_CI, RV64_ASMFL_C16, {0, 0}}, - {MN("c.lui"), 0x6001u, 0xe003u, RV64_FMT_CI, RV64_ASMFL_C16, {0, 0}}, + {MN("c.nop"), 0x0001u, 0xffffu, RV64_FMT_C_NONE, RV64_ASMFL_C16, {0, 0}}, + {MN("c.ebreak"), 0x9002u, 0xffffu, RV64_FMT_C_NONE, RV64_ASMFL_C16, {0, 0}}, + {MN("c.jr"), 0x8002u, 0xf07fu, RV64_FMT_CR, RV64_ASMFL_C16, {0, 0}}, + {MN("c.jalr"), 0x9002u, 0xf07fu, RV64_FMT_CR, RV64_ASMFL_C16, {0, 0}}, + {MN("c.mv"), 0x8002u, 0xf003u, RV64_FMT_CR, RV64_ASMFL_C16, {0, 0}}, + {MN("c.add"), 0x9002u, 0xf003u, RV64_FMT_CR, RV64_ASMFL_C16, {0, 0}}, + {MN("c.li"), 0x4001u, 0xe003u, RV64_FMT_CI, RV64_ASMFL_C16, {0, 0}}, + {MN("c.addi"), 0x0001u, 0xe003u, RV64_FMT_CI, RV64_ASMFL_C16, {0, 0}}, + {MN("c.addiw"), 0x2001u, 0xe003u, RV64_FMT_CI, RV64_ASMFL_C16, {0, 0}}, + {MN("c.slli"), 0x0002u, 0xe003u, RV64_FMT_CI, RV64_ASMFL_C16, {0, 0}}, + {MN("c.lui"), 0x6001u, 0xe003u, RV64_FMT_CI, RV64_ASMFL_C16, {0, 0}}, {MN("c.addi16sp"), 0x6101u, 0xef83u, RV64_FMT_CI, RV64_ASMFL_C16, {0, 0}}, - {MN("c.lwsp"), 0x4002u, 0xe003u, RV64_FMT_CI, RV64_ASMFL_C16, {0, 0}}, - {MN("c.ldsp"), 0x6002u, 0xe003u, RV64_FMT_CI, RV64_ASMFL_C16, {0, 0}}, - {MN("c.fldsp"), 0x2002u, 0xe003u, RV64_FMT_CI, - RV64_ASMFL_C16 | RV64_ASMFL_FP, {0, 0}}, - {MN("c.swsp"), 0xc002u, 0xe003u, RV64_FMT_CSS, RV64_ASMFL_C16, - {0, 0}}, - {MN("c.sdsp"), 0xe002u, 0xe003u, RV64_FMT_CSS, RV64_ASMFL_C16, - {0, 0}}, - {MN("c.fsdsp"), 0xa002u, 0xe003u, RV64_FMT_CSS, - RV64_ASMFL_C16 | RV64_ASMFL_FP, {0, 0}}, - {MN("c.addi4spn"), 0x0000u, 0xe003u, RV64_FMT_CIW, RV64_ASMFL_C16, - {0, 0}}, - {MN("c.lw"), 0x4000u, 0xe003u, RV64_FMT_CL, RV64_ASMFL_C16, {0, 0}}, - {MN("c.ld"), 0x6000u, 0xe003u, RV64_FMT_CL, RV64_ASMFL_C16, {0, 0}}, - {MN("c.fld"), 0x2000u, 0xe003u, RV64_FMT_CL, - RV64_ASMFL_C16 | RV64_ASMFL_FP, {0, 0}}, - {MN("c.sw"), 0xc000u, 0xe003u, RV64_FMT_CS, RV64_ASMFL_C16, {0, 0}}, - {MN("c.sd"), 0xe000u, 0xe003u, RV64_FMT_CS, RV64_ASMFL_C16, {0, 0}}, - {MN("c.fsd"), 0xa000u, 0xe003u, RV64_FMT_CS, - RV64_ASMFL_C16 | RV64_ASMFL_FP, {0, 0}}, - {MN("c.srli"), 0x8001u, 0xec03u, RV64_FMT_CB, RV64_ASMFL_C16, {0, 0}}, - {MN("c.srai"), 0x8401u, 0xec03u, RV64_FMT_CB, RV64_ASMFL_C16, {0, 0}}, - {MN("c.andi"), 0x8801u, 0xec03u, RV64_FMT_CB, RV64_ASMFL_C16, {0, 0}}, - {MN("c.sub"), 0x8c01u, 0xfc63u, RV64_FMT_CA, RV64_ASMFL_C16, {0, 0}}, - {MN("c.xor"), 0x8c21u, 0xfc63u, RV64_FMT_CA, RV64_ASMFL_C16, {0, 0}}, - {MN("c.or"), 0x8c41u, 0xfc63u, RV64_FMT_CA, RV64_ASMFL_C16, {0, 0}}, - {MN("c.and"), 0x8c61u, 0xfc63u, RV64_FMT_CA, RV64_ASMFL_C16, {0, 0}}, - {MN("c.subw"), 0x9c01u, 0xfc63u, RV64_FMT_CA, RV64_ASMFL_C16, {0, 0}}, - {MN("c.addw"), 0x9c21u, 0xfc63u, RV64_FMT_CA, RV64_ASMFL_C16, {0, 0}}, - {MN("c.j"), 0xa001u, 0xe003u, RV64_FMT_CJ, RV64_ASMFL_C16, {0, 0}}, - {MN("c.beqz"), 0xc001u, 0xe003u, RV64_FMT_CB, RV64_ASMFL_C16, {0, 0}}, - {MN("c.bnez"), 0xe001u, 0xe003u, RV64_FMT_CB, RV64_ASMFL_C16, {0, 0}}, + {MN("c.lwsp"), 0x4002u, 0xe003u, RV64_FMT_CI, RV64_ASMFL_C16, {0, 0}}, + {MN("c.ldsp"), 0x6002u, 0xe003u, RV64_FMT_CI, RV64_ASMFL_C16, {0, 0}}, + {MN("c.fldsp"), + 0x2002u, + 0xe003u, + RV64_FMT_CI, + RV64_ASMFL_C16 | RV64_ASMFL_FP, + {0, 0}}, + {MN("c.swsp"), 0xc002u, 0xe003u, RV64_FMT_CSS, RV64_ASMFL_C16, {0, 0}}, + {MN("c.sdsp"), 0xe002u, 0xe003u, RV64_FMT_CSS, RV64_ASMFL_C16, {0, 0}}, + {MN("c.fsdsp"), + 0xa002u, + 0xe003u, + RV64_FMT_CSS, + RV64_ASMFL_C16 | RV64_ASMFL_FP, + {0, 0}}, + {MN("c.addi4spn"), 0x0000u, 0xe003u, RV64_FMT_CIW, RV64_ASMFL_C16, {0, 0}}, + {MN("c.lw"), 0x4000u, 0xe003u, RV64_FMT_CL, RV64_ASMFL_C16, {0, 0}}, + {MN("c.ld"), 0x6000u, 0xe003u, RV64_FMT_CL, RV64_ASMFL_C16, {0, 0}}, + {MN("c.fld"), + 0x2000u, + 0xe003u, + RV64_FMT_CL, + RV64_ASMFL_C16 | RV64_ASMFL_FP, + {0, 0}}, + {MN("c.sw"), 0xc000u, 0xe003u, RV64_FMT_CS, RV64_ASMFL_C16, {0, 0}}, + {MN("c.sd"), 0xe000u, 0xe003u, RV64_FMT_CS, RV64_ASMFL_C16, {0, 0}}, + {MN("c.fsd"), + 0xa000u, + 0xe003u, + RV64_FMT_CS, + RV64_ASMFL_C16 | RV64_ASMFL_FP, + {0, 0}}, + {MN("c.srli"), 0x8001u, 0xec03u, RV64_FMT_CB, RV64_ASMFL_C16, {0, 0}}, + {MN("c.srai"), 0x8401u, 0xec03u, RV64_FMT_CB, RV64_ASMFL_C16, {0, 0}}, + {MN("c.andi"), 0x8801u, 0xec03u, RV64_FMT_CB, RV64_ASMFL_C16, {0, 0}}, + {MN("c.sub"), 0x8c01u, 0xfc63u, RV64_FMT_CA, RV64_ASMFL_C16, {0, 0}}, + {MN("c.xor"), 0x8c21u, 0xfc63u, RV64_FMT_CA, RV64_ASMFL_C16, {0, 0}}, + {MN("c.or"), 0x8c41u, 0xfc63u, RV64_FMT_CA, RV64_ASMFL_C16, {0, 0}}, + {MN("c.and"), 0x8c61u, 0xfc63u, RV64_FMT_CA, RV64_ASMFL_C16, {0, 0}}, + {MN("c.subw"), 0x9c01u, 0xfc63u, RV64_FMT_CA, RV64_ASMFL_C16, {0, 0}}, + {MN("c.addw"), 0x9c21u, 0xfc63u, RV64_FMT_CA, RV64_ASMFL_C16, {0, 0}}, + {MN("c.j"), 0xa001u, 0xe003u, RV64_FMT_CJ, RV64_ASMFL_C16, {0, 0}}, + {MN("c.beqz"), 0xc001u, 0xe003u, RV64_FMT_CB, RV64_ASMFL_C16, {0, 0}}, + {MN("c.bnez"), 0xe001u, 0xe003u, RV64_FMT_CB, RV64_ASMFL_C16, {0, 0}}, }; #undef RV64_AMO_ORDER_ROWS @@ -601,7 +1083,8 @@ static u32 rv64c_lookup_simple(u32 w) { if (w == 0x0001u) return 1; /* index in table-c below */ /* C.EBREAK: 0x9002 */ if (w == 0x9002u) return 2; - (void)op; (void)f3; + (void)op; + (void)f3; return 0; } @@ -611,8 +1094,8 @@ static u32 rv64c_lookup_simple(u32 w) { static const Rv64InsnDesc rv64_c_table[] = { /* index 0 reserved (no match). */ {MN("c.unknown"), 0, 0xffffu, RV64_FMT_C_NONE, RV64_ASMFL_C16, {0, 0}}, - {MN("c.nop"), 0x0001u, 0xffffu, RV64_FMT_C_NONE, RV64_ASMFL_C16, {0, 0}}, - {MN("c.ebreak"), 0x9002u, 0xffffu, RV64_FMT_C_NONE, RV64_ASMFL_C16, {0, 0}}, + {MN("c.nop"), 0x0001u, 0xffffu, RV64_FMT_C_NONE, RV64_ASMFL_C16, {0, 0}}, + {MN("c.ebreak"), 0x9002u, 0xffffu, RV64_FMT_C_NONE, RV64_ASMFL_C16, {0, 0}}, }; #undef MN @@ -634,8 +1117,12 @@ const Rv64InsnDesc* rv64_disasm_find_c(u32 word) { u32 rd_rs1 = (hw >> 7) & 0x1fu; u32 rs2 = (hw >> 2) & 0x1fu; if (funct4 == 0x8u) { - dyn = (Rv64InsnDesc){slice_from_cstr(rs2 == 0 ? "c.jr" : "c.mv"), hw, - 0xffffu, RV64_FMT_CR, RV64_ASMFL_C16, {0, 0}}; + dyn = (Rv64InsnDesc){slice_from_cstr(rs2 == 0 ? "c.jr" : "c.mv"), + hw, + 0xffffu, + RV64_FMT_CR, + RV64_ASMFL_C16, + {0, 0}}; return rd_rs1 == 0 ? NULL : &dyn; } if (funct4 == 0x9u) { @@ -643,39 +1130,59 @@ const Rv64InsnDesc* rv64_disasm_find_c(u32 word) { dyn = rv64_c_table[2]; /* c.ebreak */ return &dyn; } - dyn = (Rv64InsnDesc){slice_from_cstr(rs2 == 0 ? "c.jalr" : "c.add"), hw, - 0xffffu, RV64_FMT_CR, RV64_ASMFL_C16, {0, 0}}; + dyn = (Rv64InsnDesc){slice_from_cstr(rs2 == 0 ? "c.jalr" : "c.add"), + hw, + 0xffffu, + RV64_FMT_CR, + RV64_ASMFL_C16, + {0, 0}}; return &dyn; } } /* C.LI / C.ADDI / C.LUI — quadrant 1 */ if (op == 1u && f3 == 2u) { - dyn = (Rv64InsnDesc){slice_from_cstr("c.li"), hw, 0xffffu, RV64_FMT_CI, - RV64_ASMFL_C16, {0, 0}}; + dyn = (Rv64InsnDesc){slice_from_cstr("c.li"), hw, 0xffffu, RV64_FMT_CI, + RV64_ASMFL_C16, {0, 0}}; return &dyn; } if (op == 1u && f3 == 1u) { - dyn = (Rv64InsnDesc){slice_from_cstr("c.addiw"), hw, 0xffffu, RV64_FMT_CI, - RV64_ASMFL_C16, {0, 0}}; + dyn = (Rv64InsnDesc){slice_from_cstr("c.addiw"), + hw, + 0xffffu, + RV64_FMT_CI, + RV64_ASMFL_C16, + {0, 0}}; return &dyn; } if (op == 1u && f3 == 0u) { - dyn = (Rv64InsnDesc){slice_from_cstr("c.addi"), hw, 0xffffu, RV64_FMT_CI, - RV64_ASMFL_C16, {0, 0}}; + dyn = (Rv64InsnDesc){slice_from_cstr("c.addi"), + hw, + 0xffffu, + RV64_FMT_CI, + RV64_ASMFL_C16, + {0, 0}}; return &dyn; } if (op == 1u && f3 == 3u) { u32 rd = (hw >> 7) & 0x1fu; - dyn = (Rv64InsnDesc){slice_from_cstr(rd == 2u ? "c.addi16sp" : "c.lui"), hw, - 0xffffu, RV64_FMT_CI, RV64_ASMFL_C16, {0, 0}}; + dyn = (Rv64InsnDesc){slice_from_cstr(rd == 2u ? "c.addi16sp" : "c.lui"), + hw, + 0xffffu, + RV64_FMT_CI, + RV64_ASMFL_C16, + {0, 0}}; return &dyn; } if (op == 1u && f3 == 4u) { u32 top = (hw >> 10) & 0x3u; if (top == 0u || top == 1u || top == 2u) { static const char* const names[3] = {"c.srli", "c.srai", "c.andi"}; - dyn = (Rv64InsnDesc){slice_from_cstr(names[top]), hw, 0xffffu, RV64_FMT_CB, - RV64_ASMFL_C16, {0, 0}}; + dyn = (Rv64InsnDesc){slice_from_cstr(names[top]), + hw, + 0xffffu, + RV64_FMT_CB, + RV64_ASMFL_C16, + {0, 0}}; return &dyn; } { @@ -685,98 +1192,134 @@ const Rv64InsnDesc* rv64_disasm_find_c(u32 word) { static const char* const ca1[4] = {"c.subw", "c.addw", NULL, NULL}; const char* name = bit12 ? ca1[subop] : ca0[subop]; if (!name) return NULL; - dyn = (Rv64InsnDesc){slice_from_cstr(name), hw, 0xffffu, RV64_FMT_CA, - RV64_ASMFL_C16, {0, 0}}; + dyn = (Rv64InsnDesc){slice_from_cstr(name), hw, 0xffffu, RV64_FMT_CA, + RV64_ASMFL_C16, {0, 0}}; return &dyn; } } if (op == 1u && f3 == 5u) { - dyn = (Rv64InsnDesc){slice_from_cstr("c.j"), hw, 0xffffu, RV64_FMT_CJ, - RV64_ASMFL_C16, {0, 0}}; + dyn = (Rv64InsnDesc){slice_from_cstr("c.j"), hw, 0xffffu, RV64_FMT_CJ, + RV64_ASMFL_C16, {0, 0}}; return &dyn; } if (op == 1u && f3 == 6u) { - dyn = (Rv64InsnDesc){slice_from_cstr("c.beqz"), hw, 0xffffu, RV64_FMT_CB, - RV64_ASMFL_C16, {0, 0}}; + dyn = (Rv64InsnDesc){slice_from_cstr("c.beqz"), + hw, + 0xffffu, + RV64_FMT_CB, + RV64_ASMFL_C16, + {0, 0}}; return &dyn; } if (op == 1u && f3 == 7u) { - dyn = (Rv64InsnDesc){slice_from_cstr("c.bnez"), hw, 0xffffu, RV64_FMT_CB, - RV64_ASMFL_C16, {0, 0}}; + dyn = (Rv64InsnDesc){slice_from_cstr("c.bnez"), + hw, + 0xffffu, + RV64_FMT_CB, + RV64_ASMFL_C16, + {0, 0}}; return &dyn; } /* C.LWSP / C.LDSP — quadrant 2, funct3=010/011 */ if (op == 2u && f3 == 2u) { - dyn = (Rv64InsnDesc){slice_from_cstr("c.lwsp"), hw, 0xffffu, RV64_FMT_CI, - RV64_ASMFL_C16, {0, 0}}; + dyn = (Rv64InsnDesc){slice_from_cstr("c.lwsp"), + hw, + 0xffffu, + RV64_FMT_CI, + RV64_ASMFL_C16, + {0, 0}}; return &dyn; } if (op == 2u && f3 == 3u) { - dyn = (Rv64InsnDesc){slice_from_cstr("c.ldsp"), hw, 0xffffu, RV64_FMT_CI, - RV64_ASMFL_C16, {0, 0}}; + dyn = (Rv64InsnDesc){slice_from_cstr("c.ldsp"), + hw, + 0xffffu, + RV64_FMT_CI, + RV64_ASMFL_C16, + {0, 0}}; return &dyn; } if (op == 2u && f3 == 0u) { - dyn = (Rv64InsnDesc){slice_from_cstr("c.slli"), hw, 0xffffu, RV64_FMT_CI, - RV64_ASMFL_C16, {0, 0}}; + dyn = (Rv64InsnDesc){slice_from_cstr("c.slli"), + hw, + 0xffffu, + RV64_FMT_CI, + RV64_ASMFL_C16, + {0, 0}}; return &dyn; } if (op == 2u && f3 == 1u) { - dyn = (Rv64InsnDesc){slice_from_cstr("c.fldsp"), hw, 0xffffu, RV64_FMT_CI, - RV64_ASMFL_C16 | RV64_ASMFL_FP, {0, 0}}; + dyn = (Rv64InsnDesc){ + slice_from_cstr("c.fldsp"), hw, 0xffffu, RV64_FMT_CI, + RV64_ASMFL_C16 | RV64_ASMFL_FP, {0, 0}}; return &dyn; } /* C.SWSP / C.SDSP — quadrant 2, funct3=110/111 */ if (op == 2u && f3 == 6u) { - dyn = (Rv64InsnDesc){slice_from_cstr("c.swsp"), hw, 0xffffu, RV64_FMT_CSS, - RV64_ASMFL_C16, {0, 0}}; + dyn = (Rv64InsnDesc){slice_from_cstr("c.swsp"), + hw, + 0xffffu, + RV64_FMT_CSS, + RV64_ASMFL_C16, + {0, 0}}; return &dyn; } if (op == 2u && f3 == 7u) { - dyn = (Rv64InsnDesc){slice_from_cstr("c.sdsp"), hw, 0xffffu, RV64_FMT_CSS, - RV64_ASMFL_C16, {0, 0}}; + dyn = (Rv64InsnDesc){slice_from_cstr("c.sdsp"), + hw, + 0xffffu, + RV64_FMT_CSS, + RV64_ASMFL_C16, + {0, 0}}; return &dyn; } if (op == 2u && f3 == 5u) { - dyn = (Rv64InsnDesc){slice_from_cstr("c.fsdsp"), hw, 0xffffu, RV64_FMT_CSS, - RV64_ASMFL_C16 | RV64_ASMFL_FP, {0, 0}}; + dyn = (Rv64InsnDesc){ + slice_from_cstr("c.fsdsp"), hw, 0xffffu, RV64_FMT_CSS, + RV64_ASMFL_C16 | RV64_ASMFL_FP, {0, 0}}; return &dyn; } /* C.ADDI4SPN — quadrant 0, funct3=000 */ if (op == 0u && f3 == 0u) { - dyn = (Rv64InsnDesc){slice_from_cstr("c.addi4spn"), hw, 0xffffu, RV64_FMT_CIW, - RV64_ASMFL_C16, {0, 0}}; + dyn = (Rv64InsnDesc){slice_from_cstr("c.addi4spn"), + hw, + 0xffffu, + RV64_FMT_CIW, + RV64_ASMFL_C16, + {0, 0}}; return &dyn; } /* C.LW / C.LD — quadrant 0, funct3=010/011 */ if (op == 0u && f3 == 2u) { - dyn = (Rv64InsnDesc){slice_from_cstr("c.lw"), hw, 0xffffu, RV64_FMT_CL, - RV64_ASMFL_C16, {0, 0}}; + dyn = (Rv64InsnDesc){slice_from_cstr("c.lw"), hw, 0xffffu, RV64_FMT_CL, + RV64_ASMFL_C16, {0, 0}}; return &dyn; } if (op == 0u && f3 == 3u) { - dyn = (Rv64InsnDesc){slice_from_cstr("c.ld"), hw, 0xffffu, RV64_FMT_CL, - RV64_ASMFL_C16, {0, 0}}; + dyn = (Rv64InsnDesc){slice_from_cstr("c.ld"), hw, 0xffffu, RV64_FMT_CL, + RV64_ASMFL_C16, {0, 0}}; return &dyn; } if (op == 0u && f3 == 1u) { - dyn = (Rv64InsnDesc){slice_from_cstr("c.fld"), hw, 0xffffu, RV64_FMT_CL, - RV64_ASMFL_C16 | RV64_ASMFL_FP, {0, 0}}; + dyn = (Rv64InsnDesc){ + slice_from_cstr("c.fld"), hw, 0xffffu, RV64_FMT_CL, + RV64_ASMFL_C16 | RV64_ASMFL_FP, {0, 0}}; return &dyn; } if (op == 0u && f3 == 6u) { - dyn = (Rv64InsnDesc){slice_from_cstr("c.sw"), hw, 0xffffu, RV64_FMT_CS, - RV64_ASMFL_C16, {0, 0}}; + dyn = (Rv64InsnDesc){slice_from_cstr("c.sw"), hw, 0xffffu, RV64_FMT_CS, + RV64_ASMFL_C16, {0, 0}}; return &dyn; } if (op == 0u && f3 == 7u) { - dyn = (Rv64InsnDesc){slice_from_cstr("c.sd"), hw, 0xffffu, RV64_FMT_CS, - RV64_ASMFL_C16, {0, 0}}; + dyn = (Rv64InsnDesc){slice_from_cstr("c.sd"), hw, 0xffffu, RV64_FMT_CS, + RV64_ASMFL_C16, {0, 0}}; return &dyn; } if (op == 0u && f3 == 5u) { - dyn = (Rv64InsnDesc){slice_from_cstr("c.fsd"), hw, 0xffffu, RV64_FMT_CS, - RV64_ASMFL_C16 | RV64_ASMFL_FP, {0, 0}}; + dyn = (Rv64InsnDesc){ + slice_from_cstr("c.fsd"), hw, 0xffffu, RV64_FMT_CS, + RV64_ASMFL_C16 | RV64_ASMFL_FP, {0, 0}}; return &dyn; } return NULL; @@ -786,17 +1329,16 @@ const Rv64InsnDesc* rv64_disasm_find_c(u32 word) { * Operand print — one helper per format. */ static const char* const RV_XNAMES[32] = { - "zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", - "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", - "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", - "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", + "zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", + "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2", "s3", "s4", "s5", + "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6", }; static const char* const RV_FNAMES[32] = { - "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7", - "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", - "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7", - "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11", + "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7", + "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", + "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7", + "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11", }; static void p_xreg(StrBuf* sb, u32 r) { strbuf_puts(sb, RV_XNAMES[r & 31u]); } @@ -809,20 +1351,27 @@ static void p_mem(StrBuf* sb, i64 off, u32 base) { strbuf_putc(sb, ')'); } static void p_rel(StrBuf* sb, u64 vaddr, i64 off) { - if (vaddr) strbuf_put_hex_u64(sb, vaddr + (u64)off); - else { strbuf_putc(sb, '#'); strbuf_put_i64(sb, off); } + if (vaddr) + strbuf_put_hex_u64(sb, vaddr + (u64)off); + else { + strbuf_putc(sb, '#'); + strbuf_put_i64(sb, off); + } } static void print_r(StrBuf* sb, u32 w, const Rv64InsnDesc* d) { Rv64R f = rv64_r_unpack(w); /* Two-operand aliases (snez/neg/negw) drop rs1=x0 from the print. */ if (d->flags & RV64_ASMFL_ALIAS) { - p_xreg(sb, f.rd); p_sep(sb); + p_xreg(sb, f.rd); + p_sep(sb); p_xreg(sb, f.rs2); return; } - p_xreg(sb, f.rd); p_sep(sb); - p_xreg(sb, f.rs1); p_sep(sb); + p_xreg(sb, f.rd); + p_sep(sb); + p_xreg(sb, f.rs1); + p_sep(sb); p_xreg(sb, f.rs2); } @@ -831,9 +1380,12 @@ static void print_r4(StrBuf* sb, u32 w) { u32 rs1 = (w >> 15) & 0x1fu; u32 rs2 = (w >> 20) & 0x1fu; u32 rs3 = (w >> 27) & 0x1fu; - p_freg(sb, rd); p_sep(sb); - p_freg(sb, rs1); p_sep(sb); - p_freg(sb, rs2); p_sep(sb); + p_freg(sb, rd); + p_sep(sb); + p_freg(sb, rs1); + p_sep(sb); + p_freg(sb, rs2); + p_sep(sb); p_freg(sb, rs3); } @@ -842,27 +1394,37 @@ static void print_i(StrBuf* sb, u32 w, const Rv64InsnDesc* d) { i64 imm = rv64_sext((u64)f.imm12, 12); /* Alias: `li rd, imm` — print rd, imm. */ if ((d->flags & RV64_ASMFL_ALIAS) && slice_eq_cstr(d->mnemonic, "li")) { - p_xreg(sb, f.rd); p_sep(sb); strbuf_put_i64(sb, imm); + p_xreg(sb, f.rd); + p_sep(sb); + strbuf_put_i64(sb, imm); return; } /* Alias: `mv rd, rs1` — print rd, rs1. */ if ((d->flags & RV64_ASMFL_ALIAS) && slice_eq_cstr(d->mnemonic, "mv")) { - p_xreg(sb, f.rd); p_sep(sb); p_xreg(sb, f.rs1); + p_xreg(sb, f.rd); + p_sep(sb); + p_xreg(sb, f.rs1); return; } /* Alias: `sext.w rd, rs1` — print rd, rs1. */ if ((d->flags & RV64_ASMFL_ALIAS) && slice_eq_cstr(d->mnemonic, "sext.w")) { - p_xreg(sb, f.rd); p_sep(sb); p_xreg(sb, f.rs1); + p_xreg(sb, f.rd); + p_sep(sb); + p_xreg(sb, f.rs1); return; } /* Alias: `seqz rd, rs` / `not rd, rs` — print rd, rs (drop imm). */ - if ((d->flags & RV64_ASMFL_ALIAS) && - (slice_eq_cstr(d->mnemonic, "seqz") || slice_eq_cstr(d->mnemonic, "not"))) { - p_xreg(sb, f.rd); p_sep(sb); p_xreg(sb, f.rs1); + if ((d->flags & RV64_ASMFL_ALIAS) && (slice_eq_cstr(d->mnemonic, "seqz") || + slice_eq_cstr(d->mnemonic, "not"))) { + p_xreg(sb, f.rd); + p_sep(sb); + p_xreg(sb, f.rs1); return; } - p_xreg(sb, f.rd); p_sep(sb); - p_xreg(sb, f.rs1); p_sep(sb); + p_xreg(sb, f.rd); + p_sep(sb); + p_xreg(sb, f.rs1); + p_sep(sb); strbuf_put_i64(sb, imm); } @@ -871,8 +1433,10 @@ static void print_i_shift(StrBuf* sb, u32 w) { u32 rd = (w >> 7) & 0x1fu; u32 rs1 = (w >> 15) & 0x1fu; u32 shamt = (w >> 20) & 0x3fu; - p_xreg(sb, rd); p_sep(sb); - p_xreg(sb, rs1); p_sep(sb); + p_xreg(sb, rd); + p_sep(sb); + p_xreg(sb, rs1); + p_sep(sb); strbuf_put_u64(sb, (u64)shamt); } @@ -880,14 +1444,17 @@ static void print_i_shiftw(StrBuf* sb, u32 w) { u32 rd = (w >> 7) & 0x1fu; u32 rs1 = (w >> 15) & 0x1fu; u32 shamt = (w >> 20) & 0x1fu; - p_xreg(sb, rd); p_sep(sb); - p_xreg(sb, rs1); p_sep(sb); + p_xreg(sb, rd); + p_sep(sb); + p_xreg(sb, rs1); + p_sep(sb); strbuf_put_u64(sb, (u64)shamt); } static void print_u(StrBuf* sb, u32 w) { Rv64U f = rv64_u_unpack(w); - p_xreg(sb, f.rd); p_sep(sb); + p_xreg(sb, f.rd); + p_sep(sb); /* The immediate is the upper-20 already shifted into bits 31:12; print * the raw 20-bit value the assembler expects. */ strbuf_put_hex_u64(sb, (u64)(f.imm32_hi20 >> 12)); @@ -896,7 +1463,10 @@ static void print_u(StrBuf* sb, u32 w) { static void print_load(StrBuf* sb, u32 w, const Rv64InsnDesc* d) { Rv64I f = rv64_i_unpack(w); i64 imm = rv64_sext((u64)f.imm12, 12); - if (d->flags & RV64_ASMFL_FP) p_freg(sb, f.rd); else p_xreg(sb, f.rd); + if (d->flags & RV64_ASMFL_FP) + p_freg(sb, f.rd); + else + p_xreg(sb, f.rd); p_sep(sb); p_mem(sb, imm, f.rs1); } @@ -904,7 +1474,10 @@ static void print_load(StrBuf* sb, u32 w, const Rv64InsnDesc* d) { static void print_store(StrBuf* sb, u32 w, const Rv64InsnDesc* d) { Rv64S f = rv64_s_unpack(w); i64 imm = rv64_sext((u64)f.imm12, 12); - if (d->flags & RV64_ASMFL_FP) p_freg(sb, f.rs2); else p_xreg(sb, f.rs2); + if (d->flags & RV64_ASMFL_FP) + p_freg(sb, f.rs2); + else + p_xreg(sb, f.rs2); p_sep(sb); p_mem(sb, imm, f.rs1); } @@ -912,13 +1485,17 @@ static void print_store(StrBuf* sb, u32 w, const Rv64InsnDesc* d) { static void print_b(StrBuf* sb, u32 w, u64 vaddr, const Rv64InsnDesc* d) { Rv64B f = rv64_b_unpack(w); i64 off = rv64_sext((u64)f.imm13, 13); - if ((d->flags & RV64_ASMFL_ALIAS) && - (slice_eq_cstr(d->mnemonic, "beqz") || slice_eq_cstr(d->mnemonic, "bnez"))) { - p_xreg(sb, f.rs1); p_sep(sb); p_rel(sb, vaddr, off); + if ((d->flags & RV64_ASMFL_ALIAS) && (slice_eq_cstr(d->mnemonic, "beqz") || + slice_eq_cstr(d->mnemonic, "bnez"))) { + p_xreg(sb, f.rs1); + p_sep(sb); + p_rel(sb, vaddr, off); return; } - p_xreg(sb, f.rs1); p_sep(sb); - p_xreg(sb, f.rs2); p_sep(sb); + p_xreg(sb, f.rs1); + p_sep(sb); + p_xreg(sb, f.rs2); + p_sep(sb); p_rel(sb, vaddr, off); } @@ -929,7 +1506,8 @@ static void print_j(StrBuf* sb, u32 w, u64 vaddr, const Rv64InsnDesc* d) { p_rel(sb, vaddr, off); return; } - p_xreg(sb, f.rd); p_sep(sb); + p_xreg(sb, f.rd); + p_sep(sb); p_rel(sb, vaddr, off); } @@ -940,7 +1518,8 @@ static void print_jalr(StrBuf* sb, u32 w, const Rv64InsnDesc* d) { p_xreg(sb, f.rs1); return; } - p_xreg(sb, f.rd); p_sep(sb); + p_xreg(sb, f.rd); + p_sep(sb); p_mem(sb, imm, f.rs1); } @@ -972,7 +1551,8 @@ static void print_fence(StrBuf* sb, u32 w) { static void print_csr(StrBuf* sb, u32 w) { Rv64I f = rv64_i_unpack(w); - p_xreg(sb, f.rd); p_sep(sb); + p_xreg(sb, f.rd); + p_sep(sb); strbuf_put_hex_u64(sb, (u64)f.imm12); p_sep(sb); p_xreg(sb, f.rs1); @@ -980,7 +1560,8 @@ static void print_csr(StrBuf* sb, u32 w) { static void print_csri(StrBuf* sb, u32 w) { Rv64I f = rv64_i_unpack(w); - p_xreg(sb, f.rd); p_sep(sb); + p_xreg(sb, f.rd); + p_sep(sb); strbuf_put_hex_u64(sb, (u64)f.imm12); p_sep(sb); strbuf_put_u64(sb, (u64)f.rs1); @@ -988,21 +1569,27 @@ static void print_csri(StrBuf* sb, u32 w) { static void print_fp_rm(StrBuf* sb, u32 w) { Rv64R f = rv64_r_unpack(w); - p_freg(sb, f.rd); p_sep(sb); - p_freg(sb, f.rs1); p_sep(sb); + p_freg(sb, f.rd); + p_sep(sb); + p_freg(sb, f.rs1); + p_sep(sb); p_freg(sb, f.rs2); } static void print_fp_r(StrBuf* sb, u32 w, const Rv64InsnDesc* d) { Rv64R f = rv64_r_unpack(w); if (d->flags & RV64_ASMFL_FP) { - p_freg(sb, f.rd); p_sep(sb); - p_freg(sb, f.rs1); p_sep(sb); + p_freg(sb, f.rd); + p_sep(sb); + p_freg(sb, f.rs1); + p_sep(sb); p_freg(sb, f.rs2); } else { /* FP compare: rd is GPR. */ - p_xreg(sb, f.rd); p_sep(sb); - p_freg(sb, f.rs1); p_sep(sb); + p_xreg(sb, f.rd); + p_sep(sb); + p_freg(sb, f.rs1); + p_sep(sb); p_freg(sb, f.rs2); } } @@ -1011,28 +1598,38 @@ static void print_fp_cvt(StrBuf* sb, u32 w, const Rv64InsnDesc* d) { Rv64R f = rv64_r_unpack(w); /* rd is FP for: fcvt.s.*, fcvt.d.*, fmv.w.x, fmv.d.x, fsqrt.{s,d}. * GPR for: fcvt.w.*, fcvt.l.*, fmv.x.w, fmv.x.d. */ - if (d->flags & RV64_ASMFL_FP) p_freg(sb, f.rd); else p_xreg(sb, f.rd); + if (d->flags & RV64_ASMFL_FP) + p_freg(sb, f.rd); + else + p_xreg(sb, f.rd); p_sep(sb); /* rs1: FP if mnemonic is fcvt.X.{S,D} or fsqrt or fmv.x.{w,d}; * GPR if mnemonic is fcvt.{S,D}.{w,wu,l,lu} or fmv.{w,d}.x. */ int rs1_is_fp = 1; - if (slice_eq_cstr(d->mnemonic, "fmv.w.x") || slice_eq_cstr(d->mnemonic, "fmv.d.x") || + if (slice_eq_cstr(d->mnemonic, "fmv.w.x") || + slice_eq_cstr(d->mnemonic, "fmv.d.x") || slice_has_prefix_cstr(d->mnemonic, "fcvt.s.", 7) || slice_has_prefix_cstr(d->mnemonic, "fcvt.d.", 7)) { /* These have rs1 as integer GPR (source is integer). Exception: * fcvt.s.d / fcvt.d.s have rs1 as FP. */ - if (slice_eq_cstr(d->mnemonic, "fcvt.s.d") || slice_eq_cstr(d->mnemonic, "fcvt.d.s")) + if (slice_eq_cstr(d->mnemonic, "fcvt.s.d") || + slice_eq_cstr(d->mnemonic, "fcvt.d.s")) rs1_is_fp = 1; else rs1_is_fp = 0; } - if (rs1_is_fp) p_freg(sb, f.rs1); else p_xreg(sb, f.rs1); + if (rs1_is_fp) + p_freg(sb, f.rs1); + else + p_xreg(sb, f.rs1); } static void print_amo(StrBuf* sb, u32 w) { Rv64R f = rv64_r_unpack(w); - p_xreg(sb, f.rd); p_sep(sb); - p_xreg(sb, f.rs2); p_sep(sb); + p_xreg(sb, f.rd); + p_sep(sb); + p_xreg(sb, f.rs2); + p_sep(sb); strbuf_putc(sb, '('); p_xreg(sb, f.rs1); strbuf_putc(sb, ')'); @@ -1040,7 +1637,8 @@ static void print_amo(StrBuf* sb, u32 w) { static void print_lr(StrBuf* sb, u32 w) { Rv64R f = rv64_r_unpack(w); - p_xreg(sb, f.rd); p_sep(sb); + p_xreg(sb, f.rd); + p_sep(sb); strbuf_putc(sb, '('); p_xreg(sb, f.rs1); strbuf_putc(sb, ')'); @@ -1052,11 +1650,14 @@ static void print_cr(StrBuf* sb, u32 w, const Rv64InsnDesc* d) { u32 hw = w & 0xffffu; u32 rd_rs1 = (hw >> 7) & 0x1fu; u32 rs2 = (hw >> 2) & 0x1fu; - if (slice_eq_cstr(d->mnemonic, "c.jr") || slice_eq_cstr(d->mnemonic, "c.jalr")) { + if (slice_eq_cstr(d->mnemonic, "c.jr") || + slice_eq_cstr(d->mnemonic, "c.jalr")) { p_xreg(sb, rd_rs1); } else { /* c.mv / c.add */ - p_xreg(sb, rd_rs1); p_sep(sb); p_xreg(sb, rs2); + p_xreg(sb, rd_rs1); + p_sep(sb); + p_xreg(sb, rs2); } } @@ -1071,7 +1672,8 @@ static void print_ci(StrBuf* sb, u32 w, const Rv64InsnDesc* d) { /* nzimm[17:12] = bits 12, 6:2 — signed extended to 18 bits. */ u64 raw = (u64)((imm5 << 5) | imm4_0); imm = rv64_sext(raw, 6) << 12; - p_xreg(sb, rd_rs1); p_sep(sb); + p_xreg(sb, rd_rs1); + p_sep(sb); strbuf_put_hex_u64(sb, (u64)imm); return; } @@ -1085,7 +1687,8 @@ static void print_ci(StrBuf* sb, u32 w, const Rv64InsnDesc* d) { u64 raw = ((u64)b9 << 9) | ((u64)b87 << 7) | ((u64)b6 << 6) | ((u64)b5 << 5) | ((u64)b4 << 4); imm = rv64_sext(raw, 10); - p_xreg(sb, rd_rs1); p_sep(sb); + p_xreg(sb, rd_rs1); + p_sep(sb); strbuf_put_i64(sb, imm); return; } @@ -1095,31 +1698,37 @@ static void print_ci(StrBuf* sb, u32 w, const Rv64InsnDesc* d) { u32 b4_2 = (imm4_0 >> 2) & 7u; u32 b7_6 = imm4_0 & 3u; u32 off = (b7_6 << 6) | (b5 << 5) | (b4_2 << 2); - p_xreg(sb, rd_rs1); p_sep(sb); + p_xreg(sb, rd_rs1); + p_sep(sb); p_mem(sb, (i64)off, 2u); return; } - if (slice_eq_cstr(d->mnemonic, "c.ldsp") || slice_eq_cstr(d->mnemonic, "c.fldsp")) { + if (slice_eq_cstr(d->mnemonic, "c.ldsp") || + slice_eq_cstr(d->mnemonic, "c.fldsp")) { /* offset[5|4:3|8:6] scaled by 8. */ u32 b5 = imm5; u32 b4_3 = (imm4_0 >> 3) & 3u; u32 b8_6 = imm4_0 & 7u; u32 off = (b8_6 << 6) | (b5 << 5) | (b4_3 << 3); - if (d->flags & RV64_ASMFL_FP) p_freg(sb, rd_rs1); - else p_xreg(sb, rd_rs1); + if (d->flags & RV64_ASMFL_FP) + p_freg(sb, rd_rs1); + else + p_xreg(sb, rd_rs1); p_sep(sb); p_mem(sb, (i64)off, 2u); return; } if (slice_eq_cstr(d->mnemonic, "c.slli")) { u32 shamt = (imm5 << 5) | imm4_0; - p_xreg(sb, rd_rs1); p_sep(sb); + p_xreg(sb, rd_rs1); + p_sep(sb); strbuf_put_u64(sb, (u64)shamt); return; } /* c.li / c.addi — signed 6-bit immediate. */ imm = rv64_sext((u64)((imm5 << 5) | imm4_0), 6); - p_xreg(sb, rd_rs1); p_sep(sb); + p_xreg(sb, rd_rs1); + p_sep(sb); strbuf_put_i64(sb, imm); } @@ -1133,7 +1742,8 @@ static void print_css(StrBuf* sb, u32 w, const Rv64InsnDesc* d) { u32 b5_2 = (imm6 >> 2) & 0xfu; u32 b7_6 = imm6 & 3u; off = (b7_6 << 6) | (b5_2 << 2); - p_xreg(sb, rs2); p_sep(sb); + p_xreg(sb, rs2); + p_sep(sb); p_mem(sb, (i64)off, 2u); return; } @@ -1142,8 +1752,10 @@ static void print_css(StrBuf* sb, u32 w, const Rv64InsnDesc* d) { u32 b5_3 = (imm6 >> 3) & 7u; u32 b8_6 = imm6 & 7u; off = (b8_6 << 6) | (b5_3 << 3); - if (d->flags & RV64_ASMFL_FP) p_freg(sb, rs2); - else p_xreg(sb, rs2); + if (d->flags & RV64_ASMFL_FP) + p_freg(sb, rs2); + else + p_xreg(sb, rs2); p_sep(sb); p_mem(sb, (i64)off, 2u); } @@ -1159,8 +1771,10 @@ static void print_ciw(StrBuf* sb, u32 w) { u32 b2 = (imm >> 1) & 1u; u32 b3 = imm & 1u; u32 off = (b9_6 << 6) | (b5_4 << 4) | (b3 << 3) | (b2 << 2); - p_xreg(sb, RVC_REG3(rd3)); p_sep(sb); - strbuf_puts(sb, "sp"); p_sep(sb); + p_xreg(sb, RVC_REG3(rd3)); + p_sep(sb); + strbuf_puts(sb, "sp"); + p_sep(sb); strbuf_put_u64(sb, (u64)off); } @@ -1180,8 +1794,10 @@ static void print_cl(StrBuf* sb, u32 w, const Rv64InsnDesc* d) { /* c.ld: offset[5:3|7:6] scaled by 8. */ off = (lo << 6) | (b5_3 << 3); } - if (d->flags & RV64_ASMFL_FP) p_freg(sb, RVC_REG3(rd3)); - else p_xreg(sb, RVC_REG3(rd3)); + if (d->flags & RV64_ASMFL_FP) + p_freg(sb, RVC_REG3(rd3)); + else + p_xreg(sb, RVC_REG3(rd3)); p_sep(sb); p_mem(sb, (i64)off, RVC_REG3(rs1_3)); } @@ -1200,8 +1816,10 @@ static void print_cs(StrBuf* sb, u32 w, const Rv64InsnDesc* d) { } else { off = (lo << 6) | (b5_3 << 3); } - if (d->flags & RV64_ASMFL_FP) p_freg(sb, RVC_REG3(rs2_3)); - else p_xreg(sb, RVC_REG3(rs2_3)); + if (d->flags & RV64_ASMFL_FP) + p_freg(sb, RVC_REG3(rs2_3)); + else + p_xreg(sb, RVC_REG3(rs2_3)); p_sep(sb); p_mem(sb, (i64)off, RVC_REG3(rs1_3)); } @@ -1210,17 +1828,20 @@ static void print_ca(StrBuf* sb, u32 w) { u32 hw = w & 0xffffu; u32 rd3 = (hw >> 7) & 7u; u32 rs2_3 = (hw >> 2) & 7u; - p_xreg(sb, RVC_REG3(rd3)); p_sep(sb); + p_xreg(sb, RVC_REG3(rd3)); + p_sep(sb); p_xreg(sb, RVC_REG3(rs2_3)); } static void print_cb(StrBuf* sb, u32 w, u64 vaddr, const Rv64InsnDesc* d) { u32 hw = w & 0xffffu; u32 rs1_3 = (hw >> 7) & 7u; - if (slice_eq_cstr(d->mnemonic, "c.srli") || slice_eq_cstr(d->mnemonic, "c.srai") || + if (slice_eq_cstr(d->mnemonic, "c.srli") || + slice_eq_cstr(d->mnemonic, "c.srai") || slice_eq_cstr(d->mnemonic, "c.andi")) { u32 imm = (((hw >> 12) & 1u) << 5) | ((hw >> 2) & 0x1fu); - p_xreg(sb, RVC_REG3(rs1_3)); p_sep(sb); + p_xreg(sb, RVC_REG3(rs1_3)); + p_sep(sb); if (slice_eq_cstr(d->mnemonic, "c.andi")) strbuf_put_i64(sb, rv64_sext((u64)imm, 6)); else @@ -1236,7 +1857,8 @@ static void print_cb(StrBuf* sb, u32 w, u64 vaddr, const Rv64InsnDesc* d) { u64 raw = ((u64)b8 << 8) | ((u64)b7_6 << 6) | ((u64)b5 << 5) | ((u64)b4_3 << 3) | ((u64)b2_1 << 1); i64 off = rv64_sext(raw, 9); - p_xreg(sb, RVC_REG3(rs1_3)); p_sep(sb); + p_xreg(sb, RVC_REG3(rs1_3)); + p_sep(sb); p_rel(sb, vaddr, off); } @@ -1252,8 +1874,8 @@ static void print_cj(StrBuf* sb, u32 w, u64 vaddr) { u32 b3_1 = (hw >> 3) & 7u; u32 b5 = (hw >> 2) & 1u; u64 raw = ((u64)b11 << 11) | ((u64)b10 << 10) | ((u64)b9_8 << 8) | - ((u64)b7 << 7) | ((u64)b6 << 6) | ((u64)b5 << 5) | - ((u64)b4 << 4) | ((u64)b3_1 << 1); + ((u64)b7 << 7) | ((u64)b6 << 6) | ((u64)b5 << 5) | ((u64)b4 << 4) | + ((u64)b3_1 << 1); i64 off = rv64_sext(raw, 12); p_rel(sb, vaddr, off); } @@ -1261,38 +1883,102 @@ static void print_cj(StrBuf* sb, u32 w, u64 vaddr) { void rv64_print_operands(StrBuf* sb, const Rv64InsnDesc* desc, u32 word, u64 vaddr) { switch ((Rv64Format)desc->fmt) { - case RV64_FMT_R: print_r(sb, word, desc); break; - case RV64_FMT_R4: print_r4(sb, word); break; - case RV64_FMT_I: print_i(sb, word, desc); break; - case RV64_FMT_I_SHIFT: print_i_shift(sb, word); break; - case RV64_FMT_I_SHIFTW: print_i_shiftw(sb, word); break; - case RV64_FMT_S: print_store(sb, word, desc); break; - case RV64_FMT_B: print_b(sb, word, vaddr, desc); break; - case RV64_FMT_U: print_u(sb, word); break; - case RV64_FMT_J: print_j(sb, word, vaddr, desc); break; - case RV64_FMT_LOAD: print_load(sb, word, desc); break; - case RV64_FMT_STORE: print_store(sb, word, desc); break; - case RV64_FMT_JALR: print_jalr(sb, word, desc); break; - case RV64_FMT_FENCE: print_fence(sb, word); break; - case RV64_FMT_SYSTEM: break; /* no operands */ - case RV64_FMT_FP_RM: print_fp_rm(sb, word); break; - case RV64_FMT_FP_R: print_fp_r(sb, word, desc); break; - case RV64_FMT_FP_CVT: print_fp_cvt(sb, word, desc); break; - case RV64_FMT_FP_LOAD: print_load(sb, word, desc); break; - case RV64_FMT_FP_STORE: print_store(sb, word, desc); break; - case RV64_FMT_AMO: print_amo(sb, word); break; - case RV64_FMT_LR: print_lr(sb, word); break; - case RV64_FMT_CSR: print_csr(sb, word); break; - case RV64_FMT_CSRI: print_csri(sb, word); break; - case RV64_FMT_CR: print_cr(sb, word, desc); break; - case RV64_FMT_CI: print_ci(sb, word, desc); break; - case RV64_FMT_CSS: print_css(sb, word, desc); break; - case RV64_FMT_CIW: print_ciw(sb, word); break; - case RV64_FMT_CL: print_cl(sb, word, desc); break; - case RV64_FMT_CS: print_cs(sb, word, desc); break; - case RV64_FMT_CA: print_ca(sb, word); break; - case RV64_FMT_CB: print_cb(sb, word, vaddr, desc); break; - case RV64_FMT_CJ: print_cj(sb, word, vaddr); break; - case RV64_FMT_C_NONE: break; + case RV64_FMT_R: + print_r(sb, word, desc); + break; + case RV64_FMT_R4: + print_r4(sb, word); + break; + case RV64_FMT_I: + print_i(sb, word, desc); + break; + case RV64_FMT_I_SHIFT: + print_i_shift(sb, word); + break; + case RV64_FMT_I_SHIFTW: + print_i_shiftw(sb, word); + break; + case RV64_FMT_S: + print_store(sb, word, desc); + break; + case RV64_FMT_B: + print_b(sb, word, vaddr, desc); + break; + case RV64_FMT_U: + print_u(sb, word); + break; + case RV64_FMT_J: + print_j(sb, word, vaddr, desc); + break; + case RV64_FMT_LOAD: + print_load(sb, word, desc); + break; + case RV64_FMT_STORE: + print_store(sb, word, desc); + break; + case RV64_FMT_JALR: + print_jalr(sb, word, desc); + break; + case RV64_FMT_FENCE: + print_fence(sb, word); + break; + case RV64_FMT_SYSTEM: + break; /* no operands */ + case RV64_FMT_FP_RM: + print_fp_rm(sb, word); + break; + case RV64_FMT_FP_R: + print_fp_r(sb, word, desc); + break; + case RV64_FMT_FP_CVT: + print_fp_cvt(sb, word, desc); + break; + case RV64_FMT_FP_LOAD: + print_load(sb, word, desc); + break; + case RV64_FMT_FP_STORE: + print_store(sb, word, desc); + break; + case RV64_FMT_AMO: + print_amo(sb, word); + break; + case RV64_FMT_LR: + print_lr(sb, word); + break; + case RV64_FMT_CSR: + print_csr(sb, word); + break; + case RV64_FMT_CSRI: + print_csri(sb, word); + break; + case RV64_FMT_CR: + print_cr(sb, word, desc); + break; + case RV64_FMT_CI: + print_ci(sb, word, desc); + break; + case RV64_FMT_CSS: + print_css(sb, word, desc); + break; + case RV64_FMT_CIW: + print_ciw(sb, word); + break; + case RV64_FMT_CL: + print_cl(sb, word, desc); + break; + case RV64_FMT_CS: + print_cs(sb, word, desc); + break; + case RV64_FMT_CA: + print_ca(sb, word); + break; + case RV64_FMT_CB: + print_cb(sb, word, vaddr, desc); + break; + case RV64_FMT_CJ: + print_cj(sb, word, vaddr); + break; + case RV64_FMT_C_NONE: + break; } } diff --git a/src/arch/rv64/isa.h b/src/arch/rv64/isa.h @@ -15,30 +15,55 @@ /* ---- Named registers (DWARF / psABI numbering matches HW) ---- */ enum { - RV_X0 = 0, RV_ZERO = 0, - RV_X1 = 1, RV_RA = 1, - RV_X2 = 2, RV_SP = 2, - RV_X3 = 3, RV_GP = 3, - RV_X4 = 4, RV_TP = 4, - RV_X5 = 5, RV_T0 = 5, - RV_X6 = 6, RV_T1 = 6, - RV_X7 = 7, RV_T2 = 7, - RV_X8 = 8, RV_S0 = 8, RV_FP = 8, - RV_X9 = 9, RV_S1 = 9, - RV_X10 = 10, RV_A0 = 10, - RV_X11 = 11, RV_A1 = 11, - RV_X12 = 12, RV_A2 = 12, - RV_X13 = 13, RV_A3 = 13, - RV_X14 = 14, RV_A4 = 14, - RV_X15 = 15, RV_A5 = 15, - RV_X16 = 16, RV_A6 = 16, - RV_X17 = 17, RV_A7 = 17, - RV_X18 = 18, RV_S2 = 18, - RV_X27 = 27, RV_S11 = 27, - RV_X28 = 28, RV_T3 = 28, - RV_X29 = 29, RV_T4 = 29, - RV_X30 = 30, RV_T5 = 30, - RV_X31 = 31, RV_T6 = 31, + RV_X0 = 0, + RV_ZERO = 0, + RV_X1 = 1, + RV_RA = 1, + RV_X2 = 2, + RV_SP = 2, + RV_X3 = 3, + RV_GP = 3, + RV_X4 = 4, + RV_TP = 4, + RV_X5 = 5, + RV_T0 = 5, + RV_X6 = 6, + RV_T1 = 6, + RV_X7 = 7, + RV_T2 = 7, + RV_X8 = 8, + RV_S0 = 8, + RV_FP = 8, + RV_X9 = 9, + RV_S1 = 9, + RV_X10 = 10, + RV_A0 = 10, + RV_X11 = 11, + RV_A1 = 11, + RV_X12 = 12, + RV_A2 = 12, + RV_X13 = 13, + RV_A3 = 13, + RV_X14 = 14, + RV_A4 = 14, + RV_X15 = 15, + RV_A5 = 15, + RV_X16 = 16, + RV_A6 = 16, + RV_X17 = 17, + RV_A7 = 17, + RV_X18 = 18, + RV_S2 = 18, + RV_X27 = 27, + RV_S11 = 27, + RV_X28 = 28, + RV_T3 = 28, + RV_X29 = 29, + RV_T4 = 29, + RV_X30 = 30, + RV_T5 = 30, + RV_X31 = 31, + RV_T6 = 31, }; #define RV_NOP 0x00000013u /* ADDI x0, x0, 0 */ @@ -47,17 +72,18 @@ enum { * * R-type: funct7(31:25) rs2(24:20) rs1(19:15) funct3(14:12) rd(11:7) op(6:0) * I-type: imm(31:20) rs1(19:15) funct3(14:12) rd(11:7) op(6:0) - * S-type: imm[11:5](31:25) rs2(24:20) rs1(19:15) funct3(14:12) imm[4:0](11:7) op(6:0) - * B-type: imm[12](31) imm[10:5](30:25) rs2(24:20) rs1(19:15) funct3(14:12) imm[4:1](11:8) imm[11](7) op(6:0) - * U-type: imm[31:12](31:12) rd(11:7) op(6:0) - * J-type: imm[20](31) imm[10:1](30:21) imm[11](20) imm[19:12](19:12) rd(11:7) op(6:0) + * S-type: imm[11:5](31:25) rs2(24:20) rs1(19:15) funct3(14:12) imm[4:0](11:7) + * op(6:0) B-type: imm[12](31) imm[10:5](30:25) rs2(24:20) rs1(19:15) + * funct3(14:12) imm[4:1](11:8) imm[11](7) op(6:0) U-type: imm[31:12](31:12) + * rd(11:7) op(6:0) J-type: imm[20](31) imm[10:1](30:21) imm[11](20) + * imm[19:12](19:12) rd(11:7) op(6:0) */ static inline u32 rv_r(u32 funct7, u32 rs2, u32 rs1, u32 funct3, u32 rd, u32 op) { return ((funct7 & 0x7fu) << 25) | ((rs2 & 0x1fu) << 20) | - ((rs1 & 0x1fu) << 15) | ((funct3 & 0x7u) << 12) | - ((rd & 0x1fu) << 7) | (op & 0x7fu); + ((rs1 & 0x1fu) << 15) | ((funct3 & 0x7u) << 12) | ((rd & 0x1fu) << 7) | + (op & 0x7fu); } static inline u32 rv_i(i32 imm12, u32 rs1, u32 funct3, u32 rd, u32 op) { return (((u32)imm12 & 0xfffu) << 20) | ((rs1 & 0x1fu) << 15) | @@ -87,51 +113,93 @@ static inline u32 rv_j(i32 imm21, u32 rd, u32 op) { /* ---- Integer ops (RV32I/RV64I) ---- */ -#define RV_OP 0x33u -#define RV_OP_IMM 0x13u -#define RV_OP_32 0x3bu +#define RV_OP 0x33u +#define RV_OP_IMM 0x13u +#define RV_OP_32 0x3bu #define RV_OP_IMM_32 0x1bu -#define RV_LUI 0x37u -#define RV_AUIPC 0x17u -#define RV_LOAD 0x03u -#define RV_STORE 0x23u -#define RV_BRANCH 0x63u -#define RV_JAL 0x6fu -#define RV_JALR 0x67u -#define RV_LOAD_FP 0x07u -#define RV_STORE_FP 0x27u -#define RV_OP_FP 0x53u -#define RV_MADD 0x43u -#define RV_MSUB 0x47u -#define RV_NMSUB 0x4bu -#define RV_NMADD 0x4fu -#define RV_AMO 0x2fu -#define RV_FENCE 0x0fu -#define RV_SYSTEM 0x73u - -static inline u32 rv_add(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x00, rs2, rs1, 0x0, rd, RV_OP); } -static inline u32 rv_sub(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x20, rs2, rs1, 0x0, rd, RV_OP); } -static inline u32 rv_sll(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x00, rs2, rs1, 0x1, rd, RV_OP); } -static inline u32 rv_slt(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x00, rs2, rs1, 0x2, rd, RV_OP); } -static inline u32 rv_sltu(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x00, rs2, rs1, 0x3, rd, RV_OP); } -static inline u32 rv_xor(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x00, rs2, rs1, 0x4, rd, RV_OP); } -static inline u32 rv_srl(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x00, rs2, rs1, 0x5, rd, RV_OP); } -static inline u32 rv_sra(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x20, rs2, rs1, 0x5, rd, RV_OP); } -static inline u32 rv_or(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x00, rs2, rs1, 0x6, rd, RV_OP); } -static inline u32 rv_and(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x00, rs2, rs1, 0x7, rd, RV_OP); } - -static inline u32 rv_addw(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x00, rs2, rs1, 0x0, rd, RV_OP_32); } -static inline u32 rv_subw(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x20, rs2, rs1, 0x0, rd, RV_OP_32); } -static inline u32 rv_sllw(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x00, rs2, rs1, 0x1, rd, RV_OP_32); } -static inline u32 rv_srlw(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x00, rs2, rs1, 0x5, rd, RV_OP_32); } -static inline u32 rv_sraw(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x20, rs2, rs1, 0x5, rd, RV_OP_32); } - -static inline u32 rv_addi(u32 rd, u32 rs1, i32 imm) { return rv_i(imm, rs1, 0x0, rd, RV_OP_IMM); } -static inline u32 rv_slti(u32 rd, u32 rs1, i32 imm) { return rv_i(imm, rs1, 0x2, rd, RV_OP_IMM); } -static inline u32 rv_sltiu(u32 rd, u32 rs1, i32 imm) { return rv_i(imm, rs1, 0x3, rd, RV_OP_IMM); } -static inline u32 rv_xori(u32 rd, u32 rs1, i32 imm) { return rv_i(imm, rs1, 0x4, rd, RV_OP_IMM); } -static inline u32 rv_ori(u32 rd, u32 rs1, i32 imm) { return rv_i(imm, rs1, 0x6, rd, RV_OP_IMM); } -static inline u32 rv_andi(u32 rd, u32 rs1, i32 imm) { return rv_i(imm, rs1, 0x7, rd, RV_OP_IMM); } +#define RV_LUI 0x37u +#define RV_AUIPC 0x17u +#define RV_LOAD 0x03u +#define RV_STORE 0x23u +#define RV_BRANCH 0x63u +#define RV_JAL 0x6fu +#define RV_JALR 0x67u +#define RV_LOAD_FP 0x07u +#define RV_STORE_FP 0x27u +#define RV_OP_FP 0x53u +#define RV_MADD 0x43u +#define RV_MSUB 0x47u +#define RV_NMSUB 0x4bu +#define RV_NMADD 0x4fu +#define RV_AMO 0x2fu +#define RV_FENCE 0x0fu +#define RV_SYSTEM 0x73u + +static inline u32 rv_add(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x00, rs2, rs1, 0x0, rd, RV_OP); +} +static inline u32 rv_sub(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x20, rs2, rs1, 0x0, rd, RV_OP); +} +static inline u32 rv_sll(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x00, rs2, rs1, 0x1, rd, RV_OP); +} +static inline u32 rv_slt(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x00, rs2, rs1, 0x2, rd, RV_OP); +} +static inline u32 rv_sltu(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x00, rs2, rs1, 0x3, rd, RV_OP); +} +static inline u32 rv_xor(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x00, rs2, rs1, 0x4, rd, RV_OP); +} +static inline u32 rv_srl(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x00, rs2, rs1, 0x5, rd, RV_OP); +} +static inline u32 rv_sra(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x20, rs2, rs1, 0x5, rd, RV_OP); +} +static inline u32 rv_or(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x00, rs2, rs1, 0x6, rd, RV_OP); +} +static inline u32 rv_and(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x00, rs2, rs1, 0x7, rd, RV_OP); +} + +static inline u32 rv_addw(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x00, rs2, rs1, 0x0, rd, RV_OP_32); +} +static inline u32 rv_subw(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x20, rs2, rs1, 0x0, rd, RV_OP_32); +} +static inline u32 rv_sllw(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x00, rs2, rs1, 0x1, rd, RV_OP_32); +} +static inline u32 rv_srlw(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x00, rs2, rs1, 0x5, rd, RV_OP_32); +} +static inline u32 rv_sraw(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x20, rs2, rs1, 0x5, rd, RV_OP_32); +} + +static inline u32 rv_addi(u32 rd, u32 rs1, i32 imm) { + return rv_i(imm, rs1, 0x0, rd, RV_OP_IMM); +} +static inline u32 rv_slti(u32 rd, u32 rs1, i32 imm) { + return rv_i(imm, rs1, 0x2, rd, RV_OP_IMM); +} +static inline u32 rv_sltiu(u32 rd, u32 rs1, i32 imm) { + return rv_i(imm, rs1, 0x3, rd, RV_OP_IMM); +} +static inline u32 rv_xori(u32 rd, u32 rs1, i32 imm) { + return rv_i(imm, rs1, 0x4, rd, RV_OP_IMM); +} +static inline u32 rv_ori(u32 rd, u32 rs1, i32 imm) { + return rv_i(imm, rs1, 0x6, rd, RV_OP_IMM); +} +static inline u32 rv_andi(u32 rd, u32 rs1, i32 imm) { + return rv_i(imm, rs1, 0x7, rd, RV_OP_IMM); +} /* Shift-immediate forms. RV64I uses a 6-bit shamt in bits 25:20 and a * 6-bit funct6 in bits 31:26 (so the funct7-vs-shamt[5] split that @@ -149,72 +217,152 @@ static inline u32 rv_srai(u32 rd, u32 rs1, u32 sh) { (0x5u << 12) | ((rd & 0x1fu) << 7) | RV_OP_IMM; } -static inline u32 rv_addiw(u32 rd, u32 rs1, i32 imm) { return rv_i(imm, rs1, 0x0, rd, RV_OP_IMM_32); } -static inline u32 rv_slliw(u32 rd, u32 rs1, u32 sh) { return rv_r(0x00, sh & 0x1fu, rs1, 0x1, rd, RV_OP_IMM_32); } -static inline u32 rv_srliw(u32 rd, u32 rs1, u32 sh) { return rv_r(0x00, sh & 0x1fu, rs1, 0x5, rd, RV_OP_IMM_32); } -static inline u32 rv_sraiw(u32 rd, u32 rs1, u32 sh) { return rv_r(0x20, sh & 0x1fu, rs1, 0x5, rd, RV_OP_IMM_32); } +static inline u32 rv_addiw(u32 rd, u32 rs1, i32 imm) { + return rv_i(imm, rs1, 0x0, rd, RV_OP_IMM_32); +} +static inline u32 rv_slliw(u32 rd, u32 rs1, u32 sh) { + return rv_r(0x00, sh & 0x1fu, rs1, 0x1, rd, RV_OP_IMM_32); +} +static inline u32 rv_srliw(u32 rd, u32 rs1, u32 sh) { + return rv_r(0x00, sh & 0x1fu, rs1, 0x5, rd, RV_OP_IMM_32); +} +static inline u32 rv_sraiw(u32 rd, u32 rs1, u32 sh) { + return rv_r(0x20, sh & 0x1fu, rs1, 0x5, rd, RV_OP_IMM_32); +} -static inline u32 rv_lui(u32 rd, u32 imm20) { return ((imm20 & 0xfffffu) << 12) | ((rd & 0x1fu) << 7) | RV_LUI; } -static inline u32 rv_auipc(u32 rd, u32 imm20) { return ((imm20 & 0xfffffu) << 12) | ((rd & 0x1fu) << 7) | RV_AUIPC; } +static inline u32 rv_lui(u32 rd, u32 imm20) { + return ((imm20 & 0xfffffu) << 12) | ((rd & 0x1fu) << 7) | RV_LUI; +} +static inline u32 rv_auipc(u32 rd, u32 imm20) { + return ((imm20 & 0xfffffu) << 12) | ((rd & 0x1fu) << 7) | RV_AUIPC; +} /* M extension */ -static inline u32 rv_mul(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x01, rs2, rs1, 0x0, rd, RV_OP); } -static inline u32 rv_mulh(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x01, rs2, rs1, 0x1, rd, RV_OP); } -static inline u32 rv_mulhsu(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x01, rs2, rs1, 0x2, rd, RV_OP); } -static inline u32 rv_mulhu(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x01, rs2, rs1, 0x3, rd, RV_OP); } -static inline u32 rv_div(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x01, rs2, rs1, 0x4, rd, RV_OP); } -static inline u32 rv_divu(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x01, rs2, rs1, 0x5, rd, RV_OP); } -static inline u32 rv_rem(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x01, rs2, rs1, 0x6, rd, RV_OP); } -static inline u32 rv_remu(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x01, rs2, rs1, 0x7, rd, RV_OP); } -static inline u32 rv_mulw(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x01, rs2, rs1, 0x0, rd, RV_OP_32); } -static inline u32 rv_divw(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x01, rs2, rs1, 0x4, rd, RV_OP_32); } -static inline u32 rv_divuw(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x01, rs2, rs1, 0x5, rd, RV_OP_32); } -static inline u32 rv_remw(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x01, rs2, rs1, 0x6, rd, RV_OP_32); } -static inline u32 rv_remuw(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x01, rs2, rs1, 0x7, rd, RV_OP_32); } +static inline u32 rv_mul(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x01, rs2, rs1, 0x0, rd, RV_OP); +} +static inline u32 rv_mulh(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x01, rs2, rs1, 0x1, rd, RV_OP); +} +static inline u32 rv_mulhsu(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x01, rs2, rs1, 0x2, rd, RV_OP); +} +static inline u32 rv_mulhu(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x01, rs2, rs1, 0x3, rd, RV_OP); +} +static inline u32 rv_div(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x01, rs2, rs1, 0x4, rd, RV_OP); +} +static inline u32 rv_divu(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x01, rs2, rs1, 0x5, rd, RV_OP); +} +static inline u32 rv_rem(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x01, rs2, rs1, 0x6, rd, RV_OP); +} +static inline u32 rv_remu(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x01, rs2, rs1, 0x7, rd, RV_OP); +} +static inline u32 rv_mulw(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x01, rs2, rs1, 0x0, rd, RV_OP_32); +} +static inline u32 rv_divw(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x01, rs2, rs1, 0x4, rd, RV_OP_32); +} +static inline u32 rv_divuw(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x01, rs2, rs1, 0x5, rd, RV_OP_32); +} +static inline u32 rv_remw(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x01, rs2, rs1, 0x6, rd, RV_OP_32); +} +static inline u32 rv_remuw(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x01, rs2, rs1, 0x7, rd, RV_OP_32); +} /* Zba (address-generation) subset — assumed available on rv64 targets. * SH{1,2,3}ADD rd, rs1, rs2 computes rd = (rs1 << {1,2,3}) + rs2 in one * instruction (funct7=0x10, opcode=OP). Used by load/store to fold an * indexed effective address `base + (index << log2_scale)` into a single * scratch register without an explicit shift+add pair. */ -static inline u32 rv_sh1add(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x10, rs2, rs1, 0x2, rd, RV_OP); } -static inline u32 rv_sh2add(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x10, rs2, rs1, 0x4, rd, RV_OP); } -static inline u32 rv_sh3add(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x10, rs2, rs1, 0x6, rd, RV_OP); } +static inline u32 rv_sh1add(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x10, rs2, rs1, 0x2, rd, RV_OP); +} +static inline u32 rv_sh2add(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x10, rs2, rs1, 0x4, rd, RV_OP); +} +static inline u32 rv_sh3add(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x10, rs2, rs1, 0x6, rd, RV_OP); +} /* Loads (funct3: 0=LB,1=LH,2=LW,3=LD,4=LBU,5=LHU,6=LWU) */ -static inline u32 rv_lb(u32 rd, u32 rs1, i32 imm) { return rv_i(imm, rs1, 0x0, rd, RV_LOAD); } -static inline u32 rv_lh(u32 rd, u32 rs1, i32 imm) { return rv_i(imm, rs1, 0x1, rd, RV_LOAD); } -static inline u32 rv_lw(u32 rd, u32 rs1, i32 imm) { return rv_i(imm, rs1, 0x2, rd, RV_LOAD); } -static inline u32 rv_ld(u32 rd, u32 rs1, i32 imm) { return rv_i(imm, rs1, 0x3, rd, RV_LOAD); } -static inline u32 rv_lbu(u32 rd, u32 rs1, i32 imm) { return rv_i(imm, rs1, 0x4, rd, RV_LOAD); } -static inline u32 rv_lhu(u32 rd, u32 rs1, i32 imm) { return rv_i(imm, rs1, 0x5, rd, RV_LOAD); } -static inline u32 rv_lwu(u32 rd, u32 rs1, i32 imm) { return rv_i(imm, rs1, 0x6, rd, RV_LOAD); } +static inline u32 rv_lb(u32 rd, u32 rs1, i32 imm) { + return rv_i(imm, rs1, 0x0, rd, RV_LOAD); +} +static inline u32 rv_lh(u32 rd, u32 rs1, i32 imm) { + return rv_i(imm, rs1, 0x1, rd, RV_LOAD); +} +static inline u32 rv_lw(u32 rd, u32 rs1, i32 imm) { + return rv_i(imm, rs1, 0x2, rd, RV_LOAD); +} +static inline u32 rv_ld(u32 rd, u32 rs1, i32 imm) { + return rv_i(imm, rs1, 0x3, rd, RV_LOAD); +} +static inline u32 rv_lbu(u32 rd, u32 rs1, i32 imm) { + return rv_i(imm, rs1, 0x4, rd, RV_LOAD); +} +static inline u32 rv_lhu(u32 rd, u32 rs1, i32 imm) { + return rv_i(imm, rs1, 0x5, rd, RV_LOAD); +} +static inline u32 rv_lwu(u32 rd, u32 rs1, i32 imm) { + return rv_i(imm, rs1, 0x6, rd, RV_LOAD); +} /* Stores (funct3: 0=SB,1=SH,2=SW,3=SD) */ -static inline u32 rv_sb(u32 rs2, u32 rs1, i32 imm) { return rv_s(imm, rs2, rs1, 0x0, RV_STORE); } -static inline u32 rv_sh(u32 rs2, u32 rs1, i32 imm) { return rv_s(imm, rs2, rs1, 0x1, RV_STORE); } -static inline u32 rv_sw(u32 rs2, u32 rs1, i32 imm) { return rv_s(imm, rs2, rs1, 0x2, RV_STORE); } -static inline u32 rv_sd(u32 rs2, u32 rs1, i32 imm) { return rv_s(imm, rs2, rs1, 0x3, RV_STORE); } +static inline u32 rv_sb(u32 rs2, u32 rs1, i32 imm) { + return rv_s(imm, rs2, rs1, 0x0, RV_STORE); +} +static inline u32 rv_sh(u32 rs2, u32 rs1, i32 imm) { + return rv_s(imm, rs2, rs1, 0x1, RV_STORE); +} +static inline u32 rv_sw(u32 rs2, u32 rs1, i32 imm) { + return rv_s(imm, rs2, rs1, 0x2, RV_STORE); +} +static inline u32 rv_sd(u32 rs2, u32 rs1, i32 imm) { + return rv_s(imm, rs2, rs1, 0x3, RV_STORE); +} /* Branches */ -static inline u32 rv_beq(u32 rs1, u32 rs2, i32 imm) { return rv_b(imm, rs2, rs1, 0x0, RV_BRANCH); } -static inline u32 rv_bne(u32 rs1, u32 rs2, i32 imm) { return rv_b(imm, rs2, rs1, 0x1, RV_BRANCH); } -static inline u32 rv_blt(u32 rs1, u32 rs2, i32 imm) { return rv_b(imm, rs2, rs1, 0x4, RV_BRANCH); } -static inline u32 rv_bge(u32 rs1, u32 rs2, i32 imm) { return rv_b(imm, rs2, rs1, 0x5, RV_BRANCH); } -static inline u32 rv_bltu(u32 rs1, u32 rs2, i32 imm) { return rv_b(imm, rs2, rs1, 0x6, RV_BRANCH); } -static inline u32 rv_bgeu(u32 rs1, u32 rs2, i32 imm) { return rv_b(imm, rs2, rs1, 0x7, RV_BRANCH); } +static inline u32 rv_beq(u32 rs1, u32 rs2, i32 imm) { + return rv_b(imm, rs2, rs1, 0x0, RV_BRANCH); +} +static inline u32 rv_bne(u32 rs1, u32 rs2, i32 imm) { + return rv_b(imm, rs2, rs1, 0x1, RV_BRANCH); +} +static inline u32 rv_blt(u32 rs1, u32 rs2, i32 imm) { + return rv_b(imm, rs2, rs1, 0x4, RV_BRANCH); +} +static inline u32 rv_bge(u32 rs1, u32 rs2, i32 imm) { + return rv_b(imm, rs2, rs1, 0x5, RV_BRANCH); +} +static inline u32 rv_bltu(u32 rs1, u32 rs2, i32 imm) { + return rv_b(imm, rs2, rs1, 0x6, RV_BRANCH); +} +static inline u32 rv_bgeu(u32 rs1, u32 rs2, i32 imm) { + return rv_b(imm, rs2, rs1, 0x7, RV_BRANCH); +} /* Jumps */ -static inline u32 rv_jal(u32 rd, i32 imm21) { return rv_j(imm21, rd, RV_JAL); } -static inline u32 rv_jalr(u32 rd, u32 rs1, i32 imm) { return rv_i(imm, rs1, 0x0, rd, RV_JALR); } +static inline u32 rv_jal(u32 rd, i32 imm21) { return rv_j(imm21, rd, RV_JAL); } +static inline u32 rv_jalr(u32 rd, u32 rs1, i32 imm) { + return rv_i(imm, rs1, 0x0, rd, RV_JALR); +} /* Convenience: jr / ret / j / nop */ -static inline u32 rv_jr(u32 rs1) { return rv_jalr(RV_ZERO, rs1, 0); } -static inline u32 rv_ret_(void) { return rv_jalr(RV_ZERO, RV_RA, 0); } -static inline u32 rv_nop(void) { return RV_NOP; } +static inline u32 rv_jr(u32 rs1) { return rv_jalr(RV_ZERO, rs1, 0); } +static inline u32 rv_ret_(void) { return rv_jalr(RV_ZERO, RV_RA, 0); } +static inline u32 rv_nop(void) { return RV_NOP; } /* System */ -static inline u32 rv_ecall(void) { return rv_i(0, 0, 0, 0, RV_SYSTEM); } +static inline u32 rv_ecall(void) { return rv_i(0, 0, 0, 0, RV_SYSTEM); } static inline u32 rv_ebreak(void) { return rv_i(1, 0, 0, 0, RV_SYSTEM); } /* FENCE: pred/succ each 4 bits in imm[11:8]/imm[7:4]. fm bits 11:8 of imm */ @@ -257,44 +405,109 @@ static inline u32 rv_fcvt(u32 funct7, u32 rs2_sel, u32 rd, u32 rs1, u32 rm) { return rv_r(funct7, rs2_sel, rs1, rm, rd, RV_OP_FP); } /* FCVT.W.S rd, rs1 (signed i32 from f32, rtz=001) : funct7=0x60 rs2=0 */ -static inline u32 rv_fcvt_w_s(u32 rd, u32 rs1) { return rv_fcvt(0x60, 0x0, rd, rs1, 0x1); } -static inline u32 rv_fcvt_wu_s(u32 rd, u32 rs1) { return rv_fcvt(0x60, 0x1, rd, rs1, 0x1); } -static inline u32 rv_fcvt_l_s(u32 rd, u32 rs1) { return rv_fcvt(0x60, 0x2, rd, rs1, 0x1); } -static inline u32 rv_fcvt_lu_s(u32 rd, u32 rs1) { return rv_fcvt(0x60, 0x3, rd, rs1, 0x1); } -static inline u32 rv_fcvt_w_d(u32 rd, u32 rs1) { return rv_fcvt(0x61, 0x0, rd, rs1, 0x1); } -static inline u32 rv_fcvt_wu_d(u32 rd, u32 rs1) { return rv_fcvt(0x61, 0x1, rd, rs1, 0x1); } -static inline u32 rv_fcvt_l_d(u32 rd, u32 rs1) { return rv_fcvt(0x61, 0x2, rd, rs1, 0x1); } -static inline u32 rv_fcvt_lu_d(u32 rd, u32 rs1) { return rv_fcvt(0x61, 0x3, rd, rs1, 0x1); } -static inline u32 rv_fcvt_s_w(u32 rd, u32 rs1) { return rv_fcvt(0x68, 0x0, rd, rs1, 0x7); } -static inline u32 rv_fcvt_s_wu(u32 rd, u32 rs1) { return rv_fcvt(0x68, 0x1, rd, rs1, 0x7); } -static inline u32 rv_fcvt_s_l(u32 rd, u32 rs1) { return rv_fcvt(0x68, 0x2, rd, rs1, 0x7); } -static inline u32 rv_fcvt_s_lu(u32 rd, u32 rs1) { return rv_fcvt(0x68, 0x3, rd, rs1, 0x7); } -static inline u32 rv_fcvt_d_w(u32 rd, u32 rs1) { return rv_fcvt(0x69, 0x0, rd, rs1, 0x7); } -static inline u32 rv_fcvt_d_wu(u32 rd, u32 rs1) { return rv_fcvt(0x69, 0x1, rd, rs1, 0x7); } -static inline u32 rv_fcvt_d_l(u32 rd, u32 rs1) { return rv_fcvt(0x69, 0x2, rd, rs1, 0x7); } -static inline u32 rv_fcvt_d_lu(u32 rd, u32 rs1) { return rv_fcvt(0x69, 0x3, rd, rs1, 0x7); } +static inline u32 rv_fcvt_w_s(u32 rd, u32 rs1) { + return rv_fcvt(0x60, 0x0, rd, rs1, 0x1); +} +static inline u32 rv_fcvt_wu_s(u32 rd, u32 rs1) { + return rv_fcvt(0x60, 0x1, rd, rs1, 0x1); +} +static inline u32 rv_fcvt_l_s(u32 rd, u32 rs1) { + return rv_fcvt(0x60, 0x2, rd, rs1, 0x1); +} +static inline u32 rv_fcvt_lu_s(u32 rd, u32 rs1) { + return rv_fcvt(0x60, 0x3, rd, rs1, 0x1); +} +static inline u32 rv_fcvt_w_d(u32 rd, u32 rs1) { + return rv_fcvt(0x61, 0x0, rd, rs1, 0x1); +} +static inline u32 rv_fcvt_wu_d(u32 rd, u32 rs1) { + return rv_fcvt(0x61, 0x1, rd, rs1, 0x1); +} +static inline u32 rv_fcvt_l_d(u32 rd, u32 rs1) { + return rv_fcvt(0x61, 0x2, rd, rs1, 0x1); +} +static inline u32 rv_fcvt_lu_d(u32 rd, u32 rs1) { + return rv_fcvt(0x61, 0x3, rd, rs1, 0x1); +} +static inline u32 rv_fcvt_s_w(u32 rd, u32 rs1) { + return rv_fcvt(0x68, 0x0, rd, rs1, 0x7); +} +static inline u32 rv_fcvt_s_wu(u32 rd, u32 rs1) { + return rv_fcvt(0x68, 0x1, rd, rs1, 0x7); +} +static inline u32 rv_fcvt_s_l(u32 rd, u32 rs1) { + return rv_fcvt(0x68, 0x2, rd, rs1, 0x7); +} +static inline u32 rv_fcvt_s_lu(u32 rd, u32 rs1) { + return rv_fcvt(0x68, 0x3, rd, rs1, 0x7); +} +static inline u32 rv_fcvt_d_w(u32 rd, u32 rs1) { + return rv_fcvt(0x69, 0x0, rd, rs1, 0x7); +} +static inline u32 rv_fcvt_d_wu(u32 rd, u32 rs1) { + return rv_fcvt(0x69, 0x1, rd, rs1, 0x7); +} +static inline u32 rv_fcvt_d_l(u32 rd, u32 rs1) { + return rv_fcvt(0x69, 0x2, rd, rs1, 0x7); +} +static inline u32 rv_fcvt_d_lu(u32 rd, u32 rs1) { + return rv_fcvt(0x69, 0x3, rd, rs1, 0x7); +} /* FCVT.S.D / FCVT.D.S */ -static inline u32 rv_fcvt_s_d(u32 rd, u32 rs1) { return rv_fcvt(0x20, 0x1, rd, rs1, 0x7); } -static inline u32 rv_fcvt_d_s(u32 rd, u32 rs1) { return rv_fcvt(0x21, 0x0, rd, rs1, 0x7); } +static inline u32 rv_fcvt_s_d(u32 rd, u32 rs1) { + return rv_fcvt(0x20, 0x1, rd, rs1, 0x7); +} +static inline u32 rv_fcvt_d_s(u32 rd, u32 rs1) { + return rv_fcvt(0x21, 0x0, rd, rs1, 0x7); +} /* FMV.X.W / FMV.W.X / FMV.X.D / FMV.D.X — bitcast between GPR and FPR. */ -static inline u32 rv_fmv_x_w(u32 rd, u32 rs1) { return rv_fcvt(0x70, 0x0, rd, rs1, 0x0); } -static inline u32 rv_fmv_w_x(u32 rd, u32 rs1) { return rv_fcvt(0x78, 0x0, rd, rs1, 0x0); } -static inline u32 rv_fmv_x_d(u32 rd, u32 rs1) { return rv_fcvt(0x71, 0x0, rd, rs1, 0x0); } -static inline u32 rv_fmv_d_x(u32 rd, u32 rs1) { return rv_fcvt(0x79, 0x0, rd, rs1, 0x0); } - -/* FP compares — rd is integer GPR. funct7 = 0x50/0x51 (S/D). rm: 0=LE, 1=LT, 2=EQ. */ -static inline u32 rv_feq_s(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x50, rs2, rs1, 0x2, rd, RV_OP_FP); } -static inline u32 rv_flt_s(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x50, rs2, rs1, 0x1, rd, RV_OP_FP); } -static inline u32 rv_fle_s(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x50, rs2, rs1, 0x0, rd, RV_OP_FP); } -static inline u32 rv_feq_d(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x51, rs2, rs1, 0x2, rd, RV_OP_FP); } -static inline u32 rv_flt_d(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x51, rs2, rs1, 0x1, rd, RV_OP_FP); } -static inline u32 rv_fle_d(u32 rd, u32 rs1, u32 rs2) { return rv_r(0x51, rs2, rs1, 0x0, rd, RV_OP_FP); } - -static inline u32 rv_flw(u32 rd, u32 rs1, i32 imm) { return rv_i(imm, rs1, 0x2, rd, RV_LOAD_FP); } -static inline u32 rv_fld(u32 rd, u32 rs1, i32 imm) { return rv_i(imm, rs1, 0x3, rd, RV_LOAD_FP); } -static inline u32 rv_fsw(u32 rs2, u32 rs1, i32 imm) { return rv_s(imm, rs2, rs1, 0x2, RV_STORE_FP); } -static inline u32 rv_fsd(u32 rs2, u32 rs1, i32 imm) { return rv_s(imm, rs2, rs1, 0x3, RV_STORE_FP); } +static inline u32 rv_fmv_x_w(u32 rd, u32 rs1) { + return rv_fcvt(0x70, 0x0, rd, rs1, 0x0); +} +static inline u32 rv_fmv_w_x(u32 rd, u32 rs1) { + return rv_fcvt(0x78, 0x0, rd, rs1, 0x0); +} +static inline u32 rv_fmv_x_d(u32 rd, u32 rs1) { + return rv_fcvt(0x71, 0x0, rd, rs1, 0x0); +} +static inline u32 rv_fmv_d_x(u32 rd, u32 rs1) { + return rv_fcvt(0x79, 0x0, rd, rs1, 0x0); +} + +/* FP compares — rd is integer GPR. funct7 = 0x50/0x51 (S/D). rm: 0=LE, 1=LT, + * 2=EQ. */ +static inline u32 rv_feq_s(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x50, rs2, rs1, 0x2, rd, RV_OP_FP); +} +static inline u32 rv_flt_s(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x50, rs2, rs1, 0x1, rd, RV_OP_FP); +} +static inline u32 rv_fle_s(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x50, rs2, rs1, 0x0, rd, RV_OP_FP); +} +static inline u32 rv_feq_d(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x51, rs2, rs1, 0x2, rd, RV_OP_FP); +} +static inline u32 rv_flt_d(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x51, rs2, rs1, 0x1, rd, RV_OP_FP); +} +static inline u32 rv_fle_d(u32 rd, u32 rs1, u32 rs2) { + return rv_r(0x51, rs2, rs1, 0x0, rd, RV_OP_FP); +} + +static inline u32 rv_flw(u32 rd, u32 rs1, i32 imm) { + return rv_i(imm, rs1, 0x2, rd, RV_LOAD_FP); +} +static inline u32 rv_fld(u32 rd, u32 rs1, i32 imm) { + return rv_i(imm, rs1, 0x3, rd, RV_LOAD_FP); +} +static inline u32 rv_fsw(u32 rs2, u32 rs1, i32 imm) { + return rv_s(imm, rs2, rs1, 0x2, RV_STORE_FP); +} +static inline u32 rv_fsd(u32 rs2, u32 rs1, i32 imm) { + return rv_s(imm, rs2, rs1, 0x3, RV_STORE_FP); +} /* ---- A extension (LR/SC + AMO) ---- * AMO funct7 layout: aq(26) rl(25) funct5(31:27) op-specific. @@ -304,19 +517,27 @@ static inline u32 rv_amo(u32 funct5, u32 aq, u32 rl, u32 rd, u32 rs1, u32 rs2, u32 funct7 = (funct5 << 2) | ((aq & 1u) << 1) | (rl & 1u); return rv_r(funct7, rs2, rs1, funct3, rd, RV_AMO); } -static inline u32 rv_lr_w(u32 rd, u32 rs1, u32 aq, u32 rl) { return rv_amo(0x02, aq, rl, rd, rs1, 0, 0x2); } -static inline u32 rv_lr_d(u32 rd, u32 rs1, u32 aq, u32 rl) { return rv_amo(0x02, aq, rl, rd, rs1, 0, 0x3); } -static inline u32 rv_sc_w(u32 rd, u32 rs1, u32 rs2, u32 aq, u32 rl) { return rv_amo(0x03, aq, rl, rd, rs1, rs2, 0x2); } -static inline u32 rv_sc_d(u32 rd, u32 rs1, u32 rs2, u32 aq, u32 rl) { return rv_amo(0x03, aq, rl, rd, rs1, rs2, 0x3); } +static inline u32 rv_lr_w(u32 rd, u32 rs1, u32 aq, u32 rl) { + return rv_amo(0x02, aq, rl, rd, rs1, 0, 0x2); +} +static inline u32 rv_lr_d(u32 rd, u32 rs1, u32 aq, u32 rl) { + return rv_amo(0x02, aq, rl, rd, rs1, 0, 0x3); +} +static inline u32 rv_sc_w(u32 rd, u32 rs1, u32 rs2, u32 aq, u32 rl) { + return rv_amo(0x03, aq, rl, rd, rs1, rs2, 0x2); +} +static inline u32 rv_sc_d(u32 rd, u32 rs1, u32 rs2, u32 aq, u32 rl) { + return rv_amo(0x03, aq, rl, rd, rs1, rs2, 0x3); +} /* Other A-extension AMO funct5 codes (W and D widths via funct3). */ #define RV_AMO_SWAP 0x01u -#define RV_AMO_ADD 0x00u -#define RV_AMO_XOR 0x04u -#define RV_AMO_AND 0x0Cu -#define RV_AMO_OR 0x08u -#define RV_AMO_MIN 0x10u -#define RV_AMO_MAX 0x14u +#define RV_AMO_ADD 0x00u +#define RV_AMO_XOR 0x04u +#define RV_AMO_AND 0x0Cu +#define RV_AMO_OR 0x08u +#define RV_AMO_MIN 0x10u +#define RV_AMO_MAX 0x14u #define RV_AMO_MINU 0x18u #define RV_AMO_MAXU 0x1Cu @@ -349,40 +570,40 @@ static inline u32 rv_csrrci(u32 rd, u32 csr, u32 uimm) { * bottom two bits of the first halfword (00/01/10 → compressed, 11 → 32). * =================================================================== */ typedef enum Rv64Format { - RV64_FMT_R, /* funct7 rs2 rs1 funct3 rd op — most ALU ops */ - RV64_FMT_R4, /* fused FMA: rs3 funct2 rs2 rs1 funct3 rd op */ - RV64_FMT_I, /* imm[11:0] rs1 funct3 rd op — ALU-imm, loads, jalr */ - RV64_FMT_I_SHIFT, /* shift-imm (shamt6/funct6) — RV64 SLLI/SRLI/SRAI */ - RV64_FMT_I_SHIFTW, /* RV32 word-shift (shamt5/funct7) — SLLIW/SRLIW/SRAIW */ - RV64_FMT_S, /* store */ - RV64_FMT_B, /* branch */ - RV64_FMT_U, /* LUI/AUIPC */ - RV64_FMT_J, /* JAL */ - RV64_FMT_LOAD, /* I-type load: rd, imm(rs1) — printer uses memory syntax */ - RV64_FMT_STORE, /* S-type store: rs2, imm(rs1) */ - RV64_FMT_JALR, /* JALR: rd, imm(rs1) — memory-style operand syntax */ - RV64_FMT_FENCE, /* FENCE pred,succ */ - RV64_FMT_SYSTEM, /* ECALL/EBREAK — no operands */ - RV64_FMT_FP_RM, /* FP arithmetic with rm: funct7 rs2 rs1 rm rd op */ - RV64_FMT_FP_R, /* FP R-type without rm-as-mnemonic-suffix (cmp/sgnj) */ - RV64_FMT_FP_CVT, /* FP conversion: rs2 is type selector, rs1 is src */ - RV64_FMT_FP_LOAD, /* fld/flw — rd[FP], imm(rs1) */ - RV64_FMT_FP_STORE, /* fsd/fsw — rs2[FP], imm(rs1) */ - RV64_FMT_AMO, /* atomic: rd, rs2, (rs1) */ - RV64_FMT_LR, /* LR.W/D: rd, (rs1) — no rs2 */ - RV64_FMT_CSR, /* csrr*: rd, csr, rs1 */ - RV64_FMT_CSRI, /* csrr*i: rd, csr, uimm5 */ + RV64_FMT_R, /* funct7 rs2 rs1 funct3 rd op — most ALU ops */ + RV64_FMT_R4, /* fused FMA: rs3 funct2 rs2 rs1 funct3 rd op */ + RV64_FMT_I, /* imm[11:0] rs1 funct3 rd op — ALU-imm, loads, jalr */ + RV64_FMT_I_SHIFT, /* shift-imm (shamt6/funct6) — RV64 SLLI/SRLI/SRAI */ + RV64_FMT_I_SHIFTW, /* RV32 word-shift (shamt5/funct7) — SLLIW/SRLIW/SRAIW */ + RV64_FMT_S, /* store */ + RV64_FMT_B, /* branch */ + RV64_FMT_U, /* LUI/AUIPC */ + RV64_FMT_J, /* JAL */ + RV64_FMT_LOAD, /* I-type load: rd, imm(rs1) — printer uses memory syntax */ + RV64_FMT_STORE, /* S-type store: rs2, imm(rs1) */ + RV64_FMT_JALR, /* JALR: rd, imm(rs1) — memory-style operand syntax */ + RV64_FMT_FENCE, /* FENCE pred,succ */ + RV64_FMT_SYSTEM, /* ECALL/EBREAK — no operands */ + RV64_FMT_FP_RM, /* FP arithmetic with rm: funct7 rs2 rs1 rm rd op */ + RV64_FMT_FP_R, /* FP R-type without rm-as-mnemonic-suffix (cmp/sgnj) */ + RV64_FMT_FP_CVT, /* FP conversion: rs2 is type selector, rs1 is src */ + RV64_FMT_FP_LOAD, /* fld/flw — rd[FP], imm(rs1) */ + RV64_FMT_FP_STORE, /* fsd/fsw — rs2[FP], imm(rs1) */ + RV64_FMT_AMO, /* atomic: rd, rs2, (rs1) */ + RV64_FMT_LR, /* LR.W/D: rd, (rs1) — no rs2 */ + RV64_FMT_CSR, /* csrr*: rd, csr, rs1 */ + RV64_FMT_CSRI, /* csrr*i: rd, csr, uimm5 */ /* ---- Compressed (16-bit) formats ---- */ - RV64_FMT_CR, /* funct4 rd/rs1 rs2 op (e.g. C.MV, C.ADD, C.JR, C.JALR) */ - RV64_FMT_CI, /* funct3 imm rd/rs1 imm op (e.g. C.ADDI, C.LI, C.LUI) */ - RV64_FMT_CSS, /* funct3 imm rs2 op (stack store: C.SDSP, C.SWSP) */ - RV64_FMT_CIW, /* funct3 imm rd' op (C.ADDI4SPN) */ - RV64_FMT_CL, /* funct3 imm rs1' imm rd' op (C.LD, C.LW) */ - RV64_FMT_CS, /* funct3 imm rs1' imm rs2' op (C.SD, C.SW) */ - RV64_FMT_CA, /* funct6 rd'/rs1' funct2 rs2' op (C.AND, C.OR, ...) */ - RV64_FMT_CB, /* branch: funct3 imm rs1' imm op (C.BEQZ, C.BNEZ) */ - RV64_FMT_CJ, /* jump: funct3 imm op (C.J, C.JAL_unused on RV64) */ - RV64_FMT_C_NONE, /* known opcode with no operands (C.NOP, C.EBREAK) */ + RV64_FMT_CR, /* funct4 rd/rs1 rs2 op (e.g. C.MV, C.ADD, C.JR, C.JALR) */ + RV64_FMT_CI, /* funct3 imm rd/rs1 imm op (e.g. C.ADDI, C.LI, C.LUI) */ + RV64_FMT_CSS, /* funct3 imm rs2 op (stack store: C.SDSP, C.SWSP) */ + RV64_FMT_CIW, /* funct3 imm rd' op (C.ADDI4SPN) */ + RV64_FMT_CL, /* funct3 imm rs1' imm rd' op (C.LD, C.LW) */ + RV64_FMT_CS, /* funct3 imm rs1' imm rs2' op (C.SD, C.SW) */ + RV64_FMT_CA, /* funct6 rd'/rs1' funct2 rs2' op (C.AND, C.OR, ...) */ + RV64_FMT_CB, /* branch: funct3 imm rs1' imm op (C.BEQZ, C.BNEZ) */ + RV64_FMT_CJ, /* jump: funct3 imm op (C.J, C.JAL_unused on RV64) */ + RV64_FMT_C_NONE, /* known opcode with no operands (C.NOP, C.EBREAK) */ } Rv64Format; typedef enum Rv64DecodedOpcode { @@ -398,21 +619,33 @@ typedef enum Rv64DecodedOpcode { } Rv64DecodedOpcode; /* ---- AsmFlags column on Rv64InsnDesc ---- */ -#define RV64_ASMFL_ALIAS 0x01u /* row is an alias (preferred print form) */ -#define RV64_ASMFL_FP 0x02u /* operands take f-register prefix */ -#define RV64_ASMFL_NORM 0x04u /* FP_RM row prints without rm suffix */ -#define RV64_ASMFL_C16 0x08u /* 16-bit compressed instruction */ +#define RV64_ASMFL_ALIAS 0x01u /* row is an alias (preferred print form) */ +#define RV64_ASMFL_FP 0x02u /* operands take f-register prefix */ +#define RV64_ASMFL_NORM 0x04u /* FP_RM row prints without rm suffix */ +#define RV64_ASMFL_C16 0x08u /* 16-bit compressed instruction */ /* =================================================================== * Per-format field structs + pack/unpack pure functions. * =================================================================== */ -typedef struct Rv64R { u32 funct7, rs2, rs1, funct3, rd, op; } Rv64R; -typedef struct Rv64I { u32 imm12, rs1, funct3, rd, op; } Rv64I; -typedef struct Rv64S { u32 imm12, rs2, rs1, funct3, op; } Rv64S; -typedef struct Rv64B { u32 imm13, rs2, rs1, funct3, op; } Rv64B; -typedef struct Rv64U { u32 imm32_hi20, rd, op; } Rv64U; -typedef struct Rv64J { u32 imm21, rd, op; } Rv64J; +typedef struct Rv64R { + u32 funct7, rs2, rs1, funct3, rd, op; +} Rv64R; +typedef struct Rv64I { + u32 imm12, rs1, funct3, rd, op; +} Rv64I; +typedef struct Rv64S { + u32 imm12, rs2, rs1, funct3, op; +} Rv64S; +typedef struct Rv64B { + u32 imm13, rs2, rs1, funct3, op; +} Rv64B; +typedef struct Rv64U { + u32 imm32_hi20, rd, op; +} Rv64U; +typedef struct Rv64J { + u32 imm21, rd, op; +} Rv64J; static inline Rv64R rv64_r_unpack(u32 w) { Rv64R f; @@ -491,7 +724,9 @@ static inline i64 rv64_sext(u64 v, u32 nbits) { * x8..x15; macro RVC_REG3 unfolds: r' → 8 + r'. */ #define RVC_REG3(r3) ((u32)(8u + ((r3) & 7u))) -typedef struct Rv64C { u32 word; } Rv64C; /* 16-bit halfword in low 16 bits */ +typedef struct Rv64C { + u32 word; +} Rv64C; /* 16-bit halfword in low 16 bits */ /* =================================================================== * Descriptor table. diff --git a/src/arch/rv64/ops.c b/src/arch/rv64/ops.c @@ -1,8 +1,7 @@ /* src/arch/rv64/ops.c — data movement, arithmetic, calls, atomics, vtable. */ -#include "arch/rv64/internal.h" - #include "arch/rv64/asm.h" +#include "arch/rv64/internal.h" #include "arch/rv64/regs.h" #include "cfree/config.h" #include "core/pool.h" @@ -11,18 +10,26 @@ /* ---- For a memory access of `nbytes`, pick the right store opcode. ---- */ u32 enc_int_store(u32 nbytes, u32 src, u32 base, i32 off) { switch (nbytes) { - case 1: return rv_sb(src, base, off); - case 2: return rv_sh(src, base, off); - case 4: return rv_sw(src, base, off); - default: return rv_sd(src, base, off); + case 1: + return rv_sb(src, base, off); + case 2: + return rv_sh(src, base, off); + case 4: + return rv_sw(src, base, off); + default: + return rv_sd(src, base, off); } } u32 enc_int_load(u32 nbytes, int sign_ext, u32 rd, u32 base, i32 off) { switch (nbytes) { - case 1: return sign_ext ? rv_lb(rd, base, off) : rv_lbu(rd, base, off); - case 2: return sign_ext ? rv_lh(rd, base, off) : rv_lhu(rd, base, off); - case 4: return sign_ext ? rv_lw(rd, base, off) : rv_lwu(rd, base, off); - default: return rv_ld(rd, base, off); + case 1: + return sign_ext ? rv_lb(rd, base, off) : rv_lbu(rd, base, off); + case 2: + return sign_ext ? rv_lh(rd, base, off) : rv_lhu(rd, base, off); + case 4: + return sign_ext ? rv_lw(rd, base, off) : rv_lwu(rd, base, off); + default: + return rv_ld(rd, base, off); } } @@ -55,9 +62,13 @@ static void rv_load_const(CGTarget* t, Operand dst, ConstBytes cb) { u32 v = lit_seq++; char tmp[16]; int tn = 0; - if (v == 0) tmp[tn++] = '0'; + if (v == 0) + tmp[tn++] = '0'; else { - while (v) { tmp[tn++] = '0' + (char)(v % 10); v /= 10; } + while (v) { + tmp[tn++] = '0' + (char)(v % 10); + v /= 10; + } } for (int i = tn - 1; i >= 0; --i) namebuf[len++] = tmp[i]; namebuf[len] = 0; @@ -83,15 +94,22 @@ static void rv_load_const(CGTarget* t, Operand dst, ConstBytes cb) { for (; p2[al]; ++al) anchor_buf[al] = p2[al]; static u32 seq2 = 0; u32 v = seq2++; - char tmp[16]; int tn = 0; - if (v == 0) tmp[tn++] = '0'; - else { while (v) { tmp[tn++] = '0' + (char)(v % 10); v /= 10; } } + char tmp[16]; + int tn = 0; + if (v == 0) + tmp[tn++] = '0'; + else { + while (v) { + tmp[tn++] = '0' + (char)(v % 10); + v /= 10; + } + } for (int i = tn - 1; i >= 0; --i) anchor_buf[al++] = tmp[i]; anchor_buf[al] = 0; } Sym aname = pool_intern_slice(t->c->global, slice_from_cstr(anchor_buf)); - ObjSymId anchor = obj_symbol(t->obj, aname, SB_LOCAL, SK_OBJ, sec, - (u64)auipc_pos, 0); + ObjSymId anchor = + obj_symbol(t->obj, aname, SB_LOCAL, SK_OBJ, sec, (u64)auipc_pos, 0); u32 lpos = t->mc->pos(t->mc); if (cb.size == 8) { rv64_emit32(t->mc, rv_fld(reg_num(dst), RV_T0, 0)); @@ -198,9 +216,16 @@ ObjSymId emit_pcrel_anchor(CGTarget* t, u32 sec, u32 auipc_pos) { for (; p[len]; ++len) buf[len] = p[len]; static u32 seq = 0; u32 v = seq++; - char tmp[16]; int tn = 0; - if (v == 0) tmp[tn++] = '0'; - else { while (v) { tmp[tn++] = '0' + (char)(v % 10); v /= 10; } } + char tmp[16]; + int tn = 0; + if (v == 0) + tmp[tn++] = '0'; + else { + while (v) { + tmp[tn++] = '0' + (char)(v % 10); + v /= 10; + } + } for (int i = tn - 1; i >= 0; --i) buf[len++] = tmp[i]; buf[len] = 0; Sym n = pool_intern_slice(t->c->global, slice_from_cstr(buf)); @@ -247,22 +272,30 @@ void rv64_emit_addr_adjust(MCEmitter* mc, u32 rd, u32 base, i32 off) { * available on rv64 targets — no feature gate. */ static Operand rv_fold_indexed(CGTarget* t, Operand addr, u32 scratch) { if (addr.kind != OPK_INDIRECT || addr.v.ind.index == REG_NONE) return addr; - u32 base = addr.v.ind.base & 0x1fu; + u32 base = addr.v.ind.base & 0x1fu; u32 index = addr.v.ind.index & 0x1fu; - u8 s = addr.v.ind.log2_scale; + u8 s = addr.v.ind.log2_scale; MCEmitter* mc = t->mc; /* sh{1,2,3}add rd, rs1, rs2 = (rs1 << s) + rs2, so rs1=index, rs2=base. */ switch (s) { - case 0: rv64_emit32(mc, rv_add (scratch, base, index)); break; - case 1: rv64_emit32(mc, rv_sh1add(scratch, index, base )); break; - case 2: rv64_emit32(mc, rv_sh2add(scratch, index, base )); break; - case 3: rv64_emit32(mc, rv_sh3add(scratch, index, base )); break; - default: compiler_panic(t->c, impl_of(t)->loc, - "rv64 rv_fold_indexed: bad log2_scale %u", - (u32)s); - } - addr.v.ind.base = scratch; - addr.v.ind.index = REG_NONE; + case 0: + rv64_emit32(mc, rv_add(scratch, base, index)); + break; + case 1: + rv64_emit32(mc, rv_sh1add(scratch, index, base)); + break; + case 2: + rv64_emit32(mc, rv_sh2add(scratch, index, base)); + break; + case 3: + rv64_emit32(mc, rv_sh3add(scratch, index, base)); + break; + default: + compiler_panic(t->c, impl_of(t)->loc, + "rv64 rv_fold_indexed: bad log2_scale %u", (u32)s); + } + addr.v.ind.base = scratch; + addr.v.ind.index = REG_NONE; addr.v.ind.log2_scale = 0; return addr; } @@ -283,8 +316,10 @@ void rv_load(CGTarget* t, Operand dst, Operand addr, MemAccess ma) { rv64_emit_got_load_addr(t, RV_T0, sym); i32 ao = (i32)add; if (dst.cls == RC_FP) { - if (sz == 8) rv64_emit32(mc, rv_fld(reg_num(dst), RV_T0, ao)); - else rv64_emit32(mc, rv_flw(reg_num(dst), RV_T0, ao)); + if (sz == 8) + rv64_emit32(mc, rv_fld(reg_num(dst), RV_T0, ao)); + else + rv64_emit32(mc, rv_flw(reg_num(dst), RV_T0, ao)); } else { int sx = type_is_signed(addr.type); rv64_emit32(mc, enc_int_load(sz, sx, reg_num(dst), RV_T0, ao)); @@ -297,8 +332,10 @@ void rv_load(CGTarget* t, Operand dst, Operand addr, MemAccess ma) { ObjSymId anchor = emit_pcrel_anchor(t, sec, ap); u32 lp = mc->pos(mc); if (dst.cls == RC_FP) { - if (sz == 8) rv64_emit32(mc, rv_fld(reg_num(dst), RV_T0, 0)); - else rv64_emit32(mc, rv_flw(reg_num(dst), RV_T0, 0)); + if (sz == 8) + rv64_emit32(mc, rv_fld(reg_num(dst), RV_T0, 0)); + else + rv64_emit32(mc, rv_flw(reg_num(dst), RV_T0, 0)); } else { int sx = type_is_signed(addr.type); rv64_emit32(mc, enc_int_load(sz, sx, reg_num(dst), RV_T0, 0)); @@ -312,8 +349,10 @@ void rv_load(CGTarget* t, Operand dst, Operand addr, MemAccess ma) { addr = rv_fold_indexed(t, addr, RV_T0); RvAddrMode am = addr_mode(t, addr, RV_T0); if (dst.cls == RC_FP) { - if (sz == 8) rv64_emit32(mc, rv_fld(reg_num(dst), am.base, am.ofs)); - else rv64_emit32(mc, rv_flw(reg_num(dst), am.base, am.ofs)); + if (sz == 8) + rv64_emit32(mc, rv_fld(reg_num(dst), am.base, am.ofs)); + else + rv64_emit32(mc, rv_flw(reg_num(dst), am.base, am.ofs)); } else { int sx = type_is_signed(addr.type); rv64_emit32(mc, enc_int_load(sz, sx, reg_num(dst), am.base, am.ofs)); @@ -346,8 +385,10 @@ void rv_store(CGTarget* t, Operand addr, Operand src, MemAccess ma) { rv64_emit_got_load_addr(t, RV_T0, sym); i32 ao = (i32)add; if (src_fp) { - if (sz == 8) rv64_emit32(mc, rv_fsd(src_reg, RV_T0, ao)); - else rv64_emit32(mc, rv_fsw(src_reg, RV_T0, ao)); + if (sz == 8) + rv64_emit32(mc, rv_fsd(src_reg, RV_T0, ao)); + else + rv64_emit32(mc, rv_fsw(src_reg, RV_T0, ao)); } else { rv64_emit32(mc, enc_int_store(sz, src_reg, RV_T0, ao)); } @@ -359,8 +400,10 @@ void rv_store(CGTarget* t, Operand addr, Operand src, MemAccess ma) { ObjSymId anchor = emit_pcrel_anchor(t, sec, ap); u32 sp_pos = mc->pos(mc); if (src_fp) { - if (sz == 8) rv64_emit32(mc, rv_fsd(src_reg, RV_T0, 0)); - else rv64_emit32(mc, rv_fsw(src_reg, RV_T0, 0)); + if (sz == 8) + rv64_emit32(mc, rv_fsd(src_reg, RV_T0, 0)); + else + rv64_emit32(mc, rv_fsw(src_reg, RV_T0, 0)); } else { rv64_emit32(mc, enc_int_store(sz, src_reg, RV_T0, 0)); } @@ -382,8 +425,10 @@ void rv_store(CGTarget* t, Operand addr, Operand src, MemAccess ma) { return; } if (src.cls == RC_FP) { - if (sz == 8) rv64_emit32(mc, rv_fsd(reg_num(src), am.base, am.ofs)); - else rv64_emit32(mc, rv_fsw(reg_num(src), am.base, am.ofs)); + if (sz == 8) + rv64_emit32(mc, rv_fsd(reg_num(src), am.base, am.ofs)); + else + rv64_emit32(mc, rv_fsw(reg_num(src), am.base, am.ofs)); } else { rv64_emit32(mc, enc_int_store(sz, reg_num(src), am.base, am.ofs)); } @@ -557,8 +602,7 @@ static void rv_set_bytes(CGTarget* t, Operand dst_addr, Operand byte_value, if (byte_value.kind == OPK_IMM) { byte = (u32)(byte_value.v.imm & 0xffu); } else { - compiler_panic(t->c, impl_of(t)->loc, - "rv64 set_bytes: REG byte NYI"); + compiler_panic(t->c, impl_of(t)->loc, "rv64 set_bytes: REG byte NYI"); } u32 n = agg.size; u32 src; @@ -566,15 +610,29 @@ static void rv_set_bytes(CGTarget* t, Operand dst_addr, Operand byte_value, src = RV_ZERO; } else { u64 b = byte; - b |= b << 8; b |= b << 16; b |= b << 32; + b |= b << 8; + b |= b << 16; + b |= b << 32; rv64_emit_load_imm(mc, 1, RV_T3, (i64)b); src = RV_T3; } u32 i = 0; - while (i + 8 <= n) { rv64_emit32(mc, rv_sd(src, dr, (i32)i)); i += 8; } - while (i + 4 <= n) { rv64_emit32(mc, rv_sw(src, dr, (i32)i)); i += 4; } - while (i + 2 <= n) { rv64_emit32(mc, rv_sh(src, dr, (i32)i)); i += 2; } - while (i < n) { rv64_emit32(mc, rv_sb(src, dr, (i32)i)); i += 1; } + while (i + 8 <= n) { + rv64_emit32(mc, rv_sd(src, dr, (i32)i)); + i += 8; + } + while (i + 4 <= n) { + rv64_emit32(mc, rv_sw(src, dr, (i32)i)); + i += 4; + } + while (i + 2 <= n) { + rv64_emit32(mc, rv_sh(src, dr, (i32)i)); + i += 2; + } + while (i < n) { + rv64_emit32(mc, rv_sb(src, dr, (i32)i)); + i += 1; + } } static void rv_bitfield_load(CGTarget* t, Operand dst, Operand record_addr, @@ -584,7 +642,8 @@ static void rv_bitfield_load(CGTarget* t, Operand dst, Operand record_addr, u32 storage_bytes = bf.storage.size ? bf.storage.size : 4u; u32 rd = reg_num(dst); /* Load full storage unit (zero-ext for shifts). */ - rv64_emit32(mc, enc_int_load(storage_bytes, 0, rd, base, (i32)bf.storage_offset)); + rv64_emit32(mc, + enc_int_load(storage_bytes, 0, rd, base, (i32)bf.storage_offset)); /* Shift left by (XLEN - (bit_offset + bit_width)) then arithmetic * right-shift by (XLEN - bit_width). Use 64-bit shifts. */ u32 lsb = bf.bit_offset; @@ -592,8 +651,10 @@ static void rv_bitfield_load(CGTarget* t, Operand dst, Operand record_addr, u32 sh_left = 64u - (lsb + width); u32 sh_right = 64u - width; rv64_emit32(mc, rv_slli(rd, rd, sh_left)); - if (bf.signed_) rv64_emit32(mc, rv_srai(rd, rd, sh_right)); - else rv64_emit32(mc, rv_srli(rd, rd, sh_right)); + if (bf.signed_) + rv64_emit32(mc, rv_srai(rd, rd, sh_right)); + else + rv64_emit32(mc, rv_srli(rd, rd, sh_right)); } static void rv_bitfield_store(CGTarget* t, Operand record_addr, Operand src, @@ -602,8 +663,8 @@ static void rv_bitfield_store(CGTarget* t, Operand record_addr, Operand src, u32 base = agg_addr_reg(t, record_addr, RV_T0); u32 storage_bytes = bf.storage.size ? bf.storage.size : 4u; /* Load current value into t1 */ - rv64_emit32(mc, enc_int_load(storage_bytes, 0, RV_T1, base, - (i32)bf.storage_offset)); + rv64_emit32( + mc, enc_int_load(storage_bytes, 0, RV_T1, base, (i32)bf.storage_offset)); u32 src_reg; if (src.kind == OPK_IMM) { rv64_emit_load_imm(mc, 1, RV_T2, src.v.imm); @@ -627,8 +688,8 @@ static void rv_bitfield_store(CGTarget* t, Operand record_addr, Operand src, rv64_emit_load_imm(mc, 1, RV_T2, (i64)~mask_in); rv64_emit32(mc, rv_and(RV_T1, RV_T1, RV_T2)); rv64_emit32(mc, rv_or(RV_T1, RV_T1, RV_T3)); - rv64_emit32(mc, enc_int_store(storage_bytes, RV_T1, base, - (i32)bf.storage_offset)); + rv64_emit32( + mc, enc_int_store(storage_bytes, RV_T1, base, (i32)bf.storage_offset)); } /* ---- arithmetic ---- */ @@ -642,11 +703,20 @@ static void rv_binop(CGTarget* t, BinOp op, Operand dst, Operand a_op, u32 fa = reg_num(a_op); u32 fb = reg_num(b_op); switch (op) { - case BO_FADD: rv64_emit32(mc, rv_fadd(fmt, rd, fa, fb)); return; - case BO_FSUB: rv64_emit32(mc, rv_fsub(fmt, rd, fa, fb)); return; - case BO_FMUL: rv64_emit32(mc, rv_fmul(fmt, rd, fa, fb)); return; - case BO_FDIV: rv64_emit32(mc, rv_fdiv(fmt, rd, fa, fb)); return; - default: break; + case BO_FADD: + rv64_emit32(mc, rv_fadd(fmt, rd, fa, fb)); + return; + case BO_FSUB: + rv64_emit32(mc, rv_fsub(fmt, rd, fa, fb)); + return; + case BO_FMUL: + rv64_emit32(mc, rv_fmul(fmt, rd, fa, fb)); + return; + case BO_FDIV: + rv64_emit32(mc, rv_fdiv(fmt, rd, fa, fb)); + return; + default: + break; } } u32 sf = type_is_64(dst.type) ? 1u : 0u; @@ -661,11 +731,14 @@ static void rv_binop(CGTarget* t, BinOp op, Operand dst, Operand a_op, case BO_OR: case BO_XOR: { if (a_op.kind == OPK_IMM && b_op.kind != OPK_IMM) { - Operand t_op = a_op; a_op = b_op; b_op = t_op; + Operand t_op = a_op; + a_op = b_op; + b_op = t_op; } break; } - default: break; + default: + break; } /* IMM-form fast paths. RV-I admits a 12-bit signed immediate for @@ -682,24 +755,35 @@ static void rv_binop(CGTarget* t, BinOp op, Operand dst, Operand a_op, switch (op) { case BO_IADD: if (fits12) { - rv64_emit32(mc, sf ? rv_addi(rd, ra, (i32)imm) : rv_addiw(rd, ra, (i32)imm)); + rv64_emit32( + mc, sf ? rv_addi(rd, ra, (i32)imm) : rv_addiw(rd, ra, (i32)imm)); return; } break; case BO_ISUB: if (imm >= -2047 && imm <= 2048) { - rv64_emit32(mc, sf ? rv_addi(rd, ra, (i32)-imm) : rv_addiw(rd, ra, (i32)-imm)); + rv64_emit32(mc, sf ? rv_addi(rd, ra, (i32)-imm) + : rv_addiw(rd, ra, (i32)-imm)); return; } break; case BO_AND: - if (fits12) { rv64_emit32(mc, rv_andi(rd, ra, (i32)imm)); return; } + if (fits12) { + rv64_emit32(mc, rv_andi(rd, ra, (i32)imm)); + return; + } break; case BO_OR: - if (fits12) { rv64_emit32(mc, rv_ori(rd, ra, (i32)imm)); return; } + if (fits12) { + rv64_emit32(mc, rv_ori(rd, ra, (i32)imm)); + return; + } break; case BO_XOR: - if (fits12) { rv64_emit32(mc, rv_xori(rd, ra, (i32)imm)); return; } + if (fits12) { + rv64_emit32(mc, rv_xori(rd, ra, (i32)imm)); + return; + } break; case BO_SHL: { u32 width = sf ? 64u : 32u; @@ -719,7 +803,8 @@ static void rv_binop(CGTarget* t, BinOp op, Operand dst, Operand a_op, rv64_emit32(mc, sf ? rv_srai(rd, ra, sh) : rv_sraiw(rd, ra, sh)); return; } - default: break; + default: + break; } } @@ -727,21 +812,48 @@ static void rv_binop(CGTarget* t, BinOp op, Operand dst, Operand a_op, u32 rb = rv64_force_reg_int(t, b_op, (ra == RV_T0) ? RV_T1 : RV_T0); switch (op) { - case BO_IADD: rv64_emit32(mc, sf ? rv_add(rd, ra, rb) : rv_addw(rd, ra, rb)); return; - case BO_ISUB: rv64_emit32(mc, sf ? rv_sub(rd, ra, rb) : rv_subw(rd, ra, rb)); return; - case BO_IMUL: rv64_emit32(mc, sf ? rv_mul(rd, ra, rb) : rv_mulw(rd, ra, rb)); return; - case BO_AND: rv64_emit32(mc, rv_and(rd, ra, rb)); return; - case BO_OR: rv64_emit32(mc, rv_or(rd, ra, rb)); return; - case BO_XOR: rv64_emit32(mc, rv_xor(rd, ra, rb)); return; - case BO_SHL: rv64_emit32(mc, sf ? rv_sll(rd, ra, rb) : rv_sllw(rd, ra, rb)); return; - case BO_SHR_U: rv64_emit32(mc, sf ? rv_srl(rd, ra, rb) : rv_srlw(rd, ra, rb)); return; - case BO_SHR_S: rv64_emit32(mc, sf ? rv_sra(rd, ra, rb) : rv_sraw(rd, ra, rb)); return; - case BO_SDIV: rv64_emit32(mc, sf ? rv_div(rd, ra, rb) : rv_divw(rd, ra, rb)); return; - case BO_UDIV: rv64_emit32(mc, sf ? rv_divu(rd, ra, rb) : rv_divuw(rd, ra, rb)); return; - case BO_SREM: rv64_emit32(mc, sf ? rv_rem(rd, ra, rb) : rv_remw(rd, ra, rb)); return; - case BO_UREM: rv64_emit32(mc, sf ? rv_remu(rd, ra, rb) : rv_remuw(rd, ra, rb)); return; + case BO_IADD: + rv64_emit32(mc, sf ? rv_add(rd, ra, rb) : rv_addw(rd, ra, rb)); + return; + case BO_ISUB: + rv64_emit32(mc, sf ? rv_sub(rd, ra, rb) : rv_subw(rd, ra, rb)); + return; + case BO_IMUL: + rv64_emit32(mc, sf ? rv_mul(rd, ra, rb) : rv_mulw(rd, ra, rb)); + return; + case BO_AND: + rv64_emit32(mc, rv_and(rd, ra, rb)); + return; + case BO_OR: + rv64_emit32(mc, rv_or(rd, ra, rb)); + return; + case BO_XOR: + rv64_emit32(mc, rv_xor(rd, ra, rb)); + return; + case BO_SHL: + rv64_emit32(mc, sf ? rv_sll(rd, ra, rb) : rv_sllw(rd, ra, rb)); + return; + case BO_SHR_U: + rv64_emit32(mc, sf ? rv_srl(rd, ra, rb) : rv_srlw(rd, ra, rb)); + return; + case BO_SHR_S: + rv64_emit32(mc, sf ? rv_sra(rd, ra, rb) : rv_sraw(rd, ra, rb)); + return; + case BO_SDIV: + rv64_emit32(mc, sf ? rv_div(rd, ra, rb) : rv_divw(rd, ra, rb)); + return; + case BO_UDIV: + rv64_emit32(mc, sf ? rv_divu(rd, ra, rb) : rv_divuw(rd, ra, rb)); + return; + case BO_SREM: + rv64_emit32(mc, sf ? rv_rem(rd, ra, rb) : rv_remw(rd, ra, rb)); + return; + case BO_UREM: + rv64_emit32(mc, sf ? rv_remu(rd, ra, rb) : rv_remuw(rd, ra, rb)); + return; default: - compiler_panic(t->c, impl_of(t)->loc, "rv64 binop: op %d unimpl", (int)op); + compiler_panic(t->c, impl_of(t)->loc, "rv64 binop: op %d unimpl", + (int)op); } } @@ -857,8 +969,12 @@ static void rv_convert(CGTarget* t, ConvKind k, Operand dst, Operand src) { } return; } - case CV_FEXT: rv64_emit32(mc, rv_fcvt_d_s(rd, rn)); return; - case CV_FTRUNC: rv64_emit32(mc, rv_fcvt_s_d(rd, rn)); return; + case CV_FEXT: + rv64_emit32(mc, rv_fcvt_d_s(rd, rn)); + return; + case CV_FTRUNC: + rv64_emit32(mc, rv_fcvt_s_d(rd, rn)); + return; case CV_BITCAST: { if (src.cls == RC_INT && dst.cls == RC_FP) { u32 sz = type_byte_size(dst.type); @@ -888,8 +1004,7 @@ static void rv_convert(CGTarget* t, ConvKind k, Operand dst, Operand src) { /* ---- calls / return ---- */ -static Operand rv_call_stack_arg_addr(CGTarget* t, u32 stack_offset, - int tail) { +static Operand rv_call_stack_arg_addr(CGTarget* t, u32 stack_offset, int tail) { RImpl* a = impl_of(t); Operand addr; memset(&addr, 0, sizeof addr); @@ -927,8 +1042,8 @@ static u32 rv_call_plan_stack_raw_size(const CGCallPlan* p) { } static void rv_store_stack_reg(CGTarget* t, u32 reg, RegClass cls, - CfreeCgTypeId type, u32 size, - u32 stack_offset, int tail) { + CfreeCgTypeId type, u32 size, u32 stack_offset, + int tail) { Operand addr = rv_call_stack_arg_addr(t, stack_offset, tail); Operand src; MemAccess ma; @@ -972,8 +1087,8 @@ static void rv_load_abi_part(CGTarget* t, Operand dst, Operand src, u32 offset, rv_load(t, dst, rv_offset_mem_operand(t, src, offset), ma); } -static void rv_store_abi_part(CGTarget* t, Operand dst, Operand src, - u32 offset, u32 size) { +static void rv_store_abi_part(CGTarget* t, Operand dst, Operand src, u32 offset, + u32 size) { MemAccess ma; memset(&ma, 0, sizeof ma); ma.type = src.type; @@ -1047,8 +1162,7 @@ static void emit_arg_value(CGTarget* t, const CGABIValue* av, u32* next_int, dst_addr.v.reg = dst_reg; rv_addr_of(t, dst_addr, av->storage); } else { - compiler_panic(t->c, a->loc, - "rv64 call: INDIRECT storage kind %d NYI", + compiler_panic(t->c, a->loc, "rv64 call: INDIRECT storage kind %d NYI", (int)av->storage.kind); } if (to_stack) { @@ -1075,8 +1189,9 @@ static void emit_arg_value(CGTarget* t, const CGABIValue* av, u32* next_int, /* Variadic FP arg pinned into an integer register: bitcast * via FMV.X.{D,W}. Otherwise normal MV. */ if (av->storage.cls == RC_FP) { - rv64_emit32(mc, (sz == 8) ? rv_fmv_x_d(dst_reg, reg_num(av->storage)) - : rv_fmv_x_w(dst_reg, reg_num(av->storage))); + rv64_emit32(mc, (sz == 8) + ? rv_fmv_x_d(dst_reg, reg_num(av->storage)) + : rv_fmv_x_w(dst_reg, reg_num(av->storage))); } else { rv64_emit32(mc, rv_addi(dst_reg, reg_num(av->storage), 0)); } @@ -1095,8 +1210,7 @@ static void emit_arg_value(CGTarget* t, const CGABIValue* av, u32* next_int, break; } default: - compiler_panic(t->c, a->loc, - "rv64 call: storage kind %d NYI", + compiler_panic(t->c, a->loc, "rv64 call: storage kind %d NYI", (int)av->storage.kind); } if (to_stack) { @@ -1141,12 +1255,12 @@ static void emit_arg_value(CGTarget* t, const CGABIValue* av, u32* next_int, tmp.v.reg = 0u; if (sz == 8) { rv_load_abi_part(t, tmp, av->storage, pt->src_offset, sz); - rv_store_stack_reg(t, /*ft0=*/0u, RC_FP, av->type, sz, - *stack_off, tail); + rv_store_stack_reg(t, /*ft0=*/0u, RC_FP, av->type, sz, *stack_off, + tail); } else { rv_load_abi_part(t, tmp, av->storage, pt->src_offset, sz); - rv_store_stack_reg(t, /*ft0=*/0u, RC_FP, av->type, sz, - *stack_off, tail); + rv_store_stack_reg(t, /*ft0=*/0u, RC_FP, av->type, sz, *stack_off, + tail); } break; } @@ -1157,12 +1271,12 @@ static void emit_arg_value(CGTarget* t, const CGABIValue* av, u32* next_int, tmp.v.reg = 0u; if (sz == 8) { rv_load_abi_part(t, tmp, av->storage, pt->src_offset, sz); - rv_store_stack_reg(t, /*ft0=*/0u, RC_FP, av->type, sz, - *stack_off, tail); + rv_store_stack_reg(t, /*ft0=*/0u, RC_FP, av->type, sz, *stack_off, + tail); } else { rv_load_abi_part(t, tmp, av->storage, pt->src_offset, sz); - rv_store_stack_reg(t, /*ft0=*/0u, RC_FP, av->type, sz, - *stack_off, tail); + rv_store_stack_reg(t, /*ft0=*/0u, RC_FP, av->type, sz, *stack_off, + tail); } break; } @@ -1178,8 +1292,8 @@ static void emit_arg_value(CGTarget* t, const CGABIValue* av, u32* next_int, } } -static void count_arg_stack(const CGABIValue* av, u32* next_int, - u32* next_fp, u32* stack_off) { +static void count_arg_stack(const CGABIValue* av, u32* next_int, u32* next_fp, + u32* stack_off) { ABIArgInfo va_ai; ABIArgPart va_pt; const ABIArgInfo* ai = av->abi; @@ -1235,7 +1349,7 @@ static u32 rv_call_stack_size(CGTarget* t, const CGCallDesc* d) { * sret callees are realizable by forwarding this function's own incoming sret * pointer (the return-shape precondition guarantees it matches). */ static const char* rv_tail_call_unrealizable_reason(CGTarget* t, - const CGCallDesc* d) { + const CGCallDesc* d) { RImpl* a = impl_of(t); u32 next_int = (d->abi && d->abi->has_sret) ? 1u : 0u; u32 next_fp = 0, stack_off = 0; @@ -1331,8 +1445,8 @@ static void rv_tail_branch(CGTarget* t, Operand callee) { u32 pos = mc->pos(mc); rv64_emit32(mc, rv_auipc(RV_T1, 0)); rv64_emit32(mc, rv_jalr(RV_ZERO, RV_T1, 0)); - mc->emit_reloc_at(mc, sec, pos, R_RV_CALL, - callee.v.global.sym, callee.v.global.addend, 0, 0); + mc->emit_reloc_at(mc, sec, pos, R_RV_CALL, callee.v.global.sym, + callee.v.global.addend, 0, 0); } else { compiler_panic(t->c, a->loc, "rv64 tail call: callee kind %d unsupported", (int)callee.kind); @@ -1402,8 +1516,8 @@ static void rv_call(CGTarget* t, const CGCallDesc* d) { u32 pos = mc->pos(mc); rv64_emit32(mc, rv_auipc(RV_RA, 0)); rv64_emit32(mc, rv_jalr(RV_RA, RV_RA, 0)); - mc->emit_reloc_at(mc, sec, pos, R_RV_CALL, - d->callee.v.global.sym, d->callee.v.global.addend, 0, 0); + mc->emit_reloc_at(mc, sec, pos, R_RV_CALL, d->callee.v.global.sym, + d->callee.v.global.addend, 0, 0); } else if (d->callee.kind == OPK_REG) { rv64_emit32(mc, rv_jalr(RV_RA, reg_num(d->callee), 0)); } else { @@ -1444,7 +1558,8 @@ static void rv_call(CGTarget* t, const CGCallDesc* d) { compiler_panic(t->c, a->loc, "rv64 call: ret part cls %d unimpl", (int)p->cls); } - } else if (rs.kind == OPK_IMM && rs.type == CG_BUILTIN_ID(CFREE_CG_BUILTIN_VOID)) { + } else if (rs.kind == OPK_IMM && + rs.type == CG_BUILTIN_ID(CFREE_CG_BUILTIN_VOID)) { /* void return placeholder — nothing to do. */ } else { compiler_panic(t->c, a->loc, "rv64 call: ret_storage kind %d unsupported", @@ -1462,7 +1577,8 @@ static void rv_emit_call_plan(CGTarget* t, const CGCallPlan* p) { /* Forward the incoming sret pointer into a0 (see rv_call). Load before * rv_tail_branch restores the frame; a0 survives the restore. */ if (a->sret_ptr_slot == FRAME_SLOT_NONE) - compiler_panic(t->c, a->loc, "rv64 tail call: missing incoming sret slot"); + compiler_panic(t->c, a->loc, + "rv64 tail call: missing incoming sret slot"); RvSlot* s = rv64_slot_get(a, a->sret_ptr_slot); if (!s) compiler_panic(t->c, a->loc, "rv64 tail call: bad sret slot"); rv64_emit32(mc, rv_ld(RV_A0, RV_S0, -(i32)s->off)); @@ -1487,8 +1603,8 @@ static void rv_emit_call_plan(CGTarget* t, const CGCallPlan* p) { u32 pos = mc->pos(mc); rv64_emit32(mc, rv_auipc(RV_RA, 0)); rv64_emit32(mc, rv_jalr(RV_RA, RV_RA, 0)); - mc->emit_reloc_at(mc, sec, pos, R_RV_CALL, - p->callee.v.global.sym, p->callee.v.global.addend, 0, 0); + mc->emit_reloc_at(mc, sec, pos, R_RV_CALL, p->callee.v.global.sym, + p->callee.v.global.addend, 0, 0); } else if (p->callee.kind == OPK_REG) { rv64_emit32(mc, rv_jalr(RV_RA, reg_num(p->callee), 0)); } else { @@ -1604,8 +1720,7 @@ static void rv_ret(CGTarget* t, const CGABIValue* val) { "rv64 ret indirect: missing aggregate size"); } } else { - compiler_panic(t->c, a->loc, - "rv64 ret indirect: storage kind %d NYI", + compiler_panic(t->c, a->loc, "rv64 ret indirect: storage kind %d NYI", (int)val->storage.kind); } RvSlot* sp = (a->sret_ptr_slot != FRAME_SLOT_NONE) @@ -1686,8 +1801,8 @@ static void rv_alloca_(CGTarget* t, Operand d, Operand sz, u32 align) { compiler_panic(t->c, a->loc, "rv64 alloca: dst must be REG"); } if (align > 16) { - compiler_panic(t->c, a->loc, - "rv64 alloca: align %u > 16 not yet supported", align); + compiler_panic(t->c, a->loc, "rv64 alloca: align %u > 16 not yet supported", + align); } if (sz.kind == OPK_IMM) { i64 v = sz.v.imm; @@ -1714,7 +1829,8 @@ static void rv_alloca_(CGTarget* t, Operand d, Operand sz, u32 align) { /* Placeholder: addi dst, sp, max_outgoing (imm patched at func_end). */ if (a->nadd_patches == a->add_patches_cap) { u32 ncap = a->add_patches_cap ? a->add_patches_cap * 2 : 4; - struct RvAllocaPatch* nb = arena_array(t->c->tu, struct RvAllocaPatch, ncap); + struct RvAllocaPatch* nb = + arena_array(t->c->tu, struct RvAllocaPatch, ncap); if (a->add_patches) memcpy(nb, a->add_patches, sizeof(*nb) * a->nadd_patches); a->add_patches = nb; @@ -1775,7 +1891,8 @@ static void rv_va_arg_(CGTarget* t, Operand dst, Operand ap_op, } static void rv_va_end_(CGTarget* t, Operand a) { - (void)t; (void)a; + (void)t; + (void)a; } static void rv_va_copy_(CGTarget* t, Operand d, Operand s) { @@ -1790,7 +1907,8 @@ static void rv_va_copy_(CGTarget* t, Operand d, Operand s) { /* ---- atomics (LL/SC + AMO) ---- */ int mem_order_is_acquire(MemOrder o) { - return o == MO_ACQUIRE || o == MO_ACQ_REL || o == MO_SEQ_CST || o == MO_CONSUME; + return o == MO_ACQUIRE || o == MO_ACQ_REL || o == MO_SEQ_CST || + o == MO_CONSUME; } int mem_order_is_release(MemOrder o) { return o == MO_RELEASE || o == MO_ACQ_REL || o == MO_SEQ_CST; @@ -1818,7 +1936,7 @@ static void rv_atomic_load(CGTarget* t, Operand dst, Operand addr, MemAccess ma, if (mem_order_is_acquire(o)) { /* lr.w/d as ordered load (aq=1, rl=0). */ rv64_emit32(mc, sf ? rv_lr_d(reg_num(dst), base, 1, 0) - : rv_lr_w(reg_num(dst), base, 1, 0)); + : rv_lr_w(reg_num(dst), base, 1, 0)); } else { rv64_emit32(mc, enc_int_load(ma.size, 0, reg_num(dst), base, 0)); } @@ -1844,7 +1962,10 @@ static void rv_atomic_store(CGTarget* t, Operand addr, Operand src, } else if (addr.kind == OPK_LOCAL) { RvAddrMode am = addr_mode(t, addr, RV_T0); base = am.base; - if (am.ofs) { rv64_emit32(mc, rv_addi(RV_T0, base, am.ofs)); base = RV_T0; } + if (am.ofs) { + rv64_emit32(mc, rv_addi(RV_T0, base, am.ofs)); + base = RV_T0; + } } else { compiler_panic(t->c, impl_of(t)->loc, "rv64 atomic_store: addr kind %d NYI", (int)addr.kind); @@ -1875,9 +1996,12 @@ static void rv_atomic_rmw(CGTarget* t, AtomicOp op, Operand dst, Operand addr, compiler_panic(t->c, impl_of(t)->loc, "rv64 atomic_rmw: addr NYI"); } u32 vreg = RV_T1; - if (val.kind == OPK_IMM) rv64_emit_load_imm(mc, sf, vreg, val.v.imm); - else if (val.kind == OPK_REG) rv64_emit32(mc, rv_addi(vreg, reg_num(val), 0)); - else compiler_panic(t->c, impl_of(t)->loc, "rv64 atomic_rmw: val kind NYI"); + if (val.kind == OPK_IMM) + rv64_emit_load_imm(mc, sf, vreg, val.v.imm); + else if (val.kind == OPK_REG) + rv64_emit32(mc, rv_addi(vreg, reg_num(val), 0)); + else + compiler_panic(t->c, impl_of(t)->loc, "rv64 atomic_rmw: val kind NYI"); int aq = mem_order_is_acquire(o); int rl = mem_order_is_release(o); @@ -1887,45 +2011,68 @@ static void rv_atomic_rmw(CGTarget* t, AtomicOp op, Operand dst, Operand addr, MCLabel L_retry = mc->label_new(mc); mc->label_place(mc, L_retry); rv64_emit32(mc, sf ? rv_lr_d(reg_num(dst), base, (u32)aq, 0) - : rv_lr_w(reg_num(dst), base, (u32)aq, 0)); + : rv_lr_w(reg_num(dst), base, (u32)aq, 0)); u32 new_r = RV_T2; switch (op) { - case AO_XCHG: rv64_emit32(mc, rv_addi(new_r, vreg, 0)); break; - case AO_ADD: rv64_emit32(mc, sf ? rv_add(new_r, reg_num(dst), vreg) : rv_addw(new_r, reg_num(dst), vreg)); break; - case AO_SUB: rv64_emit32(mc, sf ? rv_sub(new_r, reg_num(dst), vreg) : rv_subw(new_r, reg_num(dst), vreg)); break; - case AO_AND: rv64_emit32(mc, rv_and(new_r, reg_num(dst), vreg)); break; - case AO_OR: rv64_emit32(mc, rv_or(new_r, reg_num(dst), vreg)); break; - case AO_XOR: rv64_emit32(mc, rv_xor(new_r, reg_num(dst), vreg)); break; + case AO_XCHG: + rv64_emit32(mc, rv_addi(new_r, vreg, 0)); + break; + case AO_ADD: + rv64_emit32(mc, sf ? rv_add(new_r, reg_num(dst), vreg) + : rv_addw(new_r, reg_num(dst), vreg)); + break; + case AO_SUB: + rv64_emit32(mc, sf ? rv_sub(new_r, reg_num(dst), vreg) + : rv_subw(new_r, reg_num(dst), vreg)); + break; + case AO_AND: + rv64_emit32(mc, rv_and(new_r, reg_num(dst), vreg)); + break; + case AO_OR: + rv64_emit32(mc, rv_or(new_r, reg_num(dst), vreg)); + break; + case AO_XOR: + rv64_emit32(mc, rv_xor(new_r, reg_num(dst), vreg)); + break; case AO_NAND: rv64_emit32(mc, rv_and(new_r, reg_num(dst), vreg)); rv64_emit32(mc, rv_xori(new_r, new_r, -1)); break; - default: rv64_emit32(mc, rv_addi(new_r, vreg, 0)); break; + default: + rv64_emit32(mc, rv_addi(new_r, vreg, 0)); + break; } /* sc.w/d t3, new_r, (base); bnez t3, retry. */ rv64_emit32(mc, sf ? rv_sc_d(RV_T3, base, new_r, 0, (u32)rl) - : rv_sc_w(RV_T3, base, new_r, 0, (u32)rl)); + : rv_sc_w(RV_T3, base, new_r, 0, (u32)rl)); rv64_emit32(mc, rv_bne(RV_T3, RV_ZERO, 0)); mc->emit_label_ref(mc, L_retry, R_RV_BRANCH, 4, 0); } static void rv_atomic_cas(CGTarget* t, Operand prior, Operand ok, Operand addr, - Operand exp, Operand des, MemAccess ma, - MemOrder succ, MemOrder fail) { + Operand exp, Operand des, MemAccess ma, MemOrder succ, + MemOrder fail) { MCEmitter* mc = t->mc; u32 sf = (ma.size == 8) ? 1u : 0u; (void)fail; u32 base = RV_T0; - if (addr.kind == OPK_REG) rv64_emit32(mc, rv_addi(base, reg_num(addr), 0)); + if (addr.kind == OPK_REG) + rv64_emit32(mc, rv_addi(base, reg_num(addr), 0)); else if (addr.kind == OPK_LOCAL) { RvAddrMode am = addr_mode(t, addr, RV_T0); - if (am.base != RV_T0 || am.ofs) rv64_emit32(mc, rv_addi(base, am.base, am.ofs)); - } else compiler_panic(t->c, impl_of(t)->loc, "rv64 atomic_cas: addr NYI"); + if (am.base != RV_T0 || am.ofs) + rv64_emit32(mc, rv_addi(base, am.base, am.ofs)); + } else + compiler_panic(t->c, impl_of(t)->loc, "rv64 atomic_cas: addr NYI"); u32 ereg = RV_T1, dreg = RV_T2; - if (exp.kind == OPK_IMM) rv64_emit_load_imm(mc, sf, ereg, exp.v.imm); - else rv64_emit32(mc, rv_addi(ereg, reg_num(exp), 0)); - if (des.kind == OPK_IMM) rv64_emit_load_imm(mc, sf, dreg, des.v.imm); - else rv64_emit32(mc, rv_addi(dreg, reg_num(des), 0)); + if (exp.kind == OPK_IMM) + rv64_emit_load_imm(mc, sf, ereg, exp.v.imm); + else + rv64_emit32(mc, rv_addi(ereg, reg_num(exp), 0)); + if (des.kind == OPK_IMM) + rv64_emit_load_imm(mc, sf, dreg, des.v.imm); + else + rv64_emit32(mc, rv_addi(dreg, reg_num(des), 0)); int aq = mem_order_is_acquire(succ); int rl = mem_order_is_release(succ); @@ -1936,13 +2083,13 @@ static void rv_atomic_cas(CGTarget* t, Operand prior, Operand ok, Operand addr, mc->label_place(mc, L_retry); rv64_emit32(mc, sf ? rv_lr_d(reg_num(prior), base, (u32)aq, 0) - : rv_lr_w(reg_num(prior), base, (u32)aq, 0)); + : rv_lr_w(reg_num(prior), base, (u32)aq, 0)); /* if (prior != expected) -> fail */ rv64_emit32(mc, rv_bne(reg_num(prior), ereg, 0)); mc->emit_label_ref(mc, L_fail, R_RV_BRANCH, 4, 0); /* sc.w/d t3, des, (base); bnez t3, retry */ rv64_emit32(mc, sf ? rv_sc_d(RV_T3, base, dreg, 0, (u32)rl) - : rv_sc_w(RV_T3, base, dreg, 0, (u32)rl)); + : rv_sc_w(RV_T3, base, dreg, 0, (u32)rl)); rv64_emit32(mc, rv_bne(RV_T3, RV_ZERO, 0)); mc->emit_label_ref(mc, L_retry, R_RV_BRANCH, 4, 0); /* ok = 1; jump done */ @@ -1964,7 +2111,8 @@ static void rv_fence(CGTarget* t, MemOrder o) { /* ---- intrinsics: do what we can; panic on the rest. ---- */ static void rv_intrinsic(CGTarget* t, IntrinKind kind, Operand* dsts, u32 nd, const Operand* args, u32 na) { - (void)nd; (void)na; + (void)nd; + (void)na; MCEmitter* mc = t->mc; RImpl* a = impl_of(t); switch (kind) { @@ -1985,7 +2133,8 @@ static void rv_intrinsic(CGTarget* t, IntrinKind kind, Operand* dsts, u32 nd, } return; } - case INTRIN_PREFETCH: return; + case INTRIN_PREFETCH: + return; case INTRIN_UNREACHABLE: case INTRIN_TRAP: rv64_emit32(mc, rv_ebreak()); @@ -1994,8 +2143,8 @@ static void rv_intrinsic(CGTarget* t, IntrinKind kind, Operand* dsts, u32 nd, /* rd = ((rs & 0xff) << 8) | ((rs >> 8) & 0xff) */ u32 rd = reg_num(dsts[0]); u32 rs = reg_num(args[0]); - rv64_emit32(mc, rv_slli(RV_T1, rs, 8)); /* t1 = rs << 8 */ - rv64_emit32(mc, rv_andi(RV_T1, RV_T1, 0)); /* placeholder */ + rv64_emit32(mc, rv_slli(RV_T1, rs, 8)); /* t1 = rs << 8 */ + rv64_emit32(mc, rv_andi(RV_T1, RV_T1, 0)); /* placeholder */ /* Use lui mask approach for portability: build mask 0xff00 in t2. */ rv64_emit32(mc, rv_addi(RV_T2, RV_ZERO, 0)); /* Simpler: 0xff00 fits in lui+addi pattern but is also small enough: @@ -2015,7 +2164,8 @@ static void rv_intrinsic(CGTarget* t, IntrinKind kind, Operand* dsts, u32 nd, case INTRIN_BSWAP32: { u32 rd = reg_num(dsts[0]); u32 rs = reg_num(args[0]); - /* result = (b0<<24)|(b1<<16)|(b2<<8)|b3, where bi = (rs >> (8*i)) & 0xff. */ + /* result = (b0<<24)|(b1<<16)|(b2<<8)|b3, where bi = (rs >> (8*i)) & 0xff. + */ /* t1 = ((rs >> 24) & 0xff) */ rv64_emit32(mc, rv_srliw(RV_T1, rs, 24)); rv64_emit32(mc, rv_andi(RV_T1, RV_T1, 0xff)); @@ -2075,13 +2225,13 @@ static void rv_intrinsic(CGTarget* t, IntrinKind kind, Operand* dsts, u32 nd, } /* t1 = t1 - ((t1 >> 1) & 0x5555...) */ rv64_emit32(mc, rv_srli(RV_T2, RV_T1, 1)); - rv64_emit_load_imm(mc, 1, RV_T3, is64 ? (i64)0x5555555555555555ll - : (i64)0x55555555); + rv64_emit_load_imm(mc, 1, RV_T3, + is64 ? (i64)0x5555555555555555ll : (i64)0x55555555); rv64_emit32(mc, rv_and(RV_T2, RV_T2, RV_T3)); rv64_emit32(mc, rv_sub(RV_T1, RV_T1, RV_T2)); /* t1 = (t1 & 0x3333...) + ((t1 >> 2) & 0x3333...) */ - rv64_emit_load_imm(mc, 1, RV_T3, is64 ? (i64)0x3333333333333333ll - : (i64)0x33333333); + rv64_emit_load_imm(mc, 1, RV_T3, + is64 ? (i64)0x3333333333333333ll : (i64)0x33333333); rv64_emit32(mc, rv_and(RV_T2, RV_T1, RV_T3)); rv64_emit32(mc, rv_srli(RV_T1, RV_T1, 2)); rv64_emit32(mc, rv_and(RV_T1, RV_T1, RV_T3)); @@ -2089,12 +2239,12 @@ static void rv_intrinsic(CGTarget* t, IntrinKind kind, Operand* dsts, u32 nd, /* t1 = (t1 + (t1 >> 4)) & 0x0f0f... */ rv64_emit32(mc, rv_srli(RV_T2, RV_T1, 4)); rv64_emit32(mc, rv_add(RV_T1, RV_T1, RV_T2)); - rv64_emit_load_imm(mc, 1, RV_T3, is64 ? (i64)0x0f0f0f0f0f0f0f0fll - : (i64)0x0f0f0f0f); + rv64_emit_load_imm(mc, 1, RV_T3, + is64 ? (i64)0x0f0f0f0f0f0f0f0fll : (i64)0x0f0f0f0f); rv64_emit32(mc, rv_and(RV_T1, RV_T1, RV_T3)); /* t1 *= 0x0101010101... ; result in top byte */ - rv64_emit_load_imm(mc, 1, RV_T3, is64 ? (i64)0x0101010101010101ll - : (i64)0x01010101); + rv64_emit_load_imm(mc, 1, RV_T3, + is64 ? (i64)0x0101010101010101ll : (i64)0x01010101); rv64_emit32(mc, rv_mul(RV_T1, RV_T1, RV_T3)); /* shift right by (XLEN - 8) */ rv64_emit32(mc, rv_srli(rd, RV_T1, is64 ? 56u : 24u)); @@ -2117,23 +2267,23 @@ static void rv_intrinsic(CGTarget* t, IntrinKind kind, Operand* dsts, u32 nd, } /* popcount(t1) into rd */ rv64_emit32(mc, rv_srli(RV_T2, RV_T1, 1)); - rv64_emit_load_imm(mc, 1, RV_T3, is64 ? (i64)0x5555555555555555ll - : (i64)0x55555555); + rv64_emit_load_imm(mc, 1, RV_T3, + is64 ? (i64)0x5555555555555555ll : (i64)0x55555555); rv64_emit32(mc, rv_and(RV_T2, RV_T2, RV_T3)); rv64_emit32(mc, rv_sub(RV_T1, RV_T1, RV_T2)); - rv64_emit_load_imm(mc, 1, RV_T3, is64 ? (i64)0x3333333333333333ll - : (i64)0x33333333); + rv64_emit_load_imm(mc, 1, RV_T3, + is64 ? (i64)0x3333333333333333ll : (i64)0x33333333); rv64_emit32(mc, rv_and(RV_T2, RV_T1, RV_T3)); rv64_emit32(mc, rv_srli(RV_T1, RV_T1, 2)); rv64_emit32(mc, rv_and(RV_T1, RV_T1, RV_T3)); rv64_emit32(mc, rv_add(RV_T1, RV_T1, RV_T2)); rv64_emit32(mc, rv_srli(RV_T2, RV_T1, 4)); rv64_emit32(mc, rv_add(RV_T1, RV_T1, RV_T2)); - rv64_emit_load_imm(mc, 1, RV_T3, is64 ? (i64)0x0f0f0f0f0f0f0f0fll - : (i64)0x0f0f0f0f); + rv64_emit_load_imm(mc, 1, RV_T3, + is64 ? (i64)0x0f0f0f0f0f0f0f0fll : (i64)0x0f0f0f0f); rv64_emit32(mc, rv_and(RV_T1, RV_T1, RV_T3)); - rv64_emit_load_imm(mc, 1, RV_T3, is64 ? (i64)0x0101010101010101ll - : (i64)0x01010101); + rv64_emit_load_imm(mc, 1, RV_T3, + is64 ? (i64)0x0101010101010101ll : (i64)0x01010101); rv64_emit32(mc, rv_mul(RV_T1, RV_T1, RV_T3)); rv64_emit32(mc, rv_srli(rd, RV_T1, is64 ? 56u : 24u)); return; @@ -2171,23 +2321,23 @@ static void rv_intrinsic(CGTarget* t, IntrinKind kind, Operand* dsts, u32 nd, } /* popcount(t1) into rd */ rv64_emit32(mc, rv_srli(RV_T2, RV_T1, 1)); - rv64_emit_load_imm(mc, 1, RV_T3, is64 ? (i64)0x5555555555555555ll - : (i64)0x55555555); + rv64_emit_load_imm(mc, 1, RV_T3, + is64 ? (i64)0x5555555555555555ll : (i64)0x55555555); rv64_emit32(mc, rv_and(RV_T2, RV_T2, RV_T3)); rv64_emit32(mc, rv_sub(RV_T1, RV_T1, RV_T2)); - rv64_emit_load_imm(mc, 1, RV_T3, is64 ? (i64)0x3333333333333333ll - : (i64)0x33333333); + rv64_emit_load_imm(mc, 1, RV_T3, + is64 ? (i64)0x3333333333333333ll : (i64)0x33333333); rv64_emit32(mc, rv_and(RV_T2, RV_T1, RV_T3)); rv64_emit32(mc, rv_srli(RV_T1, RV_T1, 2)); rv64_emit32(mc, rv_and(RV_T1, RV_T1, RV_T3)); rv64_emit32(mc, rv_add(RV_T1, RV_T1, RV_T2)); rv64_emit32(mc, rv_srli(RV_T2, RV_T1, 4)); rv64_emit32(mc, rv_add(RV_T1, RV_T1, RV_T2)); - rv64_emit_load_imm(mc, 1, RV_T3, is64 ? (i64)0x0f0f0f0f0f0f0f0fll - : (i64)0x0f0f0f0f); + rv64_emit_load_imm(mc, 1, RV_T3, + is64 ? (i64)0x0f0f0f0f0f0f0f0fll : (i64)0x0f0f0f0f); rv64_emit32(mc, rv_and(RV_T1, RV_T1, RV_T3)); - rv64_emit_load_imm(mc, 1, RV_T3, is64 ? (i64)0x0101010101010101ll - : (i64)0x01010101); + rv64_emit_load_imm(mc, 1, RV_T3, + is64 ? (i64)0x0101010101010101ll : (i64)0x01010101); rv64_emit32(mc, rv_mul(RV_T1, RV_T1, RV_T3)); rv64_emit32(mc, rv_srli(rd, RV_T1, is64 ? 56u : 24u)); return; @@ -2223,7 +2373,8 @@ static void rv_intrinsic(CGTarget* t, IntrinKind kind, Operand* dsts, u32 nd, } /* shift right to extract sign bit */ u32 sh = is64 ? 63u : 31u; - rv64_emit32(mc, is64 ? rv_srli(rovf, rovf, sh) : rv_srliw(rovf, rovf, sh)); + rv64_emit32(mc, + is64 ? rv_srli(rovf, rovf, sh) : rv_srliw(rovf, rovf, sh)); rv64_emit32(mc, rv_andi(rovf, rovf, 1)); /* Now write the value. */ rv64_emit32(mc, rv_addi(rd, RV_T2, 0)); @@ -2325,16 +2476,48 @@ static void rv_intrinsic(CGTarget* t, IntrinKind kind, Operand* dsts, u32 nd, u32 dr = reg_num(da), sr = reg_num(sa), n = (u32)nb.v.imm; if (kind == INTRIN_MEMCPY) { u32 i = 0; - while (i + 8 <= n) { rv64_emit32(mc, rv_ld(RV_T3, sr, (i32)i)); rv64_emit32(mc, rv_sd(RV_T3, dr, (i32)i)); i += 8; } - while (i + 4 <= n) { rv64_emit32(mc, rv_lwu(RV_T3, sr, (i32)i)); rv64_emit32(mc, rv_sw(RV_T3, dr, (i32)i)); i += 4; } - while (i + 2 <= n) { rv64_emit32(mc, rv_lhu(RV_T3, sr, (i32)i)); rv64_emit32(mc, rv_sh(RV_T3, dr, (i32)i)); i += 2; } - while (i < n) { rv64_emit32(mc, rv_lbu(RV_T3, sr, (i32)i)); rv64_emit32(mc, rv_sb(RV_T3, dr, (i32)i)); i += 1; } + while (i + 8 <= n) { + rv64_emit32(mc, rv_ld(RV_T3, sr, (i32)i)); + rv64_emit32(mc, rv_sd(RV_T3, dr, (i32)i)); + i += 8; + } + while (i + 4 <= n) { + rv64_emit32(mc, rv_lwu(RV_T3, sr, (i32)i)); + rv64_emit32(mc, rv_sw(RV_T3, dr, (i32)i)); + i += 4; + } + while (i + 2 <= n) { + rv64_emit32(mc, rv_lhu(RV_T3, sr, (i32)i)); + rv64_emit32(mc, rv_sh(RV_T3, dr, (i32)i)); + i += 2; + } + while (i < n) { + rv64_emit32(mc, rv_lbu(RV_T3, sr, (i32)i)); + rv64_emit32(mc, rv_sb(RV_T3, dr, (i32)i)); + i += 1; + } } else { u32 i = n; - while (i >= 8) { i -= 8; rv64_emit32(mc, rv_ld(RV_T3, sr, (i32)i)); rv64_emit32(mc, rv_sd(RV_T3, dr, (i32)i)); } - while (i >= 4) { i -= 4; rv64_emit32(mc, rv_lwu(RV_T3, sr, (i32)i)); rv64_emit32(mc, rv_sw(RV_T3, dr, (i32)i)); } - while (i >= 2) { i -= 2; rv64_emit32(mc, rv_lhu(RV_T3, sr, (i32)i)); rv64_emit32(mc, rv_sh(RV_T3, dr, (i32)i)); } - while (i >= 1) { i -= 1; rv64_emit32(mc, rv_lbu(RV_T3, sr, (i32)i)); rv64_emit32(mc, rv_sb(RV_T3, dr, (i32)i)); } + while (i >= 8) { + i -= 8; + rv64_emit32(mc, rv_ld(RV_T3, sr, (i32)i)); + rv64_emit32(mc, rv_sd(RV_T3, dr, (i32)i)); + } + while (i >= 4) { + i -= 4; + rv64_emit32(mc, rv_lwu(RV_T3, sr, (i32)i)); + rv64_emit32(mc, rv_sw(RV_T3, dr, (i32)i)); + } + while (i >= 2) { + i -= 2; + rv64_emit32(mc, rv_lhu(RV_T3, sr, (i32)i)); + rv64_emit32(mc, rv_sh(RV_T3, dr, (i32)i)); + } + while (i >= 1) { + i -= 1; + rv64_emit32(mc, rv_lbu(RV_T3, sr, (i32)i)); + rv64_emit32(mc, rv_sb(RV_T3, dr, (i32)i)); + } } return; } @@ -2347,9 +2530,13 @@ static void rv_intrinsic(CGTarget* t, IntrinKind kind, Operand* dsts, u32 nd, u32 src; if (bv.kind == OPK_IMM) { u32 byte = (u32)(bv.v.imm & 0xffu); - if (byte == 0) src = RV_ZERO; + if (byte == 0) + src = RV_ZERO; else { - u64 b = byte; b |= b << 8; b |= b << 16; b |= b << 32; + u64 b = byte; + b |= b << 8; + b |= b << 16; + b |= b << 32; rv64_emit_load_imm(mc, 1, RV_T3, (i64)b); src = RV_T3; } @@ -2357,10 +2544,22 @@ static void rv_intrinsic(CGTarget* t, IntrinKind kind, Operand* dsts, u32 nd, compiler_panic(t->c, a->loc, "rv64 intrinsic: memset REG byte NYI"); } u32 i = 0; - while (i + 8 <= n) { rv64_emit32(mc, rv_sd(src, dr, (i32)i)); i += 8; } - while (i + 4 <= n) { rv64_emit32(mc, rv_sw(src, dr, (i32)i)); i += 4; } - while (i + 2 <= n) { rv64_emit32(mc, rv_sh(src, dr, (i32)i)); i += 2; } - while (i < n) { rv64_emit32(mc, rv_sb(src, dr, (i32)i)); i += 1; } + while (i + 8 <= n) { + rv64_emit32(mc, rv_sd(src, dr, (i32)i)); + i += 8; + } + while (i + 4 <= n) { + rv64_emit32(mc, rv_sw(src, dr, (i32)i)); + i += 4; + } + while (i + 2 <= n) { + rv64_emit32(mc, rv_sh(src, dr, (i32)i)); + i += 2; + } + while (i < n) { + rv64_emit32(mc, rv_sb(src, dr, (i32)i)); + i += 1; + } return; } default: @@ -2387,8 +2586,7 @@ static void rv_asm_block(CGTarget* t, const char* tmpl, if (rv64_register_index(buf, &dwarf) != 0) continue; if (dwarf <= 31u) { /* Integer reg: s0=x8, s1=x9, s2..s11=x18..x27. */ - if (dwarf == 8u || dwarf == 9u || - (dwarf >= 18u && dwarf <= 27u)) { + if (dwarf == 8u || dwarf == 9u || (dwarf >= 18u && dwarf <= 27u)) { impl->used_cs_int_mask |= 1u << dwarf; } } else if (dwarf >= 32u && dwarf <= 63u) { diff --git a/src/arch/rv64/opt_coord.c b/src/arch/rv64/opt_coord.c @@ -6,28 +6,23 @@ * Static register tables reported to caller-owned allocators. */ static const Reg rv_int_allocable[] = {20, 21, 22, 23, 24, 25, 26, 27}; -static const Reg rv_fp_allocable[] = {20, 21, 22, 23, 24, 25, 26, 27}; +static const Reg rv_fp_allocable[] = {20, 21, 22, 23, 24, 25, 26, 27}; static const Reg rv_int_scratch[] = {18, 19}; /* s2, s3; reserved by opt_emit */ -static const Reg rv_fp_scratch[] = {18, 19}; /* fs2, fs3; reserved by opt_emit */ +static const Reg rv_fp_scratch[] = {18, + 19}; /* fs2, fs3; reserved by opt_emit */ static const CGPhysRegInfo rv_int_phys[] = { - {10, RC_INT, 0, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG | CG_REG_RET, 0, 0}, - {11, RC_INT, 1, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG | CG_REG_RET, 0, 0}, - {12, RC_INT, 2, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {13, RC_INT, 3, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {14, RC_INT, 4, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {15, RC_INT, 5, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {16, RC_INT, 6, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {17, RC_INT, 7, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, + {10, RC_INT, 0, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG | CG_REG_RET, 0, 0}, + {11, RC_INT, 1, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG | CG_REG_RET, 0, 0}, + {12, RC_INT, 2, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, 0}, + {13, RC_INT, 3, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, 0}, + {14, RC_INT, 4, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, 0}, + {15, RC_INT, 5, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, 0}, + {16, RC_INT, 6, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, 0}, + {17, RC_INT, 7, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, 0}, {20, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLEE_SAVED, 50, 4}, {21, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLEE_SAVED, 50, 4}, {22, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLEE_SAVED, 50, 4}, @@ -36,30 +31,24 @@ static const CGPhysRegInfo rv_int_phys[] = { {25, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLEE_SAVED, 50, 4}, {26, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLEE_SAVED, 50, 4}, {27, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLEE_SAVED, 50, 4}, - {29, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_TEMP_PREFERRED, 0, 0}, - {30, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_TEMP_PREFERRED, 0, 0}, - {31, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_TEMP_PREFERRED, 0, 0}, + {29, RC_INT, 0xff, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_TEMP_PREFERRED, 0, 0}, + {30, RC_INT, 0xff, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_TEMP_PREFERRED, 0, 0}, + {31, RC_INT, 0xff, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_TEMP_PREFERRED, 0, 0}, }; static const CGPhysRegInfo rv_fp_phys[] = { - {10, RC_FP, 0, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG | CG_REG_RET, 0, 0}, - {11, RC_FP, 1, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG | CG_REG_RET, 0, 0}, - {12, RC_FP, 2, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {13, RC_FP, 3, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {14, RC_FP, 4, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {15, RC_FP, 5, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {16, RC_FP, 6, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {17, RC_FP, 7, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, + {10, RC_FP, 0, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG | CG_REG_RET, 0, 0}, + {11, RC_FP, 1, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG | CG_REG_RET, 0, 0}, + {12, RC_FP, 2, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, 0}, + {13, RC_FP, 3, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, 0}, + {14, RC_FP, 4, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, 0}, + {15, RC_FP, 5, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, 0}, + {16, RC_FP, 6, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, 0}, + {17, RC_FP, 7, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, 0}, {20, RC_FP, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLEE_SAVED, 50, 4}, {21, RC_FP, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLEE_SAVED, 50, 4}, {22, RC_FP, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLEE_SAVED, 50, 4}, @@ -77,8 +66,8 @@ static const CGPhysRegInfo rv_fp_phys[] = { /* ============================================================ * Vtable methods */ -static void rv_get_allocable_regs(CGTarget* t, RegClass cls, - const Reg** out, u32* nregs) { +static void rv_get_allocable_regs(CGTarget* t, RegClass cls, const Reg** out, + u32* nregs) { (void)t; switch (cls) { case RC_INT: @@ -96,8 +85,8 @@ static void rv_get_allocable_regs(CGTarget* t, RegClass cls, } } -static void rv_get_scratch_regs(CGTarget* t, RegClass cls, - const Reg** out, u32* nregs) { +static void rv_get_scratch_regs(CGTarget* t, RegClass cls, const Reg** out, + u32* nregs) { (void)t; switch (cls) { case RC_INT: @@ -180,8 +169,10 @@ static u32 rv_return_reg_mask(CGTarget* t, const ABIFuncInfo* abi, u32 mask = 0, ni = 0, nf = 0; for (u16 i = 0; i < abi->ret.nparts; ++i) { const ABIArgPart* p = &abi->ret.parts[i]; - if (cls == RC_INT && p->cls == ABI_CLASS_INT) mask |= 1u << (RV_A0 + ni++); - else if (cls == RC_FP && p->cls == ABI_CLASS_FP) mask |= 1u << (10u + nf++); + if (cls == RC_INT && p->cls == ABI_CLASS_INT) + mask |= 1u << (RV_A0 + ni++); + else if (cls == RC_FP && p->cls == ABI_CLASS_FP) + mask |= 1u << (10u + nf++); } return mask; } @@ -280,8 +271,8 @@ static void rv_plan_call(CGTarget* t, const CGCallDesc* d, CGCallPlan* out) { } } } - if ((d->flags & CG_CALL_TAIL) == 0 && - d->abi && d->abi->ret.kind != ABI_ARG_IGNORE && + if ((d->flags & CG_CALL_TAIL) == 0 && d->abi && + d->abi->ret.kind != ABI_ARG_IGNORE && d->abi->ret.kind != ABI_ARG_INDIRECT) { u32 ni = 0, nf = 0; for (u16 i = 0; i < d->abi->ret.nparts; ++i) { @@ -303,8 +294,8 @@ static void rv_plan_call(CGTarget* t, const CGCallDesc* d, CGCallPlan* out) { } } -static void rv_reserve_hard_regs(CGTarget* t, RegClass cls, - const Reg* regs, u32 n) { +static void rv_reserve_hard_regs(CGTarget* t, RegClass cls, const Reg* regs, + u32 n) { RImpl* a = impl_of(t); for (u32 i = 0; i < n; ++i) { Reg r = regs[i]; @@ -342,13 +333,13 @@ static void rv_plan_hard_regs(CGTarget* t, RegClass cls, const Reg* regs, void rv_coord_vtable_init(CGTarget* t) { t->get_allocable_regs = rv_get_allocable_regs; - t->get_phys_regs = rv_get_phys_regs; - t->get_scratch_regs = rv_get_scratch_regs; - t->is_caller_saved = rv_is_caller_saved; - t->call_clobber_mask = rv_call_clobber_mask; - t->return_reg_mask = rv_return_reg_mask; - t->callee_save_mask = rv_callee_save_mask; - t->plan_call = rv_plan_call; - t->plan_hard_regs = rv_plan_hard_regs; - t->reserve_hard_regs = rv_reserve_hard_regs; + t->get_phys_regs = rv_get_phys_regs; + t->get_scratch_regs = rv_get_scratch_regs; + t->is_caller_saved = rv_is_caller_saved; + t->call_clobber_mask = rv_call_clobber_mask; + t->return_reg_mask = rv_return_reg_mask; + t->callee_save_mask = rv_callee_save_mask; + t->plan_call = rv_plan_call; + t->plan_hard_regs = rv_plan_hard_regs; + t->reserve_hard_regs = rv_reserve_hard_regs; } diff --git a/src/arch/rv64/regs.c b/src/arch/rv64/regs.c @@ -17,25 +17,25 @@ typedef struct Rv64Reg { } Rv64Reg; static const Rv64Reg RV64_REGS[] = { - {0, "zero"}, {1, "ra"}, {2, "sp"}, {3, "gp"}, {4, "tp"}, - {5, "t0"}, {6, "t1"}, {7, "t2"}, {8, "s0"}, {9, "s1"}, - {10, "a0"}, {11, "a1"}, {12, "a2"}, {13, "a3"}, {14, "a4"}, - {15, "a5"}, {16, "a6"}, {17, "a7"}, {18, "s2"}, {19, "s3"}, - {20, "s4"}, {21, "s5"}, {22, "s6"}, {23, "s7"}, {24, "s8"}, - {25, "s9"}, {26, "s10"}, {27, "s11"}, {28, "t3"}, {29, "t4"}, - {30, "t5"}, {31, "t6"}, + {0, "zero"}, {1, "ra"}, {2, "sp"}, {3, "gp"}, {4, "tp"}, + {5, "t0"}, {6, "t1"}, {7, "t2"}, {8, "s0"}, {9, "s1"}, + {10, "a0"}, {11, "a1"}, {12, "a2"}, {13, "a3"}, {14, "a4"}, + {15, "a5"}, {16, "a6"}, {17, "a7"}, {18, "s2"}, {19, "s3"}, + {20, "s4"}, {21, "s5"}, {22, "s6"}, {23, "s7"}, {24, "s8"}, + {25, "s9"}, {26, "s10"}, {27, "s11"}, {28, "t3"}, {29, "t4"}, + {30, "t5"}, {31, "t6"}, - {32, "ft0"}, {33, "ft1"}, {34, "ft2"}, {35, "ft3"}, {36, "ft4"}, - {37, "ft5"}, {38, "ft6"}, {39, "ft7"}, {40, "fs0"}, {41, "fs1"}, - {42, "fa0"}, {43, "fa1"}, {44, "fa2"}, {45, "fa3"}, {46, "fa4"}, - {47, "fa5"}, {48, "fa6"}, {49, "fa7"}, {50, "fs2"}, {51, "fs3"}, - {52, "fs4"}, {53, "fs5"}, {54, "fs6"}, {55, "fs7"}, {56, "fs8"}, - {57, "fs9"}, {58, "fs10"}, {59, "fs11"}, {60, "ft8"}, {61, "ft9"}, + {32, "ft0"}, {33, "ft1"}, {34, "ft2"}, {35, "ft3"}, {36, "ft4"}, + {37, "ft5"}, {38, "ft6"}, {39, "ft7"}, {40, "fs0"}, {41, "fs1"}, + {42, "fa0"}, {43, "fa1"}, {44, "fa2"}, {45, "fa3"}, {46, "fa4"}, + {47, "fa5"}, {48, "fa6"}, {49, "fa7"}, {50, "fs2"}, {51, "fs3"}, + {52, "fs4"}, {53, "fs5"}, {54, "fs6"}, {55, "fs7"}, {56, "fs8"}, + {57, "fs9"}, {58, "fs10"}, {59, "fs11"}, {60, "ft8"}, {61, "ft9"}, {62, "ft10"}, {63, "ft11"}, }; -static const uint32_t RV64_REGS_N = (uint32_t)(sizeof RV64_REGS / - sizeof RV64_REGS[0]); +static const uint32_t RV64_REGS_N = + (uint32_t)(sizeof RV64_REGS / sizeof RV64_REGS[0]); static int parse_num_suffix(const char* name, char prefix, uint32_t max, uint32_t* out) { diff --git a/src/arch/wasm/abi.c b/src/arch/wasm/abi.c @@ -1,6 +1,7 @@ /* wasm32 BasicCABI classifier. * - * Reference: https://github.com/WebAssembly/tool-conventions/blob/main/BasicCABI.md + * Reference: + * https://github.com/WebAssembly/tool-conventions/blob/main/BasicCABI.md * * Coverage for v1: * void -> IGNORE @@ -68,8 +69,7 @@ static int try_classify_singleton(TargetABI* a, CfreeCgTypeId t, field_ty = ty->record.fields[0].type; field = cg_type_get(a->c, field_ty); if (!field) return 0; - if (field->kind == CFREE_CG_TYPE_RECORD || - field->kind == CFREE_CG_TYPE_ARRAY) + if (field->kind == CFREE_CG_TYPE_RECORD || field->kind == CFREE_CG_TYPE_ARRAY) return 0; ti = abi_internal_type_info(a, field_ty); if (ti.size != (u32)ty->size) return 0; diff --git a/src/arch/wasm/arch.c b/src/arch/wasm/arch.c @@ -6,6 +6,7 @@ * wasm_encode. There is no assembly form for wasm32 in the toolchain. */ #include "arch/arch.h" + #include "arch/wasm/internal.h" /* Predefined macros mirroring clang/llvm conventions. */ @@ -15,7 +16,8 @@ static const CfreePredefinedMacro wasm_predefined_macros[] = { {CFREE_SLICE_LIT("__ILP32__"), CFREE_SLICE_LIT("1")}, {CFREE_SLICE_LIT("__ORDER_LITTLE_ENDIAN__"), CFREE_SLICE_LIT("1234")}, {CFREE_SLICE_LIT("__ORDER_BIG_ENDIAN__"), CFREE_SLICE_LIT("4321")}, - {CFREE_SLICE_LIT("__BYTE_ORDER__"), CFREE_SLICE_LIT("__ORDER_LITTLE_ENDIAN__")}, + {CFREE_SLICE_LIT("__BYTE_ORDER__"), + CFREE_SLICE_LIT("__ORDER_LITTLE_ENDIAN__")}, {CFREE_SLICE_LIT("__LITTLE_ENDIAN__"), CFREE_SLICE_LIT("1")}, }; diff --git a/src/arch/wasm/emit.c b/src/arch/wasm/emit.c @@ -5,12 +5,11 @@ * flow that fits the cfree_cg_if_begin/else/end pattern lowers to * if/else/end, while CG scopes (SCOPE_LOOP) lower to (block (loop ...)). */ -#include "arch/wasm/internal.h" - #include <stdarg.h> #include <string.h> #include "abi/abi.h" +#include "arch/wasm/internal.h" #include "arch/wasm/wasm_imports.h" #include "cg/type.h" #include "core/arena.h" @@ -89,8 +88,7 @@ static u32 align_to_u32(u32 v, u32 a) { #define WASM_DATA_NULL_GUARD 16u static void type_size_align(WTarget* t, CfreeCgTypeId ty, u32 fallback_size, - u32 fallback_align, u32* size_out, - u32* align_out) { + u32 fallback_align, u32* size_out, u32* align_out) { ABITypeInfo ti; if (ty) { ti = abi_cg_type_info(t->c->abi, ty); @@ -158,8 +156,8 @@ static u32 reg_local(WTarget* t, Reg r, CfreeCgTypeId ty, RegClass cls) { if (r >= t->reg_cap) { u32 nc = t->reg_cap ? t->reg_cap : 16u; while (nc <= r) nc *= 2u; - u32* nl = (u32*)h->realloc(h, t->reg_to_local, - sizeof(u32) * t->reg_cap, sizeof(u32) * nc, _Alignof(u32)); + u32* nl = (u32*)h->realloc(h, t->reg_to_local, sizeof(u32) * t->reg_cap, + sizeof(u32) * nc, _Alignof(u32)); CfreeCgTypeId* nt = (CfreeCgTypeId*)h->realloc( h, t->reg_type, sizeof(CfreeCgTypeId) * t->reg_cap, sizeof(CfreeCgTypeId) * nc, _Alignof(CfreeCgTypeId)); @@ -214,7 +212,13 @@ static WIR* wir_push(WTarget* t) { } /* Operand-kind encoding stored in WIR's imm_kind / imm_kind_b. */ -enum { WOP_REG = 0, WOP_IMM = 1, WOP_LOCAL = 2, WOP_WASM_LOCAL = 3, WOP_ADDR = 4 }; +enum { + WOP_REG = 0, + WOP_IMM = 1, + WOP_LOCAL = 2, + WOP_WASM_LOCAL = 3, + WOP_ADDR = 4 +}; static void wir_capture_operand(WIR* w, int which, Operand op) { u32 kind; @@ -314,8 +318,7 @@ void wasm_jump(CGTarget* tg, Label l) { void wasm_cmp_branch(CGTarget* tg, CmpOp op, Operand a, Operand b, Label l) { WTarget* t = (WTarget*)tg; if (t->dead) return; - if (!lookup_label(t, l)) - wfail(t, "wasm: cmp_branch to unknown label"); + if (!lookup_label(t, l)) wfail(t, "wasm: cmp_branch to unknown label"); WIR* w = wir_push(t); w->op = WIR_CMP_BRANCH; w->cgop = (u8)op; @@ -332,10 +335,8 @@ void wasm_switch(CGTarget* tg, const CGSwitchDesc* d) { if (!d) wfail(t, "wasm: switch without descriptor"); if (d->default_label == LABEL_NONE) wfail(t, "wasm: switch without default label"); - if (d->ncases && !d->cases) - wfail(t, "wasm: switch case count without cases"); - if (d->ncases >= 64u) - wfail(t, "wasm: too many switch cases for br_table"); + if (d->ncases && !d->cases) wfail(t, "wasm: switch case count without cases"); + if (d->ncases >= 64u) wfail(t, "wasm: too many switch cases for br_table"); if (d->selector.kind != OPK_REG && d->selector.kind != OPK_IMM && d->selector.kind != OPK_LOCAL) wfail(t, "wasm: switch selector has unsupported operand kind"); @@ -354,9 +355,8 @@ void wasm_switch(CGTarget* tg, const CGSwitchDesc* d) { w->switch_ncases = d->ncases; if (d->ncases) { Heap* h = t->c->ctx->heap; - w->switch_cases = - (CGSwitchCase*)h->alloc(h, sizeof(CGSwitchCase) * d->ncases, - _Alignof(CGSwitchCase)); + w->switch_cases = (CGSwitchCase*)h->alloc( + h, sizeof(CGSwitchCase) * d->ncases, _Alignof(CGSwitchCase)); if (!w->switch_cases) wfail(t, "wasm: out of memory"); memcpy(w->switch_cases, d->cases, sizeof(CGSwitchCase) * d->ncases); } @@ -369,8 +369,7 @@ void wasm_switch(CGTarget* tg, const CGSwitchDesc* d) { CGScope wasm_scope_begin(CGTarget* tg, const CGScopeDesc* d) { WTarget* t = (WTarget*)tg; - if (t->nscopes >= 32u) - wfail(t, "wasm: too many nested scopes (max 32)"); + if (t->nscopes >= 32u) wfail(t, "wasm: too many nested scopes (max 32)"); WScope* s = &t->scopes[t->nscopes]; memset(s, 0, sizeof *s); s->id = ++t->next_scope_id; @@ -435,8 +434,7 @@ void wasm_scope_else(CGTarget* tg, CGScope sc) { WTarget* t = (WTarget*)tg; WScope* s = scope_by_id(t, (u32)sc); if (!s) wfail(t, "wasm: scope_else on unknown scope"); - if (s->cg_kind != SCOPE_IF) - wfail(t, "wasm: scope_else on non-if scope"); + if (s->cg_kind != SCOPE_IF) wfail(t, "wasm: scope_else on non-if scope"); WIR* w = wir_push(t); w->op = WIR_SCOPE_ELSE; w->scope_id = s->id; @@ -495,9 +493,9 @@ static u32 sym_to_wasm_func(WTarget* t, ObjSymId sym, WasmFunc** out_func) { if (sym >= t->sym_to_func_cap) { u32 nc = t->sym_to_func_cap ? t->sym_to_func_cap : 16u; while (nc <= sym) nc *= 2u; - u32* p = (u32*)h->realloc(h, t->sym_to_func, - sizeof(u32) * t->sym_to_func_cap, - sizeof(u32) * nc, _Alignof(u32)); + u32* p = + (u32*)h->realloc(h, t->sym_to_func, sizeof(u32) * t->sym_to_func_cap, + sizeof(u32) * nc, _Alignof(u32)); if (!p) wfail(t, "wasm: out of memory"); for (u32 i = t->sym_to_func_cap; i < nc; ++i) p[i] = 0; t->sym_to_func = p; @@ -625,7 +623,8 @@ void wasm_func_begin(CGTarget* tg, const CGFuncDesc* d) { * params/locals/local_names grow on demand — no fixed cap. */ f->nparams = 0; if (abi->has_sret) { - t->sret_param_local = wasm_func_push_param(t->c, t->module, f, WASM_VAL_I32); + t->sret_param_local = + wasm_func_push_param(t->c, t->module, f, WASM_VAL_I32); t->cur_has_sret = 1; ensure_linear_memory(t); } @@ -668,9 +667,11 @@ void wasm_func_begin(CGTarget* tg, const CGFuncDesc* d) { ensure_linear_memory(t); } f->nresults = 0; - if (!abi->has_sret && abi->ret.kind == ABI_ARG_DIRECT && abi->ret.nparts == 1) { + if (!abi->has_sret && abi->ret.kind == ABI_ARG_DIRECT && + abi->ret.nparts == 1) { const ABIArgPart* p = &abi->ret.parts[0]; - f->results[0] = valtype_for_size_kind(t, p->size, p->cls == ABI_CLASS_FP ? ABI_SC_FLOAT : ABI_SC_INT); + f->results[0] = valtype_for_size_kind( + t, p->size, p->cls == ABI_CLASS_FP ? ABI_SC_FLOAT : ABI_SC_INT); f->nresults = 1; } f->typeidx = wasm_intern_func_type(t->c, t->module, f); @@ -703,8 +704,8 @@ CGLocalStorage wasm_param(CGTarget* tg, const CGParamDesc* d) { WSlot* s; memset(&ls, 0, sizeof ls); if (d->index >= t->nparams_cg) - wfail(t, "wasm: param index %u out of range (nparams=%u)", - d->index, t->nparams_cg); + wfail(t, "wasm: param index %u out of range (nparams=%u)", d->index, + t->nparams_cg); wli = t->param_local_idx[d->index]; if (wli == 0xffffffffu) { /* ABI_ARG_IGNORE — no wasm storage. Push a placeholder slot so the @@ -775,9 +776,9 @@ static FrameSlot alloc_frame_slot(WTarget* t, CfreeCgTypeId ty) { FrameSlot wasm_frame_slot(CGTarget* tg, const FrameSlotDesc* d) { WTarget* t = (WTarget*)tg; if (!d->type && !d->size) wfail(t, "wasm: frame slot without type/size"); - return alloc_frame_slot_kind(t, d->type, d->size, d->align, - (d->flags & FSF_ADDR_TAKEN) != 0 || - d->kind == FS_ALLOCA); + return alloc_frame_slot_kind( + t, d->type, d->size, d->align, + (d->flags & FSF_ADDR_TAKEN) != 0 || d->kind == FS_ALLOCA); } CGLocalStorage wasm_local(CGTarget* tg, const CGLocalDesc* d) { @@ -786,8 +787,7 @@ CGLocalStorage wasm_local(CGTarget* tg, const CGLocalDesc* d) { memset(&ls, 0, sizeof ls); if (d->flags & (CG_LOCAL_ADDR_TAKEN | CG_LOCAL_MEMORY_REQUIRED)) { ls.kind = CG_LOCAL_STORAGE_FRAME; - ls.v.frame_slot = - alloc_frame_slot_kind(t, d->type, d->size, d->align, 1); + ls.v.frame_slot = alloc_frame_slot_kind(t, d->type, d->size, d->align, 1); return ls; } ls.kind = CG_LOCAL_STORAGE_FRAME; @@ -837,9 +837,12 @@ void wasm_load_const(CGTarget* tg, Operand dst, ConstBytes cb) { memcpy(&v, cb.bytes, cb.size < 8 ? cb.size : 8u); /* Sign-extend for small signed types so the immediate has the expected * bit pattern. */ - if (cb.size == 1) v = (i64)(i8)v; - else if (cb.size == 2) v = (i64)(i16)v; - else if (cb.size == 4) v = (i64)(i32)v; + if (cb.size == 1) + v = (i64)(i8)v; + else if (cb.size == 2) + v = (i64)(i16)v; + else if (cb.size == 4) + v = (i64)(i32)v; w->op = WIR_LOAD_IMM; w->imm = v; } @@ -1007,8 +1010,9 @@ static void promote_import_func(WTarget* t, ObjSymId sym, WasmFunc* f, if (os->section_id != OBJ_SEC_NONE) return; /* already defined locally */ if (os->kind != SK_UNDEF && os->kind != SK_FUNC) return; if (!abi) - wfail(t, "wasm: cannot synthesize import signature for '%s' " - "(missing ABI info)", + wfail(t, + "wasm: cannot synthesize import signature for '%s' " + "(missing ABI info)", pool_sym_cstr(t->c->global, os->name, NULL)); if (f->ninsns != 0) wfail(t, "wasm: cannot promote function with emitted body to import"); @@ -1028,8 +1032,8 @@ static void promote_import_func(WTarget* t, ObjSymId sym, WasmFunc* f, { const char* prefix = "import '"; const char* suffix = "'"; - size_t plen = 8u; /* strlen(prefix) */ - size_t slen = 1u; /* strlen(suffix) */ + size_t plen = 8u; /* strlen(prefix) */ + size_t slen = 1u; /* strlen(suffix) */ size_t nlen = sym_name_len ? sym_name_len : strlen(sym_name); if (nlen > sizeof(what) - plen - slen - 1u) nlen = sizeof(what) - plen - slen - 1u; @@ -1050,12 +1054,12 @@ static void promote_import_func(WTarget* t, ObjSymId sym, WasmFunc* f, * import_name)) on the C declaration. */ (void)wasm_imports_get(t->obj, os->name, &attr_module, &attr_name); if (attr_module) mod_str = pool_sym_cstr(t->c->global, attr_module, &mod_len); - const char* name_str = attr_name ? pool_sym_cstr(t->c->global, attr_name, - &sym_name_len) - : sym_name; - size_t name_len = attr_name ? sym_name_len - : (sym_name_len ? sym_name_len - : strlen(name_str)); + const char* name_str = + attr_name ? pool_sym_cstr(t->c->global, attr_name, &sym_name_len) + : sym_name; + size_t name_len = attr_name + ? sym_name_len + : (sym_name_len ? sym_name_len : strlen(name_str)); f->is_import = 1; { char* m = (char*)h->alloc(h, mod_len + 1u, 1); @@ -1110,16 +1114,14 @@ void wasm_call(CGTarget* tg, const CGCallDesc* d) { u32 nvar = 0u; if (callee_variadic) { if (d->nargs < d->abi->nparams) - wfail(t, - "wasm: variadic call has fewer args (%u) than fixed params (%u)", + wfail(t, "wasm: variadic call has fewer args (%u) than fixed params (%u)", (unsigned)d->nargs, (unsigned)d->abi->nparams); nfixed = d->abi->nparams; nvar = (u32)d->nargs - nfixed; } WIR* w = wir_push(t); if (is_indirect) { - if (!d->abi) - wfail(t, "wasm: indirect call without ABIFuncInfo"); + if (!d->abi) wfail(t, "wasm: indirect call without ABIFuncInfo"); ensure_module(t); w->op = WIR_CALL_INDIRECT; w->a = d->callee.v.reg; @@ -1140,8 +1142,8 @@ void wasm_call(CGTarget* tg, const CGCallDesc* d) { WasmFunc* f; ensure_module(t); (void)sym_to_wasm_func(t, d->callee.v.global.sym, &f); - if (!f->is_import) promote_import_func(t, d->callee.v.global.sym, f, - d->abi); + if (!f->is_import) + promote_import_func(t, d->callee.v.global.sym, f, d->abi); } } } @@ -1160,24 +1162,21 @@ void wasm_call(CGTarget* tg, const CGCallDesc* d) { } if (nfixed) { w->call_args = (Reg*)h->alloc(h, sizeof(Reg) * nfixed, _Alignof(Reg)); - w->call_arg_imms = - (i64*)h->alloc(h, sizeof(i64) * nfixed, _Alignof(i64)); + w->call_arg_imms = (i64*)h->alloc(h, sizeof(i64) * nfixed, _Alignof(i64)); w->call_arg_kinds = (u8*)h->alloc(h, nfixed, 1); w->call_arg_types = (CfreeCgTypeId*)h->alloc( h, sizeof(CfreeCgTypeId) * nfixed, _Alignof(CfreeCgTypeId)); - w->call_arg_addrs = (Operand*)h->alloc( - h, sizeof(Operand) * nfixed, _Alignof(Operand)); + w->call_arg_addrs = + (Operand*)h->alloc(h, sizeof(Operand) * nfixed, _Alignof(Operand)); memset(w->call_arg_addrs, 0, sizeof(Operand) * nfixed); for (u32 i = 0; i < nfixed; ++i) { const CGABIValue* av = &d->args[i]; w->call_arg_types[i] = av->type; int is_indirect = (av->abi && av->abi->kind == ABI_ARG_INDIRECT); if (is_indirect) { - if (av->storage.kind != OPK_LOCAL && - av->storage.kind != OPK_INDIRECT && + if (av->storage.kind != OPK_LOCAL && av->storage.kind != OPK_INDIRECT && av->storage.kind != OPK_GLOBAL) { - wfail(t, - "wasm: byval call arg %u storage kind %u must be an address", + wfail(t, "wasm: byval call arg %u storage kind %u must be an address", i, (unsigned)av->storage.kind); } w->call_arg_kinds[i] = WOP_ADDR; @@ -1203,8 +1202,7 @@ void wasm_call(CGTarget* tg, const CGCallDesc* d) { } if (nvar) { w->call_var_regs = (Reg*)h->alloc(h, sizeof(Reg) * nvar, _Alignof(Reg)); - w->call_var_imms = - (i64*)h->alloc(h, sizeof(i64) * nvar, _Alignof(i64)); + w->call_var_imms = (i64*)h->alloc(h, sizeof(i64) * nvar, _Alignof(i64)); w->call_var_kinds = (u8*)h->alloc(h, nvar, 1); w->call_var_types = (CfreeCgTypeId*)h->alloc( h, sizeof(CfreeCgTypeId) * nvar, _Alignof(CfreeCgTypeId)); @@ -1212,12 +1210,9 @@ void wasm_call(CGTarget* tg, const CGCallDesc* d) { const CGABIValue* av = &d->args[nfixed + i]; const CgType* aty = av->type ? cg_type_get(t->c, av->type) : NULL; w->call_var_types[i] = av->type; - if (aty && - (aty->kind == CFREE_CG_TYPE_RECORD || - aty->kind == CFREE_CG_TYPE_ARRAY)) { - wfail(t, - "wasm target: aggregate variadic arg %u not yet supported", - i); + if (aty && (aty->kind == CFREE_CG_TYPE_RECORD || + aty->kind == CFREE_CG_TYPE_ARRAY)) { + wfail(t, "wasm target: aggregate variadic arg %u not yet supported", i); } if (av->storage.kind == OPK_REG) { w->call_var_kinds[i] = WOP_REG; @@ -1239,7 +1234,8 @@ void wasm_call(CGTarget* tg, const CGCallDesc* d) { /* The call has no wasm result; the buffer pointed to by the sret arg * holds the aggregate. */ w->dst = REG_NONE; - } else if (d->ret.storage.kind == OPK_REG && d->ret.storage.v.reg != REG_NONE) { + } else if (d->ret.storage.kind == OPK_REG && + d->ret.storage.v.reg != REG_NONE) { w->dst = d->ret.storage.v.reg; } else { w->dst = REG_NONE; @@ -1256,8 +1252,7 @@ void wasm_ret(CGTarget* tg, const CGABIValue* v) { * pointed to by the hidden sret parameter, then a void return. */ w->addr = v->storage; w->type = v->type; - w->agg.size = - v->size ? v->size : (u32)abi_cg_sizeof(t->c->abi, v->type); + w->agg.size = v->size ? v->size : (u32)abi_cg_sizeof(t->c->abi, v->type); w->agg.align = 1u; w->cgop = 1; /* tag: sret copy */ w->dst = REG_NONE; @@ -1283,15 +1278,16 @@ void wasm_load(CGTarget* tg, Operand dst, Operand addr, MemAccess mem) { slot_for(t, addr.v.frame_slot)->kind == W_SLOT_STACK) ensure_linear_memory(t); WIR* w = wir_push(t); - w->op = (addr.kind == OPK_LOCAL && slot_for(t, addr.v.frame_slot)->kind == W_SLOT_LOCAL) + w->op = (addr.kind == OPK_LOCAL && + slot_for(t, addr.v.frame_slot)->kind == W_SLOT_LOCAL) ? WIR_LOAD_LOCAL : WIR_LOAD_MEM; w->dst = dst.v.reg; w->addr = addr; if (addr.kind == OPK_LOCAL) { WSlot* s = slot_for(t, addr.v.frame_slot); - w->imm = (w->op == WIR_LOAD_LOCAL) ? (i64)s->wasm_local - : (i64)addr.v.frame_slot; + w->imm = + (w->op == WIR_LOAD_LOCAL) ? (i64)s->wasm_local : (i64)addr.v.frame_slot; } w->mem = mem; w->type = dst.type; @@ -1305,7 +1301,8 @@ void wasm_store(CGTarget* tg, Operand addr, Operand src, MemAccess mem) { slot_for(t, addr.v.frame_slot)->kind == W_SLOT_STACK) ensure_linear_memory(t); WIR* w = wir_push(t); - w->op = (addr.kind == OPK_LOCAL && slot_for(t, addr.v.frame_slot)->kind == W_SLOT_LOCAL) + w->op = (addr.kind == OPK_LOCAL && + slot_for(t, addr.v.frame_slot)->kind == W_SLOT_LOCAL) ? WIR_STORE_LOCAL : WIR_STORE_MEM; w->addr = addr; @@ -1340,8 +1337,8 @@ void wasm_va_arg(CGTarget* tg, Operand dst, Operand ap_addr, if (t->dead) return; if (dst.kind != OPK_REG) wfail(t, "wasm: va_arg dst must be REG"); const CgType* aty = type ? cg_type_get(t->c, type) : NULL; - if (aty && (aty->kind == CFREE_CG_TYPE_RECORD || - aty->kind == CFREE_CG_TYPE_ARRAY)) { + if (aty && + (aty->kind == CFREE_CG_TYPE_RECORD || aty->kind == CFREE_CG_TYPE_ARRAY)) { wfail(t, "wasm target: va_arg of aggregate type not yet supported"); } ensure_linear_memory(t); @@ -1367,7 +1364,7 @@ void wasm_va_copy(CGTarget* tg, Operand dst_ap_addr, Operand src_ap_addr) { WIR* w = wir_push(t); w->op = WIR_VA_COPY; w->addr = dst_ap_addr; - w->call_sret_addr = src_ap_addr; /* reused slot — see WIR comment */ + w->call_sret_addr = src_ap_addr; /* reused slot — see WIR comment */ } void wasm_addr_of(CGTarget* tg, Operand dst, Operand lv) { @@ -1417,7 +1414,8 @@ void wasm_alloca(CGTarget* tg, Operand dst, Operand size, u32 align) { w->imm = align ? align : 16u; } -void wasm_copy_bytes(CGTarget* tg, Operand dst, Operand src, AggregateAccess a) { +void wasm_copy_bytes(CGTarget* tg, Operand dst, Operand src, + AggregateAccess a) { WTarget* t = (WTarget*)tg; if (t->dead) return; ensure_linear_memory(t); @@ -1428,7 +1426,8 @@ void wasm_copy_bytes(CGTarget* tg, Operand dst, Operand src, AggregateAccess a) w->agg = a; } -void wasm_set_bytes(CGTarget* tg, Operand dst, Operand byte, AggregateAccess a) { +void wasm_set_bytes(CGTarget* tg, Operand dst, Operand byte, + AggregateAccess a) { WTarget* t = (WTarget*)tg; if (t->dead) return; WIR* w = wir_push(t); @@ -1563,29 +1562,52 @@ void wasm_emit_unreachable(WTarget* t); * users see "wasm target: __builtin_clz ..." instead of a numeric kind. */ static const char* intrin_name(IntrinKind k) { switch (k) { - case INTRIN_NONE: return "<none>"; - case INTRIN_POPCOUNT: return "__builtin_popcount"; - case INTRIN_CTZ: return "__builtin_ctz"; - case INTRIN_CLZ: return "__builtin_clz"; - case INTRIN_BSWAP16: return "__builtin_bswap16"; - case INTRIN_BSWAP32: return "__builtin_bswap32"; - case INTRIN_BSWAP64: return "__builtin_bswap64"; - case INTRIN_MEMCPY: return "memcpy"; - case INTRIN_MEMMOVE: return "memmove"; - case INTRIN_MEMSET: return "memset"; - case INTRIN_PREFETCH: return "__builtin_prefetch"; - case INTRIN_ASSUME_ALIGNED: return "__builtin_assume_aligned"; - case INTRIN_EXPECT: return "__builtin_expect"; - case INTRIN_UNREACHABLE: return "__builtin_unreachable"; - case INTRIN_TRAP: return "__builtin_trap"; - case INTRIN_SETJMP: return "setjmp"; - case INTRIN_LONGJMP: return "longjmp"; - case INTRIN_SADD_OVERFLOW: return "__builtin_sadd_overflow"; - case INTRIN_UADD_OVERFLOW: return "__builtin_uadd_overflow"; - case INTRIN_SSUB_OVERFLOW: return "__builtin_ssub_overflow"; - case INTRIN_USUB_OVERFLOW: return "__builtin_usub_overflow"; - case INTRIN_SMUL_OVERFLOW: return "__builtin_smul_overflow"; - case INTRIN_UMUL_OVERFLOW: return "__builtin_umul_overflow"; + case INTRIN_NONE: + return "<none>"; + case INTRIN_POPCOUNT: + return "__builtin_popcount"; + case INTRIN_CTZ: + return "__builtin_ctz"; + case INTRIN_CLZ: + return "__builtin_clz"; + case INTRIN_BSWAP16: + return "__builtin_bswap16"; + case INTRIN_BSWAP32: + return "__builtin_bswap32"; + case INTRIN_BSWAP64: + return "__builtin_bswap64"; + case INTRIN_MEMCPY: + return "memcpy"; + case INTRIN_MEMMOVE: + return "memmove"; + case INTRIN_MEMSET: + return "memset"; + case INTRIN_PREFETCH: + return "__builtin_prefetch"; + case INTRIN_ASSUME_ALIGNED: + return "__builtin_assume_aligned"; + case INTRIN_EXPECT: + return "__builtin_expect"; + case INTRIN_UNREACHABLE: + return "__builtin_unreachable"; + case INTRIN_TRAP: + return "__builtin_trap"; + case INTRIN_SETJMP: + return "setjmp"; + case INTRIN_LONGJMP: + return "longjmp"; + case INTRIN_SADD_OVERFLOW: + return "__builtin_sadd_overflow"; + case INTRIN_UADD_OVERFLOW: + return "__builtin_uadd_overflow"; + case INTRIN_SSUB_OVERFLOW: + return "__builtin_ssub_overflow"; + case INTRIN_USUB_OVERFLOW: + return "__builtin_usub_overflow"; + case INTRIN_SMUL_OVERFLOW: + return "__builtin_smul_overflow"; + case INTRIN_UMUL_OVERFLOW: + return "__builtin_umul_overflow"; } return "<unknown>"; } @@ -1634,7 +1656,8 @@ void wasm_intrinsic(CGTarget* tg, IntrinKind k, Operand* dst, u32 ndst, if (args[2].kind != OPK_IMM) { compiler_panic(t->c, cur_loc(t), "wasm target: %s with non-constant size is not yet " - "supported", intrin_name(k)); + "supported", + intrin_name(k)); return; } ensure_linear_memory(t); @@ -1738,7 +1761,8 @@ void wasm_intrinsic(CGTarget* tg, IntrinKind k, Operand* dst, u32 ndst, case INTRIN_LONGJMP: compiler_panic(t->c, cur_loc(t), "wasm target: %s is not yet supported (no exception/" - "stack-unwind runtime)", intrin_name(k)); + "stack-unwind runtime)", + intrin_name(k)); return; case INTRIN_NONE: @@ -1768,17 +1792,17 @@ static WasmValType wasm_asm_operand_vt(WTarget* t, CfreeCgTypeId ty, WasmValType vt; if (!ty) wfail_at(t, loc, "wasm target: asm %s with no CG type", what); vt = valtype_for_type(t, ty); - if (vt != WASM_VAL_I32 && vt != WASM_VAL_I64 && - vt != WASM_VAL_F32 && vt != WASM_VAL_F64) + if (vt != WASM_VAL_I32 && vt != WASM_VAL_I64 && vt != WASM_VAL_F32 && + vt != WASM_VAL_F64) wfail_at(t, loc, "wasm target: asm %s of non-scalar type not supported", what); return vt; } -void wasm_asm_block(CGTarget* tg, const char* tmpl, - const AsmConstraint* outs, u32 nout, Operand* out_ops, - const AsmConstraint* ins, u32 nin, const Operand* in_ops, - const Sym* clob, u32 nclob) { +void wasm_asm_block(CGTarget* tg, const char* tmpl, const AsmConstraint* outs, + u32 nout, Operand* out_ops, const AsmConstraint* ins, + u32 nin, const Operand* in_ops, const Sym* clob, + u32 nclob) { WTarget* t = (WTarget*)tg; Heap* h = t->c->ctx->heap; Sym sym_memory; @@ -1795,8 +1819,7 @@ void wasm_asm_block(CGTarget* tg, const char* tmpl, sym_memory = pool_intern_slice(t->c->global, SLICE_LIT("memory")); for (i = 0; i < nclob; ++i) { if (clob[i] != sym_memory) - wfail_at(t, loc, - "wasm target: asm register clobbers not yet supported"); + wfail_at(t, loc, "wasm target: asm register clobbers not yet supported"); } /* Build a scratch WasmFunc with the synthetic signature. Layout is: @@ -1812,8 +1835,7 @@ void wasm_asm_block(CGTarget* tg, const char* tmpl, WasmValType vt = wasm_asm_operand_vt(t, ins[i].type, "input operand", loc); /* Constraint-specific checks: "i" requires an immediate operand; "m" * requires an indirect (i32 address). */ - if (ins[i].str && ins[i].str[0] == 'i' && - in_ops[i].kind != OPK_IMM) + if (ins[i].str && ins[i].str[0] == 'i' && in_ops[i].kind != OPK_IMM) wfail_at(t, loc, "wasm target: asm 'i' input must be an immediate"); if (ins[i].str && ins[i].str[0] == 'm') { if (in_ops[i].kind != OPK_INDIRECT) @@ -1895,12 +1917,10 @@ void wasm_asm_block(CGTarget* tg, const char* tmpl, w->op = WIR_ASM_BLOCK; w->raw_ninsns = scratch.ninsns; if (scratch.ninsns) { - w->raw_insns = - (WasmInsn*)h->alloc(h, sizeof(WasmInsn) * scratch.ninsns, - _Alignof(WasmInsn)); + w->raw_insns = (WasmInsn*)h->alloc(h, sizeof(WasmInsn) * scratch.ninsns, + _Alignof(WasmInsn)); if (!w->raw_insns) wfail(t, "wasm: out of memory"); - memcpy(w->raw_insns, scratch.insns, - sizeof(WasmInsn) * scratch.ninsns); + memcpy(w->raw_insns, scratch.insns, sizeof(WasmInsn) * scratch.ninsns); } w->asm_nin = nin; w->asm_nout = nout; @@ -1908,10 +1928,9 @@ void wasm_asm_block(CGTarget* tg, const char* tmpl, w->asm_in_kinds = (u8*)h->alloc(h, nin, 1); w->asm_in_imms = (i64*)h->alloc(h, sizeof(i64) * nin, _Alignof(i64)); w->asm_in_regs = (Reg*)h->alloc(h, sizeof(Reg) * nin, _Alignof(Reg)); - w->asm_in_types = (CfreeCgTypeId*)h->alloc( - h, sizeof(CfreeCgTypeId) * nin, _Alignof(CfreeCgTypeId)); - w->asm_in_share_out = (i32*)h->alloc( - h, sizeof(i32) * nin, _Alignof(i32)); + w->asm_in_types = (CfreeCgTypeId*)h->alloc(h, sizeof(CfreeCgTypeId) * nin, + _Alignof(CfreeCgTypeId)); + w->asm_in_share_out = (i32*)h->alloc(h, sizeof(i32) * nin, _Alignof(i32)); if (!w->asm_in_kinds || !w->asm_in_imms || !w->asm_in_regs || !w->asm_in_types || !w->asm_in_share_out) wfail(t, "wasm: out of memory"); @@ -1952,8 +1971,7 @@ void wasm_asm_block(CGTarget* tg, const char* tmpl, w->asm_in_types[i] = builtin_id(CFREE_CG_BUILTIN_I32); break; default: - wfail_at(t, loc, - "wasm target: unsupported asm input operand kind"); + wfail_at(t, loc, "wasm target: unsupported asm input operand kind"); } } } @@ -1967,8 +1985,7 @@ void wasm_asm_block(CGTarget* tg, const char* tmpl, if (out_ops[i].kind != OPK_REG) wfail_at(t, loc, "wasm target: asm output must be a register"); w->asm_out_regs[i] = out_ops[i].v.reg; - w->asm_out_types[i] = - out_ops[i].type ? out_ops[i].type : outs[i].type; + w->asm_out_types[i] = out_ops[i].type ? out_ops[i].type : outs[i].type; } } } @@ -1985,7 +2002,8 @@ void wasm_asm_block(CGTarget* tg, const char* tmpl, void wasm_file_scope_asm(CGTarget* tg, const char* src, size_t len) { WTarget* t = (WTarget*)tg; - (void)src; (void)len; + (void)src; + (void)len; compiler_panic(t->c, cur_loc(t), "wasm target: file-scope asm not yet supported"); } @@ -2031,8 +2049,8 @@ static WasmValType type_valtype(WTarget* t, CfreeCgTypeId ty) { } static void emit_push_imm(WTarget* t, WasmValType vt, i64 imm) { - WasmInsnKind k = (vt == WASM_VAL_I64) ? WASM_INSN_I64_CONST - : WASM_INSN_I32_CONST; + WasmInsnKind k = + (vt == WASM_VAL_I64) ? WASM_INSN_I64_CONST : WASM_INSN_I32_CONST; emit_insn(t, k, imm); } @@ -2060,17 +2078,18 @@ static void emit_push_operand(WTarget* t, u32 kind, i64 imm, Reg r, ma.align = s->align; emit_insn(t, WASM_INSN_LOCAL_GET, (i64)t->frame_base_local); WasmInsnKind k = load_kind_for(t, ty, ma); - wasm_func_add_mem_insn(t->c, t->module, t->cur_func, k, - memarg_align_log2(ma.align, - wasm_mem_width((uint8_t)k)), - s->frame_offset, 0); + wasm_func_add_mem_insn( + t->c, t->module, t->cur_func, k, + memarg_align_log2(ma.align, wasm_mem_width((uint8_t)k)), + s->frame_offset, 0); } } else { emit_push_operand_reg(t, r); } } -static void emit_local_set(WTarget* t, Reg dst, CfreeCgTypeId ty, RegClass cls) { +static void emit_local_set(WTarget* t, Reg dst, CfreeCgTypeId ty, + RegClass cls) { u32 idx = reg_local(t, dst, ty, cls); emit_insn(t, WASM_INSN_LOCAL_SET, (i64)idx); } @@ -2127,8 +2146,9 @@ static WasmInsnKind atomic_load_kind_for(WTarget* t, CfreeCgTypeId ty, WasmValType vt = type_valtype(t, ty); u32 size = ma.size ? ma.size : (u32)abi_cg_sizeof(t->c->abi, ty); if (vt == WASM_VAL_F32 || vt == WASM_VAL_F64) - wfail(t, "wasm target: atomic load of floating-point value is not " - "representable in wasm threads"); + wfail(t, + "wasm target: atomic load of floating-point value is not " + "representable in wasm threads"); if (vt == WASM_VAL_I64) { if (size == 1) return WASM_INSN_I64_ATOMIC_LOAD8_U; if (size == 2) return WASM_INSN_I64_ATOMIC_LOAD16_U; @@ -2147,8 +2167,9 @@ static WasmInsnKind atomic_store_kind_for(WTarget* t, CfreeCgTypeId ty, WasmValType vt = type_valtype(t, ty); u32 size = ma.size ? ma.size : (u32)abi_cg_sizeof(t->c->abi, ty); if (vt == WASM_VAL_F32 || vt == WASM_VAL_F64) - wfail(t, "wasm target: atomic store of floating-point value is not " - "representable in wasm threads"); + wfail(t, + "wasm target: atomic store of floating-point value is not " + "representable in wasm threads"); if (vt == WASM_VAL_I64) { if (size == 1) return WASM_INSN_I64_ATOMIC_STORE8; if (size == 2) return WASM_INSN_I64_ATOMIC_STORE16; @@ -2168,12 +2189,15 @@ static WasmInsnKind atomic_rmw_kind_for(WTarget* t, AtomicOp op, u32 size = ma.size ? ma.size : (u32)abi_cg_sizeof(t->c->abi, ty); int is64 = (vt == WASM_VAL_I64); if (vt == WASM_VAL_F32 || vt == WASM_VAL_F64) - wfail(t, "wasm target: atomic RMW on floating-point value is not " - "representable in wasm threads"); + wfail(t, + "wasm target: atomic RMW on floating-point value is not " + "representable in wasm threads"); if (!(size == 4 || size == 8) || (is64 && size != 8) || (!is64 && size != 4)) { - wfail(t, "wasm target: atomic RMW size %u not yet supported (only " - "full-width i32 and i64 atomic RMW are wired)", size); + wfail(t, + "wasm target: atomic RMW size %u not yet supported (only " + "full-width i32 and i64 atomic RMW are wired)", + size); } switch (op) { case AO_ADD: @@ -2187,7 +2211,8 @@ static WasmInsnKind atomic_rmw_kind_for(WTarget* t, AtomicOp op, case AO_XOR: return is64 ? WASM_INSN_I64_ATOMIC_RMW_XOR : WASM_INSN_I32_ATOMIC_RMW_XOR; case AO_XCHG: - return is64 ? WASM_INSN_I64_ATOMIC_RMW_XCHG : WASM_INSN_I32_ATOMIC_RMW_XCHG; + return is64 ? WASM_INSN_I64_ATOMIC_RMW_XCHG + : WASM_INSN_I32_ATOMIC_RMW_XCHG; case AO_NAND: wfail(t, "wasm target: atomic NAND has no native wasm-threads opcode"); } @@ -2199,8 +2224,9 @@ static WasmInsnKind atomic_cmpxchg_kind_for(WTarget* t, CfreeCgTypeId ty, WasmValType vt = type_valtype(t, ty); u32 size = ma.size ? ma.size : (u32)abi_cg_sizeof(t->c->abi, ty); if (vt == WASM_VAL_F32 || vt == WASM_VAL_F64) - wfail(t, "wasm target: atomic cmpxchg on floating-point value is not " - "representable in wasm threads"); + wfail(t, + "wasm target: atomic cmpxchg on floating-point value is not " + "representable in wasm threads"); if (vt == WASM_VAL_I64) { if (size != 8) wfail(t, "wasm target: atomic cmpxchg i64 size %u not yet supported", @@ -2221,8 +2247,7 @@ static u32 func_table_index_for(WTarget* t, ObjSymId sym) { } if (t->func_table_count == t->func_table_cap) { u32 nc = t->func_table_cap ? t->func_table_cap * 2u : 8u; - void* p = h->realloc(h, t->func_table, - sizeof(ObjSymId) * t->func_table_cap, + void* p = h->realloc(h, t->func_table, sizeof(ObjSymId) * t->func_table_cap, sizeof(ObjSymId) * nc, _Alignof(ObjSymId)); if (!p) wfail(t, "wasm: out of memory"); t->func_table = (ObjSymId*)p; @@ -2246,16 +2271,15 @@ static void queue_func_table_fixup(WTarget* t, ObjSymId sym) { emit_insn(t, WASM_INSN_I32_CONST, 0); if (t->func_table_fixups_count == t->func_table_fixups_cap) { u32 nc = t->func_table_fixups_cap ? t->func_table_fixups_cap * 2u : 16u; - void* p = h->realloc(h, t->func_table_fixups, - sizeof(WFuncTableFixup) * t->func_table_fixups_cap, - sizeof(WFuncTableFixup) * nc, - _Alignof(WFuncTableFixup)); + void* p = + h->realloc(h, t->func_table_fixups, + sizeof(WFuncTableFixup) * t->func_table_fixups_cap, + sizeof(WFuncTableFixup) * nc, _Alignof(WFuncTableFixup)); if (!p) wfail(t, "wasm: out of memory"); t->func_table_fixups = (WFuncTableFixup*)p; t->func_table_fixups_cap = nc; } - WFuncTableFixup* fx = - &t->func_table_fixups[t->func_table_fixups_count++]; + WFuncTableFixup* fx = &t->func_table_fixups[t->func_table_fixups_count++]; fx->wasm_func_idx = t->cur_func_idx; fx->insn_idx = t->cur_func->ninsns - 1u; fx->sym = sym; @@ -2291,8 +2315,9 @@ static void queue_symbol_addr_fixup(WTarget* t, ObjSymId sym, i64 addend) { emit_insn(t, WASM_INSN_I32_CONST, 0); if (t->sym_fixups_count == t->sym_fixups_cap) { u32 nc = t->sym_fixups_cap ? t->sym_fixups_cap * 2u : 16u; - void* p = h->realloc(h, t->sym_fixups, sizeof(WSymFixup) * t->sym_fixups_cap, - sizeof(WSymFixup) * nc, _Alignof(WSymFixup)); + void* p = + h->realloc(h, t->sym_fixups, sizeof(WSymFixup) * t->sym_fixups_cap, + sizeof(WSymFixup) * nc, _Alignof(WSymFixup)); if (!p) wfail(t, "wasm: out of memory"); t->sym_fixups = (WSymFixup*)p; t->sym_fixups_cap = nc; @@ -2395,23 +2420,40 @@ static void emit_store_addr(WTarget* t, Operand addr, CfreeCgTypeId ty, /* Map (BinOp, valtype) to wasm opcode. */ static WasmInsnKind binop_kind(WTarget* t, BinOp op, WasmValType vt) { switch (op) { - case BO_IADD: return vt == WASM_VAL_I64 ? WASM_INSN_I64_ADD : WASM_INSN_I32_ADD; - case BO_ISUB: return vt == WASM_VAL_I64 ? WASM_INSN_I64_SUB : WASM_INSN_I32_SUB; - case BO_IMUL: return vt == WASM_VAL_I64 ? WASM_INSN_I64_MUL : WASM_INSN_I32_MUL; - case BO_SDIV: return vt == WASM_VAL_I64 ? WASM_INSN_I64_DIV_S : WASM_INSN_I32_DIV_S; - case BO_UDIV: return vt == WASM_VAL_I64 ? WASM_INSN_I64_DIV_U : WASM_INSN_I32_DIV_U; - case BO_SREM: return vt == WASM_VAL_I64 ? WASM_INSN_I64_REM_S : WASM_INSN_I32_REM_S; - case BO_UREM: return vt == WASM_VAL_I64 ? WASM_INSN_I64_REM_U : WASM_INSN_I32_REM_U; - case BO_AND: return vt == WASM_VAL_I64 ? WASM_INSN_I64_AND : WASM_INSN_I32_AND; - case BO_OR: return vt == WASM_VAL_I64 ? WASM_INSN_I64_OR : WASM_INSN_I32_OR; - case BO_XOR: return vt == WASM_VAL_I64 ? WASM_INSN_I64_XOR : WASM_INSN_I32_XOR; - case BO_SHL: return vt == WASM_VAL_I64 ? WASM_INSN_I64_SHL : WASM_INSN_I32_SHL; - case BO_SHR_S:return vt == WASM_VAL_I64 ? WASM_INSN_I64_SHR_S : WASM_INSN_I32_SHR_S; - case BO_SHR_U:return vt == WASM_VAL_I64 ? WASM_INSN_I64_SHR_U : WASM_INSN_I32_SHR_U; - case BO_FADD: return vt == WASM_VAL_F64 ? WASM_INSN_F64_ADD : WASM_INSN_F32_ADD; - case BO_FSUB: return vt == WASM_VAL_F64 ? WASM_INSN_F64_SUB : WASM_INSN_F32_SUB; - case BO_FMUL: return vt == WASM_VAL_F64 ? WASM_INSN_F64_MUL : WASM_INSN_F32_MUL; - case BO_FDIV: return vt == WASM_VAL_F64 ? WASM_INSN_F64_DIV : WASM_INSN_F32_DIV; + case BO_IADD: + return vt == WASM_VAL_I64 ? WASM_INSN_I64_ADD : WASM_INSN_I32_ADD; + case BO_ISUB: + return vt == WASM_VAL_I64 ? WASM_INSN_I64_SUB : WASM_INSN_I32_SUB; + case BO_IMUL: + return vt == WASM_VAL_I64 ? WASM_INSN_I64_MUL : WASM_INSN_I32_MUL; + case BO_SDIV: + return vt == WASM_VAL_I64 ? WASM_INSN_I64_DIV_S : WASM_INSN_I32_DIV_S; + case BO_UDIV: + return vt == WASM_VAL_I64 ? WASM_INSN_I64_DIV_U : WASM_INSN_I32_DIV_U; + case BO_SREM: + return vt == WASM_VAL_I64 ? WASM_INSN_I64_REM_S : WASM_INSN_I32_REM_S; + case BO_UREM: + return vt == WASM_VAL_I64 ? WASM_INSN_I64_REM_U : WASM_INSN_I32_REM_U; + case BO_AND: + return vt == WASM_VAL_I64 ? WASM_INSN_I64_AND : WASM_INSN_I32_AND; + case BO_OR: + return vt == WASM_VAL_I64 ? WASM_INSN_I64_OR : WASM_INSN_I32_OR; + case BO_XOR: + return vt == WASM_VAL_I64 ? WASM_INSN_I64_XOR : WASM_INSN_I32_XOR; + case BO_SHL: + return vt == WASM_VAL_I64 ? WASM_INSN_I64_SHL : WASM_INSN_I32_SHL; + case BO_SHR_S: + return vt == WASM_VAL_I64 ? WASM_INSN_I64_SHR_S : WASM_INSN_I32_SHR_S; + case BO_SHR_U: + return vt == WASM_VAL_I64 ? WASM_INSN_I64_SHR_U : WASM_INSN_I32_SHR_U; + case BO_FADD: + return vt == WASM_VAL_F64 ? WASM_INSN_F64_ADD : WASM_INSN_F32_ADD; + case BO_FSUB: + return vt == WASM_VAL_F64 ? WASM_INSN_F64_SUB : WASM_INSN_F32_SUB; + case BO_FMUL: + return vt == WASM_VAL_F64 ? WASM_INSN_F64_MUL : WASM_INSN_F32_MUL; + case BO_FDIV: + return vt == WASM_VAL_F64 ? WASM_INSN_F64_DIV : WASM_INSN_F32_DIV; } wfail(t, "wasm: unsupported binop %d", (int)op); } @@ -2419,103 +2461,176 @@ static WasmInsnKind binop_kind(WTarget* t, BinOp op, WasmValType vt) { static WasmInsnKind cmp_kind(WTarget* t, CmpOp op, WasmValType vt) { int is64 = (vt == WASM_VAL_I64); switch (op) { - case CMP_EQ: return is64 ? WASM_INSN_I64_EQ : WASM_INSN_I32_EQ; - case CMP_NE: return is64 ? WASM_INSN_I64_NE : WASM_INSN_I32_NE; - case CMP_LT_S: return is64 ? WASM_INSN_I64_LT_S : WASM_INSN_I32_LT_S; - case CMP_LE_S: return is64 ? WASM_INSN_I64_LE_S : WASM_INSN_I32_LE_S; - case CMP_GT_S: return is64 ? WASM_INSN_I64_GT_S : WASM_INSN_I32_GT_S; - case CMP_GE_S: return is64 ? WASM_INSN_I64_GE_S : WASM_INSN_I32_GE_S; - case CMP_LT_U: return is64 ? WASM_INSN_I64_LT_U : WASM_INSN_I32_LT_U; - case CMP_LE_U: return is64 ? WASM_INSN_I64_LE_U : WASM_INSN_I32_LE_U; - case CMP_GT_U: return is64 ? WASM_INSN_I64_GT_U : WASM_INSN_I32_GT_U; - case CMP_GE_U: return is64 ? WASM_INSN_I64_GE_U : WASM_INSN_I32_GE_U; - case CMP_LT_F: return vt == WASM_VAL_F64 ? WASM_INSN_F64_LT : WASM_INSN_F32_LT; - case CMP_LE_F: return vt == WASM_VAL_F64 ? WASM_INSN_F64_LE : WASM_INSN_F32_LE; - case CMP_GT_F: return vt == WASM_VAL_F64 ? WASM_INSN_F64_GT : WASM_INSN_F32_GT; - case CMP_GE_F: return vt == WASM_VAL_F64 ? WASM_INSN_F64_GE : WASM_INSN_F32_GE; + case CMP_EQ: + return is64 ? WASM_INSN_I64_EQ : WASM_INSN_I32_EQ; + case CMP_NE: + return is64 ? WASM_INSN_I64_NE : WASM_INSN_I32_NE; + case CMP_LT_S: + return is64 ? WASM_INSN_I64_LT_S : WASM_INSN_I32_LT_S; + case CMP_LE_S: + return is64 ? WASM_INSN_I64_LE_S : WASM_INSN_I32_LE_S; + case CMP_GT_S: + return is64 ? WASM_INSN_I64_GT_S : WASM_INSN_I32_GT_S; + case CMP_GE_S: + return is64 ? WASM_INSN_I64_GE_S : WASM_INSN_I32_GE_S; + case CMP_LT_U: + return is64 ? WASM_INSN_I64_LT_U : WASM_INSN_I32_LT_U; + case CMP_LE_U: + return is64 ? WASM_INSN_I64_LE_U : WASM_INSN_I32_LE_U; + case CMP_GT_U: + return is64 ? WASM_INSN_I64_GT_U : WASM_INSN_I32_GT_U; + case CMP_GE_U: + return is64 ? WASM_INSN_I64_GE_U : WASM_INSN_I32_GE_U; + case CMP_LT_F: + return vt == WASM_VAL_F64 ? WASM_INSN_F64_LT : WASM_INSN_F32_LT; + case CMP_LE_F: + return vt == WASM_VAL_F64 ? WASM_INSN_F64_LE : WASM_INSN_F32_LE; + case CMP_GT_F: + return vt == WASM_VAL_F64 ? WASM_INSN_F64_GT : WASM_INSN_F32_GT; + case CMP_GE_F: + return vt == WASM_VAL_F64 ? WASM_INSN_F64_GE : WASM_INSN_F32_GE; } wfail(t, "wasm: unsupported cmp %d", (int)op); } static void emit_convert(WTarget* t, ConvKind ck, WasmValType src, WasmValType dst) { - if (src == dst && (ck == CV_BITCAST || ck == CV_ZEXT || ck == CV_SEXT || - ck == CV_TRUNC)) { + if (src == dst && + (ck == CV_BITCAST || ck == CV_ZEXT || ck == CV_SEXT || ck == CV_TRUNC)) { /* No-op conversion. */ return; } if (ck == CV_BITCAST) { if (src == WASM_VAL_I32 && dst == WASM_VAL_F32) { - emit_insn(t, WASM_INSN_F32_REINTERPRET_I32, 0); return; + emit_insn(t, WASM_INSN_F32_REINTERPRET_I32, 0); + return; } if (src == WASM_VAL_F32 && dst == WASM_VAL_I32) { - emit_insn(t, WASM_INSN_I32_REINTERPRET_F32, 0); return; + emit_insn(t, WASM_INSN_I32_REINTERPRET_F32, 0); + return; } if (src == WASM_VAL_I64 && dst == WASM_VAL_F64) { - emit_insn(t, WASM_INSN_F64_REINTERPRET_I64, 0); return; + emit_insn(t, WASM_INSN_F64_REINTERPRET_I64, 0); + return; } if (src == WASM_VAL_F64 && dst == WASM_VAL_I64) { - emit_insn(t, WASM_INSN_I64_REINTERPRET_F64, 0); return; + emit_insn(t, WASM_INSN_I64_REINTERPRET_F64, 0); + return; } /* Width-changing ptr/int bitcasts: cfree_cg_ptr_to_int and * cfree_cg_int_to_ptr route through CV_BITCAST, and on wasm32 a pointer * is i32 while the frontend integer side may be i64. Lower as * wrap/extend (zero-extend; pointers are non-negative addresses). */ if (src == WASM_VAL_I64 && dst == WASM_VAL_I32) { - emit_insn(t, WASM_INSN_I32_WRAP_I64, 0); return; + emit_insn(t, WASM_INSN_I32_WRAP_I64, 0); + return; } if (src == WASM_VAL_I32 && dst == WASM_VAL_I64) { - emit_insn(t, WASM_INSN_I64_EXTEND_I32_U, 0); return; + emit_insn(t, WASM_INSN_I64_EXTEND_I32_U, 0); + return; } wfail(t, "wasm: unsupported bitcast"); } if (ck == CV_SEXT) { if (src == WASM_VAL_I32 && dst == WASM_VAL_I64) { - emit_insn(t, WASM_INSN_I64_EXTEND_I32_S, 0); return; + emit_insn(t, WASM_INSN_I64_EXTEND_I32_S, 0); + return; } } if (ck == CV_ZEXT) { if (src == WASM_VAL_I32 && dst == WASM_VAL_I64) { - emit_insn(t, WASM_INSN_I64_EXTEND_I32_U, 0); return; + emit_insn(t, WASM_INSN_I64_EXTEND_I32_U, 0); + return; } } if (ck == CV_TRUNC) { if (src == WASM_VAL_I64 && dst == WASM_VAL_I32) { - emit_insn(t, WASM_INSN_I32_WRAP_I64, 0); return; + emit_insn(t, WASM_INSN_I32_WRAP_I64, 0); + return; } } if (ck == CV_FEXT && src == WASM_VAL_F32 && dst == WASM_VAL_F64) { - emit_insn(t, WASM_INSN_F64_PROMOTE_F32, 0); return; + emit_insn(t, WASM_INSN_F64_PROMOTE_F32, 0); + return; } if (ck == CV_FTRUNC && src == WASM_VAL_F64 && dst == WASM_VAL_F32) { - emit_insn(t, WASM_INSN_F32_DEMOTE_F64, 0); return; + emit_insn(t, WASM_INSN_F32_DEMOTE_F64, 0); + return; } if (ck == CV_ITOF_S) { - if (src == WASM_VAL_I32 && dst == WASM_VAL_F32) { emit_insn(t, WASM_INSN_F32_CONVERT_I32_S, 0); return; } - if (src == WASM_VAL_I32 && dst == WASM_VAL_F64) { emit_insn(t, WASM_INSN_F64_CONVERT_I32_S, 0); return; } - if (src == WASM_VAL_I64 && dst == WASM_VAL_F32) { emit_insn(t, WASM_INSN_F32_CONVERT_I64_S, 0); return; } - if (src == WASM_VAL_I64 && dst == WASM_VAL_F64) { emit_insn(t, WASM_INSN_F64_CONVERT_I64_S, 0); return; } + if (src == WASM_VAL_I32 && dst == WASM_VAL_F32) { + emit_insn(t, WASM_INSN_F32_CONVERT_I32_S, 0); + return; + } + if (src == WASM_VAL_I32 && dst == WASM_VAL_F64) { + emit_insn(t, WASM_INSN_F64_CONVERT_I32_S, 0); + return; + } + if (src == WASM_VAL_I64 && dst == WASM_VAL_F32) { + emit_insn(t, WASM_INSN_F32_CONVERT_I64_S, 0); + return; + } + if (src == WASM_VAL_I64 && dst == WASM_VAL_F64) { + emit_insn(t, WASM_INSN_F64_CONVERT_I64_S, 0); + return; + } } if (ck == CV_ITOF_U) { - if (src == WASM_VAL_I32 && dst == WASM_VAL_F32) { emit_insn(t, WASM_INSN_F32_CONVERT_I32_U, 0); return; } - if (src == WASM_VAL_I32 && dst == WASM_VAL_F64) { emit_insn(t, WASM_INSN_F64_CONVERT_I32_U, 0); return; } - if (src == WASM_VAL_I64 && dst == WASM_VAL_F32) { emit_insn(t, WASM_INSN_F32_CONVERT_I64_U, 0); return; } - if (src == WASM_VAL_I64 && dst == WASM_VAL_F64) { emit_insn(t, WASM_INSN_F64_CONVERT_I64_U, 0); return; } + if (src == WASM_VAL_I32 && dst == WASM_VAL_F32) { + emit_insn(t, WASM_INSN_F32_CONVERT_I32_U, 0); + return; + } + if (src == WASM_VAL_I32 && dst == WASM_VAL_F64) { + emit_insn(t, WASM_INSN_F64_CONVERT_I32_U, 0); + return; + } + if (src == WASM_VAL_I64 && dst == WASM_VAL_F32) { + emit_insn(t, WASM_INSN_F32_CONVERT_I64_U, 0); + return; + } + if (src == WASM_VAL_I64 && dst == WASM_VAL_F64) { + emit_insn(t, WASM_INSN_F64_CONVERT_I64_U, 0); + return; + } } if (ck == CV_FTOI_S) { - if (src == WASM_VAL_F32 && dst == WASM_VAL_I32) { emit_insn(t, WASM_INSN_I32_TRUNC_F32_S, 0); return; } - if (src == WASM_VAL_F64 && dst == WASM_VAL_I32) { emit_insn(t, WASM_INSN_I32_TRUNC_F64_S, 0); return; } - if (src == WASM_VAL_F32 && dst == WASM_VAL_I64) { emit_insn(t, WASM_INSN_I64_TRUNC_F32_S, 0); return; } - if (src == WASM_VAL_F64 && dst == WASM_VAL_I64) { emit_insn(t, WASM_INSN_I64_TRUNC_F64_S, 0); return; } + if (src == WASM_VAL_F32 && dst == WASM_VAL_I32) { + emit_insn(t, WASM_INSN_I32_TRUNC_F32_S, 0); + return; + } + if (src == WASM_VAL_F64 && dst == WASM_VAL_I32) { + emit_insn(t, WASM_INSN_I32_TRUNC_F64_S, 0); + return; + } + if (src == WASM_VAL_F32 && dst == WASM_VAL_I64) { + emit_insn(t, WASM_INSN_I64_TRUNC_F32_S, 0); + return; + } + if (src == WASM_VAL_F64 && dst == WASM_VAL_I64) { + emit_insn(t, WASM_INSN_I64_TRUNC_F64_S, 0); + return; + } } if (ck == CV_FTOI_U) { - if (src == WASM_VAL_F32 && dst == WASM_VAL_I32) { emit_insn(t, WASM_INSN_I32_TRUNC_F32_U, 0); return; } - if (src == WASM_VAL_F64 && dst == WASM_VAL_I32) { emit_insn(t, WASM_INSN_I32_TRUNC_F64_U, 0); return; } - if (src == WASM_VAL_F32 && dst == WASM_VAL_I64) { emit_insn(t, WASM_INSN_I64_TRUNC_F32_U, 0); return; } - if (src == WASM_VAL_F64 && dst == WASM_VAL_I64) { emit_insn(t, WASM_INSN_I64_TRUNC_F64_U, 0); return; } + if (src == WASM_VAL_F32 && dst == WASM_VAL_I32) { + emit_insn(t, WASM_INSN_I32_TRUNC_F32_U, 0); + return; + } + if (src == WASM_VAL_F64 && dst == WASM_VAL_I32) { + emit_insn(t, WASM_INSN_I32_TRUNC_F64_U, 0); + return; + } + if (src == WASM_VAL_F32 && dst == WASM_VAL_I64) { + emit_insn(t, WASM_INSN_I64_TRUNC_F32_U, 0); + return; + } + if (src == WASM_VAL_F64 && dst == WASM_VAL_I64) { + emit_insn(t, WASM_INSN_I64_TRUNC_F64_U, 0); + return; + } } - wfail(t, "wasm: unsupported convert kind %d (%d -> %d)", (int)ck, - (int)src, (int)dst); + wfail(t, "wasm: unsupported convert kind %d (%d -> %d)", (int)ck, (int)src, + (int)dst); } /* During lowering we keep a running active-scope stack so we can compute @@ -2563,8 +2678,9 @@ static u32 br_to_label(LoweringState* L, Label l) { * unroll_switch_islands reorders the WIR so switch case labels are * forward refs from WIR_SWITCH. Arriving here means the structurer * missed a shape — a bug, not a feature gap. */ - wfail(L->t, "wasm: br to free label whose synthetic scope was not " - "emitted; structurer bug"); + wfail(L->t, + "wasm: br to free label whose synthetic scope was not " + "emitted; structurer bug"); } static i64 wasm_switch_sign_extend(u64 v, u32 width) { @@ -2633,8 +2749,7 @@ static void emit_switch_br_table(WTarget* t, LoweringState* L, const WIR* w) { i64 vi = wasm_switch_sign_extend(w->switch_cases[i].value, width); emit_push_operand(t, w->imm_kind, w->imm_a, w->a, w->type); emit_push_imm(t, vt, vi); - emit_insn(t, vt == WASM_VAL_I64 ? WASM_INSN_I64_EQ : WASM_INSN_I32_EQ, - 0); + emit_insn(t, vt == WASM_VAL_I64 ? WASM_INSN_I64_EQ : WASM_INSN_I32_EQ, 0); emit_insn(t, WASM_INSN_BR_IF, (i64)br_to_label(L, w->switch_cases[i].label)); } @@ -2657,8 +2772,7 @@ static void emit_switch_br_table(WTarget* t, LoweringState* L, const WIR* w) { wfail(t, "wasm: switch selector must be integer"); if (vmin != 0) { emit_push_imm(t, vt, vmin); - emit_insn(t, vt == WASM_VAL_I64 ? WASM_INSN_I64_SUB : WASM_INSN_I32_SUB, - 0); + emit_insn(t, vt == WASM_VAL_I64 ? WASM_INSN_I64_SUB : WASM_INSN_I32_SUB, 0); } if (vt == WASM_VAL_I64) emit_insn(t, WASM_INSN_I32_WRAP_I64, 0); @@ -2776,13 +2890,20 @@ static void emit_intrinsic_bswap(WTarget* t, const WIR* w) { static void emit_intrinsic_overflow(WTarget* t, const WIR* w) { IntrinKind k = (IntrinKind)w->cgop; WasmValType vt = type_valtype(t, w->type); - WasmInsnKind k_add = (vt == WASM_VAL_I64) ? WASM_INSN_I64_ADD : WASM_INSN_I32_ADD; - WasmInsnKind k_sub = (vt == WASM_VAL_I64) ? WASM_INSN_I64_SUB : WASM_INSN_I32_SUB; - WasmInsnKind k_and = (vt == WASM_VAL_I64) ? WASM_INSN_I64_AND : WASM_INSN_I32_AND; - WasmInsnKind k_xor = (vt == WASM_VAL_I64) ? WASM_INSN_I64_XOR : WASM_INSN_I32_XOR; - WasmInsnKind k_shr_u = (vt == WASM_VAL_I64) ? WASM_INSN_I64_SHR_U : WASM_INSN_I32_SHR_U; - WasmInsnKind k_lt_u = (vt == WASM_VAL_I64) ? WASM_INSN_I64_LT_U : WASM_INSN_I32_LT_U; - WasmInsnKind k_const = (vt == WASM_VAL_I64) ? WASM_INSN_I64_CONST : WASM_INSN_I32_CONST; + WasmInsnKind k_add = + (vt == WASM_VAL_I64) ? WASM_INSN_I64_ADD : WASM_INSN_I32_ADD; + WasmInsnKind k_sub = + (vt == WASM_VAL_I64) ? WASM_INSN_I64_SUB : WASM_INSN_I32_SUB; + WasmInsnKind k_and = + (vt == WASM_VAL_I64) ? WASM_INSN_I64_AND : WASM_INSN_I32_AND; + WasmInsnKind k_xor = + (vt == WASM_VAL_I64) ? WASM_INSN_I64_XOR : WASM_INSN_I32_XOR; + WasmInsnKind k_shr_u = + (vt == WASM_VAL_I64) ? WASM_INSN_I64_SHR_U : WASM_INSN_I32_SHR_U; + WasmInsnKind k_lt_u = + (vt == WASM_VAL_I64) ? WASM_INSN_I64_LT_U : WASM_INSN_I32_LT_U; + WasmInsnKind k_const = + (vt == WASM_VAL_I64) ? WASM_INSN_I64_CONST : WASM_INSN_I32_CONST; CfreeCgTypeId bool_ty = builtin_id(CFREE_CG_BUILTIN_BOOL); /* Stash both operands in scratch locals so each side of the expansion can @@ -2933,9 +3054,9 @@ static void emit_intrinsic(WTarget* t, const WIR* w) { static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end); -#if 0 /* Switch-island matcher: replaced by wasm_structurize's - * unroll_switch_islands, which reorders the WIR in-place so case - * labels become forward refs handled by the general structurer. */ +#if 0 /* Switch-island matcher: replaced by wasm_structurize's \ + * unroll_switch_islands, which reorders the WIR in-place so case \ + * labels become forward refs handled by the general structurer. */ static int label_in_list(Label l, const Label* labels, u32 nlabels) { for (u32 i = 0; i < nlabels; ++i) { if (labels[i] == l) return 1; @@ -3076,7 +3197,8 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) { } case WIR_LOAD_CONST_F: { WasmValType vt = type_valtype(t, w->type); - emit_fp(t, vt == WASM_VAL_F64 ? WASM_INSN_F64_CONST : WASM_INSN_F32_CONST, + emit_fp(t, + vt == WASM_VAL_F64 ? WASM_INSN_F64_CONST : WASM_INSN_F32_CONST, w->fp_imm); emit_local_set(t, w->dst, w->type, (RegClass)w->cls); break; @@ -3101,23 +3223,30 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) { /* 0 - a */ emit_push_imm(t, vt, 0); emit_push_operand(t, w->imm_kind, w->imm_a, w->a, w->type); - emit_insn(t, vt == WASM_VAL_I64 ? WASM_INSN_I64_SUB : WASM_INSN_I32_SUB, 0); + emit_insn( + t, vt == WASM_VAL_I64 ? WASM_INSN_I64_SUB : WASM_INSN_I32_SUB, + 0); break; } case UO_FNEG: { - wfail(t, "wasm: fneg via 0-x not supported; emit f32/f64.neg later"); + wfail(t, + "wasm: fneg via 0-x not supported; emit f32/f64.neg later"); } case UO_BNOT: { /* a XOR -1 */ emit_push_operand(t, w->imm_kind, w->imm_a, w->a, w->type); emit_push_imm(t, vt, -1); - emit_insn(t, vt == WASM_VAL_I64 ? WASM_INSN_I64_XOR : WASM_INSN_I32_XOR, 0); + emit_insn( + t, vt == WASM_VAL_I64 ? WASM_INSN_I64_XOR : WASM_INSN_I32_XOR, + 0); break; } case UO_NOT: { /* a == 0 — produces i32 0/1 */ emit_push_operand(t, w->imm_kind, w->imm_a, w->a, w->type); - emit_insn(t, vt == WASM_VAL_I64 ? WASM_INSN_I64_EQZ : WASM_INSN_I32_EQZ, 0); + emit_insn( + t, vt == WASM_VAL_I64 ? WASM_INSN_I64_EQZ : WASM_INSN_I32_EQZ, + 0); break; } } @@ -3212,18 +3341,14 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) { t->varcall_buf_local = add_wasm_local(t, WASM_VAL_I32); u32 buf_size = w->call_nvar * 8u; /* Save SP, allocate aligned buffer, set SP = buf. */ - emit_insn(t, WASM_INSN_GLOBAL_GET, - (i64)t->stack_pointer_global); - emit_insn(t, WASM_INSN_LOCAL_TEE, - (i64)t->varcall_saved_sp_local); + emit_insn(t, WASM_INSN_GLOBAL_GET, (i64)t->stack_pointer_global); + emit_insn(t, WASM_INSN_LOCAL_TEE, (i64)t->varcall_saved_sp_local); emit_insn(t, WASM_INSN_I32_CONST, (i64)buf_size); emit_insn(t, WASM_INSN_I32_SUB, 0); emit_insn(t, WASM_INSN_I32_CONST, -(i64)8); emit_insn(t, WASM_INSN_I32_AND, 0); - emit_insn(t, WASM_INSN_LOCAL_TEE, - (i64)t->varcall_buf_local); - emit_insn(t, WASM_INSN_GLOBAL_SET, - (i64)t->stack_pointer_global); + emit_insn(t, WASM_INSN_LOCAL_TEE, (i64)t->varcall_buf_local); + emit_insn(t, WASM_INSN_GLOBAL_SET, (i64)t->stack_pointer_global); /* Pack each variadic arg at offset i*8. Store width is the * value's natural width (i32/i64/f32/f64); the unused high * bytes of i32/f32 slots are left as whatever __stack_pointer @@ -3234,16 +3359,19 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) { WasmInsnKind store_op; u32 width; if (vvt == WASM_VAL_I64) { - store_op = WASM_INSN_I64_STORE; width = 8u; + store_op = WASM_INSN_I64_STORE; + width = 8u; } else if (vvt == WASM_VAL_F32) { - store_op = WASM_INSN_F32_STORE; width = 4u; + store_op = WASM_INSN_F32_STORE; + width = 4u; } else if (vvt == WASM_VAL_F64) { - store_op = WASM_INSN_F64_STORE; width = 8u; + store_op = WASM_INSN_F64_STORE; + width = 8u; } else { - store_op = WASM_INSN_I32_STORE; width = 4u; + store_op = WASM_INSN_I32_STORE; + width = 4u; } - emit_insn(t, WASM_INSN_LOCAL_GET, - (i64)t->varcall_buf_local); + emit_insn(t, WASM_INSN_LOCAL_GET, (i64)t->varcall_buf_local); if (w->call_var_kinds[v] == WOP_REG) { emit_push_operand_reg(t, w->call_var_regs[v]); } else if (w->call_var_kinds[v] == WOP_IMM) { @@ -3259,8 +3387,7 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) { (u64)(v * 8u), 0u); } /* Push buf addr as hidden last arg. */ - emit_insn(t, WASM_INSN_LOCAL_GET, - (i64)t->varcall_buf_local); + emit_insn(t, WASM_INSN_LOCAL_GET, (i64)t->varcall_buf_local); } } if (w->op == WIR_CALL_INDIRECT) { @@ -3276,8 +3403,7 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) { t->cur_func->insns[t->cur_func->ninsns - 1u].align = 0u; } else { u32 idx = sym_to_wasm_func(t, w->call_sym, NULL); - emit_insn(t, - w->call_tail ? WASM_INSN_RETURN_CALL : WASM_INSN_CALL, + emit_insn(t, w->call_tail ? WASM_INSN_RETURN_CALL : WASM_INSN_CALL, (i64)idx); } /* Tail calls never return to this function: the operand stack is @@ -3293,10 +3419,8 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) { * don't accumulate stack usage. Done after stashing the return * value into its local. */ if (w->call_variadic && w->call_nvar) { - emit_insn(t, WASM_INSN_LOCAL_GET, - (i64)t->varcall_saved_sp_local); - emit_insn(t, WASM_INSN_GLOBAL_SET, - (i64)t->stack_pointer_global); + emit_insn(t, WASM_INSN_LOCAL_GET, (i64)t->varcall_saved_sp_local); + emit_insn(t, WASM_INSN_GLOBAL_SET, (i64)t->stack_pointer_global); } } break; @@ -3318,8 +3442,10 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) { emit_insn(t, WASM_INSN_LOCAL_GET, (i64)t->sret_param_local); /* Load src byte at (w->addr + n). */ Operand src = w->addr; - if (src.kind == OPK_INDIRECT) src.v.ind.ofs += (i32)n; - else if (src.kind == OPK_GLOBAL) src.v.global.addend += n; + if (src.kind == OPK_INDIRECT) + src.v.ind.ofs += (i32)n; + else if (src.kind == OPK_GLOBAL) + src.v.global.addend += n; uint64_t src_off; emit_addr_operand(t, src, &src_off); if (src.kind == OPK_LOCAL) src_off += n; @@ -3328,7 +3454,8 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) { wasm_func_add_mem_insn(t->c, t->module, t->cur_func, WASM_INSN_I32_STORE8, 0, n, 0); } - } else if (w->dst != REG_NONE) emit_push_operand_reg(t, w->dst); + } else if (w->dst != REG_NONE) + emit_push_operand_reg(t, w->dst); else if (w->imm_kind == 1) { WasmValType vt = type_valtype(t, w->type); emit_push_imm(t, vt, w->imm_a); @@ -3371,10 +3498,12 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) { memset(&src, 0, sizeof src); src.kind = w->imm_kind == WOP_IMM ? OPK_IMM : OPK_REG; src.type = w->type; - if (src.kind == OPK_IMM) src.v.imm = w->imm_a; - else src.v.reg = w->a; - emit_store_addr(t, w->addr, w->type, src, w->mem, w->imm_kind, - w->imm_a, w->a); + if (src.kind == OPK_IMM) + src.v.imm = w->imm_a; + else + src.v.reg = w->a; + emit_store_addr(t, w->addr, w->type, src, w->mem, w->imm_kind, w->imm_a, + w->a); break; } case WIR_ADDR_OF: { @@ -3390,9 +3519,9 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) { case WIR_ALLOCA: { u32 align = (u32)w->imm; emit_insn(t, WASM_INSN_GLOBAL_GET, (i64)t->stack_pointer_global); - emit_push_operand(t, w->imm_kind, w->imm_a, w->a, - w->type2 ? w->type2 - : builtin_id(CFREE_CG_BUILTIN_I32)); + emit_push_operand( + t, w->imm_kind, w->imm_a, w->a, + w->type2 ? w->type2 : builtin_id(CFREE_CG_BUILTIN_I32)); if (w->type2 && type_valtype(t, w->type2) == WASM_VAL_I64) emit_insn(t, WASM_INSN_I32_WRAP_I64, 0); emit_insn(t, WASM_INSN_I32_SUB, 0); @@ -3406,7 +3535,8 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) { break; } case WIR_COPY_BYTES: { - /* memory.copy: stack = dst_addr, src_addr, n; both memidx fields = 0. */ + /* memory.copy: stack = dst_addr, src_addr, n; both memidx fields = 0. + */ Operand src_addr; if (w->imm_kind != WOP_REG) wfail(t, "wasm: copy_bytes source must be a register pointer"); @@ -3421,8 +3551,8 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) { emit_push_addr_value(t, w->addr); emit_push_addr_value(t, src_addr); emit_insn(t, WASM_INSN_I32_CONST, (i64)(uint32_t)w->agg.size); - wasm_func_add_insn(t->c, t->module, t->cur_func, - WASM_INSN_MEMORY_COPY, 0); + wasm_func_add_insn(t->c, t->module, t->cur_func, WASM_INSN_MEMORY_COPY, + 0); /* dst memidx = 0, src memidx = 0 (cfree-cc single-memory module). */ t->cur_func->insns[t->cur_func->ninsns - 1u].memidx = 0; t->cur_func->insns[t->cur_func->ninsns - 1u].aux_idx = 0; @@ -3436,8 +3566,8 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) { emit_push_addr_value(t, w->addr); emit_insn(t, WASM_INSN_I32_CONST, (i64)(w->imm_a & 0xff)); emit_insn(t, WASM_INSN_I32_CONST, (i64)(uint32_t)w->agg.size); - wasm_func_add_insn(t->c, t->module, t->cur_func, - WASM_INSN_MEMORY_FILL, 0); + wasm_func_add_insn(t->c, t->module, t->cur_func, WASM_INSN_MEMORY_FILL, + 0); t->cur_func->insns[t->cur_func->ninsns - 1u].memidx = 0; break; } @@ -3460,8 +3590,8 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) { break; } case WIR_ATOMIC_RMW: { - WasmInsnKind k = atomic_rmw_kind_for(t, (AtomicOp)w->cgop, w->type, - w->mem); + WasmInsnKind k = + atomic_rmw_kind_for(t, (AtomicOp)w->cgop, w->type, w->mem); u32 width = wasm_mem_width((uint8_t)k); emit_push_operand_reg(t, w->a); emit_push_operand(t, w->imm_kind_b, w->imm_b, w->b, w->type); @@ -3522,7 +3652,8 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) { break; } case WIR_SCOPE_OPEN: { - if (L->nstack >= 1024u) wfail(t, "wasm: scope nesting too deep (max 1024)"); + if (L->nstack >= 1024u) + wfail(t, "wasm: scope nesting too deep (max 1024)"); LoweringScope* s = &L->stack[L->nstack++]; s->id = w->scope_id; s->kind = w->cgop; @@ -3600,27 +3731,31 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) { WasmInsnKind load_op; u32 width; if (vt == WASM_VAL_I64) { - load_op = WASM_INSN_I64_LOAD; width = 8u; + load_op = WASM_INSN_I64_LOAD; + width = 8u; } else if (vt == WASM_VAL_F32) { - load_op = WASM_INSN_F32_LOAD; width = 4u; + load_op = WASM_INSN_F32_LOAD; + width = 4u; } else if (vt == WASM_VAL_F64) { - load_op = WASM_INSN_F64_LOAD; width = 8u; + load_op = WASM_INSN_F64_LOAD; + width = 8u; } else { - load_op = WASM_INSN_I32_LOAD; width = 4u; + load_op = WASM_INSN_I32_LOAD; + width = 4u; } /* Load T from current *ap and stash into dst. */ emit_push_addr_value(t, w->addr); emit_insn(t, WASM_INSN_LOCAL_TEE, (i64)t->va_arg_tmp_addr_local); - wasm_func_add_mem_insn(t->c, t->module, t->cur_func, - WASM_INSN_I32_LOAD, 2u, 0u, 0u); + wasm_func_add_mem_insn(t->c, t->module, t->cur_func, WASM_INSN_I32_LOAD, + 2u, 0u, 0u); wasm_func_add_mem_insn(t->c, t->module, t->cur_func, load_op, memarg_align_log2(width, width), 0u, 0u); emit_local_set(t, w->dst, w->type, (RegClass)w->cls); /* Advance: *ap = *ap + 8. */ emit_insn(t, WASM_INSN_LOCAL_GET, (i64)t->va_arg_tmp_addr_local); emit_insn(t, WASM_INSN_LOCAL_GET, (i64)t->va_arg_tmp_addr_local); - wasm_func_add_mem_insn(t->c, t->module, t->cur_func, - WASM_INSN_I32_LOAD, 2u, 0u, 0u); + wasm_func_add_mem_insn(t->c, t->module, t->cur_func, WASM_INSN_I32_LOAD, + 2u, 0u, 0u); emit_insn(t, WASM_INSN_I32_CONST, (i64)8); emit_insn(t, WASM_INSN_I32_ADD, 0); wasm_func_add_mem_insn(t->c, t->module, t->cur_func, @@ -3631,8 +3766,8 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) { /* *dst_ap = *src_ap (single i32). */ emit_push_addr_value(t, w->addr); emit_push_addr_value(t, w->call_sret_addr); - wasm_func_add_mem_insn(t->c, t->module, t->cur_func, - WASM_INSN_I32_LOAD, 2u, 0u, 0u); + wasm_func_add_mem_insn(t->c, t->module, t->cur_func, WASM_INSN_I32_LOAD, + 2u, 0u, 0u); wasm_func_add_mem_insn(t->c, t->module, t->cur_func, WASM_INSN_I32_STORE, 2u, 0u, 0u); break; @@ -3648,19 +3783,19 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) { u32* in_locals = NULL; u32* out_locals = NULL; if (nin) { - in_locals = (u32*)h_blk->alloc(h_blk, sizeof(u32) * nin, - _Alignof(u32)); + in_locals = + (u32*)h_blk->alloc(h_blk, sizeof(u32) * nin, _Alignof(u32)); if (!in_locals) wfail(t, "wasm: out of memory"); /* defer per-input allocation until after output locals are known * so numeric tieback ("+r", "0".."9") can share. */ } if (nout) { - out_locals = (u32*)h_blk->alloc(h_blk, sizeof(u32) * nout, - _Alignof(u32)); + out_locals = + (u32*)h_blk->alloc(h_blk, sizeof(u32) * nout, _Alignof(u32)); if (!out_locals) wfail(t, "wasm: out of memory"); for (u32 i = 0; i < nout; ++i) - out_locals[i] = add_wasm_local(t, valtype_for_type(t, - w->asm_out_types[i])); + out_locals[i] = + add_wasm_local(t, valtype_for_type(t, w->asm_out_types[i])); } if (nin) { for (u32 i = 0; i < nin; ++i) { @@ -3668,8 +3803,8 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) { if (share >= 0 && (u32)share < nout) { in_locals[i] = out_locals[share]; } else { - in_locals[i] = add_wasm_local( - t, valtype_for_type(t, w->asm_in_types[i])); + in_locals[i] = + add_wasm_local(t, valtype_for_type(t, w->asm_in_types[i])); } } } @@ -3708,8 +3843,8 @@ static void linearize_range(WTarget* t, LoweringState* L, u32 start, u32 end) { * Reg's wasm local. */ for (u32 i = 0; i < nout; ++i) { WasmValType ovt = valtype_for_type(t, w->asm_out_types[i]); - RegClass cls = (ovt == WASM_VAL_F32 || ovt == WASM_VAL_F64) - ? RC_FP : RC_INT; + RegClass cls = + (ovt == WASM_VAL_F32 || ovt == WASM_VAL_F64) ? RC_FP : RC_INT; emit_insn(t, WASM_INSN_LOCAL_GET, (i64)out_locals[i]); emit_local_set(t, w->asm_out_regs[i], w->asm_out_types[i], cls); } @@ -3762,14 +3897,14 @@ static void linearize(WTarget* t) { emit_insn(t, WASM_INSN_LOCAL_GET, (i64)bc->ptr_wasm_local); wasm_func_add_mem_insn(t->c, t->module, t->cur_func, WASM_INSN_I32_LOAD8_U, 0, n, 0); - wasm_func_add_mem_insn(t->c, t->module, t->cur_func, - WASM_INSN_I32_STORE8, 0, s->frame_offset + n, 0); + wasm_func_add_mem_insn(t->c, t->module, t->cur_func, WASM_INSN_I32_STORE8, + 0, s->frame_offset + n, 0); } } linearize_range(t, &L, 0, t->nwir); - if (L.nstack != 0) wfail(t, "wasm: function ended with %u open scopes", - L.nstack); + if (L.nstack != 0) + wfail(t, "wasm: function ended with %u open scopes", L.nstack); /* If the body's last real WIR is a terminator (return / br / switch / * unreachable / tail call) buried inside nested blocks, cfree's wasm * validator does not propagate the unreachable flag across enclosing @@ -3888,9 +4023,9 @@ void wasm_alias(CGTarget* tg, ObjSymId alias_sym, ObjSymId target_sym, Heap* h = t->c->ctx->heap; u32 nc = t->sym_to_func_cap ? t->sym_to_func_cap : 16u; while (nc <= alias_sym) nc *= 2u; - u32* p = (u32*)h->realloc(h, t->sym_to_func, - sizeof(u32) * t->sym_to_func_cap, - sizeof(u32) * nc, _Alignof(u32)); + u32* p = + (u32*)h->realloc(h, t->sym_to_func, sizeof(u32) * t->sym_to_func_cap, + sizeof(u32) * nc, _Alignof(u32)); if (!p) wfail(t, "wasm: out of memory"); for (u32 i = t->sym_to_func_cap; i < nc; ++i) p[i] = 0; t->sym_to_func = p; @@ -3940,9 +4075,8 @@ static u32 assign_section_bases(WTarget* t) { if (nsec > t->section_base_cap) { u32 nc = t->section_base_cap ? t->section_base_cap : 4u; while (nc < nsec) nc *= 2u; - void* p = - h->realloc(h, t->section_base, sizeof(u32) * t->section_base_cap, - sizeof(u32) * nc, _Alignof(u32)); + void* p = h->realloc(h, t->section_base, sizeof(u32) * t->section_base_cap, + sizeof(u32) * nc, _Alignof(u32)); if (!p) wfail(t, "wasm: out of memory"); t->section_base = (u32*)p; for (u32 i = t->section_base_cap; i < nc; ++i) @@ -3959,10 +4093,10 @@ static u32 assign_section_bases(WTarget* t) { if (align < 1u) align = 1u; next = align_to_u32(next, align); t->section_base[sid] = next; - u32 sz = (s->kind == SEC_BSS || s->sem == SSEM_NOBITS) ? s->bss_size - : (u32)s->bytes.total; - if (sz > UINT32_MAX - next) - wfail(t, "wasm: linear memory image too large"); + u32 sz = (s->kind == SEC_BSS || s->sem == SSEM_NOBITS) + ? s->bss_size + : (u32)s->bytes.total; + if (sz > UINT32_MAX - next) wfail(t, "wasm: linear memory image too large"); next += sz; } return next; @@ -4014,14 +4148,12 @@ static u32 assign_common_bases(WTarget* t, u32 next) { * section-defined symbols (via t->section_base[sym->section_id]) and * common symbols (via t->common_base[sym]). Returns 0 and sets *ok=0 if * the symbol can't be resolved here; callers diagnose. */ -static u32 wasm_sym_linear_addr(WTarget* t, ObjSymId sym, i64 addend, - int* ok) { +static u32 wasm_sym_linear_addr(WTarget* t, ObjSymId sym, i64 addend, int* ok) { const ObjSym* os = obj_symbol_get(t->obj, sym); *ok = 0; if (!os) return 0; if (os->kind == SK_COMMON) { - if (sym >= t->common_base_cap || - t->common_base[sym] == 0xFFFFFFFFu) + if (sym >= t->common_base_cap || t->common_base[sym] == 0xFFFFFFFFu) return 0; *ok = 1; return t->common_base[sym] + (u32)addend; @@ -4050,8 +4182,7 @@ static void apply_data_relocs(WTarget* t, u8* mem) { if (!rs || rs->flags & SF_EXEC) continue; const ObjSym* tos = obj_symbol_get(t->obj, r->sym); if (!tos) - wfail(t, - "wasm: data relocation against unresolved symbol not supported"); + wfail(t, "wasm: data relocation against unresolved symbol not supported"); /* Function-symbol references in data sections (e.g. a static vtable * `static fn_t v = &foo;`) resolve to wasm function-table indices, not * linear-memory addresses. The funcref table is built before @@ -4074,8 +4205,7 @@ static void apply_data_relocs(WTarget* t, u8* mem) { continue; } if (tos->section_id == OBJ_SEC_NONE && tos->kind != SK_COMMON) - wfail(t, - "wasm: data relocation against unresolved symbol not supported"); + wfail(t, "wasm: data relocation against unresolved symbol not supported"); { int ok = 0; /* The addend is already added by `value = sym_addr + r->addend` below; @@ -4110,8 +4240,7 @@ static void apply_sym_fixups(WTarget* t) { WSymFixup fx = t->sym_fixups[i]; int ok = 0; u32 addr = wasm_sym_linear_addr(t, fx.sym, fx.addend, &ok); - if (!ok) - wfail(t, "wasm: deferred symbol fixup against unresolved symbol"); + if (!ok) wfail(t, "wasm: deferred symbol fixup against unresolved symbol"); WasmFunc* f = &t->module->funcs[fx.wasm_func_idx]; if (fx.insn_idx >= f->ninsns) wfail(t, "wasm: deferred symbol fixup insn_idx out of range"); @@ -4222,8 +4351,7 @@ static void wasm_materialize_functable(WTarget* t) { seg->offset = 1; for (u32 i = 0; i < t->func_table_count; ++i) { ObjSymId sym = t->func_table[i]; - wasm_elem_push_func(t->c, t->module, seg, - sym_to_wasm_func(t, sym, NULL)); + wasm_elem_push_func(t->c, t->module, seg, sym_to_wasm_func(t, sym, NULL)); } } /* Patch placeholders. */ @@ -4253,15 +4381,18 @@ static void wasm_reorder_funcs_imports_first(WTarget* t) { int needs_reorder = 0; for (u32 i = 0; i < n; ++i) { if (m->funcs[i].is_import) { - if (seen_def) { needs_reorder = 1; break; } + if (seen_def) { + needs_reorder = 1; + break; + } } else { seen_def = 1; } } if (!needs_reorder) return; u32* old_to_new = (u32*)h->alloc(h, sizeof(u32) * n, _Alignof(u32)); - WasmFunc* new_funcs = (WasmFunc*)h->alloc(h, sizeof(WasmFunc) * n, - _Alignof(WasmFunc)); + WasmFunc* new_funcs = + (WasmFunc*)h->alloc(h, sizeof(WasmFunc) * n, _Alignof(WasmFunc)); if (!old_to_new || !new_funcs) wfail(t, "wasm: out of memory"); u32 w_idx = 0; for (u32 i = 0; i < n; ++i) { @@ -4331,7 +4462,11 @@ static void wasm_export_memory(WTarget* t) { u32 mem_idx = 0; int found = 0; for (u32 i = 0; i < m->nmemories; ++i) { - if (!m->memories[i].is_import) { mem_idx = i; found = 1; break; } + if (!m->memories[i].is_import) { + mem_idx = i; + found = 1; + break; + } } if (!found) return; /* Skip if the user already added a memory export (e.g. via the WAT path diff --git a/src/arch/wasm/internal.h b/src/arch/wasm/internal.h @@ -36,73 +36,73 @@ struct WasmFunc; * label/jump → wasm-block resolution without baking forward-only structure * into the recording side. */ typedef enum WIROp { - WIR_LOAD_IMM, /* dst, imm, type */ - WIR_LOAD_CONST_F, /* dst, fp_imm, type */ - WIR_COPY, /* dst, src */ - WIR_BINOP, /* dst, a, b, BinOp */ - WIR_UNOP, /* dst, a, UnOp */ - WIR_CMP, /* dst, a, b, CmpOp */ - WIR_CONVERT, /* dst, src, ConvKind */ - WIR_LABEL, /* place label[0] */ - WIR_JUMP, /* jump to label[0] */ - WIR_CMP_BRANCH, /* cmp_branch op a b -> label[0] */ - WIR_CALL, /* callee_sym, nargs, args[], ret_reg (or REG_NONE) */ - WIR_CALL_INDIRECT, /* callee in `a` (i32 table index), typeidx in `imm`, - nargs/args[]/ret_reg same shape as WIR_CALL */ - WIR_RET, /* val (or REG_NONE) */ - WIR_SCOPE_OPEN, /* scope_id; kind == SCOPE_LOOP/BLOCK/IF; cond reg for IF */ - WIR_SCOPE_CLOSE, /* scope_id */ - WIR_SCOPE_ELSE, /* scope_id */ + WIR_LOAD_IMM, /* dst, imm, type */ + WIR_LOAD_CONST_F, /* dst, fp_imm, type */ + WIR_COPY, /* dst, src */ + WIR_BINOP, /* dst, a, b, BinOp */ + WIR_UNOP, /* dst, a, UnOp */ + WIR_CMP, /* dst, a, b, CmpOp */ + WIR_CONVERT, /* dst, src, ConvKind */ + WIR_LABEL, /* place label[0] */ + WIR_JUMP, /* jump to label[0] */ + WIR_CMP_BRANCH, /* cmp_branch op a b -> label[0] */ + WIR_CALL, /* callee_sym, nargs, args[], ret_reg (or REG_NONE) */ + WIR_CALL_INDIRECT, /* callee in `a` (i32 table index), typeidx in `imm`, + nargs/args[]/ret_reg same shape as WIR_CALL */ + WIR_RET, /* val (or REG_NONE) */ + WIR_SCOPE_OPEN, /* scope_id; kind == SCOPE_LOOP/BLOCK/IF; cond reg for IF */ + WIR_SCOPE_CLOSE, /* scope_id */ + WIR_SCOPE_ELSE, /* scope_id */ WIR_UNREACHABLE, - WIR_SWITCH, /* selector operand + dense label table at lowering */ - WIR_LOAD_LOCAL, /* dst, frame_slot in `imm`, type */ - WIR_STORE_LOCAL, /* frame_slot in `imm`, src (a/imm_a/imm_kind), type */ - WIR_LOAD_MEM, /* dst = load addr */ - WIR_STORE_MEM, /* store src -> addr */ - WIR_ADDR_OF, /* dst = address of addr */ - WIR_ALLOCA, /* dst = stack allocation of size operand */ - WIR_COPY_BYTES, /* memcpy-like byte copy */ - WIR_SET_BYTES, /* memset-like byte set */ - WIR_ATOMIC_LOAD, /* dst = atomic.load(addr_reg), mem holds access info */ - WIR_ATOMIC_STORE, /* atomic.store(addr_reg, src) */ - WIR_ATOMIC_RMW, /* dst = atomic.rmw_<op>(addr_reg, val); cgop = AtomicOp */ - WIR_ATOMIC_CAS, /* dst = prior; dst2 = ok (i32 0/1); a=addr_reg, - b/imm_kind_b=expected, op_c/imm_kind_c=desired */ - WIR_FENCE, /* atomic.fence (memory order ignored, wasm has seq_cst) */ - WIR_VA_START, /* addr = ap_addr; stores va_ptr_param_local i32 at *ap */ - WIR_VA_ARG, /* dst = load of `type` from *(*addr); advance *addr by 8 */ - WIR_VA_COPY, /* addr = dst_ap_addr; call_sret_addr = src_ap_addr */ - WIR_INTRINSIC, /* cgop = IntrinKind; operand layout per kind: - - bit ops (CLZ/CTZ/POPCOUNT/BSWAP16/32/64): one - register operand in `a`, single dst in `dst`, - `type` carries the operand/result type. - - overflow arith (S/U{ADD,SUB,MUL}_OVERFLOW): two - value operands captured into a/imm_a/imm_kind and - b/imm_b/imm_kind_b, dst = value reg, dst2 = i32 - overflow flag reg, `type` = value type. */ - WIR_ASM_BLOCK, /* inline asm block. raw_insns[0..raw_ninsns) is the - pre-parsed body; local.get/set/tee indices in - [0, asm_nin) are remapped to freshly allocated wasm - locals at linearize time. Input bindings are - captured into asm_in_kinds/asm_in_imms/asm_in_regs; - output bindings into asm_out_regs. */ + WIR_SWITCH, /* selector operand + dense label table at lowering */ + WIR_LOAD_LOCAL, /* dst, frame_slot in `imm`, type */ + WIR_STORE_LOCAL, /* frame_slot in `imm`, src (a/imm_a/imm_kind), type */ + WIR_LOAD_MEM, /* dst = load addr */ + WIR_STORE_MEM, /* store src -> addr */ + WIR_ADDR_OF, /* dst = address of addr */ + WIR_ALLOCA, /* dst = stack allocation of size operand */ + WIR_COPY_BYTES, /* memcpy-like byte copy */ + WIR_SET_BYTES, /* memset-like byte set */ + WIR_ATOMIC_LOAD, /* dst = atomic.load(addr_reg), mem holds access info */ + WIR_ATOMIC_STORE, /* atomic.store(addr_reg, src) */ + WIR_ATOMIC_RMW, /* dst = atomic.rmw_<op>(addr_reg, val); cgop = AtomicOp */ + WIR_ATOMIC_CAS, /* dst = prior; dst2 = ok (i32 0/1); a=addr_reg, + b/imm_kind_b=expected, op_c/imm_kind_c=desired */ + WIR_FENCE, /* atomic.fence (memory order ignored, wasm has seq_cst) */ + WIR_VA_START, /* addr = ap_addr; stores va_ptr_param_local i32 at *ap */ + WIR_VA_ARG, /* dst = load of `type` from *(*addr); advance *addr by 8 */ + WIR_VA_COPY, /* addr = dst_ap_addr; call_sret_addr = src_ap_addr */ + WIR_INTRINSIC, /* cgop = IntrinKind; operand layout per kind: + - bit ops (CLZ/CTZ/POPCOUNT/BSWAP16/32/64): one + register operand in `a`, single dst in `dst`, + `type` carries the operand/result type. + - overflow arith (S/U{ADD,SUB,MUL}_OVERFLOW): two + value operands captured into a/imm_a/imm_kind and + b/imm_b/imm_kind_b, dst = value reg, dst2 = i32 + overflow flag reg, `type` = value type. */ + WIR_ASM_BLOCK, /* inline asm block. raw_insns[0..raw_ninsns) is the + pre-parsed body; local.get/set/tee indices in + [0, asm_nin) are remapped to freshly allocated wasm + locals at linearize time. Input bindings are + captured into asm_in_kinds/asm_in_imms/asm_in_regs; + output bindings into asm_out_regs. */ } WIROp; typedef struct WIR { u8 op; - u8 cls; /* RegClass for the produced value or branch operand */ - u8 cgop; /* BinOp/UnOp/CmpOp/ConvKind discriminator */ + u8 cls; /* RegClass for the produced value or branch operand */ + u8 cgop; /* BinOp/UnOp/CmpOp/ConvKind discriminator */ u8 pad; - CfreeCgTypeId type; /* type of dst (or operand type for cmp/store) */ - CfreeCgTypeId type2; /* operand type for convert/cmp */ + CfreeCgTypeId type; /* type of dst (or operand type for cmp/store) */ + CfreeCgTypeId type2; /* operand type for convert/cmp */ Reg dst; Reg a; Reg b; i64 imm; double fp_imm; - Label labels[1]; /* used by LABEL/JUMP/CMP_BRANCH */ + Label labels[1]; /* used by LABEL/JUMP/CMP_BRANCH */ u32 scope_id; - u32 imm_kind; /* 0=reg, 1=imm — operand variant for a/b */ + u32 imm_kind; /* 0=reg, 1=imm — operand variant for a/b */ u32 imm_kind_b; i64 imm_a; i64 imm_b; @@ -124,9 +124,9 @@ typedef struct WIR { * prepends an i32 pointer to a caller-allocated buffer. call_sret_addr is * that buffer's address operand; emit-time pushes its i32 first. */ u8 call_has_sret; - u8 call_variadic; /* callee is variadic; pack call_var_* into linear-memory - * buffer and push its addr as hidden trailing i32 arg. */ - u8 call_tail; /* emit as return_call / return_call_indirect */ + u8 call_variadic; /* callee is variadic; pack call_var_* into linear-memory + * buffer and push its addr as hidden trailing i32 arg. */ + u8 call_tail; /* emit as return_call / return_call_indirect */ u8 pad_call[1]; Operand call_sret_addr; /* Variadic args (those past d->abi->nparams when callee is variadic). Stored @@ -155,7 +155,7 @@ typedef struct WIR { u32 raw_ninsns; u32 asm_nin; u32 asm_nout; - u8* asm_in_kinds; /* WOP_REG / WOP_IMM / WOP_LOCAL */ + u8* asm_in_kinds; /* WOP_REG / WOP_IMM / WOP_LOCAL */ i64* asm_in_imms; Reg* asm_in_regs; CfreeCgTypeId* asm_in_types; @@ -168,14 +168,14 @@ typedef struct WIR { } WIR; typedef struct WScope { - u8 cg_kind; /* ScopeKind */ - u8 placed_in_wir; /* WIR_SCOPE_OPEN emitted */ - u8 break_seen; /* break_label_place arrived */ - u8 cont_seen; /* continue_label_place arrived */ + u8 cg_kind; /* ScopeKind */ + u8 placed_in_wir; /* WIR_SCOPE_OPEN emitted */ + u8 break_seen; /* break_label_place arrived */ + u8 cont_seen; /* continue_label_place arrived */ u32 id; Label break_lbl; Label cont_lbl; - Reg cond_reg; /* SCOPE_IF: condition operand carried by scope_begin */ + Reg cond_reg; /* SCOPE_IF: condition operand carried by scope_begin */ CfreeCgTypeId result_type; } WScope; @@ -183,20 +183,20 @@ typedef enum WLabelKind { WLBL_UNBOUND = 0, WLBL_SCOPE_BREAK, WLBL_SCOPE_CONT, - WLBL_FORWARD, /* placed via label_place but not tied to a scope */ + WLBL_FORWARD, /* placed via label_place but not tied to a scope */ } WLabelKind; typedef struct WLabel { u8 kind; u8 placed; u8 pad[2]; - u32 scope_id; /* for SCOPE_BREAK/SCOPE_CONT */ - u32 wir_index; /* WIR_LABEL position once placed */ + u32 scope_id; /* for SCOPE_BREAK/SCOPE_CONT */ + u32 wir_index; /* WIR_LABEL position once placed */ } WLabel; typedef struct WFunc { ObjSymId sym; - u32 wasm_func_idx; /* index into WasmModule.funcs */ + u32 wasm_func_idx; /* index into WasmModule.funcs */ CfreeCgTypeId fn_type; u8 has_export_name; u8 pad[3]; @@ -213,8 +213,8 @@ typedef enum WSlotKind { * wasm_param time and emit the byte copies in the prologue, after frame setup * and before the user body. */ typedef struct WByvalCopy { - u32 ptr_wasm_local; /* wasm-local holding the source pointer (param slot) */ - u32 dst_slot_id; /* index into WTarget.slots; slot is W_SLOT_STACK */ + u32 ptr_wasm_local; /* wasm-local holding the source pointer (param slot) */ + u32 dst_slot_id; /* index into WTarget.slots; slot is W_SLOT_STACK */ } WByvalCopy; typedef struct WSlot { @@ -353,14 +353,16 @@ typedef struct WTarget { * wasm_param/ret/call to translate sret + byval through the wasm32 BasicCABI * shape (sret pointer as hidden i32 leading param, byval args as i32 * pointers, callee copy-in into a stack-backed local buffer). */ - u32 sret_param_local; /* wasm-local idx of the sret pointer; 0xffffffffu when none */ - u32 va_ptr_param_local; /* wasm-local idx of the hidden i32 va_ptr trailing param - * on variadic functions; 0xffffffffu when none. Read by - * wasm_va_start to seed the va_list. */ - u32* param_local_idx; /* per CG-param idx -> wasm-local idx (0xffffffffu for IGNORE) */ + u32 sret_param_local; /* wasm-local idx of the sret pointer; 0xffffffffu when + none */ + u32 va_ptr_param_local; /* wasm-local idx of the hidden i32 va_ptr trailing + * param on variadic functions; 0xffffffffu when none. + * Read by wasm_va_start to seed the va_list. */ + u32* param_local_idx; /* per CG-param idx -> wasm-local idx (0xffffffffu for + IGNORE) */ u32 param_local_idx_cap; - u32 nparams_cg; /* count of entries in param_local_idx */ - u8 cur_is_variadic; /* current function declared variadic (abi->variadic) */ + u32 nparams_cg; /* count of entries in param_local_idx */ + u8 cur_is_variadic; /* current function declared variadic (abi->variadic) */ /* Per-function scratch locals for variadic-call packing. Lazily allocated * on the first variadic call site; reused across all variadic calls in the * same function (each call's save/restore window is self-contained, so a diff --git a/src/arch/wasm/structure.c b/src/arch/wasm/structure.c @@ -21,11 +21,10 @@ * sits inside an extra CG scope; the synthetic block's start cannot * lift across the scope boundary cleanly. */ -#include "arch/wasm/internal.h" - #include <stdarg.h> #include <string.h> +#include "arch/wasm/internal.h" #include "core/heap.h" static _Noreturn void sfail(WTarget* t, const char* fmt, ...) { @@ -39,8 +38,8 @@ static _Noreturn void sfail(WTarget* t, const char* fmt, ...) { /* Per-free-label working state. */ typedef struct WSLbl { Label label; - u32 wir_idx; /* WIR_LABEL position */ - u32 scope_depth; /* CG-scope nesting depth at the label */ + u32 wir_idx; /* WIR_LABEL position */ + u32 scope_depth; /* CG-scope nesting depth at the label */ /* Forward predecessor stats: min adjusted start (so the synthetic block * opens at the same scope depth as L). UINT32_MAX = no forward pred. */ u32 fwd_start_idx; @@ -56,7 +55,7 @@ typedef struct WSLbl { u32 open_idx; u32 close_idx; u8 is_loop; - u8 valid; /* 1 if structurer will wrap this label */ + u8 valid; /* 1 if structurer will wrap this label */ u8 pad[2]; } WSLbl; @@ -75,17 +74,17 @@ typedef enum WSEvKind { typedef struct WSEvent { u32 wir_idx; u32 pair_idx; - u8 kind; /* WSEvKind */ + u8 kind; /* WSEvKind */ u8 pad[3]; u32 scope_id; - Label label; /* break (BLOCK) or continue (LOOP) */ + Label label; /* break (BLOCK) or continue (LOOP) */ } WSEvent; /* Per-idx scope chain entry. */ typedef struct WSScopeFrame { u32 scope_id; u32 open_idx; - u32 depth; /* 1-based */ + u32 depth; /* 1-based */ } WSScopeFrame; typedef struct WSCtx { @@ -140,8 +139,8 @@ static WSLbl* push_lbl(WSCtx* x, Label l) { static void pass_scope_depth(WSCtx* x) { WTarget* t = x->t; Heap* h = t->c->ctx->heap; - x->depth_at = (u32*)h->alloc(h, sizeof(u32) * (t->nwir ? t->nwir : 1u), - _Alignof(u32)); + x->depth_at = + (u32*)h->alloc(h, sizeof(u32) * (t->nwir ? t->nwir : 1u), _Alignof(u32)); if (!x->depth_at) sfail(t, "wasm: out of memory in structurer"); x->ndepth = t->nwir; x->nstack = 0; @@ -175,8 +174,7 @@ static void pass_scope_depth(WSCtx* x) { } } if (x->nstack != 0) - sfail(t, "wasm: structurer finished with %u scopes still open", - x->nstack); + sfail(t, "wasm: structurer finished with %u scopes still open", x->nstack); } /* ---- pass 2: locate the smallest "outside" idx for a pred at depth `pd` @@ -197,7 +195,7 @@ static u32 lift_to_label_depth(WSCtx* x, u32 pred_idx, u32 ld) { if (t->wir[i].op == WIR_SCOPE_OPEN) { cur--; if (cur == ld) { - best = i; /* place synthetic OPEN right before this CG OPEN */ + best = i; /* place synthetic OPEN right before this CG OPEN */ break; } } else if (t->wir[i].op == WIR_SCOPE_CLOSE) { @@ -306,9 +304,9 @@ static void note_pred(WSCtx* x, u32 pred_idx, Label tgt) { * support multiple non-nested switch islands per function and stop on * the first intervening terminator that breaks the dispatch shape. */ typedef struct WSIsland { - u32 j; /* JUMP dispatch idx */ - u32 d; /* LABEL dispatch idx */ - u32 s; /* WIR_SWITCH idx */ + u32 j; /* JUMP dispatch idx */ + u32 d; /* LABEL dispatch idx */ + u32 s; /* WIR_SWITCH idx */ } WSIsland; static WIR* wir_append(WTarget* t, WIR** out, u32* nout, u32* cap); @@ -320,23 +318,41 @@ static void unroll_switch_islands(WSCtx* x) { u32 nislands = 0; u32 scan = 0; while (scan < t->nwir) { - if (t->wir[scan].op != WIR_JUMP) { scan++; continue; } + if (t->wir[scan].op != WIR_JUMP) { + scan++; + continue; + } Label disp = t->wir[scan].labels[0]; - if (disp == LABEL_NONE || disp - 1u >= t->nlabels) { scan++; continue; } + if (disp == LABEL_NONE || disp - 1u >= t->nlabels) { + scan++; + continue; + } WLabel* dlbl = &t->labels[disp - 1u]; if (dlbl->kind != WLBL_FORWARD || !dlbl->placed || - dlbl->wir_index <= scan) { scan++; continue; } + dlbl->wir_index <= scan) { + scan++; + continue; + } /* Find WIR_SWITCH just past dispatch label; bail on intervening * terminator. */ u32 sw_i = UINT32_MAX; for (u32 k = dlbl->wir_index + 1u; k < t->nwir; ++k) { - if (t->wir[k].op == WIR_SWITCH) { sw_i = k; break; } + if (t->wir[k].op == WIR_SWITCH) { + sw_i = k; + break; + } if (t->wir[k].op == WIR_JUMP || t->wir[k].op == WIR_CMP_BRANCH || - t->wir[k].op == WIR_RET || t->wir[k].op == WIR_UNREACHABLE) break; + t->wir[k].op == WIR_RET || t->wir[k].op == WIR_UNREACHABLE) + break; + } + if (sw_i == UINT32_MAX) { + scan++; + continue; } - if (sw_i == UINT32_MAX) { scan++; continue; } if (nislands >= 16u) - sfail(t, "wasm: too many switch islands per function (max 16 supported in v1)"); + sfail(t, + "wasm: too many switch islands per function (max 16 supported in " + "v1)"); islands[nislands].j = scan; islands[nislands].d = dlbl->wir_index; islands[nislands].s = sw_i; @@ -388,8 +404,7 @@ static void unroll_switch_islands(WSCtx* x) { for (u32 k = 0; k < t->nwir; ++k) { if (t->wir[k].op != WIR_LABEL) continue; Label l = t->wir[k].labels[0]; - if (l != LABEL_NONE && l - 1u < t->nlabels) - t->labels[l - 1u].wir_index = k; + if (l != LABEL_NONE && l - 1u < t->nlabels) t->labels[l - 1u].wir_index = k; } } @@ -474,8 +489,7 @@ static int ev_cmp(const WSEvent* a, const WSEvent* b) { if (a_close) { /* CLOSE: innermost first. pair_idx = open_idx; the more-recently-opened * scope has a LATER open_idx, so larger pair_idx closes first. */ - if (a->pair_idx != b->pair_idx) - return a->pair_idx > b->pair_idx ? -1 : 1; + if (a->pair_idx != b->pair_idx) return a->pair_idx > b->pair_idx ? -1 : 1; return 0; } /* OPEN: outer first. pair_idx = close_idx; the larger range (later close) @@ -640,7 +654,10 @@ void wasm_structurize(WTarget* t) { if (x.nlbls > 0) { int any = 0; for (u32 i = 0; i < x.nlbls; ++i) - if (x.lbls[i].valid) { any = 1; break; } + if (x.lbls[i].valid) { + any = 1; + break; + } if (any) { merge_ranges(&x); pass_events(&x); diff --git a/src/arch/wasm/target.c b/src/arch/wasm/target.c @@ -5,10 +5,9 @@ * Methods that are not yet implemented panic with a precise message so users * see exactly which Wasm-target feature is still pending. */ -#include "arch/wasm/internal.h" - #include <string.h> +#include "arch/wasm/internal.h" #include "core/heap.h" /* Real implementations in emit.c. */ @@ -63,95 +62,155 @@ void wasm_set_loc(CGTarget*, SrcLoc); void wasm_finalize(CGTarget*); void wasm_destroy(CGTarget*); -#define WASM_UNIMPL(name) \ - compiler_panic(((WTarget*)t)->c, \ +#define WASM_UNIMPL(name) \ + compiler_panic(((WTarget*)t)->c, \ ((WTarget*)t)->cur_fn_desc ? ((WTarget*)t)->cur_fn_desc->loc \ - : (SrcLoc){0, 0, 0}, \ + : (SrcLoc){0, 0, 0}, \ "wasm target: " name " not yet implemented") static void unimpl_known_frame(CGTarget* t, const CGFuncDesc* f, const CGKnownFrameDesc* k, FrameSlot* out) { - (void)f; (void)k; (void)out; WASM_UNIMPL("func_begin_known_frame"); + (void)f; + (void)k; + (void)out; + WASM_UNIMPL("func_begin_known_frame"); } static void unimpl_local_addr(CGTarget* t, Operand op, const CGLocalDesc* d, CGLocalStorage s) { - (void)op; (void)d; (void)s; WASM_UNIMPL("local_addr (address-taken locals)"); + (void)op; + (void)d; + (void)s; + WASM_UNIMPL("local_addr (address-taken locals)"); } -static void unimpl_spill_reg(CGTarget* t, Operand a, FrameSlot s, - MemAccess m) { - (void)a; (void)s; (void)m; WASM_UNIMPL("spill_reg"); +static void unimpl_spill_reg(CGTarget* t, Operand a, FrameSlot s, MemAccess m) { + (void)a; + (void)s; + (void)m; + WASM_UNIMPL("spill_reg"); } static void unimpl_reload_reg(CGTarget* t, Operand a, FrameSlot s, MemAccess m) { - (void)a; (void)s; (void)m; WASM_UNIMPL("reload_reg"); + (void)a; + (void)s; + (void)m; + WASM_UNIMPL("reload_reg"); } static void no_regs(CGTarget* t, RegClass cls, const Reg** out, u32* n) { - (void)t; (void)cls; *out = NULL; *n = 0; + (void)t; + (void)cls; + *out = NULL; + *n = 0; } static void no_phys_regs(CGTarget* t, RegClass cls, const CGPhysRegInfo** out, u32* n) { - (void)t; (void)cls; *out = NULL; *n = 0; + (void)t; + (void)cls; + *out = NULL; + *n = 0; } static int no_caller_saved(CGTarget* t, RegClass cls, Reg r) { - (void)t; (void)cls; (void)r; return 0; + (void)t; + (void)cls; + (void)r; + return 0; } static u32 zero_mask(CGTarget* t, const CGCallDesc* d, RegClass cls) { - (void)t; (void)d; (void)cls; return 0; + (void)t; + (void)d; + (void)cls; + return 0; } static u32 zero_ret_mask(CGTarget* t, const ABIFuncInfo* f, RegClass cls) { - (void)t; (void)f; (void)cls; return 0; + (void)t; + (void)f; + (void)cls; + return 0; } static u32 zero_cs_mask(CGTarget* t, RegClass cls) { - (void)t; (void)cls; return 0; + (void)t; + (void)cls; + return 0; } static void noop_plan_regs(CGTarget* t, RegClass cls, const Reg* r, u32 n) { - (void)t; (void)cls; (void)r; (void)n; + (void)t; + (void)cls; + (void)r; + (void)n; } static void noop_reserve_regs(CGTarget* t, RegClass cls, const Reg* r, u32 n) { - (void)t; (void)cls; (void)r; (void)n; + (void)t; + (void)cls; + (void)r; + (void)n; } static u32 zero_call_stack(CGTarget* t, const CGCallDesc* d) { - (void)t; (void)d; return 0; + (void)t; + (void)d; + return 0; } static void unimpl_plan_call(CGTarget* t, const CGCallDesc* d, CGCallPlan* p) { - (void)d; (void)p; WASM_UNIMPL("plan_call"); + (void)d; + (void)p; + WASM_UNIMPL("plan_call"); } static void unimpl_load_call_arg(CGTarget* t, Operand d, const CGCallPlanMove* m) { - (void)d; (void)m; WASM_UNIMPL("load_call_arg"); + (void)d; + (void)m; + WASM_UNIMPL("load_call_arg"); } static void unimpl_store_call_arg(CGTarget* t, const CGCallPlanMove* m) { - (void)m; WASM_UNIMPL("store_call_arg"); + (void)m; + WASM_UNIMPL("store_call_arg"); } static void unimpl_store_call_ret(CGTarget* t, const CGCallPlanRet* r, Operand s) { - (void)r; (void)s; WASM_UNIMPL("store_call_ret"); + (void)r; + (void)s; + WASM_UNIMPL("store_call_ret"); } static void unimpl_emit_call_plan(CGTarget* t, const CGCallPlan* p) { - (void)p; WASM_UNIMPL("emit_call_plan"); + (void)p; + WASM_UNIMPL("emit_call_plan"); } static void unimpl_tls_addr_of(CGTarget* t, Operand d, ObjSymId s, i64 a) { - (void)d; (void)s; (void)a; WASM_UNIMPL("tls_addr_of"); + (void)d; + (void)s; + (void)a; + WASM_UNIMPL("tls_addr_of"); } static void unimpl_bf_load(CGTarget* t, Operand d, Operand r, BitFieldAccess a) { - (void)d; (void)r; (void)a; WASM_UNIMPL("bitfield_load"); + (void)d; + (void)r; + (void)a; + WASM_UNIMPL("bitfield_load"); } static void unimpl_bf_store(CGTarget* t, Operand r, Operand s, BitFieldAccess a) { - (void)r; (void)s; (void)a; WASM_UNIMPL("bitfield_store"); + (void)r; + (void)s; + (void)a; + WASM_UNIMPL("bitfield_store"); } static void unimpl_indirect_branch(CGTarget* t, Operand a, const Label* l, u32 n) { - (void)a; (void)l; (void)n; WASM_UNIMPL("indirect_branch (computed goto)"); + (void)a; + (void)l; + (void)n; + WASM_UNIMPL("indirect_branch (computed goto)"); } static void unimpl_load_label_addr(CGTarget* t, Operand d, Label l) { - (void)d; (void)l; WASM_UNIMPL("load_label_addr (&&label)"); + (void)d; + (void)l; + WASM_UNIMPL("load_label_addr (&&label)"); } static int unimpl_lsdb(CGTarget* t, const CGLocalStaticDataDesc* d) { - (void)t; (void)d; return 0; /* opt out — CG falls back to TU-wide data emission */ + (void)t; + (void)d; + return 0; /* opt out — CG falls back to TU-wide data emission */ } /* The TU-wide data path (cg/data.c) routes function-local-label addresses * inside static-data initializers through the MCEmitter. The Wasm backend @@ -164,10 +223,15 @@ static const char* wasm_data_label_addr_unsupported_msg(CGTarget* t) { "not yet supported"; } static void unimpl_lsdw(CGTarget* t, const u8* d, u64 n) { - (void)d; (void)n; WASM_UNIMPL("local_static_data_write"); + (void)d; + (void)n; + WASM_UNIMPL("local_static_data_write"); } static void unimpl_lsdl(CGTarget* t, Label l, i64 a, u32 w, u32 sp) { - (void)l; (void)a; (void)w; (void)sp; + (void)l; + (void)a; + (void)w; + (void)sp; WASM_UNIMPL("local_static_data_label_addr"); } static void unimpl_lsde(CGTarget* t) { WASM_UNIMPL("local_static_data_end"); } diff --git a/src/arch/wasm/wasm_imports.c b/src/arch/wasm/wasm_imports.c @@ -29,8 +29,8 @@ static void wasm_imports_free(Compiler* c, void* p) { (void)c; WasmImportTable* t = (WasmImportTable*)p; if (!t) return; - if (t->entries) t->heap->free(t->heap, t->entries, - sizeof(*t->entries) * t->cap); + if (t->entries) + t->heap->free(t->heap, t->entries, sizeof(*t->entries) * t->cap); t->heap->free(t->heap, t, sizeof(*t)); } @@ -75,10 +75,9 @@ void wasm_imports_set(ObjBuilder* o, Sym name, Sym import_module, } if (t->count == t->cap) { u32 nc = t->cap ? t->cap * 2u : 8u; - void* p = t->heap->realloc(t->heap, t->entries, - sizeof(*t->entries) * t->cap, - sizeof(*t->entries) * nc, - _Alignof(WasmImportEntry)); + void* p = + t->heap->realloc(t->heap, t->entries, sizeof(*t->entries) * t->cap, + sizeof(*t->entries) * nc, _Alignof(WasmImportEntry)); if (!p) return; t->entries = (WasmImportEntry*)p; t->cap = nc; diff --git a/src/arch/x64/alloc.c b/src/arch/x64/alloc.c @@ -8,13 +8,13 @@ #include <string.h> #include "arch/arch.h" -#include "core/slice.h" #include "arch/x64/internal.h" #include "arch/x64/isa.h" #include "arch/x64/regs.h" #include "arch/x64/x64.h" #include "core/arena.h" #include "core/pool.h" +#include "core/slice.h" #include "obj/obj.h" /* ============================================================ @@ -115,9 +115,8 @@ static void x_consume_param_location(XImpl* a, const ABIArgInfo* ai) { x_param_sync_slot(a); return; } - if (ai->kind == ABI_ARG_DIRECT && x64_abi_direct_to_stack( - ai, a->next_param_int, - a->next_param_fp)) { + if (ai->kind == ABI_ARG_DIRECT && + x64_abi_direct_to_stack(ai, a->next_param_int, a->next_param_fp)) { a->next_param_stack += (u32)ai->nparts * 8u; return; } @@ -165,7 +164,8 @@ CGLocalStorage x_param(CGTarget* t, const CGParamDesc* p) { * Win64 reserves 32 B of caller-provided "home space" for the 4 * register arg slots immediately above the return address, so stack * args start at [rbp + 16 + 32] = +48. SysV has no shadow space. */ - i32 incoming_stack_bias = a->omit_frame ? 8 : (i32)(16u + a->abi->shadow_space); + i32 incoming_stack_bias = + a->omit_frame ? 8 : (i32)(16u + a->abi->shadow_space); if (ai->kind == ABI_ARG_IGNORE) return st; if (st.kind == CG_LOCAL_STORAGE_REG && st.v.reg == (Reg)REG_NONE) { diff --git a/src/arch/x64/asm.c b/src/arch/x64/asm.c @@ -45,8 +45,8 @@ typedef struct X64AsmOperand { i32 disp; } X64AsmOperand; -static int x64_reg_from_name(AsmDriver* d, Sym s, u32* reg_out, - u32* width_out, u32* high8_out) { +static int x64_reg_from_name(AsmDriver* d, Sym s, u32* reg_out, u32* width_out, + u32* high8_out) { Slice sl = pool_slice(asm_driver_pool(d), s); char buf[16]; u32 reg; @@ -158,7 +158,8 @@ static X64AsmOperand parse_operand(AsmDriver* d) { AsmTok ident; (void)asm_driver_next(d); ident = asm_driver_next(d); - if (ident.kind != ASM_TOK_IDENT) asm_driver_panic(d, "x64 asm: bad register"); + if (ident.kind != ASM_TOK_IDENT) + asm_driver_panic(d, "x64 asm: bad register"); if (x64_segment_prefix_from_name(d, ident.v.ident, &op.seg)) { asm_driver_expect_punct(d, ':', "':' after x64 segment register"); op.kind = X64_ASM_OP_MEM; @@ -272,8 +273,10 @@ static void reject_high8_with_rex(AsmDriver* d, const X64AsmOperand* a, } } -static __attribute__((unused)) void emit_movb_rr_operand( - AsmDriver* d, MCEmitter* mc, X64AsmOperand dst, X64AsmOperand src) { +static __attribute__((unused)) void emit_movb_rr_operand(AsmDriver* d, + MCEmitter* mc, + X64AsmOperand dst, + X64AsmOperand src) { u8 ob = 0x88; reject_high8_with_rex(d, &dst, &src); if (byte_reg_needs_rex(&dst) || byte_reg_needs_rex(&src)) @@ -287,8 +290,10 @@ static __attribute__((unused)) void emit_movb_rr_operand( } } -static __attribute__((unused)) void emit_movb_store_operand( - AsmDriver* d, MCEmitter* mc, X64AsmOperand src, X64AsmOperand dst) { +static __attribute__((unused)) void emit_movb_store_operand(AsmDriver* d, + MCEmitter* mc, + X64AsmOperand src, + X64AsmOperand dst) { if (src.high8) { u8 ob = 0x88; if (dst.no_base || dst.base >= 8u) @@ -395,16 +400,16 @@ static __attribute__((unused)) void emit_reg_rm_twobyte( * lands in follow-ups. */ #define X64_SFX_NONE 0u -#define X64_SFX_B 1u -#define X64_SFX_W 2u -#define X64_SFX_L 4u -#define X64_SFX_Q 8u +#define X64_SFX_B 1u +#define X64_SFX_W 2u +#define X64_SFX_L 4u +#define X64_SFX_Q 8u typedef struct X64MnInfo { char base[16]; /* stripped mnemonic (table-spelling) */ u32 base_len; - u32 width; /* X64_SFX_* — 0 if mnemonic carries no size letter */ - u32 cc; /* condition nibble for jcc/cmovcc/setcc, or 16 if none */ + u32 width; /* X64_SFX_* — 0 if mnemonic carries no size letter */ + u32 cc; /* condition nibble for jcc/cmovcc/setcc, or 16 if none */ } X64MnInfo; /* Parse the user-supplied mnemonic into (root, width, cc). Handles: @@ -414,14 +419,17 @@ typedef struct X64MnInfo { * - setXX → ("set", cc) * - exact-match mnemonics carried verbatim (movslq, movzbl, ud2, ...) */ static int parse_mnemonic(const char* s, size_t n, X64MnInfo* out) { - static const struct { const char* name; u8 cc; } kCC[] = { + static const struct { + const char* name; + u8 cc; + } kCC[] = { /* Two-letter codes first so e.g. "ne" beats "n" if we ever add it. */ {"ae", X64_CC_AE}, {"be", X64_CC_BE}, {"ge", X64_CC_GE}, {"le", X64_CC_LE}, {"ne", X64_CC_NE}, {"no", X64_CC_NO}, - {"np", X64_CC_NP}, {"ns", X64_CC_NS}, - {"a", X64_CC_A}, {"b", X64_CC_B}, {"e", X64_CC_E}, - {"g", X64_CC_G}, {"l", X64_CC_L}, {"o", X64_CC_O}, - {"p", X64_CC_P}, {"s", X64_CC_S}, + {"np", X64_CC_NP}, {"ns", X64_CC_NS}, {"a", X64_CC_A}, + {"b", X64_CC_B}, {"e", X64_CC_E}, {"g", X64_CC_G}, + {"l", X64_CC_L}, {"o", X64_CC_O}, {"p", X64_CC_P}, + {"s", X64_CC_S}, }; out->base_len = 0; out->width = X64_SFX_NONE; @@ -433,28 +441,34 @@ static int parse_mnemonic(const char* s, size_t n, X64MnInfo* out) { /* Exact-match mnemonics that carry their own width letters or are * already canonical table spellings. */ if (n >= 6 && memcmp(s, "movslq", 6) == 0) { - memcpy(out->base, "movslq", 6); out->base_len = 6; out->width = X64_SFX_Q; + memcpy(out->base, "movslq", 6); + out->base_len = 6; + out->width = X64_SFX_Q; return 1; } - if (n >= 6 && - (memcmp(s, "movzbl", 6) == 0 || memcmp(s, "movzwl", 6) == 0 || - memcmp(s, "movsbl", 6) == 0 || memcmp(s, "movswl", 6) == 0)) { - memcpy(out->base, s, 6); out->base_len = 6; + if (n >= 6 && (memcmp(s, "movzbl", 6) == 0 || memcmp(s, "movzwl", 6) == 0 || + memcmp(s, "movsbl", 6) == 0 || memcmp(s, "movswl", 6) == 0)) { + memcpy(out->base, s, 6); + out->base_len = 6; return 1; } if (n == 3 && memcmp(s, "ud2", 3) == 0) { - out->base_len = 3; return 1; + out->base_len = 3; + return 1; } if (n == 3 && memcmp(s, "nop", 3) == 0) { - out->base_len = 3; return 1; + out->base_len = 3; + return 1; } if (n == 3 && memcmp(s, "ret", 3) == 0) { - out->base_len = 3; return 1; + out->base_len = 3; + return 1; } /* "syscall" ends in 'l' — return early so the generic size-suffix * stripper below does not mistake it for a movl-style width letter. */ if (n == 7 && memcmp(s, "syscall", 7) == 0) { - out->base_len = 7; return 1; + out->base_len = 7; + return 1; } /* Indirect-branch spellings carry an explicit 'q' suffix that must be @@ -467,10 +481,14 @@ static int parse_mnemonic(const char* s, size_t n, X64MnInfo* out) { return 1; } if (n == 4 && memcmp(s, "jmpq", 4) == 0) { - out->base_len = 4; out->width = X64_SFX_Q; return 1; + out->base_len = 4; + out->width = X64_SFX_Q; + return 1; } if (n == 5 && memcmp(s, "callq", 5) == 0) { - out->base_len = 5; out->width = X64_SFX_Q; return 1; + out->base_len = 5; + out->width = X64_SFX_Q; + return 1; } /* CMOVcc: cmov<cc>[suffix]. Strip optional trailing q/l/w/b first. */ @@ -577,8 +595,8 @@ typedef struct X64ParseCtx { AsmDriver* d; MCEmitter* mc; const X64InsnDesc* desc; - u32 width; /* 1/2/4/8 — derived from suffix or row */ - u32 cc; /* condition nibble (jcc/cmovcc/setcc); 16 if unused */ + u32 width; /* 1/2/4/8 — derived from suffix or row */ + u32 cc; /* condition nibble (jcc/cmovcc/setcc); 16 if unused */ } X64ParseCtx; /* w-bit for emit_rex / emit_alu_rr / emit_mov_rr etc. */ @@ -680,16 +698,16 @@ static void parse_alu_rr(X64ParseCtx* p) { /* MOV r, r/m goes through MOV_RM_LOAD; MOV r, m goes through * MOV_RM_LOAD (load) or ALU_RR with mem dst (store). We handle the * store side here only when the mnemonic is "mov" (opc 0x89). */ - if (p->desc->opc[0] == 0x89u && - src.kind == X64_ASM_OP_REG && dst.kind == X64_ASM_OP_MEM) { + if (p->desc->opc[0] == 0x89u && src.kind == X64_ASM_OP_REG && + dst.kind == X64_ASM_OP_MEM) { if (p->width == 1u) emit_movb_store_operand(p->d, p->mc, src, dst); else emit_mov_store_operand(p->mc, p->width, src.reg, dst, 0); return; } - if (p->desc->opc[0] == 0x89u && - src.kind == X64_ASM_OP_MEM && dst.kind == X64_ASM_OP_REG) { + if (p->desc->opc[0] == 0x89u && src.kind == X64_ASM_OP_MEM && + dst.kind == X64_ASM_OP_REG) { emit_mov_load_operand(p->mc, p->width, dst.reg, src); return; } @@ -754,10 +772,12 @@ static void parse_movsxd(X64ParseCtx* p) { emit_extend_rr(p->mc, 1, 1, 4, dst.reg, src.reg); } else if (src.kind == X64_ASM_OP_MEM) { u8 buf[16]; - u32 n = x64_mov_rm_load_pack( - (X64MovRMLoad){.w = 1, .opc0 = X64_OPC_MOVSXD, .dst = dst.reg, - .base = src.base, .disp = src.disp}, - buf); + u32 n = x64_mov_rm_load_pack((X64MovRMLoad){.w = 1, + .opc0 = X64_OPC_MOVSXD, + .dst = dst.reg, + .base = src.base, + .disp = src.disp}, + buf); emit_packed(p->mc, buf, n); } else { asm_driver_panic(p->d, "x64 asm: movslq source"); @@ -806,7 +826,8 @@ static void parse_push_pop(X64ParseCtx* p) { X64AsmOperand op = parse_operand(p->d); u8 base = p->desc->opc[0]; u8 ob; - if (op.kind != X64_ASM_OP_REG) asm_driver_panic(p->d, "x64 asm: push/pop register"); + if (op.kind != X64_ASM_OP_REG) + asm_driver_panic(p->d, "x64 asm: push/pop register"); emit_rex(p->mc, 0, 0, 0, op.reg); ob = (u8)(base | (op.reg & 7u)); p->mc->emit_bytes(p->mc, &ob, 1); @@ -817,11 +838,12 @@ static void parse_movzx_movsx(X64ParseCtx* p) { X64AsmOperand dst; expect_comma(p->d); dst = parse_operand(p->d); - if (dst.kind != X64_ASM_OP_REG) asm_driver_panic(p->d, "x64 asm: movx dst register"); - emit_reg_rm_twobyte(p->d, p->mc, 4u, p->desc->opc[1], dst.reg, src, - p->desc->opc[1] == X64_OPC_MOVZX_B || - p->desc->opc[1] == X64_OPC_MOVSX_B, - 0); + if (dst.kind != X64_ASM_OP_REG) + asm_driver_panic(p->d, "x64 asm: movx dst register"); + emit_reg_rm_twobyte( + p->d, p->mc, 4u, p->desc->opc[1], dst.reg, src, + p->desc->opc[1] == X64_OPC_MOVZX_B || p->desc->opc[1] == X64_OPC_MOVSX_B, + 0); } static void parse_imul_rr(X64ParseCtx* p) { @@ -833,7 +855,8 @@ static void parse_imul_rr(X64ParseCtx* p) { real_src = parse_operand(p->d); expect_comma(p->d); dst = parse_operand(p->d); - if (dst.kind != X64_ASM_OP_REG) asm_driver_panic(p->d, "x64 asm: imul dst register"); + if (dst.kind != X64_ASM_OP_REG) + asm_driver_panic(p->d, "x64 asm: imul dst register"); if (real_src.kind == X64_ASM_OP_REG) { if (imm_fits_i8(src.imm)) emit_imul_imm8(p->mc, width_to_w(p->width), dst.reg, real_src.reg, @@ -866,9 +889,10 @@ static void parse_imul_rr(X64ParseCtx* p) { } expect_comma(p->d); dst = parse_operand(p->d); - if (dst.kind != X64_ASM_OP_REG) asm_driver_panic(p->d, "x64 asm: imul dst register"); - emit_reg_rm_twobyte(p->d, p->mc, p->width, X64_OPC_IMUL_2B, dst.reg, src, - 0, 0); + if (dst.kind != X64_ASM_OP_REG) + asm_driver_panic(p->d, "x64 asm: imul dst register"); + emit_reg_rm_twobyte(p->d, p->mc, p->width, X64_OPC_IMUL_2B, dst.reg, src, 0, + 0); } static void parse_imul_rri(X64ParseCtx* p) { @@ -880,7 +904,8 @@ static void parse_imul_rri(X64ParseCtx* p) { src = parse_operand(p->d); expect_comma(p->d); dst = parse_operand(p->d); - if (dst.kind != X64_ASM_OP_REG) asm_driver_panic(p->d, "x64 asm: imul dst register"); + if (dst.kind != X64_ASM_OP_REG) + asm_driver_panic(p->d, "x64 asm: imul dst register"); if (src.kind == X64_ASM_OP_REG) { if (p->desc->opc[0] == X64_OPC_IMUL_IMM8 || imm_fits_i8(imm.imm)) emit_imul_imm8(p->mc, width_to_w(p->width), dst.reg, src.reg, @@ -927,8 +952,8 @@ static void parse_shift(X64ParseCtx* p) { return; } if (src.kind != X64_ASM_OP_IMM) asm_driver_panic(p->d, "x64 asm: shift imm"); - emit_rm_imm(p->d, p->mc, p->width, X64_OPC_SHIFT_IMM, p->desc->modrm_reg, - dst, (i32)src.imm, 0); + emit_rm_imm(p->d, p->mc, p->width, X64_OPC_SHIFT_IMM, p->desc->modrm_reg, dst, + (i32)src.imm, 0); } static void parse_rel32_branch(X64ParseCtx* p) { @@ -946,11 +971,12 @@ static void parse_rel32_branch(X64ParseCtx* p) { disp_pos = p->mc->pos(p->mc); emit_u32le(p->mc, 0); asm_driver_parse_sym_expr(p->d, &sym, &off); - if (sym == OBJ_SYM_NONE) asm_driver_panic(p->d, "x64 asm: symbolic branch target required"); - p->mc->emit_reloc_at(p->mc, asm_driver_cur_section(p->d), disp_pos, - p->desc->fmt == X64_FMT_CALL_REL32 ? R_X64_PLT32 - : R_PC32, - sym, off - 4, 1, 0); + if (sym == OBJ_SYM_NONE) + asm_driver_panic(p->d, "x64 asm: symbolic branch target required"); + p->mc->emit_reloc_at( + p->mc, asm_driver_cur_section(p->d), disp_pos, + p->desc->fmt == X64_FMT_CALL_REL32 ? R_X64_PLT32 : R_PC32, sym, off - 4, + 1, 0); } static void parse_setcc(X64ParseCtx* p) { @@ -991,8 +1017,8 @@ static void parse_sse_rr(X64ParseCtx* p) { emit_sse_rr_w(p->mc, p->desc->leg_pfx, p->desc->opc[1], width_to_w(p->width), dst.reg, src.reg); else if (src.kind == X64_ASM_OP_MEM) - emit_reg_rm_twobyte(p->d, p->mc, p->width, p->desc->opc[1], dst.reg, - src, 0, p->desc->leg_pfx); + emit_reg_rm_twobyte(p->d, p->mc, p->width, p->desc->opc[1], dst.reg, src, + 0, p->desc->leg_pfx); else asm_driver_panic(p->d, "x64 asm: cvtt source"); return; @@ -1004,8 +1030,8 @@ static void parse_sse_rr(X64ParseCtx* p) { emit_sse_rr_w(p->mc, p->desc->leg_pfx, p->desc->opc[1], width_to_w(p->width), dst.reg, src.reg); else if (src.kind == X64_ASM_OP_MEM) - emit_sse_load(p->mc, p->desc->leg_pfx, p->desc->opc[1], dst.reg, - src.base, src.disp); + emit_sse_load(p->mc, p->desc->leg_pfx, p->desc->opc[1], dst.reg, src.base, + src.disp); else asm_driver_panic(p->d, "x64 asm: cvtsi source"); return; @@ -1014,18 +1040,16 @@ static void parse_sse_rr(X64ParseCtx* p) { p->desc->opc[1] == 0x10u && (slice_eq_cstr(p->desc->mnemonic, "movsd") || slice_eq_cstr(p->desc->mnemonic, "movss"))) { - emit_sse_store(p->mc, p->desc->leg_pfx, 0x11, src.reg, dst.base, - dst.disp); + emit_sse_store(p->mc, p->desc->leg_pfx, 0x11, src.reg, dst.base, dst.disp); return; } if (dst.kind == X64_ASM_OP_MEM && src.kind == X64_ASM_OP_XMM && - p->desc->opc[1] == 0x28u && - slice_eq_cstr(p->desc->mnemonic, "movaps")) { - emit_sse_store(p->mc, p->desc->leg_pfx, 0x29, src.reg, dst.base, - dst.disp); + p->desc->opc[1] == 0x28u && slice_eq_cstr(p->desc->mnemonic, "movaps")) { + emit_sse_store(p->mc, p->desc->leg_pfx, 0x29, src.reg, dst.base, dst.disp); return; } - if (dst.kind != X64_ASM_OP_XMM) asm_driver_panic(p->d, "x64 asm: sse dst xmm"); + if (dst.kind != X64_ASM_OP_XMM) + asm_driver_panic(p->d, "x64 asm: sse dst xmm"); if (src.kind == X64_ASM_OP_XMM) emit_sse_rr(p->mc, p->desc->leg_pfx, p->desc->opc[1], dst.reg, src.reg); else if (src.kind == X64_ASM_OP_MEM) @@ -1050,7 +1074,8 @@ static void parse_bs_popcnt(X64ParseCtx* p) { X64AsmOperand dst; expect_comma(p->d); dst = parse_operand(p->d); - if (dst.kind != X64_ASM_OP_REG) asm_driver_panic(p->d, "x64 asm: bit-scan dst register"); + if (dst.kind != X64_ASM_OP_REG) + asm_driver_panic(p->d, "x64 asm: bit-scan dst register"); emit_reg_rm_twobyte(p->d, p->mc, p->width, p->desc->opc[1], dst.reg, src, 0, p->desc->leg_pfx); } @@ -1213,8 +1238,7 @@ static void x64_arch_asm_insn(ArchAsm* base, AsmDriver* d, Sym mnemonic) { /* Find the MOV_RI row. */ for (u32 i = 0; i < x64_insn_table_n; ++i) { const X64InsnDesc* dr = &x64_insn_table[i]; - if (dr->fmt == X64_FMT_MOV_RI && - slice_eq_cstr(dr->mnemonic, "mov")) { + if (dr->fmt == X64_FMT_MOV_RI && slice_eq_cstr(dr->mnemonic, "mov")) { ctx.d = d; ctx.mc = mc; ctx.desc = dr; @@ -1274,7 +1298,8 @@ static void x64_arch_asm_insn(ArchAsm* base, AsmDriver* d, Sym mnemonic) { for (u32 i = 0; i < x64_insn_table_n; ++i) { const X64InsnDesc* dr = &x64_insn_table[i]; if (dr->fmt != X64_FMT_BR_RM) continue; - if (!slice_eq(dr->mnemonic, (Slice){{info.base}, info.base_len})) continue; + if (!slice_eq(dr->mnemonic, (Slice){{info.base}, info.base_len})) + continue; desc = dr; break; } @@ -1331,7 +1356,7 @@ _Noreturn static void inline_panic(X64Asm* a, const char* msg) { * forms recognised by the template walker. */ #define X64_REG_WIDTH_64 0 #define X64_REG_WIDTH_32 1 -#define X64_REG_WIDTH_8 2 +#define X64_REG_WIDTH_8 2 #define X64_REG_WIDTH_16 3 #define X64_REG_WIDTH_H8 4 @@ -1385,12 +1410,12 @@ static void render_indirect(StrBuf* sb, Reg base, i32 ofs) { /* Operand-modifier forms used by the template walker. */ #define X64_FORM_DEFAULT 0 -#define X64_FORM_W 1 /* %w — 16-bit */ -#define X64_FORM_X 2 /* %x — 64-bit */ -#define X64_FORM_A 3 /* %a — address / memory */ -#define X64_FORM_B 4 /* %b — 8-bit (byte) register */ -#define X64_FORM_K 5 /* %k — 32-bit */ -#define X64_FORM_H 6 /* %h — high 8-bit register (a/c/d/b only) */ +#define X64_FORM_W 1 /* %w — 16-bit */ +#define X64_FORM_X 2 /* %x — 64-bit */ +#define X64_FORM_A 3 /* %a — address / memory */ +#define X64_FORM_B 4 /* %b — 8-bit (byte) register */ +#define X64_FORM_K 5 /* %k — 32-bit */ +#define X64_FORM_H 6 /* %h — high 8-bit register (a/c/d/b only) */ static char x64_size_suffix_for_operand(X64Asm* a, u32 idx) { u32 ntot = a->nout + a->nin; @@ -1435,17 +1460,22 @@ static void render_operand(X64Asm* a, StrBuf* sb, u32 idx, int form) { } if (op->kind == OPK_REG) { int width; - if (form == X64_FORM_B) width = X64_REG_WIDTH_8; + if (form == X64_FORM_B) + width = X64_REG_WIDTH_8; else if (form == X64_FORM_H) { if (op->v.reg > X64_RBX) { inline_panic(a, "%h modifier requires ax/cx/dx/bx register"); } width = X64_REG_WIDTH_H8; - } else if (form == X64_FORM_W) width = X64_REG_WIDTH_16; - else if (form == X64_FORM_K) width = X64_REG_WIDTH_32; - else if (form == X64_FORM_X) width = X64_REG_WIDTH_64; - else width = x64_type_prefers_32(op->type) ? X64_REG_WIDTH_32 - : X64_REG_WIDTH_64; + } else if (form == X64_FORM_W) + width = X64_REG_WIDTH_16; + else if (form == X64_FORM_K) + width = X64_REG_WIDTH_32; + else if (form == X64_FORM_X) + width = X64_REG_WIDTH_64; + else + width = + x64_type_prefers_32(op->type) ? X64_REG_WIDTH_32 : X64_REG_WIDTH_64; render_reg(sb, (u32)op->v.reg, width); return; } @@ -1524,8 +1554,8 @@ static void render_and_run_line(X64Asm* a, MCEmitter* mc, StrBuf* sb, ++p; continue; } - if (n == 'w' || n == 'x' || n == 'a' || n == 'b' || n == 'k' || - n == 'h' || n == 'z') { + if (n == 'w' || n == 'x' || n == 'a' || n == 'b' || n == 'k' || n == 'h' || + n == 'z') { form = (n == 'w') ? X64_FORM_W : (n == 'x') ? X64_FORM_X : (n == 'a') ? X64_FORM_A diff --git a/src/arch/x64/emit.c b/src/arch/x64/emit.c @@ -7,6 +7,7 @@ #include <string.h> #include "arch/arch.h" +#include "arch/x64/internal.h" #include "arch/x64/isa.h" #include "arch/x64/x64.h" #include "core/arena.h" @@ -14,8 +15,6 @@ #include "core/slice.h" #include "obj/obj.h" -#include "arch/x64/internal.h" - /* ============================================================ * Shared constant tables. */ @@ -78,13 +77,12 @@ const X64ABIRegs* x64_abi_for_os(CfreeOSKind os) { * displacement, optional immediate. Helpers below build sequences * into the active MCEmitter section, recording one Debug row per * instruction-start. */ -static void emit1(MCEmitter *mc, u8 b) { +static void emit1(MCEmitter* mc, u8 b) { u32 ofs = obj_pos(mc->obj, mc->section_id); mc->emit_bytes(mc, &b, 1); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } -void emit_u32le(MCEmitter *mc, u32 v) { +void emit_u32le(MCEmitter* mc, u32 v) { u8 b[4]; b[0] = (u8)v; b[1] = (u8)(v >> 8); @@ -94,24 +92,19 @@ void emit_u32le(MCEmitter *mc, u32 v) { } static u8 make_rex(int w, u32 reg, u32 index, u32 rm) { u8 r = 0; - if (w) - r |= X64_REX_W; - if (reg & 8) - r |= X64_REX_R; - if (index & 8) - r |= X64_REX_X; - if (rm & 8) - r |= X64_REX_B; + if (w) r |= X64_REX_W; + if (reg & 8) r |= X64_REX_R; + if (index & 8) r |= X64_REX_X; + if (rm & 8) r |= X64_REX_B; return r ? (u8)(X64_REX_BASE | r) : 0; } -void emit_rex(MCEmitter *mc, int w, u32 reg, u32 index, u32 rm) { +void emit_rex(MCEmitter* mc, int w, u32 reg, u32 index, u32 rm) { u8 r = make_rex(w, reg, index, rm); - if (r) - mc->emit_bytes(mc, &r, 1); + if (r) mc->emit_bytes(mc, &r, 1); } /* Force REX (even REX=0x40) — required for byte-reg encodings that * promote SIL/DIL/etc. */ -void emit_rex_force(MCEmitter *mc, int w, u32 reg, u32 index, u32 rm) { +void emit_rex_force(MCEmitter* mc, int w, u32 reg, u32 index, u32 rm) { u8 r = (u8)(X64_REX_BASE | (w ? X64_REX_W : 0) | ((reg & 8) ? X64_REX_R : 0) | ((index & 8) ? X64_REX_X : 0) | ((rm & 8) ? X64_REX_B : 0)); mc->emit_bytes(mc, &r, 1); @@ -125,14 +118,12 @@ u8 sib(u32 scale, u32 index, u32 base) { } static u32 disp_mod(u32 base, i32 disp) { - if (disp == 0 && (base & 7u) != 5u) - return 0u; /* [base] */ - if (disp >= -128 && disp <= 127) - return 1u; /* [base + disp8] */ - return 2u; /* [base + disp32] */ + if (disp == 0 && (base & 7u) != 5u) return 0u; /* [base] */ + if (disp >= -128 && disp <= 127) return 1u; /* [base + disp8] */ + return 2u; /* [base + disp32] */ } -void emit_mem_operand(MCEmitter *mc, u32 reg, u32 base, i32 disp) { +void emit_mem_operand(MCEmitter* mc, u32 reg, u32 base, i32 disp) { u32 m = disp_mod(base, disp); if ((base & 7u) == 4u) { /* SIB byte required: index=4 (none), base=base. */ @@ -151,7 +142,7 @@ void emit_mem_operand(MCEmitter *mc, u32 reg, u32 base, i32 disp) { emit_u32le(mc, (u32)disp); } } -void emit_rm_reg(MCEmitter *mc, u32 reg, u32 rm) { +void emit_rm_reg(MCEmitter* mc, u32 reg, u32 rm) { u8 mr = modrm(3u, reg, rm); mc->emit_bytes(mc, &mr, 1); } @@ -159,99 +150,113 @@ void emit_rm_reg(MCEmitter *mc, u32 reg, u32 rm) { /* ---- specific instruction emitters ---- */ /* mov rd, rs (64-bit if w, else 32-bit). */ -void emit_mov_rr(MCEmitter *mc, int w, u32 dst, u32 src) { +void emit_mov_rr(MCEmitter* mc, int w, u32 dst, u32 src) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 buf[16]; u32 n = x64_alu_rr_pack( (X64AluRR){.w = w, .op = X64_OPC_MOV_RM_R, .dst = dst, .src = src}, buf); mc->emit_bytes(mc, buf, n); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } /* mov reg, [base + disp]; size 1/2/4/8. */ -void emit_mov_load(MCEmitter *mc, u32 size, int signed_ext, u32 dst, u32 base, +void emit_mov_load(MCEmitter* mc, u32 size, int signed_ext, u32 dst, u32 base, i32 disp) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 buf[16]; u32 n = 0; if (size == 8) { - n = x64_mov_rm_load_pack( - (X64MovRMLoad){.w = 1, .opc0 = X64_OPC_MOV_R_RM, .dst = dst, - .base = base, .disp = disp}, - buf); + n = x64_mov_rm_load_pack((X64MovRMLoad){.w = 1, + .opc0 = X64_OPC_MOV_R_RM, + .dst = dst, + .base = base, + .disp = disp}, + buf); } else if (size == 4) { - n = x64_mov_rm_load_pack( - (X64MovRMLoad){.w = 0, .opc0 = X64_OPC_MOV_R_RM, .dst = dst, - .base = base, .disp = disp}, - buf); + n = x64_mov_rm_load_pack((X64MovRMLoad){.w = 0, + .opc0 = X64_OPC_MOV_R_RM, + .dst = dst, + .base = base, + .disp = disp}, + buf); } else if (size == 2) { n = x64_mov_rm_load_pack( (X64MovRMLoad){.w = 0, .opc1 = signed_ext ? X64_OPC_MOVSX_W : X64_OPC_MOVZX_W, - .dst = dst, .base = base, .disp = disp}, + .dst = dst, + .base = base, + .disp = disp}, buf); } else if (size == 1) { n = x64_mov_rm_load_pack( (X64MovRMLoad){.w = 0, .opc1 = signed_ext ? X64_OPC_MOVSX_B : X64_OPC_MOVZX_B, - .dst = dst, .base = base, .disp = disp}, + .dst = dst, + .base = base, + .disp = disp}, buf); } if (n) mc->emit_bytes(mc, buf, n); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } /* mov [base + disp], src; size 1/2/4/8. */ -void emit_mov_store(MCEmitter *mc, u32 size, u32 src, u32 base, i32 disp) { +void emit_mov_store(MCEmitter* mc, u32 size, u32 src, u32 base, i32 disp) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 buf[16]; u32 n = 0; if (size == 8) { - n = x64_alu_rm_pack( - (X64AluRM){.w = 1, .op = X64_OPC_MOV_RM_R, .src = src, .base = base, - .disp = disp}, - buf); + n = x64_alu_rm_pack((X64AluRM){.w = 1, + .op = X64_OPC_MOV_RM_R, + .src = src, + .base = base, + .disp = disp}, + buf); } else if (size == 4) { - n = x64_alu_rm_pack( - (X64AluRM){.w = 0, .op = X64_OPC_MOV_RM_R, .src = src, .base = base, - .disp = disp}, - buf); + n = x64_alu_rm_pack((X64AluRM){.w = 0, + .op = X64_OPC_MOV_RM_R, + .src = src, + .base = base, + .disp = disp}, + buf); } else if (size == 2) { - n = x64_alu_rm_pack( - (X64AluRM){.prefix = X64_OPSIZE_PFX, .w = 0, .op = X64_OPC_MOV_RM_R, - .src = src, .base = base, .disp = disp}, - buf); + n = x64_alu_rm_pack((X64AluRM){.prefix = X64_OPSIZE_PFX, + .w = 0, + .op = X64_OPC_MOV_RM_R, + .src = src, + .base = base, + .disp = disp}, + buf); } else if (size == 1) { /* Force REX so SIL/DIL/etc are addressable as byte regs. */ - n = x64_alu_rm_pack( - (X64AluRM){.w = 0, .op = X64_OPC_MOV_RM_R8, .force_rex = 1, .src = src, - .base = base, .disp = disp}, - buf); + n = x64_alu_rm_pack((X64AluRM){.w = 0, + .op = X64_OPC_MOV_RM_R8, + .force_rex = 1, + .src = src, + .base = base, + .disp = disp}, + buf); } if (n) mc->emit_bytes(mc, buf, n); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } -void emit_lea(MCEmitter *mc, u32 dst, u32 base, i32 disp) { +void emit_lea(MCEmitter* mc, u32 dst, u32 base, i32 disp) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 buf[16]; u32 n = x64_mov_rm_load_pack( - (X64MovRMLoad){.w = 1, .opc0 = X64_OPC_LEA, .dst = dst, .base = base, - .disp = disp}, + (X64MovRMLoad){ + .w = 1, .opc0 = X64_OPC_LEA, .dst = dst, .base = base, .disp = disp}, buf); mc->emit_bytes(mc, buf, n); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } /* Common low-level emit for `[base + index<<log2_scale + disp]` GPR/SSE * memory operands. Builds REX with index, opcode(s), and SIB by hand * (the existing `*_pack` helpers route through `x64_pack_mem`, which * forces SIB index = 4 (none)). */ -static void emit_mem_idx_op(MCEmitter *mc, u8 prefix, int w, int force_rex, +static void emit_mem_idx_op(MCEmitter* mc, u8 prefix, int w, int force_rex, u8 opc0, u8 opc1, u32 reg, u32 base, u32 index, u32 log2_scale, i32 disp) { u8 buf[16]; @@ -272,7 +277,7 @@ static void emit_mem_idx_op(MCEmitter *mc, u8 prefix, int w, int force_rex, } /* mov reg, [base + index<<log2_scale + disp]; size 1/2/4/8. */ -void emit_mov_load_idx(MCEmitter *mc, u32 size, int signed_ext, u32 dst, +void emit_mov_load_idx(MCEmitter* mc, u32 size, int signed_ext, u32 dst, u32 base, u32 index, u32 log2_scale, i32 disp) { if (index == REG_NONE) { emit_mov_load(mc, size, signed_ext, dst, base, disp); @@ -298,7 +303,7 @@ void emit_mov_load_idx(MCEmitter *mc, u32 size, int signed_ext, u32 dst, } /* mov [base + index<<log2_scale + disp], src; size 1/2/4/8. */ -void emit_mov_store_idx(MCEmitter *mc, u32 size, u32 src, u32 base, u32 index, +void emit_mov_store_idx(MCEmitter* mc, u32 size, u32 src, u32 base, u32 index, u32 log2_scale, i32 disp) { if (index == REG_NONE) { emit_mov_store(mc, size, src, base, disp); @@ -324,138 +329,123 @@ void emit_mov_store_idx(MCEmitter *mc, u32 size, u32 src, u32 base, u32 index, /* movabs reg, imm64 (REX.W + B8+r imm64) for is64; mov r32, imm32 (B8+r * imm32) for !is64. Both 10/5 bytes. */ -void x64_emit_load_imm(MCEmitter *mc, int is64, u32 dst, i64 imm) { +void x64_emit_load_imm(MCEmitter* mc, int is64, u32 dst, i64 imm) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 buf[16]; - u32 n = x64_mov_ri_pack( - (X64MovRI){.is64 = is64, .dst = dst, .imm = imm}, buf); + u32 n = + x64_mov_ri_pack((X64MovRI){.is64 = is64, .dst = dst, .imm = imm}, buf); mc->emit_bytes(mc, buf, n); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } /* Two-operand ALU r/m, r. op picks ADD(01)/SUB(29)/AND(21)/OR(09)/XOR(31)/ * CMP(39)/MOV(89)/TEST(85). */ -void emit_alu_rr(MCEmitter *mc, int w, u8 op, u32 dst, u32 src) { +void emit_alu_rr(MCEmitter* mc, int w, u8 op, u32 dst, u32 src) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 buf[16]; - u32 n = x64_alu_rr_pack( - (X64AluRR){.w = w, .op = op, .dst = dst, .src = src}, buf); + u32 n = x64_alu_rr_pack((X64AluRR){.w = w, .op = op, .dst = dst, .src = src}, + buf); mc->emit_bytes(mc, buf, n); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } -void emit_imul_rr(MCEmitter *mc, int w, u32 dst, u32 src) { +void emit_imul_rr(MCEmitter* mc, int w, u32 dst, u32 src) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 buf[16]; - u32 n = x64_imul_rr_pack( - (X64ImulRR){.w = w, .dst = dst, .src = src}, buf); + u32 n = x64_imul_rr_pack((X64ImulRR){.w = w, .dst = dst, .src = src}, buf); mc->emit_bytes(mc, buf, n); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } -void emit_f7_rm(MCEmitter *mc, int w, u32 sub, u32 reg) { +void emit_f7_rm(MCEmitter* mc, int w, u32 sub, u32 reg) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 buf[16]; - u32 n = x64_f7_rm_pack( - (X64F7RM){.w = w, .sub = sub, .reg = reg}, buf); + u32 n = x64_f7_rm_pack((X64F7RM){.w = w, .sub = sub, .reg = reg}, buf); mc->emit_bytes(mc, buf, n); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } -void emit_shift_cl(MCEmitter *mc, int w, u32 sub, u32 reg) { +void emit_shift_cl(MCEmitter* mc, int w, u32 sub, u32 reg) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 buf[16]; - u32 n = x64_shift_cl_pack( - (X64ShiftCL){.w = w, .sub = sub, .reg = reg}, buf); + u32 n = x64_shift_cl_pack((X64ShiftCL){.w = w, .sub = sub, .reg = reg}, buf); mc->emit_bytes(mc, buf, n); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } /* Shift r/m by imm8: opcode C1 /sub ib. sub: SHL=4, SHR=5, SAR=7. */ -void emit_shift_imm(MCEmitter *mc, int w, u32 sub, u32 reg, u8 imm) { +void emit_shift_imm(MCEmitter* mc, int w, u32 sub, u32 reg, u8 imm) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 buf[16]; u32 n = x64_shift_imm_pack( (X64ShiftImm){.w = w, .sub = sub, .reg = reg, .imm = imm}, buf); mc->emit_bytes(mc, buf, n); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } -void emit_cqo_or_cdq(MCEmitter *mc, int w) { +void emit_cqo_or_cdq(MCEmitter* mc, int w) { u8 buf[16]; - u32 n = x64_nullary_pack( - (X64Nullary){.w = w, .opc0 = X64_OPC_CDQ_CQO}, buf); + u32 n = x64_nullary_pack((X64Nullary){.w = w, .opc0 = X64_OPC_CDQ_CQO}, buf); mc->emit_bytes(mc, buf, n); } -void emit_xor_self(MCEmitter *mc, int w, u32 r) { +void emit_xor_self(MCEmitter* mc, int w, u32 r) { emit_alu_rr(mc, w, X64_OPC_ALU_XOR, r, r); } /* cmp r/m, imm8 (0x83 /7). */ -void emit_cmp_imm8(MCEmitter *mc, int w, u32 reg, i8 imm) { +void emit_cmp_imm8(MCEmitter* mc, int w, u32 reg, i8 imm) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 buf[16]; u32 n = x64_alu_imm8_pack( (X64AluRmImm8){.w = w, .sub = X64_ALU_SUB_CMP, .reg = reg, .imm = imm}, buf); mc->emit_bytes(mc, buf, n); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } /* ALU r/m, imm8: opcode 0x83 /sub ib (sign-extended). sub: ADD=0, * OR=1, ADC=2, SBB=3, AND=4, SUB=5, XOR=6, CMP=7. */ -void emit_alu_imm8(MCEmitter *mc, int w, u32 sub, u32 reg, i8 imm) { +void emit_alu_imm8(MCEmitter* mc, int w, u32 sub, u32 reg, i8 imm) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 buf[16]; u32 n = x64_alu_imm8_pack( (X64AluRmImm8){.w = w, .sub = sub, .reg = reg, .imm = imm}, buf); mc->emit_bytes(mc, buf, n); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } /* ALU r/m, imm32: opcode 0x81 /sub id (sign-extended for w=1). */ -void emit_alu_imm32(MCEmitter *mc, int w, u32 sub, u32 reg, i32 imm) { +void emit_alu_imm32(MCEmitter* mc, int w, u32 sub, u32 reg, i32 imm) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 buf[16]; u32 n = x64_alu_imm32_pack( (X64AluRmImm32){.w = w, .sub = sub, .reg = reg, .imm = imm}, buf); mc->emit_bytes(mc, buf, n); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } /* IMUL r, r/m, imm: 0x6B /r ib (imm8 sext) or 0x69 /r id (imm32 sext). * Both forms write the result back to the same `dst` register so the * caller doesn't need an explicit copy beforehand — unlike the ALU * forms which read-modify-write a single operand. */ -void emit_imul_imm8(MCEmitter *mc, int w, u32 dst, u32 src, i8 imm) { +void emit_imul_imm8(MCEmitter* mc, int w, u32 dst, u32 src, i8 imm) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 buf[16]; u32 n = x64_imul_rri_pack( (X64ImulRRI){.w = w, .imm32 = 0, .dst = dst, .src = src, .imm = imm}, buf); mc->emit_bytes(mc, buf, n); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } -void emit_imul_imm32(MCEmitter *mc, int w, u32 dst, u32 src, i32 imm) { +void emit_imul_imm32(MCEmitter* mc, int w, u32 dst, u32 src, i32 imm) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 buf[16]; u32 n = x64_imul_rri_pack( (X64ImulRRI){.w = w, .imm32 = 1, .dst = dst, .src = src, .imm = imm}, buf); mc->emit_bytes(mc, buf, n); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } /* Width predicate: does `imm` fit in an i8 (used by the 0x83/0x6B @@ -469,33 +459,33 @@ int imm_fits_i32(i64 imm) { return imm >= -2147483648LL && imm <= 2147483647LL; } -void emit_test_self(MCEmitter *mc, int w, u32 reg) { +void emit_test_self(MCEmitter* mc, int w, u32 reg) { emit_alu_rr(mc, w, X64_OPC_ALU_TEST, reg, reg); } -void emit_setcc(MCEmitter *mc, u32 cc, u32 reg) { +void emit_setcc(MCEmitter* mc, u32 cc, u32 reg) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 buf[16]; u32 n = x64_setcc_pack((X64Setcc){.cc = cc, .reg = reg}, buf); mc->emit_bytes(mc, buf, n); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } -void emit_movzx_r32_r8(MCEmitter *mc, u32 dst, u32 src) { +void emit_movzx_r32_r8(MCEmitter* mc, u32 dst, u32 src) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 buf[16]; - u32 n = x64_movzx_rr_pack( - (X64MovzxRR){.w = 0, .opc1 = X64_OPC_MOVZX_B, .force_rex = 1, - .dst = dst, .src = src}, - buf); + u32 n = x64_movzx_rr_pack((X64MovzxRR){.w = 0, + .opc1 = X64_OPC_MOVZX_B, + .force_rex = 1, + .dst = dst, + .src = src}, + buf); mc->emit_bytes(mc, buf, n); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } /* movzx/movsx r→r. src_size is source byte width. */ -void emit_extend_rr(MCEmitter *mc, int w, int signed_ext, u32 src_size, u32 dst, +void emit_extend_rr(MCEmitter* mc, int w, int signed_ext, u32 src_size, u32 dst, u32 src) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 buf[16]; @@ -512,13 +502,17 @@ void emit_extend_rr(MCEmitter *mc, int w, int signed_ext, u32 src_size, u32 dst, n = x64_movzx_rr_pack( (X64MovzxRR){.w = w, .opc1 = signed_ext ? X64_OPC_MOVSX_B : X64_OPC_MOVZX_B, - .force_rex = 1, .dst = dst, .src = src}, + .force_rex = 1, + .dst = dst, + .src = src}, buf); } else if (src_size == 2) { n = x64_movzx_rr_pack( (X64MovzxRR){.w = w, .opc1 = signed_ext ? X64_OPC_MOVSX_W : X64_OPC_MOVZX_W, - .force_rex = 0, .dst = dst, .src = src}, + .force_rex = 0, + .dst = dst, + .src = src}, buf); } else { /* No extension to perform (src already at least as wide as dst, e.g. @@ -527,56 +521,56 @@ void emit_extend_rr(MCEmitter *mc, int w, int signed_ext, u32 src_size, u32 dst, if (dst != src) emit_mov_rr(mc, w, dst, src); } if (n) mc->emit_bytes(mc, buf, n); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } -void emit_ret(MCEmitter *mc) { +void emit_ret(MCEmitter* mc) { u8 op = X64_OPC_RET; mc->emit_bytes(mc, &op, 1); } -static void emit_leave(MCEmitter *mc) { +static void emit_leave(MCEmitter* mc) { u8 op = X64_OPC_LEAVE; mc->emit_bytes(mc, &op, 1); } /* ---- SSE scalar FP encoders ---- */ -void emit_sse_rr(MCEmitter *mc, u8 prefix, u8 opcode, u32 dst, u32 src) { +void emit_sse_rr(MCEmitter* mc, u8 prefix, u8 opcode, u32 dst, u32 src) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 buf[16]; u32 n = x64_sse_rr_pack( - (X64SseRR){.prefix = prefix, .opcode = opcode, .w = 0, .dst = dst, - .src = src}, + (X64SseRR){ + .prefix = prefix, .opcode = opcode, .w = 0, .dst = dst, .src = src}, buf); mc->emit_bytes(mc, buf, n); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } -void emit_sse_load(MCEmitter *mc, u8 prefix, u8 opcode, u32 dst, u32 base, +void emit_sse_load(MCEmitter* mc, u8 prefix, u8 opcode, u32 dst, u32 base, i32 disp) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 buf[16]; - u32 n = x64_sse_mem_pack( - (X64SseMem){.prefix = prefix, .opcode = opcode, .reg = dst, - .base = base, .disp = disp}, - buf); + u32 n = x64_sse_mem_pack((X64SseMem){.prefix = prefix, + .opcode = opcode, + .reg = dst, + .base = base, + .disp = disp}, + buf); mc->emit_bytes(mc, buf, n); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } -void emit_sse_store(MCEmitter *mc, u8 prefix, u8 opcode, u32 src, u32 base, +void emit_sse_store(MCEmitter* mc, u8 prefix, u8 opcode, u32 src, u32 base, i32 disp) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 buf[16]; - u32 n = x64_sse_mem_pack( - (X64SseMem){.prefix = prefix, .opcode = opcode, .reg = src, - .base = base, .disp = disp}, - buf); + u32 n = x64_sse_mem_pack((X64SseMem){.prefix = prefix, + .opcode = opcode, + .reg = src, + .base = base, + .disp = disp}, + buf); mc->emit_bytes(mc, buf, n); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } -void emit_sse_load_idx(MCEmitter *mc, u8 prefix, u8 opcode, u32 dst, u32 base, +void emit_sse_load_idx(MCEmitter* mc, u8 prefix, u8 opcode, u32 dst, u32 base, u32 index, u32 log2_scale, i32 disp) { if (index == REG_NONE) { emit_sse_load(mc, prefix, opcode, dst, base, disp); @@ -587,7 +581,7 @@ void emit_sse_load_idx(MCEmitter *mc, u8 prefix, u8 opcode, u32 dst, u32 base, log2_scale, disp); if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } -void emit_sse_store_idx(MCEmitter *mc, u8 prefix, u8 opcode, u32 src, u32 base, +void emit_sse_store_idx(MCEmitter* mc, u8 prefix, u8 opcode, u32 src, u32 base, u32 index, u32 log2_scale, i32 disp) { if (index == REG_NONE) { emit_sse_store(mc, prefix, opcode, src, base, disp); @@ -598,17 +592,16 @@ void emit_sse_store_idx(MCEmitter *mc, u8 prefix, u8 opcode, u32 src, u32 base, log2_scale, disp); if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } -void emit_sse_rr_w(MCEmitter *mc, u8 prefix, u8 opcode, int w, u32 dst, +void emit_sse_rr_w(MCEmitter* mc, u8 prefix, u8 opcode, int w, u32 dst, u32 src) { u32 ofs = obj_pos(mc->obj, mc->section_id); u8 buf[16]; u32 n = x64_sse_rr_pack( - (X64SseRR){.prefix = prefix, .opcode = opcode, .w = w, .dst = dst, - .src = src}, + (X64SseRR){ + .prefix = prefix, .opcode = opcode, .w = w, .dst = dst, .src = src}, buf); mc->emit_bytes(mc, buf, n); - if (mc->debug) - debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); + if (mc->debug) debug_emit_row(mc->debug, mc->section_id, ofs, mc->loc); } /* ============================================================ @@ -640,7 +633,7 @@ static u32 count_x64_cs_fp(u32 mask, u64 cs_fp_mask) { return n; } -static u32 x64_planned_prologue_bytes(const XImpl *a) { +static u32 x64_planned_prologue_bytes(const XImpl* a) { u32 n = X64_PROLOGUE_BASE_BYTES; if (a->has_sret) n += X64_PROLOGUE_SRET_BYTES; n += count_x64_cs_int(a->planned_cs_int_mask, a->abi->cs_int_mask) * @@ -654,9 +647,9 @@ static u32 x64_planned_prologue_bytes(const XImpl *a) { return n ? n : 1u; } -static void x_func_begin_init(CGTarget *t, const CGFuncDesc *fd) { - XImpl *a = impl_of(t); - MCEmitter *mc = t->mc; +static void x_func_begin_init(CGTarget* t, const CGFuncDesc* fd) { + XImpl* a = impl_of(t); + MCEmitter* mc = t->mc; mc->set_section(mc, fd->text_section_id); mc->emit_align(mc, 16, 0x90); @@ -677,11 +670,10 @@ static void x_func_begin_init(CGTarget *t, const CGFuncDesc *fd) { a->max_outgoing = 0; a->used_cs_int_mask = a->has_planned_regs ? a->planned_cs_int_mask : 0; a->used_cs_fp_mask = a->has_planned_regs ? a->planned_cs_fp_mask : 0; - a->prologue_nbytes = - a->has_planned_regs - ? x64_planned_prologue_bytes(a) - : (a->abi->shadow_space ? X64_PROLOGUE_BYTES_WIN64 - : X64_PROLOGUE_BYTES); + a->prologue_nbytes = a->has_planned_regs + ? x64_planned_prologue_bytes(a) + : (a->abi->shadow_space ? X64_PROLOGUE_BYTES_WIN64 + : X64_PROLOGUE_BYTES); a->planned_cs_int_mask = 0; a->planned_cs_fp_mask = 0; a->has_planned_regs = 0; @@ -695,8 +687,8 @@ static void x_func_begin_init(CGTarget *t, const CGFuncDesc *fd) { mc->cfi_startproc(mc); } -static void x_add_entry_frame_slots(CGTarget *t) { - XImpl *a = impl_of(t); +static void x_add_entry_frame_slots(CGTarget* t) { + XImpl* a = impl_of(t); /* sret: the first int arg reg at entry holds the destination pointer * (RDI on SysV, RCX on Win64). Spill it to a hidden slot so the body @@ -735,13 +727,13 @@ static void x_add_entry_frame_slots(CGTarget *t) { } } -static void x_emit_variadic_reg_saves(CGTarget *t) { - XImpl *a = impl_of(t); - MCEmitter *mc = t->mc; +static void x_emit_variadic_reg_saves(CGTarget* t) { + XImpl* a = impl_of(t); + MCEmitter* mc = t->mc; if (!a->is_variadic) return; if (a->abi->emit_sysv_vararg_save) { - XSlot *rs = x64_slot_get(a, a->reg_save_slot); + XSlot* rs = x64_slot_get(a, a->reg_save_slot); static const u32 gprs[6] = {X64_RDI, X64_RSI, X64_RDX, X64_RCX, X64_R8, X64_R9}; for (u32 i = 0; i < 6; ++i) { @@ -763,8 +755,8 @@ static void x_emit_variadic_reg_saves(CGTarget *t) { * they're already in the GPR home slot. */ emit_mov_store(mc, 8, X64_RCX, X64_RBP, 16); emit_mov_store(mc, 8, X64_RDX, X64_RBP, 24); - emit_mov_store(mc, 8, X64_R8, X64_RBP, 32); - emit_mov_store(mc, 8, X64_R9, X64_RBP, 40); + emit_mov_store(mc, 8, X64_R8, X64_RBP, 32); + emit_mov_store(mc, 8, X64_R9, X64_RBP, 40); } static u32 align_up_u32(u32 v, u32 a) { return (v + (a - 1u)) & ~(a - 1u); } @@ -780,12 +772,11 @@ static const Reg g_cs_int_order_all[X64_MAX_CS_INT_REGS] = { /* Spill order for Win64 callee-saved XMMs (XMM6..XMM15). */ #define X64_MAX_CS_FP_REGS 10u static const Reg g_cs_fp_order_all[X64_MAX_CS_FP_REGS] = { - X64_XMM6, X64_XMM7, X64_XMM8, X64_XMM0 + 9, - X64_XMM0 + 10, X64_XMM0 + 11, X64_XMM0 + 12, X64_XMM0 + 13, - X64_XMM0 + 14, X64_XMM15, + X64_XMM6, X64_XMM7, X64_XMM8, X64_XMM0 + 9, X64_XMM0 + 10, + X64_XMM0 + 11, X64_XMM0 + 12, X64_XMM0 + 13, X64_XMM0 + 14, X64_XMM15, }; -static u32 x_collect_cs_regs(const XImpl *a, Reg *cs_regs) { +static u32 x_collect_cs_regs(const XImpl* a, Reg* cs_regs) { u32 cs_used = 0; u64 mask = (u64)a->used_cs_int_mask & a->abi->cs_int_mask; mask &= ~(1ull << X64_RBP); @@ -796,7 +787,7 @@ static u32 x_collect_cs_regs(const XImpl *a, Reg *cs_regs) { return cs_used; } -static u32 x_collect_cs_fp_regs(const XImpl *a, Reg *cs_fp_regs) { +static u32 x_collect_cs_fp_regs(const XImpl* a, Reg* cs_fp_regs) { u32 n = 0; u64 mask = (u64)a->used_cs_fp_mask & a->abi->cs_fp_mask; for (u32 i = 0; i < X64_MAX_CS_FP_REGS; ++i) { @@ -814,12 +805,12 @@ static u32 x_collect_cs_fp_regs(const XImpl *a, Reg *cs_fp_regs) { * [rsp] : outgoing args (max_outgoing, 16-aligned) * xmm_base = align_up(cum_off, 16) when any XMM saved, else == cum_off. * Frame size includes the alignment pad so rsp lands at 0 mod 16. */ -static u32 x_xmm_base(const XImpl *a, u32 cs_fp_used) { +static u32 x_xmm_base(const XImpl* a, u32 cs_fp_used) { if (cs_fp_used == 0) return a->cum_off; return align_up_u32(a->cum_off, 16u); } -static u32 x_compute_frame_size(const XImpl *a, u32 cs_used, u32 cs_fp_used) { +static u32 x_compute_frame_size(const XImpl* a, u32 cs_used, u32 cs_fp_used) { u32 xmm_base = x_xmm_base(a, cs_fp_used); u32 cs_size = cs_used * 8u; u32 xmm_size = cs_fp_used * 16u; @@ -832,7 +823,7 @@ static u32 x_compute_frame_size(const XImpl *a, u32 cs_used, u32 cs_fp_used) { * stack-probe helper is provided by mingw's libmingwex / MSVC's CRT; * cfree references it on demand from the prologue and lets the linker * resolve it. */ -static ObjSymId x_chkstk_sym(CGTarget *t) { +static ObjSymId x_chkstk_sym(CGTarget* t) { Sym name = pool_intern_slice(t->c->global, SLICE_LIT("__chkstk")); ObjSymId s = obj_symbol_find(t->obj, name); if (s != 0) return s; @@ -844,11 +835,11 @@ static ObjSymId x_chkstk_sym(CGTarget *t) { * taken, stores the byte offset of the `call __chkstk` disp32 within * `buf` so the caller can emit the matching R_X64_PLT32 reloc. Sets * it to UINT32_MAX otherwise. */ -static u32 x_build_prologue(CGTarget *t, u8 *buf, u32 cap, u32 frame_size, - const Reg *cs_regs, u32 cs_used, - const Reg *cs_fp_regs, u32 cs_fp_used, - u32 *chkstk_disp_pos_out) { - XImpl *a = impl_of(t); +static u32 x_build_prologue(CGTarget* t, u8* buf, u32 cap, u32 frame_size, + const Reg* cs_regs, u32 cs_used, + const Reg* cs_fp_regs, u32 cs_fp_used, + u32* chkstk_disp_pos_out) { + XImpl* a = impl_of(t); u32 wi = 0; if (chkstk_disp_pos_out) *chkstk_disp_pos_out = (u32)-1; @@ -902,7 +893,7 @@ static u32 x_build_prologue(CGTarget *t, u8 *buf, u32 cap, u32 frame_size, * pointer at entry) to the hidden slot. SysV uses RDI; Win64 uses * RCX. */ if (a->has_sret && a->sret_ptr_slot != FRAME_SLOT_NONE) { - XSlot *s = x64_slot_get(a, a->sret_ptr_slot); + XSlot* s = x64_slot_get(a, a->sret_ptr_slot); if (s) { i32 off = -(i32)s->off; u32 sret_reg = a->abi->int_args[0]; @@ -961,25 +952,24 @@ overflow: return 0; } -void x_func_begin(CGTarget *t, const CGFuncDesc *fd) { - XImpl *a = impl_of(t); - MCEmitter *mc = t->mc; +void x_func_begin(CGTarget* t, const CGFuncDesc* fd) { + XImpl* a = impl_of(t); + MCEmitter* mc = t->mc; x_func_begin_init(t, fd); /* Reserve a fixed-size prologue placeholder filled with NOPs. */ a->prologue_pos = mc->pos(mc); - for (u32 i = 0; i < a->prologue_nbytes; ++i) - emit1(mc, 0x90); + for (u32 i = 0; i < a->prologue_nbytes; ++i) emit1(mc, 0x90); x_add_entry_frame_slots(t); x_emit_variadic_reg_saves(t); } -void x_func_begin_known_frame(CGTarget *t, const CGFuncDesc *fd, - const CGKnownFrameDesc *frame, - FrameSlot *out_slots) { - XImpl *a = impl_of(t); +void x_func_begin_known_frame(CGTarget* t, const CGFuncDesc* fd, + const CGKnownFrameDesc* frame, + FrameSlot* out_slots) { + XImpl* a = impl_of(t); Reg cs_regs[X64_MAX_CS_INT_REGS]; Reg cs_fp_regs[X64_MAX_CS_FP_REGS]; u8 buf[X64_PROLOGUE_BYTES_WIN64]; @@ -1007,22 +997,22 @@ void x_func_begin_known_frame(CGTarget *t, const CGFuncDesc *fd, u32 frame_size = x_compute_frame_size(a, cs_used, cs_fp_used); a->prologue_pos = t->mc->pos(t->mc); u32 chkstk_disp_pos = (u32)-1; - u32 nbytes = x_build_prologue(t, buf, sizeof buf, frame_size, - cs_regs, cs_used, cs_fp_regs, cs_fp_used, - &chkstk_disp_pos); + u32 nbytes = + x_build_prologue(t, buf, sizeof buf, frame_size, cs_regs, cs_used, + cs_fp_regs, cs_fp_used, &chkstk_disp_pos); t->mc->emit_bytes(t->mc, buf, nbytes); if (chkstk_disp_pos != (u32)-1) { ObjSymId chk = x_chkstk_sym(t); t->mc->emit_reloc_at(t->mc, t->mc->section_id, - a->prologue_pos + chkstk_disp_pos, R_X64_PLT32, - chk, -4, 1, 0); + a->prologue_pos + chkstk_disp_pos, R_X64_PLT32, chk, + -4, 1, 0); } x_emit_variadic_reg_saves(t); } -void x_func_end(CGTarget *t) { - XImpl *a = impl_of(t); - MCEmitter *mc = t->mc; +void x_func_end(CGTarget* t) { + XImpl* a = impl_of(t); + MCEmitter* mc = t->mc; Reg cs_regs[X64_MAX_CS_INT_REGS]; Reg cs_fp_regs[X64_MAX_CS_FP_REGS]; @@ -1064,21 +1054,19 @@ void x_func_end(CGTarget *t) { if (!a->known_frame) { /* Patch prologue placeholder. */ u8 buf[X64_PROLOGUE_BYTES_WIN64]; - u32 prologue_nbytes = a->prologue_nbytes ? a->prologue_nbytes - : X64_PROLOGUE_BYTES; - for (u32 i = 0; i < prologue_nbytes; ++i) - buf[i] = 0x90; + u32 prologue_nbytes = + a->prologue_nbytes ? a->prologue_nbytes : X64_PROLOGUE_BYTES; + for (u32 i = 0; i < prologue_nbytes; ++i) buf[i] = 0x90; u32 chkstk_disp_pos = (u32)-1; (void)x_build_prologue(t, buf, prologue_nbytes, frame_size, cs_regs, - cs_used, cs_fp_regs, cs_fp_used, - &chkstk_disp_pos); + cs_used, cs_fp_regs, cs_fp_used, &chkstk_disp_pos); obj_patch(t->obj, a->fd->text_section_id, a->prologue_pos, buf, prologue_nbytes); if (chkstk_disp_pos != (u32)-1) { ObjSymId chk = x_chkstk_sym(t); mc->emit_reloc_at(mc, a->fd->text_section_id, - a->prologue_pos + chkstk_disp_pos, R_X64_PLT32, - chk, -4, 1, 0); + a->prologue_pos + chkstk_disp_pos, R_X64_PLT32, chk, -4, + 1, 0); } } @@ -1096,8 +1084,7 @@ void x_func_end(CGTarget *t) { dbuf, 4); } -finish: - ; +finish:; /* Define the function symbol. */ u32 end = mc->pos(mc); obj_symbol_define(t->obj, a->fd->sym, a->fd->text_section_id, diff --git a/src/arch/x64/internal.h b/src/arch/x64/internal.h @@ -45,7 +45,7 @@ #define X64_PROLOGUE_CHKSTK_DELTA 6u /* Win64-specific constants. */ -#define X64_WIN64_SHADOW_SPACE 32u /* 4 home slots, 8 B each. */ +#define X64_WIN64_SHADOW_SPACE 32u /* 4 home slots, 8 B each. */ #define X64_WIN64_CHKSTK_THRESHOLD 4096u /* Maximum callee-saved GPRs across all supported ABIs. SysV saves up to @@ -196,8 +196,8 @@ static inline _Noreturn void x_panic(CGTarget* t, const char* what) { extern const Reg g_int_order[6]; extern const Reg g_fp_order[10]; -static inline void x64_abi_direct_reg_need(const ABIArgInfo* ai, - u32* need_int, u32* need_fp) { +static inline void x64_abi_direct_reg_need(const ABIArgInfo* ai, u32* need_int, + u32* need_fp) { *need_int = 0; *need_fp = 0; if (!ai || ai->kind != ABI_ARG_DIRECT) return; diff --git a/src/arch/x64/isa.c b/src/arch/x64/isa.c @@ -111,14 +111,14 @@ const X64InsnDesc x64_insn_table[] = { X64_FMT_MOV_RM_LOAD, X64_ASMFL_W_FROM_REX), /* ---- MOVZX / MOVSX r32, r/m{8,16} ---- */ - ROW("movzbl", X64_PFX_NONE, 2, 0x0F, 0xB6, 0, 0xFF, NO_MODRM, - X64_W_REQ_ANY, X64_FMT_MOVZX_MOVSX, 0), - ROW("movzwl", X64_PFX_NONE, 2, 0x0F, 0xB7, 0, 0xFF, NO_MODRM, - X64_W_REQ_ANY, X64_FMT_MOVZX_MOVSX, 0), - ROW("movsbl", X64_PFX_NONE, 2, 0x0F, 0xBE, 0, 0xFF, NO_MODRM, - X64_W_REQ_ANY, X64_FMT_MOVZX_MOVSX, 0), - ROW("movswl", X64_PFX_NONE, 2, 0x0F, 0xBF, 0, 0xFF, NO_MODRM, - X64_W_REQ_ANY, X64_FMT_MOVZX_MOVSX, 0), + ROW("movzbl", X64_PFX_NONE, 2, 0x0F, 0xB6, 0, 0xFF, NO_MODRM, X64_W_REQ_ANY, + X64_FMT_MOVZX_MOVSX, 0), + ROW("movzwl", X64_PFX_NONE, 2, 0x0F, 0xB7, 0, 0xFF, NO_MODRM, X64_W_REQ_ANY, + X64_FMT_MOVZX_MOVSX, 0), + ROW("movsbl", X64_PFX_NONE, 2, 0x0F, 0xBE, 0, 0xFF, NO_MODRM, X64_W_REQ_ANY, + X64_FMT_MOVZX_MOVSX, 0), + ROW("movswl", X64_PFX_NONE, 2, 0x0F, 0xBF, 0, 0xFF, NO_MODRM, X64_W_REQ_ANY, + X64_FMT_MOVZX_MOVSX, 0), /* ---- MOVSXD r64, r/m32 ---- */ ROW("movslq", X64_PFX_NONE, 1, 0x63, 0, 0, 0xFF, NO_MODRM, X64_W_REQ_1, @@ -260,10 +260,10 @@ const X64InsnDesc x64_insn_table[] = { ROW("movss", X64_PFX_F3, 2, 0x0F, 0x11, 0, 0xFF, NO_MODRM, X64_W_REQ_ANY, X64_FMT_SSE_RR, X64_ASMFL_ALIAS), /* MOVAPS */ - ROW("movaps", X64_PFX_NONE, 2, 0x0F, 0x28, 0, 0xFF, NO_MODRM, - X64_W_REQ_ANY, X64_FMT_SSE_RR, 0), - ROW("movaps", X64_PFX_NONE, 2, 0x0F, 0x29, 0, 0xFF, NO_MODRM, - X64_W_REQ_ANY, X64_FMT_SSE_RR, X64_ASMFL_ALIAS), + ROW("movaps", X64_PFX_NONE, 2, 0x0F, 0x28, 0, 0xFF, NO_MODRM, X64_W_REQ_ANY, + X64_FMT_SSE_RR, 0), + ROW("movaps", X64_PFX_NONE, 2, 0x0F, 0x29, 0, 0xFF, NO_MODRM, X64_W_REQ_ANY, + X64_FMT_SSE_RR, X64_ASMFL_ALIAS), /* ADD/SUB/MUL/DIV — opcodes 58/5C/59/5E (same byte for ss and sd; * prefix picks). */ ROW("addsd", X64_PFX_F2, 2, 0x0F, 0x58, 0, 0xFF, NO_MODRM, X64_W_REQ_ANY, @@ -283,27 +283,27 @@ const X64InsnDesc x64_insn_table[] = { ROW("divss", X64_PFX_F3, 2, 0x0F, 0x5E, 0, 0xFF, NO_MODRM, X64_W_REQ_ANY, X64_FMT_SSE_RR, 0), /* Compare scalar (UCOMISS / UCOMISD) */ - ROW("ucomisd", X64_PFX_66, 2, 0x0F, 0x2E, 0, 0xFF, NO_MODRM, - X64_W_REQ_ANY, X64_FMT_SSE_RR, 0), + ROW("ucomisd", X64_PFX_66, 2, 0x0F, 0x2E, 0, 0xFF, NO_MODRM, X64_W_REQ_ANY, + X64_FMT_SSE_RR, 0), ROW("ucomiss", X64_PFX_NONE, 2, 0x0F, 0x2E, 0, 0xFF, NO_MODRM, X64_W_REQ_ANY, X64_FMT_SSE_RR, 0), /* Conversions touched by FP↔int paths: CVTSI2SS/SD, CVTTSS/SD2SI. */ - ROW("cvtsi2sd", X64_PFX_F2, 2, 0x0F, 0x2A, 0, 0xFF, NO_MODRM, - X64_W_REQ_ANY, X64_FMT_SSE_RR, X64_ASMFL_W_FROM_REX), - ROW("cvtsi2ss", X64_PFX_F3, 2, 0x0F, 0x2A, 0, 0xFF, NO_MODRM, - X64_W_REQ_ANY, X64_FMT_SSE_RR, X64_ASMFL_W_FROM_REX), + ROW("cvtsi2sd", X64_PFX_F2, 2, 0x0F, 0x2A, 0, 0xFF, NO_MODRM, X64_W_REQ_ANY, + X64_FMT_SSE_RR, X64_ASMFL_W_FROM_REX), + ROW("cvtsi2ss", X64_PFX_F3, 2, 0x0F, 0x2A, 0, 0xFF, NO_MODRM, X64_W_REQ_ANY, + X64_FMT_SSE_RR, X64_ASMFL_W_FROM_REX), ROW("cvttsd2si", X64_PFX_F2, 2, 0x0F, 0x2C, 0, 0xFF, NO_MODRM, X64_W_REQ_ANY, X64_FMT_SSE_RR, X64_ASMFL_W_FROM_REX), ROW("cvttss2si", X64_PFX_F3, 2, 0x0F, 0x2C, 0, 0xFF, NO_MODRM, X64_W_REQ_ANY, X64_FMT_SSE_RR, X64_ASMFL_W_FROM_REX), - ROW("cvtsd2ss", X64_PFX_F2, 2, 0x0F, 0x5A, 0, 0xFF, NO_MODRM, - X64_W_REQ_ANY, X64_FMT_SSE_RR, 0), - ROW("cvtss2sd", X64_PFX_F3, 2, 0x0F, 0x5A, 0, 0xFF, NO_MODRM, - X64_W_REQ_ANY, X64_FMT_SSE_RR, 0), + ROW("cvtsd2ss", X64_PFX_F2, 2, 0x0F, 0x5A, 0, 0xFF, NO_MODRM, X64_W_REQ_ANY, + X64_FMT_SSE_RR, 0), + ROW("cvtss2sd", X64_PFX_F3, 2, 0x0F, 0x5A, 0, 0xFF, NO_MODRM, X64_W_REQ_ANY, + X64_FMT_SSE_RR, 0), }; -const u32 x64_insn_table_n = (u32)(sizeof x64_insn_table / - sizeof x64_insn_table[0]); +const u32 x64_insn_table_n = + (u32)(sizeof x64_insn_table / sizeof x64_insn_table[0]); /* ==================================================================== * Prefix decode. @@ -390,8 +390,8 @@ const X64InsnDesc* x64_disasm_find(const u8* bytes, u32 len, #define X64_REG_RIP 16u static const char* g_cc_name[16] = { - "o", "no", "b", "ae", "e", "ne", "be", "a", - "s", "ns", "p", "np", "l", "ge", "le", "g", + "o", "no", "b", "ae", "e", "ne", "be", "a", + "s", "ns", "p", "np", "l", "ge", "le", "g", }; /* AT&T register names by width. Index 0..15 covers RAX..R15. */ @@ -423,8 +423,8 @@ static const char* reg_name(u32 reg, u32 width_bytes, int has_rex) { static const char* xmm_name(u32 reg) { static const char* x[16] = { - "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", - "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15", + "xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7", + "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15", }; return x[reg & 15u]; } @@ -608,8 +608,8 @@ char x64_size_suffix_for(const X64InsnDesc* desc, const X64DecodeCtx* ctx) { /* Decode a ModR/M with reg+r/m. Returns total bytes consumed by the * ModR/M + any SIB/disp. */ typedef struct RegRm { - u32 reg; /* high bit from REX.R */ - u32 rm_low; /* low 3 bits */ + u32 reg; /* high bit from REX.R */ + u32 rm_low; /* low 3 bits */ u32 mod; u32 bytes_after_modrm; /* SIB/disp bytes */ DecodedMem mem; /* valid iff mod != 3 */ @@ -627,8 +627,8 @@ static int read_modrm(const u8* bytes, u32 len, u32 off, X64DecodeCtx ctx, memset(&rr->mem, 0, sizeof rr->mem); return 1; } - u32 used = decode_mem(bytes, len, off + 1u, ctx, rr->mod, rr->rm_low, - &rr->mem); + u32 used = + decode_mem(bytes, len, off + 1u, ctx, rr->mod, rr->rm_low, &rr->mem); if (used == (u32)-1) return 0; rr->bytes_after_modrm = used; return 1; @@ -705,9 +705,8 @@ static u32 print_alu_rr(StrBuf* sb, const X64InsnDesc* d, const u8* bytes, return off + 1u + rr.bytes_after_modrm; } -static u32 print_mov_rm_load(StrBuf* sb, const X64InsnDesc* d, - const u8* bytes, u32 len, - const X64DecodeCtx* ctx) { +static u32 print_mov_rm_load(StrBuf* sb, const X64InsnDesc* d, const u8* bytes, + u32 len, const X64DecodeCtx* ctx) { /* op r, r/m. */ u32 off = ctx->opc_off + d->opc_len; RegRm rr; @@ -720,9 +719,8 @@ static u32 print_mov_rm_load(StrBuf* sb, const X64InsnDesc* d, return off + 1u + rr.bytes_after_modrm; } -static u32 print_movzx_movsx(StrBuf* sb, const X64InsnDesc* d, - const u8* bytes, u32 len, - const X64DecodeCtx* ctx) { +static u32 print_movzx_movsx(StrBuf* sb, const X64InsnDesc* d, const u8* bytes, + u32 len, const X64DecodeCtx* ctx) { u32 off = ctx->opc_off + d->opc_len; RegRm rr; if (!read_modrm(bytes, len, off, *ctx, &rr)) return 0; @@ -975,9 +973,8 @@ static u32 print_xchg_mem(StrBuf* sb, const X64InsnDesc* d, const u8* bytes, return off + 1u + rr.bytes_after_modrm; } -static u32 print_cmpxchg_mem(StrBuf* sb, const X64InsnDesc* d, - const u8* bytes, u32 len, - const X64DecodeCtx* ctx) { +static u32 print_cmpxchg_mem(StrBuf* sb, const X64InsnDesc* d, const u8* bytes, + u32 len, const X64DecodeCtx* ctx) { /* CMPXCHG r/m, r — implicit RAX is the comparand; not shown. */ u32 off = ctx->opc_off + d->opc_len; RegRm rr; @@ -1050,7 +1047,7 @@ u32 x64_print_operands(StrBuf* sb, const X64InsnDesc* d, const u8* bytes, case X64_FMT_BS: return print_bs(sb, d, bytes, len, ctx); case X64_FMT_POPCNT: - return print_bs(sb, d, bytes, len, ctx); /* same shape */ + return print_bs(sb, d, bytes, len, ctx); /* same shape */ case X64_FMT_SSE_RR: case X64_FMT_SSE_LOAD: case X64_FMT_SSE_STORE: @@ -1069,6 +1066,4 @@ u32 x64_print_operands(StrBuf* sb, const X64InsnDesc* d, const u8* bytes, /* Resolve the condition nibble for Jcc/SETcc/CMOVcc to its AT&T mnemonic * suffix. Used by the disassembler to spell j → "je", set → "sete", etc. */ -const char* x64_cc_name(u8 cc) { - return g_cc_name[cc & 0xFu]; -} +const char* x64_cc_name(u8 cc) { return g_cc_name[cc & 0xFu]; } diff --git a/src/arch/x64/isa.h b/src/arch/x64/isa.h @@ -43,8 +43,8 @@ enum { X64_RBP = 5, X64_RSI = 6, X64_RDI = 7, - X64_R8 = 8, - X64_R9 = 9, + X64_R8 = 8, + X64_R9 = 9, X64_R10 = 10, X64_R11 = 11, X64_R12 = 12, @@ -69,30 +69,30 @@ enum { /* Condition codes for Jcc / SETcc / CMOVcc. Encoded in the low nibble. */ enum { - X64_CC_O = 0x0, - X64_CC_NO = 0x1, - X64_CC_B = 0x2, /* below / CF=1 → CMP_LT_U */ - X64_CC_AE = 0x3, /* above-or-equal / CF=0 → CMP_GE_U */ - X64_CC_E = 0x4, /* equal / ZF=1 → CMP_EQ */ - X64_CC_NE = 0x5, /* → CMP_NE */ - X64_CC_BE = 0x6, /* below-or-equal / CF=1 or ZF=1 → CMP_LE_U */ - X64_CC_A = 0x7, /* above / CF=0 and ZF=0 → CMP_GT_U */ - X64_CC_S = 0x8, - X64_CC_NS = 0x9, - X64_CC_P = 0xA, - X64_CC_NP = 0xB, - X64_CC_L = 0xC, /* less (signed) / SF!=OF → CMP_LT_S */ - X64_CC_GE = 0xD, /* → CMP_GE_S */ - X64_CC_LE = 0xE, /* less-or-equal (signed) → CMP_LE_S */ - X64_CC_G = 0xF, /* greater → CMP_GT_S */ + X64_CC_O = 0x0, + X64_CC_NO = 0x1, + X64_CC_B = 0x2, /* below / CF=1 → CMP_LT_U */ + X64_CC_AE = 0x3, /* above-or-equal / CF=0 → CMP_GE_U */ + X64_CC_E = 0x4, /* equal / ZF=1 → CMP_EQ */ + X64_CC_NE = 0x5, /* → CMP_NE */ + X64_CC_BE = 0x6, /* below-or-equal / CF=1 or ZF=1 → CMP_LE_U */ + X64_CC_A = 0x7, /* above / CF=0 and ZF=0 → CMP_GT_U */ + X64_CC_S = 0x8, + X64_CC_NS = 0x9, + X64_CC_P = 0xA, + X64_CC_NP = 0xB, + X64_CC_L = 0xC, /* less (signed) / SF!=OF → CMP_LT_S */ + X64_CC_GE = 0xD, /* → CMP_GE_S */ + X64_CC_LE = 0xE, /* less-or-equal (signed) → CMP_LE_S */ + X64_CC_G = 0xF, /* greater → CMP_GT_S */ }; /* REX prefix is 0x40 | W<<3 | R<<2 | X<<1 | B. */ #define X64_REX_BASE 0x40u -#define X64_REX_W 0x08u -#define X64_REX_R 0x04u -#define X64_REX_X 0x02u -#define X64_REX_B 0x01u +#define X64_REX_W 0x08u +#define X64_REX_R 0x04u +#define X64_REX_X 0x02u +#define X64_REX_B 0x01u /* ---- Branch / NOP encoding constants ---- * @@ -102,24 +102,24 @@ enum { /* JMP r/m64 — opcode FF /4. ModR/M for the RIP+disp32 form is * mod=00, reg=/4 (JMP m64), r/m=101 → 0x25. */ -#define X64_OP_JMP_RM64 0xFFu -#define X64_MODRM_JMP_RIPREL 0x25u +#define X64_OP_JMP_RM64 0xFFu +#define X64_MODRM_JMP_RIPREL 0x25u /* Single-byte NOP. */ -#define X64_NOP1 0x90u +#define X64_NOP1 0x90u /* Intel multi-byte ("long") NOP forms. The 6-byte form is the * canonical IPLT-stub tail pad (NOPW 0(%rax,%rax,1)). */ -#define X64_NOP6_BYTE0 0x66u -#define X64_NOP6_BYTE1 0x0Fu -#define X64_NOP6_BYTE2 0x1Fu -#define X64_NOP6_BYTE3 0x44u -#define X64_NOP6_BYTE4 0x00u -#define X64_NOP6_BYTE5 0x00u +#define X64_NOP6_BYTE0 0x66u +#define X64_NOP6_BYTE1 0x0Fu +#define X64_NOP6_BYTE2 0x1Fu +#define X64_NOP6_BYTE3 0x44u +#define X64_NOP6_BYTE4 0x00u +#define X64_NOP6_BYTE5 0x00u /* Sizes of the encoded forms above. */ -#define X64_JMP_RIPREL_SIZE 6u -#define X64_NOP6_SIZE 6u +#define X64_JMP_RIPREL_SIZE 6u +#define X64_NOP6_SIZE 6u /* Write a 6-byte `jmp [rip + disp32]` (FF 25 disp32) at dst. */ static inline void x64_write_jmp_riprel(u8* dst, i32 disp32) { @@ -153,20 +153,20 @@ static inline void x64_write_nop6(u8* dst) { * ==================================================================== */ #define X64_PFX_NONE 0u -#define X64_PFX_66 0x66u /* operand-size override (16-bit) */ -#define X64_PFX_F2 0xF2u /* SSE scalar double / REPNE */ -#define X64_PFX_F3 0xF3u /* SSE scalar single / REP */ +#define X64_PFX_66 0x66u /* operand-size override (16-bit) */ +#define X64_PFX_F2 0xF2u /* SSE scalar double / REPNE */ +#define X64_PFX_F3 0xF3u /* SSE scalar single / REP */ #define X64_W_REQ_ANY 0u /* row matches either REX.W value */ -#define X64_W_REQ_1 1u /* row requires REX.W = 1 (64-bit form) */ -#define X64_W_REQ_0 2u /* row requires REX.W = 0 (force 32-bit form) */ +#define X64_W_REQ_1 1u /* row requires REX.W = 1 (64-bit form) */ +#define X64_W_REQ_0 2u /* row requires REX.W = 0 (force 32-bit form) */ typedef struct X64DecodeCtx { - u8 leg_pfx; /* 0 / 0x66 / 0xF2 / 0xF3 (last seen wins) */ + u8 leg_pfx; /* 0 / 0x66 / 0xF2 / 0xF3 (last seen wins) */ u8 has_lock; u8 has_rex; u8 rex_w, rex_r, rex_x, rex_b; - u32 opc_off; /* offset of first opcode byte inside the instruction */ + u32 opc_off; /* offset of first opcode byte inside the instruction */ } X64DecodeCtx; /* Walk legacy prefix bytes (0x66 / 0xF2 / 0xF3 / 0xF0 LOCK) followed by an @@ -182,24 +182,24 @@ u32 x64_decode_prefixes(const u8* bytes, u32 len, X64DecodeCtx* ctx); * still spell their own opcode bytes inline). */ /* ALU r/m, r — opcode picks the operation. */ -#define X64_OPC_ALU_ADD 0x01u -#define X64_OPC_ALU_OR 0x09u -#define X64_OPC_ALU_AND 0x21u -#define X64_OPC_ALU_SUB 0x29u -#define X64_OPC_ALU_XOR 0x31u -#define X64_OPC_ALU_CMP 0x39u +#define X64_OPC_ALU_ADD 0x01u +#define X64_OPC_ALU_OR 0x09u +#define X64_OPC_ALU_AND 0x21u +#define X64_OPC_ALU_SUB 0x29u +#define X64_OPC_ALU_XOR 0x31u +#define X64_OPC_ALU_CMP 0x39u #define X64_OPC_ALU_TEST 0x85u #define X64_OPC_MOV_RM_R 0x89u /* MOV r/m, r */ #define X64_OPC_MOV_RM_R8 0x88u /* MOV r/m8, r8 */ #define X64_OPC_MOV_R_RM 0x8Bu /* MOV r, r/m */ -#define X64_OPC_LEA 0x8Du -#define X64_OPC_MOVSXD 0x63u +#define X64_OPC_LEA 0x8Du +#define X64_OPC_MOVSXD 0x63u /* ALU r/m, imm — /sub picks op. */ -#define X64_OPC_ALU_IMM8 0x83u +#define X64_OPC_ALU_IMM8 0x83u #define X64_OPC_ALU_IMM32 0x81u #define X64_ALU_SUB_ADD 0u -#define X64_ALU_SUB_OR 1u +#define X64_ALU_SUB_OR 1u #define X64_ALU_SUB_AND 4u #define X64_ALU_SUB_SUB 5u #define X64_ALU_SUB_XOR 6u @@ -209,22 +209,22 @@ u32 x64_decode_prefixes(const u8* bytes, u32 len, X64DecodeCtx* ctx); #define X64_OPC_MOV_RI 0xB8u /* IMUL r, r/m (two-byte) and IMUL r, r/m, imm. */ -#define X64_OPC_IMUL_2B 0xAFu /* preceded by 0x0F */ +#define X64_OPC_IMUL_2B 0xAFu /* preceded by 0x0F */ #define X64_OPC_IMUL_IMM8 0x6Bu #define X64_OPC_IMUL_IMM32 0x69u /* F7 /sub family. */ #define X64_OPC_F7 0xF7u -#define X64_F7_SUB_NOT 2u -#define X64_F7_SUB_NEG 3u -#define X64_F7_SUB_MUL 4u +#define X64_F7_SUB_NOT 2u +#define X64_F7_SUB_NEG 3u +#define X64_F7_SUB_MUL 4u #define X64_F7_SUB_IMUL 5u -#define X64_F7_SUB_DIV 6u +#define X64_F7_SUB_DIV 6u #define X64_F7_SUB_IDIV 7u /* Shifts. */ #define X64_OPC_SHIFT_IMM 0xC1u -#define X64_OPC_SHIFT_CL 0xD3u +#define X64_OPC_SHIFT_CL 0xD3u #define X64_SHIFT_SUB_SHL 4u #define X64_SHIFT_SUB_SHR 5u #define X64_SHIFT_SUB_SAR 7u @@ -240,19 +240,19 @@ u32 x64_decode_prefixes(const u8* bytes, u32 len, X64DecodeCtx* ctx); #define X64_OPC_CMOVCC_BASE 0x40u /* Branches. */ -#define X64_OPC_JMP_REL32 0xE9u -#define X64_OPC_CALL_REL32 0xE8u -#define X64_OPC_JCC_BASE 0x80u /* preceded by 0x0F, low nibble = cc */ +#define X64_OPC_JMP_REL32 0xE9u +#define X64_OPC_CALL_REL32 0xE8u +#define X64_OPC_JCC_BASE 0x80u /* preceded by 0x0F, low nibble = cc */ /* Stack. */ #define X64_OPC_PUSH_R 0x50u -#define X64_OPC_POP_R 0x58u +#define X64_OPC_POP_R 0x58u /* Misc. */ -#define X64_OPC_RET 0xC3u -#define X64_OPC_LEAVE 0xC9u -#define X64_OPC_CDQ_CQO 0x99u -#define X64_OPC_TWOBYTE 0x0Fu +#define X64_OPC_RET 0xC3u +#define X64_OPC_LEAVE 0xC9u +#define X64_OPC_CDQ_CQO 0x99u +#define X64_OPC_TWOBYTE 0x0Fu /* 0x66 operand-size override, used to force 16-bit forms. */ #define X64_OPSIZE_PFX 0x66u @@ -264,62 +264,63 @@ u32 x64_decode_prefixes(const u8* bytes, u32 len, X64DecodeCtx* ctx); * ==================================================================== */ typedef enum X64Format { - X64_FMT_NULLARY, /* no operands: RET, NOP, UD2, LEAVE, CDQ/CQO */ - X64_FMT_NOP_MULTI, /* multi-byte NOP family (66 0F 1F ...) */ - X64_FMT_PUSH_POP, /* 50+rd / 58+rd — register in low 3 bits */ - X64_FMT_MOV_RI, /* B8+rd imm{32,64} — width via REX.W */ - X64_FMT_ALU_RR, /* op r/m, r — ADD/OR/AND/SUB/XOR/CMP/MOV/TEST */ - X64_FMT_MOV_RM_LOAD, /* 8B /r — MOV r, r/m (also LEA via 8D /r) */ - X64_FMT_MOVZX_MOVSX, /* 0F B6/B7/BE/BF /r — width-extending loads */ - X64_FMT_MOVSXD, /* REX.W 63 /r — MOVSXD r64, r/m32 */ - X64_FMT_ALU_RM_IMM8, /* 83 /sub ib — ADD/OR/AND/SUB/XOR/CMP r/m, imm8 */ - X64_FMT_ALU_RM_IMM32, /* 81 /sub id — same family, imm32 */ - X64_FMT_IMUL_RR, /* 0F AF /r — IMUL r, r/m */ - X64_FMT_IMUL_RRI, /* 69/6B /r i{8,32} — IMUL r, r/m, imm */ - X64_FMT_F7_RM, /* F7 /sub — NOT/NEG/MUL/IMUL/DIV/IDIV */ - X64_FMT_SHIFT_IMM, /* C1 /sub ib — SHL/SHR/SAR r/m, imm8 */ - X64_FMT_SHIFT_CL, /* D3 /sub — SHL/SHR/SAR r/m, %cl */ - X64_FMT_JCC_REL32, /* 0F 8x rel32 — Jcc near */ - X64_FMT_JMP_REL32, /* E9 rel32 */ - X64_FMT_CALL_REL32, /* E8 rel32 */ - X64_FMT_BR_RM, /* FF /2 or /4 — call/jmp indirect r/m */ - X64_FMT_SETCC_RM, /* 0F 9x /0 r/m8 — SETcc */ - X64_FMT_CMOVCC_RR, /* 0F 4x /r — CMOVcc r, r/m */ - X64_FMT_SSE_RR, /* {F2|F3|66}? 0F xx /r — scalar FP reg-reg */ - X64_FMT_SSE_LOAD, /* same, dst <- [base+disp] */ - X64_FMT_SSE_STORE, /* same, [base+disp] <- src */ - X64_FMT_BSWAP, /* 0F C8+rd */ - X64_FMT_BS, /* 0F BC/BD /r — BSF/BSR */ - X64_FMT_POPCNT, /* F3 0F B8 /r */ - X64_FMT_XADD_MEM, /* LOCK 0F C1 /r — XADD m, r */ - X64_FMT_XCHG_MEM, /* 87 /r — XCHG r, m (LOCK implicit on mem dst) */ - X64_FMT_CMPXCHG_MEM, /* LOCK 0F B1 /r — CMPXCHG m, r */ - X64_FMT_RAW_BYTE, /* sentinel: render as `.byte 0xNN` (no match) */ + X64_FMT_NULLARY, /* no operands: RET, NOP, UD2, LEAVE, CDQ/CQO */ + X64_FMT_NOP_MULTI, /* multi-byte NOP family (66 0F 1F ...) */ + X64_FMT_PUSH_POP, /* 50+rd / 58+rd — register in low 3 bits */ + X64_FMT_MOV_RI, /* B8+rd imm{32,64} — width via REX.W */ + X64_FMT_ALU_RR, /* op r/m, r — ADD/OR/AND/SUB/XOR/CMP/MOV/TEST */ + X64_FMT_MOV_RM_LOAD, /* 8B /r — MOV r, r/m (also LEA via 8D /r) */ + X64_FMT_MOVZX_MOVSX, /* 0F B6/B7/BE/BF /r — width-extending loads */ + X64_FMT_MOVSXD, /* REX.W 63 /r — MOVSXD r64, r/m32 */ + X64_FMT_ALU_RM_IMM8, /* 83 /sub ib — ADD/OR/AND/SUB/XOR/CMP r/m, imm8 */ + X64_FMT_ALU_RM_IMM32, /* 81 /sub id — same family, imm32 */ + X64_FMT_IMUL_RR, /* 0F AF /r — IMUL r, r/m */ + X64_FMT_IMUL_RRI, /* 69/6B /r i{8,32} — IMUL r, r/m, imm */ + X64_FMT_F7_RM, /* F7 /sub — NOT/NEG/MUL/IMUL/DIV/IDIV */ + X64_FMT_SHIFT_IMM, /* C1 /sub ib — SHL/SHR/SAR r/m, imm8 */ + X64_FMT_SHIFT_CL, /* D3 /sub — SHL/SHR/SAR r/m, %cl */ + X64_FMT_JCC_REL32, /* 0F 8x rel32 — Jcc near */ + X64_FMT_JMP_REL32, /* E9 rel32 */ + X64_FMT_CALL_REL32, /* E8 rel32 */ + X64_FMT_BR_RM, /* FF /2 or /4 — call/jmp indirect r/m */ + X64_FMT_SETCC_RM, /* 0F 9x /0 r/m8 — SETcc */ + X64_FMT_CMOVCC_RR, /* 0F 4x /r — CMOVcc r, r/m */ + X64_FMT_SSE_RR, /* {F2|F3|66}? 0F xx /r — scalar FP reg-reg */ + X64_FMT_SSE_LOAD, /* same, dst <- [base+disp] */ + X64_FMT_SSE_STORE, /* same, [base+disp] <- src */ + X64_FMT_BSWAP, /* 0F C8+rd */ + X64_FMT_BS, /* 0F BC/BD /r — BSF/BSR */ + X64_FMT_POPCNT, /* F3 0F B8 /r */ + X64_FMT_XADD_MEM, /* LOCK 0F C1 /r — XADD m, r */ + X64_FMT_XCHG_MEM, /* 87 /r — XCHG r, m (LOCK implicit on mem dst) */ + X64_FMT_CMPXCHG_MEM, /* LOCK 0F B1 /r — CMPXCHG m, r */ + X64_FMT_RAW_BYTE, /* sentinel: render as `.byte 0xNN` (no match) */ } X64Format; -#define X64_ASMFL_ALIAS 0x01u /* row is an alias spelling (prefer-on-decode) */ +#define X64_ASMFL_ALIAS 0x01u /* row is an alias spelling (prefer-on-decode) \ + */ #define X64_ASMFL_W_FROM_REX 0x02u /* fmt picks width from ctx->rex_w */ -#define X64_ASMFL_FORCE_W64 0x04u /* fmt always 64-bit regardless of REX.W */ -#define X64_ASMFL_BYTE 0x08u /* fixed-byte operand (movb, setcc) */ -#define X64_ASMFL_W16 0x10u /* fixed 16-bit (via 0x66 prefix override) */ +#define X64_ASMFL_FORCE_W64 0x04u /* fmt always 64-bit regardless of REX.W */ +#define X64_ASMFL_BYTE 0x08u /* fixed-byte operand (movb, setcc) */ +#define X64_ASMFL_W16 0x10u /* fixed 16-bit (via 0x66 prefix override) */ /* ==================================================================== * Descriptor table row. * ==================================================================== */ typedef struct X64InsnDesc { - Slice mnemonic; /* AT&T mnemonic without size suffix; printer adds - a size letter (b/w/l/q) based on fmt + ctx. */ - u8 leg_pfx; /* X64_PFX_NONE / 0x66 / 0xF2 / 0xF3 */ - u8 opc_len; /* 1..3 */ - u8 opc[3]; /* opcode bytes */ - u8 opc_last_mask; /* 0xFF for exact match on opc[opc_len-1]; - 0xF8 for embed-reg in low 3 bits; - 0xF0 for Jcc / SETcc / CMOVcc condition nibble */ - u8 modrm_reg; /* 0..7 if /digit, 0xFF otherwise */ - u8 rex_w_req; /* X64_W_REQ_* */ - u8 fmt; /* X64Format */ - u8 flags; /* X64_ASMFL_* */ + Slice mnemonic; /* AT&T mnemonic without size suffix; printer adds + a size letter (b/w/l/q) based on fmt + ctx. */ + u8 leg_pfx; /* X64_PFX_NONE / 0x66 / 0xF2 / 0xF3 */ + u8 opc_len; /* 1..3 */ + u8 opc[3]; /* opcode bytes */ + u8 opc_last_mask; /* 0xFF for exact match on opc[opc_len-1]; + 0xF8 for embed-reg in low 3 bits; + 0xF0 for Jcc / SETcc / CMOVcc condition nibble */ + u8 modrm_reg; /* 0..7 if /digit, 0xFF otherwise */ + u8 rex_w_req; /* X64_W_REQ_* */ + u8 fmt; /* X64Format */ + u8 flags; /* X64_ASMFL_* */ } X64InsnDesc; extern const X64InsnDesc x64_insn_table[]; @@ -329,8 +330,7 @@ extern const u32 x64_insn_table_n; * starts. Returns the matching descriptor, or NULL on no match (caller * should emit a `.byte` fallback). On success, opc_off is unchanged; * the caller can derive opc_end as opc_off + desc->opc_len. */ -const X64InsnDesc* x64_disasm_find(const u8* bytes, u32 len, - X64DecodeCtx* ctx); +const X64InsnDesc* x64_disasm_find(const u8* bytes, u32 len, X64DecodeCtx* ctx); /* Render operand text for a matched descriptor into `sb` and return the * total instruction length in bytes (from bytes[0], including any @@ -480,10 +480,9 @@ static inline u32 x64_pack_rex(u8* out, int w, u32 reg, u32 index, u32 rm) { /* Always emit a REX byte (force form). */ static inline u32 x64_pack_rex_force(u8* out, int w, u32 reg, u32 index, u32 rm) { - out[0] = (u8)(X64_REX_BASE | (w ? X64_REX_W : 0u) | - ((reg & 8u) ? X64_REX_R : 0u) | - ((index & 8u) ? X64_REX_X : 0u) | - ((rm & 8u) ? X64_REX_B : 0u)); + out[0] = + (u8)(X64_REX_BASE | (w ? X64_REX_W : 0u) | ((reg & 8u) ? X64_REX_R : 0u) | + ((index & 8u) ? X64_REX_X : 0u) | ((rm & 8u) ? X64_REX_B : 0u)); return 1u; } @@ -524,7 +523,7 @@ static inline u32 x64_alu_rr_pack(X64AluRR f, u8* out) { * Optional 0x66 | REX(w, src, 0, base) | op | mem(src, base, disp) * `force_rex` matches emit_mov_store size=1 (byte-reg promotion). */ typedef struct X64AluRM { - u8 prefix; /* 0 or 0x66 */ + u8 prefix; /* 0 or 0x66 */ int w; u8 op; int force_rex; /* 1 → always emit REX (byte-reg form) */ @@ -564,10 +563,10 @@ static inline u32 x64_mov_ri_pack(X64MovRI f, u8* out) { * Also covers MOVZX/MOVSX with memory source (two-byte opcode). ---- */ typedef struct X64MovRMLoad { int w; - u8 opc0; /* primary opcode byte */ - u8 opc1; /* 0 for one-byte opcode; nonzero = 0F xx form */ - u32 dst; /* reg */ - u32 base; /* mem base */ + u8 opc0; /* primary opcode byte */ + u8 opc1; /* 0 for one-byte opcode; nonzero = 0F xx form */ + u32 dst; /* reg */ + u32 base; /* mem base */ i32 disp; } X64MovRMLoad; static inline u32 x64_mov_rm_load_pack(X64MovRMLoad f, u8* out) { @@ -587,7 +586,7 @@ static inline u32 x64_mov_rm_load_pack(X64MovRMLoad f, u8* out) { * regs) from the word-source form. */ typedef struct X64MovzxRR { int w; - u8 opc1; /* B6 / B7 / BE / BF */ + u8 opc1; /* B6 / B7 / BE / BF */ int force_rex; u32 dst; u32 src; @@ -663,10 +662,10 @@ static inline u32 x64_imul_rr_pack(X64ImulRR f, u8* out) { /* ---- X64_FMT_IMUL_RRI: 6B /r ib (imm8) or 69 /r id (imm32). ---- */ typedef struct X64ImulRRI { int w; - int imm32; /* 1 → 0x69 with imm32; 0 → 0x6B with imm8 */ + int imm32; /* 1 → 0x69 with imm32; 0 → 0x6B with imm8 */ u32 dst; u32 src; - i32 imm; /* sign-extended; for imm32=0, only low byte used */ + i32 imm; /* sign-extended; for imm32=0, only low byte used */ } X64ImulRRI; static inline u32 x64_imul_rri_pack(X64ImulRRI f, u8* out) { u32 n = x64_pack_rex(out, f.w, f.dst, 0, f.src); @@ -737,7 +736,7 @@ static inline u32 x64_setcc_pack(X64Setcc f, u8* out) { typedef struct X64SseRR { u8 prefix; /* 0 / 0x66 / 0xF2 / 0xF3 */ u8 opcode; - int w; /* REX.W for 64-bit CVTSI2 / CVTT2SI forms */ + int w; /* REX.W for 64-bit CVTSI2 / CVTT2SI forms */ u32 dst; u32 src; } X64SseRR; diff --git a/src/arch/x64/ops.c b/src/arch/x64/ops.c @@ -14,10 +14,10 @@ #include "arch/arch.h" #include "arch/x64/asm.h" -#include "cfree/config.h" #include "arch/x64/internal.h" #include "arch/x64/isa.h" #include "arch/x64/x64.h" +#include "cfree/config.h" #include "core/arena.h" #include "core/pool.h" #include "core/slice.h" @@ -88,15 +88,13 @@ static void x_copy(CGTarget* t, Operand dst, Operand src) { if (dst.cls == RC_FP && src.cls == RC_INT) { u32 sz = type_byte_size(dst.type); int w = sz == 8 ? 1 : 0; - emit_sse_rr_w(t->mc, 0x66, 0x6E, w, dst.v.reg & 0xFu, - src.v.reg & 0xFu); + emit_sse_rr_w(t->mc, 0x66, 0x6E, w, dst.v.reg & 0xFu, src.v.reg & 0xFu); return; } if (dst.cls == RC_INT && src.cls == RC_FP) { u32 sz = type_byte_size(src.type); int w = sz == 8 ? 1 : 0; - emit_sse_rr_w(t->mc, 0x66, 0x7E, w, src.v.reg & 0xFu, - dst.v.reg & 0xFu); + emit_sse_rr_w(t->mc, 0x66, 0x7E, w, src.v.reg & 0xFu, dst.v.reg & 0xFu); return; } if (dst.cls == RC_FP || src.cls == RC_FP) { @@ -125,8 +123,8 @@ static u32 addr_mode(CGTarget* t, Operand addr, u32* out_index, return X64_RBP; } if (addr.kind == OPK_INDIRECT) { - *out_index = (addr.v.ind.index == REG_NONE) ? REG_NONE - : (addr.v.ind.index & 0xFu); + *out_index = + (addr.v.ind.index == REG_NONE) ? REG_NONE : (addr.v.ind.index & 0xFu); *out_log2_scale = addr.v.ind.log2_scale; *out_off = addr.v.ind.ofs; return addr.v.ind.base & 0xFu; @@ -455,8 +453,8 @@ static void x_tls_addr_of_win64(CGTarget* t, Operand dst, ObjSymId sym, Sym idx_name = pool_intern_slice(t->c->global, SLICE_LIT("_tls_index")); ObjSymId idx_sym = obj_symbol_find(t->obj, idx_name); if (idx_sym == 0) { - idx_sym = obj_symbol(t->obj, idx_name, SB_GLOBAL, SK_UNDEF, - OBJ_SEC_NONE, 0, 0); + idx_sym = + obj_symbol(t->obj, idx_name, SB_GLOBAL, SK_UNDEF, OBJ_SEC_NONE, 0, 0); } u8 rex_r_only = X64_REX_BASE | X64_REX_R; /* R11 in ModRM.reg. */ mc->emit_bytes(mc, &rex_r_only, 1); @@ -469,9 +467,9 @@ static void x_tls_addr_of_win64(CGTarget* t, Operand dst, ObjSymId sym, mc->emit_reloc_at(mc, sec, idx_disp_pos, R_PC32, idx_sym, -4, 1, 0); /* (3) mov rd, [rd + r11*8]: REX.W + (REX.X for r11) + (REX.B for rd>=8) + - * 8B modrm(mod, reg=rd&7, rm=4=SIB) sib(scale=3, index=3=r11&7, base=rd&7). - * When base&7 == 5 (rbp/r13) mod=0 means "disp32 only"; force mod=01 - * with disp8=0 to actually mean [reg+r11*8 + 0]. */ + * 8B modrm(mod, reg=rd&7, rm=4=SIB) sib(scale=3, index=3=r11&7, + * base=rd&7). When base&7 == 5 (rbp/r13) mod=0 means "disp32 only"; force + * mod=01 with disp8=0 to actually mean [reg+r11*8 + 0]. */ u8 rex3 = X64_REX_BASE | X64_REX_W | X64_REX_X; if (rd & 8) rex3 |= X64_REX_R; /* reg = rd */ if (rd & 8) rex3 |= X64_REX_B; /* base = rd */ @@ -492,8 +490,8 @@ static void x_tls_addr_of_win64(CGTarget* t, Operand dst, ObjSymId sym, mc->emit_bytes(mc, &s3, 1); } - /* (4) lea rd, [rd + disp32@SECREL]: REX.W + (.R/.B for rd) + 8D modrm + disp32. - * rsp/r12 (rd&7==4) needs a SIB; rbp/r13 (rd&7==5) already takes + /* (4) lea rd, [rd + disp32@SECREL]: REX.W + (.R/.B for rd) + 8D modrm + + * disp32. rsp/r12 (rd&7==4) needs a SIB; rbp/r13 (rd&7==5) already takes * disp32 form natively at mod=10. */ u8 rex4 = X64_REX_BASE | X64_REX_W; if (rd & 8) rex4 |= X64_REX_R; /* reg = rd */ @@ -1035,8 +1033,8 @@ static void x_convert(CGTarget* t, ConvKind k, Operand dst, Operand src) { mc->label_place(mc, L_high); emit_mov_rr(mc, 1, X64_R11, rr); emit_mov_rr(mc, 1, X64_RAX, rr); - emit_alu_imm8(mc, 1, 4u, X64_RAX, 1); /* and rax, 1 */ - emit_shift_imm(mc, 1, 5u, X64_R11, 1); /* shr r11, 1 */ + emit_alu_imm8(mc, 1, 4u, X64_RAX, 1); /* and rax, 1 */ + emit_shift_imm(mc, 1, 5u, X64_R11, 1); /* shr r11, 1 */ emit_alu_rr(mc, 1, 0x09, X64_R11, X64_RAX); /* or r11, rax */ emit_sse_rr_w(mc, prefix2, 0x2A, 1, rd, X64_R11); emit_sse_rr(mc, prefix2, 0x58, rd, rd); /* addss/addsd dst, dst */ @@ -1191,8 +1189,8 @@ static void emit_arg_value(CGTarget* t, const CGABIValue* av, u32* next_int, if (ai->kind == ABI_ARG_INDIRECT) { /* Pass &av->storage_local in the next int arg reg. */ u32 nargs_reg = a->abi->n_int_args; - u32 dst_reg = (*next_int < nargs_reg) ? a->abi->int_args[(*next_int)++] - : X64_RAX; + u32 dst_reg = + (*next_int < nargs_reg) ? a->abi->int_args[(*next_int)++] : X64_RAX; int to_stack = (dst_reg == X64_RAX); x_call_sync_slot(a->abi, next_int, next_fp); if (av->storage.kind == OPK_LOCAL) { @@ -1268,8 +1266,7 @@ static void emit_arg_value(CGTarget* t, const CGABIValue* av, u32* next_int, break; } case OPK_INDIRECT: - emit_mov_load(t->mc, sz, 0, X64_RAX, - av->storage.v.ind.base & 0xFu, + emit_mov_load(t->mc, sz, 0, X64_RAX, av->storage.v.ind.base & 0xFu, av->storage.v.ind.ofs + (i32)pt->src_offset); break; default: @@ -1483,9 +1480,8 @@ static const Reg g_tail_cs_int_order_all[X64_MAX_CS_INT_REGS] = { #define X64_TAIL_MAX_CS_FP_REGS 10u static const Reg g_tail_cs_fp_order_all[X64_TAIL_MAX_CS_FP_REGS] = { - X64_XMM6, X64_XMM7, X64_XMM8, X64_XMM0 + 9, - X64_XMM0 + 10, X64_XMM0 + 11, X64_XMM0 + 12, X64_XMM0 + 13, - X64_XMM0 + 14, X64_XMM15, + X64_XMM6, X64_XMM7, X64_XMM8, X64_XMM0 + 9, X64_XMM0 + 10, + X64_XMM0 + 11, X64_XMM0 + 12, X64_XMM0 + 13, X64_XMM0 + 14, X64_XMM15, }; /* Realizability of a sibling call (see CGTarget.tail_call_unrealizable_reason). @@ -1495,7 +1491,7 @@ static const Reg g_tail_cs_fp_order_all[X64_TAIL_MAX_CS_FP_REGS] = { * and sret callees are realizable by forwarding this function's own incoming * sret pointer (the return-shape precondition guarantees it matches). */ static const char* x_tail_call_unrealizable_reason(CGTarget* t, - const CGCallDesc* d) { + const CGCallDesc* d) { XImpl* a = impl_of(t); if (x_call_stack_size(t, d) > a->next_param_stack) return "tail call stack arguments exceed the caller's parameter area"; @@ -1727,7 +1723,8 @@ static void x_emit_call_plan(CGTarget* t, const CGCallPlan* p) { /* Forward the incoming sret pointer into the ABI sret register (see * x_call). Load before x_tail_branch restores the frame. */ if (a->sret_ptr_slot == FRAME_SLOT_NONE) - compiler_panic(t->c, a->loc, "x64 tail call: missing incoming sret slot"); + compiler_panic(t->c, a->loc, + "x64 tail call: missing incoming sret slot"); XSlot* s = x64_slot_get(a, a->sret_ptr_slot); if (!s) compiler_panic(t->c, a->loc, "x64 tail call: bad sret slot"); emit_mov_load(mc, 8, 0, a->abi->int_args[0], X64_RBP, -(i32)s->off); @@ -2617,10 +2614,10 @@ static void x_intrinsic(CGTarget* t, IntrinKind kind, Operand* dsts, u32 nd, /* args = (dst_addr, src_addr, n_bytes). v1: const n, REG ptrs. */ Operand da = args[0], sa = args[1], nb = args[2]; if (da.kind != OPK_REG || sa.kind != OPK_REG || nb.kind != OPK_IMM) { - compiler_panic(t->c, a->loc, - "x64 intrinsic: %.*s with non-const n or non-REG ptr", - SLICE_ARG(slice_from_cstr( - kind == INTRIN_MEMCPY ? "memcpy" : "memmove"))); + compiler_panic( + t->c, a->loc, "x64 intrinsic: %.*s with non-const n or non-REG ptr", + SLICE_ARG( + slice_from_cstr(kind == INTRIN_MEMCPY ? "memcpy" : "memmove"))); } u32 dr = da.v.reg & 0xFu; u32 sr = sa.v.reg & 0xFu; diff --git a/src/arch/x64/opt_coord.c b/src/arch/x64/opt_coord.c @@ -10,46 +10,45 @@ * XMM15 in a few lowering paths) and out of opt's allocable pool. */ static const Reg x_int_allocable[] = {X64_R13, X64_R14, X64_R15, X64_R10}; -static const Reg x_fp_allocable[] = {X64_XMM6, X64_XMM7, X64_XMM8, - X64_XMM0 + 9, X64_XMM0 + 10, - X64_XMM0 + 11, X64_XMM0 + 12, - X64_XMM0 + 13}; +static const Reg x_fp_allocable[] = { + X64_XMM6, X64_XMM7, X64_XMM8, X64_XMM0 + 9, + X64_XMM0 + 10, X64_XMM0 + 11, X64_XMM0 + 12, X64_XMM0 + 13}; static const Reg x_int_scratch[] = {X64_RBX, X64_R12}; -static const Reg x_fp_scratch[] = {X64_XMM0 + 14, X64_XMM15}; +static const Reg x_fp_scratch[] = {X64_XMM0 + 14, X64_XMM15}; static const CGPhysRegInfo x_int_phys[] = { - {X64_RDI, RC_INT, 0, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {X64_RSI, RC_INT, 1, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {X64_R8, RC_INT, 4, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {X64_R9, RC_INT, 5, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {X64_R10, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_TEMP_PREFERRED, 0, 0}, + {X64_RDI, RC_INT, 0, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, + 0}, + {X64_RSI, RC_INT, 1, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, + 0}, + {X64_R8, RC_INT, 4, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, + 0}, + {X64_R9, RC_INT, 5, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, + 0}, + {X64_R10, RC_INT, 0xff, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_TEMP_PREFERRED, 0, 0}, {X64_R13, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLEE_SAVED, 50, 4}, {X64_R14, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLEE_SAVED, 50, 4}, {X64_R15, RC_INT, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLEE_SAVED, 50, 4}, }; static const CGPhysRegInfo x_fp_phys[] = { - {X64_XMM0, RC_FP, 0, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG | CG_REG_RET, 0, 0}, - {X64_XMM0 + 1, RC_FP, 1, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG | CG_REG_RET, 0, 0}, - {X64_XMM0 + 2, RC_FP, 2, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {X64_XMM0 + 3, RC_FP, 3, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {X64_XMM0 + 4, RC_FP, 4, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {X64_XMM0 + 5, RC_FP, 5, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {X64_XMM6, RC_FP, 6, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, - {X64_XMM7, RC_FP, 7, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | - CG_REG_ARG, 0, 0}, + {X64_XMM0, RC_FP, 0, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG | CG_REG_RET, 0, 0}, + {X64_XMM0 + 1, RC_FP, 1, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG | CG_REG_RET, 0, 0}, + {X64_XMM0 + 2, RC_FP, 2, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, 0}, + {X64_XMM0 + 3, RC_FP, 3, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, 0}, + {X64_XMM0 + 4, RC_FP, 4, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, 0}, + {X64_XMM0 + 5, RC_FP, 5, + CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, 0}, + {X64_XMM6, RC_FP, 6, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, + 0}, + {X64_XMM7, RC_FP, 7, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED | CG_REG_ARG, 0, + 0}, {X64_XMM8, RC_FP, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED, 0, 0}, {X64_XMM0 + 9, RC_FP, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED, 0, 0}, {X64_XMM0 + 10, RC_FP, 0xff, CG_REG_ALLOCABLE | CG_REG_CALLER_SAVED, 0, 0}, @@ -61,8 +60,8 @@ static const CGPhysRegInfo x_fp_phys[] = { /* ============================================================ * Vtable methods */ -static void x_get_allocable_regs(CGTarget* t, RegClass cls, - const Reg** out, u32* nregs) { +static void x_get_allocable_regs(CGTarget* t, RegClass cls, const Reg** out, + u32* nregs) { (void)t; switch (cls) { case RC_INT: @@ -80,8 +79,8 @@ static void x_get_allocable_regs(CGTarget* t, RegClass cls, } } -static void x_get_scratch_regs(CGTarget* t, RegClass cls, - const Reg** out, u32* nregs) { +static void x_get_scratch_regs(CGTarget* t, RegClass cls, const Reg** out, + u32* nregs) { (void)t; switch (cls) { case RC_INT: @@ -137,8 +136,7 @@ static int x_is_caller_saved(CGTarget* t, RegClass cls, Reg reg) { } } -static u32 x_call_clobber_mask(CGTarget* t, const CGCallDesc* d, - RegClass cls) { +static u32 x_call_clobber_mask(CGTarget* t, const CGCallDesc* d, RegClass cls) { (void)d; const X64ABIRegs* abi = x64_abi_for_os(t->c->target.os); switch (cls) { @@ -186,8 +184,10 @@ static u32 x_return_reg_mask(CGTarget* t, const ABIFuncInfo* abi, static const u32 iregs[2] = {X64_RAX, X64_RDX}; for (u16 i = 0; i < abi->ret.nparts; ++i) { const ABIArgPart* p = &abi->ret.parts[i]; - if (cls == RC_INT && p->cls == ABI_CLASS_INT && ni < 2) mask |= 1u << iregs[ni++]; - else if (cls == RC_FP && p->cls == ABI_CLASS_FP && nf < 2) mask |= 1u << (X64_XMM0 + nf++); + if (cls == RC_INT && p->cls == ABI_CLASS_INT && ni < 2) + mask |= 1u << iregs[ni++]; + else if (cls == RC_FP && p->cls == ABI_CLASS_FP && nf < 2) + mask |= 1u << (X64_XMM0 + nf++); } return mask; } @@ -330,8 +330,8 @@ static void x_plan_call(CGTarget* t, const CGCallDesc* d, CGCallPlan* out) { } } out->variadic_fp_count = (u8)next_fp; - if ((out->flags & CG_CALL_TAIL) == 0 && - d->abi && d->abi->ret.kind != ABI_ARG_IGNORE && + if ((out->flags & CG_CALL_TAIL) == 0 && d->abi && + d->abi->ret.kind != ABI_ARG_IGNORE && d->abi->ret.kind != ABI_ARG_INDIRECT && !x_is_void_ret_storage(d->ret.storage)) { u32 ni = 0, nf = 0; @@ -355,8 +355,8 @@ static void x_plan_call(CGTarget* t, const CGCallDesc* d, CGCallPlan* out) { } } -static void x_reserve_hard_regs(CGTarget* t, RegClass cls, - const Reg* regs, u32 n) { +static void x_reserve_hard_regs(CGTarget* t, RegClass cls, const Reg* regs, + u32 n) { XImpl* a = impl_of(t); for (u32 i = 0; i < n; ++i) { Reg r = regs[i]; @@ -398,13 +398,13 @@ static void x_plan_hard_regs(CGTarget* t, RegClass cls, const Reg* regs, void x_coord_vtable_init(CGTarget* t) { t->get_allocable_regs = x_get_allocable_regs; - t->get_phys_regs = x_get_phys_regs; - t->get_scratch_regs = x_get_scratch_regs; - t->is_caller_saved = x_is_caller_saved; - t->call_clobber_mask = x_call_clobber_mask; - t->return_reg_mask = x_return_reg_mask; - t->callee_save_mask = x_callee_save_mask; - t->plan_call = x_plan_call; - t->plan_hard_regs = x_plan_hard_regs; - t->reserve_hard_regs = x_reserve_hard_regs; + t->get_phys_regs = x_get_phys_regs; + t->get_scratch_regs = x_get_scratch_regs; + t->is_caller_saved = x_is_caller_saved; + t->call_clobber_mask = x_call_clobber_mask; + t->return_reg_mask = x_return_reg_mask; + t->callee_save_mask = x_callee_save_mask; + t->plan_call = x_plan_call; + t->plan_hard_regs = x_plan_hard_regs; + t->reserve_hard_regs = x_reserve_hard_regs; } diff --git a/src/asm/asm.c b/src/asm/asm.c @@ -588,7 +588,8 @@ static void decode_string(AsmDriver* d, Sym spelling, u8** out, u32* nout) { static Sym expect_ident(AsmDriver* d, const char* what) { AsmTok t = d_peek(d); if (t.kind != ASM_TOK_IDENT) - d_panicf(d, "asm: %.*s: expected identifier", SLICE_ARG(slice_from_cstr(what))); + d_panicf(d, "asm: %.*s: expected identifier", + SLICE_ARG(slice_from_cstr(what))); (void)d_next(d); return t.v.ident; } @@ -637,7 +638,8 @@ static void do_directive(AsmDriver* d, Sym name) { return; } if (sym_eq(d, name, "rodata")) { - if (!d->n_rodata) d->n_rodata = pool_intern_slice(d->pool, SLICE_LIT(".rodata")); + if (!d->n_rodata) + d->n_rodata = pool_intern_slice(d->pool, SLICE_LIT(".rodata")); set_section(d, d->n_rodata, SEC_RODATA, (u16)SF_ALLOC, 8); d_skip_to_eol(d); return; @@ -658,7 +660,7 @@ static void do_directive(AsmDriver* d, Sym name) { size_t n = 0; const char* p = asm_str(d, t.spelling, &n); if (n >= 2 && p[0] == '"') - sname = pool_intern_slice(d->pool, (Slice){ .s = p + 1, .len = n - 2 }); + sname = pool_intern_slice(d->pool, (Slice){.s = p + 1, .len = n - 2}); (void)d_next(d); } else if (tok_is_punct(t, '.')) { (void)d_next(d); @@ -670,7 +672,7 @@ static void do_directive(AsmDriver* d, Sym name) { if (ni + 1 >= sizeof buf) d_panicf(d, "asm: .section: name too long"); buf[0] = '.'; for (size_t i = 0; i < ni; ++i) buf[i + 1] = nm[i]; - sname = pool_intern_slice(d->pool, (Slice){ .s = buf, .len = ni + 1 }); + sname = pool_intern_slice(d->pool, (Slice){.s = buf, .len = ni + 1}); } else { d_panicf(d, "asm: .section: expected name"); } @@ -752,7 +754,7 @@ static void do_directive(AsmDriver* d, Sym name) { size_t sn = 0; const char* sp = asm_str(d, t.spelling, &sn); if (sn >= 2 && sp[0] == '"' && sp[sn - 1] == '"') - tag = pool_intern_slice(d->pool, (Slice){ .s = sp + 1, .len = sn - 2 }); + tag = pool_intern_slice(d->pool, (Slice){.s = sp + 1, .len = sn - 2}); } else { d_panicf(d, "asm: .type: tag"); } @@ -950,7 +952,7 @@ static Sym maybe_compose_mnemonic(AsmDriver* d, Sym head) { for (size_t i = 0; i < hn; ++i) buf[i] = hp[i]; buf[hn] = '.'; for (size_t i = 0; i < rn; ++i) buf[hn + 1 + i] = rp[i]; - head = pool_intern_slice(d->pool, (Slice){ .s = buf, .len = n }); + head = pool_intern_slice(d->pool, (Slice){.s = buf, .len = n}); } } diff --git a/src/asm/asm_lex.c b/src/asm/asm_lex.c @@ -171,8 +171,8 @@ static Sym intern_spliced(AsmLexer* l, size_t start, size_t end) { } } if (!has_splice) - return pool_intern_slice( - l->pool, (Slice){ .s = l->src + start, .len = end - start }); + return pool_intern_slice(l->pool, + (Slice){.s = l->src + start, .len = end - start}); buf = (char*)l->heap->alloc(l->heap, end - start, 1); k = 0; @@ -183,7 +183,7 @@ static Sym intern_spliced(AsmLexer* l, size_t start, size_t end) { } buf[k++] = l->src[i++]; } - sym = pool_intern_slice(l->pool, (Slice){ .s = buf, .len = k }); + sym = pool_intern_slice(l->pool, (Slice){.s = buf, .len = k}); l->heap->free(l->heap, buf, end - start); return sym; } @@ -478,7 +478,7 @@ AsmTok asm_lex_next(AsmLexer* l) { break; } } - t.spelling = pool_intern_slice(l->pool, (Slice){ .s = pbuf, .len = k }); + t.spelling = pool_intern_slice(l->pool, (Slice){.s = pbuf, .len = k}); l->heap->free(l->heap, pbuf, plen ? plen : 1); return t; } diff --git a/src/cg/asm.c b/src/cg/asm.c @@ -322,8 +322,8 @@ void cfree_cg_file_scope_asm(CfreeCg* g, CfreeSlice asm_source) { "C target: file-scope asm not yet supported"); } api_local_const_memory_boundary(g); - lex = asm_lex_open_mem(g->c, "<file-scope asm>", asm_source.s, - asm_source.len); + lex = + asm_lex_open_mem(g->c, "<file-scope asm>", asm_source.s, asm_source.len); if (!lex) compiler_panic(g->c, api_no_loc(), "CfreeCg: file-scope asm out of memory"); asm_parse(g->c, lex, g->mc); diff --git a/src/cg/control.c b/src/cg/control.c @@ -166,7 +166,8 @@ static CGSwitchPlan cg_plan_switch(CfreeCg* g, const CGSwitchDesc* d) { if (d->opt_level >= 2 && plan.span != d->ncases) return plan; if (d->ncases < CG_SWITCH_TABLE_MIN_CASES_O1) return plan; if (plan.span > CG_SWITCH_TABLE_MAX_SPAN_O1) return plan; - if (plan.span > (u64)d->ncases * CG_SWITCH_TABLE_DENSITY_RECIP_O1) return plan; + if (plan.span > (u64)d->ncases * CG_SWITCH_TABLE_DENSITY_RECIP_O1) + return plan; plan.cls = CG_SWITCH_CLS_TABLE; return plan; } @@ -206,20 +207,20 @@ static void cg_emit_switch_table(CfreeCg* g, const CGSwitchDesc* d, * cases). The selector copy lets us recompute idx after the bounds * branch instead of carrying a duplicated arithmetic value across * control flow. */ - cfree_cg_dup(g); /* [sel, sel] */ + cfree_cg_dup(g); /* [sel, sel] */ cfree_cg_push_int(g, (uint64_t)plan->vmin, sel_ty); - cfree_cg_int_binop(g, CFREE_CG_INT_SUB, 0); /* [sel, idx] */ + cfree_cg_int_binop(g, CFREE_CG_INT_SUB, 0); /* [sel, idx] */ /* 2. Bounds check: branch to default when idx u> span-1. */ - cfree_cg_dup(g); /* [sel, idx, idx] */ + cfree_cg_dup(g); /* [sel, idx, idx] */ cfree_cg_push_int(g, plan->span - 1u, sel_ty); - cfree_cg_int_cmp(g, CFREE_CG_INT_GT_U); /* [sel, idx, cond] */ + cfree_cg_int_cmp(g, CFREE_CG_INT_GT_U); /* [sel, idx, cond] */ cfree_cg_branch_true(g, (CfreeCgLabel)d->default_label); /* [sel, idx] */ /* 3. Recompute idx from the preserved selector for table addressing. */ - cfree_cg_drop(g); /* [sel] */ + cfree_cg_drop(g); /* [sel] */ cfree_cg_push_int(g, (uint64_t)plan->vmin, sel_ty); - cfree_cg_int_binop(g, CFREE_CG_INT_SUB, 0); /* [idx] */ + cfree_cg_int_binop(g, CFREE_CG_INT_SUB, 0); /* [idx] */ /* 4. Widen idx to i64 so the subsequent index multiply runs at * pointer width regardless of selector signedness. The bounds @@ -230,8 +231,8 @@ static void cg_emit_switch_table(CfreeCg* g, const CGSwitchDesc* d, } /* 5. Build the dense label[] slot array and emit the rodata table. */ - labels = (Label*)h->alloc(h, (size_t)plan->span * sizeof *labels, - _Alignof(Label)); + labels = + (Label*)h->alloc(h, (size_t)plan->span * sizeof *labels, _Alignof(Label)); if (!labels) compiler_panic(c, g->cur_loc, "cfree_cg_switch: oom"); for (i = 0; i < plan->span; ++i) labels[i] = d->default_label; width = sel_w; @@ -260,8 +261,8 @@ static void cg_emit_switch_table(CfreeCg* g, const CGSwitchDesc* d, /* 6. Load table[idx]: push the table's address, swap so the index is on top, * then load with EA scale = pointer size. */ - cfree_cg_push_symbol_addr(g, (CfreeCgSym)table_sym, 0); /* [idx, &table] */ - cfree_cg_swap(g); /* [&table, idx] */ + cfree_cg_push_symbol_addr(g, (CfreeCgSym)table_sym, 0); /* [idx, &table] */ + cfree_cg_swap(g); /* [&table, idx] */ memset(&acc, 0, sizeof acc); acc.type = void_ptr_ty; acc.align = (uint32_t)c->target.ptr_align; @@ -269,7 +270,7 @@ static void cg_emit_switch_table(CfreeCg* g, const CGSwitchDesc* d, CfreeCgEffAddr ea; ea.offset = 0; ea.scale = (uint32_t)c->target.ptr_size; - cfree_cg_load(g, acc, ea); /* [label_addr] */ + cfree_cg_load(g, acc, ea); /* [label_addr] */ } /* 7. Indirect branch with the full closed target set (every case + @@ -310,7 +311,8 @@ void cfree_cg_switch(CfreeCg* g, CfreeCgSwitch sw) { h = g->c->ctx->heap; cases = (CGSwitchCase*)h->alloc(h, sw.ncases * sizeof(CGSwitchCase), _Alignof(CGSwitchCase)); - if (!cases) compiler_panic(g->c, g->cur_loc, "cfree_cg_switch: out of memory"); + if (!cases) + compiler_panic(g->c, g->cur_loc, "cfree_cg_switch: out of memory"); for (u32 i = 0; i < sw.ncases; ++i) { cases[i].value = sw.cases[i].value; cases[i].label = (Label)sw.cases[i].label; @@ -467,11 +469,10 @@ static CfreeCgScope api_scope_begin_kind(CfreeCg* g, u8 kind, u32 idx; if (!g) return 0; break_lbl = g->target->label_new(g->target); - cont_lbl = (kind == SCOPE_LOOP) ? g->target->label_new(g->target) - : LABEL_NONE; + cont_lbl = + (kind == SCOPE_LOOP) ? g->target->label_new(g->target) : LABEL_NONE; api_local_const_control_boundary(g); - if (cont_lbl != LABEL_NONE) - g->target->label_place(g->target, cont_lbl); + if (cont_lbl != LABEL_NONE) g->target->label_place(g->target, cont_lbl); if (g->nscopes >= API_CG_MAX_SCOPES) { compiler_panic(g->c, g->cur_loc, "CfreeCg: too many nested scopes"); @@ -517,14 +518,14 @@ CfreeCgScope cfree_cg_block_begin(CfreeCg* g, CfreeCgTypeId result_type) { } CfreeCgLabel cfree_cg_scope_break_label(CfreeCg* g, CfreeCgScope scope) { - ApiCgScope* s = api_scope_from_handle(g, scope, 0, - "CfreeCg: scope_break_label"); + ApiCgScope* s = + api_scope_from_handle(g, scope, 0, "CfreeCg: scope_break_label"); return s ? (CfreeCgLabel)s->break_lbl : (CfreeCgLabel)0; } CfreeCgLabel cfree_cg_scope_continue_label(CfreeCg* g, CfreeCgScope scope) { - ApiCgScope* s = api_scope_from_handle(g, scope, 0, - "CfreeCg: scope_continue_label"); + ApiCgScope* s = + api_scope_from_handle(g, scope, 0, "CfreeCg: scope_continue_label"); return s ? (CfreeCgLabel)s->continue_lbl : (CfreeCgLabel)0; } diff --git a/src/cg/data.c b/src/cg/data.c @@ -80,8 +80,8 @@ void cfree_cg_data_begin(CfreeCg* g, CfreeCgSym cg_sym, align = attrs.align ? attrs.align : (u32)abi_cg_alignof(c->abi, decl_attrs.type); - if ((attrs.flags & CFREE_CG_DATADEF_FUNCTION_LOCAL) && - g->target && g->target->local_static_data_begin) { + if ((attrs.flags & CFREE_CG_DATADEF_FUNCTION_LOCAL) && g->target && + g->target->local_static_data_begin) { CGLocalStaticDataDesc desc; memset(&desc, 0, sizeof desc); desc.sym = sym; @@ -455,8 +455,7 @@ void cfree_cg_data_label_addr(CfreeCg* g, CfreeCgLabel target, int64_t addend, return; } if (g->target && g->target->data_label_addr_unsupported_msg) { - const char* msg = - g->target->data_label_addr_unsupported_msg(g->target); + const char* msg = g->target->data_label_addr_unsupported_msg(g->target); if (msg) { compiler_panic(g->c, g->cur_loc, "%s", msg); return; @@ -716,9 +715,8 @@ ObjSymId api_emit_label_table(CfreeCg* g, const Label* labels, u32 n) { obj_write(ob, sec, pad, ptrsz); } for (i = 0; i < n; ++i) { - MCLabel ml = T->cg_label_to_mc_label - ? T->cg_label_to_mc_label(T, labels[i]) - : (MCLabel)labels[i]; + MCLabel ml = T->cg_label_to_mc_label ? T->cg_label_to_mc_label(T, labels[i]) + : (MCLabel)labels[i]; if (ml == MC_LABEL_NONE) { compiler_panic(c, g->cur_loc, "api_emit_label_table: label has no MCLabel"); @@ -730,9 +728,8 @@ ObjSymId api_emit_label_table(CfreeCg* g, const Label* labels, u32 n) { strbuf_init(&name_sb, name_buf, sizeof name_buf); strbuf_put_slice(&name_sb, SLICE_LIT(".Lcfree_jt.")); strbuf_put_u64(&name_sb, g->rodata_counter++); - anon = pool_intern_slice( - c->global, - (Slice){.s = strbuf_cstr(&name_sb), .len = strbuf_len(&name_sb)}); + anon = pool_intern_slice(c->global, (Slice){.s = strbuf_cstr(&name_sb), + .len = strbuf_len(&name_sb)}); sym = obj_symbol(ob, anon, SB_LOCAL, SK_OBJ, sec, base, (u64)n * ptrsz); return sym; } diff --git a/src/cg/debug.c b/src/cg/debug.c @@ -9,9 +9,9 @@ DebugTypeId api_debug_type(CfreeCg* g, CfreeCgTypeId id) { case CFREE_CG_TYPE_VOID: return debug_type_void(g->debug); case CFREE_CG_TYPE_BOOL: - return debug_type_base(g->debug, - pool_intern_slice(g->c->global, SLICE_LIT("_Bool")), - DEBUG_BE_BOOL, 1); + return debug_type_base( + g->debug, pool_intern_slice(g->c->global, SLICE_LIT("_Bool")), + DEBUG_BE_BOOL, 1); case CFREE_CG_TYPE_INT: { const char* name = "long long"; if (ty->integer.width <= 8) diff --git a/src/cg/memory.c b/src/cg/memory.c @@ -203,9 +203,9 @@ static Operand fold_ea_into_operand(CfreeCg* g, Operand addr, i64 offset, CfreeCgTypeId access_ty, Reg* out_owned_base) { CGTarget* T = g->target; - CfreeCgTypeId base_ty = - cg_type_is_ptr(g->c, addr.type) ? addr.type - : cg_type_ptr_to(g->c, access_ty); + CfreeCgTypeId base_ty = cg_type_is_ptr(g->c, addr.type) + ? addr.type + : cg_type_ptr_to(g->c, access_ty); *out_owned_base = REG_NONE; if (index == REG_NONE) { @@ -227,15 +227,14 @@ static Operand fold_ea_into_operand(CfreeCg* g, Operand addr, i64 offset, *out_owned_base = br; return api_op_indirect(br, (i32)offset, access_ty); } - T->binop(T, BO_IADD, base_reg, base_reg, - api_op_imm(offset, base_ty)); + T->binop(T, BO_IADD, base_reg, base_reg, api_op_imm(offset, base_ty)); *out_owned_base = br; return api_op_indirect(br, 0, access_ty); } } if (addr.kind == OPK_GLOBAL) { - Operand r = api_op_global(addr.v.global.sym, addr.v.global.addend + offset, - access_ty); + Operand r = api_op_global(addr.v.global.sym, + addr.v.global.addend + offset, access_ty); return r; } if (addr.kind == OPK_INDIRECT) { @@ -250,12 +249,11 @@ static Operand fold_ea_into_operand(CfreeCg* g, Operand addr, i64 offset, Reg br = api_alloc_reg_or_spill(g, RC_INT, base_ty); Operand base_reg = api_op_reg(br, base_ty); T->copy(T, base_reg, api_op_reg(addr.v.ind.base, base_ty)); - T->binop(T, BO_IADD, base_reg, base_reg, - api_op_imm(offset, base_ty)); + T->binop(T, BO_IADD, base_reg, base_reg, api_op_imm(offset, base_ty)); *out_owned_base = br; return api_op_indirect_indexed(br, addr.v.ind.index, - addr.v.ind.log2_scale, - addr.v.ind.ofs, access_ty); + addr.v.ind.log2_scale, addr.v.ind.ofs, + access_ty); } } /* OPK_REG (pointer rvalue) */ @@ -460,10 +458,9 @@ void cfree_cg_load(CfreeCg* g, CfreeCgMemAccess access, CfreeCgEffAddr ea) { ty = api_mem_access_type(g, access, api_sv_type(&base), "load"); access_ty = ty; - if (!has_index && !is_bitfield && !is_lvalue && - base.kind == SV_OPERAND && base.op.kind == OPK_GLOBAL && - (cg_type_is_aggregate(g->c, ty) || - api_is_wide16_scalar_type(g->c, ty))) { + if (!has_index && !is_bitfield && !is_lvalue && base.kind == SV_OPERAND && + base.op.kind == OPK_GLOBAL && + (cg_type_is_aggregate(g->c, ty) || api_is_wide16_scalar_type(g->c, ty))) { base.type = ty; base.op.type = ty; base.lvalue = 1; @@ -512,8 +509,10 @@ void cfree_cg_load(CfreeCg* g, CfreeCgMemAccess access, CfreeCgEffAddr ea) { Operand addr = api_lvalue_addr(g, &base, pty); mem_op = fold_ea_into_operand(g, addr, ea.offset, REG_NONE, 0, ty, &owned_base); - if (owned_base == REG_NONE) owned_base = addr.v.reg; - else if (owned_base != addr.v.reg) api_free_reg(g, addr.v.reg, RC_INT); + if (owned_base == REG_NONE) + owned_base = addr.v.reg; + else if (owned_base != addr.v.reg) + api_free_reg(g, addr.v.reg, RC_INT); } else { mem_op = fold_ea_into_operand(g, base.op, ea.offset, REG_NONE, 0, ty, &owned_base); @@ -535,11 +534,13 @@ void cfree_cg_load(CfreeCg* g, CfreeCgMemAccess access, CfreeCgEffAddr ea) { * the lvalue's address first. */ CfreeCgTypeId pty = cg_type_ptr_to(g->c, api_sv_type(&base)); Operand addr = api_lvalue_addr(g, &base, pty); - mem_op = fold_ea_into_operand(g, addr, ea.offset, owned_index, - log2_scale, access_ty, &owned_base); + mem_op = fold_ea_into_operand(g, addr, ea.offset, owned_index, log2_scale, + access_ty, &owned_base); /* `addr` is an owned register from api_lvalue_addr. */ - if (owned_base == REG_NONE) owned_base = addr.v.reg; - else if (owned_base != addr.v.reg) api_free_reg(g, addr.v.reg, RC_INT); + if (owned_base == REG_NONE) + owned_base = addr.v.reg; + else if (owned_base != addr.v.reg) + api_free_reg(g, addr.v.reg, RC_INT); } else { /* The lvalue carries its own operand; fold the EA into it. */ mem_op = fold_ea_into_operand(g, base.op, ea.offset, owned_index, @@ -556,8 +557,8 @@ void cfree_cg_load(CfreeCg* g, CfreeCgMemAccess access, CfreeCgEffAddr ea) { * the base. */ CfreeCgTypeId pty = api_sv_type(&base); Operand ptr_op = api_force_reg(g, &base, pty); - mem_op = fold_ea_into_operand(g, ptr_op, ea.offset, owned_index, - log2_scale, access_ty, &owned_base); + mem_op = fold_ea_into_operand(g, ptr_op, ea.offset, owned_index, log2_scale, + access_ty, &owned_base); } /* Mutate source-local tracking. Any EA-shaped load through a tracked local @@ -725,8 +726,7 @@ void cfree_cg_store(CfreeCg* g, CfreeCgMemAccess access, CfreeCgEffAddr ea) { } memset(&agg, 0, sizeof agg); agg.size = access_size; - agg.align = access.align ? access.align - : abi_cg_alignof(g->c->abi, ty); + agg.align = access.align ? access.align : abi_cg_alignof(g->c->abi, ty); T->copy_bytes(T, dst_addr, src_addr, agg); if (dst_addr_owned) api_free_reg(g, dst_addr.v.reg, RC_INT); if (src_addr_owned) api_free_reg(g, src_addr.v.reg, RC_INT); @@ -778,8 +778,9 @@ void cfree_cg_store(CfreeCg* g, CfreeCgMemAccess access, CfreeCgEffAddr ea) { agg.align = access.align ? access.align : 16; T->copy_bytes(T, dst_addr, src_addr, agg); if (dst_addr_owned) { - api_free_reg(g, dst_addr.kind == OPK_INDIRECT ? dst_addr.v.ind.base - : dst_addr.v.reg, + api_free_reg(g, + dst_addr.kind == OPK_INDIRECT ? dst_addr.v.ind.base + : dst_addr.v.reg, RC_INT); } if (src_addr_owned) api_free_reg(g, src_addr.v.reg, RC_INT); @@ -866,10 +867,12 @@ void cfree_cg_store(CfreeCg* g, CfreeCgMemAccess access, CfreeCgEffAddr ea) { if (!api_operand_can_address(&base.op)) { CfreeCgTypeId pty = cg_type_ptr_to(g->c, api_sv_type(&base)); Operand addr = api_lvalue_addr(g, &base, pty); - mem_op = fold_ea_into_operand(g, addr, ea.offset, owned_index, - log2_scale, access_ty, &owned_base); - if (owned_base == REG_NONE) owned_base = addr.v.reg; - else if (owned_base != addr.v.reg) api_free_reg(g, addr.v.reg, RC_INT); + mem_op = fold_ea_into_operand(g, addr, ea.offset, owned_index, log2_scale, + access_ty, &owned_base); + if (owned_base == REG_NONE) + owned_base = addr.v.reg; + else if (owned_base != addr.v.reg) + api_free_reg(g, addr.v.reg, RC_INT); } else { mem_op = fold_ea_into_operand(g, base.op, ea.offset, owned_index, log2_scale, access_ty, &owned_base); @@ -881,8 +884,8 @@ void cfree_cg_store(CfreeCg* g, CfreeCgMemAccess access, CfreeCgEffAddr ea) { } else { CfreeCgTypeId pty = api_sv_type(&base); Operand ptr_op = api_force_reg(g, &base, pty); - mem_op = fold_ea_into_operand(g, ptr_op, ea.offset, owned_index, - log2_scale, access_ty, &owned_base); + mem_op = fold_ea_into_operand(g, ptr_op, ea.offset, owned_index, log2_scale, + access_ty, &owned_base); } /* Source-local tracking. Only the plain no-EA scalar-to-scalar store can @@ -948,8 +951,7 @@ void cfree_cg_dup(CfreeCg* g) { return; } dst = api_op_reg(r, ty); - g->target->copy(g->target, dst, - api_op_reg((Reg)api_reg_of_sv(&v), ty)); + g->target->copy(g->target, dst, api_op_reg((Reg)api_reg_of_sv(&v), ty)); dup = v; api_set_owned_reg(&dup, r); dup.res = RES_REG; @@ -1004,10 +1006,10 @@ void cfree_cg_dup2(CfreeCg* g) { if (!g || g->sp < 2) return; /* Stack: [..., a, b] * Step 1: dup the lower (a). We push under TOS by first swapping. */ - cfree_cg_swap(g); /* [..., b, a] */ - cfree_cg_dup(g); /* [..., b, a, a] */ - cfree_cg_rot3(g); /* [..., a, a, b] */ - cfree_cg_dup(g); /* [..., a, a, b, b] */ + cfree_cg_swap(g); /* [..., b, a] */ + cfree_cg_dup(g); /* [..., b, a, a] */ + cfree_cg_rot3(g); /* [..., a, a, b] */ + cfree_cg_dup(g); /* [..., a, a, b, b] */ /* Now: [..., a, a, b, b]; we want [..., a, b, a, b]. */ /* swap middle two: this is the [..., x, a, b, y]-shaped rotation. We * implement it by rot3 then swap. */ diff --git a/src/cg/value.c b/src/cg/value.c @@ -1365,8 +1365,8 @@ int api_try_collapse_binop_identity(CfreeCg* g, BinOp op, CfreeCgTypeId ty, return 1; } if (op == BO_OR && bv == api_width_mask(width)) { - *out = api_make_sv(api_op_imm(api_fold_result(g->c, ty, bv, width), ty), - ty); + *out = + api_make_sv(api_op_imm(api_fold_result(g->c, ty, bv, width), ty), ty); return 1; } } @@ -1381,15 +1381,14 @@ int api_try_collapse_binop_identity(CfreeCg* g, BinOp op, CfreeCgTypeId ty, return 1; } if (a->kind == SV_OPERAND && a->op.kind == OPK_IMM && b->kind == SV_OPERAND && - b->op.kind != OPK_IMM && - (op == BO_IMUL || op == BO_AND || op == BO_OR)) { + b->op.kind != OPK_IMM && (op == BO_IMUL || op == BO_AND || op == BO_OR)) { if ((op == BO_IMUL || op == BO_AND) && av == 0) { *out = api_make_sv(api_op_imm(0, ty), ty); return 1; } if (op == BO_OR && av == api_width_mask(width)) { - *out = api_make_sv(api_op_imm(api_fold_result(g->c, ty, av, width), ty), - ty); + *out = + api_make_sv(api_op_imm(api_fold_result(g->c, ty, av, width), ty), ty); return 1; } } diff --git a/src/cg/wide.c b/src/cg/wide.c @@ -169,10 +169,9 @@ CfreeCgSym api_runtime_helper(CfreeCg* g, const char* name, CfreeCgTypeId ret, sig.call_conv = CFREE_CG_CC_TARGET_C; memset(&decl, 0, sizeof decl); decl.kind = CFREE_CG_DECL_FUNC; - decl.linkage_name = - cfree_cg_c_linkage_name((CfreeCompiler*)g->c, - pool_intern_slice(g->c->global, - slice_from_cstr(name))); + decl.linkage_name = cfree_cg_c_linkage_name( + (CfreeCompiler*)g->c, + pool_intern_slice(g->c->global, slice_from_cstr(name))); decl.display_name = decl.linkage_name; decl.type = cfree_cg_type_func((CfreeCompiler*)g->c, sig); decl.sym.bind = CFREE_SB_GLOBAL; diff --git a/src/core/core.h b/src/core/core.h @@ -125,9 +125,9 @@ struct CfreeCompiler { * cfree_wasm_set_host_imports; consumed by runners that call * cfree_wasm_bind_host_imports after the link image is produced. The * pointers are borrowed: callers own the lifetime. */ - const void* wasm_host_imports; /* CfreeWasmHostImport array */ + const void* wasm_host_imports; /* CfreeWasmHostImport array */ size_t wasm_host_nimports; - void* wasm_host_resolve; /* CfreeWasmResolveFn */ + void* wasm_host_resolve; /* CfreeWasmResolveFn */ void* wasm_host_user; /* Keep jmp_buf last: its size comes from the including C environment * (host libc for some tests, rt/include for libcfree), and must not shift diff --git a/src/core/pool.c b/src/core/pool.c @@ -135,5 +135,5 @@ Sym pool_intern_slice(Pool* p, Slice in) { Slice pool_slice(Pool* p, Sym sym) { if (sym == 0 || sym >= p->nentries) return SLICE_NULL; - return (Slice){ .s = p->entries[sym].data, .len = p->entries[sym].len }; + return (Slice){.s = p->entries[sym].data, .len = p->entries[sym].len}; } diff --git a/src/core/sha256.c b/src/core/sha256.c @@ -1,7 +1,7 @@ -#include <string.h> - #include "core/sha256.h" +#include <string.h> + static const u32 SHA256_K[64] = { 0x428a2f98u, 0x71374491u, 0xb5c0fbcfu, 0xe9b5dba5u, 0x3956c25bu, 0x59f111f1u, 0x923f82a4u, 0xab1c5ed5u, 0xd807aa98u, 0x12835b01u, @@ -17,9 +17,7 @@ static const u32 SHA256_K[64] = { 0x682e6ff3u, 0x748f82eeu, 0x78a5636fu, 0x84c87814u, 0x8cc70208u, 0x90befffau, 0xa4506cebu, 0xbef9a3f7u, 0xc67178f2u}; -static u32 sha256_rotr32(u32 v, u32 n) { - return (v >> n) | (v << (32 - n)); -} +static u32 sha256_rotr32(u32 v, u32 n) { return (v >> n) | (v << (32 - n)); } void sha256_init(Sha256* s) { s->h[0] = 0x6a09e667u; @@ -40,21 +38,19 @@ static void sha256_block(Sha256* s, const u8* p) { w[i] = ((u32)p[i * 4] << 24) | ((u32)p[i * 4 + 1] << 16) | ((u32)p[i * 4 + 2] << 8) | (u32)p[i * 4 + 3]; for (u32 i = 16; i < 64; ++i) { - u32 s0 = sha256_rotr32(w[i - 15], 7) ^ - sha256_rotr32(w[i - 15], 18) ^ (w[i - 15] >> 3); - u32 s1 = sha256_rotr32(w[i - 2], 17) ^ - sha256_rotr32(w[i - 2], 19) ^ (w[i - 2] >> 10); + u32 s0 = sha256_rotr32(w[i - 15], 7) ^ sha256_rotr32(w[i - 15], 18) ^ + (w[i - 15] >> 3); + u32 s1 = sha256_rotr32(w[i - 2], 17) ^ sha256_rotr32(w[i - 2], 19) ^ + (w[i - 2] >> 10); w[i] = w[i - 16] + s0 + w[i - 7] + s1; } u32 a = s->h[0], b = s->h[1], cc = s->h[2], d = s->h[3]; u32 e = s->h[4], f = s->h[5], g = s->h[6], hh = s->h[7]; for (u32 i = 0; i < 64; ++i) { - u32 S1 = sha256_rotr32(e, 6) ^ sha256_rotr32(e, 11) ^ - sha256_rotr32(e, 25); + u32 S1 = sha256_rotr32(e, 6) ^ sha256_rotr32(e, 11) ^ sha256_rotr32(e, 25); u32 ch = (e & f) ^ ((~e) & g); u32 t1 = hh + S1 + ch + SHA256_K[i] + w[i]; - u32 S0 = sha256_rotr32(a, 2) ^ sha256_rotr32(a, 13) ^ - sha256_rotr32(a, 22); + u32 S0 = sha256_rotr32(a, 2) ^ sha256_rotr32(a, 13) ^ sha256_rotr32(a, 22); u32 mj = (a & b) ^ (a & cc) ^ (b & cc); u32 t2 = S0 + mj; hh = g; diff --git a/src/core/slice.c b/src/core/slice.c @@ -4,7 +4,7 @@ Slice slice_from_cstr(const char* z) { if (!z) return SLICE_NULL; - return (Slice){ .s = z, .len = strlen(z) }; + return (Slice){.s = z, .len = strlen(z)}; } bool slice_eq(Slice a, Slice b) { @@ -24,5 +24,5 @@ bool slice_eq_cstr(Slice a, const char* z) { Slice slice_dup(Arena* arena, Slice in) { char* dst = arena_strdup(arena, in.s, in.len); - return (Slice){ .s = dst, .len = in.len }; + return (Slice){.s = dst, .len = in.len}; } diff --git a/src/core/slice.h b/src/core/slice.h @@ -17,15 +17,16 @@ typedef CfreeSlice Slice; /* Build a slice from a string literal (length is compile-time, no strlen). */ -#define SLICE_LIT(lit) ((Slice){ .s = (lit), .len = sizeof(lit) - 1 }) +#define SLICE_LIT(lit) ((Slice){.s = (lit), .len = sizeof(lit) - 1}) /* The empty slice. */ -#define SLICE_NULL ((Slice){ .s = NULL, .len = 0 }) +#define SLICE_NULL ((Slice){.s = NULL, .len = 0}) /* Spread a slice into printf "%.*s" arguments. */ #define SLICE_ARG(x) CFREE_SLICE_ARG(x) /* Boundary helper: lift a NUL-terminated C string into a slice. The only * sanctioned NUL scan; use exclusively where a string arrives from the OS - * (argv, getenv) or another NUL-terminated foreign API. NULL yields SLICE_NULL. */ + * (argv, getenv) or another NUL-terminated foreign API. NULL yields SLICE_NULL. + */ Slice slice_from_cstr(const char* z); /* Byte-exact equality. */ diff --git a/src/core/source.c b/src/core/source.c @@ -115,8 +115,7 @@ CfreeStatus source_add_file(SourceManager* sm, const char* path, system_header, id_out); } -CfreeStatus source_add_memory(SourceManager* sm, CfreeSlice name, - u32* id_out) { +CfreeStatus source_add_memory(SourceManager* sm, CfreeSlice name, u32* id_out) { return file_register(sm, name, SRC_FILE_MEMORY, 0, id_out); } diff --git a/src/core/strbuf.h b/src/core/strbuf.h @@ -48,7 +48,7 @@ static inline const char* strbuf_cstr(const StrBuf* sb) { return sb->base; } * NUL-terminated, so the slice's `.s` is safe to hand to NUL-requiring * boundaries while `.len` carries the exact length. */ static inline Slice strbuf_slice(const StrBuf* sb) { - return (Slice){ .s = sb->base, .len = strbuf_len(sb) }; + return (Slice){.s = sb->base, .len = strbuf_len(sb)}; } static inline void strbuf_putc(StrBuf* sb, char c) { diff --git a/src/dbg/bp.c b/src/dbg/bp.c @@ -6,10 +6,10 @@ * of the patched range substitute the saved bytes so `x` and disasm stay * honest. */ -#include "dbg/dbg.h" - #include <string.h> +#include "dbg/dbg.h" + static u32 bp_find_slot(DbgBpTable* t, uint64_t addr) { u32 i; for (i = 0; i < t->cap; ++i) { @@ -27,8 +27,8 @@ static u32 bp_alloc_slot(CfreeJitSession* s) { /* grow */ { u32 ncap = t->cap ? t->cap * 2 : 16; - DbgBp* nslots = (DbgBp*)s->heap->alloc(s->heap, sizeof(DbgBp) * ncap, - _Alignof(DbgBp)); + DbgBp* nslots = + (DbgBp*)s->heap->alloc(s->heap, sizeof(DbgBp) * ncap, _Alignof(DbgBp)); if (!nslots) return (u32)-1; memset(nslots, 0, sizeof(DbgBp) * ncap); if (t->slots) { @@ -80,8 +80,7 @@ static CfreeStatus bp_install_patch(CfreeJitSession* s, DbgBp* b) { uint8_t patch[ARCH_DBG_MAX_TRAP_BYTES]; u32 patch_len = 0; CfreeStatus st; - if (!s->arch_dbg || !s->arch_dbg->breakpoint_patch) - return CFREE_UNSUPPORTED; + if (!s->arch_dbg || !s->arch_dbg->breakpoint_patch) return CFREE_UNSUPPORTED; st = s->arch_dbg->breakpoint_patch(patch, (u32)sizeof(patch), &patch_len); if (st != CFREE_OK) return st; if (patch_len == 0 || patch_len > sizeof(b->saved)) return CFREE_ERR; @@ -123,7 +122,8 @@ static CfreeStatus bp_set_common(CfreeJitSession* s, DbgBp* b; /* Internal bps may live in the displaced-step scratch page, which is * outside the JIT image; only user bps are constrained to image range. */ - if (!internal && !cfree_jit_image_contains(s->jit, addr)) return CFREE_INVALID; + if (!internal && !cfree_jit_image_contains(s->jit, addr)) + return CFREE_INVALID; /* idempotent: existing slot at this address bumps refcount and returns * its already-issued id. */ diff --git a/src/dbg/dbg.h b/src/dbg/dbg.h @@ -35,9 +35,9 @@ typedef struct DbgBp { u8 saved[DBG_BP_MAX_INSN_LEN]; u32 saved_len; u32 refcount; - u32 user_id; /* public handle returned to caller; 0 = unused slot */ + u32 user_id; /* public handle returned to caller; 0 = unused slot */ u8 enabled; - u8 internal; /* set when the entry was armed by step.c */ + u8 internal; /* set when the entry was armed by step.c */ u16 pad; uint64_t hit_count; uint64_t skip_count; @@ -50,8 +50,8 @@ typedef struct DbgBpTable { DbgBp* slots; u32 cap; u32 count; - u32 next_user_id; /* monotonic, starts at 1 */ - u32 next_internal_id; /* monotonic, starts at DBG_BP_ID_INTERNAL_BASE */ + u32 next_user_id; /* monotonic, starts at 1 */ + u32 next_internal_id; /* monotonic, starts at DBG_BP_ID_INTERNAL_BASE */ } DbgBpTable; struct CfreeJitSession; /* fwd */ @@ -62,8 +62,8 @@ void dbg_bp_fini(struct CfreeJitSession*); /* set/clear with the user-facing handle space. The internal variants are * used by step.c for one-shot temporaries. */ CfreeStatus dbg_bp_set(struct CfreeJitSession*, uint64_t addr, u32* id_out); -CfreeStatus dbg_bp_set_spec(struct CfreeJitSession*, - const CfreeBreakpointSpec*, u32* id_out); +CfreeStatus dbg_bp_set_spec(struct CfreeJitSession*, const CfreeBreakpointSpec*, + u32* id_out); CfreeStatus dbg_bp_set_internal(struct CfreeJitSession*, uint64_t addr, u32* id_out); CfreeStatus dbg_bp_clear(struct CfreeJitSession*, u32 id); @@ -93,8 +93,8 @@ CfreeStatus dbg_mem_write(struct CfreeJitSession*, uint64_t addr, typedef struct DbgDisplaced { CfreeExecMemRegion region; int valid; - uint64_t orig_pc; /* original user PC of the insn being stepped */ - uint64_t return_pc; /* PC the shim's trap sentinel lives at */ + uint64_t orig_pc; /* original user PC of the insn being stepped */ + uint64_t return_pc; /* PC the shim's trap sentinel lives at */ uint64_t fallthrough_pc; uint32_t internal_bp; /* id of the one-shot bp at return_pc */ } DbgDisplaced; diff --git a/src/dbg/displaced.c b/src/dbg/displaced.c @@ -8,10 +8,10 @@ * the fault classifier sees the internal bp and the session uses * dbg_displaced_finalize to restore the user-visible PC. */ -#include "dbg/dbg.h" - #include <string.h> +#include "dbg/dbg.h" + CfreeStatus dbg_displaced_init(CfreeJitSession* s) { const CfreeExecMem* mem; CfreeStatus st; @@ -22,9 +22,9 @@ CfreeStatus dbg_displaced_init(CfreeJitSession* s) { st = mem->reserve(mem->user, DBG_SCRATCH_PAGE_SIZE, CFREE_PROT_READ | CFREE_PROT_EXEC, &s->displaced.region); if (st != CFREE_OK) return st; - st = mem->protect(mem->user, s->displaced.region.runtime, - s->displaced.region.size, - CFREE_PROT_READ | CFREE_PROT_EXEC); + st = + mem->protect(mem->user, s->displaced.region.runtime, + s->displaced.region.size, CFREE_PROT_READ | CFREE_PROT_EXEC); if (st != CFREE_OK) { mem->release(mem->user, &s->displaced.region); memset(&s->displaced.region, 0, sizeof(s->displaced.region)); diff --git a/src/dbg/mem.c b/src/dbg/mem.c @@ -3,10 +3,10 @@ * just delegates and then overlays original bytes from the bp table * over any patched ranges in read results. */ -#include "dbg/dbg.h" - #include <string.h> +#include "dbg/dbg.h" + CfreeStatus dbg_mem_read(CfreeJitSession* s, uint64_t addr, void* dst, size_t n) { CfreeStatus st; diff --git a/src/dbg/session.c b/src/dbg/session.c @@ -7,10 +7,10 @@ * on_fault here; this TU is also the only place that touches the public * CfreeJitSession entries. */ -#include "dbg/dbg.h" - #include <string.h> +#include "dbg/dbg.h" + /* ---- fault classification ------------------------------------------- */ static int signo_is_trap(int signo) { @@ -171,83 +171,77 @@ park: static void worker_run_entry(void* arg) { CfreeJitSession* s = (CfreeJitSession*)arg; typedef int (*EntryIntArgv)(int, char**); - typedef uint64_t (*EntryU64_0)(void); - typedef uint64_t (*EntryU64_1)(uint64_t); - typedef uint64_t (*EntryU64_2)(uint64_t, uint64_t); - typedef uint64_t (*EntryU64_3)(uint64_t, uint64_t, uint64_t); - typedef uint64_t (*EntryU64_4)(uint64_t, uint64_t, uint64_t, uint64_t); - typedef uint64_t (*EntryU64_5)(uint64_t, uint64_t, uint64_t, uint64_t, - uint64_t); - typedef uint64_t (*EntryU64_6)(uint64_t, uint64_t, uint64_t, uint64_t, - uint64_t, uint64_t); - typedef uint64_t (*EntryU64_7)(uint64_t, uint64_t, uint64_t, uint64_t, - uint64_t, uint64_t, uint64_t); - typedef uint64_t (*EntryU64_8)(uint64_t, uint64_t, uint64_t, uint64_t, - uint64_t, uint64_t, uint64_t, uint64_t); - int ret = 0; - switch (s->entry_kind) { - case CFREE_ENTRY_INT_ARGV: - ret = ((EntryIntArgv)s->entry)(s->entry_argc, s->entry_argv); + typedef uint64_t (*EntryU64_0)(void); + typedef uint64_t (*EntryU64_1)(uint64_t); + typedef uint64_t (*EntryU64_2)(uint64_t, uint64_t); + typedef uint64_t (*EntryU64_3)(uint64_t, uint64_t, uint64_t); + typedef uint64_t (*EntryU64_4)(uint64_t, uint64_t, uint64_t, uint64_t); + typedef uint64_t (*EntryU64_5)(uint64_t, uint64_t, uint64_t, uint64_t, + uint64_t); + typedef uint64_t (*EntryU64_6)(uint64_t, uint64_t, uint64_t, uint64_t, + uint64_t, uint64_t); + typedef uint64_t (*EntryU64_7)(uint64_t, uint64_t, uint64_t, uint64_t, + uint64_t, uint64_t, uint64_t); + typedef uint64_t (*EntryU64_8)(uint64_t, uint64_t, uint64_t, uint64_t, + uint64_t, uint64_t, uint64_t, uint64_t); + int ret = 0; + switch (s->entry_kind) { + case CFREE_ENTRY_INT_ARGV: + ret = ((EntryIntArgv)s->entry)(s->entry_argc, s->entry_argv); + break; + case CFREE_ENTRY_U64: + switch (s->entry_u64_nargs) { + case 0: + s->entry_u64_ret = ((EntryU64_0)s->entry)(); + break; + case 1: + s->entry_u64_ret = ((EntryU64_1)s->entry)(s->entry_u64_args[0]); + break; + case 2: + s->entry_u64_ret = ((EntryU64_2)s->entry)(s->entry_u64_args[0], + s->entry_u64_args[1]); + break; + case 3: + s->entry_u64_ret = ((EntryU64_3)s->entry)( + s->entry_u64_args[0], s->entry_u64_args[1], s->entry_u64_args[2]); break; - case CFREE_ENTRY_U64: - switch (s->entry_u64_nargs) { - case 0: - s->entry_u64_ret = ((EntryU64_0)s->entry)(); - break; - case 1: - s->entry_u64_ret = - ((EntryU64_1)s->entry)(s->entry_u64_args[0]); - break; - case 2: - s->entry_u64_ret = ((EntryU64_2)s->entry)( - s->entry_u64_args[0], s->entry_u64_args[1]); - break; - case 3: - s->entry_u64_ret = ((EntryU64_3)s->entry)( - s->entry_u64_args[0], s->entry_u64_args[1], - s->entry_u64_args[2]); - break; - case 4: - s->entry_u64_ret = ((EntryU64_4)s->entry)( - s->entry_u64_args[0], s->entry_u64_args[1], - s->entry_u64_args[2], s->entry_u64_args[3]); - break; - case 5: - s->entry_u64_ret = ((EntryU64_5)s->entry)( - s->entry_u64_args[0], s->entry_u64_args[1], - s->entry_u64_args[2], s->entry_u64_args[3], - s->entry_u64_args[4]); - break; - case 6: - s->entry_u64_ret = ((EntryU64_6)s->entry)( - s->entry_u64_args[0], s->entry_u64_args[1], - s->entry_u64_args[2], s->entry_u64_args[3], - s->entry_u64_args[4], s->entry_u64_args[5]); - break; - case 7: - s->entry_u64_ret = ((EntryU64_7)s->entry)( - s->entry_u64_args[0], s->entry_u64_args[1], - s->entry_u64_args[2], s->entry_u64_args[3], - s->entry_u64_args[4], s->entry_u64_args[5], - s->entry_u64_args[6]); - break; - case 8: - s->entry_u64_ret = ((EntryU64_8)s->entry)( - s->entry_u64_args[0], s->entry_u64_args[1], - s->entry_u64_args[2], s->entry_u64_args[3], - s->entry_u64_args[4], s->entry_u64_args[5], - s->entry_u64_args[6], s->entry_u64_args[7]); - break; - default: - s->entry_u64_ret = 0; - break; - } - ret = (int)s->entry_u64_ret; + case 4: + s->entry_u64_ret = ((EntryU64_4)s->entry)( + s->entry_u64_args[0], s->entry_u64_args[1], s->entry_u64_args[2], + s->entry_u64_args[3]); + break; + case 5: + s->entry_u64_ret = ((EntryU64_5)s->entry)( + s->entry_u64_args[0], s->entry_u64_args[1], s->entry_u64_args[2], + s->entry_u64_args[3], s->entry_u64_args[4]); + break; + case 6: + s->entry_u64_ret = ((EntryU64_6)s->entry)( + s->entry_u64_args[0], s->entry_u64_args[1], s->entry_u64_args[2], + s->entry_u64_args[3], s->entry_u64_args[4], s->entry_u64_args[5]); + break; + case 7: + s->entry_u64_ret = ((EntryU64_7)s->entry)( + s->entry_u64_args[0], s->entry_u64_args[1], s->entry_u64_args[2], + s->entry_u64_args[3], s->entry_u64_args[4], s->entry_u64_args[5], + s->entry_u64_args[6]); + break; + case 8: + s->entry_u64_ret = ((EntryU64_8)s->entry)( + s->entry_u64_args[0], s->entry_u64_args[1], s->entry_u64_args[2], + s->entry_u64_args[3], s->entry_u64_args[4], s->entry_u64_args[5], + s->entry_u64_args[6], s->entry_u64_args[7]); + break; + default: + s->entry_u64_ret = 0; break; } - memset(&s->stop, 0, sizeof(s->stop)); - s->stop.kind = CFREE_STOP_EXIT; - s->stop.exit_code = ret; + ret = (int)s->entry_u64_ret; + break; + } + memset(&s->stop, 0, sizeof(s->stop)); + s->stop.kind = CFREE_STOP_EXIT; + s->stop.exit_code = ret; } static void worker_main(void* arg) { @@ -304,7 +298,8 @@ CfreeStatus cfree_jit_session_new(CfreeJit* jit, const CfreeDbgHost* host, } heap = c->ctx->heap; - s = (CfreeJitSession*)heap->alloc(heap, sizeof(*s), _Alignof(CfreeJitSession)); + s = (CfreeJitSession*)heap->alloc(heap, sizeof(*s), + _Alignof(CfreeJitSession)); if (!s) return CFREE_NOMEM; memset(s, 0, sizeof(*s)); s->jit = jit; diff --git a/src/dbg/step.c b/src/dbg/step.c @@ -5,11 +5,10 @@ * drive their own signal/wait cycles in-loop and set pending_done so the outer * resume short-circuits. */ -#include "dbg/dbg.h" - #include <string.h> #include "core/slice.h" +#include "dbg/dbg.h" #define DBG_STEP_LINE_INSN_CAP 1024u @@ -156,7 +155,8 @@ static CfreeStatus run_next_line(CfreeJitSession* s) { u32 bp_id = 0; CfreeStatus st; frame.pc = step_rt_to_img(s, frame.pc); - if (cfree_dwarf_unwind_step(s->dwarf, &frame) != CFREE_OK || frame.pc == 0) { + if (cfree_dwarf_unwind_step(s->dwarf, &frame) != CFREE_OK || + frame.pc == 0) { /* Fall back to stepping into the call. */ return run_step_line_loop(s); } diff --git a/src/debug/debug.c b/src/debug/debug.c @@ -14,7 +14,8 @@ static _Noreturn void debug_oom(Debug* d, const char* what) { SrcLoc nl = {0, 0, 0}; - compiler_panic(d->c, nl, "debug: oom (%.*s)", SLICE_ARG(slice_from_cstr(what))); + compiler_panic(d->c, nl, "debug: oom (%.*s)", + SLICE_ARG(slice_from_cstr(what))); } static DebugTypeId type_alloc(Debug* d) { @@ -112,9 +113,9 @@ static void split_path(Pool* p, Sym path, Sym* dir_out, Sym* base_out) { *base_out = path; return; } - *dir_out = pool_intern_slice(p, (Slice){ .s = s, .len = slash }); + *dir_out = pool_intern_slice(p, (Slice){.s = s, .len = slash}); *base_out = - pool_intern_slice(p, (Slice){ .s = s + slash + 1, .len = len - slash - 1 }); + pool_intern_slice(p, (Slice){.s = s + slash + 1, .len = len - slash - 1}); } u32 debug_file(Debug* d, u32 source_file_id) { diff --git a/src/debug/debug_emit.c b/src/debug/debug_emit.c @@ -24,7 +24,7 @@ #include "core/vec.h" #include "debug/debug_internal.h" -void abbrev_fini_heap(DebugAbbrevPool *p, Heap *h); +void abbrev_fini_heap(DebugAbbrevPool* p, Heap* h); /* ---------------------------------------------------------------- */ /* String tables. */ @@ -33,12 +33,12 @@ typedef struct StrTab { Buf buf; SymToU32 by_sym; /* Sym → byte offset within buf */ /* Insertion order — used to populate .debug_str_offsets. */ - Sym *syms; + Sym* syms; u32 nsyms; u32 syms_cap; } StrTab; -static void str_init(StrTab *s, Heap *h) { +static void str_init(StrTab* s, Heap* h) { buf_init(&s->buf, h); SymToU32_init(&s->by_sym, h); s->syms = NULL; @@ -46,50 +46,44 @@ static void str_init(StrTab *s, Heap *h) { s->syms_cap = 0; } -static void str_fini(StrTab *s, Heap *h) { +static void str_fini(StrTab* s, Heap* h) { buf_fini(&s->buf); SymToU32_fini(&s->by_sym); - if (s->syms) - h->free(h, s->syms, sizeof(Sym) * s->syms_cap); + if (s->syms) h->free(h, s->syms, sizeof(Sym) * s->syms_cap); s->syms = NULL; s->nsyms = 0; s->syms_cap = 0; } -static u32 str_intern(StrTab *s, Heap *h, Pool *pool, Sym sym) { - u32 *found; +static u32 str_intern(StrTab* s, Heap* h, Pool* pool, Sym sym) { + u32* found; u32 ofs; size_t len; - const char *str; - if (sym == 0) - sym = pool_intern_slice(pool, SLICE_LIT("")); + const char* str; + if (sym == 0) sym = pool_intern_slice(pool, SLICE_LIT("")); found = SymToU32_get(&s->by_sym, sym); - if (found) - return *found; + if (found) return *found; ofs = buf_pos(&s->buf); { Slice sl = pool_slice(pool, sym); str = sl.s; len = sl.len; } - if (str && len) - buf_write(&s->buf, str, len); + if (str && len) buf_write(&s->buf, str, len); { u8 nul = 0; buf_write(&s->buf, &nul, 1); } SymToU32_set(&s->by_sym, sym, ofs); - if (VEC_GROW(h, s->syms, s->syms_cap, s->nsyms + 1)) - return ofs; + if (VEC_GROW(h, s->syms, s->syms_cap, s->nsyms + 1)) return ofs; s->syms[s->nsyms++] = sym; return ofs; } -static u32 str_index_of(StrTab *s, Sym sym) { +static u32 str_index_of(StrTab* s, Sym sym) { u32 i; for (i = 0; i < s->nsyms; ++i) { - if (s->syms[i] == sym) - return i; + if (s->syms[i] == sym) return i; } return 0; } @@ -109,10 +103,10 @@ typedef struct AddrReloc { } AddrReloc; typedef struct EmitCtx { - Debug *d; - Heap *heap; - Pool *pool; - ObjBuilder *ob; + Debug* d; + Heap* heap; + Pool* pool; + ObjBuilder* ob; StrTab str; /* .debug_str */ StrTab line_str; /* .debug_line_str */ @@ -146,27 +140,27 @@ typedef struct EmitCtx { Buf info_body; /* Forward type-ref fixups (info_body-relative). */ - DieFixup *fixups; + DieFixup* fixups; u32 nfixups; u32 fixups_cap; /* low_pc relocs in .debug_info (info_body-relative offset). */ - AddrReloc *info_relocs; + AddrReloc* info_relocs; u32 ninfo_relocs; u32 info_relocs_cap; /* line-program address relocs (.debug_line offset within program region). */ - AddrReloc *line_relocs; + AddrReloc* line_relocs; u32 nline_relocs; u32 line_relocs_cap; /* aranges relocs (section-relative once we know offsets). */ - AddrReloc *aranges_relocs; + AddrReloc* aranges_relocs; u32 naranges_relocs; u32 aranges_relocs_cap; /* rnglists relocs. */ - AddrReloc *rng_relocs; + AddrReloc* rng_relocs; u32 nrng_relocs; u32 nrng_relocs_cap; @@ -210,17 +204,16 @@ typedef struct EmitCtx { /* ---------------------------------------------------------------- */ -static void add_fixup(EmitCtx *e, u32 buf_offset, DebugTypeId target) { - DieFixup *fx; - if (VEC_GROW(e->heap, e->fixups, e->fixups_cap, e->nfixups + 1)) - return; +static void add_fixup(EmitCtx* e, u32 buf_offset, DebugTypeId target) { + DieFixup* fx; + if (VEC_GROW(e->heap, e->fixups, e->fixups_cap, e->nfixups + 1)) return; fx = &e->fixups[e->nfixups++]; fx->buf_offset = buf_offset; fx->target = target; } -static void add_info_reloc(EmitCtx *e, u32 buf_offset, ObjSymId sym) { - AddrReloc *r; +static void add_info_reloc(EmitCtx* e, u32 buf_offset, ObjSymId sym) { + AddrReloc* r; if (VEC_GROW(e->heap, e->info_relocs, e->info_relocs_cap, e->ninfo_relocs + 1)) return; @@ -230,8 +223,8 @@ static void add_info_reloc(EmitCtx *e, u32 buf_offset, ObjSymId sym) { r->section = OBJ_SEC_NONE; } -static void add_line_reloc(EmitCtx *e, u32 buf_offset, ObjSymId sym) { - AddrReloc *r; +static void add_line_reloc(EmitCtx* e, u32 buf_offset, ObjSymId sym) { + AddrReloc* r; if (VEC_GROW(e->heap, e->line_relocs, e->line_relocs_cap, e->nline_relocs + 1)) return; @@ -241,8 +234,8 @@ static void add_line_reloc(EmitCtx *e, u32 buf_offset, ObjSymId sym) { r->section = OBJ_SEC_NONE; } -static void add_aranges_reloc(EmitCtx *e, u32 buf_offset, ObjSymId sym) { - AddrReloc *r; +static void add_aranges_reloc(EmitCtx* e, u32 buf_offset, ObjSymId sym) { + AddrReloc* r; if (VEC_GROW(e->heap, e->aranges_relocs, e->aranges_relocs_cap, e->naranges_relocs + 1)) return; @@ -252,8 +245,8 @@ static void add_aranges_reloc(EmitCtx *e, u32 buf_offset, ObjSymId sym) { r->section = OBJ_SEC_NONE; } -static void add_rng_reloc(EmitCtx *e, u32 buf_offset, ObjSymId sym) { - AddrReloc *r; +static void add_rng_reloc(EmitCtx* e, u32 buf_offset, ObjSymId sym) { + AddrReloc* r; if (VEC_GROW(e->heap, e->rng_relocs, e->nrng_relocs_cap, e->nrng_relocs + 1)) return; r = &e->rng_relocs[e->nrng_relocs++]; @@ -265,7 +258,7 @@ static void add_rng_reloc(EmitCtx *e, u32 buf_offset, ObjSymId sym) { /* ---------------------------------------------------------------- */ /* String emit shortcuts. */ -static void emit_strx4(EmitCtx *e, Buf *b, Sym name) { +static void emit_strx4(EmitCtx* e, Buf* b, Sym name) { str_intern(&e->str, e->heap, e->pool, name); { Sym key = name ? name : pool_intern_slice(e->pool, SLICE_LIT("")); @@ -274,19 +267,19 @@ static void emit_strx4(EmitCtx *e, Buf *b, Sym name) { } } -static u32 line_str_offset(EmitCtx *e, Sym sym) { +static u32 line_str_offset(EmitCtx* e, Sym sym) { return str_intern(&e->line_str, e->heap, e->pool, sym); } /* ---------------------------------------------------------------- */ /* Abbrev resolution. */ -static u32 abbr_intern(EmitCtx *e, u16 tag, u8 has_children, - const DebugAbbrevAttr *attrs, u32 nattrs) { +static u32 abbr_intern(EmitCtx* e, u16 tag, u8 has_children, + const DebugAbbrevAttr* attrs, u32 nattrs) { return abbrev_intern(&e->abbr, e->heap, tag, has_children, attrs, nattrs); } -static void resolve_abbrevs(EmitCtx *e) { +static void resolve_abbrevs(EmitCtx* e) { /* Order of intern == order of code assignment. */ { DebugAbbrevAttr a[] = { @@ -416,9 +409,9 @@ static void resolve_abbrevs(EmitCtx *e) { /* ---------------------------------------------------------------- */ /* Per-type DIE emission. */ -static void emit_type_die(EmitCtx *e, DebugTypeId id); +static void emit_type_die(EmitCtx* e, DebugTypeId id); -static void emit_type_ref(EmitCtx *e, DebugTypeId tid) { +static void emit_type_ref(EmitCtx* e, DebugTypeId tid) { u32 ofs = buf_pos(&e->info_body); u32 placeholder = 0; buf_write(&e->info_body, &placeholder, 4); @@ -429,195 +422,192 @@ static void emit_type_ref(EmitCtx *e, DebugTypeId tid) { static u8 base_enc(DebugBaseEncoding enc) { switch (enc) { - case DEBUG_BE_BOOL: - return DW_ATE_boolean; - case DEBUG_BE_SIGNED: - return DW_ATE_signed; - case DEBUG_BE_UNSIGNED: - return DW_ATE_unsigned; - case DEBUG_BE_SIGNED_CHAR: - return DW_ATE_signed_char; - case DEBUG_BE_UNSIGNED_CHAR: - return DW_ATE_unsigned_char; - case DEBUG_BE_FLOAT: - return DW_ATE_float; - case DEBUG_BE_UTF: - return DW_ATE_UTF; - case DEBUG_BE_ADDRESS: - return DW_ATE_address; + case DEBUG_BE_BOOL: + return DW_ATE_boolean; + case DEBUG_BE_SIGNED: + return DW_ATE_signed; + case DEBUG_BE_UNSIGNED: + return DW_ATE_unsigned; + case DEBUG_BE_SIGNED_CHAR: + return DW_ATE_signed_char; + case DEBUG_BE_UNSIGNED_CHAR: + return DW_ATE_unsigned_char; + case DEBUG_BE_FLOAT: + return DW_ATE_float; + case DEBUG_BE_UTF: + return DW_ATE_UTF; + case DEBUG_BE_ADDRESS: + return DW_ATE_address; } return DW_ATE_signed; } -static void emit_type_die(EmitCtx *e, DebugTypeId id) { - DebugType *t; - Debug *d = e->d; - if (id == DEBUG_TYPE_NONE || id > d->ntypes) - return; +static void emit_type_die(EmitCtx* e, DebugTypeId id) { + DebugType* t; + Debug* d = e->d; + if (id == DEBUG_TYPE_NONE || id > d->ntypes) return; t = &d->types[id - 1]; - if (t->die_offset != 0) - return; + if (t->die_offset != 0) return; switch ((DebugTypeKind)t->kind) { - case DTK_VOID: - /* No DIE — t->die_offset stays 0; refs will encode as 0 (consumer - * interprets as void). */ - return; - case DTK_BASE: - t->die_offset = buf_pos(&e->info_body); - form_uleb(&e->info_body, e->abbr_base); - emit_strx4(e, &e->info_body, t->name); - form_u8(&e->info_body, base_enc((DebugBaseEncoding)t->base_encoding)); - form_u8(&e->info_body, (u8)t->byte_size); - return; - case DTK_PTR: - t->die_offset = buf_pos(&e->info_body); - form_uleb(&e->info_body, e->abbr_ptr); - form_u8(&e->info_body, (u8)t->byte_size); - emit_type_ref(e, t->inner); - return; - case DTK_TYPEDEF: - t->die_offset = buf_pos(&e->info_body); - form_uleb(&e->info_body, e->abbr_typedef); - emit_strx4(e, &e->info_body, t->name); - emit_type_ref(e, t->inner); - return; - case DTK_CONST: - t->die_offset = buf_pos(&e->info_body); - form_uleb(&e->info_body, e->abbr_qual_const); - emit_type_ref(e, t->inner); - return; - case DTK_VOLATILE: - t->die_offset = buf_pos(&e->info_body); - form_uleb(&e->info_body, e->abbr_qual_volatile); - emit_type_ref(e, t->inner); - return; - case DTK_RESTRICT: - t->die_offset = buf_pos(&e->info_body); - form_uleb(&e->info_body, e->abbr_qual_restrict); - emit_type_ref(e, t->inner); - return; - case DTK_ARRAY: - t->die_offset = buf_pos(&e->info_body); - form_uleb(&e->info_body, e->abbr_array); - emit_type_ref(e, t->inner); - if (t->array_count) { - form_uleb(&e->info_body, e->abbr_array_subrange); - form_uleb(&e->info_body, t->array_count); - } else { - form_uleb(&e->info_body, e->abbr_array_subrange_unbounded); - } - form_uleb(&e->info_body, 0); - return; - case DTK_FUNC: { - u32 i; - t->die_offset = buf_pos(&e->info_body); - form_uleb(&e->info_body, e->abbr_func_type); - emit_type_ref(e, t->inner); - /* DW_AT_prototyped flag_present has no body */ - for (i = 0; i < t->nparams; ++i) { - form_uleb(&e->info_body, e->abbr_func_type_param); - emit_type_ref(e, t->params[i]); + case DTK_VOID: + /* No DIE — t->die_offset stays 0; refs will encode as 0 (consumer + * interprets as void). */ + return; + case DTK_BASE: + t->die_offset = buf_pos(&e->info_body); + form_uleb(&e->info_body, e->abbr_base); + emit_strx4(e, &e->info_body, t->name); + form_u8(&e->info_body, base_enc((DebugBaseEncoding)t->base_encoding)); + form_u8(&e->info_body, (u8)t->byte_size); + return; + case DTK_PTR: + t->die_offset = buf_pos(&e->info_body); + form_uleb(&e->info_body, e->abbr_ptr); + form_u8(&e->info_body, (u8)t->byte_size); + emit_type_ref(e, t->inner); + return; + case DTK_TYPEDEF: + t->die_offset = buf_pos(&e->info_body); + form_uleb(&e->info_body, e->abbr_typedef); + emit_strx4(e, &e->info_body, t->name); + emit_type_ref(e, t->inner); + return; + case DTK_CONST: + t->die_offset = buf_pos(&e->info_body); + form_uleb(&e->info_body, e->abbr_qual_const); + emit_type_ref(e, t->inner); + return; + case DTK_VOLATILE: + t->die_offset = buf_pos(&e->info_body); + form_uleb(&e->info_body, e->abbr_qual_volatile); + emit_type_ref(e, t->inner); + return; + case DTK_RESTRICT: + t->die_offset = buf_pos(&e->info_body); + form_uleb(&e->info_body, e->abbr_qual_restrict); + emit_type_ref(e, t->inner); + return; + case DTK_ARRAY: + t->die_offset = buf_pos(&e->info_body); + form_uleb(&e->info_body, e->abbr_array); + emit_type_ref(e, t->inner); + if (t->array_count) { + form_uleb(&e->info_body, e->abbr_array_subrange); + form_uleb(&e->info_body, t->array_count); + } else { + form_uleb(&e->info_body, e->abbr_array_subrange_unbounded); + } + form_uleb(&e->info_body, 0); + return; + case DTK_FUNC: { + u32 i; + t->die_offset = buf_pos(&e->info_body); + form_uleb(&e->info_body, e->abbr_func_type); + emit_type_ref(e, t->inner); + /* DW_AT_prototyped flag_present has no body */ + for (i = 0; i < t->nparams; ++i) { + form_uleb(&e->info_body, e->abbr_func_type_param); + emit_type_ref(e, t->params[i]); + } + form_uleb(&e->info_body, 0); + return; } - form_uleb(&e->info_body, 0); - return; - } - case DTK_RECORD: { - u32 i; - t->die_offset = buf_pos(&e->info_body); - form_uleb(&e->info_body, t->is_union ? e->abbr_union : e->abbr_struct); - emit_strx4(e, &e->info_body, t->name); - form_uleb(&e->info_body, t->byte_size); - for (i = 0; i < t->nfields; ++i) { - DebugRecField *f = &t->fields[i]; - form_uleb(&e->info_body, e->abbr_member); - emit_strx4(e, &e->info_body, f->name); - emit_type_ref(e, f->type); - form_uleb(&e->info_body, f->byte_offset); + case DTK_RECORD: { + u32 i; + t->die_offset = buf_pos(&e->info_body); + form_uleb(&e->info_body, t->is_union ? e->abbr_union : e->abbr_struct); + emit_strx4(e, &e->info_body, t->name); + form_uleb(&e->info_body, t->byte_size); + for (i = 0; i < t->nfields; ++i) { + DebugRecField* f = &t->fields[i]; + form_uleb(&e->info_body, e->abbr_member); + emit_strx4(e, &e->info_body, f->name); + emit_type_ref(e, f->type); + form_uleb(&e->info_body, f->byte_offset); + } + form_uleb(&e->info_body, 0); + return; } - form_uleb(&e->info_body, 0); - return; - } - case DTK_ENUM: { - u32 i; - DebugType *base; - t->die_offset = buf_pos(&e->info_body); - form_uleb(&e->info_body, e->abbr_enum); - emit_strx4(e, &e->info_body, t->name); - emit_type_ref(e, t->inner); - base = (t->inner != DEBUG_TYPE_NONE && t->inner <= e->d->ntypes) - ? &e->d->types[t->inner - 1] - : NULL; - form_uleb(&e->info_body, base ? base->byte_size : 4); - for (i = 0; i < t->nenums; ++i) { - form_uleb(&e->info_body, e->abbr_enum_val); - emit_strx4(e, &e->info_body, t->enum_vals[i].name); - form_sleb(&e->info_body, t->enum_vals[i].value); + case DTK_ENUM: { + u32 i; + DebugType* base; + t->die_offset = buf_pos(&e->info_body); + form_uleb(&e->info_body, e->abbr_enum); + emit_strx4(e, &e->info_body, t->name); + emit_type_ref(e, t->inner); + base = (t->inner != DEBUG_TYPE_NONE && t->inner <= e->d->ntypes) + ? &e->d->types[t->inner - 1] + : NULL; + form_uleb(&e->info_body, base ? base->byte_size : 4); + for (i = 0; i < t->nenums; ++i) { + form_uleb(&e->info_body, e->abbr_enum_val); + emit_strx4(e, &e->info_body, t->enum_vals[i].name); + form_sleb(&e->info_body, t->enum_vals[i].value); + } + form_uleb(&e->info_body, 0); + return; } - form_uleb(&e->info_body, 0); - return; - } } } /* ---------------------------------------------------------------- */ /* Variable / scope emission. */ -static void emit_var_loc_exprloc(EmitCtx *e, Buf *b, DebugVarLoc loc) { +static void emit_var_loc_exprloc(EmitCtx* e, Buf* b, DebugVarLoc loc) { u8 expr[32]; u32 n = 0; switch ((DebugVarLocKind)loc.kind) { - case DVL_REG: - if (loc.v.reg < 32) { - expr[n++] = (u8)(DW_OP_reg0 + loc.v.reg); - } else { - u64 v = loc.v.reg; - expr[n++] = DW_OP_regx; - while (v >= 0x80) { - expr[n++] = (u8)((v & 0x7f) | 0x80); + case DVL_REG: + if (loc.v.reg < 32) { + expr[n++] = (u8)(DW_OP_reg0 + loc.v.reg); + } else { + u64 v = loc.v.reg; + expr[n++] = DW_OP_regx; + while (v >= 0x80) { + expr[n++] = (u8)((v & 0x7f) | 0x80); + v >>= 7; + } + expr[n++] = (u8)v; + } + break; + case DVL_FRAME: { + i64 v = loc.v.frame_ofs; + int more = 1; + expr[n++] = DW_OP_fbreg; + while (more) { + u8 byte = (u8)(v & 0x7f); v >>= 7; + if ((v == 0 && (byte & 0x40) == 0) || (v == -1 && (byte & 0x40) != 0)) { + more = 0; + } else { + byte |= 0x80; + } + expr[n++] = byte; } - expr[n++] = (u8)v; + break; } - break; - case DVL_FRAME: { - i64 v = loc.v.frame_ofs; - int more = 1; - expr[n++] = DW_OP_fbreg; - while (more) { - u8 byte = (u8)(v & 0x7f); - v >>= 7; - if ((v == 0 && (byte & 0x40) == 0) || (v == -1 && (byte & 0x40) != 0)) { - more = 0; - } else { - byte |= 0x80; - } - expr[n++] = byte; + case DVL_GLOBAL: { + /* DW_OP_addr <ptr_size>: relocation against the symbol. We can't + * place a section reloc inside an exprloc body without computing + * its absolute info-section offset post-emit. For Phase 1 we emit + * the literal symbol value as zero and trust that DVL_GLOBAL is + * not yet exercised by any harness case. Documented in the + * agent report as a Phase-1 limitation. */ + u32 i; + expr[n++] = DW_OP_addr; + for (i = 0; i < e->d->c->target.ptr_size; ++i) expr[n++] = 0; + (void)loc.v.global; + break; } - break; - } - case DVL_GLOBAL: { - /* DW_OP_addr <ptr_size>: relocation against the symbol. We can't - * place a section reloc inside an exprloc body without computing - * its absolute info-section offset post-emit. For Phase 1 we emit - * the literal symbol value as zero and trust that DVL_GLOBAL is - * not yet exercised by any harness case. Documented in the - * agent report as a Phase-1 limitation. */ - u32 i; - expr[n++] = DW_OP_addr; - for (i = 0; i < e->d->c->target.ptr_size; ++i) - expr[n++] = 0; - (void)loc.v.global; - break; - } - case DVL_LOCLIST: - /* Phase 5: emit as DW_FORM_loclistx. Phase 1: empty expr. */ - break; + case DVL_LOCLIST: + /* Phase 5: emit as DW_FORM_loclistx. Phase 1: empty expr. */ + break; } form_uleb(b, n); buf_write(b, expr, n); } -static void emit_var_die(EmitCtx *e, DebugVarDIE *v) { +static void emit_var_die(EmitCtx* e, DebugVarDIE* v) { u32 abbrev = v->is_param ? e->abbr_param : e->abbr_var; v->die_offset = buf_pos(&e->info_body); form_uleb(&e->info_body, abbrev); @@ -628,16 +618,14 @@ static void emit_var_die(EmitCtx *e, DebugVarDIE *v) { emit_var_loc_exprloc(e, &e->info_body, v->loc); } -static void emit_scope_subtree(EmitCtx *e, DebugFunc *f, i32 scope_idx); +static void emit_scope_subtree(EmitCtx* e, DebugFunc* f, i32 scope_idx); -static void emit_vars_in_scope(EmitCtx *e, DebugFunc *f, i32 scope_idx) { +static void emit_vars_in_scope(EmitCtx* e, DebugFunc* f, i32 scope_idx) { u32 i; for (i = 0; i < f->nvars; ++i) { - DebugVarDIE *v = &f->vars[i]; - if (v->is_param) - continue; - if (v->scope_idx == scope_idx) - emit_var_die(e, v); + DebugVarDIE* v = &f->vars[i]; + if (v->is_param) continue; + if (v->scope_idx == scope_idx) emit_var_die(e, v); } { u32 s; @@ -649,23 +637,22 @@ static void emit_vars_in_scope(EmitCtx *e, DebugFunc *f, i32 scope_idx) { } } -static void emit_scope_subtree(EmitCtx *e, DebugFunc *f, i32 scope_idx) { +static void emit_scope_subtree(EmitCtx* e, DebugFunc* f, i32 scope_idx) { f->scopes[scope_idx].die_offset = buf_pos(&e->info_body); form_uleb(&e->info_body, e->abbr_lexical_block); emit_vars_in_scope(e, f, scope_idx); form_uleb(&e->info_body, 0); } -static void emit_subprogram_die(EmitCtx *e, DebugFunc *f) { - const ObjSym *osym = obj_symbol_get(e->ob, f->sym); +static void emit_subprogram_die(EmitCtx* e, DebugFunc* f) { + const ObjSym* osym = obj_symbol_get(e->ob, f->sym); Sym name = osym ? osym->name : 0; u32 reloc_off; u32 fn_size; DebugTypeId ret_type = DEBUG_TYPE_NONE; if (f->fn_type != DEBUG_TYPE_NONE && f->fn_type <= e->d->ntypes) { - DebugType *tt = &e->d->types[f->fn_type - 1]; - if (tt->kind == DTK_FUNC) - ret_type = tt->inner; + DebugType* tt = &e->d->types[f->fn_type - 1]; + if (tt->kind == DTK_FUNC) ret_type = tt->inner; } f->die_offset = buf_pos(&e->info_body); form_uleb(&e->info_body, e->abbr_subprogram); @@ -699,7 +686,7 @@ static void emit_subprogram_die(EmitCtx *e, DebugFunc *f) { } if (!emitted_params && f->fn_type != DEBUG_TYPE_NONE && f->fn_type <= e->d->ntypes) { - DebugType *tt = &e->d->types[f->fn_type - 1]; + DebugType* tt = &e->d->types[f->fn_type - 1]; if (tt->kind == DTK_FUNC) { for (i = 0; i < tt->nparams; ++i) { form_uleb(&e->info_body, e->abbr_func_type_param); @@ -715,7 +702,7 @@ static void emit_subprogram_die(EmitCtx *e, DebugFunc *f) { /* ---------------------------------------------------------------- */ /* Section flushing. */ -static ObjSecId mk_section(EmitCtx *e, const char *name) { +static ObjSecId mk_section(EmitCtx* e, const char* name) { Sym n = pool_intern_slice(e->pool, slice_from_cstr(name)); return obj_section(e->ob, n, SEC_DEBUG, 0, 1); } @@ -723,31 +710,29 @@ static ObjSecId mk_section(EmitCtx *e, const char *name) { /* Pre-create one SK_SECTION ObjSym pointing at `sec`. Section symbols are * nameless (Sym 0); identity is the section_id they reference. SB_LOCAL * because section symbols are always local in ELF/Mach-O. */ -static ObjSymId mk_section_sym(EmitCtx *e, ObjSecId sec) { +static ObjSymId mk_section_sym(EmitCtx* e, ObjSecId sec) { return obj_symbol(e->ob, 0, SB_LOCAL, SK_SECTION, sec, 0, 0); } -static void flatten_to_section(EmitCtx *e, ObjSecId sec, const Buf *src) { +static void flatten_to_section(EmitCtx* e, ObjSecId sec, const Buf* src) { u32 total = buf_pos(src); - if (total == 0) - return; + if (total == 0) return; { - u8 *dst = obj_reserve(e->ob, sec, total); - if (!dst) - return; + u8* dst = obj_reserve(e->ob, sec, total); + if (!dst) return; buf_flatten(src, dst); } } -static void emit_section_str(EmitCtx *e) { +static void emit_section_str(EmitCtx* e) { flatten_to_section(e, e->sec_str, &e->str.buf); } -static void emit_section_line_str(EmitCtx *e) { +static void emit_section_line_str(EmitCtx* e) { flatten_to_section(e, e->sec_line_str, &e->line_str.buf); } -static void emit_section_str_offsets(EmitCtx *e) { +static void emit_section_str_offsets(EmitCtx* e) { Buf b; u32 i; u32 unit_length; @@ -767,19 +752,19 @@ static void emit_section_str_offsets(EmitCtx *e) { * out) S=0 so the value is unchanged, and for the concatenated JIT * view S = view-prefix into .debug_str so the slot picks up the * right per-input offset. */ - u32 *ofs = SymToU32_get(&e->str.by_sym, e->str.syms[i]); + u32* ofs = SymToU32_get(&e->str.by_sym, e->str.syms[i]); form_u32(&b, ofs ? *ofs : 0); } flatten_to_section(e, e->sec_str_off, &b); for (i = 0; i < e->str.nsyms; ++i) { - u32 *ofs = SymToU32_get(&e->str.by_sym, e->str.syms[i]); + u32* ofs = SymToU32_get(&e->str.by_sym, e->str.syms[i]); obj_reloc(e->ob, e->sec_str_off, entries_off + i * 4u, R_ABS32, e->ssym_str, (i64)(ofs ? *ofs : 0)); } buf_fini(&b); } -static void emit_section_abbrev(EmitCtx *e) { +static void emit_section_abbrev(EmitCtx* e) { Buf b; buf_init(&b, e->heap); abbrev_encode(&e->abbr, &b); @@ -787,23 +772,22 @@ static void emit_section_abbrev(EmitCtx *e) { buf_fini(&b); } -static ArchDwarfOps debug_dwarf_ops(const Debug *d) { - const ArchImpl *arch = arch_for_compiler(d ? d->c : NULL); +static ArchDwarfOps debug_dwarf_ops(const Debug* d) { + const ArchImpl* arch = arch_for_compiler(d ? d->c : NULL); ArchDwarfOps ops; ops.min_inst_len = 1u; ops.max_ops_per_inst = 1u; ops.pad[0] = 0; ops.pad[1] = 0; if (arch && arch->dwarf) { - if (arch->dwarf->min_inst_len) - ops.min_inst_len = arch->dwarf->min_inst_len; + if (arch->dwarf->min_inst_len) ops.min_inst_len = arch->dwarf->min_inst_len; if (arch->dwarf->max_ops_per_inst) ops.max_ops_per_inst = arch->dwarf->max_ops_per_inst; } return ops; } -static void line_advance_pc(Buf *prog, u32 byte_delta, u32 min_inst_len) { +static void line_advance_pc(Buf* prog, u32 byte_delta, u32 min_inst_len) { if (byte_delta == 0) return; if (min_inst_len == 0) min_inst_len = 1; if ((byte_delta % min_inst_len) == 0) { @@ -833,18 +817,17 @@ static void line_advance_pc(Buf *prog, u32 byte_delta, u32 min_inst_len) { * * We emit, then track the program-start byte offset within the section so * we can place address relocations. */ -static void emit_section_line(EmitCtx *e) { +static void emit_section_line(EmitCtx* e) { Buf prog; Buf hdr_body; /* header from min_inst_length onward */ Buf out; - Pool *pool = e->pool; + Pool* pool = e->pool; u32 i, j; u32 dir_count; - Sym *dirs = NULL; + Sym* dirs = NULL; u32 ndirs = 0, dirs_cap = 0; ArchDwarfOps dwarf_ops = debug_dwarf_ops(e->d); - const u32 min_inst_len = - dwarf_ops.min_inst_len ? dwarf_ops.min_inst_len : 1u; + const u32 min_inst_len = dwarf_ops.min_inst_len ? dwarf_ops.min_inst_len : 1u; const u32 max_ops_per_inst = dwarf_ops.max_ops_per_inst ? dwarf_ops.max_ops_per_inst : 1u; /* Pending line_strp relocs. Each slot is a u32 in hdr_body at @@ -855,7 +838,7 @@ static void emit_section_line(EmitCtx *e) { struct LineStrpSlot { u32 at; u32 ofs; - } *lsp_slots = NULL; + }* lsp_slots = NULL; u32 nlsp = 0, lsp_cap = 0; buf_init(&prog, e->heap); @@ -864,11 +847,10 @@ static void emit_section_line(EmitCtx *e) { /* Build the program first (so we know its length). */ for (i = 0; i < e->d->nfuncs; ++i) { - DebugFunc *f = &e->d->funcs[i]; - LineRow *prev = NULL; + DebugFunc* f = &e->d->funcs[i]; + LineRow* prev = NULL; u8 addr_size; - if (!f->has_pc_range) - continue; + if (!f->has_pc_range) continue; addr_size = e->d->c->target.ptr_size; /* DW_LNE_set_address */ form_u8(&prog, 0); @@ -881,7 +863,7 @@ static void emit_section_line(EmitCtx *e) { add_line_reloc(e, buf_ofs, f->sym); } for (j = 0; j < f->nrows; ++j) { - LineRow *r = &f->rows[j]; + LineRow* r = &f->rows[j]; u32 dwfile = debug_file(e->d, r->loc.file_id); i64 prev_line = prev ? prev->loc.line : 1; u32 prev_offset = prev ? prev->offset : f->begin_ofs; @@ -922,10 +904,10 @@ static void emit_section_line(EmitCtx *e) { /* Build header body (from min_inst_length onward). */ form_u8(&hdr_body, (u8)min_inst_len); /* min_inst_length */ form_u8(&hdr_body, (u8)max_ops_per_inst); /* max_ops_per_inst */ - form_u8(&hdr_body, 1); /* default_is_stmt = 1 */ - form_u8(&hdr_body, (u8)(i8)-5); /* line_base */ - form_u8(&hdr_body, 14); /* line_range */ - form_u8(&hdr_body, 13); /* opcode_base = #standard ops + 1 */ + form_u8(&hdr_body, 1); /* default_is_stmt = 1 */ + form_u8(&hdr_body, (u8)(i8)-5); /* line_base */ + form_u8(&hdr_body, 14); /* line_range */ + form_u8(&hdr_body, 13); /* opcode_base = #standard ops + 1 */ /* DWARF 5 standard_opcode_lengths for opcodes 1..12 */ { u8 lens[12]; @@ -966,8 +948,7 @@ static void emit_section_line(EmitCtx *e) { } } if (!found) { - if (!VEC_GROW(e->heap, dirs, dirs_cap, ndirs + 1)) - dirs[ndirs++] = dir; + if (!VEC_GROW(e->heap, dirs, dirs_cap, ndirs + 1)) dirs[ndirs++] = dir; } } dir_count = ndirs; @@ -1006,7 +987,7 @@ static void emit_section_line(EmitCtx *e) { } else { form_uleb(&hdr_body, e->d->nfiles); for (i = 0; i < e->d->nfiles; ++i) { - DebugFile *df = &e->d->files[i]; + DebugFile* df = &e->d->files[i]; u32 di; u32 at = buf_pos(&hdr_body); u32 ofs = line_str_offset(e, df->base); @@ -1017,15 +998,13 @@ static void emit_section_line(EmitCtx *e) { nlsp++; } for (di = 0; di < ndirs; ++di) { - if (dirs[di] == df->dir) - break; + if (dirs[di] == df->dir) break; } form_uleb(&hdr_body, di < ndirs ? di : 0); } } - if (dirs) - e->heap->free(e->heap, dirs, sizeof(Sym) * dirs_cap); + if (dirs) e->heap->free(e->heap, dirs, sizeof(Sym) * dirs_cap); /* Compose final section bytes: unit-length header + hdr_body + program. */ { @@ -1041,23 +1020,21 @@ static void emit_section_line(EmitCtx *e) { form_u32(&out, hl); /* Append hdr_body bytes */ { - u8 *tmp = (u8 *)e->heap->alloc(e->heap, hl ? hl : 1, 1); + u8* tmp = (u8*)e->heap->alloc(e->heap, hl ? hl : 1, 1); if (tmp && hl) { buf_flatten(&hdr_body, tmp); buf_write(&out, tmp, hl); } - if (tmp) - e->heap->free(e->heap, tmp, hl ? hl : 1); + if (tmp) e->heap->free(e->heap, tmp, hl ? hl : 1); } /* Append program bytes */ { - u8 *tmp = (u8 *)e->heap->alloc(e->heap, plen ? plen : 1, 1); + u8* tmp = (u8*)e->heap->alloc(e->heap, plen ? plen : 1, 1); if (tmp && plen) { buf_flatten(&prog, tmp); buf_write(&out, tmp, plen); } - if (tmp) - e->heap->free(e->heap, tmp, plen ? plen : 1); + if (tmp) e->heap->free(e->heap, tmp, plen ? plen : 1); } flatten_to_section(e, e->sec_line, &out); /* program-start in section bytes = 12 (unit_length+ver+addr+seg+hl) + hl. @@ -1086,7 +1063,7 @@ static void emit_section_line(EmitCtx *e) { } /* .debug_aranges */ -static void emit_section_aranges(EmitCtx *e) { +static void emit_section_aranges(EmitCtx* e) { Buf b; u32 i; u32 unit_length; @@ -1111,9 +1088,8 @@ static void emit_section_aranges(EmitCtx *e) { } } for (i = 0; i < e->d->nfuncs; ++i) { - DebugFunc *f = &e->d->funcs[i]; - if (!f->has_pc_range) - continue; + DebugFunc* f = &e->d->funcs[i]; + if (!f->has_pc_range) continue; { u32 reloc_at = buf_pos(&b); u8 zeros[8] = {0}; @@ -1151,7 +1127,7 @@ static void emit_section_aranges(EmitCtx *e) { } /* .debug_rnglists */ -static void emit_section_rnglists(EmitCtx *e) { +static void emit_section_rnglists(EmitCtx* e) { Buf b; u32 unit_length; u32 i; @@ -1163,9 +1139,8 @@ static void emit_section_rnglists(EmitCtx *e) { form_u8(&b, 0); form_u32(&b, 0); /* offset_entry_count */ for (i = 0; i < e->d->nfuncs; ++i) { - DebugFunc *f = &e->d->funcs[i]; - if (!f->has_pc_range) - continue; + DebugFunc* f = &e->d->funcs[i]; + if (!f->has_pc_range) continue; form_u8(&b, DW_RLE_start_length); { u32 reloc_at = buf_pos(&b); @@ -1194,7 +1169,7 @@ static void emit_section_rnglists(EmitCtx *e) { } /* .debug_info: prepend CU header, append body, apply relocs and fixups. */ -static void emit_section_info(EmitCtx *e) { +static void emit_section_info(EmitCtx* e) { Buf out; u32 cu_header_size = 12; u32 body_size = buf_pos(&e->info_body); @@ -1208,13 +1183,12 @@ static void emit_section_info(EmitCtx *e) { /* Append body */ { u32 plen = body_size; - u8 *tmp = (u8 *)e->heap->alloc(e->heap, plen ? plen : 1, 1); + u8* tmp = (u8*)e->heap->alloc(e->heap, plen ? plen : 1, 1); if (tmp && plen) { buf_flatten(&e->info_body, tmp); buf_write(&out, tmp, plen); } - if (tmp) - e->heap->free(e->heap, tmp, plen ? plen : 1); + if (tmp) e->heap->free(e->heap, tmp, plen ? plen : 1); } flatten_to_section(e, e->sec_info, &out); /* CU header cross-section refs: debug_abbrev_offset at byte 8. Root @@ -1239,8 +1213,8 @@ static void emit_section_info(EmitCtx *e) { { u32 i; for (i = 0; i < e->nfixups; ++i) { - DieFixup *fx = &e->fixups[i]; - DebugType *tt = + DieFixup* fx = &e->fixups[i]; + DebugType* tt = (fx->target != DEBUG_TYPE_NONE && fx->target <= e->d->ntypes) ? &e->d->types[fx->target - 1] : NULL; @@ -1265,9 +1239,9 @@ static void emit_section_info(EmitCtx *e) { /* ---------------------------------------------------------------- */ -void debug_emit(Debug *d) { +void debug_emit(Debug* d) { EmitCtx ec; - Pool *pool = d->c->global; + Pool* pool = d->c->global; Sym producer_sym; Sym primary_dir = 0, primary_base = 0; u32 i; @@ -1276,10 +1250,9 @@ void debug_emit(Debug *d) { * to bzero on this size. We zero with an explicit byte-loop fallback * to match the lib_deps allowlist (which forbids _bzero). */ { - u8 *p = (u8 *)&ec; + u8* p = (u8*)&ec; size_t k; - for (k = 0; k < sizeof(ec); ++k) - p[k] = 0; + for (k = 0; k < sizeof(ec); ++k) p[k] = 0; } ec.d = d; ec.heap = d->heap; @@ -1347,10 +1320,8 @@ void debug_emit(Debug *d) { ec.root_str_off_base_at = buf_pos(&ec.info_body); form_u32(&ec.info_body, 8); - for (i = 0; i < d->ntypes; ++i) - emit_type_die(&ec, (DebugTypeId)(i + 1)); - for (i = 0; i < d->nfuncs; ++i) - emit_subprogram_die(&ec, &d->funcs[i]); + for (i = 0; i < d->ntypes; ++i) emit_type_die(&ec, (DebugTypeId)(i + 1)); + for (i = 0; i < d->nfuncs; ++i) emit_subprogram_die(&ec, &d->funcs[i]); form_uleb(&ec.info_body, 0); /* end of CU children */ /* Order: build sections that don't depend on later ones first. The str diff --git a/src/debug/dwarf_cfi.c b/src/debug/dwarf_cfi.c @@ -12,11 +12,10 @@ * callers must treat 1 as "stack bottom" per the API contract. */ -#include <stdint.h> -#include <string.h> - #include <cfree/arch.h> #include <cfree/dwarf.h> +#include <stdint.h> +#include <string.h> #include "core/core.h" #include "core/heap.h" @@ -211,7 +210,8 @@ static void run_cfi(const u8* prog, u32 plen, CfiState* st, u64* loc, } } -CfreeStatus cfree_dwarf_unwind_step(CfreeDebugInfo* d, CfreeUnwindFrame* frame) { +CfreeStatus cfree_dwarf_unwind_step(CfreeDebugInfo* d, + CfreeUnwindFrame* frame) { u32 off; if (!d || !frame) return CFREE_INVALID; if (d->eh_frame.sec_idx == UINT32_MAX || d->eh_frame.size == 0) @@ -223,7 +223,7 @@ CfreeStatus cfree_dwarf_unwind_step(CfreeDebugInfo* d, CfreeUnwindFrame* frame) u32 entry_end; u32 cie_id_off = off; u32 cie_id; - if (length == 0) break; /* terminator */ + if (length == 0) break; /* terminator */ if (length == 0xffffffffu) return CFREE_UNSUPPORTED; /* 64-bit eh_frame */ entry_end = off + length; cie_id = dw_u32(d->eh_frame.data, d->eh_frame.size, &off); diff --git a/src/debug/dwarf_die.c b/src/debug/dwarf_die.c @@ -5,12 +5,11 @@ * variables. Cross-CU refs land later when needed. */ +#include <cfree/dwarf.h> #include <stddef.h> #include <stdint.h> #include <string.h> -#include <cfree/dwarf.h> - #include "core/core.h" #include "core/heap.h" #include "core/util.h" @@ -18,123 +17,120 @@ /* ---- subprogram + lexical_block walk --------------------------------- */ -static void pack_init(DieAttrPack *p) { memset(p, 0, sizeof(*p)); } +static void pack_init(DieAttrPack* p) { memset(p, 0, sizeof(*p)); } /* Read all attributes of a DIE into pack `p`; updates *off to past attrs. */ -static void read_pack(CfreeDebugInfo *d, const DwCu *cu, DwDie *die, - DieAttrPack *p, u32 *off) { +static void read_pack(CfreeDebugInfo* d, const DwCu* cu, DwDie* die, + DieAttrPack* p, u32* off) { u32 i; - if (!die->abbrev) - return; + if (!die->abbrev) return; for (i = 0; i < die->abbrev->nattrs; ++i) { - DwAbbrevAttr *aa = &die->abbrev->attrs[i]; + DwAbbrevAttr* aa = &die->abbrev->attrs[i]; DwAttrValue v; dw_read_form(d, cu, aa->form, aa->implicit_const, off, &v); switch (aa->attr) { - case DW_AT_name: - p->name = v.str; - break; - case DW_AT_low_pc: - p->low_pc = v.u; - p->has_low_pc = 1; - break; - case DW_AT_high_pc: - p->high_pc_value = v.u; - p->high_pc_form = aa->form; - p->has_high_pc = 1; - break; - case DW_AT_type: - /* Local CU offset: ref* forms are CU-relative; ref_addr is - * .debug_info-absolute. */ - if (aa->form == DW_FORM_ref_addr) - p->type_die_offset = (u32)v.u; - else - p->type_die_offset = cu->hdr_offset + (u32)v.u; - p->has_type = 1; - break; - case DW_AT_decl_file: - p->decl_file = (u32)v.u; - break; - case DW_AT_decl_line: - p->decl_line = (u32)v.u; - break; - case DW_AT_location: - if (aa->form == DW_FORM_loclistx) { - p->has_loclist = 1; - p->loclist_index = v.u; - } else if (aa->form == DW_FORM_exprloc || aa->form == DW_FORM_block || - aa->form == DW_FORM_block1 || aa->form == DW_FORM_block2 || - aa->form == DW_FORM_block4) { - p->loc_block = v.block; - p->loc_block_len = v.block_len; - } else if (aa->form == DW_FORM_sec_offset) { - /* Reference into .debug_loclists — not supported in Phase 5 - * baseline. */ - p->has_loclist = 1; - p->loclist_index = v.u; - } - break; - case DW_AT_frame_base: - p->fb_block = v.block; - p->fb_block_len = v.block_len; - break; - case DW_AT_const_value: - p->const_value = v.s; - p->has_const_value = 1; - break; - case DW_AT_data_member_location: - if (aa->form == DW_FORM_exprloc || aa->form == DW_FORM_block || - aa->form == DW_FORM_block1 || aa->form == DW_FORM_block2 || - aa->form == DW_FORM_block4) { - /* Best effort: evaluate a single DW_OP_plus_uconst form by - * peeking. */ - if (v.block && v.block_len > 0 && v.block[0] == DW_OP_plus_uconst) { - u32 t = 1; - p->byte_offset = (u32)dw_uleb(v.block, v.block_len, &t); + case DW_AT_name: + p->name = v.str; + break; + case DW_AT_low_pc: + p->low_pc = v.u; + p->has_low_pc = 1; + break; + case DW_AT_high_pc: + p->high_pc_value = v.u; + p->high_pc_form = aa->form; + p->has_high_pc = 1; + break; + case DW_AT_type: + /* Local CU offset: ref* forms are CU-relative; ref_addr is + * .debug_info-absolute. */ + if (aa->form == DW_FORM_ref_addr) + p->type_die_offset = (u32)v.u; + else + p->type_die_offset = cu->hdr_offset + (u32)v.u; + p->has_type = 1; + break; + case DW_AT_decl_file: + p->decl_file = (u32)v.u; + break; + case DW_AT_decl_line: + p->decl_line = (u32)v.u; + break; + case DW_AT_location: + if (aa->form == DW_FORM_loclistx) { + p->has_loclist = 1; + p->loclist_index = v.u; + } else if (aa->form == DW_FORM_exprloc || aa->form == DW_FORM_block || + aa->form == DW_FORM_block1 || aa->form == DW_FORM_block2 || + aa->form == DW_FORM_block4) { + p->loc_block = v.block; + p->loc_block_len = v.block_len; + } else if (aa->form == DW_FORM_sec_offset) { + /* Reference into .debug_loclists — not supported in Phase 5 + * baseline. */ + p->has_loclist = 1; + p->loclist_index = v.u; + } + break; + case DW_AT_frame_base: + p->fb_block = v.block; + p->fb_block_len = v.block_len; + break; + case DW_AT_const_value: + p->const_value = v.s; + p->has_const_value = 1; + break; + case DW_AT_data_member_location: + if (aa->form == DW_FORM_exprloc || aa->form == DW_FORM_block || + aa->form == DW_FORM_block1 || aa->form == DW_FORM_block2 || + aa->form == DW_FORM_block4) { + /* Best effort: evaluate a single DW_OP_plus_uconst form by + * peeking. */ + if (v.block && v.block_len > 0 && v.block[0] == DW_OP_plus_uconst) { + u32 t = 1; + p->byte_offset = (u32)dw_uleb(v.block, v.block_len, &t); + p->has_byte_offset = 1; + } + } else { + p->byte_offset = (u32)v.u; p->has_byte_offset = 1; } - } else { - p->byte_offset = (u32)v.u; - p->has_byte_offset = 1; - } - break; - case DW_AT_byte_size: - p->byte_size = (u32)v.u; - p->has_byte_size = 1; - break; - case DW_AT_bit_size: - p->bit_size = (u32)v.u; - p->has_bit_size = 1; - break; - case DW_AT_bit_offset: - case DW_AT_data_bit_offset: - p->bit_offset = (u32)v.u; - p->has_bit_offset = 1; - break; - case DW_AT_encoding: - p->base_encoding = (u32)v.u; - p->has_encoding = 1; - break; - case DW_AT_count: - case DW_AT_upper_bound: - p->array_count = (u32)v.u; - if (aa->attr == DW_AT_upper_bound) - p->array_count++; - p->has_array_count = 1; - break; + break; + case DW_AT_byte_size: + p->byte_size = (u32)v.u; + p->has_byte_size = 1; + break; + case DW_AT_bit_size: + p->bit_size = (u32)v.u; + p->has_bit_size = 1; + break; + case DW_AT_bit_offset: + case DW_AT_data_bit_offset: + p->bit_offset = (u32)v.u; + p->has_bit_offset = 1; + break; + case DW_AT_encoding: + p->base_encoding = (u32)v.u; + p->has_encoding = 1; + break; + case DW_AT_count: + case DW_AT_upper_bound: + p->array_count = (u32)v.u; + if (aa->attr == DW_AT_upper_bound) p->array_count++; + p->has_array_count = 1; + break; } } } /* Append a subprogram (or skip if its bounds aren't useful). */ -static void push_subprog(CfreeDebugInfo *d, DwSubprog *sp) { +static void push_subprog(CfreeDebugInfo* d, DwSubprog* sp) { if (d->nsubs == d->subs_cap) { u32 ncap = d->subs_cap ? d->subs_cap * 2 : 8; - DwSubprog *na = (DwSubprog *)d->h->realloc( - d->h, d->subs, d->subs_cap * sizeof(*d->subs), ncap * sizeof(*d->subs), - _Alignof(DwSubprog)); - if (!na) - return; + DwSubprog* na = + (DwSubprog*)d->h->realloc(d->h, d->subs, d->subs_cap * sizeof(*d->subs), + ncap * sizeof(*d->subs), _Alignof(DwSubprog)); + if (!na) return; d->subs = na; d->subs_cap = ncap; } @@ -142,12 +138,11 @@ static void push_subprog(CfreeDebugInfo *d, DwSubprog *sp) { } /* Walk a DIE subtree, collecting subprograms. */ -static void walk_for_subs(CfreeDebugInfo *d, u32 cu_idx, u32 *off) { - DwCu *cu = &d->cus[cu_idx]; +static void walk_for_subs(CfreeDebugInfo* d, u32 cu_idx, u32* off) { + DwCu* cu = &d->cus[cu_idx]; for (;;) { DwDie die; - if (!dw_read_die(d, cu, off, &die)) - return; + if (!dw_read_die(d, cu, off, &die)) return; if (die.abbrev->tag == DW_TAG_subprogram || die.abbrev->tag == DW_TAG_inlined_subroutine) { DieAttrPack p; @@ -172,9 +167,8 @@ static void walk_for_subs(CfreeDebugInfo *d, u32 cu_idx, u32 *off) { /* Resolve decl_file via the CU's line program. */ sp.decl_file = ""; if (p.decl_file != 0 && cu->has_stmt_list) { - DwLineProgram *lp; - if (!d->lines_built[cu_idx]) - dw_build_line(d, cu_idx); + DwLineProgram* lp; + if (!d->lines_built[cu_idx]) dw_build_line(d, cu_idx); lp = &d->lines_by_cu[cu_idx]; if (lp->nfile_norm && p.decl_file < lp->nfile_norm) sp.decl_file = lp->file_norm[p.decl_file]; @@ -197,52 +191,48 @@ static void walk_for_subs(CfreeDebugInfo *d, u32 cu_idx, u32 *off) { /* Skip attrs, then descend. */ u32 i; for (i = 0; i < die.abbrev->nattrs; ++i) { - DwAbbrevAttr *aa = &die.abbrev->attrs[i]; + DwAbbrevAttr* aa = &die.abbrev->attrs[i]; dw_skip_form(d, cu, aa->form, aa->implicit_const, off); } walk_for_subs(d, cu_idx, off); } else { u32 i; for (i = 0; i < die.abbrev->nattrs; ++i) { - DwAbbrevAttr *aa = &die.abbrev->attrs[i]; + DwAbbrevAttr* aa = &die.abbrev->attrs[i]; dw_skip_form(d, cu, aa->form, aa->implicit_const, off); } } } } -void dw_build_subs(CfreeDebugInfo *d) { +void dw_build_subs(CfreeDebugInfo* d) { u32 i; - if (d->subs_built) - return; + if (d->subs_built) return; d->subs_built = 1; for (i = 0; i < d->ncus; ++i) { - DwCu *cu = &d->cus[i]; + DwCu* cu = &d->cus[i]; u32 off = cu->die_start_off; /* The root DIE is the CU itself — recurse into it. */ DwDie root; - if (!dw_read_die(d, cu, &off, &root)) - continue; + if (!dw_read_die(d, cu, &off, &root)) continue; /* Skip root attrs */ { u32 j; for (j = 0; j < root.abbrev->nattrs; ++j) { - DwAbbrevAttr *aa = &root.abbrev->attrs[j]; + DwAbbrevAttr* aa = &root.abbrev->attrs[j]; dw_skip_form(d, cu, aa->form, aa->implicit_const, &off); } } - if (root.abbrev->has_children) - walk_for_subs(d, i, &off); + if (root.abbrev->has_children) walk_for_subs(d, i, &off); } } -DwSubprog *dw_find_subprog(CfreeDebugInfo *d, u64 pc) { +DwSubprog* dw_find_subprog(CfreeDebugInfo* d, u64 pc) { u32 i; dw_build_subs(d); for (i = 0; i < d->nsubs; ++i) { - DwSubprog *sp = &d->subs[i]; - if (sp->low_pc <= pc && pc < sp->high_pc) - return sp; + DwSubprog* sp = &d->subs[i]; + if (sp->low_pc <= pc && pc < sp->high_pc) return sp; } return NULL; } @@ -250,49 +240,46 @@ DwSubprog *dw_find_subprog(CfreeDebugInfo *d, u64 pc) { /* ---- locals + parameters --------------------------------------------- */ typedef struct LocalCtx { - CfreeDebugInfo *d; + CfreeDebugInfo* d; u32 cu_idx; - DwLocal *params; + DwLocal* params; u32 nparams, params_cap; - DwLocal *locals; + DwLocal* locals; u32 nlocals, locals_cap; } LocalCtx; -static void push_param(LocalCtx *x, DwLocal *v) { +static void push_param(LocalCtx* x, DwLocal* v) { if (x->nparams == x->params_cap) { u32 ncap = x->params_cap ? x->params_cap * 2 : 4; - DwLocal *na = (DwLocal *)x->d->h->realloc( + DwLocal* na = (DwLocal*)x->d->h->realloc( x->d->h, x->params, x->params_cap * sizeof(*x->params), ncap * sizeof(*x->params), _Alignof(DwLocal)); - if (!na) - return; + if (!na) return; x->params = na; x->params_cap = ncap; } x->params[x->nparams++] = *v; } -static void push_local(LocalCtx *x, DwLocal *v) { +static void push_local(LocalCtx* x, DwLocal* v) { if (x->nlocals == x->locals_cap) { u32 ncap = x->locals_cap ? x->locals_cap * 2 : 4; - DwLocal *na = (DwLocal *)x->d->h->realloc( + DwLocal* na = (DwLocal*)x->d->h->realloc( x->d->h, x->locals, x->locals_cap * sizeof(*x->locals), ncap * sizeof(*x->locals), _Alignof(DwLocal)); - if (!na) - return; + if (!na) return; x->locals = na; x->locals_cap = ncap; } x->locals[x->nlocals++] = *v; } -static void walk_subprog_body(LocalCtx *x, u32 *off, u64 scope_lo, u64 scope_hi, +static void walk_subprog_body(LocalCtx* x, u32* off, u64 scope_lo, u64 scope_hi, u32 scope_die_off, u8 has_scope) { - CfreeDebugInfo *d = x->d; - DwCu *cu = &d->cus[x->cu_idx]; + CfreeDebugInfo* d = x->d; + DwCu* cu = &d->cus[x->cu_idx]; for (;;) { DwDie die; - if (!dw_read_die(d, cu, off, &die)) - return; + if (!dw_read_die(d, cu, off, &die)) return; if (die.abbrev->tag == DW_TAG_formal_parameter || die.abbrev->tag == DW_TAG_variable) { DieAttrPack p; @@ -335,7 +322,7 @@ static void walk_subprog_body(LocalCtx *x, u32 *off, u64 scope_lo, u64 scope_hi, } else { u32 i; for (i = 0; i < die.abbrev->nattrs; ++i) { - DwAbbrevAttr *aa = &die.abbrev->attrs[i]; + DwAbbrevAttr* aa = &die.abbrev->attrs[i]; dw_skip_form(d, cu, aa->form, aa->implicit_const, off); } if (die.abbrev->has_children) @@ -344,25 +331,22 @@ static void walk_subprog_body(LocalCtx *x, u32 *off, u64 scope_lo, u64 scope_hi, } } -void dw_build_locals(CfreeDebugInfo *d, DwSubprog *sp) { +void dw_build_locals(CfreeDebugInfo* d, DwSubprog* sp) { LocalCtx x; - DwCu *cu; + DwCu* cu; u32 off; DwDie die; - if (sp->cached_locals) - return; + if (sp->cached_locals) return; sp->cached_locals = 1; cu = &d->cus[sp->cu_idx]; off = sp->die_offset; - if (!dw_read_die(d, cu, &off, &die)) - return; - if (!die.abbrev || !die.abbrev->has_children) - return; + if (!dw_read_die(d, cu, &off, &die)) return; + if (!die.abbrev || !die.abbrev->has_children) return; /* Skip subprog attrs */ { u32 i; for (i = 0; i < die.abbrev->nattrs; ++i) { - DwAbbrevAttr *aa = &die.abbrev->attrs[i]; + DwAbbrevAttr* aa = &die.abbrev->attrs[i]; dw_skip_form(d, cu, aa->form, aa->implicit_const, &off); } } @@ -378,31 +362,27 @@ void dw_build_locals(CfreeDebugInfo *d, DwSubprog *sp) { /* ---- globals --------------------------------------------------------- */ -void dw_build_globals(CfreeDebugInfo *d) { +void dw_build_globals(CfreeDebugInfo* d) { u32 i; - if (d->globals_built) - return; + if (d->globals_built) return; d->globals_built = 1; for (i = 0; i < d->ncus; ++i) { - DwCu *cu = &d->cus[i]; + DwCu* cu = &d->cus[i]; u32 off = cu->die_start_off; DwDie root; - if (!dw_read_die(d, cu, &off, &root)) - continue; + if (!dw_read_die(d, cu, &off, &root)) continue; { u32 j; for (j = 0; j < root.abbrev->nattrs; ++j) { - DwAbbrevAttr *aa = &root.abbrev->attrs[j]; + DwAbbrevAttr* aa = &root.abbrev->attrs[j]; dw_skip_form(d, cu, aa->form, aa->implicit_const, &off); } } - if (!root.abbrev->has_children) - continue; + if (!root.abbrev->has_children) continue; /* Walk only top-level children of the CU; collect DW_TAG_variable. */ for (;;) { DwDie die; - if (!dw_read_die(d, cu, &off, &die)) - break; + if (!dw_read_die(d, cu, &off, &die)) break; if (die.abbrev->tag == DW_TAG_variable) { DieAttrPack p; DwLocal v; @@ -420,11 +400,10 @@ void dw_build_globals(CfreeDebugInfo *d) { v.is_global = 1; if (d->nglobals == d->globals_cap) { u32 ncap = d->globals_cap ? d->globals_cap * 2 : 8; - DwLocal *na = (DwLocal *)d->h->realloc( + DwLocal* na = (DwLocal*)d->h->realloc( d->h, d->globals, d->globals_cap * sizeof(*d->globals), ncap * sizeof(*d->globals), _Alignof(DwLocal)); - if (!na) - break; + if (!na) break; d->globals = na; d->globals_cap = ncap; } @@ -433,8 +412,7 @@ void dw_build_globals(CfreeDebugInfo *d) { /* Skip children. */ for (;;) { DwDie c; - if (!dw_read_die(d, cu, &off, &c)) - break; + if (!dw_read_die(d, cu, &off, &c)) break; dw_skip_die_subtree(d, cu, &c, &off); } } @@ -446,8 +424,8 @@ void dw_build_globals(CfreeDebugInfo *d) { } /* Public accessor for the type module: read attrs given die. */ -void dw_die_pack(CfreeDebugInfo *d, const DwCu *cu, DwDie *die, - DieAttrPack *p) { +void dw_die_pack(CfreeDebugInfo* d, const DwCu* cu, DwDie* die, + DieAttrPack* p) { u32 off = die->attrs_off; pack_init(p); read_pack(d, cu, die, p, &off); diff --git a/src/debug/dwarf_internal.h b/src/debug/dwarf_internal.h @@ -20,7 +20,7 @@ /* ---- Section & byte slice helpers ------------------------------------- */ typedef struct DwSection { - const u8 *data; + const u8* data; u32 size; u32 sec_idx; /* 0-based section index, or UINT32_MAX if missing */ } DwSection; @@ -38,14 +38,14 @@ typedef struct DwAbbrev { u32 tag; /* DW_TAG_* */ u8 has_children; u32 nattrs; - DwAbbrevAttr *attrs; /* heap-allocated */ + DwAbbrevAttr* attrs; /* heap-allocated */ } DwAbbrev; typedef struct DwAbbrevTable { u32 cu_abbrev_offset; /* offset into .debug_abbrev */ /* Dense map: code → index (or 0 if absent). For typical small tables we * keep them in a sorted array searched linearly. */ - DwAbbrev *abbrevs; + DwAbbrev* abbrevs; u32 nabbrevs; u32 cap; } DwAbbrevTable; @@ -69,8 +69,8 @@ typedef struct DwCu { u32 rnglists_base; u32 stmt_list; /* DW_AT_stmt_list value (offset into .debug_line) */ u8 has_stmt_list; - const char *comp_dir; - const char *name; + const char* comp_dir; + const char* name; /* Index of abbrev table in dbg->abbrevs */ u32 abbrev_table_idx; } DwCu; @@ -102,33 +102,33 @@ typedef enum DwTypeKind { } DwTypeKind; typedef struct DwField { - const char *name; + const char* name; u32 byte_offset; u32 bit_offset; u32 bit_size; - struct CfreeDwarfType *type; + struct CfreeDwarfType* type; } DwField; typedef struct DwEnumVal { - const char *name; + const char* name; i64 value; } DwEnumVal; struct CfreeDwarfType { DwTypeKind kind; u32 byte_size; - const char *name; + const char* name; u32 element_count; u32 die_offset; /* origin DIE for cycle-detection / dedup */ /* DT_PTR/ARRAY/TYPEDEF/CONST/VOLATILE/RESTRICT/FUNC: inner type */ - struct CfreeDwarfType *inner; + struct CfreeDwarfType* inner; /* Base type encoding (DW_ATE_*) — used to derive SINT/UINT/CHAR/BOOL/FLOAT */ u32 base_encoding; /* STRUCT/UNION fields */ - DwField *fields; + DwField* fields; u32 nfields; /* ENUM values */ - DwEnumVal *evals; + DwEnumVal* evals; u32 nevals; }; @@ -144,30 +144,30 @@ typedef struct DwLineRow { } DwLineRow; typedef struct DwLineFile { - const char *path; /* interned in our string table */ + const char* path; /* interned in our string table */ u32 dir_index; } DwLineFile; typedef struct DwLineProgram { /* Per-CU line program decoding state. We materialize all rows into a * single rows array for fast lookup. */ - DwLineRow *rows; + DwLineRow* rows; u32 nrows; u32 cap; /* File table (file_index 0 is the CU primary in DW5). */ - DwLineFile *files; + DwLineFile* files; u32 nfiles; - const char **dirs; + const char** dirs; u32 ndirs; /* Cached fully-qualified path per file, lazily built. */ - const char **file_norm; + const char** file_norm; u32 nfile_norm; } DwLineProgram; /* ---- Subprogram descriptor (cached) ---- */ typedef struct DwLocal { - const char *name; + const char* name; u32 die_offset; u32 type_die_offset; u64 scope_lo; /* PCs at which the var is in scope. */ @@ -175,7 +175,7 @@ typedef struct DwLocal { u32 scope_offset; /* offset of the lexical_block DIE; 0 = subprog scope */ u8 has_scope; /* Location form: either an exprloc or a loclistx index. */ - const u8 *loc; + const u8* loc; u32 loc_len; u8 has_loclist; u64 loclist_index; @@ -186,21 +186,21 @@ typedef struct DwLocal { } DwLocal; typedef struct DwSubprog { - const char *name; + const char* name; u64 low_pc; u64 high_pc; - const char *decl_file; + const char* decl_file; u32 decl_line; u32 cu_idx; u32 die_offset; /* offset of the subprogram DIE */ u32 type_die_offset; /* Frame base — DW_AT_frame_base exprloc bytes (or NULL). */ - const u8 *frame_base; + const u8* frame_base; u32 frame_base_len; /* Cached params and locals (lazily). */ - DwLocal *params; + DwLocal* params; u32 nparams; - DwLocal *locals; + DwLocal* locals; u32 nlocals; u8 inlined; u8 cached_locals; @@ -213,13 +213,13 @@ typedef struct DwString { } DwString; struct CfreeDebugInfo { - const CfreeContext *ctx; - Heap *h; + const CfreeContext* ctx; + Heap* h; /* Local string pool for interned strings (file paths, etc). The * consumer used to borrow the compiler's global pool, but the new * cfree_dwarf_open takes only a CfreeContext — no compiler. */ - struct Pool *strs; - const CfreeObjFile *obj; + struct Pool* strs; + const CfreeObjFile* obj; /* Sections */ DwSection abbrev; @@ -235,33 +235,33 @@ struct CfreeDebugInfo { DwSection aranges; /* Abbrev tables (one per unique abbrev_offset we've seen). */ - DwAbbrevTable *abbrevs; + DwAbbrevTable* abbrevs; u32 nabbrevs; u32 abbrevs_cap; /* CUs */ - DwCu *cus; + DwCu* cus; u32 ncus; u32 cus_cap; /* Line programs by CU index (parallel to cus). Each lazily built. */ - DwLineProgram *lines_by_cu; - u8 *lines_built; /* parallel; 0 = not yet decoded */ + DwLineProgram* lines_by_cu; + u8* lines_built; /* parallel; 0 = not yet decoded */ /* Subprograms (sorted by low_pc on first build). */ - DwSubprog *subs; + DwSubprog* subs; u32 nsubs; u32 subs_cap; u8 subs_built; /* Type cache: DIE-offset → CfreeDwarfType*. */ - CfreeDwarfType **types_by_off; /* parallel arrays */ - u32 *types_off; + CfreeDwarfType** types_by_off; /* parallel arrays */ + u32* types_off; u32 ntypes; u32 types_cap; /* Globals (top-level DW_TAG_variable in any CU). */ - DwLocal *globals; + DwLocal* globals; u32 nglobals; u32 globals_cap; u8 globals_built; @@ -271,37 +271,37 @@ struct CfreeDebugInfo { /* Section lookup by name. Sets out->data/size; sec_idx = UINT32_MAX if missing. */ -void dw_find_section(CfreeDebugInfo *d, const char *name, DwSection *out); +void dw_find_section(CfreeDebugInfo* d, const char* name, DwSection* out); /* Read primitives. Each returns the new offset on success and panics on EOF. */ -u8 dw_u8(const u8 *base, u32 size, u32 *off); -u16 dw_u16(const u8 *base, u32 size, u32 *off); -u32 dw_u24(const u8 *base, u32 size, u32 *off); -u32 dw_u32(const u8 *base, u32 size, u32 *off); -u64 dw_u64(const u8 *base, u32 size, u32 *off); -u64 dw_uleb(const u8 *base, u32 size, u32 *off); -i64 dw_sleb(const u8 *base, u32 size, u32 *off); -const char *dw_cstr(const u8 *base, u32 size, u32 *off); +u8 dw_u8(const u8* base, u32 size, u32* off); +u16 dw_u16(const u8* base, u32 size, u32* off); +u32 dw_u24(const u8* base, u32 size, u32* off); +u32 dw_u32(const u8* base, u32 size, u32* off); +u64 dw_u64(const u8* base, u32 size, u32* off); +u64 dw_uleb(const u8* base, u32 size, u32* off); +i64 dw_sleb(const u8* base, u32 size, u32* off); +const char* dw_cstr(const u8* base, u32 size, u32* off); /* Abbrev parsing: ensure (and return) the abbrev table for `offset`. */ -DwAbbrevTable *dw_abbrev_get(CfreeDebugInfo *d, u32 offset); -DwAbbrev *dw_abbrev_lookup(DwAbbrevTable *t, u64 code); +DwAbbrevTable* dw_abbrev_get(CfreeDebugInfo* d, u32 offset); +DwAbbrev* dw_abbrev_lookup(DwAbbrevTable* t, u64 code); /* Parse the CU header at offset `off` in .debug_info into `cu`. * Returns the offset of the next CU header. */ -u32 dw_cu_parse_header(CfreeDebugInfo *d, u32 off, DwCu *cu); +u32 dw_cu_parse_header(CfreeDebugInfo* d, u32 off, DwCu* cu); /* Skim every CU and populate dbg->cus. */ -void dw_parse_all_cus(CfreeDebugInfo *d); +void dw_parse_all_cus(CfreeDebugInfo* d); /* Open the .debug_str_offsets table indexed by str_offsets_base. */ -const char *dw_str(CfreeDebugInfo *d, u32 offset); -const char *dw_line_str(CfreeDebugInfo *d, u32 offset); -const char *dw_strx(CfreeDebugInfo *d, const DwCu *cu, u64 idx); +const char* dw_str(CfreeDebugInfo* d, u32 offset); +const char* dw_line_str(CfreeDebugInfo* d, u32 offset); +const char* dw_strx(CfreeDebugInfo* d, const DwCu* cu, u64 idx); /* Skip one attribute value of `form` size. *off is updated. */ -void dw_skip_form(CfreeDebugInfo *d, const DwCu *cu, u32 form, - i64 implicit_const, u32 *off); +void dw_skip_form(CfreeDebugInfo* d, const DwCu* cu, u32 form, + i64 implicit_const, u32* off); /* Read attribute value into a typed accumulator. Caller picks which getter. */ typedef struct DwAttrValue { @@ -309,19 +309,19 @@ typedef struct DwAttrValue { /* Values for various forms — only one slot is meaningful per form. */ u64 u; /* udata, addr, ref (CU-relative offset for local refs) */ i64 s; /* sdata */ - const char *str; /* strp/string/strx/line_strp resolved cstring */ - const u8 *block; /* exprloc/block bytes */ + const char* str; /* strp/string/strx/line_strp resolved cstring */ + const u8* block; /* exprloc/block bytes */ u32 block_len; } DwAttrValue; /* Read attr value at *off using `form`. Updates *off. */ -void dw_read_form(CfreeDebugInfo *d, const DwCu *cu, u32 form, - i64 implicit_const, u32 *off, DwAttrValue *out); +void dw_read_form(CfreeDebugInfo* d, const DwCu* cu, u32 form, + i64 implicit_const, u32* off, DwAttrValue* out); /* DIE iteration helpers. */ typedef struct DwDie { u64 abbrev_code; - DwAbbrev *abbrev; /* NULL if abbrev_code==0 (null entry) */ + DwAbbrev* abbrev; /* NULL if abbrev_code==0 (null entry) */ u32 die_off; /* offset of this DIE itself in .debug_info */ u32 attrs_off; /* where attribute encodings start */ u32 next_sibling_off; /* lazily computed */ @@ -330,48 +330,45 @@ typedef struct DwDie { /* Read one DIE header at *off. Updates *off to point past the abbrev code, * to the start of the attribute area. Returns 1 on success, 0 if this is a * null-entry (terminates a sibling chain). */ -int dw_read_die(CfreeDebugInfo *d, const DwCu *cu, u32 *off, DwDie *out); +int dw_read_die(CfreeDebugInfo* d, const DwCu* cu, u32* off, DwDie* out); /* Skip a DIE's attribute area, advancing *off past it. */ -void dw_skip_die_attrs(CfreeDebugInfo *d, const DwCu *cu, DwDie *die, u32 *off); +void dw_skip_die_attrs(CfreeDebugInfo* d, const DwCu* cu, DwDie* die, u32* off); /* Skip an entire DIE subtree (including children), starting at attrs_off. * On entry, *off == die->attrs_off. On exit, *off is past the children * terminator (if has_children) or just past the attrs (if no children). */ -void dw_skip_die_subtree(CfreeDebugInfo *d, const DwCu *cu, DwDie *die, - u32 *off); +void dw_skip_die_subtree(CfreeDebugInfo* d, const DwCu* cu, DwDie* die, + u32* off); /* Lookup an attribute on `die` by attr code. Returns 1 if found and fills * *out; 0 otherwise. Restartable (rewinds the cursor). */ -int dw_die_attr(CfreeDebugInfo *d, const DwCu *cu, DwDie *die, u32 attr, - DwAttrValue *out); +int dw_die_attr(CfreeDebugInfo* d, const DwCu* cu, DwDie* die, u32 attr, + DwAttrValue* out); /* String interning into the compiler's global pool. */ -const char *dw_intern(CfreeDebugInfo *d, const char *s, size_t len); +const char* dw_intern(CfreeDebugInfo* d, const char* s, size_t len); /* Inline strcmp/strlen — libcfree avoids a runtime libc dep beyond the * tightly-controlled allowlist (test/lib_deps.allowlist). */ -static inline int dw_streq(const char *a, const char *b) { - if (!a || !b) - return 0; +static inline int dw_streq(const char* a, const char* b) { + if (!a || !b) return 0; while (*a && *b && *a == *b) { a++; b++; } return *a == 0 && *b == 0; } -static inline size_t dw_strlen(const char *s) { +static inline size_t dw_strlen(const char* s) { size_t n = 0; - if (!s) - return 0; - while (s[n]) - n++; + if (!s) return 0; + while (s[n]) n++; return n; } /* DIE attribute pack — shared between dwarf_die.c and dwarf_type.c. */ typedef struct DieAttrPack { - const char *name; + const char* name; u64 low_pc; u64 high_pc_value; u32 high_pc_form; @@ -381,11 +378,11 @@ typedef struct DieAttrPack { u8 has_type; u32 decl_file; u32 decl_line; - const u8 *loc_block; + const u8* loc_block; u32 loc_block_len; u8 has_loclist; u64 loclist_index; - const u8 *fb_block; + const u8* fb_block; u32 fb_block_len; i64 const_value; u8 has_const_value; @@ -404,22 +401,22 @@ typedef struct DieAttrPack { u8 inlined; } DieAttrPack; -void dw_die_pack(CfreeDebugInfo *d, const DwCu *cu, DwDie *die, DieAttrPack *p); +void dw_die_pack(CfreeDebugInfo* d, const DwCu* cu, DwDie* die, DieAttrPack* p); /* Subprograms */ -void dw_build_subs(CfreeDebugInfo *d); -DwSubprog *dw_find_subprog(CfreeDebugInfo *d, u64 pc); -void dw_build_locals(CfreeDebugInfo *d, DwSubprog *sp); +void dw_build_subs(CfreeDebugInfo* d); +DwSubprog* dw_find_subprog(CfreeDebugInfo* d, u64 pc); +void dw_build_locals(CfreeDebugInfo* d, DwSubprog* sp); /* Globals */ -void dw_build_globals(CfreeDebugInfo *d); +void dw_build_globals(CfreeDebugInfo* d); /* Line program */ -void dw_build_line(CfreeDebugInfo *d, u32 cu_idx); +void dw_build_line(CfreeDebugInfo* d, u32 cu_idx); /* Type DIE → CfreeDwarfType*. die_offset is absolute offset in .debug_info. */ -CfreeDwarfType *dw_type_from_die(CfreeDebugInfo *d, u32 cu_idx, u32 die_offset); -CfreeDwarfType *dw_void_type(CfreeDebugInfo *d); +CfreeDwarfType* dw_type_from_die(CfreeDebugInfo* d, u32 cu_idx, u32 die_offset); +CfreeDwarfType* dw_void_type(CfreeDebugInfo* d); /* Loc-expr evaluator. Evaluates `expr` of length `len` in the context of * `frame` (regs, cfa) and `frame_base_expr` (the subprog's DW_AT_frame_base @@ -432,16 +429,16 @@ typedef struct DwExprResult { u64 value; /* address if kind=0; literal if kind=1; reg# if kind=2 */ } DwExprResult; -int dw_eval_expr(CfreeDebugInfo *d, const u8 *expr, u32 len, const u8 *fb_expr, - u32 fb_len, const CfreeUnwindFrame *frame, DwExprResult *out); +int dw_eval_expr(CfreeDebugInfo* d, const u8* expr, u32 len, const u8* fb_expr, + u32 fb_len, const CfreeUnwindFrame* frame, DwExprResult* out); /* CU lookup helpers. */ -DwCu *dw_cu_at_die_offset(CfreeDebugInfo *d, u32 die_offset); +DwCu* dw_cu_at_die_offset(CfreeDebugInfo* d, u32 die_offset); /* Resolve a DW_FORM_loclistx into the matching location list entry for * `pc`. Returns 1 and fills bytes/len on success; 0 if the section is * absent, the index is bad, or no entry covers `pc`. */ -int dw_loclist_resolve(CfreeDebugInfo *d, const DwCu *cu, u64 idx, u64 pc, - const u8 **bytes, u32 *len); +int dw_loclist_resolve(CfreeDebugInfo* d, const DwCu* cu, u64 idx, u64 pc, + const u8** bytes, u32* len); #endif diff --git a/src/debug/dwarf_line.c b/src/debug/dwarf_line.c @@ -4,12 +4,11 @@ * a row matrix, and index it for addr→line and (file, line)→addr lookup. */ +#include <cfree/dwarf.h> #include <stddef.h> #include <stdint.h> #include <string.h> -#include <cfree/dwarf.h> - #include "core/core.h" #include "core/heap.h" #include "core/slice.h" @@ -481,7 +480,8 @@ CfreeStatus cfree_dwarf_addr_to_line(CfreeDebugInfo* d, uint64_t pc, /* file_norm matches user-typed `file` if either it is exactly equal, or it * ends with `/<file>`. Suffix matching keeps `b util.c:42` working when * the DWARF file_norm is the absolute path the compiler saw. */ -static int dw_file_matches(const char* file_norm, const char* user, size_t ulen) { +static int dw_file_matches(const char* file_norm, const char* user, + size_t ulen) { size_t flen; if (!file_norm) return 0; if (dw_streq(file_norm, user)) return 1; diff --git a/src/debug/dwarf_loc.c b/src/debug/dwarf_loc.c @@ -6,11 +6,10 @@ * caller passes the CFA in via frame->cfa. */ -#include <stdint.h> -#include <string.h> - #include <cfree/arch.h> #include <cfree/dwarf.h> +#include <stdint.h> +#include <string.h> #include "core/core.h" #include "core/heap.h" diff --git a/src/debug/dwarf_open.c b/src/debug/dwarf_open.c @@ -5,12 +5,11 @@ * Return NULL if any of those mandatory five are missing. */ -#include <stdint.h> -#include <string.h> - #include <cfree/arch.h> #include <cfree/dwarf.h> #include <cfree/object.h> +#include <stdint.h> +#include <string.h> #include "core/core.h" #include "core/heap.h" @@ -137,7 +136,7 @@ const char* dw_cstr(const u8* base, u32 size, u32* off) { /* ---- string interning ------------------------------------------------- */ const char* dw_intern(CfreeDebugInfo* d, const char* s, size_t len) { - Sym sym = pool_intern_slice(d->strs, (Slice){ .s = s, .len = len }); + Sym sym = pool_intern_slice(d->strs, (Slice){.s = s, .len = len}); return pool_slice(d->strs, sym).s; } diff --git a/src/debug/dwarf_query.c b/src/debug/dwarf_query.c @@ -4,19 +4,18 @@ * subprogram_at / func_at, var_at, vars_at_*, param_iter_*, loc_read. */ +#include <cfree/arch.h> +#include <cfree/dwarf.h> #include <stddef.h> #include <stdint.h> #include <string.h> -#include <cfree/arch.h> -#include <cfree/dwarf.h> - #include "core/core.h" #include "core/heap.h" #include "debug/dwarf_internal.h" -static void fill_subprogram(CfreeDebugInfo *d, DwSubprog *sp, - CfreeDwarfSubprogram *out) { +static void fill_subprogram(CfreeDebugInfo* d, DwSubprog* sp, + CfreeDwarfSubprogram* out) { memset(out, 0, sizeof(*out)); out->name = sp->name ? cfree_slice_cstr(sp->name) : CFREE_SLICE_NULL; out->low_pc = sp->low_pc; @@ -30,75 +29,61 @@ static void fill_subprogram(CfreeDebugInfo *d, DwSubprog *sp, out->inlined = sp->inlined; } -CfreeStatus cfree_dwarf_subprogram_at(CfreeDebugInfo *d, uint64_t pc, - CfreeDwarfSubprogram *out) { - DwSubprog *sp; - if (!d || !out) - return CFREE_INVALID; +CfreeStatus cfree_dwarf_subprogram_at(CfreeDebugInfo* d, uint64_t pc, + CfreeDwarfSubprogram* out) { + DwSubprog* sp; + if (!d || !out) return CFREE_INVALID; sp = dw_find_subprog(d, pc); - if (!sp) - return CFREE_NOT_FOUND; + if (!sp) return CFREE_NOT_FOUND; fill_subprogram(d, sp, out); return CFREE_OK; } -static DwSubprog *dw_find_subprog_named(CfreeDebugInfo *d, const char *name) { +static DwSubprog* dw_find_subprog_named(CfreeDebugInfo* d, const char* name) { u32 i; - if (!d || !name) - return NULL; + if (!d || !name) return NULL; dw_build_subs(d); for (i = 0; i < d->nsubs; ++i) { - DwSubprog *sp = &d->subs[i]; - if (sp->inlined) - continue; - if (!sp->name || !dw_streq(sp->name, name)) - continue; - if (sp->high_pc > sp->low_pc) - return sp; + DwSubprog* sp = &d->subs[i]; + if (sp->inlined) continue; + if (!sp->name || !dw_streq(sp->name, name)) continue; + if (sp->high_pc > sp->low_pc) return sp; } for (i = 0; i < d->nsubs; ++i) { - DwSubprog *sp = &d->subs[i]; - if (sp->inlined) - continue; - if (sp->name && dw_streq(sp->name, name)) - return sp; + DwSubprog* sp = &d->subs[i]; + if (sp->inlined) continue; + if (sp->name && dw_streq(sp->name, name)) return sp; } return NULL; } -CfreeStatus cfree_dwarf_subprogram_named(CfreeDebugInfo *d, CfreeSlice name, - CfreeDwarfSubprogram *out) { - DwSubprog *sp; - if (!d || !name.s || !out) - return CFREE_INVALID; +CfreeStatus cfree_dwarf_subprogram_named(CfreeDebugInfo* d, CfreeSlice name, + CfreeDwarfSubprogram* out) { + DwSubprog* sp; + if (!d || !name.s || !out) return CFREE_INVALID; sp = dw_find_subprog_named(d, name.s); - if (!sp) - return CFREE_NOT_FOUND; + if (!sp) return CFREE_NOT_FOUND; fill_subprogram(d, sp, out); return CFREE_OK; } -CfreeStatus cfree_dwarf_func_at(CfreeDebugInfo *d, uint64_t pc, - CfreeSlice *name_out, uint64_t *low_out, - uint64_t *high_out) { +CfreeStatus cfree_dwarf_func_at(CfreeDebugInfo* d, uint64_t pc, + CfreeSlice* name_out, uint64_t* low_out, + uint64_t* high_out) { CfreeDwarfSubprogram sp; CfreeStatus st = cfree_dwarf_subprogram_at(d, pc, &sp); - if (st != CFREE_OK) - return st; - if (name_out) - *name_out = sp.name; - if (low_out) - *low_out = sp.low_pc; - if (high_out) - *high_out = sp.high_pc; + if (st != CFREE_OK) return st; + if (name_out) *name_out = sp.name; + if (low_out) *low_out = sp.low_pc; + if (high_out) *high_out = sp.high_pc; return CFREE_OK; } /* ---- variable resolution -------------------------------------------- */ -static void fill_varloc(CfreeDebugInfo *d, u32 cu_idx, const DwLocal *v, u64 pc, - CfreeDwarfVarLoc *out) { - const u8 *lbytes = v->loc; +static void fill_varloc(CfreeDebugInfo* d, u32 cu_idx, const DwLocal* v, u64 pc, + CfreeDwarfVarLoc* out) { + const u8* lbytes = v->loc; u32 llen = v->loc_len; memset(out, 0, sizeof(*out)); out->kind = CFREE_DLOC_EXPR; @@ -106,13 +91,12 @@ static void fill_varloc(CfreeDebugInfo *d, u32 cu_idx, const DwLocal *v, u64 pc, out->type = NULL; if (v->type_die_offset) { out->type = dw_type_from_die(d, cu_idx, v->type_die_offset); - if (out->type) - out->byte_size = out->type->byte_size; + if (out->type) out->byte_size = out->type->byte_size; } /* If the variable was emitted with a loclistx, resolve it now. The * resolved bytes get the same single-op fast-path treatment below. */ if (v->has_loclist && cu_idx < d->ncus) { - const u8 *lb = NULL; + const u8* lb = NULL; u32 ll = 0; if (dw_loclist_resolve(d, &d->cus[cu_idx], v->loclist_index, pc, &lb, &ll)) { @@ -130,7 +114,7 @@ static void fill_varloc(CfreeDebugInfo *d, u32 cu_idx, const DwLocal *v, u64 pc, * we expose the structured kind so callers can fast-path. Otherwise * we surface the raw bytes as EXPR. */ if (lbytes && llen > 0) { - const u8 *e = lbytes; + const u8* e = lbytes; if (llen == 1 && e[0] >= DW_OP_reg0 && e[0] <= DW_OP_reg0 + 31) { out->kind = CFREE_DLOC_REG; out->v.reg = e[0] - DW_OP_reg0; @@ -172,18 +156,17 @@ static void fill_varloc(CfreeDebugInfo *d, u32 cu_idx, const DwLocal *v, u64 pc, out->v.expr.len = 0; } -CfreeStatus cfree_dwarf_var_at(CfreeDebugInfo *d, uint64_t pc, CfreeSlice name, - CfreeDwarfVarLoc *out) { +CfreeStatus cfree_dwarf_var_at(CfreeDebugInfo* d, uint64_t pc, CfreeSlice name, + CfreeDwarfVarLoc* out) { /* Status codes: * CFREE_OK — found; *out filled. * CFREE_INVALID — bad args. * CFREE_NOT_FOUND — pc inside a subprog but no var named `name`, or * pc outside any subprogram and not a global. */ - DwSubprog *sp; + DwSubprog* sp; u32 i; - if (!d || !name.s || !out) - return CFREE_INVALID; + if (!d || !name.s || !out) return CFREE_INVALID; memset(out, 0, sizeof(*out)); sp = dw_find_subprog(d, pc); if (sp) { @@ -191,19 +174,16 @@ CfreeStatus cfree_dwarf_var_at(CfreeDebugInfo *d, uint64_t pc, CfreeSlice name, /* Deepest scope first: walk locals from end (innermost blocks added * after enclosing). */ for (i = sp->nlocals; i > 0; --i) { - DwLocal *v = &sp->locals[i - 1]; - if (!v->name || !dw_streq(v->name, name.s)) - continue; - if (v->has_scope && (pc < v->scope_lo || pc >= v->scope_hi)) - continue; + DwLocal* v = &sp->locals[i - 1]; + if (!v->name || !dw_streq(v->name, name.s)) continue; + if (v->has_scope && (pc < v->scope_lo || pc >= v->scope_hi)) continue; fill_varloc(d, sp->cu_idx, v, pc, out); return CFREE_OK; } /* Then params. */ for (i = 0; i < sp->nparams; ++i) { - DwLocal *v = &sp->params[i]; - if (!v->name || !dw_streq(v->name, name.s)) - continue; + DwLocal* v = &sp->params[i]; + if (!v->name || !dw_streq(v->name, name.s)) continue; fill_varloc(d, sp->cu_idx, v, pc, out); return CFREE_OK; } @@ -211,97 +191,81 @@ CfreeStatus cfree_dwarf_var_at(CfreeDebugInfo *d, uint64_t pc, CfreeSlice name, /* Globals. */ dw_build_globals(d); for (i = 0; i < d->nglobals; ++i) { - DwLocal *v = &d->globals[i]; - if (!v->name || !dw_streq(v->name, name.s)) - continue; + DwLocal* v = &d->globals[i]; + if (!v->name || !dw_streq(v->name, name.s)) continue; fill_varloc(d, 0, v, pc, out); return CFREE_OK; } return CFREE_NOT_FOUND; } -CfreeStatus cfree_dwarf_loc_read(CfreeDebugInfo *d, const CfreeDwarfVarLoc *loc, - const CfreeUnwindFrame *frame, - CfreeDwarfReadMemFn read_mem, void *read_user, - void *dst, size_t cap, size_t *read_out) { +CfreeStatus cfree_dwarf_loc_read(CfreeDebugInfo* d, const CfreeDwarfVarLoc* loc, + const CfreeUnwindFrame* frame, + CfreeDwarfReadMemFn read_mem, void* read_user, + void* dst, size_t cap, size_t* read_out) { size_t want; - if (read_out) - *read_out = 0; - if (!d || !loc || !frame || !dst) - return CFREE_INVALID; + if (read_out) *read_out = 0; + if (!d || !loc || !frame || !dst) return CFREE_INVALID; want = loc->byte_size ? loc->byte_size : cap; - if (want > cap) - want = cap; + if (want > cap) want = cap; switch (loc->kind) { - case CFREE_DLOC_REG: { - uint64_t v = (loc->v.reg < 32) ? frame->regs[loc->v.reg] : 0; - size_t n = want > sizeof(v) ? sizeof(v) : want; - memcpy(dst, &v, n); - if (read_out) - *read_out = n; - return CFREE_OK; - } - case CFREE_DLOC_FRAME_OFS: { - uint64_t addr = frame->cfa + (uint64_t)(int64_t)loc->v.frame_ofs; - CfreeStatus st; - if (!read_mem) - return CFREE_INVALID; - st = read_mem(read_user, addr, dst, want); - if (st != CFREE_OK) - return st; - if (read_out) - *read_out = want; - return CFREE_OK; - } - case CFREE_DLOC_GLOBAL: { - uint64_t addr = loc->v.global; - CfreeStatus st; - if (!read_mem) - return CFREE_INVALID; - st = read_mem(read_user, addr, dst, want); - if (st != CFREE_OK) - return st; - if (read_out) - *read_out = want; - return CFREE_OK; - } - case CFREE_DLOC_EXPR: { - /* Evaluate. We don't have direct access to the variable's - * subprogram's frame_base here — caller-supplied frame must already - * carry the right CFA. The expression itself may be DW_OP_call_frame_cfa - * + DW_OP_consts + DW_OP_plus, etc. */ - DwExprResult r; - if (loc->v.expr.bytes == NULL || loc->v.expr.len == 0) - return CFREE_NOT_FOUND; - if (dw_eval_expr(d, loc->v.expr.bytes, (u32)loc->v.expr.len, NULL, 0, frame, - &r) != 0) - return CFREE_UNSUPPORTED; - if (r.kind == 0) { - CfreeStatus st; - if (!read_mem) - return CFREE_INVALID; - st = read_mem(read_user, r.value, dst, want); - if (st != CFREE_OK) - return st; - if (read_out) - *read_out = want; - return CFREE_OK; - } else if (r.kind == 1) { - size_t n = want > sizeof(r.value) ? sizeof(r.value) : want; - memcpy(dst, &r.value, n); - if (read_out) - *read_out = n; - return CFREE_OK; - } else if (r.kind == 2) { - u64 v = (r.value < 32) ? frame->regs[r.value] : 0; + case CFREE_DLOC_REG: { + uint64_t v = (loc->v.reg < 32) ? frame->regs[loc->v.reg] : 0; size_t n = want > sizeof(v) ? sizeof(v) : want; memcpy(dst, &v, n); - if (read_out) - *read_out = n; + if (read_out) *read_out = n; return CFREE_OK; } - return CFREE_UNSUPPORTED; - } + case CFREE_DLOC_FRAME_OFS: { + uint64_t addr = frame->cfa + (uint64_t)(int64_t)loc->v.frame_ofs; + CfreeStatus st; + if (!read_mem) return CFREE_INVALID; + st = read_mem(read_user, addr, dst, want); + if (st != CFREE_OK) return st; + if (read_out) *read_out = want; + return CFREE_OK; + } + case CFREE_DLOC_GLOBAL: { + uint64_t addr = loc->v.global; + CfreeStatus st; + if (!read_mem) return CFREE_INVALID; + st = read_mem(read_user, addr, dst, want); + if (st != CFREE_OK) return st; + if (read_out) *read_out = want; + return CFREE_OK; + } + case CFREE_DLOC_EXPR: { + /* Evaluate. We don't have direct access to the variable's + * subprogram's frame_base here — caller-supplied frame must already + * carry the right CFA. The expression itself may be DW_OP_call_frame_cfa + * + DW_OP_consts + DW_OP_plus, etc. */ + DwExprResult r; + if (loc->v.expr.bytes == NULL || loc->v.expr.len == 0) + return CFREE_NOT_FOUND; + if (dw_eval_expr(d, loc->v.expr.bytes, (u32)loc->v.expr.len, NULL, 0, + frame, &r) != 0) + return CFREE_UNSUPPORTED; + if (r.kind == 0) { + CfreeStatus st; + if (!read_mem) return CFREE_INVALID; + st = read_mem(read_user, r.value, dst, want); + if (st != CFREE_OK) return st; + if (read_out) *read_out = want; + return CFREE_OK; + } else if (r.kind == 1) { + size_t n = want > sizeof(r.value) ? sizeof(r.value) : want; + memcpy(dst, &r.value, n); + if (read_out) *read_out = n; + return CFREE_OK; + } else if (r.kind == 2) { + u64 v = (r.value < 32) ? frame->regs[r.value] : 0; + size_t n = want > sizeof(v) ? sizeof(v) : want; + memcpy(dst, &v, n); + if (read_out) *read_out = n; + return CFREE_OK; + } + return CFREE_UNSUPPORTED; + } } return CFREE_UNSUPPORTED; } @@ -309,140 +273,130 @@ CfreeStatus cfree_dwarf_loc_read(CfreeDebugInfo *d, const CfreeDwarfVarLoc *loc, /* ---- vars_at_* iterator --------------------------------------------- */ struct CfreeDwarfVarIter { - CfreeDebugInfo *d; - DwSubprog *sp; + CfreeDebugInfo* d; + DwSubprog* sp; u64 pc; u32 mask; u32 phase; /* 0 = locals, 1 = params, 2 = globals, 3 = done */ u32 idx; }; -CfreeStatus cfree_dwarf_vars_at_new(CfreeDebugInfo *d, uint64_t pc, - uint32_t mask, CfreeDwarfVarIter **out) { - CfreeDwarfVarIter *it; - if (!out) - return CFREE_INVALID; +CfreeStatus cfree_dwarf_vars_at_new(CfreeDebugInfo* d, uint64_t pc, + uint32_t mask, CfreeDwarfVarIter** out) { + CfreeDwarfVarIter* it; + if (!out) return CFREE_INVALID; *out = NULL; - if (!d) - return CFREE_INVALID; - it = (CfreeDwarfVarIter *)d->h->alloc(d->h, sizeof(*it), - _Alignof(CfreeDwarfVarIter)); - if (!it) - return CFREE_NOMEM; + if (!d) return CFREE_INVALID; + it = (CfreeDwarfVarIter*)d->h->alloc(d->h, sizeof(*it), + _Alignof(CfreeDwarfVarIter)); + if (!it) return CFREE_NOMEM; it->d = d; it->pc = pc; it->mask = mask; it->sp = dw_find_subprog(d, pc); - if (it->sp) - dw_build_locals(d, it->sp); + if (it->sp) dw_build_locals(d, it->sp); it->phase = 0; it->idx = it->sp ? it->sp->nlocals : 0; *out = it; return CFREE_OK; } -CfreeIterResult cfree_dwarf_vars_at_next(CfreeDwarfVarIter *it, - CfreeDwarfVar *out) { - if (!it || !out) - return CFREE_ITER_ERROR; +CfreeIterResult cfree_dwarf_vars_at_next(CfreeDwarfVarIter* it, + CfreeDwarfVar* out) { + if (!it || !out) return CFREE_ITER_ERROR; for (;;) { switch (it->phase) { - case 0: { - if (!(it->mask & (1u << CFREE_DVR_LOCAL))) { - it->phase = 1; - it->idx = 0; - break; - } - if (it->idx == 0) { - it->phase = 1; - it->idx = 0; - break; - } - { - DwLocal *v = &it->sp->locals[--it->idx]; - if (v->has_scope && (it->pc < v->scope_lo || it->pc >= v->scope_hi)) + case 0: { + if (!(it->mask & (1u << CFREE_DVR_LOCAL))) { + it->phase = 1; + it->idx = 0; break; - out->name = v->name ? cfree_slice_cstr(v->name) : CFREE_SLICE_NULL; - out->role = CFREE_DVR_LOCAL; - fill_varloc(it->d, it->sp->cu_idx, v, it->pc, &out->loc); - return CFREE_ITER_ITEM; - } - } - case 1: { - if (!it->sp || !(it->mask & (1u << CFREE_DVR_ARG))) { - it->phase = 2; - it->idx = 0; - break; - } - if (it->idx >= it->sp->nparams) { - it->phase = 2; - it->idx = 0; - break; - } - { - DwLocal *v = &it->sp->params[it->idx++]; - out->name = v->name ? cfree_slice_cstr(v->name) : CFREE_SLICE_NULL; - out->role = CFREE_DVR_ARG; - fill_varloc(it->d, it->sp->cu_idx, v, it->pc, &out->loc); - return CFREE_ITER_ITEM; - } - } - case 2: { - if (!(it->mask & (1u << CFREE_DVR_GLOBAL))) { - it->phase = 3; - break; + } + if (it->idx == 0) { + it->phase = 1; + it->idx = 0; + break; + } + { + DwLocal* v = &it->sp->locals[--it->idx]; + if (v->has_scope && (it->pc < v->scope_lo || it->pc >= v->scope_hi)) + break; + out->name = v->name ? cfree_slice_cstr(v->name) : CFREE_SLICE_NULL; + out->role = CFREE_DVR_LOCAL; + fill_varloc(it->d, it->sp->cu_idx, v, it->pc, &out->loc); + return CFREE_ITER_ITEM; + } } - dw_build_globals(it->d); - if (it->idx >= it->d->nglobals) { - it->phase = 3; - break; + case 1: { + if (!it->sp || !(it->mask & (1u << CFREE_DVR_ARG))) { + it->phase = 2; + it->idx = 0; + break; + } + if (it->idx >= it->sp->nparams) { + it->phase = 2; + it->idx = 0; + break; + } + { + DwLocal* v = &it->sp->params[it->idx++]; + out->name = v->name ? cfree_slice_cstr(v->name) : CFREE_SLICE_NULL; + out->role = CFREE_DVR_ARG; + fill_varloc(it->d, it->sp->cu_idx, v, it->pc, &out->loc); + return CFREE_ITER_ITEM; + } } - { - DwLocal *v = &it->d->globals[it->idx++]; - out->name = v->name ? cfree_slice_cstr(v->name) : CFREE_SLICE_NULL; - out->role = CFREE_DVR_GLOBAL; - fill_varloc(it->d, 0, v, it->pc, &out->loc); - return CFREE_ITER_ITEM; + case 2: { + if (!(it->mask & (1u << CFREE_DVR_GLOBAL))) { + it->phase = 3; + break; + } + dw_build_globals(it->d); + if (it->idx >= it->d->nglobals) { + it->phase = 3; + break; + } + { + DwLocal* v = &it->d->globals[it->idx++]; + out->name = v->name ? cfree_slice_cstr(v->name) : CFREE_SLICE_NULL; + out->role = CFREE_DVR_GLOBAL; + fill_varloc(it->d, 0, v, it->pc, &out->loc); + return CFREE_ITER_ITEM; + } } - } - default: - return CFREE_ITER_END; + default: + return CFREE_ITER_END; } } } -void cfree_dwarf_vars_at_free(CfreeDwarfVarIter *it) { - if (!it) - return; +void cfree_dwarf_vars_at_free(CfreeDwarfVarIter* it) { + if (!it) return; it->d->h->free(it->d->h, it, sizeof(*it)); } /* ---- param_iter_* --------------------------------------------------- */ struct CfreeDwarfParamIter { - CfreeDebugInfo *d; - DwSubprog *sp; + CfreeDebugInfo* d; + DwSubprog* sp; u64 pc; u32 idx; }; -CfreeStatus cfree_dwarf_param_iter_new(CfreeDebugInfo *d, uint64_t pc, - CfreeDwarfParamIter **out) { - CfreeDwarfParamIter *it; - DwSubprog *sp; - if (!out) - return CFREE_INVALID; +CfreeStatus cfree_dwarf_param_iter_new(CfreeDebugInfo* d, uint64_t pc, + CfreeDwarfParamIter** out) { + CfreeDwarfParamIter* it; + DwSubprog* sp; + if (!out) return CFREE_INVALID; *out = NULL; - if (!d) - return CFREE_INVALID; + if (!d) return CFREE_INVALID; sp = dw_find_subprog(d, pc); - if (!sp) - return CFREE_NOT_FOUND; + if (!sp) return CFREE_NOT_FOUND; dw_build_locals(d, sp); - it = (CfreeDwarfParamIter *)d->h->alloc(d->h, sizeof(*it), - _Alignof(CfreeDwarfParamIter)); - if (!it) - return CFREE_NOMEM; + it = (CfreeDwarfParamIter*)d->h->alloc(d->h, sizeof(*it), + _Alignof(CfreeDwarfParamIter)); + if (!it) return CFREE_NOMEM; it->d = d; it->sp = sp; it->pc = pc; @@ -451,24 +405,19 @@ CfreeStatus cfree_dwarf_param_iter_new(CfreeDebugInfo *d, uint64_t pc, return CFREE_OK; } -CfreeStatus cfree_dwarf_param_iter_new_named(CfreeDebugInfo *d, - CfreeSlice name, - CfreeDwarfParamIter **out) { - CfreeDwarfParamIter *it; - DwSubprog *sp; - if (!out) - return CFREE_INVALID; +CfreeStatus cfree_dwarf_param_iter_new_named(CfreeDebugInfo* d, CfreeSlice name, + CfreeDwarfParamIter** out) { + CfreeDwarfParamIter* it; + DwSubprog* sp; + if (!out) return CFREE_INVALID; *out = NULL; - if (!d || !name.s) - return CFREE_INVALID; + if (!d || !name.s) return CFREE_INVALID; sp = dw_find_subprog_named(d, name.s); - if (!sp) - return CFREE_NOT_FOUND; + if (!sp) return CFREE_NOT_FOUND; dw_build_locals(d, sp); - it = (CfreeDwarfParamIter *)d->h->alloc(d->h, sizeof(*it), - _Alignof(CfreeDwarfParamIter)); - if (!it) - return CFREE_NOMEM; + it = (CfreeDwarfParamIter*)d->h->alloc(d->h, sizeof(*it), + _Alignof(CfreeDwarfParamIter)); + if (!it) return CFREE_NOMEM; it->d = d; it->sp = sp; it->pc = sp->low_pc; @@ -477,14 +426,12 @@ CfreeStatus cfree_dwarf_param_iter_new_named(CfreeDebugInfo *d, return CFREE_OK; } -CfreeIterResult cfree_dwarf_param_iter_next(CfreeDwarfParamIter *it, - CfreeDwarfVar *out) { - if (!it || !out) - return CFREE_ITER_ERROR; - if (it->idx >= it->sp->nparams) - return CFREE_ITER_END; +CfreeIterResult cfree_dwarf_param_iter_next(CfreeDwarfParamIter* it, + CfreeDwarfVar* out) { + if (!it || !out) return CFREE_ITER_ERROR; + if (it->idx >= it->sp->nparams) return CFREE_ITER_END; { - DwLocal *v = &it->sp->params[it->idx++]; + DwLocal* v = &it->sp->params[it->idx++]; out->name = v->name ? cfree_slice_cstr(v->name) : CFREE_SLICE_NULL; out->role = CFREE_DVR_ARG; fill_varloc(it->d, it->sp->cu_idx, v, it->pc, &out->loc); @@ -492,8 +439,7 @@ CfreeIterResult cfree_dwarf_param_iter_next(CfreeDwarfParamIter *it, return CFREE_ITER_ITEM; } -void cfree_dwarf_param_iter_free(CfreeDwarfParamIter *it) { - if (!it) - return; +void cfree_dwarf_param_iter_free(CfreeDwarfParamIter* it) { + if (!it) return; it->d->h->free(it->d->h, it, sizeof(*it)); } diff --git a/src/debug/dwarf_type.c b/src/debug/dwarf_type.c @@ -5,12 +5,11 @@ * and qualifier-types (const/volatile/restrict transparent to inner). */ +#include <cfree/dwarf.h> #include <stddef.h> #include <stdint.h> #include <string.h> -#include <cfree/dwarf.h> - #include "core/core.h" #include "core/heap.h" #include "core/util.h" @@ -482,7 +481,8 @@ struct CfreeDwarfEnumIter { u32 idx; }; -CfreeStatus cfree_dwarf_enum_iter_new(CfreeDebugInfo* d, const CfreeDwarfType* t, +CfreeStatus cfree_dwarf_enum_iter_new(CfreeDebugInfo* d, + const CfreeDwarfType* t, CfreeDwarfEnumIter** out) { CfreeDwarfEnumIter* it; if (!out) return CFREE_INVALID; @@ -510,7 +510,7 @@ CfreeIterResult cfree_dwarf_enum_iter_next(CfreeDwarfEnumIter* it, if (t->kind != DTK_ENUM) return CFREE_ITER_END; if (it->idx >= t->nevals) return CFREE_ITER_END; out->name = t->evals[it->idx].name ? cfree_slice_cstr(t->evals[it->idx].name) - : CFREE_SLICE_NULL; + : CFREE_SLICE_NULL; out->value = t->evals[it->idx].value; it->idx++; return CFREE_ITER_ITEM; diff --git a/src/emu/cpu.c b/src/emu/cpu.c @@ -25,8 +25,7 @@ struct EmuCPUState { }; EmuCPUState* emu_cpu_new_with_arch_state(Compiler* c, CfreeArchKind arch, - u64 initial_pc, - size_t arch_state_size, + u64 initial_pc, size_t arch_state_size, size_t arch_state_align) { Heap* h; EmuCPUState* s; @@ -70,9 +69,7 @@ void emu_cpu_set_thread(EmuCPUState* s, EmuThread* thread) { if (s) s->thread = thread; } -EmuThread* emu_cpu_thread(const EmuCPUState* s) { - return s ? s->thread : NULL; -} +EmuThread* emu_cpu_thread(const EmuCPUState* s) { return s ? s->thread : NULL; } u64 emu_cpu_pc(const EmuCPUState* s) { return s ? s->pc : 0; } @@ -110,8 +107,7 @@ u8* emu_cpu_va_to_host_pub(EmuCPUState* s, u64 va, u64 nbytes) { return emu_cpu_va_to_host_perm(s, va, nbytes, 0); } -u8* emu_cpu_va_to_host_perm(EmuCPUState* s, u64 va, u64 nbytes, - u8 need_perms) { +u8* emu_cpu_va_to_host_perm(EmuCPUState* s, u64 va, u64 nbytes, u8 need_perms) { if (!s || !s->addr_space) return NULL; return emu_addr_space_ptr(s->addr_space, va, nbytes, need_perms); } @@ -141,9 +137,7 @@ void emu_cpu_clear_trap(EmuCPUState* s) { s->exit_code = 0; } -EmuCPUState* emu_thread_cpu(EmuThread* t) { - return t ? t->cpu : NULL; -} +EmuCPUState* emu_thread_cpu(EmuThread* t) { return t ? t->cpu : NULL; } CfreeCgTypeId emu_thread_type(Compiler* c) { return cfree_cg_type_ptr( diff --git a/src/emu/dl.c b/src/emu/dl.c @@ -100,13 +100,11 @@ static CfreeStatus add_import_binding(Compiler* c, EmuProcess* process, if (img->import_thunk_next + thunk_size > img->import_thunk_base + img->import_thunk_size) return CFREE_NOMEM; - if (ensure_import_binding_cap(c, img, img->nimport_bindings + 1u) != - CFREE_OK) + if (ensure_import_binding_cap(c, img, img->nimport_bindings + 1u) != CFREE_OK) return CFREE_ERR; thunk = img->import_thunk_next; img->import_thunk_next += thunk_size; - if (emit_import_thunk(process, thunk) != CFREE_OK) - return CFREE_ERR; + if (emit_import_thunk(process, thunk) != CFREE_OK) return CFREE_ERR; b = &img->import_bindings[img->nimport_bindings++]; memset(b, 0, sizeof(*b)); b->object_name = req->object_name; @@ -119,7 +117,8 @@ static CfreeStatus add_import_binding(Compiler* c, EmuProcess* process, b->signature = resolved->signature.nargs || resolved->signature.result ? resolved->signature : req->signature; - if (!b->signature.nargs && !b->signature.result) b->signature = default_u64_sig(); + if (!b->signature.nargs && !b->signature.result) + b->signature = default_u64_sig(); *out_addr = thunk; return CFREE_OK; } @@ -145,8 +144,7 @@ CfreeStatus emu_dl_resolve_import_thunk(EmuProcess* process, u64 target, } CfreeStatus emu_call_host_import(EmuThread* thread, EmuImportBinding* b, - const u64* args, u32 nargs, - u64* result_out) { + const u64* args, u32 nargs, u64* result_out) { CfreeEmuImportSignature sig; if (result_out) *result_out = 0; if (!thread || !b || !b->resolved_host_fn) return CFREE_INVALID; @@ -156,19 +154,19 @@ CfreeStatus emu_call_host_import(EmuThread* thread, EmuImportBinding* b, if (sig.nargs > nargs || sig.nargs > 3u) return CFREE_UNSUPPORTED; if (sig.nargs == 0u) { if (sig.result != CFREE_EMU_VALUE_VOID) { - u64 (*fn0)(void) = (u64(*)(void))b->resolved_host_fn; + u64 (*fn0)(void) = (u64 (*)(void))b->resolved_host_fn; if (result_out) *result_out = fn0(); } else { ((void (*)(void))b->resolved_host_fn)(); } } else if (sig.nargs == 1u) { - u64 (*fn1)(u64) = (u64(*)(u64))b->resolved_host_fn; + u64 (*fn1)(u64) = (u64 (*)(u64))b->resolved_host_fn; if (result_out) *result_out = fn1(args[0]); } else if (sig.nargs == 2u) { - u64 (*fn2)(u64, u64) = (u64(*)(u64, u64))b->resolved_host_fn; + u64 (*fn2)(u64, u64) = (u64 (*)(u64, u64))b->resolved_host_fn; if (result_out) *result_out = fn2(args[0], args[1]); } else if (sig.nargs == 3u) { - u64 (*fn3)(u64, u64, u64) = (u64(*)(u64, u64, u64))b->resolved_host_fn; + u64 (*fn3)(u64, u64, u64) = (u64 (*)(u64, u64, u64))b->resolved_host_fn; if (result_out) *result_out = fn3(args[0], args[1], args[2]); } return CFREE_OK; @@ -193,23 +191,19 @@ static CfreeStatus load_needed_objects(Compiler* c, EmuProcess* process, !opts->bindings->resolve_object) continue; for (k = 0; k < img->link_map.nobjects; ++k) { - if (cfree_slice_eq(img->link_map.objects[k].name, - needed) || - cfree_slice_eq(img->link_map.objects[k].soname, - needed)) { + if (cfree_slice_eq(img->link_map.objects[k].name, needed) || + cfree_slice_eq(img->link_map.objects[k].soname, needed)) { loaded = 1; break; } } if (loaded) continue; - if (opts->bindings->resolve_object(opts->bindings->user, process, - needed, &bytes) != - CFREE_OK || + if (opts->bindings->resolve_object(opts->bindings->user, process, needed, + &bytes) != CFREE_OK || !bytes.data) return CFREE_NOT_FOUND; if (!fmt->map_object || - fmt->map_object(c, process, img, needed, bytes, 0, - &k) != CFREE_OK) + fmt->map_object(c, process, img, needed, bytes, 0, &k) != CFREE_OK) return CFREE_ERR; } } @@ -220,8 +214,7 @@ static CfreeStatus resolve_reloc_symbol(Compiler* c, EmuProcess* process, const EmuLoadOptions* opts, const ObjFormatEmuOps* fmt, EmuLoadedObject* obj, u64 sym_idx, - u64 patch_addr, - EmuDynamicImport* req, + u64 patch_addr, EmuDynamicImport* req, u64* value_out) { EmuLoadedImage* img = &process->image; EmuDynSymbol sym; @@ -231,8 +224,7 @@ static CfreeStatus resolve_reloc_symbol(Compiler* c, EmuProcess* process, fmt->dyn_symbol_by_index(process, obj, sym_idx, &sym) != CFREE_OK) return CFREE_INVALID; memset(req, 0, sizeof(*req)); - req->object_name = - obj->imports.nneeded ? obj->imports.needed[0] : obj->name; + req->object_name = obj->imports.nneeded ? obj->imports.needed[0] : obj->name; req->symbol_name = sym.name; req->got_vaddr = patch_addr; st = emu_dl_lookup_symbol(process, sym.name, value_out); @@ -266,8 +258,7 @@ static CfreeStatus apply_reloc_table(Compiler* c, EmuProcess* process, u32 kind_u; EmuDynRelocClass cls; patch = emu_addr_space_ptr(&img->addr_space, reloc.patch_addr, - reloc.width ? reloc.width : 8u, - EMU_MEM_WRITE); + reloc.width ? reloc.width : 8u, EMU_MEM_WRITE); if (!patch) return CFREE_INVALID; if (fmt->reloc_classify(process, obj, &reloc, &cls, &kind_u) != CFREE_OK) @@ -280,8 +271,7 @@ static CfreeStatus apply_reloc_table(Compiler* c, EmuProcess* process, EmuDynamicImport req; CfreeStatus st = resolve_reloc_symbol(c, process, opts, fmt, obj, reloc.symbol_index, - reloc.patch_addr, - &req, &value); + reloc.patch_addr, &req, &value); if (st != CFREE_OK) { if (cls == EMU_DYN_RELOC_IMPORT_SLOT) { u32 thunk_size = import_thunk_size(process); @@ -291,8 +281,7 @@ static CfreeStatus apply_reloc_table(Compiler* c, EmuProcess* process, return CFREE_NOMEM; value = img->import_thunk_next; img->import_thunk_next += thunk_size; - if (emit_import_thunk(process, value) != CFREE_OK) - return CFREE_ERR; + if (emit_import_thunk(process, value) != CFREE_OK) return CFREE_ERR; } else { return st; } @@ -302,8 +291,7 @@ static CfreeStatus apply_reloc_table(Compiler* c, EmuProcess* process, } if (emu_apply_reloc_bytes(c, kind, patch, value, reloc.addend, - reloc.patch_addr) != - CFREE_OK) + reloc.patch_addr) != CFREE_OK) return CFREE_ERR; emu_addr_space_invalidate(&img->addr_space, reloc.patch_addr, reloc.width ? reloc.width : 8u); @@ -319,11 +307,10 @@ static CfreeStatus apply_dynamic_relocs(Compiler* c, EmuProcess* process, for (oi = 0; oi < img->link_map.nobjects; ++oi) { EmuLoadedObject* obj = &img->link_map.objects[oi]; CfreeStatus st; - st = apply_reloc_table(c, process, opts, fmt, obj, - EMU_DYN_RELOC_TABLE_MAIN); + st = + apply_reloc_table(c, process, opts, fmt, obj, EMU_DYN_RELOC_TABLE_MAIN); if (st != CFREE_OK) return st; - st = apply_reloc_table(c, process, opts, fmt, obj, - EMU_DYN_RELOC_TABLE_PLT); + st = apply_reloc_table(c, process, opts, fmt, obj, EMU_DYN_RELOC_TABLE_PLT); if (st != CFREE_OK) return st; } return CFREE_OK; @@ -339,12 +326,10 @@ CfreeStatus emu_dl_init_process(Compiler* c, EmuProcess* process) { return CFREE_UNSUPPORTED; if (process->os->emu_find_map_region(process, EMU_IMPORT_THUNK_RESERVE, img->addr_space.page_size, - EMU_OS_MAP_DL_THUNKS, &base) != - CFREE_OK) + EMU_OS_MAP_DL_THUNKS, &base) != CFREE_OK) return CFREE_ERR; if (emu_addr_space_map(&img->addr_space, base, EMU_IMPORT_THUNK_RESERVE, - EMU_MEM_READ | EMU_MEM_EXEC, EMU_MAP_ANON) != - CFREE_OK) + EMU_MEM_READ | EMU_MEM_EXEC, EMU_MAP_ANON) != CFREE_OK) return CFREE_ERR; img->import_thunk_base = base; img->import_thunk_size = EMU_IMPORT_THUNK_RESERVE; @@ -361,7 +346,8 @@ CfreeStatus emu_dl_load_dependencies_and_relocate(Compiler* c, const ObjFormatEmuOps* fmt) { CfreeStatus st; if (!c || !process || !opts || !fmt) return CFREE_INVALID; - process->dl_policy.global_scope_head = process->image.link_map.global_scope_head; + process->dl_policy.global_scope_head = + process->image.link_map.global_scope_head; st = load_needed_objects(c, process, opts, fmt); if (st != CFREE_OK) return st; st = emu_tls_rebuild_modules(c, process); diff --git a/src/emu/emu.c b/src/emu/emu.c @@ -100,8 +100,7 @@ static CfreeStatus emu_public_import_adapter(void* user, EmuProcess* process, CfreeEmu* e = (CfreeEmu*)user; CfreeEmuImportRequest public_req; (void)process; - if (!e || !e->bindings.resolve_import || !req || !out) - return CFREE_INVALID; + if (!e || !e->bindings.resolve_import || !req || !out) return CFREE_INVALID; memset(&public_req, 0, sizeof(public_req)); public_req.object_name = req->object_name; public_req.symbol_name = req->symbol_name; @@ -121,8 +120,8 @@ static CfreeStatus emu_public_object_adapter(void* user, EmuProcess* process, memset(&public_req, 0, sizeof(public_req)); public_req.object_name = object_name; memset(&public_out, 0, sizeof(public_out)); - st = e->bindings.resolve_object(e->bindings.user, e, &public_req, - &public_out); + st = + e->bindings.resolve_object(e->bindings.user, e, &public_req, &public_out); if (st != CFREE_OK) return st; *out_bytes = public_out.object_bytes; return public_out.object_bytes.data ? CFREE_OK : CFREE_NOT_FOUND; @@ -137,8 +136,8 @@ const CfreeJitHost* emu_get_jit_host(const CfreeEmu* e) { return e ? e->host : NULL; } -CfreeStatus emu_process_os_alloc(Compiler* c, EmuProcess* process, - size_t size, size_t align) { +CfreeStatus emu_process_os_alloc(Compiler* c, EmuProcess* process, size_t size, + size_t align) { Heap* heap; if (!c || !process || !size || process->os_private) return CFREE_INVALID; heap = c->ctx->heap; @@ -185,7 +184,8 @@ static CfreeStatus emu_resolve_config(Compiler* c, const CfreeEmuOptions* opts, const CfreeOsImpl* os; CfreeStatus st; - if (!c || !opts || !out || !opts->guest_bytes.data || opts->guest_bytes.len == 0) + if (!c || !opts || !out || !opts->guest_bytes.data || + opts->guest_bytes.len == 0) return CFREE_INVALID; memset(out, 0, sizeof(*out)); @@ -406,8 +406,7 @@ static void* translate_block(CfreeEmu* e, u64 guest_pc) { return NULL; host_pc = emu_cpu_va_to_host_perm(emu_main_cpu(e), guest_pc, - arch->decode->min_insn_len, - EMU_MEM_EXEC); + arch->decode->min_insn_len, EMU_MEM_EXEC); if (!host_pc) return NULL; va_end = emu_addr_space_contig_len(&e->process.image.addr_space, guest_pc, EMU_MEM_EXEC); @@ -415,7 +414,8 @@ static void* translate_block(CfreeEmu* e, u64 guest_pc) { decode_len = (size_t)va_end; heap = e->c->ctx->heap; insts = (CfreeDecodedInsn*)heap->alloc( - heap, sizeof(*insts) * EMU_MAX_INSTS_PER_BLOCK, _Alignof(CfreeDecodedInsn)); + heap, sizeof(*insts) * EMU_MAX_INSTS_PER_BLOCK, + _Alignof(CfreeDecodedInsn)); if (!insts) compiler_panic(e->c, no_loc(), "emu: out of memory"); st = arch->decode->decode_block(e->c, host_pc, decode_len, guest_pc, insts, EMU_MAX_INSTS_PER_BLOCK, &ninsts); @@ -510,7 +510,8 @@ void* cfree_emu_lookup(CfreeEmu* e, uint64_t guest_pc) { if (!e) return NULL; - if (e->cache && e->cache_generation != e->process.image.addr_space.generation) { + if (e->cache && + e->cache_generation != e->process.image.addr_space.generation) { emu_cache_free(e->cache); e->cache = NULL; e->cache_generation = 0; @@ -618,9 +619,7 @@ CfreeStatus cfree_emu_run(CfreeCompiler* c, const CfreeEmuOptions* opts, * Used by emu_runtime_extern_resolver for EMU_SYM_CPU_STATE. */ EmuCPUState* emu_internal_cpu(CfreeEmu* e) { return emu_main_cpu(e); } -EmuProcess* emu_internal_process(CfreeEmu* e) { - return e ? &e->process : NULL; -} +EmuProcess* emu_internal_process(CfreeEmu* e) { return e ? &e->process : NULL; } /* ---- Block symbol naming ---- * "emu_block_<16-hex-pc>" — fixed-width hex so the linker's hash diff --git a/src/emu/emu.h b/src/emu/emu.h @@ -48,7 +48,8 @@ typedef struct EmuObjectFormatData EmuObjectFormatData; /* ---- Per-emu JIT host wiring ------------------------------------ */ /* `host` is borrowed and must outlive the CfreeEmu. The setter remains for - * internal callers that construct an emu before wiring driver-owned JIT state. */ + * internal callers that construct an emu before wiring driver-owned JIT state. + */ void emu_set_jit_host(CfreeEmu*, const CfreeJitHost*); const CfreeJitHost* emu_get_jit_host(const CfreeEmu*); @@ -290,8 +291,8 @@ struct EmuExternalBindings { CfreeStatus (*resolve_import)(void* user, EmuProcess*, const EmuDynamicImport*, CfreeEmuResolvedImport* out); - CfreeStatus (*resolve_object)(void* user, EmuProcess*, - CfreeSlice object_name, CfreeSlice* out_bytes); + CfreeStatus (*resolve_object)(void* user, EmuProcess*, CfreeSlice object_name, + CfreeSlice* out_bytes); void* user; }; @@ -329,20 +330,18 @@ struct CfreeOsImpl { void (*emu_destroy_process_private)(Compiler*, EmuProcess*); CfreeStatus (*emu_init_thread_private)(Compiler*, EmuProcess*, EmuThread*); void (*emu_destroy_thread_private)(Compiler*, EmuThread*); - CfreeStatus (*emu_init_process)(Compiler*, EmuProcess*, - const EmuLoadOptions*, + CfreeStatus (*emu_init_process)(Compiler*, EmuProcess*, const EmuLoadOptions*, const EmuLoadedImage*); CfreeStatus (*emu_init_thread)(Compiler*, EmuProcess*, EmuThread*); CfreeStatus (*emu_decode_syscall)(EmuProcess*, EmuThread*, EmuSyscallRequest* out); CfreeStatus (*emu_encode_syscall_result)(EmuProcess*, EmuThread*, const EmuSyscallResult*); - u64 (*emu_syscall_next_pc)(EmuProcess*, EmuThread*, - const EmuSyscallRequest*, u64 next_pc); + u64 (*emu_syscall_next_pc)(EmuProcess*, EmuThread*, const EmuSyscallRequest*, + u64 next_pc); CfreeStatus (*emu_find_map_region)(EmuProcess*, u64 nbytes, u64 align, u32 purpose, u64* out); - void (*emu_note_map_region)(EmuProcess*, u64 base, u64 nbytes, - u32 purpose); + void (*emu_note_map_region)(EmuProcess*, u64 base, u64 nbytes, u32 purpose); CfreeStatus (*emu_default_syscall)(void* user, EmuProcess*, EmuThread*, const EmuSyscallRequest*, EmuSyscallResult* out); @@ -362,12 +361,11 @@ CfreeStatus emu_dl_init_process(Compiler*, EmuProcess*); CfreeStatus emu_dl_load_dependencies_and_relocate(Compiler*, EmuProcess*, const EmuLoadOptions*, const ObjFormatEmuOps*); -CfreeStatus emu_dl_lookup_symbol(EmuProcess*, CfreeSlice symbol, - u64* out_addr); +CfreeStatus emu_dl_lookup_symbol(EmuProcess*, CfreeSlice symbol, u64* out_addr); CfreeStatus emu_dl_resolve_import_thunk(EmuProcess*, u64 target, EmuImportBinding** out); -CfreeStatus emu_call_host_import(EmuThread*, EmuImportBinding*, - const u64* args, u32 nargs, u64* result_out); +CfreeStatus emu_call_host_import(EmuThread*, EmuImportBinding*, const u64* args, + u32 nargs, u64* result_out); CfreeStatus emu_object_format_data_alloc(Compiler*, EmuLoadedObject*, size_t, size_t, void** out); CfreeStatus emu_apply_reloc_bytes(Compiler*, RelocKind, u8* P_bytes, u64 S, @@ -379,8 +377,8 @@ CfreeStatus emu_tls_copy_module_image(EmuProcess*, const EmuTlsModule*, u64 base); void emu_tls_destroy_process(Compiler*, EmuProcess*); void emu_tls_destroy_blocks(Compiler*, EmuTlsBlocks*); -CfreeStatus emu_fault_deliver(EmuProcess*, EmuThread*, - const EmuFaultEvent*, u64* next_pc_out); +CfreeStatus emu_fault_deliver(EmuProcess*, EmuThread*, const EmuFaultEvent*, + u64* next_pc_out); CfreeStatus emu_process_os_alloc(Compiler*, EmuProcess*, size_t size, size_t align); void emu_process_os_free(Compiler*, EmuProcess*, size_t size); @@ -392,8 +390,7 @@ void emu_addr_space_destroy(EmuAddrSpace*); CfreeStatus emu_addr_space_map(EmuAddrSpace*, u64 va, u64 nbytes, u8 perms, EmuMapKind kind); CfreeStatus emu_addr_space_unmap(EmuAddrSpace*, u64 va, u64 nbytes); -CfreeStatus emu_addr_space_protect(EmuAddrSpace*, u64 va, u64 nbytes, - u8 perms); +CfreeStatus emu_addr_space_protect(EmuAddrSpace*, u64 va, u64 nbytes, u8 perms); CfreeStatus emu_addr_space_find_gap(EmuAddrSpace*, u64 nbytes, u64 align, u64 min_va, u64 max_va, u64* out); CfreeStatus emu_addr_space_set_brk(EmuAddrSpace*, u64 requested, @@ -417,8 +414,7 @@ typedef enum EmuTrapReason { } EmuTrapReason; EmuCPUState* emu_cpu_new_with_arch_state(Compiler*, CfreeArchKind, - u64 initial_pc, - size_t arch_state_size, + u64 initial_pc, size_t arch_state_size, size_t arch_state_align); void emu_cpu_free(EmuCPUState*); void* emu_cpu_arch_state(EmuCPUState*); diff --git a/src/emu/image.c b/src/emu/image.c @@ -75,10 +75,9 @@ static CfreeStatus ensure_map_cap(EmuAddrSpace* as, u32 need) { old_cap = as->maps_cap; new_cap = old_cap ? old_cap * 2u : 8u; while (new_cap < need) new_cap *= 2u; - grown = (EmuMap*)as->heap->realloc(as->heap, as->maps, - sizeof(*as->maps) * old_cap, - sizeof(*as->maps) * new_cap, - _Alignof(EmuMap)); + grown = (EmuMap*)as->heap->realloc( + as->heap, as->maps, sizeof(*as->maps) * old_cap, + sizeof(*as->maps) * new_cap, _Alignof(EmuMap)); if (!grown) return CFREE_NOMEM; as->maps = grown; as->maps_cap = new_cap; @@ -162,8 +161,7 @@ CfreeStatus emu_addr_space_map(EmuAddrSpace* as, u64 va, u64 nbytes, u8 perms, EmuMap m; CfreeStatus st; if (!as || !as->heap || !nbytes) return CFREE_INVALID; - if ((va & (as->page_size - 1u)) != 0 || - (nbytes & (as->page_size - 1u)) != 0) + if ((va & (as->page_size - 1u)) != 0 || (nbytes & (as->page_size - 1u)) != 0) return CFREE_INVALID; if (va + nbytes < va) return CFREE_INVALID; if (!range_is_free(as, va, va + nbytes)) return CFREE_INVALID; diff --git a/src/emu/runtime.c b/src/emu/runtime.c @@ -204,9 +204,8 @@ static u64 emu_deliver_memory_fault(EmuThread* thread, u64 addr, u8 access, return delivered_pc; } -static u64 emu_mem_load_checked(EmuThread* t, u64 addr, u64 nbytes, - u8 access, u64 fault_pc, u64 next_pc, - u64* value_out) { +static u64 emu_mem_load_checked(EmuThread* t, u64 addr, u64 nbytes, u8 access, + u64 fault_pc, u64 next_pc, u64* value_out) { EmuCPUState* s = emu_thread_cpu(t); u8* p = emu_cpu_va_to_host_perm(s, addr, nbytes, access); u64 v = 0; diff --git a/src/emu/tls.c b/src/emu/tls.c @@ -72,8 +72,8 @@ CfreeStatus emu_tls_rebuild_modules(Compiler* c, EmuProcess* process) { return CFREE_OK; } -CfreeStatus emu_tls_blocks_add(Compiler* c, EmuTlsBlocks* blocks, - u32 module_id, u64 base, u64 memsz) { +CfreeStatus emu_tls_blocks_add(Compiler* c, EmuTlsBlocks* blocks, u32 module_id, + u64 base, u64 memsz) { EmuTlsBlock* b; if (!c || !blocks || !module_id) return CFREE_INVALID; if (ensure_tls_block_cap(c, blocks, blocks->nblocks + 1u) != CFREE_OK) @@ -102,9 +102,9 @@ void emu_tls_destroy_process(Compiler* c, EmuProcess* process) { if (!c || !process) return; heap = c->ctx->heap; if (process->tls_state.modules) { - heap->free(heap, process->tls_state.modules, - sizeof(*process->tls_state.modules) * - process->tls_state.modules_cap); + heap->free( + heap, process->tls_state.modules, + sizeof(*process->tls_state.modules) * process->tls_state.modules_cap); } memset(&process->tls_state, 0, sizeof(process->tls_state)); } diff --git a/src/link/link_image_id.c b/src/link/link_image_id.c @@ -28,8 +28,7 @@ static u64 fnv1a64(const u8* data, size_t n, u64 seed) { return h; } -void link_image_id_compute(const LinkImage* img, - u8 out[LINK_IMAGE_ID_BYTES]) { +void link_image_id_compute(const LinkImage* img, u8 out[LINK_IMAGE_ID_BYTES]) { const u64 SEED_LO = 0xcbf29ce484222325ull; const u64 SEED_HI = 0x14650fb0739d0383ull; u64 lo = SEED_LO, hi = SEED_HI; diff --git a/src/link/link_relocatable.c b/src/link/link_relocatable.c @@ -296,9 +296,9 @@ static void rel_copy_sections(Linker* l, ObjBuilder* out, RelInputMap* maps, if (!s) continue; out_sec = rel_find_compatible_section(out, s); if (out_sec == OBJ_SEC_NONE) { - out_sec = obj_section_ex(out, s->name, (SecKind)s->kind, - (SecSem)s->sem, s->flags, s->align, - s->entsize, OBJ_SEC_NONE, s->info); + out_sec = obj_section_ex(out, s->name, (SecKind)s->kind, (SecSem)s->sem, + s->flags, s->align, s->entsize, OBJ_SEC_NONE, + s->info); if (out_sec == OBJ_SEC_NONE) compiler_panic(l->c, no_loc(), "link -r: oom copying section"); if (s->ext_kind != OBJ_EXT_NONE || s->ext_type || s->ext_flags) @@ -460,8 +460,7 @@ void link_emit_relocatable_writer(Linker* l, Writer* w) { h = l->heap; if (l->script) - compiler_panic(l->c, no_loc(), - "link -r: linker scripts are not supported"); + compiler_panic(l->c, no_loc(), "link -r: linker scripts are not supported"); link_ingest_archives(l); ninputs = LinkInputs_count(&l->inputs); diff --git a/src/obj/coff/archive.c b/src/obj/coff/archive.c @@ -1,11 +1,10 @@ -#include "obj/format.h" - #include <string.h> #include "core/arena.h" #include "core/core.h" #include "core/pool.h" #include "core/slice.h" +#include "obj/format.h" #include "obj/obj.h" /* mingw import archives store import thunks as ordinary COFF members with @@ -60,7 +59,7 @@ Sym coff_archive_hint(Compiler* c, const char* path) { out = (char*)arena_array(c->scratch, char, out_len); memcpy(out, base, n); memcpy(out + n, ".dll", 4); - return pool_intern_slice(c->global, (Slice){ .s = out, .len = (u32)out_len }); + return pool_intern_slice(c->global, (Slice){.s = out, .len = (u32)out_len}); } static Sym derive_dll_name_from_archive_member(Compiler* c, @@ -75,9 +74,9 @@ static Sym derive_dll_name_from_archive_member(Compiler* c, if (*p == '/' || *p == '\\') base = p + 1; n = slice_from_cstr(base).len; if (n >= 4 && memcmp(base + n - 4, ".dll", 4) == 0) - return pool_intern_slice(c->global, (Slice){ .s = base, .len = (u32)n }); + return pool_intern_slice(c->global, (Slice){.s = base, .len = (u32)n}); if (n >= 4 && memcmp(base + n - 4, ".DLL", 4) == 0) - return pool_intern_slice(c->global, (Slice){ .s = base, .len = (u32)n }); + return pool_intern_slice(c->global, (Slice){.s = base, .len = (u32)n}); return fallback; } @@ -116,8 +115,10 @@ static void coff_resolve_sym_name_(const u8* rec, const u8* strtab, #define COFF_FILE_HDR_SIZE_ 20u #define COFF_SYM_CLASS_EXTERNAL_ 2u -static CoffArMemberClass classify_coff_archive_member_bytes( - Compiler* c, const u8* data, size_t len, Sym* out_name) { +static CoffArMemberClass classify_coff_archive_member_bytes(Compiler* c, + const u8* data, + size_t len, + Sym* out_name) { u32 ptr_to_symtab; u32 nsymbols; u16 nsections; @@ -133,10 +134,10 @@ static CoffArMemberClass classify_coff_archive_member_bytes( *out_name = 0; if (len < COFF_FILE_HDR_SIZE_) return COFF_AR_KEEP; nsections = (u16)((u32)data[2] | ((u32)data[3] << 8)); - ptr_to_symtab = (u32)data[8] | ((u32)data[9] << 8) | - ((u32)data[10] << 16) | ((u32)data[11] << 24); - nsymbols = (u32)data[12] | ((u32)data[13] << 8) | - ((u32)data[14] << 16) | ((u32)data[15] << 24); + ptr_to_symtab = (u32)data[8] | ((u32)data[9] << 8) | ((u32)data[10] << 16) | + ((u32)data[11] << 24); + nsymbols = (u32)data[12] | ((u32)data[13] << 8) | ((u32)data[14] << 16) | + ((u32)data[15] << 24); if (nsymbols == 0 || ptr_to_symtab == 0) return COFF_AR_KEEP; if ((u64)COFF_FILE_HDR_SIZE_ + (u64)nsections * 40u <= (u64)len) { u32 si; @@ -155,8 +156,7 @@ static CoffArMemberClass classify_coff_archive_member_bytes( u64 symtab_end = (u64)ptr_to_symtab + (u64)nsymbols * (u64)COFF_SYM_REC_SIZE_; if (symtab_end + 4u <= (u64)len) { - u32 declared = (u32)data[symtab_end] | - ((u32)data[symtab_end + 1] << 8) | + u32 declared = (u32)data[symtab_end] | ((u32)data[symtab_end + 1] << 8) | ((u32)data[symtab_end + 2] << 16) | ((u32)data[symtab_end + 3] << 24); if (declared < 4u || symtab_end + (u64)declared > (u64)len) { @@ -188,7 +188,7 @@ static CoffArMemberClass classify_coff_archive_member_bytes( const char* tail = nm + kCoffImpPrefixLen_; u32 tail_len = nlen - kCoffImpPrefixLen_; imp_bare_name = - pool_intern_slice(c->global, (Slice){ .s = tail, .len = tail_len }); + pool_intern_slice(c->global, (Slice){.s = tail, .len = tail_len}); } } else if (nlen > kCoffHeadPrefixLen_ && memcmp(nm, kCoffHeadPrefix_, kCoffHeadPrefixLen_) == 0) { @@ -235,7 +235,7 @@ static ObjBuilder* build_coff_long_import_shim(Compiler* c, Sym bare_name, imp_buf = (char*)arena_array(c->scratch, char, imp_len); memcpy(imp_buf, kCoffImpPrefix_, kCoffImpPrefixLen_); memcpy(imp_buf + kCoffImpPrefixLen_, bare, bare_len); - imp_sn = pool_intern_slice(c->global, (Slice){ .s = imp_buf, .len = imp_len }); + imp_sn = pool_intern_slice(c->global, (Slice){.s = imp_buf, .len = imp_len}); imp_id = obj_symbol_ex(ob, imp_sn, SB_GLOBAL, SV_DEFAULT, SK_OBJ, OBJ_SEC_NONE, 0, 0, 0); obj_sym_mark_referenced(ob, imp_id); @@ -271,9 +271,8 @@ ObjFormatArchiveAction coff_archive_member(Compiler* c, if (coff_skip_long_import_shim_bare(c, bare)) { return OBJ_FORMAT_ARCHIVE_SKIP; } else { - Sym member_dll = - derive_dll_name_from_archive_member(c, mem->member_name, - mem->archive_hint); + Sym member_dll = derive_dll_name_from_archive_member(c, mem->member_name, + mem->archive_hint); if (out) *out = build_coff_long_import_shim(c, bare, member_dll); return OBJ_FORMAT_ARCHIVE_REPLACE; } diff --git a/src/obj/coff/coff.h b/src/obj/coff/coff.h @@ -27,7 +27,7 @@ #define COFF_FILE_HEADER_SIZE 20u typedef struct ImageFileHeader { - u16 Machine; /* IMAGE_FILE_MACHINE_* */ + u16 Machine; /* IMAGE_FILE_MACHINE_* */ u16 NumberOfSections; u32 TimeDateStamp; /* zero for reproducible builds */ u32 PointerToSymbolTable; /* file offset, or 0 if no symtab */ @@ -40,14 +40,15 @@ typedef struct ImageFileHeader { * rest are listed for completeness so readers can give a useful * "unsupported machine" diagnostic instead of "unknown machine". */ #define IMAGE_FILE_MACHINE_UNKNOWN 0x0000u -#define IMAGE_FILE_MACHINE_AMD64 0x8664u /* x86_64, cfree supports */ -#define IMAGE_FILE_MACHINE_ARM64 0xAA64u /* aarch64, cfree supports */ -#define IMAGE_FILE_MACHINE_ARM64EC 0xA641u /* ARM64EC — readers alias - * to AArch64 (encoding is - * identical, only ABI - * differs). llvm-mingw's - * compiler-rt builtins ship - * as ARM64EC objects. */ +#define IMAGE_FILE_MACHINE_AMD64 0x8664u /* x86_64, cfree supports */ +#define IMAGE_FILE_MACHINE_ARM64 0xAA64u /* aarch64, cfree supports */ +#define IMAGE_FILE_MACHINE_ARM64EC \ + 0xA641u /* ARM64EC — readers alias \ + * to AArch64 (encoding is \ + * identical, only ABI \ + * differs). llvm-mingw's \ + * compiler-rt builtins ship \ + * as ARM64EC objects. */ /* Not supported by cfree (here for diagnostic recognition only): */ #define IMAGE_FILE_MACHINE_I386 0x014Cu #define IMAGE_FILE_MACHINE_ARM 0x01C0u @@ -69,11 +70,11 @@ typedef struct ImageFileHeader { * program (typically prints "This program cannot be run in DOS mode") * is emitted as a separate byte blob after this header. */ #define COFF_DOS_HEADER_SIZE 64u -#define IMAGE_DOS_SIGNATURE 0x5A4Du /* 'MZ' little-endian */ +#define IMAGE_DOS_SIGNATURE 0x5A4Du /* 'MZ' little-endian */ #define IMAGE_NT_SIGNATURE 0x00004550u /* "PE\0\0" little-endian */ typedef struct ImageDosHeader { - u16 e_magic; /* IMAGE_DOS_SIGNATURE */ + u16 e_magic; /* IMAGE_DOS_SIGNATURE */ u16 e_cblp; u16 e_cp; u16 e_crlc; @@ -91,7 +92,7 @@ typedef struct ImageDosHeader { u16 e_oemid; u16 e_oeminfo; u16 e_res2[10]; - u32 e_lfanew; /* file offset of "PE\0\0" */ + u32 e_lfanew; /* file offset of "PE\0\0" */ } ImageDosHeader; /* ---- optional header (PE32+, IMAGE_OPTIONAL_HEADER64) ---- @@ -141,36 +142,36 @@ typedef struct ImageDataDirectory { typedef struct ImageOptionalHeader64 { /* Standard fields (28 bytes for PE32+). */ - u16 Magic; /* IMAGE_NT_OPTIONAL_HDR64_MAGIC */ + u16 Magic; /* IMAGE_NT_OPTIONAL_HDR64_MAGIC */ u8 MajorLinkerVersion; u8 MinorLinkerVersion; u32 SizeOfCode; u32 SizeOfInitializedData; u32 SizeOfUninitializedData; - u32 AddressOfEntryPoint; /* RVA of _start */ + u32 AddressOfEntryPoint; /* RVA of _start */ u32 BaseOfCode; /* Windows-specific (88 bytes for PE32+). */ - u64 ImageBase; /* preferred load address */ - u32 SectionAlignment; /* in-memory alignment, >= page */ - u32 FileAlignment; /* on-disk alignment */ + u64 ImageBase; /* preferred load address */ + u32 SectionAlignment; /* in-memory alignment, >= page */ + u32 FileAlignment; /* on-disk alignment */ u16 MajorOperatingSystemVersion; u16 MinorOperatingSystemVersion; u16 MajorImageVersion; u16 MinorImageVersion; u16 MajorSubsystemVersion; u16 MinorSubsystemVersion; - u32 Win32VersionValue; /* reserved, zero */ - u32 SizeOfImage; /* in-memory size, SectionAlignment-padded */ - u32 SizeOfHeaders; /* file offset of first section's raw data */ + u32 Win32VersionValue; /* reserved, zero */ + u32 SizeOfImage; /* in-memory size, SectionAlignment-padded */ + u32 SizeOfHeaders; /* file offset of first section's raw data */ u32 CheckSum; - u16 Subsystem; /* IMAGE_SUBSYSTEM_* */ - u16 DllCharacteristics; /* IMAGE_DLLCHARACTERISTICS_* */ + u16 Subsystem; /* IMAGE_SUBSYSTEM_* */ + u16 DllCharacteristics; /* IMAGE_DLLCHARACTERISTICS_* */ u64 SizeOfStackReserve; u64 SizeOfStackCommit; u64 SizeOfHeapReserve; u64 SizeOfHeapCommit; - u32 LoaderFlags; /* reserved, zero */ - u32 NumberOfRvaAndSizes; /* COFF_NUM_DATA_DIRECTORIES */ + u32 LoaderFlags; /* reserved, zero */ + u32 NumberOfRvaAndSizes; /* COFF_NUM_DATA_DIRECTORIES */ /* Data directories (128 bytes = 16 * 8). */ ImageDataDirectory DataDirectory[COFF_NUM_DATA_DIRECTORIES]; } ImageOptionalHeader64; @@ -187,15 +188,15 @@ typedef struct ImageOptionalHeader64 { * must marshal this convention explicitly. */ typedef struct ImageSectionHeader { char Name[8]; - u32 VirtualSize; /* size in image; for .obj usually 0 */ - u32 VirtualAddress; /* RVA in image; for .obj usually 0 */ + u32 VirtualSize; /* size in image; for .obj usually 0 */ + u32 VirtualAddress; /* RVA in image; for .obj usually 0 */ u32 SizeOfRawData; u32 PointerToRawData; /* file offset */ u32 PointerToRelocations; /* file offset of reloc array */ u32 PointerToLinenumbers; /* file offset of COFF linenumbers (legacy) */ u16 NumberOfRelocations; u16 NumberOfLinenumbers; - u32 Characteristics; /* IMAGE_SCN_* */ + u32 Characteristics; /* IMAGE_SCN_* */ } ImageSectionHeader; /* Section characteristics flags. */ @@ -246,16 +247,16 @@ typedef struct ImageSectionHeader { typedef struct ImageSymbol { union { - char ShortName[8]; /* in-place if name <= 8 bytes */ + char ShortName[8]; /* in-place if name <= 8 bytes */ struct { - u32 Zeroes; /* 0 signals strtab lookup */ - u32 Offset; /* string-table offset (>= 4) */ + u32 Zeroes; /* 0 signals strtab lookup */ + u32 Offset; /* string-table offset (>= 4) */ } LongName; } Name; u32 Value; - i16 SectionNumber; /* 1-based; specials below */ - u16 Type; /* low4=base, high12=derived */ - u8 StorageClass; /* IMAGE_SYM_CLASS_* */ + i16 SectionNumber; /* 1-based; specials below */ + u16 Type; /* low4=base, high12=derived */ + u8 StorageClass; /* IMAGE_SYM_CLASS_* */ u8 NumberOfAuxSymbols; } ImageSymbol; @@ -285,8 +286,8 @@ typedef struct ImageSymbol { #define IMAGE_SYM_CLASS_EXTERNAL_DEF 5u #define IMAGE_SYM_CLASS_LABEL 6u #define IMAGE_SYM_CLASS_UNDEFINED_LABEL 7u -#define IMAGE_SYM_CLASS_FUNCTION 101u /* .bf / .ef markers */ -#define IMAGE_SYM_CLASS_FILE 103u /* aux records hold filename */ +#define IMAGE_SYM_CLASS_FUNCTION 101u /* .bf / .ef markers */ +#define IMAGE_SYM_CLASS_FILE 103u /* aux records hold filename */ #define IMAGE_SYM_CLASS_SECTION 104u #define IMAGE_SYM_CLASS_WEAK_EXTERNAL 105u #define IMAGE_SYM_CLASS_CLR_TOKEN 107u @@ -304,12 +305,12 @@ typedef struct ImageSymbol { * section's 1-based index. Encodes per-section metadata + COMDAT * grouping. */ typedef struct ImageAuxSymbolSection { - u32 Length; /* section's SizeOfRawData */ + u32 Length; /* section's SizeOfRawData */ u16 NumberOfRelocations; u16 NumberOfLinenumbers; - u32 CheckSum; /* COMDAT checksum, 0 otherwise */ - u16 Number; /* associated section idx for COMDAT */ - u8 Selection; /* IMAGE_COMDAT_SELECT_* */ + u32 CheckSum; /* COMDAT checksum, 0 otherwise */ + u16 Number; /* associated section idx for COMDAT */ + u8 Selection; /* IMAGE_COMDAT_SELECT_* */ u8 Unused[3]; } ImageAuxSymbolSection; @@ -317,7 +318,7 @@ typedef struct ImageAuxSymbolSection { * of the fall-back symbol used when the weak ref is unresolved. */ typedef struct ImageAuxSymbolWeakExternal { u32 TagIndex; - u32 Characteristics; /* IMAGE_WEAK_EXTERN_SEARCH_* */ + u32 Characteristics; /* IMAGE_WEAK_EXTERN_SEARCH_* */ u8 Unused[10]; } ImageAuxSymbolWeakExternal; @@ -359,9 +360,9 @@ typedef struct ImageAuxSymbolFunction { #define COFF_RELOC_SIZE 10u typedef struct ImageRelocation { - u32 VirtualAddress; /* offset within the section being patched */ + u32 VirtualAddress; /* offset within the section being patched */ u32 SymbolTableIndex; - u16 Type; /* IMAGE_REL_<machine>_* */ + u16 Type; /* IMAGE_REL_<machine>_* */ } ImageRelocation; /* ---- string table layout ---- @@ -380,7 +381,7 @@ typedef struct ImageRelocation { * (type:4, offset:12) where offset is relative to VirtualAddress. */ typedef struct ImageBaseRelocation { u32 VirtualAddress; - u32 SizeOfBlock; /* header (8) + entries; padded to u32 */ + u32 SizeOfBlock; /* header (8) + entries; padded to u32 */ } ImageBaseRelocation; #define COFF_BASE_RELOCATION_SIZE 8u @@ -390,7 +391,7 @@ typedef struct ImageBaseRelocation { #define IMAGE_REL_BASED_HIGHLOW 3u #define IMAGE_REL_BASED_HIGHADJ 4u #define IMAGE_REL_BASED_ARM_MOV32 5u -#define IMAGE_REL_BASED_DIR64 10u /* the one used on x64 / arm64 */ +#define IMAGE_REL_BASED_DIR64 10u /* the one used on x64 / arm64 */ /* ---- export directory (IMAGE_EXPORT_DIRECTORY) ---- * One record, pointed at by IMAGE_DIRECTORY_ENTRY_EXPORT in the @@ -408,8 +409,8 @@ typedef struct ImageExportDirectory { u32 TimeDateStamp; u16 MajorVersion; u16 MinorVersion; - u32 Name; /* RVA of DLL name */ - u32 Base; /* first ordinal */ + u32 Name; /* RVA of DLL name */ + u32 Base; /* first ordinal */ u32 NumberOfFunctions; u32 NumberOfNames; u32 AddressOfFunctions; /* EAT: RVA[NumberOfFunctions] */ @@ -425,11 +426,11 @@ typedef struct ImageExportDirectory { #define COFF_IMPORT_DESCRIPTOR_SIZE 20u typedef struct ImageImportDescriptor { - u32 OriginalFirstThunk; /* RVA -> IMAGE_THUNK_DATA64[] (ILT) */ + u32 OriginalFirstThunk; /* RVA -> IMAGE_THUNK_DATA64[] (ILT) */ u32 TimeDateStamp; u32 ForwarderChain; - u32 Name; /* RVA -> NUL-terminated DLL name */ - u32 FirstThunk; /* RVA -> IMAGE_THUNK_DATA64[] (IAT) */ + u32 Name; /* RVA -> NUL-terminated DLL name */ + u32 FirstThunk; /* RVA -> IMAGE_THUNK_DATA64[] (IAT) */ } ImageImportDescriptor; /* Thunk entries are u64 on PE32+. If the high bit (IMAGE_ORDINAL_FLAG64) @@ -439,7 +440,7 @@ typedef struct ImageImportDescriptor { #define COFF_THUNK_DATA64_SIZE 8u typedef struct ImageImportByName { - u16 Hint; /* index hint into the DLL's export table */ + u16 Hint; /* index hint into the DLL's export table */ /* char Name[]; NUL-terminated, followed by optional pad to even. */ } ImageImportByName; @@ -451,10 +452,10 @@ typedef struct ImageImportByName { typedef struct ImageTlsDirectory64 { u64 StartAddressOfRawData; u64 EndAddressOfRawData; - u64 AddressOfIndex; /* VA of u32 _tls_index */ - u64 AddressOfCallBacks; /* VA of NULL-terminated callback array */ + u64 AddressOfIndex; /* VA of u32 _tls_index */ + u64 AddressOfCallBacks; /* VA of NULL-terminated callback array */ u32 SizeOfZeroFill; - u32 Characteristics; /* alignment encoded as IMAGE_SCN_ALIGN_* */ + u32 Characteristics; /* alignment encoded as IMAGE_SCN_ALIGN_* */ } ImageTlsDirectory64; /* ---- short import record (Microsoft .lib member) ---- @@ -467,12 +468,12 @@ typedef struct ImageTlsDirectory64 { #define IMPORT_OBJECT_HDR_SIG2 0xFFFFu typedef struct ImportObjectHeader { - u16 Sig1; /* IMPORT_OBJECT_HDR_SIG1 (0) */ - u16 Sig2; /* IMPORT_OBJECT_HDR_SIG2 (0xFFFF) */ + u16 Sig1; /* IMPORT_OBJECT_HDR_SIG1 (0) */ + u16 Sig2; /* IMPORT_OBJECT_HDR_SIG2 (0xFFFF) */ u16 Version; - u16 Machine; /* IMAGE_FILE_MACHINE_* */ + u16 Machine; /* IMAGE_FILE_MACHINE_* */ u32 TimeDateStamp; - u32 SizeOfData; /* bytes after this header */ + u32 SizeOfData; /* bytes after this header */ u16 OrdinalOrHint; /* Bitfield encoded as a single u16 on the wire: * Type:2, NameType:3, Reserved:11 (low-to-high). */ @@ -494,14 +495,14 @@ typedef struct ImportObjectHeader { #define COFF_DEBUG_DIRECTORY_SIZE 28u typedef struct ImageDebugDirectory { - u32 Characteristics; /* reserved, zero */ + u32 Characteristics; /* reserved, zero */ u32 TimeDateStamp; u16 MajorVersion; u16 MinorVersion; - u32 Type; /* IMAGE_DEBUG_TYPE_* */ + u32 Type; /* IMAGE_DEBUG_TYPE_* */ u32 SizeOfData; - u32 AddressOfRawData; /* RVA in image */ - u32 PointerToRawData; /* file offset */ + u32 AddressOfRawData; /* RVA in image */ + u32 PointerToRawData; /* file offset */ } ImageDebugDirectory; #define IMAGE_DEBUG_TYPE_UNKNOWN 0u @@ -515,17 +516,17 @@ typedef struct ImageDebugDirectory { * field (so REL32_1 maps to a -1 implicit addend in cfree's S + A - P * model). Plain REL32 is relative to the byte after the 4-byte field. */ #define IMAGE_REL_AMD64_ABSOLUTE 0u -#define IMAGE_REL_AMD64_ADDR64 1u /* 64-bit VA */ -#define IMAGE_REL_AMD64_ADDR32 2u /* 32-bit VA */ -#define IMAGE_REL_AMD64_ADDR32NB 3u /* 32-bit RVA (image-relative) */ -#define IMAGE_REL_AMD64_REL32 4u /* 32-bit relative to next inst */ +#define IMAGE_REL_AMD64_ADDR64 1u /* 64-bit VA */ +#define IMAGE_REL_AMD64_ADDR32 2u /* 32-bit VA */ +#define IMAGE_REL_AMD64_ADDR32NB 3u /* 32-bit RVA (image-relative) */ +#define IMAGE_REL_AMD64_REL32 4u /* 32-bit relative to next inst */ #define IMAGE_REL_AMD64_REL32_1 5u #define IMAGE_REL_AMD64_REL32_2 6u #define IMAGE_REL_AMD64_REL32_3 7u #define IMAGE_REL_AMD64_REL32_4 8u #define IMAGE_REL_AMD64_REL32_5 9u -#define IMAGE_REL_AMD64_SECTION 10u /* 16-bit section index */ -#define IMAGE_REL_AMD64_SECREL 11u /* 32-bit section-relative */ +#define IMAGE_REL_AMD64_SECTION 10u /* 16-bit section index */ +#define IMAGE_REL_AMD64_SECREL 11u /* 32-bit section-relative */ #define IMAGE_REL_AMD64_SECREL7 12u #define IMAGE_REL_AMD64_TOKEN 13u #define IMAGE_REL_AMD64_SREL32 14u diff --git a/src/obj/elf/elf.h b/src/obj/elf/elf.h @@ -59,9 +59,9 @@ #define ELF64_EHDR_SIZE 64 #define ELF64_SHDR_SIZE 64 #define ELF64_PHDR_SIZE 56 -#define ELF64_SYM_SIZE 24u +#define ELF64_SYM_SIZE 24u #define ELF64_RELA_SIZE 24u -#define ELF64_DYN_SIZE 16u +#define ELF64_DYN_SIZE 16u /* ---- special section indices ---- */ #define SHN_UNDEF 0u diff --git a/src/obj/elf/emu_load.c b/src/obj/elf/emu_load.c @@ -139,8 +139,8 @@ static CfreeStatus parse_object_dynamic(EmuLoadedImage* img, EmuElfDynInfo* dinfo = elf_dyn(obj); if (!dinfo || !dinfo->dynamic_vaddr) return CFREE_OK; dynamic_size = dinfo->dynamic_size; - dyn = emu_addr_space_ptr(&img->addr_space, dinfo->dynamic_vaddr, - dynamic_size, EMU_MEM_READ); + dyn = emu_addr_space_ptr(&img->addr_space, dinfo->dynamic_vaddr, dynamic_size, + EMU_MEM_READ); if (!dyn) return CFREE_INVALID; for (j = 0; j + ELF64_DYN_SIZE <= dynamic_size; j += ELF64_DYN_SIZE) { u64 tag = rd64(dyn + j); @@ -223,22 +223,22 @@ static CfreeStatus parse_object_dynamic(EmuLoadedImage* img, } for (j = 0; j < nneeded_offs; ++j) { u64 val = needed_offs[j]; - if (strtab && obj->imports.nneeded < - sizeof(obj->imports.needed) / - sizeof(obj->imports.needed[0])) { - u8* s = emu_addr_space_ptr(&img->addr_space, strtab + val, 1, - EMU_MEM_READ); - if (s) obj->imports.needed[obj->imports.nneeded++] = - cstr_at(s, strsz > val ? strsz - val : 0); + if (strtab && obj->imports.nneeded < sizeof(obj->imports.needed) / + sizeof(obj->imports.needed[0])) { + u8* s = + emu_addr_space_ptr(&img->addr_space, strtab + val, 1, EMU_MEM_READ); + if (s) + obj->imports.needed[obj->imports.nneeded++] = + cstr_at(s, strsz > val ? strsz - val : 0); } } return CFREE_OK; } static CfreeStatus elf_load_one_object(Compiler* c, EmuProcess* process, - EmuLoadedImage* img, - CfreeSlice name, CfreeSlice bytes_slice, - int is_main, u32* out_index) { + EmuLoadedImage* img, CfreeSlice name, + CfreeSlice bytes_slice, int is_main, + u32* out_index) { const u8* bytes = bytes_slice.data; size_t len = bytes_slice.len; u16 e_type, e_machine, e_phentsize, e_phnum; @@ -290,9 +290,9 @@ static CfreeStatus elf_load_one_object(Compiler* c, EmuProcess* process, } if (!saw_load) return CFREE_INVALID; if (!is_main) { - if (emu_addr_space_find_gap(&img->addr_space, hi_va - lo_va, - EMU_PAGE_SIZE, 0x2000000000ull, - 0x3000000000ull, &load_bias) != CFREE_OK) + if (emu_addr_space_find_gap(&img->addr_space, hi_va - lo_va, EMU_PAGE_SIZE, + 0x2000000000ull, 0x3000000000ull, + &load_bias) != CFREE_OK) return CFREE_ERR; load_bias -= lo_va; } @@ -323,11 +323,9 @@ static CfreeStatus elf_load_one_object(Compiler* c, EmuProcess* process, if (p_type == PT_LOAD) { u64 map_start = round_down(load_bias + p_vaddr, EMU_PAGE_SIZE); u64 map_end = round_up(load_bias + p_vaddr + p_memsz, EMU_PAGE_SIZE); - if (p_filesz > p_memsz || p_offset + p_filesz > len) - return CFREE_INVALID; + if (p_filesz > p_memsz || p_offset + p_filesz > len) return CFREE_INVALID; if (emu_addr_space_map(&img->addr_space, map_start, map_end - map_start, - elf_phdr_perms(p_flags), EMU_MAP_FILE) != - CFREE_OK) + elf_phdr_perms(p_flags), EMU_MAP_FILE) != CFREE_OK) return CFREE_ERR; if (p_filesz && emu_addr_space_copy_in(&img->addr_space, load_bias + p_vaddr, @@ -344,8 +342,7 @@ static CfreeStatus elf_load_one_object(Compiler* c, EmuProcess* process, obj->tls.memsz = p_memsz; obj->tls.align = p_align; obj->tls.module_id = *out_index + 1u; - } else if (is_main && p_type == PT_INTERP && - p_offset + p_filesz <= len) { + } else if (is_main && p_type == PT_INTERP && p_offset + p_filesz <= len) { img->process_info.interpreter_path = cstr_at(bytes + p_offset, p_filesz); } } @@ -406,8 +403,7 @@ static CfreeStatus elf_symbol_at(EmuProcess* process, u16 st_shndx; u8* name; const EmuElfDynInfo* dinfo = elf_dyn_const(obj); - if (!process || !obj || !out || !dinfo || !dinfo->symtab || - !dinfo->strtab) + if (!process || !obj || !out || !dinfo || !dinfo->symtab || !dinfo->strtab) return CFREE_INVALID; sym = emu_addr_space_ptr(&process->image.addr_space, dinfo->symtab + index * ELF64_SYM_SIZE, @@ -422,12 +418,10 @@ static CfreeStatus elf_symbol_at(EmuProcess* process, out->defined = st_shndx != SHN_UNDEF; if (st_name) { name = emu_addr_space_ptr(&process->image.addr_space, - dinfo->strtab + st_name, 1u, - EMU_MEM_READ); + dinfo->strtab + st_name, 1u, EMU_MEM_READ); if (!name) return CFREE_INVALID; - out->name = cstr_at(name, dinfo->strsz > st_name - ? dinfo->strsz - st_name - : 256u); + out->name = + cstr_at(name, dinfo->strsz > st_name ? dinfo->strsz - st_name : 256u); } return CFREE_OK; } @@ -450,8 +444,7 @@ static int elf_dyn_needed_next(EmuProcess* process, EmuDynNeededIter* it, static CfreeStatus elf_dyn_symbol_lookup(EmuProcess* process, const EmuLoadedObject* obj, - CfreeSlice symbol, - EmuDynSymbol* out) { + CfreeSlice symbol, EmuDynSymbol* out) { u32 n; u32 i; if (!process || !obj || !out) return CFREE_INVALID; @@ -475,8 +468,7 @@ static CfreeStatus elf_dyn_symbol_by_index(EmuProcess* process, } static void elf_reloc_iter(const EmuLoadedObject* obj, - EmuDynRelocTableKind table, - EmuDynRelocIter* out) { + EmuDynRelocTableKind table, EmuDynRelocIter* out) { if (!out) return; memset(out, 0, sizeof(*out)); out->object = obj; @@ -520,8 +512,7 @@ static int elf_reloc_next(EmuProcess* process, EmuDynRelocIter* it, static CfreeStatus elf_reloc_classify(EmuProcess* process, const EmuLoadedObject* obj, const EmuDynReloc* reloc, - EmuDynRelocClass* cls, - u32* kind_out) { + EmuDynRelocClass* cls, u32* kind_out) { u32 r_type; (void)obj; if (!process || !reloc || !cls || !kind_out) return CFREE_INVALID; diff --git a/src/obj/macho/emit.c b/src/obj/macho/emit.c @@ -619,8 +619,7 @@ void emit_macho(Compiler* c, ObjBuilder* ob, Writer* w) { * r_extern would make readers interpret the addend as a symbol * index. */ u32 packed = ((u32)(i64)r->addend & 0x00ffffffu) | (0u << 24) | - (length << 25) | - (ARM64_RELOC_ADDEND << 28); + (length << 25) | (ARM64_RELOC_ADDEND << 28); wr_u32_le(slot + 4, packed); ++j; } diff --git a/src/obj/macho/macho.h b/src/obj/macho/macho.h @@ -19,7 +19,8 @@ /* ---- magic ---- */ #define MH_MAGIC_64 0xfeedfacfu -#define MH_CIGAM_64 0xcffaedfeu /* byte-swapped (big-endian host reading LE) */ +#define MH_CIGAM_64 0xcffaedfeu /* byte-swapped (big-endian host reading LE) \ + */ /* ---- cputype / cpusubtype (subset cfree cares about) ---- */ #define CPU_TYPE_X86 0x00000007 @@ -92,8 +93,8 @@ typedef struct MachLoadCmd { /* LC_SEGMENT_64: one per Mach-O segment. Followed by `nsects` * MachSection64 records inline. */ typedef struct MachSegmentCmd64 { - u32 cmd; /* LC_SEGMENT_64 */ - u32 cmdsize; /* sizeof(this) + nsects * sizeof(MachSection64) */ + u32 cmd; /* LC_SEGMENT_64 */ + u32 cmdsize; /* sizeof(this) + nsects * sizeof(MachSection64) */ char segname[16]; u64 vmaddr; u64 vmsize; diff --git a/src/obj/macho/tbd_read.c b/src/obj/macho/tbd_read.c @@ -51,9 +51,8 @@ static SrcLoc no_loc(void) { static int is_id_start(u8 c) { return c == '_'; } static int is_id_cont(u8 c) { - return (c == '_') || (c == '$') || (c == '.') || - (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || - (c >= '0' && c <= '9'); + return (c == '_') || (c == '$') || (c == '.') || (c >= 'A' && c <= 'Z') || + (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9'); } /* Extract the install-name from the first document. We look for a @@ -74,9 +73,8 @@ static Sym extract_install_name(Compiler* c, const u8* data, size_t len) { while (j < len && data[j] != '\n' && data[j] != '\r') ++j; size_t end = j; /* Strip trailing whitespace. */ - while (end > start && - (data[end - 1] == ' ' || data[end - 1] == '\t' || - data[end - 1] == '\r')) + while (end > start && (data[end - 1] == ' ' || data[end - 1] == '\t' || + data[end - 1] == '\r')) --end; /* Strip surrounding single or double quotes. */ if (end > start + 1u && (data[start] == '\'' || data[start] == '"') && @@ -85,7 +83,9 @@ static Sym extract_install_name(Compiler* c, const u8* data, size_t len) { --end; } if (end > start) - return pool_intern_slice(c->global, (Slice){ .s = (const char*)(data + start), .len = (u32)(end - start) }); + return pool_intern_slice( + c->global, + (Slice){.s = (const char*)(data + start), .len = (u32)(end - start)}); return 0; } return 0; @@ -95,8 +95,7 @@ ObjBuilder* read_tbd(Compiler* c, const char* name, const u8* data, size_t len, Sym* install_name_out) { (void)name; if (install_name_out) *install_name_out = 0; - if (!data || !len) - compiler_panic(c, no_loc(), "read_tbd: empty input"); + if (!data || !len) compiler_panic(c, no_loc(), "read_tbd: empty input"); /* Validate magic: a tbd starts with `--- !tapi-tbd` (or any `---`). */ if (len < 4 || data[0] != '-' || data[1] != '-' || data[2] != '-') @@ -140,9 +139,10 @@ ObjBuilder* read_tbd(Compiler* c, const char* name, const u8* data, size_t len, * keep tokens of length >= 2. Single `_` is the throwaway-name * convention and never an exported symbol. */ if (tlen < 2u) continue; - Sym sn = pool_intern_slice(c->global, (Slice){ .s = (const char*)(data + start), .len = (u32)tlen }); - obj_symbol_ex(ob, sn, SB_GLOBAL, SV_DEFAULT, SK_NOTYPE, OBJ_SEC_NONE, 0, - 0, 0); + Sym sn = pool_intern_slice( + c->global, (Slice){.s = (const char*)(data + start), .len = (u32)tlen}); + obj_symbol_ex(ob, sn, SB_GLOBAL, SV_DEFAULT, SK_NOTYPE, OBJ_SEC_NONE, 0, 0, + 0); } obj_finalize(ob); diff --git a/src/obj/obj.c b/src/obj/obj.c @@ -35,7 +35,7 @@ struct CfreeObjBuilder { Symbols symbols; /* index 0 reserved as "none" */ Relocs relocs; /* flat across all sections; filtered on read */ Groups groups; /* index 0 reserved as "none" */ - Atoms atoms; /* index 0 reserved as "none" */ + Atoms atoms; /* index 0 reserved as "none" */ /* Format-specific ELF e_flags. Set by read_elf to the input's * e_flags (e.g. on RISC-V, EF_RISCV_RVC | EF_RISCV_FLOAT_ABI_DOUBLE); * consumed by emit_elf to round-trip. Zero when not set — emit_elf @@ -721,8 +721,7 @@ ObjAtomId obj_atom_find(const ObjBuilder* ob, ObjSecId sid, u32 offset) { for (u32 i = 1; i < n; ++i) { const ObjAtom* a = Atoms_at(&ob->atoms, i); if (!a || a->removed || a->section_id != sid) continue; - if (a->size == 0 && offset == a->offset) - return (ObjAtomId)i; + if (a->size == 0 && offset == a->offset) return (ObjAtomId)i; } return OBJ_ATOM_NONE; } @@ -811,7 +810,9 @@ void obj_groupiter_free(ObjGroupIter* it) { * spelling GNU objdump uses minus its arch prefix. */ const char* reloc_kind_name(RelocKind k) { switch (k) { -#define _CASE(name) case name: return &(#name)[2] /* strip "R_" */ +#define _CASE(name) \ + case name: \ + return &(#name)[2] /* strip "R_" */ _CASE(R_NONE); _CASE(R_ABS32); _CASE(R_ABS64); diff --git a/src/obj/obj.h b/src/obj/obj.h @@ -623,7 +623,7 @@ Sym obj_secname_tbss(Compiler*); * The `_tlv_bootstrap` undef extern is cached on the ObjBuilder so a * second TLV var in the same TU shares one symbol entry. */ typedef struct ObjTlsReloc { - u32 offset; /* within the data buffer */ + u32 offset; /* within the data buffer */ RelocKind kind; ObjSymId target; i64 addend; diff --git a/src/obj/obj_secnames.c b/src/obj/obj_secnames.c @@ -17,8 +17,6 @@ * panics with a "TODO" until the macho writer lands in Phase 2/3. COFF * panics in the same way and is filled in later. */ -#include "obj/obj.h" - #include <string.h> #include "core/core.h" @@ -26,6 +24,7 @@ #include "core/pool.h" #include "core/slice.h" #include "obj/format.h" +#include "obj/obj.h" static Sym secname_panic_unimpl(Compiler* c, const char* which) { SrcLoc l = {0, 0, 0}; @@ -174,7 +173,7 @@ Sym obj_format_c_mangle(Compiler* c, const char* name) { buf[0] = '_'; memcpy(buf + 1, name, n); buf[n + 1] = 0; - s = pool_intern_slice(c->global, (Slice){ .s = buf, .len = (u32)(n + 1u) }); + s = pool_intern_slice(c->global, (Slice){.s = buf, .len = (u32)(n + 1u)}); h->free(h, buf, n + 2u); return s; } @@ -183,8 +182,7 @@ Sym obj_format_c_mangle(Compiler* c, const char* name) { * format's leading C-mangle byte from `*name` (advancing the pointer * and decrementing `*len`) so panic text shows the source-level name * regardless of target format. No-op for formats with no prefix. */ -void obj_format_demangle_c(const Compiler* c, const char** name, - size_t* len) { +void obj_format_demangle_c(const Compiler* c, const char** name, size_t* len) { if (!c || !name || !len || !*name) return; if (c->target.obj == CFREE_OBJ_MACHO && *len >= 1u && (*name)[0] == '_') { ++(*name); diff --git a/src/obj/obj_tls.c b/src/obj/obj_tls.c @@ -28,14 +28,13 @@ * TLV vars in one TU share one entry; the linker dedupes across TUs by * name. */ -#include "obj/obj.h" - #include <string.h> #include "core/core.h" #include "core/heap.h" #include "core/pool.h" #include "core/slice.h" +#include "obj/obj.h" /* ObjBuilder is opaque outside obj.c; obj_tls.c reaches the bootstrap * cache via these accessors defined in obj.c. Declared here to avoid @@ -53,17 +52,17 @@ static void define_tls_elf(ObjBuilder* ob, Compiler* c, ObjSymId sym, u32 a = align ? align : 1u; if (!data || !has_nonzero_init) { Sym sname = obj_secname_tbss(c); - ObjSecId sec = obj_section_ex(ob, sname, SEC_BSS, SSEM_NOBITS, - SF_ALLOC | SF_WRITE | SF_TLS, a, 0, - OBJ_SEC_NONE, 0); + ObjSecId sec = + obj_section_ex(ob, sname, SEC_BSS, SSEM_NOBITS, + SF_ALLOC | SF_WRITE | SF_TLS, a, 0, OBJ_SEC_NONE, 0); u32 base = obj_align_to(ob, sec, a); obj_reserve_bss(ob, sec, base + size, a); obj_symbol_define(ob, sym, sec, base, size); return; } Sym sname = obj_secname_tdata(c); - ObjSecId sec = obj_section(ob, sname, SEC_DATA, - SF_ALLOC | SF_WRITE | SF_TLS, a); + ObjSecId sec = + obj_section(ob, sname, SEC_DATA, SF_ALLOC | SF_WRITE | SF_TLS, a); u32 base = obj_align_to(ob, sec, a); { u8* dst = obj_reserve(ob, sec, size); @@ -96,22 +95,25 @@ static ObjSymId mint_init_sym(ObjBuilder* ob, Compiler* c, Sym desc_name) { Heap* h = (Heap*)c->ctx->heap; char* buf = (char*)h->alloc(h, nlen + slen + 1u, 1); if (!buf) - compiler_panic(c, (SrcLoc){0, 0, 0}, "obj_define_tls: oom interning init name"); + compiler_panic(c, (SrcLoc){0, 0, 0}, + "obj_define_tls: oom interning init name"); if (nlen) memcpy(buf, nm, nlen); memcpy(buf + nlen, suffix, slen); buf[nlen + slen] = 0; - Sym n = pool_intern_slice(c->global, (Slice){ .s = buf, .len = (u32)(nlen + slen) }); + Sym n = pool_intern_slice(c->global, + (Slice){.s = buf, .len = (u32)(nlen + slen)}); h->free(h, buf, nlen + slen + 1u); return obj_symbol(ob, n, SB_LOCAL, SK_TLS, OBJ_SEC_NONE, 0, 0); } static void define_tls_macho(ObjBuilder* ob, Compiler* c, ObjSymId sym, const u8* data, u32 size, int has_nonzero_init, - u32 align, - const ObjTlsReloc* relocs, u32 nrelocs) { + u32 align, const ObjTlsReloc* relocs, + u32 nrelocs) { const ObjSym* desc_os = obj_symbol_get(ob, sym); if (!desc_os) - compiler_panic(c, (SrcLoc){0, 0, 0}, "obj_define_tls: descriptor sym not found"); + compiler_panic(c, (SrcLoc){0, 0, 0}, + "obj_define_tls: descriptor sym not found"); ObjSymId data_sym = mint_init_sym(ob, c, desc_os->name); /* Storage section: __thread_data (initialized) or __thread_bss (BSS). @@ -120,16 +122,16 @@ static void define_tls_macho(ObjBuilder* ob, Compiler* c, ObjSymId sym, u32 a = align ? align : 1u; if (!data || !has_nonzero_init) { Sym sname = obj_secname_tbss(c); - ObjSecId sec = obj_section_ex(ob, sname, SEC_BSS, SSEM_NOBITS, - SF_ALLOC | SF_WRITE | SF_TLS, a, 0, - OBJ_SEC_NONE, 0); + ObjSecId sec = + obj_section_ex(ob, sname, SEC_BSS, SSEM_NOBITS, + SF_ALLOC | SF_WRITE | SF_TLS, a, 0, OBJ_SEC_NONE, 0); u32 base = obj_align_to(ob, sec, a); obj_reserve_bss(ob, sec, base + size, a); obj_symbol_define(ob, data_sym, sec, base, size); } else { Sym sname = obj_secname_tdata(c); - ObjSecId sec = obj_section(ob, sname, SEC_DATA, - SF_ALLOC | SF_WRITE | SF_TLS, a); + ObjSecId sec = + obj_section(ob, sname, SEC_DATA, SF_ALLOC | SF_WRITE | SF_TLS, a); u32 base = obj_align_to(ob, sec, a); { u8* dst = obj_reserve(ob, sec, size); @@ -145,9 +147,10 @@ static void define_tls_macho(ObjBuilder* ob, Compiler* c, ObjSymId sym, /* Descriptor in __DATA,__thread_vars: 24 bytes aligned 8. * The user-visible `sym` lives here; the TLVP relocs in code target * this symbol so the linker can route them through __thread_ptrs. */ - Sym vars_name = pool_intern_slice(c->global, SLICE_LIT("__DATA,__thread_vars")); - ObjSecId vars_sec = obj_section(ob, vars_name, SEC_DATA, - SF_ALLOC | SF_WRITE | SF_TLS, 8u); + Sym vars_name = + pool_intern_slice(c->global, SLICE_LIT("__DATA,__thread_vars")); + ObjSecId vars_sec = + obj_section(ob, vars_name, SEC_DATA, SF_ALLOC | SF_WRITE | SF_TLS, 8u); u32 desc_base = obj_align_to(ob, vars_sec, 8u); { u8* dst = obj_reserve(ob, vars_sec, 24u); diff --git a/src/obj/reloc_apply.c b/src/obj/reloc_apply.c @@ -14,10 +14,11 @@ * R_RV_* RelocKind values; LO12_S sits at the S-type imm * slots, LO12_I at I-type, and BRANCH/JAL at B/J-type. */ +#include "obj/reloc_apply.h" + #include <string.h> #include "core/bytes.h" -#include "obj/reloc_apply.h" static SrcLoc no_loc(void) { SrcLoc l = {0, 0, 0}; @@ -254,9 +255,8 @@ void link_reloc_apply(Compiler* c, RelocKind k, u8* P_bytes, u64 S, i64 A, compiler_panic(c, no_loc(), "link: LDST%u_ABS_LO12_NC misaligned address " "(kind=%u S=0x%llx A=%lld P=0x%llx)", - 1u << (3 + shift), (unsigned)k, - (unsigned long long)S, (long long)A, - (unsigned long long)P); + 1u << (3 + shift), (unsigned)k, (unsigned long long)S, + (long long)A, (unsigned long long)P); instr = (instr & ~(0xfffu << 10)) | ((u32)(imm12 & 0xfffu) << 10); wr_u32_le(P_bytes, instr); return; @@ -322,7 +322,8 @@ void link_reloc_apply(Compiler* c, RelocKind k, u8* P_bytes, u64 S, i64 A, if (disp & 1) compiler_panic(c, no_loc(), "link: RV BRANCH misaligned displacement"); if (disp < -(i64)(1 << 12) || disp >= (i64)(1 << 12)) - compiler_panic(c, no_loc(), "link: RV BRANCH out of range (need ±4KiB)"); + compiler_panic(c, no_loc(), + "link: RV BRANCH out of range (need ±4KiB)"); b = (u32)((u64)disp & 0x1ffeu) | ((u32)(((u64)disp >> 11) & 1u) << 11) | ((u32)(((u64)disp >> 12) & 1u) << 12); instr = rd_u32_le(P_bytes); @@ -345,8 +346,7 @@ void link_reloc_apply(Compiler* c, RelocKind k, u8* P_bytes, u64 S, i64 A, compiler_panic(c, no_loc(), "link: RV JAL misaligned displacement"); if (disp < -(i64)(1 << 20) || disp >= (i64)(1 << 20)) compiler_panic(c, no_loc(), "link: RV JAL out of range (need ±1MiB)"); - b = (u32)((u64)disp & 0x1ffffeu) | - ((u32)(((u64)disp >> 11) & 1u) << 11) | + b = (u32)((u64)disp & 0x1ffffeu) | ((u32)(((u64)disp >> 11) & 1u) << 11) | ((u32)(((u64)disp >> 20) & 1u) << 20); instr = rd_u32_le(P_bytes); instr &= 0x00000fffu; @@ -509,8 +509,7 @@ void link_reloc_apply(Compiler* c, RelocKind k, u8* P_bytes, u64 S, i64 A, wr_u32_le(P_bytes, (u32)((S + (u64)A) & 0xffffffffu)); return; default: - compiler_panic(c, no_loc(), - "link: unsupported reloc kind %u", + compiler_panic(c, no_loc(), "link: unsupported reloc kind %u", (unsigned)k); } } diff --git a/src/opt/opt.c b/src/opt/opt.c @@ -1017,7 +1017,7 @@ static void w_call(CGTarget* t, const CGCallDesc* d) { } static const char* w_tail_call_unrealizable_reason(CGTarget* t, - const CGCallDesc* d) { + const CGCallDesc* d) { (void)t; (void)d; /* The recorder accepts every tail call. Realizability depends on the laid- diff --git a/src/opt/opt.h b/src/opt/opt.h @@ -28,7 +28,8 @@ * 2 — full pipeline below. Inlining enabled. */ CGTarget* opt_cgtarget_new(Compiler*, CGTarget* target, int level); -/* ----- intra-procedural passes (run per retained Func at finalize on -O2) ----- */ +/* ----- intra-procedural passes (run per retained Func at finalize on -O2) + * ----- */ void opt_build_cfg(Func*); typedef enum OptJumpCleanupStage { OPT_JUMP_CLEANUP_CFG, @@ -42,8 +43,8 @@ void opt_addr_xform(Func*); void opt_addr_xform_pregs(Func*); /* O1: PReg-namespace addr-of-local folding */ void opt_promote_scalar_locals(Func*); /* O1: promote non-escaped scalar frame slots to mutable PRegs. */ -void opt_addr_of_global_cse(Func*); /* O1: hoist duplicate ADDR_OF(global) - defs to a single entry-block compute. */ +void opt_addr_of_global_cse(Func*); /* O1: hoist duplicate ADDR_OF(global) + defs to a single entry-block compute. */ void opt_simplify_local(Func*); void opt_simplify(Func*); void opt_gvn(Func*); /* incl. constprop, redundant-load elim */ diff --git a/src/opt/opt_internal.h b/src/opt/opt_internal.h @@ -119,8 +119,7 @@ static inline u8 opt_preg_loc_cls(const Func* f, PReg r) { static inline Reg opt_preg_hard_reg(const Func* f, PReg r) { const OptLoc* loc = opt_preg_loc(f, r); if (loc && loc->kind == OPT_LOC_HARD) return loc->hard_reg; - if (f && f->preg_info && opt_reg_valid(f, r)) - return f->preg_info[r].hard_reg; + if (f && f->preg_info && opt_reg_valid(f, r)) return f->preg_info[r].hard_reg; return REG_NONE; } diff --git a/src/opt/opt_util.c b/src/opt/opt_util.c @@ -1,7 +1,7 @@ -#include "opt/opt_internal.h" - #include <string.h> +#include "opt/opt_internal.h" + int opt_val_in_inst_defs(const Inst* in, Val v) { if (!in || v == VAL_NONE) return 0; if (in->def == v) return 1; @@ -73,9 +73,9 @@ void opt_walk_inst_operands(Func* f, Inst* in, OptOperandWalkFn fn, void* ctx) { if (in->def == VAL_NONE) break; memset(&def, 0, sizeof def); def.kind = OPK_REG; - def.cls = - (f->preg_info && in->def < opt_reg_count(f)) ? f->preg_info[in->def].cls - : 0; + def.cls = (f->preg_info && in->def < opt_reg_count(f)) + ? f->preg_info[in->def].cls + : 0; def.type = in->type; def.v.reg = (Reg)in->def; opt_walk_operand(f, in, &def, 1, fn, ctx); diff --git a/src/opt/pass_analysis.c b/src/opt/pass_analysis.c @@ -13,7 +13,6 @@ static SrcLoc opt_no_loc(void) { return loc; } - static void opt_fail(Func* f, const char* stage, const char* msg, u32 a, u32 b) { compiler_panic(f->c, opt_no_loc(), "opt verify[%.*s]: %.*s (%u, %u)", @@ -51,8 +50,7 @@ static void verify_frame_slot(Func* f, const char* stage, FrameSlot slot, } static void verify_storage(Func* f, const char* stage, CGLocalStorage st, - CfreeCgTypeId type, u8 expect_cls, - const char* msg) { + CfreeCgTypeId type, u8 expect_cls, const char* msg) { switch ((CGLocalStorageKind)st.kind) { case CG_LOCAL_STORAGE_FRAME: verify_frame_slot(f, stage, st.v.frame_slot, msg); @@ -121,8 +119,8 @@ static void verify_abivalue_shape(Func* f, const char* stage, CGABIValue* v, verify_operand_shape(f, stage, &v->parts[i].op, physical_regs); } -static void verify_call_plan_shape(Func* f, const char* stage, - CGCallPlan* plan, int physical_regs) { +static void verify_call_plan_shape(Func* f, const char* stage, CGCallPlan* plan, + int physical_regs) { if (!plan) return; verify_operand_shape(f, stage, &plan->callee, physical_regs); for (u32 i = 0; i < plan->nargs; ++i) { @@ -593,7 +591,8 @@ static void verify_function_storage(Func* f, const char* stage) { for (u32 i = 0; i < f->nframe_slots; ++i) { IRFrameSlot* s = &f->frame_slots[i]; if (s->id != i + 1u) opt_fail(f, stage, "frame slot id mismatch", s->id, i); - if (s->kind > FS_SPILL) opt_fail(f, stage, "bad frame slot kind", s->kind, i); + if (s->kind > FS_SPILL) + opt_fail(f, stage, "bad frame slot kind", s->kind, i); } for (u32 i = 0; i < f->nparams; ++i) { IRParam* p = &f->params[i]; @@ -631,8 +630,7 @@ static void verify_allocations(Func* f, const char* stage) { case OPT_ALLOC_HARD: if (opt_preg_hard_reg(f, r) == (Reg)REG_NONE || opt_preg_hard_reg(f, r) >= OPT_MAX_HARD_REGS) - opt_fail(f, stage, "bad hard allocation", r, - opt_preg_hard_reg(f, r)); + opt_fail(f, stage, "bad hard allocation", r, opt_preg_hard_reg(f, r)); if (pi && (pi->cls != cls || pi->hard_reg != opt_preg_hard_reg(f, r))) opt_fail(f, stage, "hard alloc mirror mismatch", r, pi->hard_reg); if (loc && (loc->kind != OPT_LOC_HARD || loc->cls != cls)) @@ -668,7 +666,8 @@ static void verify_allocations(Func* f, const char* stage) { for (u32 si = f->opt_first_segment_by_preg[r]; si != OPT_RANGE_NONE; si = f->opt_alloc_segments[si].next) { OptAllocSegment* s = &f->opt_alloc_segments[si]; - if (s->block >= f->nblocks) opt_fail(f, stage, "bad split block", r, si); + if (s->block >= f->nblocks) + opt_fail(f, stage, "bad split block", r, si); if (s->start > s->end) opt_fail(f, stage, "bad split range", r, si); if (s->cls >= OPT_REG_CLASSES) opt_fail(f, stage, "bad split class", r, s->cls); diff --git a/src/opt/pass_combine.c b/src/opt/pass_combine.c @@ -326,7 +326,8 @@ static int inst_reads_memory(const Inst* in) { } /* ---- substitution-slot whitelist (operand positions that accept a register - * substitute, an immediate substitute, or are valid for ext-of-ext folding) ---- */ + * substitute, an immediate substitute, or are valid for ext-of-ext folding) + * ---- */ typedef enum SubstKind { SK_REG, /* register-to-register (IR_COPY producer) */ @@ -427,8 +428,7 @@ static void ctx_record(CombineCtx* ctx, const Inst* in, i32 i) { if (inst_writes_memory(in)) ctx->last_mem_def = i; if (inst_is_clobber_barrier(in)) { for (u32 c = 0; c < OPT_REG_CLASSES; ++c) - for (u32 r = 0; r < OPT_MAX_HARD_REGS; ++r) - ctx->last_def[c][r] = i; + for (u32 r = 0; r < OPT_MAX_HARD_REGS; ++r) ctx->last_def[c][r] = i; return; } switch ((IROp)in->op) { @@ -702,8 +702,7 @@ static int subst_consumer_operands(Inst* in, const Operand* def, if (op->kind == OPK_INDIRECT && kind == SK_REG && src->kind == OPK_REG && def->kind == OPK_REG && def->cls == RC_INT && src->cls == RC_INT && (op->v.ind.base == def->v.reg || - (op->v.ind.index != (Reg)REG_NONE && - op->v.ind.index == def->v.reg))) { + (op->v.ind.index != (Reg)REG_NONE && op->v.ind.index == def->v.reg))) { if ((IROp)in->op == IR_STORE || (IROp)in->op == IR_ATOMIC_STORE || (IROp)in->op == IR_BITFIELD_STORE || (IROp)in->op == IR_AGG_COPY || (IROp)in->op == IR_AGG_SET) @@ -717,8 +716,8 @@ static int subst_consumer_operands(Inst* in, const Operand* def, /* Try to substitute the producer of (cls, reg) into uses of that register * in `in`. Returns 1 if at least one operand was rewritten. */ -static int try_substitute_for_reg(CombineCtx* ctx, Inst* in, i32 i, - u8 cls, Reg reg) { +static int try_substitute_for_reg(CombineCtx* ctx, Inst* in, i32 i, u8 cls, + Reg reg) { i32 prod_idx = ctx_producer_of(ctx, cls, reg); if (prod_idx < 0 || prod_idx >= i) return 0; Inst* prod = &ctx->bl->insts[prod_idx]; @@ -769,7 +768,7 @@ static int try_substitute_for_reg(CombineCtx* ctx, Inst* in, i32 i, int uses_total = count_uses_in_live_range(ctx->bl, prod_idx, &def, &killed); if (uses_total != 1) return 0; if (!killed && opt_block_live_out_has_phys_reg(ctx->f, ctx->hard_live, - ctx->bl->id, &def)) + ctx->bl->id, &def)) return 0; int n = subst_consumer_operands(in, &def, &src_op, kind); @@ -838,11 +837,11 @@ static int try_addr_synth_one_op(CombineCtx* ctx, Inst* in, i32 i, /* Single-use within producer's live range (the only further use * before next redef/barrier). */ int killed = 0; - int uses_after = count_uses_in_live_range(ctx->bl, prod_idx, - &prod_def, &killed); + int uses_after = + count_uses_in_live_range(ctx->bl, prod_idx, &prod_def, &killed); if (uses_after == 1 && (killed || !opt_block_live_out_has_phys_reg( - ctx->f, ctx->hard_live, ctx->bl->id, &prod_def))) { + ctx->f, ctx->hard_live, ctx->bl->id, &prod_def))) { Operand lhs = prod->opnds[1]; Operand rhs = prod->opnds[2]; int has_no_index = (op->v.ind.index == (Reg)REG_NONE); @@ -892,8 +891,7 @@ static int try_addr_synth_one_op(CombineCtx* ctx, Inst* in, i32 i, if (prod_idx >= 0 && prod_idx < i) { Inst* prod = &ctx->bl->insts[prod_idx]; if ((IROp)prod->op == IR_BINOP && prod->nopnds == 3 && - (BinOp)prod->extra.imm == BO_SHL && - prod->opnds[0].kind == OPK_REG && + (BinOp)prod->extra.imm == BO_SHL && prod->opnds[0].kind == OPK_REG && prod->opnds[0].cls == RC_INT && prod->opnds[0].v.reg == idx && prod->opnds[1].kind == OPK_REG && prod->opnds[1].cls == RC_INT && prod->opnds[2].kind == OPK_IMM) { @@ -901,15 +899,15 @@ static int try_addr_synth_one_op(CombineCtx* ctx, Inst* in, i32 i, if (sh >= 1 && sh <= 3) { Operand prod_def = prod->opnds[0]; int killed = 0; - int uses_after = count_uses_in_live_range(ctx->bl, prod_idx, - &prod_def, &killed); + int uses_after = + count_uses_in_live_range(ctx->bl, prod_idx, &prod_def, &killed); /* `<= 2` allows the degenerate [base == index] case where the SHL * dst appears twice in the same indirect; rewriting only the index * still yields equivalent arithmetic when base also held the SHL * dst (base unchanged: r*4; index rewritten: r_src*4; r*4 == r*4). */ if (uses_after >= 1 && uses_after <= 2 && (killed || !opt_block_live_out_has_phys_reg( - ctx->f, ctx->hard_live, ctx->bl->id, &prod_def)) && + ctx->f, ctx->hard_live, ctx->bl->id, &prod_def)) && !ctx_def_changed_since(ctx, RC_INT, prod->opnds[1].v.reg, prod_idx)) { op->v.ind.index = prod->opnds[1].v.reg; @@ -959,8 +957,7 @@ static int try_sink(CombineCtx* ctx, Inst* in, i32 i) { if (p->kind == OPK_REG) { if (ctx_def_changed_since(ctx, p->cls, p->v.reg, prod_idx)) return 0; } else if (p->kind == OPK_INDIRECT) { - if (ctx_def_changed_since(ctx, RC_INT, p->v.ind.base, prod_idx)) - return 0; + if (ctx_def_changed_since(ctx, RC_INT, p->v.ind.base, prod_idx)) return 0; if (p->v.ind.index != (Reg)REG_NONE && ctx_def_changed_since(ctx, RC_INT, p->v.ind.index, prod_idx)) return 0; @@ -986,7 +983,7 @@ static int try_sink(CombineCtx* ctx, Inst* in, i32 i) { if (killed && use_after_clobber_before_redef(ctx->bl, prod_idx, &src)) return 0; if (!killed && opt_block_live_out_has_phys_reg(ctx->f, ctx->hard_live, - ctx->bl->id, &src)) + ctx->bl->id, &src)) return 0; int swap_binop = 0; @@ -1042,16 +1039,16 @@ static int try_combine_exts(CombineCtx* ctx, Inst* in, i32 i) { /* Single-use of inner ext dst within its live range (only this insn). */ Operand prod_def = prod->opnds[0]; int killed = 0; - int uses_total = count_uses_in_live_range(ctx->bl, prod_idx, &prod_def, - &killed); + int uses_total = + count_uses_in_live_range(ctx->bl, prod_idx, &prod_def, &killed); if (uses_total != 1) return 0; if (!killed && opt_block_live_out_has_phys_reg(ctx->f, ctx->hard_live, - ctx->bl->id, &prod_def)) + ctx->bl->id, &prod_def)) return 0; /* Outer width `db`, inner width `idb`. Inner reads `isb` bytes. */ - u32 outer_in = sb; /* outer's source width */ - u32 inner_out = idb; /* inner's output width */ + u32 outer_in = sb; /* outer's source width */ + u32 inner_out = idb; /* inner's output width */ if (outer_in > inner_out) return 0; /* sanity: inner feeds outer */ /* If inner is an identity-shaped convert that reads back its own def @@ -1096,15 +1093,14 @@ static int try_ret_retarget(Func* f, Block* bl, i32 i) { Operand* ret_op = NULL; Reg ret_reg = REG_NONE; if (!aux || !aux->present || !ret_scalar_storage(&aux->val, &ret_op) || - !first_return_reg(f, ret_op->cls, &ret_reg) || - ret_reg == (Reg)REG_NONE || ret_reg == ret_op->v.reg) + !first_return_reg(f, ret_op->cls, &ret_reg) || ret_reg == (Reg)REG_NONE || + ret_reg == ret_op->v.reg) return 0; Inst* producer = &bl->insts[i - 1u]; Operand ret_dst = *ret_op; ret_dst.v.reg = ret_reg; int swap_binop = 0; - if (producer->nopnds < 1 || - !same_phys_reg(&producer->opnds[0], ret_op) || + if (producer->nopnds < 1 || !same_phys_reg(&producer->opnds[0], ret_op) || !retarget_producer_legal(producer, &ret_dst, &swap_binop)) return 0; if (swap_binop) { @@ -1143,7 +1139,8 @@ static int opt_combine_fold_block(Func* f, Block* bl, probe.cls = c; for (Reg r = 0; r < OPT_MAX_HARD_REGS; ++r) { probe.v.reg = r; - if (ctx.last_def[c][r] == i - 1 && !inst_defines_phys_reg(prev, &probe)) + if (ctx.last_def[c][r] == i - 1 && + !inst_defines_phys_reg(prev, &probe)) ctx_restore_removed_def(&ctx, &probe, i - 1); } } diff --git a/src/opt/pass_emit.c b/src/opt/pass_emit.c @@ -176,8 +176,7 @@ static int operand_uses_reg_for_replay(const Operand* op, const Operand* r) { if (op->kind == OPK_INDIRECT) return r->cls == RC_INT && (op->v.ind.base == r->v.reg || - (op->v.ind.index != (Reg)REG_NONE && - op->v.ind.index == r->v.reg)); + (op->v.ind.index != (Reg)REG_NONE && op->v.ind.index == r->v.reg)); return 0; } @@ -478,9 +477,8 @@ static void replay_planned_call(ReplayCtx* r, const IRCallAux* aux, if (src_plan->flags & CG_CALL_TAIL) return; CGCallPlanRet* rets = - src_plan->nrets - ? arena_array(r->f->arena, CGCallPlanRet, src_plan->nrets) - : NULL; + src_plan->nrets ? arena_array(r->f->arena, CGCallPlanRet, src_plan->nrets) + : NULL; ReplayParallelMove* ret_moves = src_plan->nrets ? arena_zarray(r->f->arena, ReplayParallelMove, src_plan->nrets) @@ -905,8 +903,9 @@ static void collect_replayed_reg(Func* f, Reg raw, RegClass cls, Reg* used, add_unique_reg(used, nused, cap, raw); } -static void collect_replayed_operand_reg(Func* f, const Operand* op, RegClass cls, - Reg* used, u32* nused, u32 cap) { +static void collect_replayed_operand_reg(Func* f, const Operand* op, + RegClass cls, Reg* used, u32* nused, + u32 cap) { if (!op) return; if (op->kind == OPK_REG) { if (op->cls == cls) @@ -921,8 +920,8 @@ static void collect_replayed_operand_reg(Func* f, const Operand* op, RegClass cl } static void collect_replayed_abivalue_regs(Func* f, const CGABIValue* v, - RegClass cls, - Reg* used, u32* nused, u32 cap) { + RegClass cls, Reg* used, u32* nused, + u32 cap) { if (!v) return; collect_replayed_operand_reg(f, &v->storage, cls, used, nused, cap); for (u32 i = 0; i < v->nparts; ++i) @@ -961,8 +960,8 @@ static u32 collect_replayed_hard_regs(Func* f, CGTarget* w, RegClass cls, IRCallAux* aux = (IRCallAux*)in->extra.aux; if (!aux) break; if (aux->use_plan_replay) { - collect_replayed_operand_reg(f, &aux->plan.callee, cls, used, &nused, - cap); + collect_replayed_operand_reg(f, &aux->plan.callee, cls, used, + &nused, cap); for (u32 j = 0; j < aux->plan.nargs; ++j) { collect_replayed_operand_reg(f, &aux->plan.args[j].src, cls, used, &nused, cap); @@ -977,8 +976,8 @@ static u32 collect_replayed_hard_regs(Func* f, CGTarget* w, RegClass cls, add_unique_reg(used, &nused, cap, aux->plan.rets[j].src_reg); } } else { - collect_replayed_operand_reg(f, &aux->desc.callee, cls, used, &nused, - cap); + collect_replayed_operand_reg(f, &aux->desc.callee, cls, used, + &nused, cap); for (u32 j = 0; j < aux->desc.nargs; ++j) collect_replayed_abivalue_regs(f, &aux->desc.args[j], cls, used, &nused, cap); @@ -990,7 +989,8 @@ static u32 collect_replayed_hard_regs(Func* f, CGTarget* w, RegClass cls, case IR_RET: { IRRetAux* aux = (IRRetAux*)in->extra.aux; if (aux && aux->present) - collect_replayed_abivalue_regs(f, &aux->val, cls, used, &nused, cap); + collect_replayed_abivalue_regs(f, &aux->val, cls, used, &nused, + cap); break; } case IR_SCOPE_BEGIN: { @@ -1015,9 +1015,11 @@ static u32 collect_replayed_hard_regs(Func* f, CGTarget* w, RegClass cls, IRIntrinAux* aux = (IRIntrinAux*)in->extra.aux; if (!aux) break; for (u32 j = 0; j < aux->narg; ++j) - collect_replayed_operand_reg(f, &aux->args[j], cls, used, &nused, cap); + collect_replayed_operand_reg(f, &aux->args[j], cls, used, &nused, + cap); for (u32 j = 0; j < aux->ndst; ++j) - collect_replayed_operand_reg(f, &aux->dsts[j], cls, used, &nused, cap); + collect_replayed_operand_reg(f, &aux->dsts[j], cls, used, &nused, + cap); break; } default: @@ -1059,7 +1061,8 @@ static int replay_param_storage_uses_frame_slot(Func* f, CGLocalStorage st) { if (replay_storage_uses_frame_slot(st)) return 1; if (st.kind != CG_LOCAL_STORAGE_REG || !f || !f->opt_rewritten) return 0; PReg pr = (PReg)st.v.reg; - return opt_reg_valid(f, pr) && opt_preg_alloc_kind(f, pr) == OPT_ALLOC_SPILL && + return opt_reg_valid(f, pr) && + opt_preg_alloc_kind(f, pr) == OPT_ALLOC_SPILL && opt_preg_spill_slot(f, pr) != FRAME_SLOT_NONE; } diff --git a/src/opt/pass_hard_live.c b/src/opt/pass_hard_live.c @@ -57,8 +57,7 @@ static void hard_use_operand(OptHardRegSet* s, const Operand* op) { hard_add(s, op->cls, op->v.reg); } else if (op->kind == OPK_INDIRECT) { hard_add(s, RC_INT, op->v.ind.base); - if (op->v.ind.index != (Reg)REG_NONE) - hard_add(s, RC_INT, op->v.ind.index); + if (op->v.ind.index != (Reg)REG_NONE) hard_add(s, RC_INT, op->v.ind.index); } } diff --git a/src/opt/pass_inline.c b/src/opt/pass_inline.c @@ -392,7 +392,8 @@ static Inst clone_inst(InlineMap* m, const Inst* src) { static void clone_block_succs(InlineMap* m, Block* dst, const Block* src) { ir_block_set_nsucc(m->caller, dst->id, src->nsucc); - for (u32 s = 0; s < src->nsucc; ++s) dst->succ[s] = map_block(m, src->succ[s]); + for (u32 s = 0; s < src->nsucc; ++s) + dst->succ[s] = map_block(m, src->succ[s]); } static int append_return_materialization(InstVec* out, InlineMap* m, @@ -426,7 +427,9 @@ static int append_return_materialization(InstVec* out, InlineMap* m, return 1; } -static Inst make_branch(Func* f, SrcLoc loc) { return make_inst(f, IR_BR, loc); } +static Inst make_branch(Func* f, SrcLoc loc) { + return make_inst(f, IR_BR, loc); +} static void emit_order_push_unique(u32* out, u32* nout, u32 b) { for (u32 i = 0; i < *nout; ++i) @@ -436,8 +439,8 @@ static void emit_order_push_unique(u32* out, u32* nout, u32 b) { static void inline_rebuild_emit_order(Func* caller, u32 anchor, InlineMap* m, u32 cont) { - u32 cap = caller->emit_order_n + m->callee->emit_order_n + m->callee->nblocks + - 2u; + u32 cap = + caller->emit_order_n + m->callee->emit_order_n + m->callee->nblocks + 2u; u32* order = arena_array(caller->arena, u32, cap ? cap : 1u); u32 norder = 0; int inserted = 0; @@ -483,8 +486,7 @@ static int inline_rewrite_supported(Func* callee, const Inst* call) { if ((IROp)in->op != IR_RET) continue; IRRetAux* ret_aux = (IRRetAux*)in->extra.aux; if (!ret_aux || !ret_aux->present) continue; - if (ret_aux->val.nparts != 0 || call_aux->desc.ret.nparts != 0) - return 0; + if (ret_aux->val.nparts != 0 || call_aux->desc.ret.nparts != 0) return 0; if (call_aux->desc.ret.storage.kind == OPK_IMM) continue; if (call_aux->desc.ret.storage.kind != OPK_REG) return 0; if (ret_aux->val.storage.kind != OPK_REG && @@ -551,8 +553,7 @@ static int inline_call_site(Func* caller, u32 block_idx, u32 inst_idx, case IR_PARAM_DECL: break; case IR_RET: { - if (!append_return_materialization(&body, &map, &call, src)) - return 0; + if (!append_return_materialization(&body, &map, &call, src)) return 0; Inst ret_br = make_branch(caller, src->loc); instvec_push(&body, &ret_br); break; @@ -568,8 +569,8 @@ static int inline_call_site(Func* caller, u32 block_idx, u32 inst_idx, dst_bl->insts = body.v; dst_bl->ninsts = body.n; dst_bl->cap = body.cap; - if (body.n && (IROp)body.v[body.n - 1u].op == IR_BR && - src_bl->ninsts && (IROp)src_bl->insts[src_bl->ninsts - 1u].op == IR_RET) { + if (body.n && (IROp)body.v[body.n - 1u].op == IR_BR && src_bl->ninsts && + (IROp)src_bl->insts[src_bl->ninsts - 1u].op == IR_RET) { ir_block_set_nsucc(caller, dst_b, 1); caller->blocks[dst_b].succ[0] = cont; } else { @@ -589,10 +590,12 @@ static int caller_growth_ok(FuncSet* fs, Func* caller, const u32* base_cost, int idx = funcset_index(fs, caller); u32 base = idx >= 0 ? base_cost[idx] : func_inline_cost(caller); u32 growth_limit = base / 4u; - if (growth_limit < INLINE_NORMAL_COST_LIMIT) growth_limit = INLINE_NORMAL_COST_LIMIT; + if (growth_limit < INLINE_NORMAL_COST_LIMIT) + growth_limit = INLINE_NORMAL_COST_LIMIT; if (policy == CFREE_CG_INLINE_HINT) { growth_limit *= 2u; - if (growth_limit < INLINE_HINT_COST_LIMIT) growth_limit = INLINE_HINT_COST_LIMIT; + if (growth_limit < INLINE_HINT_COST_LIMIT) + growth_limit = INLINE_HINT_COST_LIMIT; if (growth_limit > INLINE_HINT_ABS_GROWTH_LIMIT) growth_limit = INLINE_HINT_ABS_GROWTH_LIMIT; } else if (growth_limit > INLINE_ABS_GROWTH_LIMIT) { @@ -659,7 +662,8 @@ void opt_inline(FuncSet* fs, int max_iters) { if (!fs || fs->nfuncs == 0 || max_iters <= 0) return; if (max_iters > 4) max_iters = 4; u32* base_cost = arena_array(fs->arena, u32, fs->nfuncs); - for (u32 i = 0; i < fs->nfuncs; ++i) base_cost[i] = func_inline_cost(fs->funcs[i]); + for (u32 i = 0; i < fs->nfuncs; ++i) + base_cost[i] = func_inline_cost(fs->funcs[i]); for (int iter = 0; iter < max_iters; ++iter) { int changed = 0; InlineOrderCtx ctx; diff --git a/src/opt/pass_jump.c b/src/opt/pass_jump.c @@ -84,8 +84,7 @@ static u32 forward_jump_target_ex(JumpCleanupCtx* c, u32 target, break; } if (!single_jump_block(c, cur, &next) && - (!allow_empty_fallthrough || - !empty_fallthrough_block(c, cur, &next))) { + (!allow_empty_fallthrough || !empty_fallthrough_block(c, cur, &next))) { result = cur; c->forwarded_target_by_block[cur] = result; break; @@ -368,8 +367,7 @@ static u32 full_forwardable_successors(const Block* bl, const Inst* term) { } } -static void full_rewrite_successor(Func* f, u32 b, u32 old_succ, - u32 new_succ) { +static void full_rewrite_successor(Func* f, u32 b, u32 old_succ, u32 new_succ) { opt_replace_succ_ref(f, b, old_succ, new_succ); } diff --git a/src/opt/pass_live.c b/src/opt/pass_live.c @@ -219,8 +219,7 @@ static void live_recompute_metrics(OptLiveInfo* live) { live->set_bit_scans += live_count_set_bits(&bl->live_use); live->set_bit_scans += live_count_set_bits(&bl->live_def); } - live->block_bytes = - live->active_words * (u64)sizeof(u64); + live->block_bytes = live->active_words * (u64)sizeof(u64); } static void live_worklist_push(u32* worklist, u8* queued, u32* n, u32 b) { @@ -284,7 +283,8 @@ void opt_live_blocks(Func* f, OptLiveInfo* live) { if (live_metric_copy(live, &lb->live_in, &tmp)) { for (u32 p = 0; p < bl->npreds; ++p) { u32 pred = bl->preds[p]; - if (pred < f->nblocks) live_worklist_push(worklist, queued, &nwork, pred); + if (pred < f->nblocks) + live_worklist_push(worklist, queued, &nwork, pred); } } } diff --git a/src/opt/pass_lower.c b/src/opt/pass_lower.c @@ -310,8 +310,7 @@ static void apply_param_incoming_register_hazards(Func* f) { u8 cls = f->preg_info[v].cls; for (u32 j = 0; j < incoming.nall; ++j) { if (incoming.all_cls[j] != cls) continue; - if (f->preg_info[v].tied_hard_reg == (i32)incoming.all_regs[j]) - continue; + if (f->preg_info[v].tied_hard_reg == (i32)incoming.all_regs[j]) continue; forbid_preg_reg(f, v, cls, incoming.all_regs[j]); } } @@ -374,7 +373,7 @@ static FrameSlot spill_slot_for(Func* f, PReg v) { static u32 hard_loc_bit(u8 cls, Reg r) { return ((u32)cls * 32u) + (u32)r; } typedef struct OptAllocCandidate { - PReg v; /* coalesce-root PReg with live ranges */ + PReg v; /* coalesce-root PReg with live ranges */ u32 spill_cost; u32 live_length; u8 tied; @@ -394,7 +393,7 @@ typedef struct OptAllocGroupInfo { } OptAllocGroupInfo; typedef struct OptAllocator { - OptLoc* locs; /* per-PReg result (cls, hard_reg, spill_slot) */ + OptLoc* locs; /* per-PReg result (cls, hard_reg, spill_slot) */ /* Per-point bitmap of locations. used_locs[p * loc_words + w] is word w * of the bitmap for compressed program point p. Bit indices: @@ -402,8 +401,8 @@ typedef struct OptAllocator { * hard_loc_bits + stack_idx -> stack slot indices */ u64* used_locs; u32 point_count; - u32 loc_words; /* width of one row, in u64 words */ - u32 hard_loc_bits; /* OPT_REG_CLASSES * 32 */ + u32 loc_words; /* width of one row, in u64 words */ + u32 hard_loc_bits; /* OPT_REG_CLASSES * 32 */ /* Stack slot table (parallel arrays). */ FrameSlot* stack_slots; @@ -419,11 +418,11 @@ typedef struct OptAllocator { u64* conflict_locs; /* Metrics. */ - u64 hard_point_visits; /* points scanned during hard-reg conflict probe */ - u64 stack_point_visits; /* points scanned during stack-slot probe */ - u64 hard_word_ors; /* word-OR operations into conflict_locs */ + u64 hard_point_visits; /* points scanned during hard-reg conflict probe */ + u64 stack_point_visits; /* points scanned during stack-slot probe */ + u64 hard_word_ors; /* word-OR operations into conflict_locs */ u64 stack_word_ors; - u64 hard_mark_points; /* points marked when assigning a hard reg */ + u64 hard_mark_points; /* points marked when assigning a hard reg */ u64 stack_mark_points; } OptAllocator; @@ -459,7 +458,8 @@ static u32 alloc_alloc_stack_slot(Func* f, OptAllocator* a, FrameSlot fs) { u32 ncap = a->stack_slot_cap ? a->stack_slot_cap * 2u : 16u; FrameSlot* ns = arena_array(f->arena, FrameSlot, ncap); if (a->stack_slots) - memcpy(ns, a->stack_slots, sizeof(a->stack_slots[0]) * a->stack_slot_count); + memcpy(ns, a->stack_slots, + sizeof(a->stack_slots[0]) * a->stack_slot_count); a->stack_slots = ns; a->stack_slot_cap = ncap; } @@ -482,7 +482,8 @@ static u32 hard_reg_alloc_score(Func* f, const OptAllocator* a, score += 20u; } else if (!is_caller_saved(f, vi->cls, hr)) { u32 bit = hard_loc_bit(vi->cls, hr); - int already_open = a->hard_open && bit < a->hard_loc_bits && a->hard_open[bit]; + int already_open = + a->hard_open && bit < a->hard_loc_bits && a->hard_open[bit]; if (!already_open) score += pi ? pi->save_cost : 50u; } return score; @@ -1371,8 +1372,8 @@ typedef struct EdgePlace { u32 block; } EdgePlace; -static u32 edge_place_for(Func* f, EdgePlace** places, u32* nplaces, - u32* cap, u32 pred, u32 succ) { +static u32 edge_place_for(Func* f, EdgePlace** places, u32* nplaces, u32* cap, + u32 pred, u32 succ) { for (u32 i = 0; i < *nplaces; ++i) if ((*places)[i].pred == pred && (*places)[i].succ == succ) return (*places)[i].block; @@ -1406,8 +1407,8 @@ static void apply_split_edge_materialization(Func* f, const EdgeMatPlan* plan) { for (u32 i = 0; i < plan->n; ++i) { const EdgeMat* m = &plan->mats[i]; if ((EdgeMatKind)m->kind != kind) continue; - u32 block = edge_place_for(f, &places, &nplaces, &place_cap, m->pred, - m->succ); + u32 block = + edge_place_for(f, &places, &nplaces, &place_cap, m->pred, m->succ); RewriteList list; memset(&list, 0, sizeof list); if (kind == EDGE_MAT_STORE) @@ -1735,8 +1736,7 @@ static void opt_verify_alloc(Func* f, const OptLiveInfo* live) { for (u32 k = 0; k < refs.ndefs; ++k) { PReg d = refs.defs[k]; u8 d_kind = opt_preg_alloc_kind(f, d); - if (d_kind != OPT_ALLOC_HARD && d_kind != OPT_ALLOC_SPILL) - continue; + if (d_kind != OPT_ALLOC_HARD && d_kind != OPT_ALLOC_SPILL) continue; for (PReg p = 1; p < nregs; ++p) { u8 p_kind; if (!cur[p] || p == d) continue; @@ -1822,8 +1822,7 @@ void opt_regalloc(Func* f, int allow_live_range_split) { opt_regalloc_place(f, allow_live_range_split, &live); EdgeMatPlan edge_mats; memset(&edge_mats, 0, sizeof edge_mats); - if (allow_live_range_split) - prepare_split_edge_materialization(f, &edge_mats); + if (allow_live_range_split) prepare_split_edge_materialization(f, &edge_mats); rewrite_func(f, &live); apply_split_edge_materialization(f, &edge_mats); } diff --git a/src/opt/pass_machinize.c b/src/opt/pass_machinize.c @@ -23,8 +23,7 @@ static int asm_resolve_fixed_constraint(Func* f, CGTarget* target, while (*end && *end != '}') ++end; if (*end != '}' || end == body + 1) return 0; Sym name = pool_intern_slice( - f->c->global, - (Slice){ .s = body + 1, .len = (size_t)(end - body - 1) }); + f->c->global, (Slice){.s = body + 1, .len = (size_t)(end - body - 1)}); return target->resolve_reg_name(target, name, reg_out, cls_out) == 0; } @@ -121,10 +120,8 @@ static void machinize_collect_regs(Func* f, CGTarget* target) { Reg hr = phys[i].reg; u16 flags = phys[i].flags; if (hr < 32u) { - if (flags & CG_REG_CALLER_SAVED) - f->opt_caller_saved[c] |= 1u << hr; - if (flags & CG_REG_CALLEE_SAVED) - f->opt_callee_saved[c] |= 1u << hr; + if (flags & CG_REG_CALLER_SAVED) f->opt_caller_saved[c] |= 1u << hr; + if (flags & CG_REG_CALLEE_SAVED) f->opt_callee_saved[c] |= 1u << hr; if (flags & CG_REG_RESERVED) f->opt_reserved_regs[c] |= 1u << hr; if (flags & CG_REG_ARG) f->opt_arg_regs[c] |= 1u << hr; if (flags & CG_REG_RET) f->opt_ret_regs[c] |= 1u << hr; diff --git a/src/opt/pass_mir.c b/src/opt/pass_mir.c @@ -26,8 +26,7 @@ static void mir_commit(Func* f, const Func* view) { static void mir_verify_reg(Func* f, const char* stage, Reg r, u8 cls, const char* what) { - if (r == (Reg)REG_NONE || cls >= OPT_REG_CLASSES || - r >= OPT_MAX_HARD_REGS) { + if (r == (Reg)REG_NONE || cls >= OPT_REG_CLASSES || r >= OPT_MAX_HARD_REGS) { SrcLoc loc = {0, 0, 0}; compiler_panic(f->c, loc, "opt MIR verify %s: bad %s cls%u reg%u", stage ? stage : "?", what, (unsigned)cls, (unsigned)r); diff --git a/src/opt/pass_o2.c b/src/opt/pass_o2.c @@ -1,6 +1,5 @@ -#include <string.h> - #include <cfree/cg.h> +#include <string.h> #include "opt/opt_internal.h" @@ -668,7 +667,6 @@ static AddrXformUseClass addr_xform_pregs_classify_use(Inst* in, Operand* op, return OPF_FOLD_EA; } - static int addr_xform_pregs_op_uses(const Operand* op, PReg p) { if (!op) return 0; if (op->kind == OPK_REG && (PReg)op->v.reg == p) return 1; @@ -801,7 +799,8 @@ void opt_addr_xform_pregs(Func* f) { if (op->v.ind.ofs != 0 || op->v.ind.index != (Reg)REG_NONE) continue; /* EA-shaped; leave alone */ Operand folded = local; - folded.type = use->extra.mem.type ? use->extra.mem.type : local.type; + folded.type = + use->extra.mem.type ? use->extra.mem.type : local.type; *op = folded; } } @@ -829,8 +828,7 @@ void opt_addr_xform_pregs(Func* f) { } } for (u32 s = 0; s < f->nframe_slots; ++s) { - if (!still_taken[s]) - f->frame_slots[s].flags &= (u16)~FSF_ADDR_TAKEN; + if (!still_taken[s]) f->frame_slots[s].flags &= (u16)~FSF_ADDR_TAKEN; } } if (changed) @@ -919,8 +917,8 @@ static int promote_aux_uses_slot(const Inst* in, FrameSlot slot) { } else { if (promote_op_uses_slot(&aux->desc.callee, slot)) return 1; for (u32 i = 0; i < aux->desc.nargs; ++i) - if (promote_abivalue_uses_slot( - (const CGABIValue*)&aux->desc.args[i], slot)) + if (promote_abivalue_uses_slot((const CGABIValue*)&aux->desc.args[i], + slot)) return 1; if (promote_abivalue_uses_slot(&aux->desc.ret, slot)) return 1; } @@ -977,8 +975,7 @@ static int promote_inst_classify(const Inst* in, FrameSlot slot, touched = 1; } /* opnds[0] is the dst REG — never OPK_LOCAL by construction. */ - if (in->nopnds >= 1 && promote_op_uses_slot(&in->opnds[0], slot)) - return -1; + if (in->nopnds >= 1 && promote_op_uses_slot(&in->opnds[0], slot)) return -1; } else if ((IROp)in->op == IR_STORE) { if (in->nopnds >= 1 && promote_op_uses_slot(&in->opnds[0], slot)) { if (opt_mem_observable(&in->extra.mem)) return -1; @@ -990,10 +987,10 @@ static int promote_inst_classify(const Inst* in, FrameSlot slot, touched = 1; } /* opnds[1] is the src value — should never be OPK_LOCAL for a scalar. */ - if (in->nopnds >= 2 && promote_op_uses_slot(&in->opnds[1], slot)) - return -1; + if (in->nopnds >= 2 && promote_op_uses_slot(&in->opnds[1], slot)) return -1; } else { - /* Any other instruction with an OPK_LOCAL(slot) operand blocks promotion. */ + /* Any other instruction with an OPK_LOCAL(slot) operand blocks promotion. + */ for (u32 o = 0; o < in->nopnds; ++o) if (promote_op_uses_slot(&in->opnds[o], slot)) return -1; } @@ -1031,8 +1028,8 @@ static void promote_rewrite_store(Func* f, Inst* in, PReg preg, } /* Rewrite an `IR_LOAD dst, OPK_LOCAL(slot)` into `IR_COPY dst, preg`. */ -static void promote_rewrite_load(Func* f, Inst* in, PReg preg, - CfreeCgTypeId ty, u8 cls) { +static void promote_rewrite_load(Func* f, Inst* in, PReg preg, CfreeCgTypeId ty, + u8 cls) { Operand dst = in->opnds[0]; Operand* opnds = arena_array(f->arena, Operand, 2); opnds[0] = dst; @@ -1073,7 +1070,10 @@ void opt_promote_scalar_locals(Func* f) { for (u32 i = 0; i < bl->ninsts; ++i) { Inst* in = &bl->insts[i]; int r = promote_inst_classify(in, id, slot->type); - if (r < 0) { rejected = 1; break; } + if (r < 0) { + rejected = 1; + break; + } touched_count += r; } } @@ -1127,10 +1127,10 @@ void opt_promote_scalar_locals(Func* f) { typedef struct AddrCseEntry { ObjSymId sym; i64 addend; - PReg canonical; /* freshly allocated PReg, def in block 0 */ - CfreeCgTypeId addr_type; /* operand[0].type from the first def */ - u8 cls; /* operand[0].cls from the first def */ - u32 count; /* number of original ADDR_OF defs seen */ + PReg canonical; /* freshly allocated PReg, def in block 0 */ + CfreeCgTypeId addr_type; /* operand[0].type from the first def */ + u8 cls; /* operand[0].cls from the first def */ + u32 count; /* number of original ADDR_OF defs seen */ } AddrCseEntry; static u32 addr_cse_find_or_add(AddrCseEntry** entries, u32* n, u32* cap, @@ -1162,12 +1162,10 @@ static void addr_cse_apply_to_operand(Operand* op, const PReg* remap) { if (!op) return; if (op->kind == OPK_REG) { PReg p = (PReg)op->v.reg; - if (p != PREG_NONE && p != 0 && remap[p] != 0) - op->v.reg = remap[p]; + if (p != PREG_NONE && p != 0 && remap[p] != 0) op->v.reg = remap[p]; } else if (op->kind == OPK_INDIRECT) { PReg p = (PReg)op->v.ind.base; - if (p != PREG_NONE && p != 0 && remap[p] != 0) - op->v.ind.base = remap[p]; + if (p != PREG_NONE && p != 0 && remap[p] != 0) op->v.ind.base = remap[p]; if (op->v.ind.index != (Reg)REG_NONE) { PReg pi = (PReg)op->v.ind.index; if (pi != PREG_NONE && pi != 0 && remap[pi] != 0) @@ -1233,8 +1231,7 @@ static Inst* block_insert_at(Func* f, Block* bl, u32 at, u32 k) { Inst* nb = arena_zarray(f->arena, Inst, ncap); if (bl->insts && at) memcpy(nb, bl->insts, sizeof(Inst) * at); if (bl->insts && bl->ninsts > at) - memcpy(nb + at + k, bl->insts + at, - sizeof(Inst) * (bl->ninsts - at)); + memcpy(nb + at + k, bl->insts + at, sizeof(Inst) * (bl->ninsts - at)); bl->insts = nb; bl->cap = ncap; } else { @@ -1280,8 +1277,8 @@ void opt_addr_of_global_cse(Func* f) { u32 dup_count = 0; for (u32 i = 0; i < n_entries; ++i) { if (entries[i].count >= 2) { - entries[i].canonical = ir_alloc_preg(f, entries[i].addr_type, - entries[i].cls); + entries[i].canonical = + ir_alloc_preg(f, entries[i].addr_type, entries[i].cls); ++dup_count; } } @@ -1435,8 +1432,7 @@ static int gvn_fold_binop(Func* f, BinOp op, CfreeCgTypeId ty, i64 a, i64 b, return 1; } -static int gvn_fold_unop(Func* f, UnOp op, CfreeCgTypeId ty, i64 a, - i64* out) { +static int gvn_fold_unop(Func* f, UnOp op, CfreeCgTypeId ty, i64 a, i64* out) { u32 width; u64 ua, r; if (!gvn_int_like_width(f, ty, &width)) return 0; @@ -1555,16 +1551,15 @@ static int gvn_const_for_operand(GvnCtx* ctx, const Operand* op, i64* out) { } if (op->kind != OPK_REG) return 0; Val v = gvn_find(ctx, (Val)op->v.reg); - if (v == VAL_NONE || v >= ctx->f->nvals || !ctx->constants[v].valid) - return 0; + if (v == VAL_NONE || v >= ctx->f->nvals || !ctx->constants[v].valid) return 0; *out = ctx->constants[v].value; return 1; } static void gvn_make_load_imm(Func* f, Inst* in, i64 value) { Val dst = in->def; - CfreeCgTypeId ty = dst != VAL_NONE && dst < f->nvals ? f->val_type[dst] - : in->type; + CfreeCgTypeId ty = + dst != VAL_NONE && dst < f->nvals ? f->val_type[dst] : in->type; u8 cls = dst != VAL_NONE && dst < f->nvals ? f->val_cls[dst] : RC_INT; Operand* opnds = in->opnds; if (!opnds) opnds = arena_array(f->arena, Operand, 1); @@ -1659,7 +1654,7 @@ static u64 gvn_key_hash(const GvnKey* k) { h = gvn_mix_u64(h, k->ops[i].v.ind.log2_scale); } else { h = gvn_mix_u64(h, k->ops[i].kind == OPK_REG ? k->ops[i].v.reg - : (u64)k->ops[i].v.imm); + : (u64)k->ops[i].v.imm); } } return h; @@ -1669,8 +1664,7 @@ static int gvn_operand_key_equal(const GvnOperandKey* a, const GvnOperandKey* b) { if (a->kind != b->kind || a->cls != b->cls || a->type != b->type) return 0; if (a->kind == OPK_INDIRECT) - return a->v.ind.base == b->v.ind.base && - a->v.ind.index == b->v.ind.index && + return a->v.ind.base == b->v.ind.base && a->v.ind.index == b->v.ind.index && a->v.ind.ofs == b->v.ind.ofs && a->v.ind.log2_scale == b->v.ind.log2_scale; if (a->kind == OPK_REG) return a->v.reg == b->v.reg; @@ -1685,10 +1679,10 @@ static int gvn_key_equal(const GvnKey* a, const GvnKey* b) { if (a->mem.valid && (a->mem.root_kind != b->mem.root_kind || a->mem.has_addr != b->mem.has_addr || - a->mem.addr_space != b->mem.addr_space || - a->mem.flags != b->mem.flags || a->mem.mem_type != b->mem.mem_type || - a->mem.size != b->mem.size || a->mem.align != b->mem.align || - a->mem.root_id != b->mem.root_id || a->mem.offset != b->mem.offset || + a->mem.addr_space != b->mem.addr_space || a->mem.flags != b->mem.flags || + a->mem.mem_type != b->mem.mem_type || a->mem.size != b->mem.size || + a->mem.align != b->mem.align || a->mem.root_id != b->mem.root_id || + a->mem.offset != b->mem.offset || a->mem.root_version != b->mem.root_version || a->mem.unknown_version != b->mem.unknown_version)) return 0; @@ -1710,8 +1704,7 @@ static void gvn_table_init(GvnTable* t, Func* f) { t->cap = 0; } -static void gvn_table_add(GvnTable* t, const GvnKey* key, Val v, u32 b, - u32 i) { +static void gvn_table_add(GvnTable* t, const GvnKey* key, Val v, u32 b, u32 i) { if (t->nentries == t->cap) { u32 ncap = t->cap ? t->cap * 2u : 32u; GvnEntry* entries = arena_array(t->f->arena, GvnEntry, ncap); @@ -1824,8 +1817,7 @@ static int gvn_make_addr_operand_key(GvnCtx* ctx, const Operand* op, static int gvn_mem_root_from_addr_val(GvnCtx* ctx, Val addr_val, u32 depth, u8* kind_out, i64* id_out, - i64* offset_out, - int* singleton_out) { + i64* offset_out, int* singleton_out) { Inst* def = NULL; if (!ctx || depth > 4u) return 0; addr_val = gvn_find(ctx, addr_val); @@ -1852,8 +1844,8 @@ static int gvn_mem_root_from_addr_val(GvnCtx* ctx, Val addr_val, u32 depth, if ((IROp)def->op == IR_COPY && def->nopnds >= 2 && def->opnds[1].kind == OPK_REG) { - return gvn_mem_root_from_addr_val(ctx, (Val)def->opnds[1].v.reg, - depth + 1u, kind_out, id_out, offset_out, + return gvn_mem_root_from_addr_val(ctx, (Val)def->opnds[1].v.reg, depth + 1u, + kind_out, id_out, offset_out, singleton_out); } @@ -1878,9 +1870,9 @@ static int gvn_mem_root_from_addr_val(GvnCtx* ctx, Val addr_val, u32 depth, } static int gvn_mem_root_from_access(GvnCtx* ctx, const Operand* addr, - const MemAccess* mem, - u8* kind_out, i64* id_out, - i64* offset_out, int* singleton_out) { + const MemAccess* mem, u8* kind_out, + i64* id_out, i64* offset_out, + int* singleton_out) { u8 kind = ALIAS_UNKNOWN; i64 id = 0; i64 offset = 0; @@ -1997,13 +1989,15 @@ static void gvn_mem_state_copy(GvnCtx* ctx, GvnMemState* dst, } static int gvn_mem_key_tracks_unknown(GvnCtx* ctx, u8 kind, i64 root_id) { - if (kind == ALIAS_LOCAL && root_id > 0 && (u32)root_id <= ctx->f->nframe_slots) + if (kind == ALIAS_LOCAL && root_id > 0 && + (u32)root_id <= ctx->f->nframe_slots) return ctx->local_escaped && ctx->local_escaped[root_id]; return kind != ALIAS_STRING; } static int gvn_mem_call_clobbers_root(GvnCtx* ctx, u8 kind, i64 root_id) { - if (kind == ALIAS_LOCAL && root_id > 0 && (u32)root_id <= ctx->f->nframe_slots) + if (kind == ALIAS_LOCAL && root_id > 0 && + (u32)root_id <= ctx->f->nframe_slots) return !ctx->local_escaped || ctx->local_escaped[root_id]; return kind != ALIAS_STRING; } @@ -2072,8 +2066,7 @@ static void gvn_mem_call_barrier(GvnCtx* ctx) { ++ctx->mem.unknown_version; for (u32 i = 0; i < ctx->mem.nroots; ++i) { GvnMemVersion* r = &ctx->mem.roots[i]; - if (gvn_mem_call_clobbers_root(ctx, r->root_kind, r->root_id)) - ++r->version; + if (gvn_mem_call_clobbers_root(ctx, r->root_kind, r->root_id)) ++r->version; } gvn_mem_avail_remove_call_clobbered(ctx); } @@ -2088,8 +2081,7 @@ static void gvn_mem_bump_store(GvnCtx* ctx, u8 kind, u16 addr_space, } static int gvn_make_memory_key(GvnCtx* ctx, const Inst* in, u32 addr_idx, - CfreeCgTypeId val_ty, u8 val_cls, - GvnKey* key) { + CfreeCgTypeId val_ty, u8 val_cls, GvnKey* key) { const MemAccess* mem; const Operand* addr; u8 root_kind; @@ -2138,8 +2130,7 @@ static int gvn_operand_key_less(const GvnOperandKey* a, if (a->type != b->type) return a->type < b->type; if (a->cls != b->cls) return a->cls < b->cls; if (a->kind == OPK_INDIRECT) { - if (a->v.ind.base != b->v.ind.base) - return a->v.ind.base < b->v.ind.base; + if (a->v.ind.base != b->v.ind.base) return a->v.ind.base < b->v.ind.base; if (a->v.ind.index != b->v.ind.index) return a->v.ind.index < b->v.ind.index; if (a->v.ind.ofs != b->v.ind.ofs) return a->v.ind.ofs < b->v.ind.ofs; @@ -2449,8 +2440,7 @@ static int gvn_raw_operand_zero(Func* f, const Operand* op) { return 0; } -static int gvn_raw_local_addr_root(Func* f, Val v, u32 depth, - FrameSlot* out) { +static int gvn_raw_local_addr_root(Func* f, Val v, u32 depth, FrameSlot* out) { Inst* def = NULL; if (!f || depth > 4u || v == VAL_NONE) return 0; if (!val_def_inst(f, v, &def) || !def) return 0; @@ -2467,17 +2457,17 @@ static int gvn_raw_local_addr_root(Func* f, Val v, u32 depth, if ((BinOp)def->extra.imm == BO_IADD) { if (def->opnds[1].kind == OPK_REG && gvn_raw_operand_zero(f, &def->opnds[2])) - return gvn_raw_local_addr_root(f, (Val)def->opnds[1].v.reg, - depth + 1u, out); + return gvn_raw_local_addr_root(f, (Val)def->opnds[1].v.reg, depth + 1u, + out); if (def->opnds[2].kind == OPK_REG && gvn_raw_operand_zero(f, &def->opnds[1])) - return gvn_raw_local_addr_root(f, (Val)def->opnds[2].v.reg, - depth + 1u, out); + return gvn_raw_local_addr_root(f, (Val)def->opnds[2].v.reg, depth + 1u, + out); } if ((BinOp)def->extra.imm == BO_ISUB && def->opnds[1].kind == OPK_REG && gvn_raw_operand_zero(f, &def->opnds[2])) - return gvn_raw_local_addr_root(f, (Val)def->opnds[1].v.reg, - depth + 1u, out); + return gvn_raw_local_addr_root(f, (Val)def->opnds[1].v.reg, depth + 1u, + out); } return 0; } @@ -2733,9 +2723,8 @@ static int dse_make_key(DseCtx* ctx, const Inst* in, u32 addr_idx, opt_mem_observable(&in->extra.mem)) return 0; if (in->extra.mem.size == 0) return 0; - if (!gvn_mem_root_from_access(&ctx->gvn, &in->opnds[addr_idx], - &in->extra.mem, &root_kind, &root_id, &offset, - &singleton)) + if (!gvn_mem_root_from_access(&ctx->gvn, &in->opnds[addr_idx], &in->extra.mem, + &root_kind, &root_id, &offset, &singleton)) return 0; if (!singleton || root_kind == ALIAS_UNKNOWN) return 0; @@ -3068,8 +3057,8 @@ static void licm_mark_body(Func* f, const u8* reachable, u32 header, u32 latch, static u32 licm_collect_loops(Func* f, OptAnalysis* a, LicmLoop** out) { u32 nloops = 0; - LicmLoop* loops = arena_zarray(f->arena, LicmLoop, f->nblocks ? f->nblocks - : 1u); + LicmLoop* loops = + arena_zarray(f->arena, LicmLoop, f->nblocks ? f->nblocks : 1u); u8* scratch = arena_zarray(f->arena, u8, f->nblocks ? f->nblocks : 1u); u32* stack = arena_array(f->arena, u32, f->nblocks ? f->nblocks : 1u); @@ -3215,7 +3204,8 @@ static u32 licm_preheader_insert_pos(Func* f, u32 preheader) { return bl->ninsts; } -static void licm_hoist_inst(Func* f, const LicmLoop* loop, u32 block, u32 inst) { +static void licm_hoist_inst(Func* f, const LicmLoop* loop, u32 block, + u32 inst) { Inst moved = f->blocks[block].insts[inst]; u32 at = licm_preheader_insert_pos(f, loop->preheader); licm_insert_inst(f, loop->preheader, at, moved); @@ -3343,8 +3333,8 @@ static int pressure_can_move_within_block(Func* f, u32 b, u32 from, u32 to) { static PressureBlockPlan* pressure_block_plan(Func* f, PressurePlan* plan, u32 b) { if (!plan->blocks) - plan->blocks = arena_zarray(f->arena, PressureBlockPlan, - f->nblocks ? f->nblocks : 1u); + plan->blocks = + arena_zarray(f->arena, PressureBlockPlan, f->nblocks ? f->nblocks : 1u); PressureBlockPlan* bp = &plan->blocks[b]; if (!bp->move_src) { Block* bl = &f->blocks[b]; diff --git a/src/opt/pass_simplify.c b/src/opt/pass_simplify.c @@ -1,6 +1,5 @@ -#include <string.h> - #include <cfree/cg.h> +#include <string.h> #include "opt/opt_internal.h" @@ -131,8 +130,7 @@ static int convert_noop(Func* f, const Inst* in) { } static int simplify_binop(Func* f, Inst* in, int ssa) { - if (!in || (IROp)in->op != IR_BINOP || in->flags || in->nopnds < 3) - return 0; + if (!in || (IROp)in->op != IR_BINOP || in->flags || in->nopnds < 3) return 0; if (in->opnds[0].kind != OPK_REG) return 0; u32 width = simplify_width(f, in->type ? in->type : in->opnds[0].type); if (!width) return 0; diff --git a/src/opt/pass_ssa.c b/src/opt/pass_ssa.c @@ -118,8 +118,7 @@ static int aux_has_slot(const Inst* in, u32 slot_id) { return 0; } -static int slot_access_promotable(const Func* f, const Inst* in, - u32 slot_id) { +static int slot_access_promotable(const Func* f, const Inst* in, u32 slot_id) { if ((IROp)in->op == IR_LOAD) { if (in->nopnds < 2 || opnd_slot_id(&in->opnds[1]) != slot_id) return 1; if (in->opnds[0].kind != OPK_REG || opt_mem_observable(&in->extra.mem)) @@ -138,8 +137,7 @@ static int slot_access_promotable(const Func* f, const Inst* in, if ((IROp)in->op == IR_STORE) { if (in->nopnds < 2 || opnd_slot_id(&in->opnds[0]) != slot_id) return 1; if (opt_mem_observable(&in->extra.mem)) return 0; - if (in->opnds[1].kind != OPK_REG && in->opnds[1].kind != OPK_IMM) - return 0; + if (in->opnds[1].kind != OPK_REG && in->opnds[1].kind != OPK_IMM) return 0; const IRFrameSlot* s = &f->frame_slots[slot_id - 1u]; CfreeCgTypeId at = in->extra.mem.type; if (at && at != s->type) return 0; @@ -204,8 +202,7 @@ static u8* find_reg_def_blocks(Func* f, u32 old_nregs) { def_blocks[in->def * f->nblocks + b] = 1; for (u32 d = 0; d < in->ndefs; ++d) { Val v = in->defs[d]; - if (v != VAL_NONE && v < old_nregs) - def_blocks[v * f->nblocks + b] = 1; + if (v != VAL_NONE && v < old_nregs) def_blocks[v * f->nblocks + b] = 1; } } } @@ -234,8 +231,7 @@ static void compute_reg_phi_sites(Func* f, OptAnalysis* a, for (u32 i = 0; i < df->n; ++i) { u32 y = df->items[i]; if (needs_phi[r * f->nblocks + y]) continue; - if (live && !opt_bitset_has(&live->blocks[y].live_in, (Val)r)) - continue; + if (live && !opt_bitset_has(&live->blocks[y].live_in, (Val)r)) continue; needs_phi[r * f->nblocks + y] = 1; if (!queued[y]) { queued[y] = 1; @@ -446,8 +442,7 @@ static void reg_define_inst_defs(RegRenameCtx* ctx, u32 b, u32 i, Inst* in, for (u32 o = 0; o < aux->nout; ++o) { if (aux->out_ops[o].kind != OPK_REG) continue; reg_define_operand(ctx, b, i, in, &aux->out_ops[o], - reg_def_index(in, aux->out_ops[o].v.reg, o), - pushed); + reg_def_index(in, aux->out_ops[o].v.reg, o), pushed); } break; } diff --git a/src/os/linux/linux.c b/src/os/linux/linux.c @@ -85,9 +85,9 @@ static LinuxThreadState* linux_thread_state(EmuThread* thread) { } static u64 linux_rd64(const u8* p) { - return (u64)p[0] | ((u64)p[1] << 8) | ((u64)p[2] << 16) | - ((u64)p[3] << 24) | ((u64)p[4] << 32) | ((u64)p[5] << 40) | - ((u64)p[6] << 48) | ((u64)p[7] << 56); + return (u64)p[0] | ((u64)p[1] << 8) | ((u64)p[2] << 16) | ((u64)p[3] << 24) | + ((u64)p[4] << 32) | ((u64)p[5] << 40) | ((u64)p[6] << 48) | + ((u64)p[7] << 56); } static void linux_wr64(u8* p, u64 v) { @@ -227,11 +227,11 @@ static CfreeStatus linux_init_process(Compiler* c, EmuProcess* process, stack_base = stack_guard_base + img->addr_space.page_size; stack_top = stack_base + EMU_LINUX_STACK_SIZE; if (emu_addr_space_map(&img->addr_space, stack_guard_base, - img->addr_space.page_size, 0, EMU_MAP_GUARD) != - CFREE_OK || + img->addr_space.page_size, 0, + EMU_MAP_GUARD) != CFREE_OK || emu_addr_space_map(&img->addr_space, stack_base, EMU_LINUX_STACK_SIZE, - EMU_MEM_READ | EMU_MEM_WRITE, EMU_MAP_ANON) != - CFREE_OK) + EMU_MEM_READ | EMU_MEM_WRITE, + EMU_MAP_ANON) != CFREE_OK) return CFREE_ERR; if (opts->argv) { @@ -256,8 +256,8 @@ static CfreeStatus linux_init_process(Compiler* c, EmuProcess* process, for (i = 0; i < (u32)argc; ++i) { size_t slen = slice_from_cstr(opts->argv[i]).len + 1u; cursor -= slen; - if (emu_addr_space_copy_in(&img->addr_space, cursor, opts->argv[i], - slen) != CFREE_OK) { + if (emu_addr_space_copy_in(&img->addr_space, cursor, opts->argv[i], slen) != + CFREE_OK) { linux_free_stack_lists(heap, argv_addrs, argc, envp_addrs, envc); return CFREE_INVALID; } @@ -266,8 +266,8 @@ static CfreeStatus linux_init_process(Compiler* c, EmuProcess* process, for (i = 0; i < (u32)envc; ++i) { size_t slen = slice_from_cstr(opts->envp[i]).len + 1u; cursor -= slen; - if (emu_addr_space_copy_in(&img->addr_space, cursor, opts->envp[i], - slen) != CFREE_OK) { + if (emu_addr_space_copy_in(&img->addr_space, cursor, opts->envp[i], slen) != + CFREE_OK) { linux_free_stack_lists(heap, argv_addrs, argc, envp_addrs, envc); return CFREE_INVALID; } @@ -301,8 +301,8 @@ static CfreeStatus linux_init_process(Compiler* c, EmuProcess* process, aux[6].type = AT_NULL_; aux[6].val = 0; - table_bytes = 8u + (u64)(argc + 1) * 8u + (u64)(envc + 1) * 8u + - (u64)aux_count * 16u; + table_bytes = + 8u + (u64)(argc + 1) * 8u + (u64)(envc + 1) * 8u + (u64)aux_count * 16u; sp = (cursor - table_bytes) & ~(u64)0xfu; tp = emu_addr_space_ptr(&img->addr_space, sp, table_bytes, EMU_MEM_WRITE); if (!tp) { @@ -339,9 +339,8 @@ static CfreeStatus linux_init_process(Compiler* c, EmuProcess* process, img->initial_sp = sp; if (emu_dl_init_process(c, process) != CFREE_OK) return CFREE_ERR; if (!process->obj_format || !process->obj_format->emu || - emu_dl_load_dependencies_and_relocate(c, process, opts, - process->obj_format->emu) != - CFREE_OK) + emu_dl_load_dependencies_and_relocate( + c, process, opts, process->obj_format->emu) != CFREE_OK) return CFREE_ERR; return CFREE_OK; } @@ -368,15 +367,15 @@ static CfreeStatus linux_init_thread(Compiler* c, EmuProcess* process, EMU_OS_MAP_TLS, &base) != CFREE_OK) return CFREE_ERR; if (emu_addr_space_map(&process->image.addr_space, base, nbytes, - EMU_MEM_READ | EMU_MEM_WRITE, EMU_MAP_ANON) != - CFREE_OK) + EMU_MEM_READ | EMU_MEM_WRITE, + EMU_MAP_ANON) != CFREE_OK) return CFREE_ERR; if (process->os->emu_note_map_region) process->os->emu_note_map_region(process, base, nbytes, EMU_OS_MAP_TLS); if (emu_tls_copy_module_image(process, m, base) != CFREE_OK) return CFREE_ERR; - if (emu_tls_blocks_add(c, &ts->tls_blocks, m->module_id, base, - m->memsz) != CFREE_OK) + if (emu_tls_blocks_add(c, &ts->tls_blocks, m->module_id, base, m->memsz) != + CFREE_OK) return CFREE_NOMEM; if (m->module_id == 1u) process->arch->emu->set_tp(thread, base); } @@ -384,9 +383,8 @@ static CfreeStatus linux_init_thread(Compiler* c, EmuProcess* process, } static CfreeStatus linux_deliver_signal(EmuProcess* process, EmuThread* thread, - int signo, u64 fault_addr, - u64 fault_pc, u64 next_pc, - u64* next_pc_out) { + int signo, u64 fault_addr, u64 fault_pc, + u64 next_pc, u64* next_pc_out) { EmuCPUState* cpu = emu_thread_cpu(thread); LinuxProcessState* ps; LinuxThreadState* ts; @@ -418,8 +416,7 @@ static CfreeStatus linux_deliver_signal(EmuProcess* process, EmuThread* thread, return CFREE_OK; } if (!process->arch || !process->arch->emu || !process->arch->emu->get_sp || - !process->arch->emu->set_sp || - !process->arch->emu->signal_context_size || + !process->arch->emu->set_sp || !process->arch->emu->signal_context_size || !process->arch->emu->save_signal_context || !process->arch->emu->set_signal_handler_args || !process->arch->emu->signal_stack_align) @@ -445,9 +442,9 @@ static CfreeStatus linux_deliver_signal(EmuProcess* process, EmuThread* thread, linux_wr64(frame + EMU_LINUX_SIGFRAME_SAVED_PC, fault_pc); linux_wr64(frame + EMU_LINUX_SIGFRAME_SIGINFO, (u64)signo); linux_wr64(frame + EMU_LINUX_SIGFRAME_SIGINFO + 16u, fault_addr); - if (process->arch->emu->save_signal_context( - process, thread, frame + EMU_LINUX_SIGFRAME_XREGS, ctx_size) != - CFREE_OK) + if (process->arch->emu->save_signal_context(process, thread, + frame + EMU_LINUX_SIGFRAME_XREGS, + ctx_size) != CFREE_OK) return CFREE_ERR; ts->signal_frame_sp = frame_sp; process->arch->emu->set_sp(thread, frame_sp); @@ -472,8 +469,7 @@ static CfreeStatus linux_deliver_fault(EmuProcess* process, EmuThread* thread, static CfreeStatus linux_decode_syscall(EmuProcess* process, EmuThread* thread, EmuSyscallRequest* out) { u32 i; - if (!process || !thread || !thread->cpu || !out) - return CFREE_INVALID; + if (!process || !thread || !thread->cpu || !out) return CFREE_INVALID; if (!process->arch || !process->arch->emu || !process->arch->emu->get_syscall_no || !process->arch->emu->get_syscall_arg) @@ -489,8 +485,7 @@ static CfreeStatus linux_encode_syscall_result(EmuProcess* process, EmuThread* thread, const EmuSyscallResult* r) { (void)process; - if (!process || !thread || !thread->cpu || !r) - return CFREE_INVALID; + if (!process || !thread || !thread->cpu || !r) return CFREE_INVALID; if (!process->arch || !process->arch->emu || !process->arch->emu->set_syscall_result) return CFREE_UNSUPPORTED; @@ -578,9 +573,9 @@ static CfreeStatus linux_default_syscall(void* user, EmuProcess* process, } map_at = addr; if (flags & LINUX_MAP_FIXED_NOREPLACE) { - st = emu_addr_space_map(as, map_at, length, linux_emu_perms(a2), - linux_emu_perms(a2) ? EMU_MAP_ANON - : EMU_MAP_GUARD); + st = emu_addr_space_map( + as, map_at, length, linux_emu_perms(a2), + linux_emu_perms(a2) ? EMU_MAP_ANON : EMU_MAP_GUARD); if (st == CFREE_OK) { if (process->os && process->os->emu_note_map_region) process->os->emu_note_map_region(process, map_at, length, @@ -593,14 +588,12 @@ static CfreeStatus linux_default_syscall(void* user, EmuProcess* process, } (void)emu_addr_space_unmap(as, map_at, length); } else { - u64 min_va = addr ? linux_round_up(addr, as->page_size) - : ps->mmap_hint; + u64 min_va = addr ? linux_round_up(addr, as->page_size) : ps->mmap_hint; if (addr) { st = emu_addr_space_find_gap(as, length, as->page_size, min_va, 0x0000800000000000ull, &map_at); } else if (process->os && process->os->emu_find_map_region) { - st = process->os->emu_find_map_region(process, length, - as->page_size, + st = process->os->emu_find_map_region(process, length, as->page_size, EMU_OS_MAP_MMAP, &map_at); } else { st = CFREE_UNSUPPORTED; @@ -610,9 +603,9 @@ static CfreeStatus linux_default_syscall(void* user, EmuProcess* process, break; } } - st = emu_addr_space_map(as, map_at, length, linux_emu_perms(a2), - linux_emu_perms(a2) ? EMU_MAP_ANON - : EMU_MAP_GUARD); + st = emu_addr_space_map( + as, map_at, length, linux_emu_perms(a2), + linux_emu_perms(a2) ? EMU_MAP_ANON : EMU_MAP_GUARD); if (st != CFREE_OK) { ret = -LINUX_ENOMEM; } else { @@ -716,8 +709,7 @@ static CfreeStatus linux_default_syscall(void* user, EmuProcess* process, u32 j; for (j = 0; j < 8u; ++j) handler |= ((u64)p[j]) << (8u * j); for (j = 0; j < 8u; ++j) flags |= ((u64)p[8u + j]) << (8u * j); - for (j = 0; j < 8u; ++j) - restorer |= ((u64)p[16u + j]) << (8u * j); + for (j = 0; j < 8u; ++j) restorer |= ((u64)p[16u + j]) << (8u * j); ps->signal_actions[a0].handler = handler; ps->signal_actions[a0].flags = flags; ps->signal_actions[a0].restorer = restorer; @@ -824,8 +816,7 @@ static u64 linux_syscall_next_pc(EmuProcess* process, EmuThread* thread, const EmuSyscallRequest* req, u64 next_pc) { EmuCPUState* s = emu_thread_cpu(thread); (void)process; - if (req && req->number == LINUX_SYS_rt_sigreturn && s) - return emu_cpu_pc(s); + if (req && req->number == LINUX_SYS_rt_sigreturn && s) return emu_cpu_pc(s); return next_pc; } diff --git a/src/wasm/decode.c b/src/wasm/decode.c @@ -125,7 +125,7 @@ static WasmValType bin_val_type(BinReader* r, int refs_ok) { } void wasm_decode_binary(CfreeCompiler* c, const CfreeSlice* input, - WasmModule* out) { + WasmModule* out) { BinReader r; uint32_t nfunc_types = 0; uint8_t last_id = 0; @@ -154,11 +154,12 @@ void wasm_decode_binary(CfreeCompiler* c, const CfreeSlice* input, "wasm: relocatable object metadata is not frontend input"); { WasmCustom* cs = wasm_add_custom(c, out); - cs->name = wasm_strdup(out->heap, (const char*)(r.data + r.pos), - name_len); + cs->name = + wasm_strdup(out->heap, (const char*)(r.data + r.pos), name_len); if (!cs->name) wasm_error(c, wasm_loc(0, 0), "wasm: out of memory"); r.pos += name_len; - if (cfree_slice_eq_cstr(cfree_slice_cstr(cs->name), "target_features") || + if (cfree_slice_eq_cstr(cfree_slice_cstr(cs->name), + "target_features") || cfree_slice_eq_cstr(cfree_slice_cstr(cs->name), "target-feature")) out->has_target_features = 1; cs->len = (uint32_t)(end - r.pos); @@ -395,8 +396,7 @@ void wasm_decode_binary(CfreeCompiler* c, const CfreeSlice* input, if (bin_u8(&r) != 0x0b || e->offset < 0) wasm_error(c, wasm_loc(0, 0), "wasm: bad element offset"); if (bin_u8(&r) != 0x00) - wasm_error(c, wasm_loc(0, 0), - "wasm: unsupported element kind"); + wasm_error(c, wasm_loc(0, 0), "wasm: unsupported element kind"); } else if (flags == 3u) { e->mode = WASM_SEG_DECLARATIVE; if (bin_u8(&r) != 0x00) @@ -433,8 +433,7 @@ void wasm_decode_binary(CfreeCompiler* c, const CfreeSlice* input, for (j = 0; j < local_groups; ++j) { uint32_t k, nlocals = bin_uleb(&r); WasmValType vt = bin_val_type(&r, 1); - for (k = 0; k < nlocals; ++k) - wasm_func_push_local(c, out, f, vt); + for (k = 0; k < nlocals; ++k) wasm_func_push_local(c, out, f, vt); } while (r.pos < body_end) { uint8_t op = bin_u8(&r); @@ -506,75 +505,163 @@ void wasm_decode_binary(CfreeCompiler* c, const CfreeSlice* input, case 0x1b: wasm_func_add_insn(c, out, f, WASM_INSN_SELECT, 0); break; - case 0x28: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_I32_LOAD, ma, mo, mi); } - break; - case 0x29: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_LOAD, ma, mo, mi); } - break; - case 0x2a: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_F32_LOAD, ma, mo, mi); } - break; - case 0x2b: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_F64_LOAD, ma, mo, mi); } - break; - case 0x2c: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_I32_LOAD8_S, ma, mo, mi); } - break; - case 0x2d: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_I32_LOAD8_U, ma, mo, mi); } - break; - case 0x2e: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_I32_LOAD16_S, ma, mo, mi); } - break; - case 0x2f: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_I32_LOAD16_U, ma, mo, mi); } - break; - case 0x30: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_LOAD8_S, ma, mo, mi); } - break; - case 0x31: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_LOAD8_U, ma, mo, mi); } - break; - case 0x32: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_LOAD16_S, ma, mo, mi); } - break; - case 0x33: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_LOAD16_U, ma, mo, mi); } - break; - case 0x34: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_LOAD32_S, ma, mo, mi); } - break; - case 0x35: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_LOAD32_U, ma, mo, mi); } - break; - case 0x36: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_I32_STORE, ma, mo, mi); } - break; - case 0x37: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_STORE, ma, mo, mi); } - break; - case 0x38: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_F32_STORE, ma, mo, mi); } - break; - case 0x39: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_F64_STORE, ma, mo, mi); } - break; - case 0x3a: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_I32_STORE8, ma, mo, mi); } - break; - case 0x3b: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_I32_STORE16, ma, mo, mi); } - break; - case 0x3c: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_STORE8, ma, mo, mi); } - break; - case 0x3d: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_STORE16, ma, mo, mi); } - break; - case 0x3e: - { uint32_t ma, mi; uint64_t mo; bin_memarg(&r, &ma, &mo, &mi); wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_STORE32, ma, mo, mi); } - break; + case 0x28: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I32_LOAD, ma, mo, mi); + } break; + case 0x29: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_LOAD, ma, mo, mi); + } break; + case 0x2a: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_F32_LOAD, ma, mo, mi); + } break; + case 0x2b: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_F64_LOAD, ma, mo, mi); + } break; + case 0x2c: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I32_LOAD8_S, ma, mo, + mi); + } break; + case 0x2d: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I32_LOAD8_U, ma, mo, + mi); + } break; + case 0x2e: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I32_LOAD16_S, ma, mo, + mi); + } break; + case 0x2f: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I32_LOAD16_U, ma, mo, + mi); + } break; + case 0x30: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_LOAD8_S, ma, mo, + mi); + } break; + case 0x31: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_LOAD8_U, ma, mo, + mi); + } break; + case 0x32: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_LOAD16_S, ma, mo, + mi); + } break; + case 0x33: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_LOAD16_U, ma, mo, + mi); + } break; + case 0x34: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_LOAD32_S, ma, mo, + mi); + } break; + case 0x35: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_LOAD32_U, ma, mo, + mi); + } break; + case 0x36: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I32_STORE, ma, mo, + mi); + } break; + case 0x37: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_STORE, ma, mo, + mi); + } break; + case 0x38: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_F32_STORE, ma, mo, + mi); + } break; + case 0x39: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_F64_STORE, ma, mo, + mi); + } break; + case 0x3a: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I32_STORE8, ma, mo, + mi); + } break; + case 0x3b: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I32_STORE16, ma, mo, + mi); + } break; + case 0x3c: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_STORE8, ma, mo, + mi); + } break; + case 0x3d: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_STORE16, ma, mo, + mi); + } break; + case 0x3e: { + uint32_t ma, mi; + uint64_t mo; + bin_memarg(&r, &ma, &mo, &mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_STORE32, ma, mo, + mi); + } break; case 0x3f: wasm_func_add_insn(c, out, f, WASM_INSN_MEMORY_SIZE, 0); f->insns[f->ninsns - 1u].memidx = bin_uleb(&r); @@ -607,8 +694,7 @@ void wasm_decode_binary(CfreeCompiler* c, const CfreeSlice* input, break; } case 0x14: - wasm_func_add_insn(c, out, f, WASM_INSN_CALL_REF, - bin_uleb(&r)); + wasm_func_add_insn(c, out, f, WASM_INSN_CALL_REF, bin_uleb(&r)); break; case 0x15: wasm_func_add_insn(c, out, f, WASM_INSN_RETURN_CALL_REF, @@ -653,8 +739,7 @@ void wasm_decode_binary(CfreeCompiler* c, const CfreeSlice* input, wasm_func_add_insn(c, out, f, WASM_INSN_REF_IS_NULL, 0); break; case 0xd2: - wasm_func_add_insn(c, out, f, WASM_INSN_REF_FUNC, - bin_uleb(&r)); + wasm_func_add_insn(c, out, f, WASM_INSN_REF_FUNC, bin_uleb(&r)); break; case 0x45: wasm_func_add_insn(c, out, f, WASM_INSN_I32_EQZ, 0); @@ -969,36 +1054,36 @@ void wasm_decode_binary(CfreeCompiler* c, const CfreeSlice* input, uint32_t sub = bin_uleb(&r); switch (sub) { case 0x00: - wasm_func_add_insn(c, out, f, - WASM_INSN_I32_TRUNC_SAT_F32_S, 0); + wasm_func_add_insn(c, out, f, WASM_INSN_I32_TRUNC_SAT_F32_S, + 0); break; case 0x01: - wasm_func_add_insn(c, out, f, - WASM_INSN_I32_TRUNC_SAT_F32_U, 0); + wasm_func_add_insn(c, out, f, WASM_INSN_I32_TRUNC_SAT_F32_U, + 0); break; case 0x02: - wasm_func_add_insn(c, out, f, - WASM_INSN_I32_TRUNC_SAT_F64_S, 0); + wasm_func_add_insn(c, out, f, WASM_INSN_I32_TRUNC_SAT_F64_S, + 0); break; case 0x03: - wasm_func_add_insn(c, out, f, - WASM_INSN_I32_TRUNC_SAT_F64_U, 0); + wasm_func_add_insn(c, out, f, WASM_INSN_I32_TRUNC_SAT_F64_U, + 0); break; case 0x04: - wasm_func_add_insn(c, out, f, - WASM_INSN_I64_TRUNC_SAT_F32_S, 0); + wasm_func_add_insn(c, out, f, WASM_INSN_I64_TRUNC_SAT_F32_S, + 0); break; case 0x05: - wasm_func_add_insn(c, out, f, - WASM_INSN_I64_TRUNC_SAT_F32_U, 0); + wasm_func_add_insn(c, out, f, WASM_INSN_I64_TRUNC_SAT_F32_U, + 0); break; case 0x06: - wasm_func_add_insn(c, out, f, - WASM_INSN_I64_TRUNC_SAT_F64_S, 0); + wasm_func_add_insn(c, out, f, WASM_INSN_I64_TRUNC_SAT_F64_S, + 0); break; case 0x07: - wasm_func_add_insn(c, out, f, - WASM_INSN_I64_TRUNC_SAT_F64_U, 0); + wasm_func_add_insn(c, out, f, WASM_INSN_I64_TRUNC_SAT_F64_U, + 0); break; case 0x08: { /* memory.init dataidx memidx */ uint32_t dataidx = bin_uleb(&r); @@ -1081,9 +1166,8 @@ void wasm_decode_binary(CfreeCompiler* c, const CfreeSlice* input, switch (sub) { case 0x00: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_MEMORY_ATOMIC_NOTIFY, ma, - mo, mi); + wasm_func_add_mem_insn( + c, out, f, WASM_INSN_MEMORY_ATOMIC_NOTIFY, ma, mo, mi); break; case 0x01: bin_memarg(&r, &ma, &mo, &mi); @@ -1112,33 +1196,28 @@ void wasm_decode_binary(CfreeCompiler* c, const CfreeSlice* input, break; case 0x12: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I32_ATOMIC_LOAD8_U, ma, mo, - mi); + wasm_func_add_mem_insn( + c, out, f, WASM_INSN_I32_ATOMIC_LOAD8_U, ma, mo, mi); break; case 0x13: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I32_ATOMIC_LOAD16_U, ma, mo, - mi); + wasm_func_add_mem_insn( + c, out, f, WASM_INSN_I32_ATOMIC_LOAD16_U, ma, mo, mi); break; case 0x14: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I64_ATOMIC_LOAD8_U, ma, mo, - mi); + wasm_func_add_mem_insn( + c, out, f, WASM_INSN_I64_ATOMIC_LOAD8_U, ma, mo, mi); break; case 0x15: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I64_ATOMIC_LOAD16_U, ma, mo, - mi); + wasm_func_add_mem_insn( + c, out, f, WASM_INSN_I64_ATOMIC_LOAD16_U, ma, mo, mi); break; case 0x16: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I64_ATOMIC_LOAD32_U, ma, mo, - mi); + wasm_func_add_mem_insn( + c, out, f, WASM_INSN_I64_ATOMIC_LOAD32_U, ma, mo, mi); break; case 0x17: bin_memarg(&r, &ma, &mo, &mi); @@ -1152,117 +1231,98 @@ void wasm_decode_binary(CfreeCompiler* c, const CfreeSlice* input, break; case 0x19: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I32_ATOMIC_STORE8, ma, mo, - mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I32_ATOMIC_STORE8, + ma, mo, mi); break; case 0x1a: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I32_ATOMIC_STORE16, ma, mo, - mi); + wasm_func_add_mem_insn( + c, out, f, WASM_INSN_I32_ATOMIC_STORE16, ma, mo, mi); break; case 0x1b: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I64_ATOMIC_STORE8, ma, mo, - mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_ATOMIC_STORE8, + ma, mo, mi); break; case 0x1c: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I64_ATOMIC_STORE16, ma, mo, - mi); + wasm_func_add_mem_insn( + c, out, f, WASM_INSN_I64_ATOMIC_STORE16, ma, mo, mi); break; case 0x1d: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I64_ATOMIC_STORE32, ma, mo, - mi); + wasm_func_add_mem_insn( + c, out, f, WASM_INSN_I64_ATOMIC_STORE32, ma, mo, mi); break; case 0x1e: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I32_ATOMIC_RMW_ADD, ma, mo, - mi); + wasm_func_add_mem_insn( + c, out, f, WASM_INSN_I32_ATOMIC_RMW_ADD, ma, mo, mi); break; case 0x1f: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I64_ATOMIC_RMW_ADD, ma, mo, - mi); + wasm_func_add_mem_insn( + c, out, f, WASM_INSN_I64_ATOMIC_RMW_ADD, ma, mo, mi); break; case 0x25: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I32_ATOMIC_RMW_SUB, ma, mo, - mi); + wasm_func_add_mem_insn( + c, out, f, WASM_INSN_I32_ATOMIC_RMW_SUB, ma, mo, mi); break; case 0x26: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I64_ATOMIC_RMW_SUB, ma, mo, - mi); + wasm_func_add_mem_insn( + c, out, f, WASM_INSN_I64_ATOMIC_RMW_SUB, ma, mo, mi); break; case 0x2c: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I32_ATOMIC_RMW_AND, ma, mo, - mi); + wasm_func_add_mem_insn( + c, out, f, WASM_INSN_I32_ATOMIC_RMW_AND, ma, mo, mi); break; case 0x2d: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I64_ATOMIC_RMW_AND, ma, mo, - mi); + wasm_func_add_mem_insn( + c, out, f, WASM_INSN_I64_ATOMIC_RMW_AND, ma, mo, mi); break; case 0x33: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I32_ATOMIC_RMW_OR, ma, mo, - mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I32_ATOMIC_RMW_OR, + ma, mo, mi); break; case 0x34: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I64_ATOMIC_RMW_OR, ma, mo, - mi); + wasm_func_add_mem_insn(c, out, f, WASM_INSN_I64_ATOMIC_RMW_OR, + ma, mo, mi); break; case 0x3a: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I32_ATOMIC_RMW_XOR, ma, mo, - mi); + wasm_func_add_mem_insn( + c, out, f, WASM_INSN_I32_ATOMIC_RMW_XOR, ma, mo, mi); break; case 0x3b: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I64_ATOMIC_RMW_XOR, ma, mo, - mi); + wasm_func_add_mem_insn( + c, out, f, WASM_INSN_I64_ATOMIC_RMW_XOR, ma, mo, mi); break; case 0x41: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I32_ATOMIC_RMW_XCHG, ma, mo, - mi); + wasm_func_add_mem_insn( + c, out, f, WASM_INSN_I32_ATOMIC_RMW_XCHG, ma, mo, mi); break; case 0x42: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I64_ATOMIC_RMW_XCHG, ma, mo, - mi); + wasm_func_add_mem_insn( + c, out, f, WASM_INSN_I64_ATOMIC_RMW_XCHG, ma, mo, mi); break; case 0x48: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I32_ATOMIC_RMW_CMPXCHG, ma, - mo, mi); + wasm_func_add_mem_insn( + c, out, f, WASM_INSN_I32_ATOMIC_RMW_CMPXCHG, ma, mo, mi); break; case 0x49: bin_memarg(&r, &ma, &mo, &mi); - wasm_func_add_mem_insn(c, out, f, - WASM_INSN_I64_ATOMIC_RMW_CMPXCHG, ma, - mo, mi); + wasm_func_add_mem_insn( + c, out, f, WASM_INSN_I64_ATOMIC_RMW_CMPXCHG, ma, mo, mi); break; default: wasm_error(c, wasm_loc(0, 0), @@ -1295,8 +1355,7 @@ void wasm_decode_binary(CfreeCompiler* c, const CfreeSlice* input, else if (op == 0x42) d->offset = bin_sleb(&r, 64); else - wasm_error(c, wasm_loc(0, 0), - "wasm: expected const data offset"); + wasm_error(c, wasm_loc(0, 0), "wasm: expected const data offset"); } if (bin_u8(&r) != 0x0b || d->offset < 0) wasm_error(c, wasm_loc(0, 0), "wasm: bad data offset"); @@ -1312,8 +1371,7 @@ void wasm_decode_binary(CfreeCompiler* c, const CfreeSlice* input, else if (op == 0x42) d->offset = bin_sleb(&r, 64); else - wasm_error(c, wasm_loc(0, 0), - "wasm: expected const data offset"); + wasm_error(c, wasm_loc(0, 0), "wasm: expected const data offset"); } if (bin_u8(&r) != 0x0b || d->offset < 0) wasm_error(c, wasm_loc(0, 0), "wasm: bad data offset"); diff --git a/src/wasm/encode.c b/src/wasm/encode.c @@ -611,25 +611,44 @@ static uint32_t wasm_threads_subopcode(uint8_t kind) { /* 0xfc-prefixed sub-opcodes: non-trapping FTOI and bulk memory ops. */ static uint32_t wasm_misc_subopcode(uint8_t kind) { switch (kind) { - case WASM_INSN_I32_TRUNC_SAT_F32_S: return 0x00; - case WASM_INSN_I32_TRUNC_SAT_F32_U: return 0x01; - case WASM_INSN_I32_TRUNC_SAT_F64_S: return 0x02; - case WASM_INSN_I32_TRUNC_SAT_F64_U: return 0x03; - case WASM_INSN_I64_TRUNC_SAT_F32_S: return 0x04; - case WASM_INSN_I64_TRUNC_SAT_F32_U: return 0x05; - case WASM_INSN_I64_TRUNC_SAT_F64_S: return 0x06; - case WASM_INSN_I64_TRUNC_SAT_F64_U: return 0x07; - case WASM_INSN_MEMORY_INIT: return 0x08; - case WASM_INSN_DATA_DROP: return 0x09; - case WASM_INSN_MEMORY_COPY: return 0x0a; - case WASM_INSN_MEMORY_FILL: return 0x0b; - case WASM_INSN_TABLE_INIT: return 0x0c; - case WASM_INSN_ELEM_DROP: return 0x0d; - case WASM_INSN_TABLE_COPY: return 0x0e; - case WASM_INSN_TABLE_GROW: return 0x0f; - case WASM_INSN_TABLE_SIZE: return 0x10; - case WASM_INSN_TABLE_FILL: return 0x11; - default: return UINT32_MAX; + case WASM_INSN_I32_TRUNC_SAT_F32_S: + return 0x00; + case WASM_INSN_I32_TRUNC_SAT_F32_U: + return 0x01; + case WASM_INSN_I32_TRUNC_SAT_F64_S: + return 0x02; + case WASM_INSN_I32_TRUNC_SAT_F64_U: + return 0x03; + case WASM_INSN_I64_TRUNC_SAT_F32_S: + return 0x04; + case WASM_INSN_I64_TRUNC_SAT_F32_U: + return 0x05; + case WASM_INSN_I64_TRUNC_SAT_F64_S: + return 0x06; + case WASM_INSN_I64_TRUNC_SAT_F64_U: + return 0x07; + case WASM_INSN_MEMORY_INIT: + return 0x08; + case WASM_INSN_DATA_DROP: + return 0x09; + case WASM_INSN_MEMORY_COPY: + return 0x0a; + case WASM_INSN_MEMORY_FILL: + return 0x0b; + case WASM_INSN_TABLE_INIT: + return 0x0c; + case WASM_INSN_ELEM_DROP: + return 0x0d; + case WASM_INSN_TABLE_COPY: + return 0x0e; + case WASM_INSN_TABLE_GROW: + return 0x0f; + case WASM_INSN_TABLE_SIZE: + return 0x10; + case WASM_INSN_TABLE_FILL: + return 0x11; + default: + return UINT32_MAX; } } @@ -709,7 +728,7 @@ static void enc_code(CfreeWriter* w, const WasmModule* m) { } else if (in.kind == WASM_INSN_ATOMIC_FENCE) { write_byte(body, 0); } else if (in.kind == WASM_INSN_BLOCK || in.kind == WASM_INSN_LOOP || - in.kind == WASM_INSN_IF) + in.kind == WASM_INSN_IF) write_byte(body, 0x40); else if (in.kind == WASM_INSN_I32_CONST || in.kind == WASM_INSN_I64_CONST) write_sleb(body, in.imm); @@ -725,8 +744,7 @@ static void enc_code(CfreeWriter* w, const WasmModule* m) { in.kind == WASM_INSN_RETURN_CALL || in.kind == WASM_INSN_CALL_REF || in.kind == WASM_INSN_RETURN_CALL_REF || - in.kind == WASM_INSN_REF_NULL || - in.kind == WASM_INSN_REF_FUNC || + in.kind == WASM_INSN_REF_NULL || in.kind == WASM_INSN_REF_FUNC || in.kind == WASM_INSN_BR || in.kind == WASM_INSN_BR_IF) write_uleb(body, (uint64_t)in.imm); else if (in.kind == WASM_INSN_CALL_INDIRECT || @@ -786,7 +804,7 @@ static void enc_elem(CfreeWriter* w, const WasmModule* m) { const WasmElemSegment* e = &m->elems[i]; if (e->mode == WASM_SEG_PASSIVE) { write_uleb(w, 1u); - write_byte(w, 0x00); /* elemkind: funcref */ + write_byte(w, 0x00); /* elemkind: funcref */ } else if (e->mode == WASM_SEG_DECLARATIVE) { write_uleb(w, 3u); write_byte(w, 0x00); @@ -828,8 +846,7 @@ static void encode_custom(CfreeHeap* h, CfreeWriter* out, const WasmModule* m, cfree_writer_close(tmp); } -void wasm_encode(CfreeCompiler* c, const WasmModule* m, - CfreeWriter* out) { +void wasm_encode(CfreeCompiler* c, const WasmModule* m, CfreeWriter* out) { static const uint8_t magic[] = {0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00}; CfreeHeap* h = cfree_compiler_context(c)->heap; diff --git a/src/wasm/insn.c b/src/wasm/insn.c @@ -18,9 +18,8 @@ int wasm_feature_enabled(const WasmModule* m, WasmFeatureSet feature) { } void wasm_require_feature_at(CfreeCompiler* c, const WasmModule* m, - WasmFeatureSet feature, - const char* feature_name, const char* what, - CfreeSrcLoc loc) { + WasmFeatureSet feature, const char* feature_name, + const char* what, CfreeSrcLoc loc) { if (!wasm_feature_enabled(m, feature)) wasm_error(c, loc, "wasm: %s requires %s", what, feature_name); } @@ -31,7 +30,6 @@ void wasm_require_feature(CfreeCompiler* c, const WasmModule* m, wasm_require_feature_at(c, m, feature, feature_name, what, wasm_loc(0, 0)); } - int wasm_insn_is_load(WasmInsnKind kind) { return kind == WASM_INSN_I32_LOAD || kind == WASM_INSN_I64_LOAD || kind == WASM_INSN_F32_LOAD || kind == WASM_INSN_F64_LOAD || @@ -162,7 +160,6 @@ uint32_t wasm_mem_width(uint8_t kind) { } } - int wasm_int_cmp_op(uint8_t kind, CfreeCgIntCmpOp* out) { switch (kind) { case WASM_INSN_I32_EQ: @@ -343,8 +340,7 @@ int wasm_fp_cmp_kind(uint8_t kind, WasmValType* vt) { return 0; } -int wasm_conversion_kind(uint8_t kind, WasmValType* src, - WasmValType* dst) { +int wasm_conversion_kind(uint8_t kind, WasmValType* src, WasmValType* dst) { switch (kind) { case WASM_INSN_I32_WRAP_I64: *src = WASM_VAL_I64; diff --git a/src/wasm/module.c b/src/wasm/module.c @@ -8,8 +8,7 @@ CfreeSrcLoc wasm_loc(uint32_t line, uint32_t col) { return loc; } -void wasm_error(CfreeCompiler* c, CfreeSrcLoc loc, const char* fmt, - ...) { +void wasm_error(CfreeCompiler* c, CfreeSrcLoc loc, const char* fmt, ...) { va_list ap; va_start(ap, fmt); cfree_frontend_vfatal(c, loc, fmt, ap); @@ -90,8 +89,7 @@ void wasm_module_free(WasmModule* m) { if (m->data[i].bytes) m->heap->free(m->heap, m->data[i].bytes, (size_t)m->data[i].nbytes); } - if (m->data) - m->heap->free(m->heap, m->data, sizeof(*m->data) * m->cap_data); + if (m->data) m->heap->free(m->heap, m->data, sizeof(*m->data) * m->cap_data); for (i = 0; i < m->nelems; ++i) { wasm_free_str(m->heap, &m->elems[i].name); if (m->elems[i].funcs) @@ -132,10 +130,9 @@ WasmMemory* wasm_add_memory(CfreeCompiler* c, WasmModule* m) { WasmMemory* mem; if (m->nmemories == m->cap_memories) { uint32_t new_cap = m->cap_memories ? m->cap_memories * 2u : 2u; - void* p = - wasm_realloc(m->heap, m->memories, - sizeof(*m->memories) * m->cap_memories, - sizeof(*m->memories) * new_cap); + void* p = wasm_realloc(m->heap, m->memories, + sizeof(*m->memories) * m->cap_memories, + sizeof(*m->memories) * new_cap); if (!p) wasm_error(c, wasm_loc(0, 0), "wasm: out of memory"); m->memories = (WasmMemory*)p; memset(m->memories + m->cap_memories, 0, @@ -246,14 +243,13 @@ uint32_t wasm_type_push_param(CfreeCompiler* c, WasmModule* m, WasmFuncType* t, } uint32_t wasm_intern_func_type(CfreeCompiler* c, WasmModule* m, - const WasmFunc* f) { + const WasmFunc* f) { uint32_t i; for (i = 0; i < m->ntypes; ++i) { WasmFuncType* t = &m->types[i]; if (t->nparams == f->nparams && t->nresults == f->nresults && - (t->nparams == 0 || - memcmp(t->params, f->params, sizeof(t->params[0]) * t->nparams) == - 0) && + (t->nparams == 0 || memcmp(t->params, f->params, + sizeof(t->params[0]) * t->nparams) == 0) && memcmp(t->results, f->results, sizeof(t->results[0]) * t->nresults) == 0) return i; @@ -343,7 +339,8 @@ WasmDataSegment* wasm_add_data(CfreeCompiler* c, WasmModule* m) { void wasm_data_set_bytes(CfreeCompiler* c, WasmModule* m, WasmDataSegment* d, const uint8_t* src, uint64_t n) { void* p; - if (n > SIZE_MAX) wasm_error(c, wasm_loc(0, 0), "wasm: data segment too large"); + if (n > SIZE_MAX) + wasm_error(c, wasm_loc(0, 0), "wasm: data segment too large"); if (d->bytes && d->nbytes) m->heap->free(m->heap, d->bytes, (size_t)d->nbytes); d->bytes = NULL; @@ -351,8 +348,10 @@ void wasm_data_set_bytes(CfreeCompiler* c, WasmModule* m, WasmDataSegment* d, if (!n) return; p = m->heap->alloc(m->heap, (size_t)n, 1); if (!p) wasm_error(c, wasm_loc(0, 0), "wasm: out of memory"); - if (src) memcpy(p, src, (size_t)n); - else memset(p, 0, (size_t)n); + if (src) + memcpy(p, src, (size_t)n); + else + memset(p, 0, (size_t)n); d->bytes = (uint8_t*)p; d->nbytes = n; } @@ -407,7 +406,7 @@ WasmCustom* wasm_add_custom(CfreeCompiler* c, WasmModule* m) { } void wasm_func_add_insn(CfreeCompiler* c, WasmModule* m, WasmFunc* f, - WasmInsnKind kind, int64_t imm) { + WasmInsnKind kind, int64_t imm) { if (f->ninsns == f->cap_insns) { uint32_t new_cap = f->cap_insns ? f->cap_insns * 2u : 16u; void* p = wasm_realloc(m->heap, f->insns, sizeof(*f->insns) * f->cap_insns, @@ -430,17 +429,17 @@ void wasm_func_add_insn(CfreeCompiler* c, WasmModule* m, WasmFunc* f, } void wasm_func_add_mem_insn(CfreeCompiler* c, WasmModule* m, WasmFunc* f, - WasmInsnKind kind, uint32_t align, - uint64_t offset, uint32_t memidx) { - wasm_func_add_insn(c, m, f, kind, offset > INT64_MAX ? INT64_MAX - : (int64_t)offset); + WasmInsnKind kind, uint32_t align, uint64_t offset, + uint32_t memidx) { + wasm_func_add_insn(c, m, f, kind, + offset > INT64_MAX ? INT64_MAX : (int64_t)offset); f->insns[f->ninsns - 1u].align = align; f->insns[f->ninsns - 1u].offset64 = offset; f->insns[f->ninsns - 1u].memidx = memidx; } void wasm_func_add_fp_insn(CfreeCompiler* c, WasmModule* m, WasmFunc* f, - WasmInsnKind kind, double value) { + WasmInsnKind kind, double value) { wasm_func_add_insn(c, m, f, kind, 0); f->insns[f->ninsns - 1u].fp = value; } diff --git a/src/wasm/validate.c b/src/wasm/validate.c @@ -29,8 +29,7 @@ static WasmValType wasm_global_init_type(const WasmInsn* in) { } static void wasm_stack_push(CfreeCompiler* c, WasmValStack* s, WasmValType vt) { - if (s->depth >= 256u) - wasm_error(c, s->loc, "wasm: operand stack too deep"); + if (s->depth >= 256u) wasm_error(c, s->loc, "wasm: operand stack too deep"); s->vals[s->depth++] = vt; } @@ -44,8 +43,7 @@ static int wasm_stack_pop(CfreeCompiler* c, WasmValStack* s, } if (expected && s->vals[s->depth - 1u] != expected) wasm_error(c, s->loc, "wasm: %s type mismatch (expected=0x%x got=0x%x)", - what, (unsigned)expected, - (unsigned)s->vals[s->depth - 1u]); + what, (unsigned)expected, (unsigned)s->vals[s->depth - 1u]); s->depth--; return 1; } @@ -95,8 +93,7 @@ void wasm_validate(WasmModule* m, CfreeCompiler* c) { m->memories[i].max_pages < m->memories[i].min_pages) wasm_error(c, wasm_loc(0, 0), "wasm: memory maximum below minimum"); if (m->memories[i].shared && !m->memories[i].has_max) - wasm_error(c, wasm_loc(0, 0), - "wasm: shared memory requires maximum"); + wasm_error(c, wasm_loc(0, 0), "wasm: shared memory requires maximum"); } for (i = 0; i < m->ntables; ++i) { if (m->tables[i].elem_type != WASM_VAL_FUNCREF) @@ -204,8 +201,7 @@ void wasm_validate_func(CfreeCompiler* c, WasmModule* m, WasmFunc* f) { wasm_require_feature(c, m, WASM_FEATURE_TAIL_CALLS, "tail calls", "return_call"); if (m->funcs[in->imm].nresults != f->nresults || - (f->nresults && - m->funcs[in->imm].results[0] != f->results[0])) + (f->nresults && m->funcs[in->imm].results[0] != f->results[0])) wasm_error(c, wasm_loc(0, 0), "wasm: return_call result type mismatch"); } @@ -270,16 +266,14 @@ void wasm_validate_func(CfreeCompiler* c, WasmModule* m, WasmFunc* f) { if (!wasm_is_ref_type((WasmValType)in->imm)) wasm_error(c, wasm_loc(0, 0), "wasm: bad ref.null type"); if ((WasmValType)in->imm != WASM_VAL_FUNCREF) - wasm_error(c, wasm_loc(0, 0), - "wasm: unsupported reference type"); + wasm_error(c, wasm_loc(0, 0), "wasm: unsupported reference type"); wasm_stack_push(c, &stack, (WasmValType)in->imm); break; case WASM_INSN_REF_FUNC: wasm_require_feature(c, m, WASM_FEATURE_TYPED_FUNC_REFS, "typed function references", "ref.func"); if (in->imm < 0 || (uint64_t)in->imm >= m->nfuncs) - wasm_error(c, wasm_loc(0, 0), - "wasm: ref.func index out of range"); + wasm_error(c, wasm_loc(0, 0), "wasm: ref.func index out of range"); wasm_stack_push(c, &stack, WASM_VAL_FUNCREF); break; case WASM_INSN_REF_IS_NULL: @@ -428,20 +422,20 @@ void wasm_validate_func(CfreeCompiler* c, WasmModule* m, WasmFunc* f) { case WASM_INSN_MEMORY_SIZE: if (in->memidx >= m->nmemories) wasm_error(c, wasm_loc(0, 0), "wasm: memory.size without memory"); - wasm_stack_push(c, &stack, - m->memories[in->memidx].is64 ? WASM_VAL_I64 - : WASM_VAL_I32); + wasm_stack_push( + c, &stack, + m->memories[in->memidx].is64 ? WASM_VAL_I64 : WASM_VAL_I32); break; case WASM_INSN_MEMORY_GROW: if (in->memidx >= m->nmemories) wasm_error(c, wasm_loc(0, 0), "wasm: memory.grow without memory"); - wasm_stack_pop(c, &stack, control, ncontrol, - m->memories[in->memidx].is64 ? WASM_VAL_I64 - : WASM_VAL_I32, - "memory.grow"); - wasm_stack_push(c, &stack, - m->memories[in->memidx].is64 ? WASM_VAL_I64 - : WASM_VAL_I32); + wasm_stack_pop( + c, &stack, control, ncontrol, + m->memories[in->memidx].is64 ? WASM_VAL_I64 : WASM_VAL_I32, + "memory.grow"); + wasm_stack_push( + c, &stack, + m->memories[in->memidx].is64 ? WASM_VAL_I64 : WASM_VAL_I32); break; case WASM_INSN_ATOMIC_FENCE: wasm_require_feature(c, m, WASM_FEATURE_THREADS, "threads", @@ -463,10 +457,10 @@ void wasm_validate_func(CfreeCompiler* c, WasmModule* m, WasmFunc* f) { "wasm: atomic load requires shared memory"); if (in->align && in->align > wasm_mem_width(in->kind)) wasm_error(c, wasm_loc(0, 0), "wasm: bad atomic alignment"); - wasm_stack_pop(c, &stack, control, ncontrol, - m->memories[in->memidx].is64 ? WASM_VAL_I64 - : WASM_VAL_I32, - "atomic load"); + wasm_stack_pop( + c, &stack, control, ncontrol, + m->memories[in->memidx].is64 ? WASM_VAL_I64 : WASM_VAL_I32, + "atomic load"); wasm_stack_push(c, &stack, wasm_atomic_value_type(in->kind)); break; case WASM_INSN_I32_ATOMIC_STORE: @@ -487,10 +481,10 @@ void wasm_validate_func(CfreeCompiler* c, WasmModule* m, WasmFunc* f) { wasm_error(c, wasm_loc(0, 0), "wasm: bad atomic alignment"); wasm_stack_pop(c, &stack, control, ncontrol, wasm_atomic_value_type(in->kind), "atomic store"); - wasm_stack_pop(c, &stack, control, ncontrol, - m->memories[in->memidx].is64 ? WASM_VAL_I64 - : WASM_VAL_I32, - "atomic store"); + wasm_stack_pop( + c, &stack, control, ncontrol, + m->memories[in->memidx].is64 ? WASM_VAL_I64 : WASM_VAL_I32, + "atomic store"); break; case WASM_INSN_I32_ATOMIC_RMW_ADD: case WASM_INSN_I64_ATOMIC_RMW_ADD: @@ -513,10 +507,10 @@ void wasm_validate_func(CfreeCompiler* c, WasmModule* m, WasmFunc* f) { "wasm: atomic rmw requires shared memory"); wasm_stack_pop(c, &stack, control, ncontrol, wasm_atomic_value_type(in->kind), "atomic rmw"); - wasm_stack_pop(c, &stack, control, ncontrol, - m->memories[in->memidx].is64 ? WASM_VAL_I64 - : WASM_VAL_I32, - "atomic rmw"); + wasm_stack_pop( + c, &stack, control, ncontrol, + m->memories[in->memidx].is64 ? WASM_VAL_I64 : WASM_VAL_I32, + "atomic rmw"); wasm_stack_push(c, &stack, wasm_atomic_value_type(in->kind)); break; case WASM_INSN_I32_ATOMIC_RMW_CMPXCHG: @@ -533,10 +527,10 @@ void wasm_validate_func(CfreeCompiler* c, WasmModule* m, WasmFunc* f) { wasm_atomic_value_type(in->kind), "atomic cmpxchg"); wasm_stack_pop(c, &stack, control, ncontrol, wasm_atomic_value_type(in->kind), "atomic cmpxchg"); - wasm_stack_pop(c, &stack, control, ncontrol, - m->memories[in->memidx].is64 ? WASM_VAL_I64 - : WASM_VAL_I32, - "atomic cmpxchg"); + wasm_stack_pop( + c, &stack, control, ncontrol, + m->memories[in->memidx].is64 ? WASM_VAL_I64 : WASM_VAL_I32, + "atomic cmpxchg"); wasm_stack_push(c, &stack, wasm_atomic_value_type(in->kind)); break; case WASM_INSN_I32_ATOMIC_WAIT: @@ -553,10 +547,10 @@ void wasm_validate_func(CfreeCompiler* c, WasmModule* m, WasmFunc* f) { wasm_stack_pop(c, &stack, control, ncontrol, wasm_atomic_value_type(in->kind), "atomic wait expected"); - wasm_stack_pop(c, &stack, control, ncontrol, - m->memories[in->memidx].is64 ? WASM_VAL_I64 - : WASM_VAL_I32, - "atomic wait address"); + wasm_stack_pop( + c, &stack, control, ncontrol, + m->memories[in->memidx].is64 ? WASM_VAL_I64 : WASM_VAL_I32, + "atomic wait address"); wasm_stack_push(c, &stack, WASM_VAL_I32); break; case WASM_INSN_MEMORY_ATOMIC_NOTIFY: @@ -569,10 +563,10 @@ void wasm_validate_func(CfreeCompiler* c, WasmModule* m, WasmFunc* f) { "wasm: atomic notify requires shared memory"); wasm_stack_pop(c, &stack, control, ncontrol, WASM_VAL_I32, "atomic notify count"); - wasm_stack_pop(c, &stack, control, ncontrol, - m->memories[in->memidx].is64 ? WASM_VAL_I64 - : WASM_VAL_I32, - "atomic notify address"); + wasm_stack_pop( + c, &stack, control, ncontrol, + m->memories[in->memidx].is64 ? WASM_VAL_I64 : WASM_VAL_I32, + "atomic notify address"); wasm_stack_push(c, &stack, WASM_VAL_I32); break; case WASM_INSN_I32_LOAD: @@ -591,10 +585,10 @@ void wasm_validate_func(CfreeCompiler* c, WasmModule* m, WasmFunc* f) { case WASM_INSN_I64_LOAD32_U: if (in->memidx >= m->nmemories) wasm_error(c, wasm_loc(0, 0), "wasm: load without memory"); - wasm_stack_pop(c, &stack, control, ncontrol, - m->memories[in->memidx].is64 ? WASM_VAL_I64 - : WASM_VAL_I32, - "load"); + wasm_stack_pop( + c, &stack, control, ncontrol, + m->memories[in->memidx].is64 ? WASM_VAL_I64 : WASM_VAL_I32, + "load"); wasm_stack_push(c, &stack, wasm_load_result_type(in->kind)); break; case WASM_INSN_I32_STORE: @@ -610,10 +604,10 @@ void wasm_validate_func(CfreeCompiler* c, WasmModule* m, WasmFunc* f) { wasm_error(c, wasm_loc(0, 0), "wasm: store without memory"); wasm_stack_pop(c, &stack, control, ncontrol, wasm_store_value_type(in->kind), "store"); - wasm_stack_pop(c, &stack, control, ncontrol, - m->memories[in->memidx].is64 ? WASM_VAL_I64 - : WASM_VAL_I32, - "store"); + wasm_stack_pop( + c, &stack, control, ncontrol, + m->memories[in->memidx].is64 ? WASM_VAL_I64 : WASM_VAL_I32, + "store"); break; case WASM_INSN_UNREACHABLE: wasm_mark_unreachable(&stack, control, ncontrol); @@ -751,20 +745,18 @@ void wasm_validate_func(CfreeCompiler* c, WasmModule* m, WasmFunc* f) { case WASM_INSN_I64_TRUNC_SAT_F64_S: case WASM_INSN_I64_TRUNC_SAT_F32_U: case WASM_INSN_I64_TRUNC_SAT_F64_U: { - WasmValType sat_src = - (in->kind == WASM_INSN_I32_TRUNC_SAT_F32_S || - in->kind == WASM_INSN_I32_TRUNC_SAT_F32_U || - in->kind == WASM_INSN_I64_TRUNC_SAT_F32_S || - in->kind == WASM_INSN_I64_TRUNC_SAT_F32_U) - ? WASM_VAL_F32 - : WASM_VAL_F64; - WasmValType sat_dst = - (in->kind == WASM_INSN_I32_TRUNC_SAT_F32_S || - in->kind == WASM_INSN_I32_TRUNC_SAT_F32_U || - in->kind == WASM_INSN_I32_TRUNC_SAT_F64_S || - in->kind == WASM_INSN_I32_TRUNC_SAT_F64_U) - ? WASM_VAL_I32 - : WASM_VAL_I64; + WasmValType sat_src = (in->kind == WASM_INSN_I32_TRUNC_SAT_F32_S || + in->kind == WASM_INSN_I32_TRUNC_SAT_F32_U || + in->kind == WASM_INSN_I64_TRUNC_SAT_F32_S || + in->kind == WASM_INSN_I64_TRUNC_SAT_F32_U) + ? WASM_VAL_F32 + : WASM_VAL_F64; + WasmValType sat_dst = (in->kind == WASM_INSN_I32_TRUNC_SAT_F32_S || + in->kind == WASM_INSN_I32_TRUNC_SAT_F32_U || + in->kind == WASM_INSN_I32_TRUNC_SAT_F64_S || + in->kind == WASM_INSN_I32_TRUNC_SAT_F64_U) + ? WASM_VAL_I32 + : WASM_VAL_I64; wasm_require_feature(c, m, WASM_FEATURE_NONTRAPPING_FTOI, "non-trapping float-to-int", "trunc_sat"); wasm_stack_pop(c, &stack, control, ncontrol, sat_src, "trunc_sat"); @@ -806,16 +798,17 @@ void wasm_validate_func(CfreeCompiler* c, WasmModule* m, WasmFunc* f) { : rhs; wasm_stack_pop(c, &stack, control, ncontrol, rhs, "operand"); if (lhs != rhs) - wasm_error(c, wasm_loc(0, 0), - "wasm: operand type mismatch (kind=0x%x lhs=0x%x rhs=0x%x)", - (unsigned)in->kind, (unsigned)lhs, (unsigned)rhs); + wasm_error( + c, wasm_loc(0, 0), + "wasm: operand type mismatch (kind=0x%x lhs=0x%x rhs=0x%x)", + (unsigned)in->kind, (unsigned)lhs, (unsigned)rhs); wasm_stack_push( c, &stack, wasm_int_cmp_op(in->kind, &cmp) ? WASM_VAL_I32 : lhs); - break; - } + break; + } #undef wasm_loc - } + } } if (ncontrol != 1u) wasm_error(c, wasm_loc(0, 0), "wasm: unterminated control block"); diff --git a/src/wasm/wasm.h b/src/wasm/wasm.h @@ -347,10 +347,10 @@ typedef enum WasmSegmentMode { * at module instantiation. Passive segments are sources for `memory.init` and * are otherwise inert until `data.drop` permanently zero-lengths them. */ typedef struct WasmDataSegment { - uint8_t mode; /* WasmSegmentMode */ - uint32_t memidx; /* meaningful when mode == WASM_SEG_ACTIVE */ - int64_t offset; /* active offset; signed to allow caller-relative builds */ - char* name; /* optional WAT `$name`, NULL otherwise */ + uint8_t mode; /* WasmSegmentMode */ + uint32_t memidx; /* meaningful when mode == WASM_SEG_ACTIVE */ + int64_t offset; /* active offset; signed to allow caller-relative builds */ + char* name; /* optional WAT `$name`, NULL otherwise */ uint8_t* bytes; uint64_t nbytes; } WasmDataSegment; @@ -380,12 +380,12 @@ typedef struct WasmGlobal { } WasmGlobal; typedef struct WasmElemSegment { - uint8_t mode; /* WasmSegmentMode */ + uint8_t mode; /* WasmSegmentMode */ WasmValType elem_type; /* funcref/externref/typed-funcref */ - uint32_t tableidx; /* meaningful when mode == WASM_SEG_ACTIVE */ - int64_t offset; /* active offset */ - char* name; /* optional WAT `$name`, NULL otherwise */ - uint32_t* funcs; /* heap-grown; each slot is a function index */ + uint32_t tableidx; /* meaningful when mode == WASM_SEG_ACTIVE */ + int64_t offset; /* active offset */ + char* name; /* optional WAT `$name`, NULL otherwise */ + uint32_t* funcs; /* heap-grown; each slot is a function index */ uint32_t nfuncs; uint32_t cap_funcs; } WasmElemSegment; @@ -489,8 +489,8 @@ uint32_t wasm_type_push_param(CfreeCompiler* c, WasmModule* m, WasmFuncType* t, void wasm_func_add_insn(CfreeCompiler* c, WasmModule* m, WasmFunc* f, WasmInsnKind kind, int64_t imm); void wasm_func_add_mem_insn(CfreeCompiler* c, WasmModule* m, WasmFunc* f, - WasmInsnKind kind, uint32_t align, - uint64_t offset, uint32_t memidx); + WasmInsnKind kind, uint32_t align, uint64_t offset, + uint32_t memidx); void wasm_func_add_fp_insn(CfreeCompiler* c, WasmModule* m, WasmFunc* f, WasmInsnKind kind, double value); diff --git a/src/wasm/wat.c b/src/wasm/wat.c @@ -1,7 +1,7 @@ -#include "wasm/wasm.h" - #include <cfree/source.h> +#include "wasm/wasm.h" + typedef struct WasmTok { const char* p; size_t len; @@ -111,8 +111,7 @@ static char* wat_dup_string(WatParser* p, WasmTok t, size_t* len_out) { static char* wat_dup_atom(WatParser* p, WasmTok t) { char* out = wasm_strdup(p->module->heap, t.p, t.len); - if (!out) - wasm_error(p->c, wasm_loc(t.line, t.col), "wasm: out of memory"); + if (!out) wasm_error(p->c, wasm_loc(t.line, t.col), "wasm: out of memory"); return out; } @@ -701,25 +700,79 @@ static int wat_instr_kind(WasmTok t, WasmInsnKind* out, int* has_imm) { return 1; } /* Bulk memory and table ops (0xfc prefix). */ - if (tok_is(t, "memory.init")) { *out = WASM_INSN_MEMORY_INIT; return 1; } - if (tok_is(t, "data.drop")) { *out = WASM_INSN_DATA_DROP; return 1; } - if (tok_is(t, "memory.copy")) { *out = WASM_INSN_MEMORY_COPY; return 1; } - if (tok_is(t, "memory.fill")) { *out = WASM_INSN_MEMORY_FILL; return 1; } - if (tok_is(t, "table.init")) { *out = WASM_INSN_TABLE_INIT; return 1; } - if (tok_is(t, "elem.drop")) { *out = WASM_INSN_ELEM_DROP; return 1; } - if (tok_is(t, "table.copy")) { *out = WASM_INSN_TABLE_COPY; return 1; } - if (tok_is(t, "table.grow")) { *out = WASM_INSN_TABLE_GROW; return 1; } - if (tok_is(t, "table.size")) { *out = WASM_INSN_TABLE_SIZE; return 1; } - if (tok_is(t, "table.fill")) { *out = WASM_INSN_TABLE_FILL; return 1; } + if (tok_is(t, "memory.init")) { + *out = WASM_INSN_MEMORY_INIT; + return 1; + } + if (tok_is(t, "data.drop")) { + *out = WASM_INSN_DATA_DROP; + return 1; + } + if (tok_is(t, "memory.copy")) { + *out = WASM_INSN_MEMORY_COPY; + return 1; + } + if (tok_is(t, "memory.fill")) { + *out = WASM_INSN_MEMORY_FILL; + return 1; + } + if (tok_is(t, "table.init")) { + *out = WASM_INSN_TABLE_INIT; + return 1; + } + if (tok_is(t, "elem.drop")) { + *out = WASM_INSN_ELEM_DROP; + return 1; + } + if (tok_is(t, "table.copy")) { + *out = WASM_INSN_TABLE_COPY; + return 1; + } + if (tok_is(t, "table.grow")) { + *out = WASM_INSN_TABLE_GROW; + return 1; + } + if (tok_is(t, "table.size")) { + *out = WASM_INSN_TABLE_SIZE; + return 1; + } + if (tok_is(t, "table.fill")) { + *out = WASM_INSN_TABLE_FILL; + return 1; + } /* Saturating float-to-int conversions. */ - if (tok_is(t, "i32.trunc_sat_f32_s")) { *out = WASM_INSN_I32_TRUNC_SAT_F32_S; return 1; } - if (tok_is(t, "i32.trunc_sat_f32_u")) { *out = WASM_INSN_I32_TRUNC_SAT_F32_U; return 1; } - if (tok_is(t, "i32.trunc_sat_f64_s")) { *out = WASM_INSN_I32_TRUNC_SAT_F64_S; return 1; } - if (tok_is(t, "i32.trunc_sat_f64_u")) { *out = WASM_INSN_I32_TRUNC_SAT_F64_U; return 1; } - if (tok_is(t, "i64.trunc_sat_f32_s")) { *out = WASM_INSN_I64_TRUNC_SAT_F32_S; return 1; } - if (tok_is(t, "i64.trunc_sat_f32_u")) { *out = WASM_INSN_I64_TRUNC_SAT_F32_U; return 1; } - if (tok_is(t, "i64.trunc_sat_f64_s")) { *out = WASM_INSN_I64_TRUNC_SAT_F64_S; return 1; } - if (tok_is(t, "i64.trunc_sat_f64_u")) { *out = WASM_INSN_I64_TRUNC_SAT_F64_U; return 1; } + if (tok_is(t, "i32.trunc_sat_f32_s")) { + *out = WASM_INSN_I32_TRUNC_SAT_F32_S; + return 1; + } + if (tok_is(t, "i32.trunc_sat_f32_u")) { + *out = WASM_INSN_I32_TRUNC_SAT_F32_U; + return 1; + } + if (tok_is(t, "i32.trunc_sat_f64_s")) { + *out = WASM_INSN_I32_TRUNC_SAT_F64_S; + return 1; + } + if (tok_is(t, "i32.trunc_sat_f64_u")) { + *out = WASM_INSN_I32_TRUNC_SAT_F64_U; + return 1; + } + if (tok_is(t, "i64.trunc_sat_f32_s")) { + *out = WASM_INSN_I64_TRUNC_SAT_F32_S; + return 1; + } + if (tok_is(t, "i64.trunc_sat_f32_u")) { + *out = WASM_INSN_I64_TRUNC_SAT_F32_U; + return 1; + } + if (tok_is(t, "i64.trunc_sat_f64_s")) { + *out = WASM_INSN_I64_TRUNC_SAT_F64_S; + return 1; + } + if (tok_is(t, "i64.trunc_sat_f64_u")) { + *out = WASM_INSN_I64_TRUNC_SAT_F64_U; + return 1; + } if (tok_is(t, "i32.add")) { *out = WASM_INSN_I32_ADD; return 1; @@ -1227,7 +1280,6 @@ static void wat_parse_instr_imm(WatParser* p, WasmFunc* f, WasmInsnKind kind, } } - static int wat_atom_prefix(WasmTok t, const char* prefix) { size_t n = cfree_slice_cstr(prefix).len; return t.kind == WT_ATOM && t.len >= n && memcmp(t.p, prefix, n) == 0; @@ -1298,8 +1350,8 @@ static void wat_parse_memory_index(WatParser* p, uint32_t* out) { *out = (uint32_t)idx; } -static void wat_parse_mem_attrs(WatParser* p, uint32_t* align, - uint64_t* offset, uint32_t* memidx) { +static void wat_parse_mem_attrs(WatParser* p, uint32_t* align, uint64_t* offset, + uint32_t* memidx) { while (p->tok.kind == WT_ATOM) { WasmTok val; if (wat_atom_prefix(p->tok, "align=")) { @@ -1362,8 +1414,7 @@ static void wat_reject_inline_result(WatParser* p, const char* what) { static void wat_parse_instr(WatParser* p, WasmFunc* f); static void wat_check_instr_feature(WatParser* p, WasmInsnKind kind) { - if (kind == WASM_INSN_RETURN_CALL || - kind == WASM_INSN_RETURN_CALL_INDIRECT || + if (kind == WASM_INSN_RETURN_CALL || kind == WASM_INSN_RETURN_CALL_INDIRECT || kind == WASM_INSN_RETURN_CALL_REF) wat_require_feature(p, WASM_FEATURE_TAIL_CALLS, "tail calls", "tail-call instruction"); @@ -1413,13 +1464,19 @@ static void wat_parse_ref_null_type(WatParser* p, int64_t* out) { * index immediates rather than a memarg. */ static int wat_is_bulk_op(WasmInsnKind k) { switch (k) { - case WASM_INSN_MEMORY_INIT: case WASM_INSN_DATA_DROP: - case WASM_INSN_MEMORY_COPY: case WASM_INSN_MEMORY_FILL: - case WASM_INSN_TABLE_INIT: case WASM_INSN_ELEM_DROP: - case WASM_INSN_TABLE_COPY: case WASM_INSN_TABLE_GROW: - case WASM_INSN_TABLE_SIZE: case WASM_INSN_TABLE_FILL: + case WASM_INSN_MEMORY_INIT: + case WASM_INSN_DATA_DROP: + case WASM_INSN_MEMORY_COPY: + case WASM_INSN_MEMORY_FILL: + case WASM_INSN_TABLE_INIT: + case WASM_INSN_ELEM_DROP: + case WASM_INSN_TABLE_COPY: + case WASM_INSN_TABLE_GROW: + case WASM_INSN_TABLE_SIZE: + case WASM_INSN_TABLE_FILL: return 1; - default: return 0; + default: + return 0; } } @@ -1477,11 +1534,17 @@ static void wat_emit_bulk_op(WatParser* p, WasmFunc* f, WasmInsnKind kind) { int got_a, got_b; WatNameResolver primary = NULL; switch (kind) { - case WASM_INSN_MEMORY_INIT: case WASM_INSN_DATA_DROP: - primary = wat_resolve_data_name; break; - case WASM_INSN_TABLE_INIT: case WASM_INSN_ELEM_DROP: - primary = wat_resolve_elem_name; break; - default: primary = NULL; break; + case WASM_INSN_MEMORY_INIT: + case WASM_INSN_DATA_DROP: + primary = wat_resolve_data_name; + break; + case WASM_INSN_TABLE_INIT: + case WASM_INSN_ELEM_DROP: + primary = wat_resolve_elem_name; + break; + default: + primary = NULL; + break; } got_a = wat_try_parse_uleb_imm_named(p, primary, &a); got_b = wat_try_parse_uleb_imm_named(p, primary, &b); @@ -1531,7 +1594,8 @@ static void wat_emit_bulk_op(WatParser* p, WasmFunc* f, WasmInsnKind kind) { case WASM_INSN_TABLE_FILL: f->insns[f->ninsns - 1u].imm = (int64_t)(got_a ? a : 0); break; - default: break; + default: + break; } } @@ -1735,8 +1799,8 @@ static void wat_parse_instr_list(WatParser* p, WasmFunc* f) { int next_has_imm; if (p->tok.kind == WT_ATOM && !wat_instr_kind(p->tok, &next_kind, &next_has_imm)) { - wat_parse_memory_index(p, &memidx); - wat_next(p); + wat_parse_memory_index(p, &memidx); + wat_next(p); } } wasm_func_add_insn(p->c, p->module, f, @@ -1843,8 +1907,8 @@ static void wat_parse_instr(WatParser* p, WasmFunc* f) { uint32_t memidx = 0; WasmInsnKind next_kind; int next_has_imm; - if (p->tok.kind == WT_ATOM && !wat_instr_kind(p->tok, &next_kind, - &next_has_imm)) { + if (p->tok.kind == WT_ATOM && + !wat_instr_kind(p->tok, &next_kind, &next_has_imm)) { wat_parse_memory_index(p, &memidx); wat_next(p); } @@ -2147,8 +2211,8 @@ static void wat_parse_memory_field(WatParser* p) { mem->name = wat_dup_atom(p, p->tok); wat_next(p); } - while (p->tok.kind == WT_ATOM && (tok_is(p->tok, "i64") || - tok_is(p->tok, "shared"))) { + while (p->tok.kind == WT_ATOM && + (tok_is(p->tok, "i64") || tok_is(p->tok, "shared"))) { if (tok_is(p->tok, "i64")) mem->is64 = 1; else @@ -2160,8 +2224,8 @@ static void wat_parse_memory_field(WatParser* p) { "wasm wat: expected memory minimum"); mem->min_pages = (uint64_t)min_pages; wat_next(p); - while (p->tok.kind == WT_ATOM && (tok_is(p->tok, "i64") || - tok_is(p->tok, "shared"))) { + while (p->tok.kind == WT_ATOM && + (tok_is(p->tok, "i64") || tok_is(p->tok, "shared"))) { if (tok_is(p->tok, "i64")) mem->is64 = 1; else @@ -2175,8 +2239,8 @@ static void wat_parse_memory_field(WatParser* p) { mem->has_max = 1; mem->max_pages = (uint64_t)max_pages; wat_next(p); - while (p->tok.kind == WT_ATOM && (tok_is(p->tok, "i64") || - tok_is(p->tok, "shared"))) { + while (p->tok.kind == WT_ATOM && + (tok_is(p->tok, "i64") || tok_is(p->tok, "shared"))) { if (tok_is(p->tok, "i64")) mem->is64 = 1; else @@ -2190,8 +2254,8 @@ static void wat_parse_memory_field(WatParser* p) { static void wat_parse_memory_limits(WatParser* p, WasmMemory* mem) { int64_t lo, hi; - while (p->tok.kind == WT_ATOM && (tok_is(p->tok, "i64") || - tok_is(p->tok, "shared"))) { + while (p->tok.kind == WT_ATOM && + (tok_is(p->tok, "i64") || tok_is(p->tok, "shared"))) { if (tok_is(p->tok, "i64")) mem->is64 = 1; else @@ -2203,8 +2267,8 @@ static void wat_parse_memory_limits(WatParser* p, WasmMemory* mem) { "wasm wat: expected memory minimum"); mem->min_pages = (uint64_t)lo; wat_next(p); - while (p->tok.kind == WT_ATOM && (tok_is(p->tok, "i64") || - tok_is(p->tok, "shared"))) { + while (p->tok.kind == WT_ATOM && + (tok_is(p->tok, "i64") || tok_is(p->tok, "shared"))) { if (tok_is(p->tok, "i64")) mem->is64 = 1; else @@ -2218,8 +2282,8 @@ static void wat_parse_memory_limits(WatParser* p, WasmMemory* mem) { mem->has_max = 1; mem->max_pages = (uint64_t)hi; wat_next(p); - while (p->tok.kind == WT_ATOM && (tok_is(p->tok, "i64") || - tok_is(p->tok, "shared"))) { + while (p->tok.kind == WT_ATOM && + (tok_is(p->tok, "i64") || tok_is(p->tok, "shared"))) { if (tok_is(p->tok, "i64")) mem->is64 = 1; else @@ -2506,9 +2570,12 @@ static void wat_parse_elem_field(WatParser* p) { e->offset = off.imm; has_offset = 1; } - if (is_declarative) e->mode = WASM_SEG_DECLARATIVE; - else if (has_offset) e->mode = WASM_SEG_ACTIVE; - else e->mode = WASM_SEG_PASSIVE; + if (is_declarative) + e->mode = WASM_SEG_DECLARATIVE; + else if (has_offset) + e->mode = WASM_SEG_ACTIVE; + else + e->mode = WASM_SEG_PASSIVE; if (tok_is(p->tok, "func")) wat_next(p); while (p->tok.kind != WT_RPAREN && p->tok.kind != WT_EOF) { int64_t idx; @@ -2659,8 +2726,7 @@ void wasm_parse_wat(CfreeCompiler* c, CfreeSlice name, const CfreeSlice* input, WasmModule* out) { WatParser p; memset(&p, 0, sizeof p); - if (name.s) - (void)cfree_source_add_memory(c, name, &out->file_id); + if (name.s) (void)cfree_source_add_memory(c, name, &out->file_id); p.c = c; p.name = name.s; p.src = input->s; diff --git a/test/api/abi_classify_test.c b/test/api/abi_classify_test.c @@ -101,24 +101,33 @@ static const ABIFuncInfo* classify_fn(CfreeCompiler* c, CfreeCgTypeId ret_ty, static const char* arch_name(CfreeArchKind a) { switch (a) { - case CFREE_ARCH_X86_64: return "x64"; - case CFREE_ARCH_ARM_64: return "aarch64"; - case CFREE_ARCH_RV64: return "rv64"; - default: return "?"; + case CFREE_ARCH_X86_64: + return "x64"; + case CFREE_ARCH_ARM_64: + return "aarch64"; + case CFREE_ARCH_RV64: + return "rv64"; + default: + return "?"; } } static const char* os_name(CfreeOSKind o) { switch (o) { - case CFREE_OS_LINUX: return "linux"; - case CFREE_OS_MACOS: return "macos"; - case CFREE_OS_WINDOWS: return "windows"; - default: return "?"; + case CFREE_OS_LINUX: + return "linux"; + case CFREE_OS_MACOS: + return "macos"; + case CFREE_OS_WINDOWS: + return "windows"; + default: + return "?"; } } /* Assert: arg/ret classify as DIRECT with two 8-byte INT parts at offsets 0/8. * This is the shape every native ABI uses for i128 (and for RV64, also f128). - * Used as both the green case (RV64) and the post-fix expectation (SysV-x64). */ + * Used as both the green case (RV64) and the post-fix expectation (SysV-x64). + */ static void expect_direct_2x_int8(const char* tag, const ABIArgInfo* ai) { EXPECT(ai->kind == ABI_ARG_DIRECT, "%s: kind=%d want DIRECT", tag, (int)ai->kind); @@ -144,9 +153,8 @@ static void expect_indirect(const char* tag, const ABIArgInfo* ai, EXPECT(ai->indirect_align >= 8, "%s: indirect_align=%u want >=8", tag, (unsigned)ai->indirect_align); u32 expected_flag = is_return ? ABI_AF_SRET : ABI_AF_BYVAL; - EXPECT((ai->flags & expected_flag) != 0, - "%s: flags=0x%x missing %s", tag, (unsigned)ai->flags, - is_return ? "SRET" : "BYVAL"); + EXPECT((ai->flags & expected_flag) != 0, "%s: flags=0x%x missing %s", tag, + (unsigned)ai->flags, is_return ? "SRET" : "BYVAL"); } /* Assert: DIRECT with a single FP part covering the full type. */ @@ -164,8 +172,8 @@ static void expect_direct_1x_fp(const char* tag, const ABIArgInfo* ai, (unsigned)ai->parts[0].src_offset); } -static void expect_direct_2(const char* tag, const ABIArgInfo* ai, u8 c0, - u8 c1, u32 s0, u32 s1) { +static void expect_direct_2(const char* tag, const ABIArgInfo* ai, u8 c0, u8 c1, + u32 s0, u32 s1) { EXPECT(ai->kind == ABI_ARG_DIRECT, "%s: kind=%d want DIRECT", tag, (int)ai->kind); EXPECT(ai->nparts == 2, "%s: nparts=%u want 2", tag, (unsigned)ai->nparts); @@ -178,10 +186,10 @@ static void expect_direct_2(const char* tag, const ABIArgInfo* ai, u8 c0, (unsigned)ai->parts[0].size, s0); EXPECT(ai->parts[1].size == s1, "%s: parts[1].size=%u want %u", tag, (unsigned)ai->parts[1].size, s1); - EXPECT(ai->parts[0].src_offset == 0, "%s: parts[0].src_offset=%u want 0", - tag, (unsigned)ai->parts[0].src_offset); - EXPECT(ai->parts[1].src_offset == 8, "%s: parts[1].src_offset=%u want 8", - tag, (unsigned)ai->parts[1].src_offset); + EXPECT(ai->parts[0].src_offset == 0, "%s: parts[0].src_offset=%u want 0", tag, + (unsigned)ai->parts[0].src_offset); + EXPECT(ai->parts[1].src_offset == 8, "%s: parts[1].src_offset=%u want 8", tag, + (unsigned)ai->parts[1].src_offset); } static CfreeCgTypeId record2(CfreeCompiler* c, CfreeCgTypeId a, @@ -225,8 +233,7 @@ static void check_target(CfreeArchKind arch, CfreeOSKind os, CfreeObjFmt obj) { * f128 before classification; defensive path treats size-16 FP as * a size-8 double — DIRECT/1 FP part of 8B for both arg and ret. */ expect_direct_1x_fp(tag, &fi->params[0], 8); - snprintf(tag, sizeof tag, "%s/%s f128 ret", arch_name(arch), - os_name(os)); + snprintf(tag, sizeof tag, "%s/%s f128 ret", arch_name(arch), os_name(os)); expect_direct_1x_fp(tag, &fi->ret, 8); EXPECT(fi->has_sret == 0, "%s/%s: f128 should not set has_sret", arch_name(arch), os_name(os)); @@ -235,8 +242,7 @@ static void check_target(CfreeArchKind arch, CfreeOSKind os, CfreeObjFmt obj) { * x87 support; classify as INDIRECT (memory) so it routes through * a stack image consistent with the wide16 CG-layer shortcut. */ expect_indirect(tag, &fi->params[0], /*is_return=*/0); - snprintf(tag, sizeof tag, "%s/%s f128 ret", arch_name(arch), - os_name(os)); + snprintf(tag, sizeof tag, "%s/%s f128 ret", arch_name(arch), os_name(os)); expect_indirect(tag, &fi->ret, /*is_return=*/1); EXPECT(fi->has_sret == 1, "%s/%s: f128 ret should set has_sret", arch_name(arch), os_name(os)); @@ -244,16 +250,14 @@ static void check_target(CfreeArchKind arch, CfreeOSKind os, CfreeObjFmt obj) { /* AAPCS64 / Apple ARM64: 128-bit FP scalar passes in a single Q * register — DIRECT/1 FP part of 16B. */ expect_direct_1x_fp(tag, &fi->params[0], 16); - snprintf(tag, sizeof tag, "%s/%s f128 ret", arch_name(arch), - os_name(os)); + snprintf(tag, sizeof tag, "%s/%s f128 ret", arch_name(arch), os_name(os)); expect_direct_1x_fp(tag, &fi->ret, 16); EXPECT(fi->has_sret == 0, "%s/%s: f128 should not set has_sret", arch_name(arch), os_name(os)); } else if (arch == CFREE_ARCH_RV64) { /* RV64 LP64D: long double passes like a 2*XLEN scalar — 2 INT parts. */ expect_direct_2x_int8(tag, &fi->params[0]); - snprintf(tag, sizeof tag, "%s/%s f128 ret", arch_name(arch), - os_name(os)); + snprintf(tag, sizeof tag, "%s/%s f128 ret", arch_name(arch), os_name(os)); expect_direct_2x_int8(tag, &fi->ret); EXPECT(fi->has_sret == 0, "%s/%s: f128 should not set has_sret", arch_name(arch), os_name(os)); @@ -261,24 +265,23 @@ static void check_target(CfreeArchKind arch, CfreeOSKind os, CfreeObjFmt obj) { } if (arch == CFREE_ARCH_X86_64) { - CfreeCgTypeId f64_i64 = record2(c, bi.id[CFREE_CG_BUILTIN_F64], - bi.id[CFREE_CG_BUILTIN_I64]); - CfreeCgTypeId i64_f64 = record2(c, bi.id[CFREE_CG_BUILTIN_I64], - bi.id[CFREE_CG_BUILTIN_F64]); - CfreeCgTypeId f32x2 = record2(c, bi.id[CFREE_CG_BUILTIN_F32], - bi.id[CFREE_CG_BUILTIN_F32]); + CfreeCgTypeId f64_i64 = + record2(c, bi.id[CFREE_CG_BUILTIN_F64], bi.id[CFREE_CG_BUILTIN_I64]); + CfreeCgTypeId i64_f64 = + record2(c, bi.id[CFREE_CG_BUILTIN_I64], bi.id[CFREE_CG_BUILTIN_F64]); + CfreeCgTypeId f32x2 = + record2(c, bi.id[CFREE_CG_BUILTIN_F32], bi.id[CFREE_CG_BUILTIN_F32]); { const ABIFuncInfo* fi = classify_fn(c, f64_i64, f64_i64); - snprintf(tag, sizeof tag, "%s/%s {double,long} arg", - arch_name(arch), os_name(os)); + snprintf(tag, sizeof tag, "%s/%s {double,long} arg", arch_name(arch), + os_name(os)); if (os == CFREE_OS_WINDOWS) { expect_indirect(tag, &fi->params[0], /*is_return=*/0); } else { - expect_direct_2(tag, &fi->params[0], ABI_CLASS_FP, ABI_CLASS_INT, 8, - 8); + expect_direct_2(tag, &fi->params[0], ABI_CLASS_FP, ABI_CLASS_INT, 8, 8); } - snprintf(tag, sizeof tag, "%s/%s {double,long} ret", - arch_name(arch), os_name(os)); + snprintf(tag, sizeof tag, "%s/%s {double,long} ret", arch_name(arch), + os_name(os)); if (os == CFREE_OS_WINDOWS) { expect_indirect(tag, &fi->ret, /*is_return=*/1); EXPECT(fi->has_sret == 1, "%s/%s: mixed record should use sret", @@ -291,16 +294,15 @@ static void check_target(CfreeArchKind arch, CfreeOSKind os, CfreeObjFmt obj) { } { const ABIFuncInfo* fi = classify_fn(c, i64_f64, i64_f64); - snprintf(tag, sizeof tag, "%s/%s {long,double} arg", - arch_name(arch), os_name(os)); + snprintf(tag, sizeof tag, "%s/%s {long,double} arg", arch_name(arch), + os_name(os)); if (os == CFREE_OS_WINDOWS) { expect_indirect(tag, &fi->params[0], /*is_return=*/0); } else { - expect_direct_2(tag, &fi->params[0], ABI_CLASS_INT, ABI_CLASS_FP, 8, - 8); + expect_direct_2(tag, &fi->params[0], ABI_CLASS_INT, ABI_CLASS_FP, 8, 8); } - snprintf(tag, sizeof tag, "%s/%s {long,double} ret", - arch_name(arch), os_name(os)); + snprintf(tag, sizeof tag, "%s/%s {long,double} ret", arch_name(arch), + os_name(os)); if (os == CFREE_OS_WINDOWS) { expect_indirect(tag, &fi->ret, /*is_return=*/1); } else { @@ -309,14 +311,14 @@ static void check_target(CfreeArchKind arch, CfreeOSKind os, CfreeObjFmt obj) { } { const ABIFuncInfo* fi = classify_fn(c, f32x2, f32x2); - snprintf(tag, sizeof tag, "%s/%s {float,float} arg", - arch_name(arch), os_name(os)); + snprintf(tag, sizeof tag, "%s/%s {float,float} arg", arch_name(arch), + os_name(os)); if (os == CFREE_OS_WINDOWS) expect_direct_1x_int(tag, &fi->params[0], 8); else expect_direct_1x_fp(tag, &fi->params[0], 8); - snprintf(tag, sizeof tag, "%s/%s {float,float} ret", - arch_name(arch), os_name(os)); + snprintf(tag, sizeof tag, "%s/%s {float,float} ret", arch_name(arch), + os_name(os)); if (os == CFREE_OS_WINDOWS) expect_direct_1x_int(tag, &fi->ret, 8); else @@ -342,8 +344,8 @@ static CfreeCgTypeId make_i8_record(CfreeCompiler* c, const char* tag_name, fields[i].name = cfree_sym_intern(c, cfree_slice_cstr(names[i])); fields[i].type = i8; } - return cfree_cg_type_record(c, cfree_sym_intern(c, cfree_slice_cstr(tag_name)), fields, - nfields); + return cfree_cg_type_record( + c, cfree_sym_intern(c, cfree_slice_cstr(tag_name)), fields, nfields); } /* Build a record { i64 a; i64 b; } — size 16, align 8. */ @@ -356,7 +358,8 @@ static CfreeCgTypeId make_two_i64_record(CfreeCompiler* c, const char* tag_n) { fields[0].type = i64; fields[1].name = cfree_sym_intern(c, CFREE_SLICE_LIT("b")); fields[1].type = i64; - return cfree_cg_type_record(c, cfree_sym_intern(c, cfree_slice_cstr(tag_n)), fields, 2); + return cfree_cg_type_record(c, cfree_sym_intern(c, cfree_slice_cstr(tag_n)), + fields, 2); } /* Classify a function `ret_ty fn(p0, p1, ..., pN-1)` and return its info. */ @@ -386,13 +389,11 @@ static void expect_indirect_align(const char* tag, const ABIArgInfo* ai, EXPECT(ai->kind == ABI_ARG_INDIRECT, "%s: kind=%d want INDIRECT", tag, (int)ai->kind); EXPECT(ai->nparts == 0, "%s: nparts=%u want 0", tag, (unsigned)ai->nparts); - EXPECT(ai->indirect_align == want_align, - "%s: indirect_align=%u want %u", tag, (unsigned)ai->indirect_align, - want_align); + EXPECT(ai->indirect_align == want_align, "%s: indirect_align=%u want %u", tag, + (unsigned)ai->indirect_align, want_align); u32 expected_flag = is_return ? ABI_AF_SRET : ABI_AF_BYVAL; - EXPECT((ai->flags & expected_flag) != 0, - "%s: flags=0x%x missing %s", tag, (unsigned)ai->flags, - is_return ? "SRET" : "BYVAL"); + EXPECT((ai->flags & expected_flag) != 0, "%s: flags=0x%x missing %s", tag, + (unsigned)ai->flags, is_return ? "SRET" : "BYVAL"); } /* Expect DIRECT with a single INT part of the given size. */ @@ -402,11 +403,10 @@ static void expect_direct_1x_int(const char* tag, const ABIArgInfo* ai, (int)ai->kind); EXPECT(ai->nparts == 1, "%s: nparts=%u want 1", tag, (unsigned)ai->nparts); if (ai->nparts != 1 || !ai->parts) return; - EXPECT(ai->parts[0].cls == ABI_CLASS_INT, - "%s: parts[0].cls=%d want INT", tag, (int)ai->parts[0].cls); - EXPECT(ai->parts[0].size == want_size, - "%s: parts[0].size=%u want %u", tag, (unsigned)ai->parts[0].size, - want_size); + EXPECT(ai->parts[0].cls == ABI_CLASS_INT, "%s: parts[0].cls=%d want INT", tag, + (int)ai->parts[0].cls); + EXPECT(ai->parts[0].size == want_size, "%s: parts[0].size=%u want %u", tag, + (unsigned)ai->parts[0].size, want_size); } /* Win64-specific ABI shape assertions: aggregate rules ({1,2,4,8} by value @@ -439,8 +439,8 @@ static void test_win64_specifics(void) { * classifier emits per-arg parts regardless. */ { CfreeCgTypeId args[5] = {i32, i32, i32, i32, i32}; - const ABIFuncInfo* fi = classify_fn_n(c, bi.id[CFREE_CG_BUILTIN_VOID], - args, 5, 0); + const ABIFuncInfo* fi = + classify_fn_n(c, bi.id[CFREE_CG_BUILTIN_VOID], args, 5, 0); EXPECT(fi->nparams == 5, "win64 5xint: nparams=%u want 5", (unsigned)fi->nparams); for (u32 i = 0; i < 5; ++i) { @@ -453,8 +453,8 @@ static void test_win64_specifics(void) { /* Case 3: void f(double,double,double,double,double) — 5 doubles. */ { CfreeCgTypeId args[5] = {f64, f64, f64, f64, f64}; - const ABIFuncInfo* fi = classify_fn_n(c, bi.id[CFREE_CG_BUILTIN_VOID], - args, 5, 0); + const ABIFuncInfo* fi = + classify_fn_n(c, bi.id[CFREE_CG_BUILTIN_VOID], args, 5, 0); EXPECT(fi->nparams == 5, "win64 5xfp: nparams=%u want 5", (unsigned)fi->nparams); for (u32 i = 0; i < 5; ++i) { @@ -469,8 +469,8 @@ static void test_win64_specifics(void) { * sharing is a codegen call-site concern. */ { CfreeCgTypeId args[4] = {i32, f64, i32, f64}; - const ABIFuncInfo* fi = classify_fn_n(c, bi.id[CFREE_CG_BUILTIN_VOID], - args, 4, 0); + const ABIFuncInfo* fi = + classify_fn_n(c, bi.id[CFREE_CG_BUILTIN_VOID], args, 4, 0); EXPECT(fi->nparams == 4, "win64 mix: nparams=%u want 4", (unsigned)fi->nparams); expect_direct_1x_int("win64 mix arg[0]", &fi->params[0], 4); @@ -507,8 +507,8 @@ static void test_win64_specifics(void) { * goes by hidden pointer (BYVAL) on Win64. */ { CfreeCgTypeId args[1] = {rec3}; - const ABIFuncInfo* fi = classify_fn_n(c, bi.id[CFREE_CG_BUILTIN_VOID], - args, 1, 0); + const ABIFuncInfo* fi = + classify_fn_n(c, bi.id[CFREE_CG_BUILTIN_VOID], args, 1, 0); EXPECT(fi->nparams == 1, "win64 S3 arg: nparams=%u want 1", (unsigned)fi->nparams); expect_indirect_align("win64 S3 arg", &fi->params[0], /*is_return=*/0, @@ -521,8 +521,7 @@ static void test_win64_specifics(void) { const ABIFuncInfo* fi = classify_fn_n(c, i32, args, 1, /*variadic=*/1); EXPECT(fi->variadic == 1, "win64 printf: variadic=%u want 1", (unsigned)fi->variadic); - EXPECT(fi->vararg_on_stack == 0, - "win64 printf: vararg_on_stack=%u want 0", + EXPECT(fi->vararg_on_stack == 0, "win64 printf: vararg_on_stack=%u want 0", (unsigned)fi->vararg_on_stack); expect_direct_1x_int("win64 printf ret", &fi->ret, 4); } @@ -531,8 +530,7 @@ static void test_win64_specifics(void) { { ABITypeInfo vi = abi_va_list_info(((Compiler*)c)->abi); EXPECT(vi.size == 8, "win64 va_list size=%u want 8", (unsigned)vi.size); - EXPECT(vi.align == 8, "win64 va_list align=%u want 8", - (unsigned)vi.align); + EXPECT(vi.align == 8, "win64 va_list align=%u want 8", (unsigned)vi.align); EXPECT(vi.scalar_kind == ABI_SC_PTR, "win64 va_list scalar_kind=%u want ABI_SC_PTR (%u)", (unsigned)vi.scalar_kind, (unsigned)ABI_SC_PTR); @@ -568,8 +566,8 @@ static void test_aarch64_windows_variadic(void) { { const ABIFuncInfo* fi = classify_fn_n(c, bi.id[CFREE_CG_BUILTIN_VOID], args, 1, 1); - expect_direct_1x_int("aarch64/windows variadic double arg", - &fi->params[0], 8); + expect_direct_1x_int("aarch64/windows variadic double arg", &fi->params[0], + 8); EXPECT(fi->vararg_on_stack == 0, "aarch64/windows variadic: vararg_on_stack=%u want 0", (unsigned)fi->vararg_on_stack); diff --git a/test/api/cg_switch_test.c b/test/api/cg_switch_test.c @@ -171,11 +171,11 @@ static void build_switch_fn(CfreeCompiler* c, CfreeCgTypeId i32_ty, /* Push selector, dispatch. */ cfree_cg_push_local(cg, param); - cfree_cg_load(cg, - (CfreeCgMemAccess){ - .type = sh->selector_type, - .align = cfree_cg_type_align(c, sh->selector_type)}, - (CfreeCgEffAddr){0, 0}); + cfree_cg_load( + cg, + (CfreeCgMemAccess){.type = sh->selector_type, + .align = cfree_cg_type_align(c, sh->selector_type)}, + (CfreeCgEffAddr){0, 0}); memset(&sw, 0, sizeof sw); sw.selector_type = sh->selector_type; sw.default_label = default_lbl; diff --git a/test/api/cg_type_test.c b/test/api/cg_type_test.c @@ -66,8 +66,7 @@ static CfreeObjBuilder* new_obj(CfreeCompiler* c) { } static int open_emitted_obj(CfreeCompiler* c, CfreeObjBuilder* ob, - CfreeWriter** writer_out, - CfreeObjFile** file_out) { + CfreeWriter** writer_out, CfreeObjFile** file_out) { CfreeWriter* w = NULL; CfreeObjFile* f = NULL; CfreeSlice bytes; @@ -393,7 +392,8 @@ static void exercise_cg_data_entsize(CfreeCompiler* c, CfreeCgTypeId i8_ty) { EXPECT(sym != CFREE_CG_SYM_NONE, "entsize object decl failed"); memset(&data_attrs, 0, sizeof data_attrs); - data_attrs.section = cfree_sym_intern(c, CFREE_SLICE_LIT(".rodata.cfree.merge")); + data_attrs.section = + cfree_sym_intern(c, CFREE_SLICE_LIT(".rodata.cfree.merge")); data_attrs.align = 1; data_attrs.entsize = 1; data_attrs.flags = CFREE_CG_DATADEF_READONLY | CFREE_CG_DATADEF_MERGE | @@ -420,8 +420,7 @@ static void exercise_cg_data_entsize(CfreeCompiler* c, CfreeCgTypeId i8_ty) { (CFREE_SF_MERGE | CFREE_SF_STRINGS)) { found = 1; EXPECT(sec.entsize == 1, - "merge string section entsize should be 1, got %u", - sec.entsize); + "merge string section entsize should be 1, got %u", sec.entsize); } } cfree_obj_free(f); @@ -1428,7 +1427,8 @@ int main(void) { "array elem mismatch"); EXPECT(cfree_cg_type_array_count(c, array_i32) == 4, "array count mismatch"); - alias = cfree_cg_type_alias(c, cfree_sym_intern(c, CFREE_SLICE_LIT("I")), i32_ty); + alias = + cfree_cg_type_alias(c, cfree_sym_intern(c, CFREE_SLICE_LIT("I")), i32_ty); EXPECT(alias != CFREE_CG_TYPE_NONE && alias != i32_ty, "alias id should be fresh"); EXPECT(cfree_cg_type_kind(c, alias) == CFREE_CG_TYPE_ALIAS, @@ -1443,10 +1443,11 @@ int main(void) { fields[1].name = cfree_sym_intern(c, CFREE_SLICE_LIT("b")); fields[1].type = ptr_i32; fields[1].align_override = 1; - rec = cfree_cg_type_record(c, cfree_sym_intern(c, CFREE_SLICE_LIT("R")), fields, 2); + rec = cfree_cg_type_record(c, cfree_sym_intern(c, CFREE_SLICE_LIT("R")), + fields, 2); EXPECT(rec != CFREE_CG_TYPE_NONE, "record type failed"); - EXPECT(cfree_cg_type_record(c, cfree_sym_intern(c, CFREE_SLICE_LIT("Bad")), fields, 0) != - CFREE_CG_TYPE_NONE, + EXPECT(cfree_cg_type_record(c, cfree_sym_intern(c, CFREE_SLICE_LIT("Bad")), + fields, 0) != CFREE_CG_TYPE_NONE, "empty record type failed"); EXPECT(cfree_cg_type_kind(c, rec) == CFREE_CG_TYPE_RECORD, "record kind mismatch"); @@ -1467,7 +1468,8 @@ int main(void) { fields[1].type = i32_ty; fields[1].flags = CFREE_CG_FIELD_BITFIELD; fields[1].bit_width = 3; - rec_ex = cfree_cg_type_record(c, cfree_sym_intern(c, CFREE_SLICE_LIT("BF")), fields, 2); + rec_ex = cfree_cg_type_record(c, cfree_sym_intern(c, CFREE_SLICE_LIT("BF")), + fields, 2); EXPECT(rec_ex != CFREE_CG_TYPE_NONE, "bit-field record type failed"); EXPECT(cfree_cg_type_size(c, rec_ex) == 4, "bit-field record size mismatch"); EXPECT(cfree_cg_type_record_field(c, rec_ex, 1, &field_out, &field_off) == 0, @@ -1500,8 +1502,8 @@ int main(void) { vals[0].value = 1; vals[1].name = cfree_sym_intern(c, CFREE_SLICE_LIT("B")); vals[1].value = 2; - enm = cfree_cg_type_enum(c, cfree_sym_intern(c, CFREE_SLICE_LIT("E")), CFREE_CG_TYPE_NONE, - vals, 2); + enm = cfree_cg_type_enum(c, cfree_sym_intern(c, CFREE_SLICE_LIT("E")), + CFREE_CG_TYPE_NONE, vals, 2); EXPECT(enm != CFREE_CG_TYPE_NONE, "enum type failed"); memset(params, 0, sizeof(params)); diff --git a/test/ar_test.c b/test/ar_test.c @@ -158,11 +158,13 @@ static int test_basic_roundtrip(void) { EXPECT(cfree_ar_iter_new(&g_ctx, &in, &it) == CFREE_OK, "iter_init"); EXPECT(cfree_ar_iter_next(it, &m), "first member"); - EXPECT(cfree_slice_eq_cstr(m.name, "a.o"), "name 0 = %.*s", CFREE_SLICE_ARG(m.name)); + EXPECT(cfree_slice_eq_cstr(m.name, "a.o"), "name 0 = %.*s", + CFREE_SLICE_ARG(m.name)); EXPECT(m.size == 4 && memcmp(m.data, "AAAA", 4) == 0, "data 0"); EXPECT(cfree_ar_iter_next(it, &m), "second member"); - EXPECT(cfree_slice_eq_cstr(m.name, "b.o"), "name 1 = %.*s", CFREE_SLICE_ARG(m.name)); + EXPECT(cfree_slice_eq_cstr(m.name, "b.o"), "name 1 = %.*s", + CFREE_SLICE_ARG(m.name)); EXPECT(m.size == 5 && memcmp(m.data, "BBBBB", 5) == 0, "data 1"); EXPECT(!cfree_ar_iter_next(it, &m), "iter end"); @@ -198,10 +200,11 @@ static int test_long_name_table(void) { in.len = bw.len; EXPECT(cfree_ar_iter_new(&g_ctx, &in, &it) == CFREE_OK, "iter_init"); EXPECT(cfree_ar_iter_next(it, &m), "first member"); - EXPECT(cfree_slice_eq_cstr(m.name, "short.o"), "name 0 = %.*s", CFREE_SLICE_ARG(m.name)); - EXPECT(cfree_ar_iter_next(it, &m), "second member"); - EXPECT(cfree_slice_eq_cstr(m.name, "this_name_is_long_enough.o"), "long name = %.*s", + EXPECT(cfree_slice_eq_cstr(m.name, "short.o"), "name 0 = %.*s", CFREE_SLICE_ARG(m.name)); + EXPECT(cfree_ar_iter_next(it, &m), "second member"); + EXPECT(cfree_slice_eq_cstr(m.name, "this_name_is_long_enough.o"), + "long name = %.*s", CFREE_SLICE_ARG(m.name)); EXPECT(!cfree_ar_iter_next(it, &m), "iter end"); cfree_ar_iter_free(it); @@ -240,7 +243,8 @@ static int test_symbol_index_empty(void) { in.len = bw.len; EXPECT(cfree_ar_iter_new(&g_ctx, &in, &it) == CFREE_OK, "iter_init"); EXPECT(cfree_ar_iter_next(it, &m), "first user member"); - EXPECT(cfree_slice_eq_cstr(m.name, "lonely.o"), "name = %.*s", CFREE_SLICE_ARG(m.name)); + EXPECT(cfree_slice_eq_cstr(m.name, "lonely.o"), "name = %.*s", + CFREE_SLICE_ARG(m.name)); EXPECT(!cfree_ar_iter_next(it, &m), "iter end"); cfree_ar_iter_free(it); @@ -359,7 +363,8 @@ static int test_symbol_index_with_long_names(void) { msyms[1].count = 1; opts.member_symbols = msyms; - ms[0].name = CFREE_SLICE_LIT("this_name_is_long_enough.o"); /* 26 chars → // */ + ms[0].name = + CFREE_SLICE_LIT("this_name_is_long_enough.o"); /* 26 chars → // */ ms[0].bytes.data = (const uint8_t*)"X"; ms[0].bytes.len = 1; ms[1].name = CFREE_SLICE_LIT("short.o"); @@ -408,10 +413,11 @@ static int test_symbol_index_with_long_names(void) { in.len = bw.len; EXPECT(cfree_ar_iter_new(&g_ctx, &in, &it) == CFREE_OK, "iter_init"); EXPECT(cfree_ar_iter_next(it, &m), "m0"); - EXPECT(cfree_slice_eq_cstr(m.name, "this_name_is_long_enough.o"), "m0 name = %.*s", - CFREE_SLICE_ARG(m.name)); + EXPECT(cfree_slice_eq_cstr(m.name, "this_name_is_long_enough.o"), + "m0 name = %.*s", CFREE_SLICE_ARG(m.name)); EXPECT(cfree_ar_iter_next(it, &m), "m1"); - EXPECT(cfree_slice_eq_cstr(m.name, "short.o"), "m1 name = %.*s", CFREE_SLICE_ARG(m.name)); + EXPECT(cfree_slice_eq_cstr(m.name, "short.o"), "m1 name = %.*s", + CFREE_SLICE_ARG(m.name)); EXPECT(!cfree_ar_iter_next(it, &m), "iter end"); /* Optional host cross-check. */ @@ -460,8 +466,7 @@ static int test_iter_skips_index(void) { in.len = bw.len; EXPECT(cfree_ar_iter_new(&g_ctx, &in, &it) == CFREE_OK, "iter_init"); while (cfree_ar_iter_next(it, &m)) { - EXPECT(!cfree_slice_eq_cstr(m.name, "/"), - "iter surfaced raw `/` member"); + EXPECT(!cfree_slice_eq_cstr(m.name, "/"), "iter surfaced raw `/` member"); seen++; } EXPECT(seen == 1, "saw %d members", seen); @@ -545,7 +550,8 @@ static int test_path_basename(void) { in.len = bw.len; EXPECT(cfree_ar_iter_new(&g_ctx, &in, &it) == CFREE_OK, "iter_init"); EXPECT(cfree_ar_iter_next(it, &m), "first"); - EXPECT(cfree_slice_eq_cstr(m.name, "foo.o"), "basename = %.*s", CFREE_SLICE_ARG(m.name)); + EXPECT(cfree_slice_eq_cstr(m.name, "foo.o"), "basename = %.*s", + CFREE_SLICE_ARG(m.name)); cfree_ar_iter_free(it); bufw_fini(&bw); @@ -571,7 +577,8 @@ static int test_truncate_when_long_names_off(void) { in.len = bw.len; EXPECT(cfree_ar_iter_new(&g_ctx, &in, &it) == CFREE_OK, "iter_init"); EXPECT(cfree_ar_iter_next(it, &m), "first"); - EXPECT(cfree_slice_eq_cstr(m.name, "abcdefghijklmno"), "truncated = %.*s", CFREE_SLICE_ARG(m.name)); + EXPECT(cfree_slice_eq_cstr(m.name, "abcdefghijklmno"), "truncated = %.*s", + CFREE_SLICE_ARG(m.name)); cfree_ar_iter_free(it); bufw_fini(&bw); @@ -603,7 +610,8 @@ static int test_name_15_char_boundary(void) { in.len = bw.len; EXPECT(cfree_ar_iter_new(&g_ctx, &in, &it) == CFREE_OK, "iter_init"); EXPECT(cfree_ar_iter_next(it, &m), "first"); - EXPECT(cfree_slice_eq_cstr(m.name, "abcdefghijklmno"), "name = %.*s", CFREE_SLICE_ARG(m.name)); + EXPECT(cfree_slice_eq_cstr(m.name, "abcdefghijklmno"), "name = %.*s", + CFREE_SLICE_ARG(m.name)); cfree_ar_iter_free(it); bufw_fini(&bw); @@ -632,7 +640,8 @@ static int test_name_16_char_boundary(void) { in.len = bw.len; EXPECT(cfree_ar_iter_new(&g_ctx, &in, &it) == CFREE_OK, "iter_init"); EXPECT(cfree_ar_iter_next(it, &m), "first"); - EXPECT(cfree_slice_eq_cstr(m.name, "abcdefghijklmnop"), "name = %.*s", CFREE_SLICE_ARG(m.name)); + EXPECT(cfree_slice_eq_cstr(m.name, "abcdefghijklmnop"), "name = %.*s", + CFREE_SLICE_ARG(m.name)); cfree_ar_iter_free(it); bufw_fini(&bw); @@ -663,11 +672,12 @@ static int test_empty_member_payload(void) { in.len = bw.len; EXPECT(cfree_ar_iter_new(&g_ctx, &in, &it) == CFREE_OK, "iter_init"); EXPECT(cfree_ar_iter_next(it, &m), "first"); - EXPECT(cfree_slice_eq_cstr(m.name, "empty.o") && m.size == 0, "empty.o size=%zu", - m.size); + EXPECT(cfree_slice_eq_cstr(m.name, "empty.o") && m.size == 0, + "empty.o size=%zu", m.size); EXPECT(cfree_ar_iter_next(it, &m), "second"); - EXPECT(cfree_slice_eq_cstr(m.name, "next.o") && m.size == 1 && m.data[0] == 'N', - "next.o"); + EXPECT( + cfree_slice_eq_cstr(m.name, "next.o") && m.size == 1 && m.data[0] == 'N', + "next.o"); EXPECT(!cfree_ar_iter_next(it, &m), "iter end"); cfree_ar_iter_free(it); @@ -748,8 +758,7 @@ static int test_iter_bad_magic(void) { in.data = bad; in.len = sizeof(bad) - 1; - EXPECT(cfree_ar_iter_new(&g_ctx, &in, &it) != CFREE_OK, - "rejects bad magic"); + EXPECT(cfree_ar_iter_new(&g_ctx, &in, &it) != CFREE_OK, "rejects bad magic"); in.data = NULL; in.len = 0; @@ -772,14 +781,16 @@ static int test_write_invalid_args(void) { bufw_init(&bw); - EXPECT(cfree_ar_write(NULL, NULL, 0, NULL) != CFREE_OK, "NULL writer rejected"); + EXPECT(cfree_ar_write(NULL, NULL, 0, NULL) != CFREE_OK, + "NULL writer rejected"); EXPECT(cfree_ar_write(&bw.base, NULL, 1, NULL) != CFREE_OK, "NULL members with nmembers>0 rejected"); ms[0].name = CFREE_SLICE_NULL; ms[0].bytes.data = (const uint8_t*)"X"; ms[0].bytes.len = 1; - EXPECT(cfree_ar_write(&bw.base, ms, 1, NULL) != CFREE_OK, "NULL name rejected"); + EXPECT(cfree_ar_write(&bw.base, ms, 1, NULL) != CFREE_OK, + "NULL name rejected"); /* NULL symbol-name with nonzero count. */ bad_syms[0] = CFREE_SLICE_NULL; @@ -850,7 +861,8 @@ static int test_iter_skips_bsd_symdef(void) { in.len = bw.len; EXPECT(cfree_ar_iter_new(&g_ctx, &in, &it) == CFREE_OK, "iter_init"); while (cfree_ar_iter_next(it, &m)) { - EXPECT(cfree_slice_eq_cstr(m.name, "u.o"), "unexpected name = %.*s", CFREE_SLICE_ARG(m.name)); + EXPECT(cfree_slice_eq_cstr(m.name, "u.o"), "unexpected name = %.*s", + CFREE_SLICE_ARG(m.name)); seen++; } EXPECT(seen == 1, "saw %d members", seen); diff --git a/test/arch/aa64_inline_test.c b/test/arch/aa64_inline_test.c @@ -5,7 +5,7 @@ #include "inline_public_test.h" #define EXPECTED_MOV_X1_X5 0xaa0503e1u -#define EXPECTED_NOP 0xd503201fu +#define EXPECTED_NOP 0xd503201fu #define EXPECTED_ADD_W0_WSP_7 0x11001fe0u static void put32le(uint8_t out[4], uint32_t v) { @@ -25,8 +25,8 @@ static void aa64_body(CfreeCompiler* c, CfreeCg* cg, CfreeCgTypeId i64_ty) { cfree_cg_push_int(cg, 7, i64_ty); imm = it_asm_op(c, "i", "imm", i64_ty, CFREE_CG_ASM_IN); - it_inline_asm(c, cg, "add w0, wsp, %[imm]", NULL, 0, &imm, 1, - &memory_clobber, 1); + it_inline_asm(c, cg, "add w0, wsp, %[imm]", NULL, 0, &imm, 1, &memory_clobber, + 1); } static void aa64_bad_add_zr(CfreeCompiler* c, CfreeCg* cg, @@ -47,8 +47,9 @@ int main(void) { uint8_t pat[12]; it_env_init(&env); - IT_EXPECT(&env, it_emit_text(&env, CFREE_ARCH_ARM_64, "aa64_inline_public", - aa64_body, &text), + IT_EXPECT(&env, + it_emit_text(&env, CFREE_ARCH_ARM_64, "aa64_inline_public", + aa64_body, &text), "failed to emit aa64 inline-asm object"); if (text.data) { put32le(pat, EXPECTED_MOV_X1_X5); diff --git a/test/arch/aa64_isa_test.c b/test/arch/aa64_isa_test.c @@ -20,7 +20,8 @@ static int fails = 0; static int cases = 0; -static void check(u32 word, const char* want_mnem, const char* want_ops_substr) { +static void check(u32 word, const char* want_mnem, + const char* want_ops_substr) { ++cases; const AA64InsnDesc* d = aa64_disasm_find(word); if (!d) { @@ -45,8 +46,7 @@ static void check(u32 word, const char* want_mnem, const char* want_ops_substr) return; } if (want_ops_substr && !strstr(buf, want_ops_substr)) { - fprintf(stderr, - "FAIL 0x%08x %s: operands=%s\n expected substring %s\n", + fprintf(stderr, "FAIL 0x%08x %s: operands=%s\n expected substring %s\n", word, want_mnem, buf, want_ops_substr); ++fails; return; @@ -131,14 +131,10 @@ int main(void) { "x29, x30, [sp, #16]!"); /* LDSTP_SOFF: STP X29, X30, [SP, #16] (signed-offset variant of pair) */ - check(aa64_ldstp_soff_pack((AA64LdStPSOff){.opc = 2, - .V = 0, - .L = 0, - .imm7 = 2, - .Rt2 = 30, - .Rn = 31, - .Rt = 29}), - "stp", "x29, x30, [sp, #16]"); + check( + aa64_ldstp_soff_pack((AA64LdStPSOff){ + .opc = 2, .V = 0, .L = 0, .imm7 = 2, .Rt2 = 30, .Rn = 31, .Rt = 29}), + "stp", "x29, x30, [sp, #16]"); /* LDST_SIMM9 (V=0, size=3): STUR X1, [X2, #-8] */ check(aa64_ldst_simm9_pack((AA64LdStSimm9){.size = 3, @@ -172,13 +168,15 @@ int main(void) { /* ---- alias precedence: ensure first-match wins ---- */ { - /* ORR X1, XZR, X2 with shift=0,imm6=0 should resolve to "mov", not "orr". */ + /* ORR X1, XZR, X2 with shift=0,imm6=0 should resolve to "mov", not "orr". + */ u32 w = aa64_mov_reg(1, 1, 2); const AA64InsnDesc* d = aa64_disasm_find(w); if (d == NULL || !slice_eq_cstr(d->mnemonic, "mov")) { - fprintf(stderr, - "FAIL: alias precedence — ORR-as-MOV resolved to %.*s (want mov)\n", - SLICE_ARG(d ? d->mnemonic : SLICE_LIT("(null)"))); + fprintf( + stderr, + "FAIL: alias precedence — ORR-as-MOV resolved to %.*s (want mov)\n", + SLICE_ARG(d ? d->mnemonic : SLICE_LIT("(null)"))); ++fails; } else if (!(d->flags & AA64_ASMFL_ALIAS)) { fprintf(stderr, "FAIL: alias precedence — resolved row missing ALIAS\n"); @@ -192,8 +190,7 @@ int main(void) { u32 w = aa64_orr(1, 1, 3, 2); const AA64InsnDesc* d = aa64_disasm_find(w); if (d == NULL || !slice_eq_cstr(d->mnemonic, "orr")) { - fprintf(stderr, - "FAIL: non-alias ORR resolved to %.*s (want orr)\n", + fprintf(stderr, "FAIL: non-alias ORR resolved to %.*s (want orr)\n", SLICE_ARG(d ? d->mnemonic : SLICE_LIT("(null)"))); ++fails; } diff --git a/test/arch/inline_public_test.h b/test/arch/inline_public_test.h @@ -80,14 +80,14 @@ static void it_env_init(InlineTestEnv* env) { env->ctx.now = -1; } -#define IT_EXPECT(env, cond, ...) \ - do { \ - if (!(cond)) { \ - (env)->fail++; \ - fprintf(stderr, "FAIL %s:%d: ", __FILE__, __LINE__); \ - fprintf(stderr, __VA_ARGS__); \ - fputc('\n', stderr); \ - } \ +#define IT_EXPECT(env, cond, ...) \ + do { \ + if (!(cond)) { \ + (env)->fail++; \ + fprintf(stderr, "FAIL %s:%d: ", __FILE__, __LINE__); \ + fprintf(stderr, __VA_ARGS__); \ + fputc('\n', stderr); \ + } \ } while (0) static CfreeTarget it_target(CfreeArchKind arch) { @@ -151,8 +151,7 @@ static CfreeStatus it_emit_func(CfreeCompiler* c, void* user) { } static int it_emit_text(InlineTestEnv* env, CfreeArchKind arch, - const char* name, InlineBodyFn body, - InlineText* text) { + const char* name, InlineBodyFn body, InlineText* text) { CfreeCompiler* c = NULL; InlineEmit emit; CfreeSlice bytes; diff --git a/test/arch/rv64_decode_test.c b/test/arch/rv64_decode_test.c @@ -91,8 +91,7 @@ static void decode_addi(CfreeCompiler* pub) { memset(&insn, 0, sizeof(insn)); st = arch_decode_one(c, bytes, sizeof(bytes), 0x1000, &insn); EXPECT(st == CFREE_OK, "decode_one(addi) status %d", (int)st); - EXPECT(insn.pc == 0x1000, "pc = 0x%llx", - (unsigned long long)insn.pc); + EXPECT(insn.pc == 0x1000, "pc = 0x%llx", (unsigned long long)insn.pc); EXPECT(insn.nbytes == 4, "nbytes = %u", (unsigned)insn.nbytes); EXPECT(insn.opcode == RV64_DEC_ADDI, "opcode = %u, want ADDI", (unsigned)insn.opcode); @@ -100,14 +99,13 @@ static void decode_addi(CfreeCompiler* pub) { "addi should not be a terminator"); EXPECT(insn.noperands == 3, "addi operand count = %u", (unsigned)insn.noperands); - EXPECT(insn.operands[0].kind == CFREE_DECOP_REG && - insn.operands[0].reg == RV_A0, - "addi rd operand wrong"); + EXPECT( + insn.operands[0].kind == CFREE_DECOP_REG && insn.operands[0].reg == RV_A0, + "addi rd operand wrong"); EXPECT(insn.operands[1].kind == CFREE_DECOP_REG && insn.operands[1].reg == RV_ZERO, "addi rs1 operand wrong"); - EXPECT(insn.operands[2].kind == CFREE_DECOP_IMM && - insn.operands[2].imm == 42, + EXPECT(insn.operands[2].kind == CFREE_DECOP_IMM && insn.operands[2].imm == 42, "addi imm operand wrong"); } @@ -127,8 +125,7 @@ static void decode_block_stops_at_ecall(CfreeCompiler* pub) { st = arch_decode_block(c, bytes, sizeof(bytes), 0x2000, insts, 4, &n); EXPECT(st == CFREE_OK, "decode_block status %d", (int)st); EXPECT(n == 3, "decode_block count = %u", (unsigned)n); - EXPECT(insts[2].nbytes == 4, "ecall nbytes = %u", - (unsigned)insts[2].nbytes); + EXPECT(insts[2].nbytes == 4, "ecall nbytes = %u", (unsigned)insts[2].nbytes); EXPECT(insts[2].opcode == RV64_DEC_ECALL, "ecall opcode = %u", (unsigned)insts[2].opcode); EXPECT((insts[2].flags & CFREE_DECODE_TERMINATOR) != 0, diff --git a/test/arch/rv64_inline_test.c b/test/arch/rv64_inline_test.c @@ -4,11 +4,11 @@ #include "inline_public_test.h" -#define ENC_EBREAK 0x00100073u -#define ENC_ECALL 0x00000073u -#define ENC_NOP 0x00000013u +#define ENC_EBREAK 0x00100073u +#define ENC_ECALL 0x00000073u +#define ENC_NOP 0x00000013u #define ENC_ADDI_T0_T1_42 0x02a30293u -#define ENC_FENCE_RW_RW 0x0330000fu +#define ENC_FENCE_RW_RW 0x0330000fu static void put32le(uint8_t out[4], uint32_t v) { out[0] = (uint8_t)v; @@ -44,8 +44,9 @@ int main(void) { uint8_t pat[12]; it_env_init(&env); - IT_EXPECT(&env, it_emit_text(&env, CFREE_ARCH_RV64, "rv64_inline_public", - rv64_body, &text), + IT_EXPECT(&env, + it_emit_text(&env, CFREE_ARCH_RV64, "rv64_inline_public", rv64_body, + &text), "failed to emit rv64 inline-asm object"); if (text.data) { put32le(pat, ENC_EBREAK); diff --git a/test/arch/x64_inline_test.c b/test/arch/x64_inline_test.c @@ -30,17 +30,19 @@ int main(void) { InlineText text; it_env_init(&env); - IT_EXPECT(&env, it_emit_text(&env, CFREE_ARCH_X86_64, "x64_inline_public", - x64_body, &text), + IT_EXPECT(&env, + it_emit_text(&env, CFREE_ARCH_X86_64, "x64_inline_public", x64_body, + &text), "failed to emit x64 inline-asm object"); if (text.data) { IT_EXPECT(&env, it_contains(text.data, text.len, nops, sizeof nops), "missing two-nop inline asm encoding"); - IT_EXPECT(&env, it_contains(text.data, text.len, movq_rcx_rax, - sizeof movq_rcx_rax), - "missing movq %%rcx, %%rax literal-escape encoding"); - IT_EXPECT(&env, it_contains(text.data, text.len, addq_7_rax, - sizeof addq_7_rax), + IT_EXPECT( + &env, + it_contains(text.data, text.len, movq_rcx_rax, sizeof movq_rcx_rax), + "missing movq %%rcx, %%rax literal-escape encoding"); + IT_EXPECT(&env, + it_contains(text.data, text.len, addq_7_rax, sizeof addq_7_rax), "missing addq $7, %%rax immediate-substitution encoding"); } it_text_close(&text); diff --git a/test/asm/harness/asm_runner.c b/test/asm/harness/asm_runner.c @@ -179,14 +179,13 @@ static CfreeStatus xm_reserve(void* u, size_t n, int p, close(fd); return CFREE_NOMEM; } - w = mmap(NULL, n, PROT_READ | PROT_WRITE, - MAP_SHARED | XM_MAP_32BIT, fd, 0); + w = mmap(NULL, n, PROT_READ | PROT_WRITE, MAP_SHARED | XM_MAP_32BIT, fd, 0); if (w == MAP_FAILED) { close(fd); return CFREE_NOMEM; } - r = mmap(xm_low_runtime_hint(n), n, PROT_READ, - MAP_SHARED | XM_MAP_32BIT, fd, 0); + r = mmap(xm_low_runtime_hint(n), n, PROT_READ, MAP_SHARED | XM_MAP_32BIT, + fd, 0); close(fd); if (r == MAP_FAILED) { munmap(w, n); @@ -754,10 +753,11 @@ static int mode_jit(const char* src_path) { #if defined(__aarch64__) || defined(__arm64__) { - char* td_start = (char*)cfree_jit_lookup(jit, CFREE_SLICE_LIT("__tdata_start")); + char* td_start = + (char*)cfree_jit_lookup(jit, CFREE_SLICE_LIT("__tdata_start")); char* td_end = (char*)cfree_jit_lookup(jit, CFREE_SLICE_LIT("__tdata_end")); - unsigned long bs_n = - (unsigned long)(unsigned long long)cfree_jit_lookup(jit, CFREE_SLICE_LIT("__tbss_size")); + unsigned long bs_n = (unsigned long)(unsigned long long)cfree_jit_lookup( + jit, CFREE_SLICE_LIT("__tbss_size")); if (td_start && td_end) { unsigned long td_n = (unsigned long)(td_end - td_start); unsigned long i; diff --git a/test/coff/pe-import-mingw.c b/test/coff/pe-import-mingw.c @@ -30,8 +30,8 @@ #include "link/link.h" #include "obj/obj.h" -#define MINGW_ARCHIVE_PATH \ - "/opt/homebrew/opt/mingw-w64/toolchain-x86_64/x86_64-w64-mingw32/lib/" \ +#define MINGW_ARCHIVE_PATH \ + "/opt/homebrew/opt/mingw-w64/toolchain-x86_64/x86_64-w64-mingw32/lib/" \ "libkernel32.a" /* mingw's archive declares the DLL name in uppercase. */ @@ -77,14 +77,14 @@ static CfreeDiagSink g_diag = {diag_emit, NULL, 0, 0}; /* ---- failure tracking --------------------------------------------- */ static int g_failures; -#define EXPECT(cond, ...) \ - do { \ - if (!(cond)) { \ - fprintf(stderr, "FAIL %s:%d: ", __FILE__, __LINE__); \ - fprintf(stderr, __VA_ARGS__); \ - fputc('\n', stderr); \ - g_failures++; \ - } \ +#define EXPECT(cond, ...) \ + do { \ + if (!(cond)) { \ + fprintf(stderr, "FAIL %s:%d: ", __FILE__, __LINE__); \ + fprintf(stderr, __VA_ARGS__); \ + fputc('\n', stderr); \ + g_failures++; \ + } \ } while (0) /* ---- target / compiler ------------------------------------------- */ @@ -121,11 +121,9 @@ static ObjBuilder* build_program(Compiler* c) { Sym text_name = pool_intern_slice(p, SLICE_LIT(".text")); Sym main_name = pool_intern_slice(p, SLICE_LIT("mainCRTStartup")); Sym exit_name = pool_intern_slice(p, SLICE_LIT(MINGW_IMPORT_FN)); - ObjSecId text = obj_section(ob, text_name, SEC_TEXT, - SF_ALLOC | SF_EXEC, 16); + ObjSecId text = obj_section(ob, text_name, SEC_TEXT, SF_ALLOC | SF_EXEC, 16); obj_write(ob, text, PROG_TEXT_X64, sizeof PROG_TEXT_X64); - obj_symbol(ob, main_name, SB_GLOBAL, SK_FUNC, text, 0, - sizeof PROG_TEXT_X64); + obj_symbol(ob, main_name, SB_GLOBAL, SK_FUNC, text, 0, sizeof PROG_TEXT_X64); ObjSymId exit_sym = obj_symbol(ob, exit_name, SB_GLOBAL, SK_UNDEF, OBJ_SEC_NONE, 0, 0); obj_reloc(ob, text, 1, R_PC32, exit_sym, -4); @@ -136,8 +134,7 @@ static ObjBuilder* build_program(Compiler* c) { /* ---- archive / objdump helpers ------------------------------------ */ static int have_mingw_objdump(void) { - FILE* fp = popen( - "command -v x86_64-w64-mingw32-objdump 2>/dev/null", "r"); + FILE* fp = popen("command -v x86_64-w64-mingw32-objdump 2>/dev/null", "r"); if (!fp) return 0; char buf[256]; size_t n = fread(buf, 1, sizeof buf - 1, fp); @@ -292,11 +289,10 @@ int main(void) { break; } } - EXPECT(found != NULL, - "%s LinkSymbol not present after link_resolve", MINGW_IMPORT_FN); + EXPECT(found != NULL, "%s LinkSymbol not present after link_resolve", + MINGW_IMPORT_FN); if (found) { - EXPECT(found->imported, - "%s.imported=0 (expected 1 after archive match)", + EXPECT(found->imported, "%s.imported=0 (expected 1 after archive match)", MINGW_IMPORT_FN); } } @@ -332,8 +328,8 @@ int main(void) { link_free(l); /* 4. Probe with objdump. */ - char* dump_p = slurp_cmd( - "x86_64-w64-mingw32-objdump -p /tmp/pe-import-mingw.exe 2>&1"); + char* dump_p = + slurp_cmd("x86_64-w64-mingw32-objdump -p /tmp/pe-import-mingw.exe 2>&1"); EXPECT(dump_p != NULL, "slurp objdump -p"); if (dump_p) { /* KERNEL32.dll listed (case-insensitive — derive_dll_name picks @@ -359,7 +355,8 @@ int main(void) { * single referenced symbol. */ EXPECT(strstr(dump_p, "CreateFile") == NULL, "objdump -p: unexpected CreateFile import (dead-strip " - "failure?)\n---\n%s\n---", dump_p); + "failure?)\n---\n%s\n---", + dump_p); EXPECT(strstr(dump_p, "CloseHandle") == NULL, "objdump -p: unexpected CloseHandle import\n---\n%s\n---", dump_p); free(dump_p); diff --git a/test/coff/pe-import-smoke.c b/test/coff/pe-import-smoke.c @@ -35,23 +35,23 @@ /* ---- short-import wire constants (mirror the spec in * test/coff/cfree-roundtrip-coff.c::test_short_import_amd64). ---- */ #define SHIM_HEADER_SIZE 20u -#define SHIM_SYM_CSTR "ExitProcess" -#define SHIM_DLL_CSTR "KERNEL32.dll" -#define SHIM_SYM_NUL_LEN 12u /* "ExitProcess\0" */ -#define SHIM_DLL_NUL_LEN 13u /* "KERNEL32.dll\0" */ -#define SHIM_DATA_LEN (SHIM_SYM_NUL_LEN + SHIM_DLL_NUL_LEN) /* 25 */ -#define SHIM_TOTAL_LEN (SHIM_HEADER_SIZE + SHIM_DATA_LEN) /* 45 */ +#define SHIM_SYM_CSTR "ExitProcess" +#define SHIM_DLL_CSTR "KERNEL32.dll" +#define SHIM_SYM_NUL_LEN 12u /* "ExitProcess\0" */ +#define SHIM_DLL_NUL_LEN 13u /* "KERNEL32.dll\0" */ +#define SHIM_DATA_LEN (SHIM_SYM_NUL_LEN + SHIM_DLL_NUL_LEN) /* 25 */ +#define SHIM_TOTAL_LEN (SHIM_HEADER_SIZE + SHIM_DATA_LEN) /* 45 */ /* IMAGE_FILE_MACHINE_AMD64. */ #define COFF_MACHINE_AMD64 0x8664u /* Sig1=0, Sig2=0xFFFF marks a short-import record. */ -#define COFF_SHIMP_SIG2 0xFFFFu +#define COFF_SHIMP_SIG2 0xFFFFu /* TypeFlags = Type=CODE(0) | (NameType=NAME(1) << 2) = 0x0004. */ #define COFF_SHIMP_TYPEFLAGS 0x0004u /* PE optional-header / data-directory constants we assert. */ #define PE_DD_IDX_IMPORT 1 -#define PE_DD_IDX_IAT 12 +#define PE_DD_IDX_IAT 12 /* The exit-process program: e8 disp32 c3 (call ExitProcess; ret). * disp32 is patched by R_PC32 against an undef ExitProcess. */ @@ -91,14 +91,14 @@ static CfreeDiagSink g_diag = {diag_emit, NULL, 0, 0}; /* ---- failure tracking --------------------------------------------- */ static int g_failures; -#define EXPECT(cond, ...) \ - do { \ - if (!(cond)) { \ - fprintf(stderr, "FAIL %s:%d: ", __FILE__, __LINE__); \ - fprintf(stderr, __VA_ARGS__); \ - fputc('\n', stderr); \ - g_failures++; \ - } \ +#define EXPECT(cond, ...) \ + do { \ + if (!(cond)) { \ + fprintf(stderr, "FAIL %s:%d: ", __FILE__, __LINE__); \ + fprintf(stderr, __VA_ARGS__); \ + fputc('\n', stderr); \ + g_failures++; \ + } \ } while (0) /* ---- target / compiler ------------------------------------------- */ @@ -163,12 +163,10 @@ static ObjBuilder* build_program(Compiler* c) { Sym text_name = pool_intern_slice(p, SLICE_LIT(".text")); Sym main_name = pool_intern_slice(p, SLICE_LIT("mainCRTStartup")); Sym exit_name = pool_intern_slice(p, SLICE_LIT(SHIM_SYM_CSTR)); - ObjSecId text = obj_section(ob, text_name, SEC_TEXT, - SF_ALLOC | SF_EXEC, 16); + ObjSecId text = obj_section(ob, text_name, SEC_TEXT, SF_ALLOC | SF_EXEC, 16); obj_write(ob, text, PROG_TEXT_X64, sizeof PROG_TEXT_X64); /* mainCRTStartup at .text offset 0. */ - obj_symbol(ob, main_name, SB_GLOBAL, SK_FUNC, text, 0, - sizeof PROG_TEXT_X64); + obj_symbol(ob, main_name, SB_GLOBAL, SK_FUNC, text, 0, sizeof PROG_TEXT_X64); /* ExitProcess as undef; reloc against the `e8` displacement (offset 1). */ ObjSymId exit_sym = obj_symbol(ob, exit_name, SB_GLOBAL, SK_UNDEF, OBJ_SEC_NONE, 0, 0); @@ -180,8 +178,7 @@ static ObjBuilder* build_program(Compiler* c) { /* ---- objdump probe ------------------------------------------------ */ static int have_mingw_objdump(void) { - FILE* fp = popen( - "command -v x86_64-w64-mingw32-objdump 2>/dev/null", "r"); + FILE* fp = popen("command -v x86_64-w64-mingw32-objdump 2>/dev/null", "r"); if (!fp) return 0; char buf[256]; size_t n = fread(buf, 1, sizeof buf - 1, fp); @@ -254,8 +251,8 @@ int main(void) { Linker* l = link_new(c); EXPECT(l != NULL, "link_new returned NULL"); link_add_obj(l, prog); - LinkInputId dso_id = link_add_obj_bytes( - l, "ExitProcess.lib-member", shim, SHIM_TOTAL_LEN); + LinkInputId dso_id = + link_add_obj_bytes(l, "ExitProcess.lib-member", shim, SHIM_TOTAL_LEN); EXPECT(dso_id != LINK_INPUT_NONE, "link_add_obj_bytes returned LINK_INPUT_NONE for short-import shim"); link_set_entry(l, CFREE_SLICE_LIT("mainCRTStartup")); @@ -327,8 +324,8 @@ int main(void) { link_free(l); /* objdump -p shows headers + import directory. */ - char* dump_p = slurp_cmd( - "x86_64-w64-mingw32-objdump -p /tmp/pe-import-smoke.exe 2>&1"); + char* dump_p = + slurp_cmd("x86_64-w64-mingw32-objdump -p /tmp/pe-import-smoke.exe 2>&1"); EXPECT(dump_p != NULL, "slurp objdump -p"); if (dump_p) { EXPECT(strstr(dump_p, "Magic\t\t\t020b") != NULL || @@ -350,8 +347,8 @@ int main(void) { "objdump -p: Subsystem != Windows CUI\n---\n%s\n---", dump_p); /* Import directory: DLL Name: KERNEL32.dll. */ EXPECT(strstr(dump_p, "DLL Name: " SHIM_DLL_CSTR) != NULL, - "objdump -p: 'DLL Name: %s' not found\n---\n%s\n---", - SHIM_DLL_CSTR, dump_p); + "objdump -p: 'DLL Name: %s' not found\n---\n%s\n---", SHIM_DLL_CSTR, + dump_p); /* The hint/name array prints "<hint> <name>". Check ExitProcess * appears in the import list. */ EXPECT(strstr(dump_p, SHIM_SYM_CSTR) != NULL, @@ -364,8 +361,7 @@ int main(void) { * Reject "00000000 00000000" on those lines. */ { const char* imp_line = strstr(dump_p, "Import Directory"); - EXPECT(imp_line != NULL, - "objdump -p: 'Import Directory' line missing"); + EXPECT(imp_line != NULL, "objdump -p: 'Import Directory' line missing"); if (imp_line) { /* Walk back to start of line. */ const char* ls = imp_line; @@ -375,8 +371,7 @@ int main(void) { "Import Directory data-dir entry is zero\nline: %.*s", (int)(imp_line - ls + (int)strlen("Import Directory")), ls); } - const char* iat_line = - strstr(dump_p, "Import Address Table Directory"); + const char* iat_line = strstr(dump_p, "Import Address Table Directory"); EXPECT(iat_line != NULL, "objdump -p: 'Import Address Table Directory' line missing"); if (iat_line) { @@ -397,13 +392,12 @@ int main(void) { * mainCRTStartup) plus the per-arch IAT stub `jmp *off(%rip)` that * link_emit_coff appends. The PE has no symbol table — there's no * <mainCRTStartup> label in the disassembly, just .text. */ - char* dump_d = slurp_cmd( - "x86_64-w64-mingw32-objdump -d /tmp/pe-import-smoke.exe 2>&1"); + char* dump_d = + slurp_cmd("x86_64-w64-mingw32-objdump -d /tmp/pe-import-smoke.exe 2>&1"); EXPECT(dump_d != NULL, "slurp objdump -d"); if (dump_d) { EXPECT(strstr(dump_d, "<.text>") != NULL, - "objdump -d: <.text> section header missing\n---\n%s\n---", - dump_d); + "objdump -d: <.text> section header missing\n---\n%s\n---", dump_d); /* The mainCRTStartup body is a `call <disp32>` at the entry. The * disp32 must have been patched away from zero by the linker — * objdump renders it as `call 0xNNNNNNNN`, never `call 0x0`. */ diff --git a/test/coff/pe-mixed-archive.c b/test/coff/pe-mixed-archive.c @@ -34,28 +34,30 @@ #include "obj/obj.h" /* ---- short-import wire constants (mirror pe-import-smoke.c). ---- */ -#define SHIM_HEADER_SIZE 20u -#define SHIM_SYM_CSTR "ImportedFn" -#define SHIM_DLL_CSTR "FOO.dll" -#define SHIM_SYM_NUL_LEN 11u /* "ImportedFn\0" */ -#define SHIM_DLL_NUL_LEN 8u /* "FOO.dll\0" */ -#define SHIM_DATA_LEN (SHIM_SYM_NUL_LEN + SHIM_DLL_NUL_LEN) /* 19 */ -#define SHIM_TOTAL_LEN (SHIM_HEADER_SIZE + SHIM_DATA_LEN) /* 39 */ -#define COFF_MACHINE_AMD64 0x8664u -#define COFF_SHIMP_SIG2 0xFFFFu -#define COFF_SHIMP_TYPEFLAGS 0x0004u /* Type=CODE | NameType=NAME */ +#define SHIM_HEADER_SIZE 20u +#define SHIM_SYM_CSTR "ImportedFn" +#define SHIM_DLL_CSTR "FOO.dll" +#define SHIM_SYM_NUL_LEN 11u /* "ImportedFn\0" */ +#define SHIM_DLL_NUL_LEN 8u /* "FOO.dll\0" */ +#define SHIM_DATA_LEN (SHIM_SYM_NUL_LEN + SHIM_DLL_NUL_LEN) /* 19 */ +#define SHIM_TOTAL_LEN (SHIM_HEADER_SIZE + SHIM_DATA_LEN) /* 39 */ +#define COFF_MACHINE_AMD64 0x8664u +#define COFF_SHIMP_SIG2 0xFFFFu +#define COFF_SHIMP_TYPEFLAGS 0x0004u /* Type=CODE | NameType=NAME */ #define HELPER_SYM_CSTR "g_helper_value" /* Program text: two `call disp32` instructions plus `ret`. Each call's * disp32 is patched by the linker via R_PC32 against an undef target. */ static const uint8_t PROG_TEXT_X64[11] = { - 0xe8, 0, 0, 0, 0, /* call ImportedFn */ - 0xe8, 0, 0, 0, 0, /* call g_helper_value (target treated as PC-rel - reference; data symbols can be referenced the - same way for the purposes of this test — the - linker just resolves the symbol address) */ - 0xc3, /* ret */ + 0xe8, 0, 0, + 0, 0, /* call ImportedFn */ + 0xe8, 0, 0, + 0, 0, /* call g_helper_value (target treated as PC-rel + reference; data symbols can be referenced the + same way for the purposes of this test — the + linker just resolves the symbol address) */ + 0xc3, /* ret */ }; /* ---- env vtables --------------------------------------------------- */ @@ -90,14 +92,14 @@ static void diag_emit(CfreeDiagSink* s, CfreeDiagKind k, CfreeSrcLoc loc, static CfreeDiagSink g_diag = {diag_emit, NULL, 0, 0}; static int g_failures; -#define EXPECT(cond, ...) \ - do { \ - if (!(cond)) { \ - fprintf(stderr, "FAIL %s:%d: ", __FILE__, __LINE__); \ - fprintf(stderr, __VA_ARGS__); \ - fputc('\n', stderr); \ - g_failures++; \ - } \ +#define EXPECT(cond, ...) \ + do { \ + if (!(cond)) { \ + fprintf(stderr, "FAIL %s:%d: ", __FILE__, __LINE__); \ + fprintf(stderr, __VA_ARGS__); \ + fputc('\n', stderr); \ + g_failures++; \ + } \ } while (0) /* ---- compiler / target -------------------------------------------- */ @@ -153,12 +155,10 @@ static uint8_t* build_helper_object(Compiler* c, size_t* len_out) { Pool* p = c->global; Sym data_name = pool_intern_slice(p, SLICE_LIT(".data")); Sym helper_name = pool_intern_slice(p, SLICE_LIT(HELPER_SYM_CSTR)); - ObjSecId data = obj_section(ob, data_name, SEC_DATA, - SF_ALLOC | SF_WRITE, 4); + ObjSecId data = obj_section(ob, data_name, SEC_DATA, SF_ALLOC | SF_WRITE, 4); static const uint8_t kHelperBytes[4] = {0x2A, 0x00, 0x00, 0x00}; obj_write(ob, data, kHelperBytes, sizeof kHelperBytes); - obj_symbol(ob, helper_name, SB_GLOBAL, SK_OBJ, data, 0, - sizeof kHelperBytes); + obj_symbol(ob, helper_name, SB_GLOBAL, SK_OBJ, data, 0, sizeof kHelperBytes); obj_finalize(ob); CfreeWriter* w = NULL; @@ -182,11 +182,9 @@ static ObjBuilder* build_program(Compiler* c) { Sym main_name = pool_intern_slice(p, SLICE_LIT("mainCRTStartup")); Sym import_name = pool_intern_slice(p, SLICE_LIT(SHIM_SYM_CSTR)); Sym helper_name = pool_intern_slice(p, SLICE_LIT(HELPER_SYM_CSTR)); - ObjSecId text = obj_section(ob, text_name, SEC_TEXT, - SF_ALLOC | SF_EXEC, 16); + ObjSecId text = obj_section(ob, text_name, SEC_TEXT, SF_ALLOC | SF_EXEC, 16); obj_write(ob, text, PROG_TEXT_X64, sizeof PROG_TEXT_X64); - obj_symbol(ob, main_name, SB_GLOBAL, SK_FUNC, text, 0, - sizeof PROG_TEXT_X64); + obj_symbol(ob, main_name, SB_GLOBAL, SK_FUNC, text, 0, sizeof PROG_TEXT_X64); ObjSymId import_sym = obj_symbol(ob, import_name, SB_GLOBAL, SK_UNDEF, OBJ_SEC_NONE, 0, 0); ObjSymId helper_sym = @@ -276,8 +274,8 @@ int main(void) { Linker* l = link_new(c); EXPECT(l != NULL, "link_new returned NULL"); link_add_obj(l, prog); - LinkInputId ar_id = link_add_archive_bytes(l, "libmixed.a", ar_bytes, - ar_len, /*whole_archive=*/0, + LinkInputId ar_id = link_add_archive_bytes(l, "libmixed.a", ar_bytes, ar_len, + /*whole_archive=*/0, /*link_mode=*/0, /*group_id=*/0); EXPECT(ar_id != LINK_INPUT_NONE, @@ -296,8 +294,10 @@ int main(void) { for (LinkSymId i = 1;; ++i) { const LinkSymbol* s = link_symbol(img, i); if (!s) break; - if (s->name == import_name) importf = s; - else if (s->name == helper_name) helper = s; + if (s->name == import_name) + importf = s; + else if (s->name == helper_name) + helper = s; } EXPECT(importf != NULL, "ImportedFn LinkSymbol not present after link_resolve"); diff --git a/test/debug/cfi_unit.c b/test/debug/cfi_unit.c @@ -154,10 +154,10 @@ static void check_arch(const CfiExpect* ex) { ob = obj_new(c); pool = c->global; - text_sec = obj_section(ob, pool_intern_slice(pool, SLICE_LIT(".text")), SEC_TEXT, - SF_EXEC | SF_ALLOC, 4); - fsym = obj_symbol(ob, pool_intern_slice(pool, SLICE_LIT("f")), SB_GLOBAL, SK_FUNC, - text_sec, 0, 16); + text_sec = obj_section(ob, pool_intern_slice(pool, SLICE_LIT(".text")), + SEC_TEXT, SF_EXEC | SF_ALLOC, 4); + fsym = obj_symbol(ob, pool_intern_slice(pool, SLICE_LIT("f")), SB_GLOBAL, + SK_FUNC, text_sec, 0, 16); mc = mc_new(c, ob); EXPECT(mc != NULL, "[%s] mc_new failed", ex->tag); @@ -263,8 +263,8 @@ static void check_arch(const CfiExpect* ex) { fde_end = off + fde_len; cie_ptr = read_u32le(bytes + off); off += 4; - EXPECT(cie_ptr != 0, - "[%s] FDE CIE_pointer = 0 — would mark this as a CIE", ex->tag); + EXPECT(cie_ptr != 0, "[%s] FDE CIE_pointer = 0 — would mark this as a CIE", + ex->tag); /* initial_location (4 bytes — patched by reloc, here zero) */ off += 4; { @@ -308,8 +308,8 @@ static void check_arch(const CfiExpect* ex) { u64 fac = dec_uleb(bytes, size, &off); /* We passed -8 as the imm and the data align factor is -8, so * factored offset should be 1. */ - EXPECT(fac == 1u, "[%s] FDE offset factor got %u expected 1", - ex->tag, (u32)fac); + EXPECT(fac == 1u, "[%s] FDE offset factor got %u expected 1", ex->tag, + (u32)fac); } } /* Any trailing DW_CFA_nop padding is fine. */ diff --git a/test/debug/roundtrip_unit.c b/test/debug/roundtrip_unit.c @@ -15,8 +15,8 @@ * fields). The end-to-end producer↔consumer round trip is exercised by * test/cg path W. */ -#include <cfree/core.h> #include <cfree/arch.h> +#include <cfree/core.h> #include <stdarg.h> #include <stdio.h> #include <stdlib.h> @@ -112,8 +112,8 @@ static u8 byte_at(const Section* s, u32 ofs) { /* Per-arch nop encoding used by the round-trip test. Both 4 bytes; the * encoders are inlined here so the test stays self-contained. */ -#define ARCH_NOP_AA64 0xd503201fu /* HINT #0 */ -#define ARCH_NOP_RV64 0x00000013u /* ADDI x0, x0, 0 */ +#define ARCH_NOP_AA64 0xd503201fu /* HINT #0 */ +#define ARCH_NOP_RV64 0x00000013u /* ADDI x0, x0, 0 */ static int run_one(CfreeArchKind arch, uint32_t nop_word, const char* tag) { CfreeTarget t; @@ -140,15 +140,15 @@ static int run_one(CfreeArchKind arch, uint32_t nop_word, const char* tag) { pool = c->global; /* .text section + symbol "f". */ - text_sec = obj_section(ob, pool_intern_slice(pool, SLICE_LIT(".text")), SEC_TEXT, - SF_EXEC | SF_ALLOC, 4); + text_sec = obj_section(ob, pool_intern_slice(pool, SLICE_LIT(".text")), + SEC_TEXT, SF_EXEC | SF_ALLOC, 4); /* one 4-byte arch nop */ { u32 nop = nop_word; obj_write(ob, text_sec, &nop, 4); } - fsym = obj_symbol(ob, pool_intern_slice(pool, SLICE_LIT("f")), SB_GLOBAL, SK_FUNC, - text_sec, 0, 4); + fsym = obj_symbol(ob, pool_intern_slice(pool, SLICE_LIT("f")), SB_GLOBAL, + SK_FUNC, text_sec, 0, 4); /* Drive Debug. */ d = debug_new(c, ob); @@ -163,8 +163,8 @@ static int run_one(CfreeArchKind arch, uint32_t nop_word, const char* tag) { (void)source_add_memory(c->sources, SLICE_LIT("p01.c"), &fid); SrcLoc decl = {fid, 1, 0}; SrcLoc l10 = {fid, 10, 0}; - DebugTypeId int_tid = - debug_type_base(d, pool_intern_slice(pool, SLICE_LIT("int")), DEBUG_BE_SIGNED, 4); + DebugTypeId int_tid = debug_type_base( + d, pool_intern_slice(pool, SLICE_LIT("int")), DEBUG_BE_SIGNED, 4); DebugTypeId fn_tid = debug_type_func(d, int_tid, NULL, 0, 0); /* Pre-register the file as DWARF index 0 = primary. */ (void)debug_file(d, fid); @@ -206,8 +206,7 @@ static int run_one(CfreeArchKind arch, uint32_t nop_word, const char* tag) { /* version */ EXPECT(le16(line, 4) == 5, "[%s] .debug_line version != 5", tag); /* address_size */ - EXPECT(byte_at(line, 6) == 8, - "[%s] .debug_line address_size != 8", tag); + EXPECT(byte_at(line, 6) == 8, "[%s] .debug_line address_size != 8", tag); /* segment selector size */ EXPECT(byte_at(line, 7) == 0, "[%s] .debug_line seg_size != 0", tag); /* DWARF 5 §6.2.4: header is unit_length(4) + version(2) + @@ -219,8 +218,8 @@ static int run_one(CfreeArchKind arch, uint32_t nop_word, const char* tag) { "[%s] .debug_line min_inst_length != 4 (got %u)", tag, byte_at(line, 12)); /* max_ops_per_inst at offset 13. */ - EXPECT(byte_at(line, 13) == 1, - "[%s] .debug_line max_ops_per_inst != 1", tag); + EXPECT(byte_at(line, 13) == 1, "[%s] .debug_line max_ops_per_inst != 1", + tag); } if (info) { u32 ul = le32(info, 0); @@ -230,8 +229,7 @@ static int run_one(CfreeArchKind arch, uint32_t nop_word, const char* tag) { EXPECT(le16(info, 4) == 5, "[%s] .debug_info version != 5", tag); EXPECT(byte_at(info, 6) == 1, "[%s] .debug_info unit_type != DW_UT_compile", tag); - EXPECT(byte_at(info, 7) == 8, - "[%s] .debug_info address_size != 8", tag); + EXPECT(byte_at(info, 7) == 8, "[%s] .debug_info address_size != 8", tag); } if (str) { /* Should contain "cfree 0.1\0" somewhere. */ @@ -255,8 +253,7 @@ static int run_one(CfreeArchKind arch, uint32_t nop_word, const char* tag) { } if (rng) { EXPECT(le16(rng, 4) == 5, "[%s] .debug_rnglists version != 5", tag); - EXPECT(byte_at(rng, 6) == 8, - "[%s] .debug_rnglists addr_size != 8", tag); + EXPECT(byte_at(rng, 6) == 8, "[%s] .debug_rnglists addr_size != 8", tag); } if (aranges) { EXPECT(le16(aranges, 4) == 2, "[%s] .debug_aranges version != 2", tag); @@ -322,11 +319,11 @@ static void run_arch_register_checks(void) { /* "fp" alias for s0/x8 on rv64. */ { uint32_t idx = 0; - CfreeStatus st = cfree_arch_register_index( - CFREE_ARCH_RV64, CFREE_SLICE_LIT("fp"), &idx); + CfreeStatus st = + cfree_arch_register_index(CFREE_ARCH_RV64, CFREE_SLICE_LIT("fp"), &idx); EXPECT(st == CFREE_OK && idx == 8, - "[rv64] register_index(fp) expected 8, got %u (status %d)", - idx, (int)st); + "[rv64] register_index(fp) expected 8, got %u (status %d)", idx, + (int)st); } } @@ -353,14 +350,14 @@ static int run_x64_debug_line_check(void) { xob = obj_new(xc); xpool = xc->global; - xtext_sec = obj_section(xob, pool_intern_slice(xpool, SLICE_LIT(".text")), SEC_TEXT, - SF_EXEC | SF_ALLOC, 1); + xtext_sec = obj_section(xob, pool_intern_slice(xpool, SLICE_LIT(".text")), + SEC_TEXT, SF_EXEC | SF_ALLOC, 1); { u8 code[2] = {0x90, 0xc3}; /* nop; ret */ obj_write(xob, xtext_sec, code, sizeof(code)); } - xfsym = obj_symbol(xob, pool_intern_slice(xpool, SLICE_LIT("xf")), SB_GLOBAL, SK_FUNC, - xtext_sec, 0, 2); + xfsym = obj_symbol(xob, pool_intern_slice(xpool, SLICE_LIT("xf")), SB_GLOBAL, + SK_FUNC, xtext_sec, 0, 2); xd = debug_new(xc, xob); EXPECT(xd != NULL, "x64 debug_new returned NULL"); @@ -386,8 +383,7 @@ static int run_x64_debug_line_check(void) { const Section* xline = sec_by_name(xob, xpool, ".debug_line"); EXPECT(xline != NULL, "x64 .debug_line missing"); if (xline) { - EXPECT(byte_at(xline, 12) == 1, - "x64 .debug_line min_inst_length != 1"); + EXPECT(byte_at(xline, 12) == 1, "x64 .debug_line min_inst_length != 1"); } } diff --git a/test/dwarf/dwarf_test.c b/test/dwarf/dwarf_test.c @@ -847,7 +847,8 @@ static void run_tests(CfreeDebugInfo* di) { /* 10. loc_read REG fast path: pull arg via a fake unwind frame. */ { CfreeDwarfVarLoc varg; - if (cfree_dwarf_var_at(di, 0x1000, CFREE_SLICE_LIT("arg"), &varg) == CFREE_OK) { + if (cfree_dwarf_var_at(di, 0x1000, CFREE_SLICE_LIT("arg"), &varg) == + CFREE_OK) { CfreeUnwindFrame fr; uint32_t v32 = 0; size_t got = 0; @@ -1020,8 +1021,10 @@ int main(void) { in.data = obj_bytes; in.len = obj_len; CfreeObjFile* obj = NULL; - EXPECT(cfree_obj_open(&ctx, CFREE_SLICE_LIT("test.o"), &in, &obj) == CFREE_OK && obj != NULL, - "cfree_obj_open failed"); + EXPECT( + cfree_obj_open(&ctx, CFREE_SLICE_LIT("test.o"), &in, &obj) == CFREE_OK && + obj != NULL, + "cfree_obj_open failed"); if (obj) { CfreeDebugInfo* di = NULL; EXPECT(cfree_dwarf_open(&ctx, obj, &di) == CFREE_OK && di != NULL, diff --git a/test/elf/unit/align_4k.c b/test/elf/unit/align_4k.c @@ -68,8 +68,11 @@ int main(void) { return 1; } - CfreeContext ctx = {.heap = &g_heap, .file_io = NULL, .diag = &g_diag, - .metrics = NULL, .now = -1}; + CfreeContext ctx = {.heap = &g_heap, + .file_io = NULL, + .diag = &g_diag, + .metrics = NULL, + .now = -1}; CfreeCompiler* cc = NULL; if (cfree_compiler_new(target, &ctx, &cc) != CFREE_OK || !cc) { fprintf(stderr, "FAIL: cfree_compiler_new\n"); @@ -101,8 +104,7 @@ int main(void) { .value = 0, .size = sizeof TEXT_BYTES, }; - CHECK(cfree_obj_builder_symbol(in, &f_desc, &sym_f) == CFREE_OK, - "symbol f"); + CHECK(cfree_obj_builder_symbol(in, &f_desc, &sym_f) == CFREE_OK, "symbol f"); CHECK(cfree_obj_builder_finalize(in) == CFREE_OK, "finalize"); CfreeWriter* w = NULL; @@ -117,7 +119,7 @@ int main(void) { CfreeSlice input = {.data = roundtrip, .len = out_len}; CfreeObjFile* back = NULL; CHECK(cfree_obj_open(&ctx, CFREE_SLICE_LIT("align_4k"), &input, &back) == - CFREE_OK && + CFREE_OK && back, "cfree_obj_open failed"); diff --git a/test/elf/unit/groupiter.c b/test/elf/unit/groupiter.c @@ -149,18 +149,20 @@ int main(void) { CfreeSlice input = {.data = roundtrip, .len = out_len}; CfreeObjFile* f = NULL; - CHECK(cfree_obj_open(&ctx, CFREE_SLICE_LIT("groupiter"), &input, &f) == CFREE_OK && f, + CHECK(cfree_obj_open(&ctx, CFREE_SLICE_LIT("groupiter"), &input, &f) == + CFREE_OK && + f, "cfree_obj_open failed"); if (f) { /* Resolve section IDs by name so the test isn't coupled to ordering. */ CfreeObjSection text_pub = CFREE_SECTION_NONE; CfreeObjSection data_pub = CFREE_SECTION_NONE; - CHECK(cfree_obj_section_by_name(f, CFREE_SLICE_LIT(".text.comdat_fn"), &text_pub) == - CFREE_OK, + CHECK(cfree_obj_section_by_name(f, CFREE_SLICE_LIT(".text.comdat_fn"), + &text_pub) == CFREE_OK, "section_by_name .text.comdat_fn"); - CHECK(cfree_obj_section_by_name(f, CFREE_SLICE_LIT(".data.comdat_fn"), &data_pub) == - CFREE_OK, + CHECK(cfree_obj_section_by_name(f, CFREE_SLICE_LIT(".data.comdat_fn"), + &data_pub) == CFREE_OK, "section_by_name .data.comdat_fn"); CfreeObjGroupIter* git = NULL; diff --git a/test/elf/unit/mutate.c b/test/elf/unit/mutate.c @@ -86,7 +86,8 @@ int main(void) { CHECK(cfree_obj_builder_new(cc, &ob) == CFREE_OK && ob, "cfree_obj_builder_new"); - CfreeSym entry_new_nm = cfree_sym_intern(cc, CFREE_SLICE_LIT("renamed_entry")); + CfreeSym entry_new_nm = + cfree_sym_intern(cc, CFREE_SLICE_LIT("renamed_entry")); CfreeObjSection sec_text = CFREE_SECTION_NONE; CfreeObjSection sec_data = CFREE_SECTION_NONE; @@ -162,8 +163,7 @@ int main(void) { .value = 0, .size = 0, }; - CHECK(cfree_obj_builder_symbol(ob, &spurious_desc, &sym_spurious) == - CFREE_OK, + CHECK(cfree_obj_builder_symbol(ob, &spurious_desc, &sym_spurious) == CFREE_OK, "symbol spurious_extern"); (void)sym_spurious; @@ -196,9 +196,9 @@ int main(void) { /* ---- mutate via the public API ---- */ CHECK(cfree_obj_builder_remove_section(ob, sec_data) == CFREE_OK, "remove_section .data"); - CHECK(cfree_obj_builder_rename_symbol(ob, sym_entry, entry_new_nm) == - CFREE_OK, - "rename_symbol entry -> renamed_entry"); + CHECK( + cfree_obj_builder_rename_symbol(ob, sym_entry, entry_new_nm) == CFREE_OK, + "rename_symbol entry -> renamed_entry"); CHECK(cfree_obj_builder_symbol_set_bind(ob, sym_keep, CFREE_SB_LOCAL) == CFREE_OK, "set_bind keep_global -> local"); @@ -216,7 +216,10 @@ int main(void) { CfreeSlice input = {.data = roundtrip, .len = out_len}; CfreeObjFile* f = NULL; - CHECK(cfree_obj_open(&ctx, CFREE_SLICE_LIT("mutate"), &input, &f) == CFREE_OK && f, "reopen"); + CHECK( + cfree_obj_open(&ctx, CFREE_SLICE_LIT("mutate"), &input, &f) == CFREE_OK && + f, + "reopen"); if (f) { /* .data should be gone. */ @@ -227,25 +230,29 @@ int main(void) { /* .text should remain. */ CfreeObjSection s_text = CFREE_SECTION_NONE; - CHECK(cfree_obj_section_by_name(f, CFREE_SLICE_LIT(".text"), &s_text) == CFREE_OK, + CHECK(cfree_obj_section_by_name(f, CFREE_SLICE_LIT(".text"), &s_text) == + CFREE_OK, ".text missing after roundtrip"); /* Renamed entry symbol is present; old name is gone. */ CfreeObjSymInfo si; - CHECK(cfree_obj_symbol_by_name(f, CFREE_SLICE_LIT("renamed_entry"), &si) == CFREE_OK, + CHECK(cfree_obj_symbol_by_name(f, CFREE_SLICE_LIT("renamed_entry"), &si) == + CFREE_OK, "renamed_entry not found"); - CHECK(cfree_obj_symbol_by_name(f, CFREE_SLICE_LIT("entry"), &si) == CFREE_NOT_FOUND, + CHECK(cfree_obj_symbol_by_name(f, CFREE_SLICE_LIT("entry"), &si) == + CFREE_NOT_FOUND, "old 'entry' symbol survived rename"); /* keep_global was localized; reads back as SB_LOCAL. */ - CHECK(cfree_obj_symbol_by_name(f, CFREE_SLICE_LIT("keep_global"), &si) == CFREE_OK, + CHECK(cfree_obj_symbol_by_name(f, CFREE_SLICE_LIT("keep_global"), &si) == + CFREE_OK, "keep_global lost"); CHECK(si.bind == CFREE_SB_LOCAL, "keep_global bind=%d, want LOCAL=%d", (int)si.bind, (int)CFREE_SB_LOCAL); /* Spurious extern was pruned by the sweep. */ - CHECK(cfree_obj_symbol_by_name(f, CFREE_SLICE_LIT("spurious_extern"), &si) == - CFREE_NOT_FOUND, + CHECK(cfree_obj_symbol_by_name(f, CFREE_SLICE_LIT("spurious_extern"), + &si) == CFREE_NOT_FOUND, "spurious_extern survived sweep"); /* foo_ref was the target of a reloc, but its containing section @@ -254,7 +261,8 @@ int main(void) { * when the relocation is created, BUT the reloc is then dropped at * sweep. The symbol's `referenced` flag remains set, so foo_ref survives * as a plain UNDEF. */ - CHECK(cfree_obj_symbol_by_name(f, CFREE_SLICE_LIT("foo_ref"), &si) == CFREE_OK, + CHECK(cfree_obj_symbol_by_name(f, CFREE_SLICE_LIT("foo_ref"), &si) == + CFREE_OK, "foo_ref UNDEF should survive"); /* No relocs should remain — all were in the removed .data. */ diff --git a/test/elf/unit/smoke.c b/test/elf/unit/smoke.c @@ -141,8 +141,7 @@ static CfreeObjBuilder* build_input(CfreeCompiler* c, CfreeTarget target) { .symbol = sym_foo, .addend = 0, }; - CHECK(cfree_obj_builder_reloc(ob, &reloc_desc) == CFREE_OK, - "reloc .data"); + CHECK(cfree_obj_builder_reloc(ob, &reloc_desc) == CFREE_OK, "reloc .data"); CHECK(cfree_obj_builder_finalize(ob) == CFREE_OK, "finalize"); return ob; @@ -153,12 +152,12 @@ static CfreeObjBuilder* build_input(CfreeCompiler* c, CfreeTarget target) { static void verify_shape(CfreeObjFile* f) { CfreeObjSection text = CFREE_SECTION_NONE; CfreeObjSection data = CFREE_SECTION_NONE; - CHECK(cfree_obj_section_by_name(f, CFREE_SLICE_LIT(".text"), &text) == - CFREE_OK, - ".text not present after roundtrip"); - CHECK(cfree_obj_section_by_name(f, CFREE_SLICE_LIT(".data"), &data) == - CFREE_OK, - ".data not present after roundtrip"); + CHECK( + cfree_obj_section_by_name(f, CFREE_SLICE_LIT(".text"), &text) == CFREE_OK, + ".text not present after roundtrip"); + CHECK( + cfree_obj_section_by_name(f, CFREE_SLICE_LIT(".data"), &data) == CFREE_OK, + ".data not present after roundtrip"); if (text != CFREE_SECTION_NONE) { CfreeObjSecInfo si; @@ -169,12 +168,14 @@ static void verify_shape(CfreeObjFile* f) { CFREE_SEC_TEXT); CHECK((si.flags & CFREE_SF_EXEC) != 0, ".text missing SF_EXEC"); CHECK((si.flags & CFREE_SF_ALLOC) != 0, ".text missing SF_ALLOC"); - CHECK(si.size == sizeof TEXT_BYTES, ".text size mismatch: got %llu, want %zu", + CHECK(si.size == sizeof TEXT_BYTES, + ".text size mismatch: got %llu, want %zu", (unsigned long long)si.size, sizeof TEXT_BYTES); CHECK(cfree_obj_section_data(f, text, &bytes, &len) == CFREE_OK, "section_data .text"); - CHECK(len == sizeof TEXT_BYTES, ".text data size mismatch: got %zu, want %zu", - len, sizeof TEXT_BYTES); + CHECK(len == sizeof TEXT_BYTES, + ".text data size mismatch: got %zu, want %zu", len, + sizeof TEXT_BYTES); if (len == sizeof TEXT_BYTES) { CHECK(memcmp(bytes, TEXT_BYTES, sizeof TEXT_BYTES) == 0, ".text bytes do not match input"); @@ -193,9 +194,9 @@ static void verify_shape(CfreeObjFile* f) { CHECK(cfree_obj_symbol_by_name(f, CFREE_SLICE_LIT("main"), &main_si) == CFREE_OK, "missing 'main' symbol"); - CHECK(cfree_obj_symbol_by_name(f, CFREE_SLICE_LIT("foo"), &foo_si) == - CFREE_OK, - "missing 'foo' symbol"); + CHECK( + cfree_obj_symbol_by_name(f, CFREE_SLICE_LIT("foo"), &foo_si) == CFREE_OK, + "missing 'foo' symbol"); if (cfree_obj_symbol_by_name(f, CFREE_SLICE_LIT("main"), &main_si) == CFREE_OK) { CHECK(main_si.bind == CFREE_SB_GLOBAL, "main bind=%u", main_si.bind); @@ -287,7 +288,7 @@ int main(void) { CfreeSlice input = {.data = roundtrip, .len = out_len}; CfreeObjFile* back = NULL; CHECK(cfree_obj_open(&ctx, CFREE_SLICE_LIT("smoke"), &input, &back) == - CFREE_OK && + CFREE_OK && back, "cfree_obj_open failed"); if (back) verify_shape(back); diff --git a/test/elf/unit/x64_disasm_annotations.c b/test/elf/unit/x64_disasm_annotations.c @@ -112,9 +112,9 @@ static CfreeObjBuilder* build_input(CfreeCompiler* c, CfreeTarget target) { .value = 5, .size = 0, }; - CHECK(cfree_obj_builder_symbol(ob, &load_data_desc, &sym_load_data) == - CFREE_OK, - "symbol load_data"); + CHECK( + cfree_obj_builder_symbol(ob, &load_data_desc, &sym_load_data) == CFREE_OK, + "symbol load_data"); CfreeObjSymbol sym_foo = CFREE_OBJ_SYMBOL_NONE; CfreeObjSymbolDesc foo_desc = { @@ -188,14 +188,18 @@ static CfreeObjBuilder* build_input(CfreeCompiler* c, CfreeTarget target) { return ob; } -static void check_reloc_names(const CfreeSlice* bytes, const CfreeContext* ctx) { +static void check_reloc_names(const CfreeSlice* bytes, + const CfreeContext* ctx) { CfreeObjFile* f = NULL; CfreeObjRelocIter* it = NULL; CfreeObjReloc r; int saw_plt32 = 0; int saw_pc32 = 0; - CHECK(cfree_obj_open(ctx, CFREE_SLICE_LIT("x64_disasm_annotations.o"), bytes, &f) == CFREE_OK && f, "cfree_obj_open"); + CHECK(cfree_obj_open(ctx, CFREE_SLICE_LIT("x64_disasm_annotations.o"), bytes, + &f) == CFREE_OK && + f, + "cfree_obj_open"); if (!f) return; CHECK(cfree_obj_reliter_new(f, &it) == CFREE_OK && it, "reliter_new"); if (!it) { diff --git a/test/emu/rv64_smoke_test.c b/test/emu/rv64_smoke_test.c @@ -313,15 +313,13 @@ static void put_phdr(unsigned char* b, size_t off, uint32_t type, put64(b, off + 48, align); } -static void put_dyn(unsigned char* b, size_t off, uint64_t tag, - uint64_t val) { +static void put_dyn(unsigned char* b, size_t off, uint64_t tag, uint64_t val) { put64(b, off + 0, tag); put64(b, off + 8, val); } -static void put_sym(unsigned char* b, size_t off, uint32_t name, - uint8_t info, uint16_t shndx, uint64_t value, - uint64_t size) { +static void put_sym(unsigned char* b, size_t off, uint32_t name, uint8_t info, + uint16_t shndx, uint64_t value, uint64_t size) { put32(b, off + 0, name); b[off + 4] = info; b[off + 5] = 0; @@ -426,9 +424,10 @@ static unsigned char* build_minimal_elf(size_t* out_len) { /* Dynamic fixture for the intended emu loader surface: * PT_INTERP + PT_DYNAMIC + DT_NEEDED + JUMP_SLOT import + PT_TLS. * - * The import resolver is expected to fill `import_add_got` with a guest-callable - * thunk for import_add(a0). The TLS setup is expected to seed tp so that - * ld t1, 0(tp) reads the PT_TLS initializer 11. The guest exits 31 + 11. */ + * The import resolver is expected to fill `import_add_got` with a + * guest-callable thunk for import_add(a0). The TLS setup is expected to seed tp + * so that ld t1, 0(tp) reads the PT_TLS initializer 11. The guest exits 31 + * + 11. */ static unsigned char* build_dynamic_import_tls_elf(size_t* out_len) { enum { PAGE = 0x1000u, @@ -486,13 +485,12 @@ static unsigned char* build_dynamic_import_tls_elf(size_t* out_len) { put_phdr(b, 64 + 1u * ELF64_PHDR_SIZE, PT_LOAD, PF_R | PF_W, DYNAMIC_OFF, dynamic_va, TLS_OFF + 8u - DYNAMIC_OFF, TLS_OFF + 8u - DYNAMIC_OFF, PAGE); - put_phdr(b, 64 + 2u * ELF64_PHDR_SIZE, PT_INTERP, PF_R, INTERP_OFF, - interp_va, sizeof(interp), sizeof(interp), 1u); - put_phdr(b, 64 + 3u * ELF64_PHDR_SIZE, PT_DYNAMIC, PF_R | PF_W, - DYNAMIC_OFF, dynamic_va, 10u * ELF64_DYN_SIZE, - 10u * ELF64_DYN_SIZE, 8u); - put_phdr(b, 64 + 4u * ELF64_PHDR_SIZE, PT_TLS, PF_R, TLS_OFF, tls_va, 8u, - 8u, 8u); + put_phdr(b, 64 + 2u * ELF64_PHDR_SIZE, PT_INTERP, PF_R, INTERP_OFF, interp_va, + sizeof(interp), sizeof(interp), 1u); + put_phdr(b, 64 + 3u * ELF64_PHDR_SIZE, PT_DYNAMIC, PF_R | PF_W, DYNAMIC_OFF, + dynamic_va, 10u * ELF64_DYN_SIZE, 10u * ELF64_DYN_SIZE, 8u); + put_phdr(b, 64 + 4u * ELF64_PHDR_SIZE, PT_TLS, PF_R, TLS_OFF, tls_va, 8u, 8u, + 8u); put32(b, TEXT_OFF + 0u, rv_auipc(RV_T0, rv_pcrel_hi(text_va, got_va))); put32(b, TEXT_OFF + 4u, rv_ld(RV_T0, RV_T0, rv_pcrel_lo(text_va, got_va))); @@ -515,18 +513,15 @@ static unsigned char* build_dynamic_import_tls_elf(size_t* out_len) { ELF64_ST_INFO(STB_GLOBAL, STT_FUNC), SHN_UNDEF, 0, 0); put_rela(b, RELA_OFF, got_va, ELF64_R_INFO(1u, ELF_R_RISCV_JUMP_SLOT), 0); - put_dyn(b, DYNAMIC_OFF + 0u * ELF64_DYN_SIZE, DT_NEEDED, - dynstr_needed_off); + put_dyn(b, DYNAMIC_OFF + 0u * ELF64_DYN_SIZE, DT_NEEDED, dynstr_needed_off); put_dyn(b, DYNAMIC_OFF + 1u * ELF64_DYN_SIZE, DT_STRTAB, dynstr_va); put_dyn(b, DYNAMIC_OFF + 2u * ELF64_DYN_SIZE, DT_STRSZ, dynstr_len); put_dyn(b, DYNAMIC_OFF + 3u * ELF64_DYN_SIZE, DT_SYMTAB, dynsym_va); put_dyn(b, DYNAMIC_OFF + 4u * ELF64_DYN_SIZE, DT_SYMENT, ELF64_SYM_SIZE); put_dyn(b, DYNAMIC_OFF + 5u * ELF64_DYN_SIZE, DT_PLTREL, DT_RELA); put_dyn(b, DYNAMIC_OFF + 6u * ELF64_DYN_SIZE, DT_JMPREL, rela_va); - put_dyn(b, DYNAMIC_OFF + 7u * ELF64_DYN_SIZE, DT_PLTRELSZ, - ELF64_RELA_SIZE); - put_dyn(b, DYNAMIC_OFF + 8u * ELF64_DYN_SIZE, DT_RELAENT, - ELF64_RELA_SIZE); + put_dyn(b, DYNAMIC_OFF + 7u * ELF64_DYN_SIZE, DT_PLTRELSZ, ELF64_RELA_SIZE); + put_dyn(b, DYNAMIC_OFF + 8u * ELF64_DYN_SIZE, DT_RELAENT, ELF64_RELA_SIZE); put_dyn(b, DYNAMIC_OFF + 9u * ELF64_DYN_SIZE, DT_NULL, 0); put64(b, TLS_OFF, 11u); @@ -568,14 +563,13 @@ static unsigned char* build_tls_distinct_elf(size_t* out_len) { put_phdr(b, 64 + 0u * ELF64_PHDR_SIZE, PT_LOAD, PF_R | PF_X, 0, BASE_VA, TEXT_OFF + 40u, TEXT_OFF + 40u, PAGE); - put_phdr(b, 64 + 1u * ELF64_PHDR_SIZE, PT_LOAD, PF_R | PF_W, TLS_OFF, - tls_va, 16u, 16u, PAGE); - put_phdr(b, 64 + 2u * ELF64_PHDR_SIZE, PT_TLS, PF_R, TLS_OFF, tls_va, 8u, - 16u, 8u); + put_phdr(b, 64 + 1u * ELF64_PHDR_SIZE, PT_LOAD, PF_R | PF_W, TLS_OFF, tls_va, + 16u, 16u, PAGE); + put_phdr(b, 64 + 2u * ELF64_PHDR_SIZE, PT_TLS, PF_R, TLS_OFF, tls_va, 8u, 16u, + 8u); put32(b, TEXT_OFF + 0u, rv_auipc(RV_T0, rv_pcrel_hi(text_va, tls_va))); - put32(b, TEXT_OFF + 4u, - rv_addi(RV_T0, RV_T0, rv_pcrel_lo(text_va, tls_va))); + put32(b, TEXT_OFF + 4u, rv_addi(RV_T0, RV_T0, rv_pcrel_lo(text_va, tls_va))); put32(b, TEXT_OFF + 8u, rv_addi(RV_T1, RV_ZERO, 9)); put32(b, TEXT_OFF + 12u, rv_sd(RV_T1, RV_TP, 0)); put32(b, TEXT_OFF + 16u, rv_ld(RV_A0, RV_T0, 0)); @@ -639,9 +633,8 @@ static unsigned char* build_host_import_elf(size_t* out_len) { put_phdr(b, 64 + 1u * ELF64_PHDR_SIZE, PT_LOAD, PF_R | PF_W, DYNAMIC_OFF, dynamic_va, GOT_OFF + 8u - DYNAMIC_OFF, GOT_OFF + 8u - DYNAMIC_OFF, PAGE); - put_phdr(b, 64 + 2u * ELF64_PHDR_SIZE, PT_DYNAMIC, PF_R | PF_W, - DYNAMIC_OFF, dynamic_va, 10u * ELF64_DYN_SIZE, - 10u * ELF64_DYN_SIZE, 8u); + put_phdr(b, 64 + 2u * ELF64_PHDR_SIZE, PT_DYNAMIC, PF_R | PF_W, DYNAMIC_OFF, + dynamic_va, 10u * ELF64_DYN_SIZE, 10u * ELF64_DYN_SIZE, 8u); put32(b, TEXT_OFF + 0u, rv_auipc(RV_T0, rv_pcrel_hi(text_va, got_va))); put32(b, TEXT_OFF + 4u, rv_ld(RV_T0, RV_T0, rv_pcrel_lo(text_va, got_va))); @@ -660,18 +653,15 @@ static unsigned char* build_host_import_elf(size_t* out_len) { put_sym(b, DYNSYM_OFF + ELF64_SYM_SIZE, (uint32_t)dynstr_import_off, ELF64_ST_INFO(STB_GLOBAL, STT_FUNC), SHN_UNDEF, 0, 0); put_rela(b, RELA_OFF, got_va, ELF64_R_INFO(1u, ELF_R_RISCV_JUMP_SLOT), 0); - put_dyn(b, DYNAMIC_OFF + 0u * ELF64_DYN_SIZE, DT_NEEDED, - dynstr_needed_off); + put_dyn(b, DYNAMIC_OFF + 0u * ELF64_DYN_SIZE, DT_NEEDED, dynstr_needed_off); put_dyn(b, DYNAMIC_OFF + 1u * ELF64_DYN_SIZE, DT_STRTAB, dynstr_va); put_dyn(b, DYNAMIC_OFF + 2u * ELF64_DYN_SIZE, DT_STRSZ, dynstr_len); put_dyn(b, DYNAMIC_OFF + 3u * ELF64_DYN_SIZE, DT_SYMTAB, dynsym_va); put_dyn(b, DYNAMIC_OFF + 4u * ELF64_DYN_SIZE, DT_SYMENT, ELF64_SYM_SIZE); put_dyn(b, DYNAMIC_OFF + 5u * ELF64_DYN_SIZE, DT_PLTREL, DT_RELA); put_dyn(b, DYNAMIC_OFF + 6u * ELF64_DYN_SIZE, DT_JMPREL, rela_va); - put_dyn(b, DYNAMIC_OFF + 7u * ELF64_DYN_SIZE, DT_PLTRELSZ, - ELF64_RELA_SIZE); - put_dyn(b, DYNAMIC_OFF + 8u * ELF64_DYN_SIZE, DT_RELAENT, - ELF64_RELA_SIZE); + put_dyn(b, DYNAMIC_OFF + 7u * ELF64_DYN_SIZE, DT_PLTRELSZ, ELF64_RELA_SIZE); + put_dyn(b, DYNAMIC_OFF + 8u * ELF64_DYN_SIZE, DT_RELAENT, ELF64_RELA_SIZE); put_dyn(b, DYNAMIC_OFF + 9u * ELF64_DYN_SIZE, DT_NULL, 0); *out_len = TOTAL; return b; @@ -727,9 +717,8 @@ static unsigned char* build_dso_import_main_elf(size_t* out_len) { put_phdr(b, 64 + 1u * ELF64_PHDR_SIZE, PT_LOAD, PF_R | PF_W, DYNAMIC_OFF, dynamic_va, GOT_OFF + 8u - DYNAMIC_OFF, GOT_OFF + 8u - DYNAMIC_OFF, PAGE); - put_phdr(b, 64 + 2u * ELF64_PHDR_SIZE, PT_DYNAMIC, PF_R | PF_W, - DYNAMIC_OFF, dynamic_va, 10u * ELF64_DYN_SIZE, - 10u * ELF64_DYN_SIZE, 8u); + put_phdr(b, 64 + 2u * ELF64_PHDR_SIZE, PT_DYNAMIC, PF_R | PF_W, DYNAMIC_OFF, + dynamic_va, 10u * ELF64_DYN_SIZE, 10u * ELF64_DYN_SIZE, 8u); put32(b, TEXT_OFF + 0u, rv_auipc(RV_T0, rv_pcrel_hi(text_va, got_va))); put32(b, TEXT_OFF + 4u, rv_ld(RV_T0, RV_T0, rv_pcrel_lo(text_va, got_va))); @@ -747,18 +736,15 @@ static unsigned char* build_dso_import_main_elf(size_t* out_len) { put_sym(b, DYNSYM_OFF + ELF64_SYM_SIZE, (uint32_t)dynstr_import_off, ELF64_ST_INFO(STB_GLOBAL, STT_FUNC), SHN_UNDEF, 0, 0); put_rela(b, RELA_OFF, got_va, ELF64_R_INFO(1u, ELF_R_RISCV_JUMP_SLOT), 0); - put_dyn(b, DYNAMIC_OFF + 0u * ELF64_DYN_SIZE, DT_NEEDED, - dynstr_needed_off); + put_dyn(b, DYNAMIC_OFF + 0u * ELF64_DYN_SIZE, DT_NEEDED, dynstr_needed_off); put_dyn(b, DYNAMIC_OFF + 1u * ELF64_DYN_SIZE, DT_STRTAB, dynstr_va); put_dyn(b, DYNAMIC_OFF + 2u * ELF64_DYN_SIZE, DT_STRSZ, dynstr_len); put_dyn(b, DYNAMIC_OFF + 3u * ELF64_DYN_SIZE, DT_SYMTAB, dynsym_va); put_dyn(b, DYNAMIC_OFF + 4u * ELF64_DYN_SIZE, DT_SYMENT, ELF64_SYM_SIZE); put_dyn(b, DYNAMIC_OFF + 5u * ELF64_DYN_SIZE, DT_PLTREL, DT_RELA); put_dyn(b, DYNAMIC_OFF + 6u * ELF64_DYN_SIZE, DT_JMPREL, rela_va); - put_dyn(b, DYNAMIC_OFF + 7u * ELF64_DYN_SIZE, DT_PLTRELSZ, - ELF64_RELA_SIZE); - put_dyn(b, DYNAMIC_OFF + 8u * ELF64_DYN_SIZE, DT_RELAENT, - ELF64_RELA_SIZE); + put_dyn(b, DYNAMIC_OFF + 7u * ELF64_DYN_SIZE, DT_PLTRELSZ, ELF64_RELA_SIZE); + put_dyn(b, DYNAMIC_OFF + 8u * ELF64_DYN_SIZE, DT_RELAENT, ELF64_RELA_SIZE); put_dyn(b, DYNAMIC_OFF + 9u * ELF64_DYN_SIZE, DT_NULL, 0); *out_len = TOTAL; return b; @@ -816,9 +802,8 @@ static unsigned char* build_dso_import_so(size_t* out_len) { put_phdr(b, 64 + 1u * ELF64_PHDR_SIZE, PT_LOAD, PF_R | PF_W, DYNAMIC_OFF, dynamic_va, DATA_OFF + 16u - DYNAMIC_OFF, DATA_OFF + 16u - DYNAMIC_OFF, PAGE); - put_phdr(b, 64 + 2u * ELF64_PHDR_SIZE, PT_DYNAMIC, PF_R | PF_W, - DYNAMIC_OFF, dynamic_va, 10u * ELF64_DYN_SIZE, - 10u * ELF64_DYN_SIZE, 8u); + put_phdr(b, 64 + 2u * ELF64_PHDR_SIZE, PT_DYNAMIC, PF_R | PF_W, DYNAMIC_OFF, + dynamic_va, 10u * ELF64_DYN_SIZE, 10u * ELF64_DYN_SIZE, 8u); put32(b, TEXT_OFF + 0u, rv_auipc(RV_T0, rv_pcrel_hi(text_va, ptr_va))); put32(b, TEXT_OFF + 4u, rv_ld(RV_T0, RV_T0, rv_pcrel_lo(text_va, ptr_va))); @@ -841,18 +826,15 @@ static unsigned char* build_dso_import_so(size_t* out_len) { put_rela(b, RELA_OFF, ptr_va, ELF64_R_INFO(0u, ELF_R_RISCV_RELATIVE), (int64_t)value_va); put64(b, DATA_OFF + 8u, 7u); - put_dyn(b, DYNAMIC_OFF + 0u * ELF64_DYN_SIZE, DT_SONAME, - dynstr_soname_off); + put_dyn(b, DYNAMIC_OFF + 0u * ELF64_DYN_SIZE, DT_SONAME, dynstr_soname_off); put_dyn(b, DYNAMIC_OFF + 1u * ELF64_DYN_SIZE, DT_STRTAB, dynstr_va); put_dyn(b, DYNAMIC_OFF + 2u * ELF64_DYN_SIZE, DT_STRSZ, dynstr_len); put_dyn(b, DYNAMIC_OFF + 3u * ELF64_DYN_SIZE, DT_SYMTAB, dynsym_va); put_dyn(b, DYNAMIC_OFF + 4u * ELF64_DYN_SIZE, DT_SYMENT, ELF64_SYM_SIZE); put_dyn(b, DYNAMIC_OFF + 5u * ELF64_DYN_SIZE, DT_HASH, hash_va); put_dyn(b, DYNAMIC_OFF + 6u * ELF64_DYN_SIZE, DT_RELA, rela_va); - put_dyn(b, DYNAMIC_OFF + 7u * ELF64_DYN_SIZE, DT_RELASZ, - ELF64_RELA_SIZE); - put_dyn(b, DYNAMIC_OFF + 8u * ELF64_DYN_SIZE, DT_RELAENT, - ELF64_RELA_SIZE); + put_dyn(b, DYNAMIC_OFF + 7u * ELF64_DYN_SIZE, DT_RELASZ, ELF64_RELA_SIZE); + put_dyn(b, DYNAMIC_OFF + 8u * ELF64_DYN_SIZE, DT_RELAENT, ELF64_RELA_SIZE); put_dyn(b, DYNAMIC_OFF + 9u * ELF64_DYN_SIZE, DT_NULL, 0); *out_len = TOTAL; return b; @@ -1041,8 +1023,7 @@ static unsigned char* build_signal_sigreturn_elf(size_t* out_len) { put32(b, TEXT_OFF + 40u, rv_addi(RV_A7, RV_ZERO, 94)); put32(b, TEXT_OFF + 44u, rv_ecall()); - put32(b, TEXT_OFF + 48u, - rv_auipc(RV_A0, rv_pcrel_hi(handler_va, text_va))); + put32(b, TEXT_OFF + 48u, rv_auipc(RV_A0, rv_pcrel_hi(handler_va, text_va))); put32(b, TEXT_OFF + 52u, rv_addi(RV_A0, RV_A0, rv_pcrel_lo(handler_va, text_va))); put32(b, TEXT_OFF + 56u, rv_addi(RV_A1, RV_ZERO, 1)); @@ -1116,13 +1097,12 @@ static void vm_unit_smoke(void) { return; } - st = emu_addr_space_map(&as, 0x10000u, 0x3000u, - EMU_MEM_READ | EMU_MEM_WRITE, EMU_MAP_ANON); + st = emu_addr_space_map(&as, 0x10000u, 0x3000u, EMU_MEM_READ | EMU_MEM_WRITE, + EMU_MAP_ANON); EXPECT(st == CFREE_OK, "vm: initial anon map returned %d", (int)st); EXPECT(as.nmaps == 1u, "vm: expected one map, got %u", as.nmaps); - st = emu_addr_space_map(&as, 0x11000u, 0x1000u, EMU_MEM_READ, - EMU_MAP_ANON); + st = emu_addr_space_map(&as, 0x11000u, 0x1000u, EMU_MEM_READ, EMU_MAP_ANON); EXPECT(st == CFREE_INVALID, "vm: overlapping map must be rejected"); p = emu_addr_space_ptr(&as, 0x10ff8u, 16u, EMU_MEM_WRITE); @@ -1325,8 +1305,8 @@ static void emu_fixture_expect_exit_with_bindings( trap = EMU_TRAP_NONE; for (i = 0; i < max_blocks && trap == EMU_TRAP_NONE; ++i) { st = cfree_emu_step(emu, 1); - EXPECT(st == CFREE_OK, "%s: cfree_emu_step returned %d at block %u", - name, (int)st, i); + EXPECT(st == CFREE_OK, "%s: cfree_emu_step returned %d at block %u", name, + (int)st, i); if (st != CFREE_OK) break; cpu = emu_internal_cpu(emu); trap = emu_cpu_trap_reason(cpu); @@ -1425,8 +1405,8 @@ static void host_import_bridge_smoke(void) { if (!elf) return; memset(&bindings, 0, sizeof(bindings)); bindings.resolve_import = host_import_resolver; - emu_fixture_expect_exit_with_bindings("host-import-bridge-rv64", elf, - elf_len, 42, 32, &bindings); + emu_fixture_expect_exit_with_bindings("host-import-bridge-rv64", elf, elf_len, + 42, 32, &bindings); } static void dso_import_reloc_smoke(void) { diff --git a/test/lib/cfree_test_target.h b/test/lib/cfree_test_target.h @@ -64,8 +64,7 @@ static inline int cfree_test_target_init(CfreeTarget* t) { } if (!strcmp(a, "rv64") || !strcmp(a, "riscv64")) { if (t->os == CFREE_OS_MACOS) { - fprintf(stderr, - "cfree_test_target: rv64 has no macOS target\n"); + fprintf(stderr, "cfree_test_target: rv64 has no macOS target\n"); return -1; } t->arch = CFREE_ARCH_RV64; diff --git a/test/libc/cases/11_strings.c b/test/libc/cases/11_strings.c @@ -8,7 +8,7 @@ #include <string.h> int main(void) { - const char *s = "hello, world"; + const char* s = "hello, world"; if (memcmp(s, "hello, world", 13) != 0) return 1; /* incl. NUL */ if (memchr(s, ',', 12) != s + 5) return 2; if (memchr(s, 'z', 12) != NULL) return 3; diff --git a/test/libc/cases/13_malloc.c b/test/libc/cases/13_malloc.c @@ -5,7 +5,7 @@ #include <string.h> int main(void) { - char *buf = malloc(64); + char* buf = malloc(64); if (!buf) return 1; int n = snprintf(buf, 64, "alloc %d bytes", 64); if (n != 14) return 2; diff --git a/test/libc/cases/14_errno_fopen.c b/test/libc/cases/14_errno_fopen.c @@ -2,15 +2,15 @@ * value for ENOENT differs across platforms but strerror's text contains * the canonical phrase, so we substring-match the human message. */ -#include <stdio.h> #include <errno.h> +#include <stdio.h> #include <string.h> int main(void) { - FILE *f = fopen("/cfree/no/such/path/at/all", "r"); + FILE* f = fopen("/cfree/no/such/path/at/all", "r"); if (f) return 1; if (errno == 0) return 2; - const char *msg = strerror(errno); + const char* msg = strerror(errno); if (!msg || !*msg) return 3; printf("fopen failed: %s\n", msg); return 0; diff --git a/test/libc/cases/15_ctype.c b/test/libc/cases/15_ctype.c @@ -1,7 +1,7 @@ /* ctype.h classifiers + tolower/toupper. */ -#include <stdio.h> #include <ctype.h> +#include <stdio.h> int main(void) { if (!isdigit('7') || isdigit('a')) return 1; diff --git a/test/link/cases/36_tls_basic/a.c b/test/link/cases/36_tls_basic/a.c @@ -9,6 +9,4 @@ _Thread_local int tls_val = 7; -int test_main(void) { - return tls_val == 7 ? 0 : 1; -} +int test_main(void) { return tls_val == 7 ? 0 : 1; } diff --git a/test/link/cases/39_macho_external_ptr_addend/a.c b/test/link/cases/39_macho_external_ptr_addend/a.c @@ -2,7 +2,7 @@ const unsigned char table[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, }; -const unsigned char *p = &table[6 - 2]; +const unsigned char* p = &table[6 - 2]; int test_main(void) { if (p[0] != 4) return 1; diff --git a/test/link/cases/41_macho_many_atom_relocs/a.c b/test/link/cases/41_macho_many_atom_relocs/a.c @@ -3,16 +3,19 @@ #define NOINLINE __attribute__((noinline)) -#define EACH64(M) \ - M(0) M(1) M(2) M(3) M(4) M(5) M(6) M(7) M(8) M(9) M(10) M(11) M(12) M(13) \ - M(14) M(15) M(16) M(17) M(18) M(19) M(20) M(21) M(22) M(23) M(24) \ - M(25) M(26) M(27) M(28) M(29) M(30) M(31) M(32) M(33) M(34) M(35) \ - M(36) M(37) M(38) M(39) M(40) M(41) M(42) M(43) M(44) M(45) \ - M(46) M(47) M(48) M(49) M(50) M(51) M(52) M(53) M(54) \ - M(55) M(56) M(57) M(58) M(59) M(60) M(61) M(62) M(63) +#define EACH64(M) \ + M(0) \ + M(1) M(2) M(3) M(4) M(5) M(6) M(7) M(8) M(9) M(10) M(11) M(12) M(13) M(14) \ + M(15) M(16) M(17) M(18) M(19) M(20) M(21) M(22) M(23) M(24) M(25) M(26) \ + M(27) M(28) M(29) M(30) M(31) M(32) M(33) M(34) M(35) M(36) M(37) \ + M(38) M(39) M(40) M(41) M(42) M(43) M(44) M(45) M(46) M(47) \ + M(48) M(49) M(50) M(51) M(52) M(53) M(54) M(55) M(56) M(57) \ + M(58) M(59) M(60) M(61) M(62) M(63) -#define LIVE_DEF(n) NOINLINE int live_##n(void) { return n; } -#define DEAD_DEF(n) NOINLINE int dead_##n(void) { return n; } +#define LIVE_DEF(n) \ + NOINLINE int live_##n(void) { return n; } +#define DEAD_DEF(n) \ + NOINLINE int dead_##n(void) { return n; } #define LIVE_REF(n) live_##n, EACH64(LIVE_DEF) diff --git a/test/link/harness/jit_runner.c b/test/link/harness/jit_runner.c @@ -181,14 +181,13 @@ static CfreeStatus xm_reserve(void* u, size_t n, int p, close(fd); return CFREE_NOMEM; } - w = mmap(NULL, n, PROT_READ | PROT_WRITE, - MAP_SHARED | XM_MAP_32BIT, fd, 0); + w = mmap(NULL, n, PROT_READ | PROT_WRITE, MAP_SHARED | XM_MAP_32BIT, fd, 0); if (w == MAP_FAILED) { close(fd); return CFREE_NOMEM; } - r = mmap(xm_low_runtime_hint(n), n, PROT_READ, - MAP_SHARED | XM_MAP_32BIT, fd, 0); + r = mmap(xm_low_runtime_hint(n), n, PROT_READ, MAP_SHARED | XM_MAP_32BIT, + fd, 0); close(fd); if (r == MAP_FAILED) { munmap(w, n); @@ -388,11 +387,11 @@ static void jit_tls_ctx_destroy(void* user, void* ctx_v) { static CfreeJitTls g_jit_tls = {jit_tls_ctx_new, jit_tls_ctx_destroy, NULL}; #if defined(__aarch64__) || defined(__arm64__) -__attribute__((noinline, no_sanitize("address", "undefined"))) -static int call_with_aarch64_tls(int (*fn)(void), void* tls_block) { +__attribute__((noinline, no_sanitize("address", "undefined"))) static int +call_with_aarch64_tls(int (*fn)(void), void* tls_block) { void* old_tp; int result; - __asm__ volatile("mrs %0, tpidr_el0" : "=r"(old_tp) :: "memory"); + __asm__ volatile("mrs %0, tpidr_el0" : "=r"(old_tp)::"memory"); __asm__ volatile("msr tpidr_el0, %0" ::"r"(tls_block) : "memory"); result = fn(); __asm__ volatile("msr tpidr_el0, %0" ::"r"(old_tp) : "memory"); @@ -574,7 +573,8 @@ int main(int argc, char** argv) { /* --check-absent SYM: verify symbol was removed (e.g. by --gc-sections). */ if (check_absent) { - int absent_ok = cfree_jit_lookup(jit, cfree_slice_cstr(check_absent)) == NULL; + int absent_ok = + cfree_jit_lookup(jit, cfree_slice_cstr(check_absent)) == NULL; if (!absent_ok) fprintf(stderr, "jit-runner: symbol '%s' present but expected absent\n", check_absent); @@ -666,14 +666,15 @@ int main(int argc, char** argv) { /* Patch the function pointer at runtime so the static initializer * stays simple — clang under -Werror dislikes function-to-void* casts * in const initializers. */ - CfreeWasmHostImport runtime_imports[sizeof(test_imports)/sizeof(test_imports[0])]; - for (size_t k = 0; k < sizeof(test_imports)/sizeof(test_imports[0]); ++k) + CfreeWasmHostImport + runtime_imports[sizeof(test_imports) / sizeof(test_imports[0])]; + for (size_t k = 0; k < sizeof(test_imports) / sizeof(test_imports[0]); ++k) runtime_imports[k] = test_imports[k]; runtime_imports[0].func = (void*)(uintptr_t)test_host_add; - if (cfree_wasm_bind_host_imports(c, jit, (CfreeWasmInstance*)instance, - runtime_imports, - sizeof(runtime_imports)/sizeof(runtime_imports[0]), - NULL, NULL) != CFREE_OK) { + if (cfree_wasm_bind_host_imports( + c, jit, (CfreeWasmInstance*)instance, runtime_imports, + sizeof(runtime_imports) / sizeof(runtime_imports[0]), NULL, + NULL) != CFREE_OK) { free(memory); free(instance); cfree_jit_run_dtors(jit); @@ -709,7 +710,8 @@ int main(int argc, char** argv) { #endif if (result == 0) { - int (*post)(void) = cfree_jit_lookup(jit, CFREE_SLICE_LIT("test_post_fini")); + int (*post)(void) = + cfree_jit_lookup(jit, CFREE_SLICE_LIT("test_post_fini")); if (post) result = post(); } diff --git a/test/link/rv64_jit_test.c b/test/link/rv64_jit_test.c @@ -200,10 +200,10 @@ static CfreeExecMem g_execmem = { /* ---- rv64 instruction encodings used by the test ---- */ /* `addi a0, zero, 42` — I-type: imm[11:0]=42, rs1=0, funct3=000 (ADDI), * rd=10 (a0), opcode=0010011. */ -#define ENC_ADDI_A0_ZERO_42 0x02a00513u +#define ENC_ADDI_A0_ZERO_42 0x02a00513u /* `jalr zero, 0(ra)` (= ret) — I-type: imm=0, rs1=1 (ra), funct3=000, * rd=0 (zero), opcode=1100111. */ -#define ENC_RET 0x00008067u +#define ENC_RET 0x00008067u /* ---- the test ---- */ typedef int (*answer_fn)(void); @@ -355,8 +355,9 @@ int main(void) { * alias). Skip the actual call — calling rv64 bytes on a non-rv64 * CPU would SIGILL. Exit-code 77 is the GNU autotools convention * for "skipped" so test wrappers can distinguish from pass/fail. */ - printf("rv64_jit_test: SKIP — non-rv64 host (image built, " - "lookup OK, bytes intact)\n"); + printf( + "rv64_jit_test: SKIP — non-rv64 host (image built, " + "lookup OK, bytes intact)\n"); cfree_jit_free(jit); cfree_compiler_free(c); return 77; diff --git a/test/opt/opt_test.c b/test/opt/opt_test.c @@ -161,8 +161,8 @@ static Operand op_indirect_(Reg base, CfreeCgTypeId ty) { return o; } -static Operand op_indexed_indirect_(Reg base, Reg index, u8 log2_scale, - i32 ofs, CfreeCgTypeId ty) { +static Operand op_indexed_indirect_(Reg base, Reg index, u8 log2_scale, i32 ofs, + CfreeCgTypeId ty) { Operand o = op_indirect_(base, ty); o.v.ind.index = index; o.v.ind.log2_scale = log2_scale; @@ -457,8 +457,8 @@ static Inst* emit_load_indexed_indirect(Func* f, u32 b, Val dst, Val base, Inst* in = ir_emit(f, b, IR_LOAD); in->opnds = arena_array(f->arena, Operand, 2); in->opnds[0] = op_reg_(dst, ty); - in->opnds[1] = op_indexed_indirect_((Reg)base, (Reg)index, log2_scale, ofs, - ty); + in->opnds[1] = + op_indexed_indirect_((Reg)base, (Reg)index, log2_scale, ofs, ty); in->nopnds = 2; in->def = dst; in->type = ty; @@ -1156,7 +1156,8 @@ static CfreeCgTypeId record_of_i64s(TestCtx* tc, const char* name, u64 count) { memset(&field, 0, sizeof field); field.name = cfree_sym_intern(tc->c, CFREE_SLICE_LIT("a")); field.type = arr; - return cfree_cg_type_record(tc->c, cfree_sym_intern(tc->c, cfree_slice_cstr(name)), &field, 1); + return cfree_cg_type_record( + tc->c, cfree_sym_intern(tc->c, cfree_slice_cstr(name)), &field, 1); } static CfreeCgTypeId make_func_type(TestCtx* tc, CfreeCgTypeId ret, @@ -1316,8 +1317,8 @@ static Inst* emit_direct_call(TestCtx* tc, Func* f, u32 b, ObjSymId callee_sym, av = arena_zarray(f->arena, CGABIValue, nargs); const ABIFuncInfo* abi = abi_cg_func_info(tc->c->abi, fn_ty); for (u32 i = 0; i < nargs; ++i) - av[i] = call_arg_value(args[i].type, abi ? &abi->params[i] : NULL, - args[i]); + av[i] = + call_arg_value(args[i].type, abi ? &abi->params[i] : NULL, args[i]); } CGABIValue rv; memset(&rv, 0, sizeof rv); @@ -2615,9 +2616,9 @@ static void opt_copy_prop_collapses_redundant_extension_chain(void) { Inst* wide = def_inst(f, w64); EXPECT(wide && (IROp)wide->op == IR_CONVERT && wide->nopnds == 2, "extension cleanup should preserve the final widening conversion"); - EXPECT(wide && wide->opnds[1].kind == OPK_REG && - wide->opnds[1].v.reg == (Reg)x, - "extension cleanup should bypass redundant intermediate extensions"); + EXPECT( + wide && wide->opnds[1].kind == OPK_REG && wide->opnds[1].v.reg == (Reg)x, + "extension cleanup should bypass redundant intermediate extensions"); expect_ir_dump_eq(f, "ir blocks=1 vals=5\n" "block 0 preds=[] succs=[] insts=5\n" @@ -2875,8 +2876,7 @@ static void opt_simplify_local_rewrites_integer_identities(void) { opt_build_cfg(f); opt_simplify_local(f); opt_verify(f, "test-simplify-local"); - EXPECT((IROp)def_inst(f, mul)->op == IR_COPY, - "x * 1 should become a copy"); + EXPECT((IROp)def_inst(f, mul)->op == IR_COPY, "x * 1 should become a copy"); EXPECT(val_is_load_imm(f, rem, 0), "x %% 1 should become zero"); EXPECT(val_is_load_imm(f, self_xor, 0), "x ^ x should become zero"); EXPECT((IROp)def_inst(f, self_or)->op == IR_COPY, @@ -4116,8 +4116,7 @@ static void opt_licm_preserves_trapping_and_memory_ops(void) { opt_licm(f); opt_verify(f, "test-licm-preserve-unsafe"); - EXPECT(f->val_def_block[loaded] == body, - "LICM must not hoist memory loads"); + EXPECT(f->val_def_block[loaded] == body, "LICM must not hoist memory loads"); EXPECT(f->val_def_block[div] == body, "LICM must not hoist potentially trapping division"); tc_fini(&tc); @@ -5519,7 +5518,7 @@ static void opt_combine_copy_chains_and_convert_pairs(void) { /* Helper: emit IR_LOAD with arbitrary indirect operand. */ static Inst* tt_emit_load_phys_indirect(Func* f, u32 b, Reg dst, Operand addr, - CfreeCgTypeId ty) { + CfreeCgTypeId ty) { Inst* in = ir_emit(f, b, IR_LOAD); in->opnds = arena_array(f->arena, Operand, 2); in->opnds[0] = op_reg_(dst, ty); @@ -5589,9 +5588,9 @@ static void opt_combine_substitutes_into_indirect_base_and_index(void) { for (u32 i = 0; i < store_f->blocks[store_f->entry].ninsts; ++i) if ((IROp)store_f->blocks[store_f->entry].insts[i].op == IR_STORE) st = &store_f->blocks[store_f->entry].insts[i]; - EXPECT(st && st->opnds[0].kind == OPK_INDIRECT && - st->opnds[0].v.ind.base == 4, - "copy substitution should not rewrite store address bases"); + EXPECT( + st && st->opnds[0].kind == OPK_INDIRECT && st->opnds[0].v.ind.base == 4, + "copy substitution should not rewrite store address bases"); tc_fini(&tc); } @@ -5675,8 +5674,7 @@ static void opt_combine_synthesizes_address_modes(void) { if ((IROp)g->blocks[g->entry].insts[i].op == IR_LOAD) load = &g->blocks[g->entry].insts[i]; EXPECT(load && load->opnds[1].kind == OPK_INDIRECT && - load->opnds[1].v.ind.base == 2 && - load->opnds[1].v.ind.ofs == 20 && + load->opnds[1].v.ind.base == 2 && load->opnds[1].v.ind.ofs == 20 && load->opnds[1].v.ind.index == (Reg)REG_NONE, "add reg+imm producer should fold immediate into indirect offset"); EXPECT(count_op(g, IR_BINOP) == 0, @@ -5725,8 +5723,7 @@ static void opt_combine_synthesizes_address_modes(void) { if ((IROp)blk->blocks[blk->entry].insts[i].op == IR_LOAD) load = &blk->blocks[blk->entry].insts[i]; EXPECT(load && load->opnds[1].kind == OPK_INDIRECT && - load->opnds[1].v.ind.base == 5 && - load->opnds[1].v.ind.index == 6, + load->opnds[1].v.ind.base == 5 && load->opnds[1].v.ind.index == 6, "addr-mode synthesis should refuse to stack two indices"); EXPECT(count_op(blk, IR_BINOP) == 1, "blocked synthesis should leave the producing add in place"); @@ -5759,8 +5756,9 @@ static void opt_combine_synthesizes_address_modes(void) { load->opnds[1].v.ind.log2_scale == 1 && load->opnds[1].v.ind.ofs == 16, "reg+imm base producer should imm-fold even when an index is set"); - EXPECT(count_op(m, IR_BINOP) == 0, - "imm-fold synthesis with existing index should kill the producing add"); + EXPECT( + count_op(m, IR_BINOP) == 0, + "imm-fold synthesis with existing index should kill the producing add"); tc_fini(&tc); } @@ -6725,9 +6723,11 @@ static void opt_inline_policy_controls_decisions(void) { } emit_preg_ret(always_callee, always_callee->entry, ar, tc.i32); - Func* call_never_callee = new_named_func(&tc, (ObjSymId)33, tc.i32, NULL, 0, 0); + Func* call_never_callee = + new_named_func(&tc, (ObjSymId)33, tc.i32, NULL, 0, 0); PReg cr = add_preg(call_never_callee, tc.i32); - emit_preg_load_imm(call_never_callee, call_never_callee->entry, cr, tc.i32, 9); + emit_preg_load_imm(call_never_callee, call_never_callee->entry, cr, tc.i32, + 9); emit_preg_ret(call_never_callee, call_never_callee->entry, cr, tc.i32); Func* hint_callee = new_named_func(&tc, (ObjSymId)34, tc.i32, NULL, 0, 0); @@ -6748,8 +6748,7 @@ static void opt_inline_policy_controls_decisions(void) { Inst* call_hint = emit_direct_call(&tc, caller, caller->entry, (ObjSymId)34, hint_callee->type, NULL, 0, op_reg_(r4, tc.i32)); - ((IRCallAux*)call_hint->extra.aux)->desc.inline_policy = - CFREE_CG_INLINE_HINT; + ((IRCallAux*)call_hint->extra.aux)->desc.inline_policy = CFREE_CG_INLINE_HINT; Inst* call_never = emit_direct_call(&tc, caller, caller->entry, (ObjSymId)33, call_never_callee->type, NULL, 0, op_reg_(r3, tc.i32)); diff --git a/test/opt/ret_aggregate_base_clobber.c b/test/opt/ret_aggregate_base_clobber.c @@ -34,5 +34,6 @@ int entry(void) { a.y = 0; a.vt = &vt; Info r = ret_info(&a); - return (int)((r.size + r.align + r.a + r.b + r.c + r.d) & 0xff); /* 343&255=87 */ + return (int)((r.size + r.align + r.a + r.b + r.c + r.d) & + 0xff); /* 343&255=87 */ } diff --git a/test/parse/cases/6_10_04_macro_unbalanced_brace_arg.c b/test/parse/cases/6_10_04_macro_unbalanced_brace_arg.c @@ -1,6 +1,6 @@ #define DROP(x) -#define WRAP(flag) \ - do { \ +#define WRAP(flag) \ + do { \ DROP(if (flag) {) return 7; \ } while (0) diff --git a/test/parse/cases/6_10_warning_directive.c b/test/parse/cases/6_10_warning_directive.c @@ -7,6 +7,4 @@ * `sys/cdefs.h`, which emits one whenever `__GNUC__ < 4`. */ #warning "non-fatal diagnostic; parsing should continue" -int test_main(void) { - return 42; -} +int test_main(void) { return 42; } diff --git a/test/parse/cases/6_2_1_01_param_shadow.c b/test/parse/cases/6_2_1_01_param_shadow.c @@ -1,2 +1,7 @@ -int f(int x){ { int x=42; return x; } } -int test_main(void){ return f(99); } +int f(int x) { + { + int x = 42; + return x; + } +} +int test_main(void) { return f(99); } diff --git a/test/parse/cases/6_2_1_02_label_in_nested_block.c b/test/parse/cases/6_2_1_02_label_in_nested_block.c @@ -1 +1,9 @@ -int test_main(void){ int r=0; goto done; { done: r=42; } return r; } +int test_main(void) { + int r = 0; + goto done; + { + done: + r = 42; + } + return r; +} diff --git a/test/parse/cases/6_2_2_01_extern_in_block_inherits_internal.c b/test/parse/cases/6_2_2_01_extern_in_block_inherits_internal.c @@ -1,2 +1,5 @@ -static int g=42; -int test_main(void){ extern int g; return g; } +static int g = 42; +int test_main(void) { + extern int g; + return g; +} diff --git a/test/parse/cases/6_2_3_01_tag_ord_namespace.c b/test/parse/cases/6_2_3_01_tag_ord_namespace.c @@ -1,6 +1,6 @@ -struct s { int v; }; +struct s { + int v; +}; int s = 42; struct s t = {0}; -int test_main(void) { - return s + t.v; -} +int test_main(void) { return s + t.v; } diff --git a/test/parse/cases/6_2_3_01b_member_namespace_two_structs.c b/test/parse/cases/6_2_3_01b_member_namespace_two_structs.c @@ -1,2 +1,11 @@ -struct A{int x;}; struct B{int x;}; -int test_main(void){ struct A a={10}; struct B b={32}; return a.x+b.x; } +struct A { + int x; +}; +struct B { + int x; +}; +int test_main(void) { + struct A a = {10}; + struct B b = {32}; + return a.x + b.x; +} diff --git a/test/parse/cases/6_2_4_02_auto_reinit_each_iteration.c b/test/parse/cases/6_2_4_02_auto_reinit_each_iteration.c @@ -1 +1,8 @@ -int test_main(void){ int s=0; for(int i=0;i<6;i++){ int x=i; s+=x; } return s; } +int test_main(void) { + int s = 0; + for (int i = 0; i < 6; i++) { + int x = i; + s += x; + } + return s; +} diff --git a/test/parse/cases/6_2_4_03_static_local_zero_init.c b/test/parse/cases/6_2_4_03_static_local_zero_init.c @@ -1,2 +1,5 @@ -int f(void){ static int n; return ++n; } -int test_main(void){ return f()+f(); } +int f(void) { + static int n; + return ++n; +} +int test_main(void) { return f() + f(); } diff --git a/test/parse/cases/6_2_5_01_void_func_no_value.c b/test/parse/cases/6_2_5_01_void_func_no_value.c @@ -1,6 +1,4 @@ -void f(int *p) { - *p = 42; -} +void f(int* p) { *p = 42; } int test_main(void) { int x = 0; f(&x); diff --git a/test/parse/cases/6_2_5_01b_unsigned_wrap.c b/test/parse/cases/6_2_5_01b_unsigned_wrap.c @@ -1 +1,5 @@ -int test_main(void){ unsigned char u=255; u++; return u; } +int test_main(void) { + unsigned char u = 255; + u++; + return u; +} diff --git a/test/parse/cases/6_2_5_02_incomplete_array_completed.c b/test/parse/cases/6_2_5_02_incomplete_array_completed.c @@ -1,3 +1,3 @@ extern int a[]; -int a[3]={0,0,42}; -int test_main(void){return a[2];} +int a[3] = {0, 0, 42}; +int test_main(void) { return a[2]; } diff --git a/test/parse/cases/6_2_7_01_composite_array_size.c b/test/parse/cases/6_2_7_01_composite_array_size.c @@ -1,4 +1,4 @@ extern int a[]; -int a[3]={40,0,0}; +int a[3] = {40, 0, 0}; extern int a[3]; -int test_main(void){return a[0]+(int)(sizeof(a)/sizeof(a[0]))-1;} +int test_main(void) { return a[0] + (int)(sizeof(a) / sizeof(a[0])) - 1; } diff --git a/test/parse/cases/6_2_8_01_char_weakest_align.c b/test/parse/cases/6_2_8_01_char_weakest_align.c @@ -1 +1 @@ -int test_main(void){ return (int)_Alignof(char); } +int test_main(void) { return (int)_Alignof(char); } diff --git a/test/parse/cases/6_3_1_2_01_bool_from_ptr.c b/test/parse/cases/6_3_1_2_01_bool_from_ptr.c @@ -1 +1,5 @@ -int test_main(void){ int x=1; _Bool b=(int*)&x ? 1 : 0; return b ? 42 : 0; } +int test_main(void) { + int x = 1; + _Bool b = (int*)&x ? 1 : 0; + return b ? 42 : 0; +} diff --git a/test/parse/cases/6_3_1_2_02_bool_from_float.c b/test/parse/cases/6_3_1_2_02_bool_from_float.c @@ -1 +1,4 @@ -int test_main(void){ _Bool b = 0.0; return b ? 99 : 42; } +int test_main(void) { + _Bool b = 0.0; + return b ? 99 : 42; +} diff --git a/test/parse/cases/6_3_1_3_03_uchar_wrap.c b/test/parse/cases/6_3_1_3_03_uchar_wrap.c @@ -1 +1,5 @@ -int test_main(void){ int n = -1; unsigned char c = (unsigned char)n; return c; } +int test_main(void) { + int n = -1; + unsigned char c = (unsigned char)n; + return c; +} diff --git a/test/parse/cases/6_3_1_8_02_signed_wins.c b/test/parse/cases/6_3_1_8_02_signed_wins.c @@ -1 +1,5 @@ -int test_main(void){ long a = 40; unsigned int b = 2; return (int)(a + b); } +int test_main(void) { + long a = 40; + unsigned int b = 2; + return (int)(a + b); +} diff --git a/test/parse/cases/6_3_2_1_01_array_to_ptr.c b/test/parse/cases/6_3_2_1_01_array_to_ptr.c @@ -1,5 +1,5 @@ int test_main(void) { int a[3] = {0, 0, 42}; - int *p = a; + int* p = a; return p[2]; } diff --git a/test/parse/cases/6_3_2_1_02_func_to_ptr.c b/test/parse/cases/6_3_2_1_02_func_to_ptr.c @@ -1,6 +1,4 @@ -int id(int x) { - return x; -} +int id(int x) { return x; } int test_main(void) { int (*fp)(int) = id; return fp(42); diff --git a/test/parse/cases/6_3_2_3_01_null_ptr_cmp.c b/test/parse/cases/6_3_2_3_01_null_ptr_cmp.c @@ -1,4 +1,4 @@ int test_main(void) { - int *p = 0; + int* p = 0; return p ? 99 : 42; } diff --git a/test/parse/cases/6_3_2_3_02_void_ptr_roundtrip.c b/test/parse/cases/6_3_2_3_02_void_ptr_roundtrip.c @@ -1,6 +1,6 @@ int test_main(void) { int x = 42; - void *v = &x; - int *p = (int *)v; + void* v = &x; + int* p = (int*)v; return *p; } diff --git a/test/parse/cases/6_3_2_3_03_null_void_cast.c b/test/parse/cases/6_3_2_3_03_null_void_cast.c @@ -1 +1,4 @@ -int test_main(void){ int *p = (void*)0; return p ? 99 : 42; } +int test_main(void) { + int* p = (void*)0; + return p ? 99 : 42; +} diff --git a/test/parse/cases/6_4_4_4_01_wide_char_ucn.c b/test/parse/cases/6_4_4_4_01_wide_char_ucn.c @@ -1,3 +1 @@ -int test_main(void) { - return L'\u00a3' == 163 ? 42 : 0; -} +int test_main(void) { return L'\u00a3' == 163 ? 42 : 0; } diff --git a/test/parse/cases/6_4_4_4_02_wide_char_hex_escape.c b/test/parse/cases/6_4_4_4_02_wide_char_hex_escape.c @@ -1,3 +1 @@ -int test_main(void) { - return L'\x012a' == 298 ? 42 : 0; -} +int test_main(void) { return L'\x012a' == 298 ? 42 : 0; } diff --git a/test/parse/cases/6_4_5_01_string_concat_expr.c b/test/parse/cases/6_4_5_01_string_concat_expr.c @@ -5,6 +5,9 @@ * Subscripting goes through a char[] (the direct-string-literal subscript * codegen path is separately limited at nonzero offsets). */ int test_main(void) { - char s[7] = "a" "bc" "def"; + char s[7] = + "a" + "bc" + "def"; return s[5]; /* 'f' = 102 */ } diff --git a/test/parse/cases/6_4_5_02_string_concat_init.c b/test/parse/cases/6_4_5_02_string_concat_init.c @@ -1,4 +1,6 @@ int test_main(void) { - char s[] = "hi" "lo"; + char s[] = + "hi" + "lo"; return s[0] + s[1] + s[2] + s[3] + s[4]; } diff --git a/test/parse/cases/6_4_5_03_wide_string_sizeof.c b/test/parse/cases/6_4_5_03_wide_string_sizeof.c @@ -1,5 +1,3 @@ #include <stddef.h> -int test_main(void) { - return (int)sizeof(L"*") * 5 + 2; -} +int test_main(void) { return (int)sizeof(L"*") * 5 + 2; } diff --git a/test/parse/cases/6_4_5_06_wide_string_ucn_init.c b/test/parse/cases/6_4_5_06_wide_string_ucn_init.c @@ -2,6 +2,6 @@ int test_main(void) { wchar_t s[] = L"A\u00a3"; - return (int)sizeof(s) + (s[0] == 65 ? 10 : 0) + - (s[1] == 163 ? 10 : 0) + (s[2] == 0 ? 10 : 0); + return (int)sizeof(s) + (s[0] == 65 ? 10 : 0) + (s[1] == 163 ? 10 : 0) + + (s[2] == 0 ? 10 : 0); } diff --git a/test/parse/cases/6_4_5_07_wide_string_concat_mixed.c b/test/parse/cases/6_4_5_07_wide_string_concat_mixed.c @@ -1,9 +1,15 @@ #include <stddef.h> int test_main(void) { - const wchar_t* s = L"A" "B" L"\u00a3"; - return sizeof(L"A" "B" L"\u00a3") == 16 && s[0] == 65 && s[1] == 66 && - s[2] == 163 && s[3] == 0 + const wchar_t* s = + L"A" + "B" + L"\u00a3"; + return sizeof( + L"A" + "B" + L"\u00a3") == 16 && + s[0] == 65 && s[1] == 66 && s[2] == 163 && s[3] == 0 ? 42 : 0; } diff --git a/test/parse/cases/6_4_5_09_utf16_surrogate_pair.c b/test/parse/cases/6_4_5_09_utf16_surrogate_pair.c @@ -1,6 +1,5 @@ int test_main(void) { unsigned short s[] = u"\U0001f600"; - return sizeof(s) == 6 && s[0] == 0xd83d && s[1] == 0xde00 && s[2] == 0 - ? 42 - : 0; + return sizeof(s) == 6 && s[0] == 0xd83d && s[1] == 0xde00 && s[2] == 0 ? 42 + : 0; } diff --git a/test/parse/cases/6_5_02_pointer_index_offset_table.c b/test/parse/cases/6_5_02_pointer_index_offset_table.c @@ -9,9 +9,9 @@ int test_main(void) { table[268] = 1; table[270] = 1; table[273] = 1; - const unsigned char *lt = &table[256 - 53]; - const unsigned char *eq = &table[256 + 6 - 53]; - const unsigned char *gt = &table[256 + 12 - 53]; + const unsigned char* lt = &table[256 - 53]; + const unsigned char* eq = &table[256 + 6 - 53]; + const unsigned char* gt = &table[256 + 12 - 53]; if (lt[53] != 1) return 1; if (eq[53] != 0) return 2; if (gt[53] != 1) return 3; diff --git a/test/parse/cases/6_5_03_large_indirect_addr_of.c b/test/parse/cases/6_5_03_large_indirect_addr_of.c @@ -5,8 +5,8 @@ struct Big { int test_main(void) { struct Big s; - struct Big *p = &s; - int *q; + struct Big* p = &s; + int* q; p->value = 37; q = &p->value; return *q; diff --git a/test/parse/cases/6_5_04_div_mod.c b/test/parse/cases/6_5_04_div_mod.c @@ -1,3 +1 @@ -int test_main(void) { - return 23 / 4 + 23 % 4; -} +int test_main(void) { return 23 / 4 + 23 % 4; } diff --git a/test/parse/cases/6_5_05_bitwise_and.c b/test/parse/cases/6_5_05_bitwise_and.c @@ -1,3 +1 @@ -int test_main(void) { - return (~3) & 0xff; -} +int test_main(void) { return (~3) & 0xff; } diff --git a/test/parse/cases/6_5_06_bitwise_or_xor.c b/test/parse/cases/6_5_06_bitwise_or_xor.c @@ -1,3 +1 @@ -int test_main(void) { - return (0xa5 ^ 0x5a) & 0xff; -} +int test_main(void) { return (0xa5 ^ 0x5a) & 0xff; } diff --git a/test/parse/cases/6_5_07_shift.c b/test/parse/cases/6_5_07_shift.c @@ -1,3 +1 @@ -int test_main(void) { - return (1<<5) | (16>>1); -} +int test_main(void) { return (1 << 5) | (16 >> 1); } diff --git a/test/parse/cases/6_5_07_shift_u8_promote.c b/test/parse/cases/6_5_07_shift_u8_promote.c @@ -1,6 +1,6 @@ typedef unsigned char u8; -static int get2(const u8 *x) { return (x[0] << 8) | x[1]; } +static int get2(const u8* x) { return (x[0] << 8) | x[1]; } int test_main(void) { u8 page[2]; diff --git a/test/parse/cases/6_5_08_unary_neg.c b/test/parse/cases/6_5_08_unary_neg.c @@ -1,3 +1 @@ -int test_main(void) { - return -7; -} +int test_main(void) { return -7; } diff --git a/test/parse/cases/6_5_09_logical_not.c b/test/parse/cases/6_5_09_logical_not.c @@ -1,3 +1 @@ -int test_main(void) { - return !0 + !!5; -} +int test_main(void) { return !0 + !!5; } diff --git a/test/parse/cases/6_5_10_cmp_eq.c b/test/parse/cases/6_5_10_cmp_eq.c @@ -1,3 +1 @@ -int test_main(void) { - return (5 == 5) + (5 == 6); -} +int test_main(void) { return (5 == 5) + (5 == 6); } diff --git a/test/parse/cases/6_5_11_cmp_lt.c b/test/parse/cases/6_5_11_cmp_lt.c @@ -1,3 +1 @@ -int test_main(void) { - return (-1 < 1); -} +int test_main(void) { return (-1 < 1); } diff --git a/test/parse/cases/6_5_12_logical_and_skip.c b/test/parse/cases/6_5_12_logical_and_skip.c @@ -1,3 +1,5 @@ int test_main(void) { - int s=0; (0) && (s=99); return s; + int s = 0; + (0) && (s = 99); + return s; } diff --git a/test/parse/cases/6_5_13_logical_or_skip.c b/test/parse/cases/6_5_13_logical_or_skip.c @@ -1,3 +1,5 @@ int test_main(void) { - int s=0; (1) || (s=99); return s; + int s = 0; + (1) || (s = 99); + return s; } diff --git a/test/parse/cases/6_5_13b_logical_or_in_if.c b/test/parse/cases/6_5_13b_logical_or_in_if.c @@ -4,17 +4,17 @@ * the body and `if (a && b)` always skipped it, regardless of operands. */ int test_main(void) { int a = 0, b = 0; - if (a || b) return 1; /* 0 || 0 → false; must skip */ + if (a || b) return 1; /* 0 || 0 → false; must skip */ if (!(a || (b = 1))) return 2; - if (b != 1) return 3; /* short-circuit right side did run */ + if (b != 1) return 3; /* short-circuit right side did run */ int c = 1, d = 0; - if (c && d) return 4; /* 1 && 0 → false; must skip */ + if (c && d) return 4; /* 1 && 0 → false; must skip */ if (!(c && (d = 7))) return 5; if (d != 7) return 6; /* Nested with `!` — the failing test/libc shape. */ - const char *msg = "hi"; + const char* msg = "hi"; if (!msg || !*msg) return 7; /* Constant-folded paths still work. */ diff --git a/test/parse/cases/6_5_14_ternary.c b/test/parse/cases/6_5_14_ternary.c @@ -1,3 +1 @@ -int test_main(void) { - return (5>3) ? 42 : 7; -} +int test_main(void) { return (5 > 3) ? 42 : 7; } diff --git a/test/parse/cases/6_5_15_02_conditional_uchar_eof.c b/test/parse/cases/6_5_15_02_conditional_uchar_eof.c @@ -2,14 +2,12 @@ typedef unsigned long cfree_size_t; struct Zio { cfree_size_t n; - const char *p; + const char* p; }; -static int fill(void) { - return -1; -} +static int fill(void) { return -1; } -static int get(struct Zio *z) { +static int get(struct Zio* z) { return ((z)->n-- > 0) ? (unsigned char)(*(z)->p++) : fill(); } diff --git a/test/parse/cases/6_5_15_comma.c b/test/parse/cases/6_5_15_comma.c @@ -1,3 +1,4 @@ int test_main(void) { - int x; return (x=1, x=42, x); + int x; + return (x = 1, x = 42, x); } diff --git a/test/parse/cases/6_5_15_ternary_null_func_ptr_slot.c b/test/parse/cases/6_5_15_ternary_null_func_ptr_slot.c @@ -1,21 +1,21 @@ typedef int (*Callback)(int); struct WalkerLike { - void *parse; + void* parse; Callback expr; Callback select; Callback select2; int depth; unsigned short code; unsigned short flags; - void *ctx; + void* ctx; }; static int callback(int x) { return x + 7; } static int run_case(int no_select) { struct WalkerLike w; - w.parse = (void *)0x12345678UL; + w.parse = (void*)0x12345678UL; w.expr = callback; w.select = no_select ? 0 : callback; w.select2 = 0; @@ -23,7 +23,7 @@ static int run_case(int no_select) { w.code = 4; w.flags = 5; w.ctx = &w; - if (w.parse != (void *)0x12345678UL) return 1; + if (w.parse != (void*)0x12345678UL) return 1; if (no_select) { if (w.select != 0) return 2; } else { diff --git a/test/parse/cases/6_5_16_05_i32_eq_minus_one.c b/test/parse/cases/6_5_16_05_i32_eq_minus_one.c @@ -1,4 +1,4 @@ int test_main(void) { - int x = -1; - return (x == -1) ? 42 : 0; + int x = -1; + return (x == -1) ? 42 : 0; } diff --git a/test/parse/cases/6_5_16_06_uint_order_high_bit.c b/test/parse/cases/6_5_16_06_uint_order_high_bit.c @@ -1,4 +1,4 @@ int test_main(void) { - unsigned int x = 0xffffffffu; - return (x > 0xfffffffeu) ? 42 : 0; + unsigned int x = 0xffffffffu; + return (x > 0xfffffffeu) ? 42 : 0; } diff --git a/test/parse/cases/6_5_16_assign.c b/test/parse/cases/6_5_16_assign.c @@ -1,3 +1,5 @@ int test_main(void) { - int x; x = 42; return x; + int x; + x = 42; + return x; } diff --git a/test/parse/cases/6_5_17_compound_assign.c b/test/parse/cases/6_5_17_compound_assign.c @@ -1,3 +1,5 @@ int test_main(void) { - int x = 40; x += 2; return x; + int x = 40; + x += 2; + return x; } diff --git a/test/parse/cases/6_5_18_pre_inc.c b/test/parse/cases/6_5_18_pre_inc.c @@ -1,3 +1,4 @@ int test_main(void) { - int x = 41; return ++x; + int x = 41; + return ++x; } diff --git a/test/parse/cases/6_5_19_post_inc.c b/test/parse/cases/6_5_19_post_inc.c @@ -1,3 +1,5 @@ int test_main(void) { - int x = 42; x++; return x; + int x = 42; + x++; + return x; } diff --git a/test/parse/cases/6_5_19b_post_inc_struct_ptr.c b/test/parse/cases/6_5_19b_post_inc_struct_ptr.c @@ -5,7 +5,7 @@ struct Pair { int test_main(void) { struct Pair xs[3] = {{1, 2}, {3, 4}, {5, 6}}; - struct Pair *p = xs; + struct Pair* p = xs; p++; if (p != xs + 1) return 20; return p->b; diff --git a/test/parse/cases/6_5_20_addr_deref.c b/test/parse/cases/6_5_20_addr_deref.c @@ -1,3 +1,5 @@ int test_main(void) { - int x = 42; int *p = &x; return *p; + int x = 42; + int* p = &x; + return *p; } diff --git a/test/parse/cases/6_5_21_sizeof_int.c b/test/parse/cases/6_5_21_sizeof_int.c @@ -1,3 +1 @@ -int test_main(void) { - return (int)sizeof(int); -} +int test_main(void) { return (int)sizeof(int); } diff --git a/test/parse/cases/6_5_22_sizeof_expr.c b/test/parse/cases/6_5_22_sizeof_expr.c @@ -1,3 +1,4 @@ int test_main(void) { - int a[7]; return (int)(sizeof(a)/sizeof(int)); + int a[7]; + return (int)(sizeof(a) / sizeof(int)); } diff --git a/test/parse/cases/6_5_22b_sizeof_string_literal.c b/test/parse/cases/6_5_22b_sizeof_string_literal.c @@ -2,6 +2,4 @@ * type per C11 §6.5.3.4 / §6.4.5 — sizeof("abcd") is 5 (4 bytes + NUL). * Today parse_primary materializes the literal as a `char*` rvalue, so * sizeof reports pointer size (8 on LP64) instead of the array size. */ -int test_main(void) { - return (int)sizeof("abcd"); -} +int test_main(void) { return (int)sizeof("abcd"); } diff --git a/test/parse/cases/6_5_23_cast.c b/test/parse/cases/6_5_23_cast.c @@ -1,3 +1 @@ -int test_main(void) { - return (int)(unsigned char)(-1); -} +int test_main(void) { return (int)(unsigned char)(-1); } diff --git a/test/parse/cases/6_5_24_func_call.c b/test/parse/cases/6_5_24_func_call.c @@ -1,4 +1,2 @@ -int id(int x){return x;} -int test_main(void) { - return id(42); -} +int id(int x) { return x; } +int test_main(void) { return id(42); } diff --git a/test/parse/cases/6_5_25_unary_plus.c b/test/parse/cases/6_5_25_unary_plus.c @@ -1,3 +1 @@ -int test_main(void) { - return +42; -} +int test_main(void) { return +42; } diff --git a/test/parse/cases/6_5_28_arrow.c b/test/parse/cases/6_5_28_arrow.c @@ -1,5 +1,7 @@ int test_main(void) { - struct S { int v; } s = {42}; - struct S *p = &s; + struct S { + int v; + } s = {42}; + struct S* p = &s; return p->v; } diff --git a/test/parse/cases/6_5_29_compound_literal.c b/test/parse/cases/6_5_29_compound_literal.c @@ -1,4 +1,4 @@ int test_main(void) { - int *p = (int[]){10, 32}; + int* p = (int[]){10, 32}; return p[0] + p[1]; } diff --git a/test/parse/cases/6_5_2_1_01_subscript_conditional_zero_branch.c b/test/parse/cases/6_5_2_1_01_subscript_conditional_zero_branch.c @@ -8,7 +8,7 @@ * which the diagnostic flags as "invalid subscript: needs one pointer * and one integer". */ int test_main(void) { - char buff[4] = { 0 }; + char buff[4] = {0}; int islittle = 1; int size = 4; buff[islittle ? 0 : size - 1] = 42; /* writes buff[0] = 42 */ diff --git a/test/parse/cases/6_5_2_2_01_struct_param_1reg.c b/test/parse/cases/6_5_2_2_01_struct_param_1reg.c @@ -1,7 +1,9 @@ /* 8-byte struct passed by value — fits in one GPR on all targets * (AAPCS64: x0; SysV-x64: rdi; RV64: a0). Exercises DIRECT classification * with a single ABI part loaded from the caller's source lvalue. */ -struct S { int a, b; }; +struct S { + int a, b; +}; int take(struct S s) { return s.a + s.b; } int test_main(void) { struct S s = {20, 22}; diff --git a/test/parse/cases/6_5_2_2_02_struct_param_2reg.c b/test/parse/cases/6_5_2_2_02_struct_param_2reg.c @@ -2,7 +2,9 @@ * (AAPCS64: x0,x1; SysV-x64: rdi,rsi; RV64: a0,a1). The DIRECT * classification carries two ABI parts; the backend loads each part from * the caller's source local at src_offset 0 and 8. */ -struct S { long a, b; }; +struct S { + long a, b; +}; long take(struct S s) { return s.a + s.b; } int test_main(void) { struct S s = {20L, 22L}; diff --git a/test/parse/cases/6_5_2_2_03_struct_param_2reg_mixed.c b/test/parse/cases/6_5_2_2_03_struct_param_2reg_mixed.c @@ -1,7 +1,9 @@ /* 16-byte struct of four ints — 2-reg DIRECT path with sub-8B chunking. * Field values are chosen so a+b+c+d == 42 but a+b+a+b == 34: if part 1 * is dropped or aliased to part 0 the sum collapses to 34. */ -struct S { int a, b, c, d; }; +struct S { + int a, b, c, d; +}; int take(struct S s) { return s.a + s.b + s.c + s.d; } int test_main(void) { struct S s = {5, 12, 10, 15}; diff --git a/test/parse/cases/6_5_2_2_04_struct_param_large.c b/test/parse/cases/6_5_2_2_04_struct_param_large.c @@ -2,7 +2,9 @@ * makes a copy in its frame and passes the address; the callee receives * the pointer in the first int-arg register and treats its home slot as * a pointer-to-copy. */ -struct S { int a[8]; }; +struct S { + int a[8]; +}; int take(struct S s) { return s.a[0] + s.a[7]; } int test_main(void) { struct S s = {{20, 0, 0, 0, 0, 0, 0, 22}}; diff --git a/test/parse/cases/6_5_2_2_05_struct_param_with_scalars.c b/test/parse/cases/6_5_2_2_05_struct_param_with_scalars.c @@ -1,7 +1,9 @@ /* Interleaved scalar/aggregate args. The 2-reg struct consumes the next * two int-arg slots and shifts the trailing scalar; this exercises the * arg-cursor accounting around a multi-part DIRECT argument. */ -struct S { long a, b; }; +struct S { + long a, b; +}; int take(int pre, struct S s, int post) { return pre + (int)s.a + (int)s.b + post; } diff --git a/test/parse/cases/6_5_2_2_06_struct_param_mixed_fp_int.c b/test/parse/cases/6_5_2_2_06_struct_param_mixed_fp_int.c @@ -1,6 +1,9 @@ /* SysV-x64 classifies this 16-byte record as SSE + INTEGER, so the * aggregate consumes one XMM arg slot and one GPR arg slot. */ -struct S { double d; long i; }; +struct S { + double d; + long i; +}; int take(int pre, struct S s, double post) { return pre + (int)s.d + (int)s.i + (int)post; diff --git a/test/parse/cases/6_5_2_2_09_funcptr_field_first_arg.c b/test/parse/cases/6_5_2_2_09_funcptr_field_first_arg.c @@ -1,36 +1,36 @@ typedef unsigned long cfree_size_t; -typedef void *(*AllocFn)(void *ud, void *ptr, cfree_size_t old_size, +typedef void* (*AllocFn)(void* ud, void* ptr, cfree_size_t old_size, cfree_size_t new_size); struct Global { AllocFn alloc; - void *ud; + void* ud; }; struct State { - struct Global *g; + struct Global* g; }; -static void *test_alloc(void *ud, void *ptr, cfree_size_t old_size, +static void* test_alloc(void* ud, void* ptr, cfree_size_t old_size, cfree_size_t new_size) { (void)ptr; - return old_size == 3 && new_size == 4 ? ud : (void *)0; + return old_size == 3 && new_size == 4 ? ud : (void*)0; } -static void *call_alloc(struct Global *g) { - return (*g->alloc)(g->ud, (void *)0, 3, 4); +static void* call_alloc(struct Global* g) { + return (*g->alloc)(g->ud, (void*)0, 3, 4); } -static void *state_alloc(struct State *s, cfree_size_t size, int tag) { - struct Global *g = s->g; - return (*g->alloc)(g->ud, (void *)0, tag, size); +static void* state_alloc(struct State* s, cfree_size_t size, int tag) { + struct Global* g = s->g; + return (*g->alloc)(g->ud, (void*)0, tag, size); } int test_main(void) { - struct Global g = {test_alloc, (void *)42}; + struct Global g = {test_alloc, (void*)42}; struct State s = {&g}; - void *p = call_alloc(&g); - void *q = state_alloc(&s, 4, 3); - return p == (void *)42 && q == (void *)42 ? 42 : 0; + void* p = call_alloc(&g); + void* q = state_alloc(&s, 4, 3); + return p == (void*)42 && q == (void*)42 ? 42 : 0; } diff --git a/test/parse/cases/6_5_2_2_09_large_frame_struct_byval.c b/test/parse/cases/6_5_2_2_09_large_frame_struct_byval.c @@ -6,9 +6,7 @@ typedef struct Big { int e; } Big; -int take_big(Big b) { - return b.a + b.e; -} +int take_big(Big b) { return b.a + b.e; } int test_main(void) { char pad[8192]; diff --git a/test/parse/cases/6_5_31_subscript_commute.c b/test/parse/cases/6_5_31_subscript_commute.c @@ -1,4 +1,4 @@ int test_main(void) { int a[5] = {0, 0, 42, 0, 0}; - return 2[a]; + return 2 [a]; } diff --git a/test/parse/cases/6_5_32_string_subscript.c b/test/parse/cases/6_5_32_string_subscript.c @@ -1,3 +1 @@ -int test_main(void) { - return "*"[0]; -} +int test_main(void) { return "*"[0]; } diff --git a/test/parse/cases/6_5_32b_string_subscript_nonzero.c b/test/parse/cases/6_5_32b_string_subscript_nonzero.c @@ -3,6 +3,4 @@ * even though `"ab"[0]` and the same byte via `char s[] = "ab"; s[1]` * both work — the limitation is specific to a direct TOK_STR subscript * with a nonzero index. */ -int test_main(void) { - return "ab"[1]; /* 'b' = 98 */ -} +int test_main(void) { return "ab"[1]; /* 'b' = 98 */ } diff --git a/test/parse/cases/6_5_33_regalloc_spill.c b/test/parse/cases/6_5_33_regalloc_spill.c @@ -19,14 +19,14 @@ * * 1+2+...+12 = 78. */ -int sum12(int a, int b, int c, int d, int e, int f, - int g, int h, int i, int j, int k, int l) { +int sum12(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, + int k, int l) { return a + b + c + d + e + f + g + h + i + j + k + l; } int test_main(void) { int x1 = 1, x2 = 2, x3 = 3, x4 = 4, x5 = 5, x6 = 6; int x7 = 7, x8 = 8, x9 = 9, x10 = 10, x11 = 11, x12 = 12; - return sum12(x1 + 0, x2 + 0, x3 + 0, x4 + 0, x5 + 0, x6 + 0, - x7 + 0, x8 + 0, x9 + 0, x10 + 0, x11 + 0, x12 + 0); + return sum12(x1 + 0, x2 + 0, x3 + 0, x4 + 0, x5 + 0, x6 + 0, x7 + 0, x8 + 0, + x9 + 0, x10 + 0, x11 + 0, x12 + 0); } diff --git a/test/parse/cases/6_5_3_2_04_call_deref_function_pointer.c b/test/parse/cases/6_5_3_2_04_call_deref_function_pointer.c @@ -2,10 +2,6 @@ typedef int (*Fn)(int); static int add1(int x) { return x + 1; } -static int call_it(Fn f, int x) { - return (*f)(x); -} +static int call_it(Fn f, int x) { return (*f)(x); } -int test_main(void) { - return call_it(add1, 41); -} +int test_main(void) { return call_it(add1, 41); } diff --git a/test/parse/cases/6_5_40_ptr_add.c b/test/parse/cases/6_5_40_ptr_add.c @@ -1 +1,6 @@ -int test_main(void) { int a[4]={0,0,0,42}; int *p=a; p=p+3; return *p; } +int test_main(void) { + int a[4] = {0, 0, 0, 42}; + int* p = a; + p = p + 3; + return *p; +} diff --git a/test/parse/cases/6_5_41_ptr_sub_ptr.c b/test/parse/cases/6_5_41_ptr_sub_ptr.c @@ -1 +1,6 @@ -int test_main(void) { int a[5]={0}; int *p=a+4; int *q=a+1; return (int)(p-q); } +int test_main(void) { + int a[5] = {0}; + int* p = a + 4; + int* q = a + 1; + return (int)(p - q); +} diff --git a/test/parse/cases/6_5_42_ptr_arith_stride.c b/test/parse/cases/6_5_42_ptr_arith_stride.c @@ -1 +1,5 @@ -int test_main(void) { double a[3]={0.0,0.0,42.0}; double *p=a+2; return (int)*p; } +int test_main(void) { + double a[3] = {0.0, 0.0, 42.0}; + double* p = a + 2; + return (int)*p; +} diff --git a/test/parse/cases/6_5_43_signed_rshift.c b/test/parse/cases/6_5_43_signed_rshift.c @@ -1 +1,4 @@ -int test_main(void) { int x = -256; return (int)((x >> 4) + 58); } +int test_main(void) { + int x = -256; + return (int)((x >> 4) + 58); +} diff --git a/test/parse/cases/6_5_44_relational_all.c b/test/parse/cases/6_5_44_relational_all.c @@ -1 +1,3 @@ -int test_main(void) { return (3>1) + (1<3) + (2<=2) + (2>=2) + (1!=2) + (2==2); } +int test_main(void) { + return (3 > 1) + (1 < 3) + (2 <= 2) + (2 >= 2) + (1 != 2) + (2 == 2); +} diff --git a/test/parse/cases/6_5_45_ptr_eq_null.c b/test/parse/cases/6_5_45_ptr_eq_null.c @@ -1 +1,6 @@ -int test_main(void) { int *p=0; int x=42; int *q=&x; return (p==0) + (q!=0) + (p!=q); } +int test_main(void) { + int* p = 0; + int x = 42; + int* q = &x; + return (p == 0) + (q != 0) + (p != q); +} diff --git a/test/parse/cases/6_5_46_ptr_relcmp.c b/test/parse/cases/6_5_46_ptr_relcmp.c @@ -1 +1,6 @@ -int test_main(void) { int a[3]={0}; int *p=a; int *q=a+2; return (p<q) + (q>p) + (p<=p); } +int test_main(void) { + int a[3] = {0}; + int* p = a; + int* q = a + 2; + return (p < q) + (q > p) + (p <= p); +} diff --git a/test/parse/cases/6_5_47_ternary_arith_conv.c b/test/parse/cases/6_5_47_ternary_arith_conv.c @@ -1 +1,5 @@ -int test_main(void) { int c=1; double r = c ? 1 : 2.5; return (int)(r + 41.0); } +int test_main(void) { + int c = 1; + double r = c ? 1 : 2.5; + return (int)(r + 41.0); +} diff --git a/test/parse/cases/6_5_48_ternary_ptr_null.c b/test/parse/cases/6_5_48_ternary_ptr_null.c @@ -1 +1,5 @@ -int test_main(void) { int x=42; int *p = 1 ? &x : 0; return *p; } +int test_main(void) { + int x = 42; + int* p = 1 ? &x : 0; + return *p; +} diff --git a/test/parse/cases/6_5_49_compound_assign_sub.c b/test/parse/cases/6_5_49_compound_assign_sub.c @@ -1 +1,5 @@ -int test_main(void) { int x = 44; x -= 2; return x; } +int test_main(void) { + int x = 44; + x -= 2; + return x; +} diff --git a/test/parse/cases/6_5_50_compound_assign_shift.c b/test/parse/cases/6_5_50_compound_assign_shift.c @@ -1 +1,5 @@ -int test_main(void) { int x = 336; x >>= 3; return x; } +int test_main(void) { + int x = 336; + x >>= 3; + return x; +} diff --git a/test/parse/cases/6_5_51_compound_assign_bitwise.c b/test/parse/cases/6_5_51_compound_assign_bitwise.c @@ -1 +1,7 @@ -int test_main(void) { int x = 0xff; x &= 0x7f; x ^= 0x55; x |= 0x00; return x; } +int test_main(void) { + int x = 0xff; + x &= 0x7f; + x ^= 0x55; + x |= 0x00; + return x; +} diff --git a/test/parse/cases/6_5_52_compound_assign_ptr.c b/test/parse/cases/6_5_52_compound_assign_ptr.c @@ -1 +1,6 @@ -int test_main(void) { int a[5] = {0, 0, 0, 0, 42}; int *p = a; p += 4; return *p; } +int test_main(void) { + int a[5] = {0, 0, 0, 0, 42}; + int* p = a; + p += 4; + return *p; +} diff --git a/test/parse/cases/6_5_53_sizeof_vla_runtime.c b/test/parse/cases/6_5_53_sizeof_vla_runtime.c @@ -1 +1,5 @@ -int test_main(void) { int n = 7; int a[n]; return (int)sizeof(a); } +int test_main(void) { + int n = 7; + int a[n]; + return (int)sizeof(a); +} diff --git a/test/parse/cases/6_5_54_sizeof_deref_ptr.c b/test/parse/cases/6_5_54_sizeof_deref_ptr.c @@ -1 +1,5 @@ -int test_main(void) { double x = 0.0; double *p = &x; return (int)sizeof(*p); } +int test_main(void) { + double x = 0.0; + double* p = &x; + return (int)sizeof(*p); +} diff --git a/test/parse/cases/6_5_55_generic_default_branch.c b/test/parse/cases/6_5_55_generic_default_branch.c @@ -1 +1,4 @@ -int test_main(void) { double x = 1.0; return _Generic((x), int: 0, default: 42); } +int test_main(void) { + double x = 1.0; + return _Generic((x), int: 0, default: 42); +} diff --git a/test/parse/cases/6_5_56_compound_literal_struct.c b/test/parse/cases/6_5_56_compound_literal_struct.c @@ -1,2 +1,7 @@ -struct S { int a, b; }; -int test_main(void) { struct S s = (struct S){.a = 20, .b = 22}; return s.a + s.b; } +struct S { + int a, b; +}; +int test_main(void) { + struct S s = (struct S){.a = 20, .b = 22}; + return s.a + s.b; +} diff --git a/test/parse/cases/6_5_57_unsigned_wrap_add.c b/test/parse/cases/6_5_57_unsigned_wrap_add.c @@ -1 +1,5 @@ -int test_main(void) { unsigned x = 0xFFFFFFFFU; x += 1; return (int)(x & 0xff); } +int test_main(void) { + unsigned x = 0xFFFFFFFFU; + x += 1; + return (int)(x & 0xff); +} diff --git a/test/parse/cases/6_5_58_large_integer_immediates.c b/test/parse/cases/6_5_58_large_integer_immediates.c @@ -1,5 +1,4 @@ -static unsigned long long add_ull(unsigned long long a, - unsigned long long b) { +static unsigned long long add_ull(unsigned long long a, unsigned long long b) { return a + b; } @@ -7,11 +6,9 @@ int test_main(void) { unsigned long long high = 9223372036854775808ULL; unsigned long long all = 18446744073709551615ULL; if (high + high != 0ULL) return 1; - if (add_ull(9223372036854775808ULL, 9223372036854775807ULL) != all) - return 2; + if (add_ull(9223372036854775808ULL, 9223372036854775807ULL) != all) return 2; if ((long long)9223372036854775808ULL != -9223372036854775807LL - 1LL) return 3; - if (9223372036854775807LL + (-9223372036854775807LL) != 0LL) - return 4; + if (9223372036854775807LL + (-9223372036854775807LL) != 0LL) return 4; return 42; } diff --git a/test/parse/cases/6_5_62_compound_assign_ptr_sub.c b/test/parse/cases/6_5_62_compound_assign_ptr_sub.c @@ -1,6 +1,6 @@ int test_main(void) { int a[5] = {42, 0, 0, 0, 0}; - int *p = a + 4; + int* p = a + 4; p -= 4; return *p; } diff --git a/test/parse/cases/6_5_63_call_arg_conversion.c b/test/parse/cases/6_5_63_call_arg_conversion.c @@ -1,7 +1,3 @@ -static int f(double x) { - return (int)x; -} +static int f(double x) { return (int)x; } -int test_main(void) { - return f(42); -} +int test_main(void) { return f(42); } diff --git a/test/parse/cases/6_5_63_ptr_post_inc_scale.c b/test/parse/cases/6_5_63_ptr_post_inc_scale.c @@ -1,7 +1,7 @@ int test_main(void) { long a[3] = {11, 22, 33}; - long *p = a; - long *old = p++; + long* p = a; + long* old = p++; if (old != a) return 1; if (p != a + 1) return 2; if (*p != 22) return 3; diff --git a/test/parse/cases/6_5_64_unsigned_size_division.c b/test/parse/cases/6_5_64_unsigned_size_division.c @@ -4,10 +4,11 @@ struct Node { char bytes[24]; }; -#define MAX_SIZE_T ((cfree_size_t)~(cfree_size_t)0) -#define LIMIT_N(n, t) \ - ((cfree_size_t)(n) <= MAX_SIZE_T / sizeof(t) ? (n) : \ - (unsigned int)(MAX_SIZE_T / sizeof(t))) +#define MAX_SIZE_T ((cfree_size_t) ~(cfree_size_t)0) +#define LIMIT_N(n, t) \ + ((cfree_size_t)(n) <= MAX_SIZE_T / sizeof(t) \ + ? (n) \ + : (unsigned int)(MAX_SIZE_T / sizeof(t))) int test_main(void) { unsigned int n = 1u << 30; diff --git a/test/parse/cases/6_5_65_file_scope_compound_literal.c b/test/parse/cases/6_5_65_file_scope_compound_literal.c @@ -1,5 +1,3 @@ -static int *p = (int[]){42}; +static int* p = (int[]){42}; -int test_main(void) { - return p[0]; -} +int test_main(void) { return p[0]; } diff --git a/test/parse/cases/6_5_66_file_scope_compound_literal_addr.c b/test/parse/cases/6_5_66_file_scope_compound_literal_addr.c @@ -1,5 +1,3 @@ -static int *p = &(int){42}; +static int* p = &(int){42}; -int test_main(void) { - return *p; -} +int test_main(void) { return *p; } diff --git a/test/parse/cases/6_5_67_file_scope_compound_literal_nested_reloc.c b/test/parse/cases/6_5_67_file_scope_compound_literal_nested_reloc.c @@ -1,6 +1,4 @@ static int x = 41; -static int **pp = (int *[]){&x}; +static int** pp = (int*[]){&x}; -int test_main(void) { - return **pp + 1; -} +int test_main(void) { return **pp + 1; } diff --git a/test/parse/cases/6_5_68_file_scope_compound_literal_struct_addr.c b/test/parse/cases/6_5_68_file_scope_compound_literal_struct_addr.c @@ -3,8 +3,6 @@ struct S { int b; }; -static struct S *p = &(struct S){.a = 20, .b = 22}; +static struct S* p = &(struct S){.a = 20, .b = 22}; -int test_main(void) { - return p->a + p->b; -} +int test_main(void) { return p->a + p->b; } diff --git a/test/parse/cases/6_5_69_file_scope_compound_literal_struct_array.c b/test/parse/cases/6_5_69_file_scope_compound_literal_struct_array.c @@ -3,8 +3,6 @@ struct S { int b; }; -static struct S *p = (struct S[]){{10, 12}, {.a = 7, .b = 13}}; +static struct S* p = (struct S[]){{10, 12}, {.a = 7, .b = 13}}; -int test_main(void) { - return p[0].a + p[0].b + p[1].a + p[1].b; -} +int test_main(void) { return p[0].a + p[0].b + p[1].a + p[1].b; } diff --git a/test/parse/cases/6_5_6_01_negative_pointer_subscript.c b/test/parse/cases/6_5_6_01_negative_pointer_subscript.c @@ -1,6 +1,6 @@ int test_main(void) { char buf[8]; - char *p = &buf[4]; + char* p = &buf[4]; buf[3] = 17; return p[-1] == 17 ? 0 : 1; } diff --git a/test/parse/cases/6_5_6_01_ptr_diff_assign_to_long.c b/test/parse/cases/6_5_6_01_ptr_diff_assign_to_long.c @@ -5,8 +5,8 @@ * "incompatible assignment from pointer to integer" constraint check. */ int test_main(void) { int a[8] = {0}; - int *p = a + 7; - int *q = a + 4; + int* p = a + 7; + int* q = a + 4; long d = p - q; return (int)d + 39; } diff --git a/test/parse/cases/6_5_70_file_scope_compound_literal_const_addr.c b/test/parse/cases/6_5_70_file_scope_compound_literal_const_addr.c @@ -1,5 +1,3 @@ -static const int *p = &(const int){42}; +static const int* p = &(const int){42}; -int test_main(void) { - return *p; -} +int test_main(void) { return *p; } diff --git a/test/parse/cases/6_5_9_01_suppressed_null_ptr_cmp.c b/test/parse/cases/6_5_9_01_suppressed_null_ptr_cmp.c @@ -1,6 +1,6 @@ int test_main(void) { int x = 0; - int *p = &x; + int* p = &x; if (0) { if (p == 0) return 1; } diff --git a/test/parse/cases/6_6_01_enum_const.c b/test/parse/cases/6_6_01_enum_const.c @@ -1,3 +1,4 @@ int test_main(void) { - enum { K = 42 }; return K; + enum { K = 42 }; + return K; } diff --git a/test/parse/cases/6_6_02_const_expr_init.c b/test/parse/cases/6_6_02_const_expr_init.c @@ -1,3 +1,4 @@ int test_main(void) { - int x = 1+2*3; return x; + int x = 1 + 2 * 3; + return x; } diff --git a/test/parse/cases/6_6_03_array_size_const.c b/test/parse/cases/6_6_03_array_size_const.c @@ -1,3 +1,4 @@ int test_main(void) { - int a[3+4] = {0}; return (int)sizeof a / (int)sizeof a[0]; + int a[3 + 4] = {0}; + return (int)sizeof a / (int)sizeof a[0]; } diff --git a/test/parse/cases/6_6_04_alignof_array_size.c b/test/parse/cases/6_6_04_alignof_array_size.c @@ -1,4 +1,4 @@ int test_main(void) { - int a[_Alignof(long long)]; - return (int)sizeof(a) / (int)sizeof(a[0]); + int a[_Alignof(long long)]; + return (int)sizeof(a) / (int)sizeof(a[0]); } diff --git a/test/parse/cases/6_6_05_addr_const_static_init.c b/test/parse/cases/6_6_05_addr_const_static_init.c @@ -1,3 +1,3 @@ static int g = 7; -static int *p = &g; +static int* p = &g; int test_main(void) { return *p * 6; } diff --git a/test/parse/cases/6_6_06_addr_const_arith_init.c b/test/parse/cases/6_6_06_addr_const_arith_init.c @@ -1,3 +1,3 @@ static int arr[4] = {0, 0, 0, 42}; -static int *p = arr + 3; +static int* p = arr + 3; int test_main(void) { return *p; } diff --git a/test/parse/cases/6_6_11_unsigned_const_expr.c b/test/parse/cases/6_6_11_unsigned_const_expr.c @@ -6,6 +6,4 @@ _Static_assert((int)1.75 == 1, "floating constant may be cast in an ICE"); enum { K = (unsigned char)260 + (1 ? 38 : 0) }; -int test_main(void) { - return K; -} +int test_main(void) { return K; } diff --git a/test/parse/cases/6_7_01_typedef.c b/test/parse/cases/6_7_01_typedef.c @@ -1,3 +1,5 @@ int test_main(void) { - typedef int I; I x = 42; return x; + typedef int I; + I x = 42; + return x; } diff --git a/test/parse/cases/6_7_02_static_local.c b/test/parse/cases/6_7_02_static_local.c @@ -1,3 +1,4 @@ int test_main(void) { - static int s = 42; return s; + static int s = 42; + return s; } diff --git a/test/parse/cases/6_7_03_static_global.c b/test/parse/cases/6_7_03_static_global.c @@ -1,2 +1,2 @@ static int g = 42; -int test_main(void){return g;} +int test_main(void) { return g; } diff --git a/test/parse/cases/6_7_04_extern_resolved.c b/test/parse/cases/6_7_04_extern_resolved.c @@ -1,3 +1,3 @@ extern int g; int g = 42; -int test_main(void){return g;} +int test_main(void) { return g; } diff --git a/test/parse/cases/6_7_05_const_qualifier.c b/test/parse/cases/6_7_05_const_qualifier.c @@ -1,3 +1,4 @@ int test_main(void) { - const int c = 42; return c; + const int c = 42; + return c; } diff --git a/test/parse/cases/6_7_06_struct_basic.c b/test/parse/cases/6_7_06_struct_basic.c @@ -1,3 +1,6 @@ int test_main(void) { - struct S { int a, b; } s = {10, 32}; return s.a + s.b; + struct S { + int a, b; + } s = {10, 32}; + return s.a + s.b; } diff --git a/test/parse/cases/6_7_07_union_basic.c b/test/parse/cases/6_7_07_union_basic.c @@ -1,3 +1,8 @@ int test_main(void) { - union U { int i; char c[4]; } u; u.i = 42; return u.i; + union U { + int i; + char c[4]; + } u; + u.i = 42; + return u.i; } diff --git a/test/parse/cases/6_7_08_enum_basic.c b/test/parse/cases/6_7_08_enum_basic.c @@ -1,3 +1,4 @@ int test_main(void) { - enum E { A = 40, B }; return B + 1; + enum E { A = 40, B }; + return B + 1; } diff --git a/test/parse/cases/6_7_09_alignof.c b/test/parse/cases/6_7_09_alignof.c @@ -1,3 +1 @@ -int test_main(void) { - return (int)_Alignof(double); -} +int test_main(void) { return (int)_Alignof(double); } diff --git a/test/parse/cases/6_7_10_01_static_assert_pass.c b/test/parse/cases/6_7_10_01_static_assert_pass.c @@ -1,5 +1,3 @@ _Static_assert(sizeof(int) >= 2, "wide int"); -int test_main(void) { - return 42; -} +int test_main(void) { return 42; } diff --git a/test/parse/cases/6_7_10_02_static_assert_const.c b/test/parse/cases/6_7_10_02_static_assert_const.c @@ -1,5 +1,3 @@ _Static_assert(1 + 1 == 2, "math"); -int test_main(void) { - return 42; -} +int test_main(void) { return 42; } diff --git a/test/parse/cases/6_7_1_01_register_sizeof.c b/test/parse/cases/6_7_1_01_register_sizeof.c @@ -1,4 +1,4 @@ int test_main(void) { - register int x = 42; - return (int)sizeof(x) > 0 ? x : 0; + register int x = 42; + return (int)sizeof(x) > 0 ? x : 0; } diff --git a/test/parse/cases/6_7_1_02_register_multi_decl.c b/test/parse/cases/6_7_1_02_register_multi_decl.c @@ -1,4 +1,4 @@ int test_main(void) { - register int x = 40, y = 2; - return x + y; + register int x = 40, y = 2; + return x + y; } diff --git a/test/parse/cases/6_7_2_01b_unsigned_long_long.c b/test/parse/cases/6_7_2_01b_unsigned_long_long.c @@ -1,4 +1,4 @@ int test_main(void) { - unsigned long long x = 42ULL; - return (int)x; + unsigned long long x = 42ULL; + return (int)x; } diff --git a/test/parse/cases/6_7_2_1_01_bitfield.c b/test/parse/cases/6_7_2_1_01_bitfield.c @@ -1,4 +1,6 @@ int test_main(void) { - struct { unsigned a:5, b:3; } s = {2, 5}; + struct { + unsigned a : 5, b : 3; + } s = {2, 5}; return s.b * 8 + s.a; } diff --git a/test/parse/cases/6_7_2_1_02_anon_struct.c b/test/parse/cases/6_7_2_1_02_anon_struct.c @@ -1,4 +1,9 @@ int test_main(void) { - struct S { int x; struct { int y; }; } s = {0, 42}; + struct S { + int x; + struct { + int y; + }; + } s = {0, 42}; return s.y; } diff --git a/test/parse/cases/6_7_2_1_03_anon_union.c b/test/parse/cases/6_7_2_1_03_anon_union.c @@ -1,5 +1,10 @@ int test_main(void) { - struct S { int x; union { int a, b; }; } s; + struct S { + int x; + union { + int a, b; + }; + } s; s.x = 0; s.a = 42; return s.b; diff --git a/test/parse/cases/6_7_2_1_04_self_ref.c b/test/parse/cases/6_7_2_1_04_self_ref.c @@ -1,5 +1,8 @@ int test_main(void) { - struct N { int v; struct N *next; }; + struct N { + int v; + struct N* next; + }; struct N b = {42, 0}; struct N a = {0, &b}; return a.next->v; diff --git a/test/parse/cases/6_7_2_1_05_forward_tag.c b/test/parse/cases/6_7_2_1_05_forward_tag.c @@ -1,7 +1,9 @@ int test_main(void) { struct S; - struct S *p; - struct S { int v; }; + struct S* p; + struct S { + int v; + }; struct S s = {42}; p = &s; return p->v; diff --git a/test/parse/cases/6_7_2_1_06_mutual_struct_ptr.c b/test/parse/cases/6_7_2_1_06_mutual_struct_ptr.c @@ -7,11 +7,11 @@ struct A; struct B; struct A { int x; - struct B *b; + struct B* b; }; struct B { int y; - struct A *a; + struct A* a; }; int test_main(void) { struct B b = {30, 0}; diff --git a/test/parse/cases/6_7_2_1_07_signed_bitfield.c b/test/parse/cases/6_7_2_1_07_signed_bitfield.c @@ -1,4 +1,6 @@ int test_main(void) { - struct { signed int s : 8; } b = {-1}; - return (b.s < 0) ? 42 : 0; + struct { + signed int s : 8; + } b = {-1}; + return (b.s < 0) ? 42 : 0; } diff --git a/test/parse/cases/6_7_2_1_08_zero_width_bitfield.c b/test/parse/cases/6_7_2_1_08_zero_width_bitfield.c @@ -1,6 +1,10 @@ int test_main(void) { - struct { unsigned a : 4; unsigned : 0; unsigned b : 4; } s; - s.a = 2; - s.b = 5; - return s.b * 8 + s.a; + struct { + unsigned a : 4; + unsigned : 0; + unsigned b : 4; + } s; + s.a = 2; + s.b = 5; + return s.b * 8 + s.a; } diff --git a/test/parse/cases/6_7_2_1_09_bool_bitfield.c b/test/parse/cases/6_7_2_1_09_bool_bitfield.c @@ -1,5 +1,7 @@ int test_main(void) { - struct { _Bool b : 1; } s; - s.b = 1; - return s.b ? 42 : 0; + struct { + _Bool b : 1; + } s; + s.b = 1; + return s.b ? 42 : 0; } diff --git a/test/parse/cases/6_7_2_1_10_static_bitfield_pack.c b/test/parse/cases/6_7_2_1_10_static_bitfield_pack.c @@ -3,6 +3,4 @@ static struct { unsigned b : 3; } g = {2, 5}; -int test_main(void) { - return g.b * 8 + g.a; -} +int test_main(void) { return g.b * 8 + g.a; } diff --git a/test/parse/cases/6_7_2_1_12_mutual_record_pointers.c b/test/parse/cases/6_7_2_1_12_mutual_record_pointers.c @@ -1,12 +1,12 @@ struct A { - struct B *b; + struct B* b; }; struct B { - struct A *a; + struct A* a; }; int test_main(void) { struct A a; - return sizeof(a) == sizeof(void *) ? 0 : 1; + return sizeof(a) == sizeof(void*) ? 0 : 1; } diff --git a/test/parse/cases/6_7_2_1_13_forward_record_ptr_before_offsetof.c b/test/parse/cases/6_7_2_1_13_forward_record_ptr_before_offsetof.c @@ -1,17 +1,13 @@ struct B; struct A { - struct B *b; + struct B* b; }; -int f(struct A a) { - return a.b != 0; -} +int f(struct A a) { return a.b != 0; } struct B { int x; }; -int test_main(void) { - return (int)__builtin_offsetof(struct B, x); -} +int test_main(void) { return (int)__builtin_offsetof(struct B, x); } diff --git a/test/parse/cases/6_7_2_1_14_record_pointer_field_access.c b/test/parse/cases/6_7_2_1_14_record_pointer_field_access.c @@ -3,7 +3,7 @@ struct B { }; struct A { - struct B *b; + struct B* b; }; int test_main(void) { diff --git a/test/parse/cases/6_7_2_2_01_enum_restart.c b/test/parse/cases/6_7_2_2_01_enum_restart.c @@ -1,4 +1,4 @@ int test_main(void) { - enum C { X = 20, Y, Z = 20, W }; - return Y + W; + enum C { X = 20, Y, Z = 20, W }; + return Y + W; } diff --git a/test/parse/cases/6_7_2_3_01_tag_inner_scope.c b/test/parse/cases/6_7_2_3_01_tag_inner_scope.c @@ -1,6 +1,10 @@ -struct S { int v; }; +struct S { + int v; +}; int test_main(void) { - struct S { int v; }; - struct S s = {42}; - return s.v; + struct S { + int v; + }; + struct S s = {42}; + return s.v; } diff --git a/test/parse/cases/6_7_3_02_restrict_param.c b/test/parse/cases/6_7_3_02_restrict_param.c @@ -1,6 +1,4 @@ -int rd(int *restrict p) { - return *p; -} +int rd(int* restrict p) { return *p; } int test_main(void) { int x = 42; diff --git a/test/parse/cases/6_7_3_03_const_pointer.c b/test/parse/cases/6_7_3_03_const_pointer.c @@ -1,5 +1,5 @@ int test_main(void) { int x = 42; - int *const p = &x; + int* const p = &x; return *p; } diff --git a/test/parse/cases/6_7_3_04_ptr_to_const.c b/test/parse/cases/6_7_3_04_ptr_to_const.c @@ -1,5 +1,5 @@ int test_main(void) { const int x = 42; - const int *p = &x; + const int* p = &x; return *p; } diff --git a/test/parse/cases/6_7_3_06_repeated_const.c b/test/parse/cases/6_7_3_06_repeated_const.c @@ -1,4 +1,4 @@ int test_main(void) { - const const int x = 42; - return x; + const const int x = 42; + return x; } diff --git a/test/parse/cases/6_7_3_07_const_array_typedef.c b/test/parse/cases/6_7_3_07_const_array_typedef.c @@ -1,5 +1,5 @@ typedef int A[3]; int test_main(void) { - const A a = {10, 20, 12}; - return a[0] + a[1] + a[2]; + const A a = {10, 20, 12}; + return a[0] + a[1] + a[2]; } diff --git a/test/parse/cases/6_7_4_01_inline.c b/test/parse/cases/6_7_4_01_inline.c @@ -1,7 +1,3 @@ -static inline int id(int x) { - return x; -} +static inline int id(int x) { return x; } -int test_main(void) { - return id(42); -} +int test_main(void) { return id(42); } diff --git a/test/parse/cases/6_7_4_02_noreturn.c b/test/parse/cases/6_7_4_02_noreturn.c @@ -1,7 +1,3 @@ -_Noreturn void die(void) { - for (;;) ; -} +_Noreturn void die(void) { for (;;); } -int test_main(void) { - return 42; -} +int test_main(void) { return 42; } diff --git a/test/parse/cases/6_7_5_01_alignas_obj.c b/test/parse/cases/6_7_5_01_alignas_obj.c @@ -1,5 +1,3 @@ _Alignas(16) static char buf[16]; -int test_main(void) { - return (((unsigned long)buf) & 15) ? 0 : 42; -} +int test_main(void) { return (((unsigned long)buf) & 15) ? 0 : 42; } diff --git a/test/parse/cases/6_7_6_01_ptr_to_ptr.c b/test/parse/cases/6_7_6_01_ptr_to_ptr.c @@ -1,6 +1,6 @@ int test_main(void) { int x = 42; - int *p = &x; - int **pp = &p; + int* p = &x; + int** pp = &p; return **pp; } diff --git a/test/parse/cases/6_7_6_03_array_of_ptr.c b/test/parse/cases/6_7_6_03_array_of_ptr.c @@ -1,5 +1,5 @@ int test_main(void) { int x = 42; - int *a[2] = {0, &x}; + int* a[2] = {0, &x}; return *a[1]; } diff --git a/test/parse/cases/6_7_6_05_funcptr_returning_ptr.c b/test/parse/cases/6_7_6_05_funcptr_returning_ptr.c @@ -1,7 +1,7 @@ -int *passthrough(int *q) { return q; } +int* passthrough(int* q) { return q; } int test_main(void) { int x = 42; - int *(*fp)(int *) = passthrough; + int* (*fp)(int*) = passthrough; return *fp(&x); } diff --git a/test/parse/cases/6_7_6_08_variadic_decl.c b/test/parse/cases/6_7_6_08_variadic_decl.c @@ -7,6 +7,4 @@ int sum(int n, ...) { return s; } -int test_main(void) { - return sum(2, 20, 22); -} +int test_main(void) { return sum(2, 20, 22); } diff --git a/test/parse/cases/6_7_6_09_ptr_to_array.c b/test/parse/cases/6_7_6_09_ptr_to_array.c @@ -1,5 +1,5 @@ int test_main(void) { - int b[3] = {0, 0, 42}; - int (*pa)[3] = &b; - return (*pa)[2]; + int b[3] = {0, 0, 42}; + int (*pa)[3] = &b; + return (*pa)[2]; } diff --git a/test/parse/cases/6_7_6_10_array_of_funcptr.c b/test/parse/cases/6_7_6_10_array_of_funcptr.c @@ -1,6 +1,6 @@ int add1(int x) { return x + 1; } int sub1(int x) { return x - 1; } int test_main(void) { - int (*ops[2])(int) = {add1, sub1}; - return ops[0](ops[1](42)); + int (*ops[2])(int) = {add1, sub1}; + return ops[0](ops[1](42)); } diff --git a/test/parse/cases/6_7_6_12_vla_param.c b/test/parse/cases/6_7_6_12_vla_param.c @@ -1,9 +1,9 @@ int sum_vla(int n, int a[n]) { - int s = 0; - for (int i = 0; i < n; i++) s += a[i]; - return s; + int s = 0; + for (int i = 0; i < n; i++) s += a[i]; + return s; } int test_main(void) { - int a[3] = {10, 20, 12}; - return sum_vla(3, a); + int a[3] = {10, 20, 12}; + return sum_vla(3, a); } diff --git a/test/parse/cases/6_7_6_13_star_in_proto.c b/test/parse/cases/6_7_6_13_star_in_proto.c @@ -1,10 +1,10 @@ int total(int n, int a[*]); int total(int n, int a[n]) { - int s = 0; - for (int i = 0; i < n; i++) s += a[i]; - return s; + int s = 0; + for (int i = 0; i < n; i++) s += a[i]; + return s; } int test_main(void) { - int b[3] = {1, 2, 39}; - return total(3, b); + int b[3] = {1, 2, 39}; + return total(3, b); } diff --git a/test/parse/cases/6_7_6_14_func_param_adjust.c b/test/parse/cases/6_7_6_14_func_param_adjust.c @@ -1,9 +1,5 @@ int inc(int x) { return x + 1; } -int apply(int f(int), int x) { - return f(x); -} +int apply(int f(int), int x) { return f(x); } -int test_main(void) { - return apply(inc, 41); -} +int test_main(void) { return apply(inc, 41); } diff --git a/test/parse/cases/6_7_6_15_multidim_vla_local.c b/test/parse/cases/6_7_6_15_multidim_vla_local.c @@ -1,7 +1,7 @@ int test_main(void) { - int n = 6; - int m = 7; - int a[n][m]; - a[n - 1][m - 1] = 42; - return a[5][6]; + int n = 6; + int m = 7; + int a[n][m]; + a[n - 1][m - 1] = 42; + return a[5][6]; } diff --git a/test/parse/cases/6_7_6_16_vla_param_2d.c b/test/parse/cases/6_7_6_16_vla_param_2d.c @@ -1,6 +1,4 @@ -int pick_last(int n, int m, int a[n][m]) { - return a[n - 1][m - 1]; -} +int pick_last(int n, int m, int a[n][m]) { return a[n - 1][m - 1]; } int test_main(void) { int a[2][3] = {{0, 0, 0}, {0, 0, 42}}; diff --git a/test/parse/cases/6_7_6_18_file_scope_array_bound_paren.c b/test/parse/cases/6_7_6_18_file_scope_array_bound_paren.c @@ -6,6 +6,4 @@ * a file-scope declaration that has no enclosing function. */ static int marks[(2 + 5)] = {0, 0, 0, 0, 0, 0, 42}; -int test_main(void) { - return marks[6]; -} +int test_main(void) { return marks[6]; } diff --git a/test/parse/cases/6_7_6_19_paren_declarator_name.c b/test/parse/cases/6_7_6_19_paren_declarator_name.c @@ -3,8 +3,6 @@ * parens is legal and changes nothing semantically. Real-world headers * (lua, glibc) use this to suppress function-like macro expansion at * the declaration site. Currently rejected with "expected declarator". */ -int (helper)(int x) { return x; } +int(helper)(int x) { return x; } -int test_main(void) { - return (helper)(42); -} +int test_main(void) { return (helper)(42); } diff --git a/test/parse/cases/6_7_6_20_func_returning_funcptr_no_typedef.c b/test/parse/cases/6_7_6_20_func_returning_funcptr_no_typedef.c @@ -12,6 +12,4 @@ int (*pick(int x))(void) { return leaf; } -int test_main(void) { - return pick(0)(); -} +int test_main(void) { return pick(0)(); } diff --git a/test/parse/cases/6_7_6_21_field_ptr_to_func_returning_funcptr.c b/test/parse/cases/6_7_6_21_field_ptr_to_func_returning_funcptr.c @@ -12,19 +12,20 @@ * sqlite3.c:1822. */ static void inner(void) {} -static void (*pick(void *p, const char *n))(void) { - (void)p; (void)n; +static void (*pick(void* p, const char* n))(void) { + (void)p; + (void)n; return inner; } struct vfs { - void (*(*xDlSym)(void *, const char *))(void); + void (*(*xDlSym)(void*, const char*))(void); }; int test_main(void) { struct vfs v; v.xDlSym = pick; - void (*fn)(void) = v.xDlSym((void *)0, "x"); + void (*fn)(void) = v.xDlSym((void*)0, "x"); fn(); return 42; } diff --git a/test/parse/cases/6_7_7_01_abstract_ptr_array_cast.c b/test/parse/cases/6_7_7_01_abstract_ptr_array_cast.c @@ -1,5 +1,5 @@ int test_main(void) { - int b[3] = {0, 0, 42}; - void *v = &b; - return ((int (*)[3])v)[0][2]; + int b[3] = {0, 0, 42}; + void* v = &b; + return ((int (*)[3])v)[0][2]; } diff --git a/test/parse/cases/6_7_8_01_typedef_struct.c b/test/parse/cases/6_7_8_01_typedef_struct.c @@ -1,5 +1,7 @@ int test_main(void) { - typedef struct { int v; } S; + typedef struct { + int v; + } S; S s = {42}; return s.v; } diff --git a/test/parse/cases/6_7_8_05_typedef_vla_size_fixed.c b/test/parse/cases/6_7_8_05_typedef_vla_size_fixed.c @@ -1,8 +1,8 @@ int f(int n) { - typedef int B[n]; - n += 10; - B a; - for (int i = 0; i < (int)(sizeof(a) / sizeof(int)); i++) a[i] = i * 6; - return a[6]; + typedef int B[n]; + n += 10; + B a; + for (int i = 0; i < (int)(sizeof(a) / sizeof(int)); i++) a[i] = i * 6; + return a[6]; } int test_main(void) { return f(7); } diff --git a/test/parse/cases/6_7_8_06_typedef_multi_decl.c b/test/parse/cases/6_7_8_06_typedef_multi_decl.c @@ -1,8 +1,8 @@ typedef int TWICE, (*PFUNC)(int); int dbl(int x) { return x * 2; } int test_main(void) { - TWICE y = 0; - PFUNC fp = dbl; - y = fp(21); - return y; + TWICE y = 0; + PFUNC fp = dbl; + y = fp(21); + return y; } diff --git a/test/parse/cases/6_7_9_01_scalar_init.c b/test/parse/cases/6_7_9_01_scalar_init.c @@ -1,3 +1,4 @@ int test_main(void) { - int x = 42; return x; + int x = 42; + return x; } diff --git a/test/parse/cases/6_7_9_02_array_brace.c b/test/parse/cases/6_7_9_02_array_brace.c @@ -1,3 +1,4 @@ int test_main(void) { - int a[3] = {10, 20, 12}; return a[0]+a[1]+a[2]; + int a[3] = {10, 20, 12}; + return a[0] + a[1] + a[2]; } diff --git a/test/parse/cases/6_7_9_03_partial_zero.c b/test/parse/cases/6_7_9_03_partial_zero.c @@ -1,3 +1,4 @@ int test_main(void) { - int a[5] = {42}; return a[0] + a[4]; + int a[5] = {42}; + return a[0] + a[4]; } diff --git a/test/parse/cases/6_7_9_04_designated.c b/test/parse/cases/6_7_9_04_designated.c @@ -1,3 +1,4 @@ int test_main(void) { - int a[5] = {[2] = 42}; return a[2]; + int a[5] = {[2] = 42}; + return a[2]; } diff --git a/test/parse/cases/6_7_9_05_struct_init.c b/test/parse/cases/6_7_9_05_struct_init.c @@ -1,3 +1,6 @@ int test_main(void) { - struct S {int a,b;} s={40,2}; return s.a+s.b; + struct S { + int a, b; + } s = {40, 2}; + return s.a + s.b; } diff --git a/test/parse/cases/6_7_9_06_string_init.c b/test/parse/cases/6_7_9_06_string_init.c @@ -1,3 +1,4 @@ int test_main(void) { - char s[] = "hi"; return s[0]+s[1]+s[2]; + char s[] = "hi"; + return s[0] + s[1] + s[2]; } diff --git a/test/parse/cases/6_7_9_07_designated_struct.c b/test/parse/cases/6_7_9_07_designated_struct.c @@ -1,4 +1,6 @@ int test_main(void) { - struct S { int a, b, c; } s = {.b = 42}; + struct S { + int a, b, c; + } s = {.b = 42}; return s.b; } diff --git a/test/parse/cases/6_7_9_09_struct_in_array.c b/test/parse/cases/6_7_9_09_struct_in_array.c @@ -1,4 +1,6 @@ int test_main(void) { - struct P { int x, y; } a[2] = {{0, 0}, {0, 42}}; + struct P { + int x, y; + } a[2] = {{0, 0}, {0, 42}}; return a[1].y; } diff --git a/test/parse/cases/6_7_9_10_zero_init_static.c b/test/parse/cases/6_7_9_10_zero_init_static.c @@ -1,5 +1,3 @@ static int g[3]; -int test_main(void) { - return g[0] + g[1] + g[2] + 42; -} +int test_main(void) { return g[0] + g[1] + g[2] + 42; } diff --git a/test/parse/cases/6_7_9_11_array_size_from_init.c b/test/parse/cases/6_7_9_11_array_size_from_init.c @@ -1,4 +1,4 @@ int test_main(void) { - int x[] = {10, 12, 20}; - return x[0] + x[1] + x[2]; + int x[] = {10, 12, 20}; + return x[0] + x[1] + x[2]; } diff --git a/test/parse/cases/6_7_9_12_designator_override.c b/test/parse/cases/6_7_9_12_designator_override.c @@ -1,4 +1,4 @@ int test_main(void) { - int a[3] = {[1] = 99, [1] = 42, [0] = 0}; - return a[1]; + int a[3] = {[1] = 99, [1] = 42, [0] = 0}; + return a[1]; } diff --git a/test/parse/cases/6_7_9_13_string_init_fixed_larger.c b/test/parse/cases/6_7_9_13_string_init_fixed_larger.c @@ -1,6 +1,6 @@ int test_main(void) { - char s[6] = "hi"; - int sum = 0; - for (int i = 0; i < 6; i++) sum += s[i]; - return sum; + char s[6] = "hi"; + int sum = 0; + for (int i = 0; i < 6; i++) sum += s[i]; + return sum; } diff --git a/test/parse/cases/6_7_9_14_struct_copy_init.c b/test/parse/cases/6_7_9_14_struct_copy_init.c @@ -1,5 +1,7 @@ int test_main(void) { - struct S { int a, b; } src = {20, 22}; - struct S dst = src; - return dst.a + dst.b; + struct S { + int a, b; + } src = {20, 22}; + struct S dst = src; + return dst.a + dst.b; } diff --git a/test/parse/cases/6_7_9_15_union_designated_nonfirst.c b/test/parse/cases/6_7_9_15_union_designated_nonfirst.c @@ -1,4 +1,7 @@ int test_main(void) { - union U { int a; int b; } u = {.b = 42}; - return u.b; + union U { + int a; + int b; + } u = {.b = 42}; + return u.b; } diff --git a/test/parse/cases/6_7_9_16_enum_designator.c b/test/parse/cases/6_7_9_16_enum_designator.c @@ -1,5 +1,5 @@ int test_main(void) { - enum { X = 2 }; - int a[4] = {[X] = 42}; - return a[X]; + enum { X = 2 }; + int a[4] = {[X] = 42}; + return a[X]; } diff --git a/test/parse/cases/6_7_9_17_inconsistent_bracket_init.c b/test/parse/cases/6_7_9_17_inconsistent_bracket_init.c @@ -1,4 +1,7 @@ int test_main(void) { - struct T { int a[2]; int b; } w[2] = {{1}, 2}; - return w[0].a[0] + w[1].a[0]; + struct T { + int a[2]; + int b; + } w[2] = {{1}, 2}; + return w[0].a[0] + w[1].a[0]; } diff --git a/test/parse/cases/6_7_9_18_static_init_string_ptr.c b/test/parse/cases/6_7_9_18_static_init_string_ptr.c @@ -1,3 +1,5 @@ -typedef struct { const char* s; } S; -static const S g = { .s = "hi" }; +typedef struct { + const char* s; +} S; +static const S g = {.s = "hi"}; int test_main(void) { return g.s[0] + g.s[1]; } diff --git a/test/parse/cases/6_7_9_19_static_init_string_array.c b/test/parse/cases/6_7_9_19_static_init_string_array.c @@ -1,4 +1,2 @@ static const char* const names[2] = {"a", "b"}; -int test_main(void) { - return names[0][0] + names[1][0] - 'a' * 2 + 41; -} +int test_main(void) { return names[0][0] + names[1][0] - 'a' * 2 + 41; } diff --git a/test/parse/cases/6_7_9_20_array_of_struct_with_array_field.c b/test/parse/cases/6_7_9_20_array_of_struct_with_array_field.c @@ -1,5 +1,9 @@ -typedef struct { unsigned a; unsigned char p[2]; } S; -static const S t[] = { {10u, {1, 2}}, {15u, {3, 11}} }; +typedef struct { + unsigned a; + unsigned char p[2]; +} S; +static const S t[] = {{10u, {1, 2}}, {15u, {3, 11}}}; int test_main(void) { - return (int)(t[0].a + t[1].a) + (int)(t[0].p[0] + t[0].p[1] + t[1].p[0] + t[1].p[1]); + return (int)(t[0].a + t[1].a) + + (int)(t[0].p[0] + t[0].p[1] + t[1].p[0] + t[1].p[1]); } diff --git a/test/parse/cases/6_7_9_21_array_of_struct_size_from_init.c b/test/parse/cases/6_7_9_21_array_of_struct_size_from_init.c @@ -1,6 +1,8 @@ -typedef struct { int a; int b; } S; -static const S t[] = { {10, 12}, {7, 13} }; +typedef struct { + int a; + int b; +} S; +static const S t[] = {{10, 12}, {7, 13}}; int test_main(void) { - return t[0].a + t[0].b + t[1].a + t[1].b - + (int)(sizeof(t) / sizeof(t[0])); + return t[0].a + t[0].b + t[1].a + t[1].b + (int)(sizeof(t) / sizeof(t[0])); } diff --git a/test/parse/cases/6_7_9_22_static_union_designated_nonfirst.c b/test/parse/cases/6_7_9_22_static_union_designated_nonfirst.c @@ -3,6 +3,4 @@ static union U { int b; } g = {.b = 42}; -int test_main(void) { - return g.b; -} +int test_main(void) { return g.b; } diff --git a/test/parse/cases/6_7_9_23_static_ptr_null_const_expr.c b/test/parse/cases/6_7_9_23_static_ptr_null_const_expr.c @@ -1,5 +1,3 @@ static int* p = 1 - 1; -int test_main(void) { - return p == 0 ? 42 : 0; -} +int test_main(void) { return p == 0 ? 42 : 0; } diff --git a/test/parse/cases/6_7_9_27_static_flat_array_init.c b/test/parse/cases/6_7_9_27_static_flat_array_init.c @@ -1,5 +1,3 @@ static int a[2][2] = {1, 2, 3, 36}; -int test_main(void) { - return a[0][0] + a[0][1] + a[1][0] + a[1][1]; -} +int test_main(void) { return a[0][0] + a[0][1] + a[1][0] + a[1][1]; } diff --git a/test/parse/cases/6_7_9_28_static_flat_struct_init.c b/test/parse/cases/6_7_9_28_static_flat_struct_init.c @@ -10,6 +10,4 @@ struct O { static struct O o = {1, 2, 39}; -int test_main(void) { - return o.i.a + o.i.b + o.c; -} +int test_main(void) { return o.i.a + o.i.b + o.c; } diff --git a/test/parse/cases/6_7_9_30_static_init_neg_float.c b/test/parse/cases/6_7_9_30_static_init_neg_float.c @@ -5,8 +5,6 @@ * "expected floating constant expression". Hits stb_sprintf's * `stbsp__negboterr` table, libm coefficient tables, and any numeric * library that ships negative constants. */ -static const double tab[2] = { -1.0, 43.0 }; +static const double tab[2] = {-1.0, 43.0}; -int test_main(void) { - return (int)(tab[0] + tab[1]); -} +int test_main(void) { return (int)(tab[0] + tab[1]); } diff --git a/test/parse/cases/6_7_9_34_static_ptr_array_addend.c b/test/parse/cases/6_7_9_34_static_ptr_array_addend.c @@ -2,7 +2,7 @@ const unsigned char table[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, }; -const unsigned char *p = &table[6 - 2]; +const unsigned char* p = &table[6 - 2]; int test_main(void) { if (p[0] != 4) return 1; diff --git a/test/parse/cases/6_7_file_scope_register.c b/test/parse/cases/6_7_file_scope_register.c @@ -1,5 +1,3 @@ register int x; -int test_main(void) { - return (int)sizeof(x) == (int)sizeof(int) ? 42 : 1; -} +int test_main(void) { return (int)sizeof(x) == (int)sizeof(int) ? 42 : 1; } diff --git a/test/parse/cases/6_8_04_do_while.c b/test/parse/cases/6_8_04_do_while.c @@ -1,3 +1,7 @@ int test_main(void) { - int i=0; do { i=42; } while (0); return i; + int i = 0; + do { + i = 42; + } while (0); + return i; } diff --git a/test/parse/cases/6_8_05_break.c b/test/parse/cases/6_8_05_break.c @@ -1,3 +1,6 @@ int test_main(void) { - int i; for (i=0;;i++) if (i==42) break; return i; + int i; + for (i = 0;; i++) + if (i == 42) break; + return i; } diff --git a/test/parse/cases/6_8_06_continue.c b/test/parse/cases/6_8_06_continue.c @@ -1,3 +1,8 @@ int test_main(void) { - int s=0; for (int i=0; i<20; i++) { if (i & 1) continue; s += i; } return s; + int s = 0; + for (int i = 0; i < 20; i++) { + if (i & 1) continue; + s += i; + } + return s; } diff --git a/test/parse/cases/6_8_07_switch_case.c b/test/parse/cases/6_8_07_switch_case.c @@ -1,3 +1,12 @@ int test_main(void) { - int x = 2; switch (x) { case 1: return 1; case 2: return 42; case 3: return 3; } return 0; + int x = 2; + switch (x) { + case 1: + return 1; + case 2: + return 42; + case 3: + return 3; + } + return 0; } diff --git a/test/parse/cases/6_8_08_switch_fallthrough.c b/test/parse/cases/6_8_08_switch_fallthrough.c @@ -1,3 +1,11 @@ int test_main(void) { - int r = 0; int x = 1; switch (x) { case 1: r += 10; case 2: r += 20; } return r; + int r = 0; + int x = 1; + switch (x) { + case 1: + r += 10; + case 2: + r += 20; + } + return r; } diff --git a/test/parse/cases/6_8_09_switch_default.c b/test/parse/cases/6_8_09_switch_default.c @@ -1,3 +1,12 @@ int test_main(void) { - int x = 99; switch (x) { case 1: return 1; case 2: return 2; default: return 7; } return 0; + int x = 99; + switch (x) { + case 1: + return 1; + case 2: + return 2; + default: + return 7; + } + return 0; } diff --git a/test/parse/cases/6_8_10_goto_forward.c b/test/parse/cases/6_8_10_goto_forward.c @@ -1,3 +1,7 @@ int test_main(void) { - int r = 0; goto L; r = 99; L: return 42; + int r = 0; + goto L; + r = 99; +L: + return 42; } diff --git a/test/parse/cases/6_8_11_goto_backward.c b/test/parse/cases/6_8_11_goto_backward.c @@ -1,3 +1,9 @@ int test_main(void) { - int i = 0; L: if (i == 10) goto E; i++; goto L; E: return i; + int i = 0; +L: + if (i == 10) goto E; + i++; + goto L; +E: + return i; } diff --git a/test/parse/cases/6_8_12_block_scope.c b/test/parse/cases/6_8_12_block_scope.c @@ -1,3 +1,7 @@ int test_main(void) { - int x = 7; { int x = 42; return x; } + int x = 7; + { + int x = 42; + return x; + } } diff --git a/test/parse/cases/6_8_13_compound_decl_mix.c b/test/parse/cases/6_8_13_compound_decl_mix.c @@ -1,3 +1,6 @@ int test_main(void) { - int a = 40; a += 1; int b = 1; return a + b; + int a = 40; + a += 1; + int b = 1; + return a + b; } diff --git a/test/parse/cases/6_8_14_return_void.c b/test/parse/cases/6_8_14_return_void.c @@ -1,2 +1,5 @@ -void f(void){return;} -int test_main(void){f(); return 42;} +void f(void) { return; } +int test_main(void) { + f(); + return 42; +} diff --git a/test/parse/cases/6_8_15_null_statement.c b/test/parse/cases/6_8_15_null_statement.c @@ -1,3 +1,5 @@ int test_main(void) { - int i; for (i = 0; i < 42; i++) ; return i; + int i; + for (i = 0; i < 42; i++); + return i; } diff --git a/test/parse/cases/6_8_16_dangling_else.c b/test/parse/cases/6_8_16_dangling_else.c @@ -1,5 +1,9 @@ int test_main(void) { - int r = 0; - if (1) if (0) r = 1; else r = 42; - return r; + int r = 0; + if (1) + if (0) + r = 1; + else + r = 42; + return r; } diff --git a/test/parse/cases/6_8_17_switch_char_ctrl.c b/test/parse/cases/6_8_17_switch_char_ctrl.c @@ -1,9 +1,13 @@ int test_main(void) { - char c = 2; - int r = 0; - switch (c) { - case 1: r = 1; break; - case 2: r = 42; break; - } - return r; + char c = 2; + int r = 0; + switch (c) { + case 1: + r = 1; + break; + case 2: + r = 42; + break; + } + return r; } diff --git a/test/parse/cases/6_8_18_switch_no_match_no_default.c b/test/parse/cases/6_8_18_switch_no_match_no_default.c @@ -1,9 +1,13 @@ int test_main(void) { - int x = 99; - int r = 7; - switch (x) { - case 1: r = 1; break; - case 2: r = 2; break; - } - return r; + int x = 99; + int r = 7; + switch (x) { + case 1: + r = 1; + break; + case 2: + r = 2; + break; + } + return r; } diff --git a/test/parse/cases/6_8_19_switch_nested_dup_case.c b/test/parse/cases/6_8_19_switch_nested_dup_case.c @@ -1,12 +1,16 @@ int test_main(void) { - int r = 0; - switch (1) { + int r = 0; + switch (1) { + case 1: + switch (2) { case 1: - switch (2) { - case 1: r = 0; break; - case 2: r = 42; break; - } - break; - } - return r; + r = 0; + break; + case 2: + r = 42; + break; + } + break; + } + return r; } diff --git a/test/parse/cases/6_8_20_switch_hidden_scope.c b/test/parse/cases/6_8_20_switch_hidden_scope.c @@ -1,9 +1,10 @@ int test_main(void) { - int r = 0; - switch (1) { - int x = 99; - (void)x; - case 1: r = 42; - } - return r; + int r = 0; + switch (1) { + int x = 99; + (void)x; + case 1: + r = 42; + } + return r; } diff --git a/test/parse/cases/6_8_21_for_infinite_break.c b/test/parse/cases/6_8_21_for_infinite_break.c @@ -1,8 +1,8 @@ int test_main(void) { - int i = 0; - for (;;) { - i++; - if (i == 42) break; - } - return i; + int i = 0; + for (;;) { + i++; + if (i == 42) break; + } + return i; } diff --git a/test/parse/cases/6_8_23_continue_do_while.c b/test/parse/cases/6_8_23_continue_do_while.c @@ -1,9 +1,9 @@ int test_main(void) { - int s = 0, i = 0; - do { - i++; - if (i % 2 == 0) continue; - s += i; - } while (i < 10); - return s; + int s = 0, i = 0; + do { + i++; + if (i % 2 == 0) continue; + s += i; + } while (i < 10); + return s; } diff --git a/test/parse/cases/6_8_24_break_switch_in_loop.c b/test/parse/cases/6_8_24_break_switch_in_loop.c @@ -1,9 +1,11 @@ int test_main(void) { - int r = 0; - for (int i = 0; i < 5; i++) { - switch (i) { - case 3: r = i; break; - } + int r = 0; + for (int i = 0; i < 5; i++) { + switch (i) { + case 3: + r = i; + break; } - return r; + } + return r; } diff --git a/test/parse/cases/6_8_25_continue_inside_switch.c b/test/parse/cases/6_8_25_continue_inside_switch.c @@ -1,10 +1,12 @@ int test_main(void) { - int s = 0; - for (int i = 0; i < 5; i++) { - switch (i % 2) { - case 0: continue; - default: s += i; - } + int s = 0; + for (int i = 0; i < 5; i++) { + switch (i % 2) { + case 0: + continue; + default: + s += i; } - return s; + } + return s; } diff --git a/test/parse/cases/6_8_26_goto_into_nested_block.c b/test/parse/cases/6_8_26_goto_into_nested_block.c @@ -1,9 +1,9 @@ int test_main(void) { - int r = 0; - goto inner; - { - inner: - r = 42; - } - return r; + int r = 0; + goto inner; + { + inner: + r = 42; + } + return r; } diff --git a/test/parse/cases/6_8_26_switch_many_cases.c b/test/parse/cases/6_8_26_switch_many_cases.c @@ -1,147 +1,289 @@ static int pick(unsigned short x) { switch (x) { - case 0: return 0; - case 1: return 1; - case 2: return 2; - case 3: return 3; - case 4: return 4; - case 5: return 5; - case 6: return 6; - case 7: return 7; - case 8: return 8; - case 9: return 9; - case 10: return 10; - case 11: return 11; - case 12: return 12; - case 13: return 13; - case 14: return 14; - case 15: return 15; - case 16: return 16; - case 17: return 17; - case 18: return 18; - case 19: return 19; - case 20: return 20; - case 21: return 21; - case 22: return 22; - case 23: return 23; - case 24: return 24; - case 25: return 25; - case 26: return 26; - case 27: return 27; - case 28: return 28; - case 29: return 29; - case 30: return 30; - case 31: return 31; - case 32: return 32; - case 33: return 33; - case 34: return 34; - case 35: return 35; - case 36: return 36; - case 37: return 37; - case 38: return 38; - case 39: return 39; - case 40: return 40; - case 41: return 41; - case 42: return 42; - case 43: return 43; - case 44: return 44; - case 45: return 45; - case 46: return 46; - case 47: return 47; - case 48: return 48; - case 49: return 49; - case 50: return 50; - case 51: return 51; - case 52: return 52; - case 53: return 53; - case 54: return 54; - case 55: return 55; - case 56: return 56; - case 57: return 57; - case 58: return 58; - case 59: return 59; - case 60: return 60; - case 61: return 61; - case 62: return 62; - case 63: return 63; - case 64: return 64; - case 65: return 65; - case 66: return 66; - case 67: return 67; - case 68: return 68; - case 69: return 69; - case 70: return 70; - case 71: return 71; - case 72: return 72; - case 73: return 73; - case 74: return 74; - case 75: return 75; - case 76: return 76; - case 77: return 77; - case 78: return 78; - case 79: return 79; - case 80: return 80; - case 81: return 81; - case 82: return 82; - case 83: return 83; - case 84: return 84; - case 85: return 85; - case 86: return 86; - case 87: return 87; - case 88: return 88; - case 89: return 89; - case 90: return 90; - case 91: return 91; - case 92: return 92; - case 93: return 93; - case 94: return 94; - case 95: return 95; - case 96: return 96; - case 97: return 97; - case 98: return 98; - case 99: return 99; - case 100: return 100; - case 101: return 101; - case 102: return 102; - case 103: return 103; - case 104: return 104; - case 105: return 105; - case 106: return 106; - case 107: return 107; - case 108: return 108; - case 109: return 109; - case 110: return 110; - case 111: return 111; - case 112: return 112; - case 113: return 113; - case 114: return 114; - case 115: return 115; - case 116: return 116; - case 117: return 117; - case 118: return 118; - case 119: return 119; - case 120: return 120; - case 121: return 121; - case 122: return 122; - case 123: return 123; - case 124: return 124; - case 125: return 125; - case 126: return 126; - case 127: return 127; - case 128: return 128; - case 129: return 129; - case 130: return 130; - case 131: return 131; - case 132: return 132; - case 133: return 133; - case 134: return 134; - case 135: return 135; - case 136: return 136; - case 137: return 137; - case 138: return 138; - case 139: return 139; - case 140: return 140; - default: return -1; + case 0: + return 0; + case 1: + return 1; + case 2: + return 2; + case 3: + return 3; + case 4: + return 4; + case 5: + return 5; + case 6: + return 6; + case 7: + return 7; + case 8: + return 8; + case 9: + return 9; + case 10: + return 10; + case 11: + return 11; + case 12: + return 12; + case 13: + return 13; + case 14: + return 14; + case 15: + return 15; + case 16: + return 16; + case 17: + return 17; + case 18: + return 18; + case 19: + return 19; + case 20: + return 20; + case 21: + return 21; + case 22: + return 22; + case 23: + return 23; + case 24: + return 24; + case 25: + return 25; + case 26: + return 26; + case 27: + return 27; + case 28: + return 28; + case 29: + return 29; + case 30: + return 30; + case 31: + return 31; + case 32: + return 32; + case 33: + return 33; + case 34: + return 34; + case 35: + return 35; + case 36: + return 36; + case 37: + return 37; + case 38: + return 38; + case 39: + return 39; + case 40: + return 40; + case 41: + return 41; + case 42: + return 42; + case 43: + return 43; + case 44: + return 44; + case 45: + return 45; + case 46: + return 46; + case 47: + return 47; + case 48: + return 48; + case 49: + return 49; + case 50: + return 50; + case 51: + return 51; + case 52: + return 52; + case 53: + return 53; + case 54: + return 54; + case 55: + return 55; + case 56: + return 56; + case 57: + return 57; + case 58: + return 58; + case 59: + return 59; + case 60: + return 60; + case 61: + return 61; + case 62: + return 62; + case 63: + return 63; + case 64: + return 64; + case 65: + return 65; + case 66: + return 66; + case 67: + return 67; + case 68: + return 68; + case 69: + return 69; + case 70: + return 70; + case 71: + return 71; + case 72: + return 72; + case 73: + return 73; + case 74: + return 74; + case 75: + return 75; + case 76: + return 76; + case 77: + return 77; + case 78: + return 78; + case 79: + return 79; + case 80: + return 80; + case 81: + return 81; + case 82: + return 82; + case 83: + return 83; + case 84: + return 84; + case 85: + return 85; + case 86: + return 86; + case 87: + return 87; + case 88: + return 88; + case 89: + return 89; + case 90: + return 90; + case 91: + return 91; + case 92: + return 92; + case 93: + return 93; + case 94: + return 94; + case 95: + return 95; + case 96: + return 96; + case 97: + return 97; + case 98: + return 98; + case 99: + return 99; + case 100: + return 100; + case 101: + return 101; + case 102: + return 102; + case 103: + return 103; + case 104: + return 104; + case 105: + return 105; + case 106: + return 106; + case 107: + return 107; + case 108: + return 108; + case 109: + return 109; + case 110: + return 110; + case 111: + return 111; + case 112: + return 112; + case 113: + return 113; + case 114: + return 114; + case 115: + return 115; + case 116: + return 116; + case 117: + return 117; + case 118: + return 118; + case 119: + return 119; + case 120: + return 120; + case 121: + return 121; + case 122: + return 122; + case 123: + return 123; + case 124: + return 124; + case 125: + return 125; + case 126: + return 126; + case 127: + return 127; + case 128: + return 128; + case 129: + return 129; + case 130: + return 130; + case 131: + return 131; + case 132: + return 132; + case 133: + return 133; + case 134: + return 134; + case 135: + return 135; + case 136: + return 136; + case 137: + return 137; + case 138: + return 138; + case 139: + return 139; + case 140: + return 140; + default: + return -1; } } diff --git a/test/parse/cases/6_8_27_label_on_null_stmt.c b/test/parse/cases/6_8_27_label_on_null_stmt.c @@ -1,5 +1,5 @@ int test_main(void) { - goto end; -end: ; - return 42; + goto end; +end:; + return 42; } diff --git a/test/parse/cases/6_8_28_return_narrow_convert.c b/test/parse/cases/6_8_28_return_narrow_convert.c @@ -1,4 +1,2 @@ unsigned char narrow(int x) { return x; } -int test_main(void) { - return narrow(298); -} +int test_main(void) { return narrow(298); } diff --git a/test/parse/cases/6_8_29_switch_signed_negative.c b/test/parse/cases/6_8_29_switch_signed_negative.c @@ -4,23 +4,31 @@ * sign-extension correctly. */ static int pick(int x) { switch (x) { - case -3: return 30; - case -2: return 31; - case -1: return 32; - case 0: return 33; - case 1: return 34; - case 2: return 35; - case 3: return 36; - default: return 99; + case -3: + return 30; + case -2: + return 31; + case -1: + return 32; + case 0: + return 33; + case 1: + return 34; + case 2: + return 35; + case 3: + return 36; + default: + return 99; } } int test_main(void) { int s = 0; - s += pick(-3); /* vmin -> 30 */ - s += pick(3); /* vmax -> 36 */ - s += pick(0); /* zero -> 33 */ - s += pick(-4); /* below vmin -> 99 */ - s += pick(4); /* above vmax -> 99 */ - return s - 197; /* 30+36+33+99+99 - 197 = 100 */ + s += pick(-3); /* vmin -> 30 */ + s += pick(3); /* vmax -> 36 */ + s += pick(0); /* zero -> 33 */ + s += pick(-4); /* below vmin -> 99 */ + s += pick(4); /* above vmax -> 99 */ + return s - 197; /* 30+36+33+99+99 - 197 = 100 */ } diff --git a/test/parse/cases/6_8_30_switch_sparse_chain.c b/test/parse/cases/6_8_30_switch_sparse_chain.c @@ -3,10 +3,14 @@ * test pins correct behavior independent of which strategy was picked. */ static int pick(int x) { switch (x) { - case 1: return 11; - case 50: return 22; - case 1000: return 33; - default: return 99; + case 1: + return 11; + case 50: + return 22; + case 1000: + return 33; + default: + return 99; } } @@ -18,5 +22,5 @@ int test_main(void) { s += pick(2); s += pick(999); s += pick(1001); - return s - 263; /* 11+22+33+99+99+99 - 263 = 100 */ + return s - 263; /* 11+22+33+99+99+99 - 263 = 100 */ } diff --git a/test/parse/cases/6_8_31_switch_char_extremes.c b/test/parse/cases/6_8_31_switch_char_extremes.c @@ -3,12 +3,18 @@ * preserving signedness would silently miscompile case INT8_MIN. */ static int pick(signed char c) { switch (c) { - case -128: return 1; - case -127: return 2; - case 0: return 3; - case 126: return 4; - case 127: return 5; - default: return 9; + case -128: + return 1; + case -127: + return 2; + case 0: + return 3; + case 126: + return 4; + case 127: + return 5; + default: + return 9; } } @@ -18,6 +24,6 @@ int test_main(void) { s += pick((signed char)-127); s += pick((signed char)0); s += pick((signed char)127); - s += pick((signed char)42); /* miss -> 9 */ - return s - 15; /* 1+2+3+5+9 - 15 = 5 */ + s += pick((signed char)42); /* miss -> 9 */ + return s - 15; /* 1+2+3+5+9 - 15 = 5 */ } diff --git a/test/parse/cases/6_8_6_4_01_struct_return_1reg.c b/test/parse/cases/6_8_6_4_01_struct_return_1reg.c @@ -1,7 +1,9 @@ /* Return an 8-byte struct — DIRECT, one part returned in the first * int-return register (x0/rax/a0). Caller stores the return reg into * its destination slot before per-field access. */ -struct S { int a, b; }; +struct S { + int a, b; +}; struct S mk(void) { struct S s = {20, 22}; return s; diff --git a/test/parse/cases/6_8_6_4_02_struct_return_2reg.c b/test/parse/cases/6_8_6_4_02_struct_return_2reg.c @@ -1,7 +1,9 @@ /* Return a 16-byte struct — DIRECT, two parts returned across the first * two int-return registers (x0,x1 / rax,rdx / a0,a1). Callee loads parts * from its local; caller stores them back into a destination slot. */ -struct S { long a, b; }; +struct S { + long a, b; +}; struct S mk(void) { struct S s = {20L, 22L}; return s; diff --git a/test/parse/cases/6_8_6_4_03_struct_return_large.c b/test/parse/cases/6_8_6_4_03_struct_return_large.c @@ -1,7 +1,9 @@ /* Return a 32-byte struct — INDIRECT/sret. The caller passes a hidden * destination pointer in the sret register (x8 / rdi / a0); the callee * memcpys the return value into [sret_ptr] before returning. */ -struct S { int a[8]; }; +struct S { + int a[8]; +}; struct S mk(void) { struct S s = {{20, 0, 0, 0, 0, 0, 0, 22}}; return s; diff --git a/test/parse/cases/6_8_6_4_04_struct_return_call_chain.c b/test/parse/cases/6_8_6_4_04_struct_return_call_chain.c @@ -3,7 +3,9 @@ * caller's destination slot for mk() is the same slot that take() reads * its byval source from, so cg must keep the slot pinned across both * sides of the call boundary. */ -struct S { long a, b; }; +struct S { + long a, b; +}; struct S mk(void) { struct S s = {20L, 22L}; return s; diff --git a/test/parse/cases/6_8_6_4_05_struct_return_mixed_fp_int.c b/test/parse/cases/6_8_6_4_05_struct_return_mixed_fp_int.c @@ -1,5 +1,8 @@ /* SysV-x64 mixed direct return: double comes back in xmm0, long in rax. */ -struct S { double d; long i; }; +struct S { + double d; + long i; +}; struct S mk(void) { struct S s = {20.0, 22L}; diff --git a/test/parse/cases/6_9_02_recursive_function.c b/test/parse/cases/6_9_02_recursive_function.c @@ -1,2 +1,5 @@ -int factorial(int n) { if (n <= 1) return 1; return n * factorial(n - 1); } +int factorial(int n) { + if (n <= 1) return 1; + return n * factorial(n - 1); +} int test_main(void) { return factorial(5); } diff --git a/test/parse/cases/6_9_06_variadic_func.c b/test/parse/cases/6_9_06_variadic_func.c @@ -7,6 +7,4 @@ int sum(int n, ...) { return s; } -int test_main(void) { - return sum(2, 20, 22); -} +int test_main(void) { return sum(2, 20, 22); } diff --git a/test/parse/cases/6_9_07_global_const.c b/test/parse/cases/6_9_07_global_const.c @@ -1,5 +1,3 @@ const int g = 42; -int test_main(void) { - return g; -} +int test_main(void) { return g; } diff --git a/test/parse/cases/6_9_08_global_struct_init.c b/test/parse/cases/6_9_08_global_struct_init.c @@ -1,5 +1,5 @@ -struct S { int v; } g = {42}; +struct S { + int v; +} g = {42}; -int test_main(void) { - return g.v; -} +int test_main(void) { return g.v; } diff --git a/test/parse/cases/6_9_09_static_data_array.c b/test/parse/cases/6_9_09_static_data_array.c @@ -1,5 +1,3 @@ static int g[3] = {0, 0, 42}; -int test_main(void) { - return g[2]; -} +int test_main(void) { return g[2]; } diff --git a/test/parse/cases/6_9_16_block_scope_func_decl.c b/test/parse/cases/6_9_16_block_scope_func_decl.c @@ -3,6 +3,4 @@ int test_main(void) { return helper(); } -int helper(void) { - return 42; -} +int helper(void) { return 42; } diff --git a/test/parse/cases/asm_01_grammar.c b/test/parse/cases/asm_01_grammar.c @@ -34,9 +34,7 @@ int test_main(void) { asm("add %w0, %w1, %w2" : "=r"(c) : "r"(a), "r"(b) : "cc"); /* Symbolic operand names ([sum], [x], [y]). */ - asm("add %w[sum], %w[x], %w[y]" - : [sum] "=r"(c) - : [x] "r"(a), [y] "r"(b)); + asm("add %w[sum], %w[x], %w[y]" : [sum] "=r"(c) : [x] "r"(a), [y] "r"(b)); /* In-out (`+r`). Decomposes to `=r` + a matching "0" input. */ asm("add %w0, %w0, #1" : "+r"(rc)); @@ -45,7 +43,7 @@ int test_main(void) { asm volatile("dmb sy" : : : "memory"); /* Empty middle sections. */ - asm("nop" : : : ); + asm("nop" : : :); return rc; } diff --git a/test/parse/cases/asm_02_file_scope.c b/test/parse/cases/asm_02_file_scope.c @@ -1,10 +1,11 @@ extern int global_asm_after; -__asm__(".data\n" - ".globl global_asm_after\n" - "global_asm_after:\n" - ".word 40\n" - ".text\n"); +__asm__( + ".data\n" + ".globl global_asm_after\n" + "global_asm_after:\n" + ".word 40\n" + ".text\n"); asm(".data\n" ".globl global_asm_before\n" @@ -14,6 +15,4 @@ asm(".data\n" extern int global_asm_before; -int test_main(void) { - return global_asm_before + global_asm_after; -} +int test_main(void) { return global_asm_before + global_asm_after; } diff --git a/test/parse/cases/attr_03_section_func.c b/test/parse/cases/attr_03_section_func.c @@ -2,6 +2,4 @@ * parses but does not set ObjSym.section; we just call the function. */ __attribute__((section(".text.foo"))) int foo(void) { return 0; } -int test_main(void) { - return foo(); -} +int test_main(void) { return foo(); } diff --git a/test/parse/cases/attr_04_used_static.c b/test/parse/cases/attr_04_used_static.c @@ -3,6 +3,4 @@ * it alive regardless. */ static int k __attribute__((used)) = 7; -int test_main(void) { - return k - 7; -} +int test_main(void) { return k - 7; } diff --git a/test/parse/cases/attr_05_noreturn_func.c b/test/parse/cases/attr_05_noreturn_func.c @@ -3,7 +3,8 @@ * not call die(), so control returns normally. Use `static` so the * unreferenced symbol does not produce an undefined external at link. */ __attribute__((noreturn)) static void die(void) { - while (1) { } + while (1) { + } } int test_main(void) { diff --git a/test/parse/cases/attr_09_format_printf.c b/test/parse/cases/attr_09_format_printf.c @@ -2,8 +2,8 @@ * definition. Phase 1 only needs to accept the attribute shape; the * function body is `static` and unreferenced to avoid an unresolved * external at link. */ -__attribute__((format(printf, 1, 2))) -static int my_printf(const char *fmt, ...) { +__attribute__((format(printf, 1, 2))) static int my_printf(const char* fmt, + ...) { (void)fmt; return 0; } diff --git a/test/parse/cases/attr_13_attr_after_record_brace.c b/test/parse/cases/attr_13_attr_after_record_brace.c @@ -1,5 +1,7 @@ /* Attribute after the closing brace of a struct definition. */ -struct S { int x; } __attribute__((packed)); +struct S { + int x; +} __attribute__((packed)); int test_main(void) { struct S s; diff --git a/test/parse/cases/attr_14_attr_in_decl_specs.c b/test/parse/cases/attr_14_attr_in_decl_specs.c @@ -1,6 +1,4 @@ /* Attribute interleaved among decl-specifiers (static, const, type). */ static __attribute__((unused)) const int K = 7; -int test_main(void) { - return K - 7; -} +int test_main(void) { return K - 7; } diff --git a/test/parse/cases/attr_16_empty_attribute.c b/test/parse/cases/attr_16_empty_attribute.c @@ -2,7 +2,7 @@ * __attribute__(()) — no attrs * __attribute__((,)) — empty entries separated by commas */ __attribute__(()) int a; -__attribute__((,)) int b; +__attribute__((, )) int b; int test_main(void) { a = 0; diff --git a/test/parse/cases/attr_17_visibility_hidden.c b/test/parse/cases/attr_17_visibility_hidden.c @@ -2,6 +2,4 @@ * the attribute but does not set ELF visibility. */ __attribute__((visibility("hidden"))) int hidden_fn(void) { return 0; } -int test_main(void) { - return hidden_fn(); -} +int test_main(void) { return hidden_fn(); } diff --git a/test/parse/cases/attr_p2_01_packed_sizeof.c b/test/parse/cases/attr_p2_01_packed_sizeof.c @@ -7,6 +7,4 @@ struct __attribute__((packed)) S { int b; }; -int test_main(void) { - return (int)sizeof(struct S); -} +int test_main(void) { return (int)sizeof(struct S); } diff --git a/test/parse/cases/attr_p2_02_packed_member_offset.c b/test/parse/cases/attr_p2_02_packed_member_offset.c @@ -5,6 +5,4 @@ struct __attribute__((packed)) S { int b; }; -int test_main(void) { - return (int)__builtin_offsetof(struct S, b); -} +int test_main(void) { return (int)__builtin_offsetof(struct S, b); } diff --git a/test/parse/cases/attr_p2_03_aligned_record.c b/test/parse/cases/attr_p2_03_aligned_record.c @@ -3,6 +3,4 @@ struct __attribute__((aligned(16))) S { int x; }; -int test_main(void) { - return (int)_Alignof(struct S); -} +int test_main(void) { return (int)_Alignof(struct S); } diff --git a/test/parse/cases/attr_p2_04_aligned_field.c b/test/parse/cases/attr_p2_04_aligned_field.c @@ -5,6 +5,4 @@ struct S { int b __attribute__((aligned(8))); }; -int test_main(void) { - return (int)__builtin_offsetof(struct S, b); -} +int test_main(void) { return (int)__builtin_offsetof(struct S, b); } diff --git a/test/parse/cases/attr_p2_06_section_var.c b/test/parse/cases/attr_p2_06_section_var.c @@ -5,6 +5,4 @@ * lives in a separate harness extension (TODO Phase 2). */ int v __attribute__((section(".data.cfree_attr_test"))) = 7; -int test_main(void) { - return v - 7; -} +int test_main(void) { return v - 7; } diff --git a/test/parse/cases/attr_p2_07_used_static.c b/test/parse/cases/attr_p2_07_used_static.c @@ -4,6 +4,4 @@ * codegen succeed and the value is reachable. */ static int kept __attribute__((used)) = 11; -int test_main(void) { - return kept - 11; -} +int test_main(void) { return kept - 11; } diff --git a/test/parse/cases/attr_p2_08_weak_undef.c b/test/parse/cases/attr_p2_08_weak_undef.c @@ -8,6 +8,4 @@ * trust the programmer to guard), so this test checks the address. */ extern int weak_missing __attribute__((weak)); -int test_main(void) { - return (&weak_missing != 0) ? 1 : 0; -} +int test_main(void) { return (&weak_missing != 0) ? 1 : 0; } diff --git a/test/parse/cases/attr_p2_09_visibility_hidden.c b/test/parse/cases/attr_p2_09_visibility_hidden.c @@ -7,6 +7,4 @@ int hidden_fn(void) __attribute__((visibility("hidden"))); int hidden_fn(void) { return 13; } -int test_main(void) { - return hidden_fn() - 13; -} +int test_main(void) { return hidden_fn() - 13; } diff --git a/test/parse/cases/attr_p2_10_alias.c b/test/parse/cases/attr_p2_10_alias.c @@ -3,6 +3,4 @@ int bar(void) { return 42; } int foo(void) __attribute__((alias("bar"))); -int test_main(void) { - return foo(); -} +int test_main(void) { return foo(); } diff --git a/test/parse/cases/attr_p2_11_noreturn.c b/test/parse/cases/attr_p2_11_noreturn.c @@ -8,7 +8,8 @@ __attribute__((noreturn)) static void bail(void); static void bail(void) { side = 7; - while (1) {} + while (1) { + } } int test_main(void) { diff --git a/test/parse/cases/builtin_01_alloca.c b/test/parse/cases/builtin_01_alloca.c @@ -1,5 +1,5 @@ int test_main(void) { - int *p = (int *)__builtin_alloca(4); + int* p = (int*)__builtin_alloca(4); *p = 42; return *p; } diff --git a/test/parse/cases/builtin_03_va_list.c b/test/parse/cases/builtin_03_va_list.c @@ -7,6 +7,4 @@ int sum3(int n, ...) { return s; } -int test_main(void) { - return sum3(3, 10, 20, 12); -} +int test_main(void) { return sum3(3, 10, 20, 12); } diff --git a/test/parse/cases/builtin_04_offsetof.c b/test/parse/cases/builtin_04_offsetof.c @@ -1,5 +1,5 @@ -struct S { int a, b; }; +struct S { + int a, b; +}; -int test_main(void) { - return (int)__builtin_offsetof(struct S, b) * 10 + 2; -} +int test_main(void) { return (int)__builtin_offsetof(struct S, b) * 10 + 2; } diff --git a/test/parse/cases/builtin_05_va_copy.c b/test/parse/cases/builtin_05_va_copy.c @@ -10,6 +10,4 @@ int sum2x(int n, ...) { return s; } -int test_main(void) { - return sum2x(2, 10, 11); -} +int test_main(void) { return sum2x(2, 10, 11); } diff --git a/test/parse/cases/builtin_11_atomic_fetch_and.c b/test/parse/cases/builtin_11_atomic_fetch_and.c @@ -1,5 +1,5 @@ int test_main(void) { - int x = 0xFE; /* 1111 1110 */ + int x = 0xFE; /* 1111 1110 */ int prior = __atomic_fetch_and(&x, 0x6F, __ATOMIC_RELAXED); /* prior=0xFE, x=0x6E. 0x6E=110, return 110 - 68 = 42 */ return x + (prior - 0xFE) - 68; diff --git a/test/parse/cases/builtin_12_atomic_fetch_or.c b/test/parse/cases/builtin_12_atomic_fetch_or.c @@ -1,5 +1,5 @@ int test_main(void) { - int x = 0x20; /* 0010 0000 */ + int x = 0x20; /* 0010 0000 */ int prior = __atomic_fetch_or(&x, 0x0A, __ATOMIC_ACQUIRE); /* prior=0x20=32, x=0x2A=42 */ (void)prior; diff --git a/test/parse/cases/builtin_13_atomic_fetch_xor.c b/test/parse/cases/builtin_13_atomic_fetch_xor.c @@ -1,5 +1,5 @@ int test_main(void) { - int x = 0x55; /* 0101 0101 = 85 */ + int x = 0x55; /* 0101 0101 = 85 */ int prior = __atomic_fetch_xor(&x, 0x7F, __ATOMIC_SEQ_CST); /* x = 0x55 ^ 0x7F = 0x2A = 42 */ (void)prior; diff --git a/test/parse/cases/builtin_15_atomic_pointer.c b/test/parse/cases/builtin_15_atomic_pointer.c @@ -4,8 +4,8 @@ int test_main(void) { arr[1] = 20; arr[2] = 12; - int *p = &arr[0]; + int* p = &arr[0]; /* Atomically load p, then read through the loaded pointer. */ - int *q = __atomic_load_n(&p, __ATOMIC_ACQUIRE); + int* q = __atomic_load_n(&p, __ATOMIC_ACQUIRE); return q[0] + q[1] + q[2]; } diff --git a/test/parse/cases/builtin_17_atomic_cas_success.c b/test/parse/cases/builtin_17_atomic_cas_success.c @@ -2,8 +2,8 @@ int test_main(void) { int x = 10; int expected = 10; /* CAS: x==expected -> store 42, return 1. x becomes 42. */ - int ok = __atomic_compare_exchange_n(&x, &expected, 42, 0, - __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); + int ok = __atomic_compare_exchange_n(&x, &expected, 42, 0, __ATOMIC_SEQ_CST, + __ATOMIC_SEQ_CST); /* ok==1, x==42, expected==10 (unchanged on success). */ return x + ok - 1; } diff --git a/test/parse/cases/builtin_18_atomic_cas_failure.c b/test/parse/cases/builtin_18_atomic_cas_failure.c @@ -1,8 +1,8 @@ int test_main(void) { int x = 7; - int expected = 5; /* mismatch: x != expected */ - int ok = __atomic_compare_exchange_n(&x, &expected, 99, 0, - __ATOMIC_SEQ_CST, __ATOMIC_RELAXED); + int expected = 5; /* mismatch: x != expected */ + int ok = __atomic_compare_exchange_n(&x, &expected, 99, 0, __ATOMIC_SEQ_CST, + __ATOMIC_RELAXED); /* ok==0, x stays at 7, expected is updated to 7 (the prior value). */ /* expected*6=42, ok==0, x==7. Return: expected*6 + ok + (x-7) = 42 */ return expected * 6 + ok + (x - 7); diff --git a/test/parse/cases/builtin_19_atomic_cas_loop.c b/test/parse/cases/builtin_19_atomic_cas_loop.c @@ -1,12 +1,12 @@ /* Lock-free increment via CAS retry loop. Single-threaded test, so the * first CAS attempt always succeeds, but the loop shape exercises the * compare-exchange surface end-to-end. */ -int atomic_inc(int *p) { +int atomic_inc(int* p) { int cur = __atomic_load_n(p, __ATOMIC_ACQUIRE); for (;;) { int next = cur + 1; - if (__atomic_compare_exchange_n(p, &cur, next, 0, - __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE)) { + if (__atomic_compare_exchange_n(p, &cur, next, 0, __ATOMIC_ACQ_REL, + __ATOMIC_ACQUIRE)) { return next; } } diff --git a/test/parse/cases/builtin_24_atomic_lock_free.c b/test/parse/cases/builtin_24_atomic_lock_free.c @@ -8,12 +8,12 @@ int test_main(void) { if (__atomic_is_lock_free(8, &y)) score += 8; if (!__atomic_always_lock_free(16, &y)) score += 27; if (__atomic_always_lock_free(32, 0)) { - unsigned __int128 *wide = (unsigned __int128 *)0; + unsigned __int128* wide = (unsigned __int128*)0; score += 90 + (int)__atomic_load_n(wide, __ATOMIC_SEQ_CST); } if (__atomic_always_lock_free(32, 0) || (__atomic_always_lock_free(32, 0) && ((unsigned long)&score % 16) == 0)) { - unsigned __int128 *wide = (unsigned __int128 *)0; + unsigned __int128* wide = (unsigned __int128*)0; score += 90 + (int)__atomic_load_n(wide, __ATOMIC_SEQ_CST); } return score; diff --git a/test/parse/cases/builtin_26_sadd_overflow.c b/test/parse/cases/builtin_26_sadd_overflow.c @@ -70,8 +70,8 @@ int test_main(void) { if (!ov || ullr != ull_max) return 13; ov = __builtin_umulll_overflow(ull_hi, 2ULL, &ullr); if (!ov || ullr != 0ULL) return 14; - ov = __builtin_uaddll_overflow(9223372036854775808ULL, - 9223372036854775808ULL, &ullr); + ov = __builtin_uaddll_overflow(9223372036854775808ULL, 9223372036854775808ULL, + &ullr); if (!ov || ullr != 0ULL) return 23; return 42; } diff --git a/test/parse/cases/call_indirect_arg_fp_field.c b/test/parse/cases/call_indirect_arg_fp_field.c @@ -1,5 +1,8 @@ /* FP-class arg lowered from an OPK_INDIRECT source. */ -typedef struct { double v; int x; } Row; +typedef struct { + double v; + int x; +} Row; int sink(double d) { return (int)d; } @@ -7,7 +10,9 @@ int call_fp(Row* row, int i) { return sink(row[i].v); } int test_main(void) { Row rows[2]; - rows[0].v = 42.0; rows[0].x = 0; - rows[1].v = 99.0; rows[1].x = 0; + rows[0].v = 42.0; + rows[0].x = 0; + rows[1].v = 99.0; + rows[1].x = 0; return call_fp(rows, 0); } diff --git a/test/parse/cases/call_indirect_arg_struct_byval.c b/test/parse/cases/call_indirect_arg_struct_byval.c @@ -1,8 +1,13 @@ /* Big struct (>16 bytes) passed via ABI_ARG_INDIRECT (byval) from an * OPK_INDIRECT source. The caller must compute `base + ind.ofs` and * pass that pointer in the first int-arg slot. */ -typedef struct { int a[8]; } Big; -typedef struct { Big big; int x; } Row; +typedef struct { + int a[8]; +} Big; +typedef struct { + Big big; + int x; +} Row; int sink(Big b) { return b.a[0] + b.a[7]; } @@ -10,7 +15,11 @@ int call_big(Row* row, int i) { return sink(row[i].big); } int test_main(void) { Row rows[2]; - rows[0].big.a[0] = 20; rows[0].big.a[7] = 22; rows[0].x = 0; - rows[1].big.a[0] = 99; rows[1].big.a[7] = 99; rows[1].x = 0; + rows[0].big.a[0] = 20; + rows[0].big.a[7] = 22; + rows[0].x = 0; + rows[1].big.a[0] = 99; + rows[1].big.a[7] = 99; + rows[1].x = 0; return call_big(rows, 0); } diff --git a/test/parse/cases/call_indirect_arg_struct_field.c b/test/parse/cases/call_indirect_arg_struct_field.c @@ -6,8 +6,14 @@ * Loc is 8 bytes (one INT ABI part on aa64/x64/rv64), so this exercises * the single-part DIRECT path; the multi-part variant lives in * call_indirect_arg_struct_field_two_parts.c. */ -typedef struct { unsigned a; unsigned b; } Loc; -typedef struct { Loc loc; int x; } Line; +typedef struct { + unsigned a; + unsigned b; +} Loc; +typedef struct { + Loc loc; + int x; +} Line; int sink(Loc l) { return (int)l.a + (int)l.b; } @@ -15,7 +21,11 @@ int call_loc(Line* line, int i) { return sink(line[i].loc); } int test_main(void) { Line lines[2]; - lines[0].loc.a = 40u; lines[0].loc.b = 2u; lines[0].x = 0; - lines[1].loc.a = 99u; lines[1].loc.b = 99u; lines[1].x = 0; + lines[0].loc.a = 40u; + lines[0].loc.b = 2u; + lines[0].x = 0; + lines[1].loc.a = 99u; + lines[1].loc.b = 99u; + lines[1].x = 0; return call_loc(lines, 0); } diff --git a/test/parse/cases/call_indirect_arg_struct_field_two_parts.c b/test/parse/cases/call_indirect_arg_struct_field_two_parts.c @@ -2,8 +2,14 @@ * OPK_INDIRECT source operand. Exercises the multi-part load path: * each part must read from the same base register at distinct * `src_offset`s, so the base must survive across iterations. */ -typedef struct { unsigned long a; unsigned long b; } Pair; -typedef struct { Pair p; int x; } Row; +typedef struct { + unsigned long a; + unsigned long b; +} Pair; +typedef struct { + Pair p; + int x; +} Row; int sink(Pair v) { return (int)(v.a + v.b); } @@ -11,7 +17,11 @@ int call_pair(Row* row, int i) { return sink(row[i].p); } int test_main(void) { Row rows[2]; - rows[0].p.a = 30; rows[0].p.b = 12; rows[0].x = 0; - rows[1].p.a = 99; rows[1].p.b = 99; rows[1].x = 0; + rows[0].p.a = 30; + rows[0].p.b = 12; + rows[0].x = 0; + rows[1].p.a = 99; + rows[1].p.b = 99; + rows[1].x = 0; return call_pair(rows, 0); } diff --git a/test/parse/cases/call_indirect_ret_into_indirect.c b/test/parse/cases/call_indirect_ret_into_indirect.c @@ -1,7 +1,10 @@ /* The destination of a call's return value is an OPK_INDIRECT lvalue: * `row[i].v = make_int()`. The call's return-receive must store the * return register through the indirect destination. */ -typedef struct { int v; int x; } Row; +typedef struct { + int v; + int x; +} Row; int make_int(void) { return 42; } @@ -9,8 +12,10 @@ void store_ret(Row* row, int i) { row[i].v = make_int(); } int test_main(void) { Row rows[2]; - rows[0].v = 0; rows[0].x = 0; - rows[1].v = 0; rows[1].x = 0; + rows[0].v = 0; + rows[0].x = 0; + rows[1].v = 0; + rows[1].x = 0; store_ret(rows, 0); return rows[0].v; } diff --git a/test/parse/cases/call_indirect_ret_struct_byval.c b/test/parse/cases/call_indirect_ret_struct_byval.c @@ -1,15 +1,24 @@ /* Return a big struct (>16B) via sret from an OPK_INDIRECT source. * The callee must memcpy from `[base + ind.ofs]` through the sret * pointer, not assume the source is OPK_LOCAL. */ -typedef struct { int a[8]; } Big; -typedef struct { Big big; int x; } Row; +typedef struct { + int a[8]; +} Big; +typedef struct { + Big big; + int x; +} Row; Big pick(Row* row, int i) { return row[i].big; } int test_main(void) { Row rows[2]; - rows[0].big.a[0] = 20; rows[0].big.a[7] = 22; rows[0].x = 0; - rows[1].big.a[0] = 99; rows[1].big.a[7] = 99; rows[1].x = 0; + rows[0].big.a[0] = 20; + rows[0].big.a[7] = 22; + rows[0].x = 0; + rows[1].big.a[0] = 99; + rows[1].big.a[7] = 99; + rows[1].x = 0; Big b = pick(rows, 0); return b.a[0] + b.a[7]; } diff --git a/test/parse/cases/call_indirect_ret_struct_direct.c b/test/parse/cases/call_indirect_ret_struct_direct.c @@ -1,15 +1,25 @@ /* Return a struct field reached through an indexed pointer. The * returned aggregate is DIRECT (fits in registers), so the callee * must load each return part from the OPK_INDIRECT source. */ -typedef struct { unsigned a; unsigned b; } Loc; -typedef struct { Loc loc; int x; } Line; +typedef struct { + unsigned a; + unsigned b; +} Loc; +typedef struct { + Loc loc; + int x; +} Line; Loc pick(Line* line, int i) { return line[i].loc; } int test_main(void) { Line lines[2]; - lines[0].loc.a = 40u; lines[0].loc.b = 2u; lines[0].x = 0; - lines[1].loc.a = 99u; lines[1].loc.b = 99u; lines[1].x = 0; + lines[0].loc.a = 40u; + lines[0].loc.b = 2u; + lines[0].x = 0; + lines[1].loc.a = 99u; + lines[1].loc.b = 99u; + lines[1].x = 0; Loc l = pick(lines, 0); return (int)l.a + (int)l.b; } diff --git a/test/parse/cases/call_large_const_global_struct_byval.c b/test/parse/cases/call_large_const_global_struct_byval.c @@ -1,12 +1,12 @@ struct S { - void *next; - void *prev; - void *child; + void* next; + void* prev; + void* child; int type; - void *valuestring; + void* valuestring; int valueint; double valuedouble; - void *string; + void* string; }; static int read_struct(struct S v) { @@ -15,6 +15,4 @@ static int read_struct(struct S v) { static const struct S invalid = {0, 0, 0, 0, 0, 0, 0.0, 0}; -int test_main(void) { - return read_struct(invalid); -} +int test_main(void) { return read_struct(invalid); } diff --git a/test/parse/cases/cg_x64_inline_asm_modifiers.c b/test/parse/cases/cg_x64_inline_asm_modifiers.c @@ -4,9 +4,7 @@ int test_main(void) { int named = 0; __asm__ volatile("movq %1, %0" : "=r"(acc) : "r"(42)); - __asm__ volatile("mov%z0 %k1, %k0" - : [out] "=r"(named) - : [in] "r"(11)); + __asm__ volatile("mov%z0 %k1, %k0" : [out] "=r"(named) : [in] "r"(11)); return (int)(acc + named); #else diff --git a/test/parse/cases/gnu_inline_alias_01.c b/test/parse/cases/gnu_inline_alias_01.c @@ -1,11 +1,5 @@ -static __inline__ int f1(void) { - return 20; -} +static __inline__ int f1(void) { return 20; } -static __inline int f2(void) { - return 22; -} +static __inline int f2(void) { return 22; } -int test_main(void) { - return f1() + f2(); -} +int test_main(void) { return f1() + f2(); } diff --git a/test/parse/cases/i128_02_literal_storage.c b/test/parse/cases/i128_02_literal_storage.c @@ -1,8 +1,7 @@ typedef unsigned __int128 u128; int test_main(void) { - u128 x = ((u128)0x1122334455667788ULL << 64) | - (u128)0x99aabbccddeeff00ULL; + u128 x = ((u128)0x1122334455667788ULL << 64) | (u128)0x99aabbccddeeff00ULL; unsigned long long lo = (unsigned long long)x; unsigned long long hi = (unsigned long long)(x >> 64); if (lo != 0x99aabbccddeeff00ULL) return 11; diff --git a/test/parse/cases/i128_09_call_return.c b/test/parse/cases/i128_09_call_return.c @@ -1,12 +1,8 @@ typedef unsigned __int128 u128; -static u128 add128(u128 a, u128 b) { - return a + b; -} +static u128 add128(u128 a, u128 b) { return a + b; } -static int low_byte(u128 x) { - return (int)(x & 255); -} +static int low_byte(u128 x) { return (int)(x & 255); } int test_main(void) { u128 a = ((u128)1 << 80) + 40; diff --git a/test/parse/cases/i128_11_union_lanes.c b/test/parse/cases/i128_11_union_lanes.c @@ -7,8 +7,7 @@ union U { int test_main(void) { union U u; - u.x = ((u128)0x0102030405060708ULL << 64) | - (u128)0x1112131415161718ULL; + u.x = ((u128)0x0102030405060708ULL << 64) | (u128)0x1112131415161718ULL; if (u.lane[0] != 0x1112131415161718ULL) return 11; if (u.lane[1] != 0x0102030405060708ULL) return 12; return 55; diff --git a/test/parse/cases/inline_external_01_local.c b/test/parse/cases/inline_external_01_local.c @@ -1,9 +1,5 @@ -inline int external_inline_add1(int x) { - return x + 1; -} +inline int external_inline_add1(int x) { return x + 1; } int external_inline_add1(int); -int test_main(void) { - return external_inline_add1(41); -} +int test_main(void) { return external_inline_add1(41); } diff --git a/test/parse/cases/ldbl128_06_call_return.c b/test/parse/cases/ldbl128_06_call_return.c @@ -1,10 +1,6 @@ -static long double add_ld(long double a, long double b) { - return a + b; -} +static long double add_ld(long double a, long double b) { return a + b; } -static int take_ld(long double x) { - return (int)x; -} +static int take_ld(long double x) { return (int)x; } int test_main(void) { if (__LDBL_MANT_DIG__ != 113) return 0; diff --git a/test/parse/cases/ldbl128_12_stack_args.c b/test/parse/cases/ldbl128_12_stack_args.c @@ -7,6 +7,6 @@ static long double sum10(long double a0, long double a1, long double a2, int test_main(void) { if (__LDBL_MANT_DIG__ != 113) return 0; - return (int)sum10(1.0L, 2.0L, 3.0L, 4.0L, 5.0L, - 6.0L, 7.0L, 8.0L, 9.0L, 10.0L); + return (int)sum10(1.0L, 2.0L, 3.0L, 4.0L, 5.0L, 6.0L, 7.0L, 8.0L, 9.0L, + 10.0L); } diff --git a/test/parse/cases/opt_02_late_addrof_join.c b/test/parse/cases/opt_02_late_addrof_join.c @@ -4,7 +4,7 @@ int test_main(void) { x = 40; else x = 1; - int *p = &x; + int* p = &x; *p = *p + 2; return x; } diff --git a/test/parse/cases/pragma_pack_01_struct_size.c b/test/parse/cases/pragma_pack_01_struct_size.c @@ -7,6 +7,4 @@ struct S { _Static_assert(sizeof(struct S) == 12, "pack4 size"); -int test_main(void) { - return 42; -} +int test_main(void) { return 42; } diff --git a/test/parse/cases/rv64_atomic_widths_orders.c b/test/parse/cases/rv64_atomic_widths_orders.c @@ -4,7 +4,7 @@ * accept: relaxed, acquire, release, acq_rel, seq_cst. Single-threaded * shape — the goal is to validate the codegen path, not detect races. */ -static int i32_loc; +static int i32_loc; static long i64_loc; int test_main(void) { @@ -26,9 +26,8 @@ int test_main(void) { /* 32-bit compare-exchange (weak then strong). */ int expected = 10; - if (!__atomic_compare_exchange_n(&i32_loc, &expected, 99, - 0 /*strong*/, __ATOMIC_SEQ_CST, - __ATOMIC_RELAXED)) + if (!__atomic_compare_exchange_n(&i32_loc, &expected, 99, 0 /*strong*/, + __ATOMIC_SEQ_CST, __ATOMIC_RELAXED)) return 5; if (i32_loc != 99 || expected != 10) return 6; @@ -43,9 +42,8 @@ int test_main(void) { if (old64 != 0x100000000L || i64_loc != 0x100000005L) return 10; long expected64 = 0x100000005L; - if (!__atomic_compare_exchange_n(&i64_loc, &expected64, 0L, - 0, __ATOMIC_SEQ_CST, - __ATOMIC_RELAXED)) + if (!__atomic_compare_exchange_n(&i64_loc, &expected64, 0L, 0, + __ATOMIC_SEQ_CST, __ATOMIC_RELAXED)) return 11; if (i64_loc != 0L) return 12; return 42; diff --git a/test/parse/cases/rv64_fp_nan_compare.c b/test/parse/cases/rv64_fp_nan_compare.c @@ -10,9 +10,9 @@ static double make_nan(void) { static int eq_d(double a, double b) { return a == b; } static int ne_d(double a, double b) { return a != b; } -static int lt_d(double a, double b) { return a < b; } +static int lt_d(double a, double b) { return a < b; } static int le_d(double a, double b) { return a <= b; } -static int gt_d(double a, double b) { return a > b; } +static int gt_d(double a, double b) { return a > b; } static int ge_d(double a, double b) { return a >= b; } int test_main(void) { diff --git a/test/parse/cases/variadic_01_zero_args.c b/test/parse/cases/variadic_01_zero_args.c @@ -7,6 +7,4 @@ int sum(int n, ...) { return s + 42; } -int test_main(void) { - return sum(0); -} +int test_main(void) { return sum(0); } diff --git a/test/parse/cases/variadic_02_many_ints.c b/test/parse/cases/variadic_02_many_ints.c @@ -10,6 +10,4 @@ int sum(int n, ...) { return s; } -int test_main(void) { - return sum(12, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 0); -} +int test_main(void) { return sum(12, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 0); } diff --git a/test/parse/cases/variadic_03_long.c b/test/parse/cases/variadic_03_long.c @@ -8,6 +8,4 @@ long sum_long(int n, ...) { return s; } -int test_main(void) { - return (int)sum_long(3, 10L, 20L, 12L); -} +int test_main(void) { return (int)sum_long(3, 10L, 20L, 12L); } diff --git a/test/parse/cases/variadic_05_double.c b/test/parse/cases/variadic_05_double.c @@ -9,6 +9,4 @@ double sum_d(int n, ...) { return s; } -int test_main(void) { - return (int)sum_d(3, 10.0, 20.0, 12.0); -} +int test_main(void) { return (int)sum_d(3, 10.0, 20.0, 12.0); } diff --git a/test/parse/cases/variadic_06_mixed.c b/test/parse/cases/variadic_06_mixed.c @@ -14,6 +14,4 @@ double mixed(int n, ...) { return i1 + d1 + i2 + d2; } -int test_main(void) { - return (int)mixed(4, 10, 11.0, 9, 12.0); -} +int test_main(void) { return (int)mixed(4, 10, 11.0, 9, 12.0); } diff --git a/test/parse/cases_err/6_2_7_conflicting_object_types.c b/test/parse/cases_err/6_2_7_conflicting_object_types.c @@ -1,6 +1,4 @@ extern int a[]; extern long a[]; -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_4_4_4_invalid_basic_char_ucn.c b/test/parse/cases_err/6_4_4_4_invalid_basic_char_ucn.c @@ -1,3 +1 @@ -int test_main(void) { - return L'\u0041'; -} +int test_main(void) { return L'\u0041'; } diff --git a/test/parse/cases_err/6_4_4_4_invalid_ucn_scalar.c b/test/parse/cases_err/6_4_4_4_invalid_ucn_scalar.c @@ -1,3 +1 @@ -int test_main(void) { - return U'\U00110000'; -} +int test_main(void) { return U'\U00110000'; } diff --git a/test/parse/cases_err/6_4_4_4_utf16_char_surrogate_pair.c b/test/parse/cases_err/6_4_4_4_utf16_char_surrogate_pair.c @@ -1,3 +1 @@ -int test_main(void) { - return u'\U0001f600'; -} +int test_main(void) { return u'\U0001f600'; } diff --git a/test/parse/cases_err/6_4_5_incompatible_string_prefix_concat.c b/test/parse/cases_err/6_4_5_incompatible_string_prefix_concat.c @@ -1,3 +1,5 @@ int test_main(void) { - return (int)sizeof(L"x" u"x"); + return (int)sizeof( + L"x" + u"x"); } diff --git a/test/parse/cases_err/6_5_addr_of_bitfield.c b/test/parse/cases_err/6_5_addr_of_bitfield.c @@ -1,5 +1,7 @@ int test_main(void) { - struct S { unsigned a : 3; } s = {1}; - unsigned *p = &s.a; + struct S { + unsigned a : 3; + } s = {1}; + unsigned* p = &s.a; return (int)*p; } diff --git a/test/parse/cases_err/6_5_address_of_register.c b/test/parse/cases_err/6_5_address_of_register.c @@ -1,4 +1,4 @@ int test_main(void) { - register int x = 0; - return &x != 0; + register int x = 0; + return &x != 0; } diff --git a/test/parse/cases_err/6_5_arrow_on_non_pointer.c b/test/parse/cases_err/6_5_arrow_on_non_pointer.c @@ -1,5 +1,7 @@ int test_main(void) { - struct S { int v; } s; + struct S { + int v; + } s; s.v = 0; return s->v; } diff --git a/test/parse/cases_err/6_5_block_static_compound_literal.c b/test/parse/cases_err/6_5_block_static_compound_literal.c @@ -1,4 +1,4 @@ int test_main(void) { - static int *p = (int[]){42}; + static int* p = (int[]){42}; return p[0]; } diff --git a/test/parse/cases_err/6_5_call_arg_incompatible.c b/test/parse/cases_err/6_5_call_arg_incompatible.c @@ -1,8 +1,8 @@ -struct S { int x; }; +struct S { + int x; +}; -static int f(int x) { - return x; -} +static int f(int x) { return x; } int test_main(void) { struct S s = {42}; diff --git a/test/parse/cases_err/6_5_cast_scalar_from_struct.c b/test/parse/cases_err/6_5_cast_scalar_from_struct.c @@ -1,4 +1,6 @@ int test_main(void) { - struct S { int v; } s = {42}; + struct S { + int v; + } s = {42}; return (int)s; } diff --git a/test/parse/cases_err/6_5_cond_incompatible_ptr.c b/test/parse/cases_err/6_5_cond_incompatible_ptr.c @@ -1,6 +1,6 @@ int test_main(void) { int i = 0; double d = 0.0; - void *p = 1 ? &i : &d; + void* p = 1 ? &i : &d; return p != 0; } diff --git a/test/parse/cases_err/6_5_file_scope_compound_literal_scalar_no_addr.c b/test/parse/cases_err/6_5_file_scope_compound_literal_scalar_no_addr.c @@ -1,5 +1,3 @@ -static int *p = (int){42}; +static int* p = (int){42}; -int test_main(void) { - return p[0]; -} +int test_main(void) { return p[0]; } diff --git a/test/parse/cases_err/6_5_generic_duplicate_compatible.c b/test/parse/cases_err/6_5_generic_duplicate_compatible.c @@ -1,3 +1 @@ -int test_main(void) { - return _Generic(0, int: 1, signed int: 2); -} +int test_main(void) { return _Generic(0, int: 1, signed int: 2); } diff --git a/test/parse/cases_err/6_5_member_not_in_struct.c b/test/parse/cases_err/6_5_member_not_in_struct.c @@ -1,5 +1,7 @@ int test_main(void) { - struct S { int a; } s; + struct S { + int a; + } s; s.zzz = 0; return 0; } diff --git a/test/parse/cases_err/6_5_pointer_add_pointer.c b/test/parse/cases_err/6_5_pointer_add_pointer.c @@ -1,6 +1,6 @@ int test_main(void) { int a[2] = {0, 1}; - int *p = a; - int *q = a + 1; + int* p = a; + int* q = a + 1; return (int)(p + q); } diff --git a/test/parse/cases_err/6_5_pointer_compound_bad.c b/test/parse/cases_err/6_5_pointer_compound_bad.c @@ -1,8 +1,8 @@ int test_main(void) { int a = 0; int b = 0; - int *p = &a; - int *q = &b; + int* p = &a; + int* q = &b; p += q; return 0; } diff --git a/test/parse/cases_err/6_5_scalar_required_if.c b/test/parse/cases_err/6_5_scalar_required_if.c @@ -1,5 +1,7 @@ int test_main(void) { - struct S { int v; } s = {42}; + struct S { + int v; + } s = {42}; if (s) return 1; return 0; } diff --git a/test/parse/cases_err/6_5_sizeof_bitfield.c b/test/parse/cases_err/6_5_sizeof_bitfield.c @@ -1,4 +1,6 @@ int test_main(void) { - struct S { unsigned a : 3; } s = {1}; + struct S { + unsigned a : 3; + } s = {1}; return (int)sizeof(s.a); } diff --git a/test/parse/cases_err/6_5_sizeof_function.c b/test/parse/cases_err/6_5_sizeof_function.c @@ -1,5 +1,3 @@ int f(void); -int test_main(void) { - return (int)sizeof(f); -} +int test_main(void) { return (int)sizeof(f); } diff --git a/test/parse/cases_err/6_5_sizeof_incomplete.c b/test/parse/cases_err/6_5_sizeof_incomplete.c @@ -1,5 +1,3 @@ struct S; -int test_main(void) { - return (int)sizeof(struct S); -} +int test_main(void) { return (int)sizeof(struct S); } diff --git a/test/parse/cases_err/6_5_type_mismatch.c b/test/parse/cases_err/6_5_type_mismatch.c @@ -1,7 +1,7 @@ int test_main(void) { int x; int y = 0; - int *p = &y; + int* p = &y; x = p; return x; } diff --git a/test/parse/cases_err/6_5_void_pointer_arith.c b/test/parse/cases_err/6_5_void_pointer_arith.c @@ -1,5 +1,5 @@ int test_main(void) { - void *p = 0; - p = p + 1; - return p != 0; + void* p = 0; + p = p + 1; + return p != 0; } diff --git a/test/parse/cases_err/6_6_array_bound_float.c b/test/parse/cases_err/6_6_array_bound_float.c @@ -1,4 +1,4 @@ int test_main(void) { - int a[1.0]; - return (int)(sizeof(a) / sizeof(a[0])); + int a[1.0]; + return (int)(sizeof(a) / sizeof(a[0])); } diff --git a/test/parse/cases_err/6_6_shift_count_out_of_range.c b/test/parse/cases_err/6_6_shift_count_out_of_range.c @@ -1,5 +1,3 @@ enum { X = 1 << 32 }; -int test_main(void) { - return X; -} +int test_main(void) { return X; } diff --git a/test/parse/cases_err/6_6_static_init_nonconstant.c b/test/parse/cases_err/6_6_static_init_nonconstant.c @@ -1,6 +1,4 @@ int g = 1; static int x = g; -int test_main(void) { - return x; -} +int test_main(void) { return x; } diff --git a/test/parse/cases_err/6_7_10_static_assert_fail.c b/test/parse/cases_err/6_7_10_static_assert_fail.c @@ -1,5 +1,3 @@ _Static_assert(0, "fail"); -int test_main(void) { - return 42; -} +int test_main(void) { return 42; } diff --git a/test/parse/cases_err/6_7_2_1_bitfield_bad_type.c b/test/parse/cases_err/6_7_2_1_bitfield_bad_type.c @@ -2,6 +2,4 @@ struct S { float f : 1; }; -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_2_1_bitfield_named_zero_width.c b/test/parse/cases_err/6_7_2_1_bitfield_named_zero_width.c @@ -2,6 +2,4 @@ struct S { unsigned a : 0; }; -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_2_1_bitfield_negative_width.c b/test/parse/cases_err/6_7_2_1_bitfield_negative_width.c @@ -2,6 +2,4 @@ struct S { unsigned a : -1; }; -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_2_1_bitfield_nonconstant_width.c b/test/parse/cases_err/6_7_2_1_bitfield_nonconstant_width.c @@ -1,5 +1,7 @@ int test_main(void) { int n = 3; - struct S { unsigned a : n; } s = {1}; + struct S { + unsigned a : n; + } s = {1}; return s.a; } diff --git a/test/parse/cases_err/6_7_2_1_bitfield_too_wide.c b/test/parse/cases_err/6_7_2_1_bitfield_too_wide.c @@ -1,4 +1,6 @@ -struct B { unsigned a:33; }; +struct B { + unsigned a : 33; +}; int test_main(void) { struct B b; diff --git a/test/parse/cases_err/6_7_2_1_duplicate_member.c b/test/parse/cases_err/6_7_2_1_duplicate_member.c @@ -1,8 +1,6 @@ struct S { - int x; - int x; + int x; + int x; }; -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_2_1_flex_array_not_last.c b/test/parse/cases_err/6_7_2_1_flex_array_not_last.c @@ -1,9 +1,7 @@ struct S { - int len; - char data[]; - int trailer; + int len; + char data[]; + int trailer; }; -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_2_1_flex_array_only_member.c b/test/parse/cases_err/6_7_2_1_flex_array_only_member.c @@ -1,7 +1,5 @@ struct S { - char data[]; + char data[]; }; -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_2_1_member_extern.c b/test/parse/cases_err/6_7_2_1_member_extern.c @@ -1,7 +1,5 @@ struct S { - extern int x; + extern int x; }; -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_2_1_member_inline.c b/test/parse/cases_err/6_7_2_1_member_inline.c @@ -1,7 +1,5 @@ struct S { - inline int x; + inline int x; }; -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_2_1_member_noreturn.c b/test/parse/cases_err/6_7_2_1_member_noreturn.c @@ -1,7 +1,5 @@ struct S { - _Noreturn int x; + _Noreturn int x; }; -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_2_1_member_static.c b/test/parse/cases_err/6_7_2_1_member_static.c @@ -1,7 +1,5 @@ struct S { - static int x; + static int x; }; -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_2_1_member_thread_local.c b/test/parse/cases_err/6_7_2_1_member_thread_local.c @@ -1,7 +1,5 @@ struct S { - _Thread_local int x; + _Thread_local int x; }; -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_2_1_member_typedef.c b/test/parse/cases_err/6_7_2_1_member_typedef.c @@ -1,7 +1,5 @@ struct S { - typedef int I; + typedef int I; }; -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_2_4_atomic_array_type.c b/test/parse/cases_err/6_7_2_4_atomic_array_type.c @@ -1,5 +1,3 @@ _Atomic(int[2]) x; -int test_main(void) { - return x[0]; -} +int test_main(void) { return x[0]; } diff --git a/test/parse/cases_err/6_7_2_4_atomic_atomic_type.c b/test/parse/cases_err/6_7_2_4_atomic_atomic_type.c @@ -1,5 +1,3 @@ _Atomic(_Atomic int) x; -int test_main(void) { - return x; -} +int test_main(void) { return x; } diff --git a/test/parse/cases_err/6_7_2_4_atomic_qualified_type.c b/test/parse/cases_err/6_7_2_4_atomic_qualified_type.c @@ -1,5 +1,3 @@ _Atomic(const int) x; -int test_main(void) { - return x; -} +int test_main(void) { return x; } diff --git a/test/parse/cases_err/6_7_2_enum_forward.c b/test/parse/cases_err/6_7_2_enum_forward.c @@ -1,5 +1,3 @@ enum E; -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_2_enum_redefinition.c b/test/parse/cases_err/6_7_2_enum_redefinition.c @@ -1,6 +1,4 @@ enum E { A }; enum E { B }; -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_2_enum_wrong_kind.c b/test/parse/cases_err/6_7_2_enum_wrong_kind.c @@ -1,6 +1,4 @@ struct T; enum T { A }; -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_2_storage_class_combo.c b/test/parse/cases_err/6_7_2_storage_class_combo.c @@ -1,5 +1,3 @@ static extern int x; -int test_main(void) { - return x; -} +int test_main(void) { return x; } diff --git a/test/parse/cases_err/6_7_2_tag_wrong_kind.c b/test/parse/cases_err/6_7_2_tag_wrong_kind.c @@ -1,6 +1,6 @@ struct T; -union T { int v; }; +union T { + int v; +}; -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_2_two_struct_defs.c b/test/parse/cases_err/6_7_2_two_struct_defs.c @@ -1,6 +1,8 @@ -struct S { int a; }; -struct S { int b; }; +struct S { + int a; +}; +struct S { + int b; +}; -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_2_void_object.c b/test/parse/cases_err/6_7_2_void_object.c @@ -1,5 +1,3 @@ void x; -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_3_restrict_object.c b/test/parse/cases_err/6_7_3_restrict_object.c @@ -1,4 +1,4 @@ int test_main(void) { - restrict int x = 0; - return x; + restrict int x = 0; + return x; } diff --git a/test/parse/cases_err/6_7_4_inline_object.c b/test/parse/cases_err/6_7_4_inline_object.c @@ -1,5 +1,3 @@ inline int x; -int test_main(void) { - return x; -} +int test_main(void) { return x; } diff --git a/test/parse/cases_err/6_7_4_noreturn_object.c b/test/parse/cases_err/6_7_4_noreturn_object.c @@ -1,5 +1,3 @@ _Noreturn int x; -int test_main(void) { - return x; -} +int test_main(void) { return x; } diff --git a/test/parse/cases_err/6_7_5_alignas_bitfield.c b/test/parse/cases_err/6_7_5_alignas_bitfield.c @@ -1,7 +1,5 @@ struct S { - _Alignas(8) int x: 3; + _Alignas(8) int x : 3; }; -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_5_alignas_function.c b/test/parse/cases_err/6_7_5_alignas_function.c @@ -1,7 +1,3 @@ -_Alignas(16) int f(void) { - return 0; -} +_Alignas(16) int f(void) { return 0; } -int test_main(void) { - return f(); -} +int test_main(void) { return f(); } diff --git a/test/parse/cases_err/6_7_5_alignas_non_power_of_two.c b/test/parse/cases_err/6_7_5_alignas_non_power_of_two.c @@ -1,5 +1,3 @@ _Alignas(3) static int x; -int test_main(void) { - return x; -} +int test_main(void) { return x; } diff --git a/test/parse/cases_err/6_7_5_alignas_typedef.c b/test/parse/cases_err/6_7_5_alignas_typedef.c @@ -1,6 +1,6 @@ _Alignas(16) typedef int I; int test_main(void) { - I x = 0; - return x; + I x = 0; + return x; } diff --git a/test/parse/cases_err/6_7_5_alignas_weaker_than_natural.c b/test/parse/cases_err/6_7_5_alignas_weaker_than_natural.c @@ -1,5 +1,3 @@ _Alignas(1) static double x; -int test_main(void) { - return (int)sizeof x; -} +int test_main(void) { return (int)sizeof x; } diff --git a/test/parse/cases_err/6_7_6_array_of_function.c b/test/parse/cases_err/6_7_6_array_of_function.c @@ -1,6 +1,4 @@ typedef int F(void); F a[3]; -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_6_function_returning_array.c b/test/parse/cases_err/6_7_6_function_returning_array.c @@ -1,5 +1,3 @@ int f(void)[3]; -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_6_function_returning_function.c b/test/parse/cases_err/6_7_6_function_returning_function.c @@ -1,5 +1,3 @@ int f(void)(void); -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_6_param_auto.c b/test/parse/cases_err/6_7_6_param_auto.c @@ -1,7 +1,3 @@ -static int f(auto int x) { - return x; -} +static int f(auto int x) { return x; } -int test_main(void) { - return f(0); -} +int test_main(void) { return f(0); } diff --git a/test/parse/cases_err/6_7_6_param_extern.c b/test/parse/cases_err/6_7_6_param_extern.c @@ -1,7 +1,3 @@ -static int f(extern int x) { - return x; -} +static int f(extern int x) { return x; } -int test_main(void) { - return f(0); -} +int test_main(void) { return f(0); } diff --git a/test/parse/cases_err/6_7_6_param_thread_local.c b/test/parse/cases_err/6_7_6_param_thread_local.c @@ -1,7 +1,3 @@ -static int f(_Thread_local int x) { - return x; -} +static int f(_Thread_local int x) { return x; } -int test_main(void) { - return f(0); -} +int test_main(void) { return f(0); } diff --git a/test/parse/cases_err/6_7_6_param_typedef.c b/test/parse/cases_err/6_7_6_param_typedef.c @@ -1,7 +1,3 @@ -static int f(typedef int x) { - return x; -} +static int f(typedef int x) { return x; } -int test_main(void) { - return f(0); -} +int test_main(void) { return f(0); } diff --git a/test/parse/cases_err/6_7_6_static_param_scalar.c b/test/parse/cases_err/6_7_6_static_param_scalar.c @@ -1,7 +1,3 @@ -static int f(static int x) { - return x; -} +static int f(static int x) { return x; } -int test_main(void) { - return f(0); -} +int test_main(void) { return f(0); } diff --git a/test/parse/cases_err/6_7_6_variadic_no_param.c b/test/parse/cases_err/6_7_6_variadic_no_param.c @@ -1,5 +1,3 @@ int f(...); -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_6_variadic_not_last.c b/test/parse/cases_err/6_7_6_variadic_not_last.c @@ -1,5 +1,3 @@ int f(int, ..., int); -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_7_9_invalid_struct_designator.c b/test/parse/cases_err/6_7_9_invalid_struct_designator.c @@ -1,4 +1,6 @@ int test_main(void) { - struct S { int a; } s = {.b = 42}; + struct S { + int a; + } s = {.b = 42}; return s.a; } diff --git a/test/parse/cases_err/6_7_9_invalid_union_designator.c b/test/parse/cases_err/6_7_9_invalid_union_designator.c @@ -1,4 +1,7 @@ int test_main(void) { - union U { int a; int b; } u = {.c = 42}; + union U { + int a; + int b; + } u = {.c = 42}; return u.a; } diff --git a/test/parse/cases_err/6_7_9_static_ptr_nonzero.c b/test/parse/cases_err/6_7_9_static_ptr_nonzero.c @@ -1,5 +1,3 @@ static int* p = 1; -int test_main(void) { - return p != 0; -} +int test_main(void) { return p != 0; } diff --git a/test/parse/cases_err/6_7_9_static_signed_char_overflow.c b/test/parse/cases_err/6_7_9_static_signed_char_overflow.c @@ -1,5 +1,3 @@ static signed char c = 128; -int test_main(void) { - return c; -} +int test_main(void) { return c; } diff --git a/test/parse/cases_err/6_7_file_scope_auto.c b/test/parse/cases_err/6_7_file_scope_auto.c @@ -1,5 +1,3 @@ auto int x; -int test_main(void) { - return x; -} +int test_main(void) { return x; } diff --git a/test/parse/cases_err/6_7_redefinition.c b/test/parse/cases_err/6_7_redefinition.c @@ -1,6 +1,4 @@ int x = 1; int x = 2; -int test_main(void) { - return x; -} +int test_main(void) { return x; } diff --git a/test/parse/cases_err/6_7_storage_class_static_thread_local_function.c b/test/parse/cases_err/6_7_storage_class_static_thread_local_function.c @@ -1,7 +1,3 @@ -static _Thread_local int f(void) { - return 0; -} +static _Thread_local int f(void) { return 0; } -int test_main(void) { - return f(); -} +int test_main(void) { return f(); } diff --git a/test/parse/cases_err/6_7_thread_local_block_auto.c b/test/parse/cases_err/6_7_thread_local_block_auto.c @@ -1,4 +1,4 @@ int test_main(void) { - _Thread_local int x = 42; - return x; + _Thread_local int x = 42; + return x; } diff --git a/test/parse/cases_err/6_7_thread_local_function.c b/test/parse/cases_err/6_7_thread_local_function.c @@ -1,7 +1,3 @@ -_Thread_local int f(void) { - return 0; -} +_Thread_local int f(void) { return 0; } -int test_main(void) { - return f(); -} +int test_main(void) { return f(); } diff --git a/test/parse/cases_err/6_7_thread_local_typedef.c b/test/parse/cases_err/6_7_thread_local_typedef.c @@ -1,6 +1,6 @@ typedef _Thread_local int I; int test_main(void) { - I x = 0; - return x; + I x = 0; + return x; } diff --git a/test/parse/cases_err/6_7_type_spec_bool_int.c b/test/parse/cases_err/6_7_type_spec_bool_int.c @@ -1,5 +1,3 @@ _Bool int x; -int test_main(void) { - return x; -} +int test_main(void) { return x; } diff --git a/test/parse/cases_err/6_7_type_spec_char_int.c b/test/parse/cases_err/6_7_type_spec_char_int.c @@ -1,5 +1,3 @@ char int x; -int test_main(void) { - return x; -} +int test_main(void) { return x; } diff --git a/test/parse/cases_err/6_7_type_spec_float_double.c b/test/parse/cases_err/6_7_type_spec_float_double.c @@ -1,5 +1,3 @@ float double x; -int test_main(void) { - return (int)x; -} +int test_main(void) { return (int)x; } diff --git a/test/parse/cases_err/6_7_type_spec_long_float.c b/test/parse/cases_err/6_7_type_spec_long_float.c @@ -1,5 +1,3 @@ long float x; -int test_main(void) { - return (int)x; -} +int test_main(void) { return (int)x; } diff --git a/test/parse/cases_err/6_7_type_spec_short_char.c b/test/parse/cases_err/6_7_type_spec_short_char.c @@ -1,5 +1,3 @@ short char x; -int test_main(void) { - return x; -} +int test_main(void) { return x; } diff --git a/test/parse/cases_err/6_7_type_spec_signed_double.c b/test/parse/cases_err/6_7_type_spec_signed_double.c @@ -1,5 +1,3 @@ signed double x; -int test_main(void) { - return (int)x; -} +int test_main(void) { return (int)x; } diff --git a/test/parse/cases_err/6_7_type_spec_too_many_longs.c b/test/parse/cases_err/6_7_type_spec_too_many_longs.c @@ -1,5 +1,3 @@ long long long x; -int test_main(void) { - return (int)x; -} +int test_main(void) { return (int)x; } diff --git a/test/parse/cases_err/6_7_type_spec_unsigned_double.c b/test/parse/cases_err/6_7_type_spec_unsigned_double.c @@ -1,5 +1,3 @@ unsigned double x; -int test_main(void) { - return (int)x; -} +int test_main(void) { return (int)x; } diff --git a/test/parse/cases_err/6_8_duplicate_case.c b/test/parse/cases_err/6_8_duplicate_case.c @@ -1,8 +1,10 @@ int test_main(void) { int x = 1; switch (x) { - case 1: return 1; - case 1: return 2; + case 1: + return 1; + case 1: + return 2; } return 0; } diff --git a/test/parse/cases_err/6_8_duplicate_default.c b/test/parse/cases_err/6_8_duplicate_default.c @@ -1,8 +1,10 @@ int test_main(void) { int x = 1; switch (x) { - default: return 1; - default: return 2; + default: + return 1; + default: + return 2; } return 0; } diff --git a/test/parse/cases_err/6_8_duplicate_label.c b/test/parse/cases_err/6_8_duplicate_label.c @@ -1,4 +1,5 @@ int test_main(void) { - L: ; - L: return 0; +L:; +L: + return 0; } diff --git a/test/parse/cases_err/6_8_goto_into_vla_scope.c b/test/parse/cases_err/6_8_goto_into_vla_scope.c @@ -1,10 +1,10 @@ int test_main(void) { - int n = 4; - goto inside; - { - int a[n]; -inside: - a[0] = 0; - } - return 0; + int n = 4; + goto inside; + { + int a[n]; + inside: + a[0] = 0; + } + return 0; } diff --git a/test/parse/cases_err/6_8_switch_float.c b/test/parse/cases_err/6_8_switch_float.c @@ -1,7 +1,7 @@ int test_main(void) { - switch (1.0) { + switch (1.0) { case 1: - return 0; - } - return 0; + return 0; + } + return 0; } diff --git a/test/parse/cases_err/6_9_conflicting_function_types.c b/test/parse/cases_err/6_9_conflicting_function_types.c @@ -1,6 +1,4 @@ int f(int); int f(long); -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/6_9_duplicate_parameter.c b/test/parse/cases_err/6_9_duplicate_parameter.c @@ -1,7 +1,3 @@ -int f(int x, int x) { - return x; -} +int f(int x, int x) { return x; } -int test_main(void) { - return f(1, 2); -} +int test_main(void) { return f(1, 2); } diff --git a/test/parse/cases_err/6_9_redefinition_function.c b/test/parse/cases_err/6_9_redefinition_function.c @@ -1,6 +1,4 @@ int f(void) { return 1; } int f(void) { return 2; } -int test_main(void) { - return f(); -} +int test_main(void) { return f(); } diff --git a/test/parse/cases_err/6_9_void_param_with_other.c b/test/parse/cases_err/6_9_void_param_with_other.c @@ -1,5 +1,3 @@ int f(void, int); -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/attr_aligned_wrong_arg.c b/test/parse/cases_err/attr_aligned_wrong_arg.c @@ -2,6 +2,4 @@ * passing a string literal must be rejected by the parser. */ int x __attribute__((aligned("oops"))); -int test_main(void) { - return x; -} +int test_main(void) { return x; } diff --git a/test/parse/cases_err/attr_format_wrong_arity.c b/test/parse/cases_err/attr_format_wrong_arity.c @@ -1,8 +1,5 @@ /* format(archetype, m, n) requires three arguments (AS_FORMAT); * passing only the archetype must be rejected. */ -__attribute__((format(printf))) -int my_printf(const char *fmt, ...); +__attribute__((format(printf))) int my_printf(const char* fmt, ...); -int test_main(void) { - return 0; -} +int test_main(void) { return 0; } diff --git a/test/parse/cases_err/attr_p2_alias_unresolved.c b/test/parse/cases_err/attr_p2_alias_unresolved.c @@ -2,6 +2,4 @@ * same TU must be diagnosed at finalize. */ int foo(void) __attribute__((alias("nonexistent_target"))); -int test_main(void) { - return foo(); -} +int test_main(void) { return foo(); } diff --git a/test/parse/cases_err/attr_p2_aligned_not_pow2.c b/test/parse/cases_err/attr_p2_aligned_not_pow2.c @@ -1,6 +1,4 @@ /* Phase 2: aligned(N) requires N to be a power of two. 3 is invalid. */ int x __attribute__((aligned(3))); -int test_main(void) { - return x; -} +int test_main(void) { return x; } diff --git a/test/parse/cases_err/attr_p2_visibility_bad.c b/test/parse/cases_err/attr_p2_visibility_bad.c @@ -4,6 +4,4 @@ int hidden_fn(void) __attribute__((visibility("totallyfake"))); int hidden_fn(void) { return 0; } -int test_main(void) { - return hidden_fn(); -} +int test_main(void) { return hidden_fn(); } diff --git a/test/parse/cases_err/attr_section_no_string.c b/test/parse/cases_err/attr_section_no_string.c @@ -2,6 +2,4 @@ * integer must be rejected. */ __attribute__((section(42))) int foo(void) { return 0; } -int test_main(void) { - return foo(); -} +int test_main(void) { return foo(); } diff --git a/test/parse/harness/parse_runner.c b/test/parse/harness/parse_runner.c @@ -174,14 +174,13 @@ static CfreeStatus xm_reserve(void* u, size_t n, int p, close(fd); return CFREE_NOMEM; } - w = mmap(NULL, n, PROT_READ | PROT_WRITE, - MAP_SHARED | XM_MAP_32BIT, fd, 0); + w = mmap(NULL, n, PROT_READ | PROT_WRITE, MAP_SHARED | XM_MAP_32BIT, fd, 0); if (w == MAP_FAILED) { close(fd); return CFREE_NOMEM; } - r = mmap(xm_low_runtime_hint(n), n, PROT_READ, - MAP_SHARED | XM_MAP_32BIT, fd, 0); + r = mmap(xm_low_runtime_hint(n), n, PROT_READ, MAP_SHARED | XM_MAP_32BIT, + fd, 0); close(fd); if (r == MAP_FAILED) { munmap(w, n); @@ -426,7 +425,8 @@ static int mode_emit_impl(const char* src_path, const char* out_path, opts.code.emit_c_source = true; opts.code.c_source_writer = w; } - if (compile_c_emit(c, &opts, cfree_slice_cstr(src_path), &in, w) != CFREE_OK) { + if (compile_c_emit(c, &opts, cfree_slice_cstr(src_path), &in, w) != + CFREE_OK) { cfree_writer_close(w); cfree_compiler_free(c); free(src); @@ -465,11 +465,11 @@ static int mode_emit_impl(const char* src_path, const char* out_path, #if defined(__aarch64__) || defined(__arm64__) static char g_tls_block[8192] __attribute__((aligned(16))); -__attribute__((noinline, no_sanitize("address", "undefined"))) -static int call_with_aarch64_tls(int (*fn)(void), void* tls_block) { +__attribute__((noinline, no_sanitize("address", "undefined"))) static int +call_with_aarch64_tls(int (*fn)(void), void* tls_block) { void* old_tp; int result; - __asm__ volatile("mrs %0, tpidr_el0" : "=r"(old_tp) :: "memory"); + __asm__ volatile("mrs %0, tpidr_el0" : "=r"(old_tp)::"memory"); __asm__ volatile("msr tpidr_el0, %0" ::"r"(tls_block) : "memory"); result = fn(); __asm__ volatile("msr tpidr_el0, %0" ::"r"(old_tp) : "memory"); @@ -512,7 +512,8 @@ static int mode_jit(const char* src_path) { opts.code.opt_level = opt_level_from_env(); add_test_system_includes(&opts); - if (compile_c_obj(c, &opts, cfree_slice_cstr(src_path), &in, &ob) != CFREE_OK || + if (compile_c_obj(c, &opts, cfree_slice_cstr(src_path), &in, &ob) != + CFREE_OK || !ob) { cfree_compiler_free(c); free(src); @@ -548,10 +549,11 @@ static int mode_jit(const char* src_path) { #if defined(__aarch64__) || defined(__arm64__) { - char* td_start = (char*)cfree_jit_lookup(jit, CFREE_SLICE_LIT("__tdata_start")); + char* td_start = + (char*)cfree_jit_lookup(jit, CFREE_SLICE_LIT("__tdata_start")); char* td_end = (char*)cfree_jit_lookup(jit, CFREE_SLICE_LIT("__tdata_end")); - unsigned long bs_n = - (unsigned long)(unsigned long long)cfree_jit_lookup(jit, CFREE_SLICE_LIT("__tbss_size")); + unsigned long bs_n = (unsigned long)(unsigned long long)cfree_jit_lookup( + jit, CFREE_SLICE_LIT("__tbss_size")); if (td_start && td_end) { unsigned long td_n = (unsigned long)(td_end - td_start); unsigned long i; diff --git a/test/wasm-target/import_decl_attribute.c b/test/wasm-target/import_decl_attribute.c @@ -7,7 +7,7 @@ * Same calling convention as `import_decl.c`; round-trip returns 5 when * `custom.add` is bound to a sum-of-args host function. */ -__attribute__((import_module("custom"), import_name("add"))) -extern int host_add(int, int); +__attribute__((import_module("custom"), import_name("add"))) extern int +host_add(int, int); int main(void) { return host_add(2, 3); } diff --git a/test/wasm/harness/start_wasm.c b/test/wasm/harness/start_wasm.c @@ -12,14 +12,14 @@ * resolve imports before calling __cfree_wasm_init. */ -extern void __cfree_wasm_init(void *); -extern int test_main(void *); +extern void __cfree_wasm_init(void*); +extern int test_main(void*); /* Imports metadata emitted by lang/wasm/cg.c when the module declares any * imports. Made weak so this harness still links for modules without them. */ typedef struct WasmStartImportDesc { - const char *module; - const char *field; + const char* module; + const char* field; unsigned int typeidx; unsigned int slot_offset; } WasmStartImportDesc; @@ -28,31 +28,33 @@ extern const unsigned int __cfree_wasm_nimports __attribute__((weak)); /* Canned test host function (also referenced by jit_runner.c, driver/run.c). * The freestanding harness inlines its own copy because it has no libc. */ -static int start_test_host_add(void *inst, int a, int b) { +static int start_test_host_add(void* inst, int a, int b) { (void)inst; return a + b; } -static int start_streq(const char *a, const char *b) { - while (*a && *a == *b) { a++; b++; } +static int start_streq(const char* a, const char* b) { + while (*a && *a == *b) { + a++; + b++; + } return *a == 0 && *b == 0; } -static void start_bind_canned_imports(void *instance) { +static void start_bind_canned_imports(void* instance) { if (!(&__cfree_wasm_nimports)) return; unsigned int n = __cfree_wasm_nimports; for (unsigned int i = 0; i < n; ++i) { - const WasmStartImportDesc *d = &__cfree_wasm_imports[i]; - if (start_streq(d->module, "env") && - start_streq(d->field, "host_add")) { - *(void **)((unsigned char *)instance + d->slot_offset) = - (void *)(unsigned long)start_test_host_add; + const WasmStartImportDesc* d = &__cfree_wasm_imports[i]; + if (start_streq(d->module, "env") && start_streq(d->field, "host_add")) { + *(void**)((unsigned char*)instance + d->slot_offset) = + (void*)(unsigned long)start_test_host_add; } } } typedef struct WasmStartMemoryPrefix { - unsigned char *data; + unsigned char* data; unsigned long long pages; unsigned long long max_pages; unsigned int flags; @@ -72,7 +74,7 @@ typedef struct WasmStartMemoryPrefix { #if defined(__APPLE__) extern void exit(int) __attribute__((noreturn)); -extern void *mmap(void *, unsigned long, int, int, int, long); +extern void* mmap(void*, unsigned long, int, int, int, long); #endif __attribute__((noreturn)) static void do_exit(int code) { @@ -97,30 +99,26 @@ __attribute__((noreturn)) static void do_exit(int code) { __builtin_unreachable(); } -static void *start_mmap(unsigned long size) { +static void* start_mmap(unsigned long size) { #if defined(__APPLE__) - void *p = mmap((void *)0, size, WASM_START_PROT_READ | WASM_START_PROT_WRITE, + void* p = mmap((void*)0, size, WASM_START_PROT_READ | WASM_START_PROT_WRITE, WASM_START_MAP_PRIVATE | WASM_START_MAP_ANON, -1, 0); - if ((long)p == -1) - return (void *)0; + if ((long)p == -1) return (void*)0; return p; #elif defined(__aarch64__) register long x8 __asm__("x8") = 222; register long x0 __asm__("x0") = 0; register long x1 __asm__("x1") = (long)size; - register long x2 __asm__("x2") = - WASM_START_PROT_READ | WASM_START_PROT_WRITE; - register long x3 __asm__("x3") = - WASM_START_MAP_PRIVATE | WASM_START_MAP_ANON; + register long x2 __asm__("x2") = WASM_START_PROT_READ | WASM_START_PROT_WRITE; + register long x3 __asm__("x3") = WASM_START_MAP_PRIVATE | WASM_START_MAP_ANON; register long x4 __asm__("x4") = -1; register long x5 __asm__("x5") = 0; __asm__ volatile("svc #0" : "+r"(x0) : "r"(x8), "r"(x1), "r"(x2), "r"(x3), "r"(x4), "r"(x5) : "memory"); - if (x0 < 0 && x0 > -4096) - return (void *)0; - return (void *)x0; + if (x0 < 0 && x0 > -4096) return (void*)0; + return (void*)x0; #elif defined(__x86_64__) register long rax __asm__("rax") = 9; register long rdi __asm__("rdi") = 0; @@ -135,26 +133,22 @@ static void *start_mmap(unsigned long size) { : "+r"(rax) : "r"(rdi), "r"(rsi), "r"(rdx), "r"(r10), "r"(r8), "r"(r9) : "rcx", "r11", "memory"); - if (rax < 0 && rax > -4096) - return (void *)0; - return (void *)rax; + if (rax < 0 && rax > -4096) return (void*)0; + return (void*)rax; #elif defined(__riscv) && __riscv_xlen == 64 register long a7 __asm__("a7") = 222; register long a0 __asm__("a0") = 0; register long a1 __asm__("a1") = (long)size; - register long a2 __asm__("a2") = - WASM_START_PROT_READ | WASM_START_PROT_WRITE; - register long a3 __asm__("a3") = - WASM_START_MAP_PRIVATE | WASM_START_MAP_ANON; + register long a2 __asm__("a2") = WASM_START_PROT_READ | WASM_START_PROT_WRITE; + register long a3 __asm__("a3") = WASM_START_MAP_PRIVATE | WASM_START_MAP_ANON; register long a4 __asm__("a4") = -1; register long a5 __asm__("a5") = 0; __asm__ volatile("ecall" : "+r"(a0) : "r"(a7), "r"(a1), "r"(a2), "r"(a3), "r"(a4), "r"(a5) : "memory"); - if (a0 < 0 && a0 > -4096) - return (void *)0; - return (void *)a0; + if (a0 < 0 && a0 > -4096) return (void*)0; + return (void*)a0; #else #error "start_wasm.c: unsupported architecture" #endif @@ -164,14 +158,13 @@ static void *start_mmap(unsigned long size) { __attribute__((force_align_arg_pointer)) #endif void _start(void) { - void *instance = start_mmap(WASM_START_INSTANCE_SIZE); - void *memory = start_mmap(WASM_START_MEMORY_SIZE); - if (!instance || !memory) - do_exit(1); + void* instance = start_mmap(WASM_START_INSTANCE_SIZE); + void* memory = start_mmap(WASM_START_MEMORY_SIZE); + if (!instance || !memory) do_exit(1); for (unsigned int i = 0; i < WASM_START_MEMORY_PREFIX_COUNT; ++i) - ((WasmStartMemoryPrefix *)instance)[i].data = - (unsigned char *)memory + i * (WASM_START_MEMORY_SIZE / - WASM_START_MEMORY_PREFIX_COUNT); + ((WasmStartMemoryPrefix*)instance)[i].data = + (unsigned char*)memory + + i * (WASM_START_MEMORY_SIZE / WASM_START_MEMORY_PREFIX_COUNT); start_bind_canned_imports(instance); __cfree_wasm_init(instance); do_exit(test_main(instance)); diff --git a/test/wasm/harness/wasm_tool.c b/test/wasm/harness/wasm_tool.c @@ -127,8 +127,7 @@ int main(int argc, char** argv) { int rc = cfree_wasm_wat_to_wasm(c, &in, w); size_t out_len = 0; const uint8_t* out = cfree_writer_mem_bytes(w, &out_len); - if (!rc) - rc = write_file(argv[3], out, out_len); + if (!rc) rc = write_file(argv[3], out, out_len); cfree_writer_close(w); cfree_compiler_free(c); free(src);