src/share/vm/adlc/adlparse.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6961690 Sdiff src/share/vm/adlc

src/share/vm/adlc/adlparse.cpp

Print this page
rev 1838 : 6961690: load oops from constant table on SPARC
Summary: oops should be loaded from the constant table of an nmethod instead of materializing them with a long code sequence.
Reviewed-by:
   1 /*
   2  * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 199         // Add the new match rule to the list
 200         rule->_next = match_parse(instr->_localNames);
 201         if (rule->_next) {
 202           rule = rule->_next;
 203           if( instr->is_ideal_control() ) {
 204             parse_err(SYNERR, "unique match rule expected for %s\n", rule->_name);
 205             return;
 206           }
 207           assert(match_rules_cnt < 100," too many match rule clones");
 208           char* buf = (char*) malloc(strlen(instr->_ident) + 4);
 209           sprintf(buf, "%s_%d", instr->_ident, match_rules_cnt++);
 210           rule->_result = buf;
 211           // Check for commutative operations with tree operands.
 212           matchrule_clone_and_swap(rule, instr->_ident, match_rules_cnt);
 213         }
 214       }
 215     }
 216     else if (!strcmp(ident, "encode"))  {
 217       parse_err(SYNERR, "Instructions specify ins_encode, not encode\n");
 218     }
 219     else if (!strcmp(ident, "ins_encode"))
 220       instr->_insencode = ins_encode_parse(*instr);
 221     else if (!strcmp(ident, "opcode"))  instr->_opcode = opcode_parse(instr);
 222     else if (!strcmp(ident, "size"))    instr->_size = size_parse(instr);
 223     else if (!strcmp(ident, "effect"))  effect_parse(instr);
 224     else if (!strcmp(ident, "expand"))  instr->_exprule = expand_parse(instr);
 225     else if (!strcmp(ident, "rewrite")) instr->_rewrule = rewrite_parse();
 226     else if (!strcmp(ident, "constraint")) {
 227       parse_err(SYNERR, "Instructions do not specify a constraint\n");
 228     }
 229     else if (!strcmp(ident, "construct")) {
 230       parse_err(SYNERR, "Instructions do not specify a construct\n");
 231     }
 232     else if (!strcmp(ident, "format"))  instr->_format  = format_parse();
 233     else if (!strcmp(ident, "interface")) {
 234       parse_err(SYNERR, "Instructions do not specify an interface\n");
 235     }
 236     else if (!strcmp(ident, "ins_pipe")) ins_pipe_parse(*instr);
 237     else {  // Done with staticly defined parts of instruction definition
 238       // Check identifier to see if it is the name of an attribute
 239       const Form    *form = _globalNames[ident];
 240       AttributeForm *attr = form ? form->is_attribute() : NULL;


 918     // Check if there is a string to pass through to output
 919     char *start = _ptr;       // Record start of the next string
 920     while ((_curchar != '$') && ((_curchar != '%') || (*(_ptr+1) != '}')) ) {
 921       // If at the start of a comment, skip past it
 922       if( (_curchar == '/') && ((*(_ptr+1) == '/') || (*(_ptr+1) == '*')) ) {
 923         skipws_no_preproc();
 924       } else {
 925         // ELSE advance to the next character, or start of the next line
 926         next_char_or_line();
 927       }
 928     }
 929     // If a string was found, terminate it and record in EncClass
 930     if ( start != _ptr ) {
 931       *_ptr  = '\0';          // Terminate the string
 932       encoding->add_code(start);
 933     }
 934 
 935     // (2)
 936     // If we are at a replacement variable,
 937     // copy it and record in EncClass
 938     if ( _curchar == '$' ) {
 939       // Found replacement Variable
 940       char *rep_var = get_rep_var_ident_dup();
 941       // Add flag to _strings list indicating we should check _rep_vars
 942       encoding->add_rep_var(rep_var);
 943     }
 944   } // end while part of format description
 945   next_char();                      // Skip '%'
 946   next_char();                      // Skip '}'
 947 
 948   skipws();
 949 
 950   if (_AD._adlocation_debug) {
 951     encoding->add_code(end_line_marker());
 952   }
 953 
 954   // Debug Stuff
 955   if (_AD._adl_debug > 1) fprintf(stderr,"EncodingClass Form: %s\n", ec_name);
 956 }
 957 
 958 //------------------------------frame_parse-----------------------------------
 959 void ADLParser::frame_parse(void) {
 960   FrameForm  *frame;              // Information about stack-frame layout


2757   if ( (rule = get_paren_expr("pred expression", true)) == NULL ) {
2758     parse_err(SYNERR, "incorrect or missing expression for 'predicate'\n");
2759     return NULL;
2760   }
2761   // Debug Stuff
2762   if (_AD._adl_debug > 1) fprintf(stderr,"Predicate: %s\n", rule);
2763   if (_curchar != ';') {
2764     parse_err(SYNERR, "missing ';' in predicate definition\n");
2765     return NULL;
2766   }
2767   next_char();                     // Point after the terminator
2768 
2769   predicate = new Predicate(rule); // Build new predicate object
2770   skipws();
2771   return predicate;
2772 }
2773 
2774 
2775 //------------------------------ins_encode_parse_block-------------------------
2776 // Parse the block form of ins_encode.  See ins_encode_parse for more details
2777 InsEncode *ADLParser::ins_encode_parse_block(InstructForm &inst) {
2778   // Create a new encoding name based on the name of the instruction
2779   // definition, which should be unique.
2780   const char * prefix = "__enc_";
2781   char* ec_name = (char*)malloc(strlen(inst._ident) + strlen(prefix) + 1);
2782   sprintf(ec_name, "%s%s", prefix, inst._ident);
2783 
2784   assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
2785   EncClass  *encoding = _AD._encode->add_EncClass(ec_name);
2786   encoding->_linenum = linenum();
2787 
2788   // synthesize the arguments list for the enc_class from the
2789   // arguments to the instruct definition.
2790   const char * param = NULL;
2791   inst._parameters.reset();
2792   while ((param = inst._parameters.iter()) != NULL) {
2793     OperandForm *opForm = (OperandForm*)inst._localNames[param];
2794     encoding->add_parameter(opForm->_ident, param);
2795   }
2796 
2797   // Add the prologue to create the MacroAssembler
2798   encoding->add_code("\n"
2799   "    // Define a MacroAssembler instance for use by the encoding.  The\n"
2800   "    // name is chosen to match the __ idiom used for assembly in other\n"
2801   "    // parts of hotspot and assumes the existence of the standard\n"
2802   "    // #define __ _masm.\n"
2803   "    MacroAssembler _masm(&cbuf);\n");
2804 
2805   // Parse the following %{ }% block
2806   enc_class_parse_block(encoding, ec_name);
2807 
2808   // Build an encoding rule which invokes the encoding rule we just
2809   // created, passing all arguments that we received.
2810   InsEncode *encrule  = new InsEncode(); // Encode class for instruction
2811   NameAndList *params = encrule->add_encode(ec_name);
2812   inst._parameters.reset();
2813   while ((param = inst._parameters.iter()) != NULL) {
2814     params->add_entry(param);
2815   }
2816 
2817   return encrule;













































































2818 }
2819 
2820 
2821 //------------------------------ins_encode_parse-------------------------------
2822 // Encode rules have the form
2823 //   ins_encode( encode_class_name(parameter_list), ... );
2824 //
2825 // The "encode_class_name" must be defined in the encode section
2826 // The parameter list contains $names that are locals.
2827 //
2828 // Alternatively it can be written like this:
2829 //
2830 //   ins_encode %{
2831 //      ... // body
2832 //   %}
2833 //
2834 // which synthesizes a new encoding class taking the same arguments as
2835 // the InstructForm, and automatically prefixes the definition with:
2836 //
2837 //    MacroAssembler masm(&cbuf);\n");
2838 //
2839 //  making it more compact to take advantage of the MacroAssembler and
2840 //  placing the assembly closer to it's use by instructions.
2841 InsEncode *ADLParser::ins_encode_parse(InstructForm &inst) {
2842 
2843   // Parse encode class name
2844   skipws();                        // Skip whitespace
2845   if (_curchar != '(') {
2846     // Check for ins_encode %{ form
2847     if ((_curchar == '%') && (*(_ptr+1) == '{')) {
2848       next_char();                      // Skip '%'
2849       next_char();                      // Skip '{'
2850 
2851       // Parse the block form of ins_encode
2852       return ins_encode_parse_block(inst);

2853     }
2854 
2855     parse_err(SYNERR, "missing '%%{' or '(' in ins_encode definition\n");
2856     return NULL;
2857   }
2858   next_char();                     // move past '('
2859   skipws();
2860 
2861   InsEncode *encrule  = new InsEncode(); // Encode class for instruction
2862   encrule->_linenum = linenum();
2863   char      *ec_name  = NULL;      // String representation of encode rule
2864   // identifier is optional.
2865   while (_curchar != ')') {
2866     ec_name = get_ident();
2867     if (ec_name == NULL) {
2868       parse_err(SYNERR, "Invalid encode class name after 'ins_encode('.\n");
2869       return NULL;
2870     }
2871     // Check that encoding is defined in the encode section
2872     EncClass *encode_class = _AD._encode->encClass(ec_name);
2873     if (encode_class == NULL) {
2874       // Like to defer checking these till later...
2875       // parse_err(WARN, "Using an undefined encode class '%s' in 'ins_encode'.\n", ec_name);
2876     }
2877 
2878     // Get list for encode method's parameters
2879     NameAndList *params = encrule->add_encode(ec_name);
2880 
2881     // Parse the parameters to this encode method.
2882     skipws();
2883     if ( _curchar == '(' ) {
2884       next_char();                 // move past '(' for parameters
2885 
2886       // Parse the encode method's parameters
2887       while (_curchar != ')') {
2888         char *param = get_ident_or_literal_constant("encoding operand");
2889         if ( param != NULL ) {
2890           // Found a parameter:
2891           // Check it is a local name, add it to the list, then check for more
2892           // New: allow hex constants as parameters to an encode method.
2893           // New: allow parenthesized expressions as parameters.
2894           // New: allow "primary", "secondary", "tertiary" as parameters.
2895           // New: allow user-defined register name as parameter
2896           if ( (inst._localNames[param] == NULL) &&
2897                !ADLParser::is_literal_constant(param) &&
2898                (Opcode::as_opcode_type(param) == Opcode::NOT_AN_OPCODE) &&
2899                ((_AD._register == NULL ) || (_AD._register->getRegDef(param) == NULL)) ) {
2900             parse_err(SYNERR, "Using non-locally defined parameter %s for encoding %s.\n", param, ec_name);
2901             return NULL;
2902           }
2903           params->add_entry(param);
2904 
2905           skipws();
2906           if (_curchar == ',' ) {
2907             // More parameters to come
2908             next_char();           // move past ',' between parameters
2909             skipws();              // Skip to next parameter
2910           }
2911           else if (_curchar == ')') {
2912             // Done with parameter list
2913           }
2914           else {
2915             // Only ',' or ')' are valid after a parameter name
2916             parse_err(SYNERR, "expected ',' or ')' after parameter %s.\n",
2917                       ec_name);
2918             return NULL;
2919           }
2920 
2921         } else {
2922           skipws();
2923           // Did not find a parameter
2924           if (_curchar == ',') {
2925             parse_err(SYNERR, "Expected encode parameter before ',' in encoding %s.\n", ec_name);
2926             return NULL;
2927           }
2928           if (_curchar != ')') {
2929             parse_err(SYNERR, "Expected ')' after encode parameters.\n");
2930             return NULL;
2931           }
2932         }
2933       } // WHILE loop collecting parameters
2934       next_char();                   // move past ')' at end of parameters
2935     } // done with parameter list for encoding
2936 
2937     // Check for ',' or ')' after encoding
2938     skipws();                      // move to character after parameters
2939     if ( _curchar == ',' ) {
2940       // Found a ','
2941       next_char();                 // move past ',' between encode methods
2942       skipws();
2943     }
2944     else if ( _curchar != ')' ) {
2945       // If not a ',' then only a ')' is allowed
2946       parse_err(SYNERR, "Expected ')' after encoding %s.\n", ec_name);
2947       return NULL;
2948     }
2949 
2950     // Check for ',' separating parameters
2951     // if ( _curchar != ',' && _curchar != ')' ) {
2952     //   parse_err(SYNERR, "expected ',' or ')' after encode method inside ins_encode.\n");
2953     //   return NULL;
2954     // }
2955 
2956   } // done parsing ins_encode methods and their parameters
2957   if (_curchar != ')') {
2958     parse_err(SYNERR, "Missing ')' at end of ins_encode description.\n");
2959     return NULL;
2960   }
2961   next_char();                     // move past ')'
2962   skipws();                        // Skip leading whitespace
2963 
2964   if ( _curchar != ';' ) {
2965     parse_err(SYNERR, "Missing ';' at end of ins_encode.\n");
2966     return NULL;
2967   }
2968   next_char();                     // move past ';'
2969   skipws();                        // be friendly to oper_parse()
2970 
2971   // Debug Stuff
2972   if (_AD._adl_debug > 1) fprintf(stderr,"Instruction Encode: %s\n", ec_name);
2973 
2974   return encrule;










































































































2975 }
2976 
2977 
2978 //------------------------------size_parse-----------------------------------
2979 char* ADLParser::size_parse(InstructForm *instr) {
2980   char* sizeOfInstr = NULL;
2981 
2982   // Get value of the instruction's size
2983   skipws();
2984 
2985   // Parse size
2986   sizeOfInstr = get_paren_expr("size expression");
2987   if (sizeOfInstr == NULL) {
2988      parse_err(SYNERR, "size of opcode expected at %c\n", _curchar);
2989      return NULL;
2990   }
2991 
2992   skipws();
2993 
2994   // Check for terminator


   1 /*
   2  * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 199         // Add the new match rule to the list
 200         rule->_next = match_parse(instr->_localNames);
 201         if (rule->_next) {
 202           rule = rule->_next;
 203           if( instr->is_ideal_control() ) {
 204             parse_err(SYNERR, "unique match rule expected for %s\n", rule->_name);
 205             return;
 206           }
 207           assert(match_rules_cnt < 100," too many match rule clones");
 208           char* buf = (char*) malloc(strlen(instr->_ident) + 4);
 209           sprintf(buf, "%s_%d", instr->_ident, match_rules_cnt++);
 210           rule->_result = buf;
 211           // Check for commutative operations with tree operands.
 212           matchrule_clone_and_swap(rule, instr->_ident, match_rules_cnt);
 213         }
 214       }
 215     }
 216     else if (!strcmp(ident, "encode"))  {
 217       parse_err(SYNERR, "Instructions specify ins_encode, not encode\n");
 218     }
 219     else if (!strcmp(ident, "ins_encode"))     ins_encode_parse(*instr);

 220     else if (!strcmp(ident, "opcode"))         instr->_opcode    = opcode_parse(instr);
 221     else if (!strcmp(ident, "size"))           instr->_size      = size_parse(instr);
 222     else if (!strcmp(ident, "effect"))         effect_parse(instr);
 223     else if (!strcmp(ident, "expand"))         instr->_exprule   = expand_parse(instr);
 224     else if (!strcmp(ident, "rewrite"))        instr->_rewrule   = rewrite_parse();
 225     else if (!strcmp(ident, "constraint")) {
 226       parse_err(SYNERR, "Instructions do not specify a constraint\n");
 227     }
 228     else if (!strcmp(ident, "construct")) {
 229       parse_err(SYNERR, "Instructions do not specify a construct\n");
 230     }
 231     else if (!strcmp(ident, "format"))         instr->_format    = format_parse();
 232     else if (!strcmp(ident, "interface")) {
 233       parse_err(SYNERR, "Instructions do not specify an interface\n");
 234     }
 235     else if (!strcmp(ident, "ins_pipe"))        ins_pipe_parse(*instr);
 236     else {  // Done with staticly defined parts of instruction definition
 237       // Check identifier to see if it is the name of an attribute
 238       const Form    *form = _globalNames[ident];
 239       AttributeForm *attr = form ? form->is_attribute() : NULL;


 917     // Check if there is a string to pass through to output
 918     char *start = _ptr;       // Record start of the next string
 919     while ((_curchar != '$') && ((_curchar != '%') || (*(_ptr+1) != '}')) ) {
 920       // If at the start of a comment, skip past it
 921       if( (_curchar == '/') && ((*(_ptr+1) == '/') || (*(_ptr+1) == '*')) ) {
 922         skipws_no_preproc();
 923       } else {
 924         // ELSE advance to the next character, or start of the next line
 925         next_char_or_line();
 926       }
 927     }
 928     // If a string was found, terminate it and record in EncClass
 929     if ( start != _ptr ) {
 930       *_ptr  = '\0';          // Terminate the string
 931       encoding->add_code(start);
 932     }
 933 
 934     // (2)
 935     // If we are at a replacement variable,
 936     // copy it and record in EncClass
 937     if (_curchar == '$') {
 938       // Found replacement Variable
 939       char* rep_var = get_rep_var_ident_dup();
 940       // Add flag to _strings list indicating we should check _rep_vars
 941       encoding->add_rep_var(rep_var);
 942     }
 943   } // end while part of format description
 944   next_char();                      // Skip '%'
 945   next_char();                      // Skip '}'
 946 
 947   skipws();
 948 
 949   if (_AD._adlocation_debug) {
 950     encoding->add_code(end_line_marker());
 951   }
 952 
 953   // Debug Stuff
 954   if (_AD._adl_debug > 1) fprintf(stderr,"EncodingClass Form: %s\n", ec_name);
 955 }
 956 
 957 //------------------------------frame_parse-----------------------------------
 958 void ADLParser::frame_parse(void) {
 959   FrameForm  *frame;              // Information about stack-frame layout


2756   if ( (rule = get_paren_expr("pred expression", true)) == NULL ) {
2757     parse_err(SYNERR, "incorrect or missing expression for 'predicate'\n");
2758     return NULL;
2759   }
2760   // Debug Stuff
2761   if (_AD._adl_debug > 1) fprintf(stderr,"Predicate: %s\n", rule);
2762   if (_curchar != ';') {
2763     parse_err(SYNERR, "missing ';' in predicate definition\n");
2764     return NULL;
2765   }
2766   next_char();                     // Point after the terminator
2767 
2768   predicate = new Predicate(rule); // Build new predicate object
2769   skipws();
2770   return predicate;
2771 }
2772 
2773 
2774 //------------------------------ins_encode_parse_block-------------------------
2775 // Parse the block form of ins_encode.  See ins_encode_parse for more details
2776 void ADLParser::ins_encode_parse_block(InstructForm& inst) {
2777   // Create a new encoding name based on the name of the instruction
2778   // definition, which should be unique.
2779   const char* prefix = "__ins_encode_";
2780   char* ec_name = (char*) malloc(strlen(inst._ident) + strlen(prefix) + 1);
2781   sprintf(ec_name, "%s%s", prefix, inst._ident);
2782 
2783   assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
2784   EncClass* encoding = _AD._encode->add_EncClass(ec_name);
2785   encoding->_linenum = linenum();
2786 
2787   // synthesize the arguments list for the enc_class from the
2788   // arguments to the instruct definition.
2789   const char* param = NULL;
2790   inst._parameters.reset();
2791   while ((param = inst._parameters.iter()) != NULL) {
2792     OperandForm* opForm = (OperandForm*) inst._localNames[param];
2793     encoding->add_parameter(opForm->_ident, param);
2794   }
2795 
2796   // Define a MacroAssembler instance for use by the encoding.  The
2797   // name is chosen to match the __ idiom used for assembly in other
2798   // parts of hotspot and assumes the existence of the standard
2799   // #define __ _masm.
2800   encoding->add_code("    MacroAssembler _masm(&cbuf);\n");


2801 
2802   // Parse the following %{ }% block
2803   ins_encode_parse_block_impl(inst, encoding, ec_name);
2804 
2805   // Build an encoding rule which invokes the encoding rule we just
2806   // created, passing all arguments that we received.
2807   InsEncode*   encrule = new InsEncode(); // Encode class for instruction
2808   NameAndList* params  = encrule->add_encode(ec_name);
2809   inst._parameters.reset();
2810   while ((param = inst._parameters.iter()) != NULL) {
2811     params->add_entry(param);
2812   }
2813 
2814   // Set encode class of this instruction.
2815   inst._insencode = encrule;
2816 }
2817 
2818 
2819 void ADLParser::ins_encode_parse_block_impl(InstructForm& inst, EncClass* encoding, char* ec_name) {
2820   skipws_no_preproc();              // Skip leading whitespace
2821   // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block
2822   if (_AD._adlocation_debug) {
2823     encoding->add_code(get_line_string());
2824   }
2825 
2826   // Collect the parts of the encode description
2827   // (1) strings that are passed through to output
2828   // (2) replacement/substitution variable, preceeded by a '$'
2829   while ((_curchar != '%') && (*(_ptr+1) != '}')) {
2830 
2831     // (1)
2832     // Check if there is a string to pass through to output
2833     char *start = _ptr;       // Record start of the next string
2834     while ((_curchar != '$') && ((_curchar != '%') || (*(_ptr+1) != '}')) ) {
2835       // If at the start of a comment, skip past it
2836       if( (_curchar == '/') && ((*(_ptr+1) == '/') || (*(_ptr+1) == '*')) ) {
2837         skipws_no_preproc();
2838       } else {
2839         // ELSE advance to the next character, or start of the next line
2840         next_char_or_line();
2841       }
2842     }
2843     // If a string was found, terminate it and record in EncClass
2844     if (start != _ptr) {
2845       *_ptr = '\0';          // Terminate the string
2846       encoding->add_code(start);
2847     }
2848 
2849     // (2)
2850     // If we are at a replacement variable,
2851     // copy it and record in EncClass
2852     if (_curchar == '$') {
2853       // Found replacement Variable
2854       char* rep_var = get_rep_var_ident_dup();
2855 
2856       // Add flag to _strings list indicating we should check _rep_vars
2857       encoding->add_rep_var(rep_var);
2858 
2859       skipws();
2860 
2861       // Check if this instruct is a MachConstantNode.
2862       if (strcmp(rep_var, "constanttablebase") == 0) {
2863         // This instruct is a MachConstantNode.
2864         inst.set_is_mach_constant(true);
2865 
2866         if (_curchar == '(')  {
2867           parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument (only constantaddress and constantoffset)", ec_name);
2868           return;
2869         }
2870       }
2871       else if ((strcmp(rep_var, "constantaddress")   == 0) ||
2872                (strcmp(rep_var, "constantoffset")    == 0)) {
2873         // This instruct is a MachConstantNode.
2874         inst.set_is_mach_constant(true);
2875 
2876         // If the constant keyword has an argument, parse it.
2877         if (_curchar == '(')  constant_parse(inst);
2878       }
2879     }
2880   } // end while part of format description
2881   next_char();                      // Skip '%'
2882   next_char();                      // Skip '}'
2883 
2884   skipws();
2885 
2886   if (_AD._adlocation_debug) {
2887     encoding->add_code(end_line_marker());
2888   }
2889 
2890   // Debug Stuff
2891   if (_AD._adl_debug > 1)  fprintf(stderr, "EncodingClass Form: %s\n", ec_name);
2892 }
2893 
2894 
2895 //------------------------------ins_encode_parse-------------------------------
2896 // Encode rules have the form
2897 //   ins_encode( encode_class_name(parameter_list), ... );
2898 //
2899 // The "encode_class_name" must be defined in the encode section
2900 // The parameter list contains $names that are locals.
2901 //
2902 // Alternatively it can be written like this:
2903 //
2904 //   ins_encode %{
2905 //      ... // body
2906 //   %}
2907 //
2908 // which synthesizes a new encoding class taking the same arguments as
2909 // the InstructForm, and automatically prefixes the definition with:
2910 //
2911 //    MacroAssembler masm(&cbuf);\n");
2912 //
2913 //  making it more compact to take advantage of the MacroAssembler and
2914 //  placing the assembly closer to it's use by instructions.
2915 void ADLParser::ins_encode_parse(InstructForm& inst) {
2916 
2917   // Parse encode class name
2918   skipws();                        // Skip whitespace
2919   if (_curchar != '(') {
2920     // Check for ins_encode %{ form
2921     if ((_curchar == '%') && (*(_ptr+1) == '{')) {
2922       next_char();                      // Skip '%'
2923       next_char();                      // Skip '{'
2924 
2925       // Parse the block form of ins_encode
2926       ins_encode_parse_block(inst);
2927       return;
2928     }
2929 
2930     parse_err(SYNERR, "missing '%%{' or '(' in ins_encode definition\n");
2931     return;
2932   }
2933   next_char();                     // move past '('
2934   skipws();
2935 
2936   InsEncode *encrule  = new InsEncode(); // Encode class for instruction
2937   encrule->_linenum = linenum();
2938   char      *ec_name  = NULL;      // String representation of encode rule
2939   // identifier is optional.
2940   while (_curchar != ')') {
2941     ec_name = get_ident();
2942     if (ec_name == NULL) {
2943       parse_err(SYNERR, "Invalid encode class name after 'ins_encode('.\n");
2944       return;
2945     }
2946     // Check that encoding is defined in the encode section
2947     EncClass *encode_class = _AD._encode->encClass(ec_name);
2948     if (encode_class == NULL) {
2949       // Like to defer checking these till later...
2950       // parse_err(WARN, "Using an undefined encode class '%s' in 'ins_encode'.\n", ec_name);
2951     }
2952 
2953     // Get list for encode method's parameters
2954     NameAndList *params = encrule->add_encode(ec_name);
2955 
2956     // Parse the parameters to this encode method.
2957     skipws();
2958     if ( _curchar == '(' ) {
2959       next_char();                 // move past '(' for parameters
2960 
2961       // Parse the encode method's parameters
2962       while (_curchar != ')') {
2963         char *param = get_ident_or_literal_constant("encoding operand");
2964         if ( param != NULL ) {
2965           // Found a parameter:
2966           // Check it is a local name, add it to the list, then check for more
2967           // New: allow hex constants as parameters to an encode method.
2968           // New: allow parenthesized expressions as parameters.
2969           // New: allow "primary", "secondary", "tertiary" as parameters.
2970           // New: allow user-defined register name as parameter
2971           if ( (inst._localNames[param] == NULL) &&
2972                !ADLParser::is_literal_constant(param) &&
2973                (Opcode::as_opcode_type(param) == Opcode::NOT_AN_OPCODE) &&
2974                ((_AD._register == NULL ) || (_AD._register->getRegDef(param) == NULL)) ) {
2975             parse_err(SYNERR, "Using non-locally defined parameter %s for encoding %s.\n", param, ec_name);
2976             return;
2977           }
2978           params->add_entry(param);
2979 
2980           skipws();
2981           if (_curchar == ',' ) {
2982             // More parameters to come
2983             next_char();           // move past ',' between parameters
2984             skipws();              // Skip to next parameter
2985           }
2986           else if (_curchar == ')') {
2987             // Done with parameter list
2988           }
2989           else {
2990             // Only ',' or ')' are valid after a parameter name
2991             parse_err(SYNERR, "expected ',' or ')' after parameter %s.\n",
2992                       ec_name);
2993             return;
2994           }
2995 
2996         } else {
2997           skipws();
2998           // Did not find a parameter
2999           if (_curchar == ',') {
3000             parse_err(SYNERR, "Expected encode parameter before ',' in encoding %s.\n", ec_name);
3001             return;
3002           }
3003           if (_curchar != ')') {
3004             parse_err(SYNERR, "Expected ')' after encode parameters.\n");
3005             return;
3006           }
3007         }
3008       } // WHILE loop collecting parameters
3009       next_char();                   // move past ')' at end of parameters
3010     } // done with parameter list for encoding
3011 
3012     // Check for ',' or ')' after encoding
3013     skipws();                      // move to character after parameters
3014     if ( _curchar == ',' ) {
3015       // Found a ','
3016       next_char();                 // move past ',' between encode methods
3017       skipws();
3018     }
3019     else if ( _curchar != ')' ) {
3020       // If not a ',' then only a ')' is allowed
3021       parse_err(SYNERR, "Expected ')' after encoding %s.\n", ec_name);
3022       return;
3023     }
3024 
3025     // Check for ',' separating parameters
3026     // if ( _curchar != ',' && _curchar != ')' ) {
3027     //   parse_err(SYNERR, "expected ',' or ')' after encode method inside ins_encode.\n");
3028     //   return NULL;
3029     // }
3030 
3031   } // done parsing ins_encode methods and their parameters
3032   if (_curchar != ')') {
3033     parse_err(SYNERR, "Missing ')' at end of ins_encode description.\n");
3034     return;
3035   }
3036   next_char();                     // move past ')'
3037   skipws();                        // Skip leading whitespace
3038 
3039   if ( _curchar != ';' ) {
3040     parse_err(SYNERR, "Missing ';' at end of ins_encode.\n");
3041     return;
3042   }
3043   next_char();                     // move past ';'
3044   skipws();                        // be friendly to oper_parse()
3045 
3046   // Debug Stuff
3047   if (_AD._adl_debug > 1) fprintf(stderr,"Instruction Encode: %s\n", ec_name);
3048 
3049   // Set encode class of this instruction.
3050   inst._insencode = encrule;
3051 }
3052 
3053 
3054 //------------------------------constant_parse---------------------------------
3055 // Parse a constant expression.
3056 void ADLParser::constant_parse(InstructForm& inst) {
3057   // Create a new encoding name based on the name of the instruction
3058   // definition, which should be unique.
3059   const char* prefix = "__constant_";
3060   char* ec_name = (char*) malloc(strlen(inst._ident) + strlen(prefix) + 1);
3061   sprintf(ec_name, "%s%s", prefix, inst._ident);
3062 
3063   assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
3064   EncClass* encoding = _AD._encode->add_EncClass(ec_name);
3065   encoding->_linenum = linenum();
3066 
3067   // synthesize the arguments list for the enc_class from the
3068   // arguments to the instruct definition.
3069   const char* param = NULL;
3070   inst._parameters.reset();
3071   while ((param = inst._parameters.iter()) != NULL) {
3072     OperandForm* opForm = (OperandForm*) inst._localNames[param];
3073     encoding->add_parameter(opForm->_ident, param);
3074   }
3075 
3076   // Parse the following ( ) expression.
3077   constant_parse_expression(encoding, ec_name);
3078 
3079   // Build an encoding rule which invokes the encoding rule we just
3080   // created, passing all arguments that we received.
3081   InsEncode*   encrule = new InsEncode(); // Encode class for instruction
3082   NameAndList* params  = encrule->add_encode(ec_name);
3083   inst._parameters.reset();
3084   while ((param = inst._parameters.iter()) != NULL) {
3085     params->add_entry(param);
3086   }
3087 
3088   // Set encode class of this instruction.
3089   inst._constant = encrule;
3090 }
3091 
3092 
3093 //------------------------------constant_parse_expression----------------------
3094 void ADLParser::constant_parse_expression(EncClass* encoding, char* ec_name) {
3095   skipws();
3096 
3097   // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block
3098   if (_AD._adlocation_debug) {
3099     encoding->add_code(get_line_string());
3100   }
3101 
3102   // Start code line.
3103   encoding->add_code("    add_to_constant_table");
3104 
3105   // Parse everything in ( ) expression.
3106   encoding->add_code("(");
3107   next_char();  // Skip '('
3108   int parens_depth = 1;
3109 
3110   // Collect the parts of the constant expression.
3111   // (1) strings that are passed through to output
3112   // (2) replacement/substitution variable, preceeded by a '$'
3113   while (parens_depth > 0) {
3114     if (_curchar == '(') {
3115       parens_depth++;
3116       encoding->add_code("(");
3117       next_char();
3118     }
3119     else if (_curchar == ')') {
3120       parens_depth--;
3121       encoding->add_code(")");
3122       next_char();
3123     }
3124     else {
3125       // (1)
3126       // Check if there is a string to pass through to output
3127       char *start = _ptr;  // Record start of the next string
3128       while ((_curchar != '$') && (_curchar != '(') && (_curchar != ')')) {
3129         next_char();
3130       }
3131       // If a string was found, terminate it and record in EncClass
3132       if (start != _ptr) {
3133         *_ptr = '\0';  // Terminate the string
3134         encoding->add_code(start);
3135       }
3136 
3137       // (2)
3138       // If we are at a replacement variable, copy it and record in EncClass.
3139       if (_curchar == '$') {
3140         // Found replacement Variable
3141         char* rep_var = get_rep_var_ident_dup();
3142         encoding->add_rep_var(rep_var);
3143       }
3144     }
3145   }
3146 
3147   // Finish code line.
3148   encoding->add_code(";");
3149 
3150   if (_AD._adlocation_debug) {
3151     encoding->add_code(end_line_marker());
3152   }
3153 
3154   // Debug Stuff
3155   if (_AD._adl_debug > 1)  fprintf(stderr, "EncodingClass Form: %s\n", ec_name);
3156 }
3157 
3158 
3159 //------------------------------size_parse-----------------------------------
3160 char* ADLParser::size_parse(InstructForm *instr) {
3161   char* sizeOfInstr = NULL;
3162 
3163   // Get value of the instruction's size
3164   skipws();
3165 
3166   // Parse size
3167   sizeOfInstr = get_paren_expr("size expression");
3168   if (sizeOfInstr == NULL) {
3169      parse_err(SYNERR, "size of opcode expected at %c\n", _curchar);
3170      return NULL;
3171   }
3172 
3173   skipws();
3174 
3175   // Check for terminator


src/share/vm/adlc/adlparse.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File