summaryrefslogtreecommitdiff
path: root/chapter22
diff options
context:
space:
mode:
Diffstat (limited to 'chapter22')
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/Parser.java4
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/StoreNode.java12
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ImmRISC.java6
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/MemOpRISC.java2
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/StoreRISC.java2
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java6
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/type/TypeMemPtr.java2
-rw-r--r--chapter22/src/test/java/com/seaofnodes/simple/Chapter20Test.java10
-rw-r--r--chapter22/src/test/java/com/seaofnodes/simple/Chapter21Test.java75
-rw-r--r--chapter22/src/test/java/com/seaofnodes/simple/Chapter22Test.java52
-rw-r--r--chapter22/src/test/java/com/seaofnodes/simple/TestC.java19
11 files changed, 135 insertions, 55 deletions
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