summaryrefslogtreecommitdiff
path: root/chapter21
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2025-04-06 16:22:38 -0700
committerCliff Click <cliffc@acm.org>2025-04-06 16:22:38 -0700
commita81794df00369f6adf4a06e2f0247d309a196e27 (patch)
tree667c1fd370acb05c21dda87baa7552822cd9841a /chapter21
parent4c4778f8cc3dd4fd354832bfb0ba1a8c03ee744d (diff)
downloadSimple-a81794df00369f6adf4a06e2f0247d309a196e27.tar.gz
Simple-a81794df00369f6adf4a06e2f0247d309a196e27.zip
Fix sieve
RA returns maxSlot+1 FunX86 prints as `subi`, uses Sub; Ret uses Add X86 knows that always RPC is passed on stack "as if" a stack arg. sieve uses unsigned ints. Driver expects an array pointer
Diffstat (limited to 'chapter21')
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/FunNode.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FunX86.java13
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RetX86.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java19
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/Chapter15Test.java4
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/Chapter19Test.java4
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java2
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/progs/sieve.c12
-rw-r--r--chapter21/src/test/java/com/seaofnodes/simple/progs/sieve.smp4
10 files changed, 30 insertions, 34 deletions
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java b/chapter21/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java
index 9042de3b..c84e6011 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/codegen/RegAlloc.java
@@ -550,7 +550,7 @@ public class RegAlloc {
Node n = bb.out(j);
if( lrg(n)!=null ) {
int slot = _code._mach.stackSlot(lrg(n)._reg);
- maxSlot = Math.max(maxSlot,slot);
+ maxSlot = Math.max(maxSlot,slot+1);
}
if( !(n instanceof SplitNode lo) ) continue;
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/FunNode.java b/chapter21/src/main/java/com/seaofnodes/simple/node/FunNode.java
index 8db30e7d..2e32b75e 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/FunNode.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/FunNode.java
@@ -184,7 +184,7 @@ public class FunNode extends RegionNode {
public short _maxSlot = -1;
// Max argument slot, set during early Encoding.
public short _maxArgSlot = -1;
- // Frame adjust, including padding, st during early Encoding
+ // Frame adjust, including padding, set during early Encoding
public short _frameAdjust;
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FunX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FunX86.java
index 923fa362..15805fee 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FunX86.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FunX86.java
@@ -7,7 +7,7 @@ import com.seaofnodes.simple.node.MachNode;
public class FunX86 extends FunNode implements MachNode {
FunX86( FunNode fun ) { super(fun); }
- @Override public String op() { return "addi"; }
+ @Override public String op() { return "subi"; }
@Override public RegMask regmap(int i) { return null; }
@Override public RegMask outregmap() { return null; }
@Override public void postSelect(CodeGen code) { code.link(this); }
@@ -16,15 +16,16 @@ public class FunX86 extends FunNode implements MachNode {
// X86, with too many args & spills:
// | CALLER |
// | argN | // slot 1, required by callER
- // +--------+
+ // +--------+ // Old frame
// | RPC | // slot 0, required by callER
+ // +--------+ // New frame top
+ // | PAD16 |
// | callee | // slot 3, callEE
// | callee | // slot 2, callEE
- // | PAD16 |
// +--------+
@Override public void encoding( Encoding enc ) {
// Stack frame size: _maxSlot - max(arg), padded to 16.
- _maxArgSlot = x86_64_v2.maxSlot(enc._fun.sig());
+ _maxArgSlot = x86_64_v2.maxArgSlot(enc._fun.sig());
int sz = _maxSlot - _maxArgSlot;
// If non-leaf function, pad to 16b
if( _hasCalls ) sz = ((sz+1) & -2)+1;
@@ -34,11 +35,11 @@ public class FunX86 extends FunNode implements MachNode {
// opcode: 0x83, addi rsp with immediate 8
enc.add1( x86_64_v2.REX_W ).add1( 0x83 );
- enc.add1( x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 0, x86_64_v2.RSP) );
+ enc.add1( x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 0b101, x86_64_v2.RSP) );
enc.add1(sz*8);
}
@Override public void asm(CodeGen code, SB sb) {
- sb.p("rsp += #").p(_frameAdjust*8);
+ sb.p("rsp -= #").p(_frameAdjust*8);
}
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RetX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RetX86.java
index a9da15c6..4faf7cb4 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RetX86.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/RetX86.java
@@ -22,7 +22,7 @@ public class RetX86 extends ReturnNode implements MachNode {
if( frameAdjust > 0 ) {
enc.add1( x86_64_v2.REX_W ).add1( 0x83 );
enc.add1( x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 0, x86_64_v2.RSP) );
- enc.add1(frameAdjust*-8);
+ enc.add1(frameAdjust*8);
}
enc.add1(0xC3);
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
index d9bca291..4770bfbb 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
@@ -59,10 +59,10 @@ public class x86_64_v2 extends Machine {
public static int REX_WB = 0x49;
public enum MOD {
- INDIRECT, // [mem]
- INDIRECT_disp8, // [mem + 0x12]
- INDIRECT_disp32,// [mem + 0x12345678]
- DIRECT, // mem
+ INDIRECT, // [mem]
+ INDIRECT_disp8, // [mem + 0x12]
+ INDIRECT_disp32, // [mem + 0x12345678]
+ DIRECT, // mem
};
// opcode included here
@@ -249,8 +249,8 @@ public class x86_64_v2 extends Machine {
throw Utils.TODO(); // Pass on stack slot
}
- // Return the max stack slot used by this signature, or 0
- static short maxSlot( TypeFunPtr tfp ) {
+ // Return the max stack slot used by this signature, or 1 (for RPC)
+ static short maxArgSlot( TypeFunPtr tfp ) {
// Count floats in signature up to index
int fcnt=0;
for( int i=0; i<tfp.nargs(); i++ )
@@ -265,12 +265,7 @@ public class x86_64_v2 extends Machine {
};
if( tfp.nargs()-fcnt >= cargs.length )
throw Utils.TODO();
- return 0; // No stack args
- }
-
- // Return single int/ptr register. Used by CallEnd output and Return input.
- static RegMask retMask( TypeFunPtr tfp ) {
- return tfp.ret() instanceof TypeFloat ? XMM0_MASK : RAX_MASK;
+ return 1; // No stack args, plus RPC
}
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/Chapter15Test.java b/chapter21/src/test/java/com/seaofnodes/simple/Chapter15Test.java
index a850b1b8..8da5cf96 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/Chapter15Test.java
+++ b/chapter21/src/test/java/com/seaofnodes/simple/Chapter15Test.java
@@ -217,8 +217,8 @@ return ary[1] * 1000 + ary[3]; // 1 * 1000 + 6
String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/sieve.smp"));
CodeGen code = new CodeGen(src+"return sieve(arg);");
code.parse().opto();
- assertEquals("return [int];", code.print());
- assertEquals("int[ 2,3,5,7,11,13,17,19]",Eval2.eval(code, 20));
+ assertEquals("return [u32];", code.print());
+ assertEquals("u32[ 2,3,5,7,11,13,17,19]",Eval2.eval(code, 20));
}
@Test
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/Chapter19Test.java b/chapter21/src/test/java/com/seaofnodes/simple/Chapter19Test.java
index 6425fb80..9ba8e972 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/Chapter19Test.java
+++ b/chapter21/src/test/java/com/seaofnodes/simple/Chapter19Test.java
@@ -303,8 +303,8 @@ return A[1];
public void sieveOfEratosthenes() throws IOException {
String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/sieve.smp"));
CodeGen code = new CodeGen(src).parse().opto().typeCheck().instSelect("x86_64_v2", "SystemV").GCM().localSched();
- assertEquals("return [int];", code.print());
- //assertEquals("int[ 2,3,5,7,11,13,17,19]",Eval2.eval(code, 20));
+ assertEquals("return [u32];", code.print());
+ //assertEquals("u32[ 2,3,5,7,11,13,17,19]",Eval2.eval(code, 20));
}
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java b/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java
index 3f764a4c..170a7674 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java
+++ b/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java
@@ -89,7 +89,7 @@ public class Chapter21Test {
@Test public void testStringExport() throws IOException { TestC.run("stringHash"); }
@Test public void testSieve() throws IOException {
- String primes = "[2, 3, ]";
+ String primes = "25[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, ]";
TestC.run("sieve",primes);
}
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/progs/sieve.c b/chapter21/src/test/java/com/seaofnodes/simple/progs/sieve.c
index 8c28aea8..b0e85dba 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/progs/sieve.c
+++ b/chapter21/src/test/java/com/seaofnodes/simple/progs/sieve.c
@@ -3,16 +3,16 @@
typedef struct AryInt {
unsigned int len;
- unsigned int data[];
+ int data[];
} AryInt;
-extern AryInt sieve(int N);
+extern AryInt *sieve(int N);
int main() {
- AryInt ps = sieve(10);
- printf("[");
- for( int i=0; i<ps.len; i++ )
- printf("%d, ",ps.data[i]);
+ AryInt* ps = sieve(100);
+ printf("%d[",ps->len);
+ for( int i=0; i<ps->len; i++ )
+ printf("%d, ",ps->data[i]);
printf("]");
return 0;
}
diff --git a/chapter21/src/test/java/com/seaofnodes/simple/progs/sieve.smp b/chapter21/src/test/java/com/seaofnodes/simple/progs/sieve.smp
index c5c3824a..6d160b1e 100644
--- a/chapter21/src/test/java/com/seaofnodes/simple/progs/sieve.smp
+++ b/chapter21/src/test/java/com/seaofnodes/simple/progs/sieve.smp
@@ -3,7 +3,7 @@
val sieve = { int N ->
bool[] !ary = new bool[N];
// The primes less than N
- int[] !primes = new int[N>>1];
+ u32[] !primes = new u32[N>>1];
// Number of primes so far, searching at index p
int nprimes = 0, p=2;
// Find primes while p^2 < N
@@ -24,7 +24,7 @@ val sieve = { int N ->
primes[nprimes++] = p;
// Copy/shrink the result array
- int[] !rez = new int[nprimes];
+ u32[] !rez = new u32[nprimes];
for( int j=0; j < nprimes; j++ )
rez[j] = primes[j];
return rez;