ACSE 2.0.3
Advanced Compiler System for Education
Loading...
Searching...
No Matches
acse.c
Go to the documentation of this file.
1
3
4#include <stdlib.h>
5#include <string.h>
6#include <getopt.h>
7#include <stdbool.h>
8#include <stdio.h>
9#include <unistd.h>
10#include "list.h"
11#include "target_info.h"
12#include "program.h"
13#include "target_asm_print.h"
14#include "target_transform.h"
15#include "cfg.h"
16#include "reg_alloc.h"
17#include "parser.h"
18#include "errors.h"
19
20
21char *getLogFileName(const char *logType, const char *fn)
22{
23 char *basename = strdup(fn);
24 if (!basename)
25 fatalError("out of memory");
26
27 int lastDot = -1;
28 for (int i = 0; basename[i] != '\0'; i++) {
29 if (basename[i] == '.')
30 lastDot = i;
31 }
32 if (lastDot >= 0)
33 basename[lastDot] = '\0';
34
35 size_t nameLen = strlen(basename) + strlen(logType) + (size_t)8;
36 char *outfn = calloc(nameLen, sizeof(char));
37 if (!outfn)
38 fatalError("out of memory");
39
40 snprintf(outfn, nameLen, "%s_%s.log", basename, logType);
41 free(basename);
42 return outfn;
43}
44
45
46void banner(void)
47{
48 printf("ACSE %s compiler, (c) 2008-24 Politecnico di Milano\n", TARGET_NAME);
49}
50
51void version(void)
52{
53 puts("ACSE toolchain version 2.0.2");
54 printf("Target: %s\n", TARGET_NAME);
55}
56
57void usage(const char *name)
58{
59 banner();
60 printf("usage: %s [options] input\n\n", name);
61 puts("Options:");
62 puts(" -o ASMFILE Name the output ASMFILE (default output.asm)");
63 puts(" -v, --version Display version number");
64 puts(" -h, --help Displays available options");
65}
66
67int main(int argc, char *argv[])
68{
69 char *name = argv[0];
70 int ch, res = 0;
71#ifndef NDEBUG
72 char *logFn;
73 FILE *logFp;
74#endif
75 static const struct option options[] = {
76 { "help", no_argument, NULL, 'h'},
77 {"version", no_argument, NULL, 'v'},
78 };
79
80 char *outputFn = "output.asm";
81
82 while ((ch = getopt_long(argc, argv, "ho:v", options, NULL)) != -1) {
83 switch (ch) {
84 case 'o':
85 outputFn = optarg;
86 break;
87 case 'h':
88 usage(name);
89 return 1;
90 case 'v':
91 version();
92 return 1;
93 default:
94 usage(name);
95 return 1;
96 }
97 }
98 argc -= optind;
99 argv += optind;
100
101 if (argc < 1) {
102 usage(name);
103 return 1;
104 } else if (argc > 1) {
105 emitError(nullFileLocation, "cannot assemble more than one file");
106 return 1;
107 }
108
109#ifndef NDEBUG
110 banner();
111 printf("\n");
112#endif
113
114 res = 1;
115
116#ifndef NDEBUG
117 fprintf(stderr, "Parsing the input program\n");
118 fprintf(stderr, " -> Reading input from \"%s\"\n", argv[0]);
119#endif
120 t_program *program = parseProgram(argv[0]);
121 if (!program)
122 goto fail;
123#ifndef NDEBUG
124 logFn = getLogFileName("frontend", outputFn);
125 logFp = fopen(logFn, "w");
126 if (logFp) {
127 fprintf(stderr, " -> Writing the output of parsing to \"%s\"\n", logFn);
128 programDump(program, logFp);
129 fclose(logFp);
130 }
131 free(logFn);
132#endif
133
134#ifndef NDEBUG
135 fprintf(stderr, "Lowering of pseudo-instructions to machine instructions.\n");
136#endif
138
139#ifndef NDEBUG
140 fprintf(stderr, "Performing register allocation.\n");
141 logFn = getLogFileName("controlFlow", outputFn);
142 logFp = fopen(logFn, "w");
143 if (logFp) {
144 fprintf(stderr, " -> Writing the control flow graph to \"%s\"\n", logFn);
145 t_cfg *cfg = programToCFG(program);
147 cfgDump(cfg, logFp, true);
148 deleteCFG(cfg);
149 fclose(logFp);
150 }
151 free(logFn);
152#endif
153 t_regAllocator *regAlloc = newRegAllocator(program);
154 regallocRun(regAlloc);
155#ifndef NDEBUG
156 logFn = getLogFileName("regAlloc", outputFn);
157 logFp = fopen(logFn, "w");
158 if (logFp) {
159 fprintf(stderr, " -> Writing the register bindings to \"%s\"\n", logFn);
160 regallocDump(regAlloc, logFp);
161 fclose(logFp);
162 }
163 free(logFn);
164#endif
165 deleteRegAllocator(regAlloc);
166
167#ifndef NDEBUG
168 fprintf(stderr, "Writing the assembly file.\n");
169 fprintf(stderr, " -> Output file name: \"%s\"\n", outputFn);
170 fprintf(stderr, " -> Code segment size: %d instructions\n",
171 listLength(program->instructions));
172 fprintf(stderr, " -> Data segment size: %d elements\n",
173 listLength(program->symbols));
174 fprintf(stderr, " -> Number of labels: %d\n", listLength(program->labels));
175#endif
176 bool ok = writeAssembly(program, outputFn);
177 if (!ok) {
178 emitError(nullFileLocation, "could not write output file");
179 goto fail;
180 }
181
182 res = 0;
183fail:
184 deleteProgram(program);
185#ifndef NDEBUG
186 fprintf(stderr, "Finished.\n");
187#endif
188 return res;
189}
int main(int argc, char *argv[])
Definition acse.c:67
void usage(const char *name)
Definition acse.c:57
void banner(void)
Definition acse.c:46
char * getLogFileName(const char *logType, const char *fn)
Definition acse.c:21
void version(void)
Definition acse.c:51
Control Flow Graph generation and related analyses.
Error logging utilities.
bool writeAssembly(t_program *program, const char *fn)
void cfgComputeLiveness(t_cfg *graph)
Definition cfg.c:639
void deleteCFG(t_cfg *graph)
Definition cfg.c:235
void cfgDump(t_cfg *graph, FILE *fout, bool verbose)
Definition cfg.c:775
t_cfg * programToCFG(t_program *program)
Definition cfg.c:370
Definition cfg.h:71
void emitError(t_fileLocation loc, const char *fmt,...)
Definition errors.c:23
void fatalError(const char *format,...)
Definition errors.c:32
int listLength(t_listNode *list)
Definition list.c:214
t_program * parseProgram(char *fn)
t_listNode * instructions
List of instructions.
Definition program.h:100
t_listNode * labels
List of all labels.
Definition program.h:99
t_listNode * symbols
Symbol table.
Definition program.h:101
void programDump(t_program *program, FILE *fout)
Definition program.c:493
void deleteProgram(t_program *program)
Definition program.c:162
t_regAllocator * newRegAllocator(t_program *program)
Definition reg_alloc.c:384
void regallocDump(t_regAllocator *RA, FILE *fout)
Definition reg_alloc.c:935
void deleteRegAllocator(t_regAllocator *RA)
Definition reg_alloc.c:434
void regallocRun(t_regAllocator *regalloc)
Definition reg_alloc.c:839
void doTargetSpecificTransformations(t_program *program)
#define TARGET_NAME
Name of the target architecture.
Definition target_info.h:27
A double-linked list.
Header file associated to parser.y.
Program object definition and management.
Structure encapsulating the state of the register allocator.
Definition reg_alloc.c:49
Register allocation pass.
Generation of the output assembly program.
Properties of the target machine.
Transformation pass for lowering target machine details.