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 ++++++++------ 20 files changed, 162 insertions(+), 150 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 (limited to 'chapter22/src/main/java/com/seaofnodes') 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); + }; + }; }; -- cgit v1.2.3