1 package net.mograsim.machine.mi.parameters;
3 import static net.mograsim.logic.core.types.Bit.U;
5 import java.util.Arrays;
6 import java.util.LinkedList;
9 import java.util.stream.Collectors;
11 import net.mograsim.logic.core.types.BitVector;
12 import net.mograsim.machine.MachineException;
13 import net.mograsim.machine.mi.parameters.MicroInstructionParameter.ParameterType;
15 public class MnemonicFamily implements ParameterClassification
17 private final Mnemonic[] values;
18 private final Mnemonic defaultValue;
19 private final String[] stringValues;
20 private Map<String, Mnemonic> byText;
21 private int vectorLength;
23 MnemonicFamily(String defaultValueName, MnemonicPair... values)
25 if (values.length == 0)
26 throw new MachineException("Mnemonics must not be empty!");
27 this.values = new Mnemonic[values.length];
28 this.stringValues = new String[values.length];
32 // if no valid defaultValue is specified, pick first value as default
33 int defaultValueIndex = 0;
34 for (int i = 0; i < values.length; i++)
35 if (stringValues[i].equals(defaultValueName))
37 defaultValueIndex = i;
40 this.defaultValue = this.values[defaultValueIndex];
43 private void setup(MnemonicPair[] values)
45 for (int i = 0; i < values.length; i++)
47 this.values[i] = createMnemonic(values[i], i);
48 this.stringValues[i] = values[i].name;
50 if (values.length == 0)
54 vectorLength = values[0].value.length();
55 for (int i = 1; i < values.length; i++)
56 if (values[i].value.length() != vectorLength)
57 throw new IllegalArgumentException("MnemonicFamily is not of uniform vector length!");
59 byText = Arrays.stream(this.values).collect(Collectors.toMap(m -> m.getText(), m -> m));
60 if (values.length != byText.keySet().size())
61 throw new IllegalArgumentException("MnemonicFamily contains multiple Mnemonics with the same name!");
64 private Mnemonic createMnemonic(MnemonicPair mnemonicPair, int ordinal)
66 return new Mnemonic(mnemonicPair.name, mnemonicPair.value, this, ordinal);
69 public Mnemonic[] values()
71 return values.clone();
74 public Mnemonic get(int ordinal)
76 return values[ordinal];
79 public Mnemonic get(String text)
81 return byText.get(text);
85 public MicroInstructionParameter getDefault()
90 public boolean contains(Mnemonic m)
93 return m.owner == this;
97 public boolean contains(String value)
99 return byText.keySet().contains(value);
104 return values.length;
107 public int getVectorLength()
113 public boolean conforms(MicroInstructionParameter param)
115 return ParameterClassification.super.conforms(param) && (param instanceof Mnemonic ? contains((Mnemonic) param) : false);
119 public ParameterType getExpectedType()
121 return ParameterType.MNEMONIC;
125 public int getExpectedBits()
130 public String[] getStringValues()
132 return stringValues.clone();
136 public int hashCode()
138 final int prime = 31;
140 result = prime * result + Arrays.hashCode(values);
145 public boolean equals(Object obj)
151 public Mnemonic parse(String toParse)
153 Mnemonic parsed = get(toParse);
155 throw new UnknownMnemonicException(toParse);
159 public static class MnemonicPair
161 public final String name;
162 public final BitVector value;
164 public MnemonicPair(String name, BitVector value)
171 public static class MnemonicFamilyBuilder
173 private final List<MnemonicPair> pairs;
174 private final int bits;
175 private String defaultValue;
177 public MnemonicFamilyBuilder(int bits)
179 this.pairs = new LinkedList<>();
183 public MnemonicFamilyBuilder addX()
185 pairs.add(new MnemonicPair("X", BitVector.of(U, bits)));
189 public MnemonicFamilyBuilder add(MnemonicPair... pairs)
191 this.pairs.addAll(List.of(pairs));
196 * Adds a name with its corresponding value to the {@link MnemonicFamily}
198 * @return this {@link MnemonicFamilyBuilder}
200 public MnemonicFamilyBuilder add(String name, BitVector value)
202 add(new MnemonicPair(name, value));
207 * Adds names with their corresponding values to the {@link MnemonicFamily}
209 * @param names The names to be added to the {@link MnemonicFamily}
210 * @param values The values as {@link BitVector}s
211 * @return this {@link MnemonicFamilyBuilder}
213 public MnemonicFamilyBuilder add(String name, long value)
215 add(new MnemonicPair(name, BitVector.from(value, bits)));
220 * Adds names with their corresponding values to the {@link MnemonicFamily}
222 * @param names The names to be added to the {@link MnemonicFamily}
223 * @param values The values as {@link BitVector}s
224 * @return this {@link MnemonicFamilyBuilder}
226 public MnemonicFamilyBuilder add(String names[], BitVector[] values)
228 if (names.length != values.length)
229 throw new IllegalArgumentException("Cannot add Mnemonics! Amount of names does not match amount of values!");
230 for (int i = 0; i < names.length; i++)
231 add(new MnemonicPair(names[i], values[i]));
236 * Adds names with their corresponding values (converted to a BitVector) to the {@link MnemonicFamily}
238 * @param names The names to be added to the {@link MnemonicFamily}
239 * @param values The values to be converted to {@link BitVector}s with a given amount of {@link MnemonicFamilyBuilder#bits}
240 * @return this {@link MnemonicFamilyBuilder}
242 public MnemonicFamilyBuilder add(String names[], long values[])
244 if (names.length != values.length)
245 throw new IllegalArgumentException("Cannot add Mnemonics! Amount of names does not match amount of values!");
246 for (int i = 0; i < names.length; i++)
247 add(new MnemonicPair(names[i], BitVector.from(values[i], bits)));
252 * Adds names to the {@link MnemonicFamily}; The corresponding {@link BitVector} value to a name is the value of its index
254 * @param names The names to be added to the {@link MnemonicFamily}
255 * @return this {@link MnemonicFamilyBuilder}
257 public MnemonicFamilyBuilder add(String... names)
259 for (int i = 0; i < names.length; i++)
265 * Sets the name of the default {@link Mnemonic} of this {@link MnemonicFamily}
267 public MnemonicFamilyBuilder setDefault(String defaultValue)
269 this.defaultValue = defaultValue;
274 * Sets the name of the default {@link Mnemonic} of this {@link MnemonicFamily} to "X"
276 public MnemonicFamilyBuilder setXDefault()
278 this.defaultValue = "X";
282 public MnemonicFamily build()
284 return new MnemonicFamily(defaultValue, pairs.toArray(new MnemonicPair[pairs.size()]));