add interpreter code and tests for loop counter instructions
[fleet.git] / src / edu / berkeley / fleet / ies44 / InstructionEncoder.java
index 2d9dada..5e4571f 100644 (file)
@@ -16,7 +16,6 @@ public abstract class InstructionEncoder {
     public static final int WIDTH_MASK_LITERAL     = 6;
     public static final int MASK_LITERAL           = 13;   // this is an excessive approximation
 
-
     public static final int OFFSET_MASK_MASSACRE   = 14;
     public static final int WIDTH_MASK_MASSACRE    = 26-14;
     public static final int MASK_MASSACRE          = 1;
@@ -33,10 +32,37 @@ public abstract class InstructionEncoder {
     public static final int WIDTH_MASK_CLOG        = 26-14;
     public static final int MASK_CLOG              = 2;
 
+    public static final int OFFSET_MASK_LOAD_LOOP_TO_DATA       = 14;
+    public static final int WIDTH_MASK_LOAD_LOOP_TO_DATA        = 12;
+    public static final int MASK_LOAD_LOOP_TO_DATA         = 0;
+
+    public static final int OFFSET_MASK_LOAD_LITERAL_TO_LOOP       = 14;
+    public static final int WIDTH_MASK_LOAD_LITERAL_TO_LOOP        = 12;
+    public static final int MASK_LOAD_LITERAL_TO_LOOP              = 1;
+
+    public static final int OFFSET_MASK_LOAD_LITERAL_TO_REPEAT       = 14;
+    public static final int WIDTH_MASK_LOAD_LITERAL_TO_REPEAT        = 12;
+    public static final int MASK_LOAD_LITERAL_TO_REPEAT              = 2;
+
+    public static final int OFFSET_MASK_LOAD_DATA_TO_REPEAT       = 14;
+    public static final int WIDTH_MASK_LOAD_DATA_TO_REPEAT        = 12;
+    public static final int MASK_LOAD_DATA_TO_REPEAT              = 3;
+
+    public static final int OFFSET_MASK_LOAD_DATA_TO_LOOP       = 14;
+    public static final int WIDTH_MASK_LOAD_DATA_TO_LOOP        = 12;
+    public static final int MASK_LOAD_DATA_TO_LOOP              = 4;
+
+    public static final int OFFSET_MASK_DECR_LOOP       = 14;
+    public static final int WIDTH_MASK_DECR_LOOP        = 12;
+    public static final int MASK_DECR_LOOP              = 5;
+
     public static final int OFFSET_MASK_NORMAL     = 25;
     public static final int WIDTH_MASK_NORMAL      = 1;
     public static final int MASK_NORMAL            = 1;
 
+    public static final int OFFSET_COUNTER_LITERAL     = 0;
+    public static final int WIDTH_COUNTER_LITERAL      = 6;
+
     public static final int OFFSET_COUNT           = 0;
     public static final int OFFSET_DEST            = OFFSET_COUNT+WIDTH_COUNT;
     public static final int OFFSET_CONTROL         = OFFSET_DEST+WIDTH_DEST_ADDR;
@@ -85,6 +111,21 @@ public abstract class InstructionEncoder {
 
     public Instruction readInstruction(long inst) {
         Pump name           = getBoxByInstAddr(getIntField(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1, OFFSET_PUMP_ADDR, inst));
+
+        int count_literal = getIntField(OFFSET_COUNTER_LITERAL+WIDTH_COUNTER_LITERAL-1, OFFSET_COUNTER_LITERAL, inst);
+        if (getIntField(OFFSET_MASK_LOAD_LOOP_TO_DATA+WIDTH_MASK_LOAD_LOOP_TO_DATA-1, OFFSET_MASK_LOAD_LOOP_TO_DATA,inst)==MASK_LOAD_LOOP_TO_DATA)
+            return new Instruction.Counter(name, Instruction.Counter.LOOP_COUNTER, Instruction.Counter.DATA_LATCH);
+        else if (getIntField(OFFSET_MASK_LOAD_DATA_TO_REPEAT+WIDTH_MASK_LOAD_DATA_TO_REPEAT-1, OFFSET_MASK_LOAD_DATA_TO_REPEAT,inst)==MASK_LOAD_DATA_TO_REPEAT)
+            return new Instruction.Counter(name, Instruction.Counter.DATA_LATCH, Instruction.Counter.REPEAT_COUNTER);
+        else if (getIntField(OFFSET_MASK_LOAD_DATA_TO_LOOP+WIDTH_MASK_LOAD_DATA_TO_LOOP-1, OFFSET_MASK_LOAD_DATA_TO_LOOP,inst)==MASK_LOAD_DATA_TO_LOOP)
+            return new Instruction.Counter(name, Instruction.Counter.DATA_LATCH, Instruction.Counter.LOOP_COUNTER);
+        else if (getIntField(OFFSET_MASK_LOAD_LITERAL_TO_LOOP+WIDTH_MASK_LOAD_LITERAL_TO_LOOP-1, OFFSET_MASK_LOAD_LITERAL_TO_LOOP,inst)==MASK_LOAD_LITERAL_TO_LOOP)
+            return new Instruction.Counter(name, count_literal, Instruction.Counter.LOOP_COUNTER);
+        else if (getIntField(OFFSET_MASK_LOAD_LITERAL_TO_REPEAT+WIDTH_MASK_LOAD_LITERAL_TO_REPEAT-1, OFFSET_MASK_LOAD_LITERAL_TO_REPEAT,inst)==MASK_LOAD_LITERAL_TO_REPEAT)
+            return new Instruction.Counter(name, count_literal, Instruction.Counter.REPEAT_COUNTER);
+        else if (getIntField(OFFSET_MASK_DECR_LOOP+WIDTH_MASK_DECR_LOOP-1, OFFSET_MASK_DECR_LOOP,inst)==MASK_DECR_LOOP)
+            return new Instruction.DecrLoop(name);
+
         if (getIntField(OFFSET_MASK_UNCLOG+WIDTH_MASK_UNCLOG-1, OFFSET_MASK_UNCLOG,inst)==MASK_UNCLOG)
             return new Instruction.UnClog(name);
         if (getIntField(OFFSET_MASK_CLOG+WIDTH_MASK_CLOG-1, OFFSET_MASK_CLOG,inst)==MASK_CLOG)
@@ -157,6 +198,32 @@ public abstract class InstructionEncoder {
                 instr = inst.literal;
             }
 
+        } else if (d instanceof Instruction.DecrLoop) {
+            instr |= putField(OFFSET_MASK_DECR_LOOP+WIDTH_MASK_DECR_LOOP-1, OFFSET_MASK_DECR_LOOP, MASK_DECR_LOOP);
+
+        } else if (d instanceof Instruction.Counter) {
+            Instruction.Counter ic = (Instruction.Counter)d;
+            if (ic.dest == Instruction.Counter.DATA_LATCH && ic.source == Instruction.Counter.LOOP_COUNTER)
+                instr |= putField(OFFSET_MASK_LOAD_LOOP_TO_DATA+WIDTH_MASK_LOAD_LOOP_TO_DATA-1,
+                                  OFFSET_MASK_LOAD_LOOP_TO_DATA,       MASK_LOAD_LOOP_TO_DATA);
+            else if (ic.dest == Instruction.Counter.REPEAT_COUNTER && ic.source == Instruction.Counter.DATA_LATCH)
+                instr |= putField(OFFSET_MASK_LOAD_DATA_TO_REPEAT+WIDTH_MASK_LOAD_DATA_TO_REPEAT-1,
+                                  OFFSET_MASK_LOAD_DATA_TO_REPEAT,       MASK_LOAD_DATA_TO_REPEAT);
+            else if (ic.dest == Instruction.Counter.LOOP_COUNTER && ic.source == Instruction.Counter.DATA_LATCH)
+                instr |= putField(OFFSET_MASK_LOAD_DATA_TO_LOOP+WIDTH_MASK_LOAD_DATA_TO_LOOP-1,
+                                  OFFSET_MASK_LOAD_DATA_TO_LOOP,       MASK_LOAD_DATA_TO_LOOP);
+            else if (ic.dest == Instruction.Counter.REPEAT_COUNTER) {
+                instr |= putField(OFFSET_MASK_LOAD_LITERAL_TO_REPEAT+WIDTH_MASK_LOAD_LITERAL_TO_REPEAT-1,
+                                  OFFSET_MASK_LOAD_LITERAL_TO_REPEAT,       MASK_LOAD_LITERAL_TO_REPEAT);
+                instr |= putField(OFFSET_COUNTER_LITERAL+WIDTH_COUNTER_LITERAL-1,
+                                  OFFSET_COUNTER_LITERAL, ic.source);
+            } else if (ic.dest == Instruction.Counter.LOOP_COUNTER) {
+                instr |= putField(OFFSET_MASK_LOAD_LITERAL_TO_LOOP+WIDTH_MASK_LOAD_LITERAL_TO_LOOP-1,
+                                  OFFSET_MASK_LOAD_LITERAL_TO_LOOP,       MASK_LOAD_LITERAL_TO_LOOP);
+                instr |= putField(OFFSET_COUNTER_LITERAL+WIDTH_COUNTER_LITERAL-1,
+                                  OFFSET_COUNTER_LITERAL, ic.source);
+            } else throw new RuntimeException();
+
         } else if (d instanceof Instruction.Move) {
             Instruction.Move inst = (Instruction.Move)d;
             instr |= putField(OFFSET_MASK_NORMAL+WIDTH_MASK_NORMAL-1, OFFSET_MASK_NORMAL,       MASK_NORMAL);