hotspot/src/share/vm/adlc/archDesc.cpp

Print this page
rev 611 : Merge
   1 //
   2 // Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
   3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4 //
   5 // This code is free software; you can redistribute it and/or modify it
   6 // under the terms of the GNU General Public License version 2 only, as
   7 // published by the Free Software Foundation.
   8 //
   9 // This code is distributed in the hope that it will be useful, but WITHOUT
  10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12 // version 2 for more details (a copy is included in the LICENSE file that
  13 // accompanied this code).
  14 //
  15 // You should have received a copy of the GNU General Public License version
  16 // 2 along with this work; if not, write to the Free Software Foundation,
  17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18 //
  19 // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  20 // CA 95054 USA or visit www.sun.com if you need additional information or
  21 // have any questions.
  22 //  


 122     //    // chain_rule(fp, indent, name, cost, rule);
 123     //    chain_rule(fp, indent, name, cost, rule);
 124     //  }
 125   }
 126   reset();
 127   if( ! chains_exist ) {
 128     fprintf(fp, "No entries in this ChainList\n");
 129   }
 130 }
 131 
 132 
 133 //---------------------------MatchList Methods-------------------------------
 134 bool MatchList::search(const char *opc, const char *res, const char *lch, 
 135                        const char *rch, Predicate *pr) {
 136   bool tmp = false;
 137   if ((res == _resultStr) || (res && _resultStr && !strcmp(res, _resultStr))) {
 138     if ((lch == _lchild) || (lch && _lchild && !strcmp(lch, _lchild))) {
 139       if ((rch == _rchild) || (rch && _rchild && !strcmp(rch, _rchild))) {
 140         char * predStr = get_pred();
 141         char * prStr = pr?pr->_pred:NULL;
 142         if ((prStr == predStr) || (prStr && predStr && !strcmp(prStr, predStr))) {
 143           return true;
 144         }
 145       }
 146     }
 147   }
 148   if (_next) {
 149     tmp = _next->search(opc, res, lch, rch, pr);
 150   }
 151   return tmp;
 152 }
 153 
 154 
 155 void MatchList::dump() {
 156   output(stderr);
 157 }
 158 
 159 void MatchList::output(FILE *fp) {
 160   fprintf(fp, "\nMatchList output is Unimplemented();\n");
 161 }
 162 


 194       _adl_debug         = 0;
 195       _adlocation_debug  = 0;
 196       _internalOpCounter = 0;
 197       _cisc_spill_debug  = false;
 198       _short_branch_debug = false;
 199 
 200       // Initialize match rule flags
 201       for (int i = 0; i < _last_opcode; i++) {
 202         _has_match_rule[i] = false;
 203       }
 204 
 205       // Error/Warning Counts
 206       _syntax_errs       = 0;
 207       _semantic_errs     = 0;
 208       _warnings          = 0;
 209       _internal_errs     = 0;
 210 
 211       // Initialize I/O Files
 212       _ADL_file._name = NULL; _ADL_file._fp = NULL;
 213       // Machine dependent output files
 214       _DFA_file._name    = "dfa_i486.cpp";  _DFA_file._fp = NULL;
 215       _HPP_file._name    = "ad_i486.hpp";   _HPP_file._fp = NULL;
 216       _CPP_file._name    = "ad_i486.cpp";   _CPP_file._fp = NULL;
 217       _bug_file._name    = "bugs.out";      _bug_file._fp = NULL;
 218 
 219       // Initialize Register & Pipeline Form Pointers
 220       _register = NULL;
 221       _encode = NULL;
 222       _pipeline = NULL;
 223 }
 224 
 225 ArchDesc::~ArchDesc() {
 226   // Clean-up and quit
 227 
 228 }
 229 
 230 //---------------------------ArchDesc methods: Public ----------------------
 231 // Store forms according to type
 232 void ArchDesc::addForm(PreHeaderForm *ptr) { _pre_header.addForm(ptr); };
 233 void ArchDesc::addForm(HeaderForm    *ptr) { _header.addForm(ptr); };
 234 void ArchDesc::addForm(SourceForm    *ptr) { _source.addForm(ptr); };
 235 void ArchDesc::addForm(EncodeForm    *ptr) { _encode = ptr; };
 236 void ArchDesc::addForm(InstructForm  *ptr) { _instructions.addForm(ptr); };


 849   regMask = reg_class_to_reg_mask( result_class );
 850 
 851   return regMask;
 852 }
 853 
 854 // Obtain the name of the RegMask for an InstructForm
 855 const char *ArchDesc::reg_mask(InstructForm &inForm) {
 856   const char *result = inForm.reduce_result();
 857   assert( result, 
 858           "Did not find result operand or RegMask for this instruction");
 859 
 860   // Instructions producing 'Universe' use RegMask::Empty
 861   if( strcmp(result,"Universe")==0 ) {
 862     return "RegMask::Empty";
 863   } 
 864 
 865   // Lookup this result operand and get its register class
 866   Form *form = (Form*)_globalNames[result];
 867   assert( form, "Result operand must be defined");
 868   OperandForm *oper = form->is_operand();

 869   assert( oper, "Result must be an OperandForm");
 870   return reg_mask( *oper );
 871 }
 872 
 873 
 874 // Obtain the STACK_OR_reg_mask name for an OperandForm
 875 char *ArchDesc::stack_or_reg_mask(OperandForm  &opForm) {
 876   // name of cisc_spillable version
 877   const char *reg_mask_name = reg_mask(opForm);
 878   assert( reg_mask_name != NULL, "called with incorrect opForm");
 879 
 880   const char *stack_or = "STACK_OR_";
 881   int   length         = (int)strlen(stack_or) + (int)strlen(reg_mask_name) + 1;
 882   char *result         = new char[length];
 883   sprintf(result,"%s%s", stack_or, reg_mask_name);
 884 
 885   return result;
 886 }
 887 
 888 // Record that the register class must generate a stack_or_reg_mask


 890   if( _register ) {
 891     RegClass *reg_class  = _register->getRegClass(reg_class_name);
 892     reg_class->_stack_or_reg = true;
 893   }
 894 }
 895     
 896 
 897 // Return the type signature for the ideal operation
 898 const char *ArchDesc::getIdealType(const char *idealOp) {
 899   // Find last character in idealOp, it specifies the type
 900   char  last_char = 0;
 901   const char *ptr = idealOp;
 902   for( ; *ptr != '\0'; ++ptr) {
 903     last_char = *ptr;
 904   }
 905 
 906   // !!!!!
 907   switch( last_char ) {
 908   case 'I':    return "TypeInt::INT";
 909   case 'P':    return "TypePtr::BOTTOM";

 910   case 'F':    return "Type::FLOAT";
 911   case 'D':    return "Type::DOUBLE";
 912   case 'L':    return "TypeLong::LONG";
 913   case 's':    return "TypeInt::CC /*flags*/";
 914   default:
 915     return NULL;
 916     // !!!!!
 917     // internal_err("Ideal type %s with unrecognized type\n",idealOp);
 918     break;
 919   }
 920 
 921   return NULL;
 922 }
 923 
 924 
 925 
 926 OperandForm *ArchDesc::constructOperand(const char *ident, 
 927                                         bool  ideal_only) {
 928   OperandForm *opForm = new OperandForm(ident, ideal_only);
 929   _globalNames.Insert(ident, opForm);
 930   addForm(opForm);
 931 
 932   return opForm;
 933 }
 934 
 935 
 936 // Import predefined base types: Set = 1, RegI, RegP, ...
 937 void ArchDesc::initBaseOpTypes() {
 938   // Create OperandForm and assign type for each opcode.
 939   for (int i = 1; i < _last_machine_leaf; ++i) {
 940     char        *ident   = (char *)NodeClassNames[i];
 941     constructOperand(ident, true);
 942   }
 943   // Create InstructForm and assign type for each ideal instruction.
 944   for ( int j = _last_machine_leaf+1; j < _last_opcode; ++j) {
 945     char         *ident    = (char *)NodeClassNames[j];
 946     if(!strcmp(ident, "ConI") || !strcmp(ident, "ConP") || 
 947        !strcmp(ident, "ConF") || !strcmp(ident, "ConD") ||
 948        !strcmp(ident, "ConL") || !strcmp(ident, "Con" ) ||
 949        !strcmp(ident, "Bool") ) {
 950       constructOperand(ident, true);
 951     }
 952     else {
 953       InstructForm *insForm  = new InstructForm(ident, true);
 954       // insForm->_opcode       = nextUserOpType(ident);
 955       _globalNames.Insert(ident,insForm);
 956       addForm(insForm);
 957     }
 958   }
 959 
 960   { OperandForm *opForm;
 961   // Create operand type "Universe" for return instructions.
 962   const char *ident = "Universe";
 963   opForm = constructOperand(ident, false);
 964 
 965   // Create operand type "label" for branch targets
 966   ident = "label";


1091 void ArchDesc::buildMustCloneMap(FILE *fp_hpp, FILE *fp_cpp) {
1092   // Build external declarations for mappings
1093   fprintf(fp_hpp, "// Mapping from machine-independent opcode to boolean\n");
1094   fprintf(fp_hpp, "// Flag cases where machine needs cloned values or instructions\n");
1095   fprintf(fp_hpp, "extern const char must_clone[];\n");
1096   fprintf(fp_hpp, "\n");
1097 
1098   // Build mapping from ideal names to ideal indices
1099   fprintf(fp_cpp, "\n");
1100   fprintf(fp_cpp, "// Mapping from machine-independent opcode to boolean\n");
1101   fprintf(fp_cpp, "const        char must_clone[] = {\n");
1102   for (int idealIndex = 0; idealIndex < _last_opcode; ++idealIndex) {
1103     int         must_clone = 0;
1104     const char *idealName = NodeClassNames[idealIndex];
1105     // Previously selected constants for cloning
1106     // !!!!!
1107     // These are the current machine-dependent clones
1108     if ( strcmp(idealName,"CmpI") == 0
1109          || strcmp(idealName,"CmpU") == 0
1110          || strcmp(idealName,"CmpP") == 0

1111          || strcmp(idealName,"CmpL") == 0
1112          || strcmp(idealName,"CmpD") == 0
1113          || strcmp(idealName,"CmpF") == 0
1114          || strcmp(idealName,"FastLock") == 0
1115          || strcmp(idealName,"FastUnlock") == 0
1116          || strcmp(idealName,"Bool") == 0 
1117          || strcmp(idealName,"Binary") == 0 ) {
1118       // Removed ConI from the must_clone list.  CPUs that cannot use
1119       // large constants as immediates manifest the constant as an
1120       // instruction.  The must_clone flag prevents the constant from
1121       // floating up out of loops.
1122       must_clone = 1;
1123     }
1124     fprintf(fp_cpp, "  %d%s // %s: %d\n", must_clone, 
1125       (idealIndex != (_last_opcode - 1)) ? "," : " // no trailing comma", 
1126       idealName, idealIndex);
1127   }
1128   // Finish defining table
1129   fprintf(fp_cpp, "};\n");
1130 }
   1 //
   2 // Copyright 1997-2008 Sun Microsystems, Inc.  All Rights Reserved.
   3 // DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4 //
   5 // This code is free software; you can redistribute it and/or modify it
   6 // under the terms of the GNU General Public License version 2 only, as
   7 // published by the Free Software Foundation.
   8 //
   9 // This code is distributed in the hope that it will be useful, but WITHOUT
  10 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12 // version 2 for more details (a copy is included in the LICENSE file that
  13 // accompanied this code).
  14 //
  15 // You should have received a copy of the GNU General Public License version
  16 // 2 along with this work; if not, write to the Free Software Foundation,
  17 // Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18 //
  19 // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
  20 // CA 95054 USA or visit www.sun.com if you need additional information or
  21 // have any questions.
  22 //  


 122     //    // chain_rule(fp, indent, name, cost, rule);
 123     //    chain_rule(fp, indent, name, cost, rule);
 124     //  }
 125   }
 126   reset();
 127   if( ! chains_exist ) {
 128     fprintf(fp, "No entries in this ChainList\n");
 129   }
 130 }
 131 
 132 
 133 //---------------------------MatchList Methods-------------------------------
 134 bool MatchList::search(const char *opc, const char *res, const char *lch, 
 135                        const char *rch, Predicate *pr) {
 136   bool tmp = false;
 137   if ((res == _resultStr) || (res && _resultStr && !strcmp(res, _resultStr))) {
 138     if ((lch == _lchild) || (lch && _lchild && !strcmp(lch, _lchild))) {
 139       if ((rch == _rchild) || (rch && _rchild && !strcmp(rch, _rchild))) {
 140         char * predStr = get_pred();
 141         char * prStr = pr?pr->_pred:NULL;
 142         if (ADLParser::equivalent_expressions(prStr, predStr)) {
 143           return true;
 144         }
 145       }
 146     }
 147   }
 148   if (_next) {
 149     tmp = _next->search(opc, res, lch, rch, pr);
 150   }
 151   return tmp;
 152 }
 153 
 154 
 155 void MatchList::dump() {
 156   output(stderr);
 157 }
 158 
 159 void MatchList::output(FILE *fp) {
 160   fprintf(fp, "\nMatchList output is Unimplemented();\n");
 161 }
 162 


 194       _adl_debug         = 0;
 195       _adlocation_debug  = 0;
 196       _internalOpCounter = 0;
 197       _cisc_spill_debug  = false;
 198       _short_branch_debug = false;
 199 
 200       // Initialize match rule flags
 201       for (int i = 0; i < _last_opcode; i++) {
 202         _has_match_rule[i] = false;
 203       }
 204 
 205       // Error/Warning Counts
 206       _syntax_errs       = 0;
 207       _semantic_errs     = 0;
 208       _warnings          = 0;
 209       _internal_errs     = 0;
 210 
 211       // Initialize I/O Files
 212       _ADL_file._name = NULL; _ADL_file._fp = NULL;
 213       // Machine dependent output files
 214       _DFA_file._name    = NULL;  _DFA_file._fp = NULL;
 215       _HPP_file._name    = NULL;  _HPP_file._fp = NULL;
 216       _CPP_file._name    = NULL;  _CPP_file._fp = NULL;
 217       _bug_file._name    = "bugs.out";      _bug_file._fp = NULL;
 218 
 219       // Initialize Register & Pipeline Form Pointers
 220       _register = NULL;
 221       _encode = NULL;
 222       _pipeline = NULL;
 223 }
 224 
 225 ArchDesc::~ArchDesc() {
 226   // Clean-up and quit
 227 
 228 }
 229 
 230 //---------------------------ArchDesc methods: Public ----------------------
 231 // Store forms according to type
 232 void ArchDesc::addForm(PreHeaderForm *ptr) { _pre_header.addForm(ptr); };
 233 void ArchDesc::addForm(HeaderForm    *ptr) { _header.addForm(ptr); };
 234 void ArchDesc::addForm(SourceForm    *ptr) { _source.addForm(ptr); };
 235 void ArchDesc::addForm(EncodeForm    *ptr) { _encode = ptr; };
 236 void ArchDesc::addForm(InstructForm  *ptr) { _instructions.addForm(ptr); };


 849   regMask = reg_class_to_reg_mask( result_class );
 850 
 851   return regMask;
 852 }
 853 
 854 // Obtain the name of the RegMask for an InstructForm
 855 const char *ArchDesc::reg_mask(InstructForm &inForm) {
 856   const char *result = inForm.reduce_result();
 857   assert( result, 
 858           "Did not find result operand or RegMask for this instruction");
 859 
 860   // Instructions producing 'Universe' use RegMask::Empty
 861   if( strcmp(result,"Universe")==0 ) {
 862     return "RegMask::Empty";
 863   } 
 864 
 865   // Lookup this result operand and get its register class
 866   Form *form = (Form*)_globalNames[result];
 867   assert( form, "Result operand must be defined");
 868   OperandForm *oper = form->is_operand();
 869   if (oper == NULL) form->dump();
 870   assert( oper, "Result must be an OperandForm");
 871   return reg_mask( *oper );
 872 }
 873 
 874 
 875 // Obtain the STACK_OR_reg_mask name for an OperandForm
 876 char *ArchDesc::stack_or_reg_mask(OperandForm  &opForm) {
 877   // name of cisc_spillable version
 878   const char *reg_mask_name = reg_mask(opForm);
 879   assert( reg_mask_name != NULL, "called with incorrect opForm");
 880 
 881   const char *stack_or = "STACK_OR_";
 882   int   length         = (int)strlen(stack_or) + (int)strlen(reg_mask_name) + 1;
 883   char *result         = new char[length];
 884   sprintf(result,"%s%s", stack_or, reg_mask_name);
 885 
 886   return result;
 887 }
 888 
 889 // Record that the register class must generate a stack_or_reg_mask


 891   if( _register ) {
 892     RegClass *reg_class  = _register->getRegClass(reg_class_name);
 893     reg_class->_stack_or_reg = true;
 894   }
 895 }
 896     
 897 
 898 // Return the type signature for the ideal operation
 899 const char *ArchDesc::getIdealType(const char *idealOp) {
 900   // Find last character in idealOp, it specifies the type
 901   char  last_char = 0;
 902   const char *ptr = idealOp;
 903   for( ; *ptr != '\0'; ++ptr) {
 904     last_char = *ptr;
 905   }
 906 
 907   // !!!!!
 908   switch( last_char ) {
 909   case 'I':    return "TypeInt::INT";
 910   case 'P':    return "TypePtr::BOTTOM";
 911   case 'N':    return "TypeNarrowOop::BOTTOM";
 912   case 'F':    return "Type::FLOAT";
 913   case 'D':    return "Type::DOUBLE";
 914   case 'L':    return "TypeLong::LONG";
 915   case 's':    return "TypeInt::CC /*flags*/";
 916   default:
 917     return NULL;
 918     // !!!!!
 919     // internal_err("Ideal type %s with unrecognized type\n",idealOp);
 920     break;
 921   }
 922 
 923   return NULL;
 924 }
 925 
 926 
 927 
 928 OperandForm *ArchDesc::constructOperand(const char *ident, 
 929                                         bool  ideal_only) {
 930   OperandForm *opForm = new OperandForm(ident, ideal_only);
 931   _globalNames.Insert(ident, opForm);
 932   addForm(opForm);
 933 
 934   return opForm;
 935 }
 936 
 937 
 938 // Import predefined base types: Set = 1, RegI, RegP, ...
 939 void ArchDesc::initBaseOpTypes() {
 940   // Create OperandForm and assign type for each opcode.
 941   for (int i = 1; i < _last_machine_leaf; ++i) {
 942     char        *ident   = (char *)NodeClassNames[i];
 943     constructOperand(ident, true);
 944   }
 945   // Create InstructForm and assign type for each ideal instruction.
 946   for ( int j = _last_machine_leaf+1; j < _last_opcode; ++j) {
 947     char         *ident    = (char *)NodeClassNames[j];
 948     if(!strcmp(ident, "ConI") || !strcmp(ident, "ConP") || !strcmp(ident, "ConN") ||
 949        !strcmp(ident, "ConF") || !strcmp(ident, "ConD") ||
 950        !strcmp(ident, "ConL") || !strcmp(ident, "Con" ) ||
 951        !strcmp(ident, "Bool") ) {
 952       constructOperand(ident, true);
 953     }
 954     else {
 955       InstructForm *insForm  = new InstructForm(ident, true);
 956       // insForm->_opcode       = nextUserOpType(ident);
 957       _globalNames.Insert(ident,insForm);
 958       addForm(insForm);
 959     }
 960   }
 961 
 962   { OperandForm *opForm;
 963   // Create operand type "Universe" for return instructions.
 964   const char *ident = "Universe";
 965   opForm = constructOperand(ident, false);
 966 
 967   // Create operand type "label" for branch targets
 968   ident = "label";


1093 void ArchDesc::buildMustCloneMap(FILE *fp_hpp, FILE *fp_cpp) {
1094   // Build external declarations for mappings
1095   fprintf(fp_hpp, "// Mapping from machine-independent opcode to boolean\n");
1096   fprintf(fp_hpp, "// Flag cases where machine needs cloned values or instructions\n");
1097   fprintf(fp_hpp, "extern const char must_clone[];\n");
1098   fprintf(fp_hpp, "\n");
1099 
1100   // Build mapping from ideal names to ideal indices
1101   fprintf(fp_cpp, "\n");
1102   fprintf(fp_cpp, "// Mapping from machine-independent opcode to boolean\n");
1103   fprintf(fp_cpp, "const        char must_clone[] = {\n");
1104   for (int idealIndex = 0; idealIndex < _last_opcode; ++idealIndex) {
1105     int         must_clone = 0;
1106     const char *idealName = NodeClassNames[idealIndex];
1107     // Previously selected constants for cloning
1108     // !!!!!
1109     // These are the current machine-dependent clones
1110     if ( strcmp(idealName,"CmpI") == 0
1111          || strcmp(idealName,"CmpU") == 0
1112          || strcmp(idealName,"CmpP") == 0
1113          || strcmp(idealName,"CmpN") == 0
1114          || strcmp(idealName,"CmpL") == 0
1115          || strcmp(idealName,"CmpD") == 0
1116          || strcmp(idealName,"CmpF") == 0
1117          || strcmp(idealName,"FastLock") == 0
1118          || strcmp(idealName,"FastUnlock") == 0
1119          || strcmp(idealName,"Bool") == 0 
1120          || strcmp(idealName,"Binary") == 0 ) {
1121       // Removed ConI from the must_clone list.  CPUs that cannot use
1122       // large constants as immediates manifest the constant as an
1123       // instruction.  The must_clone flag prevents the constant from
1124       // floating up out of loops.
1125       must_clone = 1;
1126     }
1127     fprintf(fp_cpp, "  %d%s // %s: %d\n", must_clone, 
1128       (idealIndex != (_last_opcode - 1)) ? "," : " // no trailing comma", 
1129       idealName, idealIndex);
1130   }
1131   // Finish defining table
1132   fprintf(fp_cpp, "};\n");
1133 }