Merge branch 'master' of git://git.hcoop.net/git/crawshaw/fleet
[fleet.git] / src / edu / berkeley / fleet / assembler / Parser.java
index fe59b8a..3a1fdbd 100644 (file)
@@ -29,7 +29,8 @@ public class Parser {
         SIGNAL_ONE.set(0,true);
     }
     
-    Parser(Fleet fleet) {
+    /** WARNING: this class may change in the future; it is not a stable interface */
+    public Parser(Fleet fleet) {
         expect = new ArrayList<Long>();
         this.fleet = fleet;
     }
@@ -103,8 +104,8 @@ public class Parser {
                 if (c.isCBD.contains(j)) {
                     Set old = (Set)inst;
                     long lit = 0;
-                    lit = FleetTwoFleet.CBD_SIZE.setval(lit, codeBags.get((int)old.immediate).size());
-                    lit = FleetTwoFleet.CBD_OFFSET.setval(lit, codeBagMap[(int)old.immediate]);
+                    lit = ((FleetTwoFleet)fleet).CBD_SIZE.setval(lit, codeBags.get((int)old.immediate).size());
+                    lit = ((FleetTwoFleet)fleet).CBD_OFFSET.setval(lit, codeBagMap[(int)old.immediate]);
                     inst = new Set(old.dock, false, IgnoreOLC, SetDest.DataLatch, lit);
                 }
                 ret.add(inst);
@@ -115,8 +116,8 @@ public class Parser {
         for(int i=0; i<codeBags.size(); i++) {
             if (codeBags.get(i)==rootCodeBag) {
                 long lit = 0;
-                lit = FleetTwoFleet.CBD_SIZE.setval(lit, codeBags.get(i).size());
-                lit = FleetTwoFleet.CBD_OFFSET.setval(lit, codeBagMap[i]);
+                lit = ((FleetTwoFleet)fleet).CBD_SIZE.setval(lit, codeBags.get(i).size());
+                lit = ((FleetTwoFleet)fleet).CBD_OFFSET.setval(lit, codeBagMap[i]);
                 startcbd = lit;
             }
         }
@@ -153,20 +154,32 @@ public class Parser {
         for(int i=0; i<instructions.length; i++) {
             long lit = ((FleetTwoFleet)fpga).writeInstruction(instructions[i], out);
             ret.add(discard(out));
-            ret.add(new Instruction.Shift(inDataWrite, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(36, 19, lit))));
-            ret.add(new Instruction.Shift(inDataWrite, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(18,  0, lit))));
+            ret.add(new Instruction.Shift(inDataWrite, false, IgnoreOLC, new BitVector(fpga.getShiftWidth()).set(getField(36, 19, lit))));
+            ret.add(new Instruction.Shift(inDataWrite, false, IgnoreOLC, new BitVector(fpga.getShiftWidth()).set(getField(18,  0, lit))));
             ret.add(deliver(inDataWrite));
-            ret.add(new Instruction.Shift(inAddrWrite, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(36, 19, i))));
-            ret.add(new Instruction.Shift(inAddrWrite, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(18,  0, i))));
+            ret.add(new Instruction.Shift(inAddrWrite, false, IgnoreOLC, new BitVector(fpga.getShiftWidth()).set(getField(36, 19, i))));
+            ret.add(new Instruction.Shift(inAddrWrite, false, IgnoreOLC, new BitVector(fpga.getShiftWidth()).set(getField(18,  0, i))));
             ret.add(deliver(inAddrWrite));
         }
-        ret.add(new Instruction.Shift(inCBD, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(36, 19, startcbd))));
-        ret.add(new Instruction.Shift(inCBD, false, IgnoreOLC, new BitVector(fpga.getWordWidth()).set(getField(18,  0, startcbd))));
+        ret.add(new Instruction.Shift(inCBD, false, IgnoreOLC, new BitVector(fpga.getShiftWidth()).set(getField(36, 19, startcbd))));
+        ret.add(new Instruction.Shift(inCBD, false, IgnoreOLC, new BitVector(fpga.getShiftWidth()).set(getField(18,  0, startcbd))));
         ret.add(wait(inCBD));
         ret.add(deliver(inCBD));
         ret.add(sendto(out, out.getPath(inCBD.getDataDestination(),null)));
-        ret.add(new Instruction.Set(ihorn, false, IgnoreOLC, SetDest.InnerLoopCounter, SetSource.Infinity));
-        ret.add(new Instruction.Move(ihorn, false, IgnoreOLC, false, null,false,true,true,true,true,false));
+
+        int count = (int)((FleetTwoFleet)fleet).CBD_SIZE.getval(startcbd);
+        // FIXME FIXME FIXME!
+        int MAX_ILC = 31;
+        int num_instrs = 0;
+        while(count > 0) {
+            int num = Math.min(count, MAX_ILC);
+            num_instrs+=2;
+            count -= num;
+            ret.add(new Instruction.Set(ihorn, false, IgnoreOLC, SetDest.InnerLoopCounter, num));
+            ret.add(new Instruction.Move(ihorn, false, IgnoreOLC, false, null,false,true,true,true,true,false));
+        }
+        if (num_instrs > ihorn.getInstructionFifoSize()) throw new RuntimeException();
+
         return (Instruction[])ret.toArray(new Instruction[0]);
     }
 
@@ -182,9 +195,6 @@ public class Parser {
                 for(Tree<String> statement : t.child(1))
                     fillCodeBag(statement, cb);
    
-        } else if (head.equals("#import")) {
-            // ignored
-
         } else if (head.equals("#ship")) {
             String name = name(t.child(0));
             String type = string(t.child(1));
@@ -200,13 +210,6 @@ public class Parser {
             }
             shipMap.put(name, ship);
 
-        } else if (head.equals("#include")) {
-            try {
-                walk(parseIt(new InputStreamReader(new FileInputStream(string(t.child(0))))), cb);
-            } catch (Exception e) {
-                throw new RuntimeException(e);
-            }
-            
         } else if (head.equals("#expect")) {
             expect.add(number(t.child(0)));
         } else if (head.equals("#skip")) {
@@ -215,7 +218,7 @@ public class Parser {
         }
     }
 
-    String string(Tree<String> t) {
+    private static String string(Tree<String> t) {
         String ret = "";
         if (t.head() != null) ret += t.head();
         for(Tree<String> c : t)
@@ -223,23 +226,21 @@ public class Parser {
         return ret;
     }
 
-    String stringBody(Tree<String> t) {
+    private static String stringBody(Tree<String> t) {
         String ret = "";
         for(Tree<String> c : t)
             ret += string(c);
         return ret;
     }
 
-    String name(Tree<String> t) {
+    private static String name(Tree<String> t) {
         return string(t.child(0))+string(t.child(1));
     }
 
     Path path(Dock dock, Tree<String> t) {
         if (!"Dock".equals(t.head()) && !"Destination".equals(t.head()) && !"ShipSpecificLiteral".equals(t.head())) return null;
-        t = t.child(0);
         String shipName = name(t.child(0));
         String portName = name(t.child(1));
-        String subPort = t.size()<3 ? null : name(t.child(2));
         Ship ship = shipMap.get(shipName);
         if (ship==null) throw new RuntimeException("no such ship \""+shipName+"\"");
         Destination ret = null;
@@ -250,10 +251,11 @@ public class Parser {
             }
         if (bb==null)
             throw new RuntimeException("no such pump \""+portName+"\"");
-        if (subPort==null) subPort="";
-        if (":i".equals(t.head())) return dock.getPath(bb.getInstructionDestination(),SIGNAL_ZERO);
-        if (":1".equals(t.head())) return dock.getPath(bb.getDataDestination(),SIGNAL_ONE);
-        if (":0".equals(t.head())) return dock.getPath(bb.getDataDestination(),SIGNAL_ZERO);
+        if (t.size() >= 3) {
+            if (":i".equals(t.child(2).head())) return dock.getPath(bb.getInstructionDestination(),SIGNAL_ZERO);
+            if (":1".equals(t.child(2).head())) return dock.getPath(bb.getDataDestination(),SIGNAL_ONE);
+            if (":0".equals(t.child(2).head())) return dock.getPath(bb.getDataDestination(),SIGNAL_ZERO);
+        }
         return dock.getPath(bb.getDataDestination(),SIGNAL_ZERO);
     }
 
@@ -320,7 +322,7 @@ public class Parser {
             s = s.substring(0, s.indexOf('='));
             hasval = true;
         }
-        ShipDescription.Constant c = ((FleetTwoDock)dd).getConstant(s);
+        ShipDescription.Constant c = ((FleetTwoDock)dd).getDockConstant(s);
         if (c==null) throw new RuntimeException("no constant " + s + " on dock " + dd);
         ret |= c.setbits;
         ret &= ~c.clearbits;
@@ -357,6 +359,12 @@ public class Parser {
             Dock dock = (Dock)dock(t.child(0));
             
             OUTER: for(Tree tt : t.child(1)) {
+
+                if ("tail".equals(tt.head()))    {
+                    cb.add(new Tail(dock));
+                    continue;
+                }
+
                 int count = 1;
                 Predicate predicate = Default;
                 boolean looping = false;
@@ -369,39 +377,46 @@ public class Parser {
                     if ("[!a]".equals(ttt.head())) predicate = NotFlagA;
                     if ("[!b]".equals(ttt.head())) predicate = NotFlagB;
                     if ("[!c]".equals(ttt.head())) predicate = NotFlagC;
-                    if ("[+]".equals(ttt.head()))  predicate = IgnoreOLC;
-                    if ("[I]".equals(ttt.head()))  interruptible = true;
-                    if ("[L]".equals(ttt.head()))  looping = true;
+                    if ("[*]".equals(ttt.head()))  predicate = IgnoreOLC;
+                    if ("[olc=0]".equals(ttt.head()))  predicate = OLCZero;
+                    if ("[Rq]".equals(ttt.head()))  looping = true;
                 }
                 tt = tt.child(1);
                 if ("tail".equals(tt.head()))    {
                     cb.add(new Tail(dock));
                     continue;
-                } else if ("setflags".equals(tt.head()))    {
+                } else if ("flags".equals(tt.head()))    {
                     cb.add(new Set(dock, looping, predicate, parseFlags(tt.child(0)), parseFlags(tt.child(1))));
                     continue;
-                } else if ("tapl".equals(tt.head()))    {
-                    cb.add(new Set(dock, looping, predicate, SetDest.TAPL, path(dock, tt.child(0))));
-                    continue;
-                } else if ("load".equals(tt.head()) && "loop".equals(tt.child(0).head()))    {
+                } else if ("olc=word".equals(tt.head()))    {
                     cb.add(new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.DataLatch));
                     continue;
-                } else if ("load".equals(tt.head()) && "repeat".equals(tt.child(0).head()))    {
+                } else if ("ilc=word".equals(tt.head()))    {
                     cb.add(new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.DataLatch));
                     continue;
                 } else if ("*".equals(tt.head()))    {
                     cb.add(new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.Infinity));
                     continue;
-                } else if ("with".equals(tt.head()) && "loop".equals(tt.child(0).head()))    {
-                    cb.add(new Set(dock, looping, predicate, SetDest.OuterLoopCounter, (number(tt.child(1)))));
+                } else if ("olc=int".equals(tt.head()))    {
+                    cb.add(new Set(dock, looping, predicate, SetDest.OuterLoopCounter, (number(tt.child(0)))));
                     continue;
-                } else if ("with".equals(tt.head()) && "repeat".equals(tt.child(0).head()))    {
-                    cb.add(new Set(dock, looping, predicate, SetDest.InnerLoopCounter, (number(tt.child(1)))));
+                } else if ("ilc=int".equals(tt.head()))    {
+                    cb.add(new Set(dock, looping, predicate, SetDest.InnerLoopCounter, (number(tt.child(0)))));
                     continue;
-                } else if ("decrement".equals(tt.head())) {
+                } else if ("--".equals(tt.head())) {
                     cb.add(new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.Decrement));
                     continue;
-                } else if ("literal".equals(tt.head())) {
+                } else if ("nop".equals(tt.head())) {
+                    if (tt.size() > 0 && "[T]".equals(tt.child(0).head())) interruptible = true;
+                    cb.add(new Move(dock, looping, predicate, interruptible, null, false, false, false, false, false, false));
+                } else if ("shift".equals(tt.head())) {
+                    cb.add(new Shift(dock, looping, predicate,
+                                     new BitVector(dock.getShip().getFleet().getShiftWidth()).set(number(tt.child(0)))));
+                    continue;
+                } else if ("flush".equals(tt.head())) {
+                    cb.add(new Flush(dock, looping, predicate));
+                    continue;
+                } else if ("word".equals(tt.head())) {
                     long literal = 0;
                     if (tt.child(0).head().equals("CodeBagBody")) {
                         Tree<String> tq = tt;
@@ -421,42 +436,34 @@ public class Parser {
                         literal = number(tt.child(0));
                     }
                     count = 1;
+                    /*
                     if ("int".equals(tt.child(1).head())) {
                         count = (int)number(tt.child(1));
                     } else if ("forever".equals(tt.child(1).head())) {
                         count = 0;
                     }
+                    */
 
 
-                    if (FleetTwoFleet.isSmallEnoughToFit(literal)) {
+                    if (((FleetTwoFleet)fleet).isSmallEnoughToFit(literal)) {
                         cb.add(new Set(dock, looping, predicate, SetDest.DataLatch, (literal)));
                     } else {
-                        // FIXME bitwidth hardwired!
-                        cb.add(new Shift(dock, looping, predicate, new BitVector(37).set(getField(36, 19, literal))));
-                        cb.add(new Shift(dock, looping, predicate, new BitVector(37).set(getField(18,  0, literal))));
+                        int counter = 0;
+                        while(counter < dock.getShip().getFleet().getWordWidth()) counter += fleet.getShiftWidth();
+                        while(counter > 0) {
+                            cb.add(new Shift(dock, looping, predicate,
+                                             new BitVector(dock.getShip().getFleet().getShiftWidth())
+                                             .set(getField(counter-1, counter-fleet.getShiftWidth(), literal))));
+                            counter -= fleet.getShiftWidth();
+                        }
                     }
                         
                     continue;
                 }
                 Tree ttx = null;
                 boolean requeue = false;
-                ttx = tt.child(1).head().equals("Commands") ? tt.child(1) : tt;
-                if ("int".equals(tt.child(2).head())) {
-                    count = (int)number(tt.child(2));
-                    requeue = true;
-                } else if ("forever".equals(tt.child(2).head())) {
-                    count = 0;
-                    requeue = true;
-                }
-                tt = tt.child(0);
-                if (tt.head().equals("[*]")) {
-                    cb.add(new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.Infinity));
-                    //count = 0;
-                    requeue = false;
-                } else if (tt.head().equals("int")) {
-                    count = (int)number(tt);
-                    requeue = false;
-                }
+                if ("[T]".equals(tt.child(0).head()))  interruptible = true;
+                ttx = tt.child(tt.size()-1);
                 boolean tokenIn = false;
                 boolean dataIn = false;
                 boolean latch = false;
@@ -469,18 +476,66 @@ public class Parser {
                 Path path = null;
                 for(int i=0; i<ttx.size(); i++) {
                     Tree ttt = ttx.child(i);
-                    if      ("wait".equals(ttt.head()))    { tokenIn = true; }
-                    else if ("nop".equals(ttt.head()))     { }
+                    if      ("recv token".equals(ttt.head()))    { tokenIn = true; }
                     else if ("discard".equals(ttt.head())) { dataIn = true; latch = false; }
                     else if ("take".equals(ttt.head()))    { dataIn = true; latch = true; }
-                    else if ("recv".equals(ttt.head()))    { dataIn = true; latch = true; }
-                    else if ("collect".equals(ttt.head()))    { dataIn = true; latch = true; }
-                    else if ("recieve".equals(ttt.head()))    { dataIn = true; latch = true; }
-                    else if ("send".equals(ttt.head()))  { dispatch = true; dataOut = true; }
-                    else if ("sendto".equals(ttt.head()))  { dataOut = true; path = path(dock, ttt.child(0)); }
+                    else if ("collect".equals(ttt.head()))    {
+                        if (dock.isInputDock())
+                            throw new RuntimeException("you can't use \"collect\" at input docks; try \"recv\" instead");
+                        dataIn = true;
+                        latch = true;
+                    }
+                    else if ("collect path".equals(ttt.head()))    {
+                        if (dock.isInputDock())
+                            throw new RuntimeException("you can't use \"collect\" at input docks; try \"recv\" instead");
+                        dataIn = true;
+                        latch = false;
+                        dispatch = true;
+                    }
+                    else if ("collect packet".equals(ttt.head()))    {
+                        if (dock.isInputDock())
+                            throw new RuntimeException("you can't use \"collect\" at input docks; try \"recv\" instead");
+                        dataIn = true;
+                        latch = true;
+                        dispatch = true;
+                    }
+                    else if ("collect nothing".equals(ttt.head()))    {
+                        if (dock.isInputDock())
+                            throw new RuntimeException("you can't use \"collect\" at input docks; try \"recv\" instead");
+                        dataIn = true;
+                    }
+                    else if ("recv".equals(ttt.head()))    {
+                        if (dock.isOutputDock())
+                            throw new RuntimeException("you can't use \"recv\" at input docks; try \"collect\" instead");
+                        dataIn = true;
+                        latch = true;
+                    }
+                    else if ("recv path".equals(ttt.head()))    {
+                        if (dock.isOutputDock())
+                            throw new RuntimeException("you can't use \"recv\" at input docks; try \"collect\" instead");
+                        dataIn = true;
+                        latch = false;
+                        dispatch = true;
+                    }
+                    else if ("recv packet".equals(ttt.head()))    {
+                        if (dock.isOutputDock())
+                            throw new RuntimeException("you can't use \"recv\" at input docks; try \"collect\" instead");
+                        dataIn = true;
+                        latch = true;
+                        dispatch = true;
+                    }
+                    else if ("recv nothing".equals(ttt.head()))    {
+                        if (dock.isOutputDock())
+                            throw new RuntimeException("you can't use \"recv\" at input docks; try \"collect\" instead");
+                        dataIn = true;
+                    }
+                    else if ("send".equals(ttt.head()))  {
+                        dataOut = true;
+                    }
+                    else if ("send to".equals(ttt.head()))  { dataOut = true; path = path(dock, ttt.child(0)); }
                     else if ("deliver".equals(ttt.head())) { dataOut = true;  }
-                    else if ("notify".equals(ttt.head()))     { tokenOut = true; path = path(dock, ttt.child(0)); }
-                    else if ("notifyLast".equals(ttt.head()))     { tokenOut = true; ignoreUntilLast = true; path = path(dock, ttt.child(0)); }
+                    else if ("send token".equals(ttt.head()))     { tokenOut = true; }
+                    else if ("send token to".equals(ttt.head()))     { tokenOut = true; path = path(dock, ttt.child(0)); }
                 }
                 cb.add(new Move(dock, looping, predicate,
                                             interruptible, path, tokenIn, dataIn,