src/share/vm/adlc/adlparse.cpp

Print this page
rev 5661 : 8003854: PPC64 (part 115): Introduce lateExpand that expands nodes after register allocation.


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


 223     else if (!strcmp(ident, "opcode"))         instr->_opcode    = opcode_parse(instr);
 224     else if (!strcmp(ident, "size"))           instr->_size      = size_parse(instr);
 225     else if (!strcmp(ident, "effect"))         effect_parse(instr);
 226     else if (!strcmp(ident, "expand"))         instr->_exprule   = expand_parse(instr);
 227     else if (!strcmp(ident, "rewrite"))        instr->_rewrule   = rewrite_parse();
 228     else if (!strcmp(ident, "constraint")) {
 229       parse_err(SYNERR, "Instructions do not specify a constraint\n");
 230     }
 231     else if (!strcmp(ident, "construct")) {
 232       parse_err(SYNERR, "Instructions do not specify a construct\n");
 233     }
 234     else if (!strcmp(ident, "format"))         instr->_format    = format_parse();
 235     else if (!strcmp(ident, "interface")) {
 236       parse_err(SYNERR, "Instructions do not specify an interface\n");
 237     }
 238     else if (!strcmp(ident, "ins_pipe"))        ins_pipe_parse(*instr);
 239     else {  // Done with staticly defined parts of instruction definition
 240       // Check identifier to see if it is the name of an attribute
 241       const Form    *form = _globalNames[ident];
 242       AttributeForm *attr = form ? form->is_attribute() : NULL;
 243       if( attr && (attr->_atype == INS_ATTR) ) {
 244         // Insert the new attribute into the linked list.
 245         Attribute *temp = attr_parse(ident);
 246         temp->_next = instr->_attribs;
 247         instr->_attribs = temp;
 248       } else {
 249         parse_err(SYNERR, "expected one of:\n predicate, match, encode, or the name of an instruction attribute at %s\n", ident);
 250       }
 251     }
 252     skipws();
 253   } while(_curchar != '%');
 254   next_char();
 255   if (_curchar != '}') {
 256     parse_err(SYNERR, "missing '%%}' in instruction definition\n");
 257     return;
 258   }
 259   // Check for "Set" form of chain rule
 260   adjust_set_rule(instr);
 261   if (_AD._pipeline ) {
 262     if( instr->expands() ) {
 263       if( instr->_ins_pipe )

 264         parse_err(WARN, "ins_pipe and expand rule both specified for instruction \"%s\"; ins_pipe will be unused\n", instr->_ident);

 265     } else {
 266       if( !instr->_ins_pipe )
 267         parse_err(WARN, "No ins_pipe specified for instruction \"%s\"\n", instr->_ident);
 268     }
 269   }

 270   // Add instruction to tail of instruction list
 271   _AD.addForm(instr);
 272 
 273   // Create instruction form for each additional match rule
 274   rule = instr->_matrule;
 275   if (rule != NULL) {
 276     rule = rule->_next;
 277     while (rule != NULL) {
 278       ident = (char*)rule->_result;
 279       InstructForm *clone = new InstructForm(ident, instr, rule); // Create new instruction form
 280       _globalNames.Insert(ident, clone); // Add name to the name table
 281       // Debugging Stuff
 282       if (_AD._adl_debug > 1)
 283         fprintf(stderr,"Parsing Instruction Form %s\n", ident);
 284       // Check for "Set" form of chain rule
 285       adjust_set_rule(clone);
 286       // Add instruction to tail of instruction list
 287       _AD.addForm(clone);
 288       rule = rule->_next;
 289       clone->_matrule->_next = NULL; // One match rule per clone


2840     }
2841 
2842     // (2)
2843     // If we are at a replacement variable,
2844     // copy it and record in EncClass
2845     if (_curchar == '$') {
2846       // Found replacement Variable
2847       char* rep_var = get_rep_var_ident_dup();
2848 
2849       // Add flag to _strings list indicating we should check _rep_vars
2850       encoding->add_rep_var(rep_var);
2851 
2852       skipws();
2853 
2854       // Check if this instruct is a MachConstantNode.
2855       if (strcmp(rep_var, "constanttablebase") == 0) {
2856         // This instruct is a MachConstantNode.
2857         inst.set_is_mach_constant(true);
2858 
2859         if (_curchar == '(')  {
2860           parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument (only constantaddress and constantoffset)", ec_name);

2861           return;
2862         }
2863       }
2864       else if ((strcmp(rep_var, "constantaddress")   == 0) ||
2865                (strcmp(rep_var, "constantoffset")    == 0)) {
2866         // This instruct is a MachConstantNode.
2867         inst.set_is_mach_constant(true);
2868 
2869         // If the constant keyword has an argument, parse it.
2870         if (_curchar == '(')  constant_parse(inst);
2871       }
2872     }
2873   } // end while part of format description
2874   next_char();                      // Skip '%'
2875   next_char();                      // Skip '}'
2876 
2877   skipws();
2878 
2879   if (_AD._adlocation_debug) {
2880     encoding->add_code(end_line_marker());


3033     parse_err(SYNERR, "Missing ';' at end of ins_encode.\n");
3034     return;
3035   }
3036   next_char();                     // move past ';'
3037   skipws();                        // be friendly to oper_parse()
3038 
3039   // Check for duplicate ins_encode sections after parsing the block
3040   // so that parsing can continue and find any other errors.
3041   if (inst._insencode != NULL) {
3042     parse_err(SYNERR, "Multiple ins_encode sections defined\n");
3043     return;
3044   }
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];




 203         rule->_next = match_parse(instr->_localNames);
 204         if (rule->_next) {
 205           rule = rule->_next;
 206           if( instr->is_ideal_control() ) {
 207             parse_err(SYNERR, "unique match rule expected for %s\n", rule->_name);
 208             return;
 209           }
 210           assert(match_rules_cnt < 100," too many match rule clones");
 211           char* buf = (char*) malloc(strlen(instr->_ident) + 4);
 212           sprintf(buf, "%s_%d", instr->_ident, match_rules_cnt++);
 213           rule->_result = buf;
 214           // Check for commutative operations with tree operands.
 215           matchrule_clone_and_swap(rule, instr->_ident, match_rules_cnt);
 216         }
 217       }
 218     }
 219     else if (!strcmp(ident, "encode"))  {
 220       parse_err(SYNERR, "Instructions specify ins_encode, not encode\n");
 221     }
 222     else if (!strcmp(ident, "ins_encode"))     ins_encode_parse(*instr);
 223     // Parse late expand keyword.
 224     else if (!strcmp(ident, "lateExpand"))     lateExpand_parse(*instr);
 225     else if (!strcmp(ident, "opcode"))         instr->_opcode    = opcode_parse(instr);
 226     else if (!strcmp(ident, "size"))           instr->_size      = size_parse(instr);
 227     else if (!strcmp(ident, "effect"))         effect_parse(instr);
 228     else if (!strcmp(ident, "expand"))         instr->_exprule   = expand_parse(instr);
 229     else if (!strcmp(ident, "rewrite"))        instr->_rewrule   = rewrite_parse();
 230     else if (!strcmp(ident, "constraint")) {
 231       parse_err(SYNERR, "Instructions do not specify a constraint\n");
 232     }
 233     else if (!strcmp(ident, "construct")) {
 234       parse_err(SYNERR, "Instructions do not specify a construct\n");
 235     }
 236     else if (!strcmp(ident, "format"))         instr->_format    = format_parse();
 237     else if (!strcmp(ident, "interface")) {
 238       parse_err(SYNERR, "Instructions do not specify an interface\n");
 239     }
 240     else if (!strcmp(ident, "ins_pipe"))        ins_pipe_parse(*instr);
 241     else {  // Done with staticly defined parts of instruction definition
 242       // Check identifier to see if it is the name of an attribute
 243       const Form    *form = _globalNames[ident];
 244       AttributeForm *attr = form ? form->is_attribute() : NULL;
 245       if (attr && (attr->_atype == INS_ATTR)) {
 246         // Insert the new attribute into the linked list.
 247         Attribute *temp = attr_parse(ident);
 248         temp->_next = instr->_attribs;
 249         instr->_attribs = temp;
 250       } else {
 251         parse_err(SYNERR, "expected one of:\n predicate, match, encode, or the name of an instruction attribute at %s\n", ident);
 252       }
 253     }
 254     skipws();
 255   } while(_curchar != '%');
 256   next_char();
 257   if (_curchar != '}') {
 258     parse_err(SYNERR, "missing '%%}' in instruction definition\n");
 259     return;
 260   }
 261   // Check for "Set" form of chain rule
 262   adjust_set_rule(instr);
 263   if (_AD._pipeline) {
 264     // No pipe required for late expand.
 265     if (instr->expands() || instr->lateExpands()) {
 266       if (instr->_ins_pipe) {
 267         parse_err(WARN, "ins_pipe and expand rule both specified for instruction \"%s\"; ins_pipe will be unused\n", instr->_ident);
 268       }
 269     } else {
 270       if (!instr->_ins_pipe) {
 271         parse_err(WARN, "No ins_pipe specified for instruction \"%s\"\n", instr->_ident);
 272       }
 273     }
 274   }
 275   // Add instruction to tail of instruction list
 276   _AD.addForm(instr);
 277 
 278   // Create instruction form for each additional match rule
 279   rule = instr->_matrule;
 280   if (rule != NULL) {
 281     rule = rule->_next;
 282     while (rule != NULL) {
 283       ident = (char*)rule->_result;
 284       InstructForm *clone = new InstructForm(ident, instr, rule); // Create new instruction form
 285       _globalNames.Insert(ident, clone); // Add name to the name table
 286       // Debugging Stuff
 287       if (_AD._adl_debug > 1)
 288         fprintf(stderr,"Parsing Instruction Form %s\n", ident);
 289       // Check for "Set" form of chain rule
 290       adjust_set_rule(clone);
 291       // Add instruction to tail of instruction list
 292       _AD.addForm(clone);
 293       rule = rule->_next;
 294       clone->_matrule->_next = NULL; // One match rule per clone


2845     }
2846 
2847     // (2)
2848     // If we are at a replacement variable,
2849     // copy it and record in EncClass
2850     if (_curchar == '$') {
2851       // Found replacement Variable
2852       char* rep_var = get_rep_var_ident_dup();
2853 
2854       // Add flag to _strings list indicating we should check _rep_vars
2855       encoding->add_rep_var(rep_var);
2856 
2857       skipws();
2858 
2859       // Check if this instruct is a MachConstantNode.
2860       if (strcmp(rep_var, "constanttablebase") == 0) {
2861         // This instruct is a MachConstantNode.
2862         inst.set_is_mach_constant(true);
2863 
2864         if (_curchar == '(')  {
2865           parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument "
2866                             "(only constantaddress and constantoffset)", ec_name);
2867           return;
2868         }
2869       }
2870       else if ((strcmp(rep_var, "constantaddress")   == 0) ||
2871                (strcmp(rep_var, "constantoffset")    == 0)) {
2872         // This instruct is a MachConstantNode.
2873         inst.set_is_mach_constant(true);
2874 
2875         // If the constant keyword has an argument, parse it.
2876         if (_curchar == '(')  constant_parse(inst);
2877       }
2878     }
2879   } // end while part of format description
2880   next_char();                      // Skip '%'
2881   next_char();                      // Skip '}'
2882 
2883   skipws();
2884 
2885   if (_AD._adlocation_debug) {
2886     encoding->add_code(end_line_marker());


3039     parse_err(SYNERR, "Missing ';' at end of ins_encode.\n");
3040     return;
3041   }
3042   next_char();                     // move past ';'
3043   skipws();                        // be friendly to oper_parse()
3044 
3045   // Check for duplicate ins_encode sections after parsing the block
3046   // so that parsing can continue and find any other errors.
3047   if (inst._insencode != NULL) {
3048     parse_err(SYNERR, "Multiple ins_encode sections defined\n");
3049     return;
3050   }
3051 
3052   // Debug Stuff
3053   if (_AD._adl_debug > 1) fprintf(stderr,"Instruction Encode: %s\n", ec_name);
3054 
3055   // Set encode class of this instruction.
3056   inst._insencode = encrule;
3057 }
3058 
3059 //------------------------------lateExpand_parse-------------------------------
3060 // Encode rules have the form
3061 //   lateExpand( encode_class_name(parameter_list) );
3062 //
3063 // The "encode_class_name" must be defined in the encode section.
3064 // The parameter list contains $names that are locals.
3065 //
3066 // This is just a copy of ins_encode_parse without the loop.
3067 void ADLParser::lateExpand_parse(InstructForm& inst) {
3068   inst._is_lateExpand = true;
3069 
3070   // Parse encode class name.
3071   skipws();                        // Skip whitespace.
3072   if (_curchar != '(') {
3073 
3074     parse_err(SYNERR, "missing '(' in lateExpand definition\n");
3075     return;
3076   }
3077   next_char();                     // Move past '('.
3078   skipws();
3079 
3080   InsEncode *encrule = new InsEncode(); // Encode class for instruction.
3081   encrule->_linenum = linenum();
3082   char      *ec_name = NULL;       // String representation of encode rule.
3083   // identifier is optional.
3084   if (_curchar != ')') {
3085     ec_name = get_ident();
3086     if (ec_name == NULL) {
3087       parse_err(SYNERR, "Invalid lateExpand class name after 'lateExpand('.\n");
3088       return;
3089     }
3090     // Check that encoding is defined in the encode section.
3091     EncClass *encode_class = _AD._encode->encClass(ec_name);
3092 
3093     // Get list for encode method's parameters
3094     NameAndList *params = encrule->add_encode(ec_name);
3095 
3096     // Parse the parameters to this encode method.
3097     skipws();
3098     if (_curchar == '(') {
3099       next_char();                 // Move past '(' for parameters.
3100 
3101       // Parse the encode method's parameters.
3102       while (_curchar != ')') {
3103         char *param = get_ident_or_literal_constant("encoding operand");
3104         if (param != NULL) {
3105           // Found a parameter:
3106 
3107           // First check for constant table support.
3108 
3109           // Check if this instruct is a MachConstantNode.
3110           if (strcmp(param, "constanttablebase") == 0) {
3111             // This instruct is a MachConstantNode.
3112             inst.set_is_mach_constant(true);
3113 
3114             if (_curchar == '(') {
3115               parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument "
3116                         "(only constantaddress and constantoffset)", ec_name);
3117               return;
3118             }
3119           }
3120           else if ((strcmp(param, "constantaddress") == 0) ||
3121                    (strcmp(param, "constantoffset")  == 0))  {
3122             // This instruct is a MachConstantNode.
3123             inst.set_is_mach_constant(true);
3124 
3125             // If the constant keyword has an argument, parse it.
3126             if (_curchar == '(') constant_parse(inst);
3127           }
3128 
3129           // Else check it is a local name, add it to the list, then check for more.
3130           // New: allow hex constants as parameters to an encode method.
3131           // New: allow parenthesized expressions as parameters.
3132           // New: allow "primary", "secondary", "tertiary" as parameters.
3133           // New: allow user-defined register name as parameter.
3134           else if ((inst._localNames[param] == NULL) &&
3135                    !ADLParser::is_literal_constant(param) &&
3136                    (Opcode::as_opcode_type(param) == Opcode::NOT_AN_OPCODE) &&
3137                    ((_AD._register == NULL) || (_AD._register->getRegDef(param) == NULL))) {
3138             parse_err(SYNERR, "Using non-locally defined parameter %s for encoding %s.\n", param, ec_name);
3139             return;
3140           }
3141           params->add_entry(param);
3142 
3143           skipws();
3144           if (_curchar == ',') {
3145             // More parameters to come.
3146             next_char();           // Move past ',' between parameters.
3147             skipws();              // Skip to next parameter.
3148           } else if (_curchar == ')') {
3149             // Done with parameter list
3150           } else {
3151             // Only ',' or ')' are valid after a parameter name.
3152             parse_err(SYNERR, "expected ',' or ')' after parameter %s.\n", ec_name);
3153             return;
3154           }
3155 
3156         } else {
3157           skipws();
3158           // Did not find a parameter.
3159           if (_curchar == ',') {
3160             parse_err(SYNERR, "Expected encode parameter before ',' in lateExpand %s.\n", ec_name);
3161             return;
3162           }
3163           if (_curchar != ')') {
3164             parse_err(SYNERR, "Expected ')' after lateExpand parameters.\n");
3165             return;
3166           }
3167         }
3168       } // WHILE loop collecting parameters.
3169       next_char();                 // Move past ')' at end of parameters.
3170     } // Done with parameter list for encoding.
3171 
3172     // Check for ',' or ')' after encoding.
3173     skipws();                      // Move to character after parameters.
3174     if (_curchar != ')') {
3175       // Only a ')' is allowed.
3176       parse_err(SYNERR, "Expected ')' after lateExpand %s.\n", ec_name);
3177       return;
3178     }
3179   } // Done parsing lateExpand method and their parameters.
3180   if (_curchar != ')') {
3181     parse_err(SYNERR, "Missing ')' at end of lateExpand description.\n");
3182     return;
3183   }
3184   next_char();                     // Move past ')'.
3185   skipws();                        // Skip leading whitespace.
3186 
3187   if (_curchar != ';') {
3188     parse_err(SYNERR, "Missing ';' at end of lateExpand.\n");
3189     return;
3190   }
3191   next_char();                     // Move past ';'.
3192   skipws();                        // Be friendly to oper_parse().
3193 
3194   // Debug Stuff.
3195   if (_AD._adl_debug > 1) fprintf(stderr, "Instruction lateExpand: %s\n", ec_name);
3196 
3197   // Set encode class of this instruction.
3198   inst._insencode = encrule;
3199 }
3200 
3201 
3202 //------------------------------constant_parse---------------------------------
3203 // Parse a constant expression.
3204 void ADLParser::constant_parse(InstructForm& inst) {
3205   // Create a new encoding name based on the name of the instruction
3206   // definition, which should be unique.
3207   const char* prefix = "__constant_";
3208   char* ec_name = (char*) malloc(strlen(inst._ident) + strlen(prefix) + 1);
3209   sprintf(ec_name, "%s%s", prefix, inst._ident);
3210 
3211   assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
3212   EncClass* encoding = _AD._encode->add_EncClass(ec_name);
3213   encoding->_linenum = linenum();
3214 
3215   // synthesize the arguments list for the enc_class from the
3216   // arguments to the instruct definition.
3217   const char* param = NULL;
3218   inst._parameters.reset();
3219   while ((param = inst._parameters.iter()) != NULL) {
3220     OperandForm* opForm = (OperandForm*) inst._localNames[param];