From: adam Date: Mon, 5 Feb 2007 19:04:19 +0000 (+0100) Subject: added ies44 instruction encoder X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=c936bdb4fa5599e9b288b2aad482bb191e753bc9;p=fleet.git added ies44 instruction encoder --- diff --git a/src/edu/berkeley/fleet/ies44/InstructionEncoder.java b/src/edu/berkeley/fleet/ies44/InstructionEncoder.java new file mode 100644 index 0000000..9fda1a0 --- /dev/null +++ b/src/edu/berkeley/fleet/ies44/InstructionEncoder.java @@ -0,0 +1,149 @@ +package edu.berkeley.fleet.ies44; +import edu.berkeley.fleet.api.*; +import edu.berkeley.fleet.*; +import java.io.*; + +public abstract class InstructionEncoder { + + /** get the bits describing this box's location on the DESTINATION HORN */ + public abstract long getBoxAddr(BenkoBox box); + + /** get the bits describing this box's location on the INSTRUCTION HORN */ + public abstract long getBoxInstAddr(BenkoBox box); + + /** given a DESTINATION HORN address, retrieve the corresponding BenkoBox object */ + public abstract BenkoBox getBoxByAddr(long dest); + + /** given an INSTRUCTION HORN address, retrieve the corresponding BenkoBox object */ + public abstract BenkoBox getBoxByInstAddr(long dest); + + /** read a machine-formatted instruction from a file (into a Java object) */ + public Instruction readInstruction(DataInputStream is) throws IOException { + long inst = 0; + try { + inst = (inst << 8) | (is.readByte() & 0xff); + inst = (inst << 8) | (is.readByte() & 0xff); + inst = (inst << 8) | (is.readByte() & 0xff); + inst = (inst << 8) | (is.readByte() & 0xff); + inst = (inst << 8) | (is.readByte() & 0xff); + inst = (inst << 8) | (is.readByte() & 0xff); + return readInstruction(inst); + } catch (EOFException eof) { + return null; + } + } + + public Instruction readInstruction(long instr) { + long inst = instr; + long head = inst & (0x3L << (24+11)); + head = head >> (24+11); + switch((int)head) { + case 0: { + BenkoBox name = getBoxByInstAddr((inst >> 24) & 0x7ff); + BenkoBox dest = getBoxByAddr ((inst >> 1) & 0x7ff); + int count = ((int)(instr >> 12)) & 0x7f; + boolean tokenIn = (instr & (1L << (11+1+7+0))) != 0; + boolean dataIn = ( instr & (1L << (11+1+7+1))) != 0; + boolean latch = ( instr & (1L << (11+1+7+2))) != 0; + boolean dataOut = (instr & (1L << (11+1+7+3))) != 0; + boolean tokenOut = (instr & (1L << (11+1+7+4))) != 0; + boolean recycle = (instr & (1L)) != 0; + if (latch & !dataIn) return new Instruction.Kill(name, count); + return new Instruction.Executable(name, dest, count, tokenIn, dataIn, + latch, dataOut, tokenOut, recycle); + } + + case 1: { + BenkoBox name = getBoxByInstAddr((inst >> 24) & 0x7ff); + int offset = ((int)(instr >> 6)) & ~(0xffffffff << 18); + if ((offset & (1<<17)) != 0) offset |= (0xffffffff << 18); + int size = ((int)(instr )) & ~(0xffffffff << 6); + return new Instruction.Literal.CodeBagDescriptor(name, offset, size); + } + + case 2: { + BenkoBox name = getBoxByInstAddr((inst >> 24) & 0x7ff); + int val = ((int)(instr )) & ~(0xffffffff << 24); + return new Instruction.Literal.Absolute(name, val); + } + + case 3: { + BenkoBox name = getBoxByInstAddr((inst >> 24) & 0x7ff); + int val = ((int)(instr )) & ~(0xffffffff << 24); + return new Instruction.Literal.Relative(name, val); + } + + } + return null; + + } + + public long writeInstruction(Instruction d) { + long instr = 0; + + // Kill is encoded as Execute with the illegal combination (Latch & ~DataIn) + if (d instanceof Instruction.Kill) { + Instruction.Kill k = (Instruction.Kill)d; + d = new Instruction.Executable(k.benkoBox, null, k.count, false, false, true, false, false, false); + } + + if (d instanceof Instruction.Executable) { + Instruction.Executable inst = (Instruction.Executable)d; + BenkoBox dest = inst.dest; + instr = dest==null ? 0 : (getBoxAddr(dest) << 1); + if (inst.count >= (1<<8)) + throw new RuntimeException("count field must be less than 128"); + instr |= (((long)inst.count) << (11+1)); + if (inst.tokenIn) instr |= (1L << (11+1+7+0)); + if (inst.dataIn) instr |= (1L << (11+1+7+1)); + if (inst.latch) instr |= (1L << (11+1+7+2)); + if (inst.dataOut) instr |= (1L << (11+1+7+3)); + if (inst.tokenOut) instr |= (1L << (11+1+7+4)); + if (inst.recycle) instr |= (1L); + instr |= (getBoxInstAddr(inst.benkoBox) << (11+5+7+1)); + + } else if (d instanceof Instruction.Literal.CodeBagDescriptor) { + Instruction.Literal.CodeBagDescriptor lc = (Instruction.Literal.CodeBagDescriptor)d; + instr = (1L << (11+24)); + if (lc.dest != null) + instr |= (getBoxAddr(lc.dest)) << 24; + if (lc.size >= (1<<6)) + throw new RuntimeException("codebag sizes must be less than 2^6"); + if (lc.offset >= (1<<17) || lc.offset <= (-1 * (1<<17))) + throw new RuntimeException("codebag offsets must be in the range -(2^17)..2^17"); + int off = (int)lc.offset; + off &= ~(0xffffffff << 18); + instr |= (off << 6); + instr |= (((long)lc.size)); + + } else if (d instanceof Instruction.Literal.Absolute) { + Instruction.Literal.Absolute ld = (Instruction.Literal.Absolute)d; + instr = (2L << (11+24)); + instr |= (getBoxAddr(ld.dest)) << 24; + if (ld.value >= (1<<25)) + throw new RuntimeException("literals must be less than 2^24"); + instr |= ((long)ld.value); + + } else if (d instanceof Instruction.Literal.Relative) { + Instruction.Literal.Relative lr = (Instruction.Literal.Relative)d; + instr = (3L << (11+24)); + instr |= (getBoxAddr(lr.dest)) << 24; + if (lr.offset >= (1<<25)) + throw new RuntimeException("literals must be less than 2^24"); + instr |= ((long)lr.offset); + + } + return instr; + } + + public void writeInstruction(DataOutputStream os, Instruction d) throws IOException { + long instr = writeInstruction(d); + os.write((int)((instr >> (5*8)) & 0xff)); + os.write((int)((instr >> (4*8)) & 0xff)); + os.write((int)((instr >> (3*8)) & 0xff)); + os.write((int)((instr >> (2*8)) & 0xff)); + os.write((int)((instr >> (1*8)) & 0xff)); + os.write((int)((instr >> (0*8)) & 0xff)); + } + +} \ No newline at end of file