From c05dcd15f4702016b63f3853b5f764770417f127 Mon Sep 17 00:00:00 2001 From: adam Date: Thu, 22 Feb 2007 16:30:50 +0100 Subject: [PATCH] IES44: lots of cleanup, use safer bitfield operations --- .../berkeley/fleet/ies44/InstructionEncoder.java | 172 +++++++++++--------- 1 file changed, 98 insertions(+), 74 deletions(-) diff --git a/src/edu/berkeley/fleet/ies44/InstructionEncoder.java b/src/edu/berkeley/fleet/ies44/InstructionEncoder.java index 0e9174d..c96f6d1 100644 --- a/src/edu/berkeley/fleet/ies44/InstructionEncoder.java +++ b/src/edu/berkeley/fleet/ies44/InstructionEncoder.java @@ -6,16 +6,16 @@ import java.io.*; 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 { @@ -33,45 +33,90 @@ public abstract class InstructionEncoder { } } + // 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)); } } @@ -91,48 +136,37 @@ public abstract class InstructionEncoder { 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; @@ -140,18 +174,8 @@ public abstract class InstructionEncoder { 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 -- 1.7.10.4