updates to instruction encoder
authorAdam Megacz <adam.megacz@sun.com>
Tue, 17 Mar 2009 17:22:34 +0000 (17:22 +0000)
committerAdam Megacz <adam.megacz@sun.com>
Tue, 17 Mar 2009 17:22:34 +0000 (17:22 +0000)
testCode/edu/berkeley/fleet/api/Dock.java
testCode/edu/berkeley/fleet/api/Instruction.java
testCode/edu/berkeley/fleet/api/Ship.java
testCode/edu/berkeley/fleet/marina/MarinaDock.java
testCode/edu/berkeley/fleet/two/DockDescription.java
testCode/edu/berkeley/fleet/two/FleetTwoDock.java
testCode/edu/berkeley/fleet/two/FleetTwoFleet.java
testCode/edu/berkeley/fleet/two/FleetTwoShip.java
testCode/edu/berkeley/fleet/two/ShipDescription.java

index be4d558..e0b79fe 100644 (file)
@@ -41,7 +41,7 @@ public abstract class Dock {
 
     /** get a constant associated with a dock; returns null if none found */
     public BitVector getConstant(String constantName) {
-        return null;
+        throw new RuntimeException("unknown constant \""+constantName+"\" on dock " + this);
     }
 
     public String toString() { return getShip()+"."+getName(); }
index 7c0719f..0eda440 100644 (file)
@@ -7,17 +7,13 @@ public abstract class Instruction {
     /** the dock which is to execute this instruction */
     public final Dock      dock;
 
-    /** true if the instruction is an outer-looping instruction */
-    public final boolean   looping;
-
     /** the instruction's predicate */
     public final Predicate predicate;
 
-    Instruction(Dock dock, boolean looping, Predicate predicate) {
+    Instruction(Dock dock, Predicate predicate) {
         if (dock==null)      throw new RuntimeException("dock may not be null");
         if (predicate==null) throw new RuntimeException("predicate may not be null");
         this.dock = dock;
-        this.looping = looping;
         this.predicate = predicate;
     }
 
@@ -27,7 +23,6 @@ public abstract class Instruction {
     public String toString() {
         String s = predicate.toString();
         if (s.length()>0) s = "["+s+"] ";
-        if (looping) s += "[Rq] ";
         return dock+": "+s;
     }
 
@@ -59,9 +54,9 @@ public abstract class Instruction {
         public final FlagFunction   newFlagB;
 
         /** basic constructor */
-        public Set(Dock dock, SetDest dest, SetSource source) { this(dock, false, Predicate.Default, dest, source); }
-        public Set(Dock dock, boolean looping, Predicate predicate, SetDest dest, SetSource source) {
-            super(dock, looping, predicate);
+        public Set(Dock dock, SetDest dest, SetSource source) { this(dock, Predicate.Default, dest, source); }
+        public Set(Dock dock, Predicate predicate, SetDest dest, SetSource source) {
+            super(dock, predicate);
             OUTER: switch(dest) {
                 case InnerLoopCounter:
                     switch(source) {
@@ -85,9 +80,9 @@ public abstract class Instruction {
         }
 
         /** constructor for set instructions with immediates */
-        public Set(Dock dock, SetDest dest, long immediate) { this(dock, false, Predicate.Default, dest, immediate); }
-        public Set(Dock dock, boolean looping, Predicate predicate, SetDest dest, long immediate) {
-            super(dock, looping, predicate);
+        public Set(Dock dock, SetDest dest, long immediate) { this(dock, Predicate.Default, dest, immediate); }
+        public Set(Dock dock, Predicate predicate, SetDest dest, long immediate) {
+            super(dock, predicate);
             if (dest!=SetDest.InnerLoopCounter && dest!=SetDest.OuterLoopCounter && dest!=SetDest.DataLatch)
                 throw new RuntimeException("a set instruction with dest="+dest+" may not take an immediate");
             this.source = SetSource.Immediate;
@@ -98,9 +93,9 @@ public abstract class Instruction {
         }
 
         /** constructor for <tt>set flags</tt> instructions */
-        public Set(Dock dock, FlagFunction newFlagA, FlagFunction newFlagB) { this(dock, false, Predicate.Default, newFlagA, newFlagB); }
-        public Set(Dock dock, boolean looping, Predicate predicate, FlagFunction newFlagA, FlagFunction newFlagB) {
-            super(dock, looping, predicate);
+        public Set(Dock dock, FlagFunction newFlagA, FlagFunction newFlagB) { this(dock, Predicate.Default, newFlagA, newFlagB); }
+        public Set(Dock dock, Predicate predicate, FlagFunction newFlagA, FlagFunction newFlagB) {
+            super(dock, predicate);
             this.source = SetSource.Immediate;
             this.dest = SetDest.Flags;
             this.immediate = 0;
@@ -220,9 +215,9 @@ public abstract class Instruction {
     /** shifts an immediate into the low-order bits of the data latch */
     public static class Shift extends Instruction {
         public final BitVector immediate;
-        public Shift(Dock dock, BitVector immediate) { this(dock, false, Predicate.Default, immediate); }
-        public Shift(Dock dock, boolean looping, Predicate predicate, BitVector immediate) {
-            super(dock, looping, predicate);
+        public Shift(Dock dock, BitVector immediate) { this(dock, Predicate.Default, immediate); }
+        public Shift(Dock dock, Predicate predicate, BitVector immediate) {
+            super(dock, predicate);
             this.immediate = immediate;
             this.immediate.setImmutable();
             if (immediate.length() != dock.getShip().getFleet().getShiftWidth())
@@ -235,9 +230,9 @@ public abstract class Instruction {
 
     /** a flush instruction */
     public static class Flush extends Instruction {
-        public Flush(Dock dock) { this(dock, false, Predicate.Default); }
-        public Flush(Dock dock, boolean looping, Predicate predicate) {
-            super(dock, looping, predicate);
+        public Flush(Dock dock) { this(dock, Predicate.Default); }
+        public Flush(Dock dock, Predicate predicate) {
+            super(dock, predicate);
             if (!dock.isInputDock()) throw new RuntimeException("Flush is only allowed at input docks");
         }
         public String toString() { return super.toString()+"flush"; }
@@ -279,9 +274,8 @@ public abstract class Instruction {
                     boolean     dataOut,
                     boolean     tokenOut
                     ) {
-            this(dock, false, Predicate.Default, false, path, tokenIn, dataIn, latchData, latchPath, dataOut, tokenOut); }
+            this(dock, Predicate.Default, false, path, tokenIn, dataIn, latchData, latchPath, dataOut, tokenOut); }
         public Move(Dock        dock,
-                    boolean     looping,
                     Predicate   predicate,
                     boolean     interruptible,
                     Path        path,
@@ -292,7 +286,7 @@ public abstract class Instruction {
                     boolean     dataOut,
                     boolean     tokenOut
                     ) {
-            super(dock, looping, predicate);
+            super(dock, predicate);
             this.path = path;
             this.tokenIn = tokenIn;
             this.dataIn = dataIn;
@@ -323,8 +317,8 @@ public abstract class Instruction {
                 else                             ret.append(!dock.isInputDock() ? ", collect nothing" : ", recv nothing");
             }
             if (dataOut && dock.isInputDock())  ret.append(", deliver");
-            if (dataOut && !dock.isInputDock()) ret.append(path==null ? ", send"  : ", send to "  + path.getDestination().getDock());
-            if (tokenOut)                       ret.append(path==null ? ", token" : ", send token to " + path.getDestination().getDock());
+            if (dataOut && !dock.isInputDock()) ret.append(path==null ? ", send"  : ", send to "  + path.getDestination());
+            if (tokenOut)                       ret.append(path==null ? ", token" : ", send token to " + path.getDestination());
             String s = ret.toString();
             s = s.equals("") ? "nop" : s.substring(2);
             if (interruptible) s = "[T] " + s;
@@ -334,19 +328,19 @@ public abstract class Instruction {
 
     /** a flush instruction */
     public static class Abort extends Instruction {
-        public Abort(Dock dock, Predicate predicate) { super(dock, false, predicate); }
+        public Abort(Dock dock, Predicate predicate) { super(dock, predicate); }
         public String toString() { return super.toString()+"abort;"; }
     }
 
     /** marks the start of a loop; closes the hatch */
     public static class Head extends Instruction {
-        public Head(Dock dock) { super(dock, false, Predicate.IgnoreFlagD); }
+        public Head(Dock dock) { super(dock, Predicate.IgnoreFlagD); }
         public String toString() { return dock+": head;"; }
     }
 
     /** marks the end of a loop; closes the hatch */
     public static class Tail extends Instruction {
-        public Tail(Dock dock) { super(dock, false, Predicate.IgnoreFlagD); }
+        public Tail(Dock dock) { super(dock, Predicate.IgnoreFlagD); }
         public String toString() { return dock+": tail;"; }
     }
 
index f5eafa4..0b7945d 100644 (file)
@@ -26,7 +26,7 @@ public abstract class Ship implements Iterable<Dock> {
 
     /** get a constant associated with a ship; returns null if none found */
     public BitVector getConstant(String constantName) {
-        return null;
+        throw new RuntimeException("unknown constant \""+constantName+"\" on ship " + this);
     }
 
     public String toString() {
index 05a301a..059a420 100644 (file)
@@ -20,7 +20,9 @@ public class MarinaDock extends FleetTwoDock {
     }
 
     public String getName() { return "fakedock"; }
-    public ShipDescription.Constant getDockConstant(String s) { return null; }
+    public BitVector getDockConstant(String s) {
+        throw new RuntimeException("not supported");
+    }
 
 }
 
index eccbe6e..d3646b8 100644 (file)
@@ -11,7 +11,7 @@ public class DockDescription {
     private final boolean inbox;
     private final boolean left;
     private final boolean isDockless;
-    private final HashMap<String,ShipDescription.Constant> constants = new HashMap<String,ShipDescription.Constant>();
+    private final HashMap<String,BitVector> constants = new HashMap<String,BitVector>();
 
     DockDescription(ShipDescription ship, String name, boolean left, boolean inbox) {
         this(ship, name, left, inbox, false);
@@ -33,11 +33,11 @@ public class DockDescription {
     boolean isLeft() { return left; }
 
     /** Searches the dock-specific constants first, then ship-wide constants */
-    public ShipDescription.Constant getConstant(String name) {
-        ShipDescription.Constant ret = constants.get(name);
+    public BitVector getConstant(String name) {
+        BitVector ret = constants.get(name);
         if (ret == null) ret = ship.getConstant(name);
         return ret;
     }
 
-    void addConstant(String s, ShipDescription.Constant c) { constants.put(s, c); }
+    void addConstant(String s, BitVector c) { constants.put(s, c); }
 }
index 3990c1d..e4b3148 100644 (file)
@@ -14,11 +14,17 @@ public abstract class FleetTwoDock extends Dock {
 
     public String getName() { return dockDescription.getName(); }
 
-    public ShipDescription.Constant getDockConstant(String s) { return dockDescription.getConstant(s); }
+    public BitVector getDockConstant(String s) { return dockDescription.getConstant(s); }
 
     public boolean isInputDock() { return dockDescription.isInputDock(); }
 
     public boolean isOutputDock() { return !dockDescription.isInputDock(); }
 
+    public BitVector getConstant(String constantName) {
+        BitVector bv = dockDescription.getConstant(constantName);
+        if (bv==null)
+            throw new RuntimeException("unknown constant \""+constantName+"\" on dock " + this);
+        return bv;
+    }
 
 }            
index e446dd0..19d5e9b 100644 (file)
@@ -25,7 +25,6 @@ public abstract class FleetTwoFleet extends Fleet {
     public final Mask DISPATCH_PATH;
     public final Mask DISPATCH_INSTR;
     public final Mask NOT_INTERRUPTIBLE;
-    public final Mask OS;
     public final Mask P;
     public final Mask P_NOT_A;
     public final Mask P_A;
@@ -77,7 +76,7 @@ public abstract class FleetTwoFleet extends Fleet {
     public final int  WIDTH_WORD;
     public final int  WIDTH_PACKET;
 
-    public final long DataLatch_WIDTH;
+    public final int DataLatch_WIDTH;
     private final long mask;
 
     public FleetTwoFleet() { this(false); }
@@ -98,8 +97,6 @@ public abstract class FleetTwoFleet extends Fleet {
 
             DISPATCH_PATH              = new Mask("v....................................");
             DISPATCH_INSTR             = new Mask(".vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv");
-            NOT_INTERRUPTIBLE          = new Mask(".................1...................");
-            OS                         = new Mask(".......1.............................");
             P                          = new Mask(".vvvvvv..............................");
             P_NOT_A                    = new Mask(".011110..............................");
             P_A                        = new Mask(".011101..............................");
@@ -110,44 +107,40 @@ public abstract class FleetTwoFleet extends Fleet {
             P_OLC_NONZERO              = new Mask(".011111..............................");
             P_ALWAYS                   = new Mask(".111111..............................");
 
-            SHIFT                      = new Mask("..........101111.1vvvvvvvvvvvvvvvvvvv");
 
-            /*
             // use these when Marina gets updated to 07-Jan-2009 version of internal encoding
             HEAD                       = new Mask(".......1.............................");
             ABORT                      = new Mask("........1............................");
             TAIL                       = new Mask(".........1...........................");
-            */
-
-            TAIL                       = new Mask("................1...................0");
-            HEAD                       = null;
-            ABORT                      = null;
-
-            MOVE                       = new Mask("..........110111.....................");
-            TI                         = new Mask("..........110111..1..................");
-            DI                         = new Mask("..........110111...1.................");
-            FLUSH                      = new Mask(".........1110111.....................");
-            DC                         = new Mask("..........110111....1................");
-            DO                         = new Mask("..........110111.....1...............");
-            TO                         = new Mask("..........110111......1..............");
-            PATH_IMMEDIATE             = new Mask("..........110111.......1vvvvvvvvvvvvv");
-            PATH_DATA                  = new Mask("..........110111.......00............");
-            PATH_NOCHANGE              = new Mask("..........110111.......01............");
-
-            SET_OLC_FROM_IMMEDIATE     = new Mask("..........111101.0.............vvvvvv");
-            SET_OLC_FROM_DATA_LATCH    = new Mask("..........111101.1...................");
-            SET_OLC_FROM_OLC_MINUS_ONE = new Mask("..........111011.....................");
-
-            SET_ILC_FROM_IMMEDIATE     = new Mask("..........011111.0...........0.vvvvvv");
-            SET_ILC_FROM_INFINITY      = new Mask("..........011111.............1.......");
-            SET_ILC_FROM_DATA_LATCH    = new Mask("..........011111.1...................");
-
-            SET_IMMEDIATE              = new Mask("..........101111.0.....vvvvvvvvvvvvvv");
-            SET_IMMEDIATE_EXTEND       = new Mask("..........101111.0....v..............");
-
-            SET_FLAGS                  = new Mask("..........111110.....................");
-            SET_FLAGS_A                = new Mask("..........111110...............vvvvvv");
-            SET_FLAGS_B                = new Mask("..........111110.........vvvvvv......");
+
+            // actually "is interruptible"
+            NOT_INTERRUPTIBLE          = new Mask("...........1....1....................");
+
+            SHIFT                      = new Mask("..........1......1vvvvvvvvvvvvvvvvvvv");
+            SET_IMMEDIATE              = new Mask("..........1......0.....vvvvvvvvvvvvvv");
+            SET_IMMEDIATE_EXTEND       = new Mask("..........1......0....v..............");
+            MOVE                       = new Mask("............1........................");
+            TI                         = new Mask("............1.....1..................");
+            DI                         = new Mask("............1......1.................");
+            FLUSH                      = new Mask("..........1......0.....011...........");
+            DC                         = new Mask("............1.......1................");
+            DO                         = new Mask("............1........1...............");
+            TO                         = new Mask("............1.........1..............");
+            PATH_IMMEDIATE             = new Mask("............1..........1vvvvvvvvvvvvv");
+            PATH_DATA                  = new Mask("............1..........00............");
+            PATH_NOCHANGE              = new Mask("............1..........01............");
+
+            SET_OLC_FROM_IMMEDIATE     = new Mask("..............1.10.............vvvvvv");
+            SET_OLC_FROM_DATA_LATCH    = new Mask("...............1.11..................");
+            SET_OLC_FROM_OLC_MINUS_ONE = new Mask("...............1.10..................");
+
+            SET_ILC_FROM_IMMEDIATE     = new Mask("...............1.00..........0.vvvvvv");
+            SET_ILC_FROM_INFINITY      = new Mask("...............1.0...........1.......");
+            SET_ILC_FROM_DATA_LATCH    = new Mask("...............1.01..................");
+
+            SET_FLAGS                  = new Mask("...............1.....................");
+            SET_FLAGS_A                = new Mask("...............1...............vvvvvv");
+            SET_FLAGS_B                = new Mask("...............1.........vvvvvv......");
 
             SET_FLAGS_VALUE_A          = new Mask(".....1");
             SET_FLAGS_VALUE_NOT_A      = new Mask("....1.");
@@ -160,7 +153,6 @@ public abstract class FleetTwoFleet extends Fleet {
             DISPATCH_PATH              = new Mask("vvvvvvvvvvv..........................");
             DISPATCH_INSTR             = new Mask("...........vvvvvvvvvvvvvvvvvvvvvvvvvv");
             NOT_INTERRUPTIBLE          = new Mask("...........1.........................");
-            OS                         = new Mask("............1........................");
             P                          = new Mask(".............vvv.....................");
             P_NOT_A                    = new Mask(".............000.....................");
             P_A                        = new Mask(".............001.....................");
@@ -226,6 +218,13 @@ public abstract class FleetTwoFleet extends Fleet {
         return false;
     }
 
+    public boolean isSmallEnoughToFit(BitVector immediate) {
+        boolean b = immediate.get((int)DataLatch_WIDTH);
+        for(int i=DataLatch_WIDTH+1; i<immediate.length(); i++)
+            if (immediate.get(i) != b) return false;
+        return true;
+    }
+
     public int getWordWidth() { return 37; }
 
     //////////////////////////////////////////////////////////////////////////////
@@ -277,31 +276,30 @@ public abstract class FleetTwoFleet extends Fleet {
         if (P_NOT_A.get(inst))  predicate = NotFlagA;
         if (P_NOT_B.get(inst))  predicate = NotFlagB;
 
-        boolean looping = !OS.get(inst);
         if (FLUSH.get(inst))
-            return new Flush(dock, looping, predicate);
+            return new Flush(dock, predicate);
         if (ABORT.get(inst))
             return new Abort(dock, predicate);
-        if (SHIFT.get(inst))                return new Shift(dock, looping, predicate, new BitVector(dock.getShip().getFleet().getShiftWidth()).set(SHIFT.getval(inst)));
+        if (SHIFT.get(inst))                return new Shift(dock, predicate, new BitVector(dock.getShip().getFleet().getShiftWidth()).set(SHIFT.getval(inst)));
         if (SET_IMMEDIATE.get(inst)) {
             boolean extend = SET_IMMEDIATE_EXTEND.getval(inst) != 0;
             long immediate = SET_IMMEDIATE.getval(inst);
             if (extend) immediate |= (-1L << DataLatch_WIDTH);
-            return new Set(dock, looping, predicate, SetDest.DataLatch, (immediate));
+            return new Set(dock, predicate, SetDest.DataLatch, (immediate));
         }
 
         if (SET_OLC_FROM_OLC_MINUS_ONE.get(inst))
-            return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.Decrement);
+            return new Set(dock, predicate, SetDest.OuterLoopCounter, SetSource.Decrement);
         if (SET_OLC_FROM_IMMEDIATE.get(inst))
-            return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, (SET_OLC_FROM_IMMEDIATE.getval(inst)));
+            return new Set(dock, predicate, SetDest.OuterLoopCounter, (SET_OLC_FROM_IMMEDIATE.getval(inst)));
         if (SET_ILC_FROM_IMMEDIATE.get(inst))
-            return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, (SET_ILC_FROM_IMMEDIATE.getval(inst)));
+            return new Set(dock, predicate, SetDest.InnerLoopCounter, (SET_ILC_FROM_IMMEDIATE.getval(inst)));
         if (SET_OLC_FROM_DATA_LATCH.get(inst))
-            return new Set(dock, looping, predicate, SetDest.OuterLoopCounter, SetSource.DataLatch);
+            return new Set(dock, predicate, SetDest.OuterLoopCounter, SetSource.DataLatch);
         if (SET_ILC_FROM_DATA_LATCH.get(inst))
-            return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.DataLatch);
+            return new Set(dock, predicate, SetDest.InnerLoopCounter, SetSource.DataLatch);
         if (SET_ILC_FROM_INFINITY.get(inst))
-            return new Set(dock, looping, predicate, SetDest.InnerLoopCounter, SetSource.Infinity);
+            return new Set(dock, predicate, SetDest.InnerLoopCounter, SetSource.Infinity);
         if (SET_FLAGS.get(inst)) {
             long flag_a = SET_FLAGS_A.getval(inst);
             long flag_b = SET_FLAGS_B.getval(inst);
@@ -319,11 +317,10 @@ public abstract class FleetTwoFleet extends Fleet {
             if (SET_FLAGS_VALUE_NOT_B.get(flag_b)) bp = bp.add(NotFlagB );
             if (SET_FLAGS_VALUE_C    .get(flag_b)) bp = bp.add(FlagC    );
             if (SET_FLAGS_VALUE_NOT_C.get(flag_b)) bp = bp.add(NotFlagC );
-            return new Set(dock, looping, predicate, ap, bp);
+            return new Set(dock,  predicate, ap, bp);
         }
         if (MOVE.get(inst))
             return new Move(dock,
-                            looping,
                             predicate,
                             !NOT_INTERRUPTIBLE.get(inst),
                             PATH_DATA.get(inst)?null:getPathByAddr(dock, PATH_IMMEDIATE.getvalAsBitVector(inst)),
@@ -351,7 +348,6 @@ public abstract class FleetTwoFleet extends Fleet {
 
         boolean dl = false;
         Instruction pi = d;
-        if (!pi.looping) instr = OS.set(instr);
         switch(pi.predicate) {
             case IgnoreFlagD:         instr = P_ALWAYS.set(instr); break;
             case FlagD:         instr = P_OLC_ZERO.set(instr); break;
index 5a89616..d8d008e 100644 (file)
@@ -30,4 +30,11 @@ public abstract class FleetTwoShip extends Ship {
         }
         throw new RuntimeException("inconsistency: Ship does not belong to its own Fleet!");
     }
+
+    public BitVector getConstant(String constantName) {
+        BitVector bv = shipDescription.getConstant(constantName);
+        if (bv==null)
+            throw new RuntimeException("unknown constant \""+constantName+"\" on ship " + this);
+        return bv;
+    }
 }
index 1aa801b..6752e70 100644 (file)
@@ -6,11 +6,12 @@ import java.util.*;
 /** NOT YET FINALIZED: A description (specification) of a ship */
 public class ShipDescription implements Iterable<DockDescription> {
 
+    private Fleet fleet;
     private String name;
     private LinkedHashMap<String,DockDescription> docks         = new LinkedHashMap<String,DockDescription>();
     private LinkedHashMap<String,DockDescription> ports = new LinkedHashMap<String,DockDescription>();
     private HashMap<String,String>                sections      = new HashMap<String,String>();
-    private HashMap<String,Constant>              constants     = new HashMap<String,Constant>();
+    private HashMap<String,BitVector>              constants     = new HashMap<String,BitVector>();
 
     public String getName() { return name; }
     public String getSection(String sectionName) { return sections.get(sectionName); }
@@ -22,9 +23,10 @@ public class ShipDescription implements Iterable<DockDescription> {
 
     public final LinkedList<PercolatedPort> percolatedPorts = new LinkedList<PercolatedPort>();
 
-    public ShipDescription(String name, BufferedReader r) throws IOException {
+    public ShipDescription(Fleet fleet, String name, BufferedReader r) throws IOException {
         if (name.endsWith(".ship")) name = name.substring(0, name.length()-".ship".length());
         this.name = name;
+        this.fleet = fleet;
         String sectionName = null;
         StringBuffer sb = new StringBuffer();
         while(true) {
@@ -47,8 +49,10 @@ public class ShipDescription implements Iterable<DockDescription> {
             processSection(s);
     }
 
-    public Constant getConstant(String name) {
-        return constants.get(name);
+    public BitVector getConstant(String name) {
+        BitVector c = constants.get(name);
+        if (c==null) throw new RuntimeException("unknown constant " + name);
+        return c;
     }
 
     private void processSection(String section) throws IOException {
@@ -69,7 +73,7 @@ public class ShipDescription implements Iterable<DockDescription> {
                 if (key.startsWith("constant")) {
                     String constname = key.substring("constant".length()+1).trim();
                     String val       = s.substring(s.indexOf(':')+1).trim();
-                    constants.put(constname, new Constant(val));
+                    constants.put(constname, new BitVector(fleet.getWordWidth()).set(Integer.parseInt(val)));
                 }
             }
         } else if (section.equals("ports")) {
@@ -104,7 +108,7 @@ public class ShipDescription implements Iterable<DockDescription> {
                 else if (key.startsWith("constant")) {
                     String constname = key.substring("constant".length()+1).trim();
                     String val       = s.substring(s.indexOf(':')+1).trim();
-                    p.addConstant(constname, new Constant(val));
+                    p.addConstant(constname, new BitVector(fleet.getWordWidth()).set(Integer.parseInt(val)));
                     continue;
                 } else if (key.startsWith("shortcut to")) {
                     continue;
@@ -203,33 +207,4 @@ public class ShipDescription implements Iterable<DockDescription> {
             pw.println(tex);
     }
 
-    // FIXME: merge with BitMask
-    public class Constant {
-        public long    setbits   = 0;
-        public long    clearbits = 0;
-        public boolean signExtend = false;
-        public int     numberOffset = 0;
-        public int     numberWidth = 0;
-        public Constant(String s) {
-            if (s.startsWith("0x")) {
-                setbits = Long.parseLong(s.substring(2), 16);
-                clearbits = ~setbits;
-            } else if (s.length() == 37) {
-                for(int i=36; i>=0; i--) {
-                    char c = s.charAt(36-i);
-                    switch(c) {
-                        case '0': clearbits |= (1<<i); break;
-                        case '1': setbits   |= (1<<i); break;
-                        case '.': break;
-                        case 's': signExtend = true;  numberOffset = i; numberWidth++; break;
-                        case 'u': signExtend = false; numberOffset = i; numberWidth++; break;
-                    }
-                }
-            } else {
-                setbits = Long.parseLong(s);
-                clearbits = ~setbits;
-            }
-        }
-    }
-
 }