archDesc.cpp revision 4444
3845N/A// Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 0N/A// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A// This code is free software; you can redistribute it and/or modify it 0N/A// under the terms of the GNU General Public License version 2 only, as 0N/A// published by the Free Software Foundation. 0N/A// This code is distributed in the hope that it will be useful, but WITHOUT 0N/A// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A// version 2 for more details (a copy is included in the LICENSE file that 0N/A// accompanied this code). 0N/A// You should have received a copy of the GNU General Public License version 0N/A// 2 along with this work; if not, write to the Free Software Foundation, 0N/A// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1472N/A// Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 0N/A//--------------------------- utility functions ----------------------------- 0N/A// Utilities to characterize effect statements 0N/A//---------------------------ChainList Methods------------------------------- 0N/A // // Check for transitive chain rules 0N/A // Form *form = (Form *)_globalNames[rule]; 0N/A // if (form->is_instruction()) { 0N/A // // chain_rule(fp, indent, name, cost, rule); 0N/A // chain_rule(fp, indent, name, cost, rule); 0N/A//---------------------------MatchList Methods------------------------------- 0N/A//---------------------------ArchDesc Constructor and Destructor------------- 0N/A // Initialize the opcode to MatchList table with NULLs 0N/A // Set-up the global tables 0N/A // Prime user-defined types with predefined types: Set, RegI, RegF, ... 0N/A // Initialize flags & counters 0N/A // Initialize match rule flags 0N/A // Initialize I/O Files 0N/A // Machine dependent output files 0N/A // Initialize Register & Pipeline Form Pointers 0N/A // Clean-up and quit 0N/A//---------------------------ArchDesc methods: Public ---------------------- 0N/A// Store forms according to type 0N/A// Build MatchList array and construct MatchLists 0N/A // Call inspection routines to populate array 0N/A// Build MatchList structures for operands 0N/A // Iterate through all operands 0N/A // Construct list of top-level operands (components) 0N/A // Ensure that match field is defined. 0N/A // Type check match rules 0N/A // Construct chain rules 0N/A // Grab the machine type of the operand 0N/A // Check for special cases 0N/A // Cost for this match 0N/A // Find result type for match. 0N/A // Construct a MatchList for this entry 0N/A// Build MatchList structures for instructions 0N/A // Iterate through all instructions 0N/A // Construct list of top-level operands (components) 0N/A // Ensure that match field is defined. 0N/A // Grab the machine type of the operand 0N/A // Cost for this match 0N/A // Find result type for match 0N/A//------------------------------result of reduction---------------------------- 0N/A//------------------------------left reduction--------------------------------- 0N/A// Return the left reduction associated with an internal name 0N/A//------------------------------right reduction-------------------------------- 0N/A//------------------------------check_optype----------------------------------- 0N/A // // Cycle through the list of match rules 0N/A // // Check for a filled in type field 0N/A // if (mrule->_opType == NULL) { 0N/A // const Form *form = operands[_result]; 0N/A // OpClassForm *opcForm = form ? form->is_opclass() : NULL; 0N/A // assert(opcForm != NULL, "Match Rule contains invalid operand name."); 0N/A // char *opType = opcForm->_ident; 0N/A//------------------------------add_chain_rule_entry-------------------------- 0N/A // Look-up the operation in chain rule table 0N/A//------------------------------build_chain_rule------------------------------- 0N/A // Check for chain rules here 0N/A // If this is only a chain rule 0N/A // Check for additional chain rules 0N/A // Any extra match rules after the first must be chain rules 0N/A // Regardles of whether the first matchrule is a chain rule, check the list 0N/A // Any extra match rules after the first must be chain rules 0N/A//------------------------------buildMatchList--------------------------------- 0N/A// operands and instructions provide the result 0N/A // Check for chain rule, and do not generate a match list for it 0N/A // Identify index position among ideal operands 0N/A // Check that this will be placed appropriately in the DFA 0N/A // Walk the MatchRule, generating MatchList entries for each level 0N/A // of the rule (each nesting of parentheses) 0N/A // Build MatchLists for children 0N/A // Check each child for an internal operand name, and use that name 0N/A // for the parent's matchlist entry if it exists 0N/A // Search for an identical matchlist entry already on the list 0N/A // Place this match rule at front of list 0N/A// Recursive call for construction of match lists 0N/A // Do not process leaves of the Match Tree if they are not ideal 0N/A // Identify index position among ideal operands 0N/A // Build MatchLists for children 0N/A // Check each child for an internal operand name, and use that name 0N/A // for the parent's matchlist entry if it exists 0N/A // Grab the string for the opcode of this list entry 0N/A // Grab the string for the result of this list entry 0N/A // Search for an identical matchlist entry already on the list 0N/A // Place this match rule at front of list 0N/A// Count number of OperandForms defined 0N/A // Only interested in ones with non-NULL match rule 0N/A// Count number of OpClassForms defined 0N/A // Only interested in ones with non-NULL match rule 0N/A// Count number of InstructForms defined 0N/A // Only interested in ones with non-NULL match rule 0N/A//------------------------------get_preproc_def-------------------------------- 0N/A// Return the textual binding for a given CPP flag name. 0N/A// Return NULL if there is no binding, or it has been #undef-ed. 4033N/A // In case of syntax errors, flag may take the value NULL. 0N/A//------------------------------set_preproc_def-------------------------------- 0N/A// Change or create a textual binding for a given CPP flag name. 0N/A// Giving NULL means the flag name is to be #undef-ed. 0N/A// In any case, _preproc_list collects all names either #defined or #undef-ed. 0N/A // fprintf(stderr,"---------------------------- Verify Operands ---------------\n"); 0N/A // _operands.verify(); 0N/A // fprintf(stderr,"\n"); 0N/A // fprintf(stderr,"---------------------------- Verify Operand Classes --------\n"); 0N/A // _opclass.verify(); 0N/A // fprintf(stderr,"\n"); 0N/A // fprintf(stderr,"---------------------------- Verify Attributes ------------\n"); 0N/A // _attributes.verify(); 0N/A // fprintf(stderr,"\n"); 0N/A fprintf(
stderr,
"---------------------------- Verify Instructions ----------------------------\n");
0N/A // fprintf(stderr,"---------------------------- Verify Encodings --------------\n"); 0N/A // _encode->verify(); 0N/A //if (_pipeline) _pipeline->verify(); 0N/A//------------------------------init_keywords---------------------------------- 0N/A// Load the kewords into the global name table 0N/A // Insert keyword strings into Global Name Table. Keywords have a NULL value 0N/A // field for quick easy identification when checking identifiers. 0N/A//------------------------------internal_err---------------------------------- 0N/A// Issue a parser error message, and skip to the end of the current line 0N/A//------------------------------syntax_err---------------------------------- 0N/A// Issue a parser error message, and skip to the end of the current line 0N/A//------------------------------emit_msg--------------------------------------- 0N/A// Emit a user message, typically a warning or error 0N/A case 1:
pref =
"Syntax Error: ";
break;
0N/A case 2:
pref =
"Semantic Error: ";
break;
0N/A case 3:
pref =
"Internal Error: ";
break;
0N/A if (!
quiet) {
/* no output if in quiet mode */ 0N/A// --------------------------------------------------------------------------- 0N/A//--------Utilities to build mappings for machine registers ------------------ 0N/A// --------------------------------------------------------------------------- 0N/A// Construct the name of the register mask. 0N/A return "RegMask::Empty";
0N/A return "(Compile::current()->FIRST_STACK_mask())";
0N/A// Convert a register class name to its register mask. 0N/A // Construct the name of the register mask. 0N/A// Obtain the name of the RegMask for an OperandForm 0N/A // Check constraints on result's register class 4033N/A "Use of an undefined result class for operand: %s",
0N/A// Obtain the name of the RegMask for an InstructForm 4033N/A "Did not find result operand or RegMask" 4033N/A " for this instruction: %s",
0N/A // Instructions producing 'Universe' use RegMask::Empty 0N/A return "RegMask::Empty";
0N/A // Lookup this result operand and get its register class 0N/A// Obtain the STACK_OR_reg_mask name for an OperandForm 0N/A // name of cisc_spillable version 4033N/A "Did not find reg_mask for opForm: %s",
0N/A// Record that the register class must generate a stack_or_reg_mask 0N/A// Return the type signature for the ideal operation 0N/A // Find last character in idealOp, it specifies the type 3845N/A case 'S':
return "TypeVect::VECTS";
3845N/A case 'D':
return "TypeVect::VECTD";
3845N/A case 'X':
return "TypeVect::VECTX";
3845N/A case 'Y':
return "TypeVect::VECTY";
0N/A case 'I':
return "TypeInt::INT";
0N/A case 'P':
return "TypePtr::BOTTOM";
113N/A case 'N':
return "TypeNarrowOop::BOTTOM";
0N/A case 'F':
return "Type::FLOAT";
0N/A case 'D':
return "Type::DOUBLE";
0N/A case 'L':
return "TypeLong::LONG";
0N/A case 's':
return "TypeInt::CC /*flags*/";
0N/A // internal_err("Ideal type %s with unrecognized type\n",idealOp); 0N/A// Import predefined base types: Set = 1, RegI, RegP, ... 0N/A // Create OperandForm and assign type for each opcode. 0N/A // Create InstructForm and assign type for each ideal instruction. 0N/A // insForm->_opcode = nextUserOpType(ident); 0N/A // Create operand type "Universe" for return instructions. 0N/A const char *
ident =
"Universe";
0N/A // Create operand type "label" for branch targets 0N/A // Create operand types "sReg[IPFDL]" for stack slot registers 0N/A // Create operand type "method" for call targets 0N/A // Create Effect Forms for each of the legal effects 0N/A // USE, DEF, USE_DEF, KILL, USE_KILL 0N/A const char *
ident =
"USE";
0N/A // Build mapping from ideal names to ideal indices 0N/A//---------------------------addSUNcopyright------------------------------- 0N/A// output SUN copyright info 1879N/A//---------------------------addIncludeGuardStart-------------------------- 1879N/A// output the start of an include guard. 0N/A // Build #include lines 1879N/A//---------------------------addIncludeGuardEnd-------------------------- 1879N/A// output the end of an include guard. 1879N/A//---------------------------addInclude-------------------------- 1879N/A// output the #include line for this file. 0N/A//---------------------------addPreprocessorChecks----------------------------- 0N/A// Output C preprocessor code to verify the backend compilation environment. 0N/A// The idea is to force code produced by "adlc -DHS64" to be compiled by a 0N/A// command of the form "CC ... -DHS64 ...", so that any #ifdefs in the source 0N/A// blocks select C code that is consistent with adlc's selections of AD code. 0N/A fprintf(
fp,
"// Check consistency of C++ compilation with ADLC options:\n");
0N/A// Convert operand name into enum name 0N/A// Convert operand name into enum name 0N/A//---------------------------buildMustCloneMap----------------------------- 0N/A// Flag cases when machine needs cloned values or instructions 0N/A // Build external declarations for mappings 0N/A fprintf(
fp_hpp,
"// Flag cases where machine needs cloned values or instructions\n");
0N/A // Build mapping from ideal names to ideal indices 0N/A // Previously selected constants for cloning 0N/A // These are the current machine-dependent clones 0N/A // Removed ConI from the must_clone list. CPUs that cannot use 0N/A // large constants as immediates manifest the constant as an 0N/A // instruction. The must_clone flag prevents the constant from 0N/A // floating up out of loops. 0N/A // Finish defining table