summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--chapter22/docs/examples/A_helloWorld.smp3
-rw-r--r--chapter22/docs/examples/BubbleSort.smp25
-rw-r--r--chapter22/simple.bat1
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/type/TypeConAry.java2
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/type/TypeConAryB.java2
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/type/TypeStruct.java3
-rw-r--r--chapter22/src/test/java/com/seaofnodes/simple/Eval2.java17
-rw-r--r--chapter22/src/test/java/com/seaofnodes/simple/Simple.java246
-rw-r--r--chapter22/src/test/java/com/seaofnodes/simple/TestC.java37
-rw-r--r--chapter22/src/test/java/com/seaofnodes/simple/progs/jig.smp21
11 files changed, 188 insertions, 172 deletions
diff --git a/.gitignore b/.gitignore
index 0ccb7896..9cec3a2c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,8 @@
# Compiled class file
*.class
build/
+docs/examples/*.o
+docs/examples/*.exe
# Log file
*.log
@@ -18,4 +20,3 @@ TAGS
# Libs
*/lib/*jar
-Unicorn/
diff --git a/chapter22/docs/examples/A_helloWorld.smp b/chapter22/docs/examples/A_helloWorld.smp
new file mode 100644
index 00000000..07ff935f
--- /dev/null
+++ b/chapter22/docs/examples/A_helloWorld.smp
@@ -0,0 +1,3 @@
+// -*- mode: java; -*-
+sys.io.p("Hello, World!");
+return 0;
diff --git a/chapter22/docs/examples/BubbleSort.smp b/chapter22/docs/examples/BubbleSort.smp
new file mode 100644
index 00000000..af110159
--- /dev/null
+++ b/chapter22/docs/examples/BubbleSort.smp
@@ -0,0 +1,25 @@
+// -*- mode: java; -*-
+
+
+val _exit = { u8[~] msg ->
+ sys.io.p(msg);
+ sys.libc._exit(1);
+};
+
+struct Scan {
+ int !x;
+ u8[~] buf;
+};
+
+
+// Read from stdin a line of the form "[ 4, 3, 2, 1]" and print it sorted.
+val main = { ->
+ Scan !s = new Scan{ buf = sys.io.stdin(); };
+ var junk = new u8[1];
+ while( s.x < s.buf# ) {
+ sys.io.p("scan ");
+ junk[0] = s.buf[s.x++];
+ sys.io.p(junk);
+ };
+ return 0;
+};
diff --git a/chapter22/simple.bat b/chapter22/simple.bat
index 563fb818..05732113 100644
--- a/chapter22/simple.bat
+++ b/chapter22/simple.bat
@@ -1 +1,2 @@
+echo off
java -cp "build/classes/test;build/classes/main;lib/hamcrest-core-1.3.jar;lib/junit-4.12.jar" com.seaofnodes.simple.Simple %*
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/type/TypeConAry.java b/chapter22/src/main/java/com/seaofnodes/simple/type/TypeConAry.java
index 8a19c9d7..29496af6 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/type/TypeConAry.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/type/TypeConAry.java
@@ -51,7 +51,7 @@ public class TypeConAry<A> extends Type {
}
return TypeInteger.make(min,max);
}
- long at(int idx) { throw Utils.TODO(); }
+ public long at(int idx) { throw Utils.TODO(); }
public int len() { throw Utils.TODO(); }
@Override public int alignment() { return 0; }
public void write( ByteArrayOutputStream baos ) { throw Utils.TODO(); }
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/type/TypeConAryB.java b/chapter22/src/main/java/com/seaofnodes/simple/type/TypeConAryB.java
index 34475ac1..c057c6a5 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/type/TypeConAryB.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/type/TypeConAryB.java
@@ -11,7 +11,7 @@ public class TypeConAryB extends TypeConAry<byte[]> {
static final TypeConAryB ABC = make("abc");
static final TypeConAryB ABCD = make("abcd");
public static void gather(ArrayList<Type> ts) { ts.add(ABC); ts.add(ABCD); }
- @Override long at(int idx) { return _ary[idx]; }
+ @Override public long at(int idx) { return _ary[idx]; }
@Override public int len() { return _ary.length; }
@Override public int alignment() { return 0; }
@Override public String str() { return "[\""+new String(_ary)+"\"]"; }
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/type/TypeStruct.java b/chapter22/src/main/java/com/seaofnodes/simple/type/TypeStruct.java
index 827e85f0..66a37d41 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/type/TypeStruct.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/type/TypeStruct.java
@@ -241,7 +241,8 @@ public class TypeStruct extends Type {
public SB print(SB sb) {
if( _con!=TypeConAry.BOT ) return sb.p(_con.str());
sb.p(_name);
- if( _fields == null || isAry() ) return sb; // Forward reference struct, just print the name
+ if( _fields == null || isAry() ) // Forward reference struct, just print the name
+ return sb.p(isFinal() ? "" : "!");
sb.p(" {");
for( Field f : _fields )
f._type.print(sb).p(f._final ? " " : " !").p(f._fname).p("; ");
diff --git a/chapter22/src/test/java/com/seaofnodes/simple/Eval2.java b/chapter22/src/test/java/com/seaofnodes/simple/Eval2.java
index 8ad72eaa..86f0e9db 100644
--- a/chapter22/src/test/java/com/seaofnodes/simple/Eval2.java
+++ b/chapter22/src/test/java/com/seaofnodes/simple/Eval2.java
@@ -289,9 +289,9 @@ public abstract class Eval2 {
// Fetch without unboxing, searching up-Frame
static Object val( Node n ) { return F.get(n); }
// Fetch and unbox as primitive long
- static long x( Node n ) { Object d = F.get(n); return d==null ? 0 : (Long) F.get(n); }
+ static long x( Node n ) { Object d = F.get(n); return d==null ? 0 : (Long)d; }
// Fetch and unbox as primitive double
- static double d( Node n ) { Object d = F.get(n); return d==null ? 0 : (Double)F.get(n); }
+ static double d( Node n ) { Object d = F.get(n); return d==null ? 0 : (Double)d; }
// Fetch and unbox a function constant
static TypeFunPtr tfp(Node n) { return (TypeFunPtr)F.get(n); }
// Fetch and unbox a closure
@@ -347,10 +347,19 @@ public abstract class Eval2 {
}
private static Object load( LoadNode ld ) {
- TypeMemPtr tmp = (TypeMemPtr)ld.ptr()._type;
- Object[] fs = (Object[])val(ld.ptr());
+ Object f = val(ld.ptr());
+ // Check for dense constant array
+ if( f instanceof TypeMemPtr tmp ) {
+ assert tmp._obj._con != TypeConAry.BOT;
+ if( ld._name.equals("#") )
+ return (long)tmp._obj._con.len();
+ int idx = offToIdx(x(ld.off()),tmp._obj);
+ return tmp._obj._con.at(idx);
+ }
+ Object[] fs = (Object[])f;
if( ld._name.equals("#") )
return (long)fs.length;
+ TypeMemPtr tmp = (TypeMemPtr)ld.ptr()._type;
int idx = tmp._obj.isAry()
? offToIdx(x(ld.off()),tmp._obj)
: tmp._obj.find(ld._name);
diff --git a/chapter22/src/test/java/com/seaofnodes/simple/Simple.java b/chapter22/src/test/java/com/seaofnodes/simple/Simple.java
index 9b1e2827..1465aa6d 100644
--- a/chapter22/src/test/java/com/seaofnodes/simple/Simple.java
+++ b/chapter22/src/test/java/com/seaofnodes/simple/Simple.java
@@ -17,7 +17,7 @@ public class Simple {
static final int DUMP_AFTER_OPTO = 1<<1;
static final int DUMP_AFTER_TYPE_CHECK = 1<<2;
static final int DUMP_AFTER_LOOP_TREE = 1<<3;
- static final int DUMP_AFTER_INSTR_SELECT = 1<<4;
+ static final int DUMP_AFTER_SELECT = 1<<4;
static final int DUMP_AFTER_GCM = 1<<5;
static final int DUMP_AFTER_LOCAL_SCHED = 1<<6;
static final int DUMP_AFTER_REG_ALLOC = 1<<7;
@@ -32,33 +32,30 @@ public class Simple {
static final int DUMP_DISASSEMBLE = 1<<31;
- static String system_cpu = null;
- static String system_abi = null;
-
static void usage() {
System.out.println(
"""
-simple <input-file> [options] [--eval|--run ...]
+simple [options] <input-file> ...args...
Options:
- --dump - dump final intermediate representation
- --dump-after-parse - dump intermediate representation after parse
- --dump-after-opto - dump intermediate representation after opto pass
- --dump-after-type-check - dump intermediate representation after type check pass
- --dump-after-instr-select - dump intermediate representation after instrution selection pass
- --dump-after-gcm - dump intermediate representation after GCM pass
- --dump-after-local-sched - dump intermediate representation after local scheduling pass
- --dump-after-reg-alloc - dump intermediate representation after register allocation pass
- --dump-after-encode - dump intermediate representation after encoding pass
- --dump-after-all - dump intermediate representation after all passes
- --dot - dump grapical representation of intermediate code into *.dot file(s)
- -S - dump generated assembler code
- --eval ... - evaluate the compiled code in emulator
- --run ... - run the compiled code natively
- --dump-size - print the size of generated code
- --dump-time - print compilation and execution times
- --cpu <cpu-name> - use specific CPU (x86_64_v2, riscv, arm)
- --abi <abi-name> - use speific ABI variant (SystemV)
- --target - print native CPU and ABI
+ --dump - dump final intermediate representation
+ --dump-after-parse - dump intermediate representation after parse
+ --dump-after-opto - dump intermediate representation after opto pass
+ --dump-after-type-check - dump intermediate representation after type check pass
+ --dump-after-select - dump intermediate representation after instrution selection pass
+ --dump-after-gcm - dump intermediate representation after GCM pass
+ --dump-after-local-sched - dump intermediate representation after local scheduling pass
+ --dump-after-reg-alloc - dump intermediate representation after register allocation pass
+ --dump-after-encode - dump intermediate representation after encoding pass
+ --dump-after-all - dump intermediate representation after all passes
+ --dot - dump grapical representation of intermediate code into *.dot file(s)
+ -S - dump generated assembler code
+ --eval - evaluate the compiled code in emulator
+ --run - run the compiled code natively; this is the default
+ --dump-size - print the size of generated code
+ --dump-time - print compilation and execution times
+ --cpu <cpu-name> - use specific CPU (x86_64_v2, riscv, arm)
+ --abi <abi-name> - use speific ABI variant (SystemV)
+ --target - print native CPU and ABI
--version
--help
"""
@@ -66,46 +63,40 @@ Options:
System.exit(0);
}
- static void bad_usage() {
- System.err.println("ERROR: Invalid usage (use --help)");
+ static void bad_usage() { bad("Invalid usage (use --help)"); }
+ static RuntimeException bad(String err) {
+ System.err.println("ERROR: "+err);
System.exit(1);
+ return new RuntimeException(err);
}
static void target() {
- if (system_cpu == null || system_abi == null) {
- System.err.println("ERROR: Unknown target");
- System.exit(1);
- }
- System.out.print(system_cpu);
+ System.out.print(TestC.CPU_PORT);
System.out.print("-");
- System.out.println(system_abi);
- System.exit(0);
+ System.out.println(TestC.CALL_CONVENTION);
}
static void dump(CodeGen code, int dump, int pass) {
if ((dump & pass) != 0) {
if ((dump & DUMP_DOT) != 0) {
String fn = switch (pass) {
- case DUMP_AFTER_PARSE -> "01-parse.dot";
- case DUMP_AFTER_OPTO -> "02-opto.dot";
- case DUMP_AFTER_TYPE_CHECK -> "03-type_check.dot";
- case DUMP_AFTER_LOOP_TREE -> "04-loop_tree.dot";
- case DUMP_AFTER_INSTR_SELECT -> "05-instr_select.dot";
- case DUMP_AFTER_GCM -> "06-gcm.dot";
- case DUMP_AFTER_LOCAL_SCHED -> "07-local_sched.dot";
- case DUMP_AFTER_REG_ALLOC -> "08-reg_allos.dot";
- case DUMP_AFTER_ENCODE -> "09-local_sched.dot";
- case DUMP_FINAL -> "10-final.dot";
- default -> throw Utils.TODO();
+ case DUMP_AFTER_PARSE -> "01-parse.dot";
+ case DUMP_AFTER_OPTO -> "02-opto.dot";
+ case DUMP_AFTER_TYPE_CHECK -> "03-type_check.dot";
+ case DUMP_AFTER_LOOP_TREE -> "04-loop_tree.dot";
+ case DUMP_AFTER_SELECT -> "05-instr_select.dot";
+ case DUMP_AFTER_GCM -> "06-gcm.dot";
+ case DUMP_AFTER_LOCAL_SCHED -> "07-local_sched.dot";
+ case DUMP_AFTER_REG_ALLOC -> "08-reg_allos.dot";
+ case DUMP_AFTER_ENCODE -> "09-local_sched.dot";
+ case DUMP_FINAL -> "10-final.dot";
+ default -> throw Utils.TODO();
};
try {
Files.writeString(Path.of(fn),
- new GraphVisualizer().generateDotOutput(code._stop, null, null));
- } catch(IOException e) {
- System.err.println("ERROR: Cannot write DOT file");
- System.exit(1);
- }
+ new GraphVisualizer().generateDotOutput(code._stop, null, null));
+ } catch(IOException e) { throw bad("Cannot write DOT file"); }
} else {
if ((dump & DUMP_PASS_NAME) != 0) {
System.err.println(switch (pass) {
@@ -113,11 +104,11 @@ Options:
case DUMP_AFTER_OPTO -> "After OPTO:";
case DUMP_AFTER_TYPE_CHECK -> "After Type Check:";
case DUMP_AFTER_LOOP_TREE -> "After Loop Tree:";
- case DUMP_AFTER_INSTR_SELECT -> "After Instruction Selection:";
+ case DUMP_AFTER_SELECT -> "After Code Selection:";
case DUMP_AFTER_GCM -> "After GCM:";
case DUMP_AFTER_LOCAL_SCHED -> "After Local Scheduling:";
case DUMP_AFTER_REG_ALLOC -> "After Register Allocation:";
- case DUMP_AFTER_ENCODE -> "After Instruction Encoding:";
+ case DUMP_AFTER_ENCODE -> "After Encoding:";
case DUMP_FINAL -> "Final:";
default -> throw Utils.TODO();
});
@@ -132,24 +123,24 @@ Options:
double t, total = 0;
total += t = code._tParse / 1e3;
- System.out.println(String.format("Parsing Time: %.3f sec", t));
+ System.out.printf( "Parsing Time: %.3f sec%n", t);
total += t = code._tOpto / 1e3;
- System.out.println(String.format("Optimization Time: %.3f sec", t));
+ System.out.printf( "Optimization Time: %.3f sec%n", t);
total += t = code._tTypeCheck / 1e3;
- System.out.println(String.format("Type Checking Time: %.3f sec", t));
+ System.out.printf( "Type Checking Time: %.3f sec%n", t);
total += t = code._tLoopTree / 1e3;
- System.out.println(String.format("Loop Tree Time: %.3f sec", t));
+ System.out.printf( "Loop Tree Time: %.3f sec%n", t);
total += t = code._tInsSel / 1e3;
- System.out.println(String.format("Instruction Selection Time: %.3f sec", t));
+ System.out.printf( "Code Selection Time: %.3f sec%n", t);
total += t = code._tGCM / 1e3;
- System.out.println(String.format("GCM Time: %.3f sec", t));
+ System.out.printf( "GCM Time: %.3f sec%n", t);
total += t = code._tLocal / 1e3;
- System.out.println(String.format("Local Scheduling Time: %.3f sec", t));
+ System.out.printf( "Local Scheduling Time: %.3f sec%n", t);
total += t = code._tRegAlloc / 1e3;
- System.out.println(String.format("Register Allocation Time: %.3f sec", t));
+ System.out.printf( "Register Allocation Time: %.3f sec%n", t);
total += t = code._tEncode / 1e3;
- System.out.println(String.format("Instruction Encoding Time: %.3f sec", t));
- System.out.println(String.format("TOTAL COMPILATION TIME: %.3f sec", total));
+ System.out.printf( "Encoding Time: %.3f sec%n", t);
+ System.out.printf( "TOTAL COMPILATION TIME: %.3f sec%n", total);
}
static String getInput() {
@@ -159,9 +150,8 @@ Options:
public static void main(String[] args) throws Exception {
String input_filename = null;
- boolean use_stdin = false;
boolean do_eval = false;
- boolean do_run = false;
+ boolean do_run = true;
boolean do_codegen = false;
boolean do_print_size = false;
boolean do_print_time = false;
@@ -171,78 +161,62 @@ Options:
String cpu = null;
String abi = null;
- // TODO: autodetect
- system_cpu = "x86_64_v2";
- system_abi = "SystemV";
-
// Parse command line
-loop: for (int i = 0; i < args.length; i++) {
+ int i; for( i = 0; i < args.length; i++ ) {
String arg = args[i];
- if (arg.charAt(0) == '-') {
- switch (arg) {
- case "-": use_stdin = true; break;
- case "--dump": dump |= DUMP_FINAL; break;
- case "--dump-after-parse": dump |= DUMP_AFTER_PARSE; break;
- case "--dump-after-opto": dump |= DUMP_AFTER_OPTO; break;
- case "--dump-after-type-check": dump |= DUMP_AFTER_TYPE_CHECK; break;
- case "--dump-after-loop-tree": dump |= DUMP_AFTER_LOOP_TREE; break;
- case "--dump-after-instr-select": dump |= DUMP_AFTER_INSTR_SELECT; break;
- case "--dump-after-gcm": dump |= DUMP_AFTER_GCM; break;
- case "--dump-after-local-sched": dump |= DUMP_AFTER_LOCAL_SCHED; break;
- case "--dump-after-reg-alloc": dump |= DUMP_AFTER_REG_ALLOC; break;
- case "--dump-after-encode": dump |= DUMP_AFTER_ENCODE; break;
- case "--dump-after-all": dump |= DUMP_AFTER_ALL; break;
- case "--dot": dump |= DUMP_DOT; break;
- case "-S": dump |= DUMP_DISASSEMBLE; break;
- case "--eval": do_eval = true; first_arg = i + 1; break loop;
- case "--run": do_run = true; first_arg = i + 1; break loop;
- case "--dump-size": do_print_size = true; break;
- case "--dump-time": do_print_time = true; break;
- case "--cpu": if (cpu != null
- || i + 1 >= args.length
- || args[i + 1].charAt(0) == '-') bad_usage();
- cpu = args[i + 1];
- i++;
- break;
- case "--abi": if (abi != null
- || i + 1 >= args.length
- || args[i + 1].charAt(0) == '-') bad_usage();
- abi = args[i + 1];
- i++;
- break;
- case "--target": target();
- case "--version": throw Utils.TODO();
- case "--help": usage();
- default: bad_usage();
- }
- } else {
- if (input_filename != null || use_stdin) bad_usage();
+ if( arg.charAt(0) != '-' ) {
input_filename = arg;
+ break;
}
- }
- if (input_filename == null && !use_stdin) {
- System.err.println("ERROR: no input file' (use --help)");
- System.exit(1);
+ switch (arg) {
+ case "-": input_filename=""; break;
+ case "--dump": dump |= DUMP_FINAL; break;
+ case "--dump-after-parse": dump |= DUMP_AFTER_PARSE; break;
+ case "--dump-after-opto": dump |= DUMP_AFTER_OPTO; break;
+ case "--dump-after-type-check": dump |= DUMP_AFTER_TYPE_CHECK; break;
+ case "--dump-after-loop-tree": dump |= DUMP_AFTER_LOOP_TREE; break;
+ case "--dump-after-select": dump |= DUMP_AFTER_SELECT; break;
+ case "--dump-after-gcm": dump |= DUMP_AFTER_GCM; break;
+ case "--dump-after-local-sched": dump |= DUMP_AFTER_LOCAL_SCHED; break;
+ case "--dump-after-reg-alloc": dump |= DUMP_AFTER_REG_ALLOC; break;
+ case "--dump-after-encode": dump |= DUMP_AFTER_ENCODE; break;
+ case "--dump-after-all": dump |= DUMP_AFTER_ALL; break;
+ case "--dot": dump |= DUMP_DOT; break;
+ case "-S": dump |= DUMP_DISASSEMBLE; break;
+ case "--eval": do_eval = true ; do_run = false; break;
+ case "--run": do_run = true ; break;
+ case "--norun": do_run = false; break;
+ case "--dump-size": do_print_size = true; break;
+ case "--dump-time": do_print_time = true; break;
+ case "--cpu": if (cpu != null || i + 1 >= args.length || args[i + 1].charAt(0) == '-') bad_usage();
+ cpu = args[++i];
+ break;
+ case "--abi": if (abi != null || i + 1 >= args.length || args[i + 1].charAt(0) == '-') bad_usage();
+ abi = args[++i];
+ break;
+ case "--target": target(); break;
+ case "--version": throw Utils.TODO();
+ case "--help": usage();
+ default: bad_usage();
+ }
}
+ if (input_filename == null) throw bad("no input file' (use --help)");
+ if( !input_filename.isEmpty() && !input_filename.endsWith(".smp") )
+ throw bad("File extension must be .smp");
+ String base = input_filename.substring(0,input_filename.length()-4);
+
if (do_run || (dump & DUMP_DISASSEMBLE) != 0 || do_print_size) {
- if (cpu == null) cpu = system_cpu;
- if (abi == null) abi = system_abi;
- if (cpu == null || abi == null) {
- System.err.println("ERROR: Cannot compile for unknown target");
- System.exit(1);
- }
+ if (cpu == null) cpu = TestC.CPU_PORT;
+ if (abi == null) abi = TestC.CALL_CONVENTION;
do_codegen = true;
}
// Read input file
try {
- src = use_stdin ? getInput() : Files.readString(Path.of(input_filename));
- } catch(IOException e) {
- System.err.println("ERROR: Cannot read input file");
- System.exit(1);
- }
+ src = input_filename.isEmpty() ? getInput() : Files.readString(Path.of(input_filename));
+ } catch( IOException e ) { throw bad("Cannot read input file: "+input_filename); }
// Compilation pipeline
CodeGen code = new CodeGen(src);
@@ -260,8 +234,8 @@ loop: for (int i = 0; i < args.length; i++) {
dump(code, dump, DUMP_AFTER_LOOP_TREE);
if (do_codegen) {
- code.instSelect(PORTS, cpu, abi);
- dump(code, dump, DUMP_AFTER_INSTR_SELECT);
+ code.instSelect(cpu, abi, PORTS);
+ dump(code, dump, DUMP_AFTER_SELECT);
}
code.GCM();
@@ -276,6 +250,8 @@ loop: for (int i = 0; i < args.length; i++) {
code.encode();
dump(code, dump, DUMP_AFTER_ENCODE);
+
+ code.exportELF(base+".o");
}
dump(code, dump, DUMP_FINAL);
@@ -285,7 +261,7 @@ loop: for (int i = 0; i < args.length; i++) {
}
if (do_print_size) {
- System.out.println(String.format("Code Size: %d", code._encoding._bits.size()));
+ System.out.printf( "Code Size: %d%n", code._encoding._bits.size());
}
if (do_print_time) {
@@ -295,19 +271,19 @@ loop: for (int i = 0; i < args.length; i++) {
if (do_eval) {
// TODO: Support for evaluation of functions with different argument numbers and types
long t = System.currentTimeMillis();
- long arg = (first_arg < args.length) ? Integer.valueOf(args[first_arg]) : 0;
+ long arg = (i+1 < args.length) ? Integer.parseInt(args[i+1]) : 0;
System.out.println(Eval2.eval(code, arg, 100000));
if (do_print_time) {
- System.out.println(String.format("EXECUTION TIME: %.3f sec",
- (System.currentTimeMillis() - t) / 1e3));
- }
- } else if (do_run) {
- if (cpu != system_cpu || abi != system_abi) {
- System.err.println("ERROR: cannot run code on not native target");
- System.exit(1);
+ System.out.printf( "EXECUTION TIME: %.3f sec%n",
+ (System.currentTimeMillis() - t) / 1e3);
}
-
- throw Utils.TODO();
+ }
+ if (do_run) {
+ if ( !TestC.CPU_PORT.equals( cpu ) || !TestC.CALL_CONVENTION.equals( abi ) )
+ throw bad("cannot run code on not native target");
+ String exe = TestC.OS.startsWith("Windows") ? base+".exe" : base;
+ String result = com.seaofnodes.simple.TestC.gcc(base+".o", null, null, true, exe);
+ System.out.print(result);
}
}
}
diff --git a/chapter22/src/test/java/com/seaofnodes/simple/TestC.java b/chapter22/src/test/java/com/seaofnodes/simple/TestC.java
index 2e68a029..93fa9b66 100644
--- a/chapter22/src/test/java/com/seaofnodes/simple/TestC.java
+++ b/chapter22/src/test/java/com/seaofnodes/simple/TestC.java
@@ -41,8 +41,20 @@ public abstract class TestC {
public static void run( String src, String simple_conv, String c_conv, String cfile, String efile, String xtn, String expected, int spills ) throws IOException {
String bin = efile+xtn;
String obj = bin+".o";
+ String exe = OS.startsWith("Windows") ? bin+".exe" : bin;
// Compile simple, emit ELF
CodeGen code = new CodeGen(src).driver( CPU_PORT, simple_conv, obj);
+ String result = gcc(obj, c_conv, cfile, false, exe );
+ assertEquals(expected,result);
+
+ // Allocation quality not degraded
+ int delta = spills>>3;
+ if( delta==0 ) delta = 1;
+ if( spills != -1 )
+ assertEquals("Expect spills:",spills,code._regAlloc._spillScaled,delta);
+ }
+
+ public static String gcc( String obj, String c_conv, String cfile, boolean stdin, String... args ) throws IOException {
// Compile the C program. Compiling code and constants in the low
// 2Gig. Pointers are 64b BUT since always in the low 2G all the
@@ -56,7 +68,7 @@ public abstract class TestC {
"-lm", // Picks up 'sqrt' for newtonFloat tests to compare
"-g",
"-o",
- bin,
+ args[0],
});
// Calling convention for C calls, if any
if( cfile!=null ) {
@@ -64,6 +76,7 @@ public abstract class TestC {
params.add("CALL_CONV="+c_conv);
}
+ // Run GCC to link (optionally compile C driver code)
Process gcc = new ProcessBuilder(params.asAry()).redirectErrorStream(true).start();
int exit;
try {
@@ -81,21 +94,13 @@ public abstract class TestC {
//assertTrue(result.isEmpty()); // No data in error stream
// Execute results
- Process smp = new ProcessBuilder(bin).redirectErrorStream(true).start();
- try { exit = (byte)smp.waitFor(); } catch( InterruptedException e ) { throw new IOException("interrupted"); }
- result = new String(smp.getInputStream().readAllBytes());
- if( exit!=0 ) {
+ ProcessBuilder smp = new ProcessBuilder(args);
+ if( stdin ) smp.redirectInput(ProcessBuilder.Redirect.INHERIT);
+ Process p = smp.start();
+ try { exit = (byte)p.waitFor(); } catch( InterruptedException e ) { throw new IOException("interrupted"); }
+ result = new String(p.getInputStream().readAllBytes());
+ if( exit!=0 )
System.err.println("exec exit code: "+exit);
- System.err.println(result);
- }
- assertEquals( 0, exit );
- assertEquals(expected,result);
-
- // Allocation quality not degraded
- int delta = spills>>3;
- if( delta==0 ) delta = 1;
- if( spills != -1 )
- assertEquals("Expect spills:",spills,code._regAlloc._spillScaled,delta);
-
+ return result;
}
}
diff --git a/chapter22/src/test/java/com/seaofnodes/simple/progs/jig.smp b/chapter22/src/test/java/com/seaofnodes/simple/progs/jig.smp
index 2d8d375b..ae0b57aa 100644
--- a/chapter22/src/test/java/com/seaofnodes/simple/progs/jig.smp
+++ b/chapter22/src/test/java/com/seaofnodes/simple/progs/jig.smp
@@ -1,15 +1,10 @@
// -*- mode: java; -*-
-// theory: conservative approx to a CG will link all target fcsn.
-// unlinked *local* fcns with *no* TFP constants can be declared unreachable and removed.
-
-// Newtons approximation to the square root
-val sqrt = { int x ->
- int guess = x;
- while( 1 ) {
- int next = (x/guess + guess)/2;
- if( next == guess ) return guess;
- guess = next;
- }
+//7599136877341746241
+//========= Reduced =========
+struct s0 {
+ Zvbjf? Ia;
+ i32 v0;
};
-int cast_int = arg+2;
-return sqrt(arg) + sqrt(cast_int);
+s0 !Z1_=new s0;
+while(new s0.v0) {
+ Z1_.Ia=Z1_.Ia;