--- a/hotspot/src/share/vm/adlc/adlparse.cpp Tue Oct 21 11:23:52 2008 -0700
+++ b/hotspot/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---------------------------------