src/share/vm/adlc/formssel.cpp

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

mercurial