diff options
13 files changed, 136 insertions, 57 deletions
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java b/chapter21/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java index 3d2e6d6a..9ec3bc7b 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java @@ -35,7 +35,6 @@ public class CodeGen { public final String _src; // Compile-time known initial argument type public final TypeInteger _arg; - // --------------------------- public CodeGen( String src ) { this(src, TypeInteger.BOT, 123L ); } public CodeGen( String src, TypeInteger arg, long workListSeed ) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java index 260025d1..3e39adc0 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java @@ -681,7 +681,7 @@ public class arm extends Machine { case ToFloatNode tfn-> new I2F8ARM(tfn); case XorNode xor -> xor(xor); - case LoopNode loop -> new LoopNode(loop); + case LoopNode loop -> new LoopNode(loop); case RegionNode region-> new RegionNode(region); default -> throw Utils.TODO(); }; diff --git a/chapter22/src/main/java/com/seaofnodes/simple/Parser.java b/chapter22/src/main/java/com/seaofnodes/simple/Parser.java index 25e3054c..d551a72a 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter22/src/main/java/com/seaofnodes/simple/Parser.java @@ -115,7 +115,7 @@ public class Parser { put("i32" ,TypeInteger.I32); put("i64" ,TypeInteger.BOT); put("i8" ,TypeInteger.I8 ); - put("int" ,TypeInteger.BOT); + put("int" ,TypeInteger.I32); put("u1" ,TypeInteger.U1 ); put("u16" ,TypeInteger.U16); put("u32" ,TypeInteger.U32); @@ -135,7 +135,7 @@ public class Parser { _scope.define(ScopeNode.CTRL, Type.CONTROL , false, null, _lexer); _scope.define(ScopeNode.MEM0, TypeMem.BOT , false, null, _lexer); - _scope.define(ScopeNode.ARG0, TypeInteger.BOT, false, null, _lexer); + _scope.define(ScopeNode.ARG0, TypeInteger.I32, false, null, _lexer); ctrl(XCTRL); _scope.mem(new MemMergeNode(false)); diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/StoreNode.java b/chapter22/src/main/java/com/seaofnodes/simple/node/StoreNode.java index b9f99f4e..6e92c67a 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/StoreNode.java +++ b/chapter22/src/main/java/com/seaofnodes/simple/node/StoreNode.java @@ -84,6 +84,18 @@ public class StoreNode extends MemOpNode { } } + if( val() instanceof SarNode shr && + shr.in(1) instanceof ShlNode shl && + shr.in(2)._type.isConstant() && + shl.in(2)._type.isConstant() ) { + + ConstantNode shr_s = (ConstantNode)(shr.in(2)); + ConstantNode shl_s = (ConstantNode)(shl.in(2)); + + if( shl_s._type == shr_s._type ) + return setDef(3, shl.in(1)); + } + return null; } diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java index 9303e566..d77a4ff9 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java +++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java @@ -40,6 +40,12 @@ abstract public class ImmRISC extends MachConcreteNode implements MachNode { @Override public void encoding( Encoding enc ) { short dst = enc.reg(this ); short src = enc.reg(in(1)); + // special case for SRAI + if(this instanceof SraIRISC) { + int body = riscv.sra_i_type(opcode(), dst, func3(), src, _imm12 & 0xFFF); + enc.add4(body); + return; + } int body = riscv.i_type(opcode(), dst, func3(), src, _imm12 & 0xFFF); enc.add4(body); } diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MemOpRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MemOpRISC.java index b8eb7644..7f9b582a 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MemOpRISC.java +++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MemOpRISC.java @@ -52,7 +52,7 @@ public abstract class MemOpRISC extends MemOpNode implements MachNode { // float if(_declaredType == TypeFloat.F32) func3 = 2; // fLW fSW if(_declaredType == TypeFloat.F64) func3 = 3; // fLD fSD - if( _declaredType instanceof TypeMemPtr ) func3=3; // 8 byte pointers + if( _declaredType instanceof TypeMemPtr) func3 = 6; // 4 byte pointers(pick lw/u) if( func3 == -1 ) throw Utils.TODO(); return func3; } diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/StoreRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/StoreRISC.java index d34d94fc..cef56f6a 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/StoreRISC.java +++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/StoreRISC.java @@ -19,7 +19,7 @@ import com.seaofnodes.simple.node.*; // sw rs2,offset(rs1) public class StoreRISC extends MemOpRISC { - StoreRISC( StoreNode st, Node base, int off, Node val ) { super(st, base, off, val); } + StoreRISC( StoreNode st, Node base, int off, Node val ) { super(st, base, off, val);} @Override public String op() { return "st"+_sz; } @Override public RegMask regmap(int i) { // 0 - ctrl diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java index 47d1db75..9db6bd5a 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java +++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java @@ -188,6 +188,12 @@ public class riscv extends Machine { return (imm12 << 20) | (rs1 << 15) | (func3 << 12) | (rd << 7) | opcode; } + public static int sra_i_type(int opcode, int rd, int func3, int rs1, int imm12) { + assert 0 <= rd && rd < 32; + assert 0 <= rs1 && rs1 < 32; + assert opcode >= 0 && func3 >=0 && imm12 >= 0; // Zero-extend by caller + return (((0x20 << 5) | imm12) << 20) | (rs1 << 15) | (func3 << 12) | (rd << 7) | opcode; + } // S-type instructions(store) public static int s_type(int opcode, int func3, int rs1, int rs2, int imm12) { diff --git a/chapter22/src/main/java/com/seaofnodes/simple/type/TypeMemPtr.java b/chapter22/src/main/java/com/seaofnodes/simple/type/TypeMemPtr.java index 78605e81..8c038f8e 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/type/TypeMemPtr.java +++ b/chapter22/src/main/java/com/seaofnodes/simple/type/TypeMemPtr.java @@ -82,7 +82,7 @@ public class TypeMemPtr extends TypeNil { // Is forward-reference @Override public boolean isFRef() { return _obj.isFRef(); } - @Override public int log_size() { return 3; } // (1<<3)==8-byte pointers + @Override public int log_size() { return 2; } // (1<<3)==4-byte pointers @Override int hash() { return _obj.hashCode() ^ super.hash() ^ (_one ? 2048 : 0); } diff --git a/chapter22/src/test/java/com/seaofnodes/simple/Chapter20Test.java b/chapter22/src/test/java/com/seaofnodes/simple/Chapter20Test.java index 5b33d1e7..baee39fe 100644 --- a/chapter22/src/test/java/com/seaofnodes/simple/Chapter20Test.java +++ b/chapter22/src/test/java/com/seaofnodes/simple/Chapter20Test.java @@ -63,7 +63,9 @@ val sqrt = { int x -> guess = next; } }; -return sqrt(arg) + sqrt(arg+2); +int truncate_me = (arg+2); +int truncate = arg; +return sqrt(truncate) + sqrt(truncate_me); """; testCPU(src,"x86_64_v2", "Win64" ,23,null); testCPU(src,"riscv" , "SystemV",19,null); @@ -92,7 +94,7 @@ return sqrt(arg) + sqrt(arg+2); @Test public void testArray1() throws IOException { String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/array1.smp")); - testCPU(src,"x86_64_v2", "SystemV",-1,"return .[];"); + testCPU(src,"x86_64_v2", "SystemV",-1,"return (add,.[],(muli,.[]));"); testCPU(src,"riscv" , "SystemV", 8,"return (add,.[],(mul,.[],1000));"); testCPU(src,"arm" , "SystemV", 5,"return (add,.[],(mul,.[],1000));"); } @@ -101,8 +103,8 @@ return sqrt(arg) + sqrt(arg+2); @Test public void testString() throws IOException { String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/stringHash.smp")); - testCPU(src,"x86_64_v2", "SystemV", 9,null); - testCPU(src,"riscv" , "SystemV", 5,null); + testCPU(src,"x86_64_v2", "SystemV", 25,null); + testCPU(src,"riscv" , "SystemV", 8,null); testCPU(src,"arm" , "SystemV", 6,null); } diff --git a/chapter22/src/test/java/com/seaofnodes/simple/Chapter21Test.java b/chapter22/src/test/java/com/seaofnodes/simple/Chapter21Test.java index 0e8c05fe..8525ef76 100644 --- a/chapter22/src/test/java/com/seaofnodes/simple/Chapter21Test.java +++ b/chapter22/src/test/java/com/seaofnodes/simple/Chapter21Test.java @@ -40,15 +40,15 @@ public class Chapter21Test { @Test public void testInfinite() { String src = "struct S { int i; }; S !s = new S; while(1) s.i++;"; - testCPU(src,"x86_64_v2", "SystemV",0,"Stop[ ]"); - testCPU(src,"riscv" , "SystemV",0,"Stop[ ]"); - testCPU(src,"arm" , "SystemV",0,"Stop[ ]"); + testCPU(src,"x86_64_v2", "SystemV",16,"return Top;"); + testCPU(src,"riscv" , "SystemV",2,"return Top;"); + testCPU(src,"arm" , "SystemV",2,"return Top;"); } @Test public void testArray1() throws IOException { String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/array1.smp")); - testCPU(src,"x86_64_v2", "SystemV",-1,"return .[];"); + testCPU(src,"x86_64_v2", "SystemV",-1,"return (add,.[],(muli,.[]));"); testCPU(src,"riscv" , "SystemV", 7,"return (add,.[],(mul,.[],1000));"); testCPU(src,"arm" , "SystemV", 5,"return (add,.[],(mul,.[],1000));"); } @@ -64,20 +64,20 @@ public class Chapter21Test { @Test public void testString() throws IOException { String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/stringHash.smp")); - testCPU(src,"x86_64_v2", "SystemV", 9,null); - testCPU(src,"riscv" , "SystemV", 5,null); + testCPU(src,"x86_64_v2", "SystemV", 25,null); + testCPU(src,"riscv" , "SystemV", 8,null); testCPU(src,"arm" , "SystemV", 6,null); } @Test public void testStringExport() throws IOException { - TestC.run("stringHash", 9); + TestC.run("stringHash", 25); } @Test public void testLoop2() throws IOException { String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/loop2.smp")); - testCPU(src,"x86_64_v2", "Win64" ,0,"return (inc,Phi(Loop,0,inc));"); - testCPU(src,"riscv" , "SystemV",0,"return ( Phi(Loop,0,addi) + #1 );"); - testCPU(src,"arm" , "SystemV",0,"return (inc,Phi(Loop,0,inc));"); + testCPU(src,"x86_64_v2", "Win64" ,0,"return (sari,(shli,(inc,Phi(Loop,0,sari))));"); + testCPU(src,"riscv" , "SystemV",0,"return ( ( ( Phi(Loop,0,srai) + #1 ) << #32 ) >> #32 );"); + testCPU(src,"arm" , "SystemV",0,"return (asri,(lsli,(inc,Phi(Loop,0,asri))));"); } @Test public void testNewtonExport() throws IOException { @@ -120,7 +120,7 @@ public class Chapter21Test { String sprimes = sb.p("]").toString(); // Compile, link against native C; expect the above string of primes to be printed out by C - TestC.run("sieve",sprimes, 257); + TestC.run("sieve",sprimes, 473); // Evaluate on RISC5 emulator; expect return of an array of primes in // the simulated heap. @@ -150,14 +150,14 @@ public class Chapter21Test { String fib = "[1, 1, 2, 3, 5, 8, 13, 21, 34, 55]"; TestC.run("fib", fib, 24); - EvalRisc5 R5 = TestRisc5.build("fib", 9, 16, false); + EvalRisc5 R5 = TestRisc5.build("fib", 9, 17, false); int trap = R5.step(100); assertEquals(0,trap); // Return register A0 holds fib(8)==55 assertEquals(55,R5.regs[riscv.A0]); // arm - EvalArm64 A5 = TestArm64.build("fib", 9, 16, false); + EvalArm64 A5 = TestArm64.build("fib", 9, 17, false); int trap_arm = A5.step(100); assertEquals(0,trap_arm); // Return register X0 holds fib(8)==55 @@ -166,48 +166,49 @@ public class Chapter21Test { @Test public void testPerson() throws IOException { String person = "6\n"; + // Todo: Need to fix it(switch to 4 byte pointers) TestC.run("person", person, 0); // Memory layout starting at PS: int ps = 1<<16; // Person array pointer starts at heap start // Person[3] = { len,pad,P0,P1,P2 }; // sizeof = 4*8 - // P0 = { age } // sizeof=8 - int p0 = ps+4*8+0*8; - // P1 = { age } // sizeof=8 - int p1 = ps+4*8+1*8; - // P2 = { age } // sizeof=8 - int p2 = ps+4*8+2*8; + // P0 = { age } // sizeof=4 + int p0 = ps+4*4+0*4; + // P1 = { age } // sizeof=4 + int p1 = ps+4*4+1*4; + // P2 = { age } // sizeof=4 + int p2 = ps+4*4+2*4; EvalRisc5 R5 = TestRisc5.build("person", ps, 0, false); R5.regs[riscv.A1] = 1; // Index 1 R5.st4(ps,3); // Length - R5.st8(ps+1*8,p0); - R5.st8(ps+2*8,p1); - R5.st8(ps+3*8,p2); - R5.st8(p0, 5); // age= 5 - R5.st8(p1,17); // age=17 - R5.st8(p2,60); // age=60 + R5.st4(ps+1*4,p0); + R5.st4(ps+2*4,p1); + R5.st4(ps+3*4,p2); + R5.st4(p0, 5); // age= 5 + R5.st4(p1,17); // age=17 + R5.st4(p2,60); // age=60 int trap = R5.step(100); assertEquals(0,trap); - assertEquals( 5+0,R5.ld8(p0)); - assertEquals(17+1,R5.ld8(p1)); - assertEquals(60+0,R5.ld8(p2)); + assertEquals( 5+0,R5.ld4s(p0)); + assertEquals(17+1,R5.ld4s(p1)); + assertEquals(60+0,R5.ld4s(p2)); EvalArm64 A5 = TestArm64.build("person", ps, 0, false); A5.regs[arm.X1] = 1; // Index 1 A5.st4(ps, 3); - A5.st8(ps+1*8,p0); - A5.st8(ps+2*8,p1); - A5.st8(ps+3*8,p2); - A5.st8(p0, 5); // age= 5 - A5.st8(p1,17); // age=17 - A5.st8(p2,60); // age=60 + A5.st4(ps+1*4,p0); + A5.st4(ps+2*4,p1); + A5.st4(ps+3*4,p2); + A5.st4(p0, 5); // age= 5 + A5.st4(p1,17); // age=17 + A5.st4(p2,60); // age=60 int trap_arm = A5.step(100); assertEquals(0,trap_arm); - assertEquals( 5+0, A5.ld8(p0)); - assertEquals(17+1, A5.ld8(p1)); - assertEquals(60+0, A5.ld8(p2)); + assertEquals( 5+0, A5.ld4s(p0)); + assertEquals(17+1, A5.ld4s(p1)); + assertEquals(60+0, A5.ld4s(p2)); } @Test public void testArgCount() throws IOException { diff --git a/chapter22/src/test/java/com/seaofnodes/simple/Chapter22Test.java b/chapter22/src/test/java/com/seaofnodes/simple/Chapter22Test.java index 3bf379cd..4932ba3f 100644 --- a/chapter22/src/test/java/com/seaofnodes/simple/Chapter22Test.java +++ b/chapter22/src/test/java/com/seaofnodes/simple/Chapter22Test.java @@ -4,6 +4,9 @@ import com.seaofnodes.simple.codegen.CodeGen; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; + +import com.seaofnodes.simple.node.cpus.arm.arm; +import com.seaofnodes.simple.node.cpus.riscv.riscv; import org.junit.Ignore; import org.junit.Test; import static org.junit.Assert.*; @@ -28,6 +31,55 @@ public class Chapter22Test { assertEquals(stop, code._stop.toString()); } + + // Int now is changed to 4 bytes. + @Test public void testPerson() throws IOException { + String person = "6\n"; + // Todo: need to fix it and switch to 4 byte pointers + TestC.run("person", person, 0); + + // Memory layout starting at PS: + int ps = 1<<16; // Person array pointer starts at heap start + // Person[3] = { len,pad,P0,P1,P2 }; // sizeof = 4*8 + // P0 = { age } // sizeof=4 + int p0 = ps+4*4+0*4; + // P1 = { age } // sizeof=4 + int p1 = ps+4*4+1*4; + // P2 = { age } // sizeof=4 + int p2 = ps+4*4+2*4; + EvalRisc5 R5 = TestRisc5.build("person", ps, 0, false); + R5.regs[riscv.A1] = 1; // Index 1 + R5.st4(ps,3); // Length + R5.st4(ps+1*4,p0); + R5.st4(ps+2*4,p1); + R5.st4(ps+3*4,p2); + R5.st4(p0, 5); // age= 5 + R5.st4(p1,17); // age=17 + R5.st4(p2,60); // age=60 + + int trap = R5.step(100); + assertEquals(0,trap); + assertEquals( 5+0,R5.ld4s(p0)); + assertEquals(17+1,R5.ld4s(p1)); + assertEquals(60+0,R5.ld4s(p2)); + + EvalArm64 A5 = TestArm64.build("person", ps, 0, false); + A5.regs[arm.X1] = 1; // Index 1 + A5.st4(ps, 3); + A5.st4(ps+1*4,p0); + A5.st4(ps+2*4,p1); + A5.st4(ps+3*4,p2); + A5.st4(p0, 5); // age= 5 + A5.st4(p1,17); // age=17 + A5.st4(p2,60); // age=60 + + int trap_arm = A5.step(100); + assertEquals(0,trap_arm); + assertEquals( 5+0, A5.ld4s(p0)); + assertEquals(17+1, A5.ld4s(p1)); + assertEquals(60+0, A5.ld4s(p2)); + } + @Test public void testCoRecur() { String src = """ diff --git a/chapter22/src/test/java/com/seaofnodes/simple/TestC.java b/chapter22/src/test/java/com/seaofnodes/simple/TestC.java index 41e646bf..761da0ba 100644 --- a/chapter22/src/test/java/com/seaofnodes/simple/TestC.java +++ b/chapter22/src/test/java/com/seaofnodes/simple/TestC.java @@ -16,8 +16,8 @@ public abstract class TestC { public static final String CALL_CONVENTION = OS.startsWith("Windows") ? "Win64" : "SystemV"; public static final String CPU_PORT = switch( CPU ) { - case "amd64" -> "x86_64_v2"; - default -> throw Utils.TODO("Map Yer CPU Port Here"); + case "amd64" -> "x86_64_v2"; + default -> throw Utils.TODO("Map Yer CPU Port Here"); }; public static void run( String file, int spills ) throws IOException { run(file,"",spills); } @@ -49,12 +49,13 @@ public abstract class TestC { params.add("gcc"); if( cfile!=null ) params.add(cfile); // Associated C driver, usually has a `main` params.addAll(new String[] { - obj, - "-lm", // Picks up 'sqrt' for newtonFloat tests to compare - "-g", - "-o", - bin, - }); + obj, + "-lm", // Picks up 'sqrt' for newtonFloat tests to compare + "-m32", + "-g", + "-o", + bin, + }); // Calling convention for C calls, if any if( cfile!=null ) { params.add("-D"); @@ -90,4 +91,4 @@ public abstract class TestC { assertEquals("Expect spills:",spills,code._regAlloc._spillScaled,delta); } -} +}
\ No newline at end of file |
