summaryrefslogtreecommitdiff
path: root/chapter21/src/main/java
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2025-04-05 15:53:10 -0700
committerCliff Click <cliffc@acm.org>2025-04-05 15:53:10 -0700
commit532b34d34fde93b2841f4c9544c673a0d89434ea (patch)
tree8fad454941c428d9b2ebb435470b09c35923979a /chapter21/src/main/java
parent7277ab049ab9cae5fa64cd5ea958f69278f773a4 (diff)
downloadSimple-532b34d34fde93b2841f4c9544c673a0d89434ea.tar.gz
Simple-532b34d34fde93b2841f4c9544c673a0d89434ea.zip
Fix vs0 bugs
Use a BoolNode.NE instead of inverting outputs; the outputs are already matched and cannot be inverted. Use a `swap` not an `invert` when switching sides in a compare.
Diffstat (limited to 'chapter21/src/main/java')
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/BoolNode.java12
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/IfNode.java14
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java2
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java5
-rw-r--r--chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java10
5 files changed, 35 insertions, 8 deletions
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/BoolNode.java b/chapter21/src/main/java/com/seaofnodes/simple/node/BoolNode.java
index f5f6a1de..fd6448a2 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/BoolNode.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/BoolNode.java
@@ -92,6 +92,18 @@ abstract public class BoolNode extends Node {
Node copyF() { return new EQF(null,null); }
}
+ public static class NE extends BoolNode {
+ public NE(Node lhs, Node rhs) { super(lhs,rhs); }
+ public String op() { return "!="; }
+ TypeInteger doOp(TypeInteger i1, TypeInteger i2) {
+ if( i1==i2 && i1.isConstant() ) return TRUE;
+ if( i1._max < i2._min || i1._min > i2._max ) return FALSE;
+ return BOOL;
+ }
+ Node copy(Node lhs, Node rhs) { return new NE(lhs,rhs); }
+ Node copyF() { throw Utils.TODO(); }
+ }
+
public static class LT extends BoolNode {
public LT(Node lhs, Node rhs) { super(lhs,rhs); }
public String op() { return "<" ; }
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/IfNode.java b/chapter21/src/main/java/com/seaofnodes/simple/node/IfNode.java
index c65e9a3b..f00f4f9f 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/IfNode.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/IfNode.java
@@ -69,6 +69,7 @@ public class IfNode extends CFGNode implements MultiNode {
// The following CProjs will be inverted by the caller.
public void invert() { throw Utils.TODO(); }
+ // Negate the sense of a test
public static String invert( String bop ) {
return switch( bop ) {
case "<" -> ">=";
@@ -80,4 +81,17 @@ public class IfNode extends CFGNode implements MultiNode {
default -> throw Utils.TODO();
};
}
+
+ // Swap compare operands
+ public static String swap( String bop ) {
+ return switch( bop ) {
+ case "<" -> ">" ;
+ case "<=" -> ">=";
+ case "==" -> "!=";
+ case "!=" -> "==";
+ case ">" -> "<" ;
+ case ">=" -> "<=";
+ default -> throw Utils.TODO();
+ };
+ }
}
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java
index 36e32bb8..b684b4c4 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SetX86.java
@@ -30,7 +30,7 @@ public class SetX86 extends MachConcreteNode implements MachNode {
enc.add1(switch (_bop) {
case "==" -> 0x94; // SETE
case "<" -> 0x9C; // SETL
- case "<=" -> 0X9E; // SETLE
+ case "<=" -> 0x96; //0X9E; // SETLE
default -> throw Utils.TODO();
});
enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, 0, dst));
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java
index f474b431..073d1d9b 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SplitX86.java
@@ -77,13 +77,14 @@ public class SplitX86 extends SplitNode {
enc.add1(0x0F);
enc.add1(0x28);
} else if( dstX && !srcX ) {
- // xmm->reg (66 REX.W 0F 6E /r MOVQ xmm, r/m64)
+ // reg->xmm (66 REX.W 0F 6E /r MOVQ xmm, r/m64)
enc.add1(0x0F);
enc.add1(0x6E);
} else if( !dstX && srcX ) {
- // reg->xmm(66 REX.W 0F 7E /r MOVQ r/m64, xmm)
+ // xmm->reg(66 0F 7E /r MOVQ r/m64, xmm)
enc.add1(0x0F);
enc.add1(0x7E);
+ short tmp=src; src=dst; dst=tmp;
}
enc.add1(x86_64_v2.modrm(x86_64_v2.MOD.DIRECT, dst, src));
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
index bf8f92ad..98b14a3c 100644
--- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
+++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/x86_64_v2.java
@@ -502,11 +502,11 @@ public class x86_64_v2 extends Machine {
// Because X86 flags, a normal ideal Bool is 2 X86 ops: a "cmp" and at "setz".
// Ideal If reading from a setz will skip it and use the "cmp" instead.
- private static boolean invert;
+ private static boolean swap;
private Node cmp( BoolNode bool ) {
- invert = false;
+ swap = false;
Node cmp = _cmp(bool);
- return new SetX86(cmp, invert ? IfNode.invert(bool.op()) : bool.op());
+ return new SetX86(cmp, swap ? IfNode.swap(bool.op()) : bool.op());
}
private Node _cmp(BoolNode bool) {
@@ -528,7 +528,7 @@ public class x86_64_v2 extends Machine {
return new CmpIX86(bool, (int)ti.value());
if( lhs instanceof ConstantNode con && con._con instanceof TypeInteger ti && imm32(ti.value()) ) {
- invert = true;
+ swap = true;
return new CmpIX86(bool, (int)ti.value(), 0.5);
}
@@ -560,7 +560,7 @@ public class x86_64_v2 extends Machine {
// Loads do not set the flags, and will need an explicit TEST
BoolNode bool;
if( iff.in(1) instanceof BoolNode bool0 ) bool = bool0;
- else iff.setDef(1, bool=new BoolNode.EQ(iff.in(1), new ConstantNode(TypeInteger.ZERO)));
+ else iff.setDef(1, bool=new BoolNode.NE(iff.in(1), new ConstantNode(TypeInteger.ZERO)));
return new JmpX86(iff, bool.op());
}