diff options
4 files changed, 35 insertions, 8 deletions
diff --git a/chapter22/docs/examples/BubbleSort.smp b/chapter22/docs/examples/BubbleSort.smp index af110159..025bb5a2 100644 --- a/chapter22/docs/examples/BubbleSort.smp +++ b/chapter22/docs/examples/BubbleSort.smp @@ -1,25 +1,46 @@ // -*- mode: java; -*- - val _exit = { u8[~] msg -> sys.io.p(msg); sys.libc._exit(1); }; +val usage = { -> _exit("stdin must look like [4, 3, 2, 1]"); }; +// Scanner struct Scan { int !x; u8[~] buf; }; +// Skip whitespace +val skip = { Scan s -> + while( s.buf[s.x] <= 32 ) + s.x++; +}; + +// Require specific syntax or usage +val require = { Scan s, u8 c -> + skip(s); + if( s.buf[s.x++] != c ) + usage(); +}; + +val number = { Scan s -> + skip(s); + i32 n = 0; + while( '0' <= s.buf[s.x] & s.buf[s.x] <= '9' ) + n = n*10 + (s.buf[s.x++] - '0'); + return n; +}; + // Read from stdin a line of the form "[ 4, 3, 2, 1]" and print it sorted. val main = { -> Scan !s = new Scan{ buf = sys.io.stdin(); }; - var junk = new u8[1]; while( s.x < s.buf# ) { - sys.io.p("scan "); - junk[0] = s.buf[s.x++]; - sys.io.p(junk); + require(s,'['); + int n = number(s); + sys.libc._exit(n); }; return 0; }; diff --git a/chapter22/src/main/java/com/seaofnodes/simple/Parser.java b/chapter22/src/main/java/com/seaofnodes/simple/Parser.java index 07fbdd5b..9c22fc43 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter22/src/main/java/com/seaofnodes/simple/Parser.java @@ -1116,6 +1116,7 @@ public class Parser { if( matchx("true" ) ) return con(1); if( matchx("false") ) return ZERO; if( matchx("null" ) ) return NIL; + if( match ("'" ) ) return parseChar(); if( match ("(" ) ) return require(parseAsgn(), ")"); if( matchx("new" ) ) return alloc(); if( match ("{" ) ) return require(func(),"}"); @@ -1548,6 +1549,10 @@ public class Parser { return new String(_lexer._input,start,pos()-start-1); } + // Already parsed "'" + private Node parseChar() { + return require(con(TypeInteger.constant(_lexer.nextChar())),"'"); + } ////////////////////////////////// // Utilities for lexical analysis diff --git a/chapter22/src/main/java/com/seaofnodes/simple/codegen/GlobalCodeMotion.java b/chapter22/src/main/java/com/seaofnodes/simple/codegen/GlobalCodeMotion.java index 3de66626..7e0a58ac 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/codegen/GlobalCodeMotion.java +++ b/chapter22/src/main/java/com/seaofnodes/simple/codegen/GlobalCodeMotion.java @@ -273,7 +273,7 @@ public abstract class GlobalCodeMotion { for( Node mem : load.mem()._outputs ) { switch( mem ) { case MemOpNode st: - if( !st._isLoad ) { + if( !st._isLoad && load._alias == st._alias ) { assert late[mem._nid] != null; lca = anti_dep( load, late[mem._nid], mem.cfg0(), lca, st ); } diff --git a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MemAddX86.java b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MemAddX86.java index a97f3d9f..f0d01b3d 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MemAddX86.java +++ b/chapter22/src/main/java/com/seaofnodes/simple/node/cpus/x86_64_v2/MemAddX86.java @@ -13,6 +13,7 @@ public class MemAddX86 extends MemOpX86 { } // Register mask allowed as a result. 0 for no register. @Override public RegMask outregmap() { return null; } + @Override public RegMask killmap() { return x86_64_v2.FLAGS_MASK; } @Override public void encoding( Encoding enc ) { // add something to memory // REX.W + 01 /r | REX.W + 81 /0 id @@ -23,11 +24,11 @@ public class MemAddX86 extends MemOpX86 { enc.add1(x86_64_v2.rex(src, ptr, idx)); // opcode - enc.add1( src == -1 ? 0x81: 0x01); + enc.add1( src == -1 ? (_imm==1 ? 0xFF : 0x81): 0x01); // includes modrm x86_64_v2.indirectAdr(_scale, idx, ptr, _off, src == -1 ? 0 : src, enc); - if( src == -1 ) enc.add4(_imm); + if( src == -1 && _imm!=1 ) enc.add4(_imm); } // General form: "add [base + idx<<2 + 12] += src" @Override public void asm(CodeGen code, SB sb) { |
