src/share/vm/adlc/output_c.cpp

changeset 2350
2f644f85485d
parent 2103
3e8fbc61cee8
child 2561
ab42c7e1cf83
     1.1 --- a/src/share/vm/adlc/output_c.cpp	Thu Dec 02 17:21:12 2010 -0800
     1.2 +++ b/src/share/vm/adlc/output_c.cpp	Fri Dec 03 01:34:31 2010 -0800
     1.3 @@ -1496,8 +1496,8 @@
     1.4    unsigned      i;
     1.5  
     1.6    // Generate Expand function header
     1.7 -  fprintf(fp,"MachNode *%sNode::Expand(State *state, Node_List &proj_list, Node* mem) {\n", node->_ident);
     1.8 -  fprintf(fp,"Compile* C = Compile::current();\n");
     1.9 +  fprintf(fp, "MachNode* %sNode::Expand(State* state, Node_List& proj_list, Node* mem) {\n", node->_ident);
    1.10 +  fprintf(fp, "  Compile* C = Compile::current();\n");
    1.11    // Generate expand code
    1.12    if( node->expands() ) {
    1.13      const char   *opid;
    1.14 @@ -1818,6 +1818,12 @@
    1.15      }
    1.16    }
    1.17  
    1.18 +  // If the node is a MachConstantNode, insert the MachConstantBaseNode edge.
    1.19 +  // NOTE: this edge must be the last input (see MachConstantNode::mach_constant_base_node_input).
    1.20 +  if (node->is_mach_constant()) {
    1.21 +    fprintf(fp,"  add_req(C->mach_constant_base_node());\n");
    1.22 +  }
    1.23 +
    1.24    fprintf(fp,"\n");
    1.25    if( node->expands() ) {
    1.26      fprintf(fp,"  return result;\n");
    1.27 @@ -1924,7 +1930,17 @@
    1.28          // No state needed.
    1.29          assert( _opclass == NULL,
    1.30                  "'primary', 'secondary' and 'tertiary' don't follow operand.");
    1.31 -      } else {
    1.32 +      }
    1.33 +      else if ((strcmp(rep_var, "constanttablebase") == 0) ||
    1.34 +               (strcmp(rep_var, "constantoffset")    == 0) ||
    1.35 +               (strcmp(rep_var, "constantaddress")   == 0)) {
    1.36 +        if (!_inst.is_mach_constant()) {
    1.37 +          _AD.syntax_err(_encoding._linenum,
    1.38 +                         "Replacement variable %s not allowed in instruct %s (only in MachConstantNode).\n",
    1.39 +                         rep_var, _encoding._name);
    1.40 +        }
    1.41 +      }
    1.42 +      else {
    1.43          // Lookup its position in parameter list
    1.44          int   param_no  = _encoding.rep_var_index(rep_var);
    1.45          if ( param_no == -1 ) {
    1.46 @@ -2380,6 +2396,15 @@
    1.47                          rep_var, _inst._ident, _encoding._name);
    1.48        }
    1.49      }
    1.50 +    else if (strcmp(rep_var, "constanttablebase") == 0) {
    1.51 +      fprintf(_fp, "as_Register(ra_->get_encode(in(mach_constant_base_node_input())))");
    1.52 +    }
    1.53 +    else if (strcmp(rep_var, "constantoffset") == 0) {
    1.54 +      fprintf(_fp, "constant_offset()");
    1.55 +    }
    1.56 +    else if (strcmp(rep_var, "constantaddress") == 0) {
    1.57 +      fprintf(_fp, "InternalAddress(__ code()->consts()->start() + constant_offset())");
    1.58 +    }
    1.59      else {
    1.60        // Lookup its position in parameter list
    1.61        int   param_no  = _encoding.rep_var_index(rep_var);
    1.62 @@ -2465,37 +2490,39 @@
    1.63    fprintf(fp,"}\n");
    1.64  }
    1.65  
    1.66 -void ArchDesc::defineEmit(FILE *fp, InstructForm &inst) {
    1.67 -  InsEncode *ins_encode = inst._insencode;
    1.68 +// defineEmit -----------------------------------------------------------------
    1.69 +void ArchDesc::defineEmit(FILE* fp, InstructForm& inst) {
    1.70 +  InsEncode* encode = inst._insencode;
    1.71  
    1.72    // (1)
    1.73    // Output instruction's emit prototype
    1.74 -  fprintf(fp,"void  %sNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {\n",
    1.75 -          inst._ident);
    1.76 +  fprintf(fp, "void %sNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {\n", inst._ident);
    1.77  
    1.78    // If user did not define an encode section,
    1.79    // provide stub that does not generate any machine code.
    1.80 -  if( (_encode == NULL) || (ins_encode == NULL) ) {
    1.81 +  if( (_encode == NULL) || (encode == NULL) ) {
    1.82      fprintf(fp, "  // User did not define an encode section.\n");
    1.83 -    fprintf(fp,"}\n");
    1.84 +    fprintf(fp, "}\n");
    1.85      return;
    1.86    }
    1.87  
    1.88    // Save current instruction's starting address (helps with relocation).
    1.89 -  fprintf(fp, "    cbuf.set_insts_mark();\n");
    1.90 -
    1.91 -  // // // idx0 is only needed for syntactic purposes and only by "storeSSI"
    1.92 -  // fprintf( fp, "    unsigned idx0  = 0;\n");
    1.93 +  fprintf(fp, "  cbuf.set_insts_mark();\n");
    1.94 +
    1.95 +  // For MachConstantNodes which are ideal jump nodes, fill the jump table.
    1.96 +  if (inst.is_mach_constant() && inst.is_ideal_jump()) {
    1.97 +    fprintf(fp, "  ra_->C->constant_table().fill_jump_table(cbuf, (MachConstantNode*) this, _index2label);\n");
    1.98 +  }
    1.99  
   1.100    // Output each operand's offset into the array of registers.
   1.101 -  inst.index_temps( fp, _globalNames );
   1.102 +  inst.index_temps(fp, _globalNames);
   1.103  
   1.104    // Output this instruction's encodings
   1.105    const char *ec_name;
   1.106    bool        user_defined = false;
   1.107 -  ins_encode->reset();
   1.108 -  while ( (ec_name = ins_encode->encode_class_iter()) != NULL ) {
   1.109 -    fprintf(fp, "  {");
   1.110 +  encode->reset();
   1.111 +  while ((ec_name = encode->encode_class_iter()) != NULL) {
   1.112 +    fprintf(fp, "  {\n");
   1.113      // Output user-defined encoding
   1.114      user_defined           = true;
   1.115  
   1.116 @@ -2507,25 +2534,25 @@
   1.117        abort();
   1.118      }
   1.119  
   1.120 -    if (ins_encode->current_encoding_num_args() != encoding->num_args()) {
   1.121 -      globalAD->syntax_err(ins_encode->_linenum, "In %s: passing %d arguments to %s but expecting %d",
   1.122 -                           inst._ident, ins_encode->current_encoding_num_args(),
   1.123 +    if (encode->current_encoding_num_args() != encoding->num_args()) {
   1.124 +      globalAD->syntax_err(encode->_linenum, "In %s: passing %d arguments to %s but expecting %d",
   1.125 +                           inst._ident, encode->current_encoding_num_args(),
   1.126                             ec_name, encoding->num_args());
   1.127      }
   1.128  
   1.129 -    DefineEmitState  pending(fp, *this, *encoding, *ins_encode, inst );
   1.130 +    DefineEmitState pending(fp, *this, *encoding, *encode, inst);
   1.131      encoding->_code.reset();
   1.132      encoding->_rep_vars.reset();
   1.133      // Process list of user-defined strings,
   1.134      // and occurrences of replacement variables.
   1.135      // Replacement Vars are pushed into a list and then output
   1.136 -    while ( (ec_code = encoding->_code.iter()) != NULL ) {
   1.137 -      if ( ! encoding->_code.is_signal( ec_code ) ) {
   1.138 +    while ((ec_code = encoding->_code.iter()) != NULL) {
   1.139 +      if (!encoding->_code.is_signal(ec_code)) {
   1.140          // Emit pending code
   1.141          pending.emit();
   1.142          pending.clear();
   1.143          // Emit this code section
   1.144 -        fprintf(fp,"%s", ec_code);
   1.145 +        fprintf(fp, "%s", ec_code);
   1.146        } else {
   1.147          // A replacement variable or one of its subfields
   1.148          // Obtain replacement variable from list
   1.149 @@ -2536,7 +2563,7 @@
   1.150      // Emit pending code
   1.151      pending.emit();
   1.152      pending.clear();
   1.153 -    fprintf(fp, "}\n");
   1.154 +    fprintf(fp, "  }\n");
   1.155    } // end while instruction's encodings
   1.156  
   1.157    // Check if user stated which encoding to user
   1.158 @@ -2545,7 +2572,86 @@
   1.159    }
   1.160  
   1.161    // (3) and (4)
   1.162 -  fprintf(fp,"}\n");
   1.163 +  fprintf(fp, "}\n");
   1.164 +}
   1.165 +
   1.166 +// defineEvalConstant ---------------------------------------------------------
   1.167 +void ArchDesc::defineEvalConstant(FILE* fp, InstructForm& inst) {
   1.168 +  InsEncode* encode = inst._constant;
   1.169 +
   1.170 +  // (1)
   1.171 +  // Output instruction's emit prototype
   1.172 +  fprintf(fp, "void %sNode::eval_constant(Compile* C) {\n", inst._ident);
   1.173 +
   1.174 +  // For ideal jump nodes, allocate a jump table.
   1.175 +  if (inst.is_ideal_jump()) {
   1.176 +    fprintf(fp, "  _constant = C->constant_table().allocate_jump_table(this);\n");
   1.177 +  }
   1.178 +
   1.179 +  // If user did not define an encode section,
   1.180 +  // provide stub that does not generate any machine code.
   1.181 +  if ((_encode == NULL) || (encode == NULL)) {
   1.182 +    fprintf(fp, "  // User did not define an encode section.\n");
   1.183 +    fprintf(fp, "}\n");
   1.184 +    return;
   1.185 +  }
   1.186 +
   1.187 +  // Output this instruction's encodings
   1.188 +  const char *ec_name;
   1.189 +  bool        user_defined = false;
   1.190 +  encode->reset();
   1.191 +  while ((ec_name = encode->encode_class_iter()) != NULL) {
   1.192 +    fprintf(fp, "  {\n");
   1.193 +    // Output user-defined encoding
   1.194 +    user_defined           = true;
   1.195 +
   1.196 +    const char *ec_code    = NULL;
   1.197 +    const char *ec_rep_var = NULL;
   1.198 +    EncClass   *encoding   = _encode->encClass(ec_name);
   1.199 +    if (encoding == NULL) {
   1.200 +      fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name);
   1.201 +      abort();
   1.202 +    }
   1.203 +
   1.204 +    if (encode->current_encoding_num_args() != encoding->num_args()) {
   1.205 +      globalAD->syntax_err(encode->_linenum, "In %s: passing %d arguments to %s but expecting %d",
   1.206 +                           inst._ident, encode->current_encoding_num_args(),
   1.207 +                           ec_name, encoding->num_args());
   1.208 +    }
   1.209 +
   1.210 +    DefineEmitState pending(fp, *this, *encoding, *encode, inst);
   1.211 +    encoding->_code.reset();
   1.212 +    encoding->_rep_vars.reset();
   1.213 +    // Process list of user-defined strings,
   1.214 +    // and occurrences of replacement variables.
   1.215 +    // Replacement Vars are pushed into a list and then output
   1.216 +    while ((ec_code = encoding->_code.iter()) != NULL) {
   1.217 +      if (!encoding->_code.is_signal(ec_code)) {
   1.218 +        // Emit pending code
   1.219 +        pending.emit();
   1.220 +        pending.clear();
   1.221 +        // Emit this code section
   1.222 +        fprintf(fp, "%s", ec_code);
   1.223 +      } else {
   1.224 +        // A replacement variable or one of its subfields
   1.225 +        // Obtain replacement variable from list
   1.226 +        ec_rep_var  = encoding->_rep_vars.iter();
   1.227 +        pending.add_rep_var(ec_rep_var);
   1.228 +      }
   1.229 +    }
   1.230 +    // Emit pending code
   1.231 +    pending.emit();
   1.232 +    pending.clear();
   1.233 +    fprintf(fp, "  }\n");
   1.234 +  } // end while instruction's encodings
   1.235 +
   1.236 +  // Check if user stated which encoding to user
   1.237 +  if (user_defined == false) {
   1.238 +    fprintf(fp, "  // User did not define which encode class to use.\n");
   1.239 +  }
   1.240 +
   1.241 +  // (3) and (4)
   1.242 +  fprintf(fp, "}\n");
   1.243  }
   1.244  
   1.245  // ---------------------------------------------------------------------------
   1.246 @@ -2952,6 +3058,7 @@
   1.247      // If there are multiple defs/kills, or an explicit expand rule, build rule
   1.248      if( instr->expands() || instr->needs_projections() ||
   1.249          instr->has_temps() ||
   1.250 +        instr->is_mach_constant() ||
   1.251          instr->_matrule != NULL &&
   1.252          instr->num_opnds() != instr->num_unique_opnds() )
   1.253        defineExpand(_CPP_EXPAND_file._fp, instr);
   1.254 @@ -3032,8 +3139,9 @@
   1.255      // Ensure this is a machine-world instruction
   1.256      if ( instr->ideal_only() ) continue;
   1.257  
   1.258 -    if (instr->_insencode) defineEmit(fp, *instr);
   1.259 -    if (instr->_size)      defineSize(fp, *instr);
   1.260 +    if (instr->_insencode)         defineEmit        (fp, *instr);
   1.261 +    if (instr->is_mach_constant()) defineEvalConstant(fp, *instr);
   1.262 +    if (instr->_size)              defineSize        (fp, *instr);
   1.263  
   1.264      // side-call to generate output that used to be in the header file:
   1.265      extern void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &oper, bool for_c_file);

mercurial