1#include "all.h"
2#include "config.h"
3#include <ctype.h>
4#include <getopt.h>
5
6Target T;
7
8char 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 */
19};
20
21extern Target T_amd64_sysv;
22extern Target T_arm64;
23extern Target T_rv64;
24
25static Target *tlist[] = {
26 &T_amd64_sysv,
27 &T_arm64,
28 &T_rv64,
29 0
30};
31static FILE *outf;
32static int dbg;
33
34static void
35data(Dat *d)
36{
37 if (dbg)
38 return;
39 if (d->type == DEnd) {
40 fputs("/* end data */\n\n", outf);
41 freeall();
42 }
43 gasemitdat(d, outf);
44}
45
46static void
47func(Fn *fn)
48{
49 uint n;
50
51 if (dbg)
52 fprintf(stderr, "**** Function %s ****", fn->name);
53 if (debug['P']) {
54 fprintf(stderr, "\n> After parsing:\n");
55 printfn(fn, stderr);
56 }
57 fillrpo(fn);
58 fillpreds(fn);
59 filluse(fn);
60 memopt(fn);
61 filluse(fn);
62 ssa(fn);
63 filluse(fn);
64 ssacheck(fn);
65 fillalias(fn);
66 loadopt(fn);
67 filluse(fn);
68 ssacheck(fn);
69 copy(fn);
70 filluse(fn);
71 fold(fn);
72 T.abi(fn);
73 fillpreds(fn);
74 filluse(fn);
75 T.isel(fn);
76 fillrpo(fn);
77 filllive(fn);
78 fillloop(fn);
79 fillcost(fn);
80 spill(fn);
81 rega(fn);
82 fillrpo(fn);
83 simpljmp(fn);
84 fillpreds(fn);
85 fillrpo(fn);
86 assert(fn->rpo[0] == fn->start);
87 for (n=0;; n++)
88 if (n == fn->nblk-1) {
89 fn->rpo[n]->link = 0;
90 break;
91 } else
92 fn->rpo[n]->link = fn->rpo[n+1];
93 if (!dbg) {
94 T.emitfn(fn, outf);
95 gasemitfntail(fn->name, outf);
96 fprintf(outf, "/* end function %s */\n\n", fn->name);
97 } else
98 fprintf(stderr, "\n");
99 freeall();
100}
101
102int
103main(int ac, char *av[])
104{
105 Target **t;
106 FILE *inf, *hf;
107 char *f, *sep;
108 int c, asmmode;
109
110 asmmode = Defasm;
111 T = Deftgt;
112 outf = stdout;
113 while ((c = getopt(ac, av, "hd:o:G:t:")) != -1)
114 switch (c) {
115 case 'd':
116 for (; *optarg; optarg++)
117 if (isalpha(*optarg)) {
118 debug[toupper(*optarg)] = 1;
119 dbg = 1;
120 }
121 break;
122 case 'o':
123 if (strcmp(optarg, "-") != 0) {
124 outf = fopen(optarg, "w");
125 if (!outf) {
126 fprintf(stderr, "cannot open '%s'\n", optarg);
127 exit(1);
128 }
129 }
130 break;
131 case 't':
132 if (strcmp(optarg, "?") == 0) {
133 puts(T.name);
134 exit(0);
135 }
136 for (t=tlist;; t++) {
137 if (!*t) {
138 fprintf(stderr, "unknown target '%s'\n", optarg);
139 exit(1);
140 }
141 if (strcmp(optarg, (*t)->name) == 0) {
142 T = **t;
143 break;
144 }
145 }
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);
155 }
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 (t=tlist, sep=""; *t; t++, sep=", ")
166 fprintf(hf, "%s%s", sep, (*t)->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');
171 }
172
173 gasinit(asmmode);
174
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);
185 }
186 }
187 parse(inf, f, data, func);
188 fclose(inf);
189 } while (++optind < ac);
190
191 if (!dbg)
192 gasemitfin(outf);
193
194 exit(0);
195}
196