Mercurial > hg > truffle
diff 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 |
line wrap: on
line diff
--- a/src/share/vm/adlc/adlparse.cpp Tue Oct 21 11:23:52 2008 -0700 +++ b/src/share/vm/adlc/adlparse.cpp Tue Oct 28 09:31:30 2008 -0700 @@ -33,7 +33,6 @@ _globalNames(archDesc.globalNames()) { _AD._syntax_errs = _AD._semantic_errs = 0; // No errors so far this file _AD._warnings = 0; // No warnings either - _linenum = 0; // Will increment to first line _curline = _ptr = NULL; // No pointers into buffer yet _preproc_depth = 0; @@ -76,7 +75,7 @@ } if (!_AD._quiet_mode) fprintf(stderr,"-----------------------------------------------------------------------------\n"); - _AD._TotalLines += _linenum-1; // -1 for overshoot in "nextline" routine + _AD._TotalLines += linenum()-1; // -1 for overshoot in "nextline" routine // Write out information we have stored // // UNIXism == fsync(stderr); @@ -148,7 +147,7 @@ if( (ident = get_unique_ident(_globalNames,"instruction")) == NULL ) return; instr = new InstructForm(ident); // Create new instruction form - instr->_linenum = _linenum; + instr->_linenum = linenum(); _globalNames.Insert(ident, instr); // Add name to the name table // Debugging Stuff if (_AD._adl_debug > 1) @@ -404,7 +403,7 @@ if( (ident = get_unique_ident(_globalNames,"operand")) == NULL ) return; oper = new OperandForm(ident); // Create new operand form - oper->_linenum = _linenum; + oper->_linenum = linenum(); _globalNames.Insert(ident, oper); // Add name to the name table // Debugging Stuff @@ -774,7 +773,7 @@ // Create the RegisterForm for the architecture description. RegisterForm *regBlock = new RegisterForm(); // Build new Source object - regBlock->_linenum = _linenum; + regBlock->_linenum = linenum(); _AD.addForm(regBlock); skipws(); // Skip leading whitespace @@ -847,7 +846,7 @@ } EncClass *encoding = _AD._encode->add_EncClass(ec_name); - encoding->_linenum = _linenum; + encoding->_linenum = linenum(); skipws(); // Skip leading whitespace // Check for optional parameter list @@ -905,7 +904,7 @@ // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block if (_AD._adlocation_debug) { const char* file = _AD._ADL_file._name; - int line = _linenum; + int line = linenum(); char* location = (char *)malloc(strlen(file) + 100); sprintf(location, "#line %d \"%s\"\n", line, file); encoding->add_code(location); @@ -2776,7 +2775,7 @@ assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist"); EncClass *encoding = _AD._encode->add_EncClass(ec_name); - encoding->_linenum = _linenum; + encoding->_linenum = linenum(); // synthesize the arguments list for the enc_class from the // arguments to the instruct definition. @@ -2852,7 +2851,7 @@ skipws(); InsEncode *encrule = new InsEncode(); // Encode class for instruction - encrule->_linenum = _linenum; + encrule->_linenum = linenum(); char *ec_name = NULL; // String representation of encode rule // identifier is optional. while (_curchar != ')') { @@ -3203,6 +3202,12 @@ char *greater_equal; char *less_equal; char *greater; + const char *equal_format = "eq"; + const char *not_equal_format = "ne"; + const char *less_format = "lt"; + const char *greater_equal_format = "ge"; + const char *less_equal_format = "le"; + const char *greater_format = "gt"; if (_curchar != '%') { parse_err(SYNERR, "Missing '%{' for 'cond_interface' block.\n"); @@ -3222,22 +3227,22 @@ return NULL; } if ( strcmp(field,"equal") == 0 ) { - equal = interface_field_parse(); + equal = interface_field_parse(&equal_format); } else if ( strcmp(field,"not_equal") == 0 ) { - not_equal = interface_field_parse(); + not_equal = interface_field_parse(¬_equal_format); } else if ( strcmp(field,"less") == 0 ) { - less = interface_field_parse(); + less = interface_field_parse(&less_format); } else if ( strcmp(field,"greater_equal") == 0 ) { - greater_equal = interface_field_parse(); + greater_equal = interface_field_parse(&greater_equal_format); } else if ( strcmp(field,"less_equal") == 0 ) { - less_equal = interface_field_parse(); + less_equal = interface_field_parse(&less_equal_format); } else if ( strcmp(field,"greater") == 0 ) { - greater = interface_field_parse(); + greater = interface_field_parse(&greater_format); } else { parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%}' ending interface.\n"); @@ -3252,14 +3257,18 @@ next_char(); // Skip '}' // Construct desired object and return - Interface *inter = new CondInterface(equal, not_equal, less, greater_equal, - less_equal, greater); + Interface *inter = new CondInterface(equal, equal_format, + not_equal, not_equal_format, + less, less_format, + greater_equal, greater_equal_format, + less_equal, less_equal_format, + greater, greater_format); return inter; } //------------------------------interface_field_parse-------------------------- -char *ADLParser::interface_field_parse(void) { +char *ADLParser::interface_field_parse(const char ** format) { char *iface_field = NULL; // Get interface field @@ -3280,6 +3289,32 @@ return NULL; } skipws(); + if (format != NULL && _curchar == ',') { + next_char(); + skipws(); + if (_curchar != '"') { + parse_err(SYNERR, "Missing '\"' in field format .\n"); + return NULL; + } + next_char(); + char *start = _ptr; // Record start of the next string + while ((_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) { + if (_curchar == '\\') next_char(); // superquote + if (_curchar == '\n') parse_err(SYNERR, "newline in string"); // unimplemented! + next_char(); + } + if (_curchar != '"') { + parse_err(SYNERR, "Missing '\"' at end of field format .\n"); + return NULL; + } + // If a string was found, terminate it and record in FormatRule + if ( start != _ptr ) { + *_ptr = '\0'; // Terminate the string + *format = start; + } + next_char(); + skipws(); + } if (_curchar != ')') { parse_err(SYNERR, "Missing ')' after interface field.\n"); return NULL; @@ -3342,6 +3377,12 @@ next_char(); // Move past the '{' skipws(); + if (_curchar == '$') { + char* ident = get_rep_var_ident(); + if (strcmp(ident, "$$template") == 0) return template_parse(); + parse_err(SYNERR, "Unknown \"%s\" directive in format", ident); + return NULL; + } // Check for the opening '"' inside the format description if ( _curchar == '"' ) { next_char(); // Move past the initial '"' @@ -3433,6 +3474,131 @@ } +//------------------------------template_parse----------------------------------- +FormatRule* ADLParser::template_parse(void) { + char *desc = NULL; + FormatRule *format = (new FormatRule(desc)); + + skipws(); + while ( (_curchar != '%') && (*(_ptr+1) != '}') ) { + + // (1) + // Check if there is a string to pass through to output + char *start = _ptr; // Record start of the next string + while ((_curchar != '$') && ((_curchar != '%') || (*(_ptr+1) != '}')) ) { + // If at the start of a comment, skip past it + if( (_curchar == '/') && ((*(_ptr+1) == '/') || (*(_ptr+1) == '*')) ) { + skipws_no_preproc(); + } else { + // ELSE advance to the next character, or start of the next line + next_char_or_line(); + } + } + // If a string was found, terminate it and record in EncClass + if ( start != _ptr ) { + *_ptr = '\0'; // Terminate the string + // Add flag to _strings list indicating we should check _rep_vars + format->_strings.addName(NameList::_signal2); + format->_strings.addName(start); + } + + // (2) + // If we are at a replacement variable, + // copy it and record in EncClass + if ( _curchar == '$' ) { + // Found replacement Variable + char *rep_var = get_rep_var_ident_dup(); + if (strcmp(rep_var, "$emit") == 0) { + // switch to normal format parsing + next_char(); + next_char(); + skipws(); + // Check for the opening '"' inside the format description + if ( _curchar == '"' ) { + next_char(); // Move past the initial '"' + if( _curchar == '"' ) { // Handle empty format string case + *_ptr = '\0'; // Terminate empty string + format->_strings.addName(_ptr); + } + + // Collect the parts of the format description + // (1) strings that are passed through to tty->print + // (2) replacement/substitution variable, preceeded by a '$' + // (3) multi-token ANSIY C style strings + while ( true ) { + if ( _curchar == '%' || _curchar == '\n' ) { + parse_err(SYNERR, "missing '\"' at end of format block"); + return NULL; + } + + // (1) + // Check if there is a string to pass through to output + char *start = _ptr; // Record start of the next string + while ((_curchar != '$') && (_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) { + if (_curchar == '\\') next_char(); // superquote + if (_curchar == '\n') parse_err(SYNERR, "newline in string"); // unimplemented! + next_char(); + } + // If a string was found, terminate it and record in FormatRule + if ( start != _ptr ) { + *_ptr = '\0'; // Terminate the string + format->_strings.addName(start); + } + + // (2) + // If we are at a replacement variable, + // copy it and record in FormatRule + if ( _curchar == '$' ) { + next_char(); // Move past the '$' + char* rep_var = get_ident(); // Nil terminate the variable name + rep_var = strdup(rep_var);// Copy the string + *_ptr = _curchar; // and replace Nil with original character + format->_rep_vars.addName(rep_var); + // Add flag to _strings list indicating we should check _rep_vars + format->_strings.addName(NameList::_signal); + } + + // (3) + // Allow very long strings to be broken up, + // using the ANSI C syntax "foo\n" <newline> "bar" + if ( _curchar == '"') { + next_char(); // Move past the '"' + skipws(); // Skip white space before next string token + if ( _curchar != '"') { + break; + } else { + // Found one. Skip both " and the whitespace in between. + next_char(); + } + } + } // end while part of format description + } + } else { + // Add flag to _strings list indicating we should check _rep_vars + format->_rep_vars.addName(rep_var); + // Add flag to _strings list indicating we should check _rep_vars + format->_strings.addName(NameList::_signal3); + } + } // end while part of format description + } + + skipws(); + // Past format description, at '%' + if ( _curchar != '%' || *(_ptr+1) != '}' ) { + parse_err(SYNERR, "missing '%}' at end of format block"); + return NULL; + } + next_char(); // Move past the '%' + next_char(); // Move past the '}' + + // Debug Stuff + if (_AD._adl_debug > 1) fprintf(stderr,"Format Rule: %s\n", desc); + + skipws(); + return format; +} + + //------------------------------effect_parse----------------------------------- void ADLParser::effect_parse(InstructForm *instr) { char* desc = NULL; @@ -3777,7 +3943,7 @@ skipws_no_preproc(); // Skip leading whitespace cppBlock = _ptr; // Point to start of expression const char* file = _AD._ADL_file._name; - int line = _linenum; + int line = linenum(); next = _ptr + 1; while(((_curchar != '%') || (*next != '}')) && (_curchar != '\0')) { next_char_or_line(); @@ -4297,11 +4463,11 @@ va_start(args, fmt); if (flag == 1) - _AD._syntax_errs += _AD.emit_msg(0, flag, _linenum, fmt, args); + _AD._syntax_errs += _AD.emit_msg(0, flag, linenum(), fmt, args); else if (flag == 2) - _AD._semantic_errs += _AD.emit_msg(0, flag, _linenum, fmt, args); + _AD._semantic_errs += _AD.emit_msg(0, flag, linenum(), fmt, args); else - _AD._warnings += _AD.emit_msg(0, flag, _linenum, fmt, args); + _AD._warnings += _AD.emit_msg(0, flag, linenum(), fmt, args); int error_char = _curchar; char* error_ptr = _ptr+1; @@ -4515,7 +4681,7 @@ //---------------------------next_line----------------------------------------- void ADLParser::next_line() { - _curline = _buf.get_line(); _linenum++; + _curline = _buf.get_line(); } //-------------------------is_literal_constant---------------------------------