summaryrefslogtreecommitdiff
path: root/chapter30/src/main/java/com/seaofnodes/simple/node
diff options
context:
space:
mode:
Diffstat (limited to 'chapter30/src/main/java/com/seaofnodes/simple/node')
-rw-r--r--chapter30/src/main/java/com/seaofnodes/simple/node/CallNode.java2
-rw-r--r--chapter30/src/main/java/com/seaofnodes/simple/node/FldOffNode.java2
-rw-r--r--chapter30/src/main/java/com/seaofnodes/simple/node/FormatNode.java33
-rw-r--r--chapter30/src/main/java/com/seaofnodes/simple/node/LoadNode.java3
-rw-r--r--chapter30/src/main/java/com/seaofnodes/simple/node/ScopeNode.java1
-rw-r--r--chapter30/src/main/java/com/seaofnodes/simple/node/cpus/arm/ExtendARM.java15
-rw-r--r--chapter30/src/main/java/com/seaofnodes/simple/node/cpus/arm/arm.java3
-rw-r--r--chapter30/src/main/java/com/seaofnodes/simple/node/cpus/riscv/ExtendRISC.java15
-rw-r--r--chapter30/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java3
-rw-r--r--chapter30/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/ExtendX86.java15
-rw-r--r--chapter30/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java4
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();