summaryrefslogtreecommitdiff
path: root/chapter23/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'chapter23/src/main/java')
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/Parser.java64
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java2
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/CallEndNode.java5
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java4
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java2
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java3
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java2
-rw-r--r--chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java2
8 files changed, 63 insertions, 21 deletions
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/Parser.java b/chapter23/src/main/java/com/seaofnodes/simple/Parser.java
index 1db873e0..ffd4bfe9 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/Parser.java
@@ -530,11 +530,11 @@ public class Parser {
// Parse predicate
require("(");
var pred = require(parseAsgn(), ")");
- return parseTrinary(pred,true,"else");
+ return parseTrinary(pred,"else");
}
// Parse a conditional expression, merging results.
- private Node parseTrinary( Node pred, boolean stmt, String fside ) {
+ private Node parseTrinary( Node pred, String fside ) {
pred.keep();
// IfNode takes current control and predicate
@@ -550,7 +550,15 @@ public class Parser {
// Parse the true side
ctrl(ifT.unkeep()); // set ctrl token to ifTrue projection
_scope.addGuards(ifT,pred,false); // Up-cast predicate
- Node lhs = (stmt ? parseStatement() : parseAsgn()).keep(); // Parse true-side
+ // Parse true-side flavor
+ Node lhs = switch( fside ) {
+ case "else" -> parseStatement(); // if( pred ) stmts;
+ case ":" -> parseAsgn(); // pred ? asgn;
+ case "&&" -> parseLogical(); // pred && expr
+ case "||" -> pred; // pred || expr_is_ignored
+ default -> throw Utils.TODO();
+ };
+ lhs.keep();
_scope.removeGuards(ifT);
// See if a one-sided def was made: "if(pred) int x = 1;" and throw.
@@ -566,17 +574,23 @@ public class Parser {
// Up-cast predicate, even if not else clause, because predicate can
// remain true if the true clause exits: `if( !ptr ) return 0; return ptr.fld;`
_scope.addGuards(ifF,pred,true);
- boolean doRHS = match(fside);
- Node rhs = (doRHS
- ? (stmt ? parseStatement() : parseAsgn())
- : con(lhs._type.makeZero())).keep();
+ // Parse false-side flavor
+ boolean doRHS = false; // RHS is optional for if/else and trinary
+ Node rhs = switch( fside ) {
+ case "else" -> (doRHS=match(fside)) ? parseStatement() : con(lhs._type.makeZero());
+ case ":" -> (doRHS=match(fside)) ? parseAsgn() : con(lhs._type.makeZero());
+ case "&&" -> rhs = pred;
+ case "||" -> rhs = parseLogical();
+ default -> throw Utils.TODO();
+ };
+ rhs.keep();
_scope.removeGuards(ifF);
if( doRHS )
fScope = _scope;
pred.unkeep();
// Check the trinary widening int/flt
- if( !stmt ) {
+ if( !fside.equals("else") ) {
rhs = widenInt( rhs.unkeep(), lhs._type ).keep();
lhs = widenInt( lhs.unkeep(), rhs._type ).keep();
}
@@ -593,7 +607,7 @@ public class Parser {
Node ret = peep(new PhiNode("",lhs._type.meet(rhs._type).glb(false),r,lhs.unkeep(),rhs.unkeep()));
// Immediately fail e.g. `arg ? 7 : ptr`
ParseException err;
- if( !stmt && (err=ret.err()) !=null ) throw err;
+ if( !fside.equals("else") && (err=ret.err()) !=null ) throw err;
r.peephole();
return ret;
}
@@ -993,8 +1007,8 @@ public class Parser {
* @return an expression {@link Node}, never {@code null}
*/
private Node parseExpression() {
- Node expr = parseBitwise();
- return match("?") ? parseTrinary(expr,false,":") : expr;
+ Node expr = parseLogical();
+ return match("?") ? parseTrinary(expr,":") : expr;
}
/**
@@ -1005,13 +1019,25 @@ public class Parser {
* </pre>
* @return a bitwise expression {@link Node}, never {@code null}
*/
+
+ private Node parseLogical() {
+ Node lhs = parseBitwise();
+ while (true) {
+ if( false ) ;
+ else if( match("&&") ) lhs = parseTrinary(lhs, "&&");
+ else if( match("||") ) lhs = parseTrinary(lhs, "||");
+ else break;
+ }
+ return lhs;
+ }
+
private Node parseBitwise() {
Node lhs = parseComparison();
while( true ) {
if( false ) ;
- else if( match("&") ) lhs = new AndNode(loc(),lhs,null);
- else if( match("|") ) lhs = new OrNode(loc(),lhs,null);
- else if( match("^") ) lhs = new XorNode(loc(),lhs,null);
+ else if( matchOp('&') ) lhs = new AndNode(loc(),lhs,null);
+ else if( matchOp('|') ) lhs = new OrNode(loc(),lhs,null);
+ else if( match ("^") ) lhs = new XorNode(loc(),lhs,null);
else break;
lhs.setDef(2,parseComparison());
lhs = peep(lhs);
@@ -1701,6 +1727,7 @@ public class Parser {
private boolean match (String syntax) { return _lexer.match (syntax); }
// Match must be "exact", not be followed by more id letters
private boolean matchx(String syntax) { return _lexer.matchx(syntax); }
+ private boolean matchOp(char c0 ) { return _lexer.matchOp(c0); }
private boolean matchOpx(char c0, char c1) { return _lexer.matchOpx(c0,c1); }
// Return true and do NOT skip if 'ch' is next
private boolean peek(char ch) { return _lexer.peek(ch); }
@@ -1876,6 +1903,15 @@ public class Parser {
_position -= syntax.length();
return false;
}
+ // Match this char, and the next char must be different.
+ // Handles '&&' vs '&'
+ boolean matchOp( char c0 ) {
+ skipWhiteSpace();
+ if( _position+1 >= _input.length || _input[_position]!=c0 || _input[_position+1]==c0 )
+ return false;
+ inc();
+ return true;
+ }
// Match these two characters in a row
boolean matchOpx(char c0, char c1) {
skipWhiteSpace();
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java b/chapter23/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java
index caa7ff44..6c958f32 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/codegen/CodeGen.java
@@ -39,6 +39,8 @@ public class CodeGen {
// ---------------------------
public CodeGen( String src ) { this(src, TypeInteger.BOT, 123L, true ); }
+ public CodeGen( String src, TypeInteger arg) { this(src, arg==null ? TypeInteger.BOT : arg, 123L, true ); }
+
public CodeGen( String src, TypeInteger arg, long workListSeed, boolean reset ) {
CODE = this;
if( reset ) Type.reset();
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/CallEndNode.java b/chapter23/src/main/java/com/seaofnodes/simple/node/CallEndNode.java
index b75852a4..d95af697 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/CallEndNode.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/CallEndNode.java
@@ -86,6 +86,11 @@ public class CallEndNode extends CFGNode implements MultiNode {
fun.setDef(2,call.ctrl()); // Bypass the Call;
fun.ret().setDef(3,null); // Return is folding also
CodeGen.CODE.addAll(fun._outputs);
+ // Repeat defs 1 layer down, for users of Parm (Phis)
+ for( Node parm : fun._outputs )
+ if( parm instanceof ParmNode )
+ CodeGen.CODE.addAll(parm._outputs);
+
// Inlining immediately blows all cache idepth fields past the inline point.
// Bump the global version number invalidating them en-masse.
CodeGen.CODE.invalidateIDepthCaches();
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java
index a2cb9bba..427cf2e2 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java
@@ -42,9 +42,9 @@ public class CallARM extends CallNode implements MachNode, RIPRelSize {
}
@Override public void asm(CodeGen code, SB sb) {
- sb.p(_name);
+ sb.p(_name).p(" ");
for( int i=0; i<nargs(); i++ )
- sb.p(code.reg(arg(i+2))).p(" ");
+ sb.p(code.reg(arg(i+2))).p(", ");
sb.unchar(2);
}
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java
index a3e1cf19..c84aa9e5 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallRRARM.java
@@ -25,7 +25,7 @@ public class CallRRARM extends CallNode implements MachNode {
@Override public void asm(CodeGen code, SB sb) {
sb.p(code.reg(fptr())).p(" ");
for( int i=0; i<nargs(); i++ )
- sb.p(code.reg(arg(i))).p(" ");
+ sb.p(code.reg(arg(i))).p(", ");
sb.unchar(2);
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java
index a676ba60..bd5dabe5 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java
@@ -57,7 +57,6 @@ public class CallRISC extends CallNode implements MachNode, RIPRelSize {
sb.p(_name).p(" ");
for( int i=0; i<nargs(); i++ )
sb.p(code.reg(arg(i+2))).p(", ");
- sb.unchar(2).p(" ").p(code.reg(fptr()));
-
+ sb.unchar(2);
}
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java
index ac36ed12..298789e8 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRRISC.java
@@ -25,7 +25,7 @@ public class CallRRISC extends CallNode implements MachNode {
@Override public void asm(CodeGen code, SB sb) {
sb.p(code.reg(fptr())).p(" ");
for( int i=0; i<nargs(); i++ )
- sb.p(code.reg(arg(i))).p(" ");
+ sb.p(code.reg(arg(i))).p(", ");
sb.unchar(2);
}
}
diff --git a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java
index ffdce7df..d74e3833 100644
--- a/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java
+++ b/chapter23/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CallX86.java
@@ -42,7 +42,7 @@ public class CallX86 extends CallNode implements MachNode, RIPRelSize {
@Override public void asm(CodeGen code, SB sb) {
sb.p(_name).p(" ");
for( int i=0; i<nargs(); i++ )
- sb.p(code.reg(in(i+2))).p(" ");
+ sb.p(code.reg(in(i+2))).p(", ");
sb.unchar(2);
}
}