//
// Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
//
// This code is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License version 2 only, as
// published by the Free Software Foundation.
//
// This code is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// version 2 for more details (a copy is included in the LICENSE file that
// accompanied this code).
//
// You should have received a copy of the GNU General Public License version
// 2 along with this work; if not, write to the Free Software Foundation,
// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
//
// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
// or visit www.oracle.com if you need additional information or have any
// questions.
//
//


// archDesc.cpp - Internal format for architecture definition
#include "adlc.hpp"

static FILE *errfile = stderr;

//--------------------------- utility functions -----------------------------
inline char toUpper(char lower) {
  return (('a' <= lower && lower <= 'z') ? ((char) (lower + ('A'-'a'))) : lower);
}
char *toUpper(const char *str) {
  char *upper  = new char[strlen(str)+1];
  char *result = upper;
  const char *end    = str + strlen(str);
  for (; str < end; ++str, ++upper) {
    *upper = toUpper(*str);
  }
  *upper = '\0';
  return result;
}

// Utilities to characterize effect statements
static bool is_def(int usedef) {
  switch(usedef) {
  case Component::DEF:
  case Component::USE_DEF: return true; break;
  }
  return false;
}

static bool is_use(int usedef) {
  switch(usedef) {
  case Component::USE:
  case Component::USE_DEF:
  case Component::USE_KILL: return true; break;
  }
  return false;
}

static bool is_kill(int usedef) {
  switch(usedef) {
  case Component::KILL:
  case Component::USE_KILL: return true; break;
  }
  return false;
}

//---------------------------ChainList Methods-------------------------------
ChainList::ChainList() {
}

void ChainList::insert(const char *name, const char *cost, const char *rule) {
  _name.addName(name);
  _cost.addName(cost);
  _rule.addName(rule);
}

bool ChainList::search(const char *name) {
  return _name.search(name);
}

void ChainList::reset() {
  _name.reset();
  _cost.reset();
  _rule.reset();
}

bool ChainList::iter(const char * &name, const char * &cost, const char * &rule) {
  bool        notDone = false;
  const char *n       = _name.iter();
  const char *c       = _cost.iter();
  const char *r       = _rule.iter();

  if (n && c && r) {
    notDone = true;
    name = n;
    cost = c;
    rule = r;
  }

  return notDone;
}

void ChainList::dump() {
  output(stderr);
}

void ChainList::output(FILE *fp) {
  fprintf(fp, "\nChain Rules: output resets iterator\n");
  const char   *cost  = NULL;
  const char   *name  = NULL;
  const char   *rule  = NULL;
  bool   chains_exist = false;
  for(reset(); (iter(name,cost,rule)) == true; ) {
    fprintf(fp, "Chain to <%s> at cost #%s using %s_rule\n",name, cost ? cost : "0", rule);
    //  // Check for transitive chain rules
    //  Form *form = (Form *)_globalNames[rule];
    //  if (form->is_instruction()) {
    //    // chain_rule(fp, indent, name, cost, rule);
    //    chain_rule(fp, indent, name, cost, rule);
    //  }
  }
  reset();
  if( ! chains_exist ) {
    fprintf(fp, "No entries in this ChainList\n");
  }
}


//---------------------------MatchList Methods-------------------------------
bool MatchList::search(const char *opc, const char *res, const char *lch,
                       const char *rch, Predicate *pr) {
  bool tmp = false;
  if ((res == _resultStr) || (res && _resultStr && !strcmp(res, _resultStr))) {
    if ((lch == _lchild) || (lch && _lchild && !strcmp(lch, _lchild))) {
      if ((rch == _rchild) || (rch && _rchild && !strcmp(rch, _rchild))) {
        char * predStr = get_pred();
        char * prStr = pr?pr->_pred:NULL;
        if (ADLParser::equivalent_expressions(prStr, predStr)) {
          return true;
        }
      }
    }
  }
  if (_next) {
    tmp = _next->search(opc, res, lch, rch, pr);
  }
  return tmp;
}


void MatchList::dump() {
  output(stderr);
}

void MatchList::output(FILE *fp) {
  fprintf(fp, "\nMatchList output is Unimplemented();\n");
}


//---------------------------ArchDesc Constructor and Destructor-------------

ArchDesc::ArchDesc()
  : _globalNames(cmpstr,hashstr, Form::arena),
    _globalDefs(cmpstr,hashstr, Form::arena),
    _preproc_table(cmpstr,hashstr, Form::arena),
    _idealIndex(cmpstr,hashstr, Form::arena),
    _internalOps(cmpstr,hashstr, Form::arena),
    _internalMatch(cmpstr,hashstr, Form::arena),
    _chainRules(cmpstr,hashstr, Form::arena),
    _cisc_spill_operand(NULL),
    _needs_clone_jvms(false) {

      // Initialize the opcode to MatchList table with NULLs
      for( int i=0; i<_last_opcode; ++i ) {
        _mlistab[i] = NULL;
      }

      // Set-up the global tables
      initKeywords(_globalNames);    // Initialize the Name Table with keywords

      // Prime user-defined types with predefined types: Set, RegI, RegF, ...
      initBaseOpTypes();

      // Initialize flags & counters
      _TotalLines        = 0;
      _no_output         = 0;
      _quiet_mode        = 0;
      _disable_warnings  = 0;
      _dfa_debug         = 0;
      _dfa_small         = 0;
      _adl_debug         = 0;
      _adlocation_debug  = 0;
      _internalOpCounter = 0;
      _cisc_spill_debug  = false;
      _short_branch_debug = false;

      // Initialize match rule flags
      for (int i = 0; i < _last_opcode; i++) {
        _has_match_rule[i] = false;
      }

      // Error/Warning Counts
      _syntax_errs       = 0;
      _semantic_errs     = 0;
      _warnings          = 0;
      _internal_errs     = 0;

      // Initialize I/O Files
      _ADL_file._name = NULL; _ADL_file._fp = NULL;
      // Machine dependent output files
      _DFA_file._name    = NULL;  _DFA_file._fp = NULL;
      _HPP_file._name    = NULL;  _HPP_file._fp = NULL;
      _CPP_file._name    = NULL;  _CPP_file._fp = NULL;
      _bug_file._name    = "bugs.out";      _bug_file._fp = NULL;

      // Initialize Register & Pipeline Form Pointers
      _register = NULL;
      _encode = NULL;
      _pipeline = NULL;
      _frame = NULL;
}

ArchDesc::~ArchDesc() {
  // Clean-up and quit

}

//---------------------------ArchDesc methods: Public ----------------------
// Store forms according to type
void ArchDesc::addForm(PreHeaderForm *ptr) { _pre_header.addForm(ptr); };
void ArchDesc::addForm(HeaderForm    *ptr) { _header.addForm(ptr); };
void ArchDesc::addForm(SourceForm    *ptr) { _source.addForm(ptr); };
void ArchDesc::addForm(EncodeForm    *ptr) { _encode = ptr; };
void ArchDesc::addForm(InstructForm  *ptr) { _instructions.addForm(ptr); };
void ArchDesc::addForm(MachNodeForm  *ptr) { _machnodes.addForm(ptr); };
void ArchDesc::addForm(OperandForm   *ptr) { _operands.addForm(ptr); };
void ArchDesc::addForm(OpClassForm   *ptr) { _opclass.addForm(ptr); };
void ArchDesc::addForm(AttributeForm *ptr) { _attributes.addForm(ptr); };
void ArchDesc::addForm(RegisterForm  *ptr) { _register = ptr; };
void ArchDesc::addForm(FrameForm     *ptr) { _frame = ptr; };
void ArchDesc::addForm(PipelineForm  *ptr) { _pipeline = ptr; };

// Build MatchList array and construct MatchLists
void ArchDesc::generateMatchLists() {
  // Call inspection routines to populate array
  inspectOperands();
  inspectInstructions();
}

// Build MatchList structures for operands
void ArchDesc::inspectOperands() {

  // Iterate through all operands
  _operands.reset();
  OperandForm *op;
  for( ; (op = (OperandForm*)_operands.iter()) != NULL;) {
    // Construct list of top-level operands (components)
    op->build_components();

    // Ensure that match field is defined.
    if ( op->_matrule == NULL )  continue;

    // Type check match rules
    check_optype(op->_matrule);

    // Construct chain rules
    build_chain_rule(op);

    MatchRule &mrule = *op->_matrule;
    Predicate *pred  =  op->_predicate;

    // Grab the machine type of the operand
    const char  *rootOp    = op->_ident;
    mrule._machType  = rootOp;

    // Check for special cases
    if (strcmp(rootOp,"Universe")==0) continue;
    if (strcmp(rootOp,"label")==0) continue;
    // !!!!! !!!!!
    assert( strcmp(rootOp,"sReg") != 0, "Disable untyped 'sReg'");
    if (strcmp(rootOp,"sRegI")==0) continue;
    if (strcmp(rootOp,"sRegP")==0) continue;
    if (strcmp(rootOp,"sRegF")==0) continue;
    if (strcmp(rootOp,"sRegD")==0) continue;
    if (strcmp(rootOp,"sRegL")==0) continue;

    // Cost for this match
    const char *costStr     = op->cost();
    const char *defaultCost =
      ((AttributeForm*)_globalNames[AttributeForm::_op_cost])->_attrdef;
    const char *cost        =  costStr? costStr : defaultCost;

    // Find result type for match.
    const char *result      = op->reduce_result();
    bool        has_root    = false;

    // Construct a MatchList for this entry
    buildMatchList(op->_matrule, result, rootOp, pred, cost);
  }
}

// Build MatchList structures for instructions
void ArchDesc::inspectInstructions() {

  // Iterate through all instructions
  _instructions.reset();
  InstructForm *instr;
  for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
    // Construct list of top-level operands (components)
    instr->build_components();

    // Ensure that match field is defined.
    if ( instr->_matrule == NULL )  continue;

    MatchRule &mrule = *instr->_matrule;
    Predicate *pred  =  instr->build_predicate();

    // Grab the machine type of the operand
    const char  *rootOp    = instr->_ident;
    mrule._machType  = rootOp;

    // Cost for this match
    const char *costStr = instr->cost();
    const char *defaultCost =
      ((AttributeForm*)_globalNames[AttributeForm::_ins_cost])->_attrdef;
    const char *cost    =  costStr? costStr : defaultCost;

    // Find result type for match
    const char *result  = instr->reduce_result();

    if ( instr->is_ideal_branch() && instr->label_position() == -1 ||
        !instr->is_ideal_branch() && instr->label_position() != -1) {
      syntax_err(instr->_linenum, "%s: Only branches to a label are supported\n", rootOp);
    }

    Attribute *attr = instr->_attribs;
    while (attr != NULL) {
      if (strcmp(attr->_ident,"ins_short_branch") == 0 &&
          attr->int_val(*this) != 0) {
        if (!instr->is_ideal_branch() || instr->label_position() == -1) {
          syntax_err(instr->_linenum, "%s: Only short branch to a label is supported\n", rootOp);
        }
        instr->set_short_branch(true);
      } else if (strcmp(attr->_ident,"ins_alignment") == 0 &&
          attr->int_val(*this) != 0) {
        instr->set_alignment(attr->int_val(*this));
      }
      attr = (Attribute *)attr->_next;
    }

    if (!instr->is_short_branch()) {
      buildMatchList(instr->_matrule, result, mrule._machType, pred, cost);
    }
  }
}

static int setsResult(MatchRule &mrule) {
  if (strcmp(mrule._name,"Set") == 0) return 1;
  return 0;
}

const char *ArchDesc::getMatchListIndex(MatchRule &mrule) {
  if (setsResult(mrule)) {
    // right child
    return mrule._rChild->_opType;
  } else {
    // first entry
    return mrule._opType;
  }
}


//------------------------------result of reduction----------------------------


//------------------------------left reduction---------------------------------
// Return the left reduction associated with an internal name
const char *ArchDesc::reduceLeft(char         *internalName) {
  const char *left  = NULL;
  MatchNode *mnode = (MatchNode*)_internalMatch[internalName];
  if (mnode->_lChild) {
    mnode = mnode->_lChild;
    left = mnode->_internalop ? mnode->_internalop : mnode->_opType;
  }
  return left;
}


//------------------------------right reduction--------------------------------
const char *ArchDesc::reduceRight(char  *internalName) {
  const char *right  = NULL;
  MatchNode *mnode = (MatchNode*)_internalMatch[internalName];
  if (mnode->_rChild) {
    mnode = mnode->_rChild;
    right = mnode->_internalop ? mnode->_internalop : mnode->_opType;
  }
  return right;
}


//------------------------------check_optype-----------------------------------
void ArchDesc::check_optype(MatchRule *mrule) {
  MatchRule *rule = mrule;

  //   !!!!!
  //   // Cycle through the list of match rules
  //   while(mrule) {
  //     // Check for a filled in type field
  //     if (mrule->_opType == NULL) {
  //     const Form  *form    = operands[_result];
  //     OpClassForm *opcForm = form ? form->is_opclass() : NULL;
  //     assert(opcForm != NULL, "Match Rule contains invalid operand name.");
  //     }
  //     char *opType = opcForm->_ident;
  //   }
}

//------------------------------add_chain_rule_entry--------------------------
void ArchDesc::add_chain_rule_entry(const char *src, const char *cost,
                                    const char *result) {
  // Look-up the operation in chain rule table
  ChainList *lst = (ChainList *)_chainRules[src];
  if (lst == NULL) {
    lst = new ChainList();
    _chainRules.Insert(src, lst);
  }
  if (!lst->search(result)) {
    if (cost == NULL) {
      cost = ((AttributeForm*)_globalNames[AttributeForm::_op_cost])->_attrdef;
    }
    lst->insert(result, cost, result);
  }
}

//------------------------------build_chain_rule-------------------------------
void ArchDesc::build_chain_rule(OperandForm *oper) {
  MatchRule     *rule;

  // Check for chain rules here
  // If this is only a chain rule
  if ((oper->_matrule) && (oper->_matrule->_lChild == NULL) &&
      (oper->_matrule->_rChild == NULL)) {

    {
      const Form *form = _globalNames[oper->_matrule->_opType];
      if ((form) && form->is_operand() &&
          (form->ideal_only() == false)) {
        add_chain_rule_entry(oper->_matrule->_opType, oper->cost(), oper->_ident);
      }
    }
    // Check for additional chain rules
    if (oper->_matrule->_next) {
      rule = oper->_matrule;
      do {
        rule = rule->_next;
        // Any extra match rules after the first must be chain rules
        const Form *form = _globalNames[rule->_opType];
        if ((form) && form->is_operand() &&
            (form->ideal_only() == false)) {
          add_chain_rule_entry(rule->_opType, oper->cost(), oper->_ident);
        }
      } while(rule->_next != NULL);
    }
  }
  else if ((oper->_matrule) && (oper->_matrule->_next)) {
    // Regardles of whether the first matchrule is a chain rule, check the list
    rule = oper->_matrule;
    do {
      rule = rule->_next;
      // Any extra match rules after the first must be chain rules
      const Form *form = _globalNames[rule->_opType];
      if ((form) && form->is_operand() &&
          (form->ideal_only() == false)) {
        assert( oper->cost(), "This case expects NULL cost, not default cost");
        add_chain_rule_entry(rule->_opType, oper->cost(), oper->_ident);
      }
    } while(rule->_next != NULL);
  }

}

//------------------------------buildMatchList---------------------------------
// operands and instructions provide the result
void ArchDesc::buildMatchList(MatchRule *mrule, const char *resultStr,
                              const char *rootOp, Predicate *pred,
                              const char *cost) {
  const char *leftstr, *rightstr;
  MatchNode  *mnode;

  leftstr = rightstr = NULL;
  // Check for chain rule, and do not generate a match list for it
  if ( mrule->is_chain_rule(_globalNames) ) {
    return;
  }

  // Identify index position among ideal operands
  intptr_t    index     = _last_opcode;
  const char  *indexStr  = getMatchListIndex(*mrule);
  index  = (intptr_t)_idealIndex[indexStr];
  if (index == 0) {
    fprintf(stderr, "Ideal node missing: %s\n", indexStr);
    assert(index != 0, "Failed lookup of ideal node\n");
  }

  // Check that this will be placed appropriately in the DFA
  if (index >= _last_opcode) {
    fprintf(stderr, "Invalid match rule %s <-- ( %s )\n",
            resultStr ? resultStr : " ",
            rootOp    ? rootOp    : " ");
    assert(index < _last_opcode, "Matching item not in ideal graph\n");
    return;
  }


  // Walk the MatchRule, generating MatchList entries for each level
  // of the rule (each nesting of parentheses)
  // Check for "Set"
  if (!strcmp(mrule->_opType, "Set")) {
    mnode = mrule->_rChild;
    buildMList(mnode, rootOp, resultStr, pred, cost);
    return;
  }
  // Build MatchLists for children
  // Check each child for an internal operand name, and use that name
  // for the parent's matchlist entry if it exists
  mnode = mrule->_lChild;
  if (mnode) {
    buildMList(mnode, NULL, NULL, NULL, NULL);
    leftstr = mnode->_internalop ? mnode->_internalop : mnode->_opType;
  }
  mnode = mrule->_rChild;
  if (mnode) {
    buildMList(mnode, NULL, NULL, NULL, NULL);
    rightstr = mnode->_internalop ? mnode->_internalop : mnode->_opType;
  }
  // Search for an identical matchlist entry already on the list
  if ((_mlistab[index] == NULL) ||
      (_mlistab[index] &&
       !_mlistab[index]->search(rootOp, resultStr, leftstr, rightstr, pred))) {
    // Place this match rule at front of list
    MatchList *mList =
      new MatchList(_mlistab[index], pred, cost,
                    rootOp, resultStr, leftstr, rightstr);
    _mlistab[index] = mList;
  }
}

// Recursive call for construction of match lists
void ArchDesc::buildMList(MatchNode *node, const char *rootOp,
                          const char *resultOp, Predicate *pred,
                          const char *cost) {
  const char *leftstr, *rightstr;
  const char *resultop;
  const char *opcode;
  MatchNode  *mnode;
  Form       *form;

  leftstr = rightstr = NULL;
  // Do not process leaves of the Match Tree if they are not ideal
  if ((node) && (node->_lChild == NULL) && (node->_rChild == NULL) &&
      ((form = (Form *)_globalNames[node->_opType]) != NULL) &&
      (!form->ideal_only())) {
    return;
  }

  // Identify index position among ideal operands
  intptr_t    index     = _last_opcode;
  const char *indexStr  = node ? node->_opType : (char *) " ";
  index            = (intptr_t)_idealIndex[indexStr];
  if (index == 0) {
    fprintf(stderr, "error: operand \"%s\" not found\n", indexStr);
    assert(0, "fatal error");
  }

  // Build MatchLists for children
  // Check each child for an internal operand name, and use that name
  // for the parent's matchlist entry if it exists
  mnode = node->_lChild;
  if (mnode) {
    buildMList(mnode, NULL, NULL, NULL, NULL);
    leftstr = mnode->_internalop ? mnode->_internalop : mnode->_opType;
  }
  mnode = node->_rChild;
  if (mnode) {
    buildMList(mnode, NULL, NULL, NULL, NULL);
    rightstr = mnode->_internalop ? mnode->_internalop : mnode->_opType;
  }
  // Grab the string for the opcode of this list entry
  if (rootOp == NULL) {
    opcode = (node->_internalop) ? node->_internalop : node->_opType;
  } else {
    opcode = rootOp;
  }
  // Grab the string for the result of this list entry
  if (resultOp == NULL) {
    resultop = (node->_internalop) ? node->_internalop : node->_opType;
  }
  else resultop = resultOp;
  // Search for an identical matchlist entry already on the list
  if ((_mlistab[index] == NULL) || (_mlistab[index] &&
                                    !_mlistab[index]->search(opcode, resultop, leftstr, rightstr, pred))) {
    // Place this match rule at front of list
    MatchList *mList =
      new MatchList(_mlistab[index],pred,cost,
                    opcode, resultop, leftstr, rightstr);
    _mlistab[index] = mList;
  }
}

// Count number of OperandForms defined
int  ArchDesc::operandFormCount() {
  // Only interested in ones with non-NULL match rule
  int  count = 0; _operands.reset();
  OperandForm *cur;
  for( ; (cur = (OperandForm*)_operands.iter()) != NULL; ) {
    if (cur->_matrule != NULL) ++count;
  };
  return count;
}

// Count number of OpClassForms defined
int  ArchDesc::opclassFormCount() {
  // Only interested in ones with non-NULL match rule
  int  count = 0; _operands.reset();
  OpClassForm *cur;
  for( ; (cur = (OpClassForm*)_opclass.iter()) != NULL; ) {
    ++count;
  };
  return count;
}

// Count number of InstructForms defined
int  ArchDesc::instructFormCount() {
  // Only interested in ones with non-NULL match rule
  int  count = 0; _instructions.reset();
  InstructForm *cur;
  for( ; (cur = (InstructForm*)_instructions.iter()) != NULL; ) {
    if (cur->_matrule != NULL) ++count;
  };
  return count;
}


//------------------------------get_preproc_def--------------------------------
// Return the textual binding for a given CPP flag name.
// Return NULL if there is no binding, or it has been #undef-ed.
char* ArchDesc::get_preproc_def(const char* flag) {
  // In case of syntax errors, flag may take the value NULL.
  SourceForm* deff = NULL;
  if (flag != NULL)
    deff = (SourceForm*) _preproc_table[flag];
  return (deff == NULL) ? NULL : deff->_code;
}


//------------------------------set_preproc_def--------------------------------
// Change or create a textual binding for a given CPP flag name.
// Giving NULL means the flag name is to be #undef-ed.
// In any case, _preproc_list collects all names either #defined or #undef-ed.
void ArchDesc::set_preproc_def(const char* flag, const char* def) {
  SourceForm* deff = (SourceForm*) _preproc_table[flag];
  if (deff == NULL) {
    deff = new SourceForm(NULL);
    _preproc_table.Insert(flag, deff);
    _preproc_list.addName(flag);   // this supports iteration
  }
  deff->_code = (char*) def;
}


bool ArchDesc::verify() {

  if (_register)
    assert( _register->verify(), "Register declarations failed verification");
  if (!_quiet_mode)
    fprintf(stderr,"\n");
  // fprintf(stderr,"---------------------------- Verify Operands ---------------\n");
  // _operands.verify();
  // fprintf(stderr,"\n");
  // fprintf(stderr,"---------------------------- Verify Operand Classes --------\n");
  // _opclass.verify();
  // fprintf(stderr,"\n");
  // fprintf(stderr,"---------------------------- Verify Attributes  ------------\n");
  // _attributes.verify();
  // fprintf(stderr,"\n");
  if (!_quiet_mode)
    fprintf(stderr,"---------------------------- Verify Instructions ----------------------------\n");
  _instructions.verify();
  if (!_quiet_mode)
    fprintf(stderr,"\n");
  // if ( _encode ) {
  //   fprintf(stderr,"---------------------------- Verify Encodings --------------\n");
  //   _encode->verify();
  // }

  //if (_pipeline) _pipeline->verify();

  return true;
}


void ArchDesc::dump() {
  _pre_header.dump();
  _header.dump();
  _source.dump();
  if (_register) _register->dump();
  fprintf(stderr,"\n");
  fprintf(stderr,"------------------ Dump Operands ---------------------\n");
  _operands.dump();
  fprintf(stderr,"\n");
  fprintf(stderr,"------------------ Dump Operand Classes --------------\n");
  _opclass.dump();
  fprintf(stderr,"\n");
  fprintf(stderr,"------------------ Dump Attributes  ------------------\n");
  _attributes.dump();
  fprintf(stderr,"\n");
  fprintf(stderr,"------------------ Dump Instructions -----------------\n");
  _instructions.dump();
  if ( _encode ) {
    fprintf(stderr,"------------------ Dump Encodings --------------------\n");
    _encode->dump();
  }
  if (_pipeline) _pipeline->dump();
}


//------------------------------init_keywords----------------------------------
// Load the kewords into the global name table
void ArchDesc::initKeywords(FormDict& names) {
  // Insert keyword strings into Global Name Table.  Keywords have a NULL value
  // field for quick easy identification when checking identifiers.
  names.Insert("instruct", NULL);
  names.Insert("operand", NULL);
  names.Insert("attribute", NULL);
  names.Insert("source", NULL);
  names.Insert("register", NULL);
  names.Insert("pipeline", NULL);
  names.Insert("constraint", NULL);
  names.Insert("predicate", NULL);
  names.Insert("encode", NULL);
  names.Insert("enc_class", NULL);
  names.Insert("interface", NULL);
  names.Insert("opcode", NULL);
  names.Insert("ins_encode", NULL);
  names.Insert("match", NULL);
  names.Insert("effect", NULL);
  names.Insert("expand", NULL);
  names.Insert("rewrite", NULL);
  names.Insert("reg_def", NULL);
  names.Insert("reg_class", NULL);
  names.Insert("alloc_class", NULL);
  names.Insert("resource", NULL);
  names.Insert("pipe_class", NULL);
  names.Insert("pipe_desc", NULL);
}


//------------------------------internal_err----------------------------------
// Issue a parser error message, and skip to the end of the current line
void ArchDesc::internal_err(const char *fmt, ...) {
  va_list args;

  va_start(args, fmt);
  _internal_errs += emit_msg(0, INTERNAL_ERR, 0, fmt, args);
  va_end(args);

  _no_output = 1;
}

//------------------------------syntax_err----------------------------------
// Issue a parser error message, and skip to the end of the current line
void ArchDesc::syntax_err(int lineno, const char *fmt, ...) {
  va_list args;

  va_start(args, fmt);
  _internal_errs += emit_msg(0, SYNERR, lineno, fmt, args);
  va_end(args);

  _no_output = 1;
}

//------------------------------emit_msg---------------------------------------
// Emit a user message, typically a warning or error
int ArchDesc::emit_msg(int quiet, int flag, int line, const char *fmt,
    va_list args) {
  static int  last_lineno = -1;
  int         i;
  const char *pref;

  switch(flag) {
  case 0: pref = "Warning: "; break;
  case 1: pref = "Syntax Error: "; break;
  case 2: pref = "Semantic Error: "; break;
  case 3: pref = "Internal Error: "; break;
  default: assert(0, ""); break;
  }

  if (line == last_lineno) return 0;
  last_lineno = line;

  if (!quiet) {                        /* no output if in quiet mode         */
    i = fprintf(errfile, "%s(%d) ", _ADL_file._name, line);
    while (i++ <= 15)  fputc(' ', errfile);
    fprintf(errfile, "%-8s:", pref);
    vfprintf(errfile, fmt, args);
    fprintf(errfile, "\n");
    fflush(errfile);
  }
  return 1;
}


// ---------------------------------------------------------------------------
//--------Utilities to build mappings for machine registers ------------------
// ---------------------------------------------------------------------------

// Construct the name of the register mask.
static const char *getRegMask(const char *reg_class_name) {
  if( reg_class_name == NULL ) return "RegMask::Empty";

  if (strcmp(reg_class_name,"Universe")==0) {
    return "RegMask::Empty";
  } else if (strcmp(reg_class_name,"stack_slots")==0) {
    return "(Compile::current()->FIRST_STACK_mask())";
  } else {
    char       *rc_name = toUpper(reg_class_name);
    const char *mask    = "_mask";
    int         length  = (int)strlen(rc_name) + (int)strlen(mask) + 5;
    char       *regMask = new char[length];
    sprintf(regMask,"%s%s()", rc_name, mask);
    delete[] rc_name;
    return regMask;
  }
}

// Convert a register class name to its register mask.
const char *ArchDesc::reg_class_to_reg_mask(const char *rc_name) {
  const char *reg_mask = "RegMask::Empty";

  if( _register ) {
    RegClass *reg_class  = _register->getRegClass(rc_name);
    if (reg_class == NULL) {
      syntax_err(0, "Use of an undefined register class %s", rc_name);
      return reg_mask;
    }

    // Construct the name of the register mask.
    reg_mask = getRegMask(rc_name);
  }

  return reg_mask;
}


// Obtain the name of the RegMask for an OperandForm
const char *ArchDesc::reg_mask(OperandForm  &opForm) {
  const char *regMask      = "RegMask::Empty";

  // Check constraints on result's register class
  const char *result_class = opForm.constrained_reg_class();
  if (result_class == NULL) {
    opForm.dump();
    syntax_err(opForm._linenum,
               "Use of an undefined result class for operand: %s",
               opForm._ident);
    abort();
  }

  regMask = reg_class_to_reg_mask( result_class );

  return regMask;
}

// Obtain the name of the RegMask for an InstructForm
const char *ArchDesc::reg_mask(InstructForm &inForm) {
  const char *result = inForm.reduce_result();

  if (result == NULL) {
    syntax_err(inForm._linenum,
               "Did not find result operand or RegMask"
               " for this instruction: %s",
               inForm._ident);
    abort();
  }

  // Instructions producing 'Universe' use RegMask::Empty
  if( strcmp(result,"Universe")==0 ) {
    return "RegMask::Empty";
  }

  // Lookup this result operand and get its register class
  Form *form = (Form*)_globalNames[result];
  if (form == NULL) {
    syntax_err(inForm._linenum,
               "Did not find result operand for result: %s", result);
    abort();
  }
  OperandForm *oper = form->is_operand();
  if (oper == NULL) {
    syntax_err(inForm._linenum, "Form is not an OperandForm:");
    form->dump();
    abort();
  }
  return reg_mask( *oper );
}


// Obtain the STACK_OR_reg_mask name for an OperandForm
char *ArchDesc::stack_or_reg_mask(OperandForm  &opForm) {
  // name of cisc_spillable version
  const char *reg_mask_name = reg_mask(opForm);

  if (reg_mask_name == NULL) {
     syntax_err(opForm._linenum,
                "Did not find reg_mask for opForm: %s",
                opForm._ident);
     abort();
  }

  const char *stack_or = "STACK_OR_";
  int   length         = (int)strlen(stack_or) + (int)strlen(reg_mask_name) + 1;
  char *result         = new char[length];
  sprintf(result,"%s%s", stack_or, reg_mask_name);

  return result;
}

// Record that the register class must generate a stack_or_reg_mask
void ArchDesc::set_stack_or_reg(const char *reg_class_name) {
  if( _register ) {
    RegClass *reg_class  = _register->getRegClass(reg_class_name);
    reg_class->set_stack_version(true);
  }
}


// Return the type signature for the ideal operation
const char *ArchDesc::getIdealType(const char *idealOp) {
  // Find last character in idealOp, it specifies the type
  char  last_char = 0;
  const char *ptr = idealOp;
  for (; *ptr != '\0'; ++ptr) {
    last_char = *ptr;
  }

  // Match Vector types.
  if (strncmp(idealOp, "Vec",3)==0) {
    switch(last_char) {
    case 'S':  return "TypeVect::VECTS";
    case 'D':  return "TypeVect::VECTD";
    case 'X':  return "TypeVect::VECTX";
    case 'Y':  return "TypeVect::VECTY";
    default:
      internal_err("Vector type %s with unrecognized type\n",idealOp);
    }
  }

  // !!!!!
  switch(last_char) {
  case 'I':    return "TypeInt::INT";
  case 'P':    return "TypePtr::BOTTOM";
  case 'N':    return "TypeNarrowOop::BOTTOM";
  case 'F':    return "Type::FLOAT";
  case 'D':    return "Type::DOUBLE";
  case 'L':    return "TypeLong::LONG";
  case 's':    return "TypeInt::CC /*flags*/";
  default:
    return NULL;
    // !!!!!
    // internal_err("Ideal type %s with unrecognized type\n",idealOp);
    break;
  }

  return NULL;
}



OperandForm *ArchDesc::constructOperand(const char *ident,
                                        bool  ideal_only) {
  OperandForm *opForm = new OperandForm(ident, ideal_only);
  _globalNames.Insert(ident, opForm);
  addForm(opForm);

  return opForm;
}


// Import predefined base types: Set = 1, RegI, RegP, ...
void ArchDesc::initBaseOpTypes() {
  // Create OperandForm and assign type for each opcode.
  for (int i = 1; i < _last_machine_leaf; ++i) {
    char        *ident   = (char *)NodeClassNames[i];
    constructOperand(ident, true);
  }
  // Create InstructForm and assign type for each ideal instruction.
  for ( int j = _last_machine_leaf+1; j < _last_opcode; ++j) {
    char         *ident    = (char *)NodeClassNames[j];
    if(!strcmp(ident, "ConI") || !strcmp(ident, "ConP") ||
       !strcmp(ident, "ConN") || !strcmp(ident, "ConNKlass") ||
       !strcmp(ident, "ConF") || !strcmp(ident, "ConD") ||
       !strcmp(ident, "ConL") || !strcmp(ident, "Con" ) ||
       !strcmp(ident, "Bool") ) {
      constructOperand(ident, true);
    }
    else {
      InstructForm *insForm  = new InstructForm(ident, true);
      // insForm->_opcode       = nextUserOpType(ident);
      _globalNames.Insert(ident,insForm);
      addForm(insForm);
    }
  }

  { OperandForm *opForm;
  // Create operand type "Universe" for return instructions.
  const char *ident = "Universe";
  opForm = constructOperand(ident, false);

  // Create operand type "label" for branch targets
  ident = "label";
  opForm = constructOperand(ident, false);

  // !!!!! Update - when adding a new sReg/stackSlot type
  // Create operand types "sReg[IPFDL]" for stack slot registers
  opForm = constructOperand("sRegI", false);
  opForm->_constraint = new Constraint("ALLOC_IN_RC", "stack_slots");
  opForm = constructOperand("sRegP", false);
  opForm->_constraint = new Constraint("ALLOC_IN_RC", "stack_slots");
  opForm = constructOperand("sRegF", false);
  opForm->_constraint = new Constraint("ALLOC_IN_RC", "stack_slots");
  opForm = constructOperand("sRegD", false);
  opForm->_constraint = new Constraint("ALLOC_IN_RC", "stack_slots");
  opForm = constructOperand("sRegL", false);
  opForm->_constraint = new Constraint("ALLOC_IN_RC", "stack_slots");

  // Create operand type "method" for call targets
  ident = "method";
  opForm = constructOperand(ident, false);
  }

  // Create Effect Forms for each of the legal effects
  // USE, DEF, USE_DEF, KILL, USE_KILL
  {
    const char *ident = "USE";
    Effect     *eForm = new Effect(ident);
    _globalNames.Insert(ident, eForm);
    ident = "DEF";
    eForm = new Effect(ident);
    _globalNames.Insert(ident, eForm);
    ident = "USE_DEF";
    eForm = new Effect(ident);
    _globalNames.Insert(ident, eForm);
    ident = "KILL";
    eForm = new Effect(ident);
    _globalNames.Insert(ident, eForm);
    ident = "USE_KILL";
    eForm = new Effect(ident);
    _globalNames.Insert(ident, eForm);
    ident = "TEMP";
    eForm = new Effect(ident);
    _globalNames.Insert(ident, eForm);
    ident = "CALL";
    eForm = new Effect(ident);
    _globalNames.Insert(ident, eForm);
  }

  //
  // Build mapping from ideal names to ideal indices
  int idealIndex = 0;
  for (idealIndex = 1; idealIndex < _last_machine_leaf; ++idealIndex) {
    const char *idealName = NodeClassNames[idealIndex];
    _idealIndex.Insert((void*) idealName, (void*) (intptr_t) idealIndex);
  }
  for ( idealIndex = _last_machine_leaf+1;
        idealIndex < _last_opcode; ++idealIndex) {
    const char *idealName = NodeClassNames[idealIndex];
    _idealIndex.Insert((void*) idealName, (void*) (intptr_t) idealIndex);
  }

}


//---------------------------addSUNcopyright-------------------------------
// output SUN copyright info
void ArchDesc::addSunCopyright(char* legal, int size, FILE *fp) {
  size_t count = fwrite(legal, 1, size, fp);
  assert(count == (size_t) size, "copyright info truncated");
  fprintf(fp,"\n");
  fprintf(fp,"// Machine Generated File.  Do Not Edit!\n");
  fprintf(fp,"\n");
}


//---------------------------addIncludeGuardStart--------------------------
// output the start of an include guard.
void ArchDesc::addIncludeGuardStart(ADLFILE &adlfile, const char* guardString) {
  // Build #include lines
  fprintf(adlfile._fp, "\n");
  fprintf(adlfile._fp, "#ifndef %s\n", guardString);
  fprintf(adlfile._fp, "#define %s\n", guardString);
  fprintf(adlfile._fp, "\n");

}

//---------------------------addIncludeGuardEnd--------------------------
// output the end of an include guard.
void ArchDesc::addIncludeGuardEnd(ADLFILE &adlfile, const char* guardString) {
  // Build #include lines
  fprintf(adlfile._fp, "\n");
  fprintf(adlfile._fp, "#endif // %s\n", guardString);

}

//---------------------------addInclude--------------------------
// output the #include line for this file.
void ArchDesc::addInclude(ADLFILE &adlfile, const char* fileName) {
  fprintf(adlfile._fp, "#include \"%s\"\n", fileName);

}

void ArchDesc::addInclude(ADLFILE &adlfile, const char* includeDir, const char* fileName) {
  fprintf(adlfile._fp, "#include \"%s/%s\"\n", includeDir, fileName);

}

//---------------------------addPreprocessorChecks-----------------------------
// Output C preprocessor code to verify the backend compilation environment.
// The idea is to force code produced by "adlc -DHS64" to be compiled by a
// command of the form "CC ... -DHS64 ...", so that any #ifdefs in the source
// blocks select C code that is consistent with adlc's selections of AD code.
void ArchDesc::addPreprocessorChecks(FILE *fp) {
  const char* flag;
  _preproc_list.reset();
  if (_preproc_list.count() > 0 && !_preproc_list.current_is_signal()) {
    fprintf(fp, "// Check consistency of C++ compilation with ADLC options:\n");
  }
  for (_preproc_list.reset(); (flag = _preproc_list.iter()) != NULL; ) {
    if (_preproc_list.current_is_signal())  break;
    char* def = get_preproc_def(flag);
    fprintf(fp, "// Check adlc ");
    if (def)
          fprintf(fp, "-D%s=%s\n", flag, def);
    else  fprintf(fp, "-U%s\n", flag);
    fprintf(fp, "#%s %s\n",
            def ? "ifndef" : "ifdef", flag);
    fprintf(fp, "#  error \"%s %s be defined\"\n",
            flag, def ? "must" : "must not");
    fprintf(fp, "#endif // %s\n", flag);
  }
}


// Convert operand name into enum name
const char *ArchDesc::machOperEnum(const char *opName) {
  return ArchDesc::getMachOperEnum(opName);
}

// Convert operand name into enum name
const char *ArchDesc::getMachOperEnum(const char *opName) {
  return (opName ? toUpper(opName) : opName);
}

//---------------------------buildMustCloneMap-----------------------------
// Flag cases when machine needs cloned values or instructions
void ArchDesc::buildMustCloneMap(FILE *fp_hpp, FILE *fp_cpp) {
  // Build external declarations for mappings
  fprintf(fp_hpp, "// Mapping from machine-independent opcode to boolean\n");
  fprintf(fp_hpp, "// Flag cases where machine needs cloned values or instructions\n");
  fprintf(fp_hpp, "extern const char must_clone[];\n");
  fprintf(fp_hpp, "\n");

  // Build mapping from ideal names to ideal indices
  fprintf(fp_cpp, "\n");
  fprintf(fp_cpp, "// Mapping from machine-independent opcode to boolean\n");
  fprintf(fp_cpp, "const        char must_clone[] = {\n");
  for (int idealIndex = 0; idealIndex < _last_opcode; ++idealIndex) {
    int         must_clone = 0;
    const char *idealName = NodeClassNames[idealIndex];
    // Previously selected constants for cloning
    // !!!!!
    // These are the current machine-dependent clones
    if ( strcmp(idealName,"CmpI") == 0
         || strcmp(idealName,"CmpU") == 0
         || strcmp(idealName,"CmpP") == 0
         || strcmp(idealName,"CmpN") == 0
         || strcmp(idealName,"CmpL") == 0
         || strcmp(idealName,"CmpUL") == 0
         || strcmp(idealName,"CmpD") == 0
         || strcmp(idealName,"CmpF") == 0
         || strcmp(idealName,"FastLock") == 0
         || strcmp(idealName,"FastUnlock") == 0
         || strcmp(idealName,"OverflowAddI") == 0
         || strcmp(idealName,"OverflowAddL") == 0
         || strcmp(idealName,"OverflowSubI") == 0
         || strcmp(idealName,"OverflowSubL") == 0
         || strcmp(idealName,"OverflowMulI") == 0
         || strcmp(idealName,"OverflowMulL") == 0
         || strcmp(idealName,"Bool") == 0
         || strcmp(idealName,"Binary") == 0 ) {
      // Removed ConI from the must_clone list.  CPUs that cannot use
      // large constants as immediates manifest the constant as an
      // instruction.  The must_clone flag prevents the constant from
      // floating up out of loops.
      must_clone = 1;
    }
    fprintf(fp_cpp, "  %d%s // %s: %d\n", must_clone,
      (idealIndex != (_last_opcode - 1)) ? "," : " // no trailing comma",
      idealName, idealIndex);
  }
  // Finish defining table
  fprintf(fp_cpp, "};\n");
}
