From a174b75edab35f078455b4b9a737f383a3be55a3 Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Wed, 7 May 2025 17:01:53 -0700 Subject: sys.io.stdin Return stdin as a u8[]. Add echo() test. Bugfix multiple dead fcns (most of sys) removal. Bugfix Call in Loop not handling mem aliases right. No outer scope during `sys`. Several tests flip/flop return order and check exact order; TODO fix the false positives. --- .../main/java/com/seaofnodes/simple/Parser.java | 9 ++- .../com/seaofnodes/simple/codegen/CodeGen.java | 5 +- .../simple/codegen/GlobalCodeMotion.java | 4 +- .../com/seaofnodes/simple/node/CallEndMach.java | 36 +++++++++++ .../java/com/seaofnodes/simple/node/CastMach.java | 19 ++++++ .../com/seaofnodes/simple/node/ExternNode.java | 3 - .../com/seaofnodes/simple/node/MemMergeNode.java | 5 +- .../com/seaofnodes/simple/node/ReadOnlyMach.java | 19 ++++++ .../com/seaofnodes/simple/node/ReadOnlyNode.java | 2 +- .../simple/node/cpus/arm/CallEndARM.java | 8 --- .../seaofnodes/simple/node/cpus/arm/CastARM.java | 18 ------ .../com/seaofnodes/simple/node/cpus/arm/arm.java | 74 +++++++++++----------- .../simple/node/cpus/riscv/CallEndRISC.java | 8 --- .../simple/node/cpus/riscv/CastRISC.java | 18 ------ .../seaofnodes/simple/node/cpus/riscv/riscv.java | 6 +- .../simple/node/cpus/x86_64_v2/CallEndX86.java | 8 --- .../simple/node/cpus/x86_64_v2/CastX86.java | 16 ----- .../simple/node/cpus/x86_64_v2/CmpMemX86.java | 2 +- .../simple/node/cpus/x86_64_v2/x86_64_v2.java | 6 +- .../main/java/com/seaofnodes/simple/sys/sys.smp | 46 ++++++++------ .../java/com/seaofnodes/simple/Chapter18Test.java | 2 +- .../java/com/seaofnodes/simple/Chapter19Test.java | 4 +- .../java/com/seaofnodes/simple/Chapter20Test.java | 2 +- .../java/com/seaofnodes/simple/Chapter21Test.java | 2 +- .../java/com/seaofnodes/simple/Chapter22Test.java | 18 ++++++ .../test/java/com/seaofnodes/simple/progs/echo.smp | 3 + 26 files changed, 188 insertions(+), 155 deletions(-) create mode 100644 chapter22/src/main/java/com/seaofnodes/simple/node/CallEndMach.java create mode 100644 chapter22/src/main/java/com/seaofnodes/simple/node/CastMach.java create mode 100644 chapter22/src/main/java/com/seaofnodes/simple/node/ReadOnlyMach.java delete mode 100644 chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallEndARM.java delete mode 100644 chapter22/src/main/java/com/seaofnodes/simple/node/cpus/arm/CastARM.java delete mode 100644 chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallEndRISC.java delete mode 100644 chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CastRISC.java delete mode 100644 chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallEndX86.java delete mode 100644 chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CastX86.java create mode 100644 chapter22/src/test/java/com/seaofnodes/simple/progs/echo.smp (limited to 'chapter22') diff --git a/chapter22/src/main/java/com/seaofnodes/simple/Parser.java b/chapter22/src/main/java/com/seaofnodes/simple/Parser.java index eae823eb..21d6c359 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter22/src/main/java/com/seaofnodes/simple/Parser.java @@ -448,8 +448,11 @@ public class Parser { // At exit the false control is the current control, and // the scope is the exit scope after the exit test. - _xScopes.pop(); - _xScopes.push(exit); + // During sys parsing, there is no xscope here. + if( !_xScopes.isEmpty() ) { + _xScopes.pop(); + _xScopes.push( exit ); + } _scope = exit; return ZERO; } @@ -1461,7 +1464,7 @@ public class Parser { throw error("Expected a function but got "+expr._type.glb(false).str()); expr.keep(); // Keep while parsing args - Ary args = new Ary(Node.class); + Ary args = new Ary<>( Node.class ); args.push(null); // Space for ctrl,mem args.push(null); while( !peek(')') ) { diff --git a/chapter22/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java b/chapter22/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java index c3e211ea..74fa1f71 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java +++ b/chapter22/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java @@ -174,13 +174,16 @@ public class CodeGen { // can call any function) to having a correct (but conservative) CG. FunNode main = link(_main); - for( Node use : _start._outputs ) + for( int i=0; i<_start.nOuts(); i++ ) { + Node use = _start.out(i); if( use instanceof FunNode fun && fun.nIns()==2 && fun.in(1)==_start && fun != main && (fun._name==null || fun._name.startsWith("sys.")) ) { add(fun).setDef(1,Parser.XCTRL); addAll(fun._outputs); + i--; } + } _iter.iterate(this); _tOpto = (int)(System.currentTimeMillis() - t0); diff --git a/chapter22/src/main/java/com/seaofnodes/simple/codegen/GlobalCodeMotion.java b/chapter22/src/main/java/com/seaofnodes/simple/codegen/GlobalCodeMotion.java index 78e2f75f..f76b35ef 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/codegen/GlobalCodeMotion.java +++ b/chapter22/src/main/java/com/seaofnodes/simple/codegen/GlobalCodeMotion.java @@ -167,7 +167,9 @@ public abstract class GlobalCodeMotion { // Load-use directly defines memory (memuse._type instanceof TypeMem || // Load-use indirectly defines memory - (memuse._type instanceof TypeTuple tt && tt._types[ld._alias] instanceof TypeMem)) ) + (memuse._type instanceof TypeTuple tt && tt._types[ld._alias] instanceof TypeMem) || + // Load-use use/defs memory + memuse instanceof CallNode) ) continue outer; // All uses done, schedule diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/CallEndMach.java b/chapter22/src/main/java/com/seaofnodes/simple/node/CallEndMach.java new file mode 100644 index 00000000..47cab07a --- /dev/null +++ b/chapter22/src/main/java/com/seaofnodes/simple/node/CallEndMach.java @@ -0,0 +1,36 @@ +package com.seaofnodes.simple.node; + +import com.seaofnodes.simple.SB; +import com.seaofnodes.simple.codegen.*; + +public class CallEndMach extends CallEndNode implements MachNode { + public CallEndMach( CallEndNode n ) { super(n); } + // MachNode specifics, shared across all CPUs + public int _xslot; + private RegMask _retMask; + private RegMask _kills; + public void cacheRegs(CodeGen code) { + // Return mask depends on TFP (either GPR or FPR) + _retMask = code._mach.retMask(call().tfp()); + // Kill mask is all caller-saves, and any mirror stack slots for args + // in registers. + RegMaskRW kills = code._callerSave.copy(); + // Start of stack slots + int maxReg = code._mach.regs().length; + // Incoming function arg slots, all low numbered in the RA + int fslot = fun()._maxArgSlot; + // Killed slots for this calls outgoing args + int xslot = code._mach.maxArgSlot(call().tfp()); + _xslot = (maxReg+fslot)+xslot; + for( int i=0; i new AddFARM(addf); - case AddNode add -> add(add); - case AndNode and -> and(and); - case BoolNode bool -> cmp(bool); - case CallNode call -> call(call); - case CastNode cast -> new CastARM(cast); - case CallEndNode cend -> new CallEndARM(cend); - case CProjNode c -> new CProjNode(c); - case ConstantNode con -> con(con); - case DivFNode divf -> new DivFARM(divf); - case DivNode div -> new DivARM(div); - case FunNode fun -> new FunARM(fun); - case IfNode iff -> jmp(iff); - case LoadNode ld -> ld(ld); - case MemMergeNode mem -> new MemMergeNode(mem); - case MinusNode neg -> new NegARM(neg); - case MulFNode mulf -> new MulFARM(mulf); - case MulNode mul -> new MulARM(mul); - case NewNode nnn -> new NewARM(nnn); - case NotNode not -> new NotARM(not); - case OrNode or -> or(or); - case ParmNode parm -> new ParmARM(parm); - case PhiNode phi -> new PhiNode(phi); - case ProjNode prj -> new ProjARM(prj); - case ReadOnlyNode read -> new ReadOnlyNode(read); - case ReturnNode ret -> new RetARM(ret,ret.fun()); - case SarNode sar -> asr(sar); - case ShlNode shl -> lsl(shl); - case ShrNode shr -> lsr(shr); + case AddFNode addf -> new AddFARM(addf); + case AddNode add -> add(add); + case AndNode and -> and(and); + case BoolNode bool -> cmp(bool); + case CallNode call -> call(call); + case CastNode cast -> new CastMach(cast); + case CallEndNode cend-> new CallEndMach(cend); + case CProjNode c -> new CProjNode(c); + case ConstantNode con-> con(con); + case DivFNode divf -> new DivFARM(divf); + case DivNode div -> new DivARM(div); + case FunNode fun -> new FunARM(fun); + case IfNode iff -> jmp(iff); + case LoadNode ld -> ld(ld); + case MemMergeNode mem-> new MemMergeNode(mem); + case MinusNode neg -> new NegARM(neg); + case MulFNode mulf -> new MulFARM(mulf); + case MulNode mul -> new MulARM(mul); + case NewNode nnn -> new NewARM(nnn); + case NotNode not -> new NotARM(not); + case OrNode or -> or(or); + case ParmNode parm -> new ParmARM(parm); + case PhiNode phi -> new PhiNode(phi); + case ProjNode prj -> new ProjARM(prj); + case ReadOnlyNode read -> new ReadOnlyMach(read); + case ReturnNode ret -> new RetARM(ret,ret.fun()); + case SarNode sar -> asr(sar); + case ShlNode shl -> lsl(shl); + case ShrNode shr -> lsr(shr); case StartNode start -> new StartNode(start); - case StopNode stop -> new StopNode(stop); - case StoreNode st -> st(st); - case SubFNode subf -> new SubFARM(subf); - case SubNode sub -> sub(sub); - case ToFloatNode tfn-> new I2F8ARM(tfn); - case XorNode xor -> xor(xor); - - case LoopNode loop -> new LoopNode(loop); + case StopNode stop -> new StopNode(stop); + case StoreNode st -> st(st); + case SubFNode subf -> new SubFARM(subf); + case SubNode sub -> sub(sub); + case ToFloatNode tfn -> new I2F8ARM(tfn); + case XorNode xor -> xor(xor); + + 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/node/cpus/riscv/CallEndRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallEndRISC.java deleted file mode 100644 index 7df68e77..00000000 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallEndRISC.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.seaofnodes.simple.node.cpus.riscv; - -import com.seaofnodes.simple.node.CallEndNode; -import com.seaofnodes.simple.node.MachNode; - -public class CallEndRISC extends CallEndNode implements MachNode { - CallEndRISC( CallEndNode cend ) { super(cend); } -} diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CastRISC.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CastRISC.java deleted file mode 100644 index c404aaa5..00000000 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CastRISC.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.seaofnodes.simple.node.cpus.riscv; - -import com.seaofnodes.simple.SB; -import com.seaofnodes.simple.codegen.CodeGen; -import com.seaofnodes.simple.codegen.Encoding; -import com.seaofnodes.simple.codegen.RegMask; -import com.seaofnodes.simple.node.CastNode; -import com.seaofnodes.simple.node.MachNode; - -public class CastRISC extends CastNode implements MachNode { - public CastRISC( CastNode cast ) { super(cast); } - @Override public String op() { return label(); } - @Override public RegMask regmap(int i) { assert i==1; return RegMask.FULL; } - @Override public RegMask outregmap() { return RegMask.FULL; } - @Override public int twoAddress( ) { return 1; } - @Override public void encoding( Encoding enc ) { } - @Override public void asm(CodeGen code, SB sb) { _t.print(sb.p(code.reg(in(1))).p(" isa ")); } -} 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 c4cde159..c1ad1647 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 @@ -327,8 +327,8 @@ public class riscv extends Machine { case AndNode and -> and(and); case BoolNode bool -> cmp(bool); case CallNode call -> call(call); - case CastNode cast -> new CastRISC(cast); - case CallEndNode cend -> new CallEndRISC(cend); + case CastNode cast -> new CastMach(cast); + case CallEndNode cend -> new CallEndMach(cend); case CProjNode c -> new CProjNode(c); case ConstantNode con -> con(con); case DivFNode divf -> new DivFRISC(divf); @@ -346,7 +346,7 @@ public class riscv extends Machine { case ParmNode parm -> new ParmRISC(parm); case PhiNode phi -> new PhiNode(phi); case ProjNode prj -> prj(prj); - case ReadOnlyNode read-> new ReadOnlyNode(read); + case ReadOnlyNode read-> new ReadOnlyMach(read); case ReturnNode ret -> new RetRISC(ret, ret.fun()); case SarNode sar -> sra(sar); case ShlNode shl -> sll(shl); diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallEndX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallEndX86.java deleted file mode 100644 index ce8b993f..00000000 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallEndX86.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.seaofnodes.simple.node.cpus.x86_64_v2; - -import com.seaofnodes.simple.node.CallEndNode; -import com.seaofnodes.simple.node.MachNode; - -public class CallEndX86 extends CallEndNode implements MachNode { - CallEndX86( CallEndNode cend ) { super(cend); } -} diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CastX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CastX86.java deleted file mode 100644 index 9537cfb3..00000000 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CastX86.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.seaofnodes.simple.node.cpus.x86_64_v2; - -import com.seaofnodes.simple.SB; -import com.seaofnodes.simple.codegen.*; -import com.seaofnodes.simple.node.CastNode; -import com.seaofnodes.simple.node.MachNode; - -public class CastX86 extends CastNode implements MachNode { - CastX86( CastNode cast ) { super(cast); } - @Override public String op() { return label(); } - @Override public RegMask regmap(int i) { assert i==1; return RegMask.FULL; } - @Override public RegMask outregmap() { return RegMask.FULL; } - @Override public int twoAddress( ) { return 1; } - @Override public void encoding( Encoding enc ) { } - @Override public void asm(CodeGen code, SB sb) { _t.print(sb.p(code.reg(in(1))).p(" isa ")); } -} diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpMemX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpMemX86.java index 489853eb..a1845363 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpMemX86.java +++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpMemX86.java @@ -11,7 +11,7 @@ public class CmpMemX86 extends MemOpX86 { CmpMemX86( BoolNode bool, LoadNode ld, Node base, Node idx, int off, int scale, int imm, Node val, boolean swap ) { super(bool,ld, base, idx, off, scale, imm, val ); _swap = swap; - assert !_swap || val() == null || bool.op()=="==" || bool.op()=="!="; // Cannot swap with immediate + assert !_swap || val() != null || bool.op()=="==" || bool.op()=="!="; // Cannot swap with immediate } @Override public String op() { return ((val()==null && _imm==0) ? "test" : "cmp") + _sz; } @Override public RegMask outregmap() { return x86_64_v2.FLAGS_MASK; } diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java index bf51f2cb..35541346 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java +++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java @@ -344,9 +344,9 @@ public class x86_64_v2 extends Machine { case AndNode and -> and(and); case BoolNode bool -> cmp(bool); case CProjNode c -> new CProjNode(c); - case CallEndNode cend -> new CallEndX86(cend); + case CallEndNode cend -> new CallEndMach(cend); case CallNode call -> call(call); - case CastNode cast -> new CastX86(cast); + case CastNode cast -> new CastMach(cast); case ConstantNode con -> con(con); case DivFNode divf -> new DivFX86(divf); case DivNode div -> new DivX86(div); @@ -363,7 +363,7 @@ public class x86_64_v2 extends Machine { case ParmNode parm -> new ParmX86(parm); case PhiNode phi -> new PhiNode(phi); case ProjNode prj -> prj(prj); - case ReadOnlyNode read-> new ReadOnlyNode(read); + case ReadOnlyNode read-> new ReadOnlyMach(read); case ReturnNode ret -> new RetX86(ret, ret.fun()); case SarNode sar -> sar(sar); case ShlNode shl -> shl(shl); diff --git a/chapter22/src/main/java/com/seaofnodes/simple/sys/sys.smp b/chapter22/src/main/java/com/seaofnodes/simple/sys/sys.smp index bc0492e8..4ac925db 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/sys/sys.smp +++ b/chapter22/src/main/java/com/seaofnodes/simple/sys/sys.smp @@ -10,8 +10,8 @@ struct sys { { i32 i64 u32 -> u32 } write = "C"; // fd buf len -> len { i32 i64 u32 -> u32 } read = "C"; - //// status - //{ i32 -> i32 } _exit = "C"; + // status + { i32 -> i32 } _exit = "C"; // addr len prot flags fd off -> void* { i64 i64 i32 i32 i32 i32 -> i64 } mmap = "C"; // mmap flags @@ -22,6 +22,13 @@ struct sys { i32 MAP_PRIVATE = 2; i32 MAP_ANON = 32; }; + struct ary { + val copy = { u8[] dst, int doff, u8[~] src, int soff, int len -> + for( int i=0; i @@ -29,22 +36,23 @@ struct sys { return sys.libc.write(1,ptr,str#); }; - //// Return stdin as a u8[] - //val stdin = { -> - // var buf = new u8[8*1024]; - // i64 ptr = buf; - // int len = 0; - // while( true ) { - // int rez = sys.libc.read(0,ptr,buf#); - // if( rez < 0 ) sys.libc._exit(sys.libc.errno); - // if( rez < buf# ) - // break; - // sys.libc._exit(-2); // Need to implement - // } - // // Compress - // var rez = new u8[len]; - // sys.ary.copy(buf,0,rez,0,len); - // return rez; - //}; + // Return stdin as a u8[] + val stdin = { -> + var buf = new u8[8*1024]; + i64 ptr = buf; + int len = 0; + while( true ) { + int rez = sys.libc.read(0,ptr,buf#); + if( rez < 0 ) sys.libc._exit(sys.libc.errno); + len += rez; + if( rez < buf# ) + break; + sys.libc._exit(-2); // Need to implement + } + // Compress + var dst = new u8[len]; + return sys.ary.copy(dst,0,buf,0,len); + }; + }; }; diff --git a/chapter22/src/test/java/com/seaofnodes/simple/Chapter18Test.java b/chapter22/src/test/java/com/seaofnodes/simple/Chapter18Test.java index cd02fbca..00d41a23 100644 --- a/chapter22/src/test/java/com/seaofnodes/simple/Chapter18Test.java +++ b/chapter22/src/test/java/com/seaofnodes/simple/Chapter18Test.java @@ -116,7 +116,7 @@ var fcn = arg ? { int x -> x*x; } : { int x -> x+x; }; return fcn(3); """); code.parse().opto(); - assertEquals("Stop[ return (Parm_x($fun2,int,3)<<1); return #2; return (Parm_x($fun1,int,3)*x); ]", code._stop.toString()); + assertEquals("Stop[ return (Parm_x($fun2,int,3)<<1); return (Parm_x($fun1,int,3)*x); return #2; ]", code._stop.toString()); assertEquals("6", Eval2.eval(code, 0)); assertEquals("9", Eval2.eval(code, 1)); } diff --git a/chapter22/src/test/java/com/seaofnodes/simple/Chapter19Test.java b/chapter22/src/test/java/com/seaofnodes/simple/Chapter19Test.java index c6a701a4..b370cd3c 100644 --- a/chapter22/src/test/java/com/seaofnodes/simple/Chapter19Test.java +++ b/chapter22/src/test/java/com/seaofnodes/simple/Chapter19Test.java @@ -25,7 +25,7 @@ return 0; public void testString() throws IOException { String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/stringHash.smp")); CodeGen code = new CodeGen(src).parse().opto().typeCheck().GCM().localSched(); - assertEquals("Stop[ return Phi(Region,1,0,0,1); return Phi(Region,._hashCode,Phi(Region,123456789,Phi(Loop,0,(.[]+((Phi_hash<<5)-Phi_hash))))); ]", code._stop.toString()); + assertEquals("Stop[ return Phi(Region,._hashCode,Phi(Region,123456789,Phi(Loop,0,(.[]+((Phi_hash<<5)-Phi_hash))))); return Phi(Region,1,0,0,1); ]", code._stop.toString()); //assertEquals("-4898613127354160978", Eval2.eval(code, 2)); } @@ -316,7 +316,7 @@ val fcn = arg ? { int x -> x*x; } : { int x -> x+x; }; return fcn(2)*10 + fcn(3); """); code.driver(Phase.LocalSched,"x86_64_v2", "SystemV"); - assertEquals("Stop[ return (shli,Parm_x($fun2,int)); return (add,#2,(muli,#2)); return (mul,Parm_x($fun1,int),x); ]", code.print()); + assertEquals("Stop[ return (shli,Parm_x($fun2,int)); return (mul,Parm_x($fun1,int),x); return (add,#2,(muli,#2)); ]", code.print()); } @Test diff --git a/chapter22/src/test/java/com/seaofnodes/simple/Chapter20Test.java b/chapter22/src/test/java/com/seaofnodes/simple/Chapter20Test.java index 4c4ac4e4..f0b31065 100644 --- a/chapter22/src/test/java/com/seaofnodes/simple/Chapter20Test.java +++ b/chapter22/src/test/java/com/seaofnodes/simple/Chapter20Test.java @@ -104,7 +104,7 @@ return sqrt(arg) + sqrt(cast_int); 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,"arm" , "SystemV", 3,null); + testCPU(src,"arm" , "SystemV", 6,null); } @Test diff --git a/chapter22/src/test/java/com/seaofnodes/simple/Chapter21Test.java b/chapter22/src/test/java/com/seaofnodes/simple/Chapter21Test.java index c6e0a3bd..96e6c5ff 100644 --- a/chapter22/src/test/java/com/seaofnodes/simple/Chapter21Test.java +++ b/chapter22/src/test/java/com/seaofnodes/simple/Chapter21Test.java @@ -65,7 +65,7 @@ public class Chapter21Test { 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,"arm" , "SystemV", 3,null); + testCPU(src,"arm" , "SystemV", 6,null); } @Test public void testStringExport() 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 eddba242..baca507c 100644 --- a/chapter22/src/test/java/com/seaofnodes/simple/Chapter22Test.java +++ b/chapter22/src/test/java/com/seaofnodes/simple/Chapter22Test.java @@ -144,4 +144,22 @@ return sum(is); } + @Test @Ignore + public void testEcho() throws IOException { + String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/echo.smp")); + TestC.run(src,TestC.CALL_CONVENTION,null,null,"build/objs/echo","","",0); + + // Evaluate on RISC5 emulator + EvalRisc5 R5 = TestRisc5.build("echo", 0, 2, false); + int trap = R5.step(100); + assertEquals(0,trap); + assertEquals(0,R5.regs[riscv.A0]); + + // Evaluate on ARM emulator + EvalArm64 arm = TestArm64.build("echo", 0, 2, false); + trap = arm.step(100); + assertEquals(0,trap); + assertEquals(0,arm.regs[0]); + } + } diff --git a/chapter22/src/test/java/com/seaofnodes/simple/progs/echo.smp b/chapter22/src/test/java/com/seaofnodes/simple/progs/echo.smp new file mode 100644 index 00000000..8eafd73b --- /dev/null +++ b/chapter22/src/test/java/com/seaofnodes/simple/progs/echo.smp @@ -0,0 +1,3 @@ +// -*- mode: java; -*- +// Echo stdin to stdout. +return sys.io.p( sys.io.stdin() ); -- cgit v1.2.3