@@ -17,7 +17,7 @@ public class Simple {
1717 static final int DUMP_AFTER_OPTO = 1 <<1 ;
1818 static final int DUMP_AFTER_TYPE_CHECK = 1 <<2 ;
1919 static final int DUMP_AFTER_LOOP_TREE = 1 <<3 ;
20- static final int DUMP_AFTER_INSTR_SELECT = 1 <<4 ;
20+ static final int DUMP_AFTER_SELECT = 1 <<4 ;
2121 static final int DUMP_AFTER_GCM = 1 <<5 ;
2222 static final int DUMP_AFTER_LOCAL_SCHED = 1 <<6 ;
2323 static final int DUMP_AFTER_REG_ALLOC = 1 <<7 ;
@@ -38,44 +38,42 @@ public class Simple {
3838 static void usage () {
3939 System .out .println (
4040"""
41- simple <input-file> [options] [--eval|--run ...]
41+ simple [options] <input-file> ...args...
4242Options:
43- --dump - dump final intermediate representation
44- --dump-after-parse - dump intermediate representation after parse
45- --dump-after-opto - dump intermediate representation after opto pass
46- --dump-after-type-check - dump intermediate representation after type check pass
47- --dump-after-instr- select - dump intermediate representation after instrution selection pass
48- --dump-after-gcm - dump intermediate representation after GCM pass
49- --dump-after-local-sched - dump intermediate representation after local scheduling pass
50- --dump-after-reg-alloc - dump intermediate representation after register allocation pass
51- --dump-after-encode - dump intermediate representation after encoding pass
52- --dump-after-all - dump intermediate representation after all passes
53- --dot - dump grapical representation of intermediate code into *.dot file(s)
54- -S - dump generated assembler code
55- --eval ... - evaluate the compiled code in emulator
56- --run ... - run the compiled code natively
57- --dump-size - print the size of generated code
58- --dump-time - print compilation and execution times
59- --cpu <cpu-name> - use specific CPU (x86_64_v2, riscv, arm)
60- --abi <abi-name> - use speific ABI variant (SystemV)
61- --target - print native CPU and ABI
43+ --dump - dump final intermediate representation
44+ --dump-after-parse - dump intermediate representation after parse
45+ --dump-after-opto - dump intermediate representation after opto pass
46+ --dump-after-type-check - dump intermediate representation after type check pass
47+ --dump-after-select - dump intermediate representation after instrution selection pass
48+ --dump-after-gcm - dump intermediate representation after GCM pass
49+ --dump-after-local-sched - dump intermediate representation after local scheduling pass
50+ --dump-after-reg-alloc - dump intermediate representation after register allocation pass
51+ --dump-after-encode - dump intermediate representation after encoding pass
52+ --dump-after-all - dump intermediate representation after all passes
53+ --dot - dump grapical representation of intermediate code into *.dot file(s)
54+ -S - dump generated assembler code
55+ --eval - evaluate the compiled code in emulator
56+ --run - run the compiled code natively; this is the default
57+ --dump-size - print the size of generated code
58+ --dump-time - print compilation and execution times
59+ --cpu <cpu-name> - use specific CPU (x86_64_v2, riscv, arm)
60+ --abi <abi-name> - use speific ABI variant (SystemV)
61+ --target - print native CPU and ABI
6262 --version
6363 --help
6464"""
6565);
6666 System .exit (0 );
6767 }
6868
69- static void bad_usage () {
70- System .err .println ("ERROR: Invalid usage (use --help)" );
69+ static void bad_usage () { bad ("Invalid usage (use --help)" ); }
70+ static RuntimeException bad (String err ) {
71+ System .err .println ("ERROR: " +err );
7172 System .exit (1 );
73+ return new RuntimeException (err );
7274 }
7375
7476 static void target () {
75- if (system_cpu == null || system_abi == null ) {
76- System .err .println ("ERROR: Unknown target" );
77- System .exit (1 );
78- }
7977 System .out .print (system_cpu );
8078 System .out .print ("-" );
8179 System .out .println (system_abi );
@@ -86,38 +84,35 @@ static void dump(CodeGen code, int dump, int pass) {
8684 if ((dump & pass ) != 0 ) {
8785 if ((dump & DUMP_DOT ) != 0 ) {
8886 String fn = switch (pass ) {
89- case DUMP_AFTER_PARSE -> "01-parse.dot" ;
90- case DUMP_AFTER_OPTO -> "02-opto.dot" ;
91- case DUMP_AFTER_TYPE_CHECK -> "03-type_check.dot" ;
92- case DUMP_AFTER_LOOP_TREE -> "04-loop_tree.dot" ;
93- case DUMP_AFTER_INSTR_SELECT -> "05-instr_select.dot" ;
94- case DUMP_AFTER_GCM -> "06-gcm.dot" ;
95- case DUMP_AFTER_LOCAL_SCHED -> "07-local_sched.dot" ;
96- case DUMP_AFTER_REG_ALLOC -> "08-reg_allos.dot" ;
97- case DUMP_AFTER_ENCODE -> "09-local_sched.dot" ;
98- case DUMP_FINAL -> "10-final.dot" ;
99- default -> throw Utils .TODO ();
87+ case DUMP_AFTER_PARSE -> "01-parse.dot" ;
88+ case DUMP_AFTER_OPTO -> "02-opto.dot" ;
89+ case DUMP_AFTER_TYPE_CHECK -> "03-type_check.dot" ;
90+ case DUMP_AFTER_LOOP_TREE -> "04-loop_tree.dot" ;
91+ case DUMP_AFTER_SELECT -> "05-instr_select.dot" ;
92+ case DUMP_AFTER_GCM -> "06-gcm.dot" ;
93+ case DUMP_AFTER_LOCAL_SCHED -> "07-local_sched.dot" ;
94+ case DUMP_AFTER_REG_ALLOC -> "08-reg_allos.dot" ;
95+ case DUMP_AFTER_ENCODE -> "09-local_sched.dot" ;
96+ case DUMP_FINAL -> "10-final.dot" ;
97+ default -> throw Utils .TODO ();
10098 };
10199
102100 try {
103101 Files .writeString (Path .of (fn ),
104- new GraphVisualizer ().generateDotOutput (code ._stop , null , null ));
105- } catch (IOException e ) {
106- System .err .println ("ERROR: Cannot write DOT file" );
107- System .exit (1 );
108- }
102+ new GraphVisualizer ().generateDotOutput (code ._stop , null , null ));
103+ } catch (IOException e ) { throw bad ("Cannot write DOT file" ); }
109104 } else {
110105 if ((dump & DUMP_PASS_NAME ) != 0 ) {
111106 System .err .println (switch (pass ) {
112107 case DUMP_AFTER_PARSE -> "After Parse:" ;
113108 case DUMP_AFTER_OPTO -> "After OPTO:" ;
114109 case DUMP_AFTER_TYPE_CHECK -> "After Type Check:" ;
115110 case DUMP_AFTER_LOOP_TREE -> "After Loop Tree:" ;
116- case DUMP_AFTER_INSTR_SELECT -> "After Instruction Selection:" ;
111+ case DUMP_AFTER_SELECT -> "After Code Selection:" ;
117112 case DUMP_AFTER_GCM -> "After GCM:" ;
118113 case DUMP_AFTER_LOCAL_SCHED -> "After Local Scheduling:" ;
119114 case DUMP_AFTER_REG_ALLOC -> "After Register Allocation:" ;
120- case DUMP_AFTER_ENCODE -> "After Instruction Encoding:" ;
115+ case DUMP_AFTER_ENCODE -> "After Encoding:" ;
121116 case DUMP_FINAL -> "Final:" ;
122117 default -> throw Utils .TODO ();
123118 });
@@ -132,24 +127,24 @@ static void print_compilation_times(CodeGen code) {
132127 double t , total = 0 ;
133128
134129 total += t = code ._tParse / 1e3 ;
135- System .out .println ( String . format ( "Parsing Time: %.3f sec" , t ) );
130+ System .out .printf ( "Parsing Time: %.3f sec%n " , t );
136131 total += t = code ._tOpto / 1e3 ;
137- System .out .println ( String . format ( "Optimization Time: %.3f sec" , t ) );
132+ System .out .printf ( "Optimization Time: %.3f sec%n " , t );
138133 total += t = code ._tTypeCheck / 1e3 ;
139- System .out .println ( String . format ( "Type Checking Time: %.3f sec" , t ) );
134+ System .out .printf ( "Type Checking Time: %.3f sec%n " , t );
140135 total += t = code ._tLoopTree / 1e3 ;
141- System .out .println ( String . format ( "Loop Tree Time: %.3f sec" , t ) );
136+ System .out .printf ( "Loop Tree Time: %.3f sec%n " , t );
142137 total += t = code ._tInsSel / 1e3 ;
143- System .out .println ( String . format ( "Instruction Selection Time: %.3f sec" , t ) );
138+ System .out .printf ( "Code Selection Time: %.3f sec%n " , t );
144139 total += t = code ._tGCM / 1e3 ;
145- System .out .println ( String . format ( "GCM Time: %.3f sec" , t ) );
140+ System .out .printf ( "GCM Time: %.3f sec%n " , t );
146141 total += t = code ._tLocal / 1e3 ;
147- System .out .println ( String . format ( "Local Scheduling Time: %.3f sec" , t ) );
142+ System .out .printf ( "Local Scheduling Time: %.3f sec%n " , t );
148143 total += t = code ._tRegAlloc / 1e3 ;
149- System .out .println ( String . format ( "Register Allocation Time: %.3f sec" , t ) );
144+ System .out .printf ( "Register Allocation Time: %.3f sec%n " , t );
150145 total += t = code ._tEncode / 1e3 ;
151- System .out .println ( String . format ( "Instruction Encoding Time: %.3f sec" , t ) );
152- System .out .println ( String . format ( "TOTAL COMPILATION TIME: %.3f sec" , total ) );
146+ System .out .printf ( " Encoding Time: %.3f sec%n " , t );
147+ System .out .printf ( "TOTAL COMPILATION TIME: %.3f sec%n " , total );
153148 }
154149
155150 static String getInput () {
@@ -159,9 +154,8 @@ static String getInput() {
159154
160155 public static void main (String [] args ) throws Exception {
161156 String input_filename = null ;
162- boolean use_stdin = false ;
163157 boolean do_eval = false ;
164- boolean do_run = false ;
158+ boolean do_run = true ;
165159 boolean do_codegen = false ;
166160 boolean do_print_size = false ;
167161 boolean do_print_time = false ;
@@ -176,73 +170,61 @@ public static void main(String[] args) throws Exception {
176170 system_abi = "SystemV" ;
177171
178172 // Parse command line
179- loop : for ( int i = 0 ; i < args .length ; i ++) {
173+ int i ; for ( i = 0 ; i < args .length ; i ++ ) {
180174 String arg = args [i ];
181- if (arg .charAt (0 ) == '-' ) {
182- switch (arg ) {
183- case "-" : use_stdin = true ; break ;
184- case "--dump" : dump |= DUMP_FINAL ; break ;
185- case "--dump-after-parse" : dump |= DUMP_AFTER_PARSE ; break ;
186- case "--dump-after-opto" : dump |= DUMP_AFTER_OPTO ; break ;
187- case "--dump-after-type-check" : dump |= DUMP_AFTER_TYPE_CHECK ; break ;
188- case "--dump-after-loop-tree" : dump |= DUMP_AFTER_LOOP_TREE ; break ;
189- case "--dump-after-instr-select" : dump |= DUMP_AFTER_INSTR_SELECT ; break ;
190- case "--dump-after-gcm" : dump |= DUMP_AFTER_GCM ; break ;
191- case "--dump-after-local-sched" : dump |= DUMP_AFTER_LOCAL_SCHED ; break ;
192- case "--dump-after-reg-alloc" : dump |= DUMP_AFTER_REG_ALLOC ; break ;
193- case "--dump-after-encode" : dump |= DUMP_AFTER_ENCODE ; break ;
194- case "--dump-after-all" : dump |= DUMP_AFTER_ALL ; break ;
195- case "--dot" : dump |= DUMP_DOT ; break ;
196- case "-S" : dump |= DUMP_DISASSEMBLE ; break ;
197- case "--eval" : do_eval = true ; first_arg = i + 1 ; break loop ;
198- case "--run" : do_run = true ; first_arg = i + 1 ; break loop ;
199- case "--dump-size" : do_print_size = true ; break ;
200- case "--dump-time" : do_print_time = true ; break ;
201- case "--cpu" : if (cpu != null
202- || i + 1 >= args .length
203- || args [i + 1 ].charAt (0 ) == '-' ) bad_usage ();
204- cpu = args [i + 1 ];
205- i ++;
206- break ;
207- case "--abi" : if (abi != null
208- || i + 1 >= args .length
209- || args [i + 1 ].charAt (0 ) == '-' ) bad_usage ();
210- abi = args [i + 1 ];
211- i ++;
212- break ;
213- case "--target" : target ();
214- case "--version" : throw Utils .TODO ();
215- case "--help" : usage ();
216- default : bad_usage ();
217- }
218- } else {
219- if (input_filename != null || use_stdin ) bad_usage ();
175+ if ( arg .charAt (0 ) != '-' ) {
220176 input_filename = arg ;
177+ break ;
221178 }
222- }
223179
224- if (input_filename == null && !use_stdin ) {
225- System .err .println ("ERROR: no input file' (use --help)" );
226- System .exit (1 );
180+ switch (arg ) {
181+ case "-" : input_filename ="" ; break ;
182+ case "--dump" : dump |= DUMP_FINAL ; break ;
183+ case "--dump-after-parse" : dump |= DUMP_AFTER_PARSE ; break ;
184+ case "--dump-after-opto" : dump |= DUMP_AFTER_OPTO ; break ;
185+ case "--dump-after-type-check" : dump |= DUMP_AFTER_TYPE_CHECK ; break ;
186+ case "--dump-after-loop-tree" : dump |= DUMP_AFTER_LOOP_TREE ; break ;
187+ case "--dump-after-select" : dump |= DUMP_AFTER_SELECT ; break ;
188+ case "--dump-after-gcm" : dump |= DUMP_AFTER_GCM ; break ;
189+ case "--dump-after-local-sched" : dump |= DUMP_AFTER_LOCAL_SCHED ; break ;
190+ case "--dump-after-reg-alloc" : dump |= DUMP_AFTER_REG_ALLOC ; break ;
191+ case "--dump-after-encode" : dump |= DUMP_AFTER_ENCODE ; break ;
192+ case "--dump-after-all" : dump |= DUMP_AFTER_ALL ; break ;
193+ case "--dot" : dump |= DUMP_DOT ; break ;
194+ case "-S" : dump |= DUMP_DISASSEMBLE ; break ;
195+ case "--eval" : do_eval = true ; do_run = false ; break ;
196+ case "--run" : do_run = true ; break ;
197+ case "--norun" : do_run = false ; break ;
198+ case "--dump-size" : do_print_size = true ; break ;
199+ case "--dump-time" : do_print_time = true ; break ;
200+ case "--cpu" : if (cpu != null || i + 1 >= args .length || args [i + 1 ].charAt (0 ) == '-' ) bad_usage ();
201+ cpu = args [++i ];
202+ break ;
203+ case "--abi" : if (abi != null || i + 1 >= args .length || args [i + 1 ].charAt (0 ) == '-' ) bad_usage ();
204+ abi = args [++i ];
205+ break ;
206+ case "--target" : target (); break ;
207+ case "--version" : throw Utils .TODO ();
208+ case "--help" : usage ();
209+ default : bad_usage ();
210+ }
227211 }
228212
213+ if (input_filename == null ) throw bad ("no input file' (use --help)" );
214+ if ( !input_filename .isEmpty () && !input_filename .endsWith (".ez" ) )
215+ throw bad ("File extension must be .ez" );
216+ String base = input_filename .substring (0 ,input_filename .length ()-4 );
217+
229218 if (do_run || (dump & DUMP_DISASSEMBLE ) != 0 || do_print_size ) {
230219 if (cpu == null ) cpu = system_cpu ;
231220 if (abi == null ) abi = system_abi ;
232- if (cpu == null || abi == null ) {
233- System .err .println ("ERROR: Cannot compile for unknown target" );
234- System .exit (1 );
235- }
236221 do_codegen = true ;
237222 }
238223
239224 // Read input file
240225 try {
241- src = use_stdin ? getInput () : Files .readString (Path .of (input_filename ));
242- } catch (IOException e ) {
243- System .err .println ("ERROR: Cannot read input file" );
244- System .exit (1 );
245- }
226+ src = input_filename .isEmpty () ? getInput () : Files .readString (Path .of (input_filename ));
227+ } catch ( IOException e ) { throw bad ("Cannot read input file: " +input_filename ); }
246228
247229 // Compilation pipeline
248230 CodeGen code = new CodeGen (src );
@@ -260,8 +242,8 @@ public static void main(String[] args) throws Exception {
260242 dump (code , dump , DUMP_AFTER_LOOP_TREE );
261243
262244 if (do_codegen ) {
263- code .instSelect (cpu , abi );
264- dump (code , dump , DUMP_AFTER_INSTR_SELECT );
245+ code .instSelect (cpu , abi , PORTS );
246+ dump (code , dump , DUMP_AFTER_SELECT );
265247 }
266248
267249 code .GCM ();
@@ -276,6 +258,8 @@ public static void main(String[] args) throws Exception {
276258
277259 code .encode ();
278260 dump (code , dump , DUMP_AFTER_ENCODE );
261+
262+ code .exportELF (base +".o" );
279263 }
280264
281265 dump (code , dump , DUMP_FINAL );
@@ -285,7 +269,7 @@ public static void main(String[] args) throws Exception {
285269 }
286270
287271 if (do_print_size ) {
288- System .out .println ( String . format ( "Code Size: %d" , code ._encoding ._bits .size () ));
272+ System .out .printf ( "Code Size: %d%n " , code ._encoding ._bits .size ());
289273 }
290274
291275 if (do_print_time ) {
0 commit comments