import edu.berkeley.fleet.api.*;
import edu.berkeley.fleet.*;
import java.io.*;
+import static edu.berkeley.fleet.ies44.BitManipulations;
public abstract class InstructionEncoder {
+ public static final int WIDTH_WORD = 37; /* word width */
+ public static final int WIDTH_CODEBAG_SIZE = 6;
+ public static final int WIDTH_PUMP_ADDR = 11;
+ public static final int WIDTH_DEST_ADDR = 11;
+ public static final int WIDTH_COUNT = 7;
+
+ public static final int OFFSET_RQ = 0;
+ public static final int OFFSET_COUNT = 1;
+ public static final int OFFSET_DEST = OFFSET_COUNT+WIDTH_COUNT;
+ public static final int OFFSET_CONTROL = OFFSET_DEST+WIDTH_DEST_ADDR;
+ public static final int OFFSET_TI = OFFSET_CONTROL+0;
+ public static final int OFFSET_DI = OFFSET_CONTROL+1;
+ public static final int OFFSET_DL = OFFSET_CONTROL+2;
+ public static final int OFFSET_DO = OFFSET_CONTROL+3;
+ public static final int OFFSET_TO = OFFSET_CONTROL+4;
+ public static final int OFFSET_PUMP_ADDR = 24;
+
/** get the bits describing this box's location on the DESTINATION HORN */
protected abstract long getDestAddr(Destination box);
}
}
- // 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;
- switch((int)getField(WBITS-1, WBITS-2, inst)) {
+ switch((int)getField(WIDTH_WORD-1, WIDTH_WORD-2, inst)) {
case 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);
+ BenkoBox name = getBoxByInstAddr(getIntField(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1, OFFSET_PUMP_ADDR, inst));
+ Destination dest = getDestByAddr (getIntField(OFFSET_DEST+WIDTH_DEST_ADDR-1, OFFSET_DEST, inst));
+ int count = getIntField( OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT, inst);
+ boolean tokenIn = getBit(OFFSET_TI, instr);
+ boolean dataIn = getBit(OFFSET_DI, instr);
+ boolean latch = getBit(OFFSET_DL, instr);
+ boolean dataOut = getBit(OFFSET_DO, instr);
+ boolean tokenOut = getBit(OFFSET_TO, 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,
}
case 1: {
- 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);
+ Destination name = getDestByAddr(getField(WIDTH_WORD-3, WIDTH_WORD-3-WIDTH_DEST_ADDR+1, inst));
+ long offset = getSignedField(WIDTH_WORD-3-WIDTH_DEST_ADDR, WIDTH_CODEBAG_SIZE, instr);
+ long size = getSignedField(WIDTH_CODEBAG_SIZE-1, 0, instr);
return new Instruction.Literal.CodeBagDescriptor(name, offset, size);
}
case 2: {
- 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));
+ Destination name = getDestByAddr(getField(WIDTH_WORD-3, WIDTH_WORD-3-WIDTH_PUMP_ADDR+1, inst));
+ return new Instruction.Literal.Absolute(name, getSignedField(WIDTH_WORD-3-WIDTH_PUMP_ADDR, 0, instr));
}
case 3: {
- 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));
+ Destination name = getDestByAddr(getField(WIDTH_WORD-3, WIDTH_WORD-3-WIDTH_PUMP_ADDR+1, inst));
+ return new Instruction.Literal.Relative(name, getSignedField(WIDTH_WORD-3-WIDTH_PUMP_ADDR, 0, instr));
}
}
if (d instanceof Instruction.Executable) {
Instruction.Executable inst = (Instruction.Executable)d;
- 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));
+ instr |= putField(OFFSET_DEST+WIDTH_DEST_ADDR-1, OFFSET_DEST, inst.dest==null?0:getDestAddr(inst.dest));
+ instr |= putField(OFFSET_COUNT+WIDTH_COUNT-1, OFFSET_COUNT, inst.count);
+ instr |= putField(OFFSET_TI, OFFSET_TI, inst.tokenIn?1:0);
+ instr |= putField(OFFSET_DI, OFFSET_DI, inst.dataIn?1:0);
+ instr |= putField(OFFSET_DL, OFFSET_DL, inst.latch?1:0);
+ instr |= putField(OFFSET_DO, OFFSET_DO, inst.dataOut?1:0);
+ instr |= putField(OFFSET_TO, OFFSET_TO, inst.tokenOut?1:0);
+ instr |= putField(OFFSET_RQ, OFFSET_RQ, inst.recycle?1:0);
+ instr |= putField(OFFSET_PUMP_ADDR+WIDTH_PUMP_ADDR-1, OFFSET_PUMP_ADDR, getBoxInstAddr(inst.benkoBox));
} else if (d instanceof Instruction.Literal.CodeBagDescriptor) {
Instruction.Literal.CodeBagDescriptor lc = (Instruction.Literal.CodeBagDescriptor)d;
- 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);
+ instr = putField(WIDTH_WORD-1, WIDTH_WORD-2, 1);
+ if (lc.dest != null) instr |= putField(WIDTH_WORD-3, WIDTH_WORD-3-WIDTH_DEST_ADDR+1, getDestAddr(lc.dest));
+ instr |= putSignedField(WIDTH_WORD-3-WIDTH_DEST_ADDR, WIDTH_CODEBAG_SIZE, lc.offset);
+ instr |= putField(WIDTH_CODEBAG_SIZE-1, 0, lc.size);
} else if (d instanceof Instruction.Literal.Absolute) {
Instruction.Literal.Absolute ld = (Instruction.Literal.Absolute)d;
- 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);
+ instr = putField(WIDTH_WORD-1, WIDTH_WORD-2, 2);
+ instr |= putField(WIDTH_WORD-3, WIDTH_WORD-3-WIDTH_DEST_ADDR+1, getDestAddr(ld.dest));
+ instr |= putSignedField(WIDTH_WORD-3-WIDTH_DEST_ADDR, 0, ld.value);
} else if (d instanceof Instruction.Literal.Relative) {
Instruction.Literal.Relative lr = (Instruction.Literal.Relative)d;
- 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);
+ instr = putField(WIDTH_WORD-1, WIDTH_WORD-2, 3);
+ instr |= putField(WIDTH_WORD-3, WIDTH_WORD-3-WIDTH_DEST_ADDR+1, getDestAddr(lr.dest));
+ instr |= putSignedField(WIDTH_WORD-3-WIDTH_DEST_ADDR, 0, lr.offset);
}
return instr;