hotspot/src/share/vm/adlc/archDesc.cpp
author xdono
Mon, 09 Mar 2009 13:28:46 -0700
changeset 2105 347008ce7984
parent 1662 76a93a5fb765
child 2154 72a9b7284ccf
permissions -rw-r--r--
6814575: Update copyright year Summary: Update copyright for files that have been modified in 2009, up to 03/09 Reviewed-by: katleman, tbell, ohair
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
//
2105
347008ce7984 6814575: Update copyright year
xdono
parents: 1662
diff changeset
     2
// Copyright 1997-2009 Sun Microsystems, Inc.  All Rights Reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
// This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
// under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
// published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
// This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
// version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
// accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
// You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
// 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    19
// Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    20
// CA 95054 USA or visit www.sun.com if you need additional information or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    21
// have any questions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
//
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
// archDesc.cpp - Internal format for architecture definition
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
#include "adlc.hpp"
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
static FILE *errfile = stderr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
//--------------------------- utility functions -----------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
inline char  toUpper(char lower) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
  return (('a' <= lower && lower <= 'z') ? (lower + ('A'-'a')) : lower);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
char *toUpper(const char *str) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
  char *upper  = new char[strlen(str)+1];
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
  char *result = upper;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
  const char *end    = str + strlen(str);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
  for (; str < end; ++str, ++upper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
    *upper = toUpper(*str);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
  *upper = '\0';
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
// Utilities to characterize effect statements
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
static bool is_def(int usedef) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
  switch(usedef) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
  case Component::DEF:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
  case Component::USE_DEF: return true; break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
static bool is_use(int usedef) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
  switch(usedef) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
  case Component::USE:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
  case Component::USE_DEF:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
  case Component::USE_KILL: return true; break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
static bool is_kill(int usedef) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
  switch(usedef) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
  case Component::KILL:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
  case Component::USE_KILL: return true; break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
  return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
//---------------------------ChainList Methods-------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
ChainList::ChainList() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
void ChainList::insert(const char *name, const char *cost, const char *rule) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
  _name.addName(name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
  _cost.addName(cost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
  _rule.addName(rule);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
bool ChainList::search(const char *name) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
  return _name.search(name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
void ChainList::reset() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
  _name.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
  _cost.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
  _rule.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
bool ChainList::iter(const char * &name, const char * &cost, const char * &rule) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
  bool        notDone = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
  const char *n       = _name.iter();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
  const char *c       = _cost.iter();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
  const char *r       = _rule.iter();
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
  if (n && c && r) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
    notDone = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
    name = n;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
    cost = c;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
    rule = r;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
  return notDone;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
void ChainList::dump() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
  output(stderr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
void ChainList::output(FILE *fp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
  fprintf(fp, "\nChain Rules: output resets iterator\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
  const char   *cost  = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
  const char   *name  = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
  const char   *rule  = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
  bool   chains_exist = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  for(reset(); (iter(name,cost,rule)) == true; ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
    fprintf(fp, "Chain to <%s> at cost #%s using %s_rule\n",name, cost ? cost : "0", rule);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
    //  // Check for transitive chain rules
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
    //  Form *form = (Form *)_globalNames[rule];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
    //  if (form->is_instruction()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
    //    // chain_rule(fp, indent, name, cost, rule);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
    //    chain_rule(fp, indent, name, cost, rule);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
    //  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
  if( ! chains_exist ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
    fprintf(fp, "No entries in this ChainList\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
//---------------------------MatchList Methods-------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
bool MatchList::search(const char *opc, const char *res, const char *lch,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
                       const char *rch, Predicate *pr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  bool tmp = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
  if ((res == _resultStr) || (res && _resultStr && !strcmp(res, _resultStr))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
    if ((lch == _lchild) || (lch && _lchild && !strcmp(lch, _lchild))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
      if ((rch == _rchild) || (rch && _rchild && !strcmp(rch, _rchild))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
        char * predStr = get_pred();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
        char * prStr = pr?pr->_pred:NULL;
1662
76a93a5fb765 6771309: debugging AD files is difficult without #line directives in generated code
jrose
parents: 1552
diff changeset
   143
        if (ADLParser::equivalent_expressions(prStr, predStr)) {
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
          return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
  if (_next) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
    tmp = _next->search(opc, res, lch, rch, pr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
  return tmp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
void MatchList::dump() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
  output(stderr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
void MatchList::output(FILE *fp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
  fprintf(fp, "\nMatchList output is Unimplemented();\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
//---------------------------ArchDesc Constructor and Destructor-------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
ArchDesc::ArchDesc()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
  : _globalNames(cmpstr,hashstr, Form::arena),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
    _globalDefs(cmpstr,hashstr, Form::arena),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
    _preproc_table(cmpstr,hashstr, Form::arena),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
    _idealIndex(cmpstr,hashstr, Form::arena),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
    _internalOps(cmpstr,hashstr, Form::arena),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
    _internalMatch(cmpstr,hashstr, Form::arena),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
    _chainRules(cmpstr,hashstr, Form::arena),
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
    _cisc_spill_operand(NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
      // Initialize the opcode to MatchList table with NULLs
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
      for( int i=0; i<_last_opcode; ++i ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
        _mlistab[i] = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
      // Set-up the global tables
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
      initKeywords(_globalNames);    // Initialize the Name Table with keywords
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
      // Prime user-defined types with predefined types: Set, RegI, RegF, ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
      initBaseOpTypes();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
      // Initialize flags & counters
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
      _TotalLines        = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
      _no_output         = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
      _quiet_mode        = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
      _disable_warnings  = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
      _dfa_debug         = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
      _dfa_small         = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
      _adl_debug         = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
      _adlocation_debug  = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
      _internalOpCounter = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
      _cisc_spill_debug  = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
      _short_branch_debug = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
      // Initialize match rule flags
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
      for (int i = 0; i < _last_opcode; i++) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
        _has_match_rule[i] = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
      // Error/Warning Counts
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
      _syntax_errs       = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
      _semantic_errs     = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
      _warnings          = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
      _internal_errs     = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
      // Initialize I/O Files
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
      _ADL_file._name = NULL; _ADL_file._fp = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
      // Machine dependent output files
1552
45c617d33fa6 6767659: Conversion from i486 to x86 missed some entries in makefiles
kvn
parents: 670
diff changeset
   215
      _DFA_file._name    = NULL;  _DFA_file._fp = NULL;
45c617d33fa6 6767659: Conversion from i486 to x86 missed some entries in makefiles
kvn
parents: 670
diff changeset
   216
      _HPP_file._name    = NULL;  _HPP_file._fp = NULL;
45c617d33fa6 6767659: Conversion from i486 to x86 missed some entries in makefiles
kvn
parents: 670
diff changeset
   217
      _CPP_file._name    = NULL;  _CPP_file._fp = NULL;
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
      _bug_file._name    = "bugs.out";      _bug_file._fp = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
      // Initialize Register & Pipeline Form Pointers
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
      _register = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
      _encode = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
      _pipeline = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
ArchDesc::~ArchDesc() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
  // Clean-up and quit
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
//---------------------------ArchDesc methods: Public ----------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
// Store forms according to type
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
void ArchDesc::addForm(PreHeaderForm *ptr) { _pre_header.addForm(ptr); };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
void ArchDesc::addForm(HeaderForm    *ptr) { _header.addForm(ptr); };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
void ArchDesc::addForm(SourceForm    *ptr) { _source.addForm(ptr); };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
void ArchDesc::addForm(EncodeForm    *ptr) { _encode = ptr; };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
void ArchDesc::addForm(InstructForm  *ptr) { _instructions.addForm(ptr); };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
void ArchDesc::addForm(MachNodeForm  *ptr) { _machnodes.addForm(ptr); };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
void ArchDesc::addForm(OperandForm   *ptr) { _operands.addForm(ptr); };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
void ArchDesc::addForm(OpClassForm   *ptr) { _opclass.addForm(ptr); };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
void ArchDesc::addForm(AttributeForm *ptr) { _attributes.addForm(ptr); };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
void ArchDesc::addForm(RegisterForm  *ptr) { _register = ptr; };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
void ArchDesc::addForm(FrameForm     *ptr) { _frame = ptr; };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
void ArchDesc::addForm(PipelineForm  *ptr) { _pipeline = ptr; };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
// Build MatchList array and construct MatchLists
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
void ArchDesc::generateMatchLists() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
  // Call inspection routines to populate array
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
  inspectOperands();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
  inspectInstructions();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
// Build MatchList structures for operands
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
void ArchDesc::inspectOperands() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
  // Iterate through all operands
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
  _operands.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
  OperandForm *op;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
  for( ; (op = (OperandForm*)_operands.iter()) != NULL;) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
    // Construct list of top-level operands (components)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
    op->build_components();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
    // Ensure that match field is defined.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
    if ( op->_matrule == NULL )  continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
    // Type check match rules
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
    check_optype(op->_matrule);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
    // Construct chain rules
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
    build_chain_rule(op);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
    MatchRule &mrule = *op->_matrule;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
    Predicate *pred  =  op->_predicate;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
    // Grab the machine type of the operand
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
    const char  *rootOp    = op->_ident;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
    mrule._machType  = rootOp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
    // Check for special cases
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
    if (strcmp(rootOp,"Universe")==0) continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
    if (strcmp(rootOp,"label")==0) continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
    // !!!!! !!!!!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
    assert( strcmp(rootOp,"sReg") != 0, "Disable untyped 'sReg'");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
    if (strcmp(rootOp,"sRegI")==0) continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
    if (strcmp(rootOp,"sRegP")==0) continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
    if (strcmp(rootOp,"sRegF")==0) continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
    if (strcmp(rootOp,"sRegD")==0) continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
    if (strcmp(rootOp,"sRegL")==0) continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
    // Cost for this match
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
    const char *costStr     = op->cost();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
    const char *defaultCost =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
      ((AttributeForm*)_globalNames[AttributeForm::_op_cost])->_attrdef;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
    const char *cost        =  costStr? costStr : defaultCost;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
    // Find result type for match.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
    const char *result      = op->reduce_result();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
    bool        has_root    = false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
    // Construct a MatchList for this entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
    buildMatchList(op->_matrule, result, rootOp, pred, cost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
// Build MatchList structures for instructions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   306
void ArchDesc::inspectInstructions() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   307
489c9b5090e2 Initial load
duke
parents:
diff changeset
   308
  // Iterate through all instructions
489c9b5090e2 Initial load
duke
parents:
diff changeset
   309
  _instructions.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   310
  InstructForm *instr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   311
  for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   312
    // Construct list of top-level operands (components)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   313
    instr->build_components();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   314
489c9b5090e2 Initial load
duke
parents:
diff changeset
   315
    // Ensure that match field is defined.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   316
    if ( instr->_matrule == NULL )  continue;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   317
489c9b5090e2 Initial load
duke
parents:
diff changeset
   318
    MatchRule &mrule = *instr->_matrule;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   319
    Predicate *pred  =  instr->build_predicate();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   320
489c9b5090e2 Initial load
duke
parents:
diff changeset
   321
    // Grab the machine type of the operand
489c9b5090e2 Initial load
duke
parents:
diff changeset
   322
    const char  *rootOp    = instr->_ident;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   323
    mrule._machType  = rootOp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   324
489c9b5090e2 Initial load
duke
parents:
diff changeset
   325
    // Cost for this match
489c9b5090e2 Initial load
duke
parents:
diff changeset
   326
    const char *costStr = instr->cost();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   327
    const char *defaultCost =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   328
      ((AttributeForm*)_globalNames[AttributeForm::_ins_cost])->_attrdef;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   329
    const char *cost    =  costStr? costStr : defaultCost;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   330
489c9b5090e2 Initial load
duke
parents:
diff changeset
   331
    // Find result type for match
489c9b5090e2 Initial load
duke
parents:
diff changeset
   332
    const char *result  = instr->reduce_result();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   333
489c9b5090e2 Initial load
duke
parents:
diff changeset
   334
    Attribute *attr = instr->_attribs;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   335
    while (attr != NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   336
      if (strcmp(attr->_ident,"ins_short_branch") == 0 &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   337
          attr->int_val(*this) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   338
        instr->set_short_branch(true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   339
      } else if (strcmp(attr->_ident,"ins_alignment") == 0 &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   340
          attr->int_val(*this) != 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   341
        instr->set_alignment(attr->int_val(*this));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   342
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   343
      attr = (Attribute *)attr->_next;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   344
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   345
489c9b5090e2 Initial load
duke
parents:
diff changeset
   346
    if (!instr->is_short_branch()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   347
      buildMatchList(instr->_matrule, result, mrule._machType, pred, cost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   348
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   349
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   350
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   351
489c9b5090e2 Initial load
duke
parents:
diff changeset
   352
static int setsResult(MatchRule &mrule) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   353
  if (strcmp(mrule._name,"Set") == 0) return 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   354
  return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   355
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   356
489c9b5090e2 Initial load
duke
parents:
diff changeset
   357
const char *ArchDesc::getMatchListIndex(MatchRule &mrule) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   358
  if (setsResult(mrule)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   359
    // right child
489c9b5090e2 Initial load
duke
parents:
diff changeset
   360
    return mrule._rChild->_opType;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   361
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   362
    // first entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   363
    return mrule._opType;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   364
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   365
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   366
489c9b5090e2 Initial load
duke
parents:
diff changeset
   367
489c9b5090e2 Initial load
duke
parents:
diff changeset
   368
//------------------------------result of reduction----------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   369
489c9b5090e2 Initial load
duke
parents:
diff changeset
   370
489c9b5090e2 Initial load
duke
parents:
diff changeset
   371
//------------------------------left reduction---------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   372
// Return the left reduction associated with an internal name
489c9b5090e2 Initial load
duke
parents:
diff changeset
   373
const char *ArchDesc::reduceLeft(char         *internalName) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   374
  const char *left  = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   375
  MatchNode *mnode = (MatchNode*)_internalMatch[internalName];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   376
  if (mnode->_lChild) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   377
    mnode = mnode->_lChild;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   378
    left = mnode->_internalop ? mnode->_internalop : mnode->_opType;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   379
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   380
  return left;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   381
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   382
489c9b5090e2 Initial load
duke
parents:
diff changeset
   383
489c9b5090e2 Initial load
duke
parents:
diff changeset
   384
//------------------------------right reduction--------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   385
const char *ArchDesc::reduceRight(char  *internalName) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   386
  const char *right  = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   387
  MatchNode *mnode = (MatchNode*)_internalMatch[internalName];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   388
  if (mnode->_rChild) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   389
    mnode = mnode->_rChild;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   390
    right = mnode->_internalop ? mnode->_internalop : mnode->_opType;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   391
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   392
  return right;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   393
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   394
489c9b5090e2 Initial load
duke
parents:
diff changeset
   395
489c9b5090e2 Initial load
duke
parents:
diff changeset
   396
//------------------------------check_optype-----------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   397
void ArchDesc::check_optype(MatchRule *mrule) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   398
  MatchRule *rule = mrule;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   399
489c9b5090e2 Initial load
duke
parents:
diff changeset
   400
  //   !!!!!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   401
  //   // Cycle through the list of match rules
489c9b5090e2 Initial load
duke
parents:
diff changeset
   402
  //   while(mrule) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   403
  //     // Check for a filled in type field
489c9b5090e2 Initial load
duke
parents:
diff changeset
   404
  //     if (mrule->_opType == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   405
  //     const Form  *form    = operands[_result];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   406
  //     OpClassForm *opcForm = form ? form->is_opclass() : NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   407
  //     assert(opcForm != NULL, "Match Rule contains invalid operand name.");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   408
  //     }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   409
  //     char *opType = opcForm->_ident;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   410
  //   }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   411
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   412
489c9b5090e2 Initial load
duke
parents:
diff changeset
   413
//------------------------------add_chain_rule_entry--------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   414
void ArchDesc::add_chain_rule_entry(const char *src, const char *cost,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   415
                                    const char *result) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   416
  // Look-up the operation in chain rule table
489c9b5090e2 Initial load
duke
parents:
diff changeset
   417
  ChainList *lst = (ChainList *)_chainRules[src];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   418
  if (lst == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   419
    lst = new ChainList();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   420
    _chainRules.Insert(src, lst);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   421
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   422
  if (!lst->search(result)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   423
    if (cost == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   424
      cost = ((AttributeForm*)_globalNames[AttributeForm::_op_cost])->_attrdef;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   425
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   426
    lst->insert(result, cost, result);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   427
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   428
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   429
489c9b5090e2 Initial load
duke
parents:
diff changeset
   430
//------------------------------build_chain_rule-------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   431
void ArchDesc::build_chain_rule(OperandForm *oper) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   432
  MatchRule     *rule;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   433
489c9b5090e2 Initial load
duke
parents:
diff changeset
   434
  // Check for chain rules here
489c9b5090e2 Initial load
duke
parents:
diff changeset
   435
  // If this is only a chain rule
489c9b5090e2 Initial load
duke
parents:
diff changeset
   436
  if ((oper->_matrule) && (oper->_matrule->_lChild == NULL) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   437
      (oper->_matrule->_rChild == NULL)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   438
489c9b5090e2 Initial load
duke
parents:
diff changeset
   439
    const Form *form = _globalNames[oper->_matrule->_opType];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   440
    if ((form) && form->is_operand() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   441
        (form->ideal_only() == false)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   442
      add_chain_rule_entry(oper->_matrule->_opType, oper->cost(), oper->_ident);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   443
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   444
    // Check for additional chain rules
489c9b5090e2 Initial load
duke
parents:
diff changeset
   445
    if (oper->_matrule->_next) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   446
      rule = oper->_matrule;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   447
      do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   448
        rule = rule->_next;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   449
        // Any extra match rules after the first must be chain rules
489c9b5090e2 Initial load
duke
parents:
diff changeset
   450
        const Form *form = _globalNames[rule->_opType];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   451
        if ((form) && form->is_operand() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   452
            (form->ideal_only() == false)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   453
          add_chain_rule_entry(rule->_opType, oper->cost(), oper->_ident);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   454
        }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   455
      } while(rule->_next != NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   456
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   457
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   458
  else if ((oper->_matrule) && (oper->_matrule->_next)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   459
    // Regardles of whether the first matchrule is a chain rule, check the list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   460
    rule = oper->_matrule;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   461
    do {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   462
      rule = rule->_next;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   463
      // Any extra match rules after the first must be chain rules
489c9b5090e2 Initial load
duke
parents:
diff changeset
   464
      const Form *form = _globalNames[rule->_opType];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   465
      if ((form) && form->is_operand() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   466
          (form->ideal_only() == false)) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   467
        assert( oper->cost(), "This case expects NULL cost, not default cost");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   468
        add_chain_rule_entry(rule->_opType, oper->cost(), oper->_ident);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   469
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   470
    } while(rule->_next != NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   471
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   472
489c9b5090e2 Initial load
duke
parents:
diff changeset
   473
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   474
489c9b5090e2 Initial load
duke
parents:
diff changeset
   475
//------------------------------buildMatchList---------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   476
// operands and instructions provide the result
489c9b5090e2 Initial load
duke
parents:
diff changeset
   477
void ArchDesc::buildMatchList(MatchRule *mrule, const char *resultStr,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   478
                              const char *rootOp, Predicate *pred,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   479
                              const char *cost) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   480
  const char *leftstr, *rightstr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   481
  MatchNode  *mnode;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   482
489c9b5090e2 Initial load
duke
parents:
diff changeset
   483
  leftstr = rightstr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   484
  // Check for chain rule, and do not generate a match list for it
489c9b5090e2 Initial load
duke
parents:
diff changeset
   485
  if ( mrule->is_chain_rule(_globalNames) ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   486
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   487
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   488
489c9b5090e2 Initial load
duke
parents:
diff changeset
   489
  // Identify index position among ideal operands
489c9b5090e2 Initial load
duke
parents:
diff changeset
   490
  intptr_t    index     = _last_opcode;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   491
  const char  *indexStr  = getMatchListIndex(*mrule);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   492
  index  = (intptr_t)_idealIndex[indexStr];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   493
  if (index == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   494
    fprintf(stderr, "Ideal node missing: %s\n", indexStr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   495
    assert(index != 0, "Failed lookup of ideal node\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   496
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   497
489c9b5090e2 Initial load
duke
parents:
diff changeset
   498
  // Check that this will be placed appropriately in the DFA
489c9b5090e2 Initial load
duke
parents:
diff changeset
   499
  if (index >= _last_opcode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   500
    fprintf(stderr, "Invalid match rule %s <-- ( %s )\n",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   501
            resultStr ? resultStr : " ",
489c9b5090e2 Initial load
duke
parents:
diff changeset
   502
            rootOp    ? rootOp    : " ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   503
    assert(index < _last_opcode, "Matching item not in ideal graph\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   504
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   505
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   506
489c9b5090e2 Initial load
duke
parents:
diff changeset
   507
489c9b5090e2 Initial load
duke
parents:
diff changeset
   508
  // Walk the MatchRule, generating MatchList entries for each level
489c9b5090e2 Initial load
duke
parents:
diff changeset
   509
  // of the rule (each nesting of parentheses)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   510
  // Check for "Set"
489c9b5090e2 Initial load
duke
parents:
diff changeset
   511
  if (!strcmp(mrule->_opType, "Set")) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   512
    mnode = mrule->_rChild;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   513
    buildMList(mnode, rootOp, resultStr, pred, cost);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   514
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   515
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   516
  // Build MatchLists for children
489c9b5090e2 Initial load
duke
parents:
diff changeset
   517
  // Check each child for an internal operand name, and use that name
489c9b5090e2 Initial load
duke
parents:
diff changeset
   518
  // for the parent's matchlist entry if it exists
489c9b5090e2 Initial load
duke
parents:
diff changeset
   519
  mnode = mrule->_lChild;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   520
  if (mnode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   521
    buildMList(mnode, NULL, NULL, NULL, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   522
    leftstr = mnode->_internalop ? mnode->_internalop : mnode->_opType;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   523
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   524
  mnode = mrule->_rChild;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   525
  if (mnode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   526
    buildMList(mnode, NULL, NULL, NULL, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   527
    rightstr = mnode->_internalop ? mnode->_internalop : mnode->_opType;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   528
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   529
  // Search for an identical matchlist entry already on the list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   530
  if ((_mlistab[index] == NULL) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   531
      (_mlistab[index] &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   532
       !_mlistab[index]->search(rootOp, resultStr, leftstr, rightstr, pred))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   533
    // Place this match rule at front of list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   534
    MatchList *mList =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   535
      new MatchList(_mlistab[index], pred, cost,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   536
                    rootOp, resultStr, leftstr, rightstr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   537
    _mlistab[index] = mList;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   538
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   539
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   540
489c9b5090e2 Initial load
duke
parents:
diff changeset
   541
// Recursive call for construction of match lists
489c9b5090e2 Initial load
duke
parents:
diff changeset
   542
void ArchDesc::buildMList(MatchNode *node, const char *rootOp,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   543
                          const char *resultOp, Predicate *pred,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   544
                          const char *cost) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   545
  const char *leftstr, *rightstr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   546
  const char *resultop;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   547
  const char *opcode;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   548
  MatchNode  *mnode;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   549
  Form       *form;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   550
489c9b5090e2 Initial load
duke
parents:
diff changeset
   551
  leftstr = rightstr = NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   552
  // Do not process leaves of the Match Tree if they are not ideal
489c9b5090e2 Initial load
duke
parents:
diff changeset
   553
  if ((node) && (node->_lChild == NULL) && (node->_rChild == NULL) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   554
      ((form = (Form *)_globalNames[node->_opType]) != NULL) &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   555
      (!form->ideal_only())) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   556
    return;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   557
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   558
489c9b5090e2 Initial load
duke
parents:
diff changeset
   559
  // Identify index position among ideal operands
489c9b5090e2 Initial load
duke
parents:
diff changeset
   560
  intptr_t    index     = _last_opcode;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   561
  const char *indexStr  = node ? node->_opType : (char *) " ";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   562
  index            = (intptr_t)_idealIndex[indexStr];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   563
  if (index == 0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   564
    fprintf(stderr, "error: operand \"%s\" not found\n", indexStr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   565
    assert(0, "fatal error");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   566
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   567
489c9b5090e2 Initial load
duke
parents:
diff changeset
   568
  // Build MatchLists for children
489c9b5090e2 Initial load
duke
parents:
diff changeset
   569
  // Check each child for an internal operand name, and use that name
489c9b5090e2 Initial load
duke
parents:
diff changeset
   570
  // for the parent's matchlist entry if it exists
489c9b5090e2 Initial load
duke
parents:
diff changeset
   571
  mnode = node->_lChild;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   572
  if (mnode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   573
    buildMList(mnode, NULL, NULL, NULL, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   574
    leftstr = mnode->_internalop ? mnode->_internalop : mnode->_opType;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   575
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   576
  mnode = node->_rChild;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   577
  if (mnode) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   578
    buildMList(mnode, NULL, NULL, NULL, NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   579
    rightstr = mnode->_internalop ? mnode->_internalop : mnode->_opType;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   580
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   581
  // Grab the string for the opcode of this list entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   582
  if (rootOp == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   583
    opcode = (node->_internalop) ? node->_internalop : node->_opType;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   584
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   585
    opcode = rootOp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   586
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   587
  // Grab the string for the result of this list entry
489c9b5090e2 Initial load
duke
parents:
diff changeset
   588
  if (resultOp == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   589
    resultop = (node->_internalop) ? node->_internalop : node->_opType;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   590
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   591
  else resultop = resultOp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   592
  // Search for an identical matchlist entry already on the list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   593
  if ((_mlistab[index] == NULL) || (_mlistab[index] &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   594
                                    !_mlistab[index]->search(opcode, resultop, leftstr, rightstr, pred))) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   595
    // Place this match rule at front of list
489c9b5090e2 Initial load
duke
parents:
diff changeset
   596
    MatchList *mList =
489c9b5090e2 Initial load
duke
parents:
diff changeset
   597
      new MatchList(_mlistab[index],pred,cost,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   598
                    opcode, resultop, leftstr, rightstr);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   599
    _mlistab[index] = mList;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   600
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   601
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   602
489c9b5090e2 Initial load
duke
parents:
diff changeset
   603
// Count number of OperandForms defined
489c9b5090e2 Initial load
duke
parents:
diff changeset
   604
int  ArchDesc::operandFormCount() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   605
  // Only interested in ones with non-NULL match rule
489c9b5090e2 Initial load
duke
parents:
diff changeset
   606
  int  count = 0; _operands.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   607
  OperandForm *cur;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   608
  for( ; (cur = (OperandForm*)_operands.iter()) != NULL; ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   609
    if (cur->_matrule != NULL) ++count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   610
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   611
  return count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   612
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   613
489c9b5090e2 Initial load
duke
parents:
diff changeset
   614
// Count number of OpClassForms defined
489c9b5090e2 Initial load
duke
parents:
diff changeset
   615
int  ArchDesc::opclassFormCount() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   616
  // Only interested in ones with non-NULL match rule
489c9b5090e2 Initial load
duke
parents:
diff changeset
   617
  int  count = 0; _operands.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   618
  OpClassForm *cur;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   619
  for( ; (cur = (OpClassForm*)_opclass.iter()) != NULL; ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   620
    ++count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   621
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   622
  return count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   623
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   624
489c9b5090e2 Initial load
duke
parents:
diff changeset
   625
// Count number of InstructForms defined
489c9b5090e2 Initial load
duke
parents:
diff changeset
   626
int  ArchDesc::instructFormCount() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   627
  // Only interested in ones with non-NULL match rule
489c9b5090e2 Initial load
duke
parents:
diff changeset
   628
  int  count = 0; _instructions.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   629
  InstructForm *cur;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   630
  for( ; (cur = (InstructForm*)_instructions.iter()) != NULL; ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   631
    if (cur->_matrule != NULL) ++count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   632
  };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   633
  return count;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   634
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   635
489c9b5090e2 Initial load
duke
parents:
diff changeset
   636
489c9b5090e2 Initial load
duke
parents:
diff changeset
   637
//------------------------------get_preproc_def--------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   638
// Return the textual binding for a given CPP flag name.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   639
// Return NULL if there is no binding, or it has been #undef-ed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   640
char* ArchDesc::get_preproc_def(const char* flag) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   641
  SourceForm* deff = (SourceForm*) _preproc_table[flag];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   642
  return (deff == NULL) ? NULL : deff->_code;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   643
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   644
489c9b5090e2 Initial load
duke
parents:
diff changeset
   645
489c9b5090e2 Initial load
duke
parents:
diff changeset
   646
//------------------------------set_preproc_def--------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   647
// Change or create a textual binding for a given CPP flag name.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   648
// Giving NULL means the flag name is to be #undef-ed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   649
// In any case, _preproc_list collects all names either #defined or #undef-ed.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   650
void ArchDesc::set_preproc_def(const char* flag, const char* def) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   651
  SourceForm* deff = (SourceForm*) _preproc_table[flag];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   652
  if (deff == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   653
    deff = new SourceForm(NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   654
    _preproc_table.Insert(flag, deff);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   655
    _preproc_list.addName(flag);   // this supports iteration
489c9b5090e2 Initial load
duke
parents:
diff changeset
   656
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   657
  deff->_code = (char*) def;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   658
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   659
489c9b5090e2 Initial load
duke
parents:
diff changeset
   660
489c9b5090e2 Initial load
duke
parents:
diff changeset
   661
bool ArchDesc::verify() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   662
489c9b5090e2 Initial load
duke
parents:
diff changeset
   663
  if (_register)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   664
    assert( _register->verify(), "Register declarations failed verification");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   665
  if (!_quiet_mode)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   666
    fprintf(stderr,"\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   667
  // fprintf(stderr,"---------------------------- Verify Operands ---------------\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   668
  // _operands.verify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   669
  // fprintf(stderr,"\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   670
  // fprintf(stderr,"---------------------------- Verify Operand Classes --------\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   671
  // _opclass.verify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   672
  // fprintf(stderr,"\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   673
  // fprintf(stderr,"---------------------------- Verify Attributes  ------------\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   674
  // _attributes.verify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   675
  // fprintf(stderr,"\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   676
  if (!_quiet_mode)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   677
    fprintf(stderr,"---------------------------- Verify Instructions ----------------------------\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   678
  _instructions.verify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   679
  if (!_quiet_mode)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   680
    fprintf(stderr,"\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   681
  // if ( _encode ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   682
  //   fprintf(stderr,"---------------------------- Verify Encodings --------------\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   683
  //   _encode->verify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   684
  // }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   685
489c9b5090e2 Initial load
duke
parents:
diff changeset
   686
  //if (_pipeline) _pipeline->verify();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   687
489c9b5090e2 Initial load
duke
parents:
diff changeset
   688
  return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   689
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   690
489c9b5090e2 Initial load
duke
parents:
diff changeset
   691
489c9b5090e2 Initial load
duke
parents:
diff changeset
   692
void ArchDesc::dump() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   693
  _pre_header.dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   694
  _header.dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   695
  _source.dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   696
  if (_register) _register->dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   697
  fprintf(stderr,"\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   698
  fprintf(stderr,"------------------ Dump Operands ---------------------\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   699
  _operands.dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   700
  fprintf(stderr,"\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   701
  fprintf(stderr,"------------------ Dump Operand Classes --------------\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   702
  _opclass.dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   703
  fprintf(stderr,"\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   704
  fprintf(stderr,"------------------ Dump Attributes  ------------------\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   705
  _attributes.dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   706
  fprintf(stderr,"\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   707
  fprintf(stderr,"------------------ Dump Instructions -----------------\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   708
  _instructions.dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   709
  if ( _encode ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   710
    fprintf(stderr,"------------------ Dump Encodings --------------------\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   711
    _encode->dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   712
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   713
  if (_pipeline) _pipeline->dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   714
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   715
489c9b5090e2 Initial load
duke
parents:
diff changeset
   716
489c9b5090e2 Initial load
duke
parents:
diff changeset
   717
//------------------------------init_keywords----------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   718
// Load the kewords into the global name table
489c9b5090e2 Initial load
duke
parents:
diff changeset
   719
void ArchDesc::initKeywords(FormDict& names) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   720
  // Insert keyword strings into Global Name Table.  Keywords have a NULL value
489c9b5090e2 Initial load
duke
parents:
diff changeset
   721
  // field for quick easy identification when checking identifiers.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   722
  names.Insert("instruct", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   723
  names.Insert("operand", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   724
  names.Insert("attribute", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   725
  names.Insert("source", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   726
  names.Insert("register", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   727
  names.Insert("pipeline", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   728
  names.Insert("constraint", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   729
  names.Insert("predicate", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   730
  names.Insert("encode", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   731
  names.Insert("enc_class", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   732
  names.Insert("interface", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   733
  names.Insert("opcode", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   734
  names.Insert("ins_encode", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   735
  names.Insert("match", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   736
  names.Insert("effect", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   737
  names.Insert("expand", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   738
  names.Insert("rewrite", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   739
  names.Insert("reg_def", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   740
  names.Insert("reg_class", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   741
  names.Insert("alloc_class", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   742
  names.Insert("resource", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   743
  names.Insert("pipe_class", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   744
  names.Insert("pipe_desc", NULL);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   745
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   746
489c9b5090e2 Initial load
duke
parents:
diff changeset
   747
489c9b5090e2 Initial load
duke
parents:
diff changeset
   748
//------------------------------internal_err----------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   749
// Issue a parser error message, and skip to the end of the current line
489c9b5090e2 Initial load
duke
parents:
diff changeset
   750
void ArchDesc::internal_err(const char *fmt, ...) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   751
  va_list args;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   752
489c9b5090e2 Initial load
duke
parents:
diff changeset
   753
  va_start(args, fmt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   754
  _internal_errs += emit_msg(0, INTERNAL_ERR, 0, fmt, args);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   755
  va_end(args);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   756
489c9b5090e2 Initial load
duke
parents:
diff changeset
   757
  _no_output = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   758
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   759
489c9b5090e2 Initial load
duke
parents:
diff changeset
   760
//------------------------------syntax_err----------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   761
// Issue a parser error message, and skip to the end of the current line
489c9b5090e2 Initial load
duke
parents:
diff changeset
   762
void ArchDesc::syntax_err(int lineno, const char *fmt, ...) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   763
  va_list args;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   764
489c9b5090e2 Initial load
duke
parents:
diff changeset
   765
  va_start(args, fmt);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   766
  _internal_errs += emit_msg(0, SYNERR, lineno, fmt, args);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   767
  va_end(args);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   768
489c9b5090e2 Initial load
duke
parents:
diff changeset
   769
  _no_output = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   770
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   771
489c9b5090e2 Initial load
duke
parents:
diff changeset
   772
//------------------------------emit_msg---------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   773
// Emit a user message, typically a warning or error
489c9b5090e2 Initial load
duke
parents:
diff changeset
   774
int ArchDesc::emit_msg(int quiet, int flag, int line, const char *fmt,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   775
    va_list args) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   776
  static int  last_lineno = -1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   777
  int         i;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   778
  const char *pref;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   779
489c9b5090e2 Initial load
duke
parents:
diff changeset
   780
  switch(flag) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   781
  case 0: pref = "Warning: "; break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   782
  case 1: pref = "Syntax Error: "; break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   783
  case 2: pref = "Semantic Error: "; break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   784
  case 3: pref = "Internal Error: "; break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   785
  default: assert(0, ""); break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   786
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   787
489c9b5090e2 Initial load
duke
parents:
diff changeset
   788
  if (line == last_lineno) return 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   789
  last_lineno = line;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   790
489c9b5090e2 Initial load
duke
parents:
diff changeset
   791
  if (!quiet) {                        /* no output if in quiet mode         */
489c9b5090e2 Initial load
duke
parents:
diff changeset
   792
    i = fprintf(errfile, "%s(%d) ", _ADL_file._name, line);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   793
    while (i++ <= 15)  fputc(' ', errfile);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   794
    fprintf(errfile, "%-8s:", pref);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   795
    vfprintf(errfile, fmt, args);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   796
    fprintf(errfile, "\n"); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   797
  return 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   798
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   799
489c9b5090e2 Initial load
duke
parents:
diff changeset
   800
489c9b5090e2 Initial load
duke
parents:
diff changeset
   801
// ---------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   802
//--------Utilities to build mappings for machine registers ------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   803
// ---------------------------------------------------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
   804
489c9b5090e2 Initial load
duke
parents:
diff changeset
   805
// Construct the name of the register mask.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   806
static const char *getRegMask(const char *reg_class_name) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   807
  if( reg_class_name == NULL ) return "RegMask::Empty";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   808
489c9b5090e2 Initial load
duke
parents:
diff changeset
   809
  if (strcmp(reg_class_name,"Universe")==0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   810
    return "RegMask::Empty";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   811
  } else if (strcmp(reg_class_name,"stack_slots")==0) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   812
    return "(Compile::current()->FIRST_STACK_mask())";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   813
  } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   814
    char       *rc_name = toUpper(reg_class_name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   815
    const char *mask    = "_mask";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   816
    int         length  = (int)strlen(rc_name) + (int)strlen(mask) + 3;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   817
    char       *regMask = new char[length];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   818
    sprintf(regMask,"%s%s", rc_name, mask);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   819
    return regMask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   820
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   821
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   822
489c9b5090e2 Initial load
duke
parents:
diff changeset
   823
// Convert a register class name to its register mask.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   824
const char *ArchDesc::reg_class_to_reg_mask(const char *rc_name) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   825
  const char *reg_mask = "RegMask::Empty";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   826
489c9b5090e2 Initial load
duke
parents:
diff changeset
   827
  if( _register ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   828
    RegClass *reg_class  = _register->getRegClass(rc_name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   829
    if (reg_class == NULL) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   830
      syntax_err(0, "Use of an undefined register class %s", rc_name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   831
      return reg_mask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   832
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   833
489c9b5090e2 Initial load
duke
parents:
diff changeset
   834
    // Construct the name of the register mask.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   835
    reg_mask = getRegMask(rc_name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   836
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   837
489c9b5090e2 Initial load
duke
parents:
diff changeset
   838
  return reg_mask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   839
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   840
489c9b5090e2 Initial load
duke
parents:
diff changeset
   841
489c9b5090e2 Initial load
duke
parents:
diff changeset
   842
// Obtain the name of the RegMask for an OperandForm
489c9b5090e2 Initial load
duke
parents:
diff changeset
   843
const char *ArchDesc::reg_mask(OperandForm  &opForm) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   844
  const char *regMask      = "RegMask::Empty";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   845
489c9b5090e2 Initial load
duke
parents:
diff changeset
   846
  // Check constraints on result's register class
489c9b5090e2 Initial load
duke
parents:
diff changeset
   847
  const char *result_class = opForm.constrained_reg_class();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   848
  if (!result_class) opForm.dump();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   849
  assert( result_class, "Resulting register class was not defined for operand");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   850
  regMask = reg_class_to_reg_mask( result_class );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   851
489c9b5090e2 Initial load
duke
parents:
diff changeset
   852
  return regMask;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   853
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   854
489c9b5090e2 Initial load
duke
parents:
diff changeset
   855
// Obtain the name of the RegMask for an InstructForm
489c9b5090e2 Initial load
duke
parents:
diff changeset
   856
const char *ArchDesc::reg_mask(InstructForm &inForm) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   857
  const char *result = inForm.reduce_result();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   858
  assert( result,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   859
          "Did not find result operand or RegMask for this instruction");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   860
489c9b5090e2 Initial load
duke
parents:
diff changeset
   861
  // Instructions producing 'Universe' use RegMask::Empty
489c9b5090e2 Initial load
duke
parents:
diff changeset
   862
  if( strcmp(result,"Universe")==0 ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   863
    return "RegMask::Empty";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   864
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   865
489c9b5090e2 Initial load
duke
parents:
diff changeset
   866
  // Lookup this result operand and get its register class
489c9b5090e2 Initial load
duke
parents:
diff changeset
   867
  Form *form = (Form*)_globalNames[result];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   868
  assert( form, "Result operand must be defined");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   869
  OperandForm *oper = form->is_operand();
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   870
  if (oper == NULL) form->dump();
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   871
  assert( oper, "Result must be an OperandForm");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   872
  return reg_mask( *oper );
489c9b5090e2 Initial load
duke
parents:
diff changeset
   873
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   874
489c9b5090e2 Initial load
duke
parents:
diff changeset
   875
489c9b5090e2 Initial load
duke
parents:
diff changeset
   876
// Obtain the STACK_OR_reg_mask name for an OperandForm
489c9b5090e2 Initial load
duke
parents:
diff changeset
   877
char *ArchDesc::stack_or_reg_mask(OperandForm  &opForm) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   878
  // name of cisc_spillable version
489c9b5090e2 Initial load
duke
parents:
diff changeset
   879
  const char *reg_mask_name = reg_mask(opForm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   880
  assert( reg_mask_name != NULL, "called with incorrect opForm");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   881
489c9b5090e2 Initial load
duke
parents:
diff changeset
   882
  const char *stack_or = "STACK_OR_";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   883
  int   length         = (int)strlen(stack_or) + (int)strlen(reg_mask_name) + 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   884
  char *result         = new char[length];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   885
  sprintf(result,"%s%s", stack_or, reg_mask_name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   886
489c9b5090e2 Initial load
duke
parents:
diff changeset
   887
  return result;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   888
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   889
489c9b5090e2 Initial load
duke
parents:
diff changeset
   890
// Record that the register class must generate a stack_or_reg_mask
489c9b5090e2 Initial load
duke
parents:
diff changeset
   891
void ArchDesc::set_stack_or_reg(const char *reg_class_name) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   892
  if( _register ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   893
    RegClass *reg_class  = _register->getRegClass(reg_class_name);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   894
    reg_class->_stack_or_reg = true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   895
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   896
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   897
489c9b5090e2 Initial load
duke
parents:
diff changeset
   898
489c9b5090e2 Initial load
duke
parents:
diff changeset
   899
// Return the type signature for the ideal operation
489c9b5090e2 Initial load
duke
parents:
diff changeset
   900
const char *ArchDesc::getIdealType(const char *idealOp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   901
  // Find last character in idealOp, it specifies the type
489c9b5090e2 Initial load
duke
parents:
diff changeset
   902
  char  last_char = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   903
  const char *ptr = idealOp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   904
  for( ; *ptr != '\0'; ++ptr) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   905
    last_char = *ptr;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   906
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   907
489c9b5090e2 Initial load
duke
parents:
diff changeset
   908
  // !!!!!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   909
  switch( last_char ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   910
  case 'I':    return "TypeInt::INT";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   911
  case 'P':    return "TypePtr::BOTTOM";
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   912
  case 'N':    return "TypeNarrowOop::BOTTOM";
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   913
  case 'F':    return "Type::FLOAT";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   914
  case 'D':    return "Type::DOUBLE";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   915
  case 'L':    return "TypeLong::LONG";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   916
  case 's':    return "TypeInt::CC /*flags*/";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   917
  default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   918
    return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   919
    // !!!!!
489c9b5090e2 Initial load
duke
parents:
diff changeset
   920
    // internal_err("Ideal type %s with unrecognized type\n",idealOp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   921
    break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   922
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   923
489c9b5090e2 Initial load
duke
parents:
diff changeset
   924
  return NULL;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   925
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   926
489c9b5090e2 Initial load
duke
parents:
diff changeset
   927
489c9b5090e2 Initial load
duke
parents:
diff changeset
   928
489c9b5090e2 Initial load
duke
parents:
diff changeset
   929
OperandForm *ArchDesc::constructOperand(const char *ident,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   930
                                        bool  ideal_only) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   931
  OperandForm *opForm = new OperandForm(ident, ideal_only);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   932
  _globalNames.Insert(ident, opForm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   933
  addForm(opForm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   934
489c9b5090e2 Initial load
duke
parents:
diff changeset
   935
  return opForm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   936
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
   937
489c9b5090e2 Initial load
duke
parents:
diff changeset
   938
489c9b5090e2 Initial load
duke
parents:
diff changeset
   939
// Import predefined base types: Set = 1, RegI, RegP, ...
489c9b5090e2 Initial load
duke
parents:
diff changeset
   940
void ArchDesc::initBaseOpTypes() {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   941
  // Create OperandForm and assign type for each opcode.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   942
  for (int i = 1; i < _last_machine_leaf; ++i) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   943
    char        *ident   = (char *)NodeClassNames[i];
489c9b5090e2 Initial load
duke
parents:
diff changeset
   944
    constructOperand(ident, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   945
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   946
  // Create InstructForm and assign type for each ideal instruction.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   947
  for ( int j = _last_machine_leaf+1; j < _last_opcode; ++j) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   948
    char         *ident    = (char *)NodeClassNames[j];
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
   949
    if(!strcmp(ident, "ConI") || !strcmp(ident, "ConP") || !strcmp(ident, "ConN") ||
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   950
       !strcmp(ident, "ConF") || !strcmp(ident, "ConD") ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   951
       !strcmp(ident, "ConL") || !strcmp(ident, "Con" ) ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   952
       !strcmp(ident, "Bool") ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   953
      constructOperand(ident, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   954
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   955
    else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   956
      InstructForm *insForm  = new InstructForm(ident, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   957
      // insForm->_opcode       = nextUserOpType(ident);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   958
      _globalNames.Insert(ident,insForm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   959
      addForm(insForm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   960
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   961
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   962
489c9b5090e2 Initial load
duke
parents:
diff changeset
   963
  { OperandForm *opForm;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   964
  // Create operand type "Universe" for return instructions.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   965
  const char *ident = "Universe";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   966
  opForm = constructOperand(ident, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   967
489c9b5090e2 Initial load
duke
parents:
diff changeset
   968
  // Create operand type "label" for branch targets
489c9b5090e2 Initial load
duke
parents:
diff changeset
   969
  ident = "label";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   970
  opForm = constructOperand(ident, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   971
489c9b5090e2 Initial load
duke
parents:
diff changeset
   972
  // !!!!! Update - when adding a new sReg/stackSlot type
489c9b5090e2 Initial load
duke
parents:
diff changeset
   973
  // Create operand types "sReg[IPFDL]" for stack slot registers
489c9b5090e2 Initial load
duke
parents:
diff changeset
   974
  opForm = constructOperand("sRegI", false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   975
  opForm->_constraint = new Constraint("ALLOC_IN_RC", "stack_slots");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   976
  opForm = constructOperand("sRegP", false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   977
  opForm->_constraint = new Constraint("ALLOC_IN_RC", "stack_slots");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   978
  opForm = constructOperand("sRegF", false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   979
  opForm->_constraint = new Constraint("ALLOC_IN_RC", "stack_slots");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   980
  opForm = constructOperand("sRegD", false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   981
  opForm->_constraint = new Constraint("ALLOC_IN_RC", "stack_slots");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   982
  opForm = constructOperand("sRegL", false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   983
  opForm->_constraint = new Constraint("ALLOC_IN_RC", "stack_slots");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   984
489c9b5090e2 Initial load
duke
parents:
diff changeset
   985
  // Create operand type "method" for call targets
489c9b5090e2 Initial load
duke
parents:
diff changeset
   986
  ident = "method";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   987
  opForm = constructOperand(ident, false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   988
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   989
489c9b5090e2 Initial load
duke
parents:
diff changeset
   990
  // Create Effect Forms for each of the legal effects
489c9b5090e2 Initial load
duke
parents:
diff changeset
   991
  // USE, DEF, USE_DEF, KILL, USE_KILL
489c9b5090e2 Initial load
duke
parents:
diff changeset
   992
  {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   993
    const char *ident = "USE";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   994
    Effect     *eForm = new Effect(ident);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   995
    _globalNames.Insert(ident, eForm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   996
    ident = "DEF";
489c9b5090e2 Initial load
duke
parents:
diff changeset
   997
    eForm = new Effect(ident);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   998
    _globalNames.Insert(ident, eForm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   999
    ident = "USE_DEF";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1000
    eForm = new Effect(ident);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1001
    _globalNames.Insert(ident, eForm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1002
    ident = "KILL";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1003
    eForm = new Effect(ident);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1004
    _globalNames.Insert(ident, eForm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1005
    ident = "USE_KILL";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1006
    eForm = new Effect(ident);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1007
    _globalNames.Insert(ident, eForm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1008
    ident = "TEMP";
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1009
    eForm = new Effect(ident);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1010
    _globalNames.Insert(ident, eForm);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1011
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1012
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1013
  //
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1014
  // Build mapping from ideal names to ideal indices
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1015
  int idealIndex = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1016
  for (idealIndex = 1; idealIndex < _last_machine_leaf; ++idealIndex) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1017
    const char *idealName = NodeClassNames[idealIndex];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1018
    _idealIndex.Insert((void*)idealName, (void*)idealIndex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1019
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1020
  for ( idealIndex = _last_machine_leaf+1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1021
        idealIndex < _last_opcode; ++idealIndex) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1022
    const char *idealName = NodeClassNames[idealIndex];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1023
    _idealIndex.Insert((void*)idealName, (void*)idealIndex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1024
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1025
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1026
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1027
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1028
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1029
//---------------------------addSUNcopyright-------------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1030
// output SUN copyright info
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1031
void ArchDesc::addSunCopyright(char* legal, int size, FILE *fp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1032
  fwrite(legal, size, 1, fp);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1033
  fprintf(fp,"\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1034
  fprintf(fp,"// Machine Generated File.  Do Not Edit!\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1035
  fprintf(fp,"\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1036
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1037
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1038
//---------------------------machineDependentIncludes--------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1039
// output #include declarations for machine specific files
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1040
void ArchDesc::machineDependentIncludes(ADLFILE &adlfile) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1041
  const char *basename = adlfile._name;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1042
  const char *cp;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1043
  for (cp = basename; *cp; cp++)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1044
    if (*cp == '/')  basename = cp+1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1045
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1046
  // Build #include lines
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1047
  fprintf(adlfile._fp, "\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1048
  fprintf(adlfile._fp, "#include \"incls/_precompiled.incl\"\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1049
  fprintf(adlfile._fp, "#include \"incls/_%s.incl\"\n",basename);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1050
  fprintf(adlfile._fp, "\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1051
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1052
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1053
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1054
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1055
//---------------------------addPreprocessorChecks-----------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1056
// Output C preprocessor code to verify the backend compilation environment.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1057
// The idea is to force code produced by "adlc -DHS64" to be compiled by a
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1058
// command of the form "CC ... -DHS64 ...", so that any #ifdefs in the source
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1059
// blocks select C code that is consistent with adlc's selections of AD code.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1060
void ArchDesc::addPreprocessorChecks(FILE *fp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1061
  const char* flag;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1062
  _preproc_list.reset();
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1063
  if (_preproc_list.count() > 0 && !_preproc_list.current_is_signal()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1064
    fprintf(fp, "// Check consistency of C++ compilation with ADLC options:\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1065
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1066
  for (_preproc_list.reset(); (flag = _preproc_list.iter()) != NULL; ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1067
    if (_preproc_list.current_is_signal())  break;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1068
    char* def = get_preproc_def(flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1069
    fprintf(fp, "// Check adlc ");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1070
    if (def)
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1071
          fprintf(fp, "-D%s=%s\n", flag, def);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1072
    else  fprintf(fp, "-U%s\n", flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1073
    fprintf(fp, "#%s %s\n",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1074
            def ? "ifndef" : "ifdef", flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1075
    fprintf(fp, "#  error \"%s %s be defined\"\n",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1076
            flag, def ? "must" : "must not");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1077
    fprintf(fp, "#endif // %s\n", flag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1078
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1079
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1080
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1081
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1082
// Convert operand name into enum name
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1083
const char *ArchDesc::machOperEnum(const char *opName) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1084
  return ArchDesc::getMachOperEnum(opName);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1085
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1086
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1087
// Convert operand name into enum name
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1088
const char *ArchDesc::getMachOperEnum(const char *opName) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1089
  return (opName ? toUpper(opName) : opName);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1090
}
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1091
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1092
//---------------------------buildMustCloneMap-----------------------------
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1093
// Flag cases when machine needs cloned values or instructions
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1094
void ArchDesc::buildMustCloneMap(FILE *fp_hpp, FILE *fp_cpp) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1095
  // Build external declarations for mappings
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1096
  fprintf(fp_hpp, "// Mapping from machine-independent opcode to boolean\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1097
  fprintf(fp_hpp, "// Flag cases where machine needs cloned values or instructions\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1098
  fprintf(fp_hpp, "extern const char must_clone[];\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1099
  fprintf(fp_hpp, "\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1100
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1101
  // Build mapping from ideal names to ideal indices
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1102
  fprintf(fp_cpp, "\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1103
  fprintf(fp_cpp, "// Mapping from machine-independent opcode to boolean\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1104
  fprintf(fp_cpp, "const        char must_clone[] = {\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1105
  for (int idealIndex = 0; idealIndex < _last_opcode; ++idealIndex) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1106
    int         must_clone = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1107
    const char *idealName = NodeClassNames[idealIndex];
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1108
    // Previously selected constants for cloning
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1109
    // !!!!!
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1110
    // These are the current machine-dependent clones
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1111
    if ( strcmp(idealName,"CmpI") == 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1112
         || strcmp(idealName,"CmpU") == 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1113
         || strcmp(idealName,"CmpP") == 0
360
21d113ecbf6a 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 1
diff changeset
  1114
         || strcmp(idealName,"CmpN") == 0
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1115
         || strcmp(idealName,"CmpL") == 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1116
         || strcmp(idealName,"CmpD") == 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1117
         || strcmp(idealName,"CmpF") == 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1118
         || strcmp(idealName,"FastLock") == 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1119
         || strcmp(idealName,"FastUnlock") == 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1120
         || strcmp(idealName,"Bool") == 0
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1121
         || strcmp(idealName,"Binary") == 0 ) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1122
      // Removed ConI from the must_clone list.  CPUs that cannot use
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1123
      // large constants as immediates manifest the constant as an
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1124
      // instruction.  The must_clone flag prevents the constant from
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1125
      // floating up out of loops.
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1126
      must_clone = 1;
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1127
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1128
    fprintf(fp_cpp, "  %d%s // %s: %d\n", must_clone,
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1129
      (idealIndex != (_last_opcode - 1)) ? "," : " // no trailing comma",
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1130
      idealName, idealIndex);
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1131
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1132
  // Finish defining table
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1133
  fprintf(fp_cpp, "};\n");
489c9b5090e2 Initial load
duke
parents:
diff changeset
  1134
}