src/share/vm/adlc/formssel.cpp

changeset 0
f90c822e73f8
child 6876
710a3c8b516e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/adlc/formssel.cpp	Wed Apr 27 01:25:04 2016 +0800
     1.3 @@ -0,0 +1,4253 @@
     1.4 +/*
     1.5 + * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.
    1.11 + *
    1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 + * version 2 for more details (a copy is included in the LICENSE file that
    1.16 + * accompanied this code).
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License version
    1.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 + *
    1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.23 + * or visit www.oracle.com if you need additional information or have any
    1.24 + * questions.
    1.25 + *
    1.26 + */
    1.27 +
    1.28 +// FORMS.CPP - Definitions for ADL Parser Forms Classes
    1.29 +#include "adlc.hpp"
    1.30 +
    1.31 +//==============================Instructions===================================
    1.32 +//------------------------------InstructForm-----------------------------------
    1.33 +InstructForm::InstructForm(const char *id, bool ideal_only)
    1.34 +  : _ident(id), _ideal_only(ideal_only),
    1.35 +    _localNames(cmpstr, hashstr, Form::arena),
    1.36 +    _effects(cmpstr, hashstr, Form::arena),
    1.37 +    _is_mach_constant(false),
    1.38 +    _needs_constant_base(false),
    1.39 +    _has_call(false)
    1.40 +{
    1.41 +      _ftype = Form::INS;
    1.42 +
    1.43 +      _matrule              = NULL;
    1.44 +      _insencode            = NULL;
    1.45 +      _constant             = NULL;
    1.46 +      _is_postalloc_expand  = false;
    1.47 +      _opcode               = NULL;
    1.48 +      _size                 = NULL;
    1.49 +      _attribs              = NULL;
    1.50 +      _predicate            = NULL;
    1.51 +      _exprule              = NULL;
    1.52 +      _rewrule              = NULL;
    1.53 +      _format               = NULL;
    1.54 +      _peephole             = NULL;
    1.55 +      _ins_pipe             = NULL;
    1.56 +      _uniq_idx             = NULL;
    1.57 +      _num_uniq             = 0;
    1.58 +      _cisc_spill_operand   = Not_cisc_spillable;// Which operand may cisc-spill
    1.59 +      _cisc_spill_alternate = NULL;            // possible cisc replacement
    1.60 +      _cisc_reg_mask_name   = NULL;
    1.61 +      _is_cisc_alternate    = false;
    1.62 +      _is_short_branch      = false;
    1.63 +      _short_branch_form    = NULL;
    1.64 +      _alignment            = 1;
    1.65 +}
    1.66 +
    1.67 +InstructForm::InstructForm(const char *id, InstructForm *instr, MatchRule *rule)
    1.68 +  : _ident(id), _ideal_only(false),
    1.69 +    _localNames(instr->_localNames),
    1.70 +    _effects(instr->_effects),
    1.71 +    _is_mach_constant(false),
    1.72 +    _needs_constant_base(false),
    1.73 +    _has_call(false)
    1.74 +{
    1.75 +      _ftype = Form::INS;
    1.76 +
    1.77 +      _matrule               = rule;
    1.78 +      _insencode             = instr->_insencode;
    1.79 +      _constant              = instr->_constant;
    1.80 +      _is_postalloc_expand   = instr->_is_postalloc_expand;
    1.81 +      _opcode                = instr->_opcode;
    1.82 +      _size                  = instr->_size;
    1.83 +      _attribs               = instr->_attribs;
    1.84 +      _predicate             = instr->_predicate;
    1.85 +      _exprule               = instr->_exprule;
    1.86 +      _rewrule               = instr->_rewrule;
    1.87 +      _format                = instr->_format;
    1.88 +      _peephole              = instr->_peephole;
    1.89 +      _ins_pipe              = instr->_ins_pipe;
    1.90 +      _uniq_idx              = instr->_uniq_idx;
    1.91 +      _num_uniq              = instr->_num_uniq;
    1.92 +      _cisc_spill_operand    = Not_cisc_spillable; // Which operand may cisc-spill
    1.93 +      _cisc_spill_alternate  = NULL;               // possible cisc replacement
    1.94 +      _cisc_reg_mask_name    = NULL;
    1.95 +      _is_cisc_alternate     = false;
    1.96 +      _is_short_branch       = false;
    1.97 +      _short_branch_form     = NULL;
    1.98 +      _alignment             = 1;
    1.99 +     // Copy parameters
   1.100 +     const char *name;
   1.101 +     instr->_parameters.reset();
   1.102 +     for (; (name = instr->_parameters.iter()) != NULL;)
   1.103 +       _parameters.addName(name);
   1.104 +}
   1.105 +
   1.106 +InstructForm::~InstructForm() {
   1.107 +}
   1.108 +
   1.109 +InstructForm *InstructForm::is_instruction() const {
   1.110 +  return (InstructForm*)this;
   1.111 +}
   1.112 +
   1.113 +bool InstructForm::ideal_only() const {
   1.114 +  return _ideal_only;
   1.115 +}
   1.116 +
   1.117 +bool InstructForm::sets_result() const {
   1.118 +  return (_matrule != NULL && _matrule->sets_result());
   1.119 +}
   1.120 +
   1.121 +bool InstructForm::needs_projections() {
   1.122 +  _components.reset();
   1.123 +  for( Component *comp; (comp = _components.iter()) != NULL; ) {
   1.124 +    if (comp->isa(Component::KILL)) {
   1.125 +      return true;
   1.126 +    }
   1.127 +  }
   1.128 +  return false;
   1.129 +}
   1.130 +
   1.131 +
   1.132 +bool InstructForm::has_temps() {
   1.133 +  if (_matrule) {
   1.134 +    // Examine each component to see if it is a TEMP
   1.135 +    _components.reset();
   1.136 +    // Skip the first component, if already handled as (SET dst (...))
   1.137 +    Component *comp = NULL;
   1.138 +    if (sets_result())  comp = _components.iter();
   1.139 +    while ((comp = _components.iter()) != NULL) {
   1.140 +      if (comp->isa(Component::TEMP)) {
   1.141 +        return true;
   1.142 +      }
   1.143 +    }
   1.144 +  }
   1.145 +
   1.146 +  return false;
   1.147 +}
   1.148 +
   1.149 +uint InstructForm::num_defs_or_kills() {
   1.150 +  uint   defs_or_kills = 0;
   1.151 +
   1.152 +  _components.reset();
   1.153 +  for( Component *comp; (comp = _components.iter()) != NULL; ) {
   1.154 +    if( comp->isa(Component::DEF) || comp->isa(Component::KILL) ) {
   1.155 +      ++defs_or_kills;
   1.156 +    }
   1.157 +  }
   1.158 +
   1.159 +  return  defs_or_kills;
   1.160 +}
   1.161 +
   1.162 +// This instruction has an expand rule?
   1.163 +bool InstructForm::expands() const {
   1.164 +  return ( _exprule != NULL );
   1.165 +}
   1.166 +
   1.167 +// This instruction has a late expand rule?
   1.168 +bool InstructForm::postalloc_expands() const {
   1.169 +  return _is_postalloc_expand;
   1.170 +}
   1.171 +
   1.172 +// This instruction has a peephole rule?
   1.173 +Peephole *InstructForm::peepholes() const {
   1.174 +  return _peephole;
   1.175 +}
   1.176 +
   1.177 +// This instruction has a peephole rule?
   1.178 +void InstructForm::append_peephole(Peephole *peephole) {
   1.179 +  if( _peephole == NULL ) {
   1.180 +    _peephole = peephole;
   1.181 +  } else {
   1.182 +    _peephole->append_peephole(peephole);
   1.183 +  }
   1.184 +}
   1.185 +
   1.186 +
   1.187 +// ideal opcode enumeration
   1.188 +const char *InstructForm::ideal_Opcode( FormDict &globalNames )  const {
   1.189 +  if( !_matrule ) return "Node"; // Something weird
   1.190 +  // Chain rules do not really have ideal Opcodes; use their source
   1.191 +  // operand ideal Opcode instead.
   1.192 +  if( is_simple_chain_rule(globalNames) ) {
   1.193 +    const char *src = _matrule->_rChild->_opType;
   1.194 +    OperandForm *src_op = globalNames[src]->is_operand();
   1.195 +    assert( src_op, "Not operand class of chain rule" );
   1.196 +    if( !src_op->_matrule ) return "Node";
   1.197 +    return src_op->_matrule->_opType;
   1.198 +  }
   1.199 +  // Operand chain rules do not really have ideal Opcodes
   1.200 +  if( _matrule->is_chain_rule(globalNames) )
   1.201 +    return "Node";
   1.202 +  return strcmp(_matrule->_opType,"Set")
   1.203 +    ? _matrule->_opType
   1.204 +    : _matrule->_rChild->_opType;
   1.205 +}
   1.206 +
   1.207 +// Recursive check on all operands' match rules in my match rule
   1.208 +bool InstructForm::is_pinned(FormDict &globals) {
   1.209 +  if ( ! _matrule)  return false;
   1.210 +
   1.211 +  int  index   = 0;
   1.212 +  if (_matrule->find_type("Goto",          index)) return true;
   1.213 +  if (_matrule->find_type("If",            index)) return true;
   1.214 +  if (_matrule->find_type("CountedLoopEnd",index)) return true;
   1.215 +  if (_matrule->find_type("Return",        index)) return true;
   1.216 +  if (_matrule->find_type("Rethrow",       index)) return true;
   1.217 +  if (_matrule->find_type("TailCall",      index)) return true;
   1.218 +  if (_matrule->find_type("TailJump",      index)) return true;
   1.219 +  if (_matrule->find_type("Halt",          index)) return true;
   1.220 +  if (_matrule->find_type("Jump",          index)) return true;
   1.221 +
   1.222 +  return is_parm(globals);
   1.223 +}
   1.224 +
   1.225 +// Recursive check on all operands' match rules in my match rule
   1.226 +bool InstructForm::is_projection(FormDict &globals) {
   1.227 +  if ( ! _matrule)  return false;
   1.228 +
   1.229 +  int  index   = 0;
   1.230 +  if (_matrule->find_type("Goto",    index)) return true;
   1.231 +  if (_matrule->find_type("Return",  index)) return true;
   1.232 +  if (_matrule->find_type("Rethrow", index)) return true;
   1.233 +  if (_matrule->find_type("TailCall",index)) return true;
   1.234 +  if (_matrule->find_type("TailJump",index)) return true;
   1.235 +  if (_matrule->find_type("Halt",    index)) return true;
   1.236 +
   1.237 +  return false;
   1.238 +}
   1.239 +
   1.240 +// Recursive check on all operands' match rules in my match rule
   1.241 +bool InstructForm::is_parm(FormDict &globals) {
   1.242 +  if ( ! _matrule)  return false;
   1.243 +
   1.244 +  int  index   = 0;
   1.245 +  if (_matrule->find_type("Parm",index)) return true;
   1.246 +
   1.247 +  return false;
   1.248 +}
   1.249 +
   1.250 +bool InstructForm::is_ideal_negD() const {
   1.251 +  return (_matrule && _matrule->_rChild && strcmp(_matrule->_rChild->_opType, "NegD") == 0);
   1.252 +}
   1.253 +
   1.254 +// Return 'true' if this instruction matches an ideal 'Copy*' node
   1.255 +int InstructForm::is_ideal_copy() const {
   1.256 +  return _matrule ? _matrule->is_ideal_copy() : 0;
   1.257 +}
   1.258 +
   1.259 +// Return 'true' if this instruction is too complex to rematerialize.
   1.260 +int InstructForm::is_expensive() const {
   1.261 +  // We can prove it is cheap if it has an empty encoding.
   1.262 +  // This helps with platform-specific nops like ThreadLocal and RoundFloat.
   1.263 +  if (is_empty_encoding())
   1.264 +    return 0;
   1.265 +
   1.266 +  if (is_tls_instruction())
   1.267 +    return 1;
   1.268 +
   1.269 +  if (_matrule == NULL)  return 0;
   1.270 +
   1.271 +  return _matrule->is_expensive();
   1.272 +}
   1.273 +
   1.274 +// Has an empty encoding if _size is a constant zero or there
   1.275 +// are no ins_encode tokens.
   1.276 +int InstructForm::is_empty_encoding() const {
   1.277 +  if (_insencode != NULL) {
   1.278 +    _insencode->reset();
   1.279 +    if (_insencode->encode_class_iter() == NULL) {
   1.280 +      return 1;
   1.281 +    }
   1.282 +  }
   1.283 +  if (_size != NULL && strcmp(_size, "0") == 0) {
   1.284 +    return 1;
   1.285 +  }
   1.286 +  return 0;
   1.287 +}
   1.288 +
   1.289 +int InstructForm::is_tls_instruction() const {
   1.290 +  if (_ident != NULL &&
   1.291 +      ( ! strcmp( _ident,"tlsLoadP") ||
   1.292 +        ! strncmp(_ident,"tlsLoadP_",9)) ) {
   1.293 +    return 1;
   1.294 +  }
   1.295 +
   1.296 +  if (_matrule != NULL && _insencode != NULL) {
   1.297 +    const char* opType = _matrule->_opType;
   1.298 +    if (strcmp(opType, "Set")==0)
   1.299 +      opType = _matrule->_rChild->_opType;
   1.300 +    if (strcmp(opType,"ThreadLocal")==0) {
   1.301 +      fprintf(stderr, "Warning: ThreadLocal instruction %s should be named 'tlsLoadP_*'\n",
   1.302 +              (_ident == NULL ? "NULL" : _ident));
   1.303 +      return 1;
   1.304 +    }
   1.305 +  }
   1.306 +
   1.307 +  return 0;
   1.308 +}
   1.309 +
   1.310 +
   1.311 +// Return 'true' if this instruction matches an ideal 'If' node
   1.312 +bool InstructForm::is_ideal_if() const {
   1.313 +  if( _matrule == NULL ) return false;
   1.314 +
   1.315 +  return _matrule->is_ideal_if();
   1.316 +}
   1.317 +
   1.318 +// Return 'true' if this instruction matches an ideal 'FastLock' node
   1.319 +bool InstructForm::is_ideal_fastlock() const {
   1.320 +  if( _matrule == NULL ) return false;
   1.321 +
   1.322 +  return _matrule->is_ideal_fastlock();
   1.323 +}
   1.324 +
   1.325 +// Return 'true' if this instruction matches an ideal 'MemBarXXX' node
   1.326 +bool InstructForm::is_ideal_membar() const {
   1.327 +  if( _matrule == NULL ) return false;
   1.328 +
   1.329 +  return _matrule->is_ideal_membar();
   1.330 +}
   1.331 +
   1.332 +// Return 'true' if this instruction matches an ideal 'LoadPC' node
   1.333 +bool InstructForm::is_ideal_loadPC() const {
   1.334 +  if( _matrule == NULL ) return false;
   1.335 +
   1.336 +  return _matrule->is_ideal_loadPC();
   1.337 +}
   1.338 +
   1.339 +// Return 'true' if this instruction matches an ideal 'Box' node
   1.340 +bool InstructForm::is_ideal_box() const {
   1.341 +  if( _matrule == NULL ) return false;
   1.342 +
   1.343 +  return _matrule->is_ideal_box();
   1.344 +}
   1.345 +
   1.346 +// Return 'true' if this instruction matches an ideal 'Goto' node
   1.347 +bool InstructForm::is_ideal_goto() const {
   1.348 +  if( _matrule == NULL ) return false;
   1.349 +
   1.350 +  return _matrule->is_ideal_goto();
   1.351 +}
   1.352 +
   1.353 +// Return 'true' if this instruction matches an ideal 'Jump' node
   1.354 +bool InstructForm::is_ideal_jump() const {
   1.355 +  if( _matrule == NULL ) return false;
   1.356 +
   1.357 +  return _matrule->is_ideal_jump();
   1.358 +}
   1.359 +
   1.360 +// Return 'true' if instruction matches ideal 'If' | 'Goto' | 'CountedLoopEnd'
   1.361 +bool InstructForm::is_ideal_branch() const {
   1.362 +  if( _matrule == NULL ) return false;
   1.363 +
   1.364 +  return _matrule->is_ideal_if() || _matrule->is_ideal_goto();
   1.365 +}
   1.366 +
   1.367 +
   1.368 +// Return 'true' if this instruction matches an ideal 'Return' node
   1.369 +bool InstructForm::is_ideal_return() const {
   1.370 +  if( _matrule == NULL ) return false;
   1.371 +
   1.372 +  // Check MatchRule to see if the first entry is the ideal "Return" node
   1.373 +  int  index   = 0;
   1.374 +  if (_matrule->find_type("Return",index)) return true;
   1.375 +  if (_matrule->find_type("Rethrow",index)) return true;
   1.376 +  if (_matrule->find_type("TailCall",index)) return true;
   1.377 +  if (_matrule->find_type("TailJump",index)) return true;
   1.378 +
   1.379 +  return false;
   1.380 +}
   1.381 +
   1.382 +// Return 'true' if this instruction matches an ideal 'Halt' node
   1.383 +bool InstructForm::is_ideal_halt() const {
   1.384 +  int  index   = 0;
   1.385 +  return _matrule && _matrule->find_type("Halt",index);
   1.386 +}
   1.387 +
   1.388 +// Return 'true' if this instruction matches an ideal 'SafePoint' node
   1.389 +bool InstructForm::is_ideal_safepoint() const {
   1.390 +  int  index   = 0;
   1.391 +  return _matrule && _matrule->find_type("SafePoint",index);
   1.392 +}
   1.393 +
   1.394 +// Return 'true' if this instruction matches an ideal 'Nop' node
   1.395 +bool InstructForm::is_ideal_nop() const {
   1.396 +  return _ident && _ident[0] == 'N' && _ident[1] == 'o' && _ident[2] == 'p' && _ident[3] == '_';
   1.397 +}
   1.398 +
   1.399 +bool InstructForm::is_ideal_control() const {
   1.400 +  if ( ! _matrule)  return false;
   1.401 +
   1.402 +  return is_ideal_return() || is_ideal_branch() || _matrule->is_ideal_jump() || is_ideal_halt();
   1.403 +}
   1.404 +
   1.405 +// Return 'true' if this instruction matches an ideal 'Call' node
   1.406 +Form::CallType InstructForm::is_ideal_call() const {
   1.407 +  if( _matrule == NULL ) return Form::invalid_type;
   1.408 +
   1.409 +  // Check MatchRule to see if the first entry is the ideal "Call" node
   1.410 +  int  idx   = 0;
   1.411 +  if(_matrule->find_type("CallStaticJava",idx))   return Form::JAVA_STATIC;
   1.412 +  idx = 0;
   1.413 +  if(_matrule->find_type("Lock",idx))             return Form::JAVA_STATIC;
   1.414 +  idx = 0;
   1.415 +  if(_matrule->find_type("Unlock",idx))           return Form::JAVA_STATIC;
   1.416 +  idx = 0;
   1.417 +  if(_matrule->find_type("CallDynamicJava",idx))  return Form::JAVA_DYNAMIC;
   1.418 +  idx = 0;
   1.419 +  if(_matrule->find_type("CallRuntime",idx))      return Form::JAVA_RUNTIME;
   1.420 +  idx = 0;
   1.421 +  if(_matrule->find_type("CallLeaf",idx))         return Form::JAVA_LEAF;
   1.422 +  idx = 0;
   1.423 +  if(_matrule->find_type("CallLeafNoFP",idx))     return Form::JAVA_LEAF;
   1.424 +  idx = 0;
   1.425 +
   1.426 +  return Form::invalid_type;
   1.427 +}
   1.428 +
   1.429 +// Return 'true' if this instruction matches an ideal 'Load?' node
   1.430 +Form::DataType InstructForm::is_ideal_load() const {
   1.431 +  if( _matrule == NULL ) return Form::none;
   1.432 +
   1.433 +  return  _matrule->is_ideal_load();
   1.434 +}
   1.435 +
   1.436 +// Return 'true' if this instruction matches an ideal 'LoadKlass' node
   1.437 +bool InstructForm::skip_antidep_check() const {
   1.438 +  if( _matrule == NULL ) return false;
   1.439 +
   1.440 +  return  _matrule->skip_antidep_check();
   1.441 +}
   1.442 +
   1.443 +// Return 'true' if this instruction matches an ideal 'Load?' node
   1.444 +Form::DataType InstructForm::is_ideal_store() const {
   1.445 +  if( _matrule == NULL ) return Form::none;
   1.446 +
   1.447 +  return  _matrule->is_ideal_store();
   1.448 +}
   1.449 +
   1.450 +// Return 'true' if this instruction matches an ideal vector node
   1.451 +bool InstructForm::is_vector() const {
   1.452 +  if( _matrule == NULL ) return false;
   1.453 +
   1.454 +  return _matrule->is_vector();
   1.455 +}
   1.456 +
   1.457 +
   1.458 +// Return the input register that must match the output register
   1.459 +// If this is not required, return 0
   1.460 +uint InstructForm::two_address(FormDict &globals) {
   1.461 +  uint  matching_input = 0;
   1.462 +  if(_components.count() == 0) return 0;
   1.463 +
   1.464 +  _components.reset();
   1.465 +  Component *comp = _components.iter();
   1.466 +  // Check if there is a DEF
   1.467 +  if( comp->isa(Component::DEF) ) {
   1.468 +    // Check that this is a register
   1.469 +    const char  *def_type = comp->_type;
   1.470 +    const Form  *form     = globals[def_type];
   1.471 +    OperandForm *op       = form->is_operand();
   1.472 +    if( op ) {
   1.473 +      if( op->constrained_reg_class() != NULL &&
   1.474 +          op->interface_type(globals) == Form::register_interface ) {
   1.475 +        // Remember the local name for equality test later
   1.476 +        const char *def_name = comp->_name;
   1.477 +        // Check if a component has the same name and is a USE
   1.478 +        do {
   1.479 +          if( comp->isa(Component::USE) && strcmp(comp->_name,def_name)==0 ) {
   1.480 +            return operand_position_format(def_name);
   1.481 +          }
   1.482 +        } while( (comp = _components.iter()) != NULL);
   1.483 +      }
   1.484 +    }
   1.485 +  }
   1.486 +
   1.487 +  return 0;
   1.488 +}
   1.489 +
   1.490 +
   1.491 +// when chaining a constant to an instruction, returns 'true' and sets opType
   1.492 +Form::DataType InstructForm::is_chain_of_constant(FormDict &globals) {
   1.493 +  const char *dummy  = NULL;
   1.494 +  const char *dummy2 = NULL;
   1.495 +  return is_chain_of_constant(globals, dummy, dummy2);
   1.496 +}
   1.497 +Form::DataType InstructForm::is_chain_of_constant(FormDict &globals,
   1.498 +                const char * &opTypeParam) {
   1.499 +  const char *result = NULL;
   1.500 +
   1.501 +  return is_chain_of_constant(globals, opTypeParam, result);
   1.502 +}
   1.503 +
   1.504 +Form::DataType InstructForm::is_chain_of_constant(FormDict &globals,
   1.505 +                const char * &opTypeParam, const char * &resultParam) {
   1.506 +  Form::DataType  data_type = Form::none;
   1.507 +  if ( ! _matrule)  return data_type;
   1.508 +
   1.509 +  // !!!!!
   1.510 +  // The source of the chain rule is 'position = 1'
   1.511 +  uint         position = 1;
   1.512 +  const char  *result   = NULL;
   1.513 +  const char  *name     = NULL;
   1.514 +  const char  *opType   = NULL;
   1.515 +  // Here base_operand is looking for an ideal type to be returned (opType).
   1.516 +  if ( _matrule->is_chain_rule(globals)
   1.517 +       && _matrule->base_operand(position, globals, result, name, opType) ) {
   1.518 +    data_type = ideal_to_const_type(opType);
   1.519 +
   1.520 +    // if it isn't an ideal constant type, just return
   1.521 +    if ( data_type == Form::none ) return data_type;
   1.522 +
   1.523 +    // Ideal constant types also adjust the opType parameter.
   1.524 +    resultParam = result;
   1.525 +    opTypeParam = opType;
   1.526 +    return data_type;
   1.527 +  }
   1.528 +
   1.529 +  return data_type;
   1.530 +}
   1.531 +
   1.532 +// Check if a simple chain rule
   1.533 +bool InstructForm::is_simple_chain_rule(FormDict &globals) const {
   1.534 +  if( _matrule && _matrule->sets_result()
   1.535 +      && _matrule->_rChild->_lChild == NULL
   1.536 +      && globals[_matrule->_rChild->_opType]
   1.537 +      && globals[_matrule->_rChild->_opType]->is_opclass() ) {
   1.538 +    return true;
   1.539 +  }
   1.540 +  return false;
   1.541 +}
   1.542 +
   1.543 +// check for structural rematerialization
   1.544 +bool InstructForm::rematerialize(FormDict &globals, RegisterForm *registers ) {
   1.545 +  bool   rematerialize = false;
   1.546 +
   1.547 +  Form::DataType data_type = is_chain_of_constant(globals);
   1.548 +  if( data_type != Form::none )
   1.549 +    rematerialize = true;
   1.550 +
   1.551 +  // Constants
   1.552 +  if( _components.count() == 1 && _components[0]->is(Component::USE_DEF) )
   1.553 +    rematerialize = true;
   1.554 +
   1.555 +  // Pseudo-constants (values easily available to the runtime)
   1.556 +  if (is_empty_encoding() && is_tls_instruction())
   1.557 +    rematerialize = true;
   1.558 +
   1.559 +  // 1-input, 1-output, such as copies or increments.
   1.560 +  if( _components.count() == 2 &&
   1.561 +      _components[0]->is(Component::DEF) &&
   1.562 +      _components[1]->isa(Component::USE) )
   1.563 +    rematerialize = true;
   1.564 +
   1.565 +  // Check for an ideal 'Load?' and eliminate rematerialize option
   1.566 +  if ( is_ideal_load() != Form::none || // Ideal load?  Do not rematerialize
   1.567 +       is_ideal_copy() != Form::none || // Ideal copy?  Do not rematerialize
   1.568 +       is_expensive()  != Form::none) { // Expensive?   Do not rematerialize
   1.569 +    rematerialize = false;
   1.570 +  }
   1.571 +
   1.572 +  // Always rematerialize the flags.  They are more expensive to save &
   1.573 +  // restore than to recompute (and possibly spill the compare's inputs).
   1.574 +  if( _components.count() >= 1 ) {
   1.575 +    Component *c = _components[0];
   1.576 +    const Form *form = globals[c->_type];
   1.577 +    OperandForm *opform = form->is_operand();
   1.578 +    if( opform ) {
   1.579 +      // Avoid the special stack_slots register classes
   1.580 +      const char *rc_name = opform->constrained_reg_class();
   1.581 +      if( rc_name ) {
   1.582 +        if( strcmp(rc_name,"stack_slots") ) {
   1.583 +          // Check for ideal_type of RegFlags
   1.584 +          const char *type = opform->ideal_type( globals, registers );
   1.585 +          if( (type != NULL) && !strcmp(type, "RegFlags") )
   1.586 +            rematerialize = true;
   1.587 +        } else
   1.588 +          rematerialize = false; // Do not rematerialize things target stk
   1.589 +      }
   1.590 +    }
   1.591 +  }
   1.592 +
   1.593 +  return rematerialize;
   1.594 +}
   1.595 +
   1.596 +// loads from memory, so must check for anti-dependence
   1.597 +bool InstructForm::needs_anti_dependence_check(FormDict &globals) const {
   1.598 +  if ( skip_antidep_check() ) return false;
   1.599 +
   1.600 +  // Machine independent loads must be checked for anti-dependences
   1.601 +  if( is_ideal_load() != Form::none )  return true;
   1.602 +
   1.603 +  // !!!!! !!!!! !!!!!
   1.604 +  // TEMPORARY
   1.605 +  // if( is_simple_chain_rule(globals) )  return false;
   1.606 +
   1.607 +  // String.(compareTo/equals/indexOf) and Arrays.equals use many memorys edges,
   1.608 +  // but writes none
   1.609 +  if( _matrule && _matrule->_rChild &&
   1.610 +      ( strcmp(_matrule->_rChild->_opType,"StrComp"    )==0 ||
   1.611 +        strcmp(_matrule->_rChild->_opType,"StrEquals"  )==0 ||
   1.612 +        strcmp(_matrule->_rChild->_opType,"StrIndexOf" )==0 ||
   1.613 +        strcmp(_matrule->_rChild->_opType,"AryEq"      )==0 ))
   1.614 +    return true;
   1.615 +
   1.616 +  // Check if instruction has a USE of a memory operand class, but no defs
   1.617 +  bool USE_of_memory  = false;
   1.618 +  bool DEF_of_memory  = false;
   1.619 +  Component     *comp = NULL;
   1.620 +  ComponentList &components = (ComponentList &)_components;
   1.621 +
   1.622 +  components.reset();
   1.623 +  while( (comp = components.iter()) != NULL ) {
   1.624 +    const Form  *form = globals[comp->_type];
   1.625 +    if( !form ) continue;
   1.626 +    OpClassForm *op   = form->is_opclass();
   1.627 +    if( !op ) continue;
   1.628 +    if( form->interface_type(globals) == Form::memory_interface ) {
   1.629 +      if( comp->isa(Component::USE) ) USE_of_memory = true;
   1.630 +      if( comp->isa(Component::DEF) ) {
   1.631 +        OperandForm *oper = form->is_operand();
   1.632 +        if( oper && oper->is_user_name_for_sReg() ) {
   1.633 +          // Stack slots are unaliased memory handled by allocator
   1.634 +          oper = oper;  // debug stopping point !!!!!
   1.635 +        } else {
   1.636 +          DEF_of_memory = true;
   1.637 +        }
   1.638 +      }
   1.639 +    }
   1.640 +  }
   1.641 +  return (USE_of_memory && !DEF_of_memory);
   1.642 +}
   1.643 +
   1.644 +
   1.645 +bool InstructForm::is_wide_memory_kill(FormDict &globals) const {
   1.646 +  if( _matrule == NULL ) return false;
   1.647 +  if( !_matrule->_opType ) return false;
   1.648 +
   1.649 +  if( strcmp(_matrule->_opType,"MemBarRelease") == 0 ) return true;
   1.650 +  if( strcmp(_matrule->_opType,"MemBarAcquire") == 0 ) return true;
   1.651 +  if( strcmp(_matrule->_opType,"MemBarReleaseLock") == 0 ) return true;
   1.652 +  if( strcmp(_matrule->_opType,"MemBarAcquireLock") == 0 ) return true;
   1.653 +  if( strcmp(_matrule->_opType,"MemBarStoreStore") == 0 ) return true;
   1.654 +  if( strcmp(_matrule->_opType,"StoreFence") == 0 ) return true;
   1.655 +  if( strcmp(_matrule->_opType,"LoadFence") == 0 ) return true;
   1.656 +
   1.657 +  return false;
   1.658 +}
   1.659 +
   1.660 +int InstructForm::memory_operand(FormDict &globals) const {
   1.661 +  // Machine independent loads must be checked for anti-dependences
   1.662 +  // Check if instruction has a USE of a memory operand class, or a def.
   1.663 +  int USE_of_memory  = 0;
   1.664 +  int DEF_of_memory  = 0;
   1.665 +  const char*    last_memory_DEF = NULL; // to test DEF/USE pairing in asserts
   1.666 +  const char*    last_memory_USE = NULL;
   1.667 +  Component     *unique          = NULL;
   1.668 +  Component     *comp            = NULL;
   1.669 +  ComponentList &components      = (ComponentList &)_components;
   1.670 +
   1.671 +  components.reset();
   1.672 +  while( (comp = components.iter()) != NULL ) {
   1.673 +    const Form  *form = globals[comp->_type];
   1.674 +    if( !form ) continue;
   1.675 +    OpClassForm *op   = form->is_opclass();
   1.676 +    if( !op ) continue;
   1.677 +    if( op->stack_slots_only(globals) )  continue;
   1.678 +    if( form->interface_type(globals) == Form::memory_interface ) {
   1.679 +      if( comp->isa(Component::DEF) ) {
   1.680 +        last_memory_DEF = comp->_name;
   1.681 +        DEF_of_memory++;
   1.682 +        unique = comp;
   1.683 +      } else if( comp->isa(Component::USE) ) {
   1.684 +        if( last_memory_DEF != NULL ) {
   1.685 +          assert(0 == strcmp(last_memory_DEF, comp->_name), "every memory DEF is followed by a USE of the same name");
   1.686 +          last_memory_DEF = NULL;
   1.687 +        }
   1.688 +        // Handles same memory being used multiple times in the case of BMI1 instructions.
   1.689 +        if (last_memory_USE != NULL) {
   1.690 +          if (strcmp(comp->_name, last_memory_USE) != 0) {
   1.691 +            USE_of_memory++;
   1.692 +          }
   1.693 +        } else {
   1.694 +          USE_of_memory++;
   1.695 +        }
   1.696 +        last_memory_USE = comp->_name;
   1.697 +
   1.698 +        if (DEF_of_memory == 0)  // defs take precedence
   1.699 +          unique = comp;
   1.700 +      } else {
   1.701 +        assert(last_memory_DEF == NULL, "unpaired memory DEF");
   1.702 +      }
   1.703 +    }
   1.704 +  }
   1.705 +  assert(last_memory_DEF == NULL, "unpaired memory DEF");
   1.706 +  assert(USE_of_memory >= DEF_of_memory, "unpaired memory DEF");
   1.707 +  USE_of_memory -= DEF_of_memory;   // treat paired DEF/USE as one occurrence
   1.708 +  if( (USE_of_memory + DEF_of_memory) > 0 ) {
   1.709 +    if( is_simple_chain_rule(globals) ) {
   1.710 +      //fprintf(stderr, "Warning: chain rule is not really a memory user.\n");
   1.711 +      //((InstructForm*)this)->dump();
   1.712 +      // Preceding code prints nothing on sparc and these insns on intel:
   1.713 +      // leaP8 leaP32 leaPIdxOff leaPIdxScale leaPIdxScaleOff leaP8 leaP32
   1.714 +      // leaPIdxOff leaPIdxScale leaPIdxScaleOff
   1.715 +      return NO_MEMORY_OPERAND;
   1.716 +    }
   1.717 +
   1.718 +    if( DEF_of_memory == 1 ) {
   1.719 +      assert(unique != NULL, "");
   1.720 +      if( USE_of_memory == 0 ) {
   1.721 +        // unique def, no uses
   1.722 +      } else {
   1.723 +        // // unique def, some uses
   1.724 +        // // must return bottom unless all uses match def
   1.725 +        // unique = NULL;
   1.726 +      }
   1.727 +    } else if( DEF_of_memory > 0 ) {
   1.728 +      // multiple defs, don't care about uses
   1.729 +      unique = NULL;
   1.730 +    } else if( USE_of_memory == 1) {
   1.731 +      // unique use, no defs
   1.732 +      assert(unique != NULL, "");
   1.733 +    } else if( USE_of_memory > 0 ) {
   1.734 +      // multiple uses, no defs
   1.735 +      unique = NULL;
   1.736 +    } else {
   1.737 +      assert(false, "bad case analysis");
   1.738 +    }
   1.739 +    // process the unique DEF or USE, if there is one
   1.740 +    if( unique == NULL ) {
   1.741 +      return MANY_MEMORY_OPERANDS;
   1.742 +    } else {
   1.743 +      int pos = components.operand_position(unique->_name);
   1.744 +      if( unique->isa(Component::DEF) ) {
   1.745 +        pos += 1;                // get corresponding USE from DEF
   1.746 +      }
   1.747 +      assert(pos >= 1, "I was just looking at it!");
   1.748 +      return pos;
   1.749 +    }
   1.750 +  }
   1.751 +
   1.752 +  // missed the memory op??
   1.753 +  if( true ) {  // %%% should not be necessary
   1.754 +    if( is_ideal_store() != Form::none ) {
   1.755 +      fprintf(stderr, "Warning: cannot find memory opnd in instr.\n");
   1.756 +      ((InstructForm*)this)->dump();
   1.757 +      // pretend it has multiple defs and uses
   1.758 +      return MANY_MEMORY_OPERANDS;
   1.759 +    }
   1.760 +    if( is_ideal_load()  != Form::none ) {
   1.761 +      fprintf(stderr, "Warning: cannot find memory opnd in instr.\n");
   1.762 +      ((InstructForm*)this)->dump();
   1.763 +      // pretend it has multiple uses and no defs
   1.764 +      return MANY_MEMORY_OPERANDS;
   1.765 +    }
   1.766 +  }
   1.767 +
   1.768 +  return NO_MEMORY_OPERAND;
   1.769 +}
   1.770 +
   1.771 +
   1.772 +// This instruction captures the machine-independent bottom_type
   1.773 +// Expected use is for pointer vs oop determination for LoadP
   1.774 +bool InstructForm::captures_bottom_type(FormDict &globals) const {
   1.775 +  if( _matrule && _matrule->_rChild &&
   1.776 +       (!strcmp(_matrule->_rChild->_opType,"CastPP")       ||  // new result type
   1.777 +        !strcmp(_matrule->_rChild->_opType,"CastX2P")      ||  // new result type
   1.778 +        !strcmp(_matrule->_rChild->_opType,"DecodeN")      ||
   1.779 +        !strcmp(_matrule->_rChild->_opType,"EncodeP")      ||
   1.780 +        !strcmp(_matrule->_rChild->_opType,"DecodeNKlass") ||
   1.781 +        !strcmp(_matrule->_rChild->_opType,"EncodePKlass") ||
   1.782 +        !strcmp(_matrule->_rChild->_opType,"LoadN")        ||
   1.783 +        !strcmp(_matrule->_rChild->_opType,"LoadNKlass")   ||
   1.784 +        !strcmp(_matrule->_rChild->_opType,"CreateEx")     ||  // type of exception
   1.785 +        !strcmp(_matrule->_rChild->_opType,"CheckCastPP")  ||
   1.786 +        !strcmp(_matrule->_rChild->_opType,"GetAndSetP")   ||
   1.787 +        !strcmp(_matrule->_rChild->_opType,"GetAndSetN")) )  return true;
   1.788 +  else if ( is_ideal_load() == Form::idealP )                return true;
   1.789 +  else if ( is_ideal_store() != Form::none  )                return true;
   1.790 +
   1.791 +  if (needs_base_oop_edge(globals)) return true;
   1.792 +
   1.793 +  if (is_vector()) return true;
   1.794 +  if (is_mach_constant()) return true;
   1.795 +
   1.796 +  return  false;
   1.797 +}
   1.798 +
   1.799 +
   1.800 +// Access instr_cost attribute or return NULL.
   1.801 +const char* InstructForm::cost() {
   1.802 +  for (Attribute* cur = _attribs; cur != NULL; cur = (Attribute*)cur->_next) {
   1.803 +    if( strcmp(cur->_ident,AttributeForm::_ins_cost) == 0 ) {
   1.804 +      return cur->_val;
   1.805 +    }
   1.806 +  }
   1.807 +  return NULL;
   1.808 +}
   1.809 +
   1.810 +// Return count of top-level operands.
   1.811 +uint InstructForm::num_opnds() {
   1.812 +  int  num_opnds = _components.num_operands();
   1.813 +
   1.814 +  // Need special handling for matching some ideal nodes
   1.815 +  // i.e. Matching a return node
   1.816 +  /*
   1.817 +  if( _matrule ) {
   1.818 +    if( strcmp(_matrule->_opType,"Return"   )==0 ||
   1.819 +        strcmp(_matrule->_opType,"Halt"     )==0 )
   1.820 +      return 3;
   1.821 +  }
   1.822 +    */
   1.823 +  return num_opnds;
   1.824 +}
   1.825 +
   1.826 +const char* InstructForm::opnd_ident(int idx) {
   1.827 +  return _components.at(idx)->_name;
   1.828 +}
   1.829 +
   1.830 +const char* InstructForm::unique_opnd_ident(uint idx) {
   1.831 +  uint i;
   1.832 +  for (i = 1; i < num_opnds(); ++i) {
   1.833 +    if (unique_opnds_idx(i) == idx) {
   1.834 +      break;
   1.835 +    }
   1.836 +  }
   1.837 +  return (_components.at(i) != NULL) ? _components.at(i)->_name : "";
   1.838 +}
   1.839 +
   1.840 +// Return count of unmatched operands.
   1.841 +uint InstructForm::num_post_match_opnds() {
   1.842 +  uint  num_post_match_opnds = _components.count();
   1.843 +  uint  num_match_opnds = _components.match_count();
   1.844 +  num_post_match_opnds = num_post_match_opnds - num_match_opnds;
   1.845 +
   1.846 +  return num_post_match_opnds;
   1.847 +}
   1.848 +
   1.849 +// Return the number of leaves below this complex operand
   1.850 +uint InstructForm::num_consts(FormDict &globals) const {
   1.851 +  if ( ! _matrule) return 0;
   1.852 +
   1.853 +  // This is a recursive invocation on all operands in the matchrule
   1.854 +  return _matrule->num_consts(globals);
   1.855 +}
   1.856 +
   1.857 +// Constants in match rule with specified type
   1.858 +uint InstructForm::num_consts(FormDict &globals, Form::DataType type) const {
   1.859 +  if ( ! _matrule) return 0;
   1.860 +
   1.861 +  // This is a recursive invocation on all operands in the matchrule
   1.862 +  return _matrule->num_consts(globals, type);
   1.863 +}
   1.864 +
   1.865 +
   1.866 +// Return the register class associated with 'leaf'.
   1.867 +const char *InstructForm::out_reg_class(FormDict &globals) {
   1.868 +  assert( false, "InstructForm::out_reg_class(FormDict &globals); Not Implemented");
   1.869 +
   1.870 +  return NULL;
   1.871 +}
   1.872 +
   1.873 +
   1.874 +
   1.875 +// Lookup the starting position of inputs we are interested in wrt. ideal nodes
   1.876 +uint InstructForm::oper_input_base(FormDict &globals) {
   1.877 +  if( !_matrule ) return 1;     // Skip control for most nodes
   1.878 +
   1.879 +  // Need special handling for matching some ideal nodes
   1.880 +  // i.e. Matching a return node
   1.881 +  if( strcmp(_matrule->_opType,"Return"    )==0 ||
   1.882 +      strcmp(_matrule->_opType,"Rethrow"   )==0 ||
   1.883 +      strcmp(_matrule->_opType,"TailCall"  )==0 ||
   1.884 +      strcmp(_matrule->_opType,"TailJump"  )==0 ||
   1.885 +      strcmp(_matrule->_opType,"SafePoint" )==0 ||
   1.886 +      strcmp(_matrule->_opType,"Halt"      )==0 )
   1.887 +    return AdlcVMDeps::Parms;   // Skip the machine-state edges
   1.888 +
   1.889 +  if( _matrule->_rChild &&
   1.890 +      ( strcmp(_matrule->_rChild->_opType,"AryEq"     )==0 ||
   1.891 +        strcmp(_matrule->_rChild->_opType,"StrComp"   )==0 ||
   1.892 +        strcmp(_matrule->_rChild->_opType,"StrEquals" )==0 ||
   1.893 +        strcmp(_matrule->_rChild->_opType,"StrIndexOf")==0 ||
   1.894 +        strcmp(_matrule->_rChild->_opType,"EncodeISOArray")==0)) {
   1.895 +        // String.(compareTo/equals/indexOf) and Arrays.equals
   1.896 +        // and sun.nio.cs.iso8859_1$Encoder.EncodeISOArray
   1.897 +        // take 1 control and 1 memory edges.
   1.898 +    return 2;
   1.899 +  }
   1.900 +
   1.901 +  // Check for handling of 'Memory' input/edge in the ideal world.
   1.902 +  // The AD file writer is shielded from knowledge of these edges.
   1.903 +  int base = 1;                 // Skip control
   1.904 +  base += _matrule->needs_ideal_memory_edge(globals);
   1.905 +
   1.906 +  // Also skip the base-oop value for uses of derived oops.
   1.907 +  // The AD file writer is shielded from knowledge of these edges.
   1.908 +  base += needs_base_oop_edge(globals);
   1.909 +
   1.910 +  return base;
   1.911 +}
   1.912 +
   1.913 +// This function determines the order of the MachOper in _opnds[]
   1.914 +// by writing the operand names into the _components list.
   1.915 +//
   1.916 +// Implementation does not modify state of internal structures
   1.917 +void InstructForm::build_components() {
   1.918 +  // Add top-level operands to the components
   1.919 +  if (_matrule)  _matrule->append_components(_localNames, _components);
   1.920 +
   1.921 +  // Add parameters that "do not appear in match rule".
   1.922 +  bool has_temp = false;
   1.923 +  const char *name;
   1.924 +  const char *kill_name = NULL;
   1.925 +  for (_parameters.reset(); (name = _parameters.iter()) != NULL;) {
   1.926 +    OperandForm *opForm = (OperandForm*)_localNames[name];
   1.927 +
   1.928 +    Effect* e = NULL;
   1.929 +    {
   1.930 +      const Form* form = _effects[name];
   1.931 +      e = form ? form->is_effect() : NULL;
   1.932 +    }
   1.933 +
   1.934 +    if (e != NULL) {
   1.935 +      has_temp |= e->is(Component::TEMP);
   1.936 +
   1.937 +      // KILLs must be declared after any TEMPs because TEMPs are real
   1.938 +      // uses so their operand numbering must directly follow the real
   1.939 +      // inputs from the match rule.  Fixing the numbering seems
   1.940 +      // complex so simply enforce the restriction during parse.
   1.941 +      if (kill_name != NULL &&
   1.942 +          e->isa(Component::TEMP) && !e->isa(Component::DEF)) {
   1.943 +        OperandForm* kill = (OperandForm*)_localNames[kill_name];
   1.944 +        globalAD->syntax_err(_linenum, "%s: %s %s must be at the end of the argument list\n",
   1.945 +                             _ident, kill->_ident, kill_name);
   1.946 +      } else if (e->isa(Component::KILL) && !e->isa(Component::USE)) {
   1.947 +        kill_name = name;
   1.948 +      }
   1.949 +    }
   1.950 +
   1.951 +    const Component *component  = _components.search(name);
   1.952 +    if ( component  == NULL ) {
   1.953 +      if (e) {
   1.954 +        _components.insert(name, opForm->_ident, e->_use_def, false);
   1.955 +        component = _components.search(name);
   1.956 +        if (component->isa(Component::USE) && !component->isa(Component::TEMP) && _matrule) {
   1.957 +          const Form *form = globalAD->globalNames()[component->_type];
   1.958 +          assert( form, "component type must be a defined form");
   1.959 +          OperandForm *op   = form->is_operand();
   1.960 +          if (op->_interface && op->_interface->is_RegInterface()) {
   1.961 +            globalAD->syntax_err(_linenum, "%s: illegal USE of non-input: %s %s\n",
   1.962 +                                 _ident, opForm->_ident, name);
   1.963 +          }
   1.964 +        }
   1.965 +      } else {
   1.966 +        // This would be a nice warning but it triggers in a few places in a benign way
   1.967 +        // if (_matrule != NULL && !expands()) {
   1.968 +        //   globalAD->syntax_err(_linenum, "%s: %s %s not mentioned in effect or match rule\n",
   1.969 +        //                        _ident, opForm->_ident, name);
   1.970 +        // }
   1.971 +        _components.insert(name, opForm->_ident, Component::INVALID, false);
   1.972 +      }
   1.973 +    }
   1.974 +    else if (e) {
   1.975 +      // Component was found in the list
   1.976 +      // Check if there is a new effect that requires an extra component.
   1.977 +      // This happens when adding 'USE' to a component that is not yet one.
   1.978 +      if ((!component->isa( Component::USE) && ((e->_use_def & Component::USE) != 0))) {
   1.979 +        if (component->isa(Component::USE) && _matrule) {
   1.980 +          const Form *form = globalAD->globalNames()[component->_type];
   1.981 +          assert( form, "component type must be a defined form");
   1.982 +          OperandForm *op   = form->is_operand();
   1.983 +          if (op->_interface && op->_interface->is_RegInterface()) {
   1.984 +            globalAD->syntax_err(_linenum, "%s: illegal USE of non-input: %s %s\n",
   1.985 +                                 _ident, opForm->_ident, name);
   1.986 +          }
   1.987 +        }
   1.988 +        _components.insert(name, opForm->_ident, e->_use_def, false);
   1.989 +      } else {
   1.990 +        Component  *comp = (Component*)component;
   1.991 +        comp->promote_use_def_info(e->_use_def);
   1.992 +      }
   1.993 +      // Component positions are zero based.
   1.994 +      int  pos  = _components.operand_position(name);
   1.995 +      assert( ! (component->isa(Component::DEF) && (pos >= 1)),
   1.996 +              "Component::DEF can only occur in the first position");
   1.997 +    }
   1.998 +  }
   1.999 +
  1.1000 +  // Resolving the interactions between expand rules and TEMPs would
  1.1001 +  // be complex so simply disallow it.
  1.1002 +  if (_matrule == NULL && has_temp) {
  1.1003 +    globalAD->syntax_err(_linenum, "%s: TEMPs without match rule isn't supported\n", _ident);
  1.1004 +  }
  1.1005 +
  1.1006 +  return;
  1.1007 +}
  1.1008 +
  1.1009 +// Return zero-based position in component list;  -1 if not in list.
  1.1010 +int   InstructForm::operand_position(const char *name, int usedef) {
  1.1011 +  return unique_opnds_idx(_components.operand_position(name, usedef, this));
  1.1012 +}
  1.1013 +
  1.1014 +int   InstructForm::operand_position_format(const char *name) {
  1.1015 +  return unique_opnds_idx(_components.operand_position_format(name, this));
  1.1016 +}
  1.1017 +
  1.1018 +// Return zero-based position in component list; -1 if not in list.
  1.1019 +int   InstructForm::label_position() {
  1.1020 +  return unique_opnds_idx(_components.label_position());
  1.1021 +}
  1.1022 +
  1.1023 +int   InstructForm::method_position() {
  1.1024 +  return unique_opnds_idx(_components.method_position());
  1.1025 +}
  1.1026 +
  1.1027 +// Return number of relocation entries needed for this instruction.
  1.1028 +uint  InstructForm::reloc(FormDict &globals) {
  1.1029 +  uint reloc_entries  = 0;
  1.1030 +  // Check for "Call" nodes
  1.1031 +  if ( is_ideal_call() )      ++reloc_entries;
  1.1032 +  if ( is_ideal_return() )    ++reloc_entries;
  1.1033 +  if ( is_ideal_safepoint() ) ++reloc_entries;
  1.1034 +
  1.1035 +
  1.1036 +  // Check if operands MAYBE oop pointers, by checking for ConP elements
  1.1037 +  // Proceed through the leaves of the match-tree and check for ConPs
  1.1038 +  if ( _matrule != NULL ) {
  1.1039 +    uint         position = 0;
  1.1040 +    const char  *result   = NULL;
  1.1041 +    const char  *name     = NULL;
  1.1042 +    const char  *opType   = NULL;
  1.1043 +    while (_matrule->base_operand(position, globals, result, name, opType)) {
  1.1044 +      if ( strcmp(opType,"ConP") == 0 ) {
  1.1045 +#ifdef SPARC
  1.1046 +        reloc_entries += 2; // 1 for sethi + 1 for setlo
  1.1047 +#else
  1.1048 +        ++reloc_entries;
  1.1049 +#endif
  1.1050 +      }
  1.1051 +      ++position;
  1.1052 +    }
  1.1053 +  }
  1.1054 +
  1.1055 +  // Above is only a conservative estimate
  1.1056 +  // because it did not check contents of operand classes.
  1.1057 +  // !!!!! !!!!!
  1.1058 +  // Add 1 to reloc info for each operand class in the component list.
  1.1059 +  Component  *comp;
  1.1060 +  _components.reset();
  1.1061 +  while ( (comp = _components.iter()) != NULL ) {
  1.1062 +    const Form        *form = globals[comp->_type];
  1.1063 +    assert( form, "Did not find component's type in global names");
  1.1064 +    const OpClassForm *opc  = form->is_opclass();
  1.1065 +    const OperandForm *oper = form->is_operand();
  1.1066 +    if ( opc && (oper == NULL) ) {
  1.1067 +      ++reloc_entries;
  1.1068 +    } else if ( oper ) {
  1.1069 +      // floats and doubles loaded out of method's constant pool require reloc info
  1.1070 +      Form::DataType type = oper->is_base_constant(globals);
  1.1071 +      if ( (type == Form::idealF) || (type == Form::idealD) ) {
  1.1072 +        ++reloc_entries;
  1.1073 +      }
  1.1074 +    }
  1.1075 +  }
  1.1076 +
  1.1077 +  // Float and Double constants may come from the CodeBuffer table
  1.1078 +  // and require relocatable addresses for access
  1.1079 +  // !!!!!
  1.1080 +  // Check for any component being an immediate float or double.
  1.1081 +  Form::DataType data_type = is_chain_of_constant(globals);
  1.1082 +  if( data_type==idealD || data_type==idealF ) {
  1.1083 +#ifdef SPARC
  1.1084 +    // sparc required more relocation entries for floating constants
  1.1085 +    // (expires 9/98)
  1.1086 +    reloc_entries += 6;
  1.1087 +#else
  1.1088 +    reloc_entries++;
  1.1089 +#endif
  1.1090 +  }
  1.1091 +
  1.1092 +  return reloc_entries;
  1.1093 +}
  1.1094 +
  1.1095 +// Utility function defined in archDesc.cpp
  1.1096 +extern bool is_def(int usedef);
  1.1097 +
  1.1098 +// Return the result of reducing an instruction
  1.1099 +const char *InstructForm::reduce_result() {
  1.1100 +  const char* result = "Universe";  // default
  1.1101 +  _components.reset();
  1.1102 +  Component *comp = _components.iter();
  1.1103 +  if (comp != NULL && comp->isa(Component::DEF)) {
  1.1104 +    result = comp->_type;
  1.1105 +    // Override this if the rule is a store operation:
  1.1106 +    if (_matrule && _matrule->_rChild &&
  1.1107 +        is_store_to_memory(_matrule->_rChild->_opType))
  1.1108 +      result = "Universe";
  1.1109 +  }
  1.1110 +  return result;
  1.1111 +}
  1.1112 +
  1.1113 +// Return the name of the operand on the right hand side of the binary match
  1.1114 +// Return NULL if there is no right hand side
  1.1115 +const char *InstructForm::reduce_right(FormDict &globals)  const {
  1.1116 +  if( _matrule == NULL ) return NULL;
  1.1117 +  return  _matrule->reduce_right(globals);
  1.1118 +}
  1.1119 +
  1.1120 +// Similar for left
  1.1121 +const char *InstructForm::reduce_left(FormDict &globals)   const {
  1.1122 +  if( _matrule == NULL ) return NULL;
  1.1123 +  return  _matrule->reduce_left(globals);
  1.1124 +}
  1.1125 +
  1.1126 +
  1.1127 +// Base class for this instruction, MachNode except for calls
  1.1128 +const char *InstructForm::mach_base_class(FormDict &globals)  const {
  1.1129 +  if( is_ideal_call() == Form::JAVA_STATIC ) {
  1.1130 +    return "MachCallStaticJavaNode";
  1.1131 +  }
  1.1132 +  else if( is_ideal_call() == Form::JAVA_DYNAMIC ) {
  1.1133 +    return "MachCallDynamicJavaNode";
  1.1134 +  }
  1.1135 +  else if( is_ideal_call() == Form::JAVA_RUNTIME ) {
  1.1136 +    return "MachCallRuntimeNode";
  1.1137 +  }
  1.1138 +  else if( is_ideal_call() == Form::JAVA_LEAF ) {
  1.1139 +    return "MachCallLeafNode";
  1.1140 +  }
  1.1141 +  else if (is_ideal_return()) {
  1.1142 +    return "MachReturnNode";
  1.1143 +  }
  1.1144 +  else if (is_ideal_halt()) {
  1.1145 +    return "MachHaltNode";
  1.1146 +  }
  1.1147 +  else if (is_ideal_safepoint()) {
  1.1148 +    return "MachSafePointNode";
  1.1149 +  }
  1.1150 +  else if (is_ideal_if()) {
  1.1151 +    return "MachIfNode";
  1.1152 +  }
  1.1153 +  else if (is_ideal_goto()) {
  1.1154 +    return "MachGotoNode";
  1.1155 +  }
  1.1156 +  else if (is_ideal_fastlock()) {
  1.1157 +    return "MachFastLockNode";
  1.1158 +  }
  1.1159 +  else if (is_ideal_nop()) {
  1.1160 +    return "MachNopNode";
  1.1161 +  }
  1.1162 +  else if (is_mach_constant()) {
  1.1163 +    return "MachConstantNode";
  1.1164 +  }
  1.1165 +  else if (captures_bottom_type(globals)) {
  1.1166 +    return "MachTypeNode";
  1.1167 +  } else {
  1.1168 +    return "MachNode";
  1.1169 +  }
  1.1170 +  assert( false, "ShouldNotReachHere()");
  1.1171 +  return NULL;
  1.1172 +}
  1.1173 +
  1.1174 +// Compare the instruction predicates for textual equality
  1.1175 +bool equivalent_predicates( const InstructForm *instr1, const InstructForm *instr2 ) {
  1.1176 +  const Predicate *pred1  = instr1->_predicate;
  1.1177 +  const Predicate *pred2  = instr2->_predicate;
  1.1178 +  if( pred1 == NULL && pred2 == NULL ) {
  1.1179 +    // no predicates means they are identical
  1.1180 +    return true;
  1.1181 +  }
  1.1182 +  if( pred1 != NULL && pred2 != NULL ) {
  1.1183 +    // compare the predicates
  1.1184 +    if (ADLParser::equivalent_expressions(pred1->_pred, pred2->_pred)) {
  1.1185 +      return true;
  1.1186 +    }
  1.1187 +  }
  1.1188 +
  1.1189 +  return false;
  1.1190 +}
  1.1191 +
  1.1192 +// Check if this instruction can cisc-spill to 'alternate'
  1.1193 +bool InstructForm::cisc_spills_to(ArchDesc &AD, InstructForm *instr) {
  1.1194 +  assert( _matrule != NULL && instr->_matrule != NULL, "must have match rules");
  1.1195 +  // Do not replace if a cisc-version has been found.
  1.1196 +  if( cisc_spill_operand() != Not_cisc_spillable ) return false;
  1.1197 +
  1.1198 +  int         cisc_spill_operand = Maybe_cisc_spillable;
  1.1199 +  char       *result             = NULL;
  1.1200 +  char       *result2            = NULL;
  1.1201 +  const char *op_name            = NULL;
  1.1202 +  const char *reg_type           = NULL;
  1.1203 +  FormDict   &globals            = AD.globalNames();
  1.1204 +  cisc_spill_operand = _matrule->matchrule_cisc_spill_match(globals, AD.get_registers(), instr->_matrule, op_name, reg_type);
  1.1205 +  if( (cisc_spill_operand != Not_cisc_spillable) && (op_name != NULL) && equivalent_predicates(this, instr) ) {
  1.1206 +    cisc_spill_operand = operand_position(op_name, Component::USE);
  1.1207 +    int def_oper  = operand_position(op_name, Component::DEF);
  1.1208 +    if( def_oper == NameList::Not_in_list && instr->num_opnds() == num_opnds()) {
  1.1209 +      // Do not support cisc-spilling for destination operands and
  1.1210 +      // make sure they have the same number of operands.
  1.1211 +      _cisc_spill_alternate = instr;
  1.1212 +      instr->set_cisc_alternate(true);
  1.1213 +      if( AD._cisc_spill_debug ) {
  1.1214 +        fprintf(stderr, "Instruction %s cisc-spills-to %s\n", _ident, instr->_ident);
  1.1215 +        fprintf(stderr, "   using operand %s %s at index %d\n", reg_type, op_name, cisc_spill_operand);
  1.1216 +      }
  1.1217 +      // Record that a stack-version of the reg_mask is needed
  1.1218 +      // !!!!!
  1.1219 +      OperandForm *oper = (OperandForm*)(globals[reg_type]->is_operand());
  1.1220 +      assert( oper != NULL, "cisc-spilling non operand");
  1.1221 +      const char *reg_class_name = oper->constrained_reg_class();
  1.1222 +      AD.set_stack_or_reg(reg_class_name);
  1.1223 +      const char *reg_mask_name  = AD.reg_mask(*oper);
  1.1224 +      set_cisc_reg_mask_name(reg_mask_name);
  1.1225 +      const char *stack_or_reg_mask_name = AD.stack_or_reg_mask(*oper);
  1.1226 +    } else {
  1.1227 +      cisc_spill_operand = Not_cisc_spillable;
  1.1228 +    }
  1.1229 +  } else {
  1.1230 +    cisc_spill_operand = Not_cisc_spillable;
  1.1231 +  }
  1.1232 +
  1.1233 +  set_cisc_spill_operand(cisc_spill_operand);
  1.1234 +  return (cisc_spill_operand != Not_cisc_spillable);
  1.1235 +}
  1.1236 +
  1.1237 +// Check to see if this instruction can be replaced with the short branch
  1.1238 +// instruction `short-branch'
  1.1239 +bool InstructForm::check_branch_variant(ArchDesc &AD, InstructForm *short_branch) {
  1.1240 +  if (_matrule != NULL &&
  1.1241 +      this != short_branch &&   // Don't match myself
  1.1242 +      !is_short_branch() &&     // Don't match another short branch variant
  1.1243 +      reduce_result() != NULL &&
  1.1244 +      strcmp(reduce_result(), short_branch->reduce_result()) == 0 &&
  1.1245 +      _matrule->equivalent(AD.globalNames(), short_branch->_matrule)) {
  1.1246 +    // The instructions are equivalent.
  1.1247 +
  1.1248 +    // Now verify that both instructions have the same parameters and
  1.1249 +    // the same effects. Both branch forms should have the same inputs
  1.1250 +    // and resulting projections to correctly replace a long branch node
  1.1251 +    // with corresponding short branch node during code generation.
  1.1252 +
  1.1253 +    bool different = false;
  1.1254 +    if (short_branch->_components.count() != _components.count()) {
  1.1255 +       different = true;
  1.1256 +    } else if (_components.count() > 0) {
  1.1257 +      short_branch->_components.reset();
  1.1258 +      _components.reset();
  1.1259 +      Component *comp;
  1.1260 +      while ((comp = _components.iter()) != NULL) {
  1.1261 +        Component *short_comp = short_branch->_components.iter();
  1.1262 +        if (short_comp == NULL ||
  1.1263 +            short_comp->_type != comp->_type ||
  1.1264 +            short_comp->_usedef != comp->_usedef) {
  1.1265 +          different = true;
  1.1266 +          break;
  1.1267 +        }
  1.1268 +      }
  1.1269 +      if (short_branch->_components.iter() != NULL)
  1.1270 +        different = true;
  1.1271 +    }
  1.1272 +    if (different) {
  1.1273 +      globalAD->syntax_err(short_branch->_linenum, "Instruction %s and its short form %s have different parameters\n", _ident, short_branch->_ident);
  1.1274 +    }
  1.1275 +    if (AD._adl_debug > 1 || AD._short_branch_debug) {
  1.1276 +      fprintf(stderr, "Instruction %s has short form %s\n", _ident, short_branch->_ident);
  1.1277 +    }
  1.1278 +    _short_branch_form = short_branch;
  1.1279 +    return true;
  1.1280 +  }
  1.1281 +  return false;
  1.1282 +}
  1.1283 +
  1.1284 +
  1.1285 +// --------------------------- FILE *output_routines
  1.1286 +//
  1.1287 +// Generate the format call for the replacement variable
  1.1288 +void InstructForm::rep_var_format(FILE *fp, const char *rep_var) {
  1.1289 +  // Handle special constant table variables.
  1.1290 +  if (strcmp(rep_var, "constanttablebase") == 0) {
  1.1291 +    fprintf(fp, "char reg[128];  ra->dump_register(in(mach_constant_base_node_input()), reg);\n");
  1.1292 +    fprintf(fp, "    st->print(\"%%s\", reg);\n");
  1.1293 +    return;
  1.1294 +  }
  1.1295 +  if (strcmp(rep_var, "constantoffset") == 0) {
  1.1296 +    fprintf(fp, "st->print(\"#%%d\", constant_offset_unchecked());\n");
  1.1297 +    return;
  1.1298 +  }
  1.1299 +  if (strcmp(rep_var, "constantaddress") == 0) {
  1.1300 +    fprintf(fp, "st->print(\"constant table base + #%%d\", constant_offset_unchecked());\n");
  1.1301 +    return;
  1.1302 +  }
  1.1303 +
  1.1304 +  // Find replacement variable's type
  1.1305 +  const Form *form   = _localNames[rep_var];
  1.1306 +  if (form == NULL) {
  1.1307 +    globalAD->syntax_err(_linenum, "Unknown replacement variable %s in format statement of %s.",
  1.1308 +                         rep_var, _ident);
  1.1309 +    return;
  1.1310 +  }
  1.1311 +  OpClassForm *opc   = form->is_opclass();
  1.1312 +  assert( opc, "replacement variable was not found in local names");
  1.1313 +  // Lookup the index position of the replacement variable
  1.1314 +  int idx  = operand_position_format(rep_var);
  1.1315 +  if ( idx == -1 ) {
  1.1316 +    globalAD->syntax_err(_linenum, "Could not find replacement variable %s in format statement of %s.\n",
  1.1317 +                         rep_var, _ident);
  1.1318 +    assert(strcmp(opc->_ident, "label") == 0, "Unimplemented");
  1.1319 +    return;
  1.1320 +  }
  1.1321 +
  1.1322 +  if (is_noninput_operand(idx)) {
  1.1323 +    // This component isn't in the input array.  Print out the static
  1.1324 +    // name of the register.
  1.1325 +    OperandForm* oper = form->is_operand();
  1.1326 +    if (oper != NULL && oper->is_bound_register()) {
  1.1327 +      const RegDef* first = oper->get_RegClass()->find_first_elem();
  1.1328 +      fprintf(fp, "    st->print_raw(\"%s\");\n", first->_regname);
  1.1329 +    } else {
  1.1330 +      globalAD->syntax_err(_linenum, "In %s can't find format for %s %s", _ident, opc->_ident, rep_var);
  1.1331 +    }
  1.1332 +  } else {
  1.1333 +    // Output the format call for this operand
  1.1334 +    fprintf(fp,"opnd_array(%d)->",idx);
  1.1335 +    if (idx == 0)
  1.1336 +      fprintf(fp,"int_format(ra, this, st); // %s\n", rep_var);
  1.1337 +    else
  1.1338 +      fprintf(fp,"ext_format(ra, this,idx%d, st); // %s\n", idx, rep_var );
  1.1339 +  }
  1.1340 +}
  1.1341 +
  1.1342 +// Seach through operands to determine parameters unique positions.
  1.1343 +void InstructForm::set_unique_opnds() {
  1.1344 +  uint* uniq_idx = NULL;
  1.1345 +  uint  nopnds = num_opnds();
  1.1346 +  uint  num_uniq = nopnds;
  1.1347 +  uint i;
  1.1348 +  _uniq_idx_length = 0;
  1.1349 +  if (nopnds > 0) {
  1.1350 +    // Allocate index array.  Worst case we're mapping from each
  1.1351 +    // component back to an index and any DEF always goes at 0 so the
  1.1352 +    // length of the array has to be the number of components + 1.
  1.1353 +    _uniq_idx_length = _components.count() + 1;
  1.1354 +    uniq_idx = (uint*) malloc(sizeof(uint) * _uniq_idx_length);
  1.1355 +    for (i = 0; i < _uniq_idx_length; i++) {
  1.1356 +      uniq_idx[i] = i;
  1.1357 +    }
  1.1358 +  }
  1.1359 +  // Do it only if there is a match rule and no expand rule.  With an
  1.1360 +  // expand rule it is done by creating new mach node in Expand()
  1.1361 +  // method.
  1.1362 +  if (nopnds > 0 && _matrule != NULL && _exprule == NULL) {
  1.1363 +    const char *name;
  1.1364 +    uint count;
  1.1365 +    bool has_dupl_use = false;
  1.1366 +
  1.1367 +    _parameters.reset();
  1.1368 +    while ((name = _parameters.iter()) != NULL) {
  1.1369 +      count = 0;
  1.1370 +      uint position = 0;
  1.1371 +      uint uniq_position = 0;
  1.1372 +      _components.reset();
  1.1373 +      Component *comp = NULL;
  1.1374 +      if (sets_result()) {
  1.1375 +        comp = _components.iter();
  1.1376 +        position++;
  1.1377 +      }
  1.1378 +      // The next code is copied from the method operand_position().
  1.1379 +      for (; (comp = _components.iter()) != NULL; ++position) {
  1.1380 +        // When the first component is not a DEF,
  1.1381 +        // leave space for the result operand!
  1.1382 +        if (position==0 && (!comp->isa(Component::DEF))) {
  1.1383 +          ++position;
  1.1384 +        }
  1.1385 +        if (strcmp(name, comp->_name) == 0) {
  1.1386 +          if (++count > 1) {
  1.1387 +            assert(position < _uniq_idx_length, "out of bounds");
  1.1388 +            uniq_idx[position] = uniq_position;
  1.1389 +            has_dupl_use = true;
  1.1390 +          } else {
  1.1391 +            uniq_position = position;
  1.1392 +          }
  1.1393 +        }
  1.1394 +        if (comp->isa(Component::DEF) && comp->isa(Component::USE)) {
  1.1395 +          ++position;
  1.1396 +          if (position != 1)
  1.1397 +            --position;   // only use two slots for the 1st USE_DEF
  1.1398 +        }
  1.1399 +      }
  1.1400 +    }
  1.1401 +    if (has_dupl_use) {
  1.1402 +      for (i = 1; i < nopnds; i++) {
  1.1403 +        if (i != uniq_idx[i]) {
  1.1404 +          break;
  1.1405 +        }
  1.1406 +      }
  1.1407 +      uint j = i;
  1.1408 +      for (; i < nopnds; i++) {
  1.1409 +        if (i == uniq_idx[i]) {
  1.1410 +          uniq_idx[i] = j++;
  1.1411 +        }
  1.1412 +      }
  1.1413 +      num_uniq = j;
  1.1414 +    }
  1.1415 +  }
  1.1416 +  _uniq_idx = uniq_idx;
  1.1417 +  _num_uniq = num_uniq;
  1.1418 +}
  1.1419 +
  1.1420 +// Generate index values needed for determining the operand position
  1.1421 +void InstructForm::index_temps(FILE *fp, FormDict &globals, const char *prefix, const char *receiver) {
  1.1422 +  uint  idx = 0;                  // position of operand in match rule
  1.1423 +  int   cur_num_opnds = num_opnds();
  1.1424 +
  1.1425 +  // Compute the index into vector of operand pointers:
  1.1426 +  // idx0=0 is used to indicate that info comes from this same node, not from input edge.
  1.1427 +  // idx1 starts at oper_input_base()
  1.1428 +  if ( cur_num_opnds >= 1 ) {
  1.1429 +    fprintf(fp,"  // Start at oper_input_base() and count operands\n");
  1.1430 +    fprintf(fp,"  unsigned %sidx0 = %d;\n", prefix, oper_input_base(globals));
  1.1431 +    fprintf(fp,"  unsigned %sidx1 = %d;", prefix, oper_input_base(globals));
  1.1432 +    fprintf(fp," \t// %s\n", unique_opnd_ident(1));
  1.1433 +
  1.1434 +    // Generate starting points for other unique operands if they exist
  1.1435 +    for ( idx = 2; idx < num_unique_opnds(); ++idx ) {
  1.1436 +      if( *receiver == 0 ) {
  1.1437 +        fprintf(fp,"  unsigned %sidx%d = %sidx%d + opnd_array(%d)->num_edges();",
  1.1438 +                prefix, idx, prefix, idx-1, idx-1 );
  1.1439 +      } else {
  1.1440 +        fprintf(fp,"  unsigned %sidx%d = %sidx%d + %s_opnds[%d]->num_edges();",
  1.1441 +                prefix, idx, prefix, idx-1, receiver, idx-1 );
  1.1442 +      }
  1.1443 +      fprintf(fp," \t// %s\n", unique_opnd_ident(idx));
  1.1444 +    }
  1.1445 +  }
  1.1446 +  if( *receiver != 0 ) {
  1.1447 +    // This value is used by generate_peepreplace when copying a node.
  1.1448 +    // Don't emit it in other cases since it can hide bugs with the
  1.1449 +    // use invalid idx's.
  1.1450 +    fprintf(fp,"  unsigned %sidx%d = %sreq(); \n", prefix, idx, receiver);
  1.1451 +  }
  1.1452 +
  1.1453 +}
  1.1454 +
  1.1455 +// ---------------------------
  1.1456 +bool InstructForm::verify() {
  1.1457 +  // !!!!! !!!!!
  1.1458 +  // Check that a "label" operand occurs last in the operand list, if present
  1.1459 +  return true;
  1.1460 +}
  1.1461 +
  1.1462 +void InstructForm::dump() {
  1.1463 +  output(stderr);
  1.1464 +}
  1.1465 +
  1.1466 +void InstructForm::output(FILE *fp) {
  1.1467 +  fprintf(fp,"\nInstruction: %s\n", (_ident?_ident:""));
  1.1468 +  if (_matrule)   _matrule->output(fp);
  1.1469 +  if (_insencode) _insencode->output(fp);
  1.1470 +  if (_constant)  _constant->output(fp);
  1.1471 +  if (_opcode)    _opcode->output(fp);
  1.1472 +  if (_attribs)   _attribs->output(fp);
  1.1473 +  if (_predicate) _predicate->output(fp);
  1.1474 +  if (_effects.Size()) {
  1.1475 +    fprintf(fp,"Effects\n");
  1.1476 +    _effects.dump();
  1.1477 +  }
  1.1478 +  if (_exprule)   _exprule->output(fp);
  1.1479 +  if (_rewrule)   _rewrule->output(fp);
  1.1480 +  if (_format)    _format->output(fp);
  1.1481 +  if (_peephole)  _peephole->output(fp);
  1.1482 +}
  1.1483 +
  1.1484 +void MachNodeForm::dump() {
  1.1485 +  output(stderr);
  1.1486 +}
  1.1487 +
  1.1488 +void MachNodeForm::output(FILE *fp) {
  1.1489 +  fprintf(fp,"\nMachNode: %s\n", (_ident?_ident:""));
  1.1490 +}
  1.1491 +
  1.1492 +//------------------------------build_predicate--------------------------------
  1.1493 +// Build instruction predicates.  If the user uses the same operand name
  1.1494 +// twice, we need to check that the operands are pointer-eequivalent in
  1.1495 +// the DFA during the labeling process.
  1.1496 +Predicate *InstructForm::build_predicate() {
  1.1497 +  char buf[1024], *s=buf;
  1.1498 +  Dict names(cmpstr,hashstr,Form::arena);       // Map Names to counts
  1.1499 +
  1.1500 +  MatchNode *mnode =
  1.1501 +    strcmp(_matrule->_opType, "Set") ? _matrule : _matrule->_rChild;
  1.1502 +  mnode->count_instr_names(names);
  1.1503 +
  1.1504 +  uint first = 1;
  1.1505 +  // Start with the predicate supplied in the .ad file.
  1.1506 +  if( _predicate ) {
  1.1507 +    if( first ) first=0;
  1.1508 +    strcpy(s,"("); s += strlen(s);
  1.1509 +    strcpy(s,_predicate->_pred);
  1.1510 +    s += strlen(s);
  1.1511 +    strcpy(s,")"); s += strlen(s);
  1.1512 +  }
  1.1513 +  for( DictI i(&names); i.test(); ++i ) {
  1.1514 +    uintptr_t cnt = (uintptr_t)i._value;
  1.1515 +    if( cnt > 1 ) {             // Need a predicate at all?
  1.1516 +      assert( cnt == 2, "Unimplemented" );
  1.1517 +      // Handle many pairs
  1.1518 +      if( first ) first=0;
  1.1519 +      else {                    // All tests must pass, so use '&&'
  1.1520 +        strcpy(s," && ");
  1.1521 +        s += strlen(s);
  1.1522 +      }
  1.1523 +      // Add predicate to working buffer
  1.1524 +      sprintf(s,"/*%s*/(",(char*)i._key);
  1.1525 +      s += strlen(s);
  1.1526 +      mnode->build_instr_pred(s,(char*)i._key,0);
  1.1527 +      s += strlen(s);
  1.1528 +      strcpy(s," == "); s += strlen(s);
  1.1529 +      mnode->build_instr_pred(s,(char*)i._key,1);
  1.1530 +      s += strlen(s);
  1.1531 +      strcpy(s,")"); s += strlen(s);
  1.1532 +    }
  1.1533 +  }
  1.1534 +  if( s == buf ) s = NULL;
  1.1535 +  else {
  1.1536 +    assert( strlen(buf) < sizeof(buf), "String buffer overflow" );
  1.1537 +    s = strdup(buf);
  1.1538 +  }
  1.1539 +  return new Predicate(s);
  1.1540 +}
  1.1541 +
  1.1542 +//------------------------------EncodeForm-------------------------------------
  1.1543 +// Constructor
  1.1544 +EncodeForm::EncodeForm()
  1.1545 +  : _encClass(cmpstr,hashstr, Form::arena) {
  1.1546 +}
  1.1547 +EncodeForm::~EncodeForm() {
  1.1548 +}
  1.1549 +
  1.1550 +// record a new register class
  1.1551 +EncClass *EncodeForm::add_EncClass(const char *className) {
  1.1552 +  EncClass *encClass = new EncClass(className);
  1.1553 +  _eclasses.addName(className);
  1.1554 +  _encClass.Insert(className,encClass);
  1.1555 +  return encClass;
  1.1556 +}
  1.1557 +
  1.1558 +// Lookup the function body for an encoding class
  1.1559 +EncClass  *EncodeForm::encClass(const char *className) {
  1.1560 +  assert( className != NULL, "Must provide a defined encoding name");
  1.1561 +
  1.1562 +  EncClass *encClass = (EncClass*)_encClass[className];
  1.1563 +  return encClass;
  1.1564 +}
  1.1565 +
  1.1566 +// Lookup the function body for an encoding class
  1.1567 +const char *EncodeForm::encClassBody(const char *className) {
  1.1568 +  if( className == NULL ) return NULL;
  1.1569 +
  1.1570 +  EncClass *encClass = (EncClass*)_encClass[className];
  1.1571 +  assert( encClass != NULL, "Encode Class is missing.");
  1.1572 +  encClass->_code.reset();
  1.1573 +  const char *code = (const char*)encClass->_code.iter();
  1.1574 +  assert( code != NULL, "Found an empty encode class body.");
  1.1575 +
  1.1576 +  return code;
  1.1577 +}
  1.1578 +
  1.1579 +// Lookup the function body for an encoding class
  1.1580 +const char *EncodeForm::encClassPrototype(const char *className) {
  1.1581 +  assert( className != NULL, "Encode class name must be non NULL.");
  1.1582 +
  1.1583 +  return className;
  1.1584 +}
  1.1585 +
  1.1586 +void EncodeForm::dump() {                  // Debug printer
  1.1587 +  output(stderr);
  1.1588 +}
  1.1589 +
  1.1590 +void EncodeForm::output(FILE *fp) {          // Write info to output files
  1.1591 +  const char *name;
  1.1592 +  fprintf(fp,"\n");
  1.1593 +  fprintf(fp,"-------------------- Dump EncodeForm --------------------\n");
  1.1594 +  for (_eclasses.reset(); (name = _eclasses.iter()) != NULL;) {
  1.1595 +    ((EncClass*)_encClass[name])->output(fp);
  1.1596 +  }
  1.1597 +  fprintf(fp,"-------------------- end  EncodeForm --------------------\n");
  1.1598 +}
  1.1599 +//------------------------------EncClass---------------------------------------
  1.1600 +EncClass::EncClass(const char *name)
  1.1601 +  : _localNames(cmpstr,hashstr, Form::arena), _name(name) {
  1.1602 +}
  1.1603 +EncClass::~EncClass() {
  1.1604 +}
  1.1605 +
  1.1606 +// Add a parameter <type,name> pair
  1.1607 +void EncClass::add_parameter(const char *parameter_type, const char *parameter_name) {
  1.1608 +  _parameter_type.addName( parameter_type );
  1.1609 +  _parameter_name.addName( parameter_name );
  1.1610 +}
  1.1611 +
  1.1612 +// Verify operand types in parameter list
  1.1613 +bool EncClass::check_parameter_types(FormDict &globals) {
  1.1614 +  // !!!!!
  1.1615 +  return false;
  1.1616 +}
  1.1617 +
  1.1618 +// Add the decomposed "code" sections of an encoding's code-block
  1.1619 +void EncClass::add_code(const char *code) {
  1.1620 +  _code.addName(code);
  1.1621 +}
  1.1622 +
  1.1623 +// Add the decomposed "replacement variables" of an encoding's code-block
  1.1624 +void EncClass::add_rep_var(char *replacement_var) {
  1.1625 +  _code.addName(NameList::_signal);
  1.1626 +  _rep_vars.addName(replacement_var);
  1.1627 +}
  1.1628 +
  1.1629 +// Lookup the function body for an encoding class
  1.1630 +int EncClass::rep_var_index(const char *rep_var) {
  1.1631 +  uint        position = 0;
  1.1632 +  const char *name     = NULL;
  1.1633 +
  1.1634 +  _parameter_name.reset();
  1.1635 +  while ( (name = _parameter_name.iter()) != NULL ) {
  1.1636 +    if ( strcmp(rep_var,name) == 0 ) return position;
  1.1637 +    ++position;
  1.1638 +  }
  1.1639 +
  1.1640 +  return -1;
  1.1641 +}
  1.1642 +
  1.1643 +// Check after parsing
  1.1644 +bool EncClass::verify() {
  1.1645 +  // 1!!!!
  1.1646 +  // Check that each replacement variable, '$name' in architecture description
  1.1647 +  // is actually a local variable for this encode class, or a reserved name
  1.1648 +  // "primary, secondary, tertiary"
  1.1649 +  return true;
  1.1650 +}
  1.1651 +
  1.1652 +void EncClass::dump() {
  1.1653 +  output(stderr);
  1.1654 +}
  1.1655 +
  1.1656 +// Write info to output files
  1.1657 +void EncClass::output(FILE *fp) {
  1.1658 +  fprintf(fp,"EncClass: %s", (_name ? _name : ""));
  1.1659 +
  1.1660 +  // Output the parameter list
  1.1661 +  _parameter_type.reset();
  1.1662 +  _parameter_name.reset();
  1.1663 +  const char *type = _parameter_type.iter();
  1.1664 +  const char *name = _parameter_name.iter();
  1.1665 +  fprintf(fp, " ( ");
  1.1666 +  for ( ; (type != NULL) && (name != NULL);
  1.1667 +        (type = _parameter_type.iter()), (name = _parameter_name.iter()) ) {
  1.1668 +    fprintf(fp, " %s %s,", type, name);
  1.1669 +  }
  1.1670 +  fprintf(fp, " ) ");
  1.1671 +
  1.1672 +  // Output the code block
  1.1673 +  _code.reset();
  1.1674 +  _rep_vars.reset();
  1.1675 +  const char *code;
  1.1676 +  while ( (code = _code.iter()) != NULL ) {
  1.1677 +    if ( _code.is_signal(code) ) {
  1.1678 +      // A replacement variable
  1.1679 +      const char *rep_var = _rep_vars.iter();
  1.1680 +      fprintf(fp,"($%s)", rep_var);
  1.1681 +    } else {
  1.1682 +      // A section of code
  1.1683 +      fprintf(fp,"%s", code);
  1.1684 +    }
  1.1685 +  }
  1.1686 +
  1.1687 +}
  1.1688 +
  1.1689 +//------------------------------Opcode-----------------------------------------
  1.1690 +Opcode::Opcode(char *primary, char *secondary, char *tertiary)
  1.1691 +  : _primary(primary), _secondary(secondary), _tertiary(tertiary) {
  1.1692 +}
  1.1693 +
  1.1694 +Opcode::~Opcode() {
  1.1695 +}
  1.1696 +
  1.1697 +Opcode::opcode_type Opcode::as_opcode_type(const char *param) {
  1.1698 +  if( strcmp(param,"primary") == 0 ) {
  1.1699 +    return Opcode::PRIMARY;
  1.1700 +  }
  1.1701 +  else if( strcmp(param,"secondary") == 0 ) {
  1.1702 +    return Opcode::SECONDARY;
  1.1703 +  }
  1.1704 +  else if( strcmp(param,"tertiary") == 0 ) {
  1.1705 +    return Opcode::TERTIARY;
  1.1706 +  }
  1.1707 +  return Opcode::NOT_AN_OPCODE;
  1.1708 +}
  1.1709 +
  1.1710 +bool Opcode::print_opcode(FILE *fp, Opcode::opcode_type desired_opcode) {
  1.1711 +  // Default values previously provided by MachNode::primary()...
  1.1712 +  const char *description = NULL;
  1.1713 +  const char *value       = NULL;
  1.1714 +  // Check if user provided any opcode definitions
  1.1715 +  if( this != NULL ) {
  1.1716 +    // Update 'value' if user provided a definition in the instruction
  1.1717 +    switch (desired_opcode) {
  1.1718 +    case PRIMARY:
  1.1719 +      description = "primary()";
  1.1720 +      if( _primary   != NULL)  { value = _primary;     }
  1.1721 +      break;
  1.1722 +    case SECONDARY:
  1.1723 +      description = "secondary()";
  1.1724 +      if( _secondary != NULL ) { value = _secondary;   }
  1.1725 +      break;
  1.1726 +    case TERTIARY:
  1.1727 +      description = "tertiary()";
  1.1728 +      if( _tertiary  != NULL ) { value = _tertiary;    }
  1.1729 +      break;
  1.1730 +    default:
  1.1731 +      assert( false, "ShouldNotReachHere();");
  1.1732 +      break;
  1.1733 +    }
  1.1734 +  }
  1.1735 +  if (value != NULL) {
  1.1736 +    fprintf(fp, "(%s /*%s*/)", value, description);
  1.1737 +  }
  1.1738 +  return value != NULL;
  1.1739 +}
  1.1740 +
  1.1741 +void Opcode::dump() {
  1.1742 +  output(stderr);
  1.1743 +}
  1.1744 +
  1.1745 +// Write info to output files
  1.1746 +void Opcode::output(FILE *fp) {
  1.1747 +  if (_primary   != NULL) fprintf(fp,"Primary   opcode: %s\n", _primary);
  1.1748 +  if (_secondary != NULL) fprintf(fp,"Secondary opcode: %s\n", _secondary);
  1.1749 +  if (_tertiary  != NULL) fprintf(fp,"Tertiary  opcode: %s\n", _tertiary);
  1.1750 +}
  1.1751 +
  1.1752 +//------------------------------InsEncode--------------------------------------
  1.1753 +InsEncode::InsEncode() {
  1.1754 +}
  1.1755 +InsEncode::~InsEncode() {
  1.1756 +}
  1.1757 +
  1.1758 +// Add "encode class name" and its parameters
  1.1759 +NameAndList *InsEncode::add_encode(char *encoding) {
  1.1760 +  assert( encoding != NULL, "Must provide name for encoding");
  1.1761 +
  1.1762 +  // add_parameter(NameList::_signal);
  1.1763 +  NameAndList *encode = new NameAndList(encoding);
  1.1764 +  _encoding.addName((char*)encode);
  1.1765 +
  1.1766 +  return encode;
  1.1767 +}
  1.1768 +
  1.1769 +// Access the list of encodings
  1.1770 +void InsEncode::reset() {
  1.1771 +  _encoding.reset();
  1.1772 +  // _parameter.reset();
  1.1773 +}
  1.1774 +const char* InsEncode::encode_class_iter() {
  1.1775 +  NameAndList  *encode_class = (NameAndList*)_encoding.iter();
  1.1776 +  return  ( encode_class != NULL ? encode_class->name() : NULL );
  1.1777 +}
  1.1778 +// Obtain parameter name from zero based index
  1.1779 +const char *InsEncode::rep_var_name(InstructForm &inst, uint param_no) {
  1.1780 +  NameAndList *params = (NameAndList*)_encoding.current();
  1.1781 +  assert( params != NULL, "Internal Error");
  1.1782 +  const char *param = (*params)[param_no];
  1.1783 +
  1.1784 +  // Remove '$' if parser placed it there.
  1.1785 +  return ( param != NULL && *param == '$') ? (param+1) : param;
  1.1786 +}
  1.1787 +
  1.1788 +void InsEncode::dump() {
  1.1789 +  output(stderr);
  1.1790 +}
  1.1791 +
  1.1792 +// Write info to output files
  1.1793 +void InsEncode::output(FILE *fp) {
  1.1794 +  NameAndList *encoding  = NULL;
  1.1795 +  const char  *parameter = NULL;
  1.1796 +
  1.1797 +  fprintf(fp,"InsEncode: ");
  1.1798 +  _encoding.reset();
  1.1799 +
  1.1800 +  while ( (encoding = (NameAndList*)_encoding.iter()) != 0 ) {
  1.1801 +    // Output the encoding being used
  1.1802 +    fprintf(fp,"%s(", encoding->name() );
  1.1803 +
  1.1804 +    // Output its parameter list, if any
  1.1805 +    bool first_param = true;
  1.1806 +    encoding->reset();
  1.1807 +    while (  (parameter = encoding->iter()) != 0 ) {
  1.1808 +      // Output the ',' between parameters
  1.1809 +      if ( ! first_param )  fprintf(fp,", ");
  1.1810 +      first_param = false;
  1.1811 +      // Output the parameter
  1.1812 +      fprintf(fp,"%s", parameter);
  1.1813 +    } // done with parameters
  1.1814 +    fprintf(fp,")  ");
  1.1815 +  } // done with encodings
  1.1816 +
  1.1817 +  fprintf(fp,"\n");
  1.1818 +}
  1.1819 +
  1.1820 +//------------------------------Effect-----------------------------------------
  1.1821 +static int effect_lookup(const char *name) {
  1.1822 +  if(!strcmp(name, "USE")) return Component::USE;
  1.1823 +  if(!strcmp(name, "DEF")) return Component::DEF;
  1.1824 +  if(!strcmp(name, "USE_DEF")) return Component::USE_DEF;
  1.1825 +  if(!strcmp(name, "KILL")) return Component::KILL;
  1.1826 +  if(!strcmp(name, "USE_KILL")) return Component::USE_KILL;
  1.1827 +  if(!strcmp(name, "TEMP")) return Component::TEMP;
  1.1828 +  if(!strcmp(name, "INVALID")) return Component::INVALID;
  1.1829 +  if(!strcmp(name, "CALL")) return Component::CALL;
  1.1830 +  assert( false,"Invalid effect name specified\n");
  1.1831 +  return Component::INVALID;
  1.1832 +}
  1.1833 +
  1.1834 +const char *Component::getUsedefName() {
  1.1835 +  switch (_usedef) {
  1.1836 +    case Component::INVALID:  return "INVALID";  break;
  1.1837 +    case Component::USE:      return "USE";      break;
  1.1838 +    case Component::USE_DEF:  return "USE_DEF";  break;
  1.1839 +    case Component::USE_KILL: return "USE_KILL"; break;
  1.1840 +    case Component::KILL:     return "KILL";     break;
  1.1841 +    case Component::TEMP:     return "TEMP";     break;
  1.1842 +    case Component::DEF:      return "DEF";      break;
  1.1843 +    case Component::CALL:     return "CALL";     break;
  1.1844 +    default: assert(false, "unknown effect");
  1.1845 +  }
  1.1846 +  return "Undefined Use/Def info";
  1.1847 +}
  1.1848 +
  1.1849 +Effect::Effect(const char *name) : _name(name), _use_def(effect_lookup(name)) {
  1.1850 +  _ftype = Form::EFF;
  1.1851 +}
  1.1852 +
  1.1853 +Effect::~Effect() {
  1.1854 +}
  1.1855 +
  1.1856 +// Dynamic type check
  1.1857 +Effect *Effect::is_effect() const {
  1.1858 +  return (Effect*)this;
  1.1859 +}
  1.1860 +
  1.1861 +
  1.1862 +// True if this component is equal to the parameter.
  1.1863 +bool Effect::is(int use_def_kill_enum) const {
  1.1864 +  return (_use_def == use_def_kill_enum ? true : false);
  1.1865 +}
  1.1866 +// True if this component is used/def'd/kill'd as the parameter suggests.
  1.1867 +bool Effect::isa(int use_def_kill_enum) const {
  1.1868 +  return (_use_def & use_def_kill_enum) == use_def_kill_enum;
  1.1869 +}
  1.1870 +
  1.1871 +void Effect::dump() {
  1.1872 +  output(stderr);
  1.1873 +}
  1.1874 +
  1.1875 +void Effect::output(FILE *fp) {          // Write info to output files
  1.1876 +  fprintf(fp,"Effect: %s\n", (_name?_name:""));
  1.1877 +}
  1.1878 +
  1.1879 +//------------------------------ExpandRule-------------------------------------
  1.1880 +ExpandRule::ExpandRule() : _expand_instrs(),
  1.1881 +                           _newopconst(cmpstr, hashstr, Form::arena) {
  1.1882 +  _ftype = Form::EXP;
  1.1883 +}
  1.1884 +
  1.1885 +ExpandRule::~ExpandRule() {                  // Destructor
  1.1886 +}
  1.1887 +
  1.1888 +void ExpandRule::add_instruction(NameAndList *instruction_name_and_operand_list) {
  1.1889 +  _expand_instrs.addName((char*)instruction_name_and_operand_list);
  1.1890 +}
  1.1891 +
  1.1892 +void ExpandRule::reset_instructions() {
  1.1893 +  _expand_instrs.reset();
  1.1894 +}
  1.1895 +
  1.1896 +NameAndList* ExpandRule::iter_instructions() {
  1.1897 +  return (NameAndList*)_expand_instrs.iter();
  1.1898 +}
  1.1899 +
  1.1900 +
  1.1901 +void ExpandRule::dump() {
  1.1902 +  output(stderr);
  1.1903 +}
  1.1904 +
  1.1905 +void ExpandRule::output(FILE *fp) {         // Write info to output files
  1.1906 +  NameAndList *expand_instr = NULL;
  1.1907 +  const char *opid = NULL;
  1.1908 +
  1.1909 +  fprintf(fp,"\nExpand Rule:\n");
  1.1910 +
  1.1911 +  // Iterate over the instructions 'node' expands into
  1.1912 +  for(reset_instructions(); (expand_instr = iter_instructions()) != NULL; ) {
  1.1913 +    fprintf(fp,"%s(", expand_instr->name());
  1.1914 +
  1.1915 +    // iterate over the operand list
  1.1916 +    for( expand_instr->reset(); (opid = expand_instr->iter()) != NULL; ) {
  1.1917 +      fprintf(fp,"%s ", opid);
  1.1918 +    }
  1.1919 +    fprintf(fp,");\n");
  1.1920 +  }
  1.1921 +}
  1.1922 +
  1.1923 +//------------------------------RewriteRule------------------------------------
  1.1924 +RewriteRule::RewriteRule(char* params, char* block)
  1.1925 +  : _tempParams(params), _tempBlock(block) { };  // Constructor
  1.1926 +RewriteRule::~RewriteRule() {                 // Destructor
  1.1927 +}
  1.1928 +
  1.1929 +void RewriteRule::dump() {
  1.1930 +  output(stderr);
  1.1931 +}
  1.1932 +
  1.1933 +void RewriteRule::output(FILE *fp) {         // Write info to output files
  1.1934 +  fprintf(fp,"\nRewrite Rule:\n%s\n%s\n",
  1.1935 +          (_tempParams?_tempParams:""),
  1.1936 +          (_tempBlock?_tempBlock:""));
  1.1937 +}
  1.1938 +
  1.1939 +
  1.1940 +//==============================MachNodes======================================
  1.1941 +//------------------------------MachNodeForm-----------------------------------
  1.1942 +MachNodeForm::MachNodeForm(char *id)
  1.1943 +  : _ident(id) {
  1.1944 +}
  1.1945 +
  1.1946 +MachNodeForm::~MachNodeForm() {
  1.1947 +}
  1.1948 +
  1.1949 +MachNodeForm *MachNodeForm::is_machnode() const {
  1.1950 +  return (MachNodeForm*)this;
  1.1951 +}
  1.1952 +
  1.1953 +//==============================Operand Classes================================
  1.1954 +//------------------------------OpClassForm------------------------------------
  1.1955 +OpClassForm::OpClassForm(const char* id) : _ident(id) {
  1.1956 +  _ftype = Form::OPCLASS;
  1.1957 +}
  1.1958 +
  1.1959 +OpClassForm::~OpClassForm() {
  1.1960 +}
  1.1961 +
  1.1962 +bool OpClassForm::ideal_only() const { return 0; }
  1.1963 +
  1.1964 +OpClassForm *OpClassForm::is_opclass() const {
  1.1965 +  return (OpClassForm*)this;
  1.1966 +}
  1.1967 +
  1.1968 +Form::InterfaceType OpClassForm::interface_type(FormDict &globals) const {
  1.1969 +  if( _oplst.count() == 0 ) return Form::no_interface;
  1.1970 +
  1.1971 +  // Check that my operands have the same interface type
  1.1972 +  Form::InterfaceType  interface;
  1.1973 +  bool  first = true;
  1.1974 +  NameList &op_list = (NameList &)_oplst;
  1.1975 +  op_list.reset();
  1.1976 +  const char *op_name;
  1.1977 +  while( (op_name = op_list.iter()) != NULL ) {
  1.1978 +    const Form  *form    = globals[op_name];
  1.1979 +    OperandForm *operand = form->is_operand();
  1.1980 +    assert( operand, "Entry in operand class that is not an operand");
  1.1981 +    if( first ) {
  1.1982 +      first     = false;
  1.1983 +      interface = operand->interface_type(globals);
  1.1984 +    } else {
  1.1985 +      interface = (interface == operand->interface_type(globals) ? interface : Form::no_interface);
  1.1986 +    }
  1.1987 +  }
  1.1988 +  return interface;
  1.1989 +}
  1.1990 +
  1.1991 +bool OpClassForm::stack_slots_only(FormDict &globals) const {
  1.1992 +  if( _oplst.count() == 0 ) return false;  // how?
  1.1993 +
  1.1994 +  NameList &op_list = (NameList &)_oplst;
  1.1995 +  op_list.reset();
  1.1996 +  const char *op_name;
  1.1997 +  while( (op_name = op_list.iter()) != NULL ) {
  1.1998 +    const Form  *form    = globals[op_name];
  1.1999 +    OperandForm *operand = form->is_operand();
  1.2000 +    assert( operand, "Entry in operand class that is not an operand");
  1.2001 +    if( !operand->stack_slots_only(globals) )  return false;
  1.2002 +  }
  1.2003 +  return true;
  1.2004 +}
  1.2005 +
  1.2006 +
  1.2007 +void OpClassForm::dump() {
  1.2008 +  output(stderr);
  1.2009 +}
  1.2010 +
  1.2011 +void OpClassForm::output(FILE *fp) {
  1.2012 +  const char *name;
  1.2013 +  fprintf(fp,"\nOperand Class: %s\n", (_ident?_ident:""));
  1.2014 +  fprintf(fp,"\nCount = %d\n", _oplst.count());
  1.2015 +  for(_oplst.reset(); (name = _oplst.iter()) != NULL;) {
  1.2016 +    fprintf(fp,"%s, ",name);
  1.2017 +  }
  1.2018 +  fprintf(fp,"\n");
  1.2019 +}
  1.2020 +
  1.2021 +
  1.2022 +//==============================Operands=======================================
  1.2023 +//------------------------------OperandForm------------------------------------
  1.2024 +OperandForm::OperandForm(const char* id)
  1.2025 +  : OpClassForm(id), _ideal_only(false),
  1.2026 +    _localNames(cmpstr, hashstr, Form::arena) {
  1.2027 +      _ftype = Form::OPER;
  1.2028 +
  1.2029 +      _matrule   = NULL;
  1.2030 +      _interface = NULL;
  1.2031 +      _attribs   = NULL;
  1.2032 +      _predicate = NULL;
  1.2033 +      _constraint= NULL;
  1.2034 +      _construct = NULL;
  1.2035 +      _format    = NULL;
  1.2036 +}
  1.2037 +OperandForm::OperandForm(const char* id, bool ideal_only)
  1.2038 +  : OpClassForm(id), _ideal_only(ideal_only),
  1.2039 +    _localNames(cmpstr, hashstr, Form::arena) {
  1.2040 +      _ftype = Form::OPER;
  1.2041 +
  1.2042 +      _matrule   = NULL;
  1.2043 +      _interface = NULL;
  1.2044 +      _attribs   = NULL;
  1.2045 +      _predicate = NULL;
  1.2046 +      _constraint= NULL;
  1.2047 +      _construct = NULL;
  1.2048 +      _format    = NULL;
  1.2049 +}
  1.2050 +OperandForm::~OperandForm() {
  1.2051 +}
  1.2052 +
  1.2053 +
  1.2054 +OperandForm *OperandForm::is_operand() const {
  1.2055 +  return (OperandForm*)this;
  1.2056 +}
  1.2057 +
  1.2058 +bool OperandForm::ideal_only() const {
  1.2059 +  return _ideal_only;
  1.2060 +}
  1.2061 +
  1.2062 +Form::InterfaceType OperandForm::interface_type(FormDict &globals) const {
  1.2063 +  if( _interface == NULL )  return Form::no_interface;
  1.2064 +
  1.2065 +  return _interface->interface_type(globals);
  1.2066 +}
  1.2067 +
  1.2068 +
  1.2069 +bool OperandForm::stack_slots_only(FormDict &globals) const {
  1.2070 +  if( _constraint == NULL )  return false;
  1.2071 +  return _constraint->stack_slots_only();
  1.2072 +}
  1.2073 +
  1.2074 +
  1.2075 +// Access op_cost attribute or return NULL.
  1.2076 +const char* OperandForm::cost() {
  1.2077 +  for (Attribute* cur = _attribs; cur != NULL; cur = (Attribute*)cur->_next) {
  1.2078 +    if( strcmp(cur->_ident,AttributeForm::_op_cost) == 0 ) {
  1.2079 +      return cur->_val;
  1.2080 +    }
  1.2081 +  }
  1.2082 +  return NULL;
  1.2083 +}
  1.2084 +
  1.2085 +// Return the number of leaves below this complex operand
  1.2086 +uint OperandForm::num_leaves() const {
  1.2087 +  if ( ! _matrule) return 0;
  1.2088 +
  1.2089 +  int num_leaves = _matrule->_numleaves;
  1.2090 +  return num_leaves;
  1.2091 +}
  1.2092 +
  1.2093 +// Return the number of constants contained within this complex operand
  1.2094 +uint OperandForm::num_consts(FormDict &globals) const {
  1.2095 +  if ( ! _matrule) return 0;
  1.2096 +
  1.2097 +  // This is a recursive invocation on all operands in the matchrule
  1.2098 +  return _matrule->num_consts(globals);
  1.2099 +}
  1.2100 +
  1.2101 +// Return the number of constants in match rule with specified type
  1.2102 +uint OperandForm::num_consts(FormDict &globals, Form::DataType type) const {
  1.2103 +  if ( ! _matrule) return 0;
  1.2104 +
  1.2105 +  // This is a recursive invocation on all operands in the matchrule
  1.2106 +  return _matrule->num_consts(globals, type);
  1.2107 +}
  1.2108 +
  1.2109 +// Return the number of pointer constants contained within this complex operand
  1.2110 +uint OperandForm::num_const_ptrs(FormDict &globals) const {
  1.2111 +  if ( ! _matrule) return 0;
  1.2112 +
  1.2113 +  // This is a recursive invocation on all operands in the matchrule
  1.2114 +  return _matrule->num_const_ptrs(globals);
  1.2115 +}
  1.2116 +
  1.2117 +uint OperandForm::num_edges(FormDict &globals) const {
  1.2118 +  uint edges  = 0;
  1.2119 +  uint leaves = num_leaves();
  1.2120 +  uint consts = num_consts(globals);
  1.2121 +
  1.2122 +  // If we are matching a constant directly, there are no leaves.
  1.2123 +  edges = ( leaves > consts ) ? leaves - consts : 0;
  1.2124 +
  1.2125 +  // !!!!!
  1.2126 +  // Special case operands that do not have a corresponding ideal node.
  1.2127 +  if( (edges == 0) && (consts == 0) ) {
  1.2128 +    if( constrained_reg_class() != NULL ) {
  1.2129 +      edges = 1;
  1.2130 +    } else {
  1.2131 +      if( _matrule
  1.2132 +          && (_matrule->_lChild == NULL) && (_matrule->_rChild == NULL) ) {
  1.2133 +        const Form *form = globals[_matrule->_opType];
  1.2134 +        OperandForm *oper = form ? form->is_operand() : NULL;
  1.2135 +        if( oper ) {
  1.2136 +          return oper->num_edges(globals);
  1.2137 +        }
  1.2138 +      }
  1.2139 +    }
  1.2140 +  }
  1.2141 +
  1.2142 +  return edges;
  1.2143 +}
  1.2144 +
  1.2145 +
  1.2146 +// Check if this operand is usable for cisc-spilling
  1.2147 +bool  OperandForm::is_cisc_reg(FormDict &globals) const {
  1.2148 +  const char *ideal = ideal_type(globals);
  1.2149 +  bool is_cisc_reg = (ideal && (ideal_to_Reg_type(ideal) != none));
  1.2150 +  return is_cisc_reg;
  1.2151 +}
  1.2152 +
  1.2153 +bool  OpClassForm::is_cisc_mem(FormDict &globals) const {
  1.2154 +  Form::InterfaceType my_interface = interface_type(globals);
  1.2155 +  return (my_interface == memory_interface);
  1.2156 +}
  1.2157 +
  1.2158 +
  1.2159 +// node matches ideal 'Bool'
  1.2160 +bool OperandForm::is_ideal_bool() const {
  1.2161 +  if( _matrule == NULL ) return false;
  1.2162 +
  1.2163 +  return _matrule->is_ideal_bool();
  1.2164 +}
  1.2165 +
  1.2166 +// Require user's name for an sRegX to be stackSlotX
  1.2167 +Form::DataType OperandForm::is_user_name_for_sReg() const {
  1.2168 +  DataType data_type = none;
  1.2169 +  if( _ident != NULL ) {
  1.2170 +    if(      strcmp(_ident,"stackSlotI") == 0 ) data_type = Form::idealI;
  1.2171 +    else if( strcmp(_ident,"stackSlotP") == 0 ) data_type = Form::idealP;
  1.2172 +    else if( strcmp(_ident,"stackSlotD") == 0 ) data_type = Form::idealD;
  1.2173 +    else if( strcmp(_ident,"stackSlotF") == 0 ) data_type = Form::idealF;
  1.2174 +    else if( strcmp(_ident,"stackSlotL") == 0 ) data_type = Form::idealL;
  1.2175 +  }
  1.2176 +  assert((data_type == none) || (_matrule == NULL), "No match-rule for stackSlotX");
  1.2177 +
  1.2178 +  return data_type;
  1.2179 +}
  1.2180 +
  1.2181 +
  1.2182 +// Return ideal type, if there is a single ideal type for this operand
  1.2183 +const char *OperandForm::ideal_type(FormDict &globals, RegisterForm *registers) const {
  1.2184 +  const char *type = NULL;
  1.2185 +  if (ideal_only()) type = _ident;
  1.2186 +  else if( _matrule == NULL ) {
  1.2187 +    // Check for condition code register
  1.2188 +    const char *rc_name = constrained_reg_class();
  1.2189 +    // !!!!!
  1.2190 +    if (rc_name == NULL) return NULL;
  1.2191 +    // !!!!! !!!!!
  1.2192 +    // Check constraints on result's register class
  1.2193 +    if( registers ) {
  1.2194 +      RegClass *reg_class  = registers->getRegClass(rc_name);
  1.2195 +      assert( reg_class != NULL, "Register class is not defined");
  1.2196 +
  1.2197 +      // Check for ideal type of entries in register class, all are the same type
  1.2198 +      reg_class->reset();
  1.2199 +      RegDef *reg_def = reg_class->RegDef_iter();
  1.2200 +      assert( reg_def != NULL, "No entries in register class");
  1.2201 +      assert( reg_def->_idealtype != NULL, "Did not define ideal type for register");
  1.2202 +      // Return substring that names the register's ideal type
  1.2203 +      type = reg_def->_idealtype + 3;
  1.2204 +      assert( *(reg_def->_idealtype + 0) == 'O', "Expect Op_ prefix");
  1.2205 +      assert( *(reg_def->_idealtype + 1) == 'p', "Expect Op_ prefix");
  1.2206 +      assert( *(reg_def->_idealtype + 2) == '_', "Expect Op_ prefix");
  1.2207 +    }
  1.2208 +  }
  1.2209 +  else if( _matrule->_lChild == NULL && _matrule->_rChild == NULL ) {
  1.2210 +    // This operand matches a single type, at the top level.
  1.2211 +    // Check for ideal type
  1.2212 +    type = _matrule->_opType;
  1.2213 +    if( strcmp(type,"Bool") == 0 )
  1.2214 +      return "Bool";
  1.2215 +    // transitive lookup
  1.2216 +    const Form *frm = globals[type];
  1.2217 +    OperandForm *op = frm->is_operand();
  1.2218 +    type = op->ideal_type(globals, registers);
  1.2219 +  }
  1.2220 +  return type;
  1.2221 +}
  1.2222 +
  1.2223 +
  1.2224 +// If there is a single ideal type for this interface field, return it.
  1.2225 +const char *OperandForm::interface_ideal_type(FormDict &globals,
  1.2226 +                                              const char *field) const {
  1.2227 +  const char  *ideal_type = NULL;
  1.2228 +  const char  *value      = NULL;
  1.2229 +
  1.2230 +  // Check if "field" is valid for this operand's interface
  1.2231 +  if ( ! is_interface_field(field, value) )   return ideal_type;
  1.2232 +
  1.2233 +  // !!!!! !!!!! !!!!!
  1.2234 +  // If a valid field has a constant value, identify "ConI" or "ConP" or ...
  1.2235 +
  1.2236 +  // Else, lookup type of field's replacement variable
  1.2237 +
  1.2238 +  return ideal_type;
  1.2239 +}
  1.2240 +
  1.2241 +
  1.2242 +RegClass* OperandForm::get_RegClass() const {
  1.2243 +  if (_interface && !_interface->is_RegInterface()) return NULL;
  1.2244 +  return globalAD->get_registers()->getRegClass(constrained_reg_class());
  1.2245 +}
  1.2246 +
  1.2247 +
  1.2248 +bool OperandForm::is_bound_register() const {
  1.2249 +  RegClass* reg_class = get_RegClass();
  1.2250 +  if (reg_class == NULL) {
  1.2251 +    return false;
  1.2252 +  }
  1.2253 +
  1.2254 +  const char* name = ideal_type(globalAD->globalNames());
  1.2255 +  if (name == NULL) {
  1.2256 +    return false;
  1.2257 +  }
  1.2258 +
  1.2259 +  uint size = 0;
  1.2260 +  if (strcmp(name, "RegFlags") == 0) size = 1;
  1.2261 +  if (strcmp(name, "RegI") == 0) size = 1;
  1.2262 +  if (strcmp(name, "RegF") == 0) size = 1;
  1.2263 +  if (strcmp(name, "RegD") == 0) size = 2;
  1.2264 +  if (strcmp(name, "RegL") == 0) size = 2;
  1.2265 +  if (strcmp(name, "RegN") == 0) size = 1;
  1.2266 +  if (strcmp(name, "RegP") == 0) size = globalAD->get_preproc_def("_LP64") ? 2 : 1;
  1.2267 +  if (size == 0) {
  1.2268 +    return false;
  1.2269 +  }
  1.2270 +  return size == reg_class->size();
  1.2271 +}
  1.2272 +
  1.2273 +
  1.2274 +// Check if this is a valid field for this operand,
  1.2275 +// Return 'true' if valid, and set the value to the string the user provided.
  1.2276 +bool  OperandForm::is_interface_field(const char *field,
  1.2277 +                                      const char * &value) const {
  1.2278 +  return false;
  1.2279 +}
  1.2280 +
  1.2281 +
  1.2282 +// Return register class name if a constraint specifies the register class.
  1.2283 +const char *OperandForm::constrained_reg_class() const {
  1.2284 +  const char *reg_class  = NULL;
  1.2285 +  if ( _constraint ) {
  1.2286 +    // !!!!!
  1.2287 +    Constraint *constraint = _constraint;
  1.2288 +    if ( strcmp(_constraint->_func,"ALLOC_IN_RC") == 0 ) {
  1.2289 +      reg_class = _constraint->_arg;
  1.2290 +    }
  1.2291 +  }
  1.2292 +
  1.2293 +  return reg_class;
  1.2294 +}
  1.2295 +
  1.2296 +
  1.2297 +// Return the register class associated with 'leaf'.
  1.2298 +const char *OperandForm::in_reg_class(uint leaf, FormDict &globals) {
  1.2299 +  const char *reg_class = NULL; // "RegMask::Empty";
  1.2300 +
  1.2301 +  if((_matrule == NULL) || (_matrule->is_chain_rule(globals))) {
  1.2302 +    reg_class = constrained_reg_class();
  1.2303 +    return reg_class;
  1.2304 +  }
  1.2305 +  const char *result   = NULL;
  1.2306 +  const char *name     = NULL;
  1.2307 +  const char *type     = NULL;
  1.2308 +  // iterate through all base operands
  1.2309 +  // until we reach the register that corresponds to "leaf"
  1.2310 +  // This function is not looking for an ideal type.  It needs the first
  1.2311 +  // level user type associated with the leaf.
  1.2312 +  for(uint idx = 0;_matrule->base_operand(idx,globals,result,name,type);++idx) {
  1.2313 +    const Form *form = (_localNames[name] ? _localNames[name] : globals[result]);
  1.2314 +    OperandForm *oper = form ? form->is_operand() : NULL;
  1.2315 +    if( oper ) {
  1.2316 +      reg_class = oper->constrained_reg_class();
  1.2317 +      if( reg_class ) {
  1.2318 +        reg_class = reg_class;
  1.2319 +      } else {
  1.2320 +        // ShouldNotReachHere();
  1.2321 +      }
  1.2322 +    } else {
  1.2323 +      // ShouldNotReachHere();
  1.2324 +    }
  1.2325 +
  1.2326 +    // Increment our target leaf position if current leaf is not a candidate.
  1.2327 +    if( reg_class == NULL)    ++leaf;
  1.2328 +    // Exit the loop with the value of reg_class when at the correct index
  1.2329 +    if( idx == leaf )         break;
  1.2330 +    // May iterate through all base operands if reg_class for 'leaf' is NULL
  1.2331 +  }
  1.2332 +  return reg_class;
  1.2333 +}
  1.2334 +
  1.2335 +
  1.2336 +// Recursive call to construct list of top-level operands.
  1.2337 +// Implementation does not modify state of internal structures
  1.2338 +void OperandForm::build_components() {
  1.2339 +  if (_matrule)  _matrule->append_components(_localNames, _components);
  1.2340 +
  1.2341 +  // Add parameters that "do not appear in match rule".
  1.2342 +  const char *name;
  1.2343 +  for (_parameters.reset(); (name = _parameters.iter()) != NULL;) {
  1.2344 +    OperandForm *opForm = (OperandForm*)_localNames[name];
  1.2345 +
  1.2346 +    if ( _components.operand_position(name) == -1 ) {
  1.2347 +      _components.insert(name, opForm->_ident, Component::INVALID, false);
  1.2348 +    }
  1.2349 +  }
  1.2350 +
  1.2351 +  return;
  1.2352 +}
  1.2353 +
  1.2354 +int OperandForm::operand_position(const char *name, int usedef) {
  1.2355 +  return _components.operand_position(name, usedef, this);
  1.2356 +}
  1.2357 +
  1.2358 +
  1.2359 +// Return zero-based position in component list, only counting constants;
  1.2360 +// Return -1 if not in list.
  1.2361 +int OperandForm::constant_position(FormDict &globals, const Component *last) {
  1.2362 +  // Iterate through components and count constants preceding 'constant'
  1.2363 +  int position = 0;
  1.2364 +  Component *comp;
  1.2365 +  _components.reset();
  1.2366 +  while( (comp = _components.iter()) != NULL  && (comp != last) ) {
  1.2367 +    // Special case for operands that take a single user-defined operand
  1.2368 +    // Skip the initial definition in the component list.
  1.2369 +    if( strcmp(comp->_name,this->_ident) == 0 ) continue;
  1.2370 +
  1.2371 +    const char *type = comp->_type;
  1.2372 +    // Lookup operand form for replacement variable's type
  1.2373 +    const Form *form = globals[type];
  1.2374 +    assert( form != NULL, "Component's type not found");
  1.2375 +    OperandForm *oper = form ? form->is_operand() : NULL;
  1.2376 +    if( oper ) {
  1.2377 +      if( oper->_matrule->is_base_constant(globals) != Form::none ) {
  1.2378 +        ++position;
  1.2379 +      }
  1.2380 +    }
  1.2381 +  }
  1.2382 +
  1.2383 +  // Check for being passed a component that was not in the list
  1.2384 +  if( comp != last )  position = -1;
  1.2385 +
  1.2386 +  return position;
  1.2387 +}
  1.2388 +// Provide position of constant by "name"
  1.2389 +int OperandForm::constant_position(FormDict &globals, const char *name) {
  1.2390 +  const Component *comp = _components.search(name);
  1.2391 +  int idx = constant_position( globals, comp );
  1.2392 +
  1.2393 +  return idx;
  1.2394 +}
  1.2395 +
  1.2396 +
  1.2397 +// Return zero-based position in component list, only counting constants;
  1.2398 +// Return -1 if not in list.
  1.2399 +int OperandForm::register_position(FormDict &globals, const char *reg_name) {
  1.2400 +  // Iterate through components and count registers preceding 'last'
  1.2401 +  uint  position = 0;
  1.2402 +  Component *comp;
  1.2403 +  _components.reset();
  1.2404 +  while( (comp = _components.iter()) != NULL
  1.2405 +         && (strcmp(comp->_name,reg_name) != 0) ) {
  1.2406 +    // Special case for operands that take a single user-defined operand
  1.2407 +    // Skip the initial definition in the component list.
  1.2408 +    if( strcmp(comp->_name,this->_ident) == 0 ) continue;
  1.2409 +
  1.2410 +    const char *type = comp->_type;
  1.2411 +    // Lookup operand form for component's type
  1.2412 +    const Form *form = globals[type];
  1.2413 +    assert( form != NULL, "Component's type not found");
  1.2414 +    OperandForm *oper = form ? form->is_operand() : NULL;
  1.2415 +    if( oper ) {
  1.2416 +      if( oper->_matrule->is_base_register(globals) ) {
  1.2417 +        ++position;
  1.2418 +      }
  1.2419 +    }
  1.2420 +  }
  1.2421 +
  1.2422 +  return position;
  1.2423 +}
  1.2424 +
  1.2425 +
  1.2426 +const char *OperandForm::reduce_result()  const {
  1.2427 +  return _ident;
  1.2428 +}
  1.2429 +// Return the name of the operand on the right hand side of the binary match
  1.2430 +// Return NULL if there is no right hand side
  1.2431 +const char *OperandForm::reduce_right(FormDict &globals)  const {
  1.2432 +  return  ( _matrule ? _matrule->reduce_right(globals) : NULL );
  1.2433 +}
  1.2434 +
  1.2435 +// Similar for left
  1.2436 +const char *OperandForm::reduce_left(FormDict &globals)   const {
  1.2437 +  return  ( _matrule ? _matrule->reduce_left(globals) : NULL );
  1.2438 +}
  1.2439 +
  1.2440 +
  1.2441 +// --------------------------- FILE *output_routines
  1.2442 +//
  1.2443 +// Output code for disp_is_oop, if true.
  1.2444 +void OperandForm::disp_is_oop(FILE *fp, FormDict &globals) {
  1.2445 +  //  Check it is a memory interface with a non-user-constant disp field
  1.2446 +  if ( this->_interface == NULL ) return;
  1.2447 +  MemInterface *mem_interface = this->_interface->is_MemInterface();
  1.2448 +  if ( mem_interface == NULL )    return;
  1.2449 +  const char   *disp  = mem_interface->_disp;
  1.2450 +  if ( *disp != '$' )             return;
  1.2451 +
  1.2452 +  // Lookup replacement variable in operand's component list
  1.2453 +  const char   *rep_var = disp + 1;
  1.2454 +  const Component *comp = this->_components.search(rep_var);
  1.2455 +  assert( comp != NULL, "Replacement variable not found in components");
  1.2456 +  // Lookup operand form for replacement variable's type
  1.2457 +  const char      *type = comp->_type;
  1.2458 +  Form            *form = (Form*)globals[type];
  1.2459 +  assert( form != NULL, "Replacement variable's type not found");
  1.2460 +  OperandForm     *op   = form->is_operand();
  1.2461 +  assert( op, "Memory Interface 'disp' can only emit an operand form");
  1.2462 +  // Check if this is a ConP, which may require relocation
  1.2463 +  if ( op->is_base_constant(globals) == Form::idealP ) {
  1.2464 +    // Find the constant's index:  _c0, _c1, _c2, ... , _cN
  1.2465 +    uint idx  = op->constant_position( globals, rep_var);
  1.2466 +    fprintf(fp,"  virtual relocInfo::relocType disp_reloc() const {");
  1.2467 +    fprintf(fp,  "  return _c%d->reloc();", idx);
  1.2468 +    fprintf(fp, " }\n");
  1.2469 +  }
  1.2470 +}
  1.2471 +
  1.2472 +// Generate code for internal and external format methods
  1.2473 +//
  1.2474 +// internal access to reg# node->_idx
  1.2475 +// access to subsumed constant _c0, _c1,
  1.2476 +void  OperandForm::int_format(FILE *fp, FormDict &globals, uint index) {
  1.2477 +  Form::DataType dtype;
  1.2478 +  if (_matrule && (_matrule->is_base_register(globals) ||
  1.2479 +                   strcmp(ideal_type(globalAD->globalNames()), "RegFlags") == 0)) {
  1.2480 +    // !!!!! !!!!!
  1.2481 +    fprintf(fp,"  { char reg_str[128];\n");
  1.2482 +    fprintf(fp,"    ra->dump_register(node,reg_str);\n");
  1.2483 +    fprintf(fp,"    st->print(\"%cs\",reg_str);\n",'%');
  1.2484 +    fprintf(fp,"  }\n");
  1.2485 +  } else if (_matrule && (dtype = _matrule->is_base_constant(globals)) != Form::none) {
  1.2486 +    format_constant( fp, index, dtype );
  1.2487 +  } else if (ideal_to_sReg_type(_ident) != Form::none) {
  1.2488 +    // Special format for Stack Slot Register
  1.2489 +    fprintf(fp,"  { char reg_str[128];\n");
  1.2490 +    fprintf(fp,"    ra->dump_register(node,reg_str);\n");
  1.2491 +    fprintf(fp,"    st->print(\"%cs\",reg_str);\n",'%');
  1.2492 +    fprintf(fp,"  }\n");
  1.2493 +  } else {
  1.2494 +    fprintf(fp,"  st->print(\"No format defined for %s\n\");\n", _ident);
  1.2495 +    fflush(fp);
  1.2496 +    fprintf(stderr,"No format defined for %s\n", _ident);
  1.2497 +    dump();
  1.2498 +    assert( false,"Internal error:\n  output_internal_operand() attempting to output other than a Register or Constant");
  1.2499 +  }
  1.2500 +}
  1.2501 +
  1.2502 +// Similar to "int_format" but for cases where data is external to operand
  1.2503 +// external access to reg# node->in(idx)->_idx,
  1.2504 +void  OperandForm::ext_format(FILE *fp, FormDict &globals, uint index) {
  1.2505 +  Form::DataType dtype;
  1.2506 +  if (_matrule && (_matrule->is_base_register(globals) ||
  1.2507 +                   strcmp(ideal_type(globalAD->globalNames()), "RegFlags") == 0)) {
  1.2508 +    fprintf(fp,"  { char reg_str[128];\n");
  1.2509 +    fprintf(fp,"    ra->dump_register(node->in(idx");
  1.2510 +    if ( index != 0 ) fprintf(fp,              "+%d",index);
  1.2511 +    fprintf(fp,                                      "),reg_str);\n");
  1.2512 +    fprintf(fp,"    st->print(\"%cs\",reg_str);\n",'%');
  1.2513 +    fprintf(fp,"  }\n");
  1.2514 +  } else if (_matrule && (dtype = _matrule->is_base_constant(globals)) != Form::none) {
  1.2515 +    format_constant( fp, index, dtype );
  1.2516 +  } else if (ideal_to_sReg_type(_ident) != Form::none) {
  1.2517 +    // Special format for Stack Slot Register
  1.2518 +    fprintf(fp,"  { char reg_str[128];\n");
  1.2519 +    fprintf(fp,"    ra->dump_register(node->in(idx");
  1.2520 +    if ( index != 0 ) fprintf(fp,                  "+%d",index);
  1.2521 +    fprintf(fp,                                       "),reg_str);\n");
  1.2522 +    fprintf(fp,"    st->print(\"%cs\",reg_str);\n",'%');
  1.2523 +    fprintf(fp,"  }\n");
  1.2524 +  } else {
  1.2525 +    fprintf(fp,"  st->print(\"No format defined for %s\n\");\n", _ident);
  1.2526 +    assert( false,"Internal error:\n  output_external_operand() attempting to output other than a Register or Constant");
  1.2527 +  }
  1.2528 +}
  1.2529 +
  1.2530 +void OperandForm::format_constant(FILE *fp, uint const_index, uint const_type) {
  1.2531 +  switch(const_type) {
  1.2532 +  case Form::idealI: fprintf(fp,"  st->print(\"#%%d\", _c%d);\n", const_index); break;
  1.2533 +  case Form::idealP: fprintf(fp,"  if (_c%d) _c%d->dump_on(st);\n", const_index, const_index); break;
  1.2534 +  case Form::idealNKlass:
  1.2535 +  case Form::idealN: fprintf(fp,"  if (_c%d) _c%d->dump_on(st);\n", const_index, const_index); break;
  1.2536 +  case Form::idealL: fprintf(fp,"  st->print(\"#\" INT64_FORMAT, (int64_t)_c%d);\n", const_index); break;
  1.2537 +  case Form::idealF: fprintf(fp,"  st->print(\"#%%f\", _c%d);\n", const_index); break;
  1.2538 +  case Form::idealD: fprintf(fp,"  st->print(\"#%%f\", _c%d);\n", const_index); break;
  1.2539 +  default:
  1.2540 +    assert( false, "ShouldNotReachHere()");
  1.2541 +  }
  1.2542 +}
  1.2543 +
  1.2544 +// Return the operand form corresponding to the given index, else NULL.
  1.2545 +OperandForm *OperandForm::constant_operand(FormDict &globals,
  1.2546 +                                           uint      index) {
  1.2547 +  // !!!!!
  1.2548 +  // Check behavior on complex operands
  1.2549 +  uint n_consts = num_consts(globals);
  1.2550 +  if( n_consts > 0 ) {
  1.2551 +    uint i = 0;
  1.2552 +    const char *type;
  1.2553 +    Component  *comp;
  1.2554 +    _components.reset();
  1.2555 +    if ((comp = _components.iter()) == NULL) {
  1.2556 +      assert(n_consts == 1, "Bad component list detected.\n");
  1.2557 +      // Current operand is THE operand
  1.2558 +      if ( index == 0 ) {
  1.2559 +        return this;
  1.2560 +      }
  1.2561 +    } // end if NULL
  1.2562 +    else {
  1.2563 +      // Skip the first component, it can not be a DEF of a constant
  1.2564 +      do {
  1.2565 +        type = comp->base_type(globals);
  1.2566 +        // Check that "type" is a 'ConI', 'ConP', ...
  1.2567 +        if ( ideal_to_const_type(type) != Form::none ) {
  1.2568 +          // When at correct component, get corresponding Operand
  1.2569 +          if ( index == 0 ) {
  1.2570 +            return globals[comp->_type]->is_operand();
  1.2571 +          }
  1.2572 +          // Decrement number of constants to go
  1.2573 +          --index;
  1.2574 +        }
  1.2575 +      } while((comp = _components.iter()) != NULL);
  1.2576 +    }
  1.2577 +  }
  1.2578 +
  1.2579 +  // Did not find a constant for this index.
  1.2580 +  return NULL;
  1.2581 +}
  1.2582 +
  1.2583 +// If this operand has a single ideal type, return its type
  1.2584 +Form::DataType OperandForm::simple_type(FormDict &globals) const {
  1.2585 +  const char *type_name = ideal_type(globals);
  1.2586 +  Form::DataType type   = type_name ? ideal_to_const_type( type_name )
  1.2587 +                                    : Form::none;
  1.2588 +  return type;
  1.2589 +}
  1.2590 +
  1.2591 +Form::DataType OperandForm::is_base_constant(FormDict &globals) const {
  1.2592 +  if ( _matrule == NULL )    return Form::none;
  1.2593 +
  1.2594 +  return _matrule->is_base_constant(globals);
  1.2595 +}
  1.2596 +
  1.2597 +// "true" if this operand is a simple type that is swallowed
  1.2598 +bool  OperandForm::swallowed(FormDict &globals) const {
  1.2599 +  Form::DataType type   = simple_type(globals);
  1.2600 +  if( type != Form::none ) {
  1.2601 +    return true;
  1.2602 +  }
  1.2603 +
  1.2604 +  return false;
  1.2605 +}
  1.2606 +
  1.2607 +// Output code to access the value of the index'th constant
  1.2608 +void OperandForm::access_constant(FILE *fp, FormDict &globals,
  1.2609 +                                  uint const_index) {
  1.2610 +  OperandForm *oper = constant_operand(globals, const_index);
  1.2611 +  assert( oper, "Index exceeds number of constants in operand");
  1.2612 +  Form::DataType dtype = oper->is_base_constant(globals);
  1.2613 +
  1.2614 +  switch(dtype) {
  1.2615 +  case idealI: fprintf(fp,"_c%d",           const_index); break;
  1.2616 +  case idealP: fprintf(fp,"_c%d->get_con()",const_index); break;
  1.2617 +  case idealL: fprintf(fp,"_c%d",           const_index); break;
  1.2618 +  case idealF: fprintf(fp,"_c%d",           const_index); break;
  1.2619 +  case idealD: fprintf(fp,"_c%d",           const_index); break;
  1.2620 +  default:
  1.2621 +    assert( false, "ShouldNotReachHere()");
  1.2622 +  }
  1.2623 +}
  1.2624 +
  1.2625 +
  1.2626 +void OperandForm::dump() {
  1.2627 +  output(stderr);
  1.2628 +}
  1.2629 +
  1.2630 +void OperandForm::output(FILE *fp) {
  1.2631 +  fprintf(fp,"\nOperand: %s\n", (_ident?_ident:""));
  1.2632 +  if (_matrule)    _matrule->dump();
  1.2633 +  if (_interface)  _interface->dump();
  1.2634 +  if (_attribs)    _attribs->dump();
  1.2635 +  if (_predicate)  _predicate->dump();
  1.2636 +  if (_constraint) _constraint->dump();
  1.2637 +  if (_construct)  _construct->dump();
  1.2638 +  if (_format)     _format->dump();
  1.2639 +}
  1.2640 +
  1.2641 +//------------------------------Constraint-------------------------------------
  1.2642 +Constraint::Constraint(const char *func, const char *arg)
  1.2643 +  : _func(func), _arg(arg) {
  1.2644 +}
  1.2645 +Constraint::~Constraint() { /* not owner of char* */
  1.2646 +}
  1.2647 +
  1.2648 +bool Constraint::stack_slots_only() const {
  1.2649 +  return strcmp(_func, "ALLOC_IN_RC") == 0
  1.2650 +      && strcmp(_arg,  "stack_slots") == 0;
  1.2651 +}
  1.2652 +
  1.2653 +void Constraint::dump() {
  1.2654 +  output(stderr);
  1.2655 +}
  1.2656 +
  1.2657 +void Constraint::output(FILE *fp) {           // Write info to output files
  1.2658 +  assert((_func != NULL && _arg != NULL),"missing constraint function or arg");
  1.2659 +  fprintf(fp,"Constraint: %s ( %s )\n", _func, _arg);
  1.2660 +}
  1.2661 +
  1.2662 +//------------------------------Predicate--------------------------------------
  1.2663 +Predicate::Predicate(char *pr)
  1.2664 +  : _pred(pr) {
  1.2665 +}
  1.2666 +Predicate::~Predicate() {
  1.2667 +}
  1.2668 +
  1.2669 +void Predicate::dump() {
  1.2670 +  output(stderr);
  1.2671 +}
  1.2672 +
  1.2673 +void Predicate::output(FILE *fp) {
  1.2674 +  fprintf(fp,"Predicate");  // Write to output files
  1.2675 +}
  1.2676 +//------------------------------Interface--------------------------------------
  1.2677 +Interface::Interface(const char *name) : _name(name) {
  1.2678 +}
  1.2679 +Interface::~Interface() {
  1.2680 +}
  1.2681 +
  1.2682 +Form::InterfaceType Interface::interface_type(FormDict &globals) const {
  1.2683 +  Interface *thsi = (Interface*)this;
  1.2684 +  if ( thsi->is_RegInterface()   ) return Form::register_interface;
  1.2685 +  if ( thsi->is_MemInterface()   ) return Form::memory_interface;
  1.2686 +  if ( thsi->is_ConstInterface() ) return Form::constant_interface;
  1.2687 +  if ( thsi->is_CondInterface()  ) return Form::conditional_interface;
  1.2688 +
  1.2689 +  return Form::no_interface;
  1.2690 +}
  1.2691 +
  1.2692 +RegInterface   *Interface::is_RegInterface() {
  1.2693 +  if ( strcmp(_name,"REG_INTER") != 0 )
  1.2694 +    return NULL;
  1.2695 +  return (RegInterface*)this;
  1.2696 +}
  1.2697 +MemInterface   *Interface::is_MemInterface() {
  1.2698 +  if ( strcmp(_name,"MEMORY_INTER") != 0 )  return NULL;
  1.2699 +  return (MemInterface*)this;
  1.2700 +}
  1.2701 +ConstInterface *Interface::is_ConstInterface() {
  1.2702 +  if ( strcmp(_name,"CONST_INTER") != 0 )  return NULL;
  1.2703 +  return (ConstInterface*)this;
  1.2704 +}
  1.2705 +CondInterface  *Interface::is_CondInterface() {
  1.2706 +  if ( strcmp(_name,"COND_INTER") != 0 )  return NULL;
  1.2707 +  return (CondInterface*)this;
  1.2708 +}
  1.2709 +
  1.2710 +
  1.2711 +void Interface::dump() {
  1.2712 +  output(stderr);
  1.2713 +}
  1.2714 +
  1.2715 +// Write info to output files
  1.2716 +void Interface::output(FILE *fp) {
  1.2717 +  fprintf(fp,"Interface: %s\n", (_name ? _name : "") );
  1.2718 +}
  1.2719 +
  1.2720 +//------------------------------RegInterface-----------------------------------
  1.2721 +RegInterface::RegInterface() : Interface("REG_INTER") {
  1.2722 +}
  1.2723 +RegInterface::~RegInterface() {
  1.2724 +}
  1.2725 +
  1.2726 +void RegInterface::dump() {
  1.2727 +  output(stderr);
  1.2728 +}
  1.2729 +
  1.2730 +// Write info to output files
  1.2731 +void RegInterface::output(FILE *fp) {
  1.2732 +  Interface::output(fp);
  1.2733 +}
  1.2734 +
  1.2735 +//------------------------------ConstInterface---------------------------------
  1.2736 +ConstInterface::ConstInterface() : Interface("CONST_INTER") {
  1.2737 +}
  1.2738 +ConstInterface::~ConstInterface() {
  1.2739 +}
  1.2740 +
  1.2741 +void ConstInterface::dump() {
  1.2742 +  output(stderr);
  1.2743 +}
  1.2744 +
  1.2745 +// Write info to output files
  1.2746 +void ConstInterface::output(FILE *fp) {
  1.2747 +  Interface::output(fp);
  1.2748 +}
  1.2749 +
  1.2750 +//------------------------------MemInterface-----------------------------------
  1.2751 +MemInterface::MemInterface(char *base, char *index, char *scale, char *disp)
  1.2752 +  : Interface("MEMORY_INTER"), _base(base), _index(index), _scale(scale), _disp(disp) {
  1.2753 +}
  1.2754 +MemInterface::~MemInterface() {
  1.2755 +  // not owner of any character arrays
  1.2756 +}
  1.2757 +
  1.2758 +void MemInterface::dump() {
  1.2759 +  output(stderr);
  1.2760 +}
  1.2761 +
  1.2762 +// Write info to output files
  1.2763 +void MemInterface::output(FILE *fp) {
  1.2764 +  Interface::output(fp);
  1.2765 +  if ( _base  != NULL ) fprintf(fp,"  base  == %s\n", _base);
  1.2766 +  if ( _index != NULL ) fprintf(fp,"  index == %s\n", _index);
  1.2767 +  if ( _scale != NULL ) fprintf(fp,"  scale == %s\n", _scale);
  1.2768 +  if ( _disp  != NULL ) fprintf(fp,"  disp  == %s\n", _disp);
  1.2769 +  // fprintf(fp,"\n");
  1.2770 +}
  1.2771 +
  1.2772 +//------------------------------CondInterface----------------------------------
  1.2773 +CondInterface::CondInterface(const char* equal,         const char* equal_format,
  1.2774 +                             const char* not_equal,     const char* not_equal_format,
  1.2775 +                             const char* less,          const char* less_format,
  1.2776 +                             const char* greater_equal, const char* greater_equal_format,
  1.2777 +                             const char* less_equal,    const char* less_equal_format,
  1.2778 +                             const char* greater,       const char* greater_format,
  1.2779 +                             const char* overflow,      const char* overflow_format,
  1.2780 +                             const char* no_overflow,   const char* no_overflow_format)
  1.2781 +  : Interface("COND_INTER"),
  1.2782 +    _equal(equal),                 _equal_format(equal_format),
  1.2783 +    _not_equal(not_equal),         _not_equal_format(not_equal_format),
  1.2784 +    _less(less),                   _less_format(less_format),
  1.2785 +    _greater_equal(greater_equal), _greater_equal_format(greater_equal_format),
  1.2786 +    _less_equal(less_equal),       _less_equal_format(less_equal_format),
  1.2787 +    _greater(greater),             _greater_format(greater_format),
  1.2788 +    _overflow(overflow),           _overflow_format(overflow_format),
  1.2789 +    _no_overflow(no_overflow),     _no_overflow_format(no_overflow_format) {
  1.2790 +}
  1.2791 +CondInterface::~CondInterface() {
  1.2792 +  // not owner of any character arrays
  1.2793 +}
  1.2794 +
  1.2795 +void CondInterface::dump() {
  1.2796 +  output(stderr);
  1.2797 +}
  1.2798 +
  1.2799 +// Write info to output files
  1.2800 +void CondInterface::output(FILE *fp) {
  1.2801 +  Interface::output(fp);
  1.2802 +  if ( _equal  != NULL )     fprintf(fp," equal        == %s\n", _equal);
  1.2803 +  if ( _not_equal  != NULL ) fprintf(fp," not_equal    == %s\n", _not_equal);
  1.2804 +  if ( _less  != NULL )      fprintf(fp," less         == %s\n", _less);
  1.2805 +  if ( _greater_equal  != NULL ) fprintf(fp," greater_equal    == %s\n", _greater_equal);
  1.2806 +  if ( _less_equal  != NULL ) fprintf(fp," less_equal   == %s\n", _less_equal);
  1.2807 +  if ( _greater  != NULL )    fprintf(fp," greater      == %s\n", _greater);
  1.2808 +  if ( _overflow != NULL )    fprintf(fp," overflow     == %s\n", _overflow);
  1.2809 +  if ( _no_overflow != NULL ) fprintf(fp," no_overflow  == %s\n", _no_overflow);
  1.2810 +  // fprintf(fp,"\n");
  1.2811 +}
  1.2812 +
  1.2813 +//------------------------------ConstructRule----------------------------------
  1.2814 +ConstructRule::ConstructRule(char *cnstr)
  1.2815 +  : _construct(cnstr) {
  1.2816 +}
  1.2817 +ConstructRule::~ConstructRule() {
  1.2818 +}
  1.2819 +
  1.2820 +void ConstructRule::dump() {
  1.2821 +  output(stderr);
  1.2822 +}
  1.2823 +
  1.2824 +void ConstructRule::output(FILE *fp) {
  1.2825 +  fprintf(fp,"\nConstruct Rule\n");  // Write to output files
  1.2826 +}
  1.2827 +
  1.2828 +
  1.2829 +//==============================Shared Forms===================================
  1.2830 +//------------------------------AttributeForm----------------------------------
  1.2831 +int         AttributeForm::_insId   = 0;           // start counter at 0
  1.2832 +int         AttributeForm::_opId    = 0;           // start counter at 0
  1.2833 +const char* AttributeForm::_ins_cost = "ins_cost"; // required name
  1.2834 +const char* AttributeForm::_op_cost  = "op_cost";  // required name
  1.2835 +
  1.2836 +AttributeForm::AttributeForm(char *attr, int type, char *attrdef)
  1.2837 +  : Form(Form::ATTR), _attrname(attr), _atype(type), _attrdef(attrdef) {
  1.2838 +    if (type==OP_ATTR) {
  1.2839 +      id = ++_opId;
  1.2840 +    }
  1.2841 +    else if (type==INS_ATTR) {
  1.2842 +      id = ++_insId;
  1.2843 +    }
  1.2844 +    else assert( false,"");
  1.2845 +}
  1.2846 +AttributeForm::~AttributeForm() {
  1.2847 +}
  1.2848 +
  1.2849 +// Dynamic type check
  1.2850 +AttributeForm *AttributeForm::is_attribute() const {
  1.2851 +  return (AttributeForm*)this;
  1.2852 +}
  1.2853 +
  1.2854 +
  1.2855 +// inlined  // int  AttributeForm::type() { return id;}
  1.2856 +
  1.2857 +void AttributeForm::dump() {
  1.2858 +  output(stderr);
  1.2859 +}
  1.2860 +
  1.2861 +void AttributeForm::output(FILE *fp) {
  1.2862 +  if( _attrname && _attrdef ) {
  1.2863 +    fprintf(fp,"\n// AttributeForm \nstatic const int %s = %s;\n",
  1.2864 +            _attrname, _attrdef);
  1.2865 +  }
  1.2866 +  else {
  1.2867 +    fprintf(fp,"\n// AttributeForm missing name %s or definition %s\n",
  1.2868 +            (_attrname?_attrname:""), (_attrdef?_attrdef:"") );
  1.2869 +  }
  1.2870 +}
  1.2871 +
  1.2872 +//------------------------------Component--------------------------------------
  1.2873 +Component::Component(const char *name, const char *type, int usedef)
  1.2874 +  : _name(name), _type(type), _usedef(usedef) {
  1.2875 +    _ftype = Form::COMP;
  1.2876 +}
  1.2877 +Component::~Component() {
  1.2878 +}
  1.2879 +
  1.2880 +// True if this component is equal to the parameter.
  1.2881 +bool Component::is(int use_def_kill_enum) const {
  1.2882 +  return (_usedef == use_def_kill_enum ? true : false);
  1.2883 +}
  1.2884 +// True if this component is used/def'd/kill'd as the parameter suggests.
  1.2885 +bool Component::isa(int use_def_kill_enum) const {
  1.2886 +  return (_usedef & use_def_kill_enum) == use_def_kill_enum;
  1.2887 +}
  1.2888 +
  1.2889 +// Extend this component with additional use/def/kill behavior
  1.2890 +int Component::promote_use_def_info(int new_use_def) {
  1.2891 +  _usedef |= new_use_def;
  1.2892 +
  1.2893 +  return _usedef;
  1.2894 +}
  1.2895 +
  1.2896 +// Check the base type of this component, if it has one
  1.2897 +const char *Component::base_type(FormDict &globals) {
  1.2898 +  const Form *frm = globals[_type];
  1.2899 +  if (frm == NULL) return NULL;
  1.2900 +  OperandForm *op = frm->is_operand();
  1.2901 +  if (op == NULL) return NULL;
  1.2902 +  if (op->ideal_only()) return op->_ident;
  1.2903 +  return (char *)op->ideal_type(globals);
  1.2904 +}
  1.2905 +
  1.2906 +void Component::dump() {
  1.2907 +  output(stderr);
  1.2908 +}
  1.2909 +
  1.2910 +void Component::output(FILE *fp) {
  1.2911 +  fprintf(fp,"Component:");  // Write to output files
  1.2912 +  fprintf(fp, "  name = %s", _name);
  1.2913 +  fprintf(fp, ", type = %s", _type);
  1.2914 +  assert(_usedef != 0, "unknown effect");
  1.2915 +  fprintf(fp, ", use/def = %s\n", getUsedefName());
  1.2916 +}
  1.2917 +
  1.2918 +
  1.2919 +//------------------------------ComponentList---------------------------------
  1.2920 +ComponentList::ComponentList() : NameList(), _matchcnt(0) {
  1.2921 +}
  1.2922 +ComponentList::~ComponentList() {
  1.2923 +  // // This list may not own its elements if copied via assignment
  1.2924 +  // Component *component;
  1.2925 +  // for (reset(); (component = iter()) != NULL;) {
  1.2926 +  //   delete component;
  1.2927 +  // }
  1.2928 +}
  1.2929 +
  1.2930 +void   ComponentList::insert(Component *component, bool mflag) {
  1.2931 +  NameList::addName((char *)component);
  1.2932 +  if(mflag) _matchcnt++;
  1.2933 +}
  1.2934 +void   ComponentList::insert(const char *name, const char *opType, int usedef,
  1.2935 +                             bool mflag) {
  1.2936 +  Component * component = new Component(name, opType, usedef);
  1.2937 +  insert(component, mflag);
  1.2938 +}
  1.2939 +Component *ComponentList::current() { return (Component*)NameList::current(); }
  1.2940 +Component *ComponentList::iter()    { return (Component*)NameList::iter(); }
  1.2941 +Component *ComponentList::match_iter() {
  1.2942 +  if(_iter < _matchcnt) return (Component*)NameList::iter();
  1.2943 +  return NULL;
  1.2944 +}
  1.2945 +Component *ComponentList::post_match_iter() {
  1.2946 +  Component *comp = iter();
  1.2947 +  // At end of list?
  1.2948 +  if ( comp == NULL ) {
  1.2949 +    return comp;
  1.2950 +  }
  1.2951 +  // In post-match components?
  1.2952 +  if (_iter > match_count()-1) {
  1.2953 +    return comp;
  1.2954 +  }
  1.2955 +
  1.2956 +  return post_match_iter();
  1.2957 +}
  1.2958 +
  1.2959 +void       ComponentList::reset()   { NameList::reset(); }
  1.2960 +int        ComponentList::count()   { return NameList::count(); }
  1.2961 +
  1.2962 +Component *ComponentList::operator[](int position) {
  1.2963 +  // Shortcut complete iteration if there are not enough entries
  1.2964 +  if (position >= count()) return NULL;
  1.2965 +
  1.2966 +  int        index     = 0;
  1.2967 +  Component *component = NULL;
  1.2968 +  for (reset(); (component = iter()) != NULL;) {
  1.2969 +    if (index == position) {
  1.2970 +      return component;
  1.2971 +    }
  1.2972 +    ++index;
  1.2973 +  }
  1.2974 +
  1.2975 +  return NULL;
  1.2976 +}
  1.2977 +
  1.2978 +const Component *ComponentList::search(const char *name) {
  1.2979 +  PreserveIter pi(this);
  1.2980 +  reset();
  1.2981 +  for( Component *comp = NULL; ((comp = iter()) != NULL); ) {
  1.2982 +    if( strcmp(comp->_name,name) == 0 ) return comp;
  1.2983 +  }
  1.2984 +
  1.2985 +  return NULL;
  1.2986 +}
  1.2987 +
  1.2988 +// Return number of USEs + number of DEFs
  1.2989 +// When there are no components, or the first component is a USE,
  1.2990 +// then we add '1' to hold a space for the 'result' operand.
  1.2991 +int ComponentList::num_operands() {
  1.2992 +  PreserveIter pi(this);
  1.2993 +  uint       count = 1;           // result operand
  1.2994 +  uint       position = 0;
  1.2995 +
  1.2996 +  Component *component  = NULL;
  1.2997 +  for( reset(); (component = iter()) != NULL; ++position ) {
  1.2998 +    if( component->isa(Component::USE) ||
  1.2999 +        ( position == 0 && (! component->isa(Component::DEF))) ) {
  1.3000 +      ++count;
  1.3001 +    }
  1.3002 +  }
  1.3003 +
  1.3004 +  return count;
  1.3005 +}
  1.3006 +
  1.3007 +// Return zero-based position of operand 'name' in list;  -1 if not in list.
  1.3008 +// if parameter 'usedef' is ::USE, it will match USE, USE_DEF, ...
  1.3009 +int ComponentList::operand_position(const char *name, int usedef, Form *fm) {
  1.3010 +  PreserveIter pi(this);
  1.3011 +  int position = 0;
  1.3012 +  int num_opnds = num_operands();
  1.3013 +  Component *component;
  1.3014 +  Component* preceding_non_use = NULL;
  1.3015 +  Component* first_def = NULL;
  1.3016 +  for (reset(); (component = iter()) != NULL; ++position) {
  1.3017 +    // When the first component is not a DEF,
  1.3018 +    // leave space for the result operand!
  1.3019 +    if ( position==0 && (! component->isa(Component::DEF)) ) {
  1.3020 +      ++position;
  1.3021 +      ++num_opnds;
  1.3022 +    }
  1.3023 +    if (strcmp(name, component->_name)==0 && (component->isa(usedef))) {
  1.3024 +      // When the first entry in the component list is a DEF and a USE
  1.3025 +      // Treat them as being separate, a DEF first, then a USE
  1.3026 +      if( position==0
  1.3027 +          && usedef==Component::USE && component->isa(Component::DEF) ) {
  1.3028 +        assert(position+1 < num_opnds, "advertised index in bounds");
  1.3029 +        return position+1;
  1.3030 +      } else {
  1.3031 +        if( preceding_non_use && strcmp(component->_name, preceding_non_use->_name) ) {
  1.3032 +          fprintf(stderr, "the name '%s(%s)' should not precede the name '%s(%s)'",
  1.3033 +                  preceding_non_use->_name, preceding_non_use->getUsedefName(),
  1.3034 +                  name, component->getUsedefName());
  1.3035 +          if (fm && fm->is_instruction()) fprintf(stderr,  "in form '%s'", fm->is_instruction()->_ident);
  1.3036 +          if (fm && fm->is_operand()) fprintf(stderr,  "in form '%s'", fm->is_operand()->_ident);
  1.3037 +          fprintf(stderr,  "\n");
  1.3038 +        }
  1.3039 +        if( position >= num_opnds ) {
  1.3040 +          fprintf(stderr, "the name '%s' is too late in its name list", name);
  1.3041 +          if (fm && fm->is_instruction()) fprintf(stderr,  "in form '%s'", fm->is_instruction()->_ident);
  1.3042 +          if (fm && fm->is_operand()) fprintf(stderr,  "in form '%s'", fm->is_operand()->_ident);
  1.3043 +          fprintf(stderr,  "\n");
  1.3044 +        }
  1.3045 +        assert(position < num_opnds, "advertised index in bounds");
  1.3046 +        return position;
  1.3047 +      }
  1.3048 +    }
  1.3049 +    if( component->isa(Component::DEF)
  1.3050 +        && component->isa(Component::USE) ) {
  1.3051 +      ++position;
  1.3052 +      if( position != 1 )  --position;   // only use two slots for the 1st USE_DEF
  1.3053 +    }
  1.3054 +    if( component->isa(Component::DEF) && !first_def ) {
  1.3055 +      first_def = component;
  1.3056 +    }
  1.3057 +    if( !component->isa(Component::USE) && component != first_def ) {
  1.3058 +      preceding_non_use = component;
  1.3059 +    } else if( preceding_non_use && !strcmp(component->_name, preceding_non_use->_name) ) {
  1.3060 +      preceding_non_use = NULL;
  1.3061 +    }
  1.3062 +  }
  1.3063 +  return Not_in_list;
  1.3064 +}
  1.3065 +
  1.3066 +// Find position for this name, regardless of use/def information
  1.3067 +int ComponentList::operand_position(const char *name) {
  1.3068 +  PreserveIter pi(this);
  1.3069 +  int position = 0;
  1.3070 +  Component *component;
  1.3071 +  for (reset(); (component = iter()) != NULL; ++position) {
  1.3072 +    // When the first component is not a DEF,
  1.3073 +    // leave space for the result operand!
  1.3074 +    if ( position==0 && (! component->isa(Component::DEF)) ) {
  1.3075 +      ++position;
  1.3076 +    }
  1.3077 +    if (strcmp(name, component->_name)==0) {
  1.3078 +      return position;
  1.3079 +    }
  1.3080 +    if( component->isa(Component::DEF)
  1.3081 +        && component->isa(Component::USE) ) {
  1.3082 +      ++position;
  1.3083 +      if( position != 1 )  --position;   // only use two slots for the 1st USE_DEF
  1.3084 +    }
  1.3085 +  }
  1.3086 +  return Not_in_list;
  1.3087 +}
  1.3088 +
  1.3089 +int ComponentList::operand_position_format(const char *name, Form *fm) {
  1.3090 +  PreserveIter pi(this);
  1.3091 +  int  first_position = operand_position(name);
  1.3092 +  int  use_position   = operand_position(name, Component::USE, fm);
  1.3093 +
  1.3094 +  return ((first_position < use_position) ? use_position : first_position);
  1.3095 +}
  1.3096 +
  1.3097 +int ComponentList::label_position() {
  1.3098 +  PreserveIter pi(this);
  1.3099 +  int position = 0;
  1.3100 +  reset();
  1.3101 +  for( Component *comp; (comp = iter()) != NULL; ++position) {
  1.3102 +    // When the first component is not a DEF,
  1.3103 +    // leave space for the result operand!
  1.3104 +    if ( position==0 && (! comp->isa(Component::DEF)) ) {
  1.3105 +      ++position;
  1.3106 +    }
  1.3107 +    if (strcmp(comp->_type, "label")==0) {
  1.3108 +      return position;
  1.3109 +    }
  1.3110 +    if( comp->isa(Component::DEF)
  1.3111 +        && comp->isa(Component::USE) ) {
  1.3112 +      ++position;
  1.3113 +      if( position != 1 )  --position;   // only use two slots for the 1st USE_DEF
  1.3114 +    }
  1.3115 +  }
  1.3116 +
  1.3117 +  return -1;
  1.3118 +}
  1.3119 +
  1.3120 +int ComponentList::method_position() {
  1.3121 +  PreserveIter pi(this);
  1.3122 +  int position = 0;
  1.3123 +  reset();
  1.3124 +  for( Component *comp; (comp = iter()) != NULL; ++position) {
  1.3125 +    // When the first component is not a DEF,
  1.3126 +    // leave space for the result operand!
  1.3127 +    if ( position==0 && (! comp->isa(Component::DEF)) ) {
  1.3128 +      ++position;
  1.3129 +    }
  1.3130 +    if (strcmp(comp->_type, "method")==0) {
  1.3131 +      return position;
  1.3132 +    }
  1.3133 +    if( comp->isa(Component::DEF)
  1.3134 +        && comp->isa(Component::USE) ) {
  1.3135 +      ++position;
  1.3136 +      if( position != 1 )  --position;   // only use two slots for the 1st USE_DEF
  1.3137 +    }
  1.3138 +  }
  1.3139 +
  1.3140 +  return -1;
  1.3141 +}
  1.3142 +
  1.3143 +void ComponentList::dump() { output(stderr); }
  1.3144 +
  1.3145 +void ComponentList::output(FILE *fp) {
  1.3146 +  PreserveIter pi(this);
  1.3147 +  fprintf(fp, "\n");
  1.3148 +  Component *component;
  1.3149 +  for (reset(); (component = iter()) != NULL;) {
  1.3150 +    component->output(fp);
  1.3151 +  }
  1.3152 +  fprintf(fp, "\n");
  1.3153 +}
  1.3154 +
  1.3155 +//------------------------------MatchNode--------------------------------------
  1.3156 +MatchNode::MatchNode(ArchDesc &ad, const char *result, const char *mexpr,
  1.3157 +                     const char *opType, MatchNode *lChild, MatchNode *rChild)
  1.3158 +  : _AD(ad), _result(result), _name(mexpr), _opType(opType),
  1.3159 +    _lChild(lChild), _rChild(rChild), _internalop(0), _numleaves(0),
  1.3160 +    _commutative_id(0) {
  1.3161 +  _numleaves = (lChild ? lChild->_numleaves : 0)
  1.3162 +               + (rChild ? rChild->_numleaves : 0);
  1.3163 +}
  1.3164 +
  1.3165 +MatchNode::MatchNode(ArchDesc &ad, MatchNode& mnode)
  1.3166 +  : _AD(ad), _result(mnode._result), _name(mnode._name),
  1.3167 +    _opType(mnode._opType), _lChild(mnode._lChild), _rChild(mnode._rChild),
  1.3168 +    _internalop(0), _numleaves(mnode._numleaves),
  1.3169 +    _commutative_id(mnode._commutative_id) {
  1.3170 +}
  1.3171 +
  1.3172 +MatchNode::MatchNode(ArchDesc &ad, MatchNode& mnode, int clone)
  1.3173 +  : _AD(ad), _result(mnode._result), _name(mnode._name),
  1.3174 +    _opType(mnode._opType),
  1.3175 +    _internalop(0), _numleaves(mnode._numleaves),
  1.3176 +    _commutative_id(mnode._commutative_id) {
  1.3177 +  if (mnode._lChild) {
  1.3178 +    _lChild = new MatchNode(ad, *mnode._lChild, clone);
  1.3179 +  } else {
  1.3180 +    _lChild = NULL;
  1.3181 +  }
  1.3182 +  if (mnode._rChild) {
  1.3183 +    _rChild = new MatchNode(ad, *mnode._rChild, clone);
  1.3184 +  } else {
  1.3185 +    _rChild = NULL;
  1.3186 +  }
  1.3187 +}
  1.3188 +
  1.3189 +MatchNode::~MatchNode() {
  1.3190 +  // // This node may not own its children if copied via assignment
  1.3191 +  // if( _lChild ) delete _lChild;
  1.3192 +  // if( _rChild ) delete _rChild;
  1.3193 +}
  1.3194 +
  1.3195 +bool  MatchNode::find_type(const char *type, int &position) const {
  1.3196 +  if ( (_lChild != NULL) && (_lChild->find_type(type, position)) ) return true;
  1.3197 +  if ( (_rChild != NULL) && (_rChild->find_type(type, position)) ) return true;
  1.3198 +
  1.3199 +  if (strcmp(type,_opType)==0)  {
  1.3200 +    return true;
  1.3201 +  } else {
  1.3202 +    ++position;
  1.3203 +  }
  1.3204 +  return false;
  1.3205 +}
  1.3206 +
  1.3207 +// Recursive call collecting info on top-level operands, not transitive.
  1.3208 +// Implementation does not modify state of internal structures.
  1.3209 +void MatchNode::append_components(FormDict& locals, ComponentList& components,
  1.3210 +                                  bool def_flag) const {
  1.3211 +  int usedef = def_flag ? Component::DEF : Component::USE;
  1.3212 +  FormDict &globals = _AD.globalNames();
  1.3213 +
  1.3214 +  assert (_name != NULL, "MatchNode::build_components encountered empty node\n");
  1.3215 +  // Base case
  1.3216 +  if (_lChild==NULL && _rChild==NULL) {
  1.3217 +    // If _opType is not an operation, do not build a component for it #####
  1.3218 +    const Form *f = globals[_opType];
  1.3219 +    if( f != NULL ) {
  1.3220 +      // Add non-ideals that are operands, operand-classes,
  1.3221 +      if( ! f->ideal_only()
  1.3222 +          && (f->is_opclass() || f->is_operand()) ) {
  1.3223 +        components.insert(_name, _opType, usedef, true);
  1.3224 +      }
  1.3225 +    }
  1.3226 +    return;
  1.3227 +  }
  1.3228 +  // Promote results of "Set" to DEF
  1.3229 +  bool tmpdef_flag = (!strcmp(_opType, "Set")) ? true : false;
  1.3230 +  if (_lChild) _lChild->append_components(locals, components, tmpdef_flag);
  1.3231 +  tmpdef_flag = false;   // only applies to component immediately following 'Set'
  1.3232 +  if (_rChild) _rChild->append_components(locals, components, tmpdef_flag);
  1.3233 +}
  1.3234 +
  1.3235 +// Find the n'th base-operand in the match node,
  1.3236 +// recursively investigates match rules of user-defined operands.
  1.3237 +//
  1.3238 +// Implementation does not modify state of internal structures since they
  1.3239 +// can be shared.
  1.3240 +bool MatchNode::base_operand(uint &position, FormDict &globals,
  1.3241 +                             const char * &result, const char * &name,
  1.3242 +                             const char * &opType) const {
  1.3243 +  assert (_name != NULL, "MatchNode::base_operand encountered empty node\n");
  1.3244 +  // Base case
  1.3245 +  if (_lChild==NULL && _rChild==NULL) {
  1.3246 +    // Check for special case: "Universe", "label"
  1.3247 +    if (strcmp(_opType,"Universe") == 0 || strcmp(_opType,"label")==0 ) {
  1.3248 +      if (position == 0) {
  1.3249 +        result = _result;
  1.3250 +        name   = _name;
  1.3251 +        opType = _opType;
  1.3252 +        return 1;
  1.3253 +      } else {
  1.3254 +        -- position;
  1.3255 +        return 0;
  1.3256 +      }
  1.3257 +    }
  1.3258 +
  1.3259 +    const Form *form = globals[_opType];
  1.3260 +    MatchNode *matchNode = NULL;
  1.3261 +    // Check for user-defined type
  1.3262 +    if (form) {
  1.3263 +      // User operand or instruction?
  1.3264 +      OperandForm  *opForm = form->is_operand();
  1.3265 +      InstructForm *inForm = form->is_instruction();
  1.3266 +      if ( opForm ) {
  1.3267 +        matchNode = (MatchNode*)opForm->_matrule;
  1.3268 +      } else if ( inForm ) {
  1.3269 +        matchNode = (MatchNode*)inForm->_matrule;
  1.3270 +      }
  1.3271 +    }
  1.3272 +    // if this is user-defined, recurse on match rule
  1.3273 +    // User-defined operand and instruction forms have a match-rule.
  1.3274 +    if (matchNode) {
  1.3275 +      return (matchNode->base_operand(position,globals,result,name,opType));
  1.3276 +    } else {
  1.3277 +      // Either not a form, or a system-defined form (no match rule).
  1.3278 +      if (position==0) {
  1.3279 +        result = _result;
  1.3280 +        name   = _name;
  1.3281 +        opType = _opType;
  1.3282 +        return 1;
  1.3283 +      } else {
  1.3284 +        --position;
  1.3285 +        return 0;
  1.3286 +      }
  1.3287 +    }
  1.3288 +
  1.3289 +  } else {
  1.3290 +    // Examine the left child and right child as well
  1.3291 +    if (_lChild) {
  1.3292 +      if (_lChild->base_operand(position, globals, result, name, opType))
  1.3293 +        return 1;
  1.3294 +    }
  1.3295 +
  1.3296 +    if (_rChild) {
  1.3297 +      if (_rChild->base_operand(position, globals, result, name, opType))
  1.3298 +        return 1;
  1.3299 +    }
  1.3300 +  }
  1.3301 +
  1.3302 +  return 0;
  1.3303 +}
  1.3304 +
  1.3305 +// Recursive call on all operands' match rules in my match rule.
  1.3306 +uint  MatchNode::num_consts(FormDict &globals) const {
  1.3307 +  uint        index      = 0;
  1.3308 +  uint        num_consts = 0;
  1.3309 +  const char *result;
  1.3310 +  const char *name;
  1.3311 +  const char *opType;
  1.3312 +
  1.3313 +  for (uint position = index;
  1.3314 +       base_operand(position,globals,result,name,opType); position = index) {
  1.3315 +    ++index;
  1.3316 +    if( ideal_to_const_type(opType) )        num_consts++;
  1.3317 +  }
  1.3318 +
  1.3319 +  return num_consts;
  1.3320 +}
  1.3321 +
  1.3322 +// Recursive call on all operands' match rules in my match rule.
  1.3323 +// Constants in match rule subtree with specified type
  1.3324 +uint  MatchNode::num_consts(FormDict &globals, Form::DataType type) const {
  1.3325 +  uint        index      = 0;
  1.3326 +  uint        num_consts = 0;
  1.3327 +  const char *result;
  1.3328 +  const char *name;
  1.3329 +  const char *opType;
  1.3330 +
  1.3331 +  for (uint position = index;
  1.3332 +       base_operand(position,globals,result,name,opType); position = index) {
  1.3333 +    ++index;
  1.3334 +    if( ideal_to_const_type(opType) == type ) num_consts++;
  1.3335 +  }
  1.3336 +
  1.3337 +  return num_consts;
  1.3338 +}
  1.3339 +
  1.3340 +// Recursive call on all operands' match rules in my match rule.
  1.3341 +uint  MatchNode::num_const_ptrs(FormDict &globals) const {
  1.3342 +  return  num_consts( globals, Form::idealP );
  1.3343 +}
  1.3344 +
  1.3345 +bool  MatchNode::sets_result() const {
  1.3346 +  return   ( (strcmp(_name,"Set") == 0) ? true : false );
  1.3347 +}
  1.3348 +
  1.3349 +const char *MatchNode::reduce_right(FormDict &globals) const {
  1.3350 +  // If there is no right reduction, return NULL.
  1.3351 +  const char      *rightStr    = NULL;
  1.3352 +
  1.3353 +  // If we are a "Set", start from the right child.
  1.3354 +  const MatchNode *const mnode = sets_result() ?
  1.3355 +    (const MatchNode *)this->_rChild :
  1.3356 +    (const MatchNode *)this;
  1.3357 +
  1.3358 +  // If our right child exists, it is the right reduction
  1.3359 +  if ( mnode->_rChild ) {
  1.3360 +    rightStr = mnode->_rChild->_internalop ? mnode->_rChild->_internalop
  1.3361 +      : mnode->_rChild->_opType;
  1.3362 +  }
  1.3363 +  // Else, May be simple chain rule: (Set dst operand_form), rightStr=NULL;
  1.3364 +  return rightStr;
  1.3365 +}
  1.3366 +
  1.3367 +const char *MatchNode::reduce_left(FormDict &globals) const {
  1.3368 +  // If there is no left reduction, return NULL.
  1.3369 +  const char  *leftStr  = NULL;
  1.3370 +
  1.3371 +  // If we are a "Set", start from the right child.
  1.3372 +  const MatchNode *const mnode = sets_result() ?
  1.3373 +    (const MatchNode *)this->_rChild :
  1.3374 +    (const MatchNode *)this;
  1.3375 +
  1.3376 +  // If our left child exists, it is the left reduction
  1.3377 +  if ( mnode->_lChild ) {
  1.3378 +    leftStr = mnode->_lChild->_internalop ? mnode->_lChild->_internalop
  1.3379 +      : mnode->_lChild->_opType;
  1.3380 +  } else {
  1.3381 +    // May be simple chain rule: (Set dst operand_form_source)
  1.3382 +    if ( sets_result() ) {
  1.3383 +      OperandForm *oper = globals[mnode->_opType]->is_operand();
  1.3384 +      if( oper ) {
  1.3385 +        leftStr = mnode->_opType;
  1.3386 +      }
  1.3387 +    }
  1.3388 +  }
  1.3389 +  return leftStr;
  1.3390 +}
  1.3391 +
  1.3392 +//------------------------------count_instr_names------------------------------
  1.3393 +// Count occurrences of operands names in the leaves of the instruction
  1.3394 +// match rule.
  1.3395 +void MatchNode::count_instr_names( Dict &names ) {
  1.3396 +  if( !this ) return;
  1.3397 +  if( _lChild ) _lChild->count_instr_names(names);
  1.3398 +  if( _rChild ) _rChild->count_instr_names(names);
  1.3399 +  if( !_lChild && !_rChild ) {
  1.3400 +    uintptr_t cnt = (uintptr_t)names[_name];
  1.3401 +    cnt++;                      // One more name found
  1.3402 +    names.Insert(_name,(void*)cnt);
  1.3403 +  }
  1.3404 +}
  1.3405 +
  1.3406 +//------------------------------build_instr_pred-------------------------------
  1.3407 +// Build a path to 'name' in buf.  Actually only build if cnt is zero, so we
  1.3408 +// can skip some leading instances of 'name'.
  1.3409 +int MatchNode::build_instr_pred( char *buf, const char *name, int cnt ) {
  1.3410 +  if( _lChild ) {
  1.3411 +    if( !cnt ) strcpy( buf, "_kids[0]->" );
  1.3412 +    cnt = _lChild->build_instr_pred( buf+strlen(buf), name, cnt );
  1.3413 +    if( cnt < 0 ) return cnt;   // Found it, all done
  1.3414 +  }
  1.3415 +  if( _rChild ) {
  1.3416 +    if( !cnt ) strcpy( buf, "_kids[1]->" );
  1.3417 +    cnt = _rChild->build_instr_pred( buf+strlen(buf), name, cnt );
  1.3418 +    if( cnt < 0 ) return cnt;   // Found it, all done
  1.3419 +  }
  1.3420 +  if( !_lChild && !_rChild ) {  // Found a leaf
  1.3421 +    // Wrong name?  Give up...
  1.3422 +    if( strcmp(name,_name) ) return cnt;
  1.3423 +    if( !cnt ) strcpy(buf,"_leaf");
  1.3424 +    return cnt-1;
  1.3425 +  }
  1.3426 +  return cnt;
  1.3427 +}
  1.3428 +
  1.3429 +
  1.3430 +//------------------------------build_internalop-------------------------------
  1.3431 +// Build string representation of subtree
  1.3432 +void MatchNode::build_internalop( ) {
  1.3433 +  char *iop, *subtree;
  1.3434 +  const char *lstr, *rstr;
  1.3435 +  // Build string representation of subtree
  1.3436 +  // Operation lchildType rchildType
  1.3437 +  int len = (int)strlen(_opType) + 4;
  1.3438 +  lstr = (_lChild) ? ((_lChild->_internalop) ?
  1.3439 +                       _lChild->_internalop : _lChild->_opType) : "";
  1.3440 +  rstr = (_rChild) ? ((_rChild->_internalop) ?
  1.3441 +                       _rChild->_internalop : _rChild->_opType) : "";
  1.3442 +  len += (int)strlen(lstr) + (int)strlen(rstr);
  1.3443 +  subtree = (char *)malloc(len);
  1.3444 +  sprintf(subtree,"_%s_%s_%s", _opType, lstr, rstr);
  1.3445 +  // Hash the subtree string in _internalOps; if a name exists, use it
  1.3446 +  iop = (char *)_AD._internalOps[subtree];
  1.3447 +  // Else create a unique name, and add it to the hash table
  1.3448 +  if (iop == NULL) {
  1.3449 +    iop = subtree;
  1.3450 +    _AD._internalOps.Insert(subtree, iop);
  1.3451 +    _AD._internalOpNames.addName(iop);
  1.3452 +    _AD._internalMatch.Insert(iop, this);
  1.3453 +  }
  1.3454 +  // Add the internal operand name to the MatchNode
  1.3455 +  _internalop = iop;
  1.3456 +  _result = iop;
  1.3457 +}
  1.3458 +
  1.3459 +
  1.3460 +void MatchNode::dump() {
  1.3461 +  output(stderr);
  1.3462 +}
  1.3463 +
  1.3464 +void MatchNode::output(FILE *fp) {
  1.3465 +  if (_lChild==0 && _rChild==0) {
  1.3466 +    fprintf(fp," %s",_name);    // operand
  1.3467 +  }
  1.3468 +  else {
  1.3469 +    fprintf(fp," (%s ",_name);  // " (opcodeName "
  1.3470 +    if(_lChild) _lChild->output(fp); //               left operand
  1.3471 +    if(_rChild) _rChild->output(fp); //                    right operand
  1.3472 +    fprintf(fp,")");                 //                                 ")"
  1.3473 +  }
  1.3474 +}
  1.3475 +
  1.3476 +int MatchNode::needs_ideal_memory_edge(FormDict &globals) const {
  1.3477 +  static const char *needs_ideal_memory_list[] = {
  1.3478 +    "StoreI","StoreL","StoreP","StoreN","StoreNKlass","StoreD","StoreF" ,
  1.3479 +    "StoreB","StoreC","Store" ,"StoreFP",
  1.3480 +    "LoadI", "LoadL", "LoadP" ,"LoadN", "LoadD" ,"LoadF"  ,
  1.3481 +    "LoadB" , "LoadUB", "LoadUS" ,"LoadS" ,"Load" ,
  1.3482 +    "StoreVector", "LoadVector",
  1.3483 +    "LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned",
  1.3484 +    "LoadPLocked",
  1.3485 +    "StorePConditional", "StoreIConditional", "StoreLConditional",
  1.3486 +    "CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN",
  1.3487 +    "StoreCM",
  1.3488 +    "ClearArray",
  1.3489 +    "GetAndAddI", "GetAndSetI", "GetAndSetP",
  1.3490 +    "GetAndAddL", "GetAndSetL", "GetAndSetN",
  1.3491 +  };
  1.3492 +  int cnt = sizeof(needs_ideal_memory_list)/sizeof(char*);
  1.3493 +  if( strcmp(_opType,"PrefetchRead")==0 ||
  1.3494 +      strcmp(_opType,"PrefetchWrite")==0 ||
  1.3495 +      strcmp(_opType,"PrefetchAllocation")==0 )
  1.3496 +    return 1;
  1.3497 +  if( _lChild ) {
  1.3498 +    const char *opType = _lChild->_opType;
  1.3499 +    for( int i=0; i<cnt; i++ )
  1.3500 +      if( strcmp(opType,needs_ideal_memory_list[i]) == 0 )
  1.3501 +        return 1;
  1.3502 +    if( _lChild->needs_ideal_memory_edge(globals) )
  1.3503 +      return 1;
  1.3504 +  }
  1.3505 +  if( _rChild ) {
  1.3506 +    const char *opType = _rChild->_opType;
  1.3507 +    for( int i=0; i<cnt; i++ )
  1.3508 +      if( strcmp(opType,needs_ideal_memory_list[i]) == 0 )
  1.3509 +        return 1;
  1.3510 +    if( _rChild->needs_ideal_memory_edge(globals) )
  1.3511 +      return 1;
  1.3512 +  }
  1.3513 +
  1.3514 +  return 0;
  1.3515 +}
  1.3516 +
  1.3517 +// TRUE if defines a derived oop, and so needs a base oop edge present
  1.3518 +// post-matching.
  1.3519 +int MatchNode::needs_base_oop_edge() const {
  1.3520 +  if( !strcmp(_opType,"AddP") ) return 1;
  1.3521 +  if( strcmp(_opType,"Set") ) return 0;
  1.3522 +  return !strcmp(_rChild->_opType,"AddP");
  1.3523 +}
  1.3524 +
  1.3525 +int InstructForm::needs_base_oop_edge(FormDict &globals) const {
  1.3526 +  if( is_simple_chain_rule(globals) ) {
  1.3527 +    const char *src = _matrule->_rChild->_opType;
  1.3528 +    OperandForm *src_op = globals[src]->is_operand();
  1.3529 +    assert( src_op, "Not operand class of chain rule" );
  1.3530 +    return src_op->_matrule ? src_op->_matrule->needs_base_oop_edge() : 0;
  1.3531 +  }                             // Else check instruction
  1.3532 +
  1.3533 +  return _matrule ? _matrule->needs_base_oop_edge() : 0;
  1.3534 +}
  1.3535 +
  1.3536 +
  1.3537 +//-------------------------cisc spilling methods-------------------------------
  1.3538 +// helper routines and methods for detecting cisc-spilling instructions
  1.3539 +//-------------------------cisc_spill_merge------------------------------------
  1.3540 +int MatchNode::cisc_spill_merge(int left_spillable, int right_spillable) {
  1.3541 +  int cisc_spillable  = Maybe_cisc_spillable;
  1.3542 +
  1.3543 +  // Combine results of left and right checks
  1.3544 +  if( (left_spillable == Maybe_cisc_spillable) && (right_spillable == Maybe_cisc_spillable) ) {
  1.3545 +    // neither side is spillable, nor prevents cisc spilling
  1.3546 +    cisc_spillable = Maybe_cisc_spillable;
  1.3547 +  }
  1.3548 +  else if( (left_spillable == Maybe_cisc_spillable) && (right_spillable > Maybe_cisc_spillable) ) {
  1.3549 +    // right side is spillable
  1.3550 +    cisc_spillable = right_spillable;
  1.3551 +  }
  1.3552 +  else if( (right_spillable == Maybe_cisc_spillable) && (left_spillable > Maybe_cisc_spillable) ) {
  1.3553 +    // left side is spillable
  1.3554 +    cisc_spillable = left_spillable;
  1.3555 +  }
  1.3556 +  else if( (left_spillable == Not_cisc_spillable) || (right_spillable == Not_cisc_spillable) ) {
  1.3557 +    // left or right prevents cisc spilling this instruction
  1.3558 +    cisc_spillable = Not_cisc_spillable;
  1.3559 +  }
  1.3560 +  else {
  1.3561 +    // Only allow one to spill
  1.3562 +    cisc_spillable = Not_cisc_spillable;
  1.3563 +  }
  1.3564 +
  1.3565 +  return cisc_spillable;
  1.3566 +}
  1.3567 +
  1.3568 +//-------------------------root_ops_match--------------------------------------
  1.3569 +bool static root_ops_match(FormDict &globals, const char *op1, const char *op2) {
  1.3570 +  // Base Case: check that the current operands/operations match
  1.3571 +  assert( op1, "Must have op's name");
  1.3572 +  assert( op2, "Must have op's name");
  1.3573 +  const Form *form1 = globals[op1];
  1.3574 +  const Form *form2 = globals[op2];
  1.3575 +
  1.3576 +  return (form1 == form2);
  1.3577 +}
  1.3578 +
  1.3579 +//-------------------------cisc_spill_match_node-------------------------------
  1.3580 +// Recursively check two MatchRules for legal conversion via cisc-spilling
  1.3581 +int MatchNode::cisc_spill_match(FormDict& globals, RegisterForm* registers, MatchNode* mRule2, const char* &operand, const char* &reg_type) {
  1.3582 +  int cisc_spillable  = Maybe_cisc_spillable;
  1.3583 +  int left_spillable  = Maybe_cisc_spillable;
  1.3584 +  int right_spillable = Maybe_cisc_spillable;
  1.3585 +
  1.3586 +  // Check that each has same number of operands at this level
  1.3587 +  if( (_lChild && !(mRule2->_lChild)) || (_rChild && !(mRule2->_rChild)) )
  1.3588 +    return Not_cisc_spillable;
  1.3589 +
  1.3590 +  // Base Case: check that the current operands/operations match
  1.3591 +  // or are CISC spillable
  1.3592 +  assert( _opType, "Must have _opType");
  1.3593 +  assert( mRule2->_opType, "Must have _opType");
  1.3594 +  const Form *form  = globals[_opType];
  1.3595 +  const Form *form2 = globals[mRule2->_opType];
  1.3596 +  if( form == form2 ) {
  1.3597 +    cisc_spillable = Maybe_cisc_spillable;
  1.3598 +  } else {
  1.3599 +    const InstructForm *form2_inst = form2 ? form2->is_instruction() : NULL;
  1.3600 +    const char *name_left  = mRule2->_lChild ? mRule2->_lChild->_opType : NULL;
  1.3601 +    const char *name_right = mRule2->_rChild ? mRule2->_rChild->_opType : NULL;
  1.3602 +    DataType data_type = Form::none;
  1.3603 +    if (form->is_operand()) {
  1.3604 +      // Make sure the loadX matches the type of the reg
  1.3605 +      data_type = form->ideal_to_Reg_type(form->is_operand()->ideal_type(globals));
  1.3606 +    }
  1.3607 +    // Detect reg vs (loadX memory)
  1.3608 +    if( form->is_cisc_reg(globals)
  1.3609 +        && form2_inst
  1.3610 +        && data_type != Form::none
  1.3611 +        && (is_load_from_memory(mRule2->_opType) == data_type) // reg vs. (load memory)
  1.3612 +        && (name_left != NULL)       // NOT (load)
  1.3613 +        && (name_right == NULL) ) {  // NOT (load memory foo)
  1.3614 +      const Form *form2_left = name_left ? globals[name_left] : NULL;
  1.3615 +      if( form2_left && form2_left->is_cisc_mem(globals) ) {
  1.3616 +        cisc_spillable = Is_cisc_spillable;
  1.3617 +        operand        = _name;
  1.3618 +        reg_type       = _result;
  1.3619 +        return Is_cisc_spillable;
  1.3620 +      } else {
  1.3621 +        cisc_spillable = Not_cisc_spillable;
  1.3622 +      }
  1.3623 +    }
  1.3624 +    // Detect reg vs memory
  1.3625 +    else if( form->is_cisc_reg(globals) && form2->is_cisc_mem(globals) ) {
  1.3626 +      cisc_spillable = Is_cisc_spillable;
  1.3627 +      operand        = _name;
  1.3628 +      reg_type       = _result;
  1.3629 +      return Is_cisc_spillable;
  1.3630 +    } else {
  1.3631 +      cisc_spillable = Not_cisc_spillable;
  1.3632 +    }
  1.3633 +  }
  1.3634 +
  1.3635 +  // If cisc is still possible, check rest of tree
  1.3636 +  if( cisc_spillable == Maybe_cisc_spillable ) {
  1.3637 +    // Check that each has same number of operands at this level
  1.3638 +    if( (_lChild && !(mRule2->_lChild)) || (_rChild && !(mRule2->_rChild)) ) return Not_cisc_spillable;
  1.3639 +
  1.3640 +    // Check left operands
  1.3641 +    if( (_lChild == NULL) && (mRule2->_lChild == NULL) ) {
  1.3642 +      left_spillable = Maybe_cisc_spillable;
  1.3643 +    } else {
  1.3644 +      left_spillable = _lChild->cisc_spill_match(globals, registers, mRule2->_lChild, operand, reg_type);
  1.3645 +    }
  1.3646 +
  1.3647 +    // Check right operands
  1.3648 +    if( (_rChild == NULL) && (mRule2->_rChild == NULL) ) {
  1.3649 +      right_spillable =  Maybe_cisc_spillable;
  1.3650 +    } else {
  1.3651 +      right_spillable = _rChild->cisc_spill_match(globals, registers, mRule2->_rChild, operand, reg_type);
  1.3652 +    }
  1.3653 +
  1.3654 +    // Combine results of left and right checks
  1.3655 +    cisc_spillable = cisc_spill_merge(left_spillable, right_spillable);
  1.3656 +  }
  1.3657 +
  1.3658 +  return cisc_spillable;
  1.3659 +}
  1.3660 +
  1.3661 +//---------------------------cisc_spill_match_rule------------------------------
  1.3662 +// Recursively check two MatchRules for legal conversion via cisc-spilling
  1.3663 +// This method handles the root of Match tree,
  1.3664 +// general recursive checks done in MatchNode
  1.3665 +int  MatchRule::matchrule_cisc_spill_match(FormDict& globals, RegisterForm* registers,
  1.3666 +                                           MatchRule* mRule2, const char* &operand,
  1.3667 +                                           const char* &reg_type) {
  1.3668 +  int cisc_spillable  = Maybe_cisc_spillable;
  1.3669 +  int left_spillable  = Maybe_cisc_spillable;
  1.3670 +  int right_spillable = Maybe_cisc_spillable;
  1.3671 +
  1.3672 +  // Check that each sets a result
  1.3673 +  if( !(sets_result() && mRule2->sets_result()) ) return Not_cisc_spillable;
  1.3674 +  // Check that each has same number of operands at this level
  1.3675 +  if( (_lChild && !(mRule2->_lChild)) || (_rChild && !(mRule2->_rChild)) ) return Not_cisc_spillable;
  1.3676 +
  1.3677 +  // Check left operands: at root, must be target of 'Set'
  1.3678 +  if( (_lChild == NULL) || (mRule2->_lChild == NULL) ) {
  1.3679 +    left_spillable = Not_cisc_spillable;
  1.3680 +  } else {
  1.3681 +    // Do not support cisc-spilling instruction's target location
  1.3682 +    if( root_ops_match(globals, _lChild->_opType, mRule2->_lChild->_opType) ) {
  1.3683 +      left_spillable = Maybe_cisc_spillable;
  1.3684 +    } else {
  1.3685 +      left_spillable = Not_cisc_spillable;
  1.3686 +    }
  1.3687 +  }
  1.3688 +
  1.3689 +  // Check right operands: recursive walk to identify reg->mem operand
  1.3690 +  if( (_rChild == NULL) && (mRule2->_rChild == NULL) ) {
  1.3691 +    right_spillable =  Maybe_cisc_spillable;
  1.3692 +  } else {
  1.3693 +    right_spillable = _rChild->cisc_spill_match(globals, registers, mRule2->_rChild, operand, reg_type);
  1.3694 +  }
  1.3695 +
  1.3696 +  // Combine results of left and right checks
  1.3697 +  cisc_spillable = cisc_spill_merge(left_spillable, right_spillable);
  1.3698 +
  1.3699 +  return cisc_spillable;
  1.3700 +}
  1.3701 +
  1.3702 +//----------------------------- equivalent ------------------------------------
  1.3703 +// Recursively check to see if two match rules are equivalent.
  1.3704 +// This rule handles the root.
  1.3705 +bool MatchRule::equivalent(FormDict &globals, MatchNode *mRule2) {
  1.3706 +  // Check that each sets a result
  1.3707 +  if (sets_result() != mRule2->sets_result()) {
  1.3708 +    return false;
  1.3709 +  }
  1.3710 +
  1.3711 +  // Check that the current operands/operations match
  1.3712 +  assert( _opType, "Must have _opType");
  1.3713 +  assert( mRule2->_opType, "Must have _opType");
  1.3714 +  const Form *form  = globals[_opType];
  1.3715 +  const Form *form2 = globals[mRule2->_opType];
  1.3716 +  if( form != form2 ) {
  1.3717 +    return false;
  1.3718 +  }
  1.3719 +
  1.3720 +  if (_lChild ) {
  1.3721 +    if( !_lChild->equivalent(globals, mRule2->_lChild) )
  1.3722 +      return false;
  1.3723 +  } else if (mRule2->_lChild) {
  1.3724 +    return false; // I have NULL left child, mRule2 has non-NULL left child.
  1.3725 +  }
  1.3726 +
  1.3727 +  if (_rChild ) {
  1.3728 +    if( !_rChild->equivalent(globals, mRule2->_rChild) )
  1.3729 +      return false;
  1.3730 +  } else if (mRule2->_rChild) {
  1.3731 +    return false; // I have NULL right child, mRule2 has non-NULL right child.
  1.3732 +  }
  1.3733 +
  1.3734 +  // We've made it through the gauntlet.
  1.3735 +  return true;
  1.3736 +}
  1.3737 +
  1.3738 +//----------------------------- equivalent ------------------------------------
  1.3739 +// Recursively check to see if two match rules are equivalent.
  1.3740 +// This rule handles the operands.
  1.3741 +bool MatchNode::equivalent(FormDict &globals, MatchNode *mNode2) {
  1.3742 +  if( !mNode2 )
  1.3743 +    return false;
  1.3744 +
  1.3745 +  // Check that the current operands/operations match
  1.3746 +  assert( _opType, "Must have _opType");
  1.3747 +  assert( mNode2->_opType, "Must have _opType");
  1.3748 +  const Form *form  = globals[_opType];
  1.3749 +  const Form *form2 = globals[mNode2->_opType];
  1.3750 +  if( form != form2 ) {
  1.3751 +    return false;
  1.3752 +  }
  1.3753 +
  1.3754 +  // Check that their children also match
  1.3755 +  if (_lChild ) {
  1.3756 +    if( !_lChild->equivalent(globals, mNode2->_lChild) )
  1.3757 +      return false;
  1.3758 +  } else if (mNode2->_lChild) {
  1.3759 +    return false; // I have NULL left child, mNode2 has non-NULL left child.
  1.3760 +  }
  1.3761 +
  1.3762 +  if (_rChild ) {
  1.3763 +    if( !_rChild->equivalent(globals, mNode2->_rChild) )
  1.3764 +      return false;
  1.3765 +  } else if (mNode2->_rChild) {
  1.3766 +    return false; // I have NULL right child, mNode2 has non-NULL right child.
  1.3767 +  }
  1.3768 +
  1.3769 +  // We've made it through the gauntlet.
  1.3770 +  return true;
  1.3771 +}
  1.3772 +
  1.3773 +//-------------------------- has_commutative_op -------------------------------
  1.3774 +// Recursively check for commutative operations with subtree operands
  1.3775 +// which could be swapped.
  1.3776 +void MatchNode::count_commutative_op(int& count) {
  1.3777 +  static const char *commut_op_list[] = {
  1.3778 +    "AddI","AddL","AddF","AddD",
  1.3779 +    "AndI","AndL",
  1.3780 +    "MaxI","MinI",
  1.3781 +    "MulI","MulL","MulF","MulD",
  1.3782 +    "OrI" ,"OrL" ,
  1.3783 +    "XorI","XorL"
  1.3784 +  };
  1.3785 +  int cnt = sizeof(commut_op_list)/sizeof(char*);
  1.3786 +
  1.3787 +  if( _lChild && _rChild && (_lChild->_lChild || _rChild->_lChild) ) {
  1.3788 +    // Don't swap if right operand is an immediate constant.
  1.3789 +    bool is_const = false;
  1.3790 +    if( _rChild->_lChild == NULL && _rChild->_rChild == NULL ) {
  1.3791 +      FormDict &globals = _AD.globalNames();
  1.3792 +      const Form *form = globals[_rChild->_opType];
  1.3793 +      if ( form ) {
  1.3794 +        OperandForm  *oper = form->is_operand();
  1.3795 +        if( oper && oper->interface_type(globals) == Form::constant_interface )
  1.3796 +          is_const = true;
  1.3797 +      }
  1.3798 +    }
  1.3799 +    if( !is_const ) {
  1.3800 +      for( int i=0; i<cnt; i++ ) {
  1.3801 +        if( strcmp(_opType, commut_op_list[i]) == 0 ) {
  1.3802 +          count++;
  1.3803 +          _commutative_id = count; // id should be > 0
  1.3804 +          break;
  1.3805 +        }
  1.3806 +      }
  1.3807 +    }
  1.3808 +  }
  1.3809 +  if( _lChild )
  1.3810 +    _lChild->count_commutative_op(count);
  1.3811 +  if( _rChild )
  1.3812 +    _rChild->count_commutative_op(count);
  1.3813 +}
  1.3814 +
  1.3815 +//-------------------------- swap_commutative_op ------------------------------
  1.3816 +// Recursively swap specified commutative operation with subtree operands.
  1.3817 +void MatchNode::swap_commutative_op(bool atroot, int id) {
  1.3818 +  if( _commutative_id == id ) { // id should be > 0
  1.3819 +    assert(_lChild && _rChild && (_lChild->_lChild || _rChild->_lChild ),
  1.3820 +            "not swappable operation");
  1.3821 +    MatchNode* tmp = _lChild;
  1.3822 +    _lChild = _rChild;
  1.3823 +    _rChild = tmp;
  1.3824 +    // Don't exit here since we need to build internalop.
  1.3825 +  }
  1.3826 +
  1.3827 +  bool is_set = ( strcmp(_opType, "Set") == 0 );
  1.3828 +  if( _lChild )
  1.3829 +    _lChild->swap_commutative_op(is_set, id);
  1.3830 +  if( _rChild )
  1.3831 +    _rChild->swap_commutative_op(is_set, id);
  1.3832 +
  1.3833 +  // If not the root, reduce this subtree to an internal operand
  1.3834 +  if( !atroot && (_lChild || _rChild) ) {
  1.3835 +    build_internalop();
  1.3836 +  }
  1.3837 +}
  1.3838 +
  1.3839 +//-------------------------- swap_commutative_op ------------------------------
  1.3840 +// Recursively swap specified commutative operation with subtree operands.
  1.3841 +void MatchRule::matchrule_swap_commutative_op(const char* instr_ident, int count, int& match_rules_cnt) {
  1.3842 +  assert(match_rules_cnt < 100," too many match rule clones");
  1.3843 +  // Clone
  1.3844 +  MatchRule* clone = new MatchRule(_AD, this);
  1.3845 +  // Swap operands of commutative operation
  1.3846 +  ((MatchNode*)clone)->swap_commutative_op(true, count);
  1.3847 +  char* buf = (char*) malloc(strlen(instr_ident) + 4);
  1.3848 +  sprintf(buf, "%s_%d", instr_ident, match_rules_cnt++);
  1.3849 +  clone->_result = buf;
  1.3850 +
  1.3851 +  clone->_next = this->_next;
  1.3852 +  this-> _next = clone;
  1.3853 +  if( (--count) > 0 ) {
  1.3854 +    this-> matchrule_swap_commutative_op(instr_ident, count, match_rules_cnt);
  1.3855 +    clone->matchrule_swap_commutative_op(instr_ident, count, match_rules_cnt);
  1.3856 +  }
  1.3857 +}
  1.3858 +
  1.3859 +//------------------------------MatchRule--------------------------------------
  1.3860 +MatchRule::MatchRule(ArchDesc &ad)
  1.3861 +  : MatchNode(ad), _depth(0), _construct(NULL), _numchilds(0) {
  1.3862 +    _next = NULL;
  1.3863 +}
  1.3864 +
  1.3865 +MatchRule::MatchRule(ArchDesc &ad, MatchRule* mRule)
  1.3866 +  : MatchNode(ad, *mRule, 0), _depth(mRule->_depth),
  1.3867 +    _construct(mRule->_construct), _numchilds(mRule->_numchilds) {
  1.3868 +    _next = NULL;
  1.3869 +}
  1.3870 +
  1.3871 +MatchRule::MatchRule(ArchDesc &ad, MatchNode* mroot, int depth, char *cnstr,
  1.3872 +                     int numleaves)
  1.3873 +  : MatchNode(ad,*mroot), _depth(depth), _construct(cnstr),
  1.3874 +    _numchilds(0) {
  1.3875 +      _next = NULL;
  1.3876 +      mroot->_lChild = NULL;
  1.3877 +      mroot->_rChild = NULL;
  1.3878 +      delete mroot;
  1.3879 +      _numleaves = numleaves;
  1.3880 +      _numchilds = (_lChild ? 1 : 0) + (_rChild ? 1 : 0);
  1.3881 +}
  1.3882 +MatchRule::~MatchRule() {
  1.3883 +}
  1.3884 +
  1.3885 +// Recursive call collecting info on top-level operands, not transitive.
  1.3886 +// Implementation does not modify state of internal structures.
  1.3887 +void MatchRule::append_components(FormDict& locals, ComponentList& components, bool def_flag) const {
  1.3888 +  assert (_name != NULL, "MatchNode::build_components encountered empty node\n");
  1.3889 +
  1.3890 +  MatchNode::append_components(locals, components,
  1.3891 +                               false /* not necessarily a def */);
  1.3892 +}
  1.3893 +
  1.3894 +// Recursive call on all operands' match rules in my match rule.
  1.3895 +// Implementation does not modify state of internal structures  since they
  1.3896 +// can be shared.
  1.3897 +// The MatchNode that is called first treats its
  1.3898 +bool MatchRule::base_operand(uint &position0, FormDict &globals,
  1.3899 +                             const char *&result, const char * &name,
  1.3900 +                             const char * &opType)const{
  1.3901 +  uint position = position0;
  1.3902 +
  1.3903 +  return (MatchNode::base_operand( position, globals, result, name, opType));
  1.3904 +}
  1.3905 +
  1.3906 +
  1.3907 +bool MatchRule::is_base_register(FormDict &globals) const {
  1.3908 +  uint   position = 1;
  1.3909 +  const char  *result   = NULL;
  1.3910 +  const char  *name     = NULL;
  1.3911 +  const char  *opType   = NULL;
  1.3912 +  if (!base_operand(position, globals, result, name, opType)) {
  1.3913 +    position = 0;
  1.3914 +    if( base_operand(position, globals, result, name, opType) &&
  1.3915 +        (strcmp(opType,"RegI")==0 ||
  1.3916 +         strcmp(opType,"RegP")==0 ||
  1.3917 +         strcmp(opType,"RegN")==0 ||
  1.3918 +         strcmp(opType,"RegL")==0 ||
  1.3919 +         strcmp(opType,"RegF")==0 ||
  1.3920 +         strcmp(opType,"RegD")==0 ||
  1.3921 +         strcmp(opType,"VecS")==0 ||
  1.3922 +         strcmp(opType,"VecD")==0 ||
  1.3923 +         strcmp(opType,"VecX")==0 ||
  1.3924 +         strcmp(opType,"VecY")==0 ||
  1.3925 +         strcmp(opType,"Reg" )==0) ) {
  1.3926 +      return 1;
  1.3927 +    }
  1.3928 +  }
  1.3929 +  return 0;
  1.3930 +}
  1.3931 +
  1.3932 +Form::DataType MatchRule::is_base_constant(FormDict &globals) const {
  1.3933 +  uint         position = 1;
  1.3934 +  const char  *result   = NULL;
  1.3935 +  const char  *name     = NULL;
  1.3936 +  const char  *opType   = NULL;
  1.3937 +  if (!base_operand(position, globals, result, name, opType)) {
  1.3938 +    position = 0;
  1.3939 +    if (base_operand(position, globals, result, name, opType)) {
  1.3940 +      return ideal_to_const_type(opType);
  1.3941 +    }
  1.3942 +  }
  1.3943 +  return Form::none;
  1.3944 +}
  1.3945 +
  1.3946 +bool MatchRule::is_chain_rule(FormDict &globals) const {
  1.3947 +
  1.3948 +  // Check for chain rule, and do not generate a match list for it
  1.3949 +  if ((_lChild == NULL) && (_rChild == NULL) ) {
  1.3950 +    const Form *form = globals[_opType];
  1.3951 +    // If this is ideal, then it is a base match, not a chain rule.
  1.3952 +    if ( form && form->is_operand() && (!form->ideal_only())) {
  1.3953 +      return true;
  1.3954 +    }
  1.3955 +  }
  1.3956 +  // Check for "Set" form of chain rule, and do not generate a match list
  1.3957 +  if (_rChild) {
  1.3958 +    const char *rch = _rChild->_opType;
  1.3959 +    const Form *form = globals[rch];
  1.3960 +    if ((!strcmp(_opType,"Set") &&
  1.3961 +         ((form) && form->is_operand()))) {
  1.3962 +      return true;
  1.3963 +    }
  1.3964 +  }
  1.3965 +  return false;
  1.3966 +}
  1.3967 +
  1.3968 +int MatchRule::is_ideal_copy() const {
  1.3969 +  if( _rChild ) {
  1.3970 +    const char  *opType = _rChild->_opType;
  1.3971 +#if 1
  1.3972 +    if( strcmp(opType,"CastIP")==0 )
  1.3973 +      return 1;
  1.3974 +#else
  1.3975 +    if( strcmp(opType,"CastII")==0 )
  1.3976 +      return 1;
  1.3977 +    // Do not treat *CastPP this way, because it
  1.3978 +    // may transfer a raw pointer to an oop.
  1.3979 +    // If the register allocator were to coalesce this
  1.3980 +    // into a single LRG, the GC maps would be incorrect.
  1.3981 +    //if( strcmp(opType,"CastPP")==0 )
  1.3982 +    //  return 1;
  1.3983 +    //if( strcmp(opType,"CheckCastPP")==0 )
  1.3984 +    //  return 1;
  1.3985 +    //
  1.3986 +    // Do not treat CastX2P or CastP2X this way, because
  1.3987 +    // raw pointers and int types are treated differently
  1.3988 +    // when saving local & stack info for safepoints in
  1.3989 +    // Output().
  1.3990 +    //if( strcmp(opType,"CastX2P")==0 )
  1.3991 +    //  return 1;
  1.3992 +    //if( strcmp(opType,"CastP2X")==0 )
  1.3993 +    //  return 1;
  1.3994 +#endif
  1.3995 +  }
  1.3996 +  if( is_chain_rule(_AD.globalNames()) &&
  1.3997 +      _lChild && strncmp(_lChild->_opType,"stackSlot",9)==0 )
  1.3998 +    return 1;
  1.3999 +  return 0;
  1.4000 +}
  1.4001 +
  1.4002 +
  1.4003 +int MatchRule::is_expensive() const {
  1.4004 +  if( _rChild ) {
  1.4005 +    const char  *opType = _rChild->_opType;
  1.4006 +    if( strcmp(opType,"AtanD")==0 ||
  1.4007 +        strcmp(opType,"CosD")==0 ||
  1.4008 +        strcmp(opType,"DivD")==0 ||
  1.4009 +        strcmp(opType,"DivF")==0 ||
  1.4010 +        strcmp(opType,"DivI")==0 ||
  1.4011 +        strcmp(opType,"ExpD")==0 ||
  1.4012 +        strcmp(opType,"LogD")==0 ||
  1.4013 +        strcmp(opType,"Log10D")==0 ||
  1.4014 +        strcmp(opType,"ModD")==0 ||
  1.4015 +        strcmp(opType,"ModF")==0 ||
  1.4016 +        strcmp(opType,"ModI")==0 ||
  1.4017 +        strcmp(opType,"PowD")==0 ||
  1.4018 +        strcmp(opType,"SinD")==0 ||
  1.4019 +        strcmp(opType,"SqrtD")==0 ||
  1.4020 +        strcmp(opType,"TanD")==0 ||
  1.4021 +        strcmp(opType,"ConvD2F")==0 ||
  1.4022 +        strcmp(opType,"ConvD2I")==0 ||
  1.4023 +        strcmp(opType,"ConvD2L")==0 ||
  1.4024 +        strcmp(opType,"ConvF2D")==0 ||
  1.4025 +        strcmp(opType,"ConvF2I")==0 ||
  1.4026 +        strcmp(opType,"ConvF2L")==0 ||
  1.4027 +        strcmp(opType,"ConvI2D")==0 ||
  1.4028 +        strcmp(opType,"ConvI2F")==0 ||
  1.4029 +        strcmp(opType,"ConvI2L")==0 ||
  1.4030 +        strcmp(opType,"ConvL2D")==0 ||
  1.4031 +        strcmp(opType,"ConvL2F")==0 ||
  1.4032 +        strcmp(opType,"ConvL2I")==0 ||
  1.4033 +        strcmp(opType,"DecodeN")==0 ||
  1.4034 +        strcmp(opType,"EncodeP")==0 ||
  1.4035 +        strcmp(opType,"EncodePKlass")==0 ||
  1.4036 +        strcmp(opType,"DecodeNKlass")==0 ||
  1.4037 +        strcmp(opType,"RoundDouble")==0 ||
  1.4038 +        strcmp(opType,"RoundFloat")==0 ||
  1.4039 +        strcmp(opType,"ReverseBytesI")==0 ||
  1.4040 +        strcmp(opType,"ReverseBytesL")==0 ||
  1.4041 +        strcmp(opType,"ReverseBytesUS")==0 ||
  1.4042 +        strcmp(opType,"ReverseBytesS")==0 ||
  1.4043 +        strcmp(opType,"ReplicateB")==0 ||
  1.4044 +        strcmp(opType,"ReplicateS")==0 ||
  1.4045 +        strcmp(opType,"ReplicateI")==0 ||
  1.4046 +        strcmp(opType,"ReplicateL")==0 ||
  1.4047 +        strcmp(opType,"ReplicateF")==0 ||
  1.4048 +        strcmp(opType,"ReplicateD")==0 ||
  1.4049 +        0 /* 0 to line up columns nicely */ )
  1.4050 +      return 1;
  1.4051 +  }
  1.4052 +  return 0;
  1.4053 +}
  1.4054 +
  1.4055 +bool MatchRule::is_ideal_if() const {
  1.4056 +  if( !_opType ) return false;
  1.4057 +  return
  1.4058 +    !strcmp(_opType,"If"            ) ||
  1.4059 +    !strcmp(_opType,"CountedLoopEnd");
  1.4060 +}
  1.4061 +
  1.4062 +bool MatchRule::is_ideal_fastlock() const {
  1.4063 +  if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) {
  1.4064 +    return (strcmp(_rChild->_opType,"FastLock") == 0);
  1.4065 +  }
  1.4066 +  return false;
  1.4067 +}
  1.4068 +
  1.4069 +bool MatchRule::is_ideal_membar() const {
  1.4070 +  if( !_opType ) return false;
  1.4071 +  return
  1.4072 +    !strcmp(_opType,"MemBarAcquire") ||
  1.4073 +    !strcmp(_opType,"MemBarRelease") ||
  1.4074 +    !strcmp(_opType,"MemBarAcquireLock") ||
  1.4075 +    !strcmp(_opType,"MemBarReleaseLock") ||
  1.4076 +    !strcmp(_opType,"LoadFence" ) ||
  1.4077 +    !strcmp(_opType,"StoreFence") ||
  1.4078 +    !strcmp(_opType,"MemBarVolatile") ||
  1.4079 +    !strcmp(_opType,"MemBarCPUOrder") ||
  1.4080 +    !strcmp(_opType,"MemBarStoreStore");
  1.4081 +}
  1.4082 +
  1.4083 +bool MatchRule::is_ideal_loadPC() const {
  1.4084 +  if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) {
  1.4085 +    return (strcmp(_rChild->_opType,"LoadPC") == 0);
  1.4086 +  }
  1.4087 +  return false;
  1.4088 +}
  1.4089 +
  1.4090 +bool MatchRule::is_ideal_box() const {
  1.4091 +  if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) {
  1.4092 +    return (strcmp(_rChild->_opType,"Box") == 0);
  1.4093 +  }
  1.4094 +  return false;
  1.4095 +}
  1.4096 +
  1.4097 +bool MatchRule::is_ideal_goto() const {
  1.4098 +  bool   ideal_goto = false;
  1.4099 +
  1.4100 +  if( _opType && (strcmp(_opType,"Goto") == 0) ) {
  1.4101 +    ideal_goto = true;
  1.4102 +  }
  1.4103 +  return ideal_goto;
  1.4104 +}
  1.4105 +
  1.4106 +bool MatchRule::is_ideal_jump() const {
  1.4107 +  if( _opType ) {
  1.4108 +    if( !strcmp(_opType,"Jump") )
  1.4109 +      return true;
  1.4110 +  }
  1.4111 +  return false;
  1.4112 +}
  1.4113 +
  1.4114 +bool MatchRule::is_ideal_bool() const {
  1.4115 +  if( _opType ) {
  1.4116 +    if( !strcmp(_opType,"Bool") )
  1.4117 +      return true;
  1.4118 +  }
  1.4119 +  return false;
  1.4120 +}
  1.4121 +
  1.4122 +
  1.4123 +Form::DataType MatchRule::is_ideal_load() const {
  1.4124 +  Form::DataType ideal_load = Form::none;
  1.4125 +
  1.4126 +  if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) {
  1.4127 +    const char *opType = _rChild->_opType;
  1.4128 +    ideal_load = is_load_from_memory(opType);
  1.4129 +  }
  1.4130 +
  1.4131 +  return ideal_load;
  1.4132 +}
  1.4133 +
  1.4134 +bool MatchRule::is_vector() const {
  1.4135 +  static const char *vector_list[] = {
  1.4136 +    "AddVB","AddVS","AddVI","AddVL","AddVF","AddVD",
  1.4137 +    "SubVB","SubVS","SubVI","SubVL","SubVF","SubVD",
  1.4138 +    "MulVS","MulVI","MulVF","MulVD",
  1.4139 +    "DivVF","DivVD",
  1.4140 +    "AndV" ,"XorV" ,"OrV",
  1.4141 +    "LShiftCntV","RShiftCntV",
  1.4142 +    "LShiftVB","LShiftVS","LShiftVI","LShiftVL",
  1.4143 +    "RShiftVB","RShiftVS","RShiftVI","RShiftVL",
  1.4144 +    "URShiftVB","URShiftVS","URShiftVI","URShiftVL",
  1.4145 +    "ReplicateB","ReplicateS","ReplicateI","ReplicateL","ReplicateF","ReplicateD",
  1.4146 +    "LoadVector","StoreVector",
  1.4147 +    // Next are not supported currently.
  1.4148 +    "PackB","PackS","PackI","PackL","PackF","PackD","Pack2L","Pack2D",
  1.4149 +    "ExtractB","ExtractUB","ExtractC","ExtractS","ExtractI","ExtractL","ExtractF","ExtractD"
  1.4150 +  };
  1.4151 +  int cnt = sizeof(vector_list)/sizeof(char*);
  1.4152 +  if (_rChild) {
  1.4153 +    const char  *opType = _rChild->_opType;
  1.4154 +    for (int i=0; i<cnt; i++)
  1.4155 +      if (strcmp(opType,vector_list[i]) == 0)
  1.4156 +        return true;
  1.4157 +  }
  1.4158 +  return false;
  1.4159 +}
  1.4160 +
  1.4161 +
  1.4162 +bool MatchRule::skip_antidep_check() const {
  1.4163 +  // Some loads operate on what is effectively immutable memory so we
  1.4164 +  // should skip the anti dep computations.  For some of these nodes
  1.4165 +  // the rewritable field keeps the anti dep logic from triggering but
  1.4166 +  // for certain kinds of LoadKlass it does not since they are
  1.4167 +  // actually reading memory which could be rewritten by the runtime,
  1.4168 +  // though never by generated code.  This disables it uniformly for
  1.4169 +  // the nodes that behave like this: LoadKlass, LoadNKlass and
  1.4170 +  // LoadRange.
  1.4171 +  if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) {
  1.4172 +    const char *opType = _rChild->_opType;
  1.4173 +    if (strcmp("LoadKlass", opType) == 0 ||
  1.4174 +        strcmp("LoadNKlass", opType) == 0 ||
  1.4175 +        strcmp("LoadRange", opType) == 0) {
  1.4176 +      return true;
  1.4177 +    }
  1.4178 +  }
  1.4179 +
  1.4180 +  return false;
  1.4181 +}
  1.4182 +
  1.4183 +
  1.4184 +Form::DataType MatchRule::is_ideal_store() const {
  1.4185 +  Form::DataType ideal_store = Form::none;
  1.4186 +
  1.4187 +  if ( _opType && (strcmp(_opType,"Set") == 0) && _rChild ) {
  1.4188 +    const char *opType = _rChild->_opType;
  1.4189 +    ideal_store = is_store_to_memory(opType);
  1.4190 +  }
  1.4191 +
  1.4192 +  return ideal_store;
  1.4193 +}
  1.4194 +
  1.4195 +
  1.4196 +void MatchRule::dump() {
  1.4197 +  output(stderr);
  1.4198 +}
  1.4199 +
  1.4200 +// Write just one line.
  1.4201 +void MatchRule::output_short(FILE *fp) {
  1.4202 +  fprintf(fp,"MatchRule: ( %s",_name);
  1.4203 +  if (_lChild) _lChild->output(fp);
  1.4204 +  if (_rChild) _rChild->output(fp);
  1.4205 +  fprintf(fp," )");
  1.4206 +}
  1.4207 +
  1.4208 +void MatchRule::output(FILE *fp) {
  1.4209 +  output_short(fp);
  1.4210 +  fprintf(fp,"\n   nesting depth = %d\n", _depth);
  1.4211 +  if (_result) fprintf(fp,"   Result Type = %s", _result);
  1.4212 +  fprintf(fp,"\n");
  1.4213 +}
  1.4214 +
  1.4215 +//------------------------------Attribute--------------------------------------
  1.4216 +Attribute::Attribute(char *id, char* val, int type)
  1.4217 +  : _ident(id), _val(val), _atype(type) {
  1.4218 +}
  1.4219 +Attribute::~Attribute() {
  1.4220 +}
  1.4221 +
  1.4222 +int Attribute::int_val(ArchDesc &ad) {
  1.4223 +  // Make sure it is an integer constant:
  1.4224 +  int result = 0;
  1.4225 +  if (!_val || !ADLParser::is_int_token(_val, result)) {
  1.4226 +    ad.syntax_err(0, "Attribute %s must have an integer value: %s",
  1.4227 +                  _ident, _val ? _val : "");
  1.4228 +  }
  1.4229 +  return result;
  1.4230 +}
  1.4231 +
  1.4232 +void Attribute::dump() {
  1.4233 +  output(stderr);
  1.4234 +} // Debug printer
  1.4235 +
  1.4236 +// Write to output files
  1.4237 +void Attribute::output(FILE *fp) {
  1.4238 +  fprintf(fp,"Attribute: %s  %s\n", (_ident?_ident:""), (_val?_val:""));
  1.4239 +}
  1.4240 +
  1.4241 +//------------------------------FormatRule----------------------------------
  1.4242 +FormatRule::FormatRule(char *temp)
  1.4243 +  : _temp(temp) {
  1.4244 +}
  1.4245 +FormatRule::~FormatRule() {
  1.4246 +}
  1.4247 +
  1.4248 +void FormatRule::dump() {
  1.4249 +  output(stderr);
  1.4250 +}
  1.4251 +
  1.4252 +// Write to output files
  1.4253 +void FormatRule::output(FILE *fp) {
  1.4254 +  fprintf(fp,"\nFormat Rule: \n%s", (_temp?_temp:""));
  1.4255 +  fprintf(fp,"\n");
  1.4256 +}

mercurial