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