summaryrefslogtreecommitdiff
path: root/chapter22
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2025-05-08 21:45:44 -0700
committerCliff Click <cliffc@acm.org>2025-05-08 21:45:44 -0700
commit239d52984594c2011ea3093e90a3aa68faad6fbd (patch)
treec0e99f8495d3d1d967cca18c6d1d7ba4f427244c /chapter22
parentef35099ea5e28dd232a5aa166aa7b2be5e4abee4 (diff)
downloadSimple-239d52984594c2011ea3093e90a3aa68faad6fbd.tar.gz
Simple-239d52984594c2011ea3093e90a3aa68faad6fbd.zip
More bubble sort test
Really a ascii scanner r/w lib. Parse a string into an array of ints, and print them back out. Couple X86 encoding bugs. Inlined Fun idom same as inlined CallEnd
Diffstat (limited to 'chapter22')
-rw-r--r--chapter22/docs/examples/BubbleSort.smp54
-rw-r--r--chapter22/docs/examples/bubble.dat2
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/FunNode.java2
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulIX86.java29
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java4
5 files changed, 77 insertions, 14 deletions
diff --git a/chapter22/docs/examples/BubbleSort.smp b/chapter22/docs/examples/BubbleSort.smp
index 025bb5a2..70f45717 100644
--- a/chapter22/docs/examples/BubbleSort.smp
+++ b/chapter22/docs/examples/BubbleSort.smp
@@ -25,6 +25,13 @@ val require = { Scan s, u8 c ->
usage();
};
+val peek = { Scan s, u8 c ->
+ skip(s);
+ if( s.buf[s.x] != c ) return false;
+ s.x++;
+ return true;
+};
+
val number = { Scan s ->
skip(s);
i32 n = 0;
@@ -37,10 +44,45 @@ val number = { Scan s ->
// 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(); };
- while( s.x < s.buf# ) {
- require(s,'[');
- int n = number(s);
- sys.libc._exit(n);
- };
- return 0;
+ require(s,'[');
+ // Array of parsed results
+ int[] !ns = new int[16];
+ i32 num = 0;
+ // Parse a list of numbers
+ if( !peek(s,']') ) { // Handle the empty list
+ // Parse "123, " until a something else
+ while( s.x < s.buf# ) {
+ int n = number(s);
+ i32 q=n;
+ ns[num++] = n;
+ if( !peek(s,',') )
+ break;
+ };
+ require(s,']'); // Close the list
+ }
+
+ // Print a list of numbers
+ sys.io.p("[ ");
+ u8[] !buf = new u8[20];
+ for( int i=0; i<num; i++ ) {
+ int x = ns[i];
+ if( !x ) { sys.io.p("0, "); continue; }
+
+ u32 log=0, q=x;
+ while( q>0 )
+ { q/=10; log++; }
+ i32 raw=log;
+ sys.libc._exit(raw);
+ // for( int j=0, a=x; j<log; j++ ) {
+ // q = x/10;
+ // buf[log-j] = '0'+(x-q*10);
+ // x = q;
+ // }
+ // int raw = buf;
+ // sys.libc.write(1,raw,log);
+ // sys.io.p(", ");
+ }
+ sys.io.p("]");
+
+ return num;
};
diff --git a/chapter22/docs/examples/bubble.dat b/chapter22/docs/examples/bubble.dat
new file mode 100644
index 00000000..6cffd25c
--- /dev/null
+++ b/chapter22/docs/examples/bubble.dat
@@ -0,0 +1,2 @@
+ [ 99, 4,3, 1]
+ \ No newline at end of file
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/FunNode.java b/chapter22/src/main/java/com/seaofnodes/simple/node/FunNode.java
index f19e1cd6..81fa627a 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/FunNode.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/FunNode.java
@@ -125,7 +125,7 @@ public class FunNode extends RegionNode {
return _folding ? super.idepth() : CodeGen.CODE.iDepthAt(1);
}
// Bypass Region idom, always assume idom is Start
- @Override public CFGNode idom(Node dep) { return cfg(1); }
+ @Override public CFGNode idom(Node dep) { return _folding && nIns()==3 ? cfg(2) : cfg(1); }
// Always in-progress until we run out of unknown callers
public boolean unknownCallers() { return nIns()<2 || in(1) instanceof StartNode; }
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulIX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulIX86.java
index a9a83fb7..d1056787 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulIX86.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulIX86.java
@@ -1,11 +1,30 @@
package com.seaofnodes.simple.node.cpus.x86_64_v2;
-import com.seaofnodes.simple.node.Node;
+import com.seaofnodes.simple.SB;
+import com.seaofnodes.simple.node.*;
+import com.seaofnodes.simple.codegen.*;
-public class MulIX86 extends ImmX86 {
- MulIX86( Node add, int imm ) { super(add,imm); }
+public class MulIX86 extends MachConcreteNode implements MachNode {
+ final int _imm;
+ MulIX86( Node add, int imm ) { super(add); _imm = imm; }
@Override public String op() { return "muli"; }
@Override public String glabel() { return "*"; }
- @Override int opcode() { return 0x69; }
- @Override int mod() { return 0; }
+ @Override public RegMask regmap(int i) { return x86_64_v2.RMASK; }
+ @Override public RegMask outregmap() { return x86_64_v2.WMASK; }
+ // Rare 3-address form
+ @Override public final void encoding( Encoding enc ) {
+ short dst = enc.reg(this ); // Also src1
+ short src = enc.reg(in(1));
+ enc.add1(x86_64_v2.rex(src, dst, 0));
+ // opcode; 0x69 or 0x6B
+ enc.add1( 0x69 + (x86_64_v2.imm8(_imm) ? 2 : 0) );
+ enc.add1( x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, src, dst) );
+ // immediate(4 bytes) 32 bits or (1 byte)8 bits
+ if( x86_64_v2.imm8(_imm) ) enc.add1(_imm);
+ else enc.add4(_imm);
+ }
+ // General form: "addi dst += #imm"
+ @Override public void asm(CodeGen code, SB sb) {
+ sb.p(code.reg(this)).p(" ").p(glabel()).p("= #").p(_imm);
+ }
}
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java
index b2902086..b8279da4 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java
@@ -27,7 +27,7 @@ public class SetX86 extends MachConcreteNode implements MachNode {
short dst = enc.reg(this );
// Optional rex, for dst
- if( dst >= 8 ) enc.add1(x86_64_v2.rex(0, dst, 0));
+ if( dst >= 4 ) enc.add1(x86_64_v2.rex(0, dst, 0, false));
enc.add1(0x0F); // opcode
enc.add1(switch (_bop) {
case "==" -> 0x94; // SETE
@@ -39,7 +39,7 @@ public class SetX86 extends MachConcreteNode implements MachNode {
enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 0, dst));
// low 8 bites are set, now zero extend for next instruction
- if( dst >= 8 ) enc.add1(x86_64_v2.rex(0, dst, 0));
+ if( dst >= 8 ) enc.add1(x86_64_v2.rex(dst, dst, 0, false));
enc.add1(0x0F); // opcode
enc.add1(0xB6); // opcode
enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, dst));