/**
   * Given an IA32 opcode, return the set of opt compiler IA32_ operators that translate to it.
   * There is, by and large, a one-to-one mapping in each each IA332_ opt operator represents an
   * IA32 opcde, so this method might seem useless. However, there are some special cases, notably
   * for operand size. In this case, an opt operator of the form ADD__B would mean use the ADD IA32
   * opcode with a byte operand size.
   */
  private static Set<String> getMatchingOperators(String lowLevelOpcode) {
    Iterator<String> e = OperatorFormatTables.getOpcodes();
    Set<String> matchingOperators = new HashSet<String>();
    while (e.hasNext()) {
      String o = (String) e.next();
      if (o.equals(lowLevelOpcode) || o.startsWith(lowLevelOpcode + "__")) matchingOperators.add(o);
    }

    return matchingOperators;
  }
  /**
   * returns a list of all IA32_ opt compiler operators that do not correspond to real IA32 opcodes
   * handled by the assembler. These are all supposed to have been removed by the time the assembler
   * is called, so the assembler actually seeing such an opcode is an internal compiler error. This
   * set is used during generating of error checking code.
   *
   * @param emittedOpcodes the set of IA32 opcodes the assembler understands.
   * @return the set of IA32 opt operators that the assembler does not understand.
   */
  private static Set<String> getErrorOpcodes(Set<String> emittedOpcodes) {
    Iterator<String> e = OperatorFormatTables.getOpcodes();
    Set<String> errorOpcodes = new HashSet<String>();
    while (e.hasNext()) {
      String opcode = (String) e.next();
      if (!emittedOpcodes.contains(opcode)) errorOpcodes.add(opcode);
    }

    return errorOpcodes;
  }