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 }
|