/*
 * Copyright (c) 1997, 2012, 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.
 *
 */

// FORMS.CPP - Definitions for ADL Parser Generic & Utility Forms Classes
#include "adlc.hpp"

//------------------------------Static Initializers----------------------------
// allocate arena used by forms
Arena  *Form::arena = Form::generate_arena(); //  = Form::generate_arena();
Arena *Form::generate_arena() {
  return (new Arena);
}

//------------------------------NameList---------------------------------------
// reserved user-defined string
const char  *NameList::_signal   = "$$SIGNAL$$";
const char  *NameList::_signal2  = "$$SIGNAL2$$";
const char  *NameList::_signal3  = "$$SIGNAL3$$";

// Constructor and Destructor
NameList::NameList() : _cur(0), _max(4), _iter(0), _justReset(true) {
  _names = (const char**)malloc(_max*sizeof(char*));
}
NameList::~NameList() {
  // The following free is a double-free, and crashes the program:
  //free(_names);                   // not owner of strings
}

void   NameList::addName(const char *name) {
  if (_cur == _max) _names =(const char**)realloc(_names,(_max *=2)*sizeof(char*));
  _names[_cur++] = name;
}

void   NameList::add_signal() {
  addName( _signal );
}
void   NameList::clear() {
  _cur   = 0;
  _iter  = 0;
  _justReset = true;
  // _max   = 4; Already allocated
}

int    NameList::count()  const { return _cur; }

void   NameList::reset()   { _iter = 0; _justReset = true;}
const char  *NameList::iter()    {
  if (_justReset) {_justReset=false; return (_iter < _cur ? _names[_iter] : NULL);}
  else return (_iter <_cur-1 ? _names[++_iter] : NULL);
}
const char  *NameList::current() { return (_iter < _cur ? _names[_iter] : NULL); }
const char  *NameList::peek(int skip) { return (_iter + skip < _cur ? _names[_iter + skip] : NULL); }

// Return 'true' if current entry is signal
bool  NameList::current_is_signal() {
  const char *entry = current();
  return is_signal(entry);
}

// Return true if entry is a signal
bool  NameList::is_signal(const char *entry) {
  return ( (strcmp(entry,NameList::_signal) == 0) ? true : false);
}

// Search for a name in the list
bool   NameList::search(const char *name) {
  const char *entry;
  for(reset(); (entry = iter()) != NULL; ) {
    if(!strcmp(entry,name)) return true;
  }
  return false;
}

// Return index of name in list
int    NameList::index(const char *name) {
  int         cnt = 0;
  const char *entry;
  for(reset(); (entry = iter()) != NULL; ) {
    if(!strcmp(entry,name)) return cnt;
    cnt++;
  }
  return Not_in_list;
}

// Return name at index in list
const char  *NameList::name(intptr_t  index) {
  return ( index < _cur ? _names[index] : NULL);
}

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

void   NameList::output(FILE *fp) {
  fprintf(fp, "\n");

  // Run iteration over all entries, independent of position of iterator.
  const char *name       = NULL;
  int         iter       = 0;
  bool        justReset  = true;

  while( ( name  = (justReset ?
                    (justReset=false, (iter < _cur ? _names[iter] : NULL)) :
                    (iter < _cur-1 ? _names[++iter] : NULL)) )
         != NULL ) {
    fprintf( fp, "  %s,\n", name);
  }
  fprintf(fp, "\n");
}

//------------------------------NameAndList------------------------------------
// Storage for a name and an associated list of names
NameAndList::NameAndList(char *name) : _name(name) {
}
NameAndList::~NameAndList() {
}

// Add to entries in list
void NameAndList::add_entry(const char *entry) {
  _list.addName(entry);
}

// Access the name and its associated list.
const char *NameAndList::name()  const {  return _name;  }
void        NameAndList::reset()       { _list.reset();  }
const char *NameAndList::iter()        { return _list.iter(); }

// Return the "index" entry in the list, zero-based
const char *NameAndList::operator[](int index) {
  assert( index >= 0, "Internal Error(): index less than 0.");

  _list.reset();
  const char *entry = _list.iter();
  // Iterate further if it isn't at index 0.
  for ( int position = 0; position != index; ++position ) {
    entry = _list.iter();
  }

  return entry;
}


void   NameAndList::dump() { output(stderr); }
void   NameAndList::output(FILE *fp) {
  fprintf(fp, "\n");

  // Output the Name
  fprintf(fp, "Name == %s", (_name ? _name : "") );

  // Output the associated list of names
  const char *name;
  fprintf(fp, " (");
  for (reset(); (name = iter()) != NULL;) {
    fprintf(fp, "  %s,\n", name);
  }
  fprintf(fp, ")");
  fprintf(fp, "\n");
}

//------------------------------Form-------------------------------------------
OpClassForm   *Form::is_opclass()     const {
  return NULL;
}

OperandForm   *Form::is_operand()     const {
  return NULL;
}

InstructForm  *Form::is_instruction() const {
  return NULL;
}

MachNodeForm  *Form::is_machnode() const {
  return NULL;
}

AttributeForm *Form::is_attribute() const {
  return NULL;
}

Effect        *Form::is_effect() const {
  return NULL;
}

ResourceForm  *Form::is_resource() const {
  return NULL;
}

PipeClassForm *Form::is_pipeclass() const {
  return NULL;
}

Form::DataType Form::ideal_to_const_type(const char *name) const {
  if( name == NULL ) { return Form::none; }

  if (strcmp(name,"ConI")==0) return Form::idealI;
  if (strcmp(name,"ConP")==0) return Form::idealP;
  if (strcmp(name,"ConN")==0) return Form::idealN;
  if (strcmp(name,"ConNKlass")==0) return Form::idealNKlass;
  if (strcmp(name,"ConL")==0) return Form::idealL;
  if (strcmp(name,"ConF")==0) return Form::idealF;
  if (strcmp(name,"ConD")==0) return Form::idealD;
  if (strcmp(name,"Bool")==0) return Form::idealI;

  return Form::none;
}

Form::DataType Form::ideal_to_sReg_type(const char *name) const {
  if( name == NULL ) { return Form::none; }

  if (strcmp(name,"sRegI")==0) return Form::idealI;
  if (strcmp(name,"sRegP")==0) return Form::idealP;
  if (strcmp(name,"sRegF")==0) return Form::idealF;
  if (strcmp(name,"sRegD")==0) return Form::idealD;
  if (strcmp(name,"sRegL")==0) return Form::idealL;
  return Form::none;
}

Form::DataType Form::ideal_to_Reg_type(const char *name) const {
  if( name == NULL ) { return Form::none; }

  if (strcmp(name,"RegI")==0) return Form::idealI;
  if (strcmp(name,"RegP")==0) return Form::idealP;
  if (strcmp(name,"RegF")==0) return Form::idealF;
  if (strcmp(name,"RegD")==0) return Form::idealD;
  if (strcmp(name,"RegL")==0) return Form::idealL;

  return Form::none;
}

// True if 'opType', an ideal name, loads or stores.
Form::DataType Form::is_load_from_memory(const char *opType) const {
  if( strcmp(opType,"LoadB")==0 )  return Form::idealB;
  if( strcmp(opType,"LoadUB")==0 )  return Form::idealB;
  if( strcmp(opType,"LoadUS")==0 )  return Form::idealC;
  if( strcmp(opType,"LoadD")==0 )  return Form::idealD;
  if( strcmp(opType,"LoadD_unaligned")==0 )  return Form::idealD;
  if( strcmp(opType,"LoadF")==0 )  return Form::idealF;
  if( strcmp(opType,"LoadI")==0 )  return Form::idealI;
  if( strcmp(opType,"LoadKlass")==0 )  return Form::idealP;
  if( strcmp(opType,"LoadNKlass")==0 ) return Form::idealNKlass;
  if( strcmp(opType,"LoadL")==0 )  return Form::idealL;
  if( strcmp(opType,"LoadL_unaligned")==0 )  return Form::idealL;
  if( strcmp(opType,"LoadPLocked")==0 )  return Form::idealP;
  if( strcmp(opType,"LoadP")==0 )  return Form::idealP;
  if( strcmp(opType,"LoadN")==0 )  return Form::idealN;
  if( strcmp(opType,"LoadRange")==0 )  return Form::idealI;
  if( strcmp(opType,"LoadS")==0 )  return Form::idealS;
  if( strcmp(opType,"LoadVector")==0 )  return Form::idealV;
  assert( strcmp(opType,"Load") != 0, "Must type Loads" );
  return Form::none;
}

Form::DataType Form::is_store_to_memory(const char *opType) const {
  if( strcmp(opType,"StoreB")==0)  return Form::idealB;
  if( strcmp(opType,"StoreCM")==0) return Form::idealB;
  if( strcmp(opType,"StoreC")==0)  return Form::idealC;
  if( strcmp(opType,"StoreD")==0)  return Form::idealD;
  if( strcmp(opType,"StoreF")==0)  return Form::idealF;
  if( strcmp(opType,"StoreI")==0)  return Form::idealI;
  if( strcmp(opType,"StoreL")==0)  return Form::idealL;
  if( strcmp(opType,"StoreP")==0)  return Form::idealP;
  if( strcmp(opType,"StoreN")==0)  return Form::idealN;
  if( strcmp(opType,"StoreNKlass")==0)  return Form::idealNKlass;
  if( strcmp(opType,"StoreVector")==0 )  return Form::idealV;
  assert( strcmp(opType,"Store") != 0, "Must type Stores" );
  return Form::none;
}

Form::InterfaceType Form::interface_type(FormDict &globals) const {
  return Form::no_interface;
}

//------------------------------FormList---------------------------------------
// Destructor
FormList::~FormList()  {
  // // This list may not own its elements
  // Form *cur  = _root;
  // Form *next = NULL;
  // for( ; (cur = next) != NULL; ) {
  //   next = (Form *)cur->_next;
  //   delete cur;
  // }
};

//------------------------------FormDict---------------------------------------
// Constructor
FormDict::FormDict( CmpKey cmp, Hash hash, Arena *arena )
  : _form(cmp, hash, arena) {
}
FormDict::~FormDict() {
}

// Return # of name-Form pairs in dict
int FormDict::Size(void) const {
  return _form.Size();
}

// Insert inserts the given key-value pair into the dictionary.  The prior
// value of the key is returned; NULL if the key was not previously defined.
const Form  *FormDict::Insert(const char *name, Form *form) {
  return (Form*)_form.Insert((void*)name, (void*)form);
}

// Finds the value of a given key; or NULL if not found.
// The dictionary is NOT changed.
const Form  *FormDict::operator [](const char *name) const {
  return (Form*)_form[name];
}

//------------------------------FormDict::private------------------------------
// Disable public use of constructor, copy-ctor, operator =, operator ==
FormDict::FormDict( ) : _form(cmpkey,hashkey) {
  assert( false, "NotImplemented");
}
FormDict::FormDict( const FormDict & fd) : _form(fd._form) {
}
FormDict &FormDict::operator =( const FormDict &rhs) {
  assert( false, "NotImplemented");
  _form = rhs._form;
  return *this;
}
// == compares two dictionaries; they must have the same keys (their keys
// must match using CmpKey) and they must have the same values (pointer
// comparison).  If so 1 is returned, if not 0 is returned.
bool FormDict::operator ==(const FormDict &d) const {
  assert( false, "NotImplemented");
  return false;
}

// Print out the dictionary contents as key-value pairs
static void dumpkey (const void* key)  { fprintf(stdout, "%s", (char*) key); }
static void dumpform(const void* form) { fflush(stdout); ((Form*)form)->dump(); }

void FormDict::dump() {
  _form.print(dumpkey, dumpform);
}

//------------------------------SourceForm-------------------------------------
SourceForm::SourceForm(char* code) : _code(code) { }; // Constructor
SourceForm::~SourceForm() {
}

void SourceForm::dump() {                    // Debug printer
  output(stderr);
}

void SourceForm::output(FILE *fp) {
  fprintf(fp,"\n//%s\n%s\n",classname(),(_code?_code:""));
}
