run omegaCounter inverter study with Electric LE code fixed
[fleet.git] / misc / obsolete-ships / ArithmeticShip.java
1 package edu.berkeley.fleet.interpreter.ships;
2 import edu.berkeley.fleet.interpreter.*;
3 import edu.berkeley.fleet.*;
4
5 import java.util.*;
6 import java.io.*;
7
8 /*
9 You should note the following:
10 I haven't implemented all the link-out policies.
11 You can give the SHIP a single cmd with up to four operations.  For
12 example, "ADD ZERO 0 SUBTRACT SIGN 1 MAX MAX 0".  These will be done
13 in left-to-right order.
14 You can use any link-out policy with any operation, though some don't
15 make much sense.
16 */
17
18 /**
19  * @author Dominic Antonelli <dantonel@berkeley.edu>
20  */
21 public class ArithmeticShip extends InterpreterShip {
22
23     private int link;
24
25     DataInbox A = new DataInbox(this, "A");
26     DataInbox B = new DataInbox(this, "B");
27     DataInbox cmd = new DataInbox(this, "cmd");
28     DataOutbox out = new DataOutbox(this, "out");
29
30     public ArithmeticShip(Interpreter fleet, String name) {
31         super(fleet, name);
32     }
33
34     public enum Operation {
35         // NOTE: NOP is not to be used, but rather simply prevents other ops from using opcode 0
36         // This is so that we can detect the "end" of a command - when the command is all zero
37         NOP       { int eval(int a, int b, int link) { System.out.println("ERROR: Arith_NOP\n"); return 0; } },
38         ADD       { int eval(int a, int b, int link) { return a + b + link;            } },
39         SUBTRACT  { int eval(int a, int b, int link) { return a - b + link;            } },
40         COPY_A    { int eval(int a, int b, int link) { return a + link;                } },
41         COPY_B    { int eval(int a, int b, int link) { return b + link;                } },
42         SELECT    { int eval(int a, int b, int link) { return ((link==1) ? b : a);     } },
43         NEGATE_A  { int eval(int a, int b, int link) { return -(a+link);               } },
44         NEGATE_B  { int eval(int a, int b, int link) { return -(b+link);               } },
45         ABS_A     { int eval(int a, int b, int link) { a+=link; return (a<0 ? -a : a); } },
46         ABS_B     { int eval(int a, int b, int link) { b+=link; return (b<0 ? -b : b); } },
47         MAX       { int eval(int a, int b, int link) { return (a>b ?  a : b) + link;   } },
48         MIN       { int eval(int a, int b, int link) { return (a<b ?  a : b) + link;   } },
49         INC_A     { int eval(int a, int b, int link) { return a+1+link;                } },
50         INC_B     { int eval(int a, int b, int link) { return b+1+link;                } },
51         RESERVED1 { int eval(int a, int b, int link) { System.out.println("ERROR: Arith_RESERVED0\n"); return 0; } },
52         RESERVED2 { int eval(int a, int b, int link) { System.out.println("ERROR: Arith_RESERVED1\n"); return 0; } };
53
54
55
56         // Do arithmetic op represented by this constant
57         abstract int eval(int a, int b, int link);
58         public static Operation convertInt( int i ) {
59             return values()[i];
60         }
61     }
62
63     public enum LinkOutPolicy {
64         LINK_IN, ZERO, CARRY, SIGN, OLD_SIGN, OVERFLOW, MAX, MIN;
65         public static LinkOutPolicy convertInt( int i ) {
66             return values()[i];
67         }
68     }
69
70     private long savedCommand = 0;
71
72     public void service() {
73         if (!out.readyForDataFromShip()) return;
74         if (!A.dataReadyForShip()) return;
75         if (!B.dataReadyForShip()) return;
76
77         long command;
78
79         if (savedCommand != 0) {
80             command = savedCommand;
81         } else if (!cmd.dataReadyForShip()) {
82             return;
83         } else {
84             command = cmd.removeDataForShip();
85         }
86
87         int inA = A.removeDataForShip();
88         int inB = B.removeDataForShip();
89         int linkInPolicy = (int)(command & 0x1);
90         LinkOutPolicy linkOutPolicy = LinkOutPolicy.convertInt((int)((command >> 1) & 0x7));
91         Operation op = Operation.convertInt((int)((command >> 4) & 0xf));
92         int result = 0;
93
94         int oldLink = link;
95         if (op == Operation.SELECT) {
96             link = link ^ linkInPolicy; // LinkInPolicy = 1 mean flip the selection for the SELECT op.
97         } else {
98             link = link & linkInPolicy; // If linkInPolicy is zero, unset the link bit for the upcoming computation.
99                                         // NOTE: The final value of link will be computed after eval.
100         }
101
102         result = op.eval(inA, inB, link);
103
104         switch (linkOutPolicy) {
105             case LINK_IN:
106                 link = oldLink;
107                 break;
108             case ZERO:
109                 link = (result == 0) ? 1 : 0;
110 //                link = 0;
111                 break;
112             case SIGN:
113                 link = (result >> 31) & 0x1;
114                 break;
115             case MAX:
116                 if (inA > inB) link = 1; else link = 0;
117                 break;
118             case MIN:
119                 if (inA < inB) link = 1; else link = 0;
120                 break;
121             case CARRY:
122             case OLD_SIGN:
123             case OVERFLOW:
124                 System.out.println("ERROR: non-implemented linkOutPolicy selected");
125                 break;
126             default:
127                 System.out.println("ERROR: Unknown linkOutPolicy selected");
128                 break;
129         };
130         out.addDataFromShip(result);
131
132         savedCommand = command >> 8;
133
134 //        System.out.println("Link is now " + link);
135     }
136
137     public int resolveShipSpecificConstant(String shipSpecificData) {
138         String[] data = shipSpecificData.split("\\s");
139         int result = 0;
140
141         if ((data.length % 3) != 0) {
142             System.out.println("ERROR: ArithmeticShip received invalid ShipSpecificConstant");
143         }
144         for (int i = data.length - 1; i >= 2; i-=3) {
145             result <<= 8;
146             if (data[i].equals("1")) {
147                 result |= 1;
148             }
149             for (LinkOutPolicy policy : LinkOutPolicy.values()) {
150                 if (data[i-1].equals(policy.toString())) {
151                     result |= (policy.ordinal() << 1);
152                 }
153             }
154             for (Operation op : Operation.values()) {
155                 if (data[i-2].equals(op.toString())) {
156                     result |= (op.ordinal() << 4);
157                 }
158             }
159         }
160         return result;
161     }
162 }