diff options
Diffstat (limited to 'chapter21/src')
20 files changed, 94 insertions, 69 deletions
diff --git a/chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java b/chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java index 413754b0..4971624d 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/codegen/Encoding.java @@ -45,7 +45,7 @@ public class Encoding { _bits = new BAOS(); } - // Short cut to the defining register + // Shortcut to the defining register public short reg(Node n) { return _code._regAlloc.regnum(n); } @@ -153,7 +153,15 @@ public class Encoding { } // Else nothing } else if( tld > bld ) { // True enters a deeper loop throw Utils.TODO(); - } // Else True exits a loop, always forward and good + } else if( fld == bld && f.out(0) instanceof LoopNode ) { // Else True exits a loop, always forward and good + // if false is the loop backedge, make sure its true/taken + // Invert test and Proj fields + iff.invert(); + t.invert(); + f.invert(); + CProjNode tmp=f; f=t; t=tmp; // Swap t/f + + } // Always visit the False side last (so True side first), so that // when the False RPO visit returns, the IF is immediately next. diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/BranchARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/BranchARM.java index daa212f5..a7cbd1aa 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/BranchARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/BranchARM.java @@ -7,7 +7,7 @@ import com.seaofnodes.simple.node.*; // Jump on flags, uses flags public class BranchARM extends IfNode implements MachNode{ - final String _bop; + String _bop; BranchARM(IfNode iff, String bop ) { super(iff); _bop = bop; @@ -27,9 +27,11 @@ public class BranchARM extends IfNode implements MachNode{ @Override public RegMask regmap(int i) { assert i==1; return arm.FLAGS_MASK; } @Override public RegMask outregmap() { return null; } + @Override public void invert() { _bop = invert(_bop); } // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { + enc.jump(this,cproj(0)); // Assuming that condition flags are already set. These flags are set // by comparison (or sub). No need for regs because it uses flags arm.COND cond = switch (_bop) { @@ -47,9 +49,10 @@ public class BranchARM extends IfNode implements MachNode{ @Override public void asm(CodeGen code, SB sb) { String src = code.reg(in(1)); if( src!="flags" ) sb.p(src); - else sb.p(" "); Node prj = cproj(0); - sb.p(prj instanceof LoopNode ? "LOOP" : "L").p(prj._nid); + while( prj.nOuts() == 1 ) + prj = prj.out(0); // Skip empty blocks + sb.p(prj instanceof LoopNode ? " LOOP" : " L").p(prj._nid); } @Override public String comment() { return "L"+cproj(1)._nid+", L"+cproj(0)._nid; } } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java index 3058e7c8..2a815f37 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/CallARM.java @@ -33,7 +33,7 @@ public class CallARM extends CallNode implements MachNode { @Override public void asm(CodeGen code, SB sb) { sb.p(_name); for( int i=0; i<nargs(); i++ ) - sb.p(code.reg(arg(i))).p(" "); + sb.p(code.reg(arg(i+2))).p(" "); sb.unchar(2); } } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java index 70e4b085..be837f04 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/arm/FloatARM.java @@ -22,7 +22,7 @@ public class FloatARM extends ConstantNode implements MachNode { // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { - short self = (short)(enc.reg(this) - arm.D_OFFSET); + short dst = (short)(enc.reg(this) - arm.D_OFFSET); double d = ((TypeFloat)_con).value(); long x = Double.doubleToRawLongBits(d); // Any number that can be expressed as +/-n * 2-r,where n and r are integers, 16 <= n <= 31, 0 <= r <= 7. diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AUIPC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AUIPC.java index ebae13b6..30c63d8d 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AUIPC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/AUIPC.java @@ -17,8 +17,7 @@ public class AUIPC extends ConstantNode implements MachNode { @Override public void encoding( Encoding enc ) { enc.relo(this,(TypeFunPtr)_con); short dst = enc.reg(this); - int auipc = riscv.u_type(0x17, dst, 0); - enc.add4(auipc); + enc.add4(riscv.u_type(0x17, dst, 0)); } @Override public void asm(CodeGen code, SB sb) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java index a7c0b7c7..f000a5d3 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/BranchRISC.java @@ -8,7 +8,7 @@ import java.util.BitSet; // Conditional branch such as: BEQ public class BranchRISC extends IfNode implements MachNode { - final String _bop; + String _bop; // label is obtained implicitly BranchRISC( IfNode iff, String bop, Node n1, Node n2 ) { super(iff); @@ -22,6 +22,7 @@ public class BranchRISC extends IfNode implements MachNode { @Override public String comment() { return "L"+cproj(1)._nid+", L"+cproj(0)._nid; } @Override public RegMask regmap(int i) { return riscv.RMASK; } @Override public RegMask outregmap() { return null; } + @Override public void invert() { _bop = invert(_bop); } @Override public StringBuilder _print1(StringBuilder sb, BitSet visited) { in(1)._print0(sb.append("if( "),visited).append(_bop); @@ -32,6 +33,7 @@ public class BranchRISC extends IfNode implements MachNode { // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { + enc.jump(this,cproj(0)); // Todo: relocs (for offset - immf) short src1 = enc.reg(in(1)); short src2 = in(2)==null ? (short)riscv.ZERO : enc.reg(in(2)); @@ -41,6 +43,8 @@ public class BranchRISC extends IfNode implements MachNode { @Override public void asm(CodeGen code, SB sb) { sb.p(code.reg(in(1))).p(" ").p(_bop).p(" ").p(in(2)==null ? "#0" : code.reg(in(2))).p(" "); Node prj = cproj(0); + while( prj.nOuts() == 1 ) + prj = prj.out(0); // Skip empty blocks sb.p(prj instanceof LoopNode ? "LOOP" : "L").p(prj._nid); } } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java index e93852da..d0309829 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/CallRISC.java @@ -40,7 +40,8 @@ public class CallRISC extends CallNode implements MachNode { @Override public void asm(CodeGen code, SB sb) { sb.p(_name).p(" "); for( int i=0; i<nargs(); i++ ) - sb.p(code.reg(arg(i))).p(" "); - sb.unchar(2); + sb.p(code.reg(arg(i+2))).p(", "); + sb.unchar(2).p(" ").p(code.reg(fptr())); + } } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FltRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FltRISC.java index 0242d333..7ce82ec7 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FltRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/FltRISC.java @@ -16,16 +16,12 @@ public class FltRISC extends ConstantNode implements MachNode{ @Override public FltRISC copy() { return new FltRISC(this); } // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { + enc.largeConstant(this,_con); short dst = (short)(enc.reg(this) - riscv.F_OFFSET); - double d = ((TypeFloat)_con).value(); - long x = Double.doubleToRawLongBits(d); - - // Encode as either a memory slot and load, or stuff into an integer - // register (probably 2 int ops), then a fmv.w.x so 3 ops. - - //int body = riscv.i_type(0x07, dst, 0X03, fpr_reg - riscv.F_OFFSET, x); - //enc.push_add4(body); - throw Utils.TODO(); + // AUIPC dst,#hi20_constant_pool + enc.add4(riscv.u_type(0x17, dst, 0)); + // Load dst,[dst+#low12_constant_pool] + enc.add4(riscv.i_type(0x07, dst, 0x03, dst, 0)); } @Override public void asm(CodeGen code, SB sb) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetFRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetFRISC.java index 52a3c24d..99345f51 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetFRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetFRISC.java @@ -28,6 +28,6 @@ public class SetFRISC extends MachConcreteNode implements MachNode { } @Override public void asm(CodeGen code, SB sb) { - sb.p(code.reg(in(1))).p(" ").p(_bop).p(" ").p(code.reg(in(2))); + sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" ").p(_bop).p(" ").p(code.reg(in(2))); } } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetRISC.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetRISC.java index cae450c5..e81e363e 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetRISC.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/SetRISC.java @@ -12,6 +12,6 @@ public class SetRISC extends MachConcreteNode implements MachNode { @Override public RegMask outregmap() { return riscv.WMASK; } @Override public void encoding( Encoding enc ) { riscv.r_type(enc,this,2,0); } @Override public void asm(CodeGen code, SB sb) { - sb.p(code.reg(in(1))).p(" < ").p(code.reg(in(2))); + sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" < ").p(code.reg(in(2))); } } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java index fcea5e28..8d44fe34 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/riscv/riscv.java @@ -170,24 +170,15 @@ public class riscv extends Machine { DYN, // In instruction’s rm field, selects dynamic rounding mode; In Rounding Mode register, reserved } - // seqz ( sltiu rd, rs, 1 ) - 0001 0011 - static public int setop(String op) { - return switch(op) { - case "<" -> 0x33; - case "<=" -> 0x13; - case "==" -> 0x33; - default -> throw Utils.TODO(); - }; - } // Since opcode is the same just return back func3 - // BEQ: 01100011 - // BLT: 01100011 - // BLE: bge rt, rs, offset: static public int jumpop(String op) { return switch(op) { + case "==" -> 0x0; + case "!=" -> 0x1; case "<" -> 0x4; case "<=" -> 0x5; - case "==" -> 0; + case "u<" -> 0x6; + case "u<=" -> 0x7; default -> throw Utils.TODO(); }; } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java index 86b3b365..839b147c 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/AddFX86.java @@ -27,6 +27,6 @@ public class AddFX86 extends MachConcreteNode implements MachNode { // General form: "addf dst += src" @Override public void asm(CodeGen code, SB sb) { - sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" + ").p(code.reg(in(2))); + sb.p(code.reg(this)).p(" += ").p(code.reg(in(2))); } } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java index bfd57b34..52988d13 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/DivFX86.java @@ -29,6 +29,6 @@ public class DivFX86 extends MachConcreteNode implements MachNode { // General form: "divf dst /= src" @Override public void asm(CodeGen code, SB sb) { - sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" / ").p(code.reg(in(2))); + sb.p(code.reg(this)).p(" /= ").p(code.reg(in(2))); } } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java index 5c4002e1..2d332764 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/FltX86.java @@ -15,7 +15,7 @@ public class FltX86 extends ConstantNode implements MachNode { // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { enc.largeConstant(this,_con); - // Simply move the constant into a FPR + // Load the constant into a FPR // movsd xmm, [rip + 0] // F2 0F 10 /r MOVSD xmm1, m64 short dst = (short)(enc.reg(this ) - x86_64_v2.XMM_OFFSET); @@ -32,6 +32,6 @@ public class FltX86 extends ConstantNode implements MachNode { } @Override public void asm(CodeGen code, SB sb) { - _con.print(sb.p(code.reg(this)).p(" #")); + _con.print(sb.p(code.reg(this)).p(" = #")); } } 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 1a5a4d0a..ae5635b8 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 @@ -6,7 +6,7 @@ import com.seaofnodes.simple.node.*; // Jump on flags, uses flags public class JmpX86 extends IfNode implements MachNode { - final String _bop; + String _bop; JmpX86( IfNode iff, String bop ) { super(iff); _bop = bop; @@ -26,6 +26,7 @@ public class JmpX86 extends IfNode implements MachNode { } @Override public RegMask regmap(int i) { assert i==1; return x86_64_v2.FLAGS_MASK; } @Override public RegMask outregmap() { return null; } + @Override public void invert() { _bop = invert(_bop); } // Encoding is appended into the byte array; size is returned @Override public void encoding( Encoding enc ) { @@ -39,7 +40,9 @@ public class JmpX86 extends IfNode implements MachNode { @Override public void asm(CodeGen code, SB sb) { String src = code.reg(in(1)); if( src!="flags" ) sb.p(src); - Node prj = cproj(0); + Node prj = cproj(0); // 0 is True is jump target + while( prj.nOuts() == 1 ) + prj = prj.out(0); // Skip empty blocks sb.p(prj instanceof LoopNode ? " LOOP" : " L").p(prj._nid); } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java index bac84140..cb18e708 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MulFX86.java @@ -29,6 +29,6 @@ public class MulFX86 extends MachConcreteNode implements MachNode { // General form: "mulf dst *= src" @Override public void asm(CodeGen code, SB sb) { - sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" * ").p(code.reg(in(2))); + sb.p(code.reg(this)).p(" *= ").p(code.reg(in(2))); } } diff --git a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java index d727d429..0c952ddc 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/SubFX86.java @@ -26,6 +26,6 @@ public class SubFX86 extends MachConcreteNode implements MachNode { // General form: "subf dst -= src" @Override public void asm(CodeGen code, SB sb) { - sb.p(code.reg(this)).p(" = ").p(code.reg(in(1))).p(" - ").p(code.reg(in(2))); + sb.p(code.reg(this)).p(" -= ").p(code.reg(in(2))); } } 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 9263616e..8cd7128d 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 @@ -62,18 +62,6 @@ public class x86_64_v2 extends Machine { DIRECT, // mem }; - // Inverting IfNode - static public String invert(String op) { - return switch (op) { - case "==" -> "!="; - case "!=" -> "=="; - case ">" -> "<="; - case "<" -> ">="; - case ">=" -> "<" ; - case "<=" -> ">" ; - default -> throw new IllegalStateException("Unexpected value: " + op); - }; - } // opcode included here // 0F 84 cd JE rel32 // 0F 85 cd JNE rel32 @@ -81,8 +69,6 @@ public class x86_64_v2 extends Machine { // 0F 8C cd JL rel32 // 0F 8E cd JLE rel32 // 0F 8D cd JGE rel32 - - static public int jumpop(String op) { return switch (op) { case "==" -> 0x84; @@ -512,9 +498,10 @@ public class x86_64_v2 extends Machine { // If/Bool combos will match to a Cmp/Set which sets flags. // Most general arith ops will also set flags, which the Jmp needs directly. // Loads do not set the flags, and will need an explicit TEST - if(!(iff.in(1) instanceof BoolNode)) - iff.setDef(1, new BoolNode.EQ(iff.in(1), new ConstantNode(TypeInteger.ZERO))); - return new JmpX86(iff, invert(((BoolNode) iff.in(1)).op())); + 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))); + return new JmpX86(iff, bool.op()); } private Node ld(LoadNode ld) { diff --git a/chapter21/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java b/chapter21/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java index 55a45a32..d511d8ad 100644 --- a/chapter21/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java +++ b/chapter21/src/main/java/com/seaofnodes/simple/print/ASMPrinter.java @@ -38,7 +38,7 @@ public abstract class ASMPrinter { return iadr; } - static private final int encWidth = 8; + static private final int encWidth = 10; static private final int opWidth = 5; static private final int argWidth = 30; static int doBlock(int iadr, SB sb, CodeGen code, FunNode fun, int cfgidx) { @@ -47,6 +47,7 @@ public abstract class ASMPrinter { sb.p(label(bb)).p(":").nl(); if( bb instanceof CallNode ) return iadr; final boolean postAlloc = code._phase.ordinal() > CodeGen.Phase.RegAlloc.ordinal(); + final boolean postEncode= code._phase.ordinal() >=CodeGen.Phase.Encoding.ordinal(); boolean once=false; for( Node n : bb.outs() ) { @@ -73,20 +74,22 @@ public abstract class ASMPrinter { // All the non-phis for( int i=0; i<bb.nOuts(); i++ ) if( !(bb.out(i) instanceof PhiNode) ) - iadr = doInst(iadr, sb,code, cfgidx, bb.out(i),postAlloc ); + iadr = doInst(iadr, sb,code, cfgidx, bb.out(i),postAlloc, postEncode ); return iadr; } - static int doInst( int iadr, SB sb, CodeGen code, int cfgidx, Node n, boolean postAlloc ) { + static int doInst( int iadr, SB sb, CodeGen code, int cfgidx, Node n, boolean postAlloc, boolean postEncode ) { if( n instanceof CProjNode ) return iadr; - if( n instanceof CalleeSaveNode && postAlloc ) return iadr; + if( postAlloc && n instanceof CalleeSaveNode ) return iadr; + if( postEncode && n instanceof ProjNode ) return iadr; if( n instanceof MemMergeNode ) return iadr; // All blocks ending in a Region will need to either fall into or jump // to this block. Until the post-reg-alloc block layout cleanup, we // need to assume a jump. There's no real hardware op here, yet. if( n instanceof RegionNode cfg && !(n instanceof FunNode) ) { + if( postEncode ) return iadr; // All jumps inserted already while( cfgidx < code._cfg._len-1 ) { CFGNode next = code._cfg.at(++cfgidx); if( next == n ) return iadr; // Fall-through, no branch @@ -108,16 +111,17 @@ public abstract class ASMPrinter { // ADDR ENCODING Op--- dst = src op src // Comment // 1234 abcdefgh ld4 RAX = [Rbase + off] // Comment - sb.hex2(iadr); - sb.p(" "); + sb.hex2(iadr).p(" "); // Encoding + int fatEncoding = 0; if( code._encoding != null ) { int size = code._encoding._opLen[n._nid]; - for( int i=0; i<size; i++ ) + for( int i=0; i<Math.min(size,encWidth>>1); i++ ) sb.hex1(code._encoding._bits.buf()[iadr++]); for( int i=size*2; i<encWidth; i++ ) sb.p(" "); + fatEncoding = size - (encWidth>>1); // Not-printed parts of encoding } else sb.fix(encWidth,""); sb.p(" "); @@ -151,11 +155,20 @@ public abstract class ASMPrinter { sb.nl(); + + if( fatEncoding > 0 ) { + sb.hex2(iadr).p(" "); + for( int i=0; i<fatEncoding; i++ ) + sb.hex1(code._encoding._bits.buf()[iadr++]); + sb.nl(); + } + + // MultiNodes are immediately followed by projection(s) if( !(n instanceof CFGNode) && n instanceof MultiNode ) { for( Node proj : n._outputs ) { assert proj instanceof ProjNode; - doInst(iadr,sb,code, cfgidx, proj,postAlloc); + doInst(iadr,sb,code, cfgidx, proj,postAlloc,postEncode); } } diff --git a/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java b/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java index 770c7165..e2a79b8f 100644 --- a/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java +++ b/chapter21/src/test/java/com/seaofnodes/simple/Chapter21Test.java @@ -42,4 +42,24 @@ public class Chapter21Test { testCPU(src,"arm" , "SystemV",0,"return (or,arg,2);"); } + @Test + public void testNewtonFloat() { + String src = +""" +// Newtons approximation to the square root +val sqrt = { flt x -> + flt guess = x; + while( 1 ) { + flt next = (x/guess + guess)/2; + if( next == guess ) return guess; + guess = next; + } +}; +flt farg = arg; +return sqrt(farg) + sqrt(farg+2.0); +"""; + testCPU(src,"x86_64_v2", "SystemV",25,null); + testCPU(src,"riscv" , "SystemV",17,null); + testCPU(src,"arm" , "SystemV",18,null); + } } |
