comparison src/share/vm/adlc/adlparse.cpp @ 415:4d9884b01ba6

6754519: don't emit flag fixup for NaN when condition being tested doesn't need it Reviewed-by: kvn, rasbold
author never
date Tue, 28 Oct 2008 09:31:30 -0700
parents a61af66fc99e
children ad8c8ca4ab0f 284d0af00d53
comparison
equal deleted inserted replaced
407:ebfd4ae89bf6 415:4d9884b01ba6
31 ADLParser::ADLParser(FileBuff& buffer, ArchDesc& archDesc) 31 ADLParser::ADLParser(FileBuff& buffer, ArchDesc& archDesc)
32 : _buf(buffer), _AD(archDesc), 32 : _buf(buffer), _AD(archDesc),
33 _globalNames(archDesc.globalNames()) { 33 _globalNames(archDesc.globalNames()) {
34 _AD._syntax_errs = _AD._semantic_errs = 0; // No errors so far this file 34 _AD._syntax_errs = _AD._semantic_errs = 0; // No errors so far this file
35 _AD._warnings = 0; // No warnings either 35 _AD._warnings = 0; // No warnings either
36 _linenum = 0; // Will increment to first line
37 _curline = _ptr = NULL; // No pointers into buffer yet 36 _curline = _ptr = NULL; // No pointers into buffer yet
38 37
39 _preproc_depth = 0; 38 _preproc_depth = 0;
40 _preproc_not_taken = 0; 39 _preproc_not_taken = 0;
41 40
74 else fprintf(stderr,".\n\n"); 73 else fprintf(stderr,".\n\n");
75 } 74 }
76 } 75 }
77 if (!_AD._quiet_mode) 76 if (!_AD._quiet_mode)
78 fprintf(stderr,"-----------------------------------------------------------------------------\n"); 77 fprintf(stderr,"-----------------------------------------------------------------------------\n");
79 _AD._TotalLines += _linenum-1; // -1 for overshoot in "nextline" routine 78 _AD._TotalLines += linenum()-1; // -1 for overshoot in "nextline" routine
80 79
81 // Write out information we have stored 80 // Write out information we have stored
82 // // UNIXism == fsync(stderr); 81 // // UNIXism == fsync(stderr);
83 } 82 }
84 83
146 145
147 // First get the name of the instruction 146 // First get the name of the instruction
148 if( (ident = get_unique_ident(_globalNames,"instruction")) == NULL ) 147 if( (ident = get_unique_ident(_globalNames,"instruction")) == NULL )
149 return; 148 return;
150 instr = new InstructForm(ident); // Create new instruction form 149 instr = new InstructForm(ident); // Create new instruction form
151 instr->_linenum = _linenum; 150 instr->_linenum = linenum();
152 _globalNames.Insert(ident, instr); // Add name to the name table 151 _globalNames.Insert(ident, instr); // Add name to the name table
153 // Debugging Stuff 152 // Debugging Stuff
154 if (_AD._adl_debug > 1) 153 if (_AD._adl_debug > 1)
155 fprintf(stderr,"Parsing Instruction Form %s\n", ident); 154 fprintf(stderr,"Parsing Instruction Form %s\n", ident);
156 155
402 // First get the name of the operand 401 // First get the name of the operand
403 skipws(); 402 skipws();
404 if( (ident = get_unique_ident(_globalNames,"operand")) == NULL ) 403 if( (ident = get_unique_ident(_globalNames,"operand")) == NULL )
405 return; 404 return;
406 oper = new OperandForm(ident); // Create new operand form 405 oper = new OperandForm(ident); // Create new operand form
407 oper->_linenum = _linenum; 406 oper->_linenum = linenum();
408 _globalNames.Insert(ident, oper); // Add name to the name table 407 _globalNames.Insert(ident, oper); // Add name to the name table
409 408
410 // Debugging Stuff 409 // Debugging Stuff
411 if (_AD._adl_debug > 1) fprintf(stderr,"Parsing Operand Form %s\n", ident); 410 if (_AD._adl_debug > 1) fprintf(stderr,"Parsing Operand Form %s\n", ident);
412 411
772 //------------------------------reg_parse-------------------------------------- 771 //------------------------------reg_parse--------------------------------------
773 void ADLParser::reg_parse(void) { 772 void ADLParser::reg_parse(void) {
774 773
775 // Create the RegisterForm for the architecture description. 774 // Create the RegisterForm for the architecture description.
776 RegisterForm *regBlock = new RegisterForm(); // Build new Source object 775 RegisterForm *regBlock = new RegisterForm(); // Build new Source object
777 regBlock->_linenum = _linenum; 776 regBlock->_linenum = linenum();
778 _AD.addForm(regBlock); 777 _AD.addForm(regBlock);
779 778
780 skipws(); // Skip leading whitespace 779 skipws(); // Skip leading whitespace
781 if (_curchar == '%' && *(_ptr+1) == '{') { 780 if (_curchar == '%' && *(_ptr+1) == '{') {
782 next_char(); next_char(); // Skip "%{" 781 next_char(); next_char(); // Skip "%{"
845 parse_err(SYNERR, "missing encoding class name after encode.\n"); 844 parse_err(SYNERR, "missing encoding class name after encode.\n");
846 return; 845 return;
847 } 846 }
848 847
849 EncClass *encoding = _AD._encode->add_EncClass(ec_name); 848 EncClass *encoding = _AD._encode->add_EncClass(ec_name);
850 encoding->_linenum = _linenum; 849 encoding->_linenum = linenum();
851 850
852 skipws(); // Skip leading whitespace 851 skipws(); // Skip leading whitespace
853 // Check for optional parameter list 852 // Check for optional parameter list
854 if (_curchar == '(') { 853 if (_curchar == '(') {
855 do { 854 do {
903 void ADLParser::enc_class_parse_block(EncClass* encoding, char* ec_name) { 902 void ADLParser::enc_class_parse_block(EncClass* encoding, char* ec_name) {
904 skipws_no_preproc(); // Skip leading whitespace 903 skipws_no_preproc(); // Skip leading whitespace
905 // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block 904 // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block
906 if (_AD._adlocation_debug) { 905 if (_AD._adlocation_debug) {
907 const char* file = _AD._ADL_file._name; 906 const char* file = _AD._ADL_file._name;
908 int line = _linenum; 907 int line = linenum();
909 char* location = (char *)malloc(strlen(file) + 100); 908 char* location = (char *)malloc(strlen(file) + 100);
910 sprintf(location, "#line %d \"%s\"\n", line, file); 909 sprintf(location, "#line %d \"%s\"\n", line, file);
911 encoding->add_code(location); 910 encoding->add_code(location);
912 } 911 }
913 912
2774 char* ec_name = (char*)malloc(strlen(inst._ident) + strlen(prefix) + 1); 2773 char* ec_name = (char*)malloc(strlen(inst._ident) + strlen(prefix) + 1);
2775 sprintf(ec_name, "%s%s", prefix, inst._ident); 2774 sprintf(ec_name, "%s%s", prefix, inst._ident);
2776 2775
2777 assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist"); 2776 assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
2778 EncClass *encoding = _AD._encode->add_EncClass(ec_name); 2777 EncClass *encoding = _AD._encode->add_EncClass(ec_name);
2779 encoding->_linenum = _linenum; 2778 encoding->_linenum = linenum();
2780 2779
2781 // synthesize the arguments list for the enc_class from the 2780 // synthesize the arguments list for the enc_class from the
2782 // arguments to the instruct definition. 2781 // arguments to the instruct definition.
2783 const char * param = NULL; 2782 const char * param = NULL;
2784 inst._parameters.reset(); 2783 inst._parameters.reset();
2850 } 2849 }
2851 next_char(); // move past '(' 2850 next_char(); // move past '('
2852 skipws(); 2851 skipws();
2853 2852
2854 InsEncode *encrule = new InsEncode(); // Encode class for instruction 2853 InsEncode *encrule = new InsEncode(); // Encode class for instruction
2855 encrule->_linenum = _linenum; 2854 encrule->_linenum = linenum();
2856 char *ec_name = NULL; // String representation of encode rule 2855 char *ec_name = NULL; // String representation of encode rule
2857 // identifier is optional. 2856 // identifier is optional.
2858 while (_curchar != ')') { 2857 while (_curchar != ')') {
2859 ec_name = get_ident(); 2858 ec_name = get_ident();
2860 if (ec_name == NULL) { 2859 if (ec_name == NULL) {
3201 char *not_equal; 3200 char *not_equal;
3202 char *less; 3201 char *less;
3203 char *greater_equal; 3202 char *greater_equal;
3204 char *less_equal; 3203 char *less_equal;
3205 char *greater; 3204 char *greater;
3205 const char *equal_format = "eq";
3206 const char *not_equal_format = "ne";
3207 const char *less_format = "lt";
3208 const char *greater_equal_format = "ge";
3209 const char *less_equal_format = "le";
3210 const char *greater_format = "gt";
3206 3211
3207 if (_curchar != '%') { 3212 if (_curchar != '%') {
3208 parse_err(SYNERR, "Missing '%{' for 'cond_interface' block.\n"); 3213 parse_err(SYNERR, "Missing '%{' for 'cond_interface' block.\n");
3209 return NULL; 3214 return NULL;
3210 } 3215 }
3220 if (field == NULL) { 3225 if (field == NULL) {
3221 parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n"); 3226 parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n");
3222 return NULL; 3227 return NULL;
3223 } 3228 }
3224 if ( strcmp(field,"equal") == 0 ) { 3229 if ( strcmp(field,"equal") == 0 ) {
3225 equal = interface_field_parse(); 3230 equal = interface_field_parse(&equal_format);
3226 } 3231 }
3227 else if ( strcmp(field,"not_equal") == 0 ) { 3232 else if ( strcmp(field,"not_equal") == 0 ) {
3228 not_equal = interface_field_parse(); 3233 not_equal = interface_field_parse(&not_equal_format);
3229 } 3234 }
3230 else if ( strcmp(field,"less") == 0 ) { 3235 else if ( strcmp(field,"less") == 0 ) {
3231 less = interface_field_parse(); 3236 less = interface_field_parse(&less_format);
3232 } 3237 }
3233 else if ( strcmp(field,"greater_equal") == 0 ) { 3238 else if ( strcmp(field,"greater_equal") == 0 ) {
3234 greater_equal = interface_field_parse(); 3239 greater_equal = interface_field_parse(&greater_equal_format);
3235 } 3240 }
3236 else if ( strcmp(field,"less_equal") == 0 ) { 3241 else if ( strcmp(field,"less_equal") == 0 ) {
3237 less_equal = interface_field_parse(); 3242 less_equal = interface_field_parse(&less_equal_format);
3238 } 3243 }
3239 else if ( strcmp(field,"greater") == 0 ) { 3244 else if ( strcmp(field,"greater") == 0 ) {
3240 greater = interface_field_parse(); 3245 greater = interface_field_parse(&greater_format);
3241 } 3246 }
3242 else { 3247 else {
3243 parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n"); 3248 parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n");
3244 return NULL; 3249 return NULL;
3245 } 3250 }
3250 return NULL; 3255 return NULL;
3251 } 3256 }
3252 next_char(); // Skip '}' 3257 next_char(); // Skip '}'
3253 3258
3254 // Construct desired object and return 3259 // Construct desired object and return
3255 Interface *inter = new CondInterface(equal, not_equal, less, greater_equal, 3260 Interface *inter = new CondInterface(equal, equal_format,
3256 less_equal, greater); 3261 not_equal, not_equal_format,
3262 less, less_format,
3263 greater_equal, greater_equal_format,
3264 less_equal, less_equal_format,
3265 greater, greater_format);
3257 return inter; 3266 return inter;
3258 } 3267 }
3259 3268
3260 3269
3261 //------------------------------interface_field_parse-------------------------- 3270 //------------------------------interface_field_parse--------------------------
3262 char *ADLParser::interface_field_parse(void) { 3271 char *ADLParser::interface_field_parse(const char ** format) {
3263 char *iface_field = NULL; 3272 char *iface_field = NULL;
3264 3273
3265 // Get interface field 3274 // Get interface field
3266 skipws(); // Skip whitespace 3275 skipws(); // Skip whitespace
3267 if (_curchar != '(') { 3276 if (_curchar != '(') {
3278 if (iface_field == NULL) { 3287 if (iface_field == NULL) {
3279 parse_err(SYNERR, "missing or invalid interface field contents.\n"); 3288 parse_err(SYNERR, "missing or invalid interface field contents.\n");
3280 return NULL; 3289 return NULL;
3281 } 3290 }
3282 skipws(); 3291 skipws();
3292 if (format != NULL && _curchar == ',') {
3293 next_char();
3294 skipws();
3295 if (_curchar != '"') {
3296 parse_err(SYNERR, "Missing '\"' in field format .\n");
3297 return NULL;
3298 }
3299 next_char();
3300 char *start = _ptr; // Record start of the next string
3301 while ((_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) {
3302 if (_curchar == '\\') next_char(); // superquote
3303 if (_curchar == '\n') parse_err(SYNERR, "newline in string"); // unimplemented!
3304 next_char();
3305 }
3306 if (_curchar != '"') {
3307 parse_err(SYNERR, "Missing '\"' at end of field format .\n");
3308 return NULL;
3309 }
3310 // If a string was found, terminate it and record in FormatRule
3311 if ( start != _ptr ) {
3312 *_ptr = '\0'; // Terminate the string
3313 *format = start;
3314 }
3315 next_char();
3316 skipws();
3317 }
3283 if (_curchar != ')') { 3318 if (_curchar != ')') {
3284 parse_err(SYNERR, "Missing ')' after interface field.\n"); 3319 parse_err(SYNERR, "Missing ')' after interface field.\n");
3285 return NULL; 3320 return NULL;
3286 } 3321 }
3287 next_char(); // move past ')' 3322 next_char(); // move past ')'
3340 else if ( _curchar == '%' && *(_ptr+1) == '{') { 3375 else if ( _curchar == '%' && *(_ptr+1) == '{') {
3341 next_char(); // Move past the '%' 3376 next_char(); // Move past the '%'
3342 next_char(); // Move past the '{' 3377 next_char(); // Move past the '{'
3343 3378
3344 skipws(); 3379 skipws();
3380 if (_curchar == '$') {
3381 char* ident = get_rep_var_ident();
3382 if (strcmp(ident, "$$template") == 0) return template_parse();
3383 parse_err(SYNERR, "Unknown \"%s\" directive in format", ident);
3384 return NULL;
3385 }
3345 // Check for the opening '"' inside the format description 3386 // Check for the opening '"' inside the format description
3346 if ( _curchar == '"' ) { 3387 if ( _curchar == '"' ) {
3347 next_char(); // Move past the initial '"' 3388 next_char(); // Move past the initial '"'
3348 if( _curchar == '"' ) { // Handle empty format string case 3389 if( _curchar == '"' ) { // Handle empty format string case
3349 *_ptr = '\0'; // Terminate empty string 3390 *_ptr = '\0'; // Terminate empty string
3423 } 3464 }
3424 else { // parameter list alone must terminate with a ';' 3465 else { // parameter list alone must terminate with a ';'
3425 parse_err(SYNERR, "missing ';' after Format expression"); 3466 parse_err(SYNERR, "missing ';' after Format expression");
3426 return NULL; 3467 return NULL;
3427 } 3468 }
3469 // Debug Stuff
3470 if (_AD._adl_debug > 1) fprintf(stderr,"Format Rule: %s\n", desc);
3471
3472 skipws();
3473 return format;
3474 }
3475
3476
3477 //------------------------------template_parse-----------------------------------
3478 FormatRule* ADLParser::template_parse(void) {
3479 char *desc = NULL;
3480 FormatRule *format = (new FormatRule(desc));
3481
3482 skipws();
3483 while ( (_curchar != '%') && (*(_ptr+1) != '}') ) {
3484
3485 // (1)
3486 // Check if there is a string to pass through to output
3487 char *start = _ptr; // Record start of the next string
3488 while ((_curchar != '$') && ((_curchar != '%') || (*(_ptr+1) != '}')) ) {
3489 // If at the start of a comment, skip past it
3490 if( (_curchar == '/') && ((*(_ptr+1) == '/') || (*(_ptr+1) == '*')) ) {
3491 skipws_no_preproc();
3492 } else {
3493 // ELSE advance to the next character, or start of the next line
3494 next_char_or_line();
3495 }
3496 }
3497 // If a string was found, terminate it and record in EncClass
3498 if ( start != _ptr ) {
3499 *_ptr = '\0'; // Terminate the string
3500 // Add flag to _strings list indicating we should check _rep_vars
3501 format->_strings.addName(NameList::_signal2);
3502 format->_strings.addName(start);
3503 }
3504
3505 // (2)
3506 // If we are at a replacement variable,
3507 // copy it and record in EncClass
3508 if ( _curchar == '$' ) {
3509 // Found replacement Variable
3510 char *rep_var = get_rep_var_ident_dup();
3511 if (strcmp(rep_var, "$emit") == 0) {
3512 // switch to normal format parsing
3513 next_char();
3514 next_char();
3515 skipws();
3516 // Check for the opening '"' inside the format description
3517 if ( _curchar == '"' ) {
3518 next_char(); // Move past the initial '"'
3519 if( _curchar == '"' ) { // Handle empty format string case
3520 *_ptr = '\0'; // Terminate empty string
3521 format->_strings.addName(_ptr);
3522 }
3523
3524 // Collect the parts of the format description
3525 // (1) strings that are passed through to tty->print
3526 // (2) replacement/substitution variable, preceeded by a '$'
3527 // (3) multi-token ANSIY C style strings
3528 while ( true ) {
3529 if ( _curchar == '%' || _curchar == '\n' ) {
3530 parse_err(SYNERR, "missing '\"' at end of format block");
3531 return NULL;
3532 }
3533
3534 // (1)
3535 // Check if there is a string to pass through to output
3536 char *start = _ptr; // Record start of the next string
3537 while ((_curchar != '$') && (_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) {
3538 if (_curchar == '\\') next_char(); // superquote
3539 if (_curchar == '\n') parse_err(SYNERR, "newline in string"); // unimplemented!
3540 next_char();
3541 }
3542 // If a string was found, terminate it and record in FormatRule
3543 if ( start != _ptr ) {
3544 *_ptr = '\0'; // Terminate the string
3545 format->_strings.addName(start);
3546 }
3547
3548 // (2)
3549 // If we are at a replacement variable,
3550 // copy it and record in FormatRule
3551 if ( _curchar == '$' ) {
3552 next_char(); // Move past the '$'
3553 char* rep_var = get_ident(); // Nil terminate the variable name
3554 rep_var = strdup(rep_var);// Copy the string
3555 *_ptr = _curchar; // and replace Nil with original character
3556 format->_rep_vars.addName(rep_var);
3557 // Add flag to _strings list indicating we should check _rep_vars
3558 format->_strings.addName(NameList::_signal);
3559 }
3560
3561 // (3)
3562 // Allow very long strings to be broken up,
3563 // using the ANSI C syntax "foo\n" <newline> "bar"
3564 if ( _curchar == '"') {
3565 next_char(); // Move past the '"'
3566 skipws(); // Skip white space before next string token
3567 if ( _curchar != '"') {
3568 break;
3569 } else {
3570 // Found one. Skip both " and the whitespace in between.
3571 next_char();
3572 }
3573 }
3574 } // end while part of format description
3575 }
3576 } else {
3577 // Add flag to _strings list indicating we should check _rep_vars
3578 format->_rep_vars.addName(rep_var);
3579 // Add flag to _strings list indicating we should check _rep_vars
3580 format->_strings.addName(NameList::_signal3);
3581 }
3582 } // end while part of format description
3583 }
3584
3585 skipws();
3586 // Past format description, at '%'
3587 if ( _curchar != '%' || *(_ptr+1) != '}' ) {
3588 parse_err(SYNERR, "missing '%}' at end of format block");
3589 return NULL;
3590 }
3591 next_char(); // Move past the '%'
3592 next_char(); // Move past the '}'
3593
3428 // Debug Stuff 3594 // Debug Stuff
3429 if (_AD._adl_debug > 1) fprintf(stderr,"Format Rule: %s\n", desc); 3595 if (_AD._adl_debug > 1) fprintf(stderr,"Format Rule: %s\n", desc);
3430 3596
3431 skipws(); 3597 skipws();
3432 return format; 3598 return format;
3775 } 3941 }
3776 next_char(); // Skip block delimiter 3942 next_char(); // Skip block delimiter
3777 skipws_no_preproc(); // Skip leading whitespace 3943 skipws_no_preproc(); // Skip leading whitespace
3778 cppBlock = _ptr; // Point to start of expression 3944 cppBlock = _ptr; // Point to start of expression
3779 const char* file = _AD._ADL_file._name; 3945 const char* file = _AD._ADL_file._name;
3780 int line = _linenum; 3946 int line = linenum();
3781 next = _ptr + 1; 3947 next = _ptr + 1;
3782 while(((_curchar != '%') || (*next != '}')) && (_curchar != '\0')) { 3948 while(((_curchar != '%') || (*next != '}')) && (_curchar != '\0')) {
3783 next_char_or_line(); 3949 next_char_or_line();
3784 next = _ptr+1; // Maintain the next pointer 3950 next = _ptr+1; // Maintain the next pointer
3785 } // Grab string 3951 } // Grab string
4295 void ADLParser::parse_err(int flag, const char *fmt, ...) { 4461 void ADLParser::parse_err(int flag, const char *fmt, ...) {
4296 va_list args; 4462 va_list args;
4297 4463
4298 va_start(args, fmt); 4464 va_start(args, fmt);
4299 if (flag == 1) 4465 if (flag == 1)
4300 _AD._syntax_errs += _AD.emit_msg(0, flag, _linenum, fmt, args); 4466 _AD._syntax_errs += _AD.emit_msg(0, flag, linenum(), fmt, args);
4301 else if (flag == 2) 4467 else if (flag == 2)
4302 _AD._semantic_errs += _AD.emit_msg(0, flag, _linenum, fmt, args); 4468 _AD._semantic_errs += _AD.emit_msg(0, flag, linenum(), fmt, args);
4303 else 4469 else
4304 _AD._warnings += _AD.emit_msg(0, flag, _linenum, fmt, args); 4470 _AD._warnings += _AD.emit_msg(0, flag, linenum(), fmt, args);
4305 4471
4306 int error_char = _curchar; 4472 int error_char = _curchar;
4307 char* error_ptr = _ptr+1; 4473 char* error_ptr = _ptr+1;
4308 for(;*_ptr != '\n'; _ptr++) ; // Skip to the end of the current line 4474 for(;*_ptr != '\n'; _ptr++) ; // Skip to the end of the current line
4309 _curchar = '\n'; 4475 _curchar = '\n';
4513 } 4679 }
4514 } 4680 }
4515 4681
4516 //---------------------------next_line----------------------------------------- 4682 //---------------------------next_line-----------------------------------------
4517 void ADLParser::next_line() { 4683 void ADLParser::next_line() {
4518 _curline = _buf.get_line(); _linenum++; 4684 _curline = _buf.get_line();
4519 } 4685 }
4520 4686
4521 //-------------------------is_literal_constant--------------------------------- 4687 //-------------------------is_literal_constant---------------------------------
4522 bool ADLParser::is_literal_constant(const char *param) { 4688 bool ADLParser::is_literal_constant(const char *param) {
4523 if (param[0] == 0) return false; // null string 4689 if (param[0] == 0) return false; // null string