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
|