summaryrefslogtreecommitdiff
path: root/chapter22
diff options
context:
space:
mode:
Diffstat (limited to 'chapter22')
-rw-r--r--chapter22/docs/examples/BubbleSort.smp30
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/XorIRISC.java1
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java2
-rw-r--r--chapter22/src/test/java/com/seaofnodes/simple/Chapter20Test.java2
-rw-r--r--chapter22/src/test/java/com/seaofnodes/simple/Chapter22Test.java4
-rw-r--r--chapter22/src/test/java/com/seaofnodes/simple/EvalArm64.java16
-rw-r--r--chapter22/src/test/java/com/seaofnodes/simple/EvalRisc5.java16
7 files changed, 50 insertions, 21 deletions
diff --git a/chapter22/docs/examples/BubbleSort.smp b/chapter22/docs/examples/BubbleSort.smp
index f6b30752..a80d6bd8 100644
--- a/chapter22/docs/examples/BubbleSort.smp
+++ b/chapter22/docs/examples/BubbleSort.smp
@@ -1,5 +1,10 @@
// -*- mode: java; -*-
+// An implementation of
+// https://sampleprograms.io/projects/bubble-sort/
+//
+// Bubble sort, with reading (parsing) and writing (formatting) the data.
+
val _exit = { u8[~] msg ->
sys.io.p(msg);
sys.libc._exit(1);
@@ -40,6 +45,19 @@ val number = { Scan s ->
return n;
};
+val sort = { int[] ns, int len ->
+ var done = false;
+ while( !done ) {
+ done = true;
+ for( var i = 0; i < len-1; i++ )
+ if( ns[i] > ns[i+1] ) {
+ int tmp = ns[i];
+ ns[i] = ns[i+1];
+ ns[i+1] = tmp; // Swap
+ done = false;
+ }
+ }
+};
// Read from stdin a line of the form "[ 4, 3, 2, 1]" and print it sorted.
val main = { ->
@@ -47,23 +65,26 @@ val main = { ->
require(s,'[');
// Array of parsed results
int[] !ns = new int[16];
- i32 num = 0;
+ i32 len = 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);
- ns[num++] = n;
+ ns[len++] = n;
if( !peek(s,',') )
break;
};
require(s,']'); // Close the list
}
+ // Bubble sort array of integers
+ sort(ns,len);
+
// Print a list of numbers
sys.io.p("[ ");
u8[] !junk = new u8[1];
- for( int i=0; i<num; i++ ) {
+ for( int i=0; i<len; i++ ) {
int x = ns[i];
if( !x ) { sys.io.p("0, "); continue; }
@@ -81,6 +102,5 @@ val main = { ->
sys.io.p(", ");
}
sys.io.p("]");
-
- return num;
+ return 0;
};
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/XorIRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/XorIRISC.java
index 61f25be2..27098033 100644
--- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/XorIRISC.java
+++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/XorIRISC.java
@@ -5,6 +5,7 @@ import com.seaofnodes.simple.node.Node;
public class XorIRISC extends ImmRISC {
public XorIRISC( Node and, int imm) { super(and,imm); }
+ public XorIRISC( Node and, int imm, boolean pop) { super(and,imm,pop); }
@Override int opcode() { return riscv.OP_IMM; }
@Override int func3() { return 4; }
@Override public String glabel() { return "^"; }
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 8e722563..3b8ff100 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
@@ -420,7 +420,7 @@ public class riscv extends Machine {
? new SetIRISC(bool, (int)ti.value(),false)
: new SetRISC(bool, false);
// x <= y - flip and negate; !(y < x); `slt tmp=y,x; xori dst=tmp,#1`
- case "<=" -> new XorIRISC(new SetRISC(bool.swap12(), false),1);
+ case "<=" -> new XorIRISC(new SetRISC(bool.swap12(), false),1,false);
// x == y - sub and vs0 == `sub tmp=x-y; sltu dst=tmp,#1`
case "==" -> new SetIRISC(new SubRISC(bool),1,true);
default -> throw Utils.TODO();
diff --git a/chapter22/src/test/java/com/seaofnodes/simple/Chapter20Test.java b/chapter22/src/test/java/com/seaofnodes/simple/Chapter20Test.java
index 4c4ac4e4..f442ae1a 100644
--- a/chapter22/src/test/java/com/seaofnodes/simple/Chapter20Test.java
+++ b/chapter22/src/test/java/com/seaofnodes/simple/Chapter20Test.java
@@ -66,7 +66,7 @@ val sqrt = { int x ->
int cast_int = arg+2;
return sqrt(arg) + sqrt(cast_int);
""";
- testCPU(src,"x86_64_v2", "Win64" ,23,null);
+ testCPU(src,"x86_64_v2", "Win64" ,55,null);
testCPU(src,"riscv" , "SystemV",19,null);
testCPU(src,"arm" , "SystemV",19,null);
}
diff --git a/chapter22/src/test/java/com/seaofnodes/simple/Chapter22Test.java b/chapter22/src/test/java/com/seaofnodes/simple/Chapter22Test.java
index 304fb1cf..4823dff8 100644
--- a/chapter22/src/test/java/com/seaofnodes/simple/Chapter22Test.java
+++ b/chapter22/src/test/java/com/seaofnodes/simple/Chapter22Test.java
@@ -116,12 +116,14 @@ return cc.cz;
int trap = R5.step(100);
assertEquals(0,trap);
assertEquals(0,R5.regs[riscv.A0]);
+ assertEquals("Hello, World!",R5._stdout.toString());
// Evaluate on ARM emulator
EvalArm64 arm = TestArm64.build("helloWorld", 0, 2, false);
trap = arm.step(100);
assertEquals(0,trap);
assertEquals(0,arm.regs[0]);
+ assertEquals("Hello, World!",arm._stdout.toString());
}
@Test
@@ -131,7 +133,7 @@ int N=4;
i32[] !is = new i32[N];
for( int i=0; i<N; i++ )
is[i] = i*i;
-val sum = { i32[~] is ->
+val sum = { i32[~] is -> // final array
int sum=0;
for( int i=0; i<is#; i++ )
sum += is[i];
diff --git a/chapter22/src/test/java/com/seaofnodes/simple/EvalArm64.java b/chapter22/src/test/java/com/seaofnodes/simple/EvalArm64.java
index 08cd7c8d..981799bb 100644
--- a/chapter22/src/test/java/com/seaofnodes/simple/EvalArm64.java
+++ b/chapter22/src/test/java/com/seaofnodes/simple/EvalArm64.java
@@ -2,8 +2,7 @@ package com.seaofnodes.simple;
import com.seaofnodes.simple.codegen.Encoding;
import com.seaofnodes.simple.node.cpus.arm.arm;
-
-import java.io.PrintStream;
+import java.io.ByteArrayOutputStream;
public class EvalArm64 {
// Memory image, always 0-based
@@ -15,8 +14,13 @@ public class EvalArm64 {
final double[] fregs;
int _pc;
+
// Start of free memory for allocation
int _heap;
+
+ // Standard out and err streams
+ ByteArrayOutputStream _stdout, _stderr;
+
// Cycle counters
int _cycle;
@@ -340,12 +344,12 @@ public class EvalArm64 {
rdid = -1;
}
if( pc == Encoding.SENTINEL_WRITE ) {
- PrintStream ps = switch((int)regs[0]) {
- case 1 -> System.out;
- case 2 -> System.err;
+ ByteArrayOutputStream baos = switch((int)regs[0]) {
+ case 1 -> _stdout==null ? (_stdout = new ByteArrayOutputStream()) : _stdout;
+ case 2 -> _stderr==null ? (_stderr = new ByteArrayOutputStream()) : _stderr;
default -> throw new IllegalArgumentException();
};
- ps.write(_buf,(int)regs[1],(int)regs[2]);
+ baos.write(_buf,(int)regs[1],(int)regs[2]);
regs[0] = regs[2];
pc = (int)rval;
rdid = -1;
diff --git a/chapter22/src/test/java/com/seaofnodes/simple/EvalRisc5.java b/chapter22/src/test/java/com/seaofnodes/simple/EvalRisc5.java
index d2255278..0a1c034f 100644
--- a/chapter22/src/test/java/com/seaofnodes/simple/EvalRisc5.java
+++ b/chapter22/src/test/java/com/seaofnodes/simple/EvalRisc5.java
@@ -10,11 +10,10 @@
import com.seaofnodes.simple.codegen.Encoding;
import com.seaofnodes.simple.node.cpus.riscv.riscv;
-
-import java.io.PrintStream;
+import java.io.ByteArrayOutputStream;
import java.util.Arrays;
- public class EvalRisc5 {
+public class EvalRisc5 {
// Memory image, always 0-based
public final byte[] _buf;
@@ -29,6 +28,9 @@ import java.util.Arrays;
// Start of free memory for allocation
int _heap;
+ // Standard out and err streams
+ ByteArrayOutputStream _stdout, _stderr;
+
// Cycle counters
int _cycle;
@@ -102,12 +104,12 @@ import java.util.Arrays;
rval = pc + 4;
pc = pc + reladdy - 4;
if( pc+4 == Encoding.SENTINEL_WRITE ) {
- PrintStream ps = switch((int)regs[10]) {
- case 1 -> System.out;
- case 2 -> System.err;
+ ByteArrayOutputStream baos = switch((int)regs[10]) {
+ case 1 -> _stdout==null ? (_stdout = new ByteArrayOutputStream()) : _stdout;
+ case 2 -> _stderr==null ? (_stderr = new ByteArrayOutputStream()) : _stderr;
default -> throw new IllegalArgumentException();
};
- ps.write(_buf,(int)regs[11],(int)regs[12]);
+ baos.write(_buf,(int)regs[11],(int)regs[12]);
regs[10] = regs[12];
rdid = 0;
pc = (int)(rval - 4); // Unwind PC, as-if returned from write