diff options
Diffstat (limited to 'chapter30/src/main/java/com/seaofnodes/simple/node')
11 files changed, 79 insertions, 17 deletions
diff --git a/chapter30/src/main/java/com/seaofnodes/simple/node/CallNode.java b/chapter30/src/main/java/com/seaofnodes/simple/node/CallNode.java index 91d27330..ac5e4eee 100644 --- a/chapter30/src/main/java/com/seaofnodes/simple/node/CallNode.java +++ b/chapter30/src/main/java/com/seaofnodes/simple/node/CallNode.java @@ -242,7 +242,7 @@ public class CallNode extends CFGNode { if( !tfp.notNull() ) return Parser.error( "Might be null calling "+tfp, _loc); if( nargs() != tfp.nargs() ) - return Parser.error( "Expecting "+tfp.nargs()+" arguments, but found "+nargs(), _loc); + return Parser.error( "Expecting "+(tfp.nargs()-1)+" arguments, but found "+(nargs()-1), _loc); // Check for args for( int i=0; i<tfp.nargs(); i++ ) diff --git a/chapter30/src/main/java/com/seaofnodes/simple/node/FldOffNode.java b/chapter30/src/main/java/com/seaofnodes/simple/node/FldOffNode.java index 09e5eac8..e49162f4 100644 --- a/chapter30/src/main/java/com/seaofnodes/simple/node/FldOffNode.java +++ b/chapter30/src/main/java/com/seaofnodes/simple/node/FldOffNode.java @@ -49,7 +49,7 @@ public class FldOffNode extends TypeNode { @Override public Parser.ParseException err() { if( in(1)._type instanceof TypeMemPtr tmp && tmp._obj._fref ) - return Parser.error("Unknown struct type '"+tmp._obj._name+"'",null); + return Parser.error("Unknown struct type '"+tmp._obj._name+"'",_loc); return null; } } diff --git a/chapter30/src/main/java/com/seaofnodes/simple/node/FormatNode.java b/chapter30/src/main/java/com/seaofnodes/simple/node/FormatNode.java new file mode 100644 index 00000000..d34b342d --- /dev/null +++ b/chapter30/src/main/java/com/seaofnodes/simple/node/FormatNode.java @@ -0,0 +1,33 @@ +package com.seaofnodes.simple.node; + +import com.seaofnodes.simple.parser.Lexer; +import com.seaofnodes.simple.parser.Parser; +import com.seaofnodes.simple.type.*; + +/** Resolve default formatting through normal type flow, including forward + * references. Valid programs fold this selector before serialization/codegen. */ +public final class FormatNode extends Node { + private final Lexer _site; + public FormatNode(Node value, Node ints, Node floats, Node strings, Lexer site) { + super(null,value,ints,floats,strings); + _site=site; + } + @Override public String label() { return "Format"; } + private int choice() { + Type t=in(1)._type; + if( t instanceof TypeInteger ) return 2; + if( t instanceof TypeFloat ) return 3; + if( t instanceof TypeMemPtr p && !p.nullable() && p._obj.isAry() && + p._obj._name.equals("[]u8") ) return 4; + return 0; + } + @Override public Type compute() { + if( in(1)._type.isHigh() ) return Type.TOP; + int c=choice(); + return c==0 ? in(2)._type.meet(in(3)._type).meet(in(4)._type) : in(c)._type; + } + @Override public Node idealize() { int c=choice(); return c==0 ? null : in(c); } + @Override public Parser.ParseException err() { + return Parser.error("Cannot format "+in(1)._type+"; expected an integer, float, or byte string",_site); + } +} diff --git a/chapter30/src/main/java/com/seaofnodes/simple/node/LoadNode.java b/chapter30/src/main/java/com/seaofnodes/simple/node/LoadNode.java index 85ab29f9..eb78ed1f 100644 --- a/chapter30/src/main/java/com/seaofnodes/simple/node/LoadNode.java +++ b/chapter30/src/main/java/com/seaofnodes/simple/node/LoadNode.java @@ -395,6 +395,9 @@ public class LoadNode extends MemOpNode { // load will need to zero/sign-extend. private Node extend(Node val) { if( !(declaredType() instanceof TypeInteger ti) ) return val; + // A typed load can already know its width while the stored value is + // still unresolved. Do not replace it with an untyped shift/and chain. + if( !(val._type instanceof TypeInteger) ) { addDep(val); return null; } if( ti._min==0 ) // Unsigned return new AndNode(null,val,con(ti._max)); // Signed extension diff --git a/chapter30/src/main/java/com/seaofnodes/simple/node/ScopeNode.java b/chapter30/src/main/java/com/seaofnodes/simple/node/ScopeNode.java index 1130cf44..80d2aa0a 100644 --- a/chapter30/src/main/java/com/seaofnodes/simple/node/ScopeNode.java +++ b/chapter30/src/main/java/com/seaofnodes/simple/node/ScopeNode.java @@ -638,6 +638,7 @@ public class ScopeNode extends MemMergeNode { int i = _guards._len; while( i > 0 ) { Node cast = _guards.at(--i); + if( cast instanceof FunNode ) break; // Function boundary if( cast instanceof CFGNode ) continue; // Marker between guard sets Node xpred = _guards.at(--i); if( xpred == pred ) diff --git a/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/arm/ExtendARM.java b/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/arm/ExtendARM.java index 814a82c2..da9afe71 100644 --- a/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/arm/ExtendARM.java +++ b/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/arm/ExtendARM.java @@ -6,14 +6,21 @@ import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.type.TypeInteger; import com.seaofnodes.simple.util.SB; -// Convert a narrow C return register to Simple's full-width integer value. +// Normalize narrow parameters and C return values to full-width integers. public class ExtendARM extends MachConcreteNode { final int _bits; final boolean _signed; ExtendARM(ProjNode prj, TypeInteger ret) { - super(prj); - _inputs.set(0,null); - _inputs.add(new ProjARM(prj)); + this(prj,new ProjARM(prj),ret); + } + ExtendARM(ParmNode parm, TypeInteger decl) { + this(parm,new ParmARM(parm),decl); + } + private ExtendARM(Node ideal, Node value, TypeInteger ret) { + super(ideal); + _inputs.clear(); + _inputs.add(null); + _inputs.add(value); _bits = 8 << ret.log_size(); _signed = ret._min < 0; } diff --git a/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java b/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java index 3c965da5..ee7b0fc3 100644 --- a/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java +++ b/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java @@ -332,7 +332,8 @@ public class arm extends Machine { case NewNode nnn -> new NewARM(nnn); case NotNode not -> new NotARM(not); case OrNode or -> or(or); - case ParmNode parm -> new ParmARM(parm); + case ParmNode parm -> parm._declaredType instanceof TypeInteger ti && ti.log_size()<3 + ? new ExtendARM(parm,ti) : new ParmARM(parm); case BulkMemPhiNode phi -> new BulkMemPhiNode(phi); case MemPhiNode phi -> new MemPhiNode(phi); case PhiNode phi -> new PhiNode(phi); diff --git a/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ExtendRISC.java b/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ExtendRISC.java index 5bd3ec1c..11182133 100644 --- a/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ExtendRISC.java +++ b/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ExtendRISC.java @@ -6,14 +6,21 @@ import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.type.TypeInteger; import com.seaofnodes.simple.util.SB; -// Convert a narrow C return register to Simple's full-width integer value. +// Normalize narrow parameters and C return values to full-width integers. public class ExtendRISC extends MachConcreteNode { final int _bits; final boolean _signed; ExtendRISC(ProjNode prj, TypeInteger ret) { - super(prj); - _inputs.set(0,null); - _inputs.add(new ProjRISC(prj)); + this(prj,new ProjRISC(prj),ret); + } + ExtendRISC(ParmNode parm, TypeInteger decl) { + this(parm,new ParmRISC(parm),decl); + } + private ExtendRISC(Node ideal, Node value, TypeInteger ret) { + super(ideal); + _inputs.clear(); + _inputs.add(null); + _inputs.add(value); _bits = 8 << ret.log_size(); _signed = ret._min < 0; } diff --git a/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java b/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java index 0195542c..378955a5 100644 --- a/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java +++ b/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java @@ -236,7 +236,8 @@ public class riscv extends Machine { case NewNode nnn -> nnn(nnn); case NotNode not -> new NotRISC(not); case OrNode or -> or(or); - case ParmNode parm -> new ParmRISC(parm); + case ParmNode parm -> parm._declaredType instanceof TypeInteger ti && ti.log_size()<3 + ? new ExtendRISC(parm,ti) : new ParmRISC(parm); case BulkMemPhiNode phi-> new BulkMemPhiNode(phi); case MemPhiNode phi -> new MemPhiNode(phi); case PhiNode phi -> new PhiNode(phi); diff --git a/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ExtendX86.java b/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ExtendX86.java index 1a6ae123..9f4da6b8 100644 --- a/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ExtendX86.java +++ b/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ExtendX86.java @@ -6,14 +6,21 @@ import com.seaofnodes.simple.node.*; import com.seaofnodes.simple.type.TypeInteger; import com.seaofnodes.simple.util.SB; -// Convert a narrow C return register to Simple's full-width integer value. +// Normalize narrow parameters and C return values to full-width integers. public class ExtendX86 extends MachConcreteNode { final int _bits; final boolean _signed; ExtendX86(ProjNode prj, TypeInteger ret) { - super(prj); - _inputs.set(0,null); - _inputs.add(new ProjX86(prj)); + this(prj,new ProjX86(prj),ret); + } + ExtendX86(ParmNode parm, TypeInteger decl) { + this(parm,new ParmX86(parm),decl); + } + private ExtendX86(Node ideal, Node value, TypeInteger ret) { + super(ideal); + _inputs.clear(); + _inputs.add(null); + _inputs.add(value); _bits = 8 << ret.log_size(); _signed = ret._min < 0; } diff --git a/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java b/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java index 3dc93bf6..3d71b4ea 100644 --- a/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java +++ b/chapter30/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java @@ -306,7 +306,8 @@ public class x86_64_v2 extends Machine { case NewNode nnn -> new NewX86(nnn); case NotNode not -> new NotX86(not); case OrNode or -> or(or); - case ParmNode parm -> new ParmX86(parm); + case ParmNode parm -> parm._declaredType instanceof TypeInteger ti && ti.log_size()<3 + ? new ExtendX86(parm,ti) : new ParmX86(parm); case BulkMemPhiNode phi-> new BulkMemPhiNode(phi); case MemPhiNode phi -> new MemPhiNode(phi); case PhiNode phi -> new PhiNode(phi); @@ -555,6 +556,7 @@ public class x86_64_v2 extends Machine { private static int off, scale, imm; private static Node idx, val; private <N extends MemOpNode > N address(N mop) { + externalAddress(mop); off = scale = imm = 0; // Reset idx = val = null; Node base = mop.ptr(); |
