aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--cc.h10
-rwxr-xr-xconfigure9
-rw-r--r--driver.c20
-rw-r--r--main.c7
-rw-r--r--targ.c34
6 files changed, 73 insertions, 9 deletions
diff --git a/Makefile b/Makefile
index 19d2906..030a012 100644
--- a/Makefile
+++ b/Makefile
@@ -31,6 +31,7 @@ SRC=\
scope.c\
siphash.c\
stmt.c\
+ targ.c\
token.c\
tree.c\
type.c\
@@ -54,6 +55,7 @@ $(objdir)/scan.o : scan.c util.h cc.h $(stagedeps) ; $(CC) $(CFLAGS)
$(objdir)/scope.o : scope.c util.h cc.h $(stagedeps) ; $(CC) $(CFLAGS) -c -o $@ scope.c
$(objdir)/siphash.o : siphash.c $(stagedeps) ; $(CC) $(CFLAGS) -c -o $@ siphash.c
$(objdir)/stmt.o : stmt.c util.h cc.h $(stagedeps) ; $(CC) $(CFLAGS) -c -o $@ stmt.c
+$(objdir)/targ.o : targ.c util.h cc.h $(stagedeps) ; $(CC) $(CFLAGS) -c -o $@ targ.c
$(objdir)/token.o : token.c util.h cc.h $(stagedeps) ; $(CC) $(CFLAGS) -c -o $@ token.c
$(objdir)/tree.o : tree.c util.h $(stagedeps) ; $(CC) $(CFLAGS) -c -o $@ tree.c
$(objdir)/type.o : type.c util.h cc.h $(stagedeps) ; $(CC) $(CFLAGS) -c -o $@ type.c
diff --git a/cc.h b/cc.h
index 1f021fa..8978d89 100644
--- a/cc.h
+++ b/cc.h
@@ -406,6 +406,16 @@ extern struct type typellong, typeullong;
extern struct type typefloat, typedouble, typeldouble;
extern struct type typevalist, typevalistptr;
+/* targ */
+
+struct target {
+ const char *name;
+};
+
+extern struct target *targ;
+
+void targinit(const char *);
+
/* decl */
struct decl *mkdecl(enum declkind, struct type *, enum typequal, enum linkage);
diff --git a/configure b/configure
index c30d4c3..39f0c0a 100755
--- a/configure
+++ b/configure
@@ -41,12 +41,6 @@ if [ "$host" != "$target" ] ; then
toolprefix=$target-
fi
-case "$target" in
-x86_64*|amd64*) qbetarget=amd64_sysv ;;
-aarch64*) qbetarget=arm64 ;;
-*) fail "unsupported architecture '${target%%-*}'"
-esac
-
startfiles=0
endfiles=0
defines=
@@ -130,6 +124,7 @@ test "$DEFAULT_DYNAMIC_LINKER" && linkflags=$linkflags' "--dynamic-linker", "'$D
printf "creating config.h... "
cat >config.h <<EOF
+static char target[] = "$target";
static char *startfiles[] = {$startfiles};
static char *endfiles[] = {$endfiles};
static char *preprocesscmd[] = {
@@ -148,7 +143,7 @@ static char *preprocesscmd[] = {
"-D", "__attribute__(x)=",
"-D", "__extension__=",
$defines};
-static char *codegencmd[] = {"$DEFAULT_QBE", "-t", "$qbetarget"};
+static char *codegencmd[] = {"$DEFAULT_QBE"};
static char *assemblecmd[] = {"$DEFAULT_ASSEMBLER"};
static char *linkcmd[] = {"$DEFAULT_LINKER", $linkflags};
EOF
diff --git a/driver.c b/driver.c
index 9d48ce6..b334f38 100644
--- a/driver.c
+++ b/driver.c
@@ -347,11 +347,17 @@ compilecommand(char *arg)
return cmd;
}
+static int
+hasprefix(const char *str, const char *pfx)
+{
+ return memcmp(str, pfx, strlen(pfx)) == 0;
+}
+
int
main(int argc, char *argv[])
{
enum phaseid first = 0, last = LINK;
- char *arg, *end, *output = NULL;
+ char *arg, *end, *output = NULL, *arch, *qbearch;
struct array inputs = {0}, *cmd;
struct input *input;
size_t i;
@@ -362,6 +368,18 @@ main(int argc, char *argv[])
arrayaddbuf(&phases[ASSEMBLE].cmd, assemblecmd, sizeof(assemblecmd));
arrayaddbuf(&phases[LINK].cmd, linkcmd, sizeof(linkcmd));
+ if (hasprefix(target, "x86_64-") || hasprefix(target, "amd64-")) {
+ arch = "x86_64";
+ qbearch = "amd64_sysv";
+ } else if (hasprefix(target, "aarch64-")) {
+ arch = "aarch64";
+ qbearch = "arm64";
+ }
+ arrayaddptr(&phases[COMPILE].cmd, "-t");
+ arrayaddptr(&phases[COMPILE].cmd, arch);
+ arrayaddptr(&phases[CODEGEN].cmd, "-t");
+ arrayaddptr(&phases[CODEGEN].cmd, qbearch);
+
argv0 = progname(argv[0], "cc");
for (;;) {
++argv, --argc;
diff --git a/main.c b/main.c
index 2f96c92..79850a5 100644
--- a/main.c
+++ b/main.c
@@ -18,13 +18,16 @@ int
main(int argc, char *argv[])
{
bool pponly = false;
- char *output = NULL;
+ char *output = NULL, *target = NULL;
argv0 = progname(argv[0], "cc-qbe");
ARGBEGIN {
case 'E':
pponly = true;
break;
+ case 't':
+ target = EARGF(usage());
+ break;
case 'o':
output = EARGF(usage());
break;
@@ -32,6 +35,8 @@ main(int argc, char *argv[])
usage();
} ARGEND
+ targinit(target);
+
if (argc > 1)
usage();
if (output && !freopen(output, "w", stdout))
diff --git a/targ.c b/targ.c
new file mode 100644
index 0000000..a3fd2f0
--- /dev/null
+++ b/targ.c
@@ -0,0 +1,34 @@
+#include <stdint.h>
+#include <string.h>
+#include "util.h"
+#include "cc.h"
+
+struct target *targ;
+
+static struct target alltargs[] = {
+ {
+ .name = "x86_64",
+ },
+ {
+ .name = "aarch64",
+ },
+};
+
+void
+targinit(const char *name)
+{
+ size_t i;
+
+ if (!name) {
+ /* TODO: provide a way to set this default */
+ targ = &alltargs[0];
+ return;
+ }
+ for (i = 0; i < LEN(alltargs); ++i) {
+ if (strcmp(alltargs[i].name, name) == 0) {
+ targ = &alltargs[i];
+ return;
+ }
+ }
+ fatal("unknown target '%s'", name);
+}