public abstract class InstructionEncoder {
/** get the bits describing this box's location on the DESTINATION HORN */
- public abstract long getBoxAddr(Destination box);
+ protected abstract long getDestAddr(Destination 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);
+ protected abstract long getBoxInstAddr(BenkoBox box);
/** given an INSTRUCTION HORN address, retrieve the corresponding BenkoBox object */
- public abstract BenkoBox getBoxByInstAddr(long dest);
+ protected abstract BenkoBox getBoxByInstAddr(long dest);
+
+ /** given a DESTINATION HORN address, retrieve the corresponding BenkoBox object */
+ protected abstract Destination getDestByAddr(long dest);
/** read a machine-formatted instruction from a file (into a Java object) */
public Instruction readInstruction(DataInputStream is) throws IOException {
}
}
+ // FIXME: use this more
+ private boolean getBit(int bit, long val) { return ((val & (1L << bit)) != 0); }
+ private long getSignedField(int highBit, int lowBit, long val) {
+ long ret = getField(highBit, lowBit, val);
+ if ((ret & (1L << ((highBit-lowBit)+1-1))) != 0)
+ ret |= 0xffffffffffffffffL << ((highBit-lowBit)+1);
+ return ret;
+ }
+ private int getIntField(int highBit, int lowBit, long val) {
+ if (highBit-lowBit+1 > 32) throw new RuntimeException("too big!");
+ return (int)getField(highBit, lowBit, val);
+ }
+ private long getField(int highBit, int lowBit, long val) {
+ long mask = 0xffffffffffffffffL;
+ mask = mask << ((highBit-lowBit)+1);
+ mask = ~mask;
+ mask = mask << lowBit;
+ long ret = val & mask;
+ ret = ret >> lowBit;
+ return ret;
+ }
+
+ private long doPutField(int highBit, int lowBit, long val) {
+ long mask = 0xffffffffffffffffL;
+ mask = mask << (highBit-lowBit+1);
+ mask = ~mask;
+ val = val & mask;
+ val = val << lowBit;
+ return val;
+ }
+ private long putField(int highBit, int lowBit, long val) {
+ if (val < 0 || val >= (1L << (highBit-lowBit+1)))
+ throw new RuntimeException("bitfield width exceeded");
+ return doPutField(highBit, lowBit, val);
+ }
+ private long putSignedField(int highBit, int lowBit, long val) {
+ if (val <= (-1L * (1L << (highBit-lowBit+1-1))))
+ throw new RuntimeException("bitfield width exceeded");
+ if (val >= ( (1L << (highBit-lowBit+1-1))))
+ throw new RuntimeException("bitfield width exceeded");
+ return doPutField(highBit, lowBit, val);
+ }
+
+ // FIXME: parameterize stuff in this file
+ private static final int WBITS = 37; /* word width */
+ private static final int IBITS = 37; /* instruction width */
+ private static final int CODEBAG_SIZE_BITS = 6;
+ private static final int BENKOBOX_NAME_BITS = 11;
+ private static final int COUNT_BITS = 7;
+ private static final int OPCODE_BITS = 5;
+
public Instruction readInstruction(long instr) {
long inst = instr;
- long head = inst & (0x3L << (24+11));
- head = head >> (24+11);
- switch((int)head) {
+ switch((int)getField(WBITS-1, WBITS-2, inst)) {
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;
+ BenkoBox name = getBoxByInstAddr((inst >> 24) & 0x7ff);
+ Destination dest = getDestByAddr ((inst >> 1) & 0x7ff);
+ int count = getIntField(COUNT_BITS+BENKOBOX_NAME_BITS+1-1, BENKOBOX_NAME_BITS+1, instr);
+ boolean tokenIn = getBit(COUNT_BITS+BENKOBOX_NAME_BITS+1+0, instr);
+ boolean dataIn = getBit(COUNT_BITS+BENKOBOX_NAME_BITS+1+1, instr);
+ boolean latch = getBit(COUNT_BITS+BENKOBOX_NAME_BITS+1+2, instr);
+ boolean dataOut = getBit(COUNT_BITS+BENKOBOX_NAME_BITS+1+3, instr);
+ boolean tokenOut = getBit(COUNT_BITS+BENKOBOX_NAME_BITS+1+4, instr);
+ boolean recycle = getBit(0, instr);
if (latch & !dataIn) return new Instruction.Kill(name, count, tokenIn);
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);
+ Destination name = getDestByAddr(getField(WBITS-3, WBITS-3-BENKOBOX_NAME_BITS+1, inst));
+ long offset = getSignedField(WBITS-3-BENKOBOX_NAME_BITS, CODEBAG_SIZE_BITS, instr);
+ long size = getSignedField(CODEBAG_SIZE_BITS-1, 0, instr);
return new Instruction.Literal.CodeBagDescriptor(name, offset, size);
}
case 2: {
- BenkoBox name = getBoxByInstAddr((inst >> 24) & 0x7ff);
- int val = ((int)(instr )) & ~(0xffffffff << 24);
- val = signExtend24(val);
- return new Instruction.Literal.Absolute(name, val);
+ Destination name = getDestByAddr(getField(WBITS-3, WBITS-3-BENKOBOX_NAME_BITS+1, inst));
+ return new Instruction.Literal.Absolute(name, getSignedField(WBITS-3-BENKOBOX_NAME_BITS, 0, instr));
}
case 3: {
- BenkoBox name = getBoxByInstAddr((inst >> 24) & 0x7ff);
- int val = ((int)(instr )) & ~(0xffffffff << 24);
- return new Instruction.Literal.Relative(name, val);
+ Destination name = getDestByAddr(getField(WBITS-3, WBITS-3-BENKOBOX_NAME_BITS+1, inst));
+ return new Instruction.Literal.Relative(name, getSignedField(WBITS-3-BENKOBOX_NAME_BITS, 0, instr));
}
}
if (d instanceof Instruction.Executable) {
Instruction.Executable inst = (Instruction.Executable)d;
- Destination 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));
+ if (inst.dest != null)
+ instr |= putField(BENKOBOX_NAME_BITS, 1, getDestAddr(inst.dest));
+ instr |= putField(COUNT_BITS+BENKOBOX_NAME_BITS+1-1, BENKOBOX_NAME_BITS+1, inst.count);
+ instr |= putField(COUNT_BITS+BENKOBOX_NAME_BITS+1+0, COUNT_BITS+BENKOBOX_NAME_BITS+1+0, inst.tokenIn ? 1 : 0);
+ instr |= putField(COUNT_BITS+BENKOBOX_NAME_BITS+1+1, COUNT_BITS+BENKOBOX_NAME_BITS+1+1, inst.dataIn ? 1 : 0);
+ instr |= putField(COUNT_BITS+BENKOBOX_NAME_BITS+1+2, COUNT_BITS+BENKOBOX_NAME_BITS+1+2, inst.latch ? 1 : 0);
+ instr |= putField(COUNT_BITS+BENKOBOX_NAME_BITS+1+3, COUNT_BITS+BENKOBOX_NAME_BITS+1+3, inst.dataOut ? 1 : 0);
+ instr |= putField(COUNT_BITS+BENKOBOX_NAME_BITS+1+4, COUNT_BITS+BENKOBOX_NAME_BITS+1+4, inst.tokenOut ? 1 : 0);
+ instr |= putField(0, 0, inst.recycle ? 1 : 0);
+ instr |= putField(BENKOBOX_NAME_BITS+OPCODE_BITS+COUNT_BITS+BENKOBOX_NAME_BITS+1-1,
+ OPCODE_BITS+COUNT_BITS+BENKOBOX_NAME_BITS+1,
+ getBoxInstAddr(inst.benkoBox));
} 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));
+ instr = putField(WBITS-1, WBITS-2, 1);
+ if (lc.dest != null) instr |= putField(WBITS-3, WBITS-3-BENKOBOX_NAME_BITS+1, getDestAddr(lc.dest));
+ instr |= putSignedField(WBITS-3-BENKOBOX_NAME_BITS, CODEBAG_SIZE_BITS, lc.offset);
+ instr |= putField(CODEBAG_SIZE_BITS-1, 0, 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) & ~(0xffffffff << 24);
+ instr = putField(WBITS-1, WBITS-2, 2);
+ instr |= putField(WBITS-3, WBITS-3-BENKOBOX_NAME_BITS+1, getDestAddr(ld.dest));
+ instr |= putSignedField(WBITS-3-BENKOBOX_NAME_BITS, 0, 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);
+ instr = putField(WBITS-1, WBITS-2, 3);
+ instr |= putField(WBITS-3, WBITS-3-BENKOBOX_NAME_BITS+1, getDestAddr(lr.dest));
+ instr |= putSignedField(WBITS-3-BENKOBOX_NAME_BITS, 0, 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));
+ for(int i=5; i>=0; i--)
+ os.write(getIntField(i*8+7, i*8, instr));
}
- public static int signExtend24(int val) {
- if ((val & (1 << 23)) != 0)
- val = val | (0xffffffff << 24);
- return val;
- }
-
}
\ No newline at end of file