1 package edu.berkeley.fleet.interpreter;
4 import java.lang.reflect.*;
5 import edu.berkeley.fleet.*;
6 import edu.berkeley.fleet.api.*;
7 import edu.berkeley.fleet.ies44.*;
8 import edu.berkeley.fleet.ships.*;
10 public class Interpreter extends Fleet /*, Fleet.WithDynamicShips*/ {
12 /** some "halt ship" can turn this on to stop the interpreter */
13 public boolean halt = false;
15 public ArrayList<InterpreterShip> shiplist = new ArrayList<InterpreterShip>();
16 public HashMap<String,InterpreterShip> ships = new HashMap<String,InterpreterShip>();
18 public void go(byte[] instructions) {
20 // find the first icache
23 if (ship instanceof Icache) {
24 icache = (Icache)ship;
28 // load the icache and take note of the 0-address CBD
30 for(int i=0; i<instructions.length; i+=6) {
32 for(int j=0; j<6; j++)
33 word = (word << 8) | (instructions[i+j] & 0xff);
34 icache.writeMem(i/6, word);
35 if (i==0) launch = word;
38 // dispatch the 0-address CBD
39 int base = (int)(launch >> 6);
40 base = base & ~(0xffffffff << 18);
41 int size = (int)launch;
42 size = size & ~(0xffffffff << 6);
43 icache.dispatch(base, size);
46 for(InterpreterShip ship : ships.values())
47 for(int j=0; j<10; j++)
50 // run the ships a bit longer for good measure
51 for(int i=0; i<100; i++)
52 for(InterpreterShip ship : ships.values())
53 for(int j=0; j<10; j++)
56 // check the state of the ships
57 for(InterpreterShip ship : ships.values())
60 Log.println(Log.yellow(" DONE: ====== FLEET is halted. Have a nice day. ======"));
63 public void dispatch(Instruction i, long address) {
65 if (i instanceof Instruction.Executable) {
66 InterpreterBenkoBox sourceBenkoBox = (InterpreterBenkoBox)(((Instruction.Executable)i).benkoBox);
67 ((InstructionPort)sourceBenkoBox).addInstruction(((Instruction.Executable)i));
69 } else if (i instanceof Instruction.Literal.CodeBagDescriptor) {
70 Instruction.Literal.CodeBagDescriptor cbd = (Instruction.Literal.CodeBagDescriptor)i;
71 InterpreterBenkoBox destBenkoBox = (InterpreterBenkoBox)(cbd.dest);
72 long absolute_cbd = ((cbd.offset+address) << 6) | cbd.size;
73 destBenkoBox.addDataFromFabric((int)absolute_cbd);
75 } else if (i instanceof Instruction.Literal.Absolute) {
76 InterpreterBenkoBox destBenkoBox = (InterpreterBenkoBox)(((Instruction.Literal.Absolute)i).dest);
77 Log.data(((Instruction.Literal.Absolute)i).value+"", null, destBenkoBox);
78 destBenkoBox.addDataFromFabric((int)((Instruction.Literal.Absolute)i).value);
80 } else if (i instanceof Instruction.Kill) {
81 InterpreterBenkoBox benkoBox = (InterpreterBenkoBox)(((Instruction.Kill)i).benkoBox);
82 ((InstructionPort)benkoBox).kill(((Instruction.Kill)i).count);
85 throw new Error("unsupported: " + i.getClass().getName());
89 public void sendToken(InterpreterBenkoBox source, InterpreterBenkoBox dest) {
90 Log.token(source, dest);
91 dest.addTokenFromFabric();
94 public void sendData(InterpreterBenkoBox source, int data, InterpreterBenkoBox dest) {
95 Log.data(data+"", source, dest);
96 dest.addDataFromFabric(data);
100 // Implementation of the Fleet class abstract methods /////////////////////////////////////////////////////////
102 public Iterator<Ship> iterator() { return (Iterator<Ship>)(Object)shiplist.iterator(); }
104 public int computeOffset(int origin, int target) { return (target - origin)/6; }
105 public int computeTarget(int origin, int offset) { return origin + (offset*6); }
107 private InterpreterInstructionEncoder iie = new InterpreterInstructionEncoder();
108 public Instruction readInstruction(DataInputStream is) throws IOException { return iie.readInstruction(is); }
109 public Instruction readInstruction(long instr) { return iie.readInstruction(instr); }
110 public long writeInstruction(Instruction d) { return writeInstruction(d); }
111 public void writeInstruction(DataOutputStream os, Instruction d) throws IOException { iie.writeInstruction(os, d); }
113 private class InterpreterInstructionEncoder extends InstructionEncoder {
114 public long getBoxAddr(BenkoBox box) { return ((InterpreterBenkoBox)box).addr; }
115 public long getBoxInstAddr(BenkoBox box) { return ((InterpreterBenkoBox)box).instr_addr; }
116 public BenkoBox getBoxByAddr(long dest) {
117 for(Ship ship : Interpreter.this)
118 for(BenkoBox bb : ship.getBenkoBoxes())
119 if (((InterpreterBenkoBox)bb).addr == dest)
123 public BenkoBox getBoxByInstAddr(long dest) {
124 for(Ship ship : Interpreter.this)
125 for(BenkoBox bb : ship.getBenkoBoxes())
126 if (((InterpreterBenkoBox)bb).instr_addr == dest)
132 public Ship createShip(String shipType, String shipname) {
134 Class c = Class.forName("edu.berkeley.fleet.ships."+shipType);
135 Constructor con = c.getConstructor(new Class[] { Interpreter.class, String.class });
136 InterpreterShip ret = (InterpreterShip)con.newInstance(new Object[] { this, shipname });
137 ships.put(shipname, ret);
140 } catch (Exception e) {
146 // Memory //////////////////////////////////////////////////////////////////////////////
148 public int[] mem = new int[0];
150 public void dumpMem() {
151 Log.print(Log.cyan(" MEMORY: "));
152 for(int i=0; i<mem.length; i++) {
153 if ((i%10)==0 && i!=0) Log.print(Log.cyan(" "));
154 Log.print(Log.cyan(mem[i] + " "));
155 if ((i%10)==9 && i!=mem.length-1) Log.println("");
160 public int readMem(int addr) {
161 return addr >= mem.length ? 0 : mem[addr];
163 public void writeMem(int addr, int data) {
164 if (addr >= mem.length) {
165 int[] mem2 = new int[addr*2+1];
166 System.arraycopy(mem, 0, mem2, 0, mem2.length);