src/share/vm/adlc/output_c.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/output_c.cpp	Sat Dec 01 00:00:00 2007 +0000
     1.3 @@ -0,0 +1,4049 @@
     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 +// output_c.cpp - Class CPP file output routines for architecture definition
    1.29 +
    1.30 +#include "adlc.hpp"
    1.31 +
    1.32 +// Utilities to characterize effect statements
    1.33 +static bool is_def(int usedef) {
    1.34 +  switch(usedef) {
    1.35 +  case Component::DEF:
    1.36 +  case Component::USE_DEF: return true; break;
    1.37 +  }
    1.38 +  return false;
    1.39 +}
    1.40 +
    1.41 +static bool is_use(int usedef) {
    1.42 +  switch(usedef) {
    1.43 +  case Component::USE:
    1.44 +  case Component::USE_DEF:
    1.45 +  case Component::USE_KILL: return true; break;
    1.46 +  }
    1.47 +  return false;
    1.48 +}
    1.49 +
    1.50 +static bool is_kill(int usedef) {
    1.51 +  switch(usedef) {
    1.52 +  case Component::KILL:
    1.53 +  case Component::USE_KILL: return true; break;
    1.54 +  }
    1.55 +  return false;
    1.56 +}
    1.57 +
    1.58 +// Define  an array containing the machine register names, strings.
    1.59 +static void defineRegNames(FILE *fp, RegisterForm *registers) {
    1.60 +  if (registers) {
    1.61 +    fprintf(fp,"\n");
    1.62 +    fprintf(fp,"// An array of character pointers to machine register names.\n");
    1.63 +    fprintf(fp,"const char *Matcher::regName[REG_COUNT] = {\n");
    1.64 +
    1.65 +    // Output the register name for each register in the allocation classes
    1.66 +    RegDef *reg_def = NULL;
    1.67 +    RegDef *next = NULL;
    1.68 +    registers->reset_RegDefs();
    1.69 +    for( reg_def = registers->iter_RegDefs(); reg_def != NULL; reg_def = next ) {
    1.70 +      next = registers->iter_RegDefs();
    1.71 +      const char *comma = (next != NULL) ? "," : " // no trailing comma";
    1.72 +      fprintf(fp,"  \"%s\"%s\n",
    1.73 +                 reg_def->_regname, comma );
    1.74 +    }
    1.75 +
    1.76 +    // Finish defining enumeration
    1.77 +    fprintf(fp,"};\n");
    1.78 +
    1.79 +    fprintf(fp,"\n");
    1.80 +    fprintf(fp,"// An array of character pointers to machine register names.\n");
    1.81 +    fprintf(fp,"const VMReg OptoReg::opto2vm[REG_COUNT] = {\n");
    1.82 +    reg_def = NULL;
    1.83 +    next = NULL;
    1.84 +    registers->reset_RegDefs();
    1.85 +    for( reg_def = registers->iter_RegDefs(); reg_def != NULL; reg_def = next ) {
    1.86 +      next = registers->iter_RegDefs();
    1.87 +      const char *comma = (next != NULL) ? "," : " // no trailing comma";
    1.88 +      fprintf(fp,"\t%s%s\n", reg_def->_concrete, comma );
    1.89 +    }
    1.90 +    // Finish defining array
    1.91 +    fprintf(fp,"\t};\n");
    1.92 +    fprintf(fp,"\n");
    1.93 +
    1.94 +    fprintf(fp," OptoReg::Name OptoReg::vm2opto[ConcreteRegisterImpl::number_of_registers];\n");
    1.95 +
    1.96 +  }
    1.97 +}
    1.98 +
    1.99 +// Define an array containing the machine register encoding values
   1.100 +static void defineRegEncodes(FILE *fp, RegisterForm *registers) {
   1.101 +  if (registers) {
   1.102 +    fprintf(fp,"\n");
   1.103 +    fprintf(fp,"// An array of the machine register encode values\n");
   1.104 +    fprintf(fp,"const unsigned char Matcher::_regEncode[REG_COUNT] = {\n");
   1.105 +
   1.106 +    // Output the register encoding for each register in the allocation classes
   1.107 +    RegDef *reg_def = NULL;
   1.108 +    RegDef *next    = NULL;
   1.109 +    registers->reset_RegDefs();
   1.110 +    for( reg_def = registers->iter_RegDefs(); reg_def != NULL; reg_def = next ) {
   1.111 +      next = registers->iter_RegDefs();
   1.112 +      const char* register_encode = reg_def->register_encode();
   1.113 +      const char *comma = (next != NULL) ? "," : " // no trailing comma";
   1.114 +      int encval;
   1.115 +      if (!ADLParser::is_int_token(register_encode, encval)) {
   1.116 +        fprintf(fp,"  %s%s  // %s\n",
   1.117 +                register_encode, comma, reg_def->_regname );
   1.118 +      } else {
   1.119 +        // Output known constants in hex char format (backward compatibility).
   1.120 +        assert(encval < 256, "Exceeded supported width for register encoding");
   1.121 +        fprintf(fp,"  (unsigned char)'\\x%X'%s  // %s\n",
   1.122 +                encval,          comma, reg_def->_regname );
   1.123 +      }
   1.124 +    }
   1.125 +    // Finish defining enumeration
   1.126 +    fprintf(fp,"};\n");
   1.127 +
   1.128 +  } // Done defining array
   1.129 +}
   1.130 +
   1.131 +// Output an enumeration of register class names
   1.132 +static void defineRegClassEnum(FILE *fp, RegisterForm *registers) {
   1.133 +  if (registers) {
   1.134 +    // Output an enumeration of register class names
   1.135 +    fprintf(fp,"\n");
   1.136 +    fprintf(fp,"// Enumeration of register class names\n");
   1.137 +    fprintf(fp, "enum machRegisterClass {\n");
   1.138 +    registers->_rclasses.reset();
   1.139 +    for( const char *class_name = NULL;
   1.140 +         (class_name = registers->_rclasses.iter()) != NULL; ) {
   1.141 +      fprintf(fp,"  %s,\n", toUpper( class_name ));
   1.142 +    }
   1.143 +    // Finish defining enumeration
   1.144 +    fprintf(fp, "  _last_Mach_Reg_Class\n");
   1.145 +    fprintf(fp, "};\n");
   1.146 +  }
   1.147 +}
   1.148 +
   1.149 +// Declare an enumeration of user-defined register classes
   1.150 +// and a list of register masks, one for each class.
   1.151 +void ArchDesc::declare_register_masks(FILE *fp_hpp) {
   1.152 +  const char  *rc_name;
   1.153 +
   1.154 +  if( _register ) {
   1.155 +    // Build enumeration of user-defined register classes.
   1.156 +    defineRegClassEnum(fp_hpp, _register);
   1.157 +
   1.158 +    // Generate a list of register masks, one for each class.
   1.159 +    fprintf(fp_hpp,"\n");
   1.160 +    fprintf(fp_hpp,"// Register masks, one for each register class.\n");
   1.161 +    _register->_rclasses.reset();
   1.162 +    for( rc_name = NULL;
   1.163 +         (rc_name = _register->_rclasses.iter()) != NULL; ) {
   1.164 +      const char *prefix    = "";
   1.165 +      RegClass   *reg_class = _register->getRegClass(rc_name);
   1.166 +      assert( reg_class, "Using an undefined register class");
   1.167 +
   1.168 +      int len = RegisterForm::RegMask_Size();
   1.169 +      fprintf(fp_hpp, "extern const RegMask %s%s_mask;\n", prefix, toUpper( rc_name ) );
   1.170 +
   1.171 +      if( reg_class->_stack_or_reg ) {
   1.172 +        fprintf(fp_hpp, "extern const RegMask %sSTACK_OR_%s_mask;\n", prefix, toUpper( rc_name ) );
   1.173 +      }
   1.174 +    }
   1.175 +  }
   1.176 +}
   1.177 +
   1.178 +// Generate an enumeration of user-defined register classes
   1.179 +// and a list of register masks, one for each class.
   1.180 +void ArchDesc::build_register_masks(FILE *fp_cpp) {
   1.181 +  const char  *rc_name;
   1.182 +
   1.183 +  if( _register ) {
   1.184 +    // Generate a list of register masks, one for each class.
   1.185 +    fprintf(fp_cpp,"\n");
   1.186 +    fprintf(fp_cpp,"// Register masks, one for each register class.\n");
   1.187 +    _register->_rclasses.reset();
   1.188 +    for( rc_name = NULL;
   1.189 +         (rc_name = _register->_rclasses.iter()) != NULL; ) {
   1.190 +      const char *prefix    = "";
   1.191 +      RegClass   *reg_class = _register->getRegClass(rc_name);
   1.192 +      assert( reg_class, "Using an undefined register class");
   1.193 +
   1.194 +      int len = RegisterForm::RegMask_Size();
   1.195 +      fprintf(fp_cpp, "const RegMask %s%s_mask(", prefix, toUpper( rc_name ) );
   1.196 +      { int i;
   1.197 +        for( i = 0; i < len-1; i++ )
   1.198 +          fprintf(fp_cpp," 0x%x,",reg_class->regs_in_word(i,false));
   1.199 +        fprintf(fp_cpp," 0x%x );\n",reg_class->regs_in_word(i,false));
   1.200 +      }
   1.201 +
   1.202 +      if( reg_class->_stack_or_reg ) {
   1.203 +        int i;
   1.204 +        fprintf(fp_cpp, "const RegMask %sSTACK_OR_%s_mask(", prefix, toUpper( rc_name ) );
   1.205 +        for( i = 0; i < len-1; i++ )
   1.206 +          fprintf(fp_cpp," 0x%x,",reg_class->regs_in_word(i,true));
   1.207 +        fprintf(fp_cpp," 0x%x );\n",reg_class->regs_in_word(i,true));
   1.208 +      }
   1.209 +    }
   1.210 +  }
   1.211 +}
   1.212 +
   1.213 +// Compute an index for an array in the pipeline_reads_NNN arrays
   1.214 +static int pipeline_reads_initializer(FILE *fp_cpp, NameList &pipeline_reads, PipeClassForm *pipeclass)
   1.215 +{
   1.216 +  int templen = 1;
   1.217 +  int paramcount = 0;
   1.218 +  const char *paramname;
   1.219 +
   1.220 +  if (pipeclass->_parameters.count() == 0)
   1.221 +    return -1;
   1.222 +
   1.223 +  pipeclass->_parameters.reset();
   1.224 +  paramname = pipeclass->_parameters.iter();
   1.225 +  const PipeClassOperandForm *pipeopnd =
   1.226 +    (const PipeClassOperandForm *)pipeclass->_localUsage[paramname];
   1.227 +  if (pipeopnd && !pipeopnd->isWrite() && strcmp(pipeopnd->_stage, "Universal"))
   1.228 +    pipeclass->_parameters.reset();
   1.229 +
   1.230 +  while ( (paramname = pipeclass->_parameters.iter()) != NULL ) {
   1.231 +    const PipeClassOperandForm *pipeopnd =
   1.232 +        (const PipeClassOperandForm *)pipeclass->_localUsage[paramname];
   1.233 +
   1.234 +    if (pipeopnd)
   1.235 +      templen += 10 + (int)strlen(pipeopnd->_stage);
   1.236 +    else
   1.237 +      templen += 19;
   1.238 +
   1.239 +    paramcount++;
   1.240 +  }
   1.241 +
   1.242 +  // See if the count is zero
   1.243 +  if (paramcount == 0) {
   1.244 +    return -1;
   1.245 +  }
   1.246 +
   1.247 +  char *operand_stages = new char [templen];
   1.248 +  operand_stages[0] = 0;
   1.249 +  int i = 0;
   1.250 +  templen = 0;
   1.251 +
   1.252 +  pipeclass->_parameters.reset();
   1.253 +  paramname = pipeclass->_parameters.iter();
   1.254 +  pipeopnd = (const PipeClassOperandForm *)pipeclass->_localUsage[paramname];
   1.255 +  if (pipeopnd && !pipeopnd->isWrite() && strcmp(pipeopnd->_stage, "Universal"))
   1.256 +    pipeclass->_parameters.reset();
   1.257 +
   1.258 +  while ( (paramname = pipeclass->_parameters.iter()) != NULL ) {
   1.259 +    const PipeClassOperandForm *pipeopnd =
   1.260 +        (const PipeClassOperandForm *)pipeclass->_localUsage[paramname];
   1.261 +    templen += sprintf(&operand_stages[templen], "  stage_%s%c\n",
   1.262 +      pipeopnd ? pipeopnd->_stage : "undefined",
   1.263 +      (++i < paramcount ? ',' : ' ') );
   1.264 +  }
   1.265 +
   1.266 +  // See if the same string is in the table
   1.267 +  int ndx = pipeline_reads.index(operand_stages);
   1.268 +
   1.269 +  // No, add it to the table
   1.270 +  if (ndx < 0) {
   1.271 +    pipeline_reads.addName(operand_stages);
   1.272 +    ndx = pipeline_reads.index(operand_stages);
   1.273 +
   1.274 +    fprintf(fp_cpp, "static const enum machPipelineStages pipeline_reads_%03d[%d] = {\n%s};\n\n",
   1.275 +      ndx+1, paramcount, operand_stages);
   1.276 +  }
   1.277 +  else
   1.278 +    delete [] operand_stages;
   1.279 +
   1.280 +  return (ndx);
   1.281 +}
   1.282 +
   1.283 +// Compute an index for an array in the pipeline_res_stages_NNN arrays
   1.284 +static int pipeline_res_stages_initializer(
   1.285 +  FILE *fp_cpp,
   1.286 +  PipelineForm *pipeline,
   1.287 +  NameList &pipeline_res_stages,
   1.288 +  PipeClassForm *pipeclass)
   1.289 +{
   1.290 +  const PipeClassResourceForm *piperesource;
   1.291 +  int * res_stages = new int [pipeline->_rescount];
   1.292 +  int i;
   1.293 +
   1.294 +  for (i = 0; i < pipeline->_rescount; i++)
   1.295 +     res_stages[i] = 0;
   1.296 +
   1.297 +  for (pipeclass->_resUsage.reset();
   1.298 +       (piperesource = (const PipeClassResourceForm *)pipeclass->_resUsage.iter()) != NULL; ) {
   1.299 +    int used_mask = pipeline->_resdict[piperesource->_resource]->is_resource()->mask();
   1.300 +    for (i = 0; i < pipeline->_rescount; i++)
   1.301 +      if ((1 << i) & used_mask) {
   1.302 +        int stage = pipeline->_stages.index(piperesource->_stage);
   1.303 +        if (res_stages[i] < stage+1)
   1.304 +          res_stages[i] = stage+1;
   1.305 +      }
   1.306 +  }
   1.307 +
   1.308 +  // Compute the length needed for the resource list
   1.309 +  int commentlen = 0;
   1.310 +  int max_stage = 0;
   1.311 +  for (i = 0; i < pipeline->_rescount; i++) {
   1.312 +    if (res_stages[i] == 0) {
   1.313 +      if (max_stage < 9)
   1.314 +        max_stage = 9;
   1.315 +    }
   1.316 +    else {
   1.317 +      int stagelen = (int)strlen(pipeline->_stages.name(res_stages[i]-1));
   1.318 +      if (max_stage < stagelen)
   1.319 +        max_stage = stagelen;
   1.320 +    }
   1.321 +
   1.322 +    commentlen += (int)strlen(pipeline->_reslist.name(i));
   1.323 +  }
   1.324 +
   1.325 +  int templen = 1 + commentlen + pipeline->_rescount * (max_stage + 14);
   1.326 +
   1.327 +  // Allocate space for the resource list
   1.328 +  char * resource_stages = new char [templen];
   1.329 +
   1.330 +  templen = 0;
   1.331 +  for (i = 0; i < pipeline->_rescount; i++) {
   1.332 +    const char * const resname =
   1.333 +      res_stages[i] == 0 ? "undefined" : pipeline->_stages.name(res_stages[i]-1);
   1.334 +
   1.335 +    templen += sprintf(&resource_stages[templen], "  stage_%s%-*s // %s\n",
   1.336 +      resname, max_stage - (int)strlen(resname) + 1,
   1.337 +      (i < pipeline->_rescount-1) ? "," : "",
   1.338 +      pipeline->_reslist.name(i));
   1.339 +  }
   1.340 +
   1.341 +  // See if the same string is in the table
   1.342 +  int ndx = pipeline_res_stages.index(resource_stages);
   1.343 +
   1.344 +  // No, add it to the table
   1.345 +  if (ndx < 0) {
   1.346 +    pipeline_res_stages.addName(resource_stages);
   1.347 +    ndx = pipeline_res_stages.index(resource_stages);
   1.348 +
   1.349 +    fprintf(fp_cpp, "static const enum machPipelineStages pipeline_res_stages_%03d[%d] = {\n%s};\n\n",
   1.350 +      ndx+1, pipeline->_rescount, resource_stages);
   1.351 +  }
   1.352 +  else
   1.353 +    delete [] resource_stages;
   1.354 +
   1.355 +  delete [] res_stages;
   1.356 +
   1.357 +  return (ndx);
   1.358 +}
   1.359 +
   1.360 +// Compute an index for an array in the pipeline_res_cycles_NNN arrays
   1.361 +static int pipeline_res_cycles_initializer(
   1.362 +  FILE *fp_cpp,
   1.363 +  PipelineForm *pipeline,
   1.364 +  NameList &pipeline_res_cycles,
   1.365 +  PipeClassForm *pipeclass)
   1.366 +{
   1.367 +  const PipeClassResourceForm *piperesource;
   1.368 +  int * res_cycles = new int [pipeline->_rescount];
   1.369 +  int i;
   1.370 +
   1.371 +  for (i = 0; i < pipeline->_rescount; i++)
   1.372 +     res_cycles[i] = 0;
   1.373 +
   1.374 +  for (pipeclass->_resUsage.reset();
   1.375 +       (piperesource = (const PipeClassResourceForm *)pipeclass->_resUsage.iter()) != NULL; ) {
   1.376 +    int used_mask = pipeline->_resdict[piperesource->_resource]->is_resource()->mask();
   1.377 +    for (i = 0; i < pipeline->_rescount; i++)
   1.378 +      if ((1 << i) & used_mask) {
   1.379 +        int cycles = piperesource->_cycles;
   1.380 +        if (res_cycles[i] < cycles)
   1.381 +          res_cycles[i] = cycles;
   1.382 +      }
   1.383 +  }
   1.384 +
   1.385 +  // Pre-compute the string length
   1.386 +  int templen;
   1.387 +  int cyclelen = 0, commentlen = 0;
   1.388 +  int max_cycles = 0;
   1.389 +  char temp[32];
   1.390 +
   1.391 +  for (i = 0; i < pipeline->_rescount; i++) {
   1.392 +    if (max_cycles < res_cycles[i])
   1.393 +      max_cycles = res_cycles[i];
   1.394 +    templen = sprintf(temp, "%d", res_cycles[i]);
   1.395 +    if (cyclelen < templen)
   1.396 +      cyclelen = templen;
   1.397 +    commentlen += (int)strlen(pipeline->_reslist.name(i));
   1.398 +  }
   1.399 +
   1.400 +  templen = 1 + commentlen + (cyclelen + 8) * pipeline->_rescount;
   1.401 +
   1.402 +  // Allocate space for the resource list
   1.403 +  char * resource_cycles = new char [templen];
   1.404 +
   1.405 +  templen = 0;
   1.406 +
   1.407 +  for (i = 0; i < pipeline->_rescount; i++) {
   1.408 +    templen += sprintf(&resource_cycles[templen], "  %*d%c // %s\n",
   1.409 +      cyclelen, res_cycles[i], (i < pipeline->_rescount-1) ? ',' : ' ', pipeline->_reslist.name(i));
   1.410 +  }
   1.411 +
   1.412 +  // See if the same string is in the table
   1.413 +  int ndx = pipeline_res_cycles.index(resource_cycles);
   1.414 +
   1.415 +  // No, add it to the table
   1.416 +  if (ndx < 0) {
   1.417 +    pipeline_res_cycles.addName(resource_cycles);
   1.418 +    ndx = pipeline_res_cycles.index(resource_cycles);
   1.419 +
   1.420 +    fprintf(fp_cpp, "static const uint pipeline_res_cycles_%03d[%d] = {\n%s};\n\n",
   1.421 +      ndx+1, pipeline->_rescount, resource_cycles);
   1.422 +  }
   1.423 +  else
   1.424 +    delete [] resource_cycles;
   1.425 +
   1.426 +  delete [] res_cycles;
   1.427 +
   1.428 +  return (ndx);
   1.429 +}
   1.430 +
   1.431 +//typedef unsigned long long uint64_t;
   1.432 +
   1.433 +// Compute an index for an array in the pipeline_res_mask_NNN arrays
   1.434 +static int pipeline_res_mask_initializer(
   1.435 +  FILE *fp_cpp,
   1.436 +  PipelineForm *pipeline,
   1.437 +  NameList &pipeline_res_mask,
   1.438 +  NameList &pipeline_res_args,
   1.439 +  PipeClassForm *pipeclass)
   1.440 +{
   1.441 +  const PipeClassResourceForm *piperesource;
   1.442 +  const uint rescount      = pipeline->_rescount;
   1.443 +  const uint maxcycleused  = pipeline->_maxcycleused;
   1.444 +  const uint cyclemasksize = (maxcycleused + 31) >> 5;
   1.445 +
   1.446 +  int i, j;
   1.447 +  int element_count = 0;
   1.448 +  uint *res_mask = new uint [cyclemasksize];
   1.449 +  uint resources_used             = 0;
   1.450 +  uint resources_used_exclusively = 0;
   1.451 +
   1.452 +  for (pipeclass->_resUsage.reset();
   1.453 +       (piperesource = (const PipeClassResourceForm *)pipeclass->_resUsage.iter()) != NULL; )
   1.454 +    element_count++;
   1.455 +
   1.456 +  // Pre-compute the string length
   1.457 +  int templen;
   1.458 +  int commentlen = 0;
   1.459 +  int max_cycles = 0;
   1.460 +
   1.461 +  int cyclelen = ((maxcycleused + 3) >> 2);
   1.462 +  int masklen = (rescount + 3) >> 2;
   1.463 +
   1.464 +  int cycledigit = 0;
   1.465 +  for (i = maxcycleused; i > 0; i /= 10)
   1.466 +    cycledigit++;
   1.467 +
   1.468 +  int maskdigit = 0;
   1.469 +  for (i = rescount; i > 0; i /= 10)
   1.470 +    maskdigit++;
   1.471 +
   1.472 +  static const char * pipeline_use_cycle_mask = "Pipeline_Use_Cycle_Mask";
   1.473 +  static const char * pipeline_use_element    = "Pipeline_Use_Element";
   1.474 +
   1.475 +  templen = 1 +
   1.476 +    (int)(strlen(pipeline_use_cycle_mask) + (int)strlen(pipeline_use_element) +
   1.477 +     (cyclemasksize * 12) + masklen + (cycledigit * 2) + 30) * element_count;
   1.478 +
   1.479 +  // Allocate space for the resource list
   1.480 +  char * resource_mask = new char [templen];
   1.481 +  char * last_comma = NULL;
   1.482 +
   1.483 +  templen = 0;
   1.484 +
   1.485 +  for (pipeclass->_resUsage.reset();
   1.486 +       (piperesource = (const PipeClassResourceForm *)pipeclass->_resUsage.iter()) != NULL; ) {
   1.487 +    int used_mask = pipeline->_resdict[piperesource->_resource]->is_resource()->mask();
   1.488 +
   1.489 +    if (!used_mask)
   1.490 +      fprintf(stderr, "*** used_mask is 0 ***\n");
   1.491 +
   1.492 +    resources_used |= used_mask;
   1.493 +
   1.494 +    uint lb, ub;
   1.495 +
   1.496 +    for (lb =  0; (used_mask & (1 << lb)) == 0; lb++);
   1.497 +    for (ub = 31; (used_mask & (1 << ub)) == 0; ub--);
   1.498 +
   1.499 +    if (lb == ub)
   1.500 +      resources_used_exclusively |= used_mask;
   1.501 +
   1.502 +    int formatlen =
   1.503 +      sprintf(&resource_mask[templen], "  %s(0x%0*x, %*d, %*d, %s %s(",
   1.504 +        pipeline_use_element,
   1.505 +        masklen, used_mask,
   1.506 +        cycledigit, lb, cycledigit, ub,
   1.507 +        ((used_mask & (used_mask-1)) != 0) ? "true, " : "false,",
   1.508 +        pipeline_use_cycle_mask);
   1.509 +
   1.510 +    templen += formatlen;
   1.511 +
   1.512 +    memset(res_mask, 0, cyclemasksize * sizeof(uint));
   1.513 +
   1.514 +    int cycles = piperesource->_cycles;
   1.515 +    uint stage          = pipeline->_stages.index(piperesource->_stage);
   1.516 +    uint upper_limit    = stage+cycles-1;
   1.517 +    uint lower_limit    = stage-1;
   1.518 +    uint upper_idx      = upper_limit >> 5;
   1.519 +    uint lower_idx      = lower_limit >> 5;
   1.520 +    uint upper_position = upper_limit & 0x1f;
   1.521 +    uint lower_position = lower_limit & 0x1f;
   1.522 +
   1.523 +    uint mask = (((uint)1) << upper_position) - 1;
   1.524 +
   1.525 +    while ( upper_idx > lower_idx ) {
   1.526 +      res_mask[upper_idx--] |= mask;
   1.527 +      mask = (uint)-1;
   1.528 +    }
   1.529 +
   1.530 +    mask -= (((uint)1) << lower_position) - 1;
   1.531 +    res_mask[upper_idx] |= mask;
   1.532 +
   1.533 +    for (j = cyclemasksize-1; j >= 0; j--) {
   1.534 +      formatlen =
   1.535 +        sprintf(&resource_mask[templen], "0x%08x%s", res_mask[j], j > 0 ? ", " : "");
   1.536 +      templen += formatlen;
   1.537 +    }
   1.538 +
   1.539 +    resource_mask[templen++] = ')';
   1.540 +    resource_mask[templen++] = ')';
   1.541 +    last_comma = &resource_mask[templen];
   1.542 +    resource_mask[templen++] = ',';
   1.543 +    resource_mask[templen++] = '\n';
   1.544 +  }
   1.545 +
   1.546 +  resource_mask[templen] = 0;
   1.547 +  if (last_comma)
   1.548 +    last_comma[0] = ' ';
   1.549 +
   1.550 +  // See if the same string is in the table
   1.551 +  int ndx = pipeline_res_mask.index(resource_mask);
   1.552 +
   1.553 +  // No, add it to the table
   1.554 +  if (ndx < 0) {
   1.555 +    pipeline_res_mask.addName(resource_mask);
   1.556 +    ndx = pipeline_res_mask.index(resource_mask);
   1.557 +
   1.558 +    if (strlen(resource_mask) > 0)
   1.559 +      fprintf(fp_cpp, "static const Pipeline_Use_Element pipeline_res_mask_%03d[%d] = {\n%s};\n\n",
   1.560 +        ndx+1, element_count, resource_mask);
   1.561 +
   1.562 +    char * args = new char [9 + 2*masklen + maskdigit];
   1.563 +
   1.564 +    sprintf(args, "0x%0*x, 0x%0*x, %*d",
   1.565 +      masklen, resources_used,
   1.566 +      masklen, resources_used_exclusively,
   1.567 +      maskdigit, element_count);
   1.568 +
   1.569 +    pipeline_res_args.addName(args);
   1.570 +  }
   1.571 +  else
   1.572 +    delete [] resource_mask;
   1.573 +
   1.574 +  delete [] res_mask;
   1.575 +//delete [] res_masks;
   1.576 +
   1.577 +  return (ndx);
   1.578 +}
   1.579 +
   1.580 +void ArchDesc::build_pipe_classes(FILE *fp_cpp) {
   1.581 +  const char *classname;
   1.582 +  const char *resourcename;
   1.583 +  int resourcenamelen = 0;
   1.584 +  NameList pipeline_reads;
   1.585 +  NameList pipeline_res_stages;
   1.586 +  NameList pipeline_res_cycles;
   1.587 +  NameList pipeline_res_masks;
   1.588 +  NameList pipeline_res_args;
   1.589 +  const int default_latency = 1;
   1.590 +  const int non_operand_latency = 0;
   1.591 +  const int node_latency = 0;
   1.592 +
   1.593 +  if (!_pipeline) {
   1.594 +    fprintf(fp_cpp, "uint Node::latency(uint i) const {\n");
   1.595 +    fprintf(fp_cpp, "  // assert(false, \"pipeline functionality is not defined\");\n");
   1.596 +    fprintf(fp_cpp, "  return %d;\n", non_operand_latency);
   1.597 +    fprintf(fp_cpp, "}\n");
   1.598 +    return;
   1.599 +  }
   1.600 +
   1.601 +  fprintf(fp_cpp, "\n");
   1.602 +  fprintf(fp_cpp, "//------------------Pipeline Methods-----------------------------------------\n");
   1.603 +  fprintf(fp_cpp, "#ifndef PRODUCT\n");
   1.604 +  fprintf(fp_cpp, "const char * Pipeline::stageName(uint s) {\n");
   1.605 +  fprintf(fp_cpp, "  static const char * const _stage_names[] = {\n");
   1.606 +  fprintf(fp_cpp, "    \"undefined\"");
   1.607 +
   1.608 +  for (int s = 0; s < _pipeline->_stagecnt; s++)
   1.609 +    fprintf(fp_cpp, ", \"%s\"", _pipeline->_stages.name(s));
   1.610 +
   1.611 +  fprintf(fp_cpp, "\n  };\n\n");
   1.612 +  fprintf(fp_cpp, "  return (s <= %d ? _stage_names[s] : \"???\");\n",
   1.613 +    _pipeline->_stagecnt);
   1.614 +  fprintf(fp_cpp, "}\n");
   1.615 +  fprintf(fp_cpp, "#endif\n\n");
   1.616 +
   1.617 +  fprintf(fp_cpp, "uint Pipeline::functional_unit_latency(uint start, const Pipeline *pred) const {\n");
   1.618 +  fprintf(fp_cpp, "  // See if the functional units overlap\n");
   1.619 +#if 0
   1.620 +  fprintf(fp_cpp, "\n#ifndef PRODUCT\n");
   1.621 +  fprintf(fp_cpp, "  if (TraceOptoOutput) {\n");
   1.622 +  fprintf(fp_cpp, "    tty->print(\"#   functional_unit_latency: start == %%d, this->exclusively == 0x%%03x, pred->exclusively == 0x%%03x\\n\", start, resourcesUsedExclusively(), pred->resourcesUsedExclusively());\n");
   1.623 +  fprintf(fp_cpp, "  }\n");
   1.624 +  fprintf(fp_cpp, "#endif\n\n");
   1.625 +#endif
   1.626 +  fprintf(fp_cpp, "  uint mask = resourcesUsedExclusively() & pred->resourcesUsedExclusively();\n");
   1.627 +  fprintf(fp_cpp, "  if (mask == 0)\n    return (start);\n\n");
   1.628 +#if 0
   1.629 +  fprintf(fp_cpp, "\n#ifndef PRODUCT\n");
   1.630 +  fprintf(fp_cpp, "  if (TraceOptoOutput) {\n");
   1.631 +  fprintf(fp_cpp, "    tty->print(\"#   functional_unit_latency: mask == 0x%%x\\n\", mask);\n");
   1.632 +  fprintf(fp_cpp, "  }\n");
   1.633 +  fprintf(fp_cpp, "#endif\n\n");
   1.634 +#endif
   1.635 +  fprintf(fp_cpp, "  for (uint i = 0; i < pred->resourceUseCount(); i++) {\n");
   1.636 +  fprintf(fp_cpp, "    const Pipeline_Use_Element *predUse = pred->resourceUseElement(i);\n");
   1.637 +  fprintf(fp_cpp, "    if (predUse->multiple())\n");
   1.638 +  fprintf(fp_cpp, "      continue;\n\n");
   1.639 +  fprintf(fp_cpp, "    for (uint j = 0; j < resourceUseCount(); j++) {\n");
   1.640 +  fprintf(fp_cpp, "      const Pipeline_Use_Element *currUse = resourceUseElement(j);\n");
   1.641 +  fprintf(fp_cpp, "      if (currUse->multiple())\n");
   1.642 +  fprintf(fp_cpp, "        continue;\n\n");
   1.643 +  fprintf(fp_cpp, "      if (predUse->used() & currUse->used()) {\n");
   1.644 +  fprintf(fp_cpp, "        Pipeline_Use_Cycle_Mask x = predUse->mask();\n");
   1.645 +  fprintf(fp_cpp, "        Pipeline_Use_Cycle_Mask y = currUse->mask();\n\n");
   1.646 +  fprintf(fp_cpp, "        for ( y <<= start; x.overlaps(y); start++ )\n");
   1.647 +  fprintf(fp_cpp, "          y <<= 1;\n");
   1.648 +  fprintf(fp_cpp, "      }\n");
   1.649 +  fprintf(fp_cpp, "    }\n");
   1.650 +  fprintf(fp_cpp, "  }\n\n");
   1.651 +  fprintf(fp_cpp, "  // There is the potential for overlap\n");
   1.652 +  fprintf(fp_cpp, "  return (start);\n");
   1.653 +  fprintf(fp_cpp, "}\n\n");
   1.654 +  fprintf(fp_cpp, "// The following two routines assume that the root Pipeline_Use entity\n");
   1.655 +  fprintf(fp_cpp, "// consists of exactly 1 element for each functional unit\n");
   1.656 +  fprintf(fp_cpp, "// start is relative to the current cycle; used for latency-based info\n");
   1.657 +  fprintf(fp_cpp, "uint Pipeline_Use::full_latency(uint delay, const Pipeline_Use &pred) const {\n");
   1.658 +  fprintf(fp_cpp, "  for (uint i = 0; i < pred._count; i++) {\n");
   1.659 +  fprintf(fp_cpp, "    const Pipeline_Use_Element *predUse = pred.element(i);\n");
   1.660 +  fprintf(fp_cpp, "    if (predUse->_multiple) {\n");
   1.661 +  fprintf(fp_cpp, "      uint min_delay = %d;\n",
   1.662 +    _pipeline->_maxcycleused+1);
   1.663 +  fprintf(fp_cpp, "      // Multiple possible functional units, choose first unused one\n");
   1.664 +  fprintf(fp_cpp, "      for (uint j = predUse->_lb; j <= predUse->_ub; j++) {\n");
   1.665 +  fprintf(fp_cpp, "        const Pipeline_Use_Element *currUse = element(j);\n");
   1.666 +  fprintf(fp_cpp, "        uint curr_delay = delay;\n");
   1.667 +  fprintf(fp_cpp, "        if (predUse->_used & currUse->_used) {\n");
   1.668 +  fprintf(fp_cpp, "          Pipeline_Use_Cycle_Mask x = predUse->_mask;\n");
   1.669 +  fprintf(fp_cpp, "          Pipeline_Use_Cycle_Mask y = currUse->_mask;\n\n");
   1.670 +  fprintf(fp_cpp, "          for ( y <<= curr_delay; x.overlaps(y); curr_delay++ )\n");
   1.671 +  fprintf(fp_cpp, "            y <<= 1;\n");
   1.672 +  fprintf(fp_cpp, "        }\n");
   1.673 +  fprintf(fp_cpp, "        if (min_delay > curr_delay)\n          min_delay = curr_delay;\n");
   1.674 +  fprintf(fp_cpp, "      }\n");
   1.675 +  fprintf(fp_cpp, "      if (delay < min_delay)\n      delay = min_delay;\n");
   1.676 +  fprintf(fp_cpp, "    }\n");
   1.677 +  fprintf(fp_cpp, "    else {\n");
   1.678 +  fprintf(fp_cpp, "      for (uint j = predUse->_lb; j <= predUse->_ub; j++) {\n");
   1.679 +  fprintf(fp_cpp, "        const Pipeline_Use_Element *currUse = element(j);\n");
   1.680 +  fprintf(fp_cpp, "        if (predUse->_used & currUse->_used) {\n");
   1.681 +  fprintf(fp_cpp, "          Pipeline_Use_Cycle_Mask x = predUse->_mask;\n");
   1.682 +  fprintf(fp_cpp, "          Pipeline_Use_Cycle_Mask y = currUse->_mask;\n\n");
   1.683 +  fprintf(fp_cpp, "          for ( y <<= delay; x.overlaps(y); delay++ )\n");
   1.684 +  fprintf(fp_cpp, "            y <<= 1;\n");
   1.685 +  fprintf(fp_cpp, "        }\n");
   1.686 +  fprintf(fp_cpp, "      }\n");
   1.687 +  fprintf(fp_cpp, "    }\n");
   1.688 +  fprintf(fp_cpp, "  }\n\n");
   1.689 +  fprintf(fp_cpp, "  return (delay);\n");
   1.690 +  fprintf(fp_cpp, "}\n\n");
   1.691 +  fprintf(fp_cpp, "void Pipeline_Use::add_usage(const Pipeline_Use &pred) {\n");
   1.692 +  fprintf(fp_cpp, "  for (uint i = 0; i < pred._count; i++) {\n");
   1.693 +  fprintf(fp_cpp, "    const Pipeline_Use_Element *predUse = pred.element(i);\n");
   1.694 +  fprintf(fp_cpp, "    if (predUse->_multiple) {\n");
   1.695 +  fprintf(fp_cpp, "      // Multiple possible functional units, choose first unused one\n");
   1.696 +  fprintf(fp_cpp, "      for (uint j = predUse->_lb; j <= predUse->_ub; j++) {\n");
   1.697 +  fprintf(fp_cpp, "        Pipeline_Use_Element *currUse = element(j);\n");
   1.698 +  fprintf(fp_cpp, "        if ( !predUse->_mask.overlaps(currUse->_mask) ) {\n");
   1.699 +  fprintf(fp_cpp, "          currUse->_used |= (1 << j);\n");
   1.700 +  fprintf(fp_cpp, "          _resources_used |= (1 << j);\n");
   1.701 +  fprintf(fp_cpp, "          currUse->_mask.Or(predUse->_mask);\n");
   1.702 +  fprintf(fp_cpp, "          break;\n");
   1.703 +  fprintf(fp_cpp, "        }\n");
   1.704 +  fprintf(fp_cpp, "      }\n");
   1.705 +  fprintf(fp_cpp, "    }\n");
   1.706 +  fprintf(fp_cpp, "    else {\n");
   1.707 +  fprintf(fp_cpp, "      for (uint j = predUse->_lb; j <= predUse->_ub; j++) {\n");
   1.708 +  fprintf(fp_cpp, "        Pipeline_Use_Element *currUse = element(j);\n");
   1.709 +  fprintf(fp_cpp, "        currUse->_used |= (1 << j);\n");
   1.710 +  fprintf(fp_cpp, "        _resources_used |= (1 << j);\n");
   1.711 +  fprintf(fp_cpp, "        currUse->_mask.Or(predUse->_mask);\n");
   1.712 +  fprintf(fp_cpp, "      }\n");
   1.713 +  fprintf(fp_cpp, "    }\n");
   1.714 +  fprintf(fp_cpp, "  }\n");
   1.715 +  fprintf(fp_cpp, "}\n\n");
   1.716 +
   1.717 +  fprintf(fp_cpp, "uint Pipeline::operand_latency(uint opnd, const Pipeline *pred) const {\n");
   1.718 +  fprintf(fp_cpp, "  int const default_latency = 1;\n");
   1.719 +  fprintf(fp_cpp, "\n");
   1.720 +#if 0
   1.721 +  fprintf(fp_cpp, "#ifndef PRODUCT\n");
   1.722 +  fprintf(fp_cpp, "  if (TraceOptoOutput) {\n");
   1.723 +  fprintf(fp_cpp, "    tty->print(\"#   operand_latency(%%d), _read_stage_count = %%d\\n\", opnd, _read_stage_count);\n");
   1.724 +  fprintf(fp_cpp, "  }\n");
   1.725 +  fprintf(fp_cpp, "#endif\n\n");
   1.726 +#endif
   1.727 +  fprintf(fp_cpp, "  assert(this, \"NULL pipeline info\")\n");
   1.728 +  fprintf(fp_cpp, "  assert(pred, \"NULL predecessor pipline info\")\n\n");
   1.729 +  fprintf(fp_cpp, "  if (pred->hasFixedLatency())\n    return (pred->fixedLatency());\n\n");
   1.730 +  fprintf(fp_cpp, "  // If this is not an operand, then assume a dependence with 0 latency\n");
   1.731 +  fprintf(fp_cpp, "  if (opnd > _read_stage_count)\n    return (0);\n\n");
   1.732 +  fprintf(fp_cpp, "  uint writeStage = pred->_write_stage;\n");
   1.733 +  fprintf(fp_cpp, "  uint readStage  = _read_stages[opnd-1];\n");
   1.734 +#if 0
   1.735 +  fprintf(fp_cpp, "\n#ifndef PRODUCT\n");
   1.736 +  fprintf(fp_cpp, "  if (TraceOptoOutput) {\n");
   1.737 +  fprintf(fp_cpp, "    tty->print(\"#   operand_latency: writeStage=%%s readStage=%%s, opnd=%%d\\n\", stageName(writeStage), stageName(readStage), opnd);\n");
   1.738 +  fprintf(fp_cpp, "  }\n");
   1.739 +  fprintf(fp_cpp, "#endif\n\n");
   1.740 +#endif
   1.741 +  fprintf(fp_cpp, "\n");
   1.742 +  fprintf(fp_cpp, "  if (writeStage == stage_undefined || readStage == stage_undefined)\n");
   1.743 +  fprintf(fp_cpp, "    return (default_latency);\n");
   1.744 +  fprintf(fp_cpp, "\n");
   1.745 +  fprintf(fp_cpp, "  int delta = writeStage - readStage;\n");
   1.746 +  fprintf(fp_cpp, "  if (delta < 0) delta = 0;\n\n");
   1.747 +#if 0
   1.748 +  fprintf(fp_cpp, "\n#ifndef PRODUCT\n");
   1.749 +  fprintf(fp_cpp, "  if (TraceOptoOutput) {\n");
   1.750 +  fprintf(fp_cpp, "    tty->print(\"# operand_latency: delta=%%d\\n\", delta);\n");
   1.751 +  fprintf(fp_cpp, "  }\n");
   1.752 +  fprintf(fp_cpp, "#endif\n\n");
   1.753 +#endif
   1.754 +  fprintf(fp_cpp, "  return (delta);\n");
   1.755 +  fprintf(fp_cpp, "}\n\n");
   1.756 +
   1.757 +  if (!_pipeline)
   1.758 +    /* Do Nothing */;
   1.759 +
   1.760 +  else if (_pipeline->_maxcycleused <=
   1.761 +#ifdef SPARC
   1.762 +    64
   1.763 +#else
   1.764 +    32
   1.765 +#endif
   1.766 +      ) {
   1.767 +    fprintf(fp_cpp, "Pipeline_Use_Cycle_Mask operator&(const Pipeline_Use_Cycle_Mask &in1, const Pipeline_Use_Cycle_Mask &in2) {\n");
   1.768 +    fprintf(fp_cpp, "  return Pipeline_Use_Cycle_Mask(in1._mask & in2._mask);\n");
   1.769 +    fprintf(fp_cpp, "}\n\n");
   1.770 +    fprintf(fp_cpp, "Pipeline_Use_Cycle_Mask operator|(const Pipeline_Use_Cycle_Mask &in1, const Pipeline_Use_Cycle_Mask &in2) {\n");
   1.771 +    fprintf(fp_cpp, "  return Pipeline_Use_Cycle_Mask(in1._mask | in2._mask);\n");
   1.772 +    fprintf(fp_cpp, "}\n\n");
   1.773 +  }
   1.774 +  else {
   1.775 +    uint l;
   1.776 +    uint masklen = (_pipeline->_maxcycleused + 31) >> 5;
   1.777 +    fprintf(fp_cpp, "Pipeline_Use_Cycle_Mask operator&(const Pipeline_Use_Cycle_Mask &in1, const Pipeline_Use_Cycle_Mask &in2) {\n");
   1.778 +    fprintf(fp_cpp, "  return Pipeline_Use_Cycle_Mask(");
   1.779 +    for (l = 1; l <= masklen; l++)
   1.780 +      fprintf(fp_cpp, "in1._mask%d & in2._mask%d%s\n", l, l, l < masklen ? ", " : "");
   1.781 +    fprintf(fp_cpp, ");\n");
   1.782 +    fprintf(fp_cpp, "}\n\n");
   1.783 +    fprintf(fp_cpp, "Pipeline_Use_Cycle_Mask operator|(const Pipeline_Use_Cycle_Mask &in1, const Pipeline_Use_Cycle_Mask &in2) {\n");
   1.784 +    fprintf(fp_cpp, "  return Pipeline_Use_Cycle_Mask(");
   1.785 +    for (l = 1; l <= masklen; l++)
   1.786 +      fprintf(fp_cpp, "in1._mask%d | in2._mask%d%s", l, l, l < masklen ? ", " : "");
   1.787 +    fprintf(fp_cpp, ");\n");
   1.788 +    fprintf(fp_cpp, "}\n\n");
   1.789 +    fprintf(fp_cpp, "void Pipeline_Use_Cycle_Mask::Or(const Pipeline_Use_Cycle_Mask &in2) {\n ");
   1.790 +    for (l = 1; l <= masklen; l++)
   1.791 +      fprintf(fp_cpp, " _mask%d |= in2._mask%d;", l, l);
   1.792 +    fprintf(fp_cpp, "\n}\n\n");
   1.793 +  }
   1.794 +
   1.795 +  /* Get the length of all the resource names */
   1.796 +  for (_pipeline->_reslist.reset(), resourcenamelen = 0;
   1.797 +       (resourcename = _pipeline->_reslist.iter()) != NULL;
   1.798 +       resourcenamelen += (int)strlen(resourcename));
   1.799 +
   1.800 +  // Create the pipeline class description
   1.801 +
   1.802 +  fprintf(fp_cpp, "static const Pipeline pipeline_class_Zero_Instructions(0, 0, true, 0, 0, false, false, false, false, NULL, NULL, NULL, Pipeline_Use(0, 0, 0, NULL));\n\n");
   1.803 +  fprintf(fp_cpp, "static const Pipeline pipeline_class_Unknown_Instructions(0, 0, true, 0, 0, false, true, true, false, NULL, NULL, NULL, Pipeline_Use(0, 0, 0, NULL));\n\n");
   1.804 +
   1.805 +  fprintf(fp_cpp, "const Pipeline_Use_Element Pipeline_Use::elaborated_elements[%d] = {\n", _pipeline->_rescount);
   1.806 +  for (int i1 = 0; i1 < _pipeline->_rescount; i1++) {
   1.807 +    fprintf(fp_cpp, "  Pipeline_Use_Element(0, %d, %d, false, Pipeline_Use_Cycle_Mask(", i1, i1);
   1.808 +    uint masklen = (_pipeline->_maxcycleused + 31) >> 5;
   1.809 +    for (int i2 = masklen-1; i2 >= 0; i2--)
   1.810 +      fprintf(fp_cpp, "0%s", i2 > 0 ? ", " : "");
   1.811 +    fprintf(fp_cpp, "))%s\n", i1 < (_pipeline->_rescount-1) ? "," : "");
   1.812 +  }
   1.813 +  fprintf(fp_cpp, "};\n\n");
   1.814 +
   1.815 +  fprintf(fp_cpp, "const Pipeline_Use Pipeline_Use::elaborated_use(0, 0, %d, (Pipeline_Use_Element *)&elaborated_elements[0]);\n\n",
   1.816 +    _pipeline->_rescount);
   1.817 +
   1.818 +  for (_pipeline->_classlist.reset(); (classname = _pipeline->_classlist.iter()) != NULL; ) {
   1.819 +    fprintf(fp_cpp, "\n");
   1.820 +    fprintf(fp_cpp, "// Pipeline Class \"%s\"\n", classname);
   1.821 +    PipeClassForm *pipeclass = _pipeline->_classdict[classname]->is_pipeclass();
   1.822 +    int maxWriteStage = -1;
   1.823 +    int maxMoreInstrs = 0;
   1.824 +    int paramcount = 0;
   1.825 +    int i = 0;
   1.826 +    const char *paramname;
   1.827 +    int resource_count = (_pipeline->_rescount + 3) >> 2;
   1.828 +
   1.829 +    // Scan the operands, looking for last output stage and number of inputs
   1.830 +    for (pipeclass->_parameters.reset(); (paramname = pipeclass->_parameters.iter()) != NULL; ) {
   1.831 +      const PipeClassOperandForm *pipeopnd =
   1.832 +          (const PipeClassOperandForm *)pipeclass->_localUsage[paramname];
   1.833 +      if (pipeopnd) {
   1.834 +        if (pipeopnd->_iswrite) {
   1.835 +           int stagenum  = _pipeline->_stages.index(pipeopnd->_stage);
   1.836 +           int moreinsts = pipeopnd->_more_instrs;
   1.837 +          if ((maxWriteStage+maxMoreInstrs) < (stagenum+moreinsts)) {
   1.838 +            maxWriteStage = stagenum;
   1.839 +            maxMoreInstrs = moreinsts;
   1.840 +          }
   1.841 +        }
   1.842 +      }
   1.843 +
   1.844 +      if (i++ > 0 || (pipeopnd && !pipeopnd->isWrite()))
   1.845 +        paramcount++;
   1.846 +    }
   1.847 +
   1.848 +    // Create the list of stages for the operands that are read
   1.849 +    // Note that we will build a NameList to reduce the number of copies
   1.850 +
   1.851 +    int pipeline_reads_index = pipeline_reads_initializer(fp_cpp, pipeline_reads, pipeclass);
   1.852 +
   1.853 +    int pipeline_res_stages_index = pipeline_res_stages_initializer(
   1.854 +      fp_cpp, _pipeline, pipeline_res_stages, pipeclass);
   1.855 +
   1.856 +    int pipeline_res_cycles_index = pipeline_res_cycles_initializer(
   1.857 +      fp_cpp, _pipeline, pipeline_res_cycles, pipeclass);
   1.858 +
   1.859 +    int pipeline_res_mask_index = pipeline_res_mask_initializer(
   1.860 +      fp_cpp, _pipeline, pipeline_res_masks, pipeline_res_args, pipeclass);
   1.861 +
   1.862 +#if 0
   1.863 +    // Process the Resources
   1.864 +    const PipeClassResourceForm *piperesource;
   1.865 +
   1.866 +    unsigned resources_used = 0;
   1.867 +    unsigned exclusive_resources_used = 0;
   1.868 +    unsigned resource_groups = 0;
   1.869 +    for (pipeclass->_resUsage.reset();
   1.870 +         (piperesource = (const PipeClassResourceForm *)pipeclass->_resUsage.iter()) != NULL; ) {
   1.871 +      int used_mask = _pipeline->_resdict[piperesource->_resource]->is_resource()->mask();
   1.872 +      if (used_mask)
   1.873 +        resource_groups++;
   1.874 +      resources_used |= used_mask;
   1.875 +      if ((used_mask & (used_mask-1)) == 0)
   1.876 +        exclusive_resources_used |= used_mask;
   1.877 +    }
   1.878 +
   1.879 +    if (resource_groups > 0) {
   1.880 +      fprintf(fp_cpp, "static const uint pipeline_res_or_masks_%03d[%d] = {",
   1.881 +        pipeclass->_num, resource_groups);
   1.882 +      for (pipeclass->_resUsage.reset(), i = 1;
   1.883 +           (piperesource = (const PipeClassResourceForm *)pipeclass->_resUsage.iter()) != NULL;
   1.884 +           i++ ) {
   1.885 +        int used_mask = _pipeline->_resdict[piperesource->_resource]->is_resource()->mask();
   1.886 +        if (used_mask) {
   1.887 +          fprintf(fp_cpp, " 0x%0*x%c", resource_count, used_mask, i < (int)resource_groups ? ',' : ' ');
   1.888 +        }
   1.889 +      }
   1.890 +      fprintf(fp_cpp, "};\n\n");
   1.891 +    }
   1.892 +#endif
   1.893 +
   1.894 +    // Create the pipeline class description
   1.895 +    fprintf(fp_cpp, "static const Pipeline pipeline_class_%03d(",
   1.896 +      pipeclass->_num);
   1.897 +    if (maxWriteStage < 0)
   1.898 +      fprintf(fp_cpp, "(uint)stage_undefined");
   1.899 +    else if (maxMoreInstrs == 0)
   1.900 +      fprintf(fp_cpp, "(uint)stage_%s", _pipeline->_stages.name(maxWriteStage));
   1.901 +    else
   1.902 +      fprintf(fp_cpp, "((uint)stage_%s)+%d", _pipeline->_stages.name(maxWriteStage), maxMoreInstrs);
   1.903 +    fprintf(fp_cpp, ", %d, %s, %d, %d, %s, %s, %s, %s,\n",
   1.904 +      paramcount,
   1.905 +      pipeclass->hasFixedLatency() ? "true" : "false",
   1.906 +      pipeclass->fixedLatency(),
   1.907 +      pipeclass->InstructionCount(),
   1.908 +      pipeclass->hasBranchDelay() ? "true" : "false",
   1.909 +      pipeclass->hasMultipleBundles() ? "true" : "false",
   1.910 +      pipeclass->forceSerialization() ? "true" : "false",
   1.911 +      pipeclass->mayHaveNoCode() ? "true" : "false" );
   1.912 +    if (paramcount > 0) {
   1.913 +      fprintf(fp_cpp, "\n  (enum machPipelineStages * const) pipeline_reads_%03d,\n ",
   1.914 +        pipeline_reads_index+1);
   1.915 +    }
   1.916 +    else
   1.917 +      fprintf(fp_cpp, " NULL,");
   1.918 +    fprintf(fp_cpp, "  (enum machPipelineStages * const) pipeline_res_stages_%03d,\n",
   1.919 +      pipeline_res_stages_index+1);
   1.920 +    fprintf(fp_cpp, "  (uint * const) pipeline_res_cycles_%03d,\n",
   1.921 +      pipeline_res_cycles_index+1);
   1.922 +    fprintf(fp_cpp, "  Pipeline_Use(%s, (Pipeline_Use_Element *)",
   1.923 +      pipeline_res_args.name(pipeline_res_mask_index));
   1.924 +    if (strlen(pipeline_res_masks.name(pipeline_res_mask_index)) > 0)
   1.925 +      fprintf(fp_cpp, "&pipeline_res_mask_%03d[0]",
   1.926 +        pipeline_res_mask_index+1);
   1.927 +    else
   1.928 +      fprintf(fp_cpp, "NULL");
   1.929 +    fprintf(fp_cpp, "));\n");
   1.930 +  }
   1.931 +
   1.932 +  // Generate the Node::latency method if _pipeline defined
   1.933 +  fprintf(fp_cpp, "\n");
   1.934 +  fprintf(fp_cpp, "//------------------Inter-Instruction Latency--------------------------------\n");
   1.935 +  fprintf(fp_cpp, "uint Node::latency(uint i) {\n");
   1.936 +  if (_pipeline) {
   1.937 +#if 0
   1.938 +    fprintf(fp_cpp, "#ifndef PRODUCT\n");
   1.939 +    fprintf(fp_cpp, " if (TraceOptoOutput) {\n");
   1.940 +    fprintf(fp_cpp, "    tty->print(\"# %%4d->latency(%%d)\\n\", _idx, i);\n");
   1.941 +    fprintf(fp_cpp, " }\n");
   1.942 +    fprintf(fp_cpp, "#endif\n");
   1.943 +#endif
   1.944 +    fprintf(fp_cpp, "  uint j;\n");
   1.945 +    fprintf(fp_cpp, "  // verify in legal range for inputs\n");
   1.946 +    fprintf(fp_cpp, "  assert(i < len(), \"index not in range\");\n\n");
   1.947 +    fprintf(fp_cpp, "  // verify input is not null\n");
   1.948 +    fprintf(fp_cpp, "  Node *pred = in(i);\n");
   1.949 +    fprintf(fp_cpp, "  if (!pred)\n    return %d;\n\n",
   1.950 +      non_operand_latency);
   1.951 +    fprintf(fp_cpp, "  if (pred->is_Proj())\n    pred = pred->in(0);\n\n");
   1.952 +    fprintf(fp_cpp, "  // if either node does not have pipeline info, use default\n");
   1.953 +    fprintf(fp_cpp, "  const Pipeline *predpipe = pred->pipeline();\n");
   1.954 +    fprintf(fp_cpp, "  assert(predpipe, \"no predecessor pipeline info\");\n\n");
   1.955 +    fprintf(fp_cpp, "  if (predpipe->hasFixedLatency())\n    return predpipe->fixedLatency();\n\n");
   1.956 +    fprintf(fp_cpp, "  const Pipeline *currpipe = pipeline();\n");
   1.957 +    fprintf(fp_cpp, "  assert(currpipe, \"no pipeline info\");\n\n");
   1.958 +    fprintf(fp_cpp, "  if (!is_Mach())\n    return %d;\n\n",
   1.959 +      node_latency);
   1.960 +    fprintf(fp_cpp, "  const MachNode *m = as_Mach();\n");
   1.961 +    fprintf(fp_cpp, "  j = m->oper_input_base();\n");
   1.962 +    fprintf(fp_cpp, "  if (i < j)\n    return currpipe->functional_unit_latency(%d, predpipe);\n\n",
   1.963 +      non_operand_latency);
   1.964 +    fprintf(fp_cpp, "  // determine which operand this is in\n");
   1.965 +    fprintf(fp_cpp, "  uint n = m->num_opnds();\n");
   1.966 +    fprintf(fp_cpp, "  int delta = %d;\n\n",
   1.967 +      non_operand_latency);
   1.968 +    fprintf(fp_cpp, "  uint k;\n");
   1.969 +    fprintf(fp_cpp, "  for (k = 1; k < n; k++) {\n");
   1.970 +    fprintf(fp_cpp, "    j += m->_opnds[k]->num_edges();\n");
   1.971 +    fprintf(fp_cpp, "    if (i < j)\n");
   1.972 +    fprintf(fp_cpp, "      break;\n");
   1.973 +    fprintf(fp_cpp, "  }\n");
   1.974 +    fprintf(fp_cpp, "  if (k < n)\n");
   1.975 +    fprintf(fp_cpp, "    delta = currpipe->operand_latency(k,predpipe);\n\n");
   1.976 +    fprintf(fp_cpp, "  return currpipe->functional_unit_latency(delta, predpipe);\n");
   1.977 +  }
   1.978 +  else {
   1.979 +    fprintf(fp_cpp, "  // assert(false, \"pipeline functionality is not defined\");\n");
   1.980 +    fprintf(fp_cpp, "  return %d;\n",
   1.981 +      non_operand_latency);
   1.982 +  }
   1.983 +  fprintf(fp_cpp, "}\n\n");
   1.984 +
   1.985 +  // Output the list of nop nodes
   1.986 +  fprintf(fp_cpp, "// Descriptions for emitting different functional unit nops\n");
   1.987 +  const char *nop;
   1.988 +  int nopcnt = 0;
   1.989 +  for ( _pipeline->_noplist.reset(); (nop = _pipeline->_noplist.iter()) != NULL; nopcnt++ );
   1.990 +
   1.991 +  fprintf(fp_cpp, "void Bundle::initialize_nops(MachNode * nop_list[%d], Compile *C) {\n", nopcnt);
   1.992 +  int i = 0;
   1.993 +  for ( _pipeline->_noplist.reset(); (nop = _pipeline->_noplist.iter()) != NULL; i++ ) {
   1.994 +    fprintf(fp_cpp, "  nop_list[%d] = (MachNode *) new (C) %sNode();\n", i, nop);
   1.995 +  }
   1.996 +  fprintf(fp_cpp, "};\n\n");
   1.997 +  fprintf(fp_cpp, "#ifndef PRODUCT\n");
   1.998 +  fprintf(fp_cpp, "void Bundle::dump() const {\n");
   1.999 +  fprintf(fp_cpp, "  static const char * bundle_flags[] = {\n");
  1.1000 +  fprintf(fp_cpp, "    \"\",\n");
  1.1001 +  fprintf(fp_cpp, "    \"use nop delay\",\n");
  1.1002 +  fprintf(fp_cpp, "    \"use unconditional delay\",\n");
  1.1003 +  fprintf(fp_cpp, "    \"use conditional delay\",\n");
  1.1004 +  fprintf(fp_cpp, "    \"used in conditional delay\",\n");
  1.1005 +  fprintf(fp_cpp, "    \"used in unconditional delay\",\n");
  1.1006 +  fprintf(fp_cpp, "    \"used in all conditional delays\",\n");
  1.1007 +  fprintf(fp_cpp, "  };\n\n");
  1.1008 +
  1.1009 +  fprintf(fp_cpp, "  static const char *resource_names[%d] = {", _pipeline->_rescount);
  1.1010 +  for (i = 0; i < _pipeline->_rescount; i++)
  1.1011 +    fprintf(fp_cpp, " \"%s\"%c", _pipeline->_reslist.name(i), i < _pipeline->_rescount-1 ? ',' : ' ');
  1.1012 +  fprintf(fp_cpp, "};\n\n");
  1.1013 +
  1.1014 +  // See if the same string is in the table
  1.1015 +  fprintf(fp_cpp, "  bool needs_comma = false;\n\n");
  1.1016 +  fprintf(fp_cpp, "  if (_flags) {\n");
  1.1017 +  fprintf(fp_cpp, "    tty->print(\"%%s\", bundle_flags[_flags]);\n");
  1.1018 +  fprintf(fp_cpp, "    needs_comma = true;\n");
  1.1019 +  fprintf(fp_cpp, "  };\n");
  1.1020 +  fprintf(fp_cpp, "  if (instr_count()) {\n");
  1.1021 +  fprintf(fp_cpp, "    tty->print(\"%%s%%d instr%%s\", needs_comma ? \", \" : \"\", instr_count(), instr_count() != 1 ? \"s\" : \"\");\n");
  1.1022 +  fprintf(fp_cpp, "    needs_comma = true;\n");
  1.1023 +  fprintf(fp_cpp, "  };\n");
  1.1024 +  fprintf(fp_cpp, "  uint r = resources_used();\n");
  1.1025 +  fprintf(fp_cpp, "  if (r) {\n");
  1.1026 +  fprintf(fp_cpp, "    tty->print(\"%%sresource%%s:\", needs_comma ? \", \" : \"\", (r & (r-1)) != 0 ? \"s\" : \"\");\n");
  1.1027 +  fprintf(fp_cpp, "    for (uint i = 0; i < %d; i++)\n", _pipeline->_rescount);
  1.1028 +  fprintf(fp_cpp, "      if ((r & (1 << i)) != 0)\n");
  1.1029 +  fprintf(fp_cpp, "        tty->print(\" %%s\", resource_names[i]);\n");
  1.1030 +  fprintf(fp_cpp, "    needs_comma = true;\n");
  1.1031 +  fprintf(fp_cpp, "  };\n");
  1.1032 +  fprintf(fp_cpp, "  tty->print(\"\\n\");\n");
  1.1033 +  fprintf(fp_cpp, "}\n");
  1.1034 +  fprintf(fp_cpp, "#endif\n");
  1.1035 +}
  1.1036 +
  1.1037 +// ---------------------------------------------------------------------------
  1.1038 +//------------------------------Utilities to build Instruction Classes--------
  1.1039 +// ---------------------------------------------------------------------------
  1.1040 +
  1.1041 +static void defineOut_RegMask(FILE *fp, const char *node, const char *regMask) {
  1.1042 +  fprintf(fp,"const RegMask &%sNode::out_RegMask() const { return (%s); }\n",
  1.1043 +          node, regMask);
  1.1044 +}
  1.1045 +
  1.1046 +// Scan the peepmatch and output a test for each instruction
  1.1047 +static void check_peepmatch_instruction_tree(FILE *fp, PeepMatch *pmatch, PeepConstraint *pconstraint) {
  1.1048 +  intptr_t   parent        = -1;
  1.1049 +  intptr_t   inst_position = 0;
  1.1050 +  const char *inst_name    = NULL;
  1.1051 +  intptr_t   input         = 0;
  1.1052 +  fprintf(fp, "      // Check instruction sub-tree\n");
  1.1053 +  pmatch->reset();
  1.1054 +  for( pmatch->next_instruction( parent, inst_position, inst_name, input );
  1.1055 +       inst_name != NULL;
  1.1056 +       pmatch->next_instruction( parent, inst_position, inst_name, input ) ) {
  1.1057 +    // If this is not a placeholder
  1.1058 +    if( ! pmatch->is_placeholder() ) {
  1.1059 +      // Define temporaries 'inst#', based on parent and parent's input index
  1.1060 +      if( parent != -1 ) {                // root was initialized
  1.1061 +        fprintf(fp, "  inst%ld = inst%ld->in(%ld);\n",
  1.1062 +                inst_position, parent, input);
  1.1063 +      }
  1.1064 +
  1.1065 +      // When not the root
  1.1066 +      // Test we have the correct instruction by comparing the rule
  1.1067 +      if( parent != -1 ) {
  1.1068 +        fprintf(fp, "  matches = matches &&  ( inst%ld->rule() == %s_rule );",
  1.1069 +                inst_position, inst_name);
  1.1070 +      }
  1.1071 +    } else {
  1.1072 +      // Check that user did not try to constrain a placeholder
  1.1073 +      assert( ! pconstraint->constrains_instruction(inst_position),
  1.1074 +              "fatal(): Can not constrain a placeholder instruction");
  1.1075 +    }
  1.1076 +  }
  1.1077 +}
  1.1078 +
  1.1079 +static void print_block_index(FILE *fp, intptr_t inst_position) {
  1.1080 +  assert( inst_position >= 0, "Instruction number less than zero");
  1.1081 +  fprintf(fp, "block_index");
  1.1082 +  if( inst_position != 0 ) {
  1.1083 +    fprintf(fp, " - %ld", inst_position);
  1.1084 +  }
  1.1085 +}
  1.1086 +
  1.1087 +// Scan the peepmatch and output a test for each instruction
  1.1088 +static void check_peepmatch_instruction_sequence(FILE *fp, PeepMatch *pmatch, PeepConstraint *pconstraint) {
  1.1089 +  intptr_t   parent        = -1;
  1.1090 +  intptr_t   inst_position = 0;
  1.1091 +  const char *inst_name    = NULL;
  1.1092 +  intptr_t   input         = 0;
  1.1093 +  fprintf(fp, "  // Check instruction sub-tree\n");
  1.1094 +  pmatch->reset();
  1.1095 +  for( pmatch->next_instruction( parent, inst_position, inst_name, input );
  1.1096 +       inst_name != NULL;
  1.1097 +       pmatch->next_instruction( parent, inst_position, inst_name, input ) ) {
  1.1098 +    // If this is not a placeholder
  1.1099 +    if( ! pmatch->is_placeholder() ) {
  1.1100 +      // Define temporaries 'inst#', based on parent and parent's input index
  1.1101 +      if( parent != -1 ) {                // root was initialized
  1.1102 +        fprintf(fp, "  // Identify previous instruction if inside this block\n");
  1.1103 +        fprintf(fp, "  if( ");
  1.1104 +        print_block_index(fp, inst_position);
  1.1105 +        fprintf(fp, " > 0 ) {\n    Node *n = block->_nodes.at(");
  1.1106 +        print_block_index(fp, inst_position);
  1.1107 +        fprintf(fp, ");\n    inst%ld = (n->is_Mach()) ? ", inst_position);
  1.1108 +        fprintf(fp, "n->as_Mach() : NULL;\n  }\n");
  1.1109 +      }
  1.1110 +
  1.1111 +      // When not the root
  1.1112 +      // Test we have the correct instruction by comparing the rule.
  1.1113 +      if( parent != -1 ) {
  1.1114 +        fprintf(fp, "  matches = matches && (inst%ld != NULL) && (inst%ld->rule() == %s_rule);\n",
  1.1115 +                inst_position, inst_position, inst_name);
  1.1116 +      }
  1.1117 +    } else {
  1.1118 +      // Check that user did not try to constrain a placeholder
  1.1119 +      assert( ! pconstraint->constrains_instruction(inst_position),
  1.1120 +              "fatal(): Can not constrain a placeholder instruction");
  1.1121 +    }
  1.1122 +  }
  1.1123 +}
  1.1124 +
  1.1125 +// Build mapping for register indices, num_edges to input
  1.1126 +static void build_instruction_index_mapping( FILE *fp, FormDict &globals, PeepMatch *pmatch ) {
  1.1127 +  intptr_t   parent        = -1;
  1.1128 +  intptr_t   inst_position = 0;
  1.1129 +  const char *inst_name    = NULL;
  1.1130 +  intptr_t   input         = 0;
  1.1131 +  fprintf(fp, "      // Build map to register info\n");
  1.1132 +  pmatch->reset();
  1.1133 +  for( pmatch->next_instruction( parent, inst_position, inst_name, input );
  1.1134 +       inst_name != NULL;
  1.1135 +       pmatch->next_instruction( parent, inst_position, inst_name, input ) ) {
  1.1136 +    // If this is not a placeholder
  1.1137 +    if( ! pmatch->is_placeholder() ) {
  1.1138 +      // Define temporaries 'inst#', based on self's inst_position
  1.1139 +      InstructForm *inst = globals[inst_name]->is_instruction();
  1.1140 +      if( inst != NULL ) {
  1.1141 +        char inst_prefix[]  = "instXXXX_";
  1.1142 +        sprintf(inst_prefix, "inst%ld_",   inst_position);
  1.1143 +        char receiver[]     = "instXXXX->";
  1.1144 +        sprintf(receiver,    "inst%ld->", inst_position);
  1.1145 +        inst->index_temps( fp, globals, inst_prefix, receiver );
  1.1146 +      }
  1.1147 +    }
  1.1148 +  }
  1.1149 +}
  1.1150 +
  1.1151 +// Generate tests for the constraints
  1.1152 +static void check_peepconstraints(FILE *fp, FormDict &globals, PeepMatch *pmatch, PeepConstraint *pconstraint) {
  1.1153 +  fprintf(fp, "\n");
  1.1154 +  fprintf(fp, "      // Check constraints on sub-tree-leaves\n");
  1.1155 +
  1.1156 +  // Build mapping from num_edges to local variables
  1.1157 +  build_instruction_index_mapping( fp, globals, pmatch );
  1.1158 +
  1.1159 +  // Build constraint tests
  1.1160 +  if( pconstraint != NULL ) {
  1.1161 +    fprintf(fp, "      matches = matches &&");
  1.1162 +    bool   first_constraint = true;
  1.1163 +    while( pconstraint != NULL ) {
  1.1164 +      // indentation and connecting '&&'
  1.1165 +      const char *indentation = "      ";
  1.1166 +      fprintf(fp, "\n%s%s", indentation, (!first_constraint ? "&& " : "  "));
  1.1167 +
  1.1168 +      // Only have '==' relation implemented
  1.1169 +      if( strcmp(pconstraint->_relation,"==") != 0 ) {
  1.1170 +        assert( false, "Unimplemented()" );
  1.1171 +      }
  1.1172 +
  1.1173 +      // LEFT
  1.1174 +      intptr_t left_index  = pconstraint->_left_inst;
  1.1175 +      const char *left_op  = pconstraint->_left_op;
  1.1176 +      // Access info on the instructions whose operands are compared
  1.1177 +      InstructForm *inst_left = globals[pmatch->instruction_name(left_index)]->is_instruction();
  1.1178 +      assert( inst_left, "Parser should guaranty this is an instruction");
  1.1179 +      int left_op_base  = inst_left->oper_input_base(globals);
  1.1180 +      // Access info on the operands being compared
  1.1181 +      int left_op_index  = inst_left->operand_position(left_op, Component::USE);
  1.1182 +      if( left_op_index == -1 ) {
  1.1183 +        left_op_index = inst_left->operand_position(left_op, Component::DEF);
  1.1184 +        if( left_op_index == -1 ) {
  1.1185 +          left_op_index = inst_left->operand_position(left_op, Component::USE_DEF);
  1.1186 +        }
  1.1187 +      }
  1.1188 +      assert( left_op_index  != NameList::Not_in_list, "Did not find operand in instruction");
  1.1189 +      ComponentList components_left = inst_left->_components;
  1.1190 +      const char *left_comp_type = components_left.at(left_op_index)->_type;
  1.1191 +      OpClassForm *left_opclass = globals[left_comp_type]->is_opclass();
  1.1192 +      Form::InterfaceType left_interface_type = left_opclass->interface_type(globals);
  1.1193 +
  1.1194 +
  1.1195 +      // RIGHT
  1.1196 +      int right_op_index = -1;
  1.1197 +      intptr_t right_index = pconstraint->_right_inst;
  1.1198 +      const char *right_op = pconstraint->_right_op;
  1.1199 +      if( right_index != -1 ) { // Match operand
  1.1200 +        // Access info on the instructions whose operands are compared
  1.1201 +        InstructForm *inst_right = globals[pmatch->instruction_name(right_index)]->is_instruction();
  1.1202 +        assert( inst_right, "Parser should guaranty this is an instruction");
  1.1203 +        int right_op_base = inst_right->oper_input_base(globals);
  1.1204 +        // Access info on the operands being compared
  1.1205 +        right_op_index = inst_right->operand_position(right_op, Component::USE);
  1.1206 +        if( right_op_index == -1 ) {
  1.1207 +          right_op_index = inst_right->operand_position(right_op, Component::DEF);
  1.1208 +          if( right_op_index == -1 ) {
  1.1209 +            right_op_index = inst_right->operand_position(right_op, Component::USE_DEF);
  1.1210 +          }
  1.1211 +        }
  1.1212 +        assert( right_op_index != NameList::Not_in_list, "Did not find operand in instruction");
  1.1213 +        ComponentList components_right = inst_right->_components;
  1.1214 +        const char *right_comp_type = components_right.at(right_op_index)->_type;
  1.1215 +        OpClassForm *right_opclass = globals[right_comp_type]->is_opclass();
  1.1216 +        Form::InterfaceType right_interface_type = right_opclass->interface_type(globals);
  1.1217 +        assert( right_interface_type == left_interface_type, "Both must be same interface");
  1.1218 +
  1.1219 +      } else {                  // Else match register
  1.1220 +        // assert( false, "should be a register" );
  1.1221 +      }
  1.1222 +
  1.1223 +      //
  1.1224 +      // Check for equivalence
  1.1225 +      //
  1.1226 +      // fprintf(fp, "phase->eqv( ");
  1.1227 +      // fprintf(fp, "inst%d->in(%d+%d) /* %s */, inst%d->in(%d+%d) /* %s */",
  1.1228 +      //         left_index,  left_op_base,  left_op_index,  left_op,
  1.1229 +      //         right_index, right_op_base, right_op_index, right_op );
  1.1230 +      // fprintf(fp, ")");
  1.1231 +      //
  1.1232 +      switch( left_interface_type ) {
  1.1233 +      case Form::register_interface: {
  1.1234 +        // Check that they are allocated to the same register
  1.1235 +        // Need parameter for index position if not result operand
  1.1236 +        char left_reg_index[] = ",instXXXX_idxXXXX";
  1.1237 +        if( left_op_index != 0 ) {
  1.1238 +          assert( (left_index <= 9999) && (left_op_index <= 9999), "exceed string size");
  1.1239 +          // Must have index into operands
  1.1240 +          sprintf(left_reg_index,",inst%d_idx%d", left_index, left_op_index);
  1.1241 +        } else {
  1.1242 +          strcpy(left_reg_index, "");
  1.1243 +        }
  1.1244 +        fprintf(fp, "(inst%d->_opnds[%d]->reg(ra_,inst%d%s)  /* %d.%s */",
  1.1245 +                left_index,  left_op_index, left_index, left_reg_index, left_index, left_op );
  1.1246 +        fprintf(fp, " == ");
  1.1247 +
  1.1248 +        if( right_index != -1 ) {
  1.1249 +          char right_reg_index[18] = ",instXXXX_idxXXXX";
  1.1250 +          if( right_op_index != 0 ) {
  1.1251 +            assert( (right_index <= 9999) && (right_op_index <= 9999), "exceed string size");
  1.1252 +            // Must have index into operands
  1.1253 +            sprintf(right_reg_index,",inst%d_idx%d", right_index, right_op_index);
  1.1254 +          } else {
  1.1255 +            strcpy(right_reg_index, "");
  1.1256 +          }
  1.1257 +          fprintf(fp, "/* %d.%s */ inst%d->_opnds[%d]->reg(ra_,inst%d%s)",
  1.1258 +                  right_index, right_op, right_index, right_op_index, right_index, right_reg_index );
  1.1259 +        } else {
  1.1260 +          fprintf(fp, "%s_enc", right_op );
  1.1261 +        }
  1.1262 +        fprintf(fp,")");
  1.1263 +        break;
  1.1264 +      }
  1.1265 +      case Form::constant_interface: {
  1.1266 +        // Compare the '->constant()' values
  1.1267 +        fprintf(fp, "(inst%d->_opnds[%d]->constant()  /* %d.%s */",
  1.1268 +                left_index,  left_op_index,  left_index, left_op );
  1.1269 +        fprintf(fp, " == ");
  1.1270 +        fprintf(fp, "/* %d.%s */ inst%d->_opnds[%d]->constant())",
  1.1271 +                right_index, right_op, right_index, right_op_index );
  1.1272 +        break;
  1.1273 +      }
  1.1274 +      case Form::memory_interface: {
  1.1275 +        // Compare 'base', 'index', 'scale', and 'disp'
  1.1276 +        // base
  1.1277 +        fprintf(fp, "( \n");
  1.1278 +        fprintf(fp, "  (inst%d->_opnds[%d]->base(ra_,inst%d,inst%d_idx%d)  /* %d.%s$$base */",
  1.1279 +          left_index, left_op_index, left_index, left_index, left_op_index, left_index, left_op );
  1.1280 +        fprintf(fp, " == ");
  1.1281 +        fprintf(fp, "/* %d.%s$$base */ inst%d->_opnds[%d]->base(ra_,inst%d,inst%d_idx%d)) &&\n",
  1.1282 +                right_index, right_op, right_index, right_op_index, right_index, right_index, right_op_index );
  1.1283 +        // index
  1.1284 +        fprintf(fp, "  (inst%d->_opnds[%d]->index(ra_,inst%d,inst%d_idx%d)  /* %d.%s$$index */",
  1.1285 +                left_index, left_op_index, left_index, left_index, left_op_index, left_index, left_op );
  1.1286 +        fprintf(fp, " == ");
  1.1287 +        fprintf(fp, "/* %d.%s$$index */ inst%d->_opnds[%d]->index(ra_,inst%d,inst%d_idx%d)) &&\n",
  1.1288 +                right_index, right_op, right_index, right_op_index, right_index, right_index, right_op_index );
  1.1289 +        // scale
  1.1290 +        fprintf(fp, "  (inst%d->_opnds[%d]->scale()  /* %d.%s$$scale */",
  1.1291 +                left_index,  left_op_index,  left_index, left_op );
  1.1292 +        fprintf(fp, " == ");
  1.1293 +        fprintf(fp, "/* %d.%s$$scale */ inst%d->_opnds[%d]->scale()) &&\n",
  1.1294 +                right_index, right_op, right_index, right_op_index );
  1.1295 +        // disp
  1.1296 +        fprintf(fp, "  (inst%d->_opnds[%d]->disp(ra_,inst%d,inst%d_idx%d)  /* %d.%s$$disp */",
  1.1297 +                left_index, left_op_index, left_index, left_index, left_op_index, left_index, left_op );
  1.1298 +        fprintf(fp, " == ");
  1.1299 +        fprintf(fp, "/* %d.%s$$disp */ inst%d->_opnds[%d]->disp(ra_,inst%d,inst%d_idx%d))\n",
  1.1300 +                right_index, right_op, right_index, right_op_index, right_index, right_index, right_op_index );
  1.1301 +        fprintf(fp, ") \n");
  1.1302 +        break;
  1.1303 +      }
  1.1304 +      case Form::conditional_interface: {
  1.1305 +        // Compare the condition code being tested
  1.1306 +        assert( false, "Unimplemented()" );
  1.1307 +        break;
  1.1308 +      }
  1.1309 +      default: {
  1.1310 +        assert( false, "ShouldNotReachHere()" );
  1.1311 +        break;
  1.1312 +      }
  1.1313 +      }
  1.1314 +
  1.1315 +      // Advance to next constraint
  1.1316 +      pconstraint = pconstraint->next();
  1.1317 +      first_constraint = false;
  1.1318 +    }
  1.1319 +
  1.1320 +    fprintf(fp, ";\n");
  1.1321 +  }
  1.1322 +}
  1.1323 +
  1.1324 +// // EXPERIMENTAL -- TEMPORARY code
  1.1325 +// static Form::DataType get_operand_type(FormDict &globals, InstructForm *instr, const char *op_name ) {
  1.1326 +//   int op_index = instr->operand_position(op_name, Component::USE);
  1.1327 +//   if( op_index == -1 ) {
  1.1328 +//     op_index = instr->operand_position(op_name, Component::DEF);
  1.1329 +//     if( op_index == -1 ) {
  1.1330 +//       op_index = instr->operand_position(op_name, Component::USE_DEF);
  1.1331 +//     }
  1.1332 +//   }
  1.1333 +//   assert( op_index != NameList::Not_in_list, "Did not find operand in instruction");
  1.1334 +//
  1.1335 +//   ComponentList components_right = instr->_components;
  1.1336 +//   char *right_comp_type = components_right.at(op_index)->_type;
  1.1337 +//   OpClassForm *right_opclass = globals[right_comp_type]->is_opclass();
  1.1338 +//   Form::InterfaceType  right_interface_type = right_opclass->interface_type(globals);
  1.1339 +//
  1.1340 +//   return;
  1.1341 +// }
  1.1342 +
  1.1343 +// Construct the new sub-tree
  1.1344 +static void generate_peepreplace( FILE *fp, FormDict &globals, PeepMatch *pmatch, PeepConstraint *pconstraint, PeepReplace *preplace, int max_position ) {
  1.1345 +  fprintf(fp, "      // IF instructions and constraints matched\n");
  1.1346 +  fprintf(fp, "      if( matches ) {\n");
  1.1347 +  fprintf(fp, "        // generate the new sub-tree\n");
  1.1348 +  fprintf(fp, "        assert( true, \"Debug stopping point\");\n");
  1.1349 +  if( preplace != NULL ) {
  1.1350 +    // Get the root of the new sub-tree
  1.1351 +    const char *root_inst = NULL;
  1.1352 +    preplace->next_instruction(root_inst);
  1.1353 +    InstructForm *root_form = globals[root_inst]->is_instruction();
  1.1354 +    assert( root_form != NULL, "Replacement instruction was not previously defined");
  1.1355 +    fprintf(fp, "        %sNode *root = new (C) %sNode();\n", root_inst, root_inst);
  1.1356 +
  1.1357 +    intptr_t    inst_num;
  1.1358 +    const char *op_name;
  1.1359 +    int         opnds_index = 0;            // define result operand
  1.1360 +    // Then install the use-operands for the new sub-tree
  1.1361 +    // preplace->reset();             // reset breaks iteration
  1.1362 +    for( preplace->next_operand( inst_num, op_name );
  1.1363 +         op_name != NULL;
  1.1364 +         preplace->next_operand( inst_num, op_name ) ) {
  1.1365 +      InstructForm *inst_form;
  1.1366 +      inst_form  = globals[pmatch->instruction_name(inst_num)]->is_instruction();
  1.1367 +      assert( inst_form, "Parser should guaranty this is an instruction");
  1.1368 +      int op_base     = inst_form->oper_input_base(globals);
  1.1369 +      int inst_op_num = inst_form->operand_position(op_name, Component::USE);
  1.1370 +      if( inst_op_num == NameList::Not_in_list )
  1.1371 +        inst_op_num = inst_form->operand_position(op_name, Component::USE_DEF);
  1.1372 +      assert( inst_op_num != NameList::Not_in_list, "Did not find operand as USE");
  1.1373 +      // find the name of the OperandForm from the local name
  1.1374 +      const Form *form   = inst_form->_localNames[op_name];
  1.1375 +      OperandForm  *op_form = form->is_operand();
  1.1376 +      if( opnds_index == 0 ) {
  1.1377 +        // Initial setup of new instruction
  1.1378 +        fprintf(fp, "        // ----- Initial setup -----\n");
  1.1379 +        //
  1.1380 +        // Add control edge for this node
  1.1381 +        fprintf(fp, "        root->add_req(_in[0]);                // control edge\n");
  1.1382 +        // Add unmatched edges from root of match tree
  1.1383 +        int op_base = root_form->oper_input_base(globals);
  1.1384 +        for( int unmatched_edge = 1; unmatched_edge < op_base; ++unmatched_edge ) {
  1.1385 +          fprintf(fp, "        root->add_req(inst%ld->in(%d));        // unmatched ideal edge\n",
  1.1386 +                                          inst_num, unmatched_edge);
  1.1387 +        }
  1.1388 +        // If new instruction captures bottom type
  1.1389 +        if( root_form->captures_bottom_type() ) {
  1.1390 +          // Get bottom type from instruction whose result we are replacing
  1.1391 +          fprintf(fp, "        root->_bottom_type = inst%ld->bottom_type();\n", inst_num);
  1.1392 +        }
  1.1393 +        // Define result register and result operand
  1.1394 +        fprintf(fp, "        ra_->add_reference(root, inst%ld);\n", inst_num);
  1.1395 +        fprintf(fp, "        ra_->set_oop (root, ra_->is_oop(inst%ld));\n", inst_num);
  1.1396 +        fprintf(fp, "        ra_->set_pair(root->_idx, ra_->get_reg_second(inst%ld), ra_->get_reg_first(inst%ld));\n", inst_num, inst_num);
  1.1397 +        fprintf(fp, "        root->_opnds[0] = inst%ld->_opnds[0]->clone(C); // result\n", inst_num);
  1.1398 +        fprintf(fp, "        // ----- Done with initial setup -----\n");
  1.1399 +      } else {
  1.1400 +        if( (op_form == NULL) || (op_form->is_base_constant(globals) == Form::none) ) {
  1.1401 +          // Do not have ideal edges for constants after matching
  1.1402 +          fprintf(fp, "        for( unsigned x%d = inst%ld_idx%d; x%d < inst%ld_idx%d; x%d++ )\n",
  1.1403 +                  inst_op_num, inst_num, inst_op_num,
  1.1404 +                  inst_op_num, inst_num, inst_op_num+1, inst_op_num );
  1.1405 +          fprintf(fp, "          root->add_req( inst%ld->in(x%d) );\n",
  1.1406 +                  inst_num, inst_op_num );
  1.1407 +        } else {
  1.1408 +          fprintf(fp, "        // no ideal edge for constants after matching\n");
  1.1409 +        }
  1.1410 +        fprintf(fp, "        root->_opnds[%d] = inst%ld->_opnds[%d]->clone(C);\n",
  1.1411 +                opnds_index, inst_num, inst_op_num );
  1.1412 +      }
  1.1413 +      ++opnds_index;
  1.1414 +    }
  1.1415 +  }else {
  1.1416 +    // Replacing subtree with empty-tree
  1.1417 +    assert( false, "ShouldNotReachHere();");
  1.1418 +  }
  1.1419 +
  1.1420 +  // Return the new sub-tree
  1.1421 +  fprintf(fp, "        deleted = %d;\n", max_position+1 /*zero to one based*/);
  1.1422 +  fprintf(fp, "        return root;  // return new root;\n");
  1.1423 +  fprintf(fp, "      }\n");
  1.1424 +}
  1.1425 +
  1.1426 +
  1.1427 +// Define the Peephole method for an instruction node
  1.1428 +void ArchDesc::definePeephole(FILE *fp, InstructForm *node) {
  1.1429 +  // Generate Peephole function header
  1.1430 +  fprintf(fp, "MachNode *%sNode::peephole( Block *block, int block_index, PhaseRegAlloc *ra_, int &deleted, Compile* C ) {\n", node->_ident);
  1.1431 +  fprintf(fp, "  bool  matches = true;\n");
  1.1432 +
  1.1433 +  // Identify the maximum instruction position,
  1.1434 +  // generate temporaries that hold current instruction
  1.1435 +  //
  1.1436 +  //   MachNode  *inst0 = NULL;
  1.1437 +  //   ...
  1.1438 +  //   MachNode  *instMAX = NULL;
  1.1439 +  //
  1.1440 +  int max_position = 0;
  1.1441 +  Peephole *peep;
  1.1442 +  for( peep = node->peepholes(); peep != NULL; peep = peep->next() ) {
  1.1443 +    PeepMatch *pmatch = peep->match();
  1.1444 +    assert( pmatch != NULL, "fatal(), missing peepmatch rule");
  1.1445 +    if( max_position < pmatch->max_position() )  max_position = pmatch->max_position();
  1.1446 +  }
  1.1447 +  for( int i = 0; i <= max_position; ++i ) {
  1.1448 +    if( i == 0 ) {
  1.1449 +      fprintf(fp, "  MachNode *inst0 = this;\n", i);
  1.1450 +    } else {
  1.1451 +      fprintf(fp, "  MachNode *inst%d = NULL;\n", i);
  1.1452 +    }
  1.1453 +  }
  1.1454 +
  1.1455 +  // For each peephole rule in architecture description
  1.1456 +  //   Construct a test for the desired instruction sub-tree
  1.1457 +  //   then check the constraints
  1.1458 +  //   If these match, Generate the new subtree
  1.1459 +  for( peep = node->peepholes(); peep != NULL; peep = peep->next() ) {
  1.1460 +    int         peephole_number = peep->peephole_number();
  1.1461 +    PeepMatch      *pmatch      = peep->match();
  1.1462 +    PeepConstraint *pconstraint = peep->constraints();
  1.1463 +    PeepReplace    *preplace    = peep->replacement();
  1.1464 +
  1.1465 +    // Root of this peephole is the current MachNode
  1.1466 +    assert( true, // %%name?%% strcmp( node->_ident, pmatch->name(0) ) == 0,
  1.1467 +            "root of PeepMatch does not match instruction");
  1.1468 +
  1.1469 +    // Make each peephole rule individually selectable
  1.1470 +    fprintf(fp, "  if( (OptoPeepholeAt == -1) || (OptoPeepholeAt==%d) ) {\n", peephole_number);
  1.1471 +    fprintf(fp, "    matches = true;\n");
  1.1472 +    // Scan the peepmatch and output a test for each instruction
  1.1473 +    check_peepmatch_instruction_sequence( fp, pmatch, pconstraint );
  1.1474 +
  1.1475 +    // Check constraints and build replacement inside scope
  1.1476 +    fprintf(fp, "    // If instruction subtree matches\n");
  1.1477 +    fprintf(fp, "    if( matches ) {\n");
  1.1478 +
  1.1479 +    // Generate tests for the constraints
  1.1480 +    check_peepconstraints( fp, _globalNames, pmatch, pconstraint );
  1.1481 +
  1.1482 +    // Construct the new sub-tree
  1.1483 +    generate_peepreplace( fp, _globalNames, pmatch, pconstraint, preplace, max_position );
  1.1484 +
  1.1485 +    // End of scope for this peephole's constraints
  1.1486 +    fprintf(fp, "    }\n");
  1.1487 +    // Closing brace '}' to make each peephole rule individually selectable
  1.1488 +    fprintf(fp, "  } // end of peephole rule #%d\n", peephole_number);
  1.1489 +    fprintf(fp, "\n");
  1.1490 +  }
  1.1491 +
  1.1492 +  fprintf(fp, "  return NULL;  // No peephole rules matched\n");
  1.1493 +  fprintf(fp, "}\n");
  1.1494 +  fprintf(fp, "\n");
  1.1495 +}
  1.1496 +
  1.1497 +// Define the Expand method for an instruction node
  1.1498 +void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
  1.1499 +  unsigned      cnt  = 0;          // Count nodes we have expand into
  1.1500 +  unsigned      i;
  1.1501 +
  1.1502 +  // Generate Expand function header
  1.1503 +  fprintf(fp,"MachNode *%sNode::Expand(State *state, Node_List &proj_list) {\n", node->_ident);
  1.1504 +  fprintf(fp,"Compile* C = Compile::current();\n");
  1.1505 +  // Generate expand code
  1.1506 +  if( node->expands() ) {
  1.1507 +    const char   *opid;
  1.1508 +    int           new_pos, exp_pos;
  1.1509 +    const char   *new_id   = NULL;
  1.1510 +    const Form   *frm      = NULL;
  1.1511 +    InstructForm *new_inst = NULL;
  1.1512 +    OperandForm  *new_oper = NULL;
  1.1513 +    unsigned      numo     = node->num_opnds() +
  1.1514 +                                node->_exprule->_newopers.count();
  1.1515 +
  1.1516 +    // If necessary, generate any operands created in expand rule
  1.1517 +    if (node->_exprule->_newopers.count()) {
  1.1518 +      for(node->_exprule->_newopers.reset();
  1.1519 +          (new_id = node->_exprule->_newopers.iter()) != NULL; cnt++) {
  1.1520 +        frm = node->_localNames[new_id];
  1.1521 +        assert(frm, "Invalid entry in new operands list of expand rule");
  1.1522 +        new_oper = frm->is_operand();
  1.1523 +        char *tmp = (char *)node->_exprule->_newopconst[new_id];
  1.1524 +        if (tmp == NULL) {
  1.1525 +          fprintf(fp,"  MachOper *op%d = new (C) %sOper();\n",
  1.1526 +                  cnt, new_oper->_ident);
  1.1527 +        }
  1.1528 +        else {
  1.1529 +          fprintf(fp,"  MachOper *op%d = new (C) %sOper(%s);\n",
  1.1530 +                  cnt, new_oper->_ident, tmp);
  1.1531 +        }
  1.1532 +      }
  1.1533 +    }
  1.1534 +    cnt = 0;
  1.1535 +    // Generate the temps to use for DAG building
  1.1536 +    for(i = 0; i < numo; i++) {
  1.1537 +      if (i < node->num_opnds()) {
  1.1538 +        fprintf(fp,"  MachNode *tmp%d = this;\n", i);
  1.1539 +      }
  1.1540 +      else {
  1.1541 +        fprintf(fp,"  MachNode *tmp%d = NULL;\n", i);
  1.1542 +      }
  1.1543 +    }
  1.1544 +    // Build mapping from num_edges to local variables
  1.1545 +    fprintf(fp,"  unsigned num0 = 0;\n");
  1.1546 +    for( i = 1; i < node->num_opnds(); i++ ) {
  1.1547 +      fprintf(fp,"  unsigned num%d = opnd_array(%d)->num_edges();\n",i,i);
  1.1548 +    }
  1.1549 +
  1.1550 +    // Build a mapping from operand index to input edges
  1.1551 +    fprintf(fp,"  unsigned idx0 = oper_input_base();\n");
  1.1552 +    for( i = 0; i < node->num_opnds(); i++ ) {
  1.1553 +      fprintf(fp,"  unsigned idx%d = idx%d + num%d;\n",
  1.1554 +              i+1,i,i);
  1.1555 +    }
  1.1556 +
  1.1557 +    // Declare variable to hold root of expansion
  1.1558 +    fprintf(fp,"  MachNode *result = NULL;\n");
  1.1559 +
  1.1560 +    // Iterate over the instructions 'node' expands into
  1.1561 +    ExpandRule  *expand       = node->_exprule;
  1.1562 +    NameAndList *expand_instr = NULL;
  1.1563 +    for(expand->reset_instructions();
  1.1564 +        (expand_instr = expand->iter_instructions()) != NULL; cnt++) {
  1.1565 +      new_id = expand_instr->name();
  1.1566 +
  1.1567 +      InstructForm* expand_instruction = (InstructForm*)globalAD->globalNames()[new_id];
  1.1568 +      if (expand_instruction->has_temps()) {
  1.1569 +        globalAD->syntax_err(node->_linenum, "In %s: expand rules using instructs with TEMPs aren't supported: %s",
  1.1570 +                             node->_ident, new_id);
  1.1571 +      }
  1.1572 +
  1.1573 +      // Build the node for the instruction
  1.1574 +      fprintf(fp,"\n  %sNode *n%d = new (C) %sNode();\n", new_id, cnt, new_id);
  1.1575 +      // Add control edge for this node
  1.1576 +      fprintf(fp,"  n%d->add_req(_in[0]);\n", cnt);
  1.1577 +      // Build the operand for the value this node defines.
  1.1578 +      Form *form = (Form*)_globalNames[new_id];
  1.1579 +      assert( form, "'new_id' must be a defined form name");
  1.1580 +      // Grab the InstructForm for the new instruction
  1.1581 +      new_inst = form->is_instruction();
  1.1582 +      assert( new_inst, "'new_id' must be an instruction name");
  1.1583 +      if( node->is_ideal_if() && new_inst->is_ideal_if() ) {
  1.1584 +        fprintf(fp, "  ((MachIfNode*)n%d)->_prob = _prob;\n",cnt);
  1.1585 +        fprintf(fp, "  ((MachIfNode*)n%d)->_fcnt = _fcnt;\n",cnt);
  1.1586 +      }
  1.1587 +
  1.1588 +      if( node->is_ideal_fastlock() && new_inst->is_ideal_fastlock() ) {
  1.1589 +        fprintf(fp, "  ((MachFastLockNode*)n%d)->_counters = _counters;\n",cnt);
  1.1590 +      }
  1.1591 +
  1.1592 +      const char *resultOper = new_inst->reduce_result();
  1.1593 +      fprintf(fp,"  n%d->set_opnd_array(0, state->MachOperGenerator( %s, C ));\n",
  1.1594 +              cnt, machOperEnum(resultOper));
  1.1595 +
  1.1596 +      // get the formal operand NameList
  1.1597 +      NameList *formal_lst = &new_inst->_parameters;
  1.1598 +      formal_lst->reset();
  1.1599 +
  1.1600 +      // Handle any memory operand
  1.1601 +      int memory_operand = new_inst->memory_operand(_globalNames);
  1.1602 +      if( memory_operand != InstructForm::NO_MEMORY_OPERAND ) {
  1.1603 +        int node_mem_op = node->memory_operand(_globalNames);
  1.1604 +        assert( node_mem_op != InstructForm::NO_MEMORY_OPERAND,
  1.1605 +                "expand rule member needs memory but top-level inst doesn't have any" );
  1.1606 +        // Copy memory edge
  1.1607 +        fprintf(fp,"  n%d->add_req(_in[1]);\t// Add memory edge\n", cnt);
  1.1608 +      }
  1.1609 +
  1.1610 +      // Iterate over the new instruction's operands
  1.1611 +      for( expand_instr->reset(); (opid = expand_instr->iter()) != NULL; ) {
  1.1612 +        // Use 'parameter' at current position in list of new instruction's formals
  1.1613 +        // instead of 'opid' when looking up info internal to new_inst
  1.1614 +        const char *parameter = formal_lst->iter();
  1.1615 +        // Check for an operand which is created in the expand rule
  1.1616 +        if ((exp_pos = node->_exprule->_newopers.index(opid)) != -1) {
  1.1617 +          new_pos = new_inst->operand_position(parameter,Component::USE);
  1.1618 +          exp_pos += node->num_opnds();
  1.1619 +          // If there is no use of the created operand, just skip it
  1.1620 +          if (new_pos != -1) {
  1.1621 +            //Copy the operand from the original made above
  1.1622 +            fprintf(fp,"  n%d->set_opnd_array(%d, op%d->clone(C)); // %s\n",
  1.1623 +                    cnt, new_pos, exp_pos-node->num_opnds(), opid);
  1.1624 +            // Check for who defines this operand & add edge if needed
  1.1625 +            fprintf(fp,"  if(tmp%d != NULL)\n", exp_pos);
  1.1626 +            fprintf(fp,"    n%d->add_req(tmp%d);\n", cnt, exp_pos);
  1.1627 +          }
  1.1628 +        }
  1.1629 +        else {
  1.1630 +          // Use operand name to get an index into instruction component list
  1.1631 +          // ins = (InstructForm *) _globalNames[new_id];
  1.1632 +          exp_pos = node->operand_position_format(opid);
  1.1633 +          assert(exp_pos != -1, "Bad expand rule");
  1.1634 +
  1.1635 +          new_pos = new_inst->operand_position(parameter,Component::USE);
  1.1636 +          if (new_pos != -1) {
  1.1637 +            // Copy the operand from the ExpandNode to the new node
  1.1638 +            fprintf(fp,"  n%d->set_opnd_array(%d, opnd_array(%d)->clone(C)); // %s\n",
  1.1639 +                    cnt, new_pos, exp_pos, opid);
  1.1640 +            // For each operand add appropriate input edges by looking at tmp's
  1.1641 +            fprintf(fp,"  if(tmp%d == this) {\n", exp_pos);
  1.1642 +            // Grab corresponding edges from ExpandNode and insert them here
  1.1643 +            fprintf(fp,"    for(unsigned i = 0; i < num%d; i++) {\n", exp_pos);
  1.1644 +            fprintf(fp,"      n%d->add_req(_in[i + idx%d]);\n", cnt, exp_pos);
  1.1645 +            fprintf(fp,"    }\n");
  1.1646 +            fprintf(fp,"  }\n");
  1.1647 +            // This value is generated by one of the new instructions
  1.1648 +            fprintf(fp,"  else n%d->add_req(tmp%d);\n", cnt, exp_pos);
  1.1649 +          }
  1.1650 +        }
  1.1651 +
  1.1652 +        // Update the DAG tmp's for values defined by this instruction
  1.1653 +        int new_def_pos = new_inst->operand_position(parameter,Component::DEF);
  1.1654 +        Effect *eform = (Effect *)new_inst->_effects[parameter];
  1.1655 +        // If this operand is a definition in either an effects rule
  1.1656 +        // or a match rule
  1.1657 +        if((eform) && (is_def(eform->_use_def))) {
  1.1658 +          // Update the temp associated with this operand
  1.1659 +          fprintf(fp,"  tmp%d = n%d;\n", exp_pos, cnt);
  1.1660 +        }
  1.1661 +        else if( new_def_pos != -1 ) {
  1.1662 +          // Instruction defines a value but user did not declare it
  1.1663 +          // in the 'effect' clause
  1.1664 +          fprintf(fp,"  tmp%d = n%d;\n", exp_pos, cnt);
  1.1665 +        }
  1.1666 +      } // done iterating over a new instruction's operands
  1.1667 +
  1.1668 +      // Invoke Expand() for the newly created instruction.
  1.1669 +      fprintf(fp,"  result = n%d->Expand( state, proj_list );\n", cnt);
  1.1670 +      assert( !new_inst->expands(), "Do not have complete support for recursive expansion");
  1.1671 +    } // done iterating over new instructions
  1.1672 +    fprintf(fp,"\n");
  1.1673 +  } // done generating expand rule
  1.1674 +
  1.1675 +  else if( node->_matrule != NULL ) {
  1.1676 +    // Remove duplicated operands and inputs which use the same name.
  1.1677 +    // Seach through match operands for the same name usage.
  1.1678 +    uint cur_num_opnds = node->num_opnds();
  1.1679 +    if( cur_num_opnds > 1 && cur_num_opnds != node->num_unique_opnds() ) {
  1.1680 +      Component *comp = NULL;
  1.1681 +      // Build mapping from num_edges to local variables
  1.1682 +      fprintf(fp,"  unsigned num0 = 0;\n");
  1.1683 +      for( i = 1; i < cur_num_opnds; i++ ) {
  1.1684 +        fprintf(fp,"  unsigned num%d = opnd_array(%d)->num_edges();\n",i,i);
  1.1685 +      }
  1.1686 +      // Build a mapping from operand index to input edges
  1.1687 +      fprintf(fp,"  unsigned idx0 = oper_input_base();\n");
  1.1688 +      for( i = 0; i < cur_num_opnds; i++ ) {
  1.1689 +        fprintf(fp,"  unsigned idx%d = idx%d + num%d;\n",
  1.1690 +                i+1,i,i);
  1.1691 +      }
  1.1692 +
  1.1693 +      uint new_num_opnds = 1;
  1.1694 +      node->_components.reset();
  1.1695 +      // Skip first unique operands.
  1.1696 +      for( i = 1; i < cur_num_opnds; i++ ) {
  1.1697 +        comp = node->_components.iter();
  1.1698 +        if( (int)i != node->unique_opnds_idx(i) ) {
  1.1699 +          break;
  1.1700 +        }
  1.1701 +        new_num_opnds++;
  1.1702 +      }
  1.1703 +      // Replace not unique operands with next unique operands.
  1.1704 +      for( ; i < cur_num_opnds; i++ ) {
  1.1705 +        comp = node->_components.iter();
  1.1706 +        int j = node->unique_opnds_idx(i);
  1.1707 +        // unique_opnds_idx(i) is unique if unique_opnds_idx(j) is not unique.
  1.1708 +        if( j != node->unique_opnds_idx(j) ) {
  1.1709 +          fprintf(fp,"  set_opnd_array(%d, opnd_array(%d)->clone(C)); // %s\n",
  1.1710 +                  new_num_opnds, i, comp->_name);
  1.1711 +          // delete not unique edges here
  1.1712 +          fprintf(fp,"  for(unsigned i = 0; i < num%d; i++) {\n", i);
  1.1713 +          fprintf(fp,"    set_req(i + idx%d, _in[i + idx%d]);\n", new_num_opnds, i);
  1.1714 +          fprintf(fp,"  }\n");
  1.1715 +          fprintf(fp,"  num%d = num%d;\n", new_num_opnds, i);
  1.1716 +          fprintf(fp,"  idx%d = idx%d + num%d;\n", new_num_opnds+1, new_num_opnds, new_num_opnds);
  1.1717 +          new_num_opnds++;
  1.1718 +        }
  1.1719 +      }
  1.1720 +      // delete the rest of edges
  1.1721 +      fprintf(fp,"  for(int i = idx%d - 1; i >= (int)idx%d; i--) {\n", cur_num_opnds, new_num_opnds);
  1.1722 +      fprintf(fp,"    del_req(i);\n", i);
  1.1723 +      fprintf(fp,"  }\n");
  1.1724 +      fprintf(fp,"  _num_opnds = %d;\n", new_num_opnds);
  1.1725 +    }
  1.1726 +  }
  1.1727 +
  1.1728 +
  1.1729 +  // Generate projections for instruction's additional DEFs and KILLs
  1.1730 +  if( ! node->expands() && (node->needs_projections() || node->has_temps())) {
  1.1731 +    // Get string representing the MachNode that projections point at
  1.1732 +    const char *machNode = "this";
  1.1733 +    // Generate the projections
  1.1734 +    fprintf(fp,"  // Add projection edges for additional defs or kills\n");
  1.1735 +
  1.1736 +    // Examine each component to see if it is a DEF or KILL
  1.1737 +    node->_components.reset();
  1.1738 +    // Skip the first component, if already handled as (SET dst (...))
  1.1739 +    Component *comp = NULL;
  1.1740 +    // For kills, the choice of projection numbers is arbitrary
  1.1741 +    int proj_no = 1;
  1.1742 +    bool declared_def  = false;
  1.1743 +    bool declared_kill = false;
  1.1744 +
  1.1745 +    while( (comp = node->_components.iter()) != NULL ) {
  1.1746 +      // Lookup register class associated with operand type
  1.1747 +      Form        *form = (Form*)_globalNames[comp->_type];
  1.1748 +      assert( form, "component type must be a defined form");
  1.1749 +      OperandForm *op   = form->is_operand();
  1.1750 +
  1.1751 +      if (comp->is(Component::TEMP)) {
  1.1752 +        fprintf(fp, "  // TEMP %s\n", comp->_name);
  1.1753 +        if (!declared_def) {
  1.1754 +          // Define the variable "def" to hold new MachProjNodes
  1.1755 +          fprintf(fp, "  MachTempNode *def;\n");
  1.1756 +          declared_def = true;
  1.1757 +        }
  1.1758 +        if (op && op->_interface && op->_interface->is_RegInterface()) {
  1.1759 +          fprintf(fp,"  def = new (C) MachTempNode(state->MachOperGenerator( %s, C ));\n",
  1.1760 +                  machOperEnum(op->_ident));
  1.1761 +          fprintf(fp,"  add_req(def);\n");
  1.1762 +          int idx  = node->operand_position_format(comp->_name);
  1.1763 +          fprintf(fp,"  set_opnd_array(%d, state->MachOperGenerator( %s, C ));\n",
  1.1764 +                  idx, machOperEnum(op->_ident));
  1.1765 +        } else {
  1.1766 +          assert(false, "can't have temps which aren't registers");
  1.1767 +        }
  1.1768 +      } else if (comp->isa(Component::KILL)) {
  1.1769 +        fprintf(fp, "  // DEF/KILL %s\n", comp->_name);
  1.1770 +
  1.1771 +        if (!declared_kill) {
  1.1772 +          // Define the variable "kill" to hold new MachProjNodes
  1.1773 +          fprintf(fp, "  MachProjNode *kill;\n");
  1.1774 +          declared_kill = true;
  1.1775 +        }
  1.1776 +
  1.1777 +        assert( op, "Support additional KILLS for base operands");
  1.1778 +        const char *regmask    = reg_mask(*op);
  1.1779 +        const char *ideal_type = op->ideal_type(_globalNames, _register);
  1.1780 +
  1.1781 +        if (!op->is_bound_register()) {
  1.1782 +          syntax_err(node->_linenum, "In %s only bound registers can be killed: %s %s\n",
  1.1783 +                     node->_ident, comp->_type, comp->_name);
  1.1784 +        }
  1.1785 +
  1.1786 +        fprintf(fp,"  kill = ");
  1.1787 +        fprintf(fp,"new (C, 1) MachProjNode( %s, %d, (%s), Op_%s );\n",
  1.1788 +                machNode, proj_no++, regmask, ideal_type);
  1.1789 +        fprintf(fp,"  proj_list.push(kill);\n");
  1.1790 +      }
  1.1791 +    }
  1.1792 +  }
  1.1793 +
  1.1794 +  fprintf(fp,"\n");
  1.1795 +  if( node->expands() ) {
  1.1796 +    fprintf(fp,"  return result;\n",cnt-1);
  1.1797 +  } else {
  1.1798 +    fprintf(fp,"  return this;\n");
  1.1799 +  }
  1.1800 +  fprintf(fp,"}\n");
  1.1801 +  fprintf(fp,"\n");
  1.1802 +}
  1.1803 +
  1.1804 +
  1.1805 +//------------------------------Emit Routines----------------------------------
  1.1806 +// Special classes and routines for defining node emit routines which output
  1.1807 +// target specific instruction object encodings.
  1.1808 +// Define the ___Node::emit() routine
  1.1809 +//
  1.1810 +// (1) void  ___Node::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
  1.1811 +// (2)   // ...  encoding defined by user
  1.1812 +// (3)
  1.1813 +// (4) }
  1.1814 +//
  1.1815 +
  1.1816 +class DefineEmitState {
  1.1817 +private:
  1.1818 +  enum reloc_format { RELOC_NONE        = -1,
  1.1819 +                      RELOC_IMMEDIATE   =  0,
  1.1820 +                      RELOC_DISP        =  1,
  1.1821 +                      RELOC_CALL_DISP   =  2 };
  1.1822 +  enum literal_status{ LITERAL_NOT_SEEN  = 0,
  1.1823 +                       LITERAL_SEEN      = 1,
  1.1824 +                       LITERAL_ACCESSED  = 2,
  1.1825 +                       LITERAL_OUTPUT    = 3 };
  1.1826 +  // Temporaries that describe current operand
  1.1827 +  bool          _cleared;
  1.1828 +  OpClassForm  *_opclass;
  1.1829 +  OperandForm  *_operand;
  1.1830 +  int           _operand_idx;
  1.1831 +  const char   *_local_name;
  1.1832 +  const char   *_operand_name;
  1.1833 +  bool          _doing_disp;
  1.1834 +  bool          _doing_constant;
  1.1835 +  Form::DataType _constant_type;
  1.1836 +  DefineEmitState::literal_status _constant_status;
  1.1837 +  DefineEmitState::literal_status _reg_status;
  1.1838 +  bool          _doing_emit8;
  1.1839 +  bool          _doing_emit_d32;
  1.1840 +  bool          _doing_emit_d16;
  1.1841 +  bool          _doing_emit_hi;
  1.1842 +  bool          _doing_emit_lo;
  1.1843 +  bool          _may_reloc;
  1.1844 +  bool          _must_reloc;
  1.1845 +  reloc_format  _reloc_form;
  1.1846 +  const char *  _reloc_type;
  1.1847 +  bool          _processing_noninput;
  1.1848 +
  1.1849 +  NameList      _strings_to_emit;
  1.1850 +
  1.1851 +  // Stable state, set by constructor
  1.1852 +  ArchDesc     &_AD;
  1.1853 +  FILE         *_fp;
  1.1854 +  EncClass     &_encoding;
  1.1855 +  InsEncode    &_ins_encode;
  1.1856 +  InstructForm &_inst;
  1.1857 +
  1.1858 +public:
  1.1859 +  DefineEmitState(FILE *fp, ArchDesc &AD, EncClass &encoding,
  1.1860 +                  InsEncode &ins_encode, InstructForm &inst)
  1.1861 +    : _AD(AD), _fp(fp), _encoding(encoding), _ins_encode(ins_encode), _inst(inst) {
  1.1862 +      clear();
  1.1863 +  }
  1.1864 +
  1.1865 +  void clear() {
  1.1866 +    _cleared       = true;
  1.1867 +    _opclass       = NULL;
  1.1868 +    _operand       = NULL;
  1.1869 +    _operand_idx   = 0;
  1.1870 +    _local_name    = "";
  1.1871 +    _operand_name  = "";
  1.1872 +    _doing_disp    = false;
  1.1873 +    _doing_constant= false;
  1.1874 +    _constant_type = Form::none;
  1.1875 +    _constant_status = LITERAL_NOT_SEEN;
  1.1876 +    _reg_status      = LITERAL_NOT_SEEN;
  1.1877 +    _doing_emit8   = false;
  1.1878 +    _doing_emit_d32= false;
  1.1879 +    _doing_emit_d16= false;
  1.1880 +    _doing_emit_hi = false;
  1.1881 +    _doing_emit_lo = false;
  1.1882 +    _may_reloc     = false;
  1.1883 +    _must_reloc    = false;
  1.1884 +    _reloc_form    = RELOC_NONE;
  1.1885 +    _reloc_type    = AdlcVMDeps::none_reloc_type();
  1.1886 +    _strings_to_emit.clear();
  1.1887 +  }
  1.1888 +
  1.1889 +  // Track necessary state when identifying a replacement variable
  1.1890 +  void update_state(const char *rep_var) {
  1.1891 +    // A replacement variable or one of its subfields
  1.1892 +    // Obtain replacement variable from list
  1.1893 +    if ( (*rep_var) != '$' ) {
  1.1894 +      // A replacement variable, '$' prefix
  1.1895 +      // check_rep_var( rep_var );
  1.1896 +      if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
  1.1897 +        // No state needed.
  1.1898 +        assert( _opclass == NULL,
  1.1899 +                "'primary', 'secondary' and 'tertiary' don't follow operand.");
  1.1900 +      } else {
  1.1901 +        // Lookup its position in parameter list
  1.1902 +        int   param_no  = _encoding.rep_var_index(rep_var);
  1.1903 +        if ( param_no == -1 ) {
  1.1904 +          _AD.syntax_err( _encoding._linenum,
  1.1905 +                          "Replacement variable %s not found in enc_class %s.\n",
  1.1906 +                          rep_var, _encoding._name);
  1.1907 +        }
  1.1908 +
  1.1909 +        // Lookup the corresponding ins_encode parameter
  1.1910 +        const char *inst_rep_var = _ins_encode.rep_var_name(_inst, param_no);
  1.1911 +        if (inst_rep_var == NULL) {
  1.1912 +          _AD.syntax_err( _ins_encode._linenum,
  1.1913 +                          "Parameter %s not passed to enc_class %s from instruct %s.\n",
  1.1914 +                          rep_var, _encoding._name, _inst._ident);
  1.1915 +        }
  1.1916 +
  1.1917 +        // Check if instruction's actual parameter is a local name in the instruction
  1.1918 +        const Form  *local     = _inst._localNames[inst_rep_var];
  1.1919 +        OpClassForm *opc       = (local != NULL) ? local->is_opclass() : NULL;
  1.1920 +        // Note: assert removed to allow constant and symbolic parameters
  1.1921 +        // assert( opc, "replacement variable was not found in local names");
  1.1922 +        // Lookup the index position iff the replacement variable is a localName
  1.1923 +        int idx  = (opc != NULL) ? _inst.operand_position_format(inst_rep_var) : -1;
  1.1924 +
  1.1925 +        if ( idx != -1 ) {
  1.1926 +          // This is a local in the instruction
  1.1927 +          // Update local state info.
  1.1928 +          _opclass        = opc;
  1.1929 +          _operand_idx    = idx;
  1.1930 +          _local_name     = rep_var;
  1.1931 +          _operand_name   = inst_rep_var;
  1.1932 +
  1.1933 +          // !!!!!
  1.1934 +          // Do not support consecutive operands.
  1.1935 +          assert( _operand == NULL, "Unimplemented()");
  1.1936 +          _operand = opc->is_operand();
  1.1937 +        }
  1.1938 +        else if( ADLParser::is_literal_constant(inst_rep_var) ) {
  1.1939 +          // Instruction provided a constant expression
  1.1940 +          // Check later that encoding specifies $$$constant to resolve as constant
  1.1941 +          _constant_status   = LITERAL_SEEN;
  1.1942 +        }
  1.1943 +        else if( Opcode::as_opcode_type(inst_rep_var) != Opcode::NOT_AN_OPCODE ) {
  1.1944 +          // Instruction provided an opcode: "primary", "secondary", "tertiary"
  1.1945 +          // Check later that encoding specifies $$$constant to resolve as constant
  1.1946 +          _constant_status   = LITERAL_SEEN;
  1.1947 +        }
  1.1948 +        else if((_AD.get_registers() != NULL ) && (_AD.get_registers()->getRegDef(inst_rep_var) != NULL)) {
  1.1949 +          // Instruction provided a literal register name for this parameter
  1.1950 +          // Check that encoding specifies $$$reg to resolve.as register.
  1.1951 +          _reg_status        = LITERAL_SEEN;
  1.1952 +        }
  1.1953 +        else {
  1.1954 +          // Check for unimplemented functionality before hard failure
  1.1955 +          assert( strcmp(opc->_ident,"label")==0, "Unimplemented() Label");
  1.1956 +          assert( false, "ShouldNotReachHere()");
  1.1957 +        }
  1.1958 +      } // done checking which operand this is.
  1.1959 +    } else {
  1.1960 +      //
  1.1961 +      // A subfield variable, '$$' prefix
  1.1962 +      // Check for fields that may require relocation information.
  1.1963 +      // Then check that literal register parameters are accessed with 'reg' or 'constant'
  1.1964 +      //
  1.1965 +      if ( strcmp(rep_var,"$disp") == 0 ) {
  1.1966 +        _doing_disp = true;
  1.1967 +        assert( _opclass, "Must use operand or operand class before '$disp'");
  1.1968 +        if( _operand == NULL ) {
  1.1969 +          // Only have an operand class, generate run-time check for relocation
  1.1970 +          _may_reloc    = true;
  1.1971 +          _reloc_form   = RELOC_DISP;
  1.1972 +          _reloc_type   = AdlcVMDeps::oop_reloc_type();
  1.1973 +        } else {
  1.1974 +          // Do precise check on operand: is it a ConP or not
  1.1975 +          //
  1.1976 +          // Check interface for value of displacement
  1.1977 +          assert( ( _operand->_interface != NULL ),
  1.1978 +                  "$disp can only follow memory interface operand");
  1.1979 +          MemInterface *mem_interface= _operand->_interface->is_MemInterface();
  1.1980 +          assert( mem_interface != NULL,
  1.1981 +                  "$disp can only follow memory interface operand");
  1.1982 +          const char *disp = mem_interface->_disp;
  1.1983 +
  1.1984 +          if( disp != NULL && (*disp == '$') ) {
  1.1985 +            // MemInterface::disp contains a replacement variable,
  1.1986 +            // Check if this matches a ConP
  1.1987 +            //
  1.1988 +            // Lookup replacement variable, in operand's component list
  1.1989 +            const char *rep_var_name = disp + 1; // Skip '$'
  1.1990 +            const Component *comp = _operand->_components.search(rep_var_name);
  1.1991 +            assert( comp != NULL,"Replacement variable not found in components");
  1.1992 +            const char      *type = comp->_type;
  1.1993 +            // Lookup operand form for replacement variable's type
  1.1994 +            const Form *form = _AD.globalNames()[type];
  1.1995 +            assert( form != NULL, "Replacement variable's type not found");
  1.1996 +            OperandForm *op = form->is_operand();
  1.1997 +            assert( op, "Attempting to emit a non-register or non-constant");
  1.1998 +            // Check if this is a constant
  1.1999 +            if (op->_matrule && op->_matrule->is_base_constant(_AD.globalNames())) {
  1.2000 +              // Check which constant this name maps to: _c0, _c1, ..., _cn
  1.2001 +              // const int idx = _operand.constant_position(_AD.globalNames(), comp);
  1.2002 +              // assert( idx != -1, "Constant component not found in operand");
  1.2003 +              Form::DataType dtype = op->is_base_constant(_AD.globalNames());
  1.2004 +              if ( dtype == Form::idealP ) {
  1.2005 +                _may_reloc    = true;
  1.2006 +                // No longer true that idealP is always an oop
  1.2007 +                _reloc_form   = RELOC_DISP;
  1.2008 +                _reloc_type   = AdlcVMDeps::oop_reloc_type();
  1.2009 +              }
  1.2010 +            }
  1.2011 +
  1.2012 +            else if( _operand->is_user_name_for_sReg() != Form::none ) {
  1.2013 +              // The only non-constant allowed access to disp is an operand sRegX in a stackSlotX
  1.2014 +              assert( op->ideal_to_sReg_type(type) != Form::none, "StackSlots access displacements using 'sRegs'");
  1.2015 +              _may_reloc   = false;
  1.2016 +            } else {
  1.2017 +              assert( false, "fatal(); Only stackSlots can access a non-constant using 'disp'");
  1.2018 +            }
  1.2019 +          }
  1.2020 +        } // finished with precise check of operand for relocation.
  1.2021 +      } // finished with subfield variable
  1.2022 +      else if ( strcmp(rep_var,"$constant") == 0 ) {
  1.2023 +        _doing_constant = true;
  1.2024 +        if ( _constant_status == LITERAL_NOT_SEEN ) {
  1.2025 +          // Check operand for type of constant
  1.2026 +          assert( _operand, "Must use operand before '$$constant'");
  1.2027 +          Form::DataType dtype = _operand->is_base_constant(_AD.globalNames());
  1.2028 +          _constant_type = dtype;
  1.2029 +          if ( dtype == Form::idealP ) {
  1.2030 +            _may_reloc    = true;
  1.2031 +            // No longer true that idealP is always an oop
  1.2032 +            // // _must_reloc   = true;
  1.2033 +            _reloc_form   = RELOC_IMMEDIATE;
  1.2034 +            _reloc_type   = AdlcVMDeps::oop_reloc_type();
  1.2035 +          } else {
  1.2036 +            // No relocation information needed
  1.2037 +          }
  1.2038 +        } else {
  1.2039 +          // User-provided literals may not require relocation information !!!!!
  1.2040 +          assert( _constant_status == LITERAL_SEEN, "Must know we are processing a user-provided literal");
  1.2041 +        }
  1.2042 +      }
  1.2043 +      else if ( strcmp(rep_var,"$label") == 0 ) {
  1.2044 +        // Calls containing labels require relocation
  1.2045 +        if ( _inst.is_ideal_call() )  {
  1.2046 +          _may_reloc    = true;
  1.2047 +          // !!!!! !!!!!
  1.2048 +          _reloc_type   = AdlcVMDeps::none_reloc_type();
  1.2049 +        }
  1.2050 +      }
  1.2051 +
  1.2052 +      // literal register parameter must be accessed as a 'reg' field.
  1.2053 +      if ( _reg_status != LITERAL_NOT_SEEN ) {
  1.2054 +        assert( _reg_status == LITERAL_SEEN, "Must have seen register literal before now");
  1.2055 +        if (strcmp(rep_var,"$reg") == 0 || reg_conversion(rep_var) != NULL) {
  1.2056 +          _reg_status  = LITERAL_ACCESSED;
  1.2057 +        } else {
  1.2058 +          assert( false, "invalid access to literal register parameter");
  1.2059 +        }
  1.2060 +      }
  1.2061 +      // literal constant parameters must be accessed as a 'constant' field
  1.2062 +      if ( _constant_status != LITERAL_NOT_SEEN ) {
  1.2063 +        assert( _constant_status == LITERAL_SEEN, "Must have seen constant literal before now");
  1.2064 +        if( strcmp(rep_var,"$constant") == 0 ) {
  1.2065 +          _constant_status  = LITERAL_ACCESSED;
  1.2066 +        } else {
  1.2067 +          assert( false, "invalid access to literal constant parameter");
  1.2068 +        }
  1.2069 +      }
  1.2070 +    } // end replacement and/or subfield
  1.2071 +
  1.2072 +  }
  1.2073 +
  1.2074 +  void add_rep_var(const char *rep_var) {
  1.2075 +    // Handle subfield and replacement variables.
  1.2076 +    if ( ( *rep_var == '$' ) && ( *(rep_var+1) == '$' ) ) {
  1.2077 +      // Check for emit prefix, '$$emit32'
  1.2078 +      assert( _cleared, "Can not nest $$$emit32");
  1.2079 +      if ( strcmp(rep_var,"$$emit32") == 0 ) {
  1.2080 +        _doing_emit_d32 = true;
  1.2081 +      }
  1.2082 +      else if ( strcmp(rep_var,"$$emit16") == 0 ) {
  1.2083 +        _doing_emit_d16 = true;
  1.2084 +      }
  1.2085 +      else if ( strcmp(rep_var,"$$emit_hi") == 0 ) {
  1.2086 +        _doing_emit_hi  = true;
  1.2087 +      }
  1.2088 +      else if ( strcmp(rep_var,"$$emit_lo") == 0 ) {
  1.2089 +        _doing_emit_lo  = true;
  1.2090 +      }
  1.2091 +      else if ( strcmp(rep_var,"$$emit8") == 0 ) {
  1.2092 +        _doing_emit8    = true;
  1.2093 +      }
  1.2094 +      else {
  1.2095 +        _AD.syntax_err(_encoding._linenum, "Unsupported $$operation '%s'\n",rep_var);
  1.2096 +        assert( false, "fatal();");
  1.2097 +      }
  1.2098 +    }
  1.2099 +    else {
  1.2100 +      // Update state for replacement variables
  1.2101 +      update_state( rep_var );
  1.2102 +      _strings_to_emit.addName(rep_var);
  1.2103 +    }
  1.2104 +    _cleared  = false;
  1.2105 +  }
  1.2106 +
  1.2107 +  void emit_replacement() {
  1.2108 +    // A replacement variable or one of its subfields
  1.2109 +    // Obtain replacement variable from list
  1.2110 +    // const char *ec_rep_var = encoding->_rep_vars.iter();
  1.2111 +    const char *rep_var;
  1.2112 +    _strings_to_emit.reset();
  1.2113 +    while ( (rep_var = _strings_to_emit.iter()) != NULL ) {
  1.2114 +
  1.2115 +      if ( (*rep_var) == '$' ) {
  1.2116 +        // A subfield variable, '$$' prefix
  1.2117 +        emit_field( rep_var );
  1.2118 +      } else {
  1.2119 +        // A replacement variable, '$' prefix
  1.2120 +        emit_rep_var( rep_var );
  1.2121 +      } // end replacement and/or subfield
  1.2122 +    }
  1.2123 +  }
  1.2124 +
  1.2125 +  void emit_reloc_type(const char* type) {
  1.2126 +    fprintf(_fp, "%s", type)
  1.2127 +      ;
  1.2128 +  }
  1.2129 +
  1.2130 +
  1.2131 +  void gen_emit_x_reloc(const char *d32_lo_hi ) {
  1.2132 +    fprintf(_fp,"emit_%s_reloc(cbuf, ", d32_lo_hi );
  1.2133 +    emit_replacement();             fprintf(_fp,", ");
  1.2134 +    emit_reloc_type( _reloc_type ); fprintf(_fp,", ");
  1.2135 +    fprintf(_fp, "%d", _reloc_form);fprintf(_fp, ");");
  1.2136 +  }
  1.2137 +
  1.2138 +
  1.2139 +  void emit() {
  1.2140 +    //
  1.2141 +    //   "emit_d32_reloc(" or "emit_hi_reloc" or "emit_lo_reloc"
  1.2142 +    //
  1.2143 +    // Emit the function name when generating an emit function
  1.2144 +    if ( _doing_emit_d32 || _doing_emit_hi || _doing_emit_lo ) {
  1.2145 +      const char *d32_hi_lo = _doing_emit_d32 ? "d32" : (_doing_emit_hi ? "hi" : "lo");
  1.2146 +      // In general, relocatable isn't known at compiler compile time.
  1.2147 +      // Check results of prior scan
  1.2148 +      if ( ! _may_reloc ) {
  1.2149 +        // Definitely don't need relocation information
  1.2150 +        fprintf( _fp, "emit_%s(cbuf, ", d32_hi_lo );
  1.2151 +        emit_replacement(); fprintf(_fp, ")");
  1.2152 +      }
  1.2153 +      else if ( _must_reloc ) {
  1.2154 +        // Must emit relocation information
  1.2155 +        gen_emit_x_reloc( d32_hi_lo );
  1.2156 +      }
  1.2157 +      else {
  1.2158 +        // Emit RUNTIME CHECK to see if value needs relocation info
  1.2159 +        // If emitting a relocatable address, use 'emit_d32_reloc'
  1.2160 +        const char *disp_constant = _doing_disp ? "disp" : _doing_constant ? "constant" : "INVALID";
  1.2161 +        assert( (_doing_disp || _doing_constant)
  1.2162 +                && !(_doing_disp && _doing_constant),
  1.2163 +                "Must be emitting either a displacement or a constant");
  1.2164 +        fprintf(_fp,"\n");
  1.2165 +        fprintf(_fp,"if ( opnd_array(%d)->%s_is_oop() ) {\n",
  1.2166 +                _operand_idx, disp_constant);
  1.2167 +        fprintf(_fp,"  ");
  1.2168 +        gen_emit_x_reloc( d32_hi_lo ); fprintf(_fp,"\n");
  1.2169 +        fprintf(_fp,"} else {\n");
  1.2170 +        fprintf(_fp,"  emit_%s(cbuf, ", d32_hi_lo);
  1.2171 +        emit_replacement(); fprintf(_fp, ");\n"); fprintf(_fp,"}");
  1.2172 +      }
  1.2173 +    }
  1.2174 +    else if ( _doing_emit_d16 ) {
  1.2175 +      // Relocation of 16-bit values is not supported
  1.2176 +      fprintf(_fp,"emit_d16(cbuf, ");
  1.2177 +      emit_replacement(); fprintf(_fp, ")");
  1.2178 +      // No relocation done for 16-bit values
  1.2179 +    }
  1.2180 +    else if ( _doing_emit8 ) {
  1.2181 +      // Relocation of 8-bit values is not supported
  1.2182 +      fprintf(_fp,"emit_d8(cbuf, ");
  1.2183 +      emit_replacement(); fprintf(_fp, ")");
  1.2184 +      // No relocation done for 8-bit values
  1.2185 +    }
  1.2186 +    else {
  1.2187 +      // Not an emit# command, just output the replacement string.
  1.2188 +      emit_replacement();
  1.2189 +    }
  1.2190 +
  1.2191 +    // Get ready for next state collection.
  1.2192 +    clear();
  1.2193 +  }
  1.2194 +
  1.2195 +private:
  1.2196 +
  1.2197 +  // recognizes names which represent MacroAssembler register types
  1.2198 +  // and return the conversion function to build them from OptoReg
  1.2199 +  const char* reg_conversion(const char* rep_var) {
  1.2200 +    if (strcmp(rep_var,"$Register") == 0)      return "as_Register";
  1.2201 +    if (strcmp(rep_var,"$FloatRegister") == 0) return "as_FloatRegister";
  1.2202 +#if defined(IA32) || defined(AMD64)
  1.2203 +    if (strcmp(rep_var,"$XMMRegister") == 0)   return "as_XMMRegister";
  1.2204 +#endif
  1.2205 +    return NULL;
  1.2206 +  }
  1.2207 +
  1.2208 +  void emit_field(const char *rep_var) {
  1.2209 +    const char* reg_convert = reg_conversion(rep_var);
  1.2210 +
  1.2211 +    // A subfield variable, '$$subfield'
  1.2212 +    if ( strcmp(rep_var, "$reg") == 0 || reg_convert != NULL) {
  1.2213 +      // $reg form or the $Register MacroAssembler type conversions
  1.2214 +      assert( _operand_idx != -1,
  1.2215 +              "Must use this subfield after operand");
  1.2216 +      if( _reg_status == LITERAL_NOT_SEEN ) {
  1.2217 +        if (_processing_noninput) {
  1.2218 +          const Form  *local     = _inst._localNames[_operand_name];
  1.2219 +          OperandForm *oper      = local->is_operand();
  1.2220 +          const RegDef* first = oper->get_RegClass()->find_first_elem();
  1.2221 +          if (reg_convert != NULL) {
  1.2222 +            fprintf(_fp, "%s(%s_enc)", reg_convert, first->_regname);
  1.2223 +          } else {
  1.2224 +            fprintf(_fp, "%s_enc", first->_regname);
  1.2225 +          }
  1.2226 +        } else {
  1.2227 +          fprintf(_fp,"->%s(ra_,this", reg_convert != NULL ? reg_convert : "reg");
  1.2228 +          // Add parameter for index position, if not result operand
  1.2229 +          if( _operand_idx != 0 ) fprintf(_fp,",idx%d", _operand_idx);
  1.2230 +          fprintf(_fp,")");
  1.2231 +        }
  1.2232 +      } else {
  1.2233 +        assert( _reg_status == LITERAL_OUTPUT, "should have output register literal in emit_rep_var");
  1.2234 +        // Register literal has already been sent to output file, nothing more needed
  1.2235 +      }
  1.2236 +    }
  1.2237 +    else if ( strcmp(rep_var,"$base") == 0 ) {
  1.2238 +      assert( _operand_idx != -1,
  1.2239 +              "Must use this subfield after operand");
  1.2240 +      assert( ! _may_reloc, "UnImplemented()");
  1.2241 +      fprintf(_fp,"->base(ra_,this,idx%d)", _operand_idx);
  1.2242 +    }
  1.2243 +    else if ( strcmp(rep_var,"$index") == 0 ) {
  1.2244 +      assert( _operand_idx != -1,
  1.2245 +              "Must use this subfield after operand");
  1.2246 +      assert( ! _may_reloc, "UnImplemented()");
  1.2247 +      fprintf(_fp,"->index(ra_,this,idx%d)", _operand_idx);
  1.2248 +    }
  1.2249 +    else if ( strcmp(rep_var,"$scale") == 0 ) {
  1.2250 +      assert( ! _may_reloc, "UnImplemented()");
  1.2251 +      fprintf(_fp,"->scale()");
  1.2252 +    }
  1.2253 +    else if ( strcmp(rep_var,"$cmpcode") == 0 ) {
  1.2254 +      assert( ! _may_reloc, "UnImplemented()");
  1.2255 +      fprintf(_fp,"->ccode()");
  1.2256 +    }
  1.2257 +    else if ( strcmp(rep_var,"$constant") == 0 ) {
  1.2258 +      if( _constant_status == LITERAL_NOT_SEEN ) {
  1.2259 +        if ( _constant_type == Form::idealD ) {
  1.2260 +          fprintf(_fp,"->constantD()");
  1.2261 +        } else if ( _constant_type == Form::idealF ) {
  1.2262 +          fprintf(_fp,"->constantF()");
  1.2263 +        } else if ( _constant_type == Form::idealL ) {
  1.2264 +          fprintf(_fp,"->constantL()");
  1.2265 +        } else {
  1.2266 +          fprintf(_fp,"->constant()");
  1.2267 +        }
  1.2268 +      } else {
  1.2269 +        assert( _constant_status == LITERAL_OUTPUT, "should have output constant literal in emit_rep_var");
  1.2270 +        // Cosntant literal has already been sent to output file, nothing more needed
  1.2271 +      }
  1.2272 +    }
  1.2273 +    else if ( strcmp(rep_var,"$disp") == 0 ) {
  1.2274 +      Form::DataType stack_type = _operand ? _operand->is_user_name_for_sReg() : Form::none;
  1.2275 +      if( _operand  && _operand_idx==0 && stack_type != Form::none ) {
  1.2276 +        fprintf(_fp,"->disp(ra_,this,0)");
  1.2277 +      } else {
  1.2278 +        fprintf(_fp,"->disp(ra_,this,idx%d)", _operand_idx);
  1.2279 +      }
  1.2280 +    }
  1.2281 +    else if ( strcmp(rep_var,"$label") == 0 ) {
  1.2282 +      fprintf(_fp,"->label()");
  1.2283 +    }
  1.2284 +    else if ( strcmp(rep_var,"$method") == 0 ) {
  1.2285 +      fprintf(_fp,"->method()");
  1.2286 +    }
  1.2287 +    else {
  1.2288 +      printf("emit_field: %s\n",rep_var);
  1.2289 +      assert( false, "UnImplemented()");
  1.2290 +    }
  1.2291 +  }
  1.2292 +
  1.2293 +
  1.2294 +  void emit_rep_var(const char *rep_var) {
  1.2295 +    _processing_noninput = false;
  1.2296 +    // A replacement variable, originally '$'
  1.2297 +    if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
  1.2298 +      _inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) );
  1.2299 +    }
  1.2300 +    else {
  1.2301 +      // Lookup its position in parameter list
  1.2302 +      int   param_no  = _encoding.rep_var_index(rep_var);
  1.2303 +      if ( param_no == -1 ) {
  1.2304 +        _AD.syntax_err( _encoding._linenum,
  1.2305 +                        "Replacement variable %s not found in enc_class %s.\n",
  1.2306 +                        rep_var, _encoding._name);
  1.2307 +      }
  1.2308 +      // Lookup the corresponding ins_encode parameter
  1.2309 +      const char *inst_rep_var = _ins_encode.rep_var_name(_inst, param_no);
  1.2310 +
  1.2311 +      // Check if instruction's actual parameter is a local name in the instruction
  1.2312 +      const Form  *local     = _inst._localNames[inst_rep_var];
  1.2313 +      OpClassForm *opc       = (local != NULL) ? local->is_opclass() : NULL;
  1.2314 +      // Note: assert removed to allow constant and symbolic parameters
  1.2315 +      // assert( opc, "replacement variable was not found in local names");
  1.2316 +      // Lookup the index position iff the replacement variable is a localName
  1.2317 +      int idx  = (opc != NULL) ? _inst.operand_position_format(inst_rep_var) : -1;
  1.2318 +      if( idx != -1 ) {
  1.2319 +        if (_inst.is_noninput_operand(idx)) {
  1.2320 +          // This operand isn't a normal input so printing it is done
  1.2321 +          // specially.
  1.2322 +          _processing_noninput = true;
  1.2323 +        } else {
  1.2324 +          // Output the emit code for this operand
  1.2325 +          fprintf(_fp,"opnd_array(%d)",idx);
  1.2326 +        }
  1.2327 +        assert( _operand == opc->is_operand(),
  1.2328 +                "Previous emit $operand does not match current");
  1.2329 +      }
  1.2330 +      else if( ADLParser::is_literal_constant(inst_rep_var) ) {
  1.2331 +        // else check if it is a constant expression
  1.2332 +        // Removed following assert to allow primitive C types as arguments to encodings
  1.2333 +        // assert( _constant_status == LITERAL_ACCESSED, "Must be processing a literal constant parameter");
  1.2334 +        fprintf(_fp,"(%s)", inst_rep_var);
  1.2335 +        _constant_status = LITERAL_OUTPUT;
  1.2336 +      }
  1.2337 +      else if( Opcode::as_opcode_type(inst_rep_var) != Opcode::NOT_AN_OPCODE ) {
  1.2338 +        // else check if "primary", "secondary", "tertiary"
  1.2339 +        assert( _constant_status == LITERAL_ACCESSED, "Must be processing a literal constant parameter");
  1.2340 +        _inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(inst_rep_var) );
  1.2341 +        _constant_status = LITERAL_OUTPUT;
  1.2342 +      }
  1.2343 +      else if((_AD.get_registers() != NULL ) && (_AD.get_registers()->getRegDef(inst_rep_var) != NULL)) {
  1.2344 +        // Instruction provided a literal register name for this parameter
  1.2345 +        // Check that encoding specifies $$$reg to resolve.as register.
  1.2346 +        assert( _reg_status == LITERAL_ACCESSED, "Must be processing a literal register parameter");
  1.2347 +        fprintf(_fp,"(%s_enc)", inst_rep_var);
  1.2348 +        _reg_status = LITERAL_OUTPUT;
  1.2349 +      }
  1.2350 +      else {
  1.2351 +        // Check for unimplemented functionality before hard failure
  1.2352 +        assert( strcmp(opc->_ident,"label")==0, "Unimplemented() Label");
  1.2353 +        assert( false, "ShouldNotReachHere()");
  1.2354 +      }
  1.2355 +      // all done
  1.2356 +    }
  1.2357 +  }
  1.2358 +
  1.2359 +};  // end class DefineEmitState
  1.2360 +
  1.2361 +
  1.2362 +void ArchDesc::defineSize(FILE *fp, InstructForm &inst) {
  1.2363 +
  1.2364 +  //(1)
  1.2365 +  // Output instruction's emit prototype
  1.2366 +  fprintf(fp,"uint  %sNode::size(PhaseRegAlloc *ra_) const {\n",
  1.2367 +          inst._ident);
  1.2368 +
  1.2369 +  //(2)
  1.2370 +  // Print the size
  1.2371 +  fprintf(fp, " return (VerifyOops ? MachNode::size(ra_) : %s);\n", inst._size);
  1.2372 +
  1.2373 +  // (3) and (4)
  1.2374 +  fprintf(fp,"}\n");
  1.2375 +}
  1.2376 +
  1.2377 +void ArchDesc::defineEmit(FILE *fp, InstructForm &inst) {
  1.2378 +  InsEncode *ins_encode = inst._insencode;
  1.2379 +
  1.2380 +  // (1)
  1.2381 +  // Output instruction's emit prototype
  1.2382 +  fprintf(fp,"void  %sNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {\n",
  1.2383 +          inst._ident);
  1.2384 +
  1.2385 +  // If user did not define an encode section,
  1.2386 +  // provide stub that does not generate any machine code.
  1.2387 +  if( (_encode == NULL) || (ins_encode == NULL) ) {
  1.2388 +    fprintf(fp, "  // User did not define an encode section.\n");
  1.2389 +    fprintf(fp,"}\n");
  1.2390 +    return;
  1.2391 +  }
  1.2392 +
  1.2393 +  // Save current instruction's starting address (helps with relocation).
  1.2394 +  fprintf( fp, "    cbuf.set_inst_mark();\n");
  1.2395 +
  1.2396 +  // // // idx0 is only needed for syntactic purposes and only by "storeSSI"
  1.2397 +  // fprintf( fp, "    unsigned idx0  = 0;\n");
  1.2398 +
  1.2399 +  // Output each operand's offset into the array of registers.
  1.2400 +  inst.index_temps( fp, _globalNames );
  1.2401 +
  1.2402 +  // Output this instruction's encodings
  1.2403 +  const char *ec_name;
  1.2404 +  bool        user_defined = false;
  1.2405 +  ins_encode->reset();
  1.2406 +  while ( (ec_name = ins_encode->encode_class_iter()) != NULL ) {
  1.2407 +    fprintf(fp, "  {");
  1.2408 +    // Output user-defined encoding
  1.2409 +    user_defined           = true;
  1.2410 +
  1.2411 +    const char *ec_code    = NULL;
  1.2412 +    const char *ec_rep_var = NULL;
  1.2413 +    EncClass   *encoding   = _encode->encClass(ec_name);
  1.2414 +    if (encoding == NULL) {
  1.2415 +      fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name);
  1.2416 +      abort();
  1.2417 +    }
  1.2418 +
  1.2419 +    if (ins_encode->current_encoding_num_args() != encoding->num_args()) {
  1.2420 +      globalAD->syntax_err(ins_encode->_linenum, "In %s: passing %d arguments to %s but expecting %d",
  1.2421 +                           inst._ident, ins_encode->current_encoding_num_args(),
  1.2422 +                           ec_name, encoding->num_args());
  1.2423 +    }
  1.2424 +
  1.2425 +    DefineEmitState  pending(fp, *this, *encoding, *ins_encode, inst );
  1.2426 +    encoding->_code.reset();
  1.2427 +    encoding->_rep_vars.reset();
  1.2428 +    // Process list of user-defined strings,
  1.2429 +    // and occurrences of replacement variables.
  1.2430 +    // Replacement Vars are pushed into a list and then output
  1.2431 +    while ( (ec_code = encoding->_code.iter()) != NULL ) {
  1.2432 +      if ( ! encoding->_code.is_signal( ec_code ) ) {
  1.2433 +        // Emit pending code
  1.2434 +        pending.emit();
  1.2435 +        pending.clear();
  1.2436 +        // Emit this code section
  1.2437 +        fprintf(fp,"%s", ec_code);
  1.2438 +      } else {
  1.2439 +        // A replacement variable or one of its subfields
  1.2440 +        // Obtain replacement variable from list
  1.2441 +        ec_rep_var  = encoding->_rep_vars.iter();
  1.2442 +        pending.add_rep_var(ec_rep_var);
  1.2443 +      }
  1.2444 +    }
  1.2445 +    // Emit pending code
  1.2446 +    pending.emit();
  1.2447 +    pending.clear();
  1.2448 +    fprintf(fp, "}\n");
  1.2449 +  } // end while instruction's encodings
  1.2450 +
  1.2451 +  // Check if user stated which encoding to user
  1.2452 +  if ( user_defined == false ) {
  1.2453 +    fprintf(fp, "  // User did not define which encode class to use.\n");
  1.2454 +  }
  1.2455 +
  1.2456 +  // (3) and (4)
  1.2457 +  fprintf(fp,"}\n");
  1.2458 +}
  1.2459 +
  1.2460 +// ---------------------------------------------------------------------------
  1.2461 +//--------Utilities to build MachOper and MachNode derived Classes------------
  1.2462 +// ---------------------------------------------------------------------------
  1.2463 +
  1.2464 +//------------------------------Utilities to build Operand Classes------------
  1.2465 +static void defineIn_RegMask(FILE *fp, FormDict &globals, OperandForm &oper) {
  1.2466 +  uint num_edges = oper.num_edges(globals);
  1.2467 +  if( num_edges != 0 ) {
  1.2468 +    // Method header
  1.2469 +    fprintf(fp, "const RegMask *%sOper::in_RegMask(int index) const {\n",
  1.2470 +            oper._ident);
  1.2471 +
  1.2472 +    // Assert that the index is in range.
  1.2473 +    fprintf(fp, "  assert(0 <= index && index < %d, \"index out of range\");\n",
  1.2474 +            num_edges);
  1.2475 +
  1.2476 +    // Figure out if all RegMasks are the same.
  1.2477 +    const char* first_reg_class = oper.in_reg_class(0, globals);
  1.2478 +    bool all_same = true;
  1.2479 +    assert(first_reg_class != NULL, "did not find register mask");
  1.2480 +
  1.2481 +    for (uint index = 1; all_same && index < num_edges; index++) {
  1.2482 +      const char* some_reg_class = oper.in_reg_class(index, globals);
  1.2483 +      assert(some_reg_class != NULL, "did not find register mask");
  1.2484 +      if (strcmp(first_reg_class, some_reg_class) != 0) {
  1.2485 +        all_same = false;
  1.2486 +      }
  1.2487 +    }
  1.2488 +
  1.2489 +    if (all_same) {
  1.2490 +      // Return the sole RegMask.
  1.2491 +      if (strcmp(first_reg_class, "stack_slots") == 0) {
  1.2492 +        fprintf(fp,"  return &(Compile::current()->FIRST_STACK_mask());\n");
  1.2493 +      } else {
  1.2494 +        fprintf(fp,"  return &%s_mask;\n", toUpper(first_reg_class));
  1.2495 +      }
  1.2496 +    } else {
  1.2497 +      // Build a switch statement to return the desired mask.
  1.2498 +      fprintf(fp,"  switch (index) {\n");
  1.2499 +
  1.2500 +      for (uint index = 0; index < num_edges; index++) {
  1.2501 +        const char *reg_class = oper.in_reg_class(index, globals);
  1.2502 +        assert(reg_class != NULL, "did not find register mask");
  1.2503 +        if( !strcmp(reg_class, "stack_slots") ) {
  1.2504 +          fprintf(fp, "  case %d: return &(Compile::current()->FIRST_STACK_mask());\n", index);
  1.2505 +        } else {
  1.2506 +          fprintf(fp, "  case %d: return &%s_mask;\n", index, toUpper(reg_class));
  1.2507 +        }
  1.2508 +      }
  1.2509 +      fprintf(fp,"  }\n");
  1.2510 +      fprintf(fp,"  ShouldNotReachHere();\n");
  1.2511 +      fprintf(fp,"  return NULL;\n");
  1.2512 +    }
  1.2513 +
  1.2514 +    // Method close
  1.2515 +    fprintf(fp, "}\n\n");
  1.2516 +  }
  1.2517 +}
  1.2518 +
  1.2519 +// generate code to create a clone for a class derived from MachOper
  1.2520 +//
  1.2521 +// (0)  MachOper  *MachOperXOper::clone(Compile* C) const {
  1.2522 +// (1)    return new (C) MachXOper( _ccode, _c0, _c1, ..., _cn);
  1.2523 +// (2)  }
  1.2524 +//
  1.2525 +static void defineClone(FILE *fp, FormDict &globalNames, OperandForm &oper) {
  1.2526 +  fprintf(fp,"MachOper  *%sOper::clone(Compile* C) const {\n", oper._ident);
  1.2527 +  // Check for constants that need to be copied over
  1.2528 +  const int  num_consts    = oper.num_consts(globalNames);
  1.2529 +  const bool is_ideal_bool = oper.is_ideal_bool();
  1.2530 +  if( (num_consts > 0) ) {
  1.2531 +    fprintf(fp,"  return  new (C) %sOper(", oper._ident);
  1.2532 +    // generate parameters for constants
  1.2533 +    int i = 0;
  1.2534 +    fprintf(fp,"_c%d", i);
  1.2535 +    for( i = 1; i < num_consts; ++i) {
  1.2536 +      fprintf(fp,", _c%d", i);
  1.2537 +    }
  1.2538 +    // finish line (1)
  1.2539 +    fprintf(fp,");\n");
  1.2540 +  }
  1.2541 +  else {
  1.2542 +    assert( num_consts == 0, "Currently support zero or one constant per operand clone function");
  1.2543 +    fprintf(fp,"  return  new (C) %sOper();\n", oper._ident);
  1.2544 +  }
  1.2545 +  // finish method
  1.2546 +  fprintf(fp,"}\n");
  1.2547 +}
  1.2548 +
  1.2549 +static void define_hash(FILE *fp, char *operand) {
  1.2550 +  fprintf(fp,"uint %sOper::hash() const { return 5; }\n", operand);
  1.2551 +}
  1.2552 +
  1.2553 +static void define_cmp(FILE *fp, char *operand) {
  1.2554 +  fprintf(fp,"uint %sOper::cmp( const MachOper &oper ) const { return opcode() == oper.opcode(); }\n", operand);
  1.2555 +}
  1.2556 +
  1.2557 +
  1.2558 +// Helper functions for bug 4796752, abstracted with minimal modification
  1.2559 +// from define_oper_interface()
  1.2560 +OperandForm *rep_var_to_operand(const char *encoding, OperandForm &oper, FormDict &globals) {
  1.2561 +  OperandForm *op = NULL;
  1.2562 +  // Check for replacement variable
  1.2563 +  if( *encoding == '$' ) {
  1.2564 +    // Replacement variable
  1.2565 +    const char *rep_var = encoding + 1;
  1.2566 +    // Lookup replacement variable, rep_var, in operand's component list
  1.2567 +    const Component *comp = oper._components.search(rep_var);
  1.2568 +    assert( comp != NULL, "Replacement variable not found in components");
  1.2569 +    // Lookup operand form for replacement variable's type
  1.2570 +    const char      *type = comp->_type;
  1.2571 +    Form            *form = (Form*)globals[type];
  1.2572 +    assert( form != NULL, "Replacement variable's type not found");
  1.2573 +    op = form->is_operand();
  1.2574 +    assert( op, "Attempting to emit a non-register or non-constant");
  1.2575 +  }
  1.2576 +
  1.2577 +  return op;
  1.2578 +}
  1.2579 +
  1.2580 +int rep_var_to_constant_index(const char *encoding, OperandForm &oper, FormDict &globals) {
  1.2581 +  int idx = -1;
  1.2582 +  // Check for replacement variable
  1.2583 +  if( *encoding == '$' ) {
  1.2584 +    // Replacement variable
  1.2585 +    const char *rep_var = encoding + 1;
  1.2586 +    // Lookup replacement variable, rep_var, in operand's component list
  1.2587 +    const Component *comp = oper._components.search(rep_var);
  1.2588 +    assert( comp != NULL, "Replacement variable not found in components");
  1.2589 +    // Lookup operand form for replacement variable's type
  1.2590 +    const char      *type = comp->_type;
  1.2591 +    Form            *form = (Form*)globals[type];
  1.2592 +    assert( form != NULL, "Replacement variable's type not found");
  1.2593 +    OperandForm *op = form->is_operand();
  1.2594 +    assert( op, "Attempting to emit a non-register or non-constant");
  1.2595 +    // Check that this is a constant and find constant's index:
  1.2596 +    if (op->_matrule && op->_matrule->is_base_constant(globals)) {
  1.2597 +      idx  = oper.constant_position(globals, comp);
  1.2598 +    }
  1.2599 +  }
  1.2600 +
  1.2601 +  return idx;
  1.2602 +}
  1.2603 +
  1.2604 +bool is_regI(const char *encoding, OperandForm &oper, FormDict &globals ) {
  1.2605 +  bool is_regI = false;
  1.2606 +
  1.2607 +  OperandForm *op = rep_var_to_operand(encoding, oper, globals);
  1.2608 +  if( op != NULL ) {
  1.2609 +    // Check that this is a register
  1.2610 +    if ( (op->_matrule && op->_matrule->is_base_register(globals)) ) {
  1.2611 +      // Register
  1.2612 +      const char* ideal  = op->ideal_type(globals);
  1.2613 +      is_regI = (ideal && (op->ideal_to_Reg_type(ideal) == Form::idealI));
  1.2614 +    }
  1.2615 +  }
  1.2616 +
  1.2617 +  return is_regI;
  1.2618 +}
  1.2619 +
  1.2620 +bool is_conP(const char *encoding, OperandForm &oper, FormDict &globals ) {
  1.2621 +  bool is_conP = false;
  1.2622 +
  1.2623 +  OperandForm *op = rep_var_to_operand(encoding, oper, globals);
  1.2624 +  if( op != NULL ) {
  1.2625 +    // Check that this is a constant pointer
  1.2626 +    if (op->_matrule && op->_matrule->is_base_constant(globals)) {
  1.2627 +      // Constant
  1.2628 +      Form::DataType dtype = op->is_base_constant(globals);
  1.2629 +      is_conP = (dtype == Form::idealP);
  1.2630 +    }
  1.2631 +  }
  1.2632 +
  1.2633 +  return is_conP;
  1.2634 +}
  1.2635 +
  1.2636 +
  1.2637 +// Define a MachOper interface methods
  1.2638 +void ArchDesc::define_oper_interface(FILE *fp, OperandForm &oper, FormDict &globals,
  1.2639 +                                     const char *name, const char *encoding) {
  1.2640 +  bool emit_position = false;
  1.2641 +  int position = -1;
  1.2642 +
  1.2643 +  fprintf(fp,"  virtual int            %s", name);
  1.2644 +  // Generate access method for base, index, scale, disp, ...
  1.2645 +  if( (strcmp(name,"base") == 0) || (strcmp(name,"index") == 0) ) {
  1.2646 +    fprintf(fp,"(PhaseRegAlloc *ra_, const Node *node, int idx) const { \n");
  1.2647 +    emit_position = true;
  1.2648 +  } else if ( (strcmp(name,"disp") == 0) ) {
  1.2649 +    fprintf(fp,"(PhaseRegAlloc *ra_, const Node *node, int idx) const { \n");
  1.2650 +  } else {
  1.2651 +    fprintf(fp,"() const { ");
  1.2652 +  }
  1.2653 +
  1.2654 +  // Check for hexadecimal value OR replacement variable
  1.2655 +  if( *encoding == '$' ) {
  1.2656 +    // Replacement variable
  1.2657 +    const char *rep_var = encoding + 1;
  1.2658 +    fprintf(fp,"// Replacement variable: %s\n", encoding+1);
  1.2659 +    // Lookup replacement variable, rep_var, in operand's component list
  1.2660 +    const Component *comp = oper._components.search(rep_var);
  1.2661 +    assert( comp != NULL, "Replacement variable not found in components");
  1.2662 +    // Lookup operand form for replacement variable's type
  1.2663 +    const char      *type = comp->_type;
  1.2664 +    Form            *form = (Form*)globals[type];
  1.2665 +    assert( form != NULL, "Replacement variable's type not found");
  1.2666 +    OperandForm *op = form->is_operand();
  1.2667 +    assert( op, "Attempting to emit a non-register or non-constant");
  1.2668 +    // Check that this is a register or a constant and generate code:
  1.2669 +    if ( (op->_matrule && op->_matrule->is_base_register(globals)) ) {
  1.2670 +      // Register
  1.2671 +      int idx_offset = oper.register_position( globals, rep_var);
  1.2672 +      position = idx_offset;
  1.2673 +      fprintf(fp,"    return (int)ra_->get_encode(node->in(idx");
  1.2674 +      if ( idx_offset > 0 ) fprintf(fp,                      "+%d",idx_offset);
  1.2675 +      fprintf(fp,"));\n");
  1.2676 +    } else if ( op->ideal_to_sReg_type(op->_ident) != Form::none ) {
  1.2677 +      // StackSlot for an sReg comes either from input node or from self, when idx==0
  1.2678 +      fprintf(fp,"    if( idx != 0 ) {\n");
  1.2679 +      fprintf(fp,"      // Access register number for input operand\n");
  1.2680 +      fprintf(fp,"      return ra_->reg2offset(ra_->get_reg_first(node->in(idx)));/* sReg */\n");
  1.2681 +      fprintf(fp,"    }\n");
  1.2682 +      fprintf(fp,"    // Access register number from myself\n");
  1.2683 +      fprintf(fp,"    return ra_->reg2offset(ra_->get_reg_first(node));/* sReg */\n");
  1.2684 +    } else if (op->_matrule && op->_matrule->is_base_constant(globals)) {
  1.2685 +      // Constant
  1.2686 +      // Check which constant this name maps to: _c0, _c1, ..., _cn
  1.2687 +      const int idx = oper.constant_position(globals, comp);
  1.2688 +      assert( idx != -1, "Constant component not found in operand");
  1.2689 +      // Output code for this constant, type dependent.
  1.2690 +      fprintf(fp,"    return (int)" );
  1.2691 +      oper.access_constant(fp, globals, (uint)idx /* , const_type */);
  1.2692 +      fprintf(fp,";\n");
  1.2693 +    } else {
  1.2694 +      assert( false, "Attempting to emit a non-register or non-constant");
  1.2695 +    }
  1.2696 +  }
  1.2697 +  else if( *encoding == '0' && *(encoding+1) == 'x' ) {
  1.2698 +    // Hex value
  1.2699 +    fprintf(fp,"return %s;", encoding);
  1.2700 +  } else {
  1.2701 +    assert( false, "Do not support octal or decimal encode constants");
  1.2702 +  }
  1.2703 +  fprintf(fp,"  }\n");
  1.2704 +
  1.2705 +  if( emit_position && (position != -1) && (oper.num_edges(globals) > 0) ) {
  1.2706 +    fprintf(fp,"  virtual int            %s_position() const { return %d; }\n", name, position);
  1.2707 +    MemInterface *mem_interface = oper._interface->is_MemInterface();
  1.2708 +    const char *base = mem_interface->_base;
  1.2709 +    const char *disp = mem_interface->_disp;
  1.2710 +    if( emit_position && (strcmp(name,"base") == 0)
  1.2711 +        && base != NULL && is_regI(base, oper, globals)
  1.2712 +        && disp != NULL && is_conP(disp, oper, globals) ) {
  1.2713 +      // Found a memory access using a constant pointer for a displacement
  1.2714 +      // and a base register containing an integer offset.
  1.2715 +      // In this case the base and disp are reversed with respect to what
  1.2716 +      // is expected by MachNode::get_base_and_disp() and MachNode::adr_type().
  1.2717 +      // Provide a non-NULL return for disp_as_type() that will allow adr_type()
  1.2718 +      // to correctly compute the access type for alias analysis.
  1.2719 +      //
  1.2720 +      // See BugId 4796752, operand indOffset32X in i486.ad
  1.2721 +      int idx = rep_var_to_constant_index(disp, oper, globals);
  1.2722 +      fprintf(fp,"  virtual const TypePtr *disp_as_type() const { return _c%d; }\n", idx);
  1.2723 +    }
  1.2724 +  }
  1.2725 +}
  1.2726 +
  1.2727 +//
  1.2728 +// Construct the method to copy _idx, inputs and operands to new node.
  1.2729 +static void define_fill_new_machnode(bool used, FILE *fp_cpp) {
  1.2730 +  fprintf(fp_cpp, "\n");
  1.2731 +  fprintf(fp_cpp, "// Copy _idx, inputs and operands to new node\n");
  1.2732 +  fprintf(fp_cpp, "void MachNode::fill_new_machnode( MachNode* node, Compile* C) const {\n");
  1.2733 +  if( !used ) {
  1.2734 +    fprintf(fp_cpp, "  // This architecture does not have cisc or short branch instructions\n");
  1.2735 +    fprintf(fp_cpp, "  ShouldNotCallThis();\n");
  1.2736 +    fprintf(fp_cpp, "}\n");
  1.2737 +  } else {
  1.2738 +    // New node must use same node index for access through allocator's tables
  1.2739 +    fprintf(fp_cpp, "  // New node must use same node index\n");
  1.2740 +    fprintf(fp_cpp, "  node->set_idx( _idx );\n");
  1.2741 +    // Copy machine-independent inputs
  1.2742 +    fprintf(fp_cpp, "  // Copy machine-independent inputs\n");
  1.2743 +    fprintf(fp_cpp, "  for( uint j = 0; j < req(); j++ ) {\n");
  1.2744 +    fprintf(fp_cpp, "    node->add_req(in(j));\n");
  1.2745 +    fprintf(fp_cpp, "  }\n");
  1.2746 +    // Copy machine operands to new MachNode
  1.2747 +    fprintf(fp_cpp, "  // Copy my operands, except for cisc position\n");
  1.2748 +    fprintf(fp_cpp, "  int nopnds = num_opnds();\n");
  1.2749 +    fprintf(fp_cpp, "  assert( node->num_opnds() == (uint)nopnds, \"Must have same number of operands\");\n");
  1.2750 +    fprintf(fp_cpp, "  MachOper **to = node->_opnds;\n");
  1.2751 +    fprintf(fp_cpp, "  for( int i = 0; i < nopnds; i++ ) {\n");
  1.2752 +    fprintf(fp_cpp, "    if( i != cisc_operand() ) \n");
  1.2753 +    fprintf(fp_cpp, "      to[i] = _opnds[i]->clone(C);\n");
  1.2754 +    fprintf(fp_cpp, "  }\n");
  1.2755 +    fprintf(fp_cpp, "}\n");
  1.2756 +  }
  1.2757 +  fprintf(fp_cpp, "\n");
  1.2758 +}
  1.2759 +
  1.2760 +//------------------------------defineClasses----------------------------------
  1.2761 +// Define members of MachNode and MachOper classes based on
  1.2762 +// operand and instruction lists
  1.2763 +void ArchDesc::defineClasses(FILE *fp) {
  1.2764 +
  1.2765 +  // Define the contents of an array containing the machine register names
  1.2766 +  defineRegNames(fp, _register);
  1.2767 +  // Define an array containing the machine register encoding values
  1.2768 +  defineRegEncodes(fp, _register);
  1.2769 +  // Generate an enumeration of user-defined register classes
  1.2770 +  // and a list of register masks, one for each class.
  1.2771 +  // Only define the RegMask value objects in the expand file.
  1.2772 +  // Declare each as an extern const RegMask ...; in ad_<arch>.hpp
  1.2773 +  declare_register_masks(_HPP_file._fp);
  1.2774 +  // build_register_masks(fp);
  1.2775 +  build_register_masks(_CPP_EXPAND_file._fp);
  1.2776 +  // Define the pipe_classes
  1.2777 +  build_pipe_classes(_CPP_PIPELINE_file._fp);
  1.2778 +
  1.2779 +  // Generate Machine Classes for each operand defined in AD file
  1.2780 +  fprintf(fp,"\n");
  1.2781 +  fprintf(fp,"\n");
  1.2782 +  fprintf(fp,"//------------------Define classes derived from MachOper---------------------\n");
  1.2783 +  // Iterate through all operands
  1.2784 +  _operands.reset();
  1.2785 +  OperandForm *oper;
  1.2786 +  for( ; (oper = (OperandForm*)_operands.iter()) != NULL; ) {
  1.2787 +    // Ensure this is a machine-world instruction
  1.2788 +    if ( oper->ideal_only() ) continue;
  1.2789 +    // !!!!!
  1.2790 +    // The declaration of labelOper is in machine-independent file: machnode
  1.2791 +    if ( strcmp(oper->_ident,"label") == 0 ) {
  1.2792 +      defineIn_RegMask(_CPP_MISC_file._fp, _globalNames, *oper);
  1.2793 +
  1.2794 +      fprintf(fp,"MachOper  *%sOper::clone(Compile* C) const {\n", oper->_ident);
  1.2795 +      fprintf(fp,"  return  new (C) %sOper(_label, _block_num);\n", oper->_ident);
  1.2796 +      fprintf(fp,"}\n");
  1.2797 +
  1.2798 +      fprintf(fp,"uint %sOper::opcode() const { return %s; }\n",
  1.2799 +              oper->_ident, machOperEnum(oper->_ident));
  1.2800 +      // // Currently all XXXOper::Hash() methods are identical (990820)
  1.2801 +      // define_hash(fp, oper->_ident);
  1.2802 +      // // Currently all XXXOper::Cmp() methods are identical (990820)
  1.2803 +      // define_cmp(fp, oper->_ident);
  1.2804 +      fprintf(fp,"\n");
  1.2805 +
  1.2806 +      continue;
  1.2807 +    }
  1.2808 +
  1.2809 +    // The declaration of methodOper is in machine-independent file: machnode
  1.2810 +    if ( strcmp(oper->_ident,"method") == 0 ) {
  1.2811 +      defineIn_RegMask(_CPP_MISC_file._fp, _globalNames, *oper);
  1.2812 +
  1.2813 +      fprintf(fp,"MachOper  *%sOper::clone(Compile* C) const {\n", oper->_ident);
  1.2814 +      fprintf(fp,"  return  new (C) %sOper(_method);\n", oper->_ident);
  1.2815 +      fprintf(fp,"}\n");
  1.2816 +
  1.2817 +      fprintf(fp,"uint %sOper::opcode() const { return %s; }\n",
  1.2818 +              oper->_ident, machOperEnum(oper->_ident));
  1.2819 +      // // Currently all XXXOper::Hash() methods are identical (990820)
  1.2820 +      // define_hash(fp, oper->_ident);
  1.2821 +      // // Currently all XXXOper::Cmp() methods are identical (990820)
  1.2822 +      // define_cmp(fp, oper->_ident);
  1.2823 +      fprintf(fp,"\n");
  1.2824 +
  1.2825 +      continue;
  1.2826 +    }
  1.2827 +
  1.2828 +    defineIn_RegMask(fp, _globalNames, *oper);
  1.2829 +    defineClone(_CPP_CLONE_file._fp, _globalNames, *oper);
  1.2830 +    // // Currently all XXXOper::Hash() methods are identical (990820)
  1.2831 +    // define_hash(fp, oper->_ident);
  1.2832 +    // // Currently all XXXOper::Cmp() methods are identical (990820)
  1.2833 +    // define_cmp(fp, oper->_ident);
  1.2834 +
  1.2835 +    // side-call to generate output that used to be in the header file:
  1.2836 +    extern void gen_oper_format(FILE *fp, FormDict &globals, OperandForm &oper, bool for_c_file);
  1.2837 +    gen_oper_format(_CPP_FORMAT_file._fp, _globalNames, *oper, true);
  1.2838 +
  1.2839 +  }
  1.2840 +
  1.2841 +
  1.2842 +  // Generate Machine Classes for each instruction defined in AD file
  1.2843 +  fprintf(fp,"//------------------Define members for classes derived from MachNode----------\n");
  1.2844 +  // Output the definitions for out_RegMask() // & kill_RegMask()
  1.2845 +  _instructions.reset();
  1.2846 +  InstructForm *instr;
  1.2847 +  MachNodeForm *machnode;
  1.2848 +  for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
  1.2849 +    // Ensure this is a machine-world instruction
  1.2850 +    if ( instr->ideal_only() ) continue;
  1.2851 +
  1.2852 +    defineOut_RegMask(_CPP_MISC_file._fp, instr->_ident, reg_mask(*instr));
  1.2853 +  }
  1.2854 +
  1.2855 +  bool used = false;
  1.2856 +  // Output the definitions for expand rules & peephole rules
  1.2857 +  _instructions.reset();
  1.2858 +  for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
  1.2859 +    // Ensure this is a machine-world instruction
  1.2860 +    if ( instr->ideal_only() ) continue;
  1.2861 +    // If there are multiple defs/kills, or an explicit expand rule, build rule
  1.2862 +    if( instr->expands() || instr->needs_projections() ||
  1.2863 +        instr->has_temps() ||
  1.2864 +        instr->_matrule != NULL &&
  1.2865 +        instr->num_opnds() != instr->num_unique_opnds() )
  1.2866 +      defineExpand(_CPP_EXPAND_file._fp, instr);
  1.2867 +    // If there is an explicit peephole rule, build it
  1.2868 +    if ( instr->peepholes() )
  1.2869 +      definePeephole(_CPP_PEEPHOLE_file._fp, instr);
  1.2870 +
  1.2871 +    // Output code to convert to the cisc version, if applicable
  1.2872 +    used |= instr->define_cisc_version(*this, fp);
  1.2873 +
  1.2874 +    // Output code to convert to the short branch version, if applicable
  1.2875 +    used |= instr->define_short_branch_methods(fp);
  1.2876 +  }
  1.2877 +
  1.2878 +  // Construct the method called by cisc_version() to copy inputs and operands.
  1.2879 +  define_fill_new_machnode(used, fp);
  1.2880 +
  1.2881 +  // Output the definitions for labels
  1.2882 +  _instructions.reset();
  1.2883 +  while( (instr = (InstructForm*)_instructions.iter()) != NULL ) {
  1.2884 +    // Ensure this is a machine-world instruction
  1.2885 +    if ( instr->ideal_only() ) continue;
  1.2886 +
  1.2887 +    // Access the fields for operand Label
  1.2888 +    int label_position = instr->label_position();
  1.2889 +    if( label_position != -1 ) {
  1.2890 +      // Set the label
  1.2891 +      fprintf(fp,"void %sNode::label_set( Label& label, uint block_num ) {\n", instr->_ident);
  1.2892 +      fprintf(fp,"  labelOper* oper  = (labelOper*)(opnd_array(%d));\n",
  1.2893 +              label_position );
  1.2894 +      fprintf(fp,"  oper->_label     = &label;\n");
  1.2895 +      fprintf(fp,"  oper->_block_num = block_num;\n");
  1.2896 +      fprintf(fp,"}\n");
  1.2897 +    }
  1.2898 +  }
  1.2899 +
  1.2900 +  // Output the definitions for methods
  1.2901 +  _instructions.reset();
  1.2902 +  while( (instr = (InstructForm*)_instructions.iter()) != NULL ) {
  1.2903 +    // Ensure this is a machine-world instruction
  1.2904 +    if ( instr->ideal_only() ) continue;
  1.2905 +
  1.2906 +    // Access the fields for operand Label
  1.2907 +    int method_position = instr->method_position();
  1.2908 +    if( method_position != -1 ) {
  1.2909 +      // Access the method's address
  1.2910 +      fprintf(fp,"void %sNode::method_set( intptr_t method ) {\n", instr->_ident);
  1.2911 +      fprintf(fp,"  ((methodOper*)opnd_array(%d))->_method = method;\n",
  1.2912 +              method_position );
  1.2913 +      fprintf(fp,"}\n");
  1.2914 +      fprintf(fp,"\n");
  1.2915 +    }
  1.2916 +  }
  1.2917 +
  1.2918 +  // Define this instruction's number of relocation entries, base is '0'
  1.2919 +  _instructions.reset();
  1.2920 +  while( (instr = (InstructForm*)_instructions.iter()) != NULL ) {
  1.2921 +    // Output the definition for number of relocation entries
  1.2922 +    uint reloc_size = instr->reloc(_globalNames);
  1.2923 +    if ( reloc_size != 0 ) {
  1.2924 +      fprintf(fp,"int  %sNode::reloc()   const {\n", instr->_ident);
  1.2925 +      fprintf(fp,  "  return  %d;\n", reloc_size );
  1.2926 +      fprintf(fp,"}\n");
  1.2927 +      fprintf(fp,"\n");
  1.2928 +    }
  1.2929 +  }
  1.2930 +  fprintf(fp,"\n");
  1.2931 +
  1.2932 +  // Output the definitions for code generation
  1.2933 +  //
  1.2934 +  // address  ___Node::emit(address ptr, PhaseRegAlloc *ra_) const {
  1.2935 +  //   // ...  encoding defined by user
  1.2936 +  //   return ptr;
  1.2937 +  // }
  1.2938 +  //
  1.2939 +  _instructions.reset();
  1.2940 +  for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
  1.2941 +    // Ensure this is a machine-world instruction
  1.2942 +    if ( instr->ideal_only() ) continue;
  1.2943 +
  1.2944 +    if (instr->_insencode) defineEmit(fp, *instr);
  1.2945 +    if (instr->_size)      defineSize(fp, *instr);
  1.2946 +
  1.2947 +    // side-call to generate output that used to be in the header file:
  1.2948 +    extern void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &oper, bool for_c_file);
  1.2949 +    gen_inst_format(_CPP_FORMAT_file._fp, _globalNames, *instr, true);
  1.2950 +  }
  1.2951 +
  1.2952 +  // Output the definitions for alias analysis
  1.2953 +  _instructions.reset();
  1.2954 +  for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
  1.2955 +    // Ensure this is a machine-world instruction
  1.2956 +    if ( instr->ideal_only() ) continue;
  1.2957 +
  1.2958 +    // Analyze machine instructions that either USE or DEF memory.
  1.2959 +    int memory_operand = instr->memory_operand(_globalNames);
  1.2960 +    // Some guys kill all of memory
  1.2961 +    if ( instr->is_wide_memory_kill(_globalNames) ) {
  1.2962 +      memory_operand = InstructForm::MANY_MEMORY_OPERANDS;
  1.2963 +    }
  1.2964 +
  1.2965 +    if ( memory_operand != InstructForm::NO_MEMORY_OPERAND ) {
  1.2966 +      if( memory_operand == InstructForm::MANY_MEMORY_OPERANDS ) {
  1.2967 +        fprintf(fp,"const TypePtr *%sNode::adr_type() const { return TypePtr::BOTTOM; }\n", instr->_ident);
  1.2968 +        fprintf(fp,"const MachOper* %sNode::memory_operand() const { return (MachOper*)-1; }\n", instr->_ident);
  1.2969 +      } else {
  1.2970 +        fprintf(fp,"const MachOper* %sNode::memory_operand() const { return _opnds[%d]; }\n", instr->_ident, memory_operand);
  1.2971 +  }
  1.2972 +    }
  1.2973 +  }
  1.2974 +
  1.2975 +  // Get the length of the longest identifier
  1.2976 +  int max_ident_len = 0;
  1.2977 +  _instructions.reset();
  1.2978 +
  1.2979 +  for ( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
  1.2980 +    if (instr->_ins_pipe && _pipeline->_classlist.search(instr->_ins_pipe)) {
  1.2981 +      int ident_len = (int)strlen(instr->_ident);
  1.2982 +      if( max_ident_len < ident_len )
  1.2983 +        max_ident_len = ident_len;
  1.2984 +    }
  1.2985 +  }
  1.2986 +
  1.2987 +  // Emit specifically for Node(s)
  1.2988 +  fprintf(_CPP_PIPELINE_file._fp, "const Pipeline * %*s::pipeline_class() { return %s; }\n",
  1.2989 +    max_ident_len, "Node", _pipeline ? "(&pipeline_class_Zero_Instructions)" : "NULL");
  1.2990 +  fprintf(_CPP_PIPELINE_file._fp, "const Pipeline * %*s::pipeline() const { return %s; }\n",
  1.2991 +    max_ident_len, "Node", _pipeline ? "(&pipeline_class_Zero_Instructions)" : "NULL");
  1.2992 +  fprintf(_CPP_PIPELINE_file._fp, "\n");
  1.2993 +
  1.2994 +  fprintf(_CPP_PIPELINE_file._fp, "const Pipeline * %*s::pipeline_class() { return %s; }\n",
  1.2995 +    max_ident_len, "MachNode", _pipeline ? "(&pipeline_class_Unknown_Instructions)" : "NULL");
  1.2996 +  fprintf(_CPP_PIPELINE_file._fp, "const Pipeline * %*s::pipeline() const { return pipeline_class(); }\n",
  1.2997 +    max_ident_len, "MachNode");
  1.2998 +  fprintf(_CPP_PIPELINE_file._fp, "\n");
  1.2999 +
  1.3000 +  // Output the definitions for machine node specific pipeline data
  1.3001 +  _machnodes.reset();
  1.3002 +
  1.3003 +  for ( ; (machnode = (MachNodeForm*)_machnodes.iter()) != NULL; ) {
  1.3004 +    fprintf(_CPP_PIPELINE_file._fp, "const Pipeline * %sNode::pipeline() const { return (&pipeline_class_%03d); }\n",
  1.3005 +      machnode->_ident, ((class PipeClassForm *)_pipeline->_classdict[machnode->_machnode_pipe])->_num);
  1.3006 +  }
  1.3007 +
  1.3008 +  fprintf(_CPP_PIPELINE_file._fp, "\n");
  1.3009 +
  1.3010 +  // Output the definitions for instruction pipeline static data references
  1.3011 +  _instructions.reset();
  1.3012 +
  1.3013 +  for ( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
  1.3014 +    if (instr->_ins_pipe && _pipeline->_classlist.search(instr->_ins_pipe)) {
  1.3015 +      fprintf(_CPP_PIPELINE_file._fp, "\n");
  1.3016 +      fprintf(_CPP_PIPELINE_file._fp, "const Pipeline * %*sNode::pipeline_class() { return (&pipeline_class_%03d); }\n",
  1.3017 +        max_ident_len, instr->_ident, ((class PipeClassForm *)_pipeline->_classdict[instr->_ins_pipe])->_num);
  1.3018 +      fprintf(_CPP_PIPELINE_file._fp, "const Pipeline * %*sNode::pipeline() const { return (&pipeline_class_%03d); }\n",
  1.3019 +        max_ident_len, instr->_ident, ((class PipeClassForm *)_pipeline->_classdict[instr->_ins_pipe])->_num);
  1.3020 +    }
  1.3021 +  }
  1.3022 +}
  1.3023 +
  1.3024 +
  1.3025 +// -------------------------------- maps ------------------------------------
  1.3026 +
  1.3027 +// Information needed to generate the ReduceOp mapping for the DFA
  1.3028 +class OutputReduceOp : public OutputMap {
  1.3029 +public:
  1.3030 +  OutputReduceOp(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
  1.3031 +    : OutputMap(hpp, cpp, globals, AD) {};
  1.3032 +
  1.3033 +  void declaration() { fprintf(_hpp, "extern const int   reduceOp[];\n"); }
  1.3034 +  void definition()  { fprintf(_cpp, "const        int   reduceOp[] = {\n"); }
  1.3035 +  void closing()     { fprintf(_cpp, "  0 // no trailing comma\n");
  1.3036 +                       OutputMap::closing();
  1.3037 +  }
  1.3038 +  void map(OpClassForm &opc)  {
  1.3039 +    const char *reduce = opc._ident;
  1.3040 +    if( reduce )  fprintf(_cpp, "  %s_rule", reduce);
  1.3041 +    else          fprintf(_cpp, "  0");
  1.3042 +  }
  1.3043 +  void map(OperandForm &oper) {
  1.3044 +    // Most operands without match rules, e.g.  eFlagsReg, do not have a result operand
  1.3045 +    const char *reduce = (oper._matrule ? oper.reduce_result() : NULL);
  1.3046 +    // operand stackSlot does not have a match rule, but produces a stackSlot
  1.3047 +    if( oper.is_user_name_for_sReg() != Form::none ) reduce = oper.reduce_result();
  1.3048 +    if( reduce )  fprintf(_cpp, "  %s_rule", reduce);
  1.3049 +    else          fprintf(_cpp, "  0");
  1.3050 +  }
  1.3051 +  void map(InstructForm &inst) {
  1.3052 +    const char *reduce = (inst._matrule ? inst.reduce_result() : NULL);
  1.3053 +    if( reduce )  fprintf(_cpp, "  %s_rule", reduce);
  1.3054 +    else          fprintf(_cpp, "  0");
  1.3055 +  }
  1.3056 +  void map(char         *reduce) {
  1.3057 +    if( reduce )  fprintf(_cpp, "  %s_rule", reduce);
  1.3058 +    else          fprintf(_cpp, "  0");
  1.3059 +  }
  1.3060 +};
  1.3061 +
  1.3062 +// Information needed to generate the LeftOp mapping for the DFA
  1.3063 +class OutputLeftOp : public OutputMap {
  1.3064 +public:
  1.3065 +  OutputLeftOp(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
  1.3066 +    : OutputMap(hpp, cpp, globals, AD) {};
  1.3067 +
  1.3068 +  void declaration() { fprintf(_hpp, "extern const int   leftOp[];\n"); }
  1.3069 +  void definition()  { fprintf(_cpp, "const        int   leftOp[] = {\n"); }
  1.3070 +  void closing()     { fprintf(_cpp, "  0 // no trailing comma\n");
  1.3071 +                       OutputMap::closing();
  1.3072 +  }
  1.3073 +  void map(OpClassForm &opc)  { fprintf(_cpp, "  0"); }
  1.3074 +  void map(OperandForm &oper) {
  1.3075 +    const char *reduce = oper.reduce_left(_globals);
  1.3076 +    if( reduce )  fprintf(_cpp, "  %s_rule", reduce);
  1.3077 +    else          fprintf(_cpp, "  0");
  1.3078 +  }
  1.3079 +  void map(char        *name) {
  1.3080 +    const char *reduce = _AD.reduceLeft(name);
  1.3081 +    if( reduce )  fprintf(_cpp, "  %s_rule", reduce);
  1.3082 +    else          fprintf(_cpp, "  0");
  1.3083 +  }
  1.3084 +  void map(InstructForm &inst) {
  1.3085 +    const char *reduce = inst.reduce_left(_globals);
  1.3086 +    if( reduce )  fprintf(_cpp, "  %s_rule", reduce);
  1.3087 +    else          fprintf(_cpp, "  0");
  1.3088 +  }
  1.3089 +};
  1.3090 +
  1.3091 +
  1.3092 +// Information needed to generate the RightOp mapping for the DFA
  1.3093 +class OutputRightOp : public OutputMap {
  1.3094 +public:
  1.3095 +  OutputRightOp(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
  1.3096 +    : OutputMap(hpp, cpp, globals, AD) {};
  1.3097 +
  1.3098 +  void declaration() { fprintf(_hpp, "extern const int   rightOp[];\n"); }
  1.3099 +  void definition()  { fprintf(_cpp, "const        int   rightOp[] = {\n"); }
  1.3100 +  void closing()     { fprintf(_cpp, "  0 // no trailing comma\n");
  1.3101 +                       OutputMap::closing();
  1.3102 +  }
  1.3103 +  void map(OpClassForm &opc)  { fprintf(_cpp, "  0"); }
  1.3104 +  void map(OperandForm &oper) {
  1.3105 +    const char *reduce = oper.reduce_right(_globals);
  1.3106 +    if( reduce )  fprintf(_cpp, "  %s_rule", reduce);
  1.3107 +    else          fprintf(_cpp, "  0");
  1.3108 +  }
  1.3109 +  void map(char        *name) {
  1.3110 +    const char *reduce = _AD.reduceRight(name);
  1.3111 +    if( reduce )  fprintf(_cpp, "  %s_rule", reduce);
  1.3112 +    else          fprintf(_cpp, "  0");
  1.3113 +  }
  1.3114 +  void map(InstructForm &inst) {
  1.3115 +    const char *reduce = inst.reduce_right(_globals);
  1.3116 +    if( reduce )  fprintf(_cpp, "  %s_rule", reduce);
  1.3117 +    else          fprintf(_cpp, "  0");
  1.3118 +  }
  1.3119 +};
  1.3120 +
  1.3121 +
  1.3122 +// Information needed to generate the Rule names for the DFA
  1.3123 +class OutputRuleName : public OutputMap {
  1.3124 +public:
  1.3125 +  OutputRuleName(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
  1.3126 +    : OutputMap(hpp, cpp, globals, AD) {};
  1.3127 +
  1.3128 +  void declaration() { fprintf(_hpp, "extern const char *ruleName[];\n"); }
  1.3129 +  void definition()  { fprintf(_cpp, "const char        *ruleName[] = {\n"); }
  1.3130 +  void closing()     { fprintf(_cpp, "  \"no trailing comma\"\n");
  1.3131 +                       OutputMap::closing();
  1.3132 +  }
  1.3133 +  void map(OpClassForm &opc)  { fprintf(_cpp, "  \"%s\"", _AD.machOperEnum(opc._ident) ); }
  1.3134 +  void map(OperandForm &oper) { fprintf(_cpp, "  \"%s\"", _AD.machOperEnum(oper._ident) ); }
  1.3135 +  void map(char        *name) { fprintf(_cpp, "  \"%s\"", name ? name : "0"); }
  1.3136 +  void map(InstructForm &inst){ fprintf(_cpp, "  \"%s\"", inst._ident ? inst._ident : "0"); }
  1.3137 +};
  1.3138 +
  1.3139 +
  1.3140 +// Information needed to generate the swallowed mapping for the DFA
  1.3141 +class OutputSwallowed : public OutputMap {
  1.3142 +public:
  1.3143 +  OutputSwallowed(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
  1.3144 +    : OutputMap(hpp, cpp, globals, AD) {};
  1.3145 +
  1.3146 +  void declaration() { fprintf(_hpp, "extern const bool  swallowed[];\n"); }
  1.3147 +  void definition()  { fprintf(_cpp, "const        bool  swallowed[] = {\n"); }
  1.3148 +  void closing()     { fprintf(_cpp, "  false // no trailing comma\n");
  1.3149 +                       OutputMap::closing();
  1.3150 +  }
  1.3151 +  void map(OperandForm &oper) { // Generate the entry for this opcode
  1.3152 +    const char *swallowed = oper.swallowed(_globals) ? "true" : "false";
  1.3153 +    fprintf(_cpp, "  %s", swallowed);
  1.3154 +  }
  1.3155 +  void map(OpClassForm &opc)  { fprintf(_cpp, "  false"); }
  1.3156 +  void map(char        *name) { fprintf(_cpp, "  false"); }
  1.3157 +  void map(InstructForm &inst){ fprintf(_cpp, "  false"); }
  1.3158 +};
  1.3159 +
  1.3160 +
  1.3161 +// Information needed to generate the decision array for instruction chain rule
  1.3162 +class OutputInstChainRule : public OutputMap {
  1.3163 +public:
  1.3164 +  OutputInstChainRule(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
  1.3165 +    : OutputMap(hpp, cpp, globals, AD) {};
  1.3166 +
  1.3167 +  void declaration() { fprintf(_hpp, "extern const bool  instruction_chain_rule[];\n"); }
  1.3168 +  void definition()  { fprintf(_cpp, "const        bool  instruction_chain_rule[] = {\n"); }
  1.3169 +  void closing()     { fprintf(_cpp, "  false // no trailing comma\n");
  1.3170 +                       OutputMap::closing();
  1.3171 +  }
  1.3172 +  void map(OpClassForm &opc)   { fprintf(_cpp, "  false"); }
  1.3173 +  void map(OperandForm &oper)  { fprintf(_cpp, "  false"); }
  1.3174 +  void map(char        *name)  { fprintf(_cpp, "  false"); }
  1.3175 +  void map(InstructForm &inst) { // Check for simple chain rule
  1.3176 +    const char *chain = inst.is_simple_chain_rule(_globals) ? "true" : "false";
  1.3177 +    fprintf(_cpp, "  %s", chain);
  1.3178 +  }
  1.3179 +};
  1.3180 +
  1.3181 +
  1.3182 +//---------------------------build_map------------------------------------
  1.3183 +// Build  mapping from enumeration for densely packed operands
  1.3184 +// TO result and child types.
  1.3185 +void ArchDesc::build_map(OutputMap &map) {
  1.3186 +  FILE         *fp_hpp = map.decl_file();
  1.3187 +  FILE         *fp_cpp = map.def_file();
  1.3188 +  int           idx    = 0;
  1.3189 +  OperandForm  *op;
  1.3190 +  OpClassForm  *opc;
  1.3191 +  InstructForm *inst;
  1.3192 +
  1.3193 +  // Construct this mapping
  1.3194 +  map.declaration();
  1.3195 +  fprintf(fp_cpp,"\n");
  1.3196 +  map.definition();
  1.3197 +
  1.3198 +  // Output the mapping for operands
  1.3199 +  map.record_position(OutputMap::BEGIN_OPERANDS, idx );
  1.3200 +  _operands.reset();
  1.3201 +  for(; (op = (OperandForm*)_operands.iter()) != NULL; ) {
  1.3202 +    // Ensure this is a machine-world instruction
  1.3203 +    if ( op->ideal_only() )  continue;
  1.3204 +
  1.3205 +    // Generate the entry for this opcode
  1.3206 +    map.map(*op);    fprintf(fp_cpp, ", // %d\n", idx);
  1.3207 +    ++idx;
  1.3208 +  };
  1.3209 +  fprintf(fp_cpp, "  // last operand\n");
  1.3210 +
  1.3211 +  // Place all user-defined operand classes into the mapping
  1.3212 +  map.record_position(OutputMap::BEGIN_OPCLASSES, idx );
  1.3213 +  _opclass.reset();
  1.3214 +  for(; (opc = (OpClassForm*)_opclass.iter()) != NULL; ) {
  1.3215 +    map.map(*opc);    fprintf(fp_cpp, ", // %d\n", idx);
  1.3216 +    ++idx;
  1.3217 +  };
  1.3218 +  fprintf(fp_cpp, "  // last operand class\n");
  1.3219 +
  1.3220 +  // Place all internally defined operands into the mapping
  1.3221 +  map.record_position(OutputMap::BEGIN_INTERNALS, idx );
  1.3222 +  _internalOpNames.reset();
  1.3223 +  char *name = NULL;
  1.3224 +  for(; (name = (char *)_internalOpNames.iter()) != NULL; ) {
  1.3225 +    map.map(name);    fprintf(fp_cpp, ", // %d\n", idx);
  1.3226 +    ++idx;
  1.3227 +  };
  1.3228 +  fprintf(fp_cpp, "  // last internally defined operand\n");
  1.3229 +
  1.3230 +  // Place all user-defined instructions into the mapping
  1.3231 +  if( map.do_instructions() ) {
  1.3232 +    map.record_position(OutputMap::BEGIN_INSTRUCTIONS, idx );
  1.3233 +    // Output all simple instruction chain rules first
  1.3234 +    map.record_position(OutputMap::BEGIN_INST_CHAIN_RULES, idx );
  1.3235 +    {
  1.3236 +      _instructions.reset();
  1.3237 +      for(; (inst = (InstructForm*)_instructions.iter()) != NULL; ) {
  1.3238 +        // Ensure this is a machine-world instruction
  1.3239 +        if ( inst->ideal_only() )  continue;
  1.3240 +        if ( ! inst->is_simple_chain_rule(_globalNames) ) continue;
  1.3241 +        if ( inst->rematerialize(_globalNames, get_registers()) ) continue;
  1.3242 +
  1.3243 +        map.map(*inst);      fprintf(fp_cpp, ", // %d\n", idx);
  1.3244 +        ++idx;
  1.3245 +      };
  1.3246 +      map.record_position(OutputMap::BEGIN_REMATERIALIZE, idx );
  1.3247 +      _instructions.reset();
  1.3248 +      for(; (inst = (InstructForm*)_instructions.iter()) != NULL; ) {
  1.3249 +        // Ensure this is a machine-world instruction
  1.3250 +        if ( inst->ideal_only() )  continue;
  1.3251 +        if ( ! inst->is_simple_chain_rule(_globalNames) ) continue;
  1.3252 +        if ( ! inst->rematerialize(_globalNames, get_registers()) ) continue;
  1.3253 +
  1.3254 +        map.map(*inst);      fprintf(fp_cpp, ", // %d\n", idx);
  1.3255 +        ++idx;
  1.3256 +      };
  1.3257 +      map.record_position(OutputMap::END_INST_CHAIN_RULES, idx );
  1.3258 +    }
  1.3259 +    // Output all instructions that are NOT simple chain rules
  1.3260 +    {
  1.3261 +      _instructions.reset();
  1.3262 +      for(; (inst = (InstructForm*)_instructions.iter()) != NULL; ) {
  1.3263 +        // Ensure this is a machine-world instruction
  1.3264 +        if ( inst->ideal_only() )  continue;
  1.3265 +        if ( inst->is_simple_chain_rule(_globalNames) ) continue;
  1.3266 +        if ( ! inst->rematerialize(_globalNames, get_registers()) ) continue;
  1.3267 +
  1.3268 +        map.map(*inst);      fprintf(fp_cpp, ", // %d\n", idx);
  1.3269 +        ++idx;
  1.3270 +      };
  1.3271 +      map.record_position(OutputMap::END_REMATERIALIZE, idx );
  1.3272 +      _instructions.reset();
  1.3273 +      for(; (inst = (InstructForm*)_instructions.iter()) != NULL; ) {
  1.3274 +        // Ensure this is a machine-world instruction
  1.3275 +        if ( inst->ideal_only() )  continue;
  1.3276 +        if ( inst->is_simple_chain_rule(_globalNames) ) continue;
  1.3277 +        if ( inst->rematerialize(_globalNames, get_registers()) ) continue;
  1.3278 +
  1.3279 +        map.map(*inst);      fprintf(fp_cpp, ", // %d\n", idx);
  1.3280 +        ++idx;
  1.3281 +      };
  1.3282 +    }
  1.3283 +    fprintf(fp_cpp, "  // last instruction\n");
  1.3284 +    map.record_position(OutputMap::END_INSTRUCTIONS, idx );
  1.3285 +  }
  1.3286 +  // Finish defining table
  1.3287 +  map.closing();
  1.3288 +};
  1.3289 +
  1.3290 +
  1.3291 +// Helper function for buildReduceMaps
  1.3292 +char reg_save_policy(const char *calling_convention) {
  1.3293 +  char callconv;
  1.3294 +
  1.3295 +  if      (!strcmp(calling_convention, "NS"))  callconv = 'N';
  1.3296 +  else if (!strcmp(calling_convention, "SOE")) callconv = 'E';
  1.3297 +  else if (!strcmp(calling_convention, "SOC")) callconv = 'C';
  1.3298 +  else if (!strcmp(calling_convention, "AS"))  callconv = 'A';
  1.3299 +  else                                         callconv = 'Z';
  1.3300 +
  1.3301 +  return callconv;
  1.3302 +}
  1.3303 +
  1.3304 +//---------------------------generate_assertion_checks-------------------
  1.3305 +void ArchDesc::generate_adlc_verification(FILE *fp_cpp) {
  1.3306 +  fprintf(fp_cpp, "\n");
  1.3307 +
  1.3308 +  fprintf(fp_cpp, "#ifndef PRODUCT\n");
  1.3309 +  fprintf(fp_cpp, "void Compile::adlc_verification() {\n");
  1.3310 +  globalDefs().print_asserts(fp_cpp);
  1.3311 +  fprintf(fp_cpp, "}\n");
  1.3312 +  fprintf(fp_cpp, "#endif\n");
  1.3313 +  fprintf(fp_cpp, "\n");
  1.3314 +}
  1.3315 +
  1.3316 +//---------------------------addSourceBlocks-----------------------------
  1.3317 +void ArchDesc::addSourceBlocks(FILE *fp_cpp) {
  1.3318 +  if (_source.count() > 0)
  1.3319 +    _source.output(fp_cpp);
  1.3320 +
  1.3321 +  generate_adlc_verification(fp_cpp);
  1.3322 +}
  1.3323 +//---------------------------addHeaderBlocks-----------------------------
  1.3324 +void ArchDesc::addHeaderBlocks(FILE *fp_hpp) {
  1.3325 +  if (_header.count() > 0)
  1.3326 +    _header.output(fp_hpp);
  1.3327 +}
  1.3328 +//-------------------------addPreHeaderBlocks----------------------------
  1.3329 +void ArchDesc::addPreHeaderBlocks(FILE *fp_hpp) {
  1.3330 +  // Output #defines from definition block
  1.3331 +  globalDefs().print_defines(fp_hpp);
  1.3332 +
  1.3333 +  if (_pre_header.count() > 0)
  1.3334 +    _pre_header.output(fp_hpp);
  1.3335 +}
  1.3336 +
  1.3337 +//---------------------------buildReduceMaps-----------------------------
  1.3338 +// Build  mapping from enumeration for densely packed operands
  1.3339 +// TO result and child types.
  1.3340 +void ArchDesc::buildReduceMaps(FILE *fp_hpp, FILE *fp_cpp) {
  1.3341 +  RegDef       *rdef;
  1.3342 +  RegDef       *next;
  1.3343 +
  1.3344 +  // The emit bodies currently require functions defined in the source block.
  1.3345 +
  1.3346 +  // Build external declarations for mappings
  1.3347 +  fprintf(fp_hpp, "\n");
  1.3348 +  fprintf(fp_hpp, "extern const char  register_save_policy[];\n");
  1.3349 +  fprintf(fp_hpp, "extern const char  c_reg_save_policy[];\n");
  1.3350 +  fprintf(fp_hpp, "extern const int   register_save_type[];\n");
  1.3351 +  fprintf(fp_hpp, "\n");
  1.3352 +
  1.3353 +  // Construct Save-Policy array
  1.3354 +  fprintf(fp_cpp, "// Map from machine-independent register number to register_save_policy\n");
  1.3355 +  fprintf(fp_cpp, "const        char register_save_policy[] = {\n");
  1.3356 +  _register->reset_RegDefs();
  1.3357 +  for( rdef = _register->iter_RegDefs(); rdef != NULL; rdef = next ) {
  1.3358 +    next              = _register->iter_RegDefs();
  1.3359 +    char policy       = reg_save_policy(rdef->_callconv);
  1.3360 +    const char *comma = (next != NULL) ? "," : " // no trailing comma";
  1.3361 +    fprintf(fp_cpp, "  '%c'%s\n", policy, comma);
  1.3362 +  }
  1.3363 +  fprintf(fp_cpp, "};\n\n");
  1.3364 +
  1.3365 +  // Construct Native Save-Policy array
  1.3366 +  fprintf(fp_cpp, "// Map from machine-independent register number to c_reg_save_policy\n");
  1.3367 +  fprintf(fp_cpp, "const        char c_reg_save_policy[] = {\n");
  1.3368 +  _register->reset_RegDefs();
  1.3369 +  for( rdef = _register->iter_RegDefs(); rdef != NULL; rdef = next ) {
  1.3370 +    next        = _register->iter_RegDefs();
  1.3371 +    char policy = reg_save_policy(rdef->_c_conv);
  1.3372 +    const char *comma = (next != NULL) ? "," : " // no trailing comma";
  1.3373 +    fprintf(fp_cpp, "  '%c'%s\n", policy, comma);
  1.3374 +  }
  1.3375 +  fprintf(fp_cpp, "};\n\n");
  1.3376 +
  1.3377 +  // Construct Register Save Type array
  1.3378 +  fprintf(fp_cpp, "// Map from machine-independent register number to register_save_type\n");
  1.3379 +  fprintf(fp_cpp, "const        int register_save_type[] = {\n");
  1.3380 +  _register->reset_RegDefs();
  1.3381 +  for( rdef = _register->iter_RegDefs(); rdef != NULL; rdef = next ) {
  1.3382 +    next = _register->iter_RegDefs();
  1.3383 +    const char *comma = (next != NULL) ? "," : " // no trailing comma";
  1.3384 +    fprintf(fp_cpp, "  %s%s\n", rdef->_idealtype, comma);
  1.3385 +  }
  1.3386 +  fprintf(fp_cpp, "};\n\n");
  1.3387 +
  1.3388 +  // Construct the table for reduceOp
  1.3389 +  OutputReduceOp output_reduce_op(fp_hpp, fp_cpp, _globalNames, *this);
  1.3390 +  build_map(output_reduce_op);
  1.3391 +  // Construct the table for leftOp
  1.3392 +  OutputLeftOp output_left_op(fp_hpp, fp_cpp, _globalNames, *this);
  1.3393 +  build_map(output_left_op);
  1.3394 +  // Construct the table for rightOp
  1.3395 +  OutputRightOp output_right_op(fp_hpp, fp_cpp, _globalNames, *this);
  1.3396 +  build_map(output_right_op);
  1.3397 +  // Construct the table of rule names
  1.3398 +  OutputRuleName output_rule_name(fp_hpp, fp_cpp, _globalNames, *this);
  1.3399 +  build_map(output_rule_name);
  1.3400 +  // Construct the boolean table for subsumed operands
  1.3401 +  OutputSwallowed output_swallowed(fp_hpp, fp_cpp, _globalNames, *this);
  1.3402 +  build_map(output_swallowed);
  1.3403 +  // // // Preserve in case we decide to use this table instead of another
  1.3404 +  //// Construct the boolean table for instruction chain rules
  1.3405 +  //OutputInstChainRule output_inst_chain(fp_hpp, fp_cpp, _globalNames, *this);
  1.3406 +  //build_map(output_inst_chain);
  1.3407 +
  1.3408 +}
  1.3409 +
  1.3410 +
  1.3411 +//---------------------------buildMachOperGenerator---------------------------
  1.3412 +
  1.3413 +// Recurse through match tree, building path through corresponding state tree,
  1.3414 +// Until we reach the constant we are looking for.
  1.3415 +static void path_to_constant(FILE *fp, FormDict &globals,
  1.3416 +                             MatchNode *mnode, uint idx) {
  1.3417 +  if ( ! mnode) return;
  1.3418 +
  1.3419 +  unsigned    position = 0;
  1.3420 +  const char *result   = NULL;
  1.3421 +  const char *name     = NULL;
  1.3422 +  const char *optype   = NULL;
  1.3423 +
  1.3424 +  // Base Case: access constant in ideal node linked to current state node
  1.3425 +  // Each type of constant has its own access function
  1.3426 +  if ( (mnode->_lChild == NULL) && (mnode->_rChild == NULL)
  1.3427 +       && mnode->base_operand(position, globals, result, name, optype) ) {
  1.3428 +    if (         strcmp(optype,"ConI") == 0 ) {
  1.3429 +      fprintf(fp, "_leaf->get_int()");
  1.3430 +    } else if ( (strcmp(optype,"ConP") == 0) ) {
  1.3431 +      fprintf(fp, "_leaf->bottom_type()->is_ptr()");
  1.3432 +    } else if ( (strcmp(optype,"ConF") == 0) ) {
  1.3433 +      fprintf(fp, "_leaf->getf()");
  1.3434 +    } else if ( (strcmp(optype,"ConD") == 0) ) {
  1.3435 +      fprintf(fp, "_leaf->getd()");
  1.3436 +    } else if ( (strcmp(optype,"ConL") == 0) ) {
  1.3437 +      fprintf(fp, "_leaf->get_long()");
  1.3438 +    } else if ( (strcmp(optype,"Con")==0) ) {
  1.3439 +      // !!!!! - Update if adding a machine-independent constant type
  1.3440 +      fprintf(fp, "_leaf->get_int()");
  1.3441 +      assert( false, "Unsupported constant type, pointer or indefinite");
  1.3442 +    } else if ( (strcmp(optype,"Bool") == 0) ) {
  1.3443 +      fprintf(fp, "_leaf->as_Bool()->_test._test");
  1.3444 +    } else {
  1.3445 +      assert( false, "Unsupported constant type");
  1.3446 +    }
  1.3447 +    return;
  1.3448 +  }
  1.3449 +
  1.3450 +  // If constant is in left child, build path and recurse
  1.3451 +  uint lConsts = (mnode->_lChild) ? (mnode->_lChild->num_consts(globals) ) : 0;
  1.3452 +  uint rConsts = (mnode->_rChild) ? (mnode->_rChild->num_consts(globals) ) : 0;
  1.3453 +  if ( (mnode->_lChild) && (lConsts > idx) ) {
  1.3454 +    fprintf(fp, "_kids[0]->");
  1.3455 +    path_to_constant(fp, globals, mnode->_lChild, idx);
  1.3456 +    return;
  1.3457 +  }
  1.3458 +  // If constant is in right child, build path and recurse
  1.3459 +  if ( (mnode->_rChild) && (rConsts > (idx - lConsts) ) ) {
  1.3460 +    idx = idx - lConsts;
  1.3461 +    fprintf(fp, "_kids[1]->");
  1.3462 +    path_to_constant(fp, globals, mnode->_rChild, idx);
  1.3463 +    return;
  1.3464 +  }
  1.3465 +  assert( false, "ShouldNotReachHere()");
  1.3466 +}
  1.3467 +
  1.3468 +// Generate code that is executed when generating a specific Machine Operand
  1.3469 +static void genMachOperCase(FILE *fp, FormDict &globalNames, ArchDesc &AD,
  1.3470 +                            OperandForm &op) {
  1.3471 +  const char *opName         = op._ident;
  1.3472 +  const char *opEnumName     = AD.machOperEnum(opName);
  1.3473 +  uint        num_consts     = op.num_consts(globalNames);
  1.3474 +
  1.3475 +  // Generate the case statement for this opcode
  1.3476 +  fprintf(fp, "  case %s:", opEnumName);
  1.3477 +  fprintf(fp, "\n    return new (C) %sOper(", opName);
  1.3478 +  // Access parameters for constructor from the stat object
  1.3479 +  //
  1.3480 +  // Build access to condition code value
  1.3481 +  if ( (num_consts > 0) ) {
  1.3482 +    uint i = 0;
  1.3483 +    path_to_constant(fp, globalNames, op._matrule, i);
  1.3484 +    for ( i = 1; i < num_consts; ++i ) {
  1.3485 +      fprintf(fp, ", ");
  1.3486 +      path_to_constant(fp, globalNames, op._matrule, i);
  1.3487 +    }
  1.3488 +  }
  1.3489 +  fprintf(fp, " );\n");
  1.3490 +}
  1.3491 +
  1.3492 +
  1.3493 +// Build switch to invoke "new" MachNode or MachOper
  1.3494 +void ArchDesc::buildMachOperGenerator(FILE *fp_cpp) {
  1.3495 +  int idx = 0;
  1.3496 +
  1.3497 +  // Build switch to invoke 'new' for a specific MachOper
  1.3498 +  fprintf(fp_cpp, "\n");
  1.3499 +  fprintf(fp_cpp, "\n");
  1.3500 +  fprintf(fp_cpp,
  1.3501 +          "//------------------------- MachOper Generator ---------------\n");
  1.3502 +  fprintf(fp_cpp,
  1.3503 +          "// A switch statement on the dense-packed user-defined type system\n"
  1.3504 +          "// that invokes 'new' on the corresponding class constructor.\n");
  1.3505 +  fprintf(fp_cpp, "\n");
  1.3506 +  fprintf(fp_cpp, "MachOper *State::MachOperGenerator");
  1.3507 +  fprintf(fp_cpp, "(int opcode, Compile* C)");
  1.3508 +  fprintf(fp_cpp, "{\n");
  1.3509 +  fprintf(fp_cpp, "\n");
  1.3510 +  fprintf(fp_cpp, "  switch(opcode) {\n");
  1.3511 +
  1.3512 +  // Place all user-defined operands into the mapping
  1.3513 +  _operands.reset();
  1.3514 +  int  opIndex = 0;
  1.3515 +  OperandForm *op;
  1.3516 +  for( ; (op =  (OperandForm*)_operands.iter()) != NULL; ) {
  1.3517 +    // Ensure this is a machine-world instruction
  1.3518 +    if ( op->ideal_only() )  continue;
  1.3519 +
  1.3520 +    genMachOperCase(fp_cpp, _globalNames, *this, *op);
  1.3521 +  };
  1.3522 +
  1.3523 +  // Do not iterate over operand classes for the  operand generator!!!
  1.3524 +
  1.3525 +  // Place all internal operands into the mapping
  1.3526 +  _internalOpNames.reset();
  1.3527 +  const char *iopn;
  1.3528 +  for( ; (iopn =  _internalOpNames.iter()) != NULL; ) {
  1.3529 +    const char *opEnumName = machOperEnum(iopn);
  1.3530 +    // Generate the case statement for this opcode
  1.3531 +    fprintf(fp_cpp, "  case %s:", opEnumName);
  1.3532 +    fprintf(fp_cpp, "    return NULL;\n");
  1.3533 +  };
  1.3534 +
  1.3535 +  // Generate the default case for switch(opcode)
  1.3536 +  fprintf(fp_cpp, "  \n");
  1.3537 +  fprintf(fp_cpp, "  default:\n");
  1.3538 +  fprintf(fp_cpp, "    fprintf(stderr, \"Default MachOper Generator invoked for: \\n\");\n");
  1.3539 +  fprintf(fp_cpp, "    fprintf(stderr, \"   opcode = %cd\\n\", opcode);\n", '%');
  1.3540 +  fprintf(fp_cpp, "    break;\n");
  1.3541 +  fprintf(fp_cpp, "  }\n");
  1.3542 +
  1.3543 +  // Generate the closing for method Matcher::MachOperGenerator
  1.3544 +  fprintf(fp_cpp, "  return NULL;\n");
  1.3545 +  fprintf(fp_cpp, "};\n");
  1.3546 +}
  1.3547 +
  1.3548 +
  1.3549 +//---------------------------buildMachNode-------------------------------------
  1.3550 +// Build a new MachNode, for MachNodeGenerator or cisc-spilling
  1.3551 +void ArchDesc::buildMachNode(FILE *fp_cpp, InstructForm *inst, const char *indent) {
  1.3552 +  const char *opType  = NULL;
  1.3553 +  const char *opClass = inst->_ident;
  1.3554 +
  1.3555 +  // Create the MachNode object
  1.3556 +  fprintf(fp_cpp, "%s %sNode *node = new (C) %sNode();\n",indent, opClass,opClass);
  1.3557 +
  1.3558 +  if ( (inst->num_post_match_opnds() != 0) ) {
  1.3559 +    // Instruction that contains operands which are not in match rule.
  1.3560 +    //
  1.3561 +    // Check if the first post-match component may be an interesting def
  1.3562 +    bool           dont_care = false;
  1.3563 +    ComponentList &comp_list = inst->_components;
  1.3564 +    Component     *comp      = NULL;
  1.3565 +    comp_list.reset();
  1.3566 +    if ( comp_list.match_iter() != NULL )    dont_care = true;
  1.3567 +
  1.3568 +    // Insert operands that are not in match-rule.
  1.3569 +    // Only insert a DEF if the do_care flag is set
  1.3570 +    comp_list.reset();
  1.3571 +    while ( comp = comp_list.post_match_iter() ) {
  1.3572 +      // Check if we don't care about DEFs or KILLs that are not USEs
  1.3573 +      if ( dont_care && (! comp->isa(Component::USE)) ) {
  1.3574 +        continue;
  1.3575 +      }
  1.3576 +      dont_care = true;
  1.3577 +      // For each operand not in the match rule, call MachOperGenerator
  1.3578 +      // with the enum for the opcode that needs to be built
  1.3579 +      // and the node just built, the parent of the operand.
  1.3580 +      ComponentList clist = inst->_components;
  1.3581 +      int         index  = clist.operand_position(comp->_name, comp->_usedef);
  1.3582 +      const char *opcode = machOperEnum(comp->_type);
  1.3583 +      const char *parent = "node";
  1.3584 +      fprintf(fp_cpp, "%s node->set_opnd_array(%d, ", indent, index);
  1.3585 +      fprintf(fp_cpp, "MachOperGenerator(%s, C));\n", opcode);
  1.3586 +      }
  1.3587 +  }
  1.3588 +  else if ( inst->is_chain_of_constant(_globalNames, opType) ) {
  1.3589 +    // An instruction that chains from a constant!
  1.3590 +    // In this case, we need to subsume the constant into the node
  1.3591 +    // at operand position, oper_input_base().
  1.3592 +    //
  1.3593 +    // Fill in the constant
  1.3594 +    fprintf(fp_cpp, "%s node->_opnd_array[%d] = ", indent,
  1.3595 +            inst->oper_input_base(_globalNames));
  1.3596 +    // #####
  1.3597 +    // Check for multiple constants and then fill them in.
  1.3598 +    // Just like MachOperGenerator
  1.3599 +    const char *opName = inst->_matrule->_rChild->_opType;
  1.3600 +    fprintf(fp_cpp, "new (C) %sOper(", opName);
  1.3601 +    // Grab operand form
  1.3602 +    OperandForm *op = (_globalNames[opName])->is_operand();
  1.3603 +    // Look up the number of constants
  1.3604 +    uint num_consts = op->num_consts(_globalNames);
  1.3605 +    if ( (num_consts > 0) ) {
  1.3606 +      uint i = 0;
  1.3607 +      path_to_constant(fp_cpp, _globalNames, op->_matrule, i);
  1.3608 +      for ( i = 1; i < num_consts; ++i ) {
  1.3609 +        fprintf(fp_cpp, ", ");
  1.3610 +        path_to_constant(fp_cpp, _globalNames, op->_matrule, i);
  1.3611 +      }
  1.3612 +    }
  1.3613 +    fprintf(fp_cpp, " );\n");
  1.3614 +    // #####
  1.3615 +  }
  1.3616 +
  1.3617 +  // Fill in the bottom_type where requested
  1.3618 +  if ( inst->captures_bottom_type() ) {
  1.3619 +    fprintf(fp_cpp, "%s node->_bottom_type = _leaf->bottom_type();\n", indent);
  1.3620 +  }
  1.3621 +  if( inst->is_ideal_if() ) {
  1.3622 +    fprintf(fp_cpp, "%s node->_prob = _leaf->as_If()->_prob;\n", indent);
  1.3623 +    fprintf(fp_cpp, "%s node->_fcnt = _leaf->as_If()->_fcnt;\n", indent);
  1.3624 +  }
  1.3625 +  if( inst->is_ideal_fastlock() ) {
  1.3626 +    fprintf(fp_cpp, "%s node->_counters = _leaf->as_FastLock()->counters();\n", indent);
  1.3627 +  }
  1.3628 +
  1.3629 +}
  1.3630 +
  1.3631 +//---------------------------declare_cisc_version------------------------------
  1.3632 +// Build CISC version of this instruction
  1.3633 +void InstructForm::declare_cisc_version(ArchDesc &AD, FILE *fp_hpp) {
  1.3634 +  if( AD.can_cisc_spill() ) {
  1.3635 +    InstructForm *inst_cisc = cisc_spill_alternate();
  1.3636 +    if (inst_cisc != NULL) {
  1.3637 +      fprintf(fp_hpp, "  virtual int            cisc_operand() const { return %d; }\n", cisc_spill_operand());
  1.3638 +      fprintf(fp_hpp, "  virtual MachNode      *cisc_version(int offset, Compile* C);\n");
  1.3639 +      fprintf(fp_hpp, "  virtual void           use_cisc_RegMask();\n");
  1.3640 +      fprintf(fp_hpp, "  virtual const RegMask *cisc_RegMask() const { return _cisc_RegMask; }\n");
  1.3641 +    }
  1.3642 +  }
  1.3643 +}
  1.3644 +
  1.3645 +//---------------------------define_cisc_version-------------------------------
  1.3646 +// Build CISC version of this instruction
  1.3647 +bool InstructForm::define_cisc_version(ArchDesc &AD, FILE *fp_cpp) {
  1.3648 +  InstructForm *inst_cisc = this->cisc_spill_alternate();
  1.3649 +  if( AD.can_cisc_spill() && (inst_cisc != NULL) ) {
  1.3650 +    const char   *name      = inst_cisc->_ident;
  1.3651 +    assert( inst_cisc->num_opnds() == this->num_opnds(), "Must have same number of operands");
  1.3652 +    OperandForm *cisc_oper = AD.cisc_spill_operand();
  1.3653 +    assert( cisc_oper != NULL, "insanity check");
  1.3654 +    const char *cisc_oper_name  = cisc_oper->_ident;
  1.3655 +    assert( cisc_oper_name != NULL, "insanity check");
  1.3656 +    //
  1.3657 +    // Set the correct reg_mask_or_stack for the cisc operand
  1.3658 +    fprintf(fp_cpp, "\n");
  1.3659 +    fprintf(fp_cpp, "void %sNode::use_cisc_RegMask() {\n", this->_ident);
  1.3660 +    // Lookup the correct reg_mask_or_stack
  1.3661 +    const char *reg_mask_name = cisc_reg_mask_name();
  1.3662 +    fprintf(fp_cpp, "  _cisc_RegMask = &STACK_OR_%s;\n", reg_mask_name);
  1.3663 +    fprintf(fp_cpp, "}\n");
  1.3664 +    //
  1.3665 +    // Construct CISC version of this instruction
  1.3666 +    fprintf(fp_cpp, "\n");
  1.3667 +    fprintf(fp_cpp, "// Build CISC version of this instruction\n");
  1.3668 +    fprintf(fp_cpp, "MachNode *%sNode::cisc_version( int offset, Compile* C ) {\n", this->_ident);
  1.3669 +    // Create the MachNode object
  1.3670 +    fprintf(fp_cpp, "  %sNode *node = new (C) %sNode();\n", name, name);
  1.3671 +    // Fill in the bottom_type where requested
  1.3672 +    if ( this->captures_bottom_type() ) {
  1.3673 +      fprintf(fp_cpp, "  node->_bottom_type = bottom_type();\n");
  1.3674 +    }
  1.3675 +    fprintf(fp_cpp, "\n");
  1.3676 +    fprintf(fp_cpp, "  // Copy _idx, inputs and operands to new node\n");
  1.3677 +    fprintf(fp_cpp, "  fill_new_machnode(node, C);\n");
  1.3678 +    // Construct operand to access [stack_pointer + offset]
  1.3679 +    fprintf(fp_cpp, "  // Construct operand to access [stack_pointer + offset]\n");
  1.3680 +    fprintf(fp_cpp, "  node->set_opnd_array(cisc_operand(), new (C) %sOper(offset));\n", cisc_oper_name);
  1.3681 +    fprintf(fp_cpp, "\n");
  1.3682 +
  1.3683 +    // Return result and exit scope
  1.3684 +    fprintf(fp_cpp, "  return node;\n");
  1.3685 +    fprintf(fp_cpp, "}\n");
  1.3686 +    fprintf(fp_cpp, "\n");
  1.3687 +    return true;
  1.3688 +  }
  1.3689 +  return false;
  1.3690 +}
  1.3691 +
  1.3692 +//---------------------------declare_short_branch_methods----------------------
  1.3693 +// Build prototypes for short branch methods
  1.3694 +void InstructForm::declare_short_branch_methods(FILE *fp_hpp) {
  1.3695 +  if (has_short_branch_form()) {
  1.3696 +    fprintf(fp_hpp, "  virtual MachNode      *short_branch_version(Compile* C);\n");
  1.3697 +  }
  1.3698 +}
  1.3699 +
  1.3700 +//---------------------------define_short_branch_methods-----------------------
  1.3701 +// Build definitions for short branch methods
  1.3702 +bool InstructForm::define_short_branch_methods(FILE *fp_cpp) {
  1.3703 +  if (has_short_branch_form()) {
  1.3704 +    InstructForm *short_branch = short_branch_form();
  1.3705 +    const char   *name         = short_branch->_ident;
  1.3706 +
  1.3707 +    // Construct short_branch_version() method.
  1.3708 +    fprintf(fp_cpp, "// Build short branch version of this instruction\n");
  1.3709 +    fprintf(fp_cpp, "MachNode *%sNode::short_branch_version(Compile* C) {\n", this->_ident);
  1.3710 +    // Create the MachNode object
  1.3711 +    fprintf(fp_cpp, "  %sNode *node = new (C) %sNode();\n", name, name);
  1.3712 +    if( is_ideal_if() ) {
  1.3713 +      fprintf(fp_cpp, "  node->_prob = _prob;\n");
  1.3714 +      fprintf(fp_cpp, "  node->_fcnt = _fcnt;\n");
  1.3715 +    }
  1.3716 +    // Fill in the bottom_type where requested
  1.3717 +    if ( this->captures_bottom_type() ) {
  1.3718 +      fprintf(fp_cpp, "  node->_bottom_type = bottom_type();\n");
  1.3719 +    }
  1.3720 +
  1.3721 +    fprintf(fp_cpp, "\n");
  1.3722 +    // Short branch version must use same node index for access
  1.3723 +    // through allocator's tables
  1.3724 +    fprintf(fp_cpp, "  // Copy _idx, inputs and operands to new node\n");
  1.3725 +    fprintf(fp_cpp, "  fill_new_machnode(node, C);\n");
  1.3726 +
  1.3727 +    // Return result and exit scope
  1.3728 +    fprintf(fp_cpp, "  return node;\n");
  1.3729 +    fprintf(fp_cpp, "}\n");
  1.3730 +    fprintf(fp_cpp,"\n");
  1.3731 +    return true;
  1.3732 +  }
  1.3733 +  return false;
  1.3734 +}
  1.3735 +
  1.3736 +
  1.3737 +//---------------------------buildMachNodeGenerator----------------------------
  1.3738 +// Build switch to invoke appropriate "new" MachNode for an opcode
  1.3739 +void ArchDesc::buildMachNodeGenerator(FILE *fp_cpp) {
  1.3740 +
  1.3741 +  // Build switch to invoke 'new' for a specific MachNode
  1.3742 +  fprintf(fp_cpp, "\n");
  1.3743 +  fprintf(fp_cpp, "\n");
  1.3744 +  fprintf(fp_cpp,
  1.3745 +          "//------------------------- MachNode Generator ---------------\n");
  1.3746 +  fprintf(fp_cpp,
  1.3747 +          "// A switch statement on the dense-packed user-defined type system\n"
  1.3748 +          "// that invokes 'new' on the corresponding class constructor.\n");
  1.3749 +  fprintf(fp_cpp, "\n");
  1.3750 +  fprintf(fp_cpp, "MachNode *State::MachNodeGenerator");
  1.3751 +  fprintf(fp_cpp, "(int opcode, Compile* C)");
  1.3752 +  fprintf(fp_cpp, "{\n");
  1.3753 +  fprintf(fp_cpp, "  switch(opcode) {\n");
  1.3754 +
  1.3755 +  // Provide constructor for all user-defined instructions
  1.3756 +  _instructions.reset();
  1.3757 +  int  opIndex = operandFormCount();
  1.3758 +  InstructForm *inst;
  1.3759 +  for( ; (inst = (InstructForm*)_instructions.iter()) != NULL; ) {
  1.3760 +    // Ensure that matrule is defined.
  1.3761 +    if ( inst->_matrule == NULL ) continue;
  1.3762 +
  1.3763 +    int         opcode  = opIndex++;
  1.3764 +    const char *opClass = inst->_ident;
  1.3765 +    char       *opType  = NULL;
  1.3766 +
  1.3767 +    // Generate the case statement for this instruction
  1.3768 +    fprintf(fp_cpp, "  case %s_rule:", opClass);
  1.3769 +
  1.3770 +    // Start local scope
  1.3771 +    fprintf(fp_cpp, "  {\n");
  1.3772 +    // Generate code to construct the new MachNode
  1.3773 +    buildMachNode(fp_cpp, inst, "     ");
  1.3774 +    // Return result and exit scope
  1.3775 +    fprintf(fp_cpp, "      return node;\n");
  1.3776 +    fprintf(fp_cpp, "    }\n");
  1.3777 +  }
  1.3778 +
  1.3779 +  // Generate the default case for switch(opcode)
  1.3780 +  fprintf(fp_cpp, "  \n");
  1.3781 +  fprintf(fp_cpp, "  default:\n");
  1.3782 +  fprintf(fp_cpp, "    fprintf(stderr, \"Default MachNode Generator invoked for: \\n\");\n");
  1.3783 +  fprintf(fp_cpp, "    fprintf(stderr, \"   opcode = %cd\\n\", opcode);\n", '%');
  1.3784 +  fprintf(fp_cpp, "    break;\n");
  1.3785 +  fprintf(fp_cpp, "  };\n");
  1.3786 +
  1.3787 +  // Generate the closing for method Matcher::MachNodeGenerator
  1.3788 +  fprintf(fp_cpp, "  return NULL;\n");
  1.3789 +  fprintf(fp_cpp, "}\n");
  1.3790 +}
  1.3791 +
  1.3792 +
  1.3793 +//---------------------------buildInstructMatchCheck--------------------------
  1.3794 +// Output the method to Matcher which checks whether or not a specific
  1.3795 +// instruction has a matching rule for the host architecture.
  1.3796 +void ArchDesc::buildInstructMatchCheck(FILE *fp_cpp) const {
  1.3797 +  fprintf(fp_cpp, "\n\n");
  1.3798 +  fprintf(fp_cpp, "const bool Matcher::has_match_rule(int opcode) {\n");
  1.3799 +  fprintf(fp_cpp, "  assert(_last_machine_leaf < opcode && opcode < _last_opcode, \"opcode in range\");\n");
  1.3800 +  fprintf(fp_cpp, "  return _hasMatchRule[opcode];\n");
  1.3801 +  fprintf(fp_cpp, "}\n\n");
  1.3802 +
  1.3803 +  fprintf(fp_cpp, "const bool Matcher::_hasMatchRule[_last_opcode] = {\n");
  1.3804 +  int i;
  1.3805 +  for (i = 0; i < _last_opcode - 1; i++) {
  1.3806 +    fprintf(fp_cpp, "    %-5s,  // %s\n",
  1.3807 +            _has_match_rule[i] ? "true" : "false",
  1.3808 +            NodeClassNames[i]);
  1.3809 +  }
  1.3810 +  fprintf(fp_cpp, "    %-5s   // %s\n",
  1.3811 +          _has_match_rule[i] ? "true" : "false",
  1.3812 +          NodeClassNames[i]);
  1.3813 +  fprintf(fp_cpp, "};\n");
  1.3814 +}
  1.3815 +
  1.3816 +//---------------------------buildFrameMethods---------------------------------
  1.3817 +// Output the methods to Matcher which specify frame behavior
  1.3818 +void ArchDesc::buildFrameMethods(FILE *fp_cpp) {
  1.3819 +  fprintf(fp_cpp,"\n\n");
  1.3820 +  // Stack Direction
  1.3821 +  fprintf(fp_cpp,"bool Matcher::stack_direction() const { return %s; }\n\n",
  1.3822 +          _frame->_direction ? "true" : "false");
  1.3823 +  // Sync Stack Slots
  1.3824 +  fprintf(fp_cpp,"int Compile::sync_stack_slots() const { return %s; }\n\n",
  1.3825 +          _frame->_sync_stack_slots);
  1.3826 +  // Java Stack Alignment
  1.3827 +  fprintf(fp_cpp,"uint Matcher::stack_alignment_in_bytes() { return %s; }\n\n",
  1.3828 +          _frame->_alignment);
  1.3829 +  // Java Return Address Location
  1.3830 +  fprintf(fp_cpp,"OptoReg::Name Matcher::return_addr() const {");
  1.3831 +  if (_frame->_return_addr_loc) {
  1.3832 +    fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
  1.3833 +            _frame->_return_addr);
  1.3834 +  }
  1.3835 +  else {
  1.3836 +    fprintf(fp_cpp," return OptoReg::stack2reg(%s); }\n\n",
  1.3837 +            _frame->_return_addr);
  1.3838 +  }
  1.3839 +  // Java Stack Slot Preservation
  1.3840 +  fprintf(fp_cpp,"uint Compile::in_preserve_stack_slots() ");
  1.3841 +  fprintf(fp_cpp,"{ return %s; }\n\n", _frame->_in_preserve_slots);
  1.3842 +  // Top Of Stack Slot Preservation, for both Java and C
  1.3843 +  fprintf(fp_cpp,"uint Compile::out_preserve_stack_slots() ");
  1.3844 +  fprintf(fp_cpp,"{ return SharedRuntime::out_preserve_stack_slots(); }\n\n");
  1.3845 +  // varargs C out slots killed
  1.3846 +  fprintf(fp_cpp,"uint Compile::varargs_C_out_slots_killed() const ");
  1.3847 +  fprintf(fp_cpp,"{ return %s; }\n\n", _frame->_varargs_C_out_slots_killed);
  1.3848 +  // Java Argument Position
  1.3849 +  fprintf(fp_cpp,"void Matcher::calling_convention(BasicType *sig_bt, VMRegPair *regs, uint length, bool is_outgoing) {\n");
  1.3850 +  fprintf(fp_cpp,"%s\n", _frame->_calling_convention);
  1.3851 +  fprintf(fp_cpp,"}\n\n");
  1.3852 +  // Native Argument Position
  1.3853 +  fprintf(fp_cpp,"void Matcher::c_calling_convention(BasicType *sig_bt, VMRegPair *regs, uint length) {\n");
  1.3854 +  fprintf(fp_cpp,"%s\n", _frame->_c_calling_convention);
  1.3855 +  fprintf(fp_cpp,"}\n\n");
  1.3856 +  // Java Return Value Location
  1.3857 +  fprintf(fp_cpp,"OptoRegPair Matcher::return_value(int ideal_reg, bool is_outgoing) {\n");
  1.3858 +  fprintf(fp_cpp,"%s\n", _frame->_return_value);
  1.3859 +  fprintf(fp_cpp,"}\n\n");
  1.3860 +  // Native Return Value Location
  1.3861 +  fprintf(fp_cpp,"OptoRegPair Matcher::c_return_value(int ideal_reg, bool is_outgoing) {\n");
  1.3862 +  fprintf(fp_cpp,"%s\n", _frame->_c_return_value);
  1.3863 +  fprintf(fp_cpp,"}\n\n");
  1.3864 +
  1.3865 +  // Inline Cache Register, mask definition, and encoding
  1.3866 +  fprintf(fp_cpp,"OptoReg::Name Matcher::inline_cache_reg() {");
  1.3867 +  fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
  1.3868 +          _frame->_inline_cache_reg);
  1.3869 +  fprintf(fp_cpp,"const RegMask &Matcher::inline_cache_reg_mask() {");
  1.3870 +  fprintf(fp_cpp," return INLINE_CACHE_REG_mask; }\n\n");
  1.3871 +  fprintf(fp_cpp,"int Matcher::inline_cache_reg_encode() {");
  1.3872 +  fprintf(fp_cpp," return _regEncode[inline_cache_reg()]; }\n\n");
  1.3873 +
  1.3874 +  // Interpreter's Method Oop Register, mask definition, and encoding
  1.3875 +  fprintf(fp_cpp,"OptoReg::Name Matcher::interpreter_method_oop_reg() {");
  1.3876 +  fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
  1.3877 +          _frame->_interpreter_method_oop_reg);
  1.3878 +  fprintf(fp_cpp,"const RegMask &Matcher::interpreter_method_oop_reg_mask() {");
  1.3879 +  fprintf(fp_cpp," return INTERPRETER_METHOD_OOP_REG_mask; }\n\n");
  1.3880 +  fprintf(fp_cpp,"int Matcher::interpreter_method_oop_reg_encode() {");
  1.3881 +  fprintf(fp_cpp," return _regEncode[interpreter_method_oop_reg()]; }\n\n");
  1.3882 +
  1.3883 +  // Interpreter's Frame Pointer Register, mask definition, and encoding
  1.3884 +  fprintf(fp_cpp,"OptoReg::Name Matcher::interpreter_frame_pointer_reg() {");
  1.3885 +  if (_frame->_interpreter_frame_pointer_reg == NULL)
  1.3886 +    fprintf(fp_cpp," return OptoReg::Bad; }\n\n");
  1.3887 +  else
  1.3888 +    fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
  1.3889 +            _frame->_interpreter_frame_pointer_reg);
  1.3890 +  fprintf(fp_cpp,"const RegMask &Matcher::interpreter_frame_pointer_reg_mask() {");
  1.3891 +  if (_frame->_interpreter_frame_pointer_reg == NULL)
  1.3892 +    fprintf(fp_cpp," static RegMask dummy; return dummy; }\n\n");
  1.3893 +  else
  1.3894 +    fprintf(fp_cpp," return INTERPRETER_FRAME_POINTER_REG_mask; }\n\n");
  1.3895 +
  1.3896 +  // Frame Pointer definition
  1.3897 +  /* CNC - I can not contemplate having a different frame pointer between
  1.3898 +     Java and native code; makes my head hurt to think about it.
  1.3899 +  fprintf(fp_cpp,"OptoReg::Name Matcher::frame_pointer() const {");
  1.3900 +  fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
  1.3901 +          _frame->_frame_pointer);
  1.3902 +  */
  1.3903 +  // (Native) Frame Pointer definition
  1.3904 +  fprintf(fp_cpp,"OptoReg::Name Matcher::c_frame_pointer() const {");
  1.3905 +  fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
  1.3906 +          _frame->_frame_pointer);
  1.3907 +
  1.3908 +  // Number of callee-save + always-save registers for calling convention
  1.3909 +  fprintf(fp_cpp, "// Number of callee-save + always-save registers\n");
  1.3910 +  fprintf(fp_cpp, "int  Matcher::number_of_saved_registers() {\n");
  1.3911 +  RegDef *rdef;
  1.3912 +  int nof_saved_registers = 0;
  1.3913 +  _register->reset_RegDefs();
  1.3914 +  while( (rdef = _register->iter_RegDefs()) != NULL ) {
  1.3915 +    if( !strcmp(rdef->_callconv, "SOE") ||  !strcmp(rdef->_callconv, "AS") )
  1.3916 +      ++nof_saved_registers;
  1.3917 +  }
  1.3918 +  fprintf(fp_cpp, "  return %d;\n", nof_saved_registers);
  1.3919 +  fprintf(fp_cpp, "};\n\n");
  1.3920 +}
  1.3921 +
  1.3922 +
  1.3923 +
  1.3924 +
  1.3925 +static int PrintAdlcCisc = 0;
  1.3926 +//---------------------------identify_cisc_spilling----------------------------
  1.3927 +// Get info for the CISC_oracle and MachNode::cisc_version()
  1.3928 +void ArchDesc::identify_cisc_spill_instructions() {
  1.3929 +
  1.3930 +  // Find the user-defined operand for cisc-spilling
  1.3931 +  if( _frame->_cisc_spilling_operand_name != NULL ) {
  1.3932 +    const Form *form = _globalNames[_frame->_cisc_spilling_operand_name];
  1.3933 +    OperandForm *oper = form ? form->is_operand() : NULL;
  1.3934 +    // Verify the user's suggestion
  1.3935 +    if( oper != NULL ) {
  1.3936 +      // Ensure that match field is defined.
  1.3937 +      if ( oper->_matrule != NULL )  {
  1.3938 +        MatchRule &mrule = *oper->_matrule;
  1.3939 +        if( strcmp(mrule._opType,"AddP") == 0 ) {
  1.3940 +          MatchNode *left = mrule._lChild;
  1.3941 +          MatchNode *right= mrule._rChild;
  1.3942 +          if( left != NULL && right != NULL ) {
  1.3943 +            const Form *left_op  = _globalNames[left->_opType]->is_operand();
  1.3944 +            const Form *right_op = _globalNames[right->_opType]->is_operand();
  1.3945 +            if(  (left_op != NULL && right_op != NULL)
  1.3946 +              && (left_op->interface_type(_globalNames) == Form::register_interface)
  1.3947 +              && (right_op->interface_type(_globalNames) == Form::constant_interface) ) {
  1.3948 +              // Successfully verified operand
  1.3949 +              set_cisc_spill_operand( oper );
  1.3950 +              if( _cisc_spill_debug ) {
  1.3951 +                fprintf(stderr, "\n\nVerified CISC-spill operand %s\n\n", oper->_ident);
  1.3952 +             }
  1.3953 +            }
  1.3954 +          }
  1.3955 +        }
  1.3956 +      }
  1.3957 +    }
  1.3958 +  }
  1.3959 +
  1.3960 +  if( cisc_spill_operand() != NULL ) {
  1.3961 +    // N^2 comparison of instructions looking for a cisc-spilling version
  1.3962 +    _instructions.reset();
  1.3963 +    InstructForm *instr;
  1.3964 +    for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
  1.3965 +      // Ensure that match field is defined.
  1.3966 +      if ( instr->_matrule == NULL )  continue;
  1.3967 +
  1.3968 +      MatchRule &mrule = *instr->_matrule;
  1.3969 +      Predicate *pred  =  instr->build_predicate();
  1.3970 +
  1.3971 +      // Grab the machine type of the operand
  1.3972 +      const char *rootOp = instr->_ident;
  1.3973 +      mrule._machType    = rootOp;
  1.3974 +
  1.3975 +      // Find result type for match
  1.3976 +      const char *result = instr->reduce_result();
  1.3977 +
  1.3978 +      if( PrintAdlcCisc ) fprintf(stderr, "  new instruction %s \n", instr->_ident ? instr->_ident : " ");
  1.3979 +      bool  found_cisc_alternate = false;
  1.3980 +      _instructions.reset2();
  1.3981 +      InstructForm *instr2;
  1.3982 +      for( ; !found_cisc_alternate && (instr2 = (InstructForm*)_instructions.iter2()) != NULL; ) {
  1.3983 +        // Ensure that match field is defined.
  1.3984 +        if( PrintAdlcCisc ) fprintf(stderr, "  instr2 == %s \n", instr2->_ident ? instr2->_ident : " ");
  1.3985 +        if ( instr2->_matrule != NULL
  1.3986 +            && (instr != instr2 )                // Skip self
  1.3987 +            && (instr2->reduce_result() != NULL) // want same result
  1.3988 +            && (strcmp(result, instr2->reduce_result()) == 0)) {
  1.3989 +          MatchRule &mrule2 = *instr2->_matrule;
  1.3990 +          Predicate *pred2  =  instr2->build_predicate();
  1.3991 +          found_cisc_alternate = instr->cisc_spills_to(*this, instr2);
  1.3992 +        }
  1.3993 +      }
  1.3994 +    }
  1.3995 +  }
  1.3996 +}
  1.3997 +
  1.3998 +//---------------------------build_cisc_spilling-------------------------------
  1.3999 +// Get info for the CISC_oracle and MachNode::cisc_version()
  1.4000 +void ArchDesc::build_cisc_spill_instructions(FILE *fp_hpp, FILE *fp_cpp) {
  1.4001 +  // Output the table for cisc spilling
  1.4002 +  fprintf(fp_cpp, "//  The following instructions can cisc-spill\n");
  1.4003 +  _instructions.reset();
  1.4004 +  InstructForm *inst = NULL;
  1.4005 +  for(; (inst = (InstructForm*)_instructions.iter()) != NULL; ) {
  1.4006 +    // Ensure this is a machine-world instruction
  1.4007 +    if ( inst->ideal_only() )  continue;
  1.4008 +    const char *inst_name = inst->_ident;
  1.4009 +    int   operand   = inst->cisc_spill_operand();
  1.4010 +    if( operand != AdlcVMDeps::Not_cisc_spillable ) {
  1.4011 +      InstructForm *inst2 = inst->cisc_spill_alternate();
  1.4012 +      fprintf(fp_cpp, "//  %s can cisc-spill operand %d to %s\n", inst->_ident, operand, inst2->_ident);
  1.4013 +    }
  1.4014 +  }
  1.4015 +  fprintf(fp_cpp, "\n\n");
  1.4016 +}
  1.4017 +
  1.4018 +//---------------------------identify_short_branches----------------------------
  1.4019 +// Get info for our short branch replacement oracle.
  1.4020 +void ArchDesc::identify_short_branches() {
  1.4021 +  // Walk over all instructions, checking to see if they match a short
  1.4022 +  // branching alternate.
  1.4023 +  _instructions.reset();
  1.4024 +  InstructForm *instr;
  1.4025 +  while( (instr = (InstructForm*)_instructions.iter()) != NULL ) {
  1.4026 +    // The instruction must have a match rule.
  1.4027 +    if (instr->_matrule != NULL &&
  1.4028 +        instr->is_short_branch()) {
  1.4029 +
  1.4030 +      _instructions.reset2();
  1.4031 +      InstructForm *instr2;
  1.4032 +      while( (instr2 = (InstructForm*)_instructions.iter2()) != NULL ) {
  1.4033 +        instr2->check_branch_variant(*this, instr);
  1.4034 +      }
  1.4035 +    }
  1.4036 +  }
  1.4037 +}
  1.4038 +
  1.4039 +
  1.4040 +//---------------------------identify_unique_operands---------------------------
  1.4041 +// Identify unique operands.
  1.4042 +void ArchDesc::identify_unique_operands() {
  1.4043 +  // Walk over all instructions.
  1.4044 +  _instructions.reset();
  1.4045 +  InstructForm *instr;
  1.4046 +  while( (instr = (InstructForm*)_instructions.iter()) != NULL ) {
  1.4047 +    // Ensure this is a machine-world instruction
  1.4048 +    if (!instr->ideal_only()) {
  1.4049 +      instr->set_unique_opnds();
  1.4050 +    }
  1.4051 +  }
  1.4052 +}

mercurial