From: adam Date: Sat, 27 Jan 2007 03:52:13 +0000 (+0100) Subject: separated interpreter from assembler X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=2f30a6dc6ddfa0bc01ba752529b40b8c174d06fd;p=fleet.git separated interpreter from assembler --- diff --git a/Makefile b/Makefile index 56f94d1..71565b7 100644 --- a/Makefile +++ b/Makefile @@ -8,9 +8,9 @@ java = java -Xmx500m run: fleeterpreter.jar $(java) -cp $(cp) $(interpreter_class) < contrib/demo.fleet -fleeterpreter.jar: $(shell find src -name \*.java) src/edu/berkeley/fleet/parser/fleet.g - mkdir -p bin/edu/berkeley/fleet/parser/ - cp src/edu/berkeley/fleet/parser/fleet.g bin/edu/berkeley/fleet/parser/ +fleeterpreter.jar: $(shell find src -name \*.java) src/edu/berkeley/fleet/assembler/fleet.g + mkdir -p bin/edu/berkeley/fleet/assembler/ + cp src/edu/berkeley/fleet/assembler/fleet.g bin/edu/berkeley/fleet/assembler/ javac -cp lib/edu.berkeley.sbp.jar -d bin $(shell find src -name \*.java) cd bin; jar xvf ../lib/edu.berkeley.sbp.jar echo 'Main-Class: $(interpreter_class)' > bin/manifest @@ -87,7 +87,7 @@ javadoc: -noqualifier all \ -d doc/api \ edu.berkeley.fleet.api \ - edu.berkeley.fleet.parser + edu.berkeley.fleet.assembler ## Misc #################################################################################### diff --git a/README b/README new file mode 100644 index 0000000..4a041ba --- /dev/null +++ b/README @@ -0,0 +1,18 @@ +== Fleet Code Distribution ======================================================================= + +Directories + + Makefile + README -- this file + doc/ + api/ -- javadoc goes here + src/ + edu/berkeley/fleet/ + api/ -- api classes + interpreter/ -- fleet interpreter + assembler/ -- assembler code + fleet.g -- fleet grammar + slipway/ -- code for Fleet-on-RAMP simulator + contrib/ -- sample code + lib/ -- jar libraries + diff --git a/src/edu/berkeley/fleet/api/Fleet.java b/src/edu/berkeley/fleet/api/Fleet.java index 4c5432a..6546d17 100644 --- a/src/edu/berkeley/fleet/api/Fleet.java +++ b/src/edu/berkeley/fleet/api/Fleet.java @@ -13,4 +13,18 @@ public abstract class Fleet implements Iterable { /** ships must be returned in the same order every time -- ordering may be significant */ public abstract Iterator iterator(); + /** + * Compute the value that should go in the MACHINE-addressed + * "offset" field of a literal given BYTE-addressed origin and + * target + */ + public abstract int computeOffset(int origin, int target); + + /** + * Compute the value that should go in the "offset" field of a + * literal given BYTE-addressed origin and MACHINE-addressed + * target + */ + public abstract int computeTarget(int origin, int offset); + } \ No newline at end of file diff --git a/src/edu/berkeley/fleet/assembler/Main.java b/src/edu/berkeley/fleet/assembler/Main.java new file mode 100644 index 0000000..6b81c8b --- /dev/null +++ b/src/edu/berkeley/fleet/assembler/Main.java @@ -0,0 +1,21 @@ +package edu.berkeley.fleet.assembler; + +import edu.berkeley.fleet.api.*; +import java.io.*; +import java.util.*; + +/** main entry point to the assembler */ +public class Main { + + /** parse the assembly code on r, encode it for fleet, and write a binary on out */ + public static void assemble(Fleet fleet, Reader r, OutputStream out) throws Exception { + new Parser(fleet).parse(r, out); + } + + /** parse the assembly code on r, encode it for fleet, and insert + * Instructions into out */ + public static void assemble(Fleet fleet, Reader r, ArrayList out) throws Exception { + new Parser(fleet).parse(r, out); + } + +} \ No newline at end of file diff --git a/src/edu/berkeley/fleet/parser/Parser.java b/src/edu/berkeley/fleet/assembler/Parser.java similarity index 55% rename from src/edu/berkeley/fleet/parser/Parser.java rename to src/edu/berkeley/fleet/assembler/Parser.java index 6c73537..7c9318e 100644 --- a/src/edu/berkeley/fleet/parser/Parser.java +++ b/src/edu/berkeley/fleet/assembler/Parser.java @@ -1,11 +1,7 @@ -package edu.berkeley.fleet.parser; +package edu.berkeley.fleet.assembler; import edu.berkeley.fleet.api.*; -// used only for special interpreter parsing extensions -import edu.berkeley.fleet.interpreter.Interpreter; -import edu.berkeley.fleet.interpreter.CodeBag; - import edu.berkeley.sbp.*; import edu.berkeley.sbp.chr.*; import edu.berkeley.sbp.misc.*; @@ -15,24 +11,27 @@ import edu.berkeley.sbp.util.*; import java.util.*; import java.io.*; -// FIXME: eliminate use of CodeBag class - /** * @author Adam Megacz - * @author Thomas Kho */ -public class Parser { +class Parser { - public Parser(Fleet fleet) { + Parser(Fleet fleet) { this.fleet = fleet; } ////////////////////////////////////////////////////////////////////////////// - private HashMap shipMap = - new HashMap(); + private Fleet fleet; + private ArrayList imports = new ArrayList(); - static Tree parse(Reader r) throws Exception { + private HashMap shipMap = new HashMap(); + + // codebags in numerical order + private ArrayList codeBags = new ArrayList(); + private HashMap codeBagsByName = new HashMap(); + + Tree parse(Reader r) throws Exception { InputStream grammarStream = Parser.class.getClassLoader().getResourceAsStream("edu/berkeley/fleet/parser/fleet.g"); CharParser metaGrammarParser = new CharParser(MetaGrammar.newInstance()); @@ -43,26 +42,93 @@ public class Parser { return tree; } - private Fleet fleet; - private ArrayList imports = new ArrayList(); + public void parse(Reader r, OutputStream out) throws Exception { + + // this needs to be "code bag zero" + CodeBag baseCodeBag = new CodeBag(); + CodeBag rootCodeBag = new CodeBag(); + baseCodeBag.add(new Instruction.Literal.CodeBagDescriptor(null, rootCodeBag.getFakeAddress(), 1)); + walk((Tree)parse(r), rootCodeBag); + + // map from arbitrary identifiers to actual addresses + int[] codeBagMap = new int[codeBags.size()]; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + CountingOutputStream cos = new CountingOutputStream(baos); + DataOutputStream dos = new DataOutputStream(cos); + for(int i=0; i out) throws Exception { + // this needs to be "code bag zero" + CodeBag baseCodeBag = new CodeBag(); + CodeBag rootCodeBag = new CodeBag(); + Instruction inst0 = new Instruction.Literal.CodeBagDescriptor(null, rootCodeBag.getFakeAddress(), 1); + baseCodeBag.add(inst0); + walk((Tree)parse(r), rootCodeBag); + // map from arbitrary identifiers to actual addresses + int[] codeBagMap = new int[codeBags.size()]; + ArrayList temp = new ArrayList(); + for(int i=0; i)parse(r)); + // now write for real + for(int i=0; i t) { - CodeBag rootCodeBag = null; + /** in the first pass, codebags are assigned "addresses" in arbitrary order */ + void walk(Tree t, CodeBag cb) { + String head = t.head(); if (head==null) { } else if (head.equals("Program")) { for(Tree tc : t.child(0)) - walk(tc); - CodeBag cb = new CodeBag(null, null); + walk(tc, cb); if (t.size()>1) for(Tree statement : t.child(1)) fillCodeBag(statement, cb); - rootCodeBag = cb; } else if (head.equals("Import")) { imports.add(string(t.child(0))); @@ -71,11 +137,13 @@ public class Parser { String name = name(t.child(0)); String type = string(t.child(1)); Ship ship = null; - if (fleet instanceof Fleet) { + if (fleet instanceof edu.berkeley.fleet.interpreter.Interpreter) { + edu.berkeley.fleet.interpreter.Interpreter interpreter = + ((edu.berkeley.fleet.interpreter.Interpreter)fleet); String classname = type; boolean good = false; for(String s : imports) - if ((ship = ((Interpreter)fleet).tryCreate(s+"."+classname, name)) != null) + if ((ship = interpreter.tryCreate(s+"."+classname, name)) != null) break; if (ship==null) throw new RuntimeException("couldn't find a ship called \""+classname+"\""); @@ -86,21 +154,20 @@ public class Parser { } else if (head.equals("Include")) { try { - walk(parse(new InputStreamReader(new FileInputStream(string(t.child(0)))))); + walk(parse(new InputStreamReader(new FileInputStream(string(t.child(0))))), cb); } catch (Exception e) { throw new RuntimeException(e); } } else if (head.equals("Memory")) { - if (((Interpreter)fleet).mem.length != 0) + if (((edu.berkeley.fleet.interpreter.Interpreter)fleet).mem.length != 0) throw new RuntimeException("multiple memory directives found"); Tree m = t.child(0); int[] mem = new int[m.size()]; for(int i=0; i t) { @@ -148,7 +215,7 @@ public class Parser { void fillCodeBag(Tree t, CodeBag cb) { if (t.head()==null) return; else if (t.head().equals("NamedCodeBag")) { - CodeBag cb2 = new CodeBag(cb, name(t.child(0))); + CodeBag cb2 = new CodeBag(name(t.child(0))); for(Tree statement : t.child(1)) fillCodeBag(statement, cb2); @@ -197,8 +264,32 @@ public class Parser { else if ("Ack".equals(ttt.head())) { tokenOut = true; dest = portReference(ttt.child(0)); } } cb.add(new Instruction.Executable(benkobox, - dest, count, tokenIn, dataIn, latch, dataOut, tokenOut, recycle)); + dest, count, tokenIn, dataIn, + latch, dataOut, tokenOut, recycle)); } } } + + private static class CountingOutputStream extends FilterOutputStream { + public CountingOutputStream(OutputStream os) { super(os); } + int count = 0; + public int getCount() { return count; } + public void write(int b) throws IOException { + super.write(b); + count++; + } + public void write(byte[] b, int off, int len) throws IOException { + super.write(b, off, len); + count += len; + } + } + + private class CodeBag extends ArrayList { + public int address = -1; + public CodeBag() { codeBags.add(this); } + public CodeBag(String name) { this(); codeBagsByName.put(name, this); } + public long getFakeAddress() { return codeBags.indexOf(this); } + public boolean equals(Object o) { return this==o; } + } + } diff --git a/src/edu/berkeley/fleet/parser/fleet.g b/src/edu/berkeley/fleet/assembler/fleet.g similarity index 100% rename from src/edu/berkeley/fleet/parser/fleet.g rename to src/edu/berkeley/fleet/assembler/fleet.g diff --git a/src/edu/berkeley/fleet/interpreter/CodeBag.java b/src/edu/berkeley/fleet/interpreter/CodeBag.java index 1e4c1be..41ef0bf 100644 --- a/src/edu/berkeley/fleet/interpreter/CodeBag.java +++ b/src/edu/berkeley/fleet/interpreter/CodeBag.java @@ -31,10 +31,13 @@ public class CodeBag { } public void dispatch(Fleet fleet) { + /* for(Instruction d : dispatchables) { Log.dispatch(d); ((Interpreter)fleet).dispatch(d); } + */ + throw new RuntimeException(); } public void add(Instruction instr) { diff --git a/src/edu/berkeley/fleet/interpreter/Interpreter.java b/src/edu/berkeley/fleet/interpreter/Interpreter.java index cff67db..5e8952c 100644 --- a/src/edu/berkeley/fleet/interpreter/Interpreter.java +++ b/src/edu/berkeley/fleet/interpreter/Interpreter.java @@ -17,7 +17,11 @@ public class Interpreter extends Fleet implements Iterable { public InterpreterBenkoBox resolve(edu.berkeley.fleet.api.BenkoBox bb) { return (InterpreterBenkoBox)bb; } - public void dispatch(Instruction i) { + public void dumpCode() { + throw new RuntimeException("not implemented"); + } + + public void dispatch(Instruction i, long address) { if (i instanceof Instruction.Executable) { InterpreterBenkoBox sourceBenkoBox = resolve(((Instruction.Executable)i).benkoBox); @@ -25,6 +29,11 @@ public class Interpreter extends Fleet implements Iterable { throw new RuntimeException(sourceBenkoBox + " is not an InstructionPort!"); ((InstructionPort)sourceBenkoBox).addInstruction(((Instruction.Executable)i)); + } else if (i instanceof Instruction.Literal.CodeBagDescriptor) { + Log.dispatch(i); + Instruction.Literal.CodeBagDescriptor cbd = (Instruction.Literal.CodeBagDescriptor)i; + dispatchCodeBag(cbd.offset+address, cbd.size); + } else if (i instanceof Instruction.Literal.Absolute) { InterpreterBenkoBox destBenkoBox = resolve(((Instruction.Literal.Absolute)i).dest); Log.data(((Instruction.Literal.Absolute)i).value+"", null, destBenkoBox); @@ -37,7 +46,7 @@ public class Interpreter extends Fleet implements Iterable { ((InstructionPort)benkoBox).kill(((Instruction.Kill)i).count); } else { - throw new Error("unsupported!"); + throw new Error("unsupported: " + i.getClass().getName()); } } @@ -45,6 +54,8 @@ public class Interpreter extends Fleet implements Iterable { public boolean halt = false; public int[] mem = new int[0]; + + public Instruction[] instructions = null; public ArrayList imports = new ArrayList(); private static String getUniqueName(Ship ship) { @@ -60,41 +71,41 @@ public class Interpreter extends Fleet implements Iterable { return null; } - public void writeInstruction(DataOutputStream os, Instruction d) throws IOException { - if (d instanceof Instruction.Executable) { - Instruction.Executable inst = (Instruction.Executable)d; - - InterpreterBenkoBox dest = resolve(inst.dest); - long instr = dest==null ? 0 : (dest.addr << 1); - - instr |= (((long)inst.count) << (11+1)); - if (inst.tokenIn) instr |= (1L << (11+1+7+0)); - if (inst.dataOut) instr |= (1L << (11+1+7+1)); - if (inst.latch) instr |= (1L << (11+1+7+2)); - if (inst.dataIn) instr |= (1L << (11+1+7+3)); - if (inst.tokenOut) instr |= (1L << (11+1+7+4)); - instr |= ((long)resolve(inst.benkoBox).instr_addr) << (11+5+7+1); - long out = 0; - out |= ((InterpreterBenkoBox)ships.get("command").getBenkoBox("data")).addr; - out |= instr << 11; - dump(os, (out >> (5*8)) & 0xff); - dump(os, (out >> (4*8)) & 0xff); - dump(os, (out >> (3*8)) & 0xff); - dump(os, (out >> (2*8)) & 0xff); - dump(os, (out >> (1*8)) & 0xff); - dump(os, (out >> (0*8)) & 0xff); - } else if (d instanceof Instruction.Literal.Absolute) { - Instruction.Literal.Absolute ld = (Instruction.Literal.Absolute)d; - long out = 0; - out |= resolve(ld.dest).addr; - out |= ((long)ld.value) << 11; - dump(os, (out >> (5*8)) & 0xff); - dump(os, (out >> (4*8)) & 0xff); - dump(os, (out >> (3*8)) & 0xff); - dump(os, (out >> (2*8)) & 0xff); - dump(os, (out >> (1*8)) & 0xff); - dump(os, (out >> (0*8)) & 0xff); - } + public void writeInstruction(DataOutputStream os, Instruction d) throws IOException { + if (d instanceof Instruction.Executable) { + Instruction.Executable inst = (Instruction.Executable)d; + + InterpreterBenkoBox dest = resolve(inst.dest); + long instr = dest==null ? 0 : (dest.addr << 1); + + instr |= (((long)inst.count) << (11+1)); + if (inst.tokenIn) instr |= (1L << (11+1+7+0)); + if (inst.dataOut) instr |= (1L << (11+1+7+1)); + if (inst.latch) instr |= (1L << (11+1+7+2)); + if (inst.dataIn) instr |= (1L << (11+1+7+3)); + if (inst.tokenOut) instr |= (1L << (11+1+7+4)); + instr |= ((long)resolve(inst.benkoBox).instr_addr) << (11+5+7+1); + long out = 0; + out |= ((InterpreterBenkoBox)ships.get("command").getBenkoBox("data")).addr; + out |= instr << 11; + dump(os, (out >> (5*8)) & 0xff); + dump(os, (out >> (4*8)) & 0xff); + dump(os, (out >> (3*8)) & 0xff); + dump(os, (out >> (2*8)) & 0xff); + dump(os, (out >> (1*8)) & 0xff); + dump(os, (out >> (0*8)) & 0xff); + } else if (d instanceof Instruction.Literal.Absolute) { + Instruction.Literal.Absolute ld = (Instruction.Literal.Absolute)d; + long out = 0; + out |= resolve(ld.dest).addr; + out |= ((long)ld.value) << 11; + dump(os, (out >> (5*8)) & 0xff); + dump(os, (out >> (4*8)) & 0xff); + dump(os, (out >> (3*8)) & 0xff); + dump(os, (out >> (2*8)) & 0xff); + dump(os, (out >> (1*8)) & 0xff); + dump(os, (out >> (0*8)) & 0xff); + } } public void dump(OutputStream os, long data_) throws IOException { int data = (int)data_; @@ -106,7 +117,16 @@ public class Interpreter extends Fleet implements Iterable { return (Iterator)(Object)shiplist.iterator(); } + public void dispatchCodeBag(long base, long size) { + for(long i=base; i { if (quiet) return; System.out.println("`include \"macros.v\""); /* - HashSet added = new HashSet(); - for(Ship ship : shiplist) - if (!added.contains(ship.getClass())) { - added.add(ship.getClass()); - System.out.println("import ["+ship.getBalsaName()+"]"); - } + HashSet added = new HashSet(); + for(Ship ship : shiplist) + if (!added.contains(ship.getClass())) { + added.add(ship.getClass()); + System.out.println("import ["+ship.getBalsaName()+"]"); + } */ System.out.println("module fabric(clk, top_r, top_a, top,"); System.out.println(" data_Debug0_out_r, data_Debug0_out_a, data_Debug0_out);"); @@ -308,7 +328,8 @@ public class Interpreter extends Fleet implements Iterable { this.prefix = prefix; root = (Node)mkNode("", component, ports, 0, ports.length, 0, 0); } - private Object mkNode(String name, String component, InterpreterBenkoBox[] ports, int start, int end, int addr, int bits) { + private Object mkNode(String name, String component, InterpreterBenkoBox[] ports, + int start, int end, int addr, int bits) { if (end-start == 0) return null; if (end-start == 1) { InterpreterBenkoBox p = ports[start]; @@ -345,8 +366,8 @@ public class Interpreter extends Fleet implements Iterable { Object right; String name; String component; - int addr; - int bits; + int addr; + int bits; public Node(String name, String component, Object left, Object right, int addr, int bits) { this.left = left; this.right = right; @@ -359,7 +380,8 @@ public class Interpreter extends Fleet implements Iterable { String indent = ""; for(int i=0; i { } } public static int krunk=0; + + public int computeOffset(int origin, int target) { return target - origin; } + public int computeTarget(int origin, int offset) { return origin + offset; } } diff --git a/src/edu/berkeley/fleet/interpreter/Main.java b/src/edu/berkeley/fleet/interpreter/Main.java index 8f84d63..0d9b3b6 100644 --- a/src/edu/berkeley/fleet/interpreter/Main.java +++ b/src/edu/berkeley/fleet/interpreter/Main.java @@ -6,12 +6,12 @@ import java.io.*; import edu.berkeley.fleet.api.Instruction; import edu.berkeley.fleet.api.BenkoBox; import edu.berkeley.fleet.*; -import edu.berkeley.fleet.parser.*; +import edu.berkeley.fleet.interpreter.*; public class Main { - private static boolean debugMemory = true; - public static boolean dump_fabric = false; - public static boolean dump_code = false; + static boolean debugMemory = true; + static boolean dump_fabric = false; + static boolean dump_code = false; public static void main(String[] s) throws Exception { for(int i=0; i arr = new ArrayList(); + edu.berkeley.fleet.assembler.Main.assemble(fleet, r, arr); + fleet.instructions = (Instruction[])arr.toArray(new Instruction[0]); + if (dump_fabric) { fleet.dumpFabric(false); } else if (dump_code) { - fleet.dumpFabric(true); - try { - rootCodeBag.dump(fleet); - } catch (Exception e) { throw new RuntimeException(e); } + fleet.dumpCode(); - } else if (rootCodeBag != null) { + } else { if (debugMemory) { fleet.dumpMem(); } - System.out.println(rootCodeBag); - rootCodeBag.dispatch(fleet); fleet.go(); if (debugMemory) { fleet.dumpMem(); } }