mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 15:24:43 +02:00
8000592: Improve adlc usability
Several changes to adlc to improve its usability Reviewed-by: kvn
This commit is contained in:
parent
6674423523
commit
f28ac57f94
11 changed files with 352 additions and 283 deletions
|
@ -1392,7 +1392,7 @@ void ADLParser::pipe_parse(void) {
|
||||||
_AD.addForm(machnode);
|
_AD.addForm(machnode);
|
||||||
}
|
}
|
||||||
else if (!strcmp(ident, "attributes")) {
|
else if (!strcmp(ident, "attributes")) {
|
||||||
bool vsi_seen = false, bhds_seen = false;
|
bool vsi_seen = false;
|
||||||
|
|
||||||
skipws();
|
skipws();
|
||||||
if ( (_curchar != '%')
|
if ( (_curchar != '%')
|
||||||
|
@ -1436,7 +1436,6 @@ void ADLParser::pipe_parse(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pipeline->_branchHasDelaySlot = true;
|
pipeline->_branchHasDelaySlot = true;
|
||||||
bhds_seen = true;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1639,6 +1638,12 @@ void ADLParser::resource_parse(PipelineForm &pipeline) {
|
||||||
next_char(); // Skip "(" or ","
|
next_char(); // Skip "(" or ","
|
||||||
ident = get_ident(); // Grab next identifier
|
ident = get_ident(); // Grab next identifier
|
||||||
|
|
||||||
|
if (_AD._adl_debug > 1) {
|
||||||
|
if (ident != NULL) {
|
||||||
|
fprintf(stderr, "resource_parse: identifier: %s\n", ident);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ident == NULL) {
|
if (ident == NULL) {
|
||||||
parse_err(SYNERR, "keyword identifier expected at \"%c\"\n", _curchar);
|
parse_err(SYNERR, "keyword identifier expected at \"%c\"\n", _curchar);
|
||||||
return;
|
return;
|
||||||
|
@ -2427,7 +2432,6 @@ InstructForm *ADLParser::peep_match_child_parse(PeepMatch &match, int parent, in
|
||||||
int lparen = 0; // keep track of parenthesis nesting depth
|
int lparen = 0; // keep track of parenthesis nesting depth
|
||||||
int rparen = 0; // position of instruction at this depth
|
int rparen = 0; // position of instruction at this depth
|
||||||
InstructForm *inst_seen = NULL;
|
InstructForm *inst_seen = NULL;
|
||||||
InstructForm *child_seen = NULL;
|
|
||||||
|
|
||||||
// Walk the match tree,
|
// Walk the match tree,
|
||||||
// Record <parent, position, instruction name, input position>
|
// Record <parent, position, instruction name, input position>
|
||||||
|
@ -2437,7 +2441,7 @@ InstructForm *ADLParser::peep_match_child_parse(PeepMatch &match, int parent, in
|
||||||
if (_curchar == '(') {
|
if (_curchar == '(') {
|
||||||
++lparen;
|
++lparen;
|
||||||
next_char();
|
next_char();
|
||||||
child_seen = peep_match_child_parse(match, parent, position, rparen);
|
( void ) peep_match_child_parse(match, parent, position, rparen);
|
||||||
}
|
}
|
||||||
// Right paren signals end of an input, may be more
|
// Right paren signals end of an input, may be more
|
||||||
else if (_curchar == ')') {
|
else if (_curchar == ')') {
|
||||||
|
@ -3154,6 +3158,9 @@ void ADLParser::constant_parse_expression(EncClass* encoding, char* ec_name) {
|
||||||
|
|
||||||
|
|
||||||
//------------------------------size_parse-----------------------------------
|
//------------------------------size_parse-----------------------------------
|
||||||
|
// Parse a 'size(<expr>)' attribute which specifies the size of the
|
||||||
|
// emitted instructions in bytes. <expr> can be a C++ expression,
|
||||||
|
// e.g. a constant.
|
||||||
char* ADLParser::size_parse(InstructForm *instr) {
|
char* ADLParser::size_parse(InstructForm *instr) {
|
||||||
char* sizeOfInstr = NULL;
|
char* sizeOfInstr = NULL;
|
||||||
|
|
||||||
|
@ -4274,7 +4281,17 @@ char *ADLParser::get_ident_common(bool do_preproc) {
|
||||||
|| ((c >= '0') && (c <= '9'))
|
|| ((c >= '0') && (c <= '9'))
|
||||||
|| ((c == '_')) || ((c == ':')) || ((c == '#')) );
|
|| ((c == '_')) || ((c == ':')) || ((c == '#')) );
|
||||||
if (start == end) { // We popped out on the first try
|
if (start == end) { // We popped out on the first try
|
||||||
parse_err(SYNERR, "identifier expected at %c\n", c);
|
// It can occur that `start' contains the rest of the input file.
|
||||||
|
// In this case the output should be truncated.
|
||||||
|
if (strlen(start) > 24) {
|
||||||
|
char buf[32];
|
||||||
|
strncpy(buf, start, 20);
|
||||||
|
buf[20] = '\0';
|
||||||
|
strcat(buf, "[...]");
|
||||||
|
parse_err(SYNERR, "Identifier expected, but found '%s'.", buf);
|
||||||
|
} else {
|
||||||
|
parse_err(SYNERR, "Identifier expected, but found '%s'.", start);
|
||||||
|
}
|
||||||
start = NULL;
|
start = NULL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -221,6 +221,7 @@ ArchDesc::ArchDesc()
|
||||||
_register = NULL;
|
_register = NULL;
|
||||||
_encode = NULL;
|
_encode = NULL;
|
||||||
_pipeline = NULL;
|
_pipeline = NULL;
|
||||||
|
_frame = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArchDesc::~ArchDesc() {
|
ArchDesc::~ArchDesc() {
|
||||||
|
@ -648,7 +649,10 @@ int ArchDesc::instructFormCount() {
|
||||||
// Return the textual binding for a given CPP flag name.
|
// Return the textual binding for a given CPP flag name.
|
||||||
// Return NULL if there is no binding, or it has been #undef-ed.
|
// Return NULL if there is no binding, or it has been #undef-ed.
|
||||||
char* ArchDesc::get_preproc_def(const char* flag) {
|
char* ArchDesc::get_preproc_def(const char* flag) {
|
||||||
SourceForm* deff = (SourceForm*) _preproc_table[flag];
|
// In case of syntax errors, flag may take the value NULL.
|
||||||
|
SourceForm* deff = NULL;
|
||||||
|
if (flag != NULL)
|
||||||
|
deff = (SourceForm*) _preproc_table[flag];
|
||||||
return (deff == NULL) ? NULL : deff->_code;
|
return (deff == NULL) ? NULL : deff->_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -803,7 +807,9 @@ int ArchDesc::emit_msg(int quiet, int flag, int line, const char *fmt,
|
||||||
while (i++ <= 15) fputc(' ', errfile);
|
while (i++ <= 15) fputc(' ', errfile);
|
||||||
fprintf(errfile, "%-8s:", pref);
|
fprintf(errfile, "%-8s:", pref);
|
||||||
vfprintf(errfile, fmt, args);
|
vfprintf(errfile, fmt, args);
|
||||||
fprintf(errfile, "\n"); }
|
fprintf(errfile, "\n");
|
||||||
|
fflush(errfile);
|
||||||
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -855,8 +861,14 @@ const char *ArchDesc::reg_mask(OperandForm &opForm) {
|
||||||
|
|
||||||
// Check constraints on result's register class
|
// Check constraints on result's register class
|
||||||
const char *result_class = opForm.constrained_reg_class();
|
const char *result_class = opForm.constrained_reg_class();
|
||||||
if (!result_class) opForm.dump();
|
if (result_class == NULL) {
|
||||||
assert( result_class, "Resulting register class was not defined for operand");
|
opForm.dump();
|
||||||
|
syntax_err(opForm._linenum,
|
||||||
|
"Use of an undefined result class for operand: %s",
|
||||||
|
opForm._ident);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
regMask = reg_class_to_reg_mask( result_class );
|
regMask = reg_class_to_reg_mask( result_class );
|
||||||
|
|
||||||
return regMask;
|
return regMask;
|
||||||
|
@ -865,8 +877,14 @@ const char *ArchDesc::reg_mask(OperandForm &opForm) {
|
||||||
// Obtain the name of the RegMask for an InstructForm
|
// Obtain the name of the RegMask for an InstructForm
|
||||||
const char *ArchDesc::reg_mask(InstructForm &inForm) {
|
const char *ArchDesc::reg_mask(InstructForm &inForm) {
|
||||||
const char *result = inForm.reduce_result();
|
const char *result = inForm.reduce_result();
|
||||||
assert( result,
|
|
||||||
"Did not find result operand or RegMask for this instruction");
|
if (result == NULL) {
|
||||||
|
syntax_err(inForm._linenum,
|
||||||
|
"Did not find result operand or RegMask"
|
||||||
|
" for this instruction: %s",
|
||||||
|
inForm._ident);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
// Instructions producing 'Universe' use RegMask::Empty
|
// Instructions producing 'Universe' use RegMask::Empty
|
||||||
if( strcmp(result,"Universe")==0 ) {
|
if( strcmp(result,"Universe")==0 ) {
|
||||||
|
@ -875,10 +893,17 @@ const char *ArchDesc::reg_mask(InstructForm &inForm) {
|
||||||
|
|
||||||
// Lookup this result operand and get its register class
|
// Lookup this result operand and get its register class
|
||||||
Form *form = (Form*)_globalNames[result];
|
Form *form = (Form*)_globalNames[result];
|
||||||
assert( form, "Result operand must be defined");
|
if (form == NULL) {
|
||||||
|
syntax_err(inForm._linenum,
|
||||||
|
"Did not find result operand for result: %s", result);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
OperandForm *oper = form->is_operand();
|
OperandForm *oper = form->is_operand();
|
||||||
if (oper == NULL) form->dump();
|
if (oper == NULL) {
|
||||||
assert( oper, "Result must be an OperandForm");
|
syntax_err(inForm._linenum, "Form is not an OperandForm:");
|
||||||
|
form->dump();
|
||||||
|
abort();
|
||||||
|
}
|
||||||
return reg_mask( *oper );
|
return reg_mask( *oper );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -887,7 +912,13 @@ const char *ArchDesc::reg_mask(InstructForm &inForm) {
|
||||||
char *ArchDesc::stack_or_reg_mask(OperandForm &opForm) {
|
char *ArchDesc::stack_or_reg_mask(OperandForm &opForm) {
|
||||||
// name of cisc_spillable version
|
// name of cisc_spillable version
|
||||||
const char *reg_mask_name = reg_mask(opForm);
|
const char *reg_mask_name = reg_mask(opForm);
|
||||||
assert( reg_mask_name != NULL, "called with incorrect opForm");
|
|
||||||
|
if (reg_mask_name == NULL) {
|
||||||
|
syntax_err(opForm._linenum,
|
||||||
|
"Did not find reg_mask for opForm: %s",
|
||||||
|
opForm._ident);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
const char *stack_or = "STACK_OR_";
|
const char *stack_or = "STACK_OR_";
|
||||||
int length = (int)strlen(stack_or) + (int)strlen(reg_mask_name) + 1;
|
int length = (int)strlen(stack_or) + (int)strlen(reg_mask_name) + 1;
|
||||||
|
|
|
@ -365,13 +365,14 @@ protected:
|
||||||
// A derived class defines the appropriate output for a specific mapping.
|
// A derived class defines the appropriate output for a specific mapping.
|
||||||
class OutputMap {
|
class OutputMap {
|
||||||
protected:
|
protected:
|
||||||
FILE *_hpp;
|
FILE *_hpp;
|
||||||
FILE *_cpp;
|
FILE *_cpp;
|
||||||
FormDict &_globals;
|
FormDict &_globals;
|
||||||
ArchDesc &_AD;
|
ArchDesc &_AD;
|
||||||
|
const char *_name;
|
||||||
public:
|
public:
|
||||||
OutputMap (FILE *decl_file, FILE *def_file, FormDict &globals, ArchDesc &AD)
|
OutputMap (FILE *decl_file, FILE *def_file, FormDict &globals, ArchDesc &AD, const char *name)
|
||||||
: _hpp(decl_file), _cpp(def_file), _globals(globals), _AD(AD) {};
|
: _hpp(decl_file), _cpp(def_file), _globals(globals), _AD(AD), _name(name) {};
|
||||||
// Access files used by this routine
|
// Access files used by this routine
|
||||||
FILE *decl_file() { return _hpp; }
|
FILE *decl_file() { return _hpp; }
|
||||||
FILE *def_file() { return _cpp; }
|
FILE *def_file() { return _cpp; }
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
// String hash tables
|
// String hash tables
|
||||||
#define MAXID 20
|
#define MAXID 20
|
||||||
static char initflag = 0; // True after 1st initialization
|
static char initflag = 0; // True after 1st initialization
|
||||||
static char shft[MAXID] = {1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6};
|
static char shft[MAXID + 1] = {1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7};
|
||||||
static short xsum[MAXID];
|
static short xsum[MAXID];
|
||||||
|
|
||||||
//------------------------------bucket---------------------------------------
|
//------------------------------bucket---------------------------------------
|
||||||
|
|
|
@ -31,10 +31,14 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
// STRUCTURE FOR HANDLING INPUT AND OUTPUT FILES
|
// STRUCTURE FOR HANDLING INPUT AND OUTPUT FILES
|
||||||
typedef struct {
|
|
||||||
|
class BufferedFile {
|
||||||
|
public:
|
||||||
const char *_name;
|
const char *_name;
|
||||||
FILE *_fp;
|
FILE *_fp;
|
||||||
} BufferedFile;
|
inline BufferedFile() { _name = NULL; _fp = NULL; };
|
||||||
|
inline ~BufferedFile() {};
|
||||||
|
};
|
||||||
|
|
||||||
class ArchDesc;
|
class ArchDesc;
|
||||||
|
|
||||||
|
|
|
@ -449,11 +449,11 @@ public:
|
||||||
// Return number of USEs + number of DEFs
|
// Return number of USEs + number of DEFs
|
||||||
int num_operands();
|
int num_operands();
|
||||||
// Return zero-based position in list; -1 if not in list.
|
// Return zero-based position in list; -1 if not in list.
|
||||||
int operand_position(const char *name, int usedef);
|
int operand_position(const char *name, int usedef, Form *fm);
|
||||||
// Find position for this name, regardless of use/def information
|
// Find position for this name, regardless of use/def information
|
||||||
int operand_position(const char *name);
|
int operand_position(const char *name);
|
||||||
// Find position for this name when looked up for output via "format"
|
// Find position for this name when looked up for output via "format"
|
||||||
int operand_position_format(const char *name);
|
int operand_position_format(const char *name, Form *fm);
|
||||||
// Find position for the Label when looked up for output via "format"
|
// Find position for the Label when looked up for output via "format"
|
||||||
int label_position();
|
int label_position();
|
||||||
// Find position for the Method when looked up for output via "format"
|
// Find position for the Method when looked up for output via "format"
|
||||||
|
|
|
@ -567,7 +567,7 @@ bool InstructForm::rematerialize(FormDict &globals, RegisterForm *registers ) {
|
||||||
if( strcmp(rc_name,"stack_slots") ) {
|
if( strcmp(rc_name,"stack_slots") ) {
|
||||||
// Check for ideal_type of RegFlags
|
// Check for ideal_type of RegFlags
|
||||||
const char *type = opform->ideal_type( globals, registers );
|
const char *type = opform->ideal_type( globals, registers );
|
||||||
if( !strcmp(type,"RegFlags") )
|
if( (type != NULL) && !strcmp(type, "RegFlags") )
|
||||||
rematerialize = true;
|
rematerialize = true;
|
||||||
} else
|
} else
|
||||||
rematerialize = false; // Do not rematerialize things target stk
|
rematerialize = false; // Do not rematerialize things target stk
|
||||||
|
@ -795,6 +795,20 @@ uint InstructForm::num_opnds() {
|
||||||
return num_opnds;
|
return num_opnds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *InstructForm::opnd_ident(int idx) {
|
||||||
|
return _components.at(idx)->_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *InstructForm::unique_opnd_ident(int idx) {
|
||||||
|
uint i;
|
||||||
|
for (i = 1; i < num_opnds(); ++i) {
|
||||||
|
if (unique_opnds_idx(i) == idx) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (_components.at(i) != NULL) ? _components.at(i)->_name : "";
|
||||||
|
}
|
||||||
|
|
||||||
// Return count of unmatched operands.
|
// Return count of unmatched operands.
|
||||||
uint InstructForm::num_post_match_opnds() {
|
uint InstructForm::num_post_match_opnds() {
|
||||||
uint num_post_match_opnds = _components.count();
|
uint num_post_match_opnds = _components.count();
|
||||||
|
@ -866,6 +880,9 @@ uint InstructForm::oper_input_base(FormDict &globals) {
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This function determines the order of the MachOper in _opnds[]
|
||||||
|
// by writing the operand names into the _components list.
|
||||||
|
//
|
||||||
// Implementation does not modify state of internal structures
|
// Implementation does not modify state of internal structures
|
||||||
void InstructForm::build_components() {
|
void InstructForm::build_components() {
|
||||||
// Add top-level operands to the components
|
// Add top-level operands to the components
|
||||||
|
@ -961,11 +978,11 @@ void InstructForm::build_components() {
|
||||||
|
|
||||||
// Return zero-based position in component list; -1 if not in list.
|
// Return zero-based position in component list; -1 if not in list.
|
||||||
int InstructForm::operand_position(const char *name, int usedef) {
|
int InstructForm::operand_position(const char *name, int usedef) {
|
||||||
return unique_opnds_idx(_components.operand_position(name, usedef));
|
return unique_opnds_idx(_components.operand_position(name, usedef, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
int InstructForm::operand_position_format(const char *name) {
|
int InstructForm::operand_position_format(const char *name) {
|
||||||
return unique_opnds_idx(_components.operand_position_format(name));
|
return unique_opnds_idx(_components.operand_position_format(name, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return zero-based position in component list; -1 if not in list.
|
// Return zero-based position in component list; -1 if not in list.
|
||||||
|
@ -1225,7 +1242,7 @@ bool InstructForm::check_branch_variant(ArchDesc &AD, InstructForm *short_branch
|
||||||
if (different) {
|
if (different) {
|
||||||
globalAD->syntax_err(short_branch->_linenum, "Instruction %s and its short form %s have different parameters\n", _ident, short_branch->_ident);
|
globalAD->syntax_err(short_branch->_linenum, "Instruction %s and its short form %s have different parameters\n", _ident, short_branch->_ident);
|
||||||
}
|
}
|
||||||
if (AD._short_branch_debug) {
|
if (AD._adl_debug > 1 || AD._short_branch_debug) {
|
||||||
fprintf(stderr, "Instruction %s has short form %s\n", _ident, short_branch->_ident);
|
fprintf(stderr, "Instruction %s has short form %s\n", _ident, short_branch->_ident);
|
||||||
}
|
}
|
||||||
_short_branch_form = short_branch;
|
_short_branch_form = short_branch;
|
||||||
|
@ -1257,16 +1274,19 @@ void InstructForm::rep_var_format(FILE *fp, const char *rep_var) {
|
||||||
// Find replacement variable's type
|
// Find replacement variable's type
|
||||||
const Form *form = _localNames[rep_var];
|
const Form *form = _localNames[rep_var];
|
||||||
if (form == NULL) {
|
if (form == NULL) {
|
||||||
fprintf(stderr, "unknown replacement variable in format statement: '%s'\n", rep_var);
|
globalAD->syntax_err(_linenum, "Unknown replacement variable %s in format statement of %s.",
|
||||||
assert(false, "ShouldNotReachHere()");
|
rep_var, _ident);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
OpClassForm *opc = form->is_opclass();
|
OpClassForm *opc = form->is_opclass();
|
||||||
assert( opc, "replacement variable was not found in local names");
|
assert( opc, "replacement variable was not found in local names");
|
||||||
// Lookup the index position of the replacement variable
|
// Lookup the index position of the replacement variable
|
||||||
int idx = operand_position_format(rep_var);
|
int idx = operand_position_format(rep_var);
|
||||||
if ( idx == -1 ) {
|
if ( idx == -1 ) {
|
||||||
assert( strcmp(opc->_ident,"label")==0, "Unimplemented");
|
globalAD->syntax_err(_linenum, "Could not find replacement variable %s in format statement of %s.\n",
|
||||||
assert( false, "ShouldNotReachHere()");
|
rep_var, _ident);
|
||||||
|
assert(strcmp(opc->_ident, "label") == 0, "Unimplemented");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_noninput_operand(idx)) {
|
if (is_noninput_operand(idx)) {
|
||||||
|
@ -1275,7 +1295,7 @@ void InstructForm::rep_var_format(FILE *fp, const char *rep_var) {
|
||||||
OperandForm* oper = form->is_operand();
|
OperandForm* oper = form->is_operand();
|
||||||
if (oper != NULL && oper->is_bound_register()) {
|
if (oper != NULL && oper->is_bound_register()) {
|
||||||
const RegDef* first = oper->get_RegClass()->find_first_elem();
|
const RegDef* first = oper->get_RegClass()->find_first_elem();
|
||||||
fprintf(fp, " tty->print(\"%s\");\n", first->_regname);
|
fprintf(fp, " st->print(\"%s\");\n", first->_regname);
|
||||||
} else {
|
} else {
|
||||||
globalAD->syntax_err(_linenum, "In %s can't find format for %s %s", _ident, opc->_ident, rep_var);
|
globalAD->syntax_err(_linenum, "In %s can't find format for %s %s", _ident, opc->_ident, rep_var);
|
||||||
}
|
}
|
||||||
|
@ -1373,26 +1393,28 @@ void InstructForm::index_temps(FILE *fp, FormDict &globals, const char *prefix,
|
||||||
// idx0=0 is used to indicate that info comes from this same node, not from input edge.
|
// idx0=0 is used to indicate that info comes from this same node, not from input edge.
|
||||||
// idx1 starts at oper_input_base()
|
// idx1 starts at oper_input_base()
|
||||||
if ( cur_num_opnds >= 1 ) {
|
if ( cur_num_opnds >= 1 ) {
|
||||||
fprintf(fp," // Start at oper_input_base() and count operands\n");
|
fprintf(fp," // Start at oper_input_base() and count operands\n");
|
||||||
fprintf(fp," unsigned %sidx0 = %d;\n", prefix, oper_input_base(globals));
|
fprintf(fp," unsigned %sidx0 = %d;\n", prefix, oper_input_base(globals));
|
||||||
fprintf(fp," unsigned %sidx1 = %d;\n", prefix, oper_input_base(globals));
|
fprintf(fp," unsigned %sidx1 = %d;", prefix, oper_input_base(globals));
|
||||||
|
fprintf(fp," \t// %s\n", unique_opnd_ident(1));
|
||||||
|
|
||||||
// Generate starting points for other unique operands if they exist
|
// Generate starting points for other unique operands if they exist
|
||||||
for ( idx = 2; idx < num_unique_opnds(); ++idx ) {
|
for ( idx = 2; idx < num_unique_opnds(); ++idx ) {
|
||||||
if( *receiver == 0 ) {
|
if( *receiver == 0 ) {
|
||||||
fprintf(fp," unsigned %sidx%d = %sidx%d + opnd_array(%d)->num_edges();\n",
|
fprintf(fp," unsigned %sidx%d = %sidx%d + opnd_array(%d)->num_edges();",
|
||||||
prefix, idx, prefix, idx-1, idx-1 );
|
prefix, idx, prefix, idx-1, idx-1 );
|
||||||
} else {
|
} else {
|
||||||
fprintf(fp," unsigned %sidx%d = %sidx%d + %s_opnds[%d]->num_edges();\n",
|
fprintf(fp," unsigned %sidx%d = %sidx%d + %s_opnds[%d]->num_edges();",
|
||||||
prefix, idx, prefix, idx-1, receiver, idx-1 );
|
prefix, idx, prefix, idx-1, receiver, idx-1 );
|
||||||
}
|
}
|
||||||
|
fprintf(fp," \t// %s\n", unique_opnd_ident(idx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( *receiver != 0 ) {
|
if( *receiver != 0 ) {
|
||||||
// This value is used by generate_peepreplace when copying a node.
|
// This value is used by generate_peepreplace when copying a node.
|
||||||
// Don't emit it in other cases since it can hide bugs with the
|
// Don't emit it in other cases since it can hide bugs with the
|
||||||
// use invalid idx's.
|
// use invalid idx's.
|
||||||
fprintf(fp," unsigned %sidx%d = %sreq(); \n", prefix, idx, receiver);
|
fprintf(fp," unsigned %sidx%d = %sreq(); \n", prefix, idx, receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1776,9 +1798,25 @@ static int effect_lookup(const char *name) {
|
||||||
return Component::INVALID;
|
return Component::INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *Component::getUsedefName() {
|
||||||
|
switch (_usedef) {
|
||||||
|
case Component::INVALID: return "INVALID"; break;
|
||||||
|
case Component::USE: return "USE"; break;
|
||||||
|
case Component::USE_DEF: return "USE_DEF"; break;
|
||||||
|
case Component::USE_KILL: return "USE_KILL"; break;
|
||||||
|
case Component::KILL: return "KILL"; break;
|
||||||
|
case Component::TEMP: return "TEMP"; break;
|
||||||
|
case Component::DEF: return "DEF"; break;
|
||||||
|
case Component::CALL: return "CALL"; break;
|
||||||
|
default: assert(false, "unknown effect");
|
||||||
|
}
|
||||||
|
return "Undefined Use/Def info";
|
||||||
|
}
|
||||||
|
|
||||||
Effect::Effect(const char *name) : _name(name), _use_def(effect_lookup(name)) {
|
Effect::Effect(const char *name) : _name(name), _use_def(effect_lookup(name)) {
|
||||||
_ftype = Form::EFF;
|
_ftype = Form::EFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
Effect::~Effect() {
|
Effect::~Effect() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2275,7 +2313,7 @@ void OperandForm::build_components() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int OperandForm::operand_position(const char *name, int usedef) {
|
int OperandForm::operand_position(const char *name, int usedef) {
|
||||||
return _components.operand_position(name, usedef);
|
return _components.operand_position(name, usedef, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2401,20 +2439,20 @@ void OperandForm::int_format(FILE *fp, FormDict &globals, uint index) {
|
||||||
if (_matrule && (_matrule->is_base_register(globals) ||
|
if (_matrule && (_matrule->is_base_register(globals) ||
|
||||||
strcmp(ideal_type(globalAD->globalNames()), "RegFlags") == 0)) {
|
strcmp(ideal_type(globalAD->globalNames()), "RegFlags") == 0)) {
|
||||||
// !!!!! !!!!!
|
// !!!!! !!!!!
|
||||||
fprintf(fp, "{ char reg_str[128];\n");
|
fprintf(fp," { char reg_str[128];\n");
|
||||||
fprintf(fp," ra->dump_register(node,reg_str);\n");
|
fprintf(fp," ra->dump_register(node,reg_str);\n");
|
||||||
fprintf(fp," tty->print(\"%cs\",reg_str);\n",'%');
|
fprintf(fp," st->print(\"%cs\",reg_str);\n",'%');
|
||||||
fprintf(fp," }\n");
|
fprintf(fp," }\n");
|
||||||
} else if (_matrule && (dtype = _matrule->is_base_constant(globals)) != Form::none) {
|
} else if (_matrule && (dtype = _matrule->is_base_constant(globals)) != Form::none) {
|
||||||
format_constant( fp, index, dtype );
|
format_constant( fp, index, dtype );
|
||||||
} else if (ideal_to_sReg_type(_ident) != Form::none) {
|
} else if (ideal_to_sReg_type(_ident) != Form::none) {
|
||||||
// Special format for Stack Slot Register
|
// Special format for Stack Slot Register
|
||||||
fprintf(fp, "{ char reg_str[128];\n");
|
fprintf(fp," { char reg_str[128];\n");
|
||||||
fprintf(fp," ra->dump_register(node,reg_str);\n");
|
fprintf(fp," ra->dump_register(node,reg_str);\n");
|
||||||
fprintf(fp," tty->print(\"%cs\",reg_str);\n",'%');
|
fprintf(fp," st->print(\"%cs\",reg_str);\n",'%');
|
||||||
fprintf(fp," }\n");
|
fprintf(fp," }\n");
|
||||||
} else {
|
} else {
|
||||||
fprintf(fp,"tty->print(\"No format defined for %s\n\");\n", _ident);
|
fprintf(fp," st->print(\"No format defined for %s\n\");\n", _ident);
|
||||||
fflush(fp);
|
fflush(fp);
|
||||||
fprintf(stderr,"No format defined for %s\n", _ident);
|
fprintf(stderr,"No format defined for %s\n", _ident);
|
||||||
dump();
|
dump();
|
||||||
|
@ -2428,37 +2466,37 @@ void OperandForm::ext_format(FILE *fp, FormDict &globals, uint index) {
|
||||||
Form::DataType dtype;
|
Form::DataType dtype;
|
||||||
if (_matrule && (_matrule->is_base_register(globals) ||
|
if (_matrule && (_matrule->is_base_register(globals) ||
|
||||||
strcmp(ideal_type(globalAD->globalNames()), "RegFlags") == 0)) {
|
strcmp(ideal_type(globalAD->globalNames()), "RegFlags") == 0)) {
|
||||||
fprintf(fp, "{ char reg_str[128];\n");
|
fprintf(fp," { char reg_str[128];\n");
|
||||||
fprintf(fp," ra->dump_register(node->in(idx");
|
fprintf(fp," ra->dump_register(node->in(idx");
|
||||||
if ( index != 0 ) fprintf(fp, "+%d",index);
|
if ( index != 0 ) fprintf(fp, "+%d",index);
|
||||||
fprintf(fp, "),reg_str);\n");
|
fprintf(fp, "),reg_str);\n");
|
||||||
fprintf(fp," tty->print(\"%cs\",reg_str);\n",'%');
|
fprintf(fp," st->print(\"%cs\",reg_str);\n",'%');
|
||||||
fprintf(fp," }\n");
|
fprintf(fp," }\n");
|
||||||
} else if (_matrule && (dtype = _matrule->is_base_constant(globals)) != Form::none) {
|
} else if (_matrule && (dtype = _matrule->is_base_constant(globals)) != Form::none) {
|
||||||
format_constant( fp, index, dtype );
|
format_constant( fp, index, dtype );
|
||||||
} else if (ideal_to_sReg_type(_ident) != Form::none) {
|
} else if (ideal_to_sReg_type(_ident) != Form::none) {
|
||||||
// Special format for Stack Slot Register
|
// Special format for Stack Slot Register
|
||||||
fprintf(fp, "{ char reg_str[128];\n");
|
fprintf(fp," { char reg_str[128];\n");
|
||||||
fprintf(fp," ra->dump_register(node->in(idx");
|
fprintf(fp," ra->dump_register(node->in(idx");
|
||||||
if ( index != 0 ) fprintf(fp, "+%d",index);
|
if ( index != 0 ) fprintf(fp, "+%d",index);
|
||||||
fprintf(fp, "),reg_str);\n");
|
fprintf(fp, "),reg_str);\n");
|
||||||
fprintf(fp," tty->print(\"%cs\",reg_str);\n",'%');
|
fprintf(fp," st->print(\"%cs\",reg_str);\n",'%');
|
||||||
fprintf(fp," }\n");
|
fprintf(fp," }\n");
|
||||||
} else {
|
} else {
|
||||||
fprintf(fp,"tty->print(\"No format defined for %s\n\");\n", _ident);
|
fprintf(fp," st->print(\"No format defined for %s\n\");\n", _ident);
|
||||||
assert( false,"Internal error:\n output_external_operand() attempting to output other than a Register or Constant");
|
assert( false,"Internal error:\n output_external_operand() attempting to output other than a Register or Constant");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OperandForm::format_constant(FILE *fp, uint const_index, uint const_type) {
|
void OperandForm::format_constant(FILE *fp, uint const_index, uint const_type) {
|
||||||
switch(const_type) {
|
switch(const_type) {
|
||||||
case Form::idealI: fprintf(fp,"st->print(\"#%%d\", _c%d);\n", const_index); break;
|
case Form::idealI: fprintf(fp," st->print(\"#%%d\", _c%d);\n", const_index); break;
|
||||||
case Form::idealP: fprintf(fp,"_c%d->dump_on(st);\n", const_index); break;
|
case Form::idealP: fprintf(fp," if (_c%d) _c%d->dump_on(st);\n", const_index, const_index); break;
|
||||||
case Form::idealNKlass:
|
case Form::idealNKlass:
|
||||||
case Form::idealN: fprintf(fp,"_c%d->dump_on(st);\n", const_index); break;
|
case Form::idealN: fprintf(fp," if (_c%d) _c%d->dump_on(st);\n", const_index, const_index); break;
|
||||||
case Form::idealL: fprintf(fp,"st->print(\"#%%lld\", _c%d);\n", const_index); break;
|
case Form::idealL: fprintf(fp," st->print(\"#%%lld\", _c%d);\n", const_index); break;
|
||||||
case Form::idealF: fprintf(fp,"st->print(\"#%%f\", _c%d);\n", const_index); break;
|
case Form::idealF: fprintf(fp," st->print(\"#%%f\", _c%d);\n", const_index); break;
|
||||||
case Form::idealD: fprintf(fp,"st->print(\"#%%f\", _c%d);\n", const_index); break;
|
case Form::idealD: fprintf(fp," st->print(\"#%%f\", _c%d);\n", const_index); break;
|
||||||
default:
|
default:
|
||||||
assert( false, "ShouldNotReachHere()");
|
assert( false, "ShouldNotReachHere()");
|
||||||
}
|
}
|
||||||
|
@ -2828,17 +2866,8 @@ void Component::output(FILE *fp) {
|
||||||
fprintf(fp,"Component:"); // Write to output files
|
fprintf(fp,"Component:"); // Write to output files
|
||||||
fprintf(fp, " name = %s", _name);
|
fprintf(fp, " name = %s", _name);
|
||||||
fprintf(fp, ", type = %s", _type);
|
fprintf(fp, ", type = %s", _type);
|
||||||
const char * usedef = "Undefined Use/Def info";
|
assert(_usedef != 0, "unknown effect");
|
||||||
switch (_usedef) {
|
fprintf(fp, ", use/def = %s\n", getUsedefName());
|
||||||
case USE: usedef = "USE"; break;
|
|
||||||
case USE_DEF: usedef = "USE_DEF"; break;
|
|
||||||
case USE_KILL: usedef = "USE_KILL"; break;
|
|
||||||
case KILL: usedef = "KILL"; break;
|
|
||||||
case TEMP: usedef = "TEMP"; break;
|
|
||||||
case DEF: usedef = "DEF"; break;
|
|
||||||
default: assert(false, "unknown effect");
|
|
||||||
}
|
|
||||||
fprintf(fp, ", use/def = %s\n", usedef);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2930,9 +2959,9 @@ int ComponentList::num_operands() {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return zero-based position in list; -1 if not in list.
|
// Return zero-based position of operand 'name' in list; -1 if not in list.
|
||||||
// if parameter 'usedef' is ::USE, it will match USE, USE_DEF, ...
|
// if parameter 'usedef' is ::USE, it will match USE, USE_DEF, ...
|
||||||
int ComponentList::operand_position(const char *name, int usedef) {
|
int ComponentList::operand_position(const char *name, int usedef, Form *fm) {
|
||||||
PreserveIter pi(this);
|
PreserveIter pi(this);
|
||||||
int position = 0;
|
int position = 0;
|
||||||
int num_opnds = num_operands();
|
int num_opnds = num_operands();
|
||||||
|
@ -2955,10 +2984,18 @@ int ComponentList::operand_position(const char *name, int usedef) {
|
||||||
return position+1;
|
return position+1;
|
||||||
} else {
|
} else {
|
||||||
if( preceding_non_use && strcmp(component->_name, preceding_non_use->_name) ) {
|
if( preceding_non_use && strcmp(component->_name, preceding_non_use->_name) ) {
|
||||||
fprintf(stderr, "the name '%s' should not precede the name '%s'\n", preceding_non_use->_name, name);
|
fprintf(stderr, "the name '%s(%s)' should not precede the name '%s(%s)'",
|
||||||
|
preceding_non_use->_name, preceding_non_use->getUsedefName(),
|
||||||
|
name, component->getUsedefName());
|
||||||
|
if (fm && fm->is_instruction()) fprintf(stderr, "in form '%s'", fm->is_instruction()->_ident);
|
||||||
|
if (fm && fm->is_operand()) fprintf(stderr, "in form '%s'", fm->is_operand()->_ident);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
if( position >= num_opnds ) {
|
if( position >= num_opnds ) {
|
||||||
fprintf(stderr, "the name '%s' is too late in its name list\n", name);
|
fprintf(stderr, "the name '%s' is too late in its name list", name);
|
||||||
|
if (fm && fm->is_instruction()) fprintf(stderr, "in form '%s'", fm->is_instruction()->_ident);
|
||||||
|
if (fm && fm->is_operand()) fprintf(stderr, "in form '%s'", fm->is_operand()->_ident);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
}
|
}
|
||||||
assert(position < num_opnds, "advertised index in bounds");
|
assert(position < num_opnds, "advertised index in bounds");
|
||||||
return position;
|
return position;
|
||||||
|
@ -3004,10 +3041,10 @@ int ComponentList::operand_position(const char *name) {
|
||||||
return Not_in_list;
|
return Not_in_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ComponentList::operand_position_format(const char *name) {
|
int ComponentList::operand_position_format(const char *name, Form *fm) {
|
||||||
PreserveIter pi(this);
|
PreserveIter pi(this);
|
||||||
int first_position = operand_position(name);
|
int first_position = operand_position(name);
|
||||||
int use_position = operand_position(name, Component::USE);
|
int use_position = operand_position(name, Component::USE, fm);
|
||||||
|
|
||||||
return ((first_position < use_position) ? use_position : first_position);
|
return ((first_position < use_position) ? use_position : first_position);
|
||||||
}
|
}
|
||||||
|
@ -3270,8 +3307,8 @@ const char *MatchNode::reduce_right(FormDict &globals) const {
|
||||||
|
|
||||||
// If we are a "Set", start from the right child.
|
// If we are a "Set", start from the right child.
|
||||||
const MatchNode *const mnode = sets_result() ?
|
const MatchNode *const mnode = sets_result() ?
|
||||||
(const MatchNode *const)this->_rChild :
|
(const MatchNode *)this->_rChild :
|
||||||
(const MatchNode *const)this;
|
(const MatchNode *)this;
|
||||||
|
|
||||||
// If our right child exists, it is the right reduction
|
// If our right child exists, it is the right reduction
|
||||||
if ( mnode->_rChild ) {
|
if ( mnode->_rChild ) {
|
||||||
|
@ -3288,8 +3325,8 @@ const char *MatchNode::reduce_left(FormDict &globals) const {
|
||||||
|
|
||||||
// If we are a "Set", start from the right child.
|
// If we are a "Set", start from the right child.
|
||||||
const MatchNode *const mnode = sets_result() ?
|
const MatchNode *const mnode = sets_result() ?
|
||||||
(const MatchNode *const)this->_rChild :
|
(const MatchNode *)this->_rChild :
|
||||||
(const MatchNode *const)this;
|
(const MatchNode *)this;
|
||||||
|
|
||||||
// If our left child exists, it is the left reduction
|
// If our left child exists, it is the left reduction
|
||||||
if ( mnode->_lChild ) {
|
if ( mnode->_lChild ) {
|
||||||
|
@ -4113,12 +4150,17 @@ void MatchRule::dump() {
|
||||||
output(stderr);
|
output(stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatchRule::output(FILE *fp) {
|
// Write just one line.
|
||||||
|
void MatchRule::output_short(FILE *fp) {
|
||||||
fprintf(fp,"MatchRule: ( %s",_name);
|
fprintf(fp,"MatchRule: ( %s",_name);
|
||||||
if (_lChild) _lChild->output(fp);
|
if (_lChild) _lChild->output(fp);
|
||||||
if (_rChild) _rChild->output(fp);
|
if (_rChild) _rChild->output(fp);
|
||||||
fprintf(fp," )\n");
|
fprintf(fp," )");
|
||||||
fprintf(fp," nesting depth = %d\n", _depth);
|
}
|
||||||
|
|
||||||
|
void MatchRule::output(FILE *fp) {
|
||||||
|
output_short(fp);
|
||||||
|
fprintf(fp,"\n nesting depth = %d\n", _depth);
|
||||||
if (_result) fprintf(fp," Result Type = %s", _result);
|
if (_result) fprintf(fp," Result Type = %s", _result);
|
||||||
fprintf(fp,"\n");
|
fprintf(fp,"\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ class InstructForm : public Form {
|
||||||
private:
|
private:
|
||||||
bool _ideal_only; // Not a user-defined instruction
|
bool _ideal_only; // Not a user-defined instruction
|
||||||
// Members used for tracking CISC-spilling
|
// Members used for tracking CISC-spilling
|
||||||
uint _cisc_spill_operand;// Which operand may cisc-spill
|
int _cisc_spill_operand;// Which operand may cisc-spill
|
||||||
void set_cisc_spill_operand(uint op_index) { _cisc_spill_operand = op_index; }
|
void set_cisc_spill_operand(uint op_index) { _cisc_spill_operand = op_index; }
|
||||||
bool _is_cisc_alternate;
|
bool _is_cisc_alternate;
|
||||||
InstructForm *_cisc_spill_alternate;// cisc possible replacement
|
InstructForm *_cisc_spill_alternate;// cisc possible replacement
|
||||||
|
@ -103,7 +103,7 @@ public:
|
||||||
RewriteRule *_rewrule; // Rewrite rule for this instruction
|
RewriteRule *_rewrule; // Rewrite rule for this instruction
|
||||||
FormatRule *_format; // Format for assembly generation
|
FormatRule *_format; // Format for assembly generation
|
||||||
Peephole *_peephole; // List of peephole rules for instruction
|
Peephole *_peephole; // List of peephole rules for instruction
|
||||||
const char *_ins_pipe; // Instruction Scheduline description class
|
const char *_ins_pipe; // Instruction Scheduling description class
|
||||||
|
|
||||||
uint *_uniq_idx; // Indexes of unique operands
|
uint *_uniq_idx; // Indexes of unique operands
|
||||||
int _uniq_idx_length; // Length of _uniq_idx array
|
int _uniq_idx_length; // Length of _uniq_idx array
|
||||||
|
@ -198,6 +198,7 @@ public:
|
||||||
|
|
||||||
virtual const char *cost(); // Access ins_cost attribute
|
virtual const char *cost(); // Access ins_cost attribute
|
||||||
virtual uint num_opnds(); // Count of num_opnds for MachNode class
|
virtual uint num_opnds(); // Count of num_opnds for MachNode class
|
||||||
|
// Counts USE_DEF opnds twice. See also num_unique_opnds().
|
||||||
virtual uint num_post_match_opnds();
|
virtual uint num_post_match_opnds();
|
||||||
virtual uint num_consts(FormDict &globals) const;// Constants in match rule
|
virtual uint num_consts(FormDict &globals) const;// Constants in match rule
|
||||||
// Constants in match rule with specified type
|
// Constants in match rule with specified type
|
||||||
|
@ -228,6 +229,7 @@ public:
|
||||||
// Return number of relocation entries needed for this instruction.
|
// Return number of relocation entries needed for this instruction.
|
||||||
virtual uint reloc(FormDict &globals);
|
virtual uint reloc(FormDict &globals);
|
||||||
|
|
||||||
|
const char *opnd_ident(int idx); // Name of operand #idx.
|
||||||
const char *reduce_result();
|
const char *reduce_result();
|
||||||
// Return the name of the operand on the right hand side of the binary match
|
// Return the name of the operand on the right hand side of the binary match
|
||||||
// Return NULL if there is no right hand side
|
// Return NULL if there is no right hand side
|
||||||
|
@ -240,7 +242,7 @@ public:
|
||||||
// Check if this instruction can cisc-spill to 'alternate'
|
// Check if this instruction can cisc-spill to 'alternate'
|
||||||
bool cisc_spills_to(ArchDesc &AD, InstructForm *alternate);
|
bool cisc_spills_to(ArchDesc &AD, InstructForm *alternate);
|
||||||
InstructForm *cisc_spill_alternate() { return _cisc_spill_alternate; }
|
InstructForm *cisc_spill_alternate() { return _cisc_spill_alternate; }
|
||||||
uint cisc_spill_operand() const { return _cisc_spill_operand; }
|
int cisc_spill_operand() const { return _cisc_spill_operand; }
|
||||||
bool is_cisc_alternate() const { return _is_cisc_alternate; }
|
bool is_cisc_alternate() const { return _is_cisc_alternate; }
|
||||||
void set_cisc_alternate(bool val) { _is_cisc_alternate = val; }
|
void set_cisc_alternate(bool val) { _is_cisc_alternate = val; }
|
||||||
const char *cisc_reg_mask_name() const { return _cisc_reg_mask_name; }
|
const char *cisc_reg_mask_name() const { return _cisc_reg_mask_name; }
|
||||||
|
@ -277,6 +279,7 @@ public:
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const char *unique_opnd_ident(int idx); // Name of operand at unique idx.
|
||||||
|
|
||||||
// Operands which are only KILLs aren't part of the input array and
|
// Operands which are only KILLs aren't part of the input array and
|
||||||
// require special handling in some cases. Their position in this
|
// require special handling in some cases. Their position in this
|
||||||
|
@ -889,6 +892,7 @@ public:
|
||||||
|
|
||||||
void dump(); // Debug printer
|
void dump(); // Debug printer
|
||||||
void output(FILE *fp); // Write to output files
|
void output(FILE *fp); // Write to output files
|
||||||
|
const char* getUsedefName();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Implementation depends upon working bit intersection and union.
|
// Implementation depends upon working bit intersection and union.
|
||||||
|
@ -1030,6 +1034,7 @@ public:
|
||||||
void matchrule_swap_commutative_op(const char* instr_ident, int count, int& match_rules_cnt);
|
void matchrule_swap_commutative_op(const char* instr_ident, int count, int& match_rules_cnt);
|
||||||
|
|
||||||
void dump();
|
void dump();
|
||||||
|
void output_short(FILE *fp);
|
||||||
void output(FILE *fp);
|
void output(FILE *fp);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -341,14 +341,20 @@ int main(int argc, char *argv[])
|
||||||
static void usage(ArchDesc& AD)
|
static void usage(ArchDesc& AD)
|
||||||
{
|
{
|
||||||
printf("Architecture Description Language Compiler\n\n");
|
printf("Architecture Description Language Compiler\n\n");
|
||||||
printf("Usage: adl [-doqw] [-Dflag[=def]] [-Uflag] [-cFILENAME] [-hFILENAME] [-aDFAFILE] ADLFILE\n");
|
printf("Usage: adlc [-doqwTs] [-#]* [-D<FLAG>[=<DEF>]] [-U<FLAG>] [-c<CPP_FILE_NAME>] [-h<HPP_FILE_NAME>] [-a<DFA_FILE_NAME>] [-v<GLOBALS_FILE_NAME>] <ADL_FILE_NAME>\n");
|
||||||
printf(" d produce DFA debugging info\n");
|
printf(" d produce DFA debugging info\n");
|
||||||
printf(" o no output produced, syntax and semantic checking only\n");
|
printf(" o no output produced, syntax and semantic checking only\n");
|
||||||
printf(" q quiet mode, supresses all non-essential messages\n");
|
printf(" q quiet mode, supresses all non-essential messages\n");
|
||||||
printf(" w suppress warning messages\n");
|
printf(" w suppress warning messages\n");
|
||||||
|
printf(" T make DFA as many subroutine calls\n");
|
||||||
|
printf(" s output which instructions are cisc-spillable\n");
|
||||||
|
printf(" D define preprocessor symbol\n");
|
||||||
|
printf(" U undefine preprocessor symbol\n");
|
||||||
printf(" c specify CPP file name (default: %s)\n", AD._CPP_file._name);
|
printf(" c specify CPP file name (default: %s)\n", AD._CPP_file._name);
|
||||||
printf(" h specify HPP file name (default: %s)\n", AD._HPP_file._name);
|
printf(" h specify HPP file name (default: %s)\n", AD._HPP_file._name);
|
||||||
printf(" a specify DFA output file name\n");
|
printf(" a specify DFA output file name\n");
|
||||||
|
printf(" v specify adGlobals output file name\n");
|
||||||
|
printf(" # increment ADL debug level\n");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,22 +456,6 @@ static char *strip_ext(char *fname)
|
||||||
return fname;
|
return fname;
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------strip_path_and_ext------------------------------
|
|
||||||
static char *strip_path_and_ext(char *fname)
|
|
||||||
{
|
|
||||||
char *ep;
|
|
||||||
char *sp;
|
|
||||||
|
|
||||||
if (fname) {
|
|
||||||
for (sp = fname; *sp; sp++)
|
|
||||||
if (*sp == '/') fname = sp+1;
|
|
||||||
ep = fname; // start at first character and look for '.'
|
|
||||||
while (ep <= (fname + strlen(fname) - 1) && *ep != '.') ep++;
|
|
||||||
if (*ep == '.') *ep = '\0'; // truncate string at '.'
|
|
||||||
}
|
|
||||||
return fname;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------base_plus_suffix-------------------------------
|
//------------------------------base_plus_suffix-------------------------------
|
||||||
// New concatenated string
|
// New concatenated string
|
||||||
static char *base_plus_suffix(const char* base, const char *suffix)
|
static char *base_plus_suffix(const char* base, const char *suffix)
|
||||||
|
@ -477,18 +467,6 @@ static char *base_plus_suffix(const char* base, const char *suffix)
|
||||||
return fname;
|
return fname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//------------------------------prefix_plus_base_plus_suffix-------------------
|
|
||||||
// New concatenated string
|
|
||||||
static char *prefix_plus_base_plus_suffix(const char* prefix, const char* base, const char *suffix)
|
|
||||||
{
|
|
||||||
int len = (int)strlen(prefix) + (int)strlen(base) + (int)strlen(suffix) + 1;
|
|
||||||
|
|
||||||
char* fname = new char[len];
|
|
||||||
sprintf(fname,"%s%s%s",prefix,base,suffix);
|
|
||||||
return fname;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------get_legal_text---------------------------------
|
//------------------------------get_legal_text---------------------------------
|
||||||
// Get pointer to legal text at the beginning of AD file.
|
// Get pointer to legal text at the beginning of AD file.
|
||||||
// This code assumes that a legal text starts at the beginning of .ad files,
|
// This code assumes that a legal text starts at the beginning of .ad files,
|
||||||
|
|
|
@ -518,6 +518,14 @@ static int pipeline_res_mask_initializer(
|
||||||
|
|
||||||
int cycles = piperesource->_cycles;
|
int cycles = piperesource->_cycles;
|
||||||
uint stage = pipeline->_stages.index(piperesource->_stage);
|
uint stage = pipeline->_stages.index(piperesource->_stage);
|
||||||
|
if (NameList::Not_in_list == stage) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"pipeline_res_mask_initializer: "
|
||||||
|
"semantic error: "
|
||||||
|
"pipeline stage undeclared: %s\n",
|
||||||
|
piperesource->_stage);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
uint upper_limit = stage+cycles-1;
|
uint upper_limit = stage+cycles-1;
|
||||||
uint lower_limit = stage-1;
|
uint lower_limit = stage-1;
|
||||||
uint upper_idx = upper_limit >> 5;
|
uint upper_idx = upper_limit >> 5;
|
||||||
|
@ -1000,7 +1008,7 @@ void ArchDesc::build_pipe_classes(FILE *fp_cpp) {
|
||||||
}
|
}
|
||||||
fprintf(fp_cpp, "};\n\n");
|
fprintf(fp_cpp, "};\n\n");
|
||||||
fprintf(fp_cpp, "#ifndef PRODUCT\n");
|
fprintf(fp_cpp, "#ifndef PRODUCT\n");
|
||||||
fprintf(fp_cpp, "void Bundle::dump() const {\n");
|
fprintf(fp_cpp, "void Bundle::dump(outputStream *st) const {\n");
|
||||||
fprintf(fp_cpp, " static const char * bundle_flags[] = {\n");
|
fprintf(fp_cpp, " static const char * bundle_flags[] = {\n");
|
||||||
fprintf(fp_cpp, " \"\",\n");
|
fprintf(fp_cpp, " \"\",\n");
|
||||||
fprintf(fp_cpp, " \"use nop delay\",\n");
|
fprintf(fp_cpp, " \"use nop delay\",\n");
|
||||||
|
@ -1019,22 +1027,22 @@ void ArchDesc::build_pipe_classes(FILE *fp_cpp) {
|
||||||
// See if the same string is in the table
|
// See if the same string is in the table
|
||||||
fprintf(fp_cpp, " bool needs_comma = false;\n\n");
|
fprintf(fp_cpp, " bool needs_comma = false;\n\n");
|
||||||
fprintf(fp_cpp, " if (_flags) {\n");
|
fprintf(fp_cpp, " if (_flags) {\n");
|
||||||
fprintf(fp_cpp, " tty->print(\"%%s\", bundle_flags[_flags]);\n");
|
fprintf(fp_cpp, " st->print(\"%%s\", bundle_flags[_flags]);\n");
|
||||||
fprintf(fp_cpp, " needs_comma = true;\n");
|
fprintf(fp_cpp, " needs_comma = true;\n");
|
||||||
fprintf(fp_cpp, " };\n");
|
fprintf(fp_cpp, " };\n");
|
||||||
fprintf(fp_cpp, " if (instr_count()) {\n");
|
fprintf(fp_cpp, " if (instr_count()) {\n");
|
||||||
fprintf(fp_cpp, " tty->print(\"%%s%%d instr%%s\", needs_comma ? \", \" : \"\", instr_count(), instr_count() != 1 ? \"s\" : \"\");\n");
|
fprintf(fp_cpp, " st->print(\"%%s%%d instr%%s\", needs_comma ? \", \" : \"\", instr_count(), instr_count() != 1 ? \"s\" : \"\");\n");
|
||||||
fprintf(fp_cpp, " needs_comma = true;\n");
|
fprintf(fp_cpp, " needs_comma = true;\n");
|
||||||
fprintf(fp_cpp, " };\n");
|
fprintf(fp_cpp, " };\n");
|
||||||
fprintf(fp_cpp, " uint r = resources_used();\n");
|
fprintf(fp_cpp, " uint r = resources_used();\n");
|
||||||
fprintf(fp_cpp, " if (r) {\n");
|
fprintf(fp_cpp, " if (r) {\n");
|
||||||
fprintf(fp_cpp, " tty->print(\"%%sresource%%s:\", needs_comma ? \", \" : \"\", (r & (r-1)) != 0 ? \"s\" : \"\");\n");
|
fprintf(fp_cpp, " st->print(\"%%sresource%%s:\", needs_comma ? \", \" : \"\", (r & (r-1)) != 0 ? \"s\" : \"\");\n");
|
||||||
fprintf(fp_cpp, " for (uint i = 0; i < %d; i++)\n", _pipeline->_rescount);
|
fprintf(fp_cpp, " for (uint i = 0; i < %d; i++)\n", _pipeline->_rescount);
|
||||||
fprintf(fp_cpp, " if ((r & (1 << i)) != 0)\n");
|
fprintf(fp_cpp, " if ((r & (1 << i)) != 0)\n");
|
||||||
fprintf(fp_cpp, " tty->print(\" %%s\", resource_names[i]);\n");
|
fprintf(fp_cpp, " st->print(\" %%s\", resource_names[i]);\n");
|
||||||
fprintf(fp_cpp, " needs_comma = true;\n");
|
fprintf(fp_cpp, " needs_comma = true;\n");
|
||||||
fprintf(fp_cpp, " };\n");
|
fprintf(fp_cpp, " };\n");
|
||||||
fprintf(fp_cpp, " tty->print(\"\\n\");\n");
|
fprintf(fp_cpp, " st->print(\"\\n\");\n");
|
||||||
fprintf(fp_cpp, "}\n");
|
fprintf(fp_cpp, "}\n");
|
||||||
fprintf(fp_cpp, "#endif\n");
|
fprintf(fp_cpp, "#endif\n");
|
||||||
}
|
}
|
||||||
|
@ -1048,39 +1056,6 @@ static void defineOut_RegMask(FILE *fp, const char *node, const char *regMask) {
|
||||||
node, regMask);
|
node, regMask);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan the peepmatch and output a test for each instruction
|
|
||||||
static void check_peepmatch_instruction_tree(FILE *fp, PeepMatch *pmatch, PeepConstraint *pconstraint) {
|
|
||||||
int parent = -1;
|
|
||||||
int inst_position = 0;
|
|
||||||
const char* inst_name = NULL;
|
|
||||||
int input = 0;
|
|
||||||
fprintf(fp, " // Check instruction sub-tree\n");
|
|
||||||
pmatch->reset();
|
|
||||||
for( pmatch->next_instruction( parent, inst_position, inst_name, input );
|
|
||||||
inst_name != NULL;
|
|
||||||
pmatch->next_instruction( parent, inst_position, inst_name, input ) ) {
|
|
||||||
// If this is not a placeholder
|
|
||||||
if( ! pmatch->is_placeholder() ) {
|
|
||||||
// Define temporaries 'inst#', based on parent and parent's input index
|
|
||||||
if( parent != -1 ) { // root was initialized
|
|
||||||
fprintf(fp, " inst%d = inst%d->in(%d);\n",
|
|
||||||
inst_position, parent, input);
|
|
||||||
}
|
|
||||||
|
|
||||||
// When not the root
|
|
||||||
// Test we have the correct instruction by comparing the rule
|
|
||||||
if( parent != -1 ) {
|
|
||||||
fprintf(fp, " matches = matches && ( inst%d->rule() == %s_rule );",
|
|
||||||
inst_position, inst_name);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Check that user did not try to constrain a placeholder
|
|
||||||
assert( ! pconstraint->constrains_instruction(inst_position),
|
|
||||||
"fatal(): Can not constrain a placeholder instruction");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void print_block_index(FILE *fp, int inst_position) {
|
static void print_block_index(FILE *fp, int inst_position) {
|
||||||
assert( inst_position >= 0, "Instruction number less than zero");
|
assert( inst_position >= 0, "Instruction number less than zero");
|
||||||
fprintf(fp, "block_index");
|
fprintf(fp, "block_index");
|
||||||
|
@ -1242,7 +1217,7 @@ static void check_peepconstraints(FILE *fp, FormDict &globals, PeepMatch *pmatch
|
||||||
if( left_op_index != 0 ) {
|
if( left_op_index != 0 ) {
|
||||||
assert( (left_index <= 9999) && (left_op_index <= 9999), "exceed string size");
|
assert( (left_index <= 9999) && (left_op_index <= 9999), "exceed string size");
|
||||||
// Must have index into operands
|
// Must have index into operands
|
||||||
sprintf(left_reg_index,",inst%d_idx%d", left_index, left_op_index);
|
sprintf(left_reg_index,",inst%d_idx%d", (int)left_index, left_op_index);
|
||||||
} else {
|
} else {
|
||||||
strcpy(left_reg_index, "");
|
strcpy(left_reg_index, "");
|
||||||
}
|
}
|
||||||
|
@ -1255,7 +1230,7 @@ static void check_peepconstraints(FILE *fp, FormDict &globals, PeepMatch *pmatch
|
||||||
if( right_op_index != 0 ) {
|
if( right_op_index != 0 ) {
|
||||||
assert( (right_index <= 9999) && (right_op_index <= 9999), "exceed string size");
|
assert( (right_index <= 9999) && (right_op_index <= 9999), "exceed string size");
|
||||||
// Must have index into operands
|
// Must have index into operands
|
||||||
sprintf(right_reg_index,",inst%d_idx%d", right_index, right_op_index);
|
sprintf(right_reg_index,",inst%d_idx%d", (int)right_index, right_op_index);
|
||||||
} else {
|
} else {
|
||||||
strcpy(right_reg_index, "");
|
strcpy(right_reg_index, "");
|
||||||
}
|
}
|
||||||
|
@ -1645,7 +1620,7 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
|
||||||
new_pos = new_inst->operand_position(parameter,Component::USE);
|
new_pos = new_inst->operand_position(parameter,Component::USE);
|
||||||
exp_pos += node->num_opnds();
|
exp_pos += node->num_opnds();
|
||||||
// If there is no use of the created operand, just skip it
|
// If there is no use of the created operand, just skip it
|
||||||
if (new_pos != -1) {
|
if (new_pos != NameList::Not_in_list) {
|
||||||
//Copy the operand from the original made above
|
//Copy the operand from the original made above
|
||||||
fprintf(fp," n%d->set_opnd_array(%d, op%d->clone(C)); // %s\n",
|
fprintf(fp," n%d->set_opnd_array(%d, op%d->clone(C)); // %s\n",
|
||||||
cnt, new_pos, exp_pos-node->num_opnds(), opid);
|
cnt, new_pos, exp_pos-node->num_opnds(), opid);
|
||||||
|
@ -1789,7 +1764,8 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
|
||||||
// Build mapping from num_edges to local variables
|
// Build mapping from num_edges to local variables
|
||||||
fprintf(fp," unsigned num0 = 0;\n");
|
fprintf(fp," unsigned num0 = 0;\n");
|
||||||
for( i = 1; i < cur_num_opnds; i++ ) {
|
for( i = 1; i < cur_num_opnds; i++ ) {
|
||||||
fprintf(fp," unsigned num%d = opnd_array(%d)->num_edges();\n",i,i);
|
fprintf(fp," unsigned num%d = opnd_array(%d)->num_edges();",i,i);
|
||||||
|
fprintf(fp, " \t// %s\n", node->opnd_ident(i));
|
||||||
}
|
}
|
||||||
// Build a mapping from operand index to input edges
|
// Build a mapping from operand index to input edges
|
||||||
fprintf(fp," unsigned idx0 = oper_input_base();\n");
|
fprintf(fp," unsigned idx0 = oper_input_base();\n");
|
||||||
|
@ -1934,6 +1910,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track necessary state when identifying a replacement variable
|
// Track necessary state when identifying a replacement variable
|
||||||
|
// @arg rep_var: The formal parameter of the encoding.
|
||||||
void update_state(const char *rep_var) {
|
void update_state(const char *rep_var) {
|
||||||
// A replacement variable or one of its subfields
|
// A replacement variable or one of its subfields
|
||||||
// Obtain replacement variable from list
|
// Obtain replacement variable from list
|
||||||
|
@ -1955,7 +1932,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Lookup its position in parameter list
|
// Lookup its position in (formal) parameter list of encoding
|
||||||
int param_no = _encoding.rep_var_index(rep_var);
|
int param_no = _encoding.rep_var_index(rep_var);
|
||||||
if ( param_no == -1 ) {
|
if ( param_no == -1 ) {
|
||||||
_AD.syntax_err( _encoding._linenum,
|
_AD.syntax_err( _encoding._linenum,
|
||||||
|
@ -1964,6 +1941,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lookup the corresponding ins_encode parameter
|
// Lookup the corresponding ins_encode parameter
|
||||||
|
// This is the argument (actual parameter) to the encoding.
|
||||||
const char *inst_rep_var = _ins_encode.rep_var_name(_inst, param_no);
|
const char *inst_rep_var = _ins_encode.rep_var_name(_inst, param_no);
|
||||||
if (inst_rep_var == NULL) {
|
if (inst_rep_var == NULL) {
|
||||||
_AD.syntax_err( _ins_encode._linenum,
|
_AD.syntax_err( _ins_encode._linenum,
|
||||||
|
@ -2329,6 +2307,7 @@ private:
|
||||||
// Add parameter for index position, if not result operand
|
// Add parameter for index position, if not result operand
|
||||||
if( _operand_idx != 0 ) fprintf(_fp,",idx%d", _operand_idx);
|
if( _operand_idx != 0 ) fprintf(_fp,",idx%d", _operand_idx);
|
||||||
fprintf(_fp,")");
|
fprintf(_fp,")");
|
||||||
|
fprintf(_fp, "/* %s */", _operand_name);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert( _reg_status == LITERAL_OUTPUT, "should have output register literal in emit_rep_var");
|
assert( _reg_status == LITERAL_OUTPUT, "should have output register literal in emit_rep_var");
|
||||||
|
@ -2368,7 +2347,7 @@ private:
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
assert( _constant_status == LITERAL_OUTPUT, "should have output constant literal in emit_rep_var");
|
assert( _constant_status == LITERAL_OUTPUT, "should have output constant literal in emit_rep_var");
|
||||||
// Cosntant literal has already been sent to output file, nothing more needed
|
// Constant literal has already been sent to output file, nothing more needed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( strcmp(rep_var,"$disp") == 0 ) {
|
else if ( strcmp(rep_var,"$disp") == 0 ) {
|
||||||
|
@ -2387,6 +2366,8 @@ private:
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
printf("emit_field: %s\n",rep_var);
|
printf("emit_field: %s\n",rep_var);
|
||||||
|
globalAD->syntax_err(_inst._linenum, "Unknown replacement variable %s in format statement of %s.",
|
||||||
|
rep_var, _inst._ident);
|
||||||
assert( false, "UnImplemented()");
|
assert( false, "UnImplemented()");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2484,14 +2465,14 @@ void ArchDesc::defineSize(FILE *fp, InstructForm &inst) {
|
||||||
|
|
||||||
//(1)
|
//(1)
|
||||||
// Output instruction's emit prototype
|
// Output instruction's emit prototype
|
||||||
fprintf(fp,"uint %sNode::size(PhaseRegAlloc *ra_) const {\n",
|
fprintf(fp,"uint %sNode::size(PhaseRegAlloc *ra_) const {\n",
|
||||||
inst._ident);
|
inst._ident);
|
||||||
|
|
||||||
fprintf(fp, " assert(VerifyOops || MachNode::size(ra_) <= %s, \"bad fixed size\");\n", inst._size);
|
fprintf(fp, " assert(VerifyOops || MachNode::size(ra_) <= %s, \"bad fixed size\");\n", inst._size);
|
||||||
|
|
||||||
//(2)
|
//(2)
|
||||||
// Print the size
|
// Print the size
|
||||||
fprintf(fp, " return (VerifyOops ? MachNode::size(ra_) : %s);\n", inst._size);
|
fprintf(fp, " return (VerifyOops ? MachNode::size(ra_) : %s);\n", inst._size);
|
||||||
|
|
||||||
// (3) and (4)
|
// (3) and (4)
|
||||||
fprintf(fp,"}\n");
|
fprintf(fp,"}\n");
|
||||||
|
@ -2579,7 +2560,7 @@ void ArchDesc::defineEmit(FILE* fp, InstructForm& inst) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// (3) and (4)
|
// (3) and (4)
|
||||||
fprintf(fp, "}\n");
|
fprintf(fp, "}\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// defineEvalConstant ---------------------------------------------------------
|
// defineEvalConstant ---------------------------------------------------------
|
||||||
|
@ -2727,12 +2708,12 @@ static void defineIn_RegMask(FILE *fp, FormDict &globals, OperandForm &oper) {
|
||||||
// (2) }
|
// (2) }
|
||||||
//
|
//
|
||||||
static void defineClone(FILE *fp, FormDict &globalNames, OperandForm &oper) {
|
static void defineClone(FILE *fp, FormDict &globalNames, OperandForm &oper) {
|
||||||
fprintf(fp,"MachOper *%sOper::clone(Compile* C) const {\n", oper._ident);
|
fprintf(fp,"MachOper *%sOper::clone(Compile* C) const {\n", oper._ident);
|
||||||
// Check for constants that need to be copied over
|
// Check for constants that need to be copied over
|
||||||
const int num_consts = oper.num_consts(globalNames);
|
const int num_consts = oper.num_consts(globalNames);
|
||||||
const bool is_ideal_bool = oper.is_ideal_bool();
|
const bool is_ideal_bool = oper.is_ideal_bool();
|
||||||
if( (num_consts > 0) ) {
|
if( (num_consts > 0) ) {
|
||||||
fprintf(fp," return new (C) %sOper(", oper._ident);
|
fprintf(fp," return new (C) %sOper(", oper._ident);
|
||||||
// generate parameters for constants
|
// generate parameters for constants
|
||||||
int i = 0;
|
int i = 0;
|
||||||
fprintf(fp,"_c%d", i);
|
fprintf(fp,"_c%d", i);
|
||||||
|
@ -2744,21 +2725,12 @@ static void defineClone(FILE *fp, FormDict &globalNames, OperandForm &oper) {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assert( num_consts == 0, "Currently support zero or one constant per operand clone function");
|
assert( num_consts == 0, "Currently support zero or one constant per operand clone function");
|
||||||
fprintf(fp," return new (C) %sOper();\n", oper._ident);
|
fprintf(fp," return new (C) %sOper();\n", oper._ident);
|
||||||
}
|
}
|
||||||
// finish method
|
// finish method
|
||||||
fprintf(fp,"}\n");
|
fprintf(fp,"}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void define_hash(FILE *fp, char *operand) {
|
|
||||||
fprintf(fp,"uint %sOper::hash() const { return 5; }\n", operand);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void define_cmp(FILE *fp, char *operand) {
|
|
||||||
fprintf(fp,"uint %sOper::cmp( const MachOper &oper ) const { return opcode() == oper.opcode(); }\n", operand);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Helper functions for bug 4796752, abstracted with minimal modification
|
// Helper functions for bug 4796752, abstracted with minimal modification
|
||||||
// from define_oper_interface()
|
// from define_oper_interface()
|
||||||
OperandForm *rep_var_to_operand(const char *encoding, OperandForm &oper, FormDict &globals) {
|
OperandForm *rep_var_to_operand(const char *encoding, OperandForm &oper, FormDict &globals) {
|
||||||
|
@ -2852,14 +2824,14 @@ void ArchDesc::define_oper_interface(FILE *fp, OperandForm &oper, FormDict &glob
|
||||||
} else if ( (strcmp(name,"disp") == 0) ) {
|
} else if ( (strcmp(name,"disp") == 0) ) {
|
||||||
fprintf(fp,"(PhaseRegAlloc *ra_, const Node *node, int idx) const { \n");
|
fprintf(fp,"(PhaseRegAlloc *ra_, const Node *node, int idx) const { \n");
|
||||||
} else {
|
} else {
|
||||||
fprintf(fp,"() const { ");
|
fprintf(fp,"() const { \n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for hexadecimal value OR replacement variable
|
// Check for hexadecimal value OR replacement variable
|
||||||
if( *encoding == '$' ) {
|
if( *encoding == '$' ) {
|
||||||
// Replacement variable
|
// Replacement variable
|
||||||
const char *rep_var = encoding + 1;
|
const char *rep_var = encoding + 1;
|
||||||
fprintf(fp,"// Replacement variable: %s\n", encoding+1);
|
fprintf(fp," // Replacement variable: %s\n", encoding+1);
|
||||||
// Lookup replacement variable, rep_var, in operand's component list
|
// Lookup replacement variable, rep_var, in operand's component list
|
||||||
const Component *comp = oper._components.search(rep_var);
|
const Component *comp = oper._components.search(rep_var);
|
||||||
assert( comp != NULL, "Replacement variable not found in components");
|
assert( comp != NULL, "Replacement variable not found in components");
|
||||||
|
@ -2880,10 +2852,10 @@ void ArchDesc::define_oper_interface(FILE *fp, OperandForm &oper, FormDict &glob
|
||||||
} else if ( op->ideal_to_sReg_type(op->_ident) != Form::none ) {
|
} else if ( op->ideal_to_sReg_type(op->_ident) != Form::none ) {
|
||||||
// StackSlot for an sReg comes either from input node or from self, when idx==0
|
// StackSlot for an sReg comes either from input node or from self, when idx==0
|
||||||
fprintf(fp," if( idx != 0 ) {\n");
|
fprintf(fp," if( idx != 0 ) {\n");
|
||||||
fprintf(fp," // Access register number for input operand\n");
|
fprintf(fp," // Access stack offset (register number) for input operand\n");
|
||||||
fprintf(fp," return ra_->reg2offset(ra_->get_reg_first(node->in(idx)));/* sReg */\n");
|
fprintf(fp," return ra_->reg2offset(ra_->get_reg_first(node->in(idx)));/* sReg */\n");
|
||||||
fprintf(fp," }\n");
|
fprintf(fp," }\n");
|
||||||
fprintf(fp," // Access register number from myself\n");
|
fprintf(fp," // Access stack offset (register number) from myself\n");
|
||||||
fprintf(fp," return ra_->reg2offset(ra_->get_reg_first(node));/* sReg */\n");
|
fprintf(fp," return ra_->reg2offset(ra_->get_reg_first(node));/* sReg */\n");
|
||||||
} else if (op->_matrule && op->_matrule->is_base_constant(globals)) {
|
} else if (op->_matrule && op->_matrule->is_base_constant(globals)) {
|
||||||
// Constant
|
// Constant
|
||||||
|
@ -2900,7 +2872,7 @@ void ArchDesc::define_oper_interface(FILE *fp, OperandForm &oper, FormDict &glob
|
||||||
}
|
}
|
||||||
else if( *encoding == '0' && *(encoding+1) == 'x' ) {
|
else if( *encoding == '0' && *(encoding+1) == 'x' ) {
|
||||||
// Hex value
|
// Hex value
|
||||||
fprintf(fp,"return %s;", encoding);
|
fprintf(fp," return %s;\n", encoding);
|
||||||
} else {
|
} else {
|
||||||
assert( false, "Do not support octal or decimal encode constants");
|
assert( false, "Do not support octal or decimal encode constants");
|
||||||
}
|
}
|
||||||
|
@ -3133,8 +3105,8 @@ void ArchDesc::defineClasses(FILE *fp) {
|
||||||
// Output the definition for number of relocation entries
|
// Output the definition for number of relocation entries
|
||||||
uint reloc_size = instr->reloc(_globalNames);
|
uint reloc_size = instr->reloc(_globalNames);
|
||||||
if ( reloc_size != 0 ) {
|
if ( reloc_size != 0 ) {
|
||||||
fprintf(fp,"int %sNode::reloc() const {\n", instr->_ident);
|
fprintf(fp,"int %sNode::reloc() const {\n", instr->_ident);
|
||||||
fprintf(fp, " return %d;\n", reloc_size );
|
fprintf(fp," return %d;\n", reloc_size);
|
||||||
fprintf(fp,"}\n");
|
fprintf(fp,"}\n");
|
||||||
fprintf(fp,"\n");
|
fprintf(fp,"\n");
|
||||||
}
|
}
|
||||||
|
@ -3241,7 +3213,7 @@ void ArchDesc::defineClasses(FILE *fp) {
|
||||||
class OutputReduceOp : public OutputMap {
|
class OutputReduceOp : public OutputMap {
|
||||||
public:
|
public:
|
||||||
OutputReduceOp(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
|
OutputReduceOp(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
|
||||||
: OutputMap(hpp, cpp, globals, AD) {};
|
: OutputMap(hpp, cpp, globals, AD, "reduceOp") {};
|
||||||
|
|
||||||
void declaration() { fprintf(_hpp, "extern const int reduceOp[];\n"); }
|
void declaration() { fprintf(_hpp, "extern const int reduceOp[];\n"); }
|
||||||
void definition() { fprintf(_cpp, "const int reduceOp[] = {\n"); }
|
void definition() { fprintf(_cpp, "const int reduceOp[] = {\n"); }
|
||||||
|
@ -3276,7 +3248,7 @@ public:
|
||||||
class OutputLeftOp : public OutputMap {
|
class OutputLeftOp : public OutputMap {
|
||||||
public:
|
public:
|
||||||
OutputLeftOp(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
|
OutputLeftOp(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
|
||||||
: OutputMap(hpp, cpp, globals, AD) {};
|
: OutputMap(hpp, cpp, globals, AD, "leftOp") {};
|
||||||
|
|
||||||
void declaration() { fprintf(_hpp, "extern const int leftOp[];\n"); }
|
void declaration() { fprintf(_hpp, "extern const int leftOp[];\n"); }
|
||||||
void definition() { fprintf(_cpp, "const int leftOp[] = {\n"); }
|
void definition() { fprintf(_cpp, "const int leftOp[] = {\n"); }
|
||||||
|
@ -3306,7 +3278,7 @@ public:
|
||||||
class OutputRightOp : public OutputMap {
|
class OutputRightOp : public OutputMap {
|
||||||
public:
|
public:
|
||||||
OutputRightOp(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
|
OutputRightOp(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
|
||||||
: OutputMap(hpp, cpp, globals, AD) {};
|
: OutputMap(hpp, cpp, globals, AD, "rightOp") {};
|
||||||
|
|
||||||
void declaration() { fprintf(_hpp, "extern const int rightOp[];\n"); }
|
void declaration() { fprintf(_hpp, "extern const int rightOp[];\n"); }
|
||||||
void definition() { fprintf(_cpp, "const int rightOp[] = {\n"); }
|
void definition() { fprintf(_cpp, "const int rightOp[] = {\n"); }
|
||||||
|
@ -3336,11 +3308,11 @@ public:
|
||||||
class OutputRuleName : public OutputMap {
|
class OutputRuleName : public OutputMap {
|
||||||
public:
|
public:
|
||||||
OutputRuleName(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
|
OutputRuleName(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
|
||||||
: OutputMap(hpp, cpp, globals, AD) {};
|
: OutputMap(hpp, cpp, globals, AD, "ruleName") {};
|
||||||
|
|
||||||
void declaration() { fprintf(_hpp, "extern const char *ruleName[];\n"); }
|
void declaration() { fprintf(_hpp, "extern const char *ruleName[];\n"); }
|
||||||
void definition() { fprintf(_cpp, "const char *ruleName[] = {\n"); }
|
void definition() { fprintf(_cpp, "const char *ruleName[] = {\n"); }
|
||||||
void closing() { fprintf(_cpp, " \"no trailing comma\"\n");
|
void closing() { fprintf(_cpp, " \"invalid rule name\" // no trailing comma\n");
|
||||||
OutputMap::closing();
|
OutputMap::closing();
|
||||||
}
|
}
|
||||||
void map(OpClassForm &opc) { fprintf(_cpp, " \"%s\"", _AD.machOperEnum(opc._ident) ); }
|
void map(OpClassForm &opc) { fprintf(_cpp, " \"%s\"", _AD.machOperEnum(opc._ident) ); }
|
||||||
|
@ -3354,7 +3326,7 @@ public:
|
||||||
class OutputSwallowed : public OutputMap {
|
class OutputSwallowed : public OutputMap {
|
||||||
public:
|
public:
|
||||||
OutputSwallowed(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
|
OutputSwallowed(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
|
||||||
: OutputMap(hpp, cpp, globals, AD) {};
|
: OutputMap(hpp, cpp, globals, AD, "swallowed") {};
|
||||||
|
|
||||||
void declaration() { fprintf(_hpp, "extern const bool swallowed[];\n"); }
|
void declaration() { fprintf(_hpp, "extern const bool swallowed[];\n"); }
|
||||||
void definition() { fprintf(_cpp, "const bool swallowed[] = {\n"); }
|
void definition() { fprintf(_cpp, "const bool swallowed[] = {\n"); }
|
||||||
|
@ -3375,7 +3347,7 @@ public:
|
||||||
class OutputInstChainRule : public OutputMap {
|
class OutputInstChainRule : public OutputMap {
|
||||||
public:
|
public:
|
||||||
OutputInstChainRule(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
|
OutputInstChainRule(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
|
||||||
: OutputMap(hpp, cpp, globals, AD) {};
|
: OutputMap(hpp, cpp, globals, AD, "instruction_chain_rule") {};
|
||||||
|
|
||||||
void declaration() { fprintf(_hpp, "extern const bool instruction_chain_rule[];\n"); }
|
void declaration() { fprintf(_hpp, "extern const bool instruction_chain_rule[];\n"); }
|
||||||
void definition() { fprintf(_cpp, "const bool instruction_chain_rule[] = {\n"); }
|
void definition() { fprintf(_cpp, "const bool instruction_chain_rule[] = {\n"); }
|
||||||
|
@ -3416,7 +3388,7 @@ void ArchDesc::build_map(OutputMap &map) {
|
||||||
if ( op->ideal_only() ) continue;
|
if ( op->ideal_only() ) continue;
|
||||||
|
|
||||||
// Generate the entry for this opcode
|
// Generate the entry for this opcode
|
||||||
map.map(*op); fprintf(fp_cpp, ", // %d\n", idx);
|
fprintf(fp_cpp, " /* %4d */", idx); map.map(*op); fprintf(fp_cpp, ",\n");
|
||||||
++idx;
|
++idx;
|
||||||
};
|
};
|
||||||
fprintf(fp_cpp, " // last operand\n");
|
fprintf(fp_cpp, " // last operand\n");
|
||||||
|
@ -3425,7 +3397,7 @@ void ArchDesc::build_map(OutputMap &map) {
|
||||||
map.record_position(OutputMap::BEGIN_OPCLASSES, idx );
|
map.record_position(OutputMap::BEGIN_OPCLASSES, idx );
|
||||||
_opclass.reset();
|
_opclass.reset();
|
||||||
for(; (opc = (OpClassForm*)_opclass.iter()) != NULL; ) {
|
for(; (opc = (OpClassForm*)_opclass.iter()) != NULL; ) {
|
||||||
map.map(*opc); fprintf(fp_cpp, ", // %d\n", idx);
|
fprintf(fp_cpp, " /* %4d */", idx); map.map(*opc); fprintf(fp_cpp, ",\n");
|
||||||
++idx;
|
++idx;
|
||||||
};
|
};
|
||||||
fprintf(fp_cpp, " // last operand class\n");
|
fprintf(fp_cpp, " // last operand class\n");
|
||||||
|
@ -3435,7 +3407,7 @@ void ArchDesc::build_map(OutputMap &map) {
|
||||||
_internalOpNames.reset();
|
_internalOpNames.reset();
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
for(; (name = (char *)_internalOpNames.iter()) != NULL; ) {
|
for(; (name = (char *)_internalOpNames.iter()) != NULL; ) {
|
||||||
map.map(name); fprintf(fp_cpp, ", // %d\n", idx);
|
fprintf(fp_cpp, " /* %4d */", idx); map.map(name); fprintf(fp_cpp, ",\n");
|
||||||
++idx;
|
++idx;
|
||||||
};
|
};
|
||||||
fprintf(fp_cpp, " // last internally defined operand\n");
|
fprintf(fp_cpp, " // last internally defined operand\n");
|
||||||
|
@ -3453,7 +3425,7 @@ void ArchDesc::build_map(OutputMap &map) {
|
||||||
if ( ! inst->is_simple_chain_rule(_globalNames) ) continue;
|
if ( ! inst->is_simple_chain_rule(_globalNames) ) continue;
|
||||||
if ( inst->rematerialize(_globalNames, get_registers()) ) continue;
|
if ( inst->rematerialize(_globalNames, get_registers()) ) continue;
|
||||||
|
|
||||||
map.map(*inst); fprintf(fp_cpp, ", // %d\n", idx);
|
fprintf(fp_cpp, " /* %4d */", idx); map.map(*inst); fprintf(fp_cpp, ",\n");
|
||||||
++idx;
|
++idx;
|
||||||
};
|
};
|
||||||
map.record_position(OutputMap::BEGIN_REMATERIALIZE, idx );
|
map.record_position(OutputMap::BEGIN_REMATERIALIZE, idx );
|
||||||
|
@ -3464,7 +3436,7 @@ void ArchDesc::build_map(OutputMap &map) {
|
||||||
if ( ! inst->is_simple_chain_rule(_globalNames) ) continue;
|
if ( ! inst->is_simple_chain_rule(_globalNames) ) continue;
|
||||||
if ( ! inst->rematerialize(_globalNames, get_registers()) ) continue;
|
if ( ! inst->rematerialize(_globalNames, get_registers()) ) continue;
|
||||||
|
|
||||||
map.map(*inst); fprintf(fp_cpp, ", // %d\n", idx);
|
fprintf(fp_cpp, " /* %4d */", idx); map.map(*inst); fprintf(fp_cpp, ",\n");
|
||||||
++idx;
|
++idx;
|
||||||
};
|
};
|
||||||
map.record_position(OutputMap::END_INST_CHAIN_RULES, idx );
|
map.record_position(OutputMap::END_INST_CHAIN_RULES, idx );
|
||||||
|
@ -3478,7 +3450,7 @@ void ArchDesc::build_map(OutputMap &map) {
|
||||||
if ( inst->is_simple_chain_rule(_globalNames) ) continue;
|
if ( inst->is_simple_chain_rule(_globalNames) ) continue;
|
||||||
if ( ! inst->rematerialize(_globalNames, get_registers()) ) continue;
|
if ( ! inst->rematerialize(_globalNames, get_registers()) ) continue;
|
||||||
|
|
||||||
map.map(*inst); fprintf(fp_cpp, ", // %d\n", idx);
|
fprintf(fp_cpp, " /* %4d */", idx); map.map(*inst); fprintf(fp_cpp, ",\n");
|
||||||
++idx;
|
++idx;
|
||||||
};
|
};
|
||||||
map.record_position(OutputMap::END_REMATERIALIZE, idx );
|
map.record_position(OutputMap::END_REMATERIALIZE, idx );
|
||||||
|
@ -3489,7 +3461,7 @@ void ArchDesc::build_map(OutputMap &map) {
|
||||||
if ( inst->is_simple_chain_rule(_globalNames) ) continue;
|
if ( inst->is_simple_chain_rule(_globalNames) ) continue;
|
||||||
if ( inst->rematerialize(_globalNames, get_registers()) ) continue;
|
if ( inst->rematerialize(_globalNames, get_registers()) ) continue;
|
||||||
|
|
||||||
map.map(*inst); fprintf(fp_cpp, ", // %d\n", idx);
|
fprintf(fp_cpp, " /* %4d */", idx); map.map(*inst); fprintf(fp_cpp, ",\n");
|
||||||
++idx;
|
++idx;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -3571,7 +3543,7 @@ void ArchDesc::buildReduceMaps(FILE *fp_hpp, FILE *fp_cpp) {
|
||||||
next = _register->iter_RegDefs();
|
next = _register->iter_RegDefs();
|
||||||
char policy = reg_save_policy(rdef->_callconv);
|
char policy = reg_save_policy(rdef->_callconv);
|
||||||
const char *comma = (next != NULL) ? "," : " // no trailing comma";
|
const char *comma = (next != NULL) ? "," : " // no trailing comma";
|
||||||
fprintf(fp_cpp, " '%c'%s\n", policy, comma);
|
fprintf(fp_cpp, " '%c'%s // %s\n", policy, comma, rdef->_regname);
|
||||||
}
|
}
|
||||||
fprintf(fp_cpp, "};\n\n");
|
fprintf(fp_cpp, "};\n\n");
|
||||||
|
|
||||||
|
@ -3583,7 +3555,7 @@ void ArchDesc::buildReduceMaps(FILE *fp_hpp, FILE *fp_cpp) {
|
||||||
next = _register->iter_RegDefs();
|
next = _register->iter_RegDefs();
|
||||||
char policy = reg_save_policy(rdef->_c_conv);
|
char policy = reg_save_policy(rdef->_c_conv);
|
||||||
const char *comma = (next != NULL) ? "," : " // no trailing comma";
|
const char *comma = (next != NULL) ? "," : " // no trailing comma";
|
||||||
fprintf(fp_cpp, " '%c'%s\n", policy, comma);
|
fprintf(fp_cpp, " '%c'%s // %s\n", policy, comma, rdef->_regname);
|
||||||
}
|
}
|
||||||
fprintf(fp_cpp, "};\n\n");
|
fprintf(fp_cpp, "};\n\n");
|
||||||
|
|
||||||
|
@ -3794,7 +3766,7 @@ void ArchDesc::buildMachNode(FILE *fp_cpp, InstructForm *inst, const char *inden
|
||||||
// For each operand not in the match rule, call MachOperGenerator
|
// For each operand not in the match rule, call MachOperGenerator
|
||||||
// with the enum for the opcode that needs to be built.
|
// with the enum for the opcode that needs to be built.
|
||||||
ComponentList clist = inst->_components;
|
ComponentList clist = inst->_components;
|
||||||
int index = clist.operand_position(comp->_name, comp->_usedef);
|
int index = clist.operand_position(comp->_name, comp->_usedef, inst);
|
||||||
const char *opcode = machOperEnum(comp->_type);
|
const char *opcode = machOperEnum(comp->_type);
|
||||||
fprintf(fp_cpp, "%s node->set_opnd_array(%d, ", indent, index);
|
fprintf(fp_cpp, "%s node->set_opnd_array(%d, ", indent, index);
|
||||||
fprintf(fp_cpp, "MachOperGenerator(%s, C));\n", opcode);
|
fprintf(fp_cpp, "MachOperGenerator(%s, C));\n", opcode);
|
||||||
|
@ -3989,7 +3961,7 @@ void ArchDesc::buildMachNodeGenerator(FILE *fp_cpp) {
|
||||||
fprintf(fp_cpp, " case %s_rule:", opClass);
|
fprintf(fp_cpp, " case %s_rule:", opClass);
|
||||||
|
|
||||||
// Start local scope
|
// Start local scope
|
||||||
fprintf(fp_cpp, " {\n");
|
fprintf(fp_cpp, " {\n");
|
||||||
// Generate code to construct the new MachNode
|
// Generate code to construct the new MachNode
|
||||||
buildMachNode(fp_cpp, inst, " ");
|
buildMachNode(fp_cpp, inst, " ");
|
||||||
// Return result and exit scope
|
// Return result and exit scope
|
||||||
|
@ -4139,6 +4111,9 @@ static int PrintAdlcCisc = 0;
|
||||||
// Get info for the CISC_oracle and MachNode::cisc_version()
|
// Get info for the CISC_oracle and MachNode::cisc_version()
|
||||||
void ArchDesc::identify_cisc_spill_instructions() {
|
void ArchDesc::identify_cisc_spill_instructions() {
|
||||||
|
|
||||||
|
if (_frame == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
// Find the user-defined operand for cisc-spilling
|
// Find the user-defined operand for cisc-spilling
|
||||||
if( _frame->_cisc_spilling_operand_name != NULL ) {
|
if( _frame->_cisc_spilling_operand_name != NULL ) {
|
||||||
const Form *form = _globalNames[_frame->_cisc_spilling_operand_name];
|
const Form *form = _globalNames[_frame->_cisc_spilling_operand_name];
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
// output_h.cpp - Class HPP file output routines for architecture definition
|
// output_h.cpp - Class HPP file output routines for architecture definition
|
||||||
#include "adlc.hpp"
|
#include "adlc.hpp"
|
||||||
|
|
||||||
|
// The comment delimiter used in format statements after assembler instructions.
|
||||||
|
#define commentSeperator "!"
|
||||||
|
|
||||||
// Generate the #define that describes the number of registers.
|
// Generate the #define that describes the number of registers.
|
||||||
static void defineRegCount(FILE *fp, RegisterForm *registers) {
|
static void defineRegCount(FILE *fp, RegisterForm *registers) {
|
||||||
|
@ -79,10 +81,15 @@ void ArchDesc::buildMachRegisterNumbers(FILE *fp_hpp) {
|
||||||
_register->reset_RegDefs();
|
_register->reset_RegDefs();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while( (reg_def = _register->iter_RegDefs()) != NULL ) {
|
while( (reg_def = _register->iter_RegDefs()) != NULL ) {
|
||||||
fprintf(fp_hpp," %s_num,\t\t// %d\n", reg_def->_regname, i++);
|
fprintf(fp_hpp," %s_num,", reg_def->_regname);
|
||||||
|
for (int j = 0; j < 20-(int)strlen(reg_def->_regname); j++) fprintf(fp_hpp, " ");
|
||||||
|
fprintf(fp_hpp," // enum %3d, regnum %3d, reg encode %3s\n",
|
||||||
|
i++,
|
||||||
|
reg_def->register_num(),
|
||||||
|
reg_def->register_encode());
|
||||||
}
|
}
|
||||||
// Finish defining enumeration
|
// Finish defining enumeration
|
||||||
fprintf(fp_hpp, " _last_Mach_Reg\t// %d\n", i);
|
fprintf(fp_hpp, " _last_Mach_Reg // %d\n", i);
|
||||||
fprintf(fp_hpp, "};\n");
|
fprintf(fp_hpp, "};\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,13 +128,24 @@ void ArchDesc::buildMachRegisterEncodes(FILE *fp_hpp) {
|
||||||
fprintf(fp_hpp, "// in the order of occurrence in the alloc_class(es).\n");
|
fprintf(fp_hpp, "// in the order of occurrence in the alloc_class(es).\n");
|
||||||
fprintf(fp_hpp, "enum MachRegisterEncodes {\n");
|
fprintf(fp_hpp, "enum MachRegisterEncodes {\n");
|
||||||
|
|
||||||
|
// Find max enum string length.
|
||||||
|
size_t maxlen = 0;
|
||||||
|
_register->reset_RegDefs();
|
||||||
|
reg_def = _register->iter_RegDefs();
|
||||||
|
while (reg_def != NULL) {
|
||||||
|
size_t len = strlen(reg_def->_regname);
|
||||||
|
if (len > maxlen) maxlen = len;
|
||||||
|
reg_def = _register->iter_RegDefs();
|
||||||
|
}
|
||||||
|
|
||||||
// Output the register encoding for each register in the allocation classes
|
// Output the register encoding for each register in the allocation classes
|
||||||
_register->reset_RegDefs();
|
_register->reset_RegDefs();
|
||||||
reg_def_next = _register->iter_RegDefs();
|
reg_def_next = _register->iter_RegDefs();
|
||||||
while( (reg_def = reg_def_next) != NULL ) {
|
while( (reg_def = reg_def_next) != NULL ) {
|
||||||
reg_def_next = _register->iter_RegDefs();
|
reg_def_next = _register->iter_RegDefs();
|
||||||
fprintf(fp_hpp," %s_enc = %s%s\n",
|
fprintf(fp_hpp," %s_enc", reg_def->_regname);
|
||||||
reg_def->_regname, reg_def->register_encode(), reg_def_next == NULL? "" : "," );
|
for (size_t i = strlen(reg_def->_regname); i < maxlen; i++) fprintf(fp_hpp, " ");
|
||||||
|
fprintf(fp_hpp," = %3s%s\n", reg_def->register_encode(), reg_def_next == NULL? "" : "," );
|
||||||
}
|
}
|
||||||
// Finish defining enumeration
|
// Finish defining enumeration
|
||||||
fprintf(fp_hpp, "};\n");
|
fprintf(fp_hpp, "};\n");
|
||||||
|
@ -177,14 +195,6 @@ static void in_RegMask(FILE *fp) {
|
||||||
fprintf(fp," virtual const RegMask *in_RegMask(int index) const;\n");
|
fprintf(fp," virtual const RegMask *in_RegMask(int index) const;\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void declare_hash(FILE *fp) {
|
|
||||||
fprintf(fp," virtual uint hash() const;\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void declare_cmp(FILE *fp) {
|
|
||||||
fprintf(fp," virtual uint cmp( const MachOper &oper ) const;\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void declareConstStorage(FILE *fp, FormDict &globals, OperandForm *oper) {
|
static void declareConstStorage(FILE *fp, FormDict &globals, OperandForm *oper) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
Component *comp;
|
Component *comp;
|
||||||
|
@ -372,18 +382,19 @@ static void defineConstructor(FILE *fp, const char *name, uint num_consts,
|
||||||
static void defineCCodeDump(OperandForm* oper, FILE *fp, int i) {
|
static void defineCCodeDump(OperandForm* oper, FILE *fp, int i) {
|
||||||
assert(oper != NULL, "what");
|
assert(oper != NULL, "what");
|
||||||
CondInterface* cond = oper->_interface->is_CondInterface();
|
CondInterface* cond = oper->_interface->is_CondInterface();
|
||||||
fprintf(fp, " if( _c%d == BoolTest::eq ) st->print(\"%s\");\n",i,cond->_equal_format);
|
fprintf(fp, " if( _c%d == BoolTest::eq ) st->print(\"%s\");\n",i,cond->_equal_format);
|
||||||
fprintf(fp, " else if( _c%d == BoolTest::ne ) st->print(\"%s\");\n",i,cond->_not_equal_format);
|
fprintf(fp, " else if( _c%d == BoolTest::ne ) st->print(\"%s\");\n",i,cond->_not_equal_format);
|
||||||
fprintf(fp, " else if( _c%d == BoolTest::le ) st->print(\"%s\");\n",i,cond->_less_equal_format);
|
fprintf(fp, " else if( _c%d == BoolTest::le ) st->print(\"%s\");\n",i,cond->_less_equal_format);
|
||||||
fprintf(fp, " else if( _c%d == BoolTest::ge ) st->print(\"%s\");\n",i,cond->_greater_equal_format);
|
fprintf(fp, " else if( _c%d == BoolTest::ge ) st->print(\"%s\");\n",i,cond->_greater_equal_format);
|
||||||
fprintf(fp, " else if( _c%d == BoolTest::lt ) st->print(\"%s\");\n",i,cond->_less_format);
|
fprintf(fp, " else if( _c%d == BoolTest::lt ) st->print(\"%s\");\n",i,cond->_less_format);
|
||||||
fprintf(fp, " else if( _c%d == BoolTest::gt ) st->print(\"%s\");\n",i,cond->_greater_format);
|
fprintf(fp, " else if( _c%d == BoolTest::gt ) st->print(\"%s\");\n",i,cond->_greater_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output code that dumps constant values, increment "i" if type is constant
|
// Output code that dumps constant values, increment "i" if type is constant
|
||||||
static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i, OperandForm* oper) {
|
static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i, OperandForm* oper) {
|
||||||
if (!strcmp(ideal_type, "ConI")) {
|
if (!strcmp(ideal_type, "ConI")) {
|
||||||
fprintf(fp," st->print(\"#%%d\", _c%d);\n", i);
|
fprintf(fp," st->print(\"#%%d\", _c%d);\n", i);
|
||||||
|
fprintf(fp," st->print(\"/0x%%08x\", _c%d);\n", i);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
else if (!strcmp(ideal_type, "ConP")) {
|
else if (!strcmp(ideal_type, "ConP")) {
|
||||||
|
@ -400,14 +411,19 @@ static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i, Operand
|
||||||
}
|
}
|
||||||
else if (!strcmp(ideal_type, "ConL")) {
|
else if (!strcmp(ideal_type, "ConL")) {
|
||||||
fprintf(fp," st->print(\"#\" INT64_FORMAT, _c%d);\n", i);
|
fprintf(fp," st->print(\"#\" INT64_FORMAT, _c%d);\n", i);
|
||||||
|
fprintf(fp," st->print(\"/\" PTR64_FORMAT, _c%d);\n", i);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
else if (!strcmp(ideal_type, "ConF")) {
|
else if (!strcmp(ideal_type, "ConF")) {
|
||||||
fprintf(fp," st->print(\"#%%f\", _c%d);\n", i);
|
fprintf(fp," st->print(\"#%%f\", _c%d);\n", i);
|
||||||
|
fprintf(fp," jint _c%di = JavaValue(_c%d).get_jint();\n", i, i);
|
||||||
|
fprintf(fp," st->print(\"/0x%%x/\", _c%di);\n", i);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
else if (!strcmp(ideal_type, "ConD")) {
|
else if (!strcmp(ideal_type, "ConD")) {
|
||||||
fprintf(fp," st->print(\"#%%f\", _c%d);\n", i);
|
fprintf(fp," st->print(\"#%%f\", _c%d);\n", i);
|
||||||
|
fprintf(fp," jlong _c%dl = JavaValue(_c%d).get_jlong();\n", i, i);
|
||||||
|
fprintf(fp," st->print(\"/\" PTR64_FORMAT, _c%dl);\n", i);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
else if (!strcmp(ideal_type, "Bool")) {
|
else if (!strcmp(ideal_type, "Bool")) {
|
||||||
|
@ -429,7 +445,7 @@ void gen_oper_format(FILE *fp, FormDict &globals, OperandForm &oper, bool for_c_
|
||||||
}
|
}
|
||||||
|
|
||||||
// Local pointer indicates remaining part of format rule
|
// Local pointer indicates remaining part of format rule
|
||||||
uint idx = 0; // position of operand in match rule
|
int idx = 0; // position of operand in match rule
|
||||||
|
|
||||||
// Generate internal format function, used when stored locally
|
// Generate internal format function, used when stored locally
|
||||||
fprintf(fp, "\n#ifndef PRODUCT\n");
|
fprintf(fp, "\n#ifndef PRODUCT\n");
|
||||||
|
@ -444,13 +460,12 @@ void gen_oper_format(FILE *fp, FormDict &globals, OperandForm &oper, bool for_c_
|
||||||
oper._format->_rep_vars.reset();
|
oper._format->_rep_vars.reset();
|
||||||
oper._format->_strings.reset();
|
oper._format->_strings.reset();
|
||||||
while ( (string = oper._format->_strings.iter()) != NULL ) {
|
while ( (string = oper._format->_strings.iter()) != NULL ) {
|
||||||
fprintf(fp," ");
|
|
||||||
|
|
||||||
// Check if this is a standard string or a replacement variable
|
// Check if this is a standard string or a replacement variable
|
||||||
if ( string != NameList::_signal ) {
|
if ( string != NameList::_signal ) {
|
||||||
// Normal string
|
// Normal string
|
||||||
// Pass through to st->print
|
// Pass through to st->print
|
||||||
fprintf(fp,"st->print(\"%s\");\n", string);
|
fprintf(fp," st->print(\"%s\");\n", string);
|
||||||
} else {
|
} else {
|
||||||
// Replacement variable
|
// Replacement variable
|
||||||
const char *rep_var = oper._format->_rep_vars.iter();
|
const char *rep_var = oper._format->_rep_vars.iter();
|
||||||
|
@ -473,7 +488,7 @@ void gen_oper_format(FILE *fp, FormDict &globals, OperandForm &oper, bool for_c_
|
||||||
}
|
}
|
||||||
|
|
||||||
// output invocation of "$..."s format function
|
// output invocation of "$..."s format function
|
||||||
if ( op != NULL ) op->int_format(fp, globals, idx);
|
if ( op != NULL ) op->int_format(fp, globals, idx);
|
||||||
|
|
||||||
if ( idx == -1 ) {
|
if ( idx == -1 ) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
|
@ -516,13 +531,12 @@ void gen_oper_format(FILE *fp, FormDict &globals, OperandForm &oper, bool for_c_
|
||||||
oper._format->_rep_vars.reset();
|
oper._format->_rep_vars.reset();
|
||||||
oper._format->_strings.reset();
|
oper._format->_strings.reset();
|
||||||
while ( (string = oper._format->_strings.iter()) != NULL ) {
|
while ( (string = oper._format->_strings.iter()) != NULL ) {
|
||||||
fprintf(fp," ");
|
|
||||||
|
|
||||||
// Check if this is a standard string or a replacement variable
|
// Check if this is a standard string or a replacement variable
|
||||||
if ( string != NameList::_signal ) {
|
if ( string != NameList::_signal ) {
|
||||||
// Normal string
|
// Normal string
|
||||||
// Pass through to st->print
|
// Pass through to st->print
|
||||||
fprintf(fp,"st->print(\"%s\");\n", string);
|
fprintf(fp," st->print(\"%s\");\n", string);
|
||||||
} else {
|
} else {
|
||||||
// Replacement variable
|
// Replacement variable
|
||||||
const char *rep_var = oper._format->_rep_vars.iter();
|
const char *rep_var = oper._format->_rep_vars.iter();
|
||||||
|
@ -547,7 +561,7 @@ void gen_oper_format(FILE *fp, FormDict &globals, OperandForm &oper, bool for_c_
|
||||||
if ( op != NULL ) op->ext_format(fp, globals, idx);
|
if ( op != NULL ) op->ext_format(fp, globals, idx);
|
||||||
|
|
||||||
// Lookup the index position of the replacement variable
|
// Lookup the index position of the replacement variable
|
||||||
idx = oper._components.operand_position_format(rep_var);
|
idx = oper._components.operand_position_format(rep_var, &oper);
|
||||||
if ( idx == -1 ) {
|
if ( idx == -1 ) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Using a name, %s, that isn't in match rule\n", rep_var);
|
"Using a name, %s, that isn't in match rule\n", rep_var);
|
||||||
|
@ -601,7 +615,7 @@ void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &inst, bool for_c
|
||||||
inst._format->_rep_vars.reset();
|
inst._format->_rep_vars.reset();
|
||||||
inst._format->_strings.reset();
|
inst._format->_strings.reset();
|
||||||
while( (string = inst._format->_strings.iter()) != NULL ) {
|
while( (string = inst._format->_strings.iter()) != NULL ) {
|
||||||
fprintf(fp," ");
|
fprintf(fp," ");
|
||||||
// Check if this is a standard string or a replacement variable
|
// Check if this is a standard string or a replacement variable
|
||||||
if( string == NameList::_signal ) { // Replacement variable
|
if( string == NameList::_signal ) { // Replacement variable
|
||||||
const char* rep_var = inst._format->_rep_vars.iter();
|
const char* rep_var = inst._format->_rep_vars.iter();
|
||||||
|
@ -658,11 +672,12 @@ void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &inst, bool for_c
|
||||||
if( call_type != Form::invalid_type ) {
|
if( call_type != Form::invalid_type ) {
|
||||||
switch( call_type ) {
|
switch( call_type ) {
|
||||||
case Form::JAVA_DYNAMIC:
|
case Form::JAVA_DYNAMIC:
|
||||||
fprintf(fp," _method->print_short_name();\n");
|
fprintf(fp," _method->print_short_name(st);\n");
|
||||||
break;
|
break;
|
||||||
case Form::JAVA_STATIC:
|
case Form::JAVA_STATIC:
|
||||||
fprintf(fp," if( _method ) _method->print_short_name(st); else st->print(\" wrapper for: %%s\", _name);\n");
|
fprintf(fp," if( _method ) _method->print_short_name(st);\n");
|
||||||
fprintf(fp," if( !_method ) dump_trap_args(st);\n");
|
fprintf(fp," else st->print(\" wrapper for: %%s\", _name);\n");
|
||||||
|
fprintf(fp," if( !_method ) dump_trap_args(st);\n");
|
||||||
break;
|
break;
|
||||||
case Form::JAVA_COMPILED:
|
case Form::JAVA_COMPILED:
|
||||||
case Form::JAVA_INTERP:
|
case Form::JAVA_INTERP:
|
||||||
|
@ -670,52 +685,46 @@ void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &inst, bool for_c
|
||||||
case Form::JAVA_RUNTIME:
|
case Form::JAVA_RUNTIME:
|
||||||
case Form::JAVA_LEAF:
|
case Form::JAVA_LEAF:
|
||||||
case Form::JAVA_NATIVE:
|
case Form::JAVA_NATIVE:
|
||||||
fprintf(fp," st->print(\" %%s\", _name);");
|
fprintf(fp," st->print(\" %%s\", _name);");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0,"ShouldNotReacHere");
|
assert(0,"ShouldNotReachHere");
|
||||||
}
|
}
|
||||||
fprintf(fp, " st->print_cr(\"\");\n" );
|
fprintf(fp, " st->print_cr(\"\");\n" );
|
||||||
fprintf(fp, " if (_jvms) _jvms->format(ra, this, st); else st->print_cr(\" No JVM State Info\");\n" );
|
fprintf(fp, " if (_jvms) _jvms->format(ra, this, st); else st->print_cr(\" No JVM State Info\");\n" );
|
||||||
fprintf(fp, " st->print(\" # \");\n" );
|
fprintf(fp, " st->print(\" # \");\n" );
|
||||||
fprintf(fp, " if( _jvms ) _oop_map->print_on(st);\n");
|
fprintf(fp, " if( _jvms && _oop_map ) _oop_map->print_on(st);\n");
|
||||||
}
|
}
|
||||||
else if(inst.is_ideal_safepoint()) {
|
else if(inst.is_ideal_safepoint()) {
|
||||||
fprintf(fp, " st->print(\"\");\n" );
|
fprintf(fp, " st->print(\"\");\n" );
|
||||||
fprintf(fp, " if (_jvms) _jvms->format(ra, this, st); else st->print_cr(\" No JVM State Info\");\n" );
|
fprintf(fp, " if (_jvms) _jvms->format(ra, this, st); else st->print_cr(\" No JVM State Info\");\n" );
|
||||||
fprintf(fp, " st->print(\" # \");\n" );
|
fprintf(fp, " st->print(\" # \");\n" );
|
||||||
fprintf(fp, " if( _jvms ) _oop_map->print_on(st);\n");
|
fprintf(fp, " if( _jvms && _oop_map ) _oop_map->print_on(st);\n");
|
||||||
}
|
}
|
||||||
else if( inst.is_ideal_if() ) {
|
else if( inst.is_ideal_if() ) {
|
||||||
fprintf(fp, " st->print(\" P=%%f C=%%f\",_prob,_fcnt);\n" );
|
fprintf(fp, " st->print(\" P=%%f C=%%f\",_prob,_fcnt);\n" );
|
||||||
}
|
}
|
||||||
else if( inst.is_ideal_mem() ) {
|
else if( inst.is_ideal_mem() ) {
|
||||||
// Print out the field name if available to improve readability
|
// Print out the field name if available to improve readability
|
||||||
fprintf(fp, " if (ra->C->alias_type(adr_type())->field() != NULL) {\n");
|
fprintf(fp, " if (ra->C->alias_type(adr_type())->field() != NULL) {\n");
|
||||||
fprintf(fp, " ciField* f = ra->C->alias_type(adr_type())->field();\n");
|
fprintf(fp, " ciField* f = ra->C->alias_type(adr_type())->field();\n");
|
||||||
fprintf(fp, " st->print(\" ! Field: \");\n");
|
fprintf(fp, " st->print(\" %s Field: \");\n", commentSeperator);
|
||||||
fprintf(fp, " if (f->is_volatile())\n");
|
fprintf(fp, " if (f->is_volatile())\n");
|
||||||
fprintf(fp, " st->print(\"volatile \");\n");
|
fprintf(fp, " st->print(\"volatile \");\n");
|
||||||
fprintf(fp, " f->holder()->name()->print_symbol_on(st);\n");
|
fprintf(fp, " f->holder()->name()->print_symbol_on(st);\n");
|
||||||
fprintf(fp, " st->print(\".\");\n");
|
fprintf(fp, " st->print(\".\");\n");
|
||||||
fprintf(fp, " f->name()->print_symbol_on(st);\n");
|
fprintf(fp, " f->name()->print_symbol_on(st);\n");
|
||||||
fprintf(fp, " if (f->is_constant())\n");
|
fprintf(fp, " if (f->is_constant())\n");
|
||||||
fprintf(fp, " st->print(\" (constant)\");\n");
|
fprintf(fp, " st->print(\" (constant)\");\n");
|
||||||
fprintf(fp, " } else\n");
|
fprintf(fp, " } else {\n");
|
||||||
// Make sure 'Volatile' gets printed out
|
// Make sure 'Volatile' gets printed out
|
||||||
fprintf(fp, " if (ra->C->alias_type(adr_type())->is_volatile())\n");
|
fprintf(fp, " if (ra->C->alias_type(adr_type())->is_volatile())\n");
|
||||||
fprintf(fp, " st->print(\" volatile!\");\n");
|
fprintf(fp, " st->print(\" volatile!\");\n");
|
||||||
|
fprintf(fp, " }\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Complete the definition of the format function
|
// Complete the definition of the format function
|
||||||
fprintf(fp, " }\n#endif\n");
|
fprintf(fp, "}\n#endif\n");
|
||||||
}
|
|
||||||
|
|
||||||
static bool is_non_constant(char* x) {
|
|
||||||
// Tells whether the string (part of an operator interface) is non-constant.
|
|
||||||
// Simply detect whether there is an occurrence of a formal parameter,
|
|
||||||
// which will always begin with '$'.
|
|
||||||
return strchr(x, '$') == 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArchDesc::declare_pipe_classes(FILE *fp_hpp) {
|
void ArchDesc::declare_pipe_classes(FILE *fp_hpp) {
|
||||||
|
@ -1107,7 +1116,7 @@ void ArchDesc::declare_pipe_classes(FILE *fp_hpp) {
|
||||||
fprintf(fp_hpp, " static void initialize_nops(MachNode *nop_list[%d], Compile* C);\n\n",
|
fprintf(fp_hpp, " static void initialize_nops(MachNode *nop_list[%d], Compile* C);\n\n",
|
||||||
_pipeline->_nopcnt);
|
_pipeline->_nopcnt);
|
||||||
fprintf(fp_hpp, "#ifndef PRODUCT\n");
|
fprintf(fp_hpp, "#ifndef PRODUCT\n");
|
||||||
fprintf(fp_hpp, " void dump() const;\n");
|
fprintf(fp_hpp, " void dump(outputStream *st = tty) const;\n");
|
||||||
fprintf(fp_hpp, "#endif\n");
|
fprintf(fp_hpp, "#endif\n");
|
||||||
fprintf(fp_hpp, "};\n\n");
|
fprintf(fp_hpp, "};\n\n");
|
||||||
|
|
||||||
|
@ -1252,7 +1261,7 @@ void ArchDesc::declareClasses(FILE *fp) {
|
||||||
unsigned int position = 0;
|
unsigned int position = 0;
|
||||||
const char *opret, *opname, *optype;
|
const char *opret, *opname, *optype;
|
||||||
oper->_matrule->base_operand(position,_globalNames,opret,opname,optype);
|
oper->_matrule->base_operand(position,_globalNames,opret,opname,optype);
|
||||||
fprintf(fp," virtual const Type *type() const {");
|
fprintf(fp," virtual const Type *type() const {");
|
||||||
const char *type = getIdealType(optype);
|
const char *type = getIdealType(optype);
|
||||||
if( type != NULL ) {
|
if( type != NULL ) {
|
||||||
Form::DataType data_type = oper->is_base_constant(_globalNames);
|
Form::DataType data_type = oper->is_base_constant(_globalNames);
|
||||||
|
@ -1531,12 +1540,19 @@ void ArchDesc::declareClasses(FILE *fp) {
|
||||||
fprintf(fp, " GrowableArray<Label*> _index2label;\n");
|
fprintf(fp, " GrowableArray<Label*> _index2label;\n");
|
||||||
}
|
}
|
||||||
fprintf(fp,"public:\n");
|
fprintf(fp,"public:\n");
|
||||||
fprintf(fp," MachOper *opnd_array(uint operand_index) const { assert(operand_index < _num_opnds, \"invalid _opnd_array index\"); return _opnd_array[operand_index]; }\n");
|
fprintf(fp," MachOper *opnd_array(uint operand_index) const {\n");
|
||||||
fprintf(fp," void set_opnd_array(uint operand_index, MachOper *operand) { assert(operand_index < _num_opnds, \"invalid _opnd_array index\"); _opnd_array[operand_index] = operand; }\n");
|
fprintf(fp," assert(operand_index < _num_opnds, \"invalid _opnd_array index\");\n");
|
||||||
|
fprintf(fp," return _opnd_array[operand_index];\n");
|
||||||
|
fprintf(fp," }\n");
|
||||||
|
fprintf(fp," void set_opnd_array(uint operand_index, MachOper *operand) {\n");
|
||||||
|
fprintf(fp," assert(operand_index < _num_opnds, \"invalid _opnd_array index\");\n");
|
||||||
|
fprintf(fp," _opnd_array[operand_index] = operand;\n");
|
||||||
|
fprintf(fp," }\n");
|
||||||
fprintf(fp,"private:\n");
|
fprintf(fp,"private:\n");
|
||||||
if ( instr->is_ideal_jump() ) {
|
if ( instr->is_ideal_jump() ) {
|
||||||
fprintf(fp," virtual void add_case_label(int index_num, Label* blockLabel) {\n");
|
fprintf(fp," virtual void add_case_label(int index_num, Label* blockLabel) {\n");
|
||||||
fprintf(fp," _index2label.at_put_grow(index_num, blockLabel);}\n");
|
fprintf(fp," _index2label.at_put_grow(index_num, blockLabel);\n");
|
||||||
|
fprintf(fp," }\n");
|
||||||
}
|
}
|
||||||
if( can_cisc_spill() && (instr->cisc_spill_alternate() != NULL) ) {
|
if( can_cisc_spill() && (instr->cisc_spill_alternate() != NULL) ) {
|
||||||
fprintf(fp," const RegMask *_cisc_RegMask;\n");
|
fprintf(fp," const RegMask *_cisc_RegMask;\n");
|
||||||
|
@ -1572,7 +1588,7 @@ void ArchDesc::declareClasses(FILE *fp) {
|
||||||
while (attr != NULL) {
|
while (attr != NULL) {
|
||||||
if (strcmp(attr->_ident,"ins_cost") &&
|
if (strcmp(attr->_ident,"ins_cost") &&
|
||||||
strcmp(attr->_ident,"ins_short_branch")) {
|
strcmp(attr->_ident,"ins_short_branch")) {
|
||||||
fprintf(fp," int %s() const { return %s; }\n",
|
fprintf(fp," int %s() const { return %s; }\n",
|
||||||
attr->_ident, attr->_val);
|
attr->_ident, attr->_val);
|
||||||
}
|
}
|
||||||
// Check value for ins_avoid_back_to_back, and if it is true (1), set the flag
|
// Check value for ins_avoid_back_to_back, and if it is true (1), set the flag
|
||||||
|
@ -1656,12 +1672,12 @@ void ArchDesc::declareClasses(FILE *fp) {
|
||||||
|
|
||||||
// Output the declaration for number of relocation entries
|
// Output the declaration for number of relocation entries
|
||||||
if ( instr->reloc(_globalNames) != 0 ) {
|
if ( instr->reloc(_globalNames) != 0 ) {
|
||||||
fprintf(fp," virtual int reloc() const;\n");
|
fprintf(fp," virtual int reloc() const;\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instr->alignment() != 1) {
|
if (instr->alignment() != 1) {
|
||||||
fprintf(fp," virtual int alignment_required() const { return %d; }\n", instr->alignment());
|
fprintf(fp," virtual int alignment_required() const { return %d; }\n", instr->alignment());
|
||||||
fprintf(fp," virtual int compute_padding(int current_offset) const;\n");
|
fprintf(fp," virtual int compute_padding(int current_offset) const;\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Starting point for inputs matcher wants.
|
// Starting point for inputs matcher wants.
|
||||||
|
@ -1831,7 +1847,7 @@ void ArchDesc::declareClasses(FILE *fp) {
|
||||||
// as is done for pointers
|
// as is done for pointers
|
||||||
//
|
//
|
||||||
// Construct appropriate constant type containing the constant value.
|
// Construct appropriate constant type containing the constant value.
|
||||||
fprintf(fp," virtual const class Type *bottom_type() const{\n");
|
fprintf(fp," virtual const class Type *bottom_type() const {\n");
|
||||||
switch( data_type ) {
|
switch( data_type ) {
|
||||||
case Form::idealI:
|
case Form::idealI:
|
||||||
fprintf(fp," return TypeInt::make(opnd_array(1)->constant());\n");
|
fprintf(fp," return TypeInt::make(opnd_array(1)->constant());\n");
|
||||||
|
@ -1862,7 +1878,7 @@ void ArchDesc::declareClasses(FILE *fp) {
|
||||||
// !!!!! !!!!!
|
// !!!!! !!!!!
|
||||||
// Provide explicit bottom type for conversions to int
|
// Provide explicit bottom type for conversions to int
|
||||||
// On Intel the result operand is a stackSlot, untyped.
|
// On Intel the result operand is a stackSlot, untyped.
|
||||||
fprintf(fp," virtual const class Type *bottom_type() const{");
|
fprintf(fp," virtual const class Type *bottom_type() const {");
|
||||||
fprintf(fp, " return TypeInt::INT;");
|
fprintf(fp, " return TypeInt::INT;");
|
||||||
fprintf(fp, " };\n");
|
fprintf(fp, " };\n");
|
||||||
}*/
|
}*/
|
||||||
|
@ -1883,7 +1899,7 @@ void ArchDesc::declareClasses(FILE *fp) {
|
||||||
// BoxNode provides the address of a stack slot.
|
// BoxNode provides the address of a stack slot.
|
||||||
// Define its bottom type to be TypeRawPtr::BOTTOM instead of TypePtr::BOTTOM
|
// Define its bottom type to be TypeRawPtr::BOTTOM instead of TypePtr::BOTTOM
|
||||||
// This prevent s insert_anti_dependencies from complaining. It will
|
// This prevent s insert_anti_dependencies from complaining. It will
|
||||||
// complain if it see that the pointer base is TypePtr::BOTTOM since
|
// complain if it sees that the pointer base is TypePtr::BOTTOM since
|
||||||
// it doesn't understand what that might alias.
|
// it doesn't understand what that might alias.
|
||||||
fprintf(fp," const Type *bottom_type() const { return TypeRawPtr::BOTTOM; } // Box?\n");
|
fprintf(fp," const Type *bottom_type() const { return TypeRawPtr::BOTTOM; } // Box?\n");
|
||||||
}
|
}
|
||||||
|
@ -2046,7 +2062,7 @@ void ArchDesc::defineStateClass(FILE *fp) {
|
||||||
class OutputMachOperands : public OutputMap {
|
class OutputMachOperands : public OutputMap {
|
||||||
public:
|
public:
|
||||||
OutputMachOperands(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
|
OutputMachOperands(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
|
||||||
: OutputMap(hpp, cpp, globals, AD) {};
|
: OutputMap(hpp, cpp, globals, AD, "MachOperands") {};
|
||||||
|
|
||||||
void declaration() { }
|
void declaration() { }
|
||||||
void definition() { fprintf(_cpp, "enum MachOperands {\n"); }
|
void definition() { fprintf(_cpp, "enum MachOperands {\n"); }
|
||||||
|
@ -2081,7 +2097,7 @@ class OutputMachOpcodes : public OutputMap {
|
||||||
int end_instructions;
|
int end_instructions;
|
||||||
public:
|
public:
|
||||||
OutputMachOpcodes(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
|
OutputMachOpcodes(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
|
||||||
: OutputMap(hpp, cpp, globals, AD),
|
: OutputMap(hpp, cpp, globals, AD, "MachOpcodes"),
|
||||||
begin_inst_chain_rule(-1), end_inst_chain_rule(-1), end_instructions(-1)
|
begin_inst_chain_rule(-1), end_inst_chain_rule(-1), end_instructions(-1)
|
||||||
{};
|
{};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue