< prev index next >

src/hotspot/share/adlc/adlparse.cpp

Print this page




 193           if( instr->is_ideal_control() ) {
 194             // Control instructions return a special result, 'Universe'
 195             rule->_result = "Universe";
 196           }
 197           // Check for commutative operations with tree operands.
 198           matchrule_clone_and_swap(rule, instr->_ident, match_rules_cnt);
 199         }
 200       } else {
 201         // Find the end of the match rule list
 202         while (rule->_next != NULL)
 203           rule = rule->_next;
 204         // Add the new match rule to the list
 205         rule->_next = match_parse(instr->_localNames);
 206         if (rule->_next) {
 207           rule = rule->_next;
 208           if( instr->is_ideal_control() ) {
 209             parse_err(SYNERR, "unique match rule expected for %s\n", rule->_name);
 210             return;
 211           }
 212           assert(match_rules_cnt < 100," too many match rule clones");
 213           char* buf = (char*) malloc(strlen(instr->_ident) + 4);
 214           sprintf(buf, "%s_%d", instr->_ident, match_rules_cnt++);
 215           rule->_result = buf;
 216           // Check for commutative operations with tree operands.
 217           matchrule_clone_and_swap(rule, instr->_ident, match_rules_cnt);
 218         }
 219       }
 220     }
 221     else if (!strcmp(ident, "encode"))  {
 222       parse_err(SYNERR, "Instructions specify ins_encode, not encode\n");
 223     }
 224     else if (!strcmp(ident, "ins_encode"))       ins_encode_parse(*instr);
 225     // Parse late expand keyword.
 226     else if (!strcmp(ident, "postalloc_expand")) postalloc_expand_parse(*instr);
 227     else if (!strcmp(ident, "opcode"))           instr->_opcode    = opcode_parse(instr);
 228     else if (!strcmp(ident, "size"))             instr->_size      = size_parse(instr);
 229     else if (!strcmp(ident, "effect"))           effect_parse(instr);
 230     else if (!strcmp(ident, "expand"))           instr->_exprule   = expand_parse(instr);
 231     else if (!strcmp(ident, "rewrite"))          instr->_rewrule   = rewrite_parse();
 232     else if (!strcmp(ident, "constraint")) {
 233       parse_err(SYNERR, "Instructions do not specify a constraint\n");


2841   // Debug Stuff
2842   if (_AD._adl_debug > 1) fprintf(stderr,"Predicate: %s\n", rule);
2843   if (_curchar != ';') {
2844     parse_err(SYNERR, "missing ';' in predicate definition\n");
2845     return NULL;
2846   }
2847   next_char();                     // Point after the terminator
2848 
2849   predicate = new Predicate(rule); // Build new predicate object
2850   skipws();
2851   return predicate;
2852 }
2853 
2854 
2855 //------------------------------ins_encode_parse_block-------------------------
2856 // Parse the block form of ins_encode.  See ins_encode_parse for more details
2857 void ADLParser::ins_encode_parse_block(InstructForm& inst) {
2858   // Create a new encoding name based on the name of the instruction
2859   // definition, which should be unique.
2860   const char* prefix = "__ins_encode_";
2861   char* ec_name = (char*) malloc(strlen(inst._ident) + strlen(prefix) + 1);
2862   sprintf(ec_name, "%s%s", prefix, inst._ident);
2863 
2864   assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
2865   EncClass* encoding = _AD._encode->add_EncClass(ec_name);
2866   encoding->_linenum = linenum();
2867 
2868   // synthesize the arguments list for the enc_class from the
2869   // arguments to the instruct definition.
2870   const char* param = NULL;
2871   inst._parameters.reset();
2872   while ((param = inst._parameters.iter()) != NULL) {
2873     OperandForm* opForm = (OperandForm*) inst._localNames[param];
2874     encoding->add_parameter(opForm->_ident, param);
2875   }
2876 
2877   if (!inst._is_postalloc_expand) {
2878     // Define a MacroAssembler instance for use by the encoding.  The
2879     // name is chosen to match the __ idiom used for assembly in other
2880     // parts of hotspot and assumes the existence of the standard
2881     // #define __ _masm.


3311     parse_err(SYNERR, "Missing ';' at end of postalloc_expand.\n");
3312     return;
3313   }
3314   next_char();                     // Move past ';'.
3315   skipws();                        // Be friendly to oper_parse().
3316 
3317   // Debug Stuff.
3318   if (_AD._adl_debug > 1) fprintf(stderr, "Instruction postalloc_expand: %s\n", ec_name);
3319 
3320   // Set encode class of this instruction.
3321   inst._insencode = encrule;
3322 }
3323 
3324 
3325 //------------------------------constant_parse---------------------------------
3326 // Parse a constant expression.
3327 void ADLParser::constant_parse(InstructForm& inst) {
3328   // Create a new encoding name based on the name of the instruction
3329   // definition, which should be unique.
3330   const char* prefix = "__constant_";
3331   char* ec_name = (char*) malloc(strlen(inst._ident) + strlen(prefix) + 1);
3332   sprintf(ec_name, "%s%s", prefix, inst._ident);
3333 
3334   assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
3335   EncClass* encoding = _AD._encode->add_EncClass(ec_name);
3336   encoding->_linenum = linenum();
3337 
3338   // synthesize the arguments list for the enc_class from the
3339   // arguments to the instruct definition.
3340   const char* param = NULL;
3341   inst._parameters.reset();
3342   while ((param = inst._parameters.iter()) != NULL) {
3343     OperandForm* opForm = (OperandForm*) inst._localNames[param];
3344     encoding->add_parameter(opForm->_ident, param);
3345   }
3346 
3347   // Parse the following ( ) expression.
3348   constant_parse_expression(encoding, ec_name);
3349 
3350   // Build an encoding rule which invokes the encoding rule we just
3351   // created, passing all arguments that we received.


4443     skipws_no_preproc();          // Skip leading whitespace
4444     cppBlock = _ptr;              // Point to start of expression
4445     int line = linenum();
4446     next = _ptr + 1;
4447     while(((_curchar != '%') || (*next != '}')) && (_curchar != '\0')) {
4448       next_char_or_line();
4449       next = _ptr+1;              // Maintain the next pointer
4450     }                             // Grab string
4451     if (_curchar == '\0') {
4452       parse_err(SYNERR, "invalid termination of %s \n", description);
4453       return NULL;
4454     }
4455     *_ptr = '\0';                 // Terminate string
4456     _ptr += 2;                    // Skip block delimiter
4457     _curchar = *_ptr;             // Maintain invariant
4458 
4459     // Prepend location descriptor, for debugging.
4460     if (_AD._adlocation_debug) {
4461       char* location = get_line_string(line);
4462       char* end_loc  = end_line_marker();
4463       char* result = (char *)malloc(strlen(location) + strlen(cppBlock) + strlen(end_loc) + 1);
4464       strcpy(result, location);
4465       strcat(result, cppBlock);
4466       strcat(result, end_loc);
4467       cppBlock = result;
4468       free(location);
4469     }
4470   }
4471 
4472   return cppBlock;
4473 }
4474 
4475 // Move to the closing token of the expression we are currently at,
4476 // as defined by stop_chars.  Match parens and quotes.
4477 char* ADLParser::get_expr(const char *desc, const char *stop_chars) {
4478   char* expr = NULL;
4479   int   paren = 0;
4480 
4481   expr = _ptr;
4482   while (paren > 0 || !strchr(stop_chars, _curchar)) {
4483     if (_curchar == '(') {        // Down level of nesting


4532   assert(strchr(stop_chars, _curchar), "non-null return must be at stop-char");
4533   *_ptr = '\0';               // Replace ')' or other stop-char with '\0'
4534   return expr;
4535 }
4536 
4537 // Helper function around get_expr
4538 // Sets _curchar to '(' so that get_paren_expr will search for a matching ')'
4539 char *ADLParser::get_paren_expr(const char *description, bool include_location) {
4540   int line = linenum();
4541   if (_curchar != '(')            // Escape if not valid starting position
4542     return NULL;
4543   next_char();                    // Skip the required initial paren.
4544   char *token2 = get_expr(description, ")");
4545   if (_curchar == ')')
4546     next_char();                  // Skip required final paren.
4547   int junk = 0;
4548   if (include_location && _AD._adlocation_debug && !is_int_token(token2, junk)) {
4549     // Prepend location descriptor, for debugging.
4550     char* location = get_line_string(line);
4551     char* end_loc  = end_line_marker();
4552     char* result = (char *)malloc(strlen(location) + strlen(token2) + strlen(end_loc) + 1);
4553     strcpy(result, location);
4554     strcat(result, token2);
4555     strcat(result, end_loc);
4556     token2 = result;
4557     free(location);
4558   }
4559   return token2;
4560 }
4561 
4562 //------------------------------get_ident_common-------------------------------
4563 // Looks for an identifier in the buffer, and turns it into a null terminated
4564 // string(still inside the file buffer).  Returns a pointer to the string or
4565 // NULL if some other token is found instead.
4566 char *ADLParser::get_ident_common(bool do_preproc) {
4567   char c;
4568   char *start;                    // Pointer to start of token
4569   char *end;                      // Pointer to end of token
4570 
4571   if( _curline == NULL )          // Return NULL at EOF.
4572     return NULL;


4630   char *ident = get_ident();
4631 
4632   // Duplicate an identifier before returning and restore string.
4633   if( ident != NULL ) {
4634     ident = strdup(ident);  // Copy the string
4635     *_ptr   = _curchar;         // and replace Nil with original character
4636   }
4637 
4638   return ident;
4639 }
4640 
4641 //----------------------get_ident_or_literal_constant--------------------------
4642 // Looks for an identifier in the buffer, or a parenthesized expression.
4643 char *ADLParser::get_ident_or_literal_constant(const char* description) {
4644   char* param = NULL;
4645   skipws();
4646   if (_curchar == '(') {
4647     // Grab a constant expression.
4648     param = get_paren_expr(description);
4649     if (param[0] != '(') {
4650       char* buf = (char*) malloc(strlen(param) + 3);
4651       sprintf(buf, "(%s)", param);
4652       param = buf;
4653     }
4654     assert(is_literal_constant(param),
4655            "expr must be recognizable as a constant");
4656   } else {
4657     param = get_ident();
4658   }
4659   return param;
4660 }
4661 
4662 //------------------------------get_rep_var_ident-----------------------------
4663 // Do NOT duplicate,
4664 // Leave nil terminator in buffer
4665 // Preserve initial '$'(s) in string
4666 char *ADLParser::get_rep_var_ident(void) {
4667   // Remember starting point
4668   char *rep_var = _ptr;
4669 
4670   // Check for replacement variable indicator '$' and pass if present


5238     _curchar = *++_ptr;
5239   } else {
5240     next_line();
5241     _ptr = _curline;
5242     _curchar = *_ptr;  // maintain invariant
5243   }
5244 }
5245 
5246 //---------------------------next_line-----------------------------------------
5247 void ADLParser::next_line() {
5248   _curline = _buf.get_line();
5249   _curchar = ' ';
5250 }
5251 
5252 //------------------------get_line_string--------------------------------------
5253 // Prepended location descriptor, for debugging.
5254 // Must return a malloced string (that can be freed if desired).
5255 char* ADLParser::get_line_string(int linenum) {
5256   const char* file = _AD._ADL_file._name;
5257   int         line = linenum ? linenum : this->linenum();
5258   char* location = (char *)malloc(strlen(file) + 100);
5259   sprintf(location, "\n#line %d \"%s\"\n", line, file);
5260   return location;
5261 }
5262 
5263 //-------------------------is_literal_constant---------------------------------
5264 bool ADLParser::is_literal_constant(const char *param) {
5265   if (param[0] == 0)     return false;  // null string
5266   if (param[0] == '(')   return true;   // parenthesized expression
5267   if (param[0] == '0' && (param[1] == 'x' || param[1] == 'X')) {
5268     // Make sure it's a hex constant.
5269     int i = 2;
5270     do {
5271       if( !ADLParser::is_hex_digit(*(param+i)) )  return false;
5272       ++i;
5273     } while( *(param+i) != 0 );
5274     return true;
5275   }
5276   return false;
5277 }
5278 




 193           if( instr->is_ideal_control() ) {
 194             // Control instructions return a special result, 'Universe'
 195             rule->_result = "Universe";
 196           }
 197           // Check for commutative operations with tree operands.
 198           matchrule_clone_and_swap(rule, instr->_ident, match_rules_cnt);
 199         }
 200       } else {
 201         // Find the end of the match rule list
 202         while (rule->_next != NULL)
 203           rule = rule->_next;
 204         // Add the new match rule to the list
 205         rule->_next = match_parse(instr->_localNames);
 206         if (rule->_next) {
 207           rule = rule->_next;
 208           if( instr->is_ideal_control() ) {
 209             parse_err(SYNERR, "unique match rule expected for %s\n", rule->_name);
 210             return;
 211           }
 212           assert(match_rules_cnt < 100," too many match rule clones");
 213           char* buf = (char*) AllocateHeap(strlen(instr->_ident) + 4);
 214           sprintf(buf, "%s_%d", instr->_ident, match_rules_cnt++);
 215           rule->_result = buf;
 216           // Check for commutative operations with tree operands.
 217           matchrule_clone_and_swap(rule, instr->_ident, match_rules_cnt);
 218         }
 219       }
 220     }
 221     else if (!strcmp(ident, "encode"))  {
 222       parse_err(SYNERR, "Instructions specify ins_encode, not encode\n");
 223     }
 224     else if (!strcmp(ident, "ins_encode"))       ins_encode_parse(*instr);
 225     // Parse late expand keyword.
 226     else if (!strcmp(ident, "postalloc_expand")) postalloc_expand_parse(*instr);
 227     else if (!strcmp(ident, "opcode"))           instr->_opcode    = opcode_parse(instr);
 228     else if (!strcmp(ident, "size"))             instr->_size      = size_parse(instr);
 229     else if (!strcmp(ident, "effect"))           effect_parse(instr);
 230     else if (!strcmp(ident, "expand"))           instr->_exprule   = expand_parse(instr);
 231     else if (!strcmp(ident, "rewrite"))          instr->_rewrule   = rewrite_parse();
 232     else if (!strcmp(ident, "constraint")) {
 233       parse_err(SYNERR, "Instructions do not specify a constraint\n");


2841   // Debug Stuff
2842   if (_AD._adl_debug > 1) fprintf(stderr,"Predicate: %s\n", rule);
2843   if (_curchar != ';') {
2844     parse_err(SYNERR, "missing ';' in predicate definition\n");
2845     return NULL;
2846   }
2847   next_char();                     // Point after the terminator
2848 
2849   predicate = new Predicate(rule); // Build new predicate object
2850   skipws();
2851   return predicate;
2852 }
2853 
2854 
2855 //------------------------------ins_encode_parse_block-------------------------
2856 // Parse the block form of ins_encode.  See ins_encode_parse for more details
2857 void ADLParser::ins_encode_parse_block(InstructForm& inst) {
2858   // Create a new encoding name based on the name of the instruction
2859   // definition, which should be unique.
2860   const char* prefix = "__ins_encode_";
2861   char* ec_name = (char*) AllocateHeap(strlen(inst._ident) + strlen(prefix) + 1);
2862   sprintf(ec_name, "%s%s", prefix, inst._ident);
2863 
2864   assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
2865   EncClass* encoding = _AD._encode->add_EncClass(ec_name);
2866   encoding->_linenum = linenum();
2867 
2868   // synthesize the arguments list for the enc_class from the
2869   // arguments to the instruct definition.
2870   const char* param = NULL;
2871   inst._parameters.reset();
2872   while ((param = inst._parameters.iter()) != NULL) {
2873     OperandForm* opForm = (OperandForm*) inst._localNames[param];
2874     encoding->add_parameter(opForm->_ident, param);
2875   }
2876 
2877   if (!inst._is_postalloc_expand) {
2878     // Define a MacroAssembler instance for use by the encoding.  The
2879     // name is chosen to match the __ idiom used for assembly in other
2880     // parts of hotspot and assumes the existence of the standard
2881     // #define __ _masm.


3311     parse_err(SYNERR, "Missing ';' at end of postalloc_expand.\n");
3312     return;
3313   }
3314   next_char();                     // Move past ';'.
3315   skipws();                        // Be friendly to oper_parse().
3316 
3317   // Debug Stuff.
3318   if (_AD._adl_debug > 1) fprintf(stderr, "Instruction postalloc_expand: %s\n", ec_name);
3319 
3320   // Set encode class of this instruction.
3321   inst._insencode = encrule;
3322 }
3323 
3324 
3325 //------------------------------constant_parse---------------------------------
3326 // Parse a constant expression.
3327 void ADLParser::constant_parse(InstructForm& inst) {
3328   // Create a new encoding name based on the name of the instruction
3329   // definition, which should be unique.
3330   const char* prefix = "__constant_";
3331   char* ec_name = (char*) AllocateHeap(strlen(inst._ident) + strlen(prefix) + 1);
3332   sprintf(ec_name, "%s%s", prefix, inst._ident);
3333 
3334   assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
3335   EncClass* encoding = _AD._encode->add_EncClass(ec_name);
3336   encoding->_linenum = linenum();
3337 
3338   // synthesize the arguments list for the enc_class from the
3339   // arguments to the instruct definition.
3340   const char* param = NULL;
3341   inst._parameters.reset();
3342   while ((param = inst._parameters.iter()) != NULL) {
3343     OperandForm* opForm = (OperandForm*) inst._localNames[param];
3344     encoding->add_parameter(opForm->_ident, param);
3345   }
3346 
3347   // Parse the following ( ) expression.
3348   constant_parse_expression(encoding, ec_name);
3349 
3350   // Build an encoding rule which invokes the encoding rule we just
3351   // created, passing all arguments that we received.


4443     skipws_no_preproc();          // Skip leading whitespace
4444     cppBlock = _ptr;              // Point to start of expression
4445     int line = linenum();
4446     next = _ptr + 1;
4447     while(((_curchar != '%') || (*next != '}')) && (_curchar != '\0')) {
4448       next_char_or_line();
4449       next = _ptr+1;              // Maintain the next pointer
4450     }                             // Grab string
4451     if (_curchar == '\0') {
4452       parse_err(SYNERR, "invalid termination of %s \n", description);
4453       return NULL;
4454     }
4455     *_ptr = '\0';                 // Terminate string
4456     _ptr += 2;                    // Skip block delimiter
4457     _curchar = *_ptr;             // Maintain invariant
4458 
4459     // Prepend location descriptor, for debugging.
4460     if (_AD._adlocation_debug) {
4461       char* location = get_line_string(line);
4462       char* end_loc  = end_line_marker();
4463       char* result = (char *)AllocateHeap(strlen(location) + strlen(cppBlock) + strlen(end_loc) + 1);
4464       strcpy(result, location);
4465       strcat(result, cppBlock);
4466       strcat(result, end_loc);
4467       cppBlock = result;
4468       free(location);
4469     }
4470   }
4471 
4472   return cppBlock;
4473 }
4474 
4475 // Move to the closing token of the expression we are currently at,
4476 // as defined by stop_chars.  Match parens and quotes.
4477 char* ADLParser::get_expr(const char *desc, const char *stop_chars) {
4478   char* expr = NULL;
4479   int   paren = 0;
4480 
4481   expr = _ptr;
4482   while (paren > 0 || !strchr(stop_chars, _curchar)) {
4483     if (_curchar == '(') {        // Down level of nesting


4532   assert(strchr(stop_chars, _curchar), "non-null return must be at stop-char");
4533   *_ptr = '\0';               // Replace ')' or other stop-char with '\0'
4534   return expr;
4535 }
4536 
4537 // Helper function around get_expr
4538 // Sets _curchar to '(' so that get_paren_expr will search for a matching ')'
4539 char *ADLParser::get_paren_expr(const char *description, bool include_location) {
4540   int line = linenum();
4541   if (_curchar != '(')            // Escape if not valid starting position
4542     return NULL;
4543   next_char();                    // Skip the required initial paren.
4544   char *token2 = get_expr(description, ")");
4545   if (_curchar == ')')
4546     next_char();                  // Skip required final paren.
4547   int junk = 0;
4548   if (include_location && _AD._adlocation_debug && !is_int_token(token2, junk)) {
4549     // Prepend location descriptor, for debugging.
4550     char* location = get_line_string(line);
4551     char* end_loc  = end_line_marker();
4552     char* result = (char *)AllocateHeap(strlen(location) + strlen(token2) + strlen(end_loc) + 1);
4553     strcpy(result, location);
4554     strcat(result, token2);
4555     strcat(result, end_loc);
4556     token2 = result;
4557     free(location);
4558   }
4559   return token2;
4560 }
4561 
4562 //------------------------------get_ident_common-------------------------------
4563 // Looks for an identifier in the buffer, and turns it into a null terminated
4564 // string(still inside the file buffer).  Returns a pointer to the string or
4565 // NULL if some other token is found instead.
4566 char *ADLParser::get_ident_common(bool do_preproc) {
4567   char c;
4568   char *start;                    // Pointer to start of token
4569   char *end;                      // Pointer to end of token
4570 
4571   if( _curline == NULL )          // Return NULL at EOF.
4572     return NULL;


4630   char *ident = get_ident();
4631 
4632   // Duplicate an identifier before returning and restore string.
4633   if( ident != NULL ) {
4634     ident = strdup(ident);  // Copy the string
4635     *_ptr   = _curchar;         // and replace Nil with original character
4636   }
4637 
4638   return ident;
4639 }
4640 
4641 //----------------------get_ident_or_literal_constant--------------------------
4642 // Looks for an identifier in the buffer, or a parenthesized expression.
4643 char *ADLParser::get_ident_or_literal_constant(const char* description) {
4644   char* param = NULL;
4645   skipws();
4646   if (_curchar == '(') {
4647     // Grab a constant expression.
4648     param = get_paren_expr(description);
4649     if (param[0] != '(') {
4650       char* buf = (char*) AllocateHeap(strlen(param) + 3);
4651       sprintf(buf, "(%s)", param);
4652       param = buf;
4653     }
4654     assert(is_literal_constant(param),
4655            "expr must be recognizable as a constant");
4656   } else {
4657     param = get_ident();
4658   }
4659   return param;
4660 }
4661 
4662 //------------------------------get_rep_var_ident-----------------------------
4663 // Do NOT duplicate,
4664 // Leave nil terminator in buffer
4665 // Preserve initial '$'(s) in string
4666 char *ADLParser::get_rep_var_ident(void) {
4667   // Remember starting point
4668   char *rep_var = _ptr;
4669 
4670   // Check for replacement variable indicator '$' and pass if present


5238     _curchar = *++_ptr;
5239   } else {
5240     next_line();
5241     _ptr = _curline;
5242     _curchar = *_ptr;  // maintain invariant
5243   }
5244 }
5245 
5246 //---------------------------next_line-----------------------------------------
5247 void ADLParser::next_line() {
5248   _curline = _buf.get_line();
5249   _curchar = ' ';
5250 }
5251 
5252 //------------------------get_line_string--------------------------------------
5253 // Prepended location descriptor, for debugging.
5254 // Must return a malloced string (that can be freed if desired).
5255 char* ADLParser::get_line_string(int linenum) {
5256   const char* file = _AD._ADL_file._name;
5257   int         line = linenum ? linenum : this->linenum();
5258   char* location = (char *)AllocateHeap(strlen(file) + 100);
5259   sprintf(location, "\n#line %d \"%s\"\n", line, file);
5260   return location;
5261 }
5262 
5263 //-------------------------is_literal_constant---------------------------------
5264 bool ADLParser::is_literal_constant(const char *param) {
5265   if (param[0] == 0)     return false;  // null string
5266   if (param[0] == '(')   return true;   // parenthesized expression
5267   if (param[0] == '0' && (param[1] == 'x' || param[1] == 'X')) {
5268     // Make sure it's a hex constant.
5269     int i = 2;
5270     do {
5271       if( !ADLParser::is_hex_digit(*(param+i)) )  return false;
5272       ++i;
5273     } while( *(param+i) != 0 );
5274     return true;
5275   }
5276   return false;
5277 }
5278 


< prev index next >