dynamic stack allocs for arm64
[qbe.git] / main.c
blob74d057d4387e60c9edbbbf028fd46db8cafd3e0c
1 #include "all.h"
2 #include "config.h"
3 #include <ctype.h>
4 #include <getopt.h>
6 Target T;
8 extern Target T_amd64_sysv;
9 extern Target T_arm64;
10 extern Target T_rv64;
12 static struct TMap {
13 char *name;
14 Target *T;
15 } tmap[] = {
16 { "amd64_sysv", &T_amd64_sysv },
17 { "arm64", &T_arm64 },
18 { "rv64", &T_rv64 },
19 { 0, 0 }
22 char debug['Z'+1] = {
23 ['P'] = 0, /* parsing */
24 ['M'] = 0, /* memory optimization */
25 ['N'] = 0, /* ssa construction */
26 ['C'] = 0, /* copy elimination */
27 ['F'] = 0, /* constant folding */
28 ['A'] = 0, /* abi lowering */
29 ['I'] = 0, /* instruction selection */
30 ['L'] = 0, /* liveness */
31 ['S'] = 0, /* spilling */
32 ['R'] = 0, /* reg. allocation */
35 static FILE *outf;
36 static int dbg;
38 static void
39 data(Dat *d)
41 if (dbg)
42 return;
43 if (d->type == DEnd) {
44 fputs("/* end data */\n\n", outf);
45 freeall();
47 gasemitdat(d, outf);
50 static void
51 func(Fn *fn)
53 uint n;
55 if (dbg)
56 fprintf(stderr, "**** Function %s ****", fn->name);
57 if (debug['P']) {
58 fprintf(stderr, "\n> After parsing:\n");
59 printfn(fn, stderr);
61 fillrpo(fn);
62 fillpreds(fn);
63 filluse(fn);
64 memopt(fn);
65 filluse(fn);
66 ssa(fn);
67 filluse(fn);
68 ssacheck(fn);
69 fillalias(fn);
70 loadopt(fn);
71 filluse(fn);
72 ssacheck(fn);
73 copy(fn);
74 filluse(fn);
75 fold(fn);
76 T.abi(fn);
77 fillpreds(fn);
78 filluse(fn);
79 T.isel(fn);
80 fillrpo(fn);
81 filllive(fn);
82 fillloop(fn);
83 fillcost(fn);
84 spill(fn);
85 rega(fn);
86 fillrpo(fn);
87 simpljmp(fn);
88 fillpreds(fn);
89 fillrpo(fn);
90 assert(fn->rpo[0] == fn->start);
91 for (n=0;; n++)
92 if (n == fn->nblk-1) {
93 fn->rpo[n]->link = 0;
94 break;
95 } else
96 fn->rpo[n]->link = fn->rpo[n+1];
97 if (!dbg) {
98 T.emitfn(fn, outf);
99 gasemitfntail(fn->name, outf);
100 fprintf(outf, "/* end function %s */\n\n", fn->name);
101 } else
102 fprintf(stderr, "\n");
103 freeall();
107 main(int ac, char *av[])
109 struct TMap *tm;
110 FILE *inf, *hf;
111 char *f, *sep;
112 int c, asmmode;
114 asmmode = Defasm;
115 T = Deftgt;
116 outf = stdout;
117 while ((c = getopt(ac, av, "hd:o:G:t:")) != -1)
118 switch (c) {
119 case 'd':
120 for (; *optarg; optarg++)
121 if (isalpha(*optarg)) {
122 debug[toupper(*optarg)] = 1;
123 dbg = 1;
125 break;
126 case 'o':
127 if (strcmp(optarg, "-") != 0) {
128 outf = fopen(optarg, "w");
129 if (!outf) {
130 fprintf(stderr, "cannot open '%s'\n", optarg);
131 exit(1);
134 break;
135 case 't':
136 for (tm=tmap;; tm++) {
137 if (!tm->name) {
138 fprintf(stderr, "unknown target '%s'\n", optarg);
139 exit(1);
141 if (strcmp(optarg, tm->name) == 0) {
142 T = *tm->T;
143 break;
146 break;
147 case 'G':
148 if (strcmp(optarg, "e") == 0)
149 asmmode = Gaself;
150 else if (strcmp(optarg, "m") == 0)
151 asmmode = Gasmacho;
152 else {
153 fprintf(stderr, "unknown gas flavor '%s'\n", optarg);
154 exit(1);
156 break;
157 case 'h':
158 default:
159 hf = c != 'h' ? stderr : stdout;
160 fprintf(hf, "%s [OPTIONS] {file.ssa, -}\n", av[0]);
161 fprintf(hf, "\t%-11s prints this help\n", "-h");
162 fprintf(hf, "\t%-11s output to file\n", "-o file");
163 fprintf(hf, "\t%-11s generate for a target among:\n", "-t <target>");
164 fprintf(hf, "\t%-11s ", "");
165 for (tm=tmap, sep=""; tm->name; tm++, sep=", ")
166 fprintf(hf, "%s%s", sep, tm->name);
167 fprintf(hf, "\n");
168 fprintf(hf, "\t%-11s generate gas (e) or osx (m) asm\n", "-G {e,m}");
169 fprintf(hf, "\t%-11s dump debug information\n", "-d <flags>");
170 exit(c != 'h');
173 gasinit(asmmode);
175 do {
176 f = av[optind];
177 if (!f || strcmp(f, "-") == 0) {
178 inf = stdin;
179 f = "-";
180 } else {
181 inf = fopen(f, "r");
182 if (!inf) {
183 fprintf(stderr, "cannot open '%s'\n", f);
184 exit(1);
187 parse(inf, f, data, func);
188 } while (++optind < ac);
190 if (!dbg) {
191 gasemitfin(outf);
192 if (asmmode == Gaself)
193 fprintf(outf, ".section .note.GNU-stack,\"\",@progbits\n");
196 exit(0);