aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/a_targ.c
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2026-03-17 13:22:00 +0100
committerlemon <lsof@mailbox.org>2026-03-17 13:22:00 +0100
commita8d6f8bf30c07edb775e56889f568ca20240bedf (patch)
treeb5a452b2675b2400f15013617291fe6061180bbf /src/a_targ.c
parent24f14b7ad1af08d872971d72ce089a529911f657 (diff)
REFACTOR: move sources to src/
Diffstat (limited to 'src/a_targ.c')
-rw-r--r--src/a_targ.c121
1 files changed, 121 insertions, 0 deletions
diff --git a/src/a_targ.c b/src/a_targ.c
new file mode 100644
index 0000000..fdc11f8
--- /dev/null
+++ b/src/a_targ.c
@@ -0,0 +1,121 @@
+#include "common.h"
+#include "type.h"
+
+extern const struct mctarg t_x86_64_sysv, t_aarch64_aapcs;
+static const struct targ {
+ struct { enum mcarch arch; uint oss, abis; };
+ struct { uchar longsize, vlongsize, ptrsize, valistsize; };
+ struct { uchar longalign, vlongalign, doublealign, ptralign; };
+ bool charsigned;
+ uchar sizetype, ptrdifftype, wchartype;
+ const struct mctarg *mctarg;
+} targs[] = {
+ { {ISx86_64, -1, -1}, {8,8,8,24}, {8,8,8,8}, 1, TYULONG, TYLONG, TYINT, &t_x86_64_sysv },
+ { {ISaarch64, -1, -1}, {8,8,8,32}, {8,8,8,8}, 0, TYULONG, TYLONG, TYUINT, &t_aarch64_aapcs },
+};
+
+struct targtriple target;
+uchar targ_primsizes[TYPTR+1];
+uchar targ_primalign[TYPTR+1];
+uint targ_valistsize;
+enum typetag targ_sizetype, targ_ptrdifftype, targ_wchartype;
+bool targ_charsigned, targ_bigendian, targ_64bit;
+enum mcarch targ_arch;
+const struct mctarg *mctarg;
+
+static bool
+matchstr(const char **s, const char *pat)
+{
+ const char *p;
+ for (p = *s; *pat; ++p, ++pat) {
+ if (*pat == '$') { if (*p) return 0; else break; }
+ else if (*p != *pat) return 0;
+ }
+ *s = p;
+ return 1;
+}
+
+static bool
+parsetriple(struct targtriple *trg, const char *str)
+{
+ if (matchstr(&str, "x86_64-") || matchstr(&str, "amd64-"))
+ trg->arch = ISx86_64;
+ else if (matchstr(&str, "aarch64-") || matchstr(&str, "arm64-"))
+ trg->arch = ISaarch64;
+ else return 0;
+
+ if (matchstr(&str, "unknown-") || matchstr(&str, "pc-")) {}
+
+ if (matchstr(&str, "linux-")) {
+ trg->os = OSlinux;
+ } else if (matchstr(&str, "linux$")) {
+ trg->os = OSlinux;
+ trg->abi = ABIgnu;
+ } else return 0;
+
+ if (matchstr(&str, "gnu")) {
+ trg->abi = ABIgnu;
+ } else if (matchstr(&str, "musl")) {
+ trg->abi = ABImusl;
+ } else return 0;
+
+ return 1;
+}
+
+#include "hostconfig.h" /* run ./configure */
+
+void
+targ_init(const char *starg)
+{
+ const struct targ *t = NULL;
+ uchar *sizes = targ_primsizes, *align = targ_primalign;
+
+ if (!starg) {
+ target.arch = HOST_ARCH;
+ target.os = HOST_OS;
+ target.abi = HOST_ABI;
+ } else if (!parsetriple(&target, starg)) {
+ fatal(NULL, "unrecognized target: %s", starg);
+ }
+
+ for (size_t i = 0; i < countof(targs); ++i) {
+ if (targs[i].arch == target.arch)
+ if (targs[i].oss & (1 << target.os))
+ if (targs[i].abis & (1 << target.abi)) {
+ t = &targs[i];
+ break;
+ }
+ }
+ if (!t) fatal(NULL, "unsupported target: %s", starg ? starg : HOST_TRIPLE);
+
+ sizes[TYBOOL] = sizes[TYCHAR] = sizes[TYSCHAR] = sizes[TYUCHAR] = 1;
+ sizes[TYSHORT] = sizes[TYUSHORT] = 2;
+ sizes[TYUINT] = sizes[TYINT] = 4;
+ sizes[TYFLOAT] = 4;
+ sizes[TYDOUBLE] = 8;
+ sizes[TYLDOUBLE] = 8;
+ memcpy(align, sizes, sizeof targ_primalign);
+ sizes[TYULONG] = sizes[TYLONG] = t->longsize;
+ sizes[TYUVLONG] = sizes[TYVLONG] = t->vlongsize;
+ sizes[TYPTR] = t->ptrsize;
+ align[TYULONG] = align[TYLONG] = t->longalign;
+ align[TYUVLONG] = align[TYVLONG] = t->vlongalign;
+ align[TYDOUBLE] = t->doublealign;
+ align[TYLDOUBLE] = t->doublealign;
+ align[TYPTR] = t->ptralign;
+ sizes[TYCOMPLEXF] = sizes[TYFLOAT]*2;
+ sizes[TYCOMPLEX] = sizes[TYDOUBLE]*2;
+ sizes[TYCOMPLEXL] = sizes[TYLDOUBLE]*2;
+ align[TYCOMPLEXF] = align[TYFLOAT];
+ align[TYCOMPLEX] = align[TYDOUBLE];
+ align[TYCOMPLEXL] = align[TYLDOUBLE];
+ targ_valistsize = t->valistsize;
+ targ_sizetype = t->sizetype;
+ targ_ptrdifftype = t->ptrdifftype;
+ targ_wchartype = t->wchartype;
+ targ_charsigned = t->charsigned;
+ targ_bigendian = 0;
+ targ_64bit = t->ptrsize == 8;
+ mctarg = t->mctarg;
+ targ_arch = ISx86_64;
+}