cheaper mul by small constants on amd64
[qbe.git] / main.c
blob5ecb4d0f7fabcffb6b6a14ef5eae1b25c68213f0
1 #include "all.h"
2 #include "config.h"
3 #include <ctype.h>
4 #include <getopt.h>
6 Target T;
8 char debug['Z'+1] = {
9 ['P'] = 0, /* parsing */
10 ['M'] = 0, /* memory optimization */
11 ['N'] = 0, /* ssa construction */
12 ['C'] = 0, /* copy elimination */
13 ['F'] = 0, /* constant folding */
14 ['A'] = 0, /* abi lowering */
15 ['I'] = 0, /* instruction selection */
16 ['L'] = 0, /* liveness */
17 ['S'] = 0, /* spilling */
18 ['R'] = 0, /* reg. allocation */
21 extern Target T_amd64_sysv;
22 extern Target T_amd64_apple;
23 extern Target T_arm64;
24 extern Target T_arm64_apple;
25 extern Target T_rv64;
27 static Target *tlist[] = {
28 &T_amd64_sysv,
29 &T_amd64_apple,
30 &T_arm64,
31 &T_arm64_apple,
32 &T_rv64,
35 static FILE *outf;
36 static int dbg;
38 static void
39 data(Dat *d)
41 if (dbg)
42 return;
43 emitdat(d, outf);
44 if (d->type == DEnd) {
45 fputs("/* end data */\n\n", outf);
46 freeall();
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 T.abi0(fn);
62 fillrpo(fn);
63 fillpreds(fn);
64 filluse(fn);
65 promote(fn);
66 filluse(fn);
67 ssa(fn);
68 filluse(fn);
69 ssacheck(fn);
70 fillalias(fn);
71 loadopt(fn);
72 filluse(fn);
73 fillalias(fn);
74 coalesce(fn);
75 filluse(fn);
76 ssacheck(fn);
77 copy(fn);
78 filluse(fn);
79 fold(fn);
80 T.abi1(fn);
81 simpl(fn);
82 fillpreds(fn);
83 filluse(fn);
84 T.isel(fn);
85 fillrpo(fn);
86 filllive(fn);
87 fillloop(fn);
88 fillcost(fn);
89 spill(fn);
90 rega(fn);
91 fillrpo(fn);
92 simpljmp(fn);
93 fillpreds(fn);
94 fillrpo(fn);
95 assert(fn->rpo[0] == fn->start);
96 for (n=0;; n++)
97 if (n == fn->nblk-1) {
98 fn->rpo[n]->link = 0;
99 break;
100 } else
101 fn->rpo[n]->link = fn->rpo[n+1];
102 if (!dbg) {
103 T.emitfn(fn, outf);
104 fprintf(outf, "/* end function %s */\n\n", fn->name);
105 } else
106 fprintf(stderr, "\n");
107 freeall();
110 static void
111 dbgfile(char *fn)
113 emitdbgfile(fn, outf);
117 main(int ac, char *av[])
119 Target **t;
120 FILE *inf, *hf;
121 char *f, *sep;
122 int c;
124 T = Deftgt;
125 outf = stdout;
126 while ((c = getopt(ac, av, "hd:o:t:")) != -1)
127 switch (c) {
128 case 'd':
129 for (; *optarg; optarg++)
130 if (isalpha(*optarg)) {
131 debug[toupper(*optarg)] = 1;
132 dbg = 1;
134 break;
135 case 'o':
136 if (strcmp(optarg, "-") != 0) {
137 outf = fopen(optarg, "w");
138 if (!outf) {
139 fprintf(stderr, "cannot open '%s'\n", optarg);
140 exit(1);
143 break;
144 case 't':
145 if (strcmp(optarg, "?") == 0) {
146 puts(T.name);
147 exit(0);
149 for (t=tlist;; t++) {
150 if (!*t) {
151 fprintf(stderr, "unknown target '%s'\n", optarg);
152 exit(1);
154 if (strcmp(optarg, (*t)->name) == 0) {
155 T = **t;
156 break;
159 break;
160 case 'h':
161 default:
162 hf = c != 'h' ? stderr : stdout;
163 fprintf(hf, "%s [OPTIONS] {file.ssa, -}\n", av[0]);
164 fprintf(hf, "\t%-11s prints this help\n", "-h");
165 fprintf(hf, "\t%-11s output to file\n", "-o file");
166 fprintf(hf, "\t%-11s generate for a target among:\n", "-t <target>");
167 fprintf(hf, "\t%-11s ", "");
168 for (t=tlist, sep=""; *t; t++, sep=", ") {
169 fprintf(hf, "%s%s", sep, (*t)->name);
170 if (*t == &Deftgt)
171 fputs(" (default)", hf);
173 fprintf(hf, "\n");
174 fprintf(hf, "\t%-11s dump debug information\n", "-d <flags>");
175 exit(c != 'h');
178 do {
179 f = av[optind];
180 if (!f || strcmp(f, "-") == 0) {
181 inf = stdin;
182 f = "-";
183 } else {
184 inf = fopen(f, "r");
185 if (!inf) {
186 fprintf(stderr, "cannot open '%s'\n", f);
187 exit(1);
190 parse(inf, f, dbgfile, data, func);
191 fclose(inf);
192 } while (++optind < ac);
194 if (!dbg)
195 T.emitfin(outf);
197 exit(0);