split literals into low-half/high-half
[fleet.git] / src / edu / berkeley / fleet / api / Instruction.java
1 package edu.berkeley.fleet.api;
2
3 public abstract class Instruction {
4
5     public final Pump pump;
6     public Instruction(Pump pump) { this.pump = pump; }
7     public String toString() { return pump+": "; }
8
9     public static abstract class CountingInstruction extends Instruction {
10         public final int count;
11         public CountingInstruction(Pump pump, int count) {
12             super(pump);
13             this.count = count;
14         }
15         public boolean isStanding() { return count==0; }
16         public abstract boolean isRequeueing();
17         public String toString() { return super.toString()+(count==1?"":(isRequeueing()?("("+(count==0?"*":(count+""))+")"):("["+(count==0?"*":(count+""))+"]")))+" "; }
18     }
19
20     public static class UnClog extends Instruction {
21         public UnClog(Pump pump) { super(pump); }
22         public String toString() { return super.toString() + "unclog;"; }
23     }
24
25     public static class Massacre extends Instruction {
26         public Massacre(Pump pump) { super(pump); }
27     }
28
29     public static class Clog extends Executable {
30         public Clog(Pump pump) { super(pump, 1); }
31         public String toString() { return super.toString() + "clog;"; }
32         public Instruction.Executable decrementCount() { return null; }
33         public boolean isRequeueing() { return false; }
34     }
35
36     public static class Kill extends CountingInstruction {
37         public Kill(Pump pump, int count) { super(pump, count); }
38         public boolean isRequeueing() { return false; }
39         public String toString() { return super.toString() + "kill;"; }
40     }
41
42     public static abstract class Executable extends CountingInstruction {
43         public Executable(Pump pump, int count) { super(pump, count); }
44         public abstract Instruction.Executable decrementCount();
45     }
46
47     public static class Move extends Executable {
48         public final Destination dest;
49
50         public final boolean     tokenIn;
51         public final boolean     dataIn;
52         public final boolean     latch;
53         public final boolean     dataOutDest;
54         public final boolean     dataOut;
55         public final boolean     tokenOut;
56         public final boolean     requeue;
57         public final boolean     ignoreUntilLast;
58
59         public boolean isRequeueing() { return requeue; }
60
61         /** count=0 denotes a standing move */
62         public Move(Pump        pump,
63                           Destination dest,
64                           int         count,
65                           boolean     tokenIn,
66                           boolean     dataIn,
67                           boolean     latch,
68                           boolean     dataOutDest,
69                           boolean     dataOut,
70                           boolean     tokenOut,
71                           boolean     requeue,
72                           boolean     ignoreUntilLast) {
73             super(pump, count);
74             this.dest = dest;
75             this.tokenIn = tokenIn;
76             this.dataIn = dataIn;
77             this.latch = latch;
78             this.dataOutDest = dataOutDest;
79             this.dataOut = dataOut;
80             this.tokenOut = tokenOut;
81             this.requeue = requeue;
82             this.ignoreUntilLast = ignoreUntilLast;
83             if (count < 0)
84                 throw new RuntimeException("count field of an instruction must be >=0");
85             if (pump.isInbox() && tokenIn && dataIn)
86                 throw new RuntimeException("cannot have both \"wait\" and \"take\"/\"recieve\" on an inbox: " + this);
87             if (pump.isOutbox() && tokenOut && dataOut)
88                 throw new RuntimeException("cannot have both \"sendto\" and \"notify\" on an outbox: " + this);
89             if (latch && !dataIn)
90                 throw new RuntimeException("cannot have latch bit set without dataIn bit: " + this);
91         }
92
93         public Instruction.Executable decrementCount() {
94             if (count==1) return null;
95             return new Move(pump, dest, count==0 ? 0 : count-1,
96                             tokenIn, dataIn, latch, dataOutDest, dataOut, tokenOut, requeue, ignoreUntilLast);
97         }
98
99         public String toString() {
100             // FIXME
101             String ret = super.toString();
102             boolean needcomma = false;
103             if (tokenIn)           { ret += (needcomma ? ", " : "") + "wait";    needcomma = true; }
104             if (dataIn && latch)  {
105                 if (pump.isInbox())
106                     ret += (needcomma ? ", " : "") + "receive";
107                 else
108                     ret += (needcomma ? ", " : "") + "take";
109                 needcomma = true;
110             }
111             if (dataIn && !latch)  { ret += (needcomma ? ", " : "") + "dismiss"; needcomma = true; }
112             if (dataOut)  {
113                 if (pump.isInbox() || dest==null)
114                     ret += (needcomma ? ", " : "") + "deliver";
115                 else
116                     ret += (needcomma ? ", " : "") + "sendto "+dest;
117                 needcomma = true;
118             }
119             if (tokenOut) { ret += (needcomma ? ", " : "") + "notify "+dest; needcomma = true; }
120             return ret;
121         }
122
123     }
124
125     public static class LocalLiteral extends Executable {
126         public final long literal;
127         public final boolean high;
128         public boolean isRequeueing() { return true; }
129         public LocalLiteral(Pump pump, long literal, int count, boolean high) {
130             super(pump, count);
131             this.literal = literal;
132             this.high = high;
133         }
134         public Instruction.Executable decrementCount() {
135             if (count==1) return null;
136             return new LocalLiteral(pump, literal, count-1, high);
137         }
138     }
139
140     public static class CodeBagDescriptor extends Instruction {
141         /** address of CBD, relative to address that this instruction was loaded from */
142         public final long offset;
143         public final long size;
144         public CodeBagDescriptor(Pump pump, long offset, long size) {
145             super(pump);
146             this.offset = offset;
147             this.size = size;
148         }
149         public String toString() {
150             String off = ""+offset;
151             if (offset > 0) off = "+"+off;
152             return "(CBD @"+off+"+"+size+"): sendto " + pump;
153         }
154     }
155
156 }