1/*
2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25// FORMS.CPP - Definitions for ADL Parser Generic & Utility Forms Classes
26#include "adlc.hpp"
27
28//------------------------------Static Initializers----------------------------
29// allocate arena used by forms
30Arena  *Form::arena = Form::generate_arena(); //  = Form::generate_arena();
31Arena *Form::generate_arena() {
32  return (new Arena);
33}
34
35//------------------------------NameList---------------------------------------
36// reserved user-defined string
37const char  *NameList::_signal   = "$$SIGNAL$$";
38const char  *NameList::_signal2  = "$$SIGNAL2$$";
39const char  *NameList::_signal3  = "$$SIGNAL3$$";
40
41// Constructor and Destructor
42NameList::NameList() : _cur(0), _max(4), _iter(0), _justReset(true) {
43  _names = (const char**)malloc(_max*sizeof(char*));
44}
45NameList::~NameList() {
46  // The following free is a double-free, and crashes the program:
47  //free(_names);                   // not owner of strings
48}
49
50void   NameList::addName(const char *name) {
51  if (_cur == _max) _names =(const char**)realloc(_names,(_max *=2)*sizeof(char*));
52  _names[_cur++] = name;
53}
54
55void   NameList::add_signal() {
56  addName( _signal );
57}
58void   NameList::clear() {
59  _cur   = 0;
60  _iter  = 0;
61  _justReset = true;
62  // _max   = 4; Already allocated
63}
64
65int    NameList::count()  const { return _cur; }
66
67void   NameList::reset()   { _iter = 0; _justReset = true;}
68const char  *NameList::iter()    {
69  if (_justReset) {_justReset=false; return (_iter < _cur ? _names[_iter] : NULL);}
70  else return (_iter <_cur-1 ? _names[++_iter] : NULL);
71}
72const char  *NameList::current() { return (_iter < _cur ? _names[_iter] : NULL); }
73const char  *NameList::peek(int skip) { return (_iter + skip < _cur ? _names[_iter + skip] : NULL); }
74
75// Return 'true' if current entry is signal
76bool  NameList::current_is_signal() {
77  const char *entry = current();
78  return is_signal(entry);
79}
80
81// Return true if entry is a signal
82bool  NameList::is_signal(const char *entry) {
83  return ( (strcmp(entry,NameList::_signal) == 0) ? true : false);
84}
85
86// Search for a name in the list
87bool   NameList::search(const char *name) {
88  const char *entry;
89  for(reset(); (entry = iter()) != NULL; ) {
90    if(!strcmp(entry,name)) return true;
91  }
92  return false;
93}
94
95// Return index of name in list
96int    NameList::index(const char *name) {
97  int         cnt = 0;
98  const char *entry;
99  for(reset(); (entry = iter()) != NULL; ) {
100    if(!strcmp(entry,name)) return cnt;
101    cnt++;
102  }
103  return Not_in_list;
104}
105
106// Return name at index in list
107const char  *NameList::name(intptr_t  index) {
108  return ( index < _cur ? _names[index] : NULL);
109}
110
111void   NameList::dump() { output(stderr); }
112
113void   NameList::output(FILE *fp) {
114  fprintf(fp, "\n");
115
116  // Run iteration over all entries, independent of position of iterator.
117  const char *name       = NULL;
118  int         iter       = 0;
119  bool        justReset  = true;
120
121  while( ( name  = (justReset ?
122                    (justReset=false, (iter < _cur ? _names[iter] : NULL)) :
123                    (iter < _cur-1 ? _names[++iter] : NULL)) )
124         != NULL ) {
125    fprintf( fp, "  %s,\n", name);
126  }
127  fprintf(fp, "\n");
128}
129
130//------------------------------NameAndList------------------------------------
131// Storage for a name and an associated list of names
132NameAndList::NameAndList(char *name) : _name(name) {
133}
134NameAndList::~NameAndList() {
135}
136
137// Add to entries in list
138void NameAndList::add_entry(const char *entry) {
139  _list.addName(entry);
140}
141
142// Access the name and its associated list.
143const char *NameAndList::name()  const {  return _name;  }
144void        NameAndList::reset()       { _list.reset();  }
145const char *NameAndList::iter()        { return _list.iter(); }
146
147// Return the "index" entry in the list, zero-based
148const char *NameAndList::operator[](int index) {
149  assert( index >= 0, "Internal Error(): index less than 0.");
150
151  _list.reset();
152  const char *entry = _list.iter();
153  // Iterate further if it isn't at index 0.
154  for ( int position = 0; position != index; ++position ) {
155    entry = _list.iter();
156  }
157
158  return entry;
159}
160
161
162void   NameAndList::dump() { output(stderr); }
163void   NameAndList::output(FILE *fp) {
164  fprintf(fp, "\n");
165
166  // Output the Name
167  fprintf(fp, "Name == %s", (_name ? _name : "") );
168
169  // Output the associated list of names
170  const char *name;
171  fprintf(fp, " (");
172  for (reset(); (name = iter()) != NULL;) {
173    fprintf(fp, "  %s,\n", name);
174  }
175  fprintf(fp, ")");
176  fprintf(fp, "\n");
177}
178
179//------------------------------Form-------------------------------------------
180OpClassForm   *Form::is_opclass()     const {
181  return NULL;
182}
183
184OperandForm   *Form::is_operand()     const {
185  return NULL;
186}
187
188InstructForm  *Form::is_instruction() const {
189  return NULL;
190}
191
192MachNodeForm  *Form::is_machnode() const {
193  return NULL;
194}
195
196AttributeForm *Form::is_attribute() const {
197  return NULL;
198}
199
200Effect        *Form::is_effect() const {
201  return NULL;
202}
203
204ResourceForm  *Form::is_resource() const {
205  return NULL;
206}
207
208PipeClassForm *Form::is_pipeclass() const {
209  return NULL;
210}
211
212Form::DataType Form::ideal_to_const_type(const char *name) const {
213  if( name == NULL ) { return Form::none; }
214
215  if (strcmp(name,"ConI")==0) return Form::idealI;
216  if (strcmp(name,"ConP")==0) return Form::idealP;
217  if (strcmp(name,"ConN")==0) return Form::idealN;
218  if (strcmp(name,"ConNKlass")==0) return Form::idealNKlass;
219  if (strcmp(name,"ConL")==0) return Form::idealL;
220  if (strcmp(name,"ConF")==0) return Form::idealF;
221  if (strcmp(name,"ConD")==0) return Form::idealD;
222  if (strcmp(name,"Bool")==0) return Form::idealI;
223
224  return Form::none;
225}
226
227Form::DataType Form::ideal_to_sReg_type(const char *name) const {
228  if( name == NULL ) { return Form::none; }
229
230  if (strcmp(name,"sRegI")==0) return Form::idealI;
231  if (strcmp(name,"sRegP")==0) return Form::idealP;
232  if (strcmp(name,"sRegF")==0) return Form::idealF;
233  if (strcmp(name,"sRegD")==0) return Form::idealD;
234  if (strcmp(name,"sRegL")==0) return Form::idealL;
235  return Form::none;
236}
237
238Form::DataType Form::ideal_to_Reg_type(const char *name) const {
239  if( name == NULL ) { return Form::none; }
240
241  if (strcmp(name,"RegI")==0) return Form::idealI;
242  if (strcmp(name,"RegP")==0) return Form::idealP;
243  if (strcmp(name,"RegF")==0) return Form::idealF;
244  if (strcmp(name,"RegD")==0) return Form::idealD;
245  if (strcmp(name,"RegL")==0) return Form::idealL;
246
247  return Form::none;
248}
249
250// True if 'opType', an ideal name, loads or stores.
251Form::DataType Form::is_load_from_memory(const char *opType) const {
252  if( strcmp(opType,"LoadB")==0 )  return Form::idealB;
253  if( strcmp(opType,"LoadUB")==0 )  return Form::idealB;
254  if( strcmp(opType,"LoadUS")==0 )  return Form::idealC;
255  if( strcmp(opType,"LoadD")==0 )  return Form::idealD;
256  if( strcmp(opType,"LoadD_unaligned")==0 )  return Form::idealD;
257  if( strcmp(opType,"LoadF")==0 )  return Form::idealF;
258  if( strcmp(opType,"LoadI")==0 )  return Form::idealI;
259  if( strcmp(opType,"LoadKlass")==0 )  return Form::idealP;
260  if( strcmp(opType,"LoadNKlass")==0 ) return Form::idealNKlass;
261  if( strcmp(opType,"LoadL")==0 )  return Form::idealL;
262  if( strcmp(opType,"LoadL_unaligned")==0 )  return Form::idealL;
263  if( strcmp(opType,"LoadPLocked")==0 )  return Form::idealP;
264  if( strcmp(opType,"LoadP")==0 )  return Form::idealP;
265  if( strcmp(opType,"LoadN")==0 )  return Form::idealN;
266  if( strcmp(opType,"LoadRange")==0 )  return Form::idealI;
267  if( strcmp(opType,"LoadS")==0 )  return Form::idealS;
268  if( strcmp(opType,"LoadVector")==0 )  return Form::idealV;
269  assert( strcmp(opType,"Load") != 0, "Must type Loads" );
270  return Form::none;
271}
272
273Form::DataType Form::is_store_to_memory(const char *opType) const {
274  if( strcmp(opType,"StoreB")==0)  return Form::idealB;
275  if( strcmp(opType,"StoreCM")==0) return Form::idealB;
276  if( strcmp(opType,"StoreC")==0)  return Form::idealC;
277  if( strcmp(opType,"StoreD")==0)  return Form::idealD;
278  if( strcmp(opType,"StoreF")==0)  return Form::idealF;
279  if( strcmp(opType,"StoreI")==0)  return Form::idealI;
280  if( strcmp(opType,"StoreL")==0)  return Form::idealL;
281  if( strcmp(opType,"StoreP")==0)  return Form::idealP;
282  if( strcmp(opType,"StoreN")==0)  return Form::idealN;
283  if( strcmp(opType,"StoreNKlass")==0)  return Form::idealNKlass;
284  if( strcmp(opType,"StoreVector")==0 )  return Form::idealV;
285  assert( strcmp(opType,"Store") != 0, "Must type Stores" );
286  return Form::none;
287}
288
289Form::InterfaceType Form::interface_type(FormDict &globals) const {
290  return Form::no_interface;
291}
292
293//------------------------------FormList---------------------------------------
294// Destructor
295FormList::~FormList()  {
296  // // This list may not own its elements
297  // Form *cur  = _root;
298  // Form *next = NULL;
299  // for( ; (cur = next) != NULL; ) {
300  //   next = (Form *)cur->_next;
301  //   delete cur;
302  // }
303};
304
305//------------------------------FormDict---------------------------------------
306// Constructor
307FormDict::FormDict( CmpKey cmp, Hash hash, Arena *arena )
308  : _form(cmp, hash, arena) {
309}
310FormDict::~FormDict() {
311}
312
313// Return # of name-Form pairs in dict
314int FormDict::Size(void) const {
315  return _form.Size();
316}
317
318// Insert inserts the given key-value pair into the dictionary.  The prior
319// value of the key is returned; NULL if the key was not previously defined.
320const Form  *FormDict::Insert(const char *name, Form *form) {
321  return (Form*)_form.Insert((void*)name, (void*)form);
322}
323
324// Finds the value of a given key; or NULL if not found.
325// The dictionary is NOT changed.
326const Form  *FormDict::operator [](const char *name) const {
327  return (Form*)_form[name];
328}
329
330//------------------------------FormDict::private------------------------------
331// Disable public use of constructor, copy-ctor, operator =, operator ==
332FormDict::FormDict( ) : _form(cmpkey,hashkey) {
333  assert( false, "NotImplemented");
334}
335FormDict::FormDict( const FormDict & fd) : _form(fd._form) {
336}
337FormDict &FormDict::operator =( const FormDict &rhs) {
338  assert( false, "NotImplemented");
339  _form = rhs._form;
340  return *this;
341}
342// == compares two dictionaries; they must have the same keys (their keys
343// must match using CmpKey) and they must have the same values (pointer
344// comparison).  If so 1 is returned, if not 0 is returned.
345bool FormDict::operator ==(const FormDict &d) const {
346  assert( false, "NotImplemented");
347  return false;
348}
349
350// Print out the dictionary contents as key-value pairs
351static void dumpkey (const void* key)  { fprintf(stdout, "%s", (char*) key); }
352static void dumpform(const void* form) { fflush(stdout); ((Form*)form)->dump(); }
353
354void FormDict::dump() {
355  _form.print(dumpkey, dumpform);
356}
357
358//------------------------------SourceForm-------------------------------------
359SourceForm::SourceForm(char* code) : _code(code) { }; // Constructor
360SourceForm::~SourceForm() {
361}
362
363void SourceForm::dump() {                    // Debug printer
364  output(stderr);
365}
366
367void SourceForm::output(FILE *fp) {
368  fprintf(fp,"\n//%s\n%s\n",classname(),(_code?_code:""));
369}
370