src/share/vm/adlc/adlparse.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/adlc/adlparse.cpp Fri Nov 12 05:56:22 2010
--- new/src/share/vm/adlc/adlparse.cpp Fri Nov 12 05:56:22 2010
*** 1,7 ****
--- 1,7 ----
/*
! * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
! * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 214,225 ****
--- 214,224 ----
}
}
else if (!strcmp(ident, "encode")) {
parse_err(SYNERR, "Instructions specify ins_encode, not encode\n");
}
! else if (!strcmp(ident, "ins_encode")) ins_encode_parse(*instr);
instr->_insencode = ins_encode_parse(*instr);
else if (!strcmp(ident, "opcode")) instr->_opcode = opcode_parse(instr);
else if (!strcmp(ident, "size")) instr->_size = size_parse(instr);
else if (!strcmp(ident, "effect")) effect_parse(instr);
else if (!strcmp(ident, "expand")) instr->_exprule = expand_parse(instr);
else if (!strcmp(ident, "rewrite")) instr->_rewrule = rewrite_parse();
*** 933,945 ****
--- 932,944 ----
}
// (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();
! char* rep_var = get_rep_var_ident_dup();
// Add flag to _strings list indicating we should check _rep_vars
encoding->add_rep_var(rep_var);
}
} // end while part of format description
next_char(); // Skip '%'
*** 2772,2822 ****
--- 2771,2896 ----
}
//------------------------------ins_encode_parse_block-------------------------
// Parse the block form of ins_encode. See ins_encode_parse for more details
! InsEncode *ADLParser::ins_encode_parse_block(InstructForm &inst) {
! void ADLParser::ins_encode_parse_block(InstructForm& inst) {
// Create a new encoding name based on the name of the instruction
// definition, which should be unique.
! const char * prefix = "__enc_";
! char* ec_name = (char*)malloc(strlen(inst._ident) + strlen(prefix) + 1);
! const char* prefix = "__ins_encode_";
! char* ec_name = (char*) malloc(strlen(inst._ident) + strlen(prefix) + 1);
sprintf(ec_name, "%s%s", prefix, inst._ident);
assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
! EncClass *encoding = _AD._encode->add_EncClass(ec_name);
! EncClass* encoding = _AD._encode->add_EncClass(ec_name);
encoding->_linenum = linenum();
// synthesize the arguments list for the enc_class from the
// arguments to the instruct definition.
- const char * param = NULL;
inst._parameters.reset();
while ((param = inst._parameters.iter()) != NULL) {
! OperandForm *opForm = (OperandForm*)inst._localNames[param];
! OperandForm* opForm = (OperandForm*) inst._localNames[param];
encoding->add_parameter(opForm->_ident, param);
}
// Add the prologue to create the MacroAssembler
encoding->add_code("\n"
" // Define a MacroAssembler instance for use by the encoding. The\n"
" // name is chosen to match the __ idiom used for assembly in other\n"
" // parts of hotspot and assumes the existence of the standard\n"
" // #define __ _masm.\n"
" MacroAssembler _masm(&cbuf);\n");
+ // Define a MacroAssembler instance for use by the encoding. The
+ // name is chosen to match the __ idiom used for assembly in other
+ // parts of hotspot and assumes the existence of the standard
+ // #define __ _masm.
+ encoding->add_code(" MacroAssembler _masm(&cbuf);\n");
// Parse the following %{ }% block
! enc_class_parse_block(encoding, ec_name);
! ins_encode_parse_block_impl(inst, encoding, ec_name);
// Build an encoding rule which invokes the encoding rule we just
// created, passing all arguments that we received.
! InsEncode *encrule = new InsEncode(); // Encode class for instruction
! NameAndList *params = encrule->add_encode(ec_name);
! InsEncode* encrule = new InsEncode(); // Encode class for instruction
! NameAndList* params = encrule->add_encode(ec_name);
inst._parameters.reset();
while ((param = inst._parameters.iter()) != NULL) {
params->add_entry(param);
}
return encrule;
+ // Set encode class of this instruction.
+ inst._insencode = encrule;
+ }
+
+
+ void ADLParser::ins_encode_parse_block_impl(InstructForm& inst, EncClass* encoding, char* ec_name) {
+ skipws_no_preproc(); // Skip leading whitespace
+ // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block
+ if (_AD._adlocation_debug) {
+ encoding->add_code(get_line_string());
+ }
+
+ // Collect the parts of the encode description
+ // (1) strings that are passed through to output
+ // (2) replacement/substitution variable, preceeded by a '$'
+ 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
+ encoding->add_code(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();
+
+ // Add flag to _strings list indicating we should check _rep_vars
+ encoding->add_rep_var(rep_var);
+
+ skipws();
+
+ // Check if this instruct is a MachConstantNode.
+ if (strcmp(rep_var, "constanttablebase") == 0) {
+ // This instruct is a MachConstantNode.
+ inst.set_is_mach_constant(true);
+
+ if (_curchar == '(') {
+ parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument (only constantaddress and constantoffset)", ec_name);
+ return;
+ }
+ }
+ else if ((strcmp(rep_var, "constantaddress") == 0) ||
+ (strcmp(rep_var, "constantoffset") == 0)) {
+ // This instruct is a MachConstantNode.
+ inst.set_is_mach_constant(true);
+
+ // If the constant keyword has an argument, parse it.
+ if (_curchar == '(') constant_parse(inst);
+ }
+ }
+ } // end while part of format description
+ next_char(); // Skip '%'
+ next_char(); // Skip '}'
+
+ skipws();
+
+ if (_AD._adlocation_debug) {
+ encoding->add_code(end_line_marker());
+ }
+
+ // Debug Stuff
+ if (_AD._adl_debug > 1) fprintf(stderr, "EncodingClass Form: %s\n", ec_name);
}
//------------------------------ins_encode_parse-------------------------------
// Encode rules have the form
*** 2836,2861 ****
--- 2910,2936 ----
//
// MacroAssembler masm(&cbuf);\n");
//
// making it more compact to take advantage of the MacroAssembler and
// placing the assembly closer to it's use by instructions.
! InsEncode *ADLParser::ins_encode_parse(InstructForm &inst) {
! void ADLParser::ins_encode_parse(InstructForm& inst) {
// Parse encode class name
skipws(); // Skip whitespace
if (_curchar != '(') {
// Check for ins_encode %{ form
if ((_curchar == '%') && (*(_ptr+1) == '{')) {
next_char(); // Skip '%'
next_char(); // Skip '{'
// Parse the block form of ins_encode
- return ins_encode_parse_block(inst);
+ return;
}
parse_err(SYNERR, "missing '%%{' or '(' in ins_encode definition\n");
- return NULL;
}
next_char(); // move past '('
skipws();
InsEncode *encrule = new InsEncode(); // Encode class for instruction
*** 2864,2874 ****
--- 2939,2949 ----
// identifier is optional.
while (_curchar != ')') {
ec_name = get_ident();
if (ec_name == NULL) {
parse_err(SYNERR, "Invalid encode class name after 'ins_encode('.\n");
- return NULL;
}
// Check that encoding is defined in the encode section
EncClass *encode_class = _AD._encode->encClass(ec_name);
if (encode_class == NULL) {
// Like to defer checking these till later...
*** 2896,2906 ****
--- 2971,2981 ----
if ( (inst._localNames[param] == NULL) &&
!ADLParser::is_literal_constant(param) &&
(Opcode::as_opcode_type(param) == Opcode::NOT_AN_OPCODE) &&
((_AD._register == NULL ) || (_AD._register->getRegDef(param) == NULL)) ) {
parse_err(SYNERR, "Using non-locally defined parameter %s for encoding %s.\n", param, ec_name);
- return NULL;
}
params->add_entry(param);
skipws();
if (_curchar == ',' ) {
*** 2913,2935 ****
--- 2988,3010 ----
}
else {
// Only ',' or ')' are valid after a parameter name
parse_err(SYNERR, "expected ',' or ')' after parameter %s.\n",
ec_name);
- return NULL;
}
} else {
skipws();
// Did not find a parameter
if (_curchar == ',') {
parse_err(SYNERR, "Expected encode parameter before ',' in encoding %s.\n", ec_name);
- return NULL;
}
if (_curchar != ')') {
parse_err(SYNERR, "Expected ')' after encode parameters.\n");
- return NULL;
}
}
} // WHILE loop collecting parameters
next_char(); // move past ')' at end of parameters
} // done with parameter list for encoding
*** 2942,2952 ****
--- 3017,3027 ----
skipws();
}
else if ( _curchar != ')' ) {
// If not a ',' then only a ')' is allowed
parse_err(SYNERR, "Expected ')' after encoding %s.\n", ec_name);
- return NULL;
}
// Check for ',' separating parameters
// if ( _curchar != ',' && _curchar != ')' ) {
// parse_err(SYNERR, "expected ',' or ')' after encode method inside ins_encode.\n");
*** 2954,2979 ****
--- 3029,3160 ----
// }
} // done parsing ins_encode methods and their parameters
if (_curchar != ')') {
parse_err(SYNERR, "Missing ')' at end of ins_encode description.\n");
- return NULL;
}
next_char(); // move past ')'
skipws(); // Skip leading whitespace
if ( _curchar != ';' ) {
parse_err(SYNERR, "Missing ';' at end of ins_encode.\n");
- return NULL;
}
next_char(); // move past ';'
skipws(); // be friendly to oper_parse()
// Debug Stuff
if (_AD._adl_debug > 1) fprintf(stderr,"Instruction Encode: %s\n", ec_name);
return encrule;
+ // Set encode class of this instruction.
+ inst._insencode = encrule;
+ }
+
+
+ //------------------------------constant_parse---------------------------------
+ // Parse a constant expression.
+ void ADLParser::constant_parse(InstructForm& inst) {
+ // Create a new encoding name based on the name of the instruction
+ // definition, which should be unique.
+ const char* prefix = "__constant_";
+ char* ec_name = (char*) malloc(strlen(inst._ident) + strlen(prefix) + 1);
+ sprintf(ec_name, "%s%s", prefix, inst._ident);
+
+ assert(_AD._encode->encClass(ec_name) == NULL, "shouldn't already exist");
+ EncClass* encoding = _AD._encode->add_EncClass(ec_name);
+ encoding->_linenum = linenum();
+
+ // synthesize the arguments list for the enc_class from the
+ // arguments to the instruct definition.
+ const char* param = NULL;
+ inst._parameters.reset();
+ while ((param = inst._parameters.iter()) != NULL) {
+ OperandForm* opForm = (OperandForm*) inst._localNames[param];
+ encoding->add_parameter(opForm->_ident, param);
+ }
+
+ // Parse the following ( ) expression.
+ constant_parse_expression(encoding, ec_name);
+
+ // Build an encoding rule which invokes the encoding rule we just
+ // created, passing all arguments that we received.
+ InsEncode* encrule = new InsEncode(); // Encode class for instruction
+ NameAndList* params = encrule->add_encode(ec_name);
+ inst._parameters.reset();
+ while ((param = inst._parameters.iter()) != NULL) {
+ params->add_entry(param);
+ }
+
+ // Set encode class of this instruction.
+ inst._constant = encrule;
+ }
+
+
+ //------------------------------constant_parse_expression----------------------
+ void ADLParser::constant_parse_expression(EncClass* encoding, char* ec_name) {
+ skipws();
+
+ // Prepend location descriptor, for debugging; cf. ADLParser::find_cpp_block
+ if (_AD._adlocation_debug) {
+ encoding->add_code(get_line_string());
+ }
+
+ // Start code line.
+ encoding->add_code(" add_to_constant_table");
+
+ // Parse everything in ( ) expression.
+ encoding->add_code("(");
+ next_char(); // Skip '('
+ int parens_depth = 1;
+
+ // Collect the parts of the constant expression.
+ // (1) strings that are passed through to output
+ // (2) replacement/substitution variable, preceeded by a '$'
+ while (parens_depth > 0) {
+ if (_curchar == '(') {
+ parens_depth++;
+ encoding->add_code("(");
+ next_char();
+ }
+ else if (_curchar == ')') {
+ parens_depth--;
+ encoding->add_code(")");
+ next_char();
+ }
+ else {
+ // (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 != ')')) {
+ next_char();
+ }
+ // If a string was found, terminate it and record in EncClass
+ if (start != _ptr) {
+ *_ptr = '\0'; // Terminate the string
+ encoding->add_code(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();
+ encoding->add_rep_var(rep_var);
+ }
+ }
+ }
+
+ // Finish code line.
+ encoding->add_code(";");
+
+ if (_AD._adlocation_debug) {
+ encoding->add_code(end_line_marker());
+ }
+
+ // Debug Stuff
+ if (_AD._adl_debug > 1) fprintf(stderr, "EncodingClass Form: %s\n", ec_name);
}
//------------------------------size_parse-----------------------------------
char* ADLParser::size_parse(InstructForm *instr) {
src/share/vm/adlc/adlparse.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File