diff options
| author | Cliff Click <cliffc@acm.org> | 2025-03-23 10:02:41 -0700 |
|---|---|---|
| committer | Cliff Click <cliffc@acm.org> | 2025-03-23 10:02:41 -0700 |
| commit | 05925aa5a73c48f4c380ec919583cb56057383ea (patch) | |
| tree | 7894d4df49b4967f2a84a2afbe8a3f5c042fc769 /chapter21/src/main/java/com | |
| parent | e1b6befcfb865e0a8e34d895a0ddc82bf31d6d4b (diff) | |
| download | Simple-05925aa5a73c48f4c380ec919583cb56057383ea.tar.gz Simple-05925aa5a73c48f4c380ec919583cb56057383ea.zip | |
x86 test op
Invert "Bool(#0,x); If " to "CmpI(x,#0); Jmp!XX"
Diffstat (limited to 'chapter21/src/main/java/com')
3 files changed, 25 insertions, 9 deletions
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java index 0db93118..ccb79710 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/CmpIX86.java @@ -18,6 +18,12 @@ public class CmpIX86 extends MachConcreteNode implements MachNode { addDef(cmp.in(1)); _imm = cmp._imm; } + CmpIX86( Node lhs, int imm, double ignore ) { + super(lhs); + _inputs.del(1); + _imm = imm; + } + @Override public String op() { return _imm==0 ? "test" : "cmp"; } @Override public RegMask regmap(int i) { return x86_64_v2.RMASK; } @Override public RegMask outregmap() { return x86_64_v2.FLAGS_MASK; } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/JmpX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/JmpX86.java index d325189a..876660aa 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/JmpX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/JmpX86.java @@ -17,9 +17,10 @@ public class JmpX86 extends IfNode implements MachNode, RIPRelSize { Node set = in(1); Node cmp = set.in(1); // Bypass an expected Set and just reference the cmp directly - if( set instanceof SetX86 && (cmp instanceof CmpX86 || cmp instanceof CmpIX86 || cmp instanceof CmpMemX86 || cmp instanceof CmpFX86) ) - _inputs.set(1,cmp); - else + if( set instanceof SetX86 setx && (cmp instanceof CmpX86 || cmp instanceof CmpIX86 || cmp instanceof CmpMemX86 || cmp instanceof CmpFX86) ) { + _inputs.set( 1, cmp ); + _bop = setx._bop; + } else throw Utils.TODO(); } @Override public RegMask regmap(int i) { assert i==1; return x86_64_v2.FLAGS_MASK; } 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 1d30bc4b..01b878a0 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 @@ -274,7 +274,7 @@ public class x86_64_v2 extends Machine { // caller saved(systemv) static final long SYSTEM5_CALLER_SAVE = - (1L<< RAX) | (1L<< RCX) | (1L<< RDX) | + (1L << RAX) | (1L << RCX) | (1L << RDX) | (1L << RDI) | (1L << RSI) | (1L << R08) | (1L << R09) | (1L << R10) | (1L << R11) | (1L << FLAGS) | // Flags are killed @@ -295,7 +295,7 @@ public class x86_64_v2 extends Machine { static RegMask x86CallerSave() { return switch (CodeGen.CODE._callingConv) { case "SystemV" -> SYSTEM5_CALLER_SAVE_MASK; - case "Win64" -> WIN64_CALLER_SAVE_MASK; + case "Win64" -> WIN64_CALLER_SAVE_MASK; default -> throw new IllegalArgumentException("Unknown calling convention: " + CodeGen.CODE._callingConv); }; } @@ -500,27 +500,36 @@ 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 Node cmp( BoolNode bool ) { + invert = false; Node cmp = _cmp(bool); - return new SetX86(cmp, bool.op()); + return new SetX86(cmp, invert ? IfNode.invert(bool.op()) : bool.op()); } private Node _cmp(BoolNode bool) { // Float variant if( bool.isFloat() ) return new CmpFX86(bool); - Node lhs = bool.in(1); Node rhs = bool.in(2); - if(lhs instanceof LoadNode ld && ld.nOuts() == 1) + + // Vs memory + if( lhs instanceof LoadNode ld && ld.nOuts() == 1 ) return new CmpMemX86(bool, address(ld), ld.ptr(), idx, off, scale, imm(rhs), val, false); - if(rhs instanceof LoadNode ld && ld.nOuts() == 1) + if( rhs instanceof LoadNode ld && ld.nOuts() == 1 ) return new CmpMemX86(bool, address(ld), ld.ptr(), idx, off, scale, imm(lhs), val, true); // Vs immediate if( rhs instanceof ConstantNode con && con._con instanceof TypeInteger ti && imm32(ti.value()) ) return new CmpIX86(bool, (int)ti.value()); + + if( lhs instanceof ConstantNode con && con._con instanceof TypeInteger ti && imm32(ti.value()) ) { + invert = true; + return new CmpIX86(bool, (int)ti.value(), 0.5); + } + // x vs y return new CmpX86(bool); } |
