documentation update
[qbe.git] / main.c
blob033ed9cce37742c23275cbf830ebbfc40c46831d
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;
11 static struct TMap {
12 char *name;
13 Target *T;
14 } tmap[] = {
15 { "amd64_sysv", &T_amd64_sysv },
16 { "arm64", &T_arm64 },
17 { 0, 0 }
20 enum Asm {
21 Gasmacho,
22 Gaself,
25 char debug['Z'+1] = {
26 ['P'] = 0, /* parsing */
27 ['A'] = 0, /* abi lowering */
28 ['I'] = 0, /* instruction selection */
29 ['L'] = 0, /* liveness */
30 ['M'] = 0, /* memory optimization */
31 ['N'] = 0, /* ssa construction */
32 ['C'] = 0, /* copy elimination */
33 ['F'] = 0, /* constant folding */
34 ['S'] = 0, /* spilling */
35 ['R'] = 0, /* reg. allocation */
38 static FILE *outf;
39 static int dbg;
41 static void
42 data(Dat *d)
44 if (dbg)
45 return;
46 if (d->type == DEnd) {
47 fputs("/* end data */\n\n", outf);
48 freeall();
50 gasemitdat(d, outf);
53 static void
54 func(Fn *fn)
56 uint n;
58 if (dbg)
59 fprintf(stderr, "**** Function %s ****", fn->name);
60 if (debug['P']) {
61 fprintf(stderr, "\n> After parsing:\n");
62 printfn(fn, stderr);
64 fillrpo(fn);
65 fillpreds(fn);
66 filluse(fn);
67 memopt(fn);
68 ssa(fn);
69 filluse(fn);
70 ssacheck(fn);
71 fillloop(fn);
72 fillalias(fn);
73 loadopt(fn);
74 filluse(fn);
75 ssacheck(fn);
76 copy(fn);
77 filluse(fn);
78 fold(fn);
79 T.abi(fn);
80 fillpreds(fn);
81 filluse(fn);
82 T.isel(fn);
83 fillrpo(fn);
84 filllive(fn);
85 fillcost(fn);
86 spill(fn);
87 rega(fn);
88 fillrpo(fn);
89 simpljmp(fn);
90 fillpreds(fn);
91 fillrpo(fn);
92 assert(fn->rpo[0] == fn->start);
93 for (n=0;; n++)
94 if (n == fn->nblk-1) {
95 fn->rpo[n]->link = 0;
96 break;
97 } else
98 fn->rpo[n]->link = fn->rpo[n+1];
99 if (!dbg) {
100 T.emitfn(fn, outf);
101 fprintf(outf, "/* end function %s */\n\n", fn->name);
102 } else
103 fprintf(stderr, "\n");
104 freeall();
108 main(int ac, char *av[])
110 struct TMap *tm;
111 FILE *inf, *hf;
112 char *f, *sep;
113 int c, asm;
115 asm = Defasm;
116 T = Deftgt;
117 outf = stdout;
118 while ((c = getopt(ac, av, "hd:o:G:t:")) != -1)
119 switch (c) {
120 case 'd':
121 for (; *optarg; optarg++)
122 if (isalpha(*optarg)) {
123 debug[toupper(*optarg)] = 1;
124 dbg = 1;
126 break;
127 case 'o':
128 if (strcmp(optarg, "-") != 0)
129 outf = fopen(optarg, "w");
130 break;
131 case 't':
132 for (tm=tmap;; tm++) {
133 if (!tm->name) {
134 fprintf(stderr, "unknown target '%s'\n", optarg);
135 exit(1);
137 if (strcmp(optarg, tm->name) == 0) {
138 T = *tm->T;
139 break;
142 break;
143 case 'G':
144 if (strcmp(optarg, "e") == 0)
145 asm = Gaself;
146 else if (strcmp(optarg, "m") == 0)
147 asm = Gasmacho;
148 else {
149 fprintf(stderr, "unknown gas flavor '%s'\n", optarg);
150 exit(1);
152 break;
153 case 'h':
154 default:
155 hf = c != 'h' ? stderr : stdout;
156 fprintf(hf, "%s [OPTIONS] {file.ssa, -}\n", av[0]);
157 fprintf(hf, "\t%-11s prints this help\n", "-h");
158 fprintf(hf, "\t%-11s output to file\n", "-o file");
159 fprintf(hf, "\t%-11s generate for a target among:\n", "-t <target>");
160 fprintf(hf, "\t%-11s ", "");
161 for (tm=tmap, sep=""; tm->name; tm++, sep=", ")
162 fprintf(hf, "%s%s", sep, tm->name);
163 fprintf(hf, "\n");
164 fprintf(hf, "\t%-11s generate gas (e) or osx (m) asm\n", "-G {e,m}");
165 fprintf(hf, "\t%-11s dump debug information\n", "-d <flags>");
166 exit(c != 'h');
169 switch (asm) {
170 case Gaself:
171 gasloc = ".L";
172 gassym = "";
173 break;
174 case Gasmacho:
175 gasloc = "L";
176 gassym = "_";
177 break;
180 do {
181 f = av[optind];
182 if (!f || strcmp(f, "-") == 0) {
183 inf = stdin;
184 f = "-";
185 } else {
186 inf = fopen(f, "r");
187 if (!inf) {
188 fprintf(stderr, "cannot open '%s'\n", f);
189 exit(1);
192 parse(inf, f, data, func);
193 } while (++optind < ac);
195 if (!dbg)
196 gasemitfin(outf);
198 exit(0);