annotate src/share/vm/adlc/output_c.cpp @ 6972:bd7a7ce2e264

6830717: replay of compilations would help with debugging Summary: When java process crashed in compiler thread, repeat the compilation process will help finding root cause. This is done with using SA dump application class data and replay data from core dump, then use debug version of jvm to recompile the problematic java method. Reviewed-by: kvn, twisti, sspitsyn Contributed-by: yumin.qi@oracle.com
author minqi
date Mon, 12 Nov 2012 14:03:53 -0800
parents d336b3173277
children 705ef39fcaa9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 4121
diff changeset
2 * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1541
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1541
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1541
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 // output_c.cpp - Class CPP file output routines for architecture definition
a61af66fc99e Initial load
duke
parents:
diff changeset
26
a61af66fc99e Initial load
duke
parents:
diff changeset
27 #include "adlc.hpp"
a61af66fc99e Initial load
duke
parents:
diff changeset
28
a61af66fc99e Initial load
duke
parents:
diff changeset
29 // Utilities to characterize effect statements
a61af66fc99e Initial load
duke
parents:
diff changeset
30 static bool is_def(int usedef) {
a61af66fc99e Initial load
duke
parents:
diff changeset
31 switch(usedef) {
a61af66fc99e Initial load
duke
parents:
diff changeset
32 case Component::DEF:
a61af66fc99e Initial load
duke
parents:
diff changeset
33 case Component::USE_DEF: return true; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
34 }
a61af66fc99e Initial load
duke
parents:
diff changeset
35 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
36 }
a61af66fc99e Initial load
duke
parents:
diff changeset
37
a61af66fc99e Initial load
duke
parents:
diff changeset
38 static bool is_use(int usedef) {
a61af66fc99e Initial load
duke
parents:
diff changeset
39 switch(usedef) {
a61af66fc99e Initial load
duke
parents:
diff changeset
40 case Component::USE:
a61af66fc99e Initial load
duke
parents:
diff changeset
41 case Component::USE_DEF:
a61af66fc99e Initial load
duke
parents:
diff changeset
42 case Component::USE_KILL: return true; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
43 }
a61af66fc99e Initial load
duke
parents:
diff changeset
44 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
45 }
a61af66fc99e Initial load
duke
parents:
diff changeset
46
a61af66fc99e Initial load
duke
parents:
diff changeset
47 static bool is_kill(int usedef) {
a61af66fc99e Initial load
duke
parents:
diff changeset
48 switch(usedef) {
a61af66fc99e Initial load
duke
parents:
diff changeset
49 case Component::KILL:
a61af66fc99e Initial load
duke
parents:
diff changeset
50 case Component::USE_KILL: return true; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
51 }
a61af66fc99e Initial load
duke
parents:
diff changeset
52 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
53 }
a61af66fc99e Initial load
duke
parents:
diff changeset
54
a61af66fc99e Initial load
duke
parents:
diff changeset
55 // Define an array containing the machine register names, strings.
a61af66fc99e Initial load
duke
parents:
diff changeset
56 static void defineRegNames(FILE *fp, RegisterForm *registers) {
a61af66fc99e Initial load
duke
parents:
diff changeset
57 if (registers) {
a61af66fc99e Initial load
duke
parents:
diff changeset
58 fprintf(fp,"\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
59 fprintf(fp,"// An array of character pointers to machine register names.\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
60 fprintf(fp,"const char *Matcher::regName[REG_COUNT] = {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
61
a61af66fc99e Initial load
duke
parents:
diff changeset
62 // Output the register name for each register in the allocation classes
a61af66fc99e Initial load
duke
parents:
diff changeset
63 RegDef *reg_def = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
64 RegDef *next = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
65 registers->reset_RegDefs();
a61af66fc99e Initial load
duke
parents:
diff changeset
66 for( reg_def = registers->iter_RegDefs(); reg_def != NULL; reg_def = next ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
67 next = registers->iter_RegDefs();
a61af66fc99e Initial load
duke
parents:
diff changeset
68 const char *comma = (next != NULL) ? "," : " // no trailing comma";
a61af66fc99e Initial load
duke
parents:
diff changeset
69 fprintf(fp," \"%s\"%s\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
70 reg_def->_regname, comma );
a61af66fc99e Initial load
duke
parents:
diff changeset
71 }
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 // Finish defining enumeration
a61af66fc99e Initial load
duke
parents:
diff changeset
74 fprintf(fp,"};\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
75
a61af66fc99e Initial load
duke
parents:
diff changeset
76 fprintf(fp,"\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
77 fprintf(fp,"// An array of character pointers to machine register names.\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
78 fprintf(fp,"const VMReg OptoReg::opto2vm[REG_COUNT] = {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
79 reg_def = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
80 next = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
81 registers->reset_RegDefs();
a61af66fc99e Initial load
duke
parents:
diff changeset
82 for( reg_def = registers->iter_RegDefs(); reg_def != NULL; reg_def = next ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
83 next = registers->iter_RegDefs();
a61af66fc99e Initial load
duke
parents:
diff changeset
84 const char *comma = (next != NULL) ? "," : " // no trailing comma";
a61af66fc99e Initial load
duke
parents:
diff changeset
85 fprintf(fp,"\t%s%s\n", reg_def->_concrete, comma );
a61af66fc99e Initial load
duke
parents:
diff changeset
86 }
a61af66fc99e Initial load
duke
parents:
diff changeset
87 // Finish defining array
a61af66fc99e Initial load
duke
parents:
diff changeset
88 fprintf(fp,"\t};\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
89 fprintf(fp,"\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
90
a61af66fc99e Initial load
duke
parents:
diff changeset
91 fprintf(fp," OptoReg::Name OptoReg::vm2opto[ConcreteRegisterImpl::number_of_registers];\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
92
a61af66fc99e Initial load
duke
parents:
diff changeset
93 }
a61af66fc99e Initial load
duke
parents:
diff changeset
94 }
a61af66fc99e Initial load
duke
parents:
diff changeset
95
a61af66fc99e Initial load
duke
parents:
diff changeset
96 // Define an array containing the machine register encoding values
a61af66fc99e Initial load
duke
parents:
diff changeset
97 static void defineRegEncodes(FILE *fp, RegisterForm *registers) {
a61af66fc99e Initial load
duke
parents:
diff changeset
98 if (registers) {
a61af66fc99e Initial load
duke
parents:
diff changeset
99 fprintf(fp,"\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
100 fprintf(fp,"// An array of the machine register encode values\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
101 fprintf(fp,"const unsigned char Matcher::_regEncode[REG_COUNT] = {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
102
a61af66fc99e Initial load
duke
parents:
diff changeset
103 // Output the register encoding for each register in the allocation classes
a61af66fc99e Initial load
duke
parents:
diff changeset
104 RegDef *reg_def = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
105 RegDef *next = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
106 registers->reset_RegDefs();
a61af66fc99e Initial load
duke
parents:
diff changeset
107 for( reg_def = registers->iter_RegDefs(); reg_def != NULL; reg_def = next ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
108 next = registers->iter_RegDefs();
a61af66fc99e Initial load
duke
parents:
diff changeset
109 const char* register_encode = reg_def->register_encode();
a61af66fc99e Initial load
duke
parents:
diff changeset
110 const char *comma = (next != NULL) ? "," : " // no trailing comma";
a61af66fc99e Initial load
duke
parents:
diff changeset
111 int encval;
a61af66fc99e Initial load
duke
parents:
diff changeset
112 if (!ADLParser::is_int_token(register_encode, encval)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
113 fprintf(fp," %s%s // %s\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
114 register_encode, comma, reg_def->_regname );
a61af66fc99e Initial load
duke
parents:
diff changeset
115 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
116 // Output known constants in hex char format (backward compatibility).
a61af66fc99e Initial load
duke
parents:
diff changeset
117 assert(encval < 256, "Exceeded supported width for register encoding");
a61af66fc99e Initial load
duke
parents:
diff changeset
118 fprintf(fp," (unsigned char)'\\x%X'%s // %s\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
119 encval, comma, reg_def->_regname );
a61af66fc99e Initial load
duke
parents:
diff changeset
120 }
a61af66fc99e Initial load
duke
parents:
diff changeset
121 }
a61af66fc99e Initial load
duke
parents:
diff changeset
122 // Finish defining enumeration
a61af66fc99e Initial load
duke
parents:
diff changeset
123 fprintf(fp,"};\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
124
a61af66fc99e Initial load
duke
parents:
diff changeset
125 } // Done defining array
a61af66fc99e Initial load
duke
parents:
diff changeset
126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
127
a61af66fc99e Initial load
duke
parents:
diff changeset
128 // Output an enumeration of register class names
a61af66fc99e Initial load
duke
parents:
diff changeset
129 static void defineRegClassEnum(FILE *fp, RegisterForm *registers) {
a61af66fc99e Initial load
duke
parents:
diff changeset
130 if (registers) {
a61af66fc99e Initial load
duke
parents:
diff changeset
131 // Output an enumeration of register class names
a61af66fc99e Initial load
duke
parents:
diff changeset
132 fprintf(fp,"\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
133 fprintf(fp,"// Enumeration of register class names\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
134 fprintf(fp, "enum machRegisterClass {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
135 registers->_rclasses.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
136 for( const char *class_name = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
137 (class_name = registers->_rclasses.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
138 fprintf(fp," %s,\n", toUpper( class_name ));
a61af66fc99e Initial load
duke
parents:
diff changeset
139 }
a61af66fc99e Initial load
duke
parents:
diff changeset
140 // Finish defining enumeration
a61af66fc99e Initial load
duke
parents:
diff changeset
141 fprintf(fp, " _last_Mach_Reg_Class\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
142 fprintf(fp, "};\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
143 }
a61af66fc99e Initial load
duke
parents:
diff changeset
144 }
a61af66fc99e Initial load
duke
parents:
diff changeset
145
a61af66fc99e Initial load
duke
parents:
diff changeset
146 // Declare an enumeration of user-defined register classes
a61af66fc99e Initial load
duke
parents:
diff changeset
147 // and a list of register masks, one for each class.
a61af66fc99e Initial load
duke
parents:
diff changeset
148 void ArchDesc::declare_register_masks(FILE *fp_hpp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
149 const char *rc_name;
a61af66fc99e Initial load
duke
parents:
diff changeset
150
a61af66fc99e Initial load
duke
parents:
diff changeset
151 if( _register ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
152 // Build enumeration of user-defined register classes.
a61af66fc99e Initial load
duke
parents:
diff changeset
153 defineRegClassEnum(fp_hpp, _register);
a61af66fc99e Initial load
duke
parents:
diff changeset
154
a61af66fc99e Initial load
duke
parents:
diff changeset
155 // Generate a list of register masks, one for each class.
a61af66fc99e Initial load
duke
parents:
diff changeset
156 fprintf(fp_hpp,"\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
157 fprintf(fp_hpp,"// Register masks, one for each register class.\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
158 _register->_rclasses.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
159 for( rc_name = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
160 (rc_name = _register->_rclasses.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
161 const char *prefix = "";
a61af66fc99e Initial load
duke
parents:
diff changeset
162 RegClass *reg_class = _register->getRegClass(rc_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
163 assert( reg_class, "Using an undefined register class");
a61af66fc99e Initial load
duke
parents:
diff changeset
164
4121
db2e64ca2d5a 7090968: Allow adlc register class to depend on runtime conditions
roland
parents: 4114
diff changeset
165 if (reg_class->_user_defined == NULL) {
db2e64ca2d5a 7090968: Allow adlc register class to depend on runtime conditions
roland
parents: 4114
diff changeset
166 fprintf(fp_hpp, "extern const RegMask _%s%s_mask;\n", prefix, toUpper( rc_name ) );
db2e64ca2d5a 7090968: Allow adlc register class to depend on runtime conditions
roland
parents: 4114
diff changeset
167 fprintf(fp_hpp, "inline const RegMask &%s%s_mask() { return _%s%s_mask; }\n", prefix, toUpper( rc_name ), prefix, toUpper( rc_name ));
db2e64ca2d5a 7090968: Allow adlc register class to depend on runtime conditions
roland
parents: 4114
diff changeset
168 } else {
db2e64ca2d5a 7090968: Allow adlc register class to depend on runtime conditions
roland
parents: 4114
diff changeset
169 fprintf(fp_hpp, "inline const RegMask &%s%s_mask() { %s }\n", prefix, toUpper( rc_name ), reg_class->_user_defined);
db2e64ca2d5a 7090968: Allow adlc register class to depend on runtime conditions
roland
parents: 4114
diff changeset
170 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
171
a61af66fc99e Initial load
duke
parents:
diff changeset
172 if( reg_class->_stack_or_reg ) {
4121
db2e64ca2d5a 7090968: Allow adlc register class to depend on runtime conditions
roland
parents: 4114
diff changeset
173 assert(reg_class->_user_defined == NULL, "no user defined reg class here");
db2e64ca2d5a 7090968: Allow adlc register class to depend on runtime conditions
roland
parents: 4114
diff changeset
174 fprintf(fp_hpp, "extern const RegMask _%sSTACK_OR_%s_mask;\n", prefix, toUpper( rc_name ) );
db2e64ca2d5a 7090968: Allow adlc register class to depend on runtime conditions
roland
parents: 4114
diff changeset
175 fprintf(fp_hpp, "inline const RegMask &%sSTACK_OR_%s_mask() { return _%sSTACK_OR_%s_mask; }\n", prefix, toUpper( rc_name ), prefix, toUpper( rc_name ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
176 }
a61af66fc99e Initial load
duke
parents:
diff changeset
177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
178 }
a61af66fc99e Initial load
duke
parents:
diff changeset
179 }
a61af66fc99e Initial load
duke
parents:
diff changeset
180
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // Generate an enumeration of user-defined register classes
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // and a list of register masks, one for each class.
a61af66fc99e Initial load
duke
parents:
diff changeset
183 void ArchDesc::build_register_masks(FILE *fp_cpp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
184 const char *rc_name;
a61af66fc99e Initial load
duke
parents:
diff changeset
185
a61af66fc99e Initial load
duke
parents:
diff changeset
186 if( _register ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
187 // Generate a list of register masks, one for each class.
a61af66fc99e Initial load
duke
parents:
diff changeset
188 fprintf(fp_cpp,"\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
189 fprintf(fp_cpp,"// Register masks, one for each register class.\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
190 _register->_rclasses.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
191 for( rc_name = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
192 (rc_name = _register->_rclasses.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
193 const char *prefix = "";
a61af66fc99e Initial load
duke
parents:
diff changeset
194 RegClass *reg_class = _register->getRegClass(rc_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
195 assert( reg_class, "Using an undefined register class");
a61af66fc99e Initial load
duke
parents:
diff changeset
196
4121
db2e64ca2d5a 7090968: Allow adlc register class to depend on runtime conditions
roland
parents: 4114
diff changeset
197 if (reg_class->_user_defined != NULL) continue;
db2e64ca2d5a 7090968: Allow adlc register class to depend on runtime conditions
roland
parents: 4114
diff changeset
198
0
a61af66fc99e Initial load
duke
parents:
diff changeset
199 int len = RegisterForm::RegMask_Size();
4121
db2e64ca2d5a 7090968: Allow adlc register class to depend on runtime conditions
roland
parents: 4114
diff changeset
200 fprintf(fp_cpp, "const RegMask _%s%s_mask(", prefix, toUpper( rc_name ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
201 { int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
202 for( i = 0; i < len-1; i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
203 fprintf(fp_cpp," 0x%x,",reg_class->regs_in_word(i,false));
a61af66fc99e Initial load
duke
parents:
diff changeset
204 fprintf(fp_cpp," 0x%x );\n",reg_class->regs_in_word(i,false));
a61af66fc99e Initial load
duke
parents:
diff changeset
205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
206
a61af66fc99e Initial load
duke
parents:
diff changeset
207 if( reg_class->_stack_or_reg ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
208 int i;
4121
db2e64ca2d5a 7090968: Allow adlc register class to depend on runtime conditions
roland
parents: 4114
diff changeset
209 fprintf(fp_cpp, "const RegMask _%sSTACK_OR_%s_mask(", prefix, toUpper( rc_name ) );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
210 for( i = 0; i < len-1; i++ )
a61af66fc99e Initial load
duke
parents:
diff changeset
211 fprintf(fp_cpp," 0x%x,",reg_class->regs_in_word(i,true));
a61af66fc99e Initial load
duke
parents:
diff changeset
212 fprintf(fp_cpp," 0x%x );\n",reg_class->regs_in_word(i,true));
a61af66fc99e Initial load
duke
parents:
diff changeset
213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
215 }
a61af66fc99e Initial load
duke
parents:
diff changeset
216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
217
a61af66fc99e Initial load
duke
parents:
diff changeset
218 // Compute an index for an array in the pipeline_reads_NNN arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
219 static int pipeline_reads_initializer(FILE *fp_cpp, NameList &pipeline_reads, PipeClassForm *pipeclass)
a61af66fc99e Initial load
duke
parents:
diff changeset
220 {
a61af66fc99e Initial load
duke
parents:
diff changeset
221 int templen = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
222 int paramcount = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
223 const char *paramname;
a61af66fc99e Initial load
duke
parents:
diff changeset
224
a61af66fc99e Initial load
duke
parents:
diff changeset
225 if (pipeclass->_parameters.count() == 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
226 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
227
a61af66fc99e Initial load
duke
parents:
diff changeset
228 pipeclass->_parameters.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
229 paramname = pipeclass->_parameters.iter();
a61af66fc99e Initial load
duke
parents:
diff changeset
230 const PipeClassOperandForm *pipeopnd =
a61af66fc99e Initial load
duke
parents:
diff changeset
231 (const PipeClassOperandForm *)pipeclass->_localUsage[paramname];
a61af66fc99e Initial load
duke
parents:
diff changeset
232 if (pipeopnd && !pipeopnd->isWrite() && strcmp(pipeopnd->_stage, "Universal"))
a61af66fc99e Initial load
duke
parents:
diff changeset
233 pipeclass->_parameters.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
234
a61af66fc99e Initial load
duke
parents:
diff changeset
235 while ( (paramname = pipeclass->_parameters.iter()) != NULL ) {
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
236 const PipeClassOperandForm *tmppipeopnd =
0
a61af66fc99e Initial load
duke
parents:
diff changeset
237 (const PipeClassOperandForm *)pipeclass->_localUsage[paramname];
a61af66fc99e Initial load
duke
parents:
diff changeset
238
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
239 if (tmppipeopnd)
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
240 templen += 10 + (int)strlen(tmppipeopnd->_stage);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
241 else
a61af66fc99e Initial load
duke
parents:
diff changeset
242 templen += 19;
a61af66fc99e Initial load
duke
parents:
diff changeset
243
a61af66fc99e Initial load
duke
parents:
diff changeset
244 paramcount++;
a61af66fc99e Initial load
duke
parents:
diff changeset
245 }
a61af66fc99e Initial load
duke
parents:
diff changeset
246
a61af66fc99e Initial load
duke
parents:
diff changeset
247 // See if the count is zero
a61af66fc99e Initial load
duke
parents:
diff changeset
248 if (paramcount == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
249 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
250 }
a61af66fc99e Initial load
duke
parents:
diff changeset
251
a61af66fc99e Initial load
duke
parents:
diff changeset
252 char *operand_stages = new char [templen];
a61af66fc99e Initial load
duke
parents:
diff changeset
253 operand_stages[0] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
254 int i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
255 templen = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
256
a61af66fc99e Initial load
duke
parents:
diff changeset
257 pipeclass->_parameters.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
258 paramname = pipeclass->_parameters.iter();
a61af66fc99e Initial load
duke
parents:
diff changeset
259 pipeopnd = (const PipeClassOperandForm *)pipeclass->_localUsage[paramname];
a61af66fc99e Initial load
duke
parents:
diff changeset
260 if (pipeopnd && !pipeopnd->isWrite() && strcmp(pipeopnd->_stage, "Universal"))
a61af66fc99e Initial load
duke
parents:
diff changeset
261 pipeclass->_parameters.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
262
a61af66fc99e Initial load
duke
parents:
diff changeset
263 while ( (paramname = pipeclass->_parameters.iter()) != NULL ) {
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
264 const PipeClassOperandForm *tmppipeopnd =
0
a61af66fc99e Initial load
duke
parents:
diff changeset
265 (const PipeClassOperandForm *)pipeclass->_localUsage[paramname];
a61af66fc99e Initial load
duke
parents:
diff changeset
266 templen += sprintf(&operand_stages[templen], " stage_%s%c\n",
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
267 tmppipeopnd ? tmppipeopnd->_stage : "undefined",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
268 (++i < paramcount ? ',' : ' ') );
a61af66fc99e Initial load
duke
parents:
diff changeset
269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
270
a61af66fc99e Initial load
duke
parents:
diff changeset
271 // See if the same string is in the table
a61af66fc99e Initial load
duke
parents:
diff changeset
272 int ndx = pipeline_reads.index(operand_stages);
a61af66fc99e Initial load
duke
parents:
diff changeset
273
a61af66fc99e Initial load
duke
parents:
diff changeset
274 // No, add it to the table
a61af66fc99e Initial load
duke
parents:
diff changeset
275 if (ndx < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
276 pipeline_reads.addName(operand_stages);
a61af66fc99e Initial load
duke
parents:
diff changeset
277 ndx = pipeline_reads.index(operand_stages);
a61af66fc99e Initial load
duke
parents:
diff changeset
278
a61af66fc99e Initial load
duke
parents:
diff changeset
279 fprintf(fp_cpp, "static const enum machPipelineStages pipeline_reads_%03d[%d] = {\n%s};\n\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
280 ndx+1, paramcount, operand_stages);
a61af66fc99e Initial load
duke
parents:
diff changeset
281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
282 else
a61af66fc99e Initial load
duke
parents:
diff changeset
283 delete [] operand_stages;
a61af66fc99e Initial load
duke
parents:
diff changeset
284
a61af66fc99e Initial load
duke
parents:
diff changeset
285 return (ndx);
a61af66fc99e Initial load
duke
parents:
diff changeset
286 }
a61af66fc99e Initial load
duke
parents:
diff changeset
287
a61af66fc99e Initial load
duke
parents:
diff changeset
288 // Compute an index for an array in the pipeline_res_stages_NNN arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
289 static int pipeline_res_stages_initializer(
a61af66fc99e Initial load
duke
parents:
diff changeset
290 FILE *fp_cpp,
a61af66fc99e Initial load
duke
parents:
diff changeset
291 PipelineForm *pipeline,
a61af66fc99e Initial load
duke
parents:
diff changeset
292 NameList &pipeline_res_stages,
a61af66fc99e Initial load
duke
parents:
diff changeset
293 PipeClassForm *pipeclass)
a61af66fc99e Initial load
duke
parents:
diff changeset
294 {
a61af66fc99e Initial load
duke
parents:
diff changeset
295 const PipeClassResourceForm *piperesource;
a61af66fc99e Initial load
duke
parents:
diff changeset
296 int * res_stages = new int [pipeline->_rescount];
a61af66fc99e Initial load
duke
parents:
diff changeset
297 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
298
a61af66fc99e Initial load
duke
parents:
diff changeset
299 for (i = 0; i < pipeline->_rescount; i++)
a61af66fc99e Initial load
duke
parents:
diff changeset
300 res_stages[i] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
301
a61af66fc99e Initial load
duke
parents:
diff changeset
302 for (pipeclass->_resUsage.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
303 (piperesource = (const PipeClassResourceForm *)pipeclass->_resUsage.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
304 int used_mask = pipeline->_resdict[piperesource->_resource]->is_resource()->mask();
a61af66fc99e Initial load
duke
parents:
diff changeset
305 for (i = 0; i < pipeline->_rescount; i++)
a61af66fc99e Initial load
duke
parents:
diff changeset
306 if ((1 << i) & used_mask) {
a61af66fc99e Initial load
duke
parents:
diff changeset
307 int stage = pipeline->_stages.index(piperesource->_stage);
a61af66fc99e Initial load
duke
parents:
diff changeset
308 if (res_stages[i] < stage+1)
a61af66fc99e Initial load
duke
parents:
diff changeset
309 res_stages[i] = stage+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
310 }
a61af66fc99e Initial load
duke
parents:
diff changeset
311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
312
a61af66fc99e Initial load
duke
parents:
diff changeset
313 // Compute the length needed for the resource list
a61af66fc99e Initial load
duke
parents:
diff changeset
314 int commentlen = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
315 int max_stage = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
316 for (i = 0; i < pipeline->_rescount; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
317 if (res_stages[i] == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
318 if (max_stage < 9)
a61af66fc99e Initial load
duke
parents:
diff changeset
319 max_stage = 9;
a61af66fc99e Initial load
duke
parents:
diff changeset
320 }
a61af66fc99e Initial load
duke
parents:
diff changeset
321 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
322 int stagelen = (int)strlen(pipeline->_stages.name(res_stages[i]-1));
a61af66fc99e Initial load
duke
parents:
diff changeset
323 if (max_stage < stagelen)
a61af66fc99e Initial load
duke
parents:
diff changeset
324 max_stage = stagelen;
a61af66fc99e Initial load
duke
parents:
diff changeset
325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
326
a61af66fc99e Initial load
duke
parents:
diff changeset
327 commentlen += (int)strlen(pipeline->_reslist.name(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
328 }
a61af66fc99e Initial load
duke
parents:
diff changeset
329
a61af66fc99e Initial load
duke
parents:
diff changeset
330 int templen = 1 + commentlen + pipeline->_rescount * (max_stage + 14);
a61af66fc99e Initial load
duke
parents:
diff changeset
331
a61af66fc99e Initial load
duke
parents:
diff changeset
332 // Allocate space for the resource list
a61af66fc99e Initial load
duke
parents:
diff changeset
333 char * resource_stages = new char [templen];
a61af66fc99e Initial load
duke
parents:
diff changeset
334
a61af66fc99e Initial load
duke
parents:
diff changeset
335 templen = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
336 for (i = 0; i < pipeline->_rescount; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
337 const char * const resname =
a61af66fc99e Initial load
duke
parents:
diff changeset
338 res_stages[i] == 0 ? "undefined" : pipeline->_stages.name(res_stages[i]-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
339
a61af66fc99e Initial load
duke
parents:
diff changeset
340 templen += sprintf(&resource_stages[templen], " stage_%s%-*s // %s\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
341 resname, max_stage - (int)strlen(resname) + 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
342 (i < pipeline->_rescount-1) ? "," : "",
a61af66fc99e Initial load
duke
parents:
diff changeset
343 pipeline->_reslist.name(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
344 }
a61af66fc99e Initial load
duke
parents:
diff changeset
345
a61af66fc99e Initial load
duke
parents:
diff changeset
346 // See if the same string is in the table
a61af66fc99e Initial load
duke
parents:
diff changeset
347 int ndx = pipeline_res_stages.index(resource_stages);
a61af66fc99e Initial load
duke
parents:
diff changeset
348
a61af66fc99e Initial load
duke
parents:
diff changeset
349 // No, add it to the table
a61af66fc99e Initial load
duke
parents:
diff changeset
350 if (ndx < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
351 pipeline_res_stages.addName(resource_stages);
a61af66fc99e Initial load
duke
parents:
diff changeset
352 ndx = pipeline_res_stages.index(resource_stages);
a61af66fc99e Initial load
duke
parents:
diff changeset
353
a61af66fc99e Initial load
duke
parents:
diff changeset
354 fprintf(fp_cpp, "static const enum machPipelineStages pipeline_res_stages_%03d[%d] = {\n%s};\n\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
355 ndx+1, pipeline->_rescount, resource_stages);
a61af66fc99e Initial load
duke
parents:
diff changeset
356 }
a61af66fc99e Initial load
duke
parents:
diff changeset
357 else
a61af66fc99e Initial load
duke
parents:
diff changeset
358 delete [] resource_stages;
a61af66fc99e Initial load
duke
parents:
diff changeset
359
a61af66fc99e Initial load
duke
parents:
diff changeset
360 delete [] res_stages;
a61af66fc99e Initial load
duke
parents:
diff changeset
361
a61af66fc99e Initial load
duke
parents:
diff changeset
362 return (ndx);
a61af66fc99e Initial load
duke
parents:
diff changeset
363 }
a61af66fc99e Initial load
duke
parents:
diff changeset
364
a61af66fc99e Initial load
duke
parents:
diff changeset
365 // Compute an index for an array in the pipeline_res_cycles_NNN arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
366 static int pipeline_res_cycles_initializer(
a61af66fc99e Initial load
duke
parents:
diff changeset
367 FILE *fp_cpp,
a61af66fc99e Initial load
duke
parents:
diff changeset
368 PipelineForm *pipeline,
a61af66fc99e Initial load
duke
parents:
diff changeset
369 NameList &pipeline_res_cycles,
a61af66fc99e Initial load
duke
parents:
diff changeset
370 PipeClassForm *pipeclass)
a61af66fc99e Initial load
duke
parents:
diff changeset
371 {
a61af66fc99e Initial load
duke
parents:
diff changeset
372 const PipeClassResourceForm *piperesource;
a61af66fc99e Initial load
duke
parents:
diff changeset
373 int * res_cycles = new int [pipeline->_rescount];
a61af66fc99e Initial load
duke
parents:
diff changeset
374 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
375
a61af66fc99e Initial load
duke
parents:
diff changeset
376 for (i = 0; i < pipeline->_rescount; i++)
a61af66fc99e Initial load
duke
parents:
diff changeset
377 res_cycles[i] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
378
a61af66fc99e Initial load
duke
parents:
diff changeset
379 for (pipeclass->_resUsage.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
380 (piperesource = (const PipeClassResourceForm *)pipeclass->_resUsage.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
381 int used_mask = pipeline->_resdict[piperesource->_resource]->is_resource()->mask();
a61af66fc99e Initial load
duke
parents:
diff changeset
382 for (i = 0; i < pipeline->_rescount; i++)
a61af66fc99e Initial load
duke
parents:
diff changeset
383 if ((1 << i) & used_mask) {
a61af66fc99e Initial load
duke
parents:
diff changeset
384 int cycles = piperesource->_cycles;
a61af66fc99e Initial load
duke
parents:
diff changeset
385 if (res_cycles[i] < cycles)
a61af66fc99e Initial load
duke
parents:
diff changeset
386 res_cycles[i] = cycles;
a61af66fc99e Initial load
duke
parents:
diff changeset
387 }
a61af66fc99e Initial load
duke
parents:
diff changeset
388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
389
a61af66fc99e Initial load
duke
parents:
diff changeset
390 // Pre-compute the string length
a61af66fc99e Initial load
duke
parents:
diff changeset
391 int templen;
a61af66fc99e Initial load
duke
parents:
diff changeset
392 int cyclelen = 0, commentlen = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
393 int max_cycles = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
394 char temp[32];
a61af66fc99e Initial load
duke
parents:
diff changeset
395
a61af66fc99e Initial load
duke
parents:
diff changeset
396 for (i = 0; i < pipeline->_rescount; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
397 if (max_cycles < res_cycles[i])
a61af66fc99e Initial load
duke
parents:
diff changeset
398 max_cycles = res_cycles[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
399 templen = sprintf(temp, "%d", res_cycles[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
400 if (cyclelen < templen)
a61af66fc99e Initial load
duke
parents:
diff changeset
401 cyclelen = templen;
a61af66fc99e Initial load
duke
parents:
diff changeset
402 commentlen += (int)strlen(pipeline->_reslist.name(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
403 }
a61af66fc99e Initial load
duke
parents:
diff changeset
404
a61af66fc99e Initial load
duke
parents:
diff changeset
405 templen = 1 + commentlen + (cyclelen + 8) * pipeline->_rescount;
a61af66fc99e Initial load
duke
parents:
diff changeset
406
a61af66fc99e Initial load
duke
parents:
diff changeset
407 // Allocate space for the resource list
a61af66fc99e Initial load
duke
parents:
diff changeset
408 char * resource_cycles = new char [templen];
a61af66fc99e Initial load
duke
parents:
diff changeset
409
a61af66fc99e Initial load
duke
parents:
diff changeset
410 templen = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
411
a61af66fc99e Initial load
duke
parents:
diff changeset
412 for (i = 0; i < pipeline->_rescount; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
413 templen += sprintf(&resource_cycles[templen], " %*d%c // %s\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
414 cyclelen, res_cycles[i], (i < pipeline->_rescount-1) ? ',' : ' ', pipeline->_reslist.name(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
415 }
a61af66fc99e Initial load
duke
parents:
diff changeset
416
a61af66fc99e Initial load
duke
parents:
diff changeset
417 // See if the same string is in the table
a61af66fc99e Initial load
duke
parents:
diff changeset
418 int ndx = pipeline_res_cycles.index(resource_cycles);
a61af66fc99e Initial load
duke
parents:
diff changeset
419
a61af66fc99e Initial load
duke
parents:
diff changeset
420 // No, add it to the table
a61af66fc99e Initial load
duke
parents:
diff changeset
421 if (ndx < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
422 pipeline_res_cycles.addName(resource_cycles);
a61af66fc99e Initial load
duke
parents:
diff changeset
423 ndx = pipeline_res_cycles.index(resource_cycles);
a61af66fc99e Initial load
duke
parents:
diff changeset
424
a61af66fc99e Initial load
duke
parents:
diff changeset
425 fprintf(fp_cpp, "static const uint pipeline_res_cycles_%03d[%d] = {\n%s};\n\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
426 ndx+1, pipeline->_rescount, resource_cycles);
a61af66fc99e Initial load
duke
parents:
diff changeset
427 }
a61af66fc99e Initial load
duke
parents:
diff changeset
428 else
a61af66fc99e Initial load
duke
parents:
diff changeset
429 delete [] resource_cycles;
a61af66fc99e Initial load
duke
parents:
diff changeset
430
a61af66fc99e Initial load
duke
parents:
diff changeset
431 delete [] res_cycles;
a61af66fc99e Initial load
duke
parents:
diff changeset
432
a61af66fc99e Initial load
duke
parents:
diff changeset
433 return (ndx);
a61af66fc99e Initial load
duke
parents:
diff changeset
434 }
a61af66fc99e Initial load
duke
parents:
diff changeset
435
a61af66fc99e Initial load
duke
parents:
diff changeset
436 //typedef unsigned long long uint64_t;
a61af66fc99e Initial load
duke
parents:
diff changeset
437
a61af66fc99e Initial load
duke
parents:
diff changeset
438 // Compute an index for an array in the pipeline_res_mask_NNN arrays
a61af66fc99e Initial load
duke
parents:
diff changeset
439 static int pipeline_res_mask_initializer(
a61af66fc99e Initial load
duke
parents:
diff changeset
440 FILE *fp_cpp,
a61af66fc99e Initial load
duke
parents:
diff changeset
441 PipelineForm *pipeline,
a61af66fc99e Initial load
duke
parents:
diff changeset
442 NameList &pipeline_res_mask,
a61af66fc99e Initial load
duke
parents:
diff changeset
443 NameList &pipeline_res_args,
a61af66fc99e Initial load
duke
parents:
diff changeset
444 PipeClassForm *pipeclass)
a61af66fc99e Initial load
duke
parents:
diff changeset
445 {
a61af66fc99e Initial load
duke
parents:
diff changeset
446 const PipeClassResourceForm *piperesource;
a61af66fc99e Initial load
duke
parents:
diff changeset
447 const uint rescount = pipeline->_rescount;
a61af66fc99e Initial load
duke
parents:
diff changeset
448 const uint maxcycleused = pipeline->_maxcycleused;
a61af66fc99e Initial load
duke
parents:
diff changeset
449 const uint cyclemasksize = (maxcycleused + 31) >> 5;
a61af66fc99e Initial load
duke
parents:
diff changeset
450
a61af66fc99e Initial load
duke
parents:
diff changeset
451 int i, j;
a61af66fc99e Initial load
duke
parents:
diff changeset
452 int element_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
453 uint *res_mask = new uint [cyclemasksize];
a61af66fc99e Initial load
duke
parents:
diff changeset
454 uint resources_used = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
455 uint resources_used_exclusively = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
456
a61af66fc99e Initial load
duke
parents:
diff changeset
457 for (pipeclass->_resUsage.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
458 (piperesource = (const PipeClassResourceForm *)pipeclass->_resUsage.iter()) != NULL; )
a61af66fc99e Initial load
duke
parents:
diff changeset
459 element_count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
460
a61af66fc99e Initial load
duke
parents:
diff changeset
461 // Pre-compute the string length
a61af66fc99e Initial load
duke
parents:
diff changeset
462 int templen;
a61af66fc99e Initial load
duke
parents:
diff changeset
463 int commentlen = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
464 int max_cycles = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
465
a61af66fc99e Initial load
duke
parents:
diff changeset
466 int cyclelen = ((maxcycleused + 3) >> 2);
a61af66fc99e Initial load
duke
parents:
diff changeset
467 int masklen = (rescount + 3) >> 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
468
a61af66fc99e Initial load
duke
parents:
diff changeset
469 int cycledigit = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
470 for (i = maxcycleused; i > 0; i /= 10)
a61af66fc99e Initial load
duke
parents:
diff changeset
471 cycledigit++;
a61af66fc99e Initial load
duke
parents:
diff changeset
472
a61af66fc99e Initial load
duke
parents:
diff changeset
473 int maskdigit = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
474 for (i = rescount; i > 0; i /= 10)
a61af66fc99e Initial load
duke
parents:
diff changeset
475 maskdigit++;
a61af66fc99e Initial load
duke
parents:
diff changeset
476
a61af66fc99e Initial load
duke
parents:
diff changeset
477 static const char * pipeline_use_cycle_mask = "Pipeline_Use_Cycle_Mask";
a61af66fc99e Initial load
duke
parents:
diff changeset
478 static const char * pipeline_use_element = "Pipeline_Use_Element";
a61af66fc99e Initial load
duke
parents:
diff changeset
479
a61af66fc99e Initial load
duke
parents:
diff changeset
480 templen = 1 +
a61af66fc99e Initial load
duke
parents:
diff changeset
481 (int)(strlen(pipeline_use_cycle_mask) + (int)strlen(pipeline_use_element) +
a61af66fc99e Initial load
duke
parents:
diff changeset
482 (cyclemasksize * 12) + masklen + (cycledigit * 2) + 30) * element_count;
a61af66fc99e Initial load
duke
parents:
diff changeset
483
a61af66fc99e Initial load
duke
parents:
diff changeset
484 // Allocate space for the resource list
a61af66fc99e Initial load
duke
parents:
diff changeset
485 char * resource_mask = new char [templen];
a61af66fc99e Initial load
duke
parents:
diff changeset
486 char * last_comma = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
487
a61af66fc99e Initial load
duke
parents:
diff changeset
488 templen = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
489
a61af66fc99e Initial load
duke
parents:
diff changeset
490 for (pipeclass->_resUsage.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
491 (piperesource = (const PipeClassResourceForm *)pipeclass->_resUsage.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
492 int used_mask = pipeline->_resdict[piperesource->_resource]->is_resource()->mask();
a61af66fc99e Initial load
duke
parents:
diff changeset
493
a61af66fc99e Initial load
duke
parents:
diff changeset
494 if (!used_mask)
a61af66fc99e Initial load
duke
parents:
diff changeset
495 fprintf(stderr, "*** used_mask is 0 ***\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
496
a61af66fc99e Initial load
duke
parents:
diff changeset
497 resources_used |= used_mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
498
a61af66fc99e Initial load
duke
parents:
diff changeset
499 uint lb, ub;
a61af66fc99e Initial load
duke
parents:
diff changeset
500
a61af66fc99e Initial load
duke
parents:
diff changeset
501 for (lb = 0; (used_mask & (1 << lb)) == 0; lb++);
a61af66fc99e Initial load
duke
parents:
diff changeset
502 for (ub = 31; (used_mask & (1 << ub)) == 0; ub--);
a61af66fc99e Initial load
duke
parents:
diff changeset
503
a61af66fc99e Initial load
duke
parents:
diff changeset
504 if (lb == ub)
a61af66fc99e Initial load
duke
parents:
diff changeset
505 resources_used_exclusively |= used_mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
506
a61af66fc99e Initial load
duke
parents:
diff changeset
507 int formatlen =
a61af66fc99e Initial load
duke
parents:
diff changeset
508 sprintf(&resource_mask[templen], " %s(0x%0*x, %*d, %*d, %s %s(",
a61af66fc99e Initial load
duke
parents:
diff changeset
509 pipeline_use_element,
a61af66fc99e Initial load
duke
parents:
diff changeset
510 masklen, used_mask,
a61af66fc99e Initial load
duke
parents:
diff changeset
511 cycledigit, lb, cycledigit, ub,
a61af66fc99e Initial load
duke
parents:
diff changeset
512 ((used_mask & (used_mask-1)) != 0) ? "true, " : "false,",
a61af66fc99e Initial load
duke
parents:
diff changeset
513 pipeline_use_cycle_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
514
a61af66fc99e Initial load
duke
parents:
diff changeset
515 templen += formatlen;
a61af66fc99e Initial load
duke
parents:
diff changeset
516
a61af66fc99e Initial load
duke
parents:
diff changeset
517 memset(res_mask, 0, cyclemasksize * sizeof(uint));
a61af66fc99e Initial load
duke
parents:
diff changeset
518
a61af66fc99e Initial load
duke
parents:
diff changeset
519 int cycles = piperesource->_cycles;
a61af66fc99e Initial load
duke
parents:
diff changeset
520 uint stage = pipeline->_stages.index(piperesource->_stage);
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
521 if (NameList::Not_in_list == stage) {
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
522 fprintf(stderr,
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
523 "pipeline_res_mask_initializer: "
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
524 "semantic error: "
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
525 "pipeline stage undeclared: %s\n",
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
526 piperesource->_stage);
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
527 exit(1);
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
528 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
529 uint upper_limit = stage+cycles-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
530 uint lower_limit = stage-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
531 uint upper_idx = upper_limit >> 5;
a61af66fc99e Initial load
duke
parents:
diff changeset
532 uint lower_idx = lower_limit >> 5;
a61af66fc99e Initial load
duke
parents:
diff changeset
533 uint upper_position = upper_limit & 0x1f;
a61af66fc99e Initial load
duke
parents:
diff changeset
534 uint lower_position = lower_limit & 0x1f;
a61af66fc99e Initial load
duke
parents:
diff changeset
535
a61af66fc99e Initial load
duke
parents:
diff changeset
536 uint mask = (((uint)1) << upper_position) - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
537
a61af66fc99e Initial load
duke
parents:
diff changeset
538 while ( upper_idx > lower_idx ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
539 res_mask[upper_idx--] |= mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
540 mask = (uint)-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
541 }
a61af66fc99e Initial load
duke
parents:
diff changeset
542
a61af66fc99e Initial load
duke
parents:
diff changeset
543 mask -= (((uint)1) << lower_position) - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
544 res_mask[upper_idx] |= mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
545
a61af66fc99e Initial load
duke
parents:
diff changeset
546 for (j = cyclemasksize-1; j >= 0; j--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
547 formatlen =
a61af66fc99e Initial load
duke
parents:
diff changeset
548 sprintf(&resource_mask[templen], "0x%08x%s", res_mask[j], j > 0 ? ", " : "");
a61af66fc99e Initial load
duke
parents:
diff changeset
549 templen += formatlen;
a61af66fc99e Initial load
duke
parents:
diff changeset
550 }
a61af66fc99e Initial load
duke
parents:
diff changeset
551
a61af66fc99e Initial load
duke
parents:
diff changeset
552 resource_mask[templen++] = ')';
a61af66fc99e Initial load
duke
parents:
diff changeset
553 resource_mask[templen++] = ')';
a61af66fc99e Initial load
duke
parents:
diff changeset
554 last_comma = &resource_mask[templen];
a61af66fc99e Initial load
duke
parents:
diff changeset
555 resource_mask[templen++] = ',';
a61af66fc99e Initial load
duke
parents:
diff changeset
556 resource_mask[templen++] = '\n';
a61af66fc99e Initial load
duke
parents:
diff changeset
557 }
a61af66fc99e Initial load
duke
parents:
diff changeset
558
a61af66fc99e Initial load
duke
parents:
diff changeset
559 resource_mask[templen] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
560 if (last_comma)
a61af66fc99e Initial load
duke
parents:
diff changeset
561 last_comma[0] = ' ';
a61af66fc99e Initial load
duke
parents:
diff changeset
562
a61af66fc99e Initial load
duke
parents:
diff changeset
563 // See if the same string is in the table
a61af66fc99e Initial load
duke
parents:
diff changeset
564 int ndx = pipeline_res_mask.index(resource_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
565
a61af66fc99e Initial load
duke
parents:
diff changeset
566 // No, add it to the table
a61af66fc99e Initial load
duke
parents:
diff changeset
567 if (ndx < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
568 pipeline_res_mask.addName(resource_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
569 ndx = pipeline_res_mask.index(resource_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
570
a61af66fc99e Initial load
duke
parents:
diff changeset
571 if (strlen(resource_mask) > 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
572 fprintf(fp_cpp, "static const Pipeline_Use_Element pipeline_res_mask_%03d[%d] = {\n%s};\n\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
573 ndx+1, element_count, resource_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
574
a61af66fc99e Initial load
duke
parents:
diff changeset
575 char * args = new char [9 + 2*masklen + maskdigit];
a61af66fc99e Initial load
duke
parents:
diff changeset
576
a61af66fc99e Initial load
duke
parents:
diff changeset
577 sprintf(args, "0x%0*x, 0x%0*x, %*d",
a61af66fc99e Initial load
duke
parents:
diff changeset
578 masklen, resources_used,
a61af66fc99e Initial load
duke
parents:
diff changeset
579 masklen, resources_used_exclusively,
a61af66fc99e Initial load
duke
parents:
diff changeset
580 maskdigit, element_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
581
a61af66fc99e Initial load
duke
parents:
diff changeset
582 pipeline_res_args.addName(args);
a61af66fc99e Initial load
duke
parents:
diff changeset
583 }
a61af66fc99e Initial load
duke
parents:
diff changeset
584 else
a61af66fc99e Initial load
duke
parents:
diff changeset
585 delete [] resource_mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
586
a61af66fc99e Initial load
duke
parents:
diff changeset
587 delete [] res_mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
588 //delete [] res_masks;
a61af66fc99e Initial load
duke
parents:
diff changeset
589
a61af66fc99e Initial load
duke
parents:
diff changeset
590 return (ndx);
a61af66fc99e Initial load
duke
parents:
diff changeset
591 }
a61af66fc99e Initial load
duke
parents:
diff changeset
592
a61af66fc99e Initial load
duke
parents:
diff changeset
593 void ArchDesc::build_pipe_classes(FILE *fp_cpp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
594 const char *classname;
a61af66fc99e Initial load
duke
parents:
diff changeset
595 const char *resourcename;
a61af66fc99e Initial load
duke
parents:
diff changeset
596 int resourcenamelen = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
597 NameList pipeline_reads;
a61af66fc99e Initial load
duke
parents:
diff changeset
598 NameList pipeline_res_stages;
a61af66fc99e Initial load
duke
parents:
diff changeset
599 NameList pipeline_res_cycles;
a61af66fc99e Initial load
duke
parents:
diff changeset
600 NameList pipeline_res_masks;
a61af66fc99e Initial load
duke
parents:
diff changeset
601 NameList pipeline_res_args;
a61af66fc99e Initial load
duke
parents:
diff changeset
602 const int default_latency = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
603 const int non_operand_latency = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
604 const int node_latency = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
605
a61af66fc99e Initial load
duke
parents:
diff changeset
606 if (!_pipeline) {
a61af66fc99e Initial load
duke
parents:
diff changeset
607 fprintf(fp_cpp, "uint Node::latency(uint i) const {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
608 fprintf(fp_cpp, " // assert(false, \"pipeline functionality is not defined\");\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
609 fprintf(fp_cpp, " return %d;\n", non_operand_latency);
a61af66fc99e Initial load
duke
parents:
diff changeset
610 fprintf(fp_cpp, "}\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
611 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
612 }
a61af66fc99e Initial load
duke
parents:
diff changeset
613
a61af66fc99e Initial load
duke
parents:
diff changeset
614 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
615 fprintf(fp_cpp, "//------------------Pipeline Methods-----------------------------------------\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
616 fprintf(fp_cpp, "#ifndef PRODUCT\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
617 fprintf(fp_cpp, "const char * Pipeline::stageName(uint s) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
618 fprintf(fp_cpp, " static const char * const _stage_names[] = {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
619 fprintf(fp_cpp, " \"undefined\"");
a61af66fc99e Initial load
duke
parents:
diff changeset
620
a61af66fc99e Initial load
duke
parents:
diff changeset
621 for (int s = 0; s < _pipeline->_stagecnt; s++)
a61af66fc99e Initial load
duke
parents:
diff changeset
622 fprintf(fp_cpp, ", \"%s\"", _pipeline->_stages.name(s));
a61af66fc99e Initial load
duke
parents:
diff changeset
623
a61af66fc99e Initial load
duke
parents:
diff changeset
624 fprintf(fp_cpp, "\n };\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
625 fprintf(fp_cpp, " return (s <= %d ? _stage_names[s] : \"???\");\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
626 _pipeline->_stagecnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
627 fprintf(fp_cpp, "}\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
628 fprintf(fp_cpp, "#endif\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
629
a61af66fc99e Initial load
duke
parents:
diff changeset
630 fprintf(fp_cpp, "uint Pipeline::functional_unit_latency(uint start, const Pipeline *pred) const {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
631 fprintf(fp_cpp, " // See if the functional units overlap\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
632 #if 0
a61af66fc99e Initial load
duke
parents:
diff changeset
633 fprintf(fp_cpp, "\n#ifndef PRODUCT\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
634 fprintf(fp_cpp, " if (TraceOptoOutput) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
635 fprintf(fp_cpp, " tty->print(\"# functional_unit_latency: start == %%d, this->exclusively == 0x%%03x, pred->exclusively == 0x%%03x\\n\", start, resourcesUsedExclusively(), pred->resourcesUsedExclusively());\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
636 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
637 fprintf(fp_cpp, "#endif\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
638 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
639 fprintf(fp_cpp, " uint mask = resourcesUsedExclusively() & pred->resourcesUsedExclusively();\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
640 fprintf(fp_cpp, " if (mask == 0)\n return (start);\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
641 #if 0
a61af66fc99e Initial load
duke
parents:
diff changeset
642 fprintf(fp_cpp, "\n#ifndef PRODUCT\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
643 fprintf(fp_cpp, " if (TraceOptoOutput) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
644 fprintf(fp_cpp, " tty->print(\"# functional_unit_latency: mask == 0x%%x\\n\", mask);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
645 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
646 fprintf(fp_cpp, "#endif\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
647 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
648 fprintf(fp_cpp, " for (uint i = 0; i < pred->resourceUseCount(); i++) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
649 fprintf(fp_cpp, " const Pipeline_Use_Element *predUse = pred->resourceUseElement(i);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
650 fprintf(fp_cpp, " if (predUse->multiple())\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
651 fprintf(fp_cpp, " continue;\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
652 fprintf(fp_cpp, " for (uint j = 0; j < resourceUseCount(); j++) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
653 fprintf(fp_cpp, " const Pipeline_Use_Element *currUse = resourceUseElement(j);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
654 fprintf(fp_cpp, " if (currUse->multiple())\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
655 fprintf(fp_cpp, " continue;\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
656 fprintf(fp_cpp, " if (predUse->used() & currUse->used()) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
657 fprintf(fp_cpp, " Pipeline_Use_Cycle_Mask x = predUse->mask();\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
658 fprintf(fp_cpp, " Pipeline_Use_Cycle_Mask y = currUse->mask();\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
659 fprintf(fp_cpp, " for ( y <<= start; x.overlaps(y); start++ )\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
660 fprintf(fp_cpp, " y <<= 1;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
661 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
662 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
663 fprintf(fp_cpp, " }\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
664 fprintf(fp_cpp, " // There is the potential for overlap\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
665 fprintf(fp_cpp, " return (start);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
666 fprintf(fp_cpp, "}\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
667 fprintf(fp_cpp, "// The following two routines assume that the root Pipeline_Use entity\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
668 fprintf(fp_cpp, "// consists of exactly 1 element for each functional unit\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
669 fprintf(fp_cpp, "// start is relative to the current cycle; used for latency-based info\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
670 fprintf(fp_cpp, "uint Pipeline_Use::full_latency(uint delay, const Pipeline_Use &pred) const {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
671 fprintf(fp_cpp, " for (uint i = 0; i < pred._count; i++) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
672 fprintf(fp_cpp, " const Pipeline_Use_Element *predUse = pred.element(i);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
673 fprintf(fp_cpp, " if (predUse->_multiple) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
674 fprintf(fp_cpp, " uint min_delay = %d;\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
675 _pipeline->_maxcycleused+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
676 fprintf(fp_cpp, " // Multiple possible functional units, choose first unused one\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
677 fprintf(fp_cpp, " for (uint j = predUse->_lb; j <= predUse->_ub; j++) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
678 fprintf(fp_cpp, " const Pipeline_Use_Element *currUse = element(j);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
679 fprintf(fp_cpp, " uint curr_delay = delay;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
680 fprintf(fp_cpp, " if (predUse->_used & currUse->_used) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
681 fprintf(fp_cpp, " Pipeline_Use_Cycle_Mask x = predUse->_mask;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
682 fprintf(fp_cpp, " Pipeline_Use_Cycle_Mask y = currUse->_mask;\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
683 fprintf(fp_cpp, " for ( y <<= curr_delay; x.overlaps(y); curr_delay++ )\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
684 fprintf(fp_cpp, " y <<= 1;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
685 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
686 fprintf(fp_cpp, " if (min_delay > curr_delay)\n min_delay = curr_delay;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
687 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
688 fprintf(fp_cpp, " if (delay < min_delay)\n delay = min_delay;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
689 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
690 fprintf(fp_cpp, " else {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
691 fprintf(fp_cpp, " for (uint j = predUse->_lb; j <= predUse->_ub; j++) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
692 fprintf(fp_cpp, " const Pipeline_Use_Element *currUse = element(j);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
693 fprintf(fp_cpp, " if (predUse->_used & currUse->_used) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
694 fprintf(fp_cpp, " Pipeline_Use_Cycle_Mask x = predUse->_mask;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
695 fprintf(fp_cpp, " Pipeline_Use_Cycle_Mask y = currUse->_mask;\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
696 fprintf(fp_cpp, " for ( y <<= delay; x.overlaps(y); delay++ )\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
697 fprintf(fp_cpp, " y <<= 1;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
698 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
699 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
700 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
701 fprintf(fp_cpp, " }\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
702 fprintf(fp_cpp, " return (delay);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
703 fprintf(fp_cpp, "}\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
704 fprintf(fp_cpp, "void Pipeline_Use::add_usage(const Pipeline_Use &pred) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
705 fprintf(fp_cpp, " for (uint i = 0; i < pred._count; i++) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
706 fprintf(fp_cpp, " const Pipeline_Use_Element *predUse = pred.element(i);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
707 fprintf(fp_cpp, " if (predUse->_multiple) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
708 fprintf(fp_cpp, " // Multiple possible functional units, choose first unused one\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
709 fprintf(fp_cpp, " for (uint j = predUse->_lb; j <= predUse->_ub; j++) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
710 fprintf(fp_cpp, " Pipeline_Use_Element *currUse = element(j);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
711 fprintf(fp_cpp, " if ( !predUse->_mask.overlaps(currUse->_mask) ) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
712 fprintf(fp_cpp, " currUse->_used |= (1 << j);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
713 fprintf(fp_cpp, " _resources_used |= (1 << j);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
714 fprintf(fp_cpp, " currUse->_mask.Or(predUse->_mask);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
715 fprintf(fp_cpp, " break;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
716 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
717 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
718 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
719 fprintf(fp_cpp, " else {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
720 fprintf(fp_cpp, " for (uint j = predUse->_lb; j <= predUse->_ub; j++) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
721 fprintf(fp_cpp, " Pipeline_Use_Element *currUse = element(j);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
722 fprintf(fp_cpp, " currUse->_used |= (1 << j);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
723 fprintf(fp_cpp, " _resources_used |= (1 << j);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
724 fprintf(fp_cpp, " currUse->_mask.Or(predUse->_mask);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
725 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
726 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
727 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
728 fprintf(fp_cpp, "}\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
729
a61af66fc99e Initial load
duke
parents:
diff changeset
730 fprintf(fp_cpp, "uint Pipeline::operand_latency(uint opnd, const Pipeline *pred) const {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
731 fprintf(fp_cpp, " int const default_latency = 1;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
732 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
733 #if 0
a61af66fc99e Initial load
duke
parents:
diff changeset
734 fprintf(fp_cpp, "#ifndef PRODUCT\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
735 fprintf(fp_cpp, " if (TraceOptoOutput) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
736 fprintf(fp_cpp, " tty->print(\"# operand_latency(%%d), _read_stage_count = %%d\\n\", opnd, _read_stage_count);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
737 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
738 fprintf(fp_cpp, "#endif\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
739 #endif
1489
cff162798819 6888953: some calls to function-like macros are missing semicolons
jcoomes
parents: 1203
diff changeset
740 fprintf(fp_cpp, " assert(this, \"NULL pipeline info\");\n");
cff162798819 6888953: some calls to function-like macros are missing semicolons
jcoomes
parents: 1203
diff changeset
741 fprintf(fp_cpp, " assert(pred, \"NULL predecessor pipline info\");\n\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
742 fprintf(fp_cpp, " if (pred->hasFixedLatency())\n return (pred->fixedLatency());\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
743 fprintf(fp_cpp, " // If this is not an operand, then assume a dependence with 0 latency\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
744 fprintf(fp_cpp, " if (opnd > _read_stage_count)\n return (0);\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
745 fprintf(fp_cpp, " uint writeStage = pred->_write_stage;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
746 fprintf(fp_cpp, " uint readStage = _read_stages[opnd-1];\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
747 #if 0
a61af66fc99e Initial load
duke
parents:
diff changeset
748 fprintf(fp_cpp, "\n#ifndef PRODUCT\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
749 fprintf(fp_cpp, " if (TraceOptoOutput) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
750 fprintf(fp_cpp, " tty->print(\"# operand_latency: writeStage=%%s readStage=%%s, opnd=%%d\\n\", stageName(writeStage), stageName(readStage), opnd);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
751 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
752 fprintf(fp_cpp, "#endif\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
753 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
754 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
755 fprintf(fp_cpp, " if (writeStage == stage_undefined || readStage == stage_undefined)\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
756 fprintf(fp_cpp, " return (default_latency);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
757 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
758 fprintf(fp_cpp, " int delta = writeStage - readStage;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
759 fprintf(fp_cpp, " if (delta < 0) delta = 0;\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
760 #if 0
a61af66fc99e Initial load
duke
parents:
diff changeset
761 fprintf(fp_cpp, "\n#ifndef PRODUCT\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
762 fprintf(fp_cpp, " if (TraceOptoOutput) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
763 fprintf(fp_cpp, " tty->print(\"# operand_latency: delta=%%d\\n\", delta);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
764 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
765 fprintf(fp_cpp, "#endif\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
766 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
767 fprintf(fp_cpp, " return (delta);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
768 fprintf(fp_cpp, "}\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
769
a61af66fc99e Initial load
duke
parents:
diff changeset
770 if (!_pipeline)
a61af66fc99e Initial load
duke
parents:
diff changeset
771 /* Do Nothing */;
a61af66fc99e Initial load
duke
parents:
diff changeset
772
a61af66fc99e Initial load
duke
parents:
diff changeset
773 else if (_pipeline->_maxcycleused <=
a61af66fc99e Initial load
duke
parents:
diff changeset
774 #ifdef SPARC
a61af66fc99e Initial load
duke
parents:
diff changeset
775 64
a61af66fc99e Initial load
duke
parents:
diff changeset
776 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
777 32
a61af66fc99e Initial load
duke
parents:
diff changeset
778 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
779 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
780 fprintf(fp_cpp, "Pipeline_Use_Cycle_Mask operator&(const Pipeline_Use_Cycle_Mask &in1, const Pipeline_Use_Cycle_Mask &in2) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
781 fprintf(fp_cpp, " return Pipeline_Use_Cycle_Mask(in1._mask & in2._mask);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
782 fprintf(fp_cpp, "}\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
783 fprintf(fp_cpp, "Pipeline_Use_Cycle_Mask operator|(const Pipeline_Use_Cycle_Mask &in1, const Pipeline_Use_Cycle_Mask &in2) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
784 fprintf(fp_cpp, " return Pipeline_Use_Cycle_Mask(in1._mask | in2._mask);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
785 fprintf(fp_cpp, "}\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
786 }
a61af66fc99e Initial load
duke
parents:
diff changeset
787 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
788 uint l;
a61af66fc99e Initial load
duke
parents:
diff changeset
789 uint masklen = (_pipeline->_maxcycleused + 31) >> 5;
a61af66fc99e Initial load
duke
parents:
diff changeset
790 fprintf(fp_cpp, "Pipeline_Use_Cycle_Mask operator&(const Pipeline_Use_Cycle_Mask &in1, const Pipeline_Use_Cycle_Mask &in2) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
791 fprintf(fp_cpp, " return Pipeline_Use_Cycle_Mask(");
a61af66fc99e Initial load
duke
parents:
diff changeset
792 for (l = 1; l <= masklen; l++)
a61af66fc99e Initial load
duke
parents:
diff changeset
793 fprintf(fp_cpp, "in1._mask%d & in2._mask%d%s\n", l, l, l < masklen ? ", " : "");
a61af66fc99e Initial load
duke
parents:
diff changeset
794 fprintf(fp_cpp, ");\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
795 fprintf(fp_cpp, "}\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
796 fprintf(fp_cpp, "Pipeline_Use_Cycle_Mask operator|(const Pipeline_Use_Cycle_Mask &in1, const Pipeline_Use_Cycle_Mask &in2) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
797 fprintf(fp_cpp, " return Pipeline_Use_Cycle_Mask(");
a61af66fc99e Initial load
duke
parents:
diff changeset
798 for (l = 1; l <= masklen; l++)
a61af66fc99e Initial load
duke
parents:
diff changeset
799 fprintf(fp_cpp, "in1._mask%d | in2._mask%d%s", l, l, l < masklen ? ", " : "");
a61af66fc99e Initial load
duke
parents:
diff changeset
800 fprintf(fp_cpp, ");\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
801 fprintf(fp_cpp, "}\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
802 fprintf(fp_cpp, "void Pipeline_Use_Cycle_Mask::Or(const Pipeline_Use_Cycle_Mask &in2) {\n ");
a61af66fc99e Initial load
duke
parents:
diff changeset
803 for (l = 1; l <= masklen; l++)
a61af66fc99e Initial load
duke
parents:
diff changeset
804 fprintf(fp_cpp, " _mask%d |= in2._mask%d;", l, l);
a61af66fc99e Initial load
duke
parents:
diff changeset
805 fprintf(fp_cpp, "\n}\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
806 }
a61af66fc99e Initial load
duke
parents:
diff changeset
807
a61af66fc99e Initial load
duke
parents:
diff changeset
808 /* Get the length of all the resource names */
a61af66fc99e Initial load
duke
parents:
diff changeset
809 for (_pipeline->_reslist.reset(), resourcenamelen = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
810 (resourcename = _pipeline->_reslist.iter()) != NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
811 resourcenamelen += (int)strlen(resourcename));
a61af66fc99e Initial load
duke
parents:
diff changeset
812
a61af66fc99e Initial load
duke
parents:
diff changeset
813 // Create the pipeline class description
a61af66fc99e Initial load
duke
parents:
diff changeset
814
a61af66fc99e Initial load
duke
parents:
diff changeset
815 fprintf(fp_cpp, "static const Pipeline pipeline_class_Zero_Instructions(0, 0, true, 0, 0, false, false, false, false, NULL, NULL, NULL, Pipeline_Use(0, 0, 0, NULL));\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
816 fprintf(fp_cpp, "static const Pipeline pipeline_class_Unknown_Instructions(0, 0, true, 0, 0, false, true, true, false, NULL, NULL, NULL, Pipeline_Use(0, 0, 0, NULL));\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
817
a61af66fc99e Initial load
duke
parents:
diff changeset
818 fprintf(fp_cpp, "const Pipeline_Use_Element Pipeline_Use::elaborated_elements[%d] = {\n", _pipeline->_rescount);
a61af66fc99e Initial load
duke
parents:
diff changeset
819 for (int i1 = 0; i1 < _pipeline->_rescount; i1++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
820 fprintf(fp_cpp, " Pipeline_Use_Element(0, %d, %d, false, Pipeline_Use_Cycle_Mask(", i1, i1);
a61af66fc99e Initial load
duke
parents:
diff changeset
821 uint masklen = (_pipeline->_maxcycleused + 31) >> 5;
a61af66fc99e Initial load
duke
parents:
diff changeset
822 for (int i2 = masklen-1; i2 >= 0; i2--)
a61af66fc99e Initial load
duke
parents:
diff changeset
823 fprintf(fp_cpp, "0%s", i2 > 0 ? ", " : "");
a61af66fc99e Initial load
duke
parents:
diff changeset
824 fprintf(fp_cpp, "))%s\n", i1 < (_pipeline->_rescount-1) ? "," : "");
a61af66fc99e Initial load
duke
parents:
diff changeset
825 }
a61af66fc99e Initial load
duke
parents:
diff changeset
826 fprintf(fp_cpp, "};\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
827
a61af66fc99e Initial load
duke
parents:
diff changeset
828 fprintf(fp_cpp, "const Pipeline_Use Pipeline_Use::elaborated_use(0, 0, %d, (Pipeline_Use_Element *)&elaborated_elements[0]);\n\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
829 _pipeline->_rescount);
a61af66fc99e Initial load
duke
parents:
diff changeset
830
a61af66fc99e Initial load
duke
parents:
diff changeset
831 for (_pipeline->_classlist.reset(); (classname = _pipeline->_classlist.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
832 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
833 fprintf(fp_cpp, "// Pipeline Class \"%s\"\n", classname);
a61af66fc99e Initial load
duke
parents:
diff changeset
834 PipeClassForm *pipeclass = _pipeline->_classdict[classname]->is_pipeclass();
a61af66fc99e Initial load
duke
parents:
diff changeset
835 int maxWriteStage = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
836 int maxMoreInstrs = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
837 int paramcount = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
838 int i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
839 const char *paramname;
a61af66fc99e Initial load
duke
parents:
diff changeset
840 int resource_count = (_pipeline->_rescount + 3) >> 2;
a61af66fc99e Initial load
duke
parents:
diff changeset
841
a61af66fc99e Initial load
duke
parents:
diff changeset
842 // Scan the operands, looking for last output stage and number of inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
843 for (pipeclass->_parameters.reset(); (paramname = pipeclass->_parameters.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
844 const PipeClassOperandForm *pipeopnd =
a61af66fc99e Initial load
duke
parents:
diff changeset
845 (const PipeClassOperandForm *)pipeclass->_localUsage[paramname];
a61af66fc99e Initial load
duke
parents:
diff changeset
846 if (pipeopnd) {
a61af66fc99e Initial load
duke
parents:
diff changeset
847 if (pipeopnd->_iswrite) {
a61af66fc99e Initial load
duke
parents:
diff changeset
848 int stagenum = _pipeline->_stages.index(pipeopnd->_stage);
a61af66fc99e Initial load
duke
parents:
diff changeset
849 int moreinsts = pipeopnd->_more_instrs;
a61af66fc99e Initial load
duke
parents:
diff changeset
850 if ((maxWriteStage+maxMoreInstrs) < (stagenum+moreinsts)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
851 maxWriteStage = stagenum;
a61af66fc99e Initial load
duke
parents:
diff changeset
852 maxMoreInstrs = moreinsts;
a61af66fc99e Initial load
duke
parents:
diff changeset
853 }
a61af66fc99e Initial load
duke
parents:
diff changeset
854 }
a61af66fc99e Initial load
duke
parents:
diff changeset
855 }
a61af66fc99e Initial load
duke
parents:
diff changeset
856
a61af66fc99e Initial load
duke
parents:
diff changeset
857 if (i++ > 0 || (pipeopnd && !pipeopnd->isWrite()))
a61af66fc99e Initial load
duke
parents:
diff changeset
858 paramcount++;
a61af66fc99e Initial load
duke
parents:
diff changeset
859 }
a61af66fc99e Initial load
duke
parents:
diff changeset
860
a61af66fc99e Initial load
duke
parents:
diff changeset
861 // Create the list of stages for the operands that are read
a61af66fc99e Initial load
duke
parents:
diff changeset
862 // Note that we will build a NameList to reduce the number of copies
a61af66fc99e Initial load
duke
parents:
diff changeset
863
a61af66fc99e Initial load
duke
parents:
diff changeset
864 int pipeline_reads_index = pipeline_reads_initializer(fp_cpp, pipeline_reads, pipeclass);
a61af66fc99e Initial load
duke
parents:
diff changeset
865
a61af66fc99e Initial load
duke
parents:
diff changeset
866 int pipeline_res_stages_index = pipeline_res_stages_initializer(
a61af66fc99e Initial load
duke
parents:
diff changeset
867 fp_cpp, _pipeline, pipeline_res_stages, pipeclass);
a61af66fc99e Initial load
duke
parents:
diff changeset
868
a61af66fc99e Initial load
duke
parents:
diff changeset
869 int pipeline_res_cycles_index = pipeline_res_cycles_initializer(
a61af66fc99e Initial load
duke
parents:
diff changeset
870 fp_cpp, _pipeline, pipeline_res_cycles, pipeclass);
a61af66fc99e Initial load
duke
parents:
diff changeset
871
a61af66fc99e Initial load
duke
parents:
diff changeset
872 int pipeline_res_mask_index = pipeline_res_mask_initializer(
a61af66fc99e Initial load
duke
parents:
diff changeset
873 fp_cpp, _pipeline, pipeline_res_masks, pipeline_res_args, pipeclass);
a61af66fc99e Initial load
duke
parents:
diff changeset
874
a61af66fc99e Initial load
duke
parents:
diff changeset
875 #if 0
a61af66fc99e Initial load
duke
parents:
diff changeset
876 // Process the Resources
a61af66fc99e Initial load
duke
parents:
diff changeset
877 const PipeClassResourceForm *piperesource;
a61af66fc99e Initial load
duke
parents:
diff changeset
878
a61af66fc99e Initial load
duke
parents:
diff changeset
879 unsigned resources_used = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
880 unsigned exclusive_resources_used = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
881 unsigned resource_groups = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
882 for (pipeclass->_resUsage.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
883 (piperesource = (const PipeClassResourceForm *)pipeclass->_resUsage.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
884 int used_mask = _pipeline->_resdict[piperesource->_resource]->is_resource()->mask();
a61af66fc99e Initial load
duke
parents:
diff changeset
885 if (used_mask)
a61af66fc99e Initial load
duke
parents:
diff changeset
886 resource_groups++;
a61af66fc99e Initial load
duke
parents:
diff changeset
887 resources_used |= used_mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
888 if ((used_mask & (used_mask-1)) == 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
889 exclusive_resources_used |= used_mask;
a61af66fc99e Initial load
duke
parents:
diff changeset
890 }
a61af66fc99e Initial load
duke
parents:
diff changeset
891
a61af66fc99e Initial load
duke
parents:
diff changeset
892 if (resource_groups > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
893 fprintf(fp_cpp, "static const uint pipeline_res_or_masks_%03d[%d] = {",
a61af66fc99e Initial load
duke
parents:
diff changeset
894 pipeclass->_num, resource_groups);
a61af66fc99e Initial load
duke
parents:
diff changeset
895 for (pipeclass->_resUsage.reset(), i = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
896 (piperesource = (const PipeClassResourceForm *)pipeclass->_resUsage.iter()) != NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
897 i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
898 int used_mask = _pipeline->_resdict[piperesource->_resource]->is_resource()->mask();
a61af66fc99e Initial load
duke
parents:
diff changeset
899 if (used_mask) {
a61af66fc99e Initial load
duke
parents:
diff changeset
900 fprintf(fp_cpp, " 0x%0*x%c", resource_count, used_mask, i < (int)resource_groups ? ',' : ' ');
a61af66fc99e Initial load
duke
parents:
diff changeset
901 }
a61af66fc99e Initial load
duke
parents:
diff changeset
902 }
a61af66fc99e Initial load
duke
parents:
diff changeset
903 fprintf(fp_cpp, "};\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
904 }
a61af66fc99e Initial load
duke
parents:
diff changeset
905 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
906
a61af66fc99e Initial load
duke
parents:
diff changeset
907 // Create the pipeline class description
a61af66fc99e Initial load
duke
parents:
diff changeset
908 fprintf(fp_cpp, "static const Pipeline pipeline_class_%03d(",
a61af66fc99e Initial load
duke
parents:
diff changeset
909 pipeclass->_num);
a61af66fc99e Initial load
duke
parents:
diff changeset
910 if (maxWriteStage < 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
911 fprintf(fp_cpp, "(uint)stage_undefined");
a61af66fc99e Initial load
duke
parents:
diff changeset
912 else if (maxMoreInstrs == 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
913 fprintf(fp_cpp, "(uint)stage_%s", _pipeline->_stages.name(maxWriteStage));
a61af66fc99e Initial load
duke
parents:
diff changeset
914 else
a61af66fc99e Initial load
duke
parents:
diff changeset
915 fprintf(fp_cpp, "((uint)stage_%s)+%d", _pipeline->_stages.name(maxWriteStage), maxMoreInstrs);
a61af66fc99e Initial load
duke
parents:
diff changeset
916 fprintf(fp_cpp, ", %d, %s, %d, %d, %s, %s, %s, %s,\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
917 paramcount,
a61af66fc99e Initial load
duke
parents:
diff changeset
918 pipeclass->hasFixedLatency() ? "true" : "false",
a61af66fc99e Initial load
duke
parents:
diff changeset
919 pipeclass->fixedLatency(),
a61af66fc99e Initial load
duke
parents:
diff changeset
920 pipeclass->InstructionCount(),
a61af66fc99e Initial load
duke
parents:
diff changeset
921 pipeclass->hasBranchDelay() ? "true" : "false",
a61af66fc99e Initial load
duke
parents:
diff changeset
922 pipeclass->hasMultipleBundles() ? "true" : "false",
a61af66fc99e Initial load
duke
parents:
diff changeset
923 pipeclass->forceSerialization() ? "true" : "false",
a61af66fc99e Initial load
duke
parents:
diff changeset
924 pipeclass->mayHaveNoCode() ? "true" : "false" );
a61af66fc99e Initial load
duke
parents:
diff changeset
925 if (paramcount > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
926 fprintf(fp_cpp, "\n (enum machPipelineStages * const) pipeline_reads_%03d,\n ",
a61af66fc99e Initial load
duke
parents:
diff changeset
927 pipeline_reads_index+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
928 }
a61af66fc99e Initial load
duke
parents:
diff changeset
929 else
a61af66fc99e Initial load
duke
parents:
diff changeset
930 fprintf(fp_cpp, " NULL,");
a61af66fc99e Initial load
duke
parents:
diff changeset
931 fprintf(fp_cpp, " (enum machPipelineStages * const) pipeline_res_stages_%03d,\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
932 pipeline_res_stages_index+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
933 fprintf(fp_cpp, " (uint * const) pipeline_res_cycles_%03d,\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
934 pipeline_res_cycles_index+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
935 fprintf(fp_cpp, " Pipeline_Use(%s, (Pipeline_Use_Element *)",
a61af66fc99e Initial load
duke
parents:
diff changeset
936 pipeline_res_args.name(pipeline_res_mask_index));
a61af66fc99e Initial load
duke
parents:
diff changeset
937 if (strlen(pipeline_res_masks.name(pipeline_res_mask_index)) > 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
938 fprintf(fp_cpp, "&pipeline_res_mask_%03d[0]",
a61af66fc99e Initial load
duke
parents:
diff changeset
939 pipeline_res_mask_index+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
940 else
a61af66fc99e Initial load
duke
parents:
diff changeset
941 fprintf(fp_cpp, "NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
942 fprintf(fp_cpp, "));\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
943 }
a61af66fc99e Initial load
duke
parents:
diff changeset
944
a61af66fc99e Initial load
duke
parents:
diff changeset
945 // Generate the Node::latency method if _pipeline defined
a61af66fc99e Initial load
duke
parents:
diff changeset
946 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
947 fprintf(fp_cpp, "//------------------Inter-Instruction Latency--------------------------------\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
948 fprintf(fp_cpp, "uint Node::latency(uint i) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
949 if (_pipeline) {
a61af66fc99e Initial load
duke
parents:
diff changeset
950 #if 0
a61af66fc99e Initial load
duke
parents:
diff changeset
951 fprintf(fp_cpp, "#ifndef PRODUCT\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
952 fprintf(fp_cpp, " if (TraceOptoOutput) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
953 fprintf(fp_cpp, " tty->print(\"# %%4d->latency(%%d)\\n\", _idx, i);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
954 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
955 fprintf(fp_cpp, "#endif\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
956 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
957 fprintf(fp_cpp, " uint j;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
958 fprintf(fp_cpp, " // verify in legal range for inputs\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
959 fprintf(fp_cpp, " assert(i < len(), \"index not in range\");\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
960 fprintf(fp_cpp, " // verify input is not null\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
961 fprintf(fp_cpp, " Node *pred = in(i);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
962 fprintf(fp_cpp, " if (!pred)\n return %d;\n\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
963 non_operand_latency);
a61af66fc99e Initial load
duke
parents:
diff changeset
964 fprintf(fp_cpp, " if (pred->is_Proj())\n pred = pred->in(0);\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
965 fprintf(fp_cpp, " // if either node does not have pipeline info, use default\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
966 fprintf(fp_cpp, " const Pipeline *predpipe = pred->pipeline();\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
967 fprintf(fp_cpp, " assert(predpipe, \"no predecessor pipeline info\");\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
968 fprintf(fp_cpp, " if (predpipe->hasFixedLatency())\n return predpipe->fixedLatency();\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
969 fprintf(fp_cpp, " const Pipeline *currpipe = pipeline();\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
970 fprintf(fp_cpp, " assert(currpipe, \"no pipeline info\");\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
971 fprintf(fp_cpp, " if (!is_Mach())\n return %d;\n\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
972 node_latency);
a61af66fc99e Initial load
duke
parents:
diff changeset
973 fprintf(fp_cpp, " const MachNode *m = as_Mach();\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
974 fprintf(fp_cpp, " j = m->oper_input_base();\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
975 fprintf(fp_cpp, " if (i < j)\n return currpipe->functional_unit_latency(%d, predpipe);\n\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
976 non_operand_latency);
a61af66fc99e Initial load
duke
parents:
diff changeset
977 fprintf(fp_cpp, " // determine which operand this is in\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
978 fprintf(fp_cpp, " uint n = m->num_opnds();\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
979 fprintf(fp_cpp, " int delta = %d;\n\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
980 non_operand_latency);
a61af66fc99e Initial load
duke
parents:
diff changeset
981 fprintf(fp_cpp, " uint k;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
982 fprintf(fp_cpp, " for (k = 1; k < n; k++) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
983 fprintf(fp_cpp, " j += m->_opnds[k]->num_edges();\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
984 fprintf(fp_cpp, " if (i < j)\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
985 fprintf(fp_cpp, " break;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
986 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
987 fprintf(fp_cpp, " if (k < n)\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
988 fprintf(fp_cpp, " delta = currpipe->operand_latency(k,predpipe);\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
989 fprintf(fp_cpp, " return currpipe->functional_unit_latency(delta, predpipe);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
990 }
a61af66fc99e Initial load
duke
parents:
diff changeset
991 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
992 fprintf(fp_cpp, " // assert(false, \"pipeline functionality is not defined\");\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
993 fprintf(fp_cpp, " return %d;\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
994 non_operand_latency);
a61af66fc99e Initial load
duke
parents:
diff changeset
995 }
a61af66fc99e Initial load
duke
parents:
diff changeset
996 fprintf(fp_cpp, "}\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
997
a61af66fc99e Initial load
duke
parents:
diff changeset
998 // Output the list of nop nodes
a61af66fc99e Initial load
duke
parents:
diff changeset
999 fprintf(fp_cpp, "// Descriptions for emitting different functional unit nops\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 const char *nop;
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 int nopcnt = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 for ( _pipeline->_noplist.reset(); (nop = _pipeline->_noplist.iter()) != NULL; nopcnt++ );
a61af66fc99e Initial load
duke
parents:
diff changeset
1003
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 fprintf(fp_cpp, "void Bundle::initialize_nops(MachNode * nop_list[%d], Compile *C) {\n", nopcnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 int i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 for ( _pipeline->_noplist.reset(); (nop = _pipeline->_noplist.iter()) != NULL; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 fprintf(fp_cpp, " nop_list[%d] = (MachNode *) new (C) %sNode();\n", i, nop);
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 fprintf(fp_cpp, "};\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 fprintf(fp_cpp, "#ifndef PRODUCT\n");
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
1011 fprintf(fp_cpp, "void Bundle::dump(outputStream *st) const {\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 fprintf(fp_cpp, " static const char * bundle_flags[] = {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 fprintf(fp_cpp, " \"\",\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 fprintf(fp_cpp, " \"use nop delay\",\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 fprintf(fp_cpp, " \"use unconditional delay\",\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 fprintf(fp_cpp, " \"use conditional delay\",\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 fprintf(fp_cpp, " \"used in conditional delay\",\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 fprintf(fp_cpp, " \"used in unconditional delay\",\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 fprintf(fp_cpp, " \"used in all conditional delays\",\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 fprintf(fp_cpp, " };\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1021
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 fprintf(fp_cpp, " static const char *resource_names[%d] = {", _pipeline->_rescount);
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 for (i = 0; i < _pipeline->_rescount; i++)
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 fprintf(fp_cpp, " \"%s\"%c", _pipeline->_reslist.name(i), i < _pipeline->_rescount-1 ? ',' : ' ');
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 fprintf(fp_cpp, "};\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1026
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 // See if the same string is in the table
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 fprintf(fp_cpp, " bool needs_comma = false;\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 fprintf(fp_cpp, " if (_flags) {\n");
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
1030 fprintf(fp_cpp, " st->print(\"%%s\", bundle_flags[_flags]);\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 fprintf(fp_cpp, " needs_comma = true;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 fprintf(fp_cpp, " };\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 fprintf(fp_cpp, " if (instr_count()) {\n");
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
1034 fprintf(fp_cpp, " st->print(\"%%s%%d instr%%s\", needs_comma ? \", \" : \"\", instr_count(), instr_count() != 1 ? \"s\" : \"\");\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 fprintf(fp_cpp, " needs_comma = true;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 fprintf(fp_cpp, " };\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 fprintf(fp_cpp, " uint r = resources_used();\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 fprintf(fp_cpp, " if (r) {\n");
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
1039 fprintf(fp_cpp, " st->print(\"%%sresource%%s:\", needs_comma ? \", \" : \"\", (r & (r-1)) != 0 ? \"s\" : \"\");\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 fprintf(fp_cpp, " for (uint i = 0; i < %d; i++)\n", _pipeline->_rescount);
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 fprintf(fp_cpp, " if ((r & (1 << i)) != 0)\n");
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
1042 fprintf(fp_cpp, " st->print(\" %%s\", resource_names[i]);\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 fprintf(fp_cpp, " needs_comma = true;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 fprintf(fp_cpp, " };\n");
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
1045 fprintf(fp_cpp, " st->print(\"\\n\");\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 fprintf(fp_cpp, "}\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 fprintf(fp_cpp, "#endif\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1049
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 // ---------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 //------------------------------Utilities to build Instruction Classes--------
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 // ---------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1053
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 static void defineOut_RegMask(FILE *fp, const char *node, const char *regMask) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 fprintf(fp,"const RegMask &%sNode::out_RegMask() const { return (%s); }\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 node, regMask);
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1058
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1059 static void print_block_index(FILE *fp, int inst_position) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 assert( inst_position >= 0, "Instruction number less than zero");
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 fprintf(fp, "block_index");
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 if( inst_position != 0 ) {
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1063 fprintf(fp, " - %d", inst_position);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1066
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 // Scan the peepmatch and output a test for each instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 static void check_peepmatch_instruction_sequence(FILE *fp, PeepMatch *pmatch, PeepConstraint *pconstraint) {
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1069 int parent = -1;
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1070 int inst_position = 0;
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1071 const char* inst_name = NULL;
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1072 int input = 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 fprintf(fp, " // Check instruction sub-tree\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 pmatch->reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 for( pmatch->next_instruction( parent, inst_position, inst_name, input );
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 inst_name != NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1077 pmatch->next_instruction( parent, inst_position, inst_name, input ) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 // If this is not a placeholder
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 if( ! pmatch->is_placeholder() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 // Define temporaries 'inst#', based on parent and parent's input index
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 if( parent != -1 ) { // root was initialized
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 fprintf(fp, " // Identify previous instruction if inside this block\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 fprintf(fp, " if( ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 print_block_index(fp, inst_position);
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 fprintf(fp, " > 0 ) {\n Node *n = block->_nodes.at(");
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 print_block_index(fp, inst_position);
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1087 fprintf(fp, ");\n inst%d = (n->is_Mach()) ? ", inst_position);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 fprintf(fp, "n->as_Mach() : NULL;\n }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1090
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 // When not the root
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 // Test we have the correct instruction by comparing the rule.
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 if( parent != -1 ) {
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1094 fprintf(fp, " matches = matches && (inst%d != NULL) && (inst%d->rule() == %s_rule);\n",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 inst_position, inst_position, inst_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 // Check that user did not try to constrain a placeholder
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 assert( ! pconstraint->constrains_instruction(inst_position),
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 "fatal(): Can not constrain a placeholder instruction");
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1104
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 // Build mapping for register indices, num_edges to input
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 static void build_instruction_index_mapping( FILE *fp, FormDict &globals, PeepMatch *pmatch ) {
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1107 int parent = -1;
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1108 int inst_position = 0;
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1109 const char* inst_name = NULL;
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1110 int input = 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 fprintf(fp, " // Build map to register info\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 pmatch->reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 for( pmatch->next_instruction( parent, inst_position, inst_name, input );
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 inst_name != NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 pmatch->next_instruction( parent, inst_position, inst_name, input ) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 // If this is not a placeholder
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 if( ! pmatch->is_placeholder() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 // Define temporaries 'inst#', based on self's inst_position
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 InstructForm *inst = globals[inst_name]->is_instruction();
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 if( inst != NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 char inst_prefix[] = "instXXXX_";
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1122 sprintf(inst_prefix, "inst%d_", inst_position);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 char receiver[] = "instXXXX->";
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1124 sprintf(receiver, "inst%d->", inst_position);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 inst->index_temps( fp, globals, inst_prefix, receiver );
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1130
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 // Generate tests for the constraints
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 static void check_peepconstraints(FILE *fp, FormDict &globals, PeepMatch *pmatch, PeepConstraint *pconstraint) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 fprintf(fp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 fprintf(fp, " // Check constraints on sub-tree-leaves\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1135
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 // Build mapping from num_edges to local variables
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 build_instruction_index_mapping( fp, globals, pmatch );
a61af66fc99e Initial load
duke
parents:
diff changeset
1138
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 // Build constraint tests
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 if( pconstraint != NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 fprintf(fp, " matches = matches &&");
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 bool first_constraint = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 while( pconstraint != NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 // indentation and connecting '&&'
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 const char *indentation = " ";
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 fprintf(fp, "\n%s%s", indentation, (!first_constraint ? "&& " : " "));
a61af66fc99e Initial load
duke
parents:
diff changeset
1147
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 // Only have '==' relation implemented
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 if( strcmp(pconstraint->_relation,"==") != 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 assert( false, "Unimplemented()" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1152
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 // LEFT
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1154 int left_index = pconstraint->_left_inst;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 const char *left_op = pconstraint->_left_op;
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 // Access info on the instructions whose operands are compared
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 InstructForm *inst_left = globals[pmatch->instruction_name(left_index)]->is_instruction();
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 assert( inst_left, "Parser should guaranty this is an instruction");
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 int left_op_base = inst_left->oper_input_base(globals);
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 // Access info on the operands being compared
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 int left_op_index = inst_left->operand_position(left_op, Component::USE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 if( left_op_index == -1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 left_op_index = inst_left->operand_position(left_op, Component::DEF);
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 if( left_op_index == -1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 left_op_index = inst_left->operand_position(left_op, Component::USE_DEF);
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 assert( left_op_index != NameList::Not_in_list, "Did not find operand in instruction");
a61af66fc99e Initial load
duke
parents:
diff changeset
1169 ComponentList components_left = inst_left->_components;
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 const char *left_comp_type = components_left.at(left_op_index)->_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 OpClassForm *left_opclass = globals[left_comp_type]->is_opclass();
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 Form::InterfaceType left_interface_type = left_opclass->interface_type(globals);
a61af66fc99e Initial load
duke
parents:
diff changeset
1173
a61af66fc99e Initial load
duke
parents:
diff changeset
1174
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 // RIGHT
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 int right_op_index = -1;
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1177 int right_index = pconstraint->_right_inst;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 const char *right_op = pconstraint->_right_op;
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 if( right_index != -1 ) { // Match operand
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 // Access info on the instructions whose operands are compared
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 InstructForm *inst_right = globals[pmatch->instruction_name(right_index)]->is_instruction();
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 assert( inst_right, "Parser should guaranty this is an instruction");
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 int right_op_base = inst_right->oper_input_base(globals);
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 // Access info on the operands being compared
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 right_op_index = inst_right->operand_position(right_op, Component::USE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 if( right_op_index == -1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 right_op_index = inst_right->operand_position(right_op, Component::DEF);
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 if( right_op_index == -1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 right_op_index = inst_right->operand_position(right_op, Component::USE_DEF);
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 assert( right_op_index != NameList::Not_in_list, "Did not find operand in instruction");
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 ComponentList components_right = inst_right->_components;
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 const char *right_comp_type = components_right.at(right_op_index)->_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 OpClassForm *right_opclass = globals[right_comp_type]->is_opclass();
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 Form::InterfaceType right_interface_type = right_opclass->interface_type(globals);
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 assert( right_interface_type == left_interface_type, "Both must be same interface");
a61af66fc99e Initial load
duke
parents:
diff changeset
1198
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 } else { // Else match register
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 // assert( false, "should be a register" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1202
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 // Check for equivalence
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 // fprintf(fp, "phase->eqv( ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 // fprintf(fp, "inst%d->in(%d+%d) /* %s */, inst%d->in(%d+%d) /* %s */",
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 // left_index, left_op_base, left_op_index, left_op,
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 // right_index, right_op_base, right_op_index, right_op );
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 // fprintf(fp, ")");
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 switch( left_interface_type ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 case Form::register_interface: {
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 // Check that they are allocated to the same register
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 // Need parameter for index position if not result operand
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 char left_reg_index[] = ",instXXXX_idxXXXX";
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 if( left_op_index != 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 assert( (left_index <= 9999) && (left_op_index <= 9999), "exceed string size");
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 // Must have index into operands
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
1220 sprintf(left_reg_index,",inst%d_idx%d", (int)left_index, left_op_index);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 strcpy(left_reg_index, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 fprintf(fp, "(inst%d->_opnds[%d]->reg(ra_,inst%d%s) /* %d.%s */",
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 left_index, left_op_index, left_index, left_reg_index, left_index, left_op );
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 fprintf(fp, " == ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1227
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 if( right_index != -1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 char right_reg_index[18] = ",instXXXX_idxXXXX";
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 if( right_op_index != 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 assert( (right_index <= 9999) && (right_op_index <= 9999), "exceed string size");
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 // Must have index into operands
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
1233 sprintf(right_reg_index,",inst%d_idx%d", (int)right_index, right_op_index);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 strcpy(right_reg_index, "");
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 fprintf(fp, "/* %d.%s */ inst%d->_opnds[%d]->reg(ra_,inst%d%s)",
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 right_index, right_op, right_index, right_op_index, right_index, right_reg_index );
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 fprintf(fp, "%s_enc", right_op );
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 fprintf(fp,")");
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 case Form::constant_interface: {
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 // Compare the '->constant()' values
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 fprintf(fp, "(inst%d->_opnds[%d]->constant() /* %d.%s */",
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 left_index, left_op_index, left_index, left_op );
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 fprintf(fp, " == ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 fprintf(fp, "/* %d.%s */ inst%d->_opnds[%d]->constant())",
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 right_index, right_op, right_index, right_op_index );
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 case Form::memory_interface: {
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 // Compare 'base', 'index', 'scale', and 'disp'
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 // base
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 fprintf(fp, "( \n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 fprintf(fp, " (inst%d->_opnds[%d]->base(ra_,inst%d,inst%d_idx%d) /* %d.%s$$base */",
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 left_index, left_op_index, left_index, left_index, left_op_index, left_index, left_op );
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 fprintf(fp, " == ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 fprintf(fp, "/* %d.%s$$base */ inst%d->_opnds[%d]->base(ra_,inst%d,inst%d_idx%d)) &&\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1262 right_index, right_op, right_index, right_op_index, right_index, right_index, right_op_index );
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 // index
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 fprintf(fp, " (inst%d->_opnds[%d]->index(ra_,inst%d,inst%d_idx%d) /* %d.%s$$index */",
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 left_index, left_op_index, left_index, left_index, left_op_index, left_index, left_op );
a61af66fc99e Initial load
duke
parents:
diff changeset
1266 fprintf(fp, " == ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 fprintf(fp, "/* %d.%s$$index */ inst%d->_opnds[%d]->index(ra_,inst%d,inst%d_idx%d)) &&\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 right_index, right_op, right_index, right_op_index, right_index, right_index, right_op_index );
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 // scale
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 fprintf(fp, " (inst%d->_opnds[%d]->scale() /* %d.%s$$scale */",
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 left_index, left_op_index, left_index, left_op );
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 fprintf(fp, " == ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 fprintf(fp, "/* %d.%s$$scale */ inst%d->_opnds[%d]->scale()) &&\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 right_index, right_op, right_index, right_op_index );
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 // disp
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 fprintf(fp, " (inst%d->_opnds[%d]->disp(ra_,inst%d,inst%d_idx%d) /* %d.%s$$disp */",
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 left_index, left_op_index, left_index, left_index, left_op_index, left_index, left_op );
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 fprintf(fp, " == ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 fprintf(fp, "/* %d.%s$$disp */ inst%d->_opnds[%d]->disp(ra_,inst%d,inst%d_idx%d))\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 right_index, right_op, right_index, right_op_index, right_index, right_index, right_op_index );
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 fprintf(fp, ") \n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 case Form::conditional_interface: {
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 // Compare the condition code being tested
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 assert( false, "Unimplemented()" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 default: {
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 assert( false, "ShouldNotReachHere()" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1294
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 // Advance to next constraint
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 pconstraint = pconstraint->next();
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 first_constraint = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1299
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 fprintf(fp, ";\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1303
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 // // EXPERIMENTAL -- TEMPORARY code
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 // static Form::DataType get_operand_type(FormDict &globals, InstructForm *instr, const char *op_name ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 // int op_index = instr->operand_position(op_name, Component::USE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 // if( op_index == -1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 // op_index = instr->operand_position(op_name, Component::DEF);
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 // if( op_index == -1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 // op_index = instr->operand_position(op_name, Component::USE_DEF);
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 // assert( op_index != NameList::Not_in_list, "Did not find operand in instruction");
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 // ComponentList components_right = instr->_components;
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 // char *right_comp_type = components_right.at(op_index)->_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 // OpClassForm *right_opclass = globals[right_comp_type]->is_opclass();
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 // Form::InterfaceType right_interface_type = right_opclass->interface_type(globals);
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 // return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
1322
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 // Construct the new sub-tree
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 static void generate_peepreplace( FILE *fp, FormDict &globals, PeepMatch *pmatch, PeepConstraint *pconstraint, PeepReplace *preplace, int max_position ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 fprintf(fp, " // IF instructions and constraints matched\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 fprintf(fp, " if( matches ) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 fprintf(fp, " // generate the new sub-tree\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 fprintf(fp, " assert( true, \"Debug stopping point\");\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 if( preplace != NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 // Get the root of the new sub-tree
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 const char *root_inst = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 preplace->next_instruction(root_inst);
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 InstructForm *root_form = globals[root_inst]->is_instruction();
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 assert( root_form != NULL, "Replacement instruction was not previously defined");
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 fprintf(fp, " %sNode *root = new (C) %sNode();\n", root_inst, root_inst);
a61af66fc99e Initial load
duke
parents:
diff changeset
1336
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1337 int inst_num;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 const char *op_name;
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 int opnds_index = 0; // define result operand
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 // Then install the use-operands for the new sub-tree
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 // preplace->reset(); // reset breaks iteration
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 for( preplace->next_operand( inst_num, op_name );
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 op_name != NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 preplace->next_operand( inst_num, op_name ) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 InstructForm *inst_form;
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 inst_form = globals[pmatch->instruction_name(inst_num)]->is_instruction();
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 assert( inst_form, "Parser should guaranty this is an instruction");
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 int inst_op_num = inst_form->operand_position(op_name, Component::USE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 if( inst_op_num == NameList::Not_in_list )
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 inst_op_num = inst_form->operand_position(op_name, Component::USE_DEF);
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 assert( inst_op_num != NameList::Not_in_list, "Did not find operand as USE");
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 // find the name of the OperandForm from the local name
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 const Form *form = inst_form->_localNames[op_name];
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 OperandForm *op_form = form->is_operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 if( opnds_index == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 // Initial setup of new instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 fprintf(fp, " // ----- Initial setup -----\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 // Add control edge for this node
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 fprintf(fp, " root->add_req(_in[0]); // control edge\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 // Add unmatched edges from root of match tree
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 int op_base = root_form->oper_input_base(globals);
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 for( int unmatched_edge = 1; unmatched_edge < op_base; ++unmatched_edge ) {
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1364 fprintf(fp, " root->add_req(inst%d->in(%d)); // unmatched ideal edge\n",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1365 inst_num, unmatched_edge);
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 // If new instruction captures bottom type
1541
b5fdf39b9749 6953576: bottom_type for matched AddPNodes doesn't always agree with ideal
never
parents: 1489
diff changeset
1368 if( root_form->captures_bottom_type(globals) ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 // Get bottom type from instruction whose result we are replacing
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1370 fprintf(fp, " root->_bottom_type = inst%d->bottom_type();\n", inst_num);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 // Define result register and result operand
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1373 fprintf(fp, " ra_->add_reference(root, inst%d);\n", inst_num);
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1374 fprintf(fp, " ra_->set_oop (root, ra_->is_oop(inst%d));\n", inst_num);
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1375 fprintf(fp, " ra_->set_pair(root->_idx, ra_->get_reg_second(inst%d), ra_->get_reg_first(inst%d));\n", inst_num, inst_num);
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1376 fprintf(fp, " root->_opnds[0] = inst%d->_opnds[0]->clone(C); // result\n", inst_num);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 fprintf(fp, " // ----- Done with initial setup -----\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 if( (op_form == NULL) || (op_form->is_base_constant(globals) == Form::none) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 // Do not have ideal edges for constants after matching
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1381 fprintf(fp, " for( unsigned x%d = inst%d_idx%d; x%d < inst%d_idx%d; x%d++ )\n",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 inst_op_num, inst_num, inst_op_num,
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 inst_op_num, inst_num, inst_op_num+1, inst_op_num );
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1384 fprintf(fp, " root->add_req( inst%d->in(x%d) );\n",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 inst_num, inst_op_num );
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 fprintf(fp, " // no ideal edge for constants after matching\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 }
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1389 fprintf(fp, " root->_opnds[%d] = inst%d->_opnds[%d]->clone(C);\n",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1390 opnds_index, inst_num, inst_op_num );
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 ++opnds_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 }else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1395 // Replacing subtree with empty-tree
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 assert( false, "ShouldNotReachHere();");
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1398
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 // Return the new sub-tree
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 fprintf(fp, " deleted = %d;\n", max_position+1 /*zero to one based*/);
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 fprintf(fp, " return root; // return new root;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 fprintf(fp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1404
a61af66fc99e Initial load
duke
parents:
diff changeset
1405
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 // Define the Peephole method for an instruction node
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 void ArchDesc::definePeephole(FILE *fp, InstructForm *node) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 // Generate Peephole function header
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 fprintf(fp, "MachNode *%sNode::peephole( Block *block, int block_index, PhaseRegAlloc *ra_, int &deleted, Compile* C ) {\n", node->_ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 fprintf(fp, " bool matches = true;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1411
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 // Identify the maximum instruction position,
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 // generate temporaries that hold current instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 // MachNode *inst0 = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 // ...
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 // MachNode *instMAX = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 int max_position = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 Peephole *peep;
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 for( peep = node->peepholes(); peep != NULL; peep = peep->next() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 PeepMatch *pmatch = peep->match();
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 assert( pmatch != NULL, "fatal(), missing peepmatch rule");
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 if( max_position < pmatch->max_position() ) max_position = pmatch->max_position();
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 for( int i = 0; i <= max_position; ++i ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 if( i == 0 ) {
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1428 fprintf(fp, " MachNode *inst0 = this;\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 fprintf(fp, " MachNode *inst%d = NULL;\n", i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1433
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 // For each peephole rule in architecture description
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 // Construct a test for the desired instruction sub-tree
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 // then check the constraints
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 // If these match, Generate the new subtree
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 for( peep = node->peepholes(); peep != NULL; peep = peep->next() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 int peephole_number = peep->peephole_number();
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 PeepMatch *pmatch = peep->match();
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 PeepConstraint *pconstraint = peep->constraints();
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 PeepReplace *preplace = peep->replacement();
a61af66fc99e Initial load
duke
parents:
diff changeset
1443
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 // Root of this peephole is the current MachNode
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 assert( true, // %%name?%% strcmp( node->_ident, pmatch->name(0) ) == 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 "root of PeepMatch does not match instruction");
a61af66fc99e Initial load
duke
parents:
diff changeset
1447
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 // Make each peephole rule individually selectable
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 fprintf(fp, " if( (OptoPeepholeAt == -1) || (OptoPeepholeAt==%d) ) {\n", peephole_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 fprintf(fp, " matches = true;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 // Scan the peepmatch and output a test for each instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 check_peepmatch_instruction_sequence( fp, pmatch, pconstraint );
a61af66fc99e Initial load
duke
parents:
diff changeset
1453
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 // Check constraints and build replacement inside scope
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 fprintf(fp, " // If instruction subtree matches\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 fprintf(fp, " if( matches ) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1457
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 // Generate tests for the constraints
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 check_peepconstraints( fp, _globalNames, pmatch, pconstraint );
a61af66fc99e Initial load
duke
parents:
diff changeset
1460
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 // Construct the new sub-tree
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 generate_peepreplace( fp, _globalNames, pmatch, pconstraint, preplace, max_position );
a61af66fc99e Initial load
duke
parents:
diff changeset
1463
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 // End of scope for this peephole's constraints
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 fprintf(fp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 // Closing brace '}' to make each peephole rule individually selectable
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 fprintf(fp, " } // end of peephole rule #%d\n", peephole_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 fprintf(fp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1470
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 fprintf(fp, " return NULL; // No peephole rules matched\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 fprintf(fp, "}\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 fprintf(fp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1475
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 // Define the Expand method for an instruction node
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 unsigned cnt = 0; // Count nodes we have expand into
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 unsigned i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1480
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 // Generate Expand function header
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
1482 fprintf(fp, "MachNode* %sNode::Expand(State* state, Node_List& proj_list, Node* mem) {\n", node->_ident);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
1483 fprintf(fp, " Compile* C = Compile::current();\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 // Generate expand code
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 if( node->expands() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 const char *opid;
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 int new_pos, exp_pos;
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 const char *new_id = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1489 const Form *frm = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 InstructForm *new_inst = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 OperandForm *new_oper = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 unsigned numo = node->num_opnds() +
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 node->_exprule->_newopers.count();
a61af66fc99e Initial load
duke
parents:
diff changeset
1494
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 // If necessary, generate any operands created in expand rule
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 if (node->_exprule->_newopers.count()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 for(node->_exprule->_newopers.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 (new_id = node->_exprule->_newopers.iter()) != NULL; cnt++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 frm = node->_localNames[new_id];
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 assert(frm, "Invalid entry in new operands list of expand rule");
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 new_oper = frm->is_operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 char *tmp = (char *)node->_exprule->_newopconst[new_id];
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 if (tmp == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 fprintf(fp," MachOper *op%d = new (C) %sOper();\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 cnt, new_oper->_ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 fprintf(fp," MachOper *op%d = new (C) %sOper(%s);\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 cnt, new_oper->_ident, tmp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 cnt = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 // Generate the temps to use for DAG building
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 for(i = 0; i < numo; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 if (i < node->num_opnds()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 fprintf(fp," MachNode *tmp%d = this;\n", i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 fprintf(fp," MachNode *tmp%d = NULL;\n", i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 // Build mapping from num_edges to local variables
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 fprintf(fp," unsigned num0 = 0;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 for( i = 1; i < node->num_opnds(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 fprintf(fp," unsigned num%d = opnd_array(%d)->num_edges();\n",i,i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1528
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 // Build a mapping from operand index to input edges
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 fprintf(fp," unsigned idx0 = oper_input_base();\n");
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
1531
1203
844a9d73ec22 6916644: C2 compiler crash on x86
never
parents: 785
diff changeset
1532 // The order in which the memory input is added to a node is very
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
1533 // strange. Store nodes get a memory input before Expand is
1203
844a9d73ec22 6916644: C2 compiler crash on x86
never
parents: 785
diff changeset
1534 // called and other nodes get it afterwards or before depending on
844a9d73ec22 6916644: C2 compiler crash on x86
never
parents: 785
diff changeset
1535 // match order so oper_input_base is wrong during expansion. This
844a9d73ec22 6916644: C2 compiler crash on x86
never
parents: 785
diff changeset
1536 // code adjusts it so that expansion will work correctly.
844a9d73ec22 6916644: C2 compiler crash on x86
never
parents: 785
diff changeset
1537 int has_memory_edge = node->_matrule->needs_ideal_memory_edge(_globalNames);
844a9d73ec22 6916644: C2 compiler crash on x86
never
parents: 785
diff changeset
1538 if (has_memory_edge) {
844a9d73ec22 6916644: C2 compiler crash on x86
never
parents: 785
diff changeset
1539 fprintf(fp," if (mem == (Node*)1) {\n");
844a9d73ec22 6916644: C2 compiler crash on x86
never
parents: 785
diff changeset
1540 fprintf(fp," idx0--; // Adjust base because memory edge hasn't been inserted yet\n");
844a9d73ec22 6916644: C2 compiler crash on x86
never
parents: 785
diff changeset
1541 fprintf(fp," }\n");
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
1542 }
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
1543
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 for( i = 0; i < node->num_opnds(); i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 fprintf(fp," unsigned idx%d = idx%d + num%d;\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 i+1,i,i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1548
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 // Declare variable to hold root of expansion
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 fprintf(fp," MachNode *result = NULL;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1551
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 // Iterate over the instructions 'node' expands into
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 ExpandRule *expand = node->_exprule;
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 NameAndList *expand_instr = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 for(expand->reset_instructions();
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 (expand_instr = expand->iter_instructions()) != NULL; cnt++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 new_id = expand_instr->name();
a61af66fc99e Initial load
duke
parents:
diff changeset
1558
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 InstructForm* expand_instruction = (InstructForm*)globalAD->globalNames()[new_id];
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 if (expand_instruction->has_temps()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 globalAD->syntax_err(node->_linenum, "In %s: expand rules using instructs with TEMPs aren't supported: %s",
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 node->_ident, new_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1564
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 // Build the node for the instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 fprintf(fp,"\n %sNode *n%d = new (C) %sNode();\n", new_id, cnt, new_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 // Add control edge for this node
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 fprintf(fp," n%d->add_req(_in[0]);\n", cnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 // Build the operand for the value this node defines.
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 Form *form = (Form*)_globalNames[new_id];
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 assert( form, "'new_id' must be a defined form name");
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 // Grab the InstructForm for the new instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
1573 new_inst = form->is_instruction();
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 assert( new_inst, "'new_id' must be an instruction name");
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 if( node->is_ideal_if() && new_inst->is_ideal_if() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 fprintf(fp, " ((MachIfNode*)n%d)->_prob = _prob;\n",cnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 fprintf(fp, " ((MachIfNode*)n%d)->_fcnt = _fcnt;\n",cnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1579
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 if( node->is_ideal_fastlock() && new_inst->is_ideal_fastlock() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 fprintf(fp, " ((MachFastLockNode*)n%d)->_counters = _counters;\n",cnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1583
6802
0702f188baeb 7200233: C2: can't use expand rules for vector instruction rules
kvn
parents: 6725
diff changeset
1584 // Fill in the bottom_type where requested
0702f188baeb 7200233: C2: can't use expand rules for vector instruction rules
kvn
parents: 6725
diff changeset
1585 if (node->captures_bottom_type(_globalNames) &&
0702f188baeb 7200233: C2: can't use expand rules for vector instruction rules
kvn
parents: 6725
diff changeset
1586 new_inst->captures_bottom_type(_globalNames)) {
0702f188baeb 7200233: C2: can't use expand rules for vector instruction rules
kvn
parents: 6725
diff changeset
1587 fprintf(fp, " ((MachTypeNode*)n%d)->_bottom_type = bottom_type();\n", cnt);
0702f188baeb 7200233: C2: can't use expand rules for vector instruction rules
kvn
parents: 6725
diff changeset
1588 }
0702f188baeb 7200233: C2: can't use expand rules for vector instruction rules
kvn
parents: 6725
diff changeset
1589
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 const char *resultOper = new_inst->reduce_result();
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 fprintf(fp," n%d->set_opnd_array(0, state->MachOperGenerator( %s, C ));\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 cnt, machOperEnum(resultOper));
a61af66fc99e Initial load
duke
parents:
diff changeset
1593
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 // get the formal operand NameList
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 NameList *formal_lst = &new_inst->_parameters;
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 formal_lst->reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
1597
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 // Handle any memory operand
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 int memory_operand = new_inst->memory_operand(_globalNames);
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 if( memory_operand != InstructForm::NO_MEMORY_OPERAND ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 int node_mem_op = node->memory_operand(_globalNames);
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 assert( node_mem_op != InstructForm::NO_MEMORY_OPERAND,
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 "expand rule member needs memory but top-level inst doesn't have any" );
1203
844a9d73ec22 6916644: C2 compiler crash on x86
never
parents: 785
diff changeset
1604 if (has_memory_edge) {
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
1605 // Copy memory edge
1203
844a9d73ec22 6916644: C2 compiler crash on x86
never
parents: 785
diff changeset
1606 fprintf(fp," if (mem != (Node*)1) {\n");
844a9d73ec22 6916644: C2 compiler crash on x86
never
parents: 785
diff changeset
1607 fprintf(fp," n%d->add_req(_in[1]);\t// Add memory edge\n", cnt);
844a9d73ec22 6916644: C2 compiler crash on x86
never
parents: 785
diff changeset
1608 fprintf(fp," }\n");
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
1609 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1611
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 // Iterate over the new instruction's operands
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
1613 int prev_pos = -1;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1614 for( expand_instr->reset(); (opid = expand_instr->iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 // Use 'parameter' at current position in list of new instruction's formals
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 // instead of 'opid' when looking up info internal to new_inst
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 const char *parameter = formal_lst->iter();
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 // Check for an operand which is created in the expand rule
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 if ((exp_pos = node->_exprule->_newopers.index(opid)) != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1620 new_pos = new_inst->operand_position(parameter,Component::USE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 exp_pos += node->num_opnds();
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 // If there is no use of the created operand, just skip it
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
1623 if (new_pos != NameList::Not_in_list) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 //Copy the operand from the original made above
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 fprintf(fp," n%d->set_opnd_array(%d, op%d->clone(C)); // %s\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 cnt, new_pos, exp_pos-node->num_opnds(), opid);
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 // Check for who defines this operand & add edge if needed
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 fprintf(fp," if(tmp%d != NULL)\n", exp_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 fprintf(fp," n%d->add_req(tmp%d);\n", cnt, exp_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 // Use operand name to get an index into instruction component list
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 // ins = (InstructForm *) _globalNames[new_id];
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 exp_pos = node->operand_position_format(opid);
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 assert(exp_pos != -1, "Bad expand rule");
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
1637 if (prev_pos > exp_pos && expand_instruction->_matrule != NULL) {
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
1638 // For the add_req calls below to work correctly they need
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
1639 // to added in the same order that a match would add them.
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
1640 // This means that they would need to be in the order of
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
1641 // the components list instead of the formal parameters.
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
1642 // This is a sort of hidden invariant that previously
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
1643 // wasn't checked and could lead to incorrectly
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
1644 // constructed nodes.
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
1645 syntax_err(node->_linenum, "For expand in %s to work, parameter declaration order in %s must follow matchrule\n",
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
1646 node->_ident, new_inst->_ident);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
1647 }
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
1648 prev_pos = exp_pos;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1649
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 new_pos = new_inst->operand_position(parameter,Component::USE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 if (new_pos != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 // Copy the operand from the ExpandNode to the new node
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 fprintf(fp," n%d->set_opnd_array(%d, opnd_array(%d)->clone(C)); // %s\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 cnt, new_pos, exp_pos, opid);
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 // For each operand add appropriate input edges by looking at tmp's
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 fprintf(fp," if(tmp%d == this) {\n", exp_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 // Grab corresponding edges from ExpandNode and insert them here
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 fprintf(fp," for(unsigned i = 0; i < num%d; i++) {\n", exp_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 fprintf(fp," n%d->add_req(_in[i + idx%d]);\n", cnt, exp_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 fprintf(fp," }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 fprintf(fp," }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 // This value is generated by one of the new instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 fprintf(fp," else n%d->add_req(tmp%d);\n", cnt, exp_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1666
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 // Update the DAG tmp's for values defined by this instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 int new_def_pos = new_inst->operand_position(parameter,Component::DEF);
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 Effect *eform = (Effect *)new_inst->_effects[parameter];
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 // If this operand is a definition in either an effects rule
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 // or a match rule
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 if((eform) && (is_def(eform->_use_def))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 // Update the temp associated with this operand
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 fprintf(fp," tmp%d = n%d;\n", exp_pos, cnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 else if( new_def_pos != -1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 // Instruction defines a value but user did not declare it
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 // in the 'effect' clause
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 fprintf(fp," tmp%d = n%d;\n", exp_pos, cnt);
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 } // done iterating over a new instruction's operands
a61af66fc99e Initial load
duke
parents:
diff changeset
1682
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 // Invoke Expand() for the newly created instruction.
1203
844a9d73ec22 6916644: C2 compiler crash on x86
never
parents: 785
diff changeset
1684 fprintf(fp," result = n%d->Expand( state, proj_list, mem );\n", cnt);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 assert( !new_inst->expands(), "Do not have complete support for recursive expansion");
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 } // done iterating over new instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 fprintf(fp,"\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 } // done generating expand rule
a61af66fc99e Initial load
duke
parents:
diff changeset
1689
2254
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1690 // Generate projections for instruction's additional DEFs and KILLs
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1691 if( ! node->expands() && (node->needs_projections() || node->has_temps())) {
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1692 // Get string representing the MachNode that projections point at
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1693 const char *machNode = "this";
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1694 // Generate the projections
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1695 fprintf(fp," // Add projection edges for additional defs or kills\n");
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1696
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1697 // Examine each component to see if it is a DEF or KILL
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1698 node->_components.reset();
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1699 // Skip the first component, if already handled as (SET dst (...))
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1700 Component *comp = NULL;
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1701 // For kills, the choice of projection numbers is arbitrary
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1702 int proj_no = 1;
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1703 bool declared_def = false;
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1704 bool declared_kill = false;
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1705
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1706 while( (comp = node->_components.iter()) != NULL ) {
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1707 // Lookup register class associated with operand type
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1708 Form *form = (Form*)_globalNames[comp->_type];
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1709 assert( form, "component type must be a defined form");
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1710 OperandForm *op = form->is_operand();
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1711
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1712 if (comp->is(Component::TEMP)) {
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1713 fprintf(fp, " // TEMP %s\n", comp->_name);
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1714 if (!declared_def) {
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1715 // Define the variable "def" to hold new MachProjNodes
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1716 fprintf(fp, " MachTempNode *def;\n");
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1717 declared_def = true;
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1718 }
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1719 if (op && op->_interface && op->_interface->is_RegInterface()) {
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1720 fprintf(fp," def = new (C) MachTempNode(state->MachOperGenerator( %s, C ));\n",
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1721 machOperEnum(op->_ident));
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1722 fprintf(fp," add_req(def);\n");
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1723 // The operand for TEMP is already constructed during
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1724 // this mach node construction, see buildMachNode().
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1725 //
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1726 // int idx = node->operand_position_format(comp->_name);
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1727 // fprintf(fp," set_opnd_array(%d, state->MachOperGenerator( %s, C ));\n",
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1728 // idx, machOperEnum(op->_ident));
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1729 } else {
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1730 assert(false, "can't have temps which aren't registers");
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1731 }
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1732 } else if (comp->isa(Component::KILL)) {
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1733 fprintf(fp, " // DEF/KILL %s\n", comp->_name);
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1734
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1735 if (!declared_kill) {
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1736 // Define the variable "kill" to hold new MachProjNodes
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1737 fprintf(fp, " MachProjNode *kill;\n");
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1738 declared_kill = true;
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1739 }
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1740
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1741 assert( op, "Support additional KILLS for base operands");
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1742 const char *regmask = reg_mask(*op);
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1743 const char *ideal_type = op->ideal_type(_globalNames, _register);
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1744
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1745 if (!op->is_bound_register()) {
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1746 syntax_err(node->_linenum, "In %s only bound registers can be killed: %s %s\n",
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1747 node->_ident, comp->_type, comp->_name);
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1748 }
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1749
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1750 fprintf(fp," kill = ");
6804
e626685e9f6c 7193318: C2: remove number of inputs requirement from Node's new operator
kvn
parents: 6802
diff changeset
1751 fprintf(fp,"new (C) MachProjNode( %s, %d, (%s), Op_%s );\n",
2254
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1752 machNode, proj_no++, regmask, ideal_type);
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1753 fprintf(fp," proj_list.push(kill);\n");
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1754 }
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1755 }
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1756 }
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1757
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
1758 if( !node->expands() && node->_matrule != NULL ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 // Remove duplicated operands and inputs which use the same name.
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 // Seach through match operands for the same name usage.
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 uint cur_num_opnds = node->num_opnds();
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 if( cur_num_opnds > 1 && cur_num_opnds != node->num_unique_opnds() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 Component *comp = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 // Build mapping from num_edges to local variables
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 fprintf(fp," unsigned num0 = 0;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 for( i = 1; i < cur_num_opnds; i++ ) {
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
1767 fprintf(fp," unsigned num%d = opnd_array(%d)->num_edges();",i,i);
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
1768 fprintf(fp, " \t// %s\n", node->opnd_ident(i));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 // Build a mapping from operand index to input edges
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 fprintf(fp," unsigned idx0 = oper_input_base();\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 for( i = 0; i < cur_num_opnds; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 fprintf(fp," unsigned idx%d = idx%d + num%d;\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 i+1,i,i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1776
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 uint new_num_opnds = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1778 node->_components.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
1779 // Skip first unique operands.
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 for( i = 1; i < cur_num_opnds; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 comp = node->_components.iter();
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 if( (int)i != node->unique_opnds_idx(i) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1783 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 new_num_opnds++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 // Replace not unique operands with next unique operands.
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 for( ; i < cur_num_opnds; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 comp = node->_components.iter();
a61af66fc99e Initial load
duke
parents:
diff changeset
1790 int j = node->unique_opnds_idx(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 // unique_opnds_idx(i) is unique if unique_opnds_idx(j) is not unique.
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 if( j != node->unique_opnds_idx(j) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 fprintf(fp," set_opnd_array(%d, opnd_array(%d)->clone(C)); // %s\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 new_num_opnds, i, comp->_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 // delete not unique edges here
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 fprintf(fp," for(unsigned i = 0; i < num%d; i++) {\n", i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 fprintf(fp," set_req(i + idx%d, _in[i + idx%d]);\n", new_num_opnds, i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 fprintf(fp," }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 fprintf(fp," num%d = num%d;\n", new_num_opnds, i);
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 fprintf(fp," idx%d = idx%d + num%d;\n", new_num_opnds+1, new_num_opnds, new_num_opnds);
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 new_num_opnds++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 // delete the rest of edges
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 fprintf(fp," for(int i = idx%d - 1; i >= (int)idx%d; i--) {\n", cur_num_opnds, new_num_opnds);
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1806 fprintf(fp," del_req(i);\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 fprintf(fp," }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 fprintf(fp," _num_opnds = %d;\n", new_num_opnds);
785
2056494941db 6814842: Load shortening optimizations
twisti
parents: 624
diff changeset
1809 assert(new_num_opnds == node->num_unique_opnds(), "what?");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1812
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
1813 // If the node is a MachConstantNode, insert the MachConstantBaseNode edge.
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
1814 // NOTE: this edge must be the last input (see MachConstantNode::mach_constant_base_node_input).
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
1815 if (node->is_mach_constant()) {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
1816 fprintf(fp," add_req(C->mach_constant_base_node());\n");
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
1817 }
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
1818
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 fprintf(fp,"\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 if( node->expands() ) {
603
dbbe28fc66b5 6778669: Patch from Red Hat -- fixes compilation errors
twisti
parents: 415
diff changeset
1821 fprintf(fp," return result;\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 fprintf(fp," return this;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1825 fprintf(fp,"}\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 fprintf(fp,"\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1828
a61af66fc99e Initial load
duke
parents:
diff changeset
1829
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 //------------------------------Emit Routines----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 // Special classes and routines for defining node emit routines which output
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 // target specific instruction object encodings.
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 // Define the ___Node::emit() routine
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 // (1) void ___Node::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 // (2) // ... encoding defined by user
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 // (3)
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 // (4) }
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1840
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 class DefineEmitState {
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1843 enum reloc_format { RELOC_NONE = -1,
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 RELOC_IMMEDIATE = 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 RELOC_DISP = 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
1846 RELOC_CALL_DISP = 2 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 enum literal_status{ LITERAL_NOT_SEEN = 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 LITERAL_SEEN = 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 LITERAL_ACCESSED = 2,
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 LITERAL_OUTPUT = 3 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 // Temporaries that describe current operand
a61af66fc99e Initial load
duke
parents:
diff changeset
1852 bool _cleared;
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 OpClassForm *_opclass;
a61af66fc99e Initial load
duke
parents:
diff changeset
1854 OperandForm *_operand;
a61af66fc99e Initial load
duke
parents:
diff changeset
1855 int _operand_idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1856 const char *_local_name;
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 const char *_operand_name;
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 bool _doing_disp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 bool _doing_constant;
a61af66fc99e Initial load
duke
parents:
diff changeset
1860 Form::DataType _constant_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 DefineEmitState::literal_status _constant_status;
a61af66fc99e Initial load
duke
parents:
diff changeset
1862 DefineEmitState::literal_status _reg_status;
a61af66fc99e Initial load
duke
parents:
diff changeset
1863 bool _doing_emit8;
a61af66fc99e Initial load
duke
parents:
diff changeset
1864 bool _doing_emit_d32;
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 bool _doing_emit_d16;
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 bool _doing_emit_hi;
a61af66fc99e Initial load
duke
parents:
diff changeset
1867 bool _doing_emit_lo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1868 bool _may_reloc;
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 reloc_format _reloc_form;
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 const char * _reloc_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
1871 bool _processing_noninput;
a61af66fc99e Initial load
duke
parents:
diff changeset
1872
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 NameList _strings_to_emit;
a61af66fc99e Initial load
duke
parents:
diff changeset
1874
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 // Stable state, set by constructor
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 ArchDesc &_AD;
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 FILE *_fp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 EncClass &_encoding;
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 InsEncode &_ins_encode;
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 InstructForm &_inst;
a61af66fc99e Initial load
duke
parents:
diff changeset
1881
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 DefineEmitState(FILE *fp, ArchDesc &AD, EncClass &encoding,
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 InsEncode &ins_encode, InstructForm &inst)
a61af66fc99e Initial load
duke
parents:
diff changeset
1885 : _AD(AD), _fp(fp), _encoding(encoding), _ins_encode(ins_encode), _inst(inst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1886 clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1887 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1888
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 void clear() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1890 _cleared = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 _opclass = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 _operand = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 _operand_idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 _local_name = "";
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 _operand_name = "";
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 _doing_disp = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 _doing_constant= false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 _constant_type = Form::none;
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 _constant_status = LITERAL_NOT_SEEN;
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 _reg_status = LITERAL_NOT_SEEN;
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 _doing_emit8 = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1902 _doing_emit_d32= false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1903 _doing_emit_d16= false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1904 _doing_emit_hi = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 _doing_emit_lo = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 _may_reloc = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 _reloc_form = RELOC_NONE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 _reloc_type = AdlcVMDeps::none_reloc_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 _strings_to_emit.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1911
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 // Track necessary state when identifying a replacement variable
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
1913 // @arg rep_var: The formal parameter of the encoding.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 void update_state(const char *rep_var) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 // A replacement variable or one of its subfields
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 // Obtain replacement variable from list
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 if ( (*rep_var) != '$' ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 // A replacement variable, '$' prefix
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 // check_rep_var( rep_var );
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 // No state needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 assert( _opclass == NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 "'primary', 'secondary' and 'tertiary' don't follow operand.");
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
1924 }
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
1925 else if ((strcmp(rep_var, "constanttablebase") == 0) ||
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
1926 (strcmp(rep_var, "constantoffset") == 0) ||
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
1927 (strcmp(rep_var, "constantaddress") == 0)) {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
1928 if (!_inst.is_mach_constant()) {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
1929 _AD.syntax_err(_encoding._linenum,
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
1930 "Replacement variable %s not allowed in instruct %s (only in MachConstantNode).\n",
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
1931 rep_var, _encoding._name);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
1932 }
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
1933 }
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
1934 else {
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
1935 // Lookup its position in (formal) parameter list of encoding
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 int param_no = _encoding.rep_var_index(rep_var);
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 if ( param_no == -1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1938 _AD.syntax_err( _encoding._linenum,
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 "Replacement variable %s not found in enc_class %s.\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1940 rep_var, _encoding._name);
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1942
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 // Lookup the corresponding ins_encode parameter
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
1944 // This is the argument (actual parameter) to the encoding.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 const char *inst_rep_var = _ins_encode.rep_var_name(_inst, param_no);
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 if (inst_rep_var == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 _AD.syntax_err( _ins_encode._linenum,
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 "Parameter %s not passed to enc_class %s from instruct %s.\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1949 rep_var, _encoding._name, _inst._ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1951
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 // Check if instruction's actual parameter is a local name in the instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 const Form *local = _inst._localNames[inst_rep_var];
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 OpClassForm *opc = (local != NULL) ? local->is_opclass() : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 // Note: assert removed to allow constant and symbolic parameters
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 // assert( opc, "replacement variable was not found in local names");
a61af66fc99e Initial load
duke
parents:
diff changeset
1957 // Lookup the index position iff the replacement variable is a localName
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 int idx = (opc != NULL) ? _inst.operand_position_format(inst_rep_var) : -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1959
a61af66fc99e Initial load
duke
parents:
diff changeset
1960 if ( idx != -1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 // This is a local in the instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 // Update local state info.
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 _opclass = opc;
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 _operand_idx = idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 _local_name = rep_var;
a61af66fc99e Initial load
duke
parents:
diff changeset
1966 _operand_name = inst_rep_var;
a61af66fc99e Initial load
duke
parents:
diff changeset
1967
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 // !!!!!
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 // Do not support consecutive operands.
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 assert( _operand == NULL, "Unimplemented()");
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 _operand = opc->is_operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 else if( ADLParser::is_literal_constant(inst_rep_var) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 // Instruction provided a constant expression
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 // Check later that encoding specifies $$$constant to resolve as constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1976 _constant_status = LITERAL_SEEN;
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1978 else if( Opcode::as_opcode_type(inst_rep_var) != Opcode::NOT_AN_OPCODE ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 // Instruction provided an opcode: "primary", "secondary", "tertiary"
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 // Check later that encoding specifies $$$constant to resolve as constant
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 _constant_status = LITERAL_SEEN;
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 else if((_AD.get_registers() != NULL ) && (_AD.get_registers()->getRegDef(inst_rep_var) != NULL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1984 // Instruction provided a literal register name for this parameter
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 // Check that encoding specifies $$$reg to resolve.as register.
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 _reg_status = LITERAL_SEEN;
a61af66fc99e Initial load
duke
parents:
diff changeset
1987 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 // Check for unimplemented functionality before hard failure
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 assert( strcmp(opc->_ident,"label")==0, "Unimplemented() Label");
a61af66fc99e Initial load
duke
parents:
diff changeset
1991 assert( false, "ShouldNotReachHere()");
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 } // done checking which operand this is.
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 // A subfield variable, '$$' prefix
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 // Check for fields that may require relocation information.
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 // Then check that literal register parameters are accessed with 'reg' or 'constant'
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 if ( strcmp(rep_var,"$disp") == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 _doing_disp = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 assert( _opclass, "Must use operand or operand class before '$disp'");
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 if( _operand == NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 // Only have an operand class, generate run-time check for relocation
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 _may_reloc = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 _reloc_form = RELOC_DISP;
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 _reloc_type = AdlcVMDeps::oop_reloc_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 // Do precise check on operand: is it a ConP or not
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 // Check interface for value of displacement
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 assert( ( _operand->_interface != NULL ),
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 "$disp can only follow memory interface operand");
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 MemInterface *mem_interface= _operand->_interface->is_MemInterface();
a61af66fc99e Initial load
duke
parents:
diff changeset
2015 assert( mem_interface != NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 "$disp can only follow memory interface operand");
a61af66fc99e Initial load
duke
parents:
diff changeset
2017 const char *disp = mem_interface->_disp;
a61af66fc99e Initial load
duke
parents:
diff changeset
2018
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 if( disp != NULL && (*disp == '$') ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2020 // MemInterface::disp contains a replacement variable,
a61af66fc99e Initial load
duke
parents:
diff changeset
2021 // Check if this matches a ConP
a61af66fc99e Initial load
duke
parents:
diff changeset
2022 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 // Lookup replacement variable, in operand's component list
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 const char *rep_var_name = disp + 1; // Skip '$'
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 const Component *comp = _operand->_components.search(rep_var_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 assert( comp != NULL,"Replacement variable not found in components");
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 const char *type = comp->_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 // Lookup operand form for replacement variable's type
a61af66fc99e Initial load
duke
parents:
diff changeset
2029 const Form *form = _AD.globalNames()[type];
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 assert( form != NULL, "Replacement variable's type not found");
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 OperandForm *op = form->is_operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 assert( op, "Attempting to emit a non-register or non-constant");
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 // Check if this is a constant
a61af66fc99e Initial load
duke
parents:
diff changeset
2034 if (op->_matrule && op->_matrule->is_base_constant(_AD.globalNames())) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2035 // Check which constant this name maps to: _c0, _c1, ..., _cn
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 // const int idx = _operand.constant_position(_AD.globalNames(), comp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2037 // assert( idx != -1, "Constant component not found in operand");
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 Form::DataType dtype = op->is_base_constant(_AD.globalNames());
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 if ( dtype == Form::idealP ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 _may_reloc = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2041 // No longer true that idealP is always an oop
a61af66fc99e Initial load
duke
parents:
diff changeset
2042 _reloc_form = RELOC_DISP;
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 _reloc_type = AdlcVMDeps::oop_reloc_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2046
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 else if( _operand->is_user_name_for_sReg() != Form::none ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2048 // The only non-constant allowed access to disp is an operand sRegX in a stackSlotX
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 assert( op->ideal_to_sReg_type(type) != Form::none, "StackSlots access displacements using 'sRegs'");
a61af66fc99e Initial load
duke
parents:
diff changeset
2050 _may_reloc = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2052 assert( false, "fatal(); Only stackSlots can access a non-constant using 'disp'");
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 } // finished with precise check of operand for relocation.
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 } // finished with subfield variable
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 else if ( strcmp(rep_var,"$constant") == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 _doing_constant = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 if ( _constant_status == LITERAL_NOT_SEEN ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2060 // Check operand for type of constant
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 assert( _operand, "Must use operand before '$$constant'");
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 Form::DataType dtype = _operand->is_base_constant(_AD.globalNames());
a61af66fc99e Initial load
duke
parents:
diff changeset
2063 _constant_type = dtype;
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 if ( dtype == Form::idealP ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 _may_reloc = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 // No longer true that idealP is always an oop
a61af66fc99e Initial load
duke
parents:
diff changeset
2067 // // _must_reloc = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 _reloc_form = RELOC_IMMEDIATE;
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 _reloc_type = AdlcVMDeps::oop_reloc_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2070 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2071 // No relocation information needed
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 // User-provided literals may not require relocation information !!!!!
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 assert( _constant_status == LITERAL_SEEN, "Must know we are processing a user-provided literal");
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 else if ( strcmp(rep_var,"$label") == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 // Calls containing labels require relocation
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 if ( _inst.is_ideal_call() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2081 _may_reloc = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 // !!!!! !!!!!
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 _reloc_type = AdlcVMDeps::none_reloc_type();
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2086
a61af66fc99e Initial load
duke
parents:
diff changeset
2087 // literal register parameter must be accessed as a 'reg' field.
a61af66fc99e Initial load
duke
parents:
diff changeset
2088 if ( _reg_status != LITERAL_NOT_SEEN ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 assert( _reg_status == LITERAL_SEEN, "Must have seen register literal before now");
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 if (strcmp(rep_var,"$reg") == 0 || reg_conversion(rep_var) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 _reg_status = LITERAL_ACCESSED;
a61af66fc99e Initial load
duke
parents:
diff changeset
2092 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 assert( false, "invalid access to literal register parameter");
a61af66fc99e Initial load
duke
parents:
diff changeset
2094 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2096 // literal constant parameters must be accessed as a 'constant' field
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 if ( _constant_status != LITERAL_NOT_SEEN ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 assert( _constant_status == LITERAL_SEEN, "Must have seen constant literal before now");
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 if( strcmp(rep_var,"$constant") == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 _constant_status = LITERAL_ACCESSED;
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 assert( false, "invalid access to literal constant parameter");
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2105 } // end replacement and/or subfield
a61af66fc99e Initial load
duke
parents:
diff changeset
2106
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2108
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 void add_rep_var(const char *rep_var) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2110 // Handle subfield and replacement variables.
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 if ( ( *rep_var == '$' ) && ( *(rep_var+1) == '$' ) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 // Check for emit prefix, '$$emit32'
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 assert( _cleared, "Can not nest $$$emit32");
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 if ( strcmp(rep_var,"$$emit32") == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 _doing_emit_d32 = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2117 else if ( strcmp(rep_var,"$$emit16") == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 _doing_emit_d16 = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 else if ( strcmp(rep_var,"$$emit_hi") == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 _doing_emit_hi = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 else if ( strcmp(rep_var,"$$emit_lo") == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 _doing_emit_lo = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2125 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 else if ( strcmp(rep_var,"$$emit8") == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 _doing_emit8 = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2129 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 _AD.syntax_err(_encoding._linenum, "Unsupported $$operation '%s'\n",rep_var);
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 assert( false, "fatal();");
a61af66fc99e Initial load
duke
parents:
diff changeset
2132 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2135 // Update state for replacement variables
a61af66fc99e Initial load
duke
parents:
diff changeset
2136 update_state( rep_var );
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 _strings_to_emit.addName(rep_var);
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 _cleared = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2141
a61af66fc99e Initial load
duke
parents:
diff changeset
2142 void emit_replacement() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 // A replacement variable or one of its subfields
a61af66fc99e Initial load
duke
parents:
diff changeset
2144 // Obtain replacement variable from list
a61af66fc99e Initial load
duke
parents:
diff changeset
2145 // const char *ec_rep_var = encoding->_rep_vars.iter();
a61af66fc99e Initial load
duke
parents:
diff changeset
2146 const char *rep_var;
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 _strings_to_emit.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
2148 while ( (rep_var = _strings_to_emit.iter()) != NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2149
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 if ( (*rep_var) == '$' ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 // A subfield variable, '$$' prefix
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 emit_field( rep_var );
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 } else {
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2154 if (_strings_to_emit.peek() != NULL &&
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2155 strcmp(_strings_to_emit.peek(), "$Address") == 0) {
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2156 fprintf(_fp, "Address::make_raw(");
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2157
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2158 emit_rep_var( rep_var );
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2159 fprintf(_fp,"->base(ra_,this,idx%d), ", _operand_idx);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2160
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2161 _reg_status = LITERAL_ACCESSED;
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2162 emit_rep_var( rep_var );
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2163 fprintf(_fp,"->index(ra_,this,idx%d), ", _operand_idx);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2164
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2165 _reg_status = LITERAL_ACCESSED;
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2166 emit_rep_var( rep_var );
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2167 fprintf(_fp,"->scale(), ");
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2168
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2169 _reg_status = LITERAL_ACCESSED;
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2170 emit_rep_var( rep_var );
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2171 Form::DataType stack_type = _operand ? _operand->is_user_name_for_sReg() : Form::none;
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2172 if( _operand && _operand_idx==0 && stack_type != Form::none ) {
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2173 fprintf(_fp,"->disp(ra_,this,0), ");
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2174 } else {
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2175 fprintf(_fp,"->disp(ra_,this,idx%d), ", _operand_idx);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2176 }
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2177
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2178 _reg_status = LITERAL_ACCESSED;
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2179 emit_rep_var( rep_var );
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 4121
diff changeset
2180 fprintf(_fp,"->disp_reloc())");
624
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2181
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2182 // skip trailing $Address
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2183 _strings_to_emit.iter();
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2184 } else {
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2185 // A replacement variable, '$' prefix
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2186 const char* next = _strings_to_emit.peek();
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2187 const char* next2 = _strings_to_emit.peek(2);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2188 if (next != NULL && next2 != NULL && strcmp(next2, "$Register") == 0 &&
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2189 (strcmp(next, "$base") == 0 || strcmp(next, "$index") == 0)) {
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2190 // handle $rev_var$$base$$Register and $rev_var$$index$$Register by
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2191 // producing as_Register(opnd_array(#)->base(ra_,this,idx1)).
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2192 fprintf(_fp, "as_Register(");
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2193 // emit the operand reference
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2194 emit_rep_var( rep_var );
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2195 rep_var = _strings_to_emit.iter();
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2196 assert(strcmp(rep_var, "$base") == 0 || strcmp(rep_var, "$index") == 0, "bad pattern");
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2197 // handle base or index
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2198 emit_field(rep_var);
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2199 rep_var = _strings_to_emit.iter();
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2200 assert(strcmp(rep_var, "$Register") == 0, "bad pattern");
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2201 // close up the parens
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2202 fprintf(_fp, ")");
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2203 } else {
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2204 emit_rep_var( rep_var );
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2205 }
337400e7a5dd 6797305: Add LoadUB and LoadUI opcode class
twisti
parents: 603
diff changeset
2206 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 } // end replacement and/or subfield
a61af66fc99e Initial load
duke
parents:
diff changeset
2208 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2210
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 void emit_reloc_type(const char* type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 fprintf(_fp, "%s", type)
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
2214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2215
a61af66fc99e Initial load
duke
parents:
diff changeset
2216
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 void emit() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2219 // "emit_d32_reloc(" or "emit_hi_reloc" or "emit_lo_reloc"
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 // Emit the function name when generating an emit function
a61af66fc99e Initial load
duke
parents:
diff changeset
2222 if ( _doing_emit_d32 || _doing_emit_hi || _doing_emit_lo ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2223 const char *d32_hi_lo = _doing_emit_d32 ? "d32" : (_doing_emit_hi ? "hi" : "lo");
a61af66fc99e Initial load
duke
parents:
diff changeset
2224 // In general, relocatable isn't known at compiler compile time.
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 // Check results of prior scan
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 if ( ! _may_reloc ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 // Definitely don't need relocation information
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 fprintf( _fp, "emit_%s(cbuf, ", d32_hi_lo );
a61af66fc99e Initial load
duke
parents:
diff changeset
2229 emit_replacement(); fprintf(_fp, ")");
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2231 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 // Emit RUNTIME CHECK to see if value needs relocation info
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 // If emitting a relocatable address, use 'emit_d32_reloc'
a61af66fc99e Initial load
duke
parents:
diff changeset
2234 const char *disp_constant = _doing_disp ? "disp" : _doing_constant ? "constant" : "INVALID";
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 assert( (_doing_disp || _doing_constant)
a61af66fc99e Initial load
duke
parents:
diff changeset
2236 && !(_doing_disp && _doing_constant),
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 "Must be emitting either a displacement or a constant");
a61af66fc99e Initial load
duke
parents:
diff changeset
2238 fprintf(_fp,"\n");
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 4121
diff changeset
2239 fprintf(_fp,"if ( opnd_array(%d)->%s_reloc() != relocInfo::none ) {\n",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2240 _operand_idx, disp_constant);
a61af66fc99e Initial load
duke
parents:
diff changeset
2241 fprintf(_fp," ");
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 4121
diff changeset
2242 fprintf(_fp,"emit_%s_reloc(cbuf, ", d32_hi_lo );
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 4121
diff changeset
2243 emit_replacement(); fprintf(_fp,", ");
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 4121
diff changeset
2244 fprintf(_fp,"opnd_array(%d)->%s_reloc(), ",
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 4121
diff changeset
2245 _operand_idx, disp_constant);
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 4121
diff changeset
2246 fprintf(_fp, "%d", _reloc_form);fprintf(_fp, ");");
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 4121
diff changeset
2247 fprintf(_fp,"\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2248 fprintf(_fp,"} else {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 fprintf(_fp," emit_%s(cbuf, ", d32_hi_lo);
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 emit_replacement(); fprintf(_fp, ");\n"); fprintf(_fp,"}");
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 else if ( _doing_emit_d16 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 // Relocation of 16-bit values is not supported
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 fprintf(_fp,"emit_d16(cbuf, ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 emit_replacement(); fprintf(_fp, ")");
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 // No relocation done for 16-bit values
a61af66fc99e Initial load
duke
parents:
diff changeset
2258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2259 else if ( _doing_emit8 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 // Relocation of 8-bit values is not supported
a61af66fc99e Initial load
duke
parents:
diff changeset
2261 fprintf(_fp,"emit_d8(cbuf, ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 emit_replacement(); fprintf(_fp, ")");
a61af66fc99e Initial load
duke
parents:
diff changeset
2263 // No relocation done for 8-bit values
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 // Not an emit# command, just output the replacement string.
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 emit_replacement();
a61af66fc99e Initial load
duke
parents:
diff changeset
2268 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2269
a61af66fc99e Initial load
duke
parents:
diff changeset
2270 // Get ready for next state collection.
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
2272 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2273
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
2275
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 // recognizes names which represent MacroAssembler register types
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 // and return the conversion function to build them from OptoReg
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 const char* reg_conversion(const char* rep_var) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2279 if (strcmp(rep_var,"$Register") == 0) return "as_Register";
a61af66fc99e Initial load
duke
parents:
diff changeset
2280 if (strcmp(rep_var,"$FloatRegister") == 0) return "as_FloatRegister";
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 #if defined(IA32) || defined(AMD64)
a61af66fc99e Initial load
duke
parents:
diff changeset
2282 if (strcmp(rep_var,"$XMMRegister") == 0) return "as_XMMRegister";
a61af66fc99e Initial load
duke
parents:
diff changeset
2283 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2285 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2286
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 void emit_field(const char *rep_var) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 const char* reg_convert = reg_conversion(rep_var);
a61af66fc99e Initial load
duke
parents:
diff changeset
2289
a61af66fc99e Initial load
duke
parents:
diff changeset
2290 // A subfield variable, '$$subfield'
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 if ( strcmp(rep_var, "$reg") == 0 || reg_convert != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2292 // $reg form or the $Register MacroAssembler type conversions
a61af66fc99e Initial load
duke
parents:
diff changeset
2293 assert( _operand_idx != -1,
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 "Must use this subfield after operand");
a61af66fc99e Initial load
duke
parents:
diff changeset
2295 if( _reg_status == LITERAL_NOT_SEEN ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 if (_processing_noninput) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2297 const Form *local = _inst._localNames[_operand_name];
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 OperandForm *oper = local->is_operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
2299 const RegDef* first = oper->get_RegClass()->find_first_elem();
a61af66fc99e Initial load
duke
parents:
diff changeset
2300 if (reg_convert != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2301 fprintf(_fp, "%s(%s_enc)", reg_convert, first->_regname);
a61af66fc99e Initial load
duke
parents:
diff changeset
2302 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 fprintf(_fp, "%s_enc", first->_regname);
a61af66fc99e Initial load
duke
parents:
diff changeset
2304 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2305 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2306 fprintf(_fp,"->%s(ra_,this", reg_convert != NULL ? reg_convert : "reg");
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 // Add parameter for index position, if not result operand
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 if( _operand_idx != 0 ) fprintf(_fp,",idx%d", _operand_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 fprintf(_fp,")");
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
2310 fprintf(_fp, "/* %s */", _operand_name);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2312 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 assert( _reg_status == LITERAL_OUTPUT, "should have output register literal in emit_rep_var");
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 // Register literal has already been sent to output file, nothing more needed
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 else if ( strcmp(rep_var,"$base") == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2318 assert( _operand_idx != -1,
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 "Must use this subfield after operand");
a61af66fc99e Initial load
duke
parents:
diff changeset
2320 assert( ! _may_reloc, "UnImplemented()");
a61af66fc99e Initial load
duke
parents:
diff changeset
2321 fprintf(_fp,"->base(ra_,this,idx%d)", _operand_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
2322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2323 else if ( strcmp(rep_var,"$index") == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2324 assert( _operand_idx != -1,
a61af66fc99e Initial load
duke
parents:
diff changeset
2325 "Must use this subfield after operand");
a61af66fc99e Initial load
duke
parents:
diff changeset
2326 assert( ! _may_reloc, "UnImplemented()");
a61af66fc99e Initial load
duke
parents:
diff changeset
2327 fprintf(_fp,"->index(ra_,this,idx%d)", _operand_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
2328 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2329 else if ( strcmp(rep_var,"$scale") == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2330 assert( ! _may_reloc, "UnImplemented()");
a61af66fc99e Initial load
duke
parents:
diff changeset
2331 fprintf(_fp,"->scale()");
a61af66fc99e Initial load
duke
parents:
diff changeset
2332 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2333 else if ( strcmp(rep_var,"$cmpcode") == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2334 assert( ! _may_reloc, "UnImplemented()");
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 fprintf(_fp,"->ccode()");
a61af66fc99e Initial load
duke
parents:
diff changeset
2336 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2337 else if ( strcmp(rep_var,"$constant") == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2338 if( _constant_status == LITERAL_NOT_SEEN ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2339 if ( _constant_type == Form::idealD ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2340 fprintf(_fp,"->constantD()");
a61af66fc99e Initial load
duke
parents:
diff changeset
2341 } else if ( _constant_type == Form::idealF ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 fprintf(_fp,"->constantF()");
a61af66fc99e Initial load
duke
parents:
diff changeset
2343 } else if ( _constant_type == Form::idealL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2344 fprintf(_fp,"->constantL()");
a61af66fc99e Initial load
duke
parents:
diff changeset
2345 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2346 fprintf(_fp,"->constant()");
a61af66fc99e Initial load
duke
parents:
diff changeset
2347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2348 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2349 assert( _constant_status == LITERAL_OUTPUT, "should have output constant literal in emit_rep_var");
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
2350 // Constant literal has already been sent to output file, nothing more needed
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2351 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2352 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 else if ( strcmp(rep_var,"$disp") == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2354 Form::DataType stack_type = _operand ? _operand->is_user_name_for_sReg() : Form::none;
a61af66fc99e Initial load
duke
parents:
diff changeset
2355 if( _operand && _operand_idx==0 && stack_type != Form::none ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2356 fprintf(_fp,"->disp(ra_,this,0)");
a61af66fc99e Initial load
duke
parents:
diff changeset
2357 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2358 fprintf(_fp,"->disp(ra_,this,idx%d)", _operand_idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
2359 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 else if ( strcmp(rep_var,"$label") == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2362 fprintf(_fp,"->label()");
a61af66fc99e Initial load
duke
parents:
diff changeset
2363 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2364 else if ( strcmp(rep_var,"$method") == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 fprintf(_fp,"->method()");
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2367 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 printf("emit_field: %s\n",rep_var);
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
2369 globalAD->syntax_err(_inst._linenum, "Unknown replacement variable %s in format statement of %s.",
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
2370 rep_var, _inst._ident);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 assert( false, "UnImplemented()");
a61af66fc99e Initial load
duke
parents:
diff changeset
2372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2373 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2374
a61af66fc99e Initial load
duke
parents:
diff changeset
2375
a61af66fc99e Initial load
duke
parents:
diff changeset
2376 void emit_rep_var(const char *rep_var) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2377 _processing_noninput = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2378 // A replacement variable, originally '$'
a61af66fc99e Initial load
duke
parents:
diff changeset
2379 if ( Opcode::as_opcode_type(rep_var) != Opcode::NOT_AN_OPCODE ) {
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
2380 if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(rep_var) )) {
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
2381 // Missing opcode
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
2382 _AD.syntax_err( _inst._linenum,
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
2383 "Missing $%s opcode definition in %s, used by encoding %s\n",
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
2384 rep_var, _inst._ident, _encoding._name);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
2385 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2386 }
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2387 else if (strcmp(rep_var, "constanttablebase") == 0) {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2388 fprintf(_fp, "as_Register(ra_->get_encode(in(mach_constant_base_node_input())))");
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2389 }
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2390 else if (strcmp(rep_var, "constantoffset") == 0) {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2391 fprintf(_fp, "constant_offset()");
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2392 }
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2393 else if (strcmp(rep_var, "constantaddress") == 0) {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2394 fprintf(_fp, "InternalAddress(__ code()->consts()->start() + constant_offset())");
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2395 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2396 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2397 // Lookup its position in parameter list
a61af66fc99e Initial load
duke
parents:
diff changeset
2398 int param_no = _encoding.rep_var_index(rep_var);
a61af66fc99e Initial load
duke
parents:
diff changeset
2399 if ( param_no == -1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2400 _AD.syntax_err( _encoding._linenum,
a61af66fc99e Initial load
duke
parents:
diff changeset
2401 "Replacement variable %s not found in enc_class %s.\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 rep_var, _encoding._name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2403 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2404 // Lookup the corresponding ins_encode parameter
a61af66fc99e Initial load
duke
parents:
diff changeset
2405 const char *inst_rep_var = _ins_encode.rep_var_name(_inst, param_no);
a61af66fc99e Initial load
duke
parents:
diff changeset
2406
a61af66fc99e Initial load
duke
parents:
diff changeset
2407 // Check if instruction's actual parameter is a local name in the instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
2408 const Form *local = _inst._localNames[inst_rep_var];
a61af66fc99e Initial load
duke
parents:
diff changeset
2409 OpClassForm *opc = (local != NULL) ? local->is_opclass() : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2410 // Note: assert removed to allow constant and symbolic parameters
a61af66fc99e Initial load
duke
parents:
diff changeset
2411 // assert( opc, "replacement variable was not found in local names");
a61af66fc99e Initial load
duke
parents:
diff changeset
2412 // Lookup the index position iff the replacement variable is a localName
a61af66fc99e Initial load
duke
parents:
diff changeset
2413 int idx = (opc != NULL) ? _inst.operand_position_format(inst_rep_var) : -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2414 if( idx != -1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2415 if (_inst.is_noninput_operand(idx)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2416 // This operand isn't a normal input so printing it is done
a61af66fc99e Initial load
duke
parents:
diff changeset
2417 // specially.
a61af66fc99e Initial load
duke
parents:
diff changeset
2418 _processing_noninput = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2419 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2420 // Output the emit code for this operand
a61af66fc99e Initial load
duke
parents:
diff changeset
2421 fprintf(_fp,"opnd_array(%d)",idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
2422 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2423 assert( _operand == opc->is_operand(),
a61af66fc99e Initial load
duke
parents:
diff changeset
2424 "Previous emit $operand does not match current");
a61af66fc99e Initial load
duke
parents:
diff changeset
2425 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2426 else if( ADLParser::is_literal_constant(inst_rep_var) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2427 // else check if it is a constant expression
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 // Removed following assert to allow primitive C types as arguments to encodings
a61af66fc99e Initial load
duke
parents:
diff changeset
2429 // assert( _constant_status == LITERAL_ACCESSED, "Must be processing a literal constant parameter");
a61af66fc99e Initial load
duke
parents:
diff changeset
2430 fprintf(_fp,"(%s)", inst_rep_var);
a61af66fc99e Initial load
duke
parents:
diff changeset
2431 _constant_status = LITERAL_OUTPUT;
a61af66fc99e Initial load
duke
parents:
diff changeset
2432 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2433 else if( Opcode::as_opcode_type(inst_rep_var) != Opcode::NOT_AN_OPCODE ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2434 // else check if "primary", "secondary", "tertiary"
a61af66fc99e Initial load
duke
parents:
diff changeset
2435 assert( _constant_status == LITERAL_ACCESSED, "Must be processing a literal constant parameter");
415
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
2436 if (!_inst._opcode->print_opcode(_fp, Opcode::as_opcode_type(inst_rep_var) )) {
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
2437 // Missing opcode
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
2438 _AD.syntax_err( _inst._linenum,
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
2439 "Missing $%s opcode definition in %s\n",
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
2440 rep_var, _inst._ident);
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
2441
4d9884b01ba6 6754519: don't emit flag fixup for NaN when condition being tested doesn't need it
never
parents: 196
diff changeset
2442 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2443 _constant_status = LITERAL_OUTPUT;
a61af66fc99e Initial load
duke
parents:
diff changeset
2444 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2445 else if((_AD.get_registers() != NULL ) && (_AD.get_registers()->getRegDef(inst_rep_var) != NULL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2446 // Instruction provided a literal register name for this parameter
a61af66fc99e Initial load
duke
parents:
diff changeset
2447 // Check that encoding specifies $$$reg to resolve.as register.
a61af66fc99e Initial load
duke
parents:
diff changeset
2448 assert( _reg_status == LITERAL_ACCESSED, "Must be processing a literal register parameter");
a61af66fc99e Initial load
duke
parents:
diff changeset
2449 fprintf(_fp,"(%s_enc)", inst_rep_var);
a61af66fc99e Initial load
duke
parents:
diff changeset
2450 _reg_status = LITERAL_OUTPUT;
a61af66fc99e Initial load
duke
parents:
diff changeset
2451 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2452 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2453 // Check for unimplemented functionality before hard failure
a61af66fc99e Initial load
duke
parents:
diff changeset
2454 assert( strcmp(opc->_ident,"label")==0, "Unimplemented() Label");
a61af66fc99e Initial load
duke
parents:
diff changeset
2455 assert( false, "ShouldNotReachHere()");
a61af66fc99e Initial load
duke
parents:
diff changeset
2456 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2457 // all done
a61af66fc99e Initial load
duke
parents:
diff changeset
2458 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2459 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2460
a61af66fc99e Initial load
duke
parents:
diff changeset
2461 }; // end class DefineEmitState
a61af66fc99e Initial load
duke
parents:
diff changeset
2462
a61af66fc99e Initial load
duke
parents:
diff changeset
2463
a61af66fc99e Initial load
duke
parents:
diff changeset
2464 void ArchDesc::defineSize(FILE *fp, InstructForm &inst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2465
a61af66fc99e Initial load
duke
parents:
diff changeset
2466 //(1)
a61af66fc99e Initial load
duke
parents:
diff changeset
2467 // Output instruction's emit prototype
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
2468 fprintf(fp,"uint %sNode::size(PhaseRegAlloc *ra_) const {\n",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2469 inst._ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
2470
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
2471 fprintf(fp, " assert(VerifyOops || MachNode::size(ra_) <= %s, \"bad fixed size\");\n", inst._size);
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
2472
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2473 //(2)
a61af66fc99e Initial load
duke
parents:
diff changeset
2474 // Print the size
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
2475 fprintf(fp, " return (VerifyOops ? MachNode::size(ra_) : %s);\n", inst._size);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2476
a61af66fc99e Initial load
duke
parents:
diff changeset
2477 // (3) and (4)
a61af66fc99e Initial load
duke
parents:
diff changeset
2478 fprintf(fp,"}\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2479 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2480
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2481 // defineEmit -----------------------------------------------------------------
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2482 void ArchDesc::defineEmit(FILE* fp, InstructForm& inst) {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2483 InsEncode* encode = inst._insencode;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2484
a61af66fc99e Initial load
duke
parents:
diff changeset
2485 // (1)
a61af66fc99e Initial load
duke
parents:
diff changeset
2486 // Output instruction's emit prototype
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2487 fprintf(fp, "void %sNode::emit(CodeBuffer& cbuf, PhaseRegAlloc* ra_) const {\n", inst._ident);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2488
a61af66fc99e Initial load
duke
parents:
diff changeset
2489 // If user did not define an encode section,
a61af66fc99e Initial load
duke
parents:
diff changeset
2490 // provide stub that does not generate any machine code.
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2491 if( (_encode == NULL) || (encode == NULL) ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2492 fprintf(fp, " // User did not define an encode section.\n");
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2493 fprintf(fp, "}\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2494 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2495 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2496
a61af66fc99e Initial load
duke
parents:
diff changeset
2497 // Save current instruction's starting address (helps with relocation).
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2498 fprintf(fp, " cbuf.set_insts_mark();\n");
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2499
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2500 // For MachConstantNodes which are ideal jump nodes, fill the jump table.
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2501 if (inst.is_mach_constant() && inst.is_ideal_jump()) {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2502 fprintf(fp, " ra_->C->constant_table().fill_jump_table(cbuf, (MachConstantNode*) this, _index2label);\n");
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2503 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2504
a61af66fc99e Initial load
duke
parents:
diff changeset
2505 // Output each operand's offset into the array of registers.
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2506 inst.index_temps(fp, _globalNames);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2507
a61af66fc99e Initial load
duke
parents:
diff changeset
2508 // Output this instruction's encodings
a61af66fc99e Initial load
duke
parents:
diff changeset
2509 const char *ec_name;
a61af66fc99e Initial load
duke
parents:
diff changeset
2510 bool user_defined = false;
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2511 encode->reset();
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2512 while ((ec_name = encode->encode_class_iter()) != NULL) {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2513 fprintf(fp, " {\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2514 // Output user-defined encoding
a61af66fc99e Initial load
duke
parents:
diff changeset
2515 user_defined = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2516
a61af66fc99e Initial load
duke
parents:
diff changeset
2517 const char *ec_code = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2518 const char *ec_rep_var = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2519 EncClass *encoding = _encode->encClass(ec_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2520 if (encoding == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2521 fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2522 abort();
a61af66fc99e Initial load
duke
parents:
diff changeset
2523 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2524
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2525 if (encode->current_encoding_num_args() != encoding->num_args()) {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2526 globalAD->syntax_err(encode->_linenum, "In %s: passing %d arguments to %s but expecting %d",
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2527 inst._ident, encode->current_encoding_num_args(),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2528 ec_name, encoding->num_args());
a61af66fc99e Initial load
duke
parents:
diff changeset
2529 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2530
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2531 DefineEmitState pending(fp, *this, *encoding, *encode, inst);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2532 encoding->_code.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
2533 encoding->_rep_vars.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
2534 // Process list of user-defined strings,
a61af66fc99e Initial load
duke
parents:
diff changeset
2535 // and occurrences of replacement variables.
a61af66fc99e Initial load
duke
parents:
diff changeset
2536 // Replacement Vars are pushed into a list and then output
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2537 while ((ec_code = encoding->_code.iter()) != NULL) {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2538 if (!encoding->_code.is_signal(ec_code)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2539 // Emit pending code
a61af66fc99e Initial load
duke
parents:
diff changeset
2540 pending.emit();
a61af66fc99e Initial load
duke
parents:
diff changeset
2541 pending.clear();
a61af66fc99e Initial load
duke
parents:
diff changeset
2542 // Emit this code section
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2543 fprintf(fp, "%s", ec_code);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2544 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2545 // A replacement variable or one of its subfields
a61af66fc99e Initial load
duke
parents:
diff changeset
2546 // Obtain replacement variable from list
a61af66fc99e Initial load
duke
parents:
diff changeset
2547 ec_rep_var = encoding->_rep_vars.iter();
a61af66fc99e Initial load
duke
parents:
diff changeset
2548 pending.add_rep_var(ec_rep_var);
a61af66fc99e Initial load
duke
parents:
diff changeset
2549 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2550 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2551 // Emit pending code
a61af66fc99e Initial load
duke
parents:
diff changeset
2552 pending.emit();
a61af66fc99e Initial load
duke
parents:
diff changeset
2553 pending.clear();
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2554 fprintf(fp, " }\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2555 } // end while instruction's encodings
a61af66fc99e Initial load
duke
parents:
diff changeset
2556
a61af66fc99e Initial load
duke
parents:
diff changeset
2557 // Check if user stated which encoding to user
a61af66fc99e Initial load
duke
parents:
diff changeset
2558 if ( user_defined == false ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2559 fprintf(fp, " // User did not define which encode class to use.\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2560 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2561
a61af66fc99e Initial load
duke
parents:
diff changeset
2562 // (3) and (4)
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
2563 fprintf(fp, "}\n\n");
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2564 }
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2565
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2566 // defineEvalConstant ---------------------------------------------------------
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2567 void ArchDesc::defineEvalConstant(FILE* fp, InstructForm& inst) {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2568 InsEncode* encode = inst._constant;
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2569
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2570 // (1)
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2571 // Output instruction's emit prototype
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2572 fprintf(fp, "void %sNode::eval_constant(Compile* C) {\n", inst._ident);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2573
4114
6729bbc1fcd6 7003454: order constants in constant table by number of references in code
twisti
parents: 3853
diff changeset
2574 // For ideal jump nodes, add a jump-table entry.
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2575 if (inst.is_ideal_jump()) {
4114
6729bbc1fcd6 7003454: order constants in constant table by number of references in code
twisti
parents: 3853
diff changeset
2576 fprintf(fp, " _constant = C->constant_table().add_jump_table(this);\n");
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2577 }
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2578
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2579 // If user did not define an encode section,
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2580 // provide stub that does not generate any machine code.
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2581 if ((_encode == NULL) || (encode == NULL)) {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2582 fprintf(fp, " // User did not define an encode section.\n");
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2583 fprintf(fp, "}\n");
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2584 return;
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2585 }
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2586
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2587 // Output this instruction's encodings
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2588 const char *ec_name;
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2589 bool user_defined = false;
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2590 encode->reset();
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2591 while ((ec_name = encode->encode_class_iter()) != NULL) {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2592 fprintf(fp, " {\n");
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2593 // Output user-defined encoding
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2594 user_defined = true;
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2595
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2596 const char *ec_code = NULL;
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2597 const char *ec_rep_var = NULL;
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2598 EncClass *encoding = _encode->encClass(ec_name);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2599 if (encoding == NULL) {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2600 fprintf(stderr, "User did not define contents of this encode_class: %s\n", ec_name);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2601 abort();
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2602 }
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2603
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2604 if (encode->current_encoding_num_args() != encoding->num_args()) {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2605 globalAD->syntax_err(encode->_linenum, "In %s: passing %d arguments to %s but expecting %d",
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2606 inst._ident, encode->current_encoding_num_args(),
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2607 ec_name, encoding->num_args());
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2608 }
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2609
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2610 DefineEmitState pending(fp, *this, *encoding, *encode, inst);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2611 encoding->_code.reset();
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2612 encoding->_rep_vars.reset();
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2613 // Process list of user-defined strings,
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2614 // and occurrences of replacement variables.
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2615 // Replacement Vars are pushed into a list and then output
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2616 while ((ec_code = encoding->_code.iter()) != NULL) {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2617 if (!encoding->_code.is_signal(ec_code)) {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2618 // Emit pending code
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2619 pending.emit();
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2620 pending.clear();
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2621 // Emit this code section
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2622 fprintf(fp, "%s", ec_code);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2623 } else {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2624 // A replacement variable or one of its subfields
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2625 // Obtain replacement variable from list
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2626 ec_rep_var = encoding->_rep_vars.iter();
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2627 pending.add_rep_var(ec_rep_var);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2628 }
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2629 }
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2630 // Emit pending code
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2631 pending.emit();
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2632 pending.clear();
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2633 fprintf(fp, " }\n");
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2634 } // end while instruction's encodings
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2635
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2636 // Check if user stated which encoding to user
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2637 if (user_defined == false) {
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2638 fprintf(fp, " // User did not define which encode class to use.\n");
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2639 }
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2640
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2641 // (3) and (4)
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
2642 fprintf(fp, "}\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2644
a61af66fc99e Initial load
duke
parents:
diff changeset
2645 // ---------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2646 //--------Utilities to build MachOper and MachNode derived Classes------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2647 // ---------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2648
a61af66fc99e Initial load
duke
parents:
diff changeset
2649 //------------------------------Utilities to build Operand Classes------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2650 static void defineIn_RegMask(FILE *fp, FormDict &globals, OperandForm &oper) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2651 uint num_edges = oper.num_edges(globals);
a61af66fc99e Initial load
duke
parents:
diff changeset
2652 if( num_edges != 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2653 // Method header
a61af66fc99e Initial load
duke
parents:
diff changeset
2654 fprintf(fp, "const RegMask *%sOper::in_RegMask(int index) const {\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
2655 oper._ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
2656
a61af66fc99e Initial load
duke
parents:
diff changeset
2657 // Assert that the index is in range.
a61af66fc99e Initial load
duke
parents:
diff changeset
2658 fprintf(fp, " assert(0 <= index && index < %d, \"index out of range\");\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
2659 num_edges);
a61af66fc99e Initial load
duke
parents:
diff changeset
2660
a61af66fc99e Initial load
duke
parents:
diff changeset
2661 // Figure out if all RegMasks are the same.
a61af66fc99e Initial load
duke
parents:
diff changeset
2662 const char* first_reg_class = oper.in_reg_class(0, globals);
a61af66fc99e Initial load
duke
parents:
diff changeset
2663 bool all_same = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2664 assert(first_reg_class != NULL, "did not find register mask");
a61af66fc99e Initial load
duke
parents:
diff changeset
2665
a61af66fc99e Initial load
duke
parents:
diff changeset
2666 for (uint index = 1; all_same && index < num_edges; index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2667 const char* some_reg_class = oper.in_reg_class(index, globals);
a61af66fc99e Initial load
duke
parents:
diff changeset
2668 assert(some_reg_class != NULL, "did not find register mask");
a61af66fc99e Initial load
duke
parents:
diff changeset
2669 if (strcmp(first_reg_class, some_reg_class) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2670 all_same = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2671 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2672 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2673
a61af66fc99e Initial load
duke
parents:
diff changeset
2674 if (all_same) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2675 // Return the sole RegMask.
a61af66fc99e Initial load
duke
parents:
diff changeset
2676 if (strcmp(first_reg_class, "stack_slots") == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2677 fprintf(fp," return &(Compile::current()->FIRST_STACK_mask());\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2678 } else {
4121
db2e64ca2d5a 7090968: Allow adlc register class to depend on runtime conditions
roland
parents: 4114
diff changeset
2679 fprintf(fp," return &%s_mask();\n", toUpper(first_reg_class));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2680 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2681 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2682 // Build a switch statement to return the desired mask.
a61af66fc99e Initial load
duke
parents:
diff changeset
2683 fprintf(fp," switch (index) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2684
a61af66fc99e Initial load
duke
parents:
diff changeset
2685 for (uint index = 0; index < num_edges; index++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2686 const char *reg_class = oper.in_reg_class(index, globals);
a61af66fc99e Initial load
duke
parents:
diff changeset
2687 assert(reg_class != NULL, "did not find register mask");
a61af66fc99e Initial load
duke
parents:
diff changeset
2688 if( !strcmp(reg_class, "stack_slots") ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2689 fprintf(fp, " case %d: return &(Compile::current()->FIRST_STACK_mask());\n", index);
a61af66fc99e Initial load
duke
parents:
diff changeset
2690 } else {
4121
db2e64ca2d5a 7090968: Allow adlc register class to depend on runtime conditions
roland
parents: 4114
diff changeset
2691 fprintf(fp, " case %d: return &%s_mask();\n", index, toUpper(reg_class));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2692 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2693 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2694 fprintf(fp," }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2695 fprintf(fp," ShouldNotReachHere();\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2696 fprintf(fp," return NULL;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2697 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2698
a61af66fc99e Initial load
duke
parents:
diff changeset
2699 // Method close
a61af66fc99e Initial load
duke
parents:
diff changeset
2700 fprintf(fp, "}\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2701 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2702 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2703
a61af66fc99e Initial load
duke
parents:
diff changeset
2704 // generate code to create a clone for a class derived from MachOper
a61af66fc99e Initial load
duke
parents:
diff changeset
2705 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2706 // (0) MachOper *MachOperXOper::clone(Compile* C) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
2707 // (1) return new (C) MachXOper( _ccode, _c0, _c1, ..., _cn);
a61af66fc99e Initial load
duke
parents:
diff changeset
2708 // (2) }
a61af66fc99e Initial load
duke
parents:
diff changeset
2709 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2710 static void defineClone(FILE *fp, FormDict &globalNames, OperandForm &oper) {
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
2711 fprintf(fp,"MachOper *%sOper::clone(Compile* C) const {\n", oper._ident);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2712 // Check for constants that need to be copied over
a61af66fc99e Initial load
duke
parents:
diff changeset
2713 const int num_consts = oper.num_consts(globalNames);
a61af66fc99e Initial load
duke
parents:
diff changeset
2714 const bool is_ideal_bool = oper.is_ideal_bool();
a61af66fc99e Initial load
duke
parents:
diff changeset
2715 if( (num_consts > 0) ) {
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
2716 fprintf(fp," return new (C) %sOper(", oper._ident);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2717 // generate parameters for constants
a61af66fc99e Initial load
duke
parents:
diff changeset
2718 int i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2719 fprintf(fp,"_c%d", i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2720 for( i = 1; i < num_consts; ++i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2721 fprintf(fp,", _c%d", i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2722 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2723 // finish line (1)
a61af66fc99e Initial load
duke
parents:
diff changeset
2724 fprintf(fp,");\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2725 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2726 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2727 assert( num_consts == 0, "Currently support zero or one constant per operand clone function");
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
2728 fprintf(fp," return new (C) %sOper();\n", oper._ident);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2730 // finish method
a61af66fc99e Initial load
duke
parents:
diff changeset
2731 fprintf(fp,"}\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2732 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2733
a61af66fc99e Initial load
duke
parents:
diff changeset
2734 // Helper functions for bug 4796752, abstracted with minimal modification
a61af66fc99e Initial load
duke
parents:
diff changeset
2735 // from define_oper_interface()
a61af66fc99e Initial load
duke
parents:
diff changeset
2736 OperandForm *rep_var_to_operand(const char *encoding, OperandForm &oper, FormDict &globals) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2737 OperandForm *op = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2738 // Check for replacement variable
a61af66fc99e Initial load
duke
parents:
diff changeset
2739 if( *encoding == '$' ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2740 // Replacement variable
a61af66fc99e Initial load
duke
parents:
diff changeset
2741 const char *rep_var = encoding + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2742 // Lookup replacement variable, rep_var, in operand's component list
a61af66fc99e Initial load
duke
parents:
diff changeset
2743 const Component *comp = oper._components.search(rep_var);
a61af66fc99e Initial load
duke
parents:
diff changeset
2744 assert( comp != NULL, "Replacement variable not found in components");
a61af66fc99e Initial load
duke
parents:
diff changeset
2745 // Lookup operand form for replacement variable's type
a61af66fc99e Initial load
duke
parents:
diff changeset
2746 const char *type = comp->_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
2747 Form *form = (Form*)globals[type];
a61af66fc99e Initial load
duke
parents:
diff changeset
2748 assert( form != NULL, "Replacement variable's type not found");
a61af66fc99e Initial load
duke
parents:
diff changeset
2749 op = form->is_operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
2750 assert( op, "Attempting to emit a non-register or non-constant");
a61af66fc99e Initial load
duke
parents:
diff changeset
2751 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2752
a61af66fc99e Initial load
duke
parents:
diff changeset
2753 return op;
a61af66fc99e Initial load
duke
parents:
diff changeset
2754 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2755
a61af66fc99e Initial load
duke
parents:
diff changeset
2756 int rep_var_to_constant_index(const char *encoding, OperandForm &oper, FormDict &globals) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2757 int idx = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2758 // Check for replacement variable
a61af66fc99e Initial load
duke
parents:
diff changeset
2759 if( *encoding == '$' ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2760 // Replacement variable
a61af66fc99e Initial load
duke
parents:
diff changeset
2761 const char *rep_var = encoding + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2762 // Lookup replacement variable, rep_var, in operand's component list
a61af66fc99e Initial load
duke
parents:
diff changeset
2763 const Component *comp = oper._components.search(rep_var);
a61af66fc99e Initial load
duke
parents:
diff changeset
2764 assert( comp != NULL, "Replacement variable not found in components");
a61af66fc99e Initial load
duke
parents:
diff changeset
2765 // Lookup operand form for replacement variable's type
a61af66fc99e Initial load
duke
parents:
diff changeset
2766 const char *type = comp->_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
2767 Form *form = (Form*)globals[type];
a61af66fc99e Initial load
duke
parents:
diff changeset
2768 assert( form != NULL, "Replacement variable's type not found");
a61af66fc99e Initial load
duke
parents:
diff changeset
2769 OperandForm *op = form->is_operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
2770 assert( op, "Attempting to emit a non-register or non-constant");
a61af66fc99e Initial load
duke
parents:
diff changeset
2771 // Check that this is a constant and find constant's index:
a61af66fc99e Initial load
duke
parents:
diff changeset
2772 if (op->_matrule && op->_matrule->is_base_constant(globals)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2773 idx = oper.constant_position(globals, comp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2774 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2775 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2776
a61af66fc99e Initial load
duke
parents:
diff changeset
2777 return idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
2778 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2779
a61af66fc99e Initial load
duke
parents:
diff changeset
2780 bool is_regI(const char *encoding, OperandForm &oper, FormDict &globals ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2781 bool is_regI = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2782
a61af66fc99e Initial load
duke
parents:
diff changeset
2783 OperandForm *op = rep_var_to_operand(encoding, oper, globals);
a61af66fc99e Initial load
duke
parents:
diff changeset
2784 if( op != NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2785 // Check that this is a register
a61af66fc99e Initial load
duke
parents:
diff changeset
2786 if ( (op->_matrule && op->_matrule->is_base_register(globals)) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2787 // Register
a61af66fc99e Initial load
duke
parents:
diff changeset
2788 const char* ideal = op->ideal_type(globals);
a61af66fc99e Initial load
duke
parents:
diff changeset
2789 is_regI = (ideal && (op->ideal_to_Reg_type(ideal) == Form::idealI));
a61af66fc99e Initial load
duke
parents:
diff changeset
2790 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2791 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2792
a61af66fc99e Initial load
duke
parents:
diff changeset
2793 return is_regI;
a61af66fc99e Initial load
duke
parents:
diff changeset
2794 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2795
a61af66fc99e Initial load
duke
parents:
diff changeset
2796 bool is_conP(const char *encoding, OperandForm &oper, FormDict &globals ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2797 bool is_conP = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2798
a61af66fc99e Initial load
duke
parents:
diff changeset
2799 OperandForm *op = rep_var_to_operand(encoding, oper, globals);
a61af66fc99e Initial load
duke
parents:
diff changeset
2800 if( op != NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2801 // Check that this is a constant pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
2802 if (op->_matrule && op->_matrule->is_base_constant(globals)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2803 // Constant
a61af66fc99e Initial load
duke
parents:
diff changeset
2804 Form::DataType dtype = op->is_base_constant(globals);
a61af66fc99e Initial load
duke
parents:
diff changeset
2805 is_conP = (dtype == Form::idealP);
a61af66fc99e Initial load
duke
parents:
diff changeset
2806 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2807 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2808
a61af66fc99e Initial load
duke
parents:
diff changeset
2809 return is_conP;
a61af66fc99e Initial load
duke
parents:
diff changeset
2810 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2811
a61af66fc99e Initial load
duke
parents:
diff changeset
2812
a61af66fc99e Initial load
duke
parents:
diff changeset
2813 // Define a MachOper interface methods
a61af66fc99e Initial load
duke
parents:
diff changeset
2814 void ArchDesc::define_oper_interface(FILE *fp, OperandForm &oper, FormDict &globals,
a61af66fc99e Initial load
duke
parents:
diff changeset
2815 const char *name, const char *encoding) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2816 bool emit_position = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2817 int position = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2818
a61af66fc99e Initial load
duke
parents:
diff changeset
2819 fprintf(fp," virtual int %s", name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2820 // Generate access method for base, index, scale, disp, ...
a61af66fc99e Initial load
duke
parents:
diff changeset
2821 if( (strcmp(name,"base") == 0) || (strcmp(name,"index") == 0) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2822 fprintf(fp,"(PhaseRegAlloc *ra_, const Node *node, int idx) const { \n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2823 emit_position = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2824 } else if ( (strcmp(name,"disp") == 0) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2825 fprintf(fp,"(PhaseRegAlloc *ra_, const Node *node, int idx) const { \n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2826 } else {
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
2827 fprintf(fp,"() const { \n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2828 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2829
a61af66fc99e Initial load
duke
parents:
diff changeset
2830 // Check for hexadecimal value OR replacement variable
a61af66fc99e Initial load
duke
parents:
diff changeset
2831 if( *encoding == '$' ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2832 // Replacement variable
a61af66fc99e Initial load
duke
parents:
diff changeset
2833 const char *rep_var = encoding + 1;
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
2834 fprintf(fp," // Replacement variable: %s\n", encoding+1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2835 // Lookup replacement variable, rep_var, in operand's component list
a61af66fc99e Initial load
duke
parents:
diff changeset
2836 const Component *comp = oper._components.search(rep_var);
a61af66fc99e Initial load
duke
parents:
diff changeset
2837 assert( comp != NULL, "Replacement variable not found in components");
a61af66fc99e Initial load
duke
parents:
diff changeset
2838 // Lookup operand form for replacement variable's type
a61af66fc99e Initial load
duke
parents:
diff changeset
2839 const char *type = comp->_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
2840 Form *form = (Form*)globals[type];
a61af66fc99e Initial load
duke
parents:
diff changeset
2841 assert( form != NULL, "Replacement variable's type not found");
a61af66fc99e Initial load
duke
parents:
diff changeset
2842 OperandForm *op = form->is_operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
2843 assert( op, "Attempting to emit a non-register or non-constant");
a61af66fc99e Initial load
duke
parents:
diff changeset
2844 // Check that this is a register or a constant and generate code:
a61af66fc99e Initial load
duke
parents:
diff changeset
2845 if ( (op->_matrule && op->_matrule->is_base_register(globals)) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2846 // Register
a61af66fc99e Initial load
duke
parents:
diff changeset
2847 int idx_offset = oper.register_position( globals, rep_var);
a61af66fc99e Initial load
duke
parents:
diff changeset
2848 position = idx_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
2849 fprintf(fp," return (int)ra_->get_encode(node->in(idx");
a61af66fc99e Initial load
duke
parents:
diff changeset
2850 if ( idx_offset > 0 ) fprintf(fp, "+%d",idx_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2851 fprintf(fp,"));\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2852 } else if ( op->ideal_to_sReg_type(op->_ident) != Form::none ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2853 // StackSlot for an sReg comes either from input node or from self, when idx==0
a61af66fc99e Initial load
duke
parents:
diff changeset
2854 fprintf(fp," if( idx != 0 ) {\n");
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
2855 fprintf(fp," // Access stack offset (register number) for input operand\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2856 fprintf(fp," return ra_->reg2offset(ra_->get_reg_first(node->in(idx)));/* sReg */\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2857 fprintf(fp," }\n");
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
2858 fprintf(fp," // Access stack offset (register number) from myself\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2859 fprintf(fp," return ra_->reg2offset(ra_->get_reg_first(node));/* sReg */\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2860 } else if (op->_matrule && op->_matrule->is_base_constant(globals)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2861 // Constant
a61af66fc99e Initial load
duke
parents:
diff changeset
2862 // Check which constant this name maps to: _c0, _c1, ..., _cn
a61af66fc99e Initial load
duke
parents:
diff changeset
2863 const int idx = oper.constant_position(globals, comp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2864 assert( idx != -1, "Constant component not found in operand");
a61af66fc99e Initial load
duke
parents:
diff changeset
2865 // Output code for this constant, type dependent.
a61af66fc99e Initial load
duke
parents:
diff changeset
2866 fprintf(fp," return (int)" );
a61af66fc99e Initial load
duke
parents:
diff changeset
2867 oper.access_constant(fp, globals, (uint)idx /* , const_type */);
a61af66fc99e Initial load
duke
parents:
diff changeset
2868 fprintf(fp,";\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2869 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2870 assert( false, "Attempting to emit a non-register or non-constant");
a61af66fc99e Initial load
duke
parents:
diff changeset
2871 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2872 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2873 else if( *encoding == '0' && *(encoding+1) == 'x' ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2874 // Hex value
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
2875 fprintf(fp," return %s;\n", encoding);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2876 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2877 assert( false, "Do not support octal or decimal encode constants");
a61af66fc99e Initial load
duke
parents:
diff changeset
2878 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2879 fprintf(fp," }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2880
a61af66fc99e Initial load
duke
parents:
diff changeset
2881 if( emit_position && (position != -1) && (oper.num_edges(globals) > 0) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2882 fprintf(fp," virtual int %s_position() const { return %d; }\n", name, position);
a61af66fc99e Initial load
duke
parents:
diff changeset
2883 MemInterface *mem_interface = oper._interface->is_MemInterface();
a61af66fc99e Initial load
duke
parents:
diff changeset
2884 const char *base = mem_interface->_base;
a61af66fc99e Initial load
duke
parents:
diff changeset
2885 const char *disp = mem_interface->_disp;
a61af66fc99e Initial load
duke
parents:
diff changeset
2886 if( emit_position && (strcmp(name,"base") == 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
2887 && base != NULL && is_regI(base, oper, globals)
a61af66fc99e Initial load
duke
parents:
diff changeset
2888 && disp != NULL && is_conP(disp, oper, globals) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2889 // Found a memory access using a constant pointer for a displacement
a61af66fc99e Initial load
duke
parents:
diff changeset
2890 // and a base register containing an integer offset.
a61af66fc99e Initial load
duke
parents:
diff changeset
2891 // In this case the base and disp are reversed with respect to what
a61af66fc99e Initial load
duke
parents:
diff changeset
2892 // is expected by MachNode::get_base_and_disp() and MachNode::adr_type().
a61af66fc99e Initial load
duke
parents:
diff changeset
2893 // Provide a non-NULL return for disp_as_type() that will allow adr_type()
a61af66fc99e Initial load
duke
parents:
diff changeset
2894 // to correctly compute the access type for alias analysis.
a61af66fc99e Initial load
duke
parents:
diff changeset
2895 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2896 // See BugId 4796752, operand indOffset32X in i486.ad
a61af66fc99e Initial load
duke
parents:
diff changeset
2897 int idx = rep_var_to_constant_index(disp, oper, globals);
a61af66fc99e Initial load
duke
parents:
diff changeset
2898 fprintf(fp," virtual const TypePtr *disp_as_type() const { return _c%d; }\n", idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
2899 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2900 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2901 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2902
a61af66fc99e Initial load
duke
parents:
diff changeset
2903 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2904 // Construct the method to copy _idx, inputs and operands to new node.
a61af66fc99e Initial load
duke
parents:
diff changeset
2905 static void define_fill_new_machnode(bool used, FILE *fp_cpp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2906 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2907 fprintf(fp_cpp, "// Copy _idx, inputs and operands to new node\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2908 fprintf(fp_cpp, "void MachNode::fill_new_machnode( MachNode* node, Compile* C) const {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2909 if( !used ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2910 fprintf(fp_cpp, " // This architecture does not have cisc or short branch instructions\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2911 fprintf(fp_cpp, " ShouldNotCallThis();\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2912 fprintf(fp_cpp, "}\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2913 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2914 // New node must use same node index for access through allocator's tables
a61af66fc99e Initial load
duke
parents:
diff changeset
2915 fprintf(fp_cpp, " // New node must use same node index\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2916 fprintf(fp_cpp, " node->set_idx( _idx );\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2917 // Copy machine-independent inputs
a61af66fc99e Initial load
duke
parents:
diff changeset
2918 fprintf(fp_cpp, " // Copy machine-independent inputs\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2919 fprintf(fp_cpp, " for( uint j = 0; j < req(); j++ ) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2920 fprintf(fp_cpp, " node->add_req(in(j));\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2921 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2922 // Copy machine operands to new MachNode
a61af66fc99e Initial load
duke
parents:
diff changeset
2923 fprintf(fp_cpp, " // Copy my operands, except for cisc position\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2924 fprintf(fp_cpp, " int nopnds = num_opnds();\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2925 fprintf(fp_cpp, " assert( node->num_opnds() == (uint)nopnds, \"Must have same number of operands\");\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2926 fprintf(fp_cpp, " MachOper **to = node->_opnds;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2927 fprintf(fp_cpp, " for( int i = 0; i < nopnds; i++ ) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2928 fprintf(fp_cpp, " if( i != cisc_operand() ) \n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2929 fprintf(fp_cpp, " to[i] = _opnds[i]->clone(C);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2930 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2931 fprintf(fp_cpp, "}\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2932 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2933 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2934 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2935
a61af66fc99e Initial load
duke
parents:
diff changeset
2936 //------------------------------defineClasses----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2937 // Define members of MachNode and MachOper classes based on
a61af66fc99e Initial load
duke
parents:
diff changeset
2938 // operand and instruction lists
a61af66fc99e Initial load
duke
parents:
diff changeset
2939 void ArchDesc::defineClasses(FILE *fp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2940
a61af66fc99e Initial load
duke
parents:
diff changeset
2941 // Define the contents of an array containing the machine register names
a61af66fc99e Initial load
duke
parents:
diff changeset
2942 defineRegNames(fp, _register);
a61af66fc99e Initial load
duke
parents:
diff changeset
2943 // Define an array containing the machine register encoding values
a61af66fc99e Initial load
duke
parents:
diff changeset
2944 defineRegEncodes(fp, _register);
a61af66fc99e Initial load
duke
parents:
diff changeset
2945 // Generate an enumeration of user-defined register classes
a61af66fc99e Initial load
duke
parents:
diff changeset
2946 // and a list of register masks, one for each class.
a61af66fc99e Initial load
duke
parents:
diff changeset
2947 // Only define the RegMask value objects in the expand file.
a61af66fc99e Initial load
duke
parents:
diff changeset
2948 // Declare each as an extern const RegMask ...; in ad_<arch>.hpp
a61af66fc99e Initial load
duke
parents:
diff changeset
2949 declare_register_masks(_HPP_file._fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2950 // build_register_masks(fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2951 build_register_masks(_CPP_EXPAND_file._fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2952 // Define the pipe_classes
a61af66fc99e Initial load
duke
parents:
diff changeset
2953 build_pipe_classes(_CPP_PIPELINE_file._fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
2954
a61af66fc99e Initial load
duke
parents:
diff changeset
2955 // Generate Machine Classes for each operand defined in AD file
a61af66fc99e Initial load
duke
parents:
diff changeset
2956 fprintf(fp,"\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2957 fprintf(fp,"\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2958 fprintf(fp,"//------------------Define classes derived from MachOper---------------------\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2959 // Iterate through all operands
a61af66fc99e Initial load
duke
parents:
diff changeset
2960 _operands.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
2961 OperandForm *oper;
a61af66fc99e Initial load
duke
parents:
diff changeset
2962 for( ; (oper = (OperandForm*)_operands.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2963 // Ensure this is a machine-world instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
2964 if ( oper->ideal_only() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2965 // !!!!!
a61af66fc99e Initial load
duke
parents:
diff changeset
2966 // The declaration of labelOper is in machine-independent file: machnode
a61af66fc99e Initial load
duke
parents:
diff changeset
2967 if ( strcmp(oper->_ident,"label") == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2968 defineIn_RegMask(_CPP_MISC_file._fp, _globalNames, *oper);
a61af66fc99e Initial load
duke
parents:
diff changeset
2969
a61af66fc99e Initial load
duke
parents:
diff changeset
2970 fprintf(fp,"MachOper *%sOper::clone(Compile* C) const {\n", oper->_ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
2971 fprintf(fp," return new (C) %sOper(_label, _block_num);\n", oper->_ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
2972 fprintf(fp,"}\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2973
a61af66fc99e Initial load
duke
parents:
diff changeset
2974 fprintf(fp,"uint %sOper::opcode() const { return %s; }\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
2975 oper->_ident, machOperEnum(oper->_ident));
a61af66fc99e Initial load
duke
parents:
diff changeset
2976 // // Currently all XXXOper::Hash() methods are identical (990820)
a61af66fc99e Initial load
duke
parents:
diff changeset
2977 // define_hash(fp, oper->_ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
2978 // // Currently all XXXOper::Cmp() methods are identical (990820)
a61af66fc99e Initial load
duke
parents:
diff changeset
2979 // define_cmp(fp, oper->_ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
2980 fprintf(fp,"\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2981
a61af66fc99e Initial load
duke
parents:
diff changeset
2982 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
2983 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2984
a61af66fc99e Initial load
duke
parents:
diff changeset
2985 // The declaration of methodOper is in machine-independent file: machnode
a61af66fc99e Initial load
duke
parents:
diff changeset
2986 if ( strcmp(oper->_ident,"method") == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2987 defineIn_RegMask(_CPP_MISC_file._fp, _globalNames, *oper);
a61af66fc99e Initial load
duke
parents:
diff changeset
2988
a61af66fc99e Initial load
duke
parents:
diff changeset
2989 fprintf(fp,"MachOper *%sOper::clone(Compile* C) const {\n", oper->_ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
2990 fprintf(fp," return new (C) %sOper(_method);\n", oper->_ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
2991 fprintf(fp,"}\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
2992
a61af66fc99e Initial load
duke
parents:
diff changeset
2993 fprintf(fp,"uint %sOper::opcode() const { return %s; }\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
2994 oper->_ident, machOperEnum(oper->_ident));
a61af66fc99e Initial load
duke
parents:
diff changeset
2995 // // Currently all XXXOper::Hash() methods are identical (990820)
a61af66fc99e Initial load
duke
parents:
diff changeset
2996 // define_hash(fp, oper->_ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
2997 // // Currently all XXXOper::Cmp() methods are identical (990820)
a61af66fc99e Initial load
duke
parents:
diff changeset
2998 // define_cmp(fp, oper->_ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
2999 fprintf(fp,"\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3000
a61af66fc99e Initial load
duke
parents:
diff changeset
3001 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3002 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3003
a61af66fc99e Initial load
duke
parents:
diff changeset
3004 defineIn_RegMask(fp, _globalNames, *oper);
a61af66fc99e Initial load
duke
parents:
diff changeset
3005 defineClone(_CPP_CLONE_file._fp, _globalNames, *oper);
a61af66fc99e Initial load
duke
parents:
diff changeset
3006 // // Currently all XXXOper::Hash() methods are identical (990820)
a61af66fc99e Initial load
duke
parents:
diff changeset
3007 // define_hash(fp, oper->_ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
3008 // // Currently all XXXOper::Cmp() methods are identical (990820)
a61af66fc99e Initial load
duke
parents:
diff changeset
3009 // define_cmp(fp, oper->_ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
3010
a61af66fc99e Initial load
duke
parents:
diff changeset
3011 // side-call to generate output that used to be in the header file:
a61af66fc99e Initial load
duke
parents:
diff changeset
3012 extern void gen_oper_format(FILE *fp, FormDict &globals, OperandForm &oper, bool for_c_file);
a61af66fc99e Initial load
duke
parents:
diff changeset
3013 gen_oper_format(_CPP_FORMAT_file._fp, _globalNames, *oper, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3014
a61af66fc99e Initial load
duke
parents:
diff changeset
3015 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3016
a61af66fc99e Initial load
duke
parents:
diff changeset
3017
a61af66fc99e Initial load
duke
parents:
diff changeset
3018 // Generate Machine Classes for each instruction defined in AD file
a61af66fc99e Initial load
duke
parents:
diff changeset
3019 fprintf(fp,"//------------------Define members for classes derived from MachNode----------\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3020 // Output the definitions for out_RegMask() // & kill_RegMask()
a61af66fc99e Initial load
duke
parents:
diff changeset
3021 _instructions.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3022 InstructForm *instr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3023 MachNodeForm *machnode;
a61af66fc99e Initial load
duke
parents:
diff changeset
3024 for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3025 // Ensure this is a machine-world instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
3026 if ( instr->ideal_only() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3027
a61af66fc99e Initial load
duke
parents:
diff changeset
3028 defineOut_RegMask(_CPP_MISC_file._fp, instr->_ident, reg_mask(*instr));
a61af66fc99e Initial load
duke
parents:
diff changeset
3029 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3030
a61af66fc99e Initial load
duke
parents:
diff changeset
3031 bool used = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3032 // Output the definitions for expand rules & peephole rules
a61af66fc99e Initial load
duke
parents:
diff changeset
3033 _instructions.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3034 for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3035 // Ensure this is a machine-world instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
3036 if ( instr->ideal_only() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3037 // If there are multiple defs/kills, or an explicit expand rule, build rule
a61af66fc99e Initial load
duke
parents:
diff changeset
3038 if( instr->expands() || instr->needs_projections() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
3039 instr->has_temps() ||
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
3040 instr->is_mach_constant() ||
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3041 instr->_matrule != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3042 instr->num_opnds() != instr->num_unique_opnds() )
a61af66fc99e Initial load
duke
parents:
diff changeset
3043 defineExpand(_CPP_EXPAND_file._fp, instr);
a61af66fc99e Initial load
duke
parents:
diff changeset
3044 // If there is an explicit peephole rule, build it
a61af66fc99e Initial load
duke
parents:
diff changeset
3045 if ( instr->peepholes() )
a61af66fc99e Initial load
duke
parents:
diff changeset
3046 definePeephole(_CPP_PEEPHOLE_file._fp, instr);
a61af66fc99e Initial load
duke
parents:
diff changeset
3047
a61af66fc99e Initial load
duke
parents:
diff changeset
3048 // Output code to convert to the cisc version, if applicable
a61af66fc99e Initial load
duke
parents:
diff changeset
3049 used |= instr->define_cisc_version(*this, fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
3050
a61af66fc99e Initial load
duke
parents:
diff changeset
3051 // Output code to convert to the short branch version, if applicable
1541
b5fdf39b9749 6953576: bottom_type for matched AddPNodes doesn't always agree with ideal
never
parents: 1489
diff changeset
3052 used |= instr->define_short_branch_methods(*this, fp);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3053 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3054
a61af66fc99e Initial load
duke
parents:
diff changeset
3055 // Construct the method called by cisc_version() to copy inputs and operands.
a61af66fc99e Initial load
duke
parents:
diff changeset
3056 define_fill_new_machnode(used, fp);
a61af66fc99e Initial load
duke
parents:
diff changeset
3057
a61af66fc99e Initial load
duke
parents:
diff changeset
3058 // Output the definitions for labels
a61af66fc99e Initial load
duke
parents:
diff changeset
3059 _instructions.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3060 while( (instr = (InstructForm*)_instructions.iter()) != NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3061 // Ensure this is a machine-world instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
3062 if ( instr->ideal_only() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3063
a61af66fc99e Initial load
duke
parents:
diff changeset
3064 // Access the fields for operand Label
a61af66fc99e Initial load
duke
parents:
diff changeset
3065 int label_position = instr->label_position();
a61af66fc99e Initial load
duke
parents:
diff changeset
3066 if( label_position != -1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3067 // Set the label
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2426
diff changeset
3068 fprintf(fp,"void %sNode::label_set( Label* label, uint block_num ) {\n", instr->_ident);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3069 fprintf(fp," labelOper* oper = (labelOper*)(opnd_array(%d));\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
3070 label_position );
3839
3d42f82cd811 7063628: Use cbcond on T4
kvn
parents: 2426
diff changeset
3071 fprintf(fp," oper->_label = label;\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3072 fprintf(fp," oper->_block_num = block_num;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3073 fprintf(fp,"}\n");
3853
11211f7cb5a0 7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents: 3839
diff changeset
3074 // Save the label
11211f7cb5a0 7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents: 3839
diff changeset
3075 fprintf(fp,"void %sNode::save_label( Label** label, uint* block_num ) {\n", instr->_ident);
11211f7cb5a0 7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents: 3839
diff changeset
3076 fprintf(fp," labelOper* oper = (labelOper*)(opnd_array(%d));\n",
11211f7cb5a0 7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents: 3839
diff changeset
3077 label_position );
11211f7cb5a0 7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents: 3839
diff changeset
3078 fprintf(fp," *label = oper->_label;\n");
11211f7cb5a0 7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents: 3839
diff changeset
3079 fprintf(fp," *block_num = oper->_block_num;\n");
11211f7cb5a0 7079317: Incorrect branch's destination block in PrintoOptoAssembly output
kvn
parents: 3839
diff changeset
3080 fprintf(fp,"}\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3081 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3082 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3083
a61af66fc99e Initial load
duke
parents:
diff changeset
3084 // Output the definitions for methods
a61af66fc99e Initial load
duke
parents:
diff changeset
3085 _instructions.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3086 while( (instr = (InstructForm*)_instructions.iter()) != NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3087 // Ensure this is a machine-world instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
3088 if ( instr->ideal_only() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3089
a61af66fc99e Initial load
duke
parents:
diff changeset
3090 // Access the fields for operand Label
a61af66fc99e Initial load
duke
parents:
diff changeset
3091 int method_position = instr->method_position();
a61af66fc99e Initial load
duke
parents:
diff changeset
3092 if( method_position != -1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3093 // Access the method's address
a61af66fc99e Initial load
duke
parents:
diff changeset
3094 fprintf(fp,"void %sNode::method_set( intptr_t method ) {\n", instr->_ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
3095 fprintf(fp," ((methodOper*)opnd_array(%d))->_method = method;\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
3096 method_position );
a61af66fc99e Initial load
duke
parents:
diff changeset
3097 fprintf(fp,"}\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3098 fprintf(fp,"\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3099 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3100 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3101
a61af66fc99e Initial load
duke
parents:
diff changeset
3102 // Define this instruction's number of relocation entries, base is '0'
a61af66fc99e Initial load
duke
parents:
diff changeset
3103 _instructions.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3104 while( (instr = (InstructForm*)_instructions.iter()) != NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3105 // Output the definition for number of relocation entries
a61af66fc99e Initial load
duke
parents:
diff changeset
3106 uint reloc_size = instr->reloc(_globalNames);
a61af66fc99e Initial load
duke
parents:
diff changeset
3107 if ( reloc_size != 0 ) {
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
3108 fprintf(fp,"int %sNode::reloc() const {\n", instr->_ident);
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
3109 fprintf(fp," return %d;\n", reloc_size);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3110 fprintf(fp,"}\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3111 fprintf(fp,"\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3112 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3114 fprintf(fp,"\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3115
a61af66fc99e Initial load
duke
parents:
diff changeset
3116 // Output the definitions for code generation
a61af66fc99e Initial load
duke
parents:
diff changeset
3117 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3118 // address ___Node::emit(address ptr, PhaseRegAlloc *ra_) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
3119 // // ... encoding defined by user
a61af66fc99e Initial load
duke
parents:
diff changeset
3120 // return ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3121 // }
a61af66fc99e Initial load
duke
parents:
diff changeset
3122 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3123 _instructions.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3124 for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3125 // Ensure this is a machine-world instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
3126 if ( instr->ideal_only() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3127
2008
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
3128 if (instr->_insencode) defineEmit (fp, *instr);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
3129 if (instr->is_mach_constant()) defineEvalConstant(fp, *instr);
2f644f85485d 6961690: load oops from constant table on SPARC
twisti
parents: 1748
diff changeset
3130 if (instr->_size) defineSize (fp, *instr);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3131
a61af66fc99e Initial load
duke
parents:
diff changeset
3132 // side-call to generate output that used to be in the header file:
a61af66fc99e Initial load
duke
parents:
diff changeset
3133 extern void gen_inst_format(FILE *fp, FormDict &globals, InstructForm &oper, bool for_c_file);
a61af66fc99e Initial load
duke
parents:
diff changeset
3134 gen_inst_format(_CPP_FORMAT_file._fp, _globalNames, *instr, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
3135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3136
a61af66fc99e Initial load
duke
parents:
diff changeset
3137 // Output the definitions for alias analysis
a61af66fc99e Initial load
duke
parents:
diff changeset
3138 _instructions.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3139 for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3140 // Ensure this is a machine-world instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
3141 if ( instr->ideal_only() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3142
a61af66fc99e Initial load
duke
parents:
diff changeset
3143 // Analyze machine instructions that either USE or DEF memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
3144 int memory_operand = instr->memory_operand(_globalNames);
a61af66fc99e Initial load
duke
parents:
diff changeset
3145 // Some guys kill all of memory
a61af66fc99e Initial load
duke
parents:
diff changeset
3146 if ( instr->is_wide_memory_kill(_globalNames) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3147 memory_operand = InstructForm::MANY_MEMORY_OPERANDS;
a61af66fc99e Initial load
duke
parents:
diff changeset
3148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3149
a61af66fc99e Initial load
duke
parents:
diff changeset
3150 if ( memory_operand != InstructForm::NO_MEMORY_OPERAND ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3151 if( memory_operand == InstructForm::MANY_MEMORY_OPERANDS ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3152 fprintf(fp,"const TypePtr *%sNode::adr_type() const { return TypePtr::BOTTOM; }\n", instr->_ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
3153 fprintf(fp,"const MachOper* %sNode::memory_operand() const { return (MachOper*)-1; }\n", instr->_ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
3154 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3155 fprintf(fp,"const MachOper* %sNode::memory_operand() const { return _opnds[%d]; }\n", instr->_ident, memory_operand);
a61af66fc99e Initial load
duke
parents:
diff changeset
3156 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3157 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3159
a61af66fc99e Initial load
duke
parents:
diff changeset
3160 // Get the length of the longest identifier
a61af66fc99e Initial load
duke
parents:
diff changeset
3161 int max_ident_len = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3162 _instructions.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3163
a61af66fc99e Initial load
duke
parents:
diff changeset
3164 for ( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3165 if (instr->_ins_pipe && _pipeline->_classlist.search(instr->_ins_pipe)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3166 int ident_len = (int)strlen(instr->_ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
3167 if( max_ident_len < ident_len )
a61af66fc99e Initial load
duke
parents:
diff changeset
3168 max_ident_len = ident_len;
a61af66fc99e Initial load
duke
parents:
diff changeset
3169 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3170 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3171
a61af66fc99e Initial load
duke
parents:
diff changeset
3172 // Emit specifically for Node(s)
a61af66fc99e Initial load
duke
parents:
diff changeset
3173 fprintf(_CPP_PIPELINE_file._fp, "const Pipeline * %*s::pipeline_class() { return %s; }\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
3174 max_ident_len, "Node", _pipeline ? "(&pipeline_class_Zero_Instructions)" : "NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
3175 fprintf(_CPP_PIPELINE_file._fp, "const Pipeline * %*s::pipeline() const { return %s; }\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
3176 max_ident_len, "Node", _pipeline ? "(&pipeline_class_Zero_Instructions)" : "NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
3177 fprintf(_CPP_PIPELINE_file._fp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3178
a61af66fc99e Initial load
duke
parents:
diff changeset
3179 fprintf(_CPP_PIPELINE_file._fp, "const Pipeline * %*s::pipeline_class() { return %s; }\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
3180 max_ident_len, "MachNode", _pipeline ? "(&pipeline_class_Unknown_Instructions)" : "NULL");
a61af66fc99e Initial load
duke
parents:
diff changeset
3181 fprintf(_CPP_PIPELINE_file._fp, "const Pipeline * %*s::pipeline() const { return pipeline_class(); }\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
3182 max_ident_len, "MachNode");
a61af66fc99e Initial load
duke
parents:
diff changeset
3183 fprintf(_CPP_PIPELINE_file._fp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3184
a61af66fc99e Initial load
duke
parents:
diff changeset
3185 // Output the definitions for machine node specific pipeline data
a61af66fc99e Initial load
duke
parents:
diff changeset
3186 _machnodes.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3187
a61af66fc99e Initial load
duke
parents:
diff changeset
3188 for ( ; (machnode = (MachNodeForm*)_machnodes.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3189 fprintf(_CPP_PIPELINE_file._fp, "const Pipeline * %sNode::pipeline() const { return (&pipeline_class_%03d); }\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
3190 machnode->_ident, ((class PipeClassForm *)_pipeline->_classdict[machnode->_machnode_pipe])->_num);
a61af66fc99e Initial load
duke
parents:
diff changeset
3191 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3192
a61af66fc99e Initial load
duke
parents:
diff changeset
3193 fprintf(_CPP_PIPELINE_file._fp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3194
a61af66fc99e Initial load
duke
parents:
diff changeset
3195 // Output the definitions for instruction pipeline static data references
a61af66fc99e Initial load
duke
parents:
diff changeset
3196 _instructions.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3197
a61af66fc99e Initial load
duke
parents:
diff changeset
3198 for ( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3199 if (instr->_ins_pipe && _pipeline->_classlist.search(instr->_ins_pipe)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3200 fprintf(_CPP_PIPELINE_file._fp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3201 fprintf(_CPP_PIPELINE_file._fp, "const Pipeline * %*sNode::pipeline_class() { return (&pipeline_class_%03d); }\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
3202 max_ident_len, instr->_ident, ((class PipeClassForm *)_pipeline->_classdict[instr->_ins_pipe])->_num);
a61af66fc99e Initial load
duke
parents:
diff changeset
3203 fprintf(_CPP_PIPELINE_file._fp, "const Pipeline * %*sNode::pipeline() const { return (&pipeline_class_%03d); }\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
3204 max_ident_len, instr->_ident, ((class PipeClassForm *)_pipeline->_classdict[instr->_ins_pipe])->_num);
a61af66fc99e Initial load
duke
parents:
diff changeset
3205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3206 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3207 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3208
a61af66fc99e Initial load
duke
parents:
diff changeset
3209
a61af66fc99e Initial load
duke
parents:
diff changeset
3210 // -------------------------------- maps ------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3211
a61af66fc99e Initial load
duke
parents:
diff changeset
3212 // Information needed to generate the ReduceOp mapping for the DFA
a61af66fc99e Initial load
duke
parents:
diff changeset
3213 class OutputReduceOp : public OutputMap {
a61af66fc99e Initial load
duke
parents:
diff changeset
3214 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
3215 OutputReduceOp(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
3216 : OutputMap(hpp, cpp, globals, AD, "reduceOp") {};
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3217
a61af66fc99e Initial load
duke
parents:
diff changeset
3218 void declaration() { fprintf(_hpp, "extern const int reduceOp[];\n"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3219 void definition() { fprintf(_cpp, "const int reduceOp[] = {\n"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3220 void closing() { fprintf(_cpp, " 0 // no trailing comma\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3221 OutputMap::closing();
a61af66fc99e Initial load
duke
parents:
diff changeset
3222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3223 void map(OpClassForm &opc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3224 const char *reduce = opc._ident;
a61af66fc99e Initial load
duke
parents:
diff changeset
3225 if( reduce ) fprintf(_cpp, " %s_rule", reduce);
a61af66fc99e Initial load
duke
parents:
diff changeset
3226 else fprintf(_cpp, " 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
3227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3228 void map(OperandForm &oper) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3229 // Most operands without match rules, e.g. eFlagsReg, do not have a result operand
a61af66fc99e Initial load
duke
parents:
diff changeset
3230 const char *reduce = (oper._matrule ? oper.reduce_result() : NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3231 // operand stackSlot does not have a match rule, but produces a stackSlot
a61af66fc99e Initial load
duke
parents:
diff changeset
3232 if( oper.is_user_name_for_sReg() != Form::none ) reduce = oper.reduce_result();
a61af66fc99e Initial load
duke
parents:
diff changeset
3233 if( reduce ) fprintf(_cpp, " %s_rule", reduce);
a61af66fc99e Initial load
duke
parents:
diff changeset
3234 else fprintf(_cpp, " 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
3235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3236 void map(InstructForm &inst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3237 const char *reduce = (inst._matrule ? inst.reduce_result() : NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
3238 if( reduce ) fprintf(_cpp, " %s_rule", reduce);
a61af66fc99e Initial load
duke
parents:
diff changeset
3239 else fprintf(_cpp, " 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
3240 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3241 void map(char *reduce) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3242 if( reduce ) fprintf(_cpp, " %s_rule", reduce);
a61af66fc99e Initial load
duke
parents:
diff changeset
3243 else fprintf(_cpp, " 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
3244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3245 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3246
a61af66fc99e Initial load
duke
parents:
diff changeset
3247 // Information needed to generate the LeftOp mapping for the DFA
a61af66fc99e Initial load
duke
parents:
diff changeset
3248 class OutputLeftOp : public OutputMap {
a61af66fc99e Initial load
duke
parents:
diff changeset
3249 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
3250 OutputLeftOp(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
3251 : OutputMap(hpp, cpp, globals, AD, "leftOp") {};
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3252
a61af66fc99e Initial load
duke
parents:
diff changeset
3253 void declaration() { fprintf(_hpp, "extern const int leftOp[];\n"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3254 void definition() { fprintf(_cpp, "const int leftOp[] = {\n"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3255 void closing() { fprintf(_cpp, " 0 // no trailing comma\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3256 OutputMap::closing();
a61af66fc99e Initial load
duke
parents:
diff changeset
3257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3258 void map(OpClassForm &opc) { fprintf(_cpp, " 0"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3259 void map(OperandForm &oper) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3260 const char *reduce = oper.reduce_left(_globals);
a61af66fc99e Initial load
duke
parents:
diff changeset
3261 if( reduce ) fprintf(_cpp, " %s_rule", reduce);
a61af66fc99e Initial load
duke
parents:
diff changeset
3262 else fprintf(_cpp, " 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
3263 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3264 void map(char *name) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3265 const char *reduce = _AD.reduceLeft(name);
a61af66fc99e Initial load
duke
parents:
diff changeset
3266 if( reduce ) fprintf(_cpp, " %s_rule", reduce);
a61af66fc99e Initial load
duke
parents:
diff changeset
3267 else fprintf(_cpp, " 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
3268 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3269 void map(InstructForm &inst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3270 const char *reduce = inst.reduce_left(_globals);
a61af66fc99e Initial load
duke
parents:
diff changeset
3271 if( reduce ) fprintf(_cpp, " %s_rule", reduce);
a61af66fc99e Initial load
duke
parents:
diff changeset
3272 else fprintf(_cpp, " 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
3273 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3274 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3275
a61af66fc99e Initial load
duke
parents:
diff changeset
3276
a61af66fc99e Initial load
duke
parents:
diff changeset
3277 // Information needed to generate the RightOp mapping for the DFA
a61af66fc99e Initial load
duke
parents:
diff changeset
3278 class OutputRightOp : public OutputMap {
a61af66fc99e Initial load
duke
parents:
diff changeset
3279 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
3280 OutputRightOp(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
3281 : OutputMap(hpp, cpp, globals, AD, "rightOp") {};
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3282
a61af66fc99e Initial load
duke
parents:
diff changeset
3283 void declaration() { fprintf(_hpp, "extern const int rightOp[];\n"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3284 void definition() { fprintf(_cpp, "const int rightOp[] = {\n"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3285 void closing() { fprintf(_cpp, " 0 // no trailing comma\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3286 OutputMap::closing();
a61af66fc99e Initial load
duke
parents:
diff changeset
3287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3288 void map(OpClassForm &opc) { fprintf(_cpp, " 0"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3289 void map(OperandForm &oper) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3290 const char *reduce = oper.reduce_right(_globals);
a61af66fc99e Initial load
duke
parents:
diff changeset
3291 if( reduce ) fprintf(_cpp, " %s_rule", reduce);
a61af66fc99e Initial load
duke
parents:
diff changeset
3292 else fprintf(_cpp, " 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
3293 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3294 void map(char *name) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3295 const char *reduce = _AD.reduceRight(name);
a61af66fc99e Initial load
duke
parents:
diff changeset
3296 if( reduce ) fprintf(_cpp, " %s_rule", reduce);
a61af66fc99e Initial load
duke
parents:
diff changeset
3297 else fprintf(_cpp, " 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
3298 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3299 void map(InstructForm &inst) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3300 const char *reduce = inst.reduce_right(_globals);
a61af66fc99e Initial load
duke
parents:
diff changeset
3301 if( reduce ) fprintf(_cpp, " %s_rule", reduce);
a61af66fc99e Initial load
duke
parents:
diff changeset
3302 else fprintf(_cpp, " 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
3303 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3304 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3305
a61af66fc99e Initial load
duke
parents:
diff changeset
3306
a61af66fc99e Initial load
duke
parents:
diff changeset
3307 // Information needed to generate the Rule names for the DFA
a61af66fc99e Initial load
duke
parents:
diff changeset
3308 class OutputRuleName : public OutputMap {
a61af66fc99e Initial load
duke
parents:
diff changeset
3309 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
3310 OutputRuleName(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
3311 : OutputMap(hpp, cpp, globals, AD, "ruleName") {};
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3312
a61af66fc99e Initial load
duke
parents:
diff changeset
3313 void declaration() { fprintf(_hpp, "extern const char *ruleName[];\n"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3314 void definition() { fprintf(_cpp, "const char *ruleName[] = {\n"); }
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
3315 void closing() { fprintf(_cpp, " \"invalid rule name\" // no trailing comma\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3316 OutputMap::closing();
a61af66fc99e Initial load
duke
parents:
diff changeset
3317 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3318 void map(OpClassForm &opc) { fprintf(_cpp, " \"%s\"", _AD.machOperEnum(opc._ident) ); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3319 void map(OperandForm &oper) { fprintf(_cpp, " \"%s\"", _AD.machOperEnum(oper._ident) ); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3320 void map(char *name) { fprintf(_cpp, " \"%s\"", name ? name : "0"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3321 void map(InstructForm &inst){ fprintf(_cpp, " \"%s\"", inst._ident ? inst._ident : "0"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3322 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3323
a61af66fc99e Initial load
duke
parents:
diff changeset
3324
a61af66fc99e Initial load
duke
parents:
diff changeset
3325 // Information needed to generate the swallowed mapping for the DFA
a61af66fc99e Initial load
duke
parents:
diff changeset
3326 class OutputSwallowed : public OutputMap {
a61af66fc99e Initial load
duke
parents:
diff changeset
3327 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
3328 OutputSwallowed(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
3329 : OutputMap(hpp, cpp, globals, AD, "swallowed") {};
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3330
a61af66fc99e Initial load
duke
parents:
diff changeset
3331 void declaration() { fprintf(_hpp, "extern const bool swallowed[];\n"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3332 void definition() { fprintf(_cpp, "const bool swallowed[] = {\n"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3333 void closing() { fprintf(_cpp, " false // no trailing comma\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3334 OutputMap::closing();
a61af66fc99e Initial load
duke
parents:
diff changeset
3335 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3336 void map(OperandForm &oper) { // Generate the entry for this opcode
a61af66fc99e Initial load
duke
parents:
diff changeset
3337 const char *swallowed = oper.swallowed(_globals) ? "true" : "false";
a61af66fc99e Initial load
duke
parents:
diff changeset
3338 fprintf(_cpp, " %s", swallowed);
a61af66fc99e Initial load
duke
parents:
diff changeset
3339 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3340 void map(OpClassForm &opc) { fprintf(_cpp, " false"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3341 void map(char *name) { fprintf(_cpp, " false"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3342 void map(InstructForm &inst){ fprintf(_cpp, " false"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3343 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3344
a61af66fc99e Initial load
duke
parents:
diff changeset
3345
a61af66fc99e Initial load
duke
parents:
diff changeset
3346 // Information needed to generate the decision array for instruction chain rule
a61af66fc99e Initial load
duke
parents:
diff changeset
3347 class OutputInstChainRule : public OutputMap {
a61af66fc99e Initial load
duke
parents:
diff changeset
3348 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
3349 OutputInstChainRule(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
3350 : OutputMap(hpp, cpp, globals, AD, "instruction_chain_rule") {};
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3351
a61af66fc99e Initial load
duke
parents:
diff changeset
3352 void declaration() { fprintf(_hpp, "extern const bool instruction_chain_rule[];\n"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3353 void definition() { fprintf(_cpp, "const bool instruction_chain_rule[] = {\n"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3354 void closing() { fprintf(_cpp, " false // no trailing comma\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3355 OutputMap::closing();
a61af66fc99e Initial load
duke
parents:
diff changeset
3356 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3357 void map(OpClassForm &opc) { fprintf(_cpp, " false"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3358 void map(OperandForm &oper) { fprintf(_cpp, " false"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3359 void map(char *name) { fprintf(_cpp, " false"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
3360 void map(InstructForm &inst) { // Check for simple chain rule
a61af66fc99e Initial load
duke
parents:
diff changeset
3361 const char *chain = inst.is_simple_chain_rule(_globals) ? "true" : "false";
a61af66fc99e Initial load
duke
parents:
diff changeset
3362 fprintf(_cpp, " %s", chain);
a61af66fc99e Initial load
duke
parents:
diff changeset
3363 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3364 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3365
a61af66fc99e Initial load
duke
parents:
diff changeset
3366
a61af66fc99e Initial load
duke
parents:
diff changeset
3367 //---------------------------build_map------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3368 // Build mapping from enumeration for densely packed operands
a61af66fc99e Initial load
duke
parents:
diff changeset
3369 // TO result and child types.
a61af66fc99e Initial load
duke
parents:
diff changeset
3370 void ArchDesc::build_map(OutputMap &map) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3371 FILE *fp_hpp = map.decl_file();
a61af66fc99e Initial load
duke
parents:
diff changeset
3372 FILE *fp_cpp = map.def_file();
a61af66fc99e Initial load
duke
parents:
diff changeset
3373 int idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3374 OperandForm *op;
a61af66fc99e Initial load
duke
parents:
diff changeset
3375 OpClassForm *opc;
a61af66fc99e Initial load
duke
parents:
diff changeset
3376 InstructForm *inst;
a61af66fc99e Initial load
duke
parents:
diff changeset
3377
a61af66fc99e Initial load
duke
parents:
diff changeset
3378 // Construct this mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
3379 map.declaration();
a61af66fc99e Initial load
duke
parents:
diff changeset
3380 fprintf(fp_cpp,"\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3381 map.definition();
a61af66fc99e Initial load
duke
parents:
diff changeset
3382
a61af66fc99e Initial load
duke
parents:
diff changeset
3383 // Output the mapping for operands
a61af66fc99e Initial load
duke
parents:
diff changeset
3384 map.record_position(OutputMap::BEGIN_OPERANDS, idx );
a61af66fc99e Initial load
duke
parents:
diff changeset
3385 _operands.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3386 for(; (op = (OperandForm*)_operands.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3387 // Ensure this is a machine-world instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
3388 if ( op->ideal_only() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3389
a61af66fc99e Initial load
duke
parents:
diff changeset
3390 // Generate the entry for this opcode
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
3391 fprintf(fp_cpp, " /* %4d */", idx); map.map(*op); fprintf(fp_cpp, ",\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3392 ++idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
3393 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3394 fprintf(fp_cpp, " // last operand\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3395
a61af66fc99e Initial load
duke
parents:
diff changeset
3396 // Place all user-defined operand classes into the mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
3397 map.record_position(OutputMap::BEGIN_OPCLASSES, idx );
a61af66fc99e Initial load
duke
parents:
diff changeset
3398 _opclass.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3399 for(; (opc = (OpClassForm*)_opclass.iter()) != NULL; ) {
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
3400 fprintf(fp_cpp, " /* %4d */", idx); map.map(*opc); fprintf(fp_cpp, ",\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3401 ++idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
3402 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3403 fprintf(fp_cpp, " // last operand class\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3404
a61af66fc99e Initial load
duke
parents:
diff changeset
3405 // Place all internally defined operands into the mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
3406 map.record_position(OutputMap::BEGIN_INTERNALS, idx );
a61af66fc99e Initial load
duke
parents:
diff changeset
3407 _internalOpNames.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3408 char *name = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3409 for(; (name = (char *)_internalOpNames.iter()) != NULL; ) {
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
3410 fprintf(fp_cpp, " /* %4d */", idx); map.map(name); fprintf(fp_cpp, ",\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3411 ++idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
3412 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3413 fprintf(fp_cpp, " // last internally defined operand\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3414
a61af66fc99e Initial load
duke
parents:
diff changeset
3415 // Place all user-defined instructions into the mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
3416 if( map.do_instructions() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3417 map.record_position(OutputMap::BEGIN_INSTRUCTIONS, idx );
a61af66fc99e Initial load
duke
parents:
diff changeset
3418 // Output all simple instruction chain rules first
a61af66fc99e Initial load
duke
parents:
diff changeset
3419 map.record_position(OutputMap::BEGIN_INST_CHAIN_RULES, idx );
a61af66fc99e Initial load
duke
parents:
diff changeset
3420 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3421 _instructions.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3422 for(; (inst = (InstructForm*)_instructions.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3423 // Ensure this is a machine-world instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
3424 if ( inst->ideal_only() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3425 if ( ! inst->is_simple_chain_rule(_globalNames) ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3426 if ( inst->rematerialize(_globalNames, get_registers()) ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3427
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
3428 fprintf(fp_cpp, " /* %4d */", idx); map.map(*inst); fprintf(fp_cpp, ",\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3429 ++idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
3430 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3431 map.record_position(OutputMap::BEGIN_REMATERIALIZE, idx );
a61af66fc99e Initial load
duke
parents:
diff changeset
3432 _instructions.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3433 for(; (inst = (InstructForm*)_instructions.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3434 // Ensure this is a machine-world instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
3435 if ( inst->ideal_only() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3436 if ( ! inst->is_simple_chain_rule(_globalNames) ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3437 if ( ! inst->rematerialize(_globalNames, get_registers()) ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3438
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
3439 fprintf(fp_cpp, " /* %4d */", idx); map.map(*inst); fprintf(fp_cpp, ",\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3440 ++idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
3441 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3442 map.record_position(OutputMap::END_INST_CHAIN_RULES, idx );
a61af66fc99e Initial load
duke
parents:
diff changeset
3443 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3444 // Output all instructions that are NOT simple chain rules
a61af66fc99e Initial load
duke
parents:
diff changeset
3445 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3446 _instructions.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3447 for(; (inst = (InstructForm*)_instructions.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3448 // Ensure this is a machine-world instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
3449 if ( inst->ideal_only() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3450 if ( inst->is_simple_chain_rule(_globalNames) ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3451 if ( ! inst->rematerialize(_globalNames, get_registers()) ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3452
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
3453 fprintf(fp_cpp, " /* %4d */", idx); map.map(*inst); fprintf(fp_cpp, ",\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3454 ++idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
3455 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3456 map.record_position(OutputMap::END_REMATERIALIZE, idx );
a61af66fc99e Initial load
duke
parents:
diff changeset
3457 _instructions.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3458 for(; (inst = (InstructForm*)_instructions.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3459 // Ensure this is a machine-world instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
3460 if ( inst->ideal_only() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3461 if ( inst->is_simple_chain_rule(_globalNames) ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3462 if ( inst->rematerialize(_globalNames, get_registers()) ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3463
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
3464 fprintf(fp_cpp, " /* %4d */", idx); map.map(*inst); fprintf(fp_cpp, ",\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3465 ++idx;
a61af66fc99e Initial load
duke
parents:
diff changeset
3466 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3467 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3468 fprintf(fp_cpp, " // last instruction\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3469 map.record_position(OutputMap::END_INSTRUCTIONS, idx );
a61af66fc99e Initial load
duke
parents:
diff changeset
3470 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3471 // Finish defining table
a61af66fc99e Initial load
duke
parents:
diff changeset
3472 map.closing();
a61af66fc99e Initial load
duke
parents:
diff changeset
3473 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3474
a61af66fc99e Initial load
duke
parents:
diff changeset
3475
a61af66fc99e Initial load
duke
parents:
diff changeset
3476 // Helper function for buildReduceMaps
a61af66fc99e Initial load
duke
parents:
diff changeset
3477 char reg_save_policy(const char *calling_convention) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3478 char callconv;
a61af66fc99e Initial load
duke
parents:
diff changeset
3479
a61af66fc99e Initial load
duke
parents:
diff changeset
3480 if (!strcmp(calling_convention, "NS")) callconv = 'N';
a61af66fc99e Initial load
duke
parents:
diff changeset
3481 else if (!strcmp(calling_convention, "SOE")) callconv = 'E';
a61af66fc99e Initial load
duke
parents:
diff changeset
3482 else if (!strcmp(calling_convention, "SOC")) callconv = 'C';
a61af66fc99e Initial load
duke
parents:
diff changeset
3483 else if (!strcmp(calling_convention, "AS")) callconv = 'A';
a61af66fc99e Initial load
duke
parents:
diff changeset
3484 else callconv = 'Z';
a61af66fc99e Initial load
duke
parents:
diff changeset
3485
a61af66fc99e Initial load
duke
parents:
diff changeset
3486 return callconv;
a61af66fc99e Initial load
duke
parents:
diff changeset
3487 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3488
a61af66fc99e Initial load
duke
parents:
diff changeset
3489 //---------------------------generate_assertion_checks-------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3490 void ArchDesc::generate_adlc_verification(FILE *fp_cpp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3491 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3492
a61af66fc99e Initial load
duke
parents:
diff changeset
3493 fprintf(fp_cpp, "#ifndef PRODUCT\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3494 fprintf(fp_cpp, "void Compile::adlc_verification() {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3495 globalDefs().print_asserts(fp_cpp);
a61af66fc99e Initial load
duke
parents:
diff changeset
3496 fprintf(fp_cpp, "}\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3497 fprintf(fp_cpp, "#endif\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3498 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3499 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3500
a61af66fc99e Initial load
duke
parents:
diff changeset
3501 //---------------------------addSourceBlocks-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3502 void ArchDesc::addSourceBlocks(FILE *fp_cpp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3503 if (_source.count() > 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
3504 _source.output(fp_cpp);
a61af66fc99e Initial load
duke
parents:
diff changeset
3505
a61af66fc99e Initial load
duke
parents:
diff changeset
3506 generate_adlc_verification(fp_cpp);
a61af66fc99e Initial load
duke
parents:
diff changeset
3507 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3508 //---------------------------addHeaderBlocks-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3509 void ArchDesc::addHeaderBlocks(FILE *fp_hpp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3510 if (_header.count() > 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
3511 _header.output(fp_hpp);
a61af66fc99e Initial load
duke
parents:
diff changeset
3512 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3513 //-------------------------addPreHeaderBlocks----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3514 void ArchDesc::addPreHeaderBlocks(FILE *fp_hpp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3515 // Output #defines from definition block
a61af66fc99e Initial load
duke
parents:
diff changeset
3516 globalDefs().print_defines(fp_hpp);
a61af66fc99e Initial load
duke
parents:
diff changeset
3517
a61af66fc99e Initial load
duke
parents:
diff changeset
3518 if (_pre_header.count() > 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
3519 _pre_header.output(fp_hpp);
a61af66fc99e Initial load
duke
parents:
diff changeset
3520 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3521
a61af66fc99e Initial load
duke
parents:
diff changeset
3522 //---------------------------buildReduceMaps-----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3523 // Build mapping from enumeration for densely packed operands
a61af66fc99e Initial load
duke
parents:
diff changeset
3524 // TO result and child types.
a61af66fc99e Initial load
duke
parents:
diff changeset
3525 void ArchDesc::buildReduceMaps(FILE *fp_hpp, FILE *fp_cpp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3526 RegDef *rdef;
a61af66fc99e Initial load
duke
parents:
diff changeset
3527 RegDef *next;
a61af66fc99e Initial load
duke
parents:
diff changeset
3528
a61af66fc99e Initial load
duke
parents:
diff changeset
3529 // The emit bodies currently require functions defined in the source block.
a61af66fc99e Initial load
duke
parents:
diff changeset
3530
a61af66fc99e Initial load
duke
parents:
diff changeset
3531 // Build external declarations for mappings
a61af66fc99e Initial load
duke
parents:
diff changeset
3532 fprintf(fp_hpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3533 fprintf(fp_hpp, "extern const char register_save_policy[];\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3534 fprintf(fp_hpp, "extern const char c_reg_save_policy[];\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3535 fprintf(fp_hpp, "extern const int register_save_type[];\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3536 fprintf(fp_hpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3537
a61af66fc99e Initial load
duke
parents:
diff changeset
3538 // Construct Save-Policy array
a61af66fc99e Initial load
duke
parents:
diff changeset
3539 fprintf(fp_cpp, "// Map from machine-independent register number to register_save_policy\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3540 fprintf(fp_cpp, "const char register_save_policy[] = {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3541 _register->reset_RegDefs();
a61af66fc99e Initial load
duke
parents:
diff changeset
3542 for( rdef = _register->iter_RegDefs(); rdef != NULL; rdef = next ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3543 next = _register->iter_RegDefs();
a61af66fc99e Initial load
duke
parents:
diff changeset
3544 char policy = reg_save_policy(rdef->_callconv);
a61af66fc99e Initial load
duke
parents:
diff changeset
3545 const char *comma = (next != NULL) ? "," : " // no trailing comma";
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
3546 fprintf(fp_cpp, " '%c'%s // %s\n", policy, comma, rdef->_regname);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3547 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3548 fprintf(fp_cpp, "};\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3549
a61af66fc99e Initial load
duke
parents:
diff changeset
3550 // Construct Native Save-Policy array
a61af66fc99e Initial load
duke
parents:
diff changeset
3551 fprintf(fp_cpp, "// Map from machine-independent register number to c_reg_save_policy\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3552 fprintf(fp_cpp, "const char c_reg_save_policy[] = {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3553 _register->reset_RegDefs();
a61af66fc99e Initial load
duke
parents:
diff changeset
3554 for( rdef = _register->iter_RegDefs(); rdef != NULL; rdef = next ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3555 next = _register->iter_RegDefs();
a61af66fc99e Initial load
duke
parents:
diff changeset
3556 char policy = reg_save_policy(rdef->_c_conv);
a61af66fc99e Initial load
duke
parents:
diff changeset
3557 const char *comma = (next != NULL) ? "," : " // no trailing comma";
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
3558 fprintf(fp_cpp, " '%c'%s // %s\n", policy, comma, rdef->_regname);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3559 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3560 fprintf(fp_cpp, "};\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3561
a61af66fc99e Initial load
duke
parents:
diff changeset
3562 // Construct Register Save Type array
a61af66fc99e Initial load
duke
parents:
diff changeset
3563 fprintf(fp_cpp, "// Map from machine-independent register number to register_save_type\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3564 fprintf(fp_cpp, "const int register_save_type[] = {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3565 _register->reset_RegDefs();
a61af66fc99e Initial load
duke
parents:
diff changeset
3566 for( rdef = _register->iter_RegDefs(); rdef != NULL; rdef = next ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3567 next = _register->iter_RegDefs();
a61af66fc99e Initial load
duke
parents:
diff changeset
3568 const char *comma = (next != NULL) ? "," : " // no trailing comma";
a61af66fc99e Initial load
duke
parents:
diff changeset
3569 fprintf(fp_cpp, " %s%s\n", rdef->_idealtype, comma);
a61af66fc99e Initial load
duke
parents:
diff changeset
3570 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3571 fprintf(fp_cpp, "};\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3572
a61af66fc99e Initial load
duke
parents:
diff changeset
3573 // Construct the table for reduceOp
a61af66fc99e Initial load
duke
parents:
diff changeset
3574 OutputReduceOp output_reduce_op(fp_hpp, fp_cpp, _globalNames, *this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3575 build_map(output_reduce_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
3576 // Construct the table for leftOp
a61af66fc99e Initial load
duke
parents:
diff changeset
3577 OutputLeftOp output_left_op(fp_hpp, fp_cpp, _globalNames, *this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3578 build_map(output_left_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
3579 // Construct the table for rightOp
a61af66fc99e Initial load
duke
parents:
diff changeset
3580 OutputRightOp output_right_op(fp_hpp, fp_cpp, _globalNames, *this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3581 build_map(output_right_op);
a61af66fc99e Initial load
duke
parents:
diff changeset
3582 // Construct the table of rule names
a61af66fc99e Initial load
duke
parents:
diff changeset
3583 OutputRuleName output_rule_name(fp_hpp, fp_cpp, _globalNames, *this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3584 build_map(output_rule_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
3585 // Construct the boolean table for subsumed operands
a61af66fc99e Initial load
duke
parents:
diff changeset
3586 OutputSwallowed output_swallowed(fp_hpp, fp_cpp, _globalNames, *this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3587 build_map(output_swallowed);
a61af66fc99e Initial load
duke
parents:
diff changeset
3588 // // // Preserve in case we decide to use this table instead of another
a61af66fc99e Initial load
duke
parents:
diff changeset
3589 //// Construct the boolean table for instruction chain rules
a61af66fc99e Initial load
duke
parents:
diff changeset
3590 //OutputInstChainRule output_inst_chain(fp_hpp, fp_cpp, _globalNames, *this);
a61af66fc99e Initial load
duke
parents:
diff changeset
3591 //build_map(output_inst_chain);
a61af66fc99e Initial load
duke
parents:
diff changeset
3592
a61af66fc99e Initial load
duke
parents:
diff changeset
3593 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3594
a61af66fc99e Initial load
duke
parents:
diff changeset
3595
a61af66fc99e Initial load
duke
parents:
diff changeset
3596 //---------------------------buildMachOperGenerator---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3597
a61af66fc99e Initial load
duke
parents:
diff changeset
3598 // Recurse through match tree, building path through corresponding state tree,
a61af66fc99e Initial load
duke
parents:
diff changeset
3599 // Until we reach the constant we are looking for.
a61af66fc99e Initial load
duke
parents:
diff changeset
3600 static void path_to_constant(FILE *fp, FormDict &globals,
a61af66fc99e Initial load
duke
parents:
diff changeset
3601 MatchNode *mnode, uint idx) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3602 if ( ! mnode) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
3603
a61af66fc99e Initial load
duke
parents:
diff changeset
3604 unsigned position = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3605 const char *result = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3606 const char *name = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3607 const char *optype = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3608
a61af66fc99e Initial load
duke
parents:
diff changeset
3609 // Base Case: access constant in ideal node linked to current state node
a61af66fc99e Initial load
duke
parents:
diff changeset
3610 // Each type of constant has its own access function
a61af66fc99e Initial load
duke
parents:
diff changeset
3611 if ( (mnode->_lChild == NULL) && (mnode->_rChild == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
3612 && mnode->base_operand(position, globals, result, name, optype) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3613 if ( strcmp(optype,"ConI") == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3614 fprintf(fp, "_leaf->get_int()");
a61af66fc99e Initial load
duke
parents:
diff changeset
3615 } else if ( (strcmp(optype,"ConP") == 0) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3616 fprintf(fp, "_leaf->bottom_type()->is_ptr()");
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
3617 } else if ( (strcmp(optype,"ConN") == 0) ) {
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 0
diff changeset
3618 fprintf(fp, "_leaf->bottom_type()->is_narrowoop()");
6848
8e47bac5643a 7054512: Compress class pointers after perm gen removal
roland
parents: 6804
diff changeset
3619 } else if ( (strcmp(optype,"ConNKlass") == 0) ) {
8e47bac5643a 7054512: Compress class pointers after perm gen removal
roland
parents: 6804
diff changeset
3620 fprintf(fp, "_leaf->bottom_type()->is_narrowklass()");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3621 } else if ( (strcmp(optype,"ConF") == 0) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3622 fprintf(fp, "_leaf->getf()");
a61af66fc99e Initial load
duke
parents:
diff changeset
3623 } else if ( (strcmp(optype,"ConD") == 0) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3624 fprintf(fp, "_leaf->getd()");
a61af66fc99e Initial load
duke
parents:
diff changeset
3625 } else if ( (strcmp(optype,"ConL") == 0) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3626 fprintf(fp, "_leaf->get_long()");
a61af66fc99e Initial load
duke
parents:
diff changeset
3627 } else if ( (strcmp(optype,"Con")==0) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3628 // !!!!! - Update if adding a machine-independent constant type
a61af66fc99e Initial load
duke
parents:
diff changeset
3629 fprintf(fp, "_leaf->get_int()");
a61af66fc99e Initial load
duke
parents:
diff changeset
3630 assert( false, "Unsupported constant type, pointer or indefinite");
a61af66fc99e Initial load
duke
parents:
diff changeset
3631 } else if ( (strcmp(optype,"Bool") == 0) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3632 fprintf(fp, "_leaf->as_Bool()->_test._test");
a61af66fc99e Initial load
duke
parents:
diff changeset
3633 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3634 assert( false, "Unsupported constant type");
a61af66fc99e Initial load
duke
parents:
diff changeset
3635 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3636 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
3637 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3638
a61af66fc99e Initial load
duke
parents:
diff changeset
3639 // If constant is in left child, build path and recurse
a61af66fc99e Initial load
duke
parents:
diff changeset
3640 uint lConsts = (mnode->_lChild) ? (mnode->_lChild->num_consts(globals) ) : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3641 uint rConsts = (mnode->_rChild) ? (mnode->_rChild->num_consts(globals) ) : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3642 if ( (mnode->_lChild) && (lConsts > idx) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3643 fprintf(fp, "_kids[0]->");
a61af66fc99e Initial load
duke
parents:
diff changeset
3644 path_to_constant(fp, globals, mnode->_lChild, idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
3645 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
3646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3647 // If constant is in right child, build path and recurse
a61af66fc99e Initial load
duke
parents:
diff changeset
3648 if ( (mnode->_rChild) && (rConsts > (idx - lConsts) ) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3649 idx = idx - lConsts;
a61af66fc99e Initial load
duke
parents:
diff changeset
3650 fprintf(fp, "_kids[1]->");
a61af66fc99e Initial load
duke
parents:
diff changeset
3651 path_to_constant(fp, globals, mnode->_rChild, idx);
a61af66fc99e Initial load
duke
parents:
diff changeset
3652 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
3653 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3654 assert( false, "ShouldNotReachHere()");
a61af66fc99e Initial load
duke
parents:
diff changeset
3655 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3656
a61af66fc99e Initial load
duke
parents:
diff changeset
3657 // Generate code that is executed when generating a specific Machine Operand
a61af66fc99e Initial load
duke
parents:
diff changeset
3658 static void genMachOperCase(FILE *fp, FormDict &globalNames, ArchDesc &AD,
a61af66fc99e Initial load
duke
parents:
diff changeset
3659 OperandForm &op) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3660 const char *opName = op._ident;
a61af66fc99e Initial load
duke
parents:
diff changeset
3661 const char *opEnumName = AD.machOperEnum(opName);
a61af66fc99e Initial load
duke
parents:
diff changeset
3662 uint num_consts = op.num_consts(globalNames);
a61af66fc99e Initial load
duke
parents:
diff changeset
3663
a61af66fc99e Initial load
duke
parents:
diff changeset
3664 // Generate the case statement for this opcode
a61af66fc99e Initial load
duke
parents:
diff changeset
3665 fprintf(fp, " case %s:", opEnumName);
a61af66fc99e Initial load
duke
parents:
diff changeset
3666 fprintf(fp, "\n return new (C) %sOper(", opName);
a61af66fc99e Initial load
duke
parents:
diff changeset
3667 // Access parameters for constructor from the stat object
a61af66fc99e Initial load
duke
parents:
diff changeset
3668 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3669 // Build access to condition code value
a61af66fc99e Initial load
duke
parents:
diff changeset
3670 if ( (num_consts > 0) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3671 uint i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3672 path_to_constant(fp, globalNames, op._matrule, i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3673 for ( i = 1; i < num_consts; ++i ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3674 fprintf(fp, ", ");
a61af66fc99e Initial load
duke
parents:
diff changeset
3675 path_to_constant(fp, globalNames, op._matrule, i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3676 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3677 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3678 fprintf(fp, " );\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3679 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3680
a61af66fc99e Initial load
duke
parents:
diff changeset
3681
a61af66fc99e Initial load
duke
parents:
diff changeset
3682 // Build switch to invoke "new" MachNode or MachOper
a61af66fc99e Initial load
duke
parents:
diff changeset
3683 void ArchDesc::buildMachOperGenerator(FILE *fp_cpp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3684 int idx = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3685
a61af66fc99e Initial load
duke
parents:
diff changeset
3686 // Build switch to invoke 'new' for a specific MachOper
a61af66fc99e Initial load
duke
parents:
diff changeset
3687 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3688 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3689 fprintf(fp_cpp,
a61af66fc99e Initial load
duke
parents:
diff changeset
3690 "//------------------------- MachOper Generator ---------------\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3691 fprintf(fp_cpp,
a61af66fc99e Initial load
duke
parents:
diff changeset
3692 "// A switch statement on the dense-packed user-defined type system\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
3693 "// that invokes 'new' on the corresponding class constructor.\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3694 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3695 fprintf(fp_cpp, "MachOper *State::MachOperGenerator");
a61af66fc99e Initial load
duke
parents:
diff changeset
3696 fprintf(fp_cpp, "(int opcode, Compile* C)");
a61af66fc99e Initial load
duke
parents:
diff changeset
3697 fprintf(fp_cpp, "{\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3698 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3699 fprintf(fp_cpp, " switch(opcode) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3700
a61af66fc99e Initial load
duke
parents:
diff changeset
3701 // Place all user-defined operands into the mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
3702 _operands.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3703 int opIndex = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3704 OperandForm *op;
a61af66fc99e Initial load
duke
parents:
diff changeset
3705 for( ; (op = (OperandForm*)_operands.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3706 // Ensure this is a machine-world instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
3707 if ( op->ideal_only() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3708
a61af66fc99e Initial load
duke
parents:
diff changeset
3709 genMachOperCase(fp_cpp, _globalNames, *this, *op);
a61af66fc99e Initial load
duke
parents:
diff changeset
3710 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3711
a61af66fc99e Initial load
duke
parents:
diff changeset
3712 // Do not iterate over operand classes for the operand generator!!!
a61af66fc99e Initial load
duke
parents:
diff changeset
3713
a61af66fc99e Initial load
duke
parents:
diff changeset
3714 // Place all internal operands into the mapping
a61af66fc99e Initial load
duke
parents:
diff changeset
3715 _internalOpNames.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3716 const char *iopn;
a61af66fc99e Initial load
duke
parents:
diff changeset
3717 for( ; (iopn = _internalOpNames.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3718 const char *opEnumName = machOperEnum(iopn);
a61af66fc99e Initial load
duke
parents:
diff changeset
3719 // Generate the case statement for this opcode
a61af66fc99e Initial load
duke
parents:
diff changeset
3720 fprintf(fp_cpp, " case %s:", opEnumName);
a61af66fc99e Initial load
duke
parents:
diff changeset
3721 fprintf(fp_cpp, " return NULL;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3722 };
a61af66fc99e Initial load
duke
parents:
diff changeset
3723
a61af66fc99e Initial load
duke
parents:
diff changeset
3724 // Generate the default case for switch(opcode)
a61af66fc99e Initial load
duke
parents:
diff changeset
3725 fprintf(fp_cpp, " \n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3726 fprintf(fp_cpp, " default:\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3727 fprintf(fp_cpp, " fprintf(stderr, \"Default MachOper Generator invoked for: \\n\");\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3728 fprintf(fp_cpp, " fprintf(stderr, \" opcode = %cd\\n\", opcode);\n", '%');
a61af66fc99e Initial load
duke
parents:
diff changeset
3729 fprintf(fp_cpp, " break;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3730 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3731
a61af66fc99e Initial load
duke
parents:
diff changeset
3732 // Generate the closing for method Matcher::MachOperGenerator
a61af66fc99e Initial load
duke
parents:
diff changeset
3733 fprintf(fp_cpp, " return NULL;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3734 fprintf(fp_cpp, "};\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3735 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3736
a61af66fc99e Initial load
duke
parents:
diff changeset
3737
a61af66fc99e Initial load
duke
parents:
diff changeset
3738 //---------------------------buildMachNode-------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3739 // Build a new MachNode, for MachNodeGenerator or cisc-spilling
a61af66fc99e Initial load
duke
parents:
diff changeset
3740 void ArchDesc::buildMachNode(FILE *fp_cpp, InstructForm *inst, const char *indent) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3741 const char *opType = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3742 const char *opClass = inst->_ident;
a61af66fc99e Initial load
duke
parents:
diff changeset
3743
a61af66fc99e Initial load
duke
parents:
diff changeset
3744 // Create the MachNode object
a61af66fc99e Initial load
duke
parents:
diff changeset
3745 fprintf(fp_cpp, "%s %sNode *node = new (C) %sNode();\n",indent, opClass,opClass);
a61af66fc99e Initial load
duke
parents:
diff changeset
3746
a61af66fc99e Initial load
duke
parents:
diff changeset
3747 if ( (inst->num_post_match_opnds() != 0) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3748 // Instruction that contains operands which are not in match rule.
a61af66fc99e Initial load
duke
parents:
diff changeset
3749 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3750 // Check if the first post-match component may be an interesting def
a61af66fc99e Initial load
duke
parents:
diff changeset
3751 bool dont_care = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3752 ComponentList &comp_list = inst->_components;
a61af66fc99e Initial load
duke
parents:
diff changeset
3753 Component *comp = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3754 comp_list.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3755 if ( comp_list.match_iter() != NULL ) dont_care = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3756
a61af66fc99e Initial load
duke
parents:
diff changeset
3757 // Insert operands that are not in match-rule.
a61af66fc99e Initial load
duke
parents:
diff changeset
3758 // Only insert a DEF if the do_care flag is set
a61af66fc99e Initial load
duke
parents:
diff changeset
3759 comp_list.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3760 while ( comp = comp_list.post_match_iter() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3761 // Check if we don't care about DEFs or KILLs that are not USEs
a61af66fc99e Initial load
duke
parents:
diff changeset
3762 if ( dont_care && (! comp->isa(Component::USE)) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3763 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3764 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3765 dont_care = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3766 // For each operand not in the match rule, call MachOperGenerator
2254
ab42c7e1cf83 7017746: Regression : C2 compiler crash due to SIGSEGV in PhaseCFG::schedule_early()
kvn
parents: 2008
diff changeset
3767 // with the enum for the opcode that needs to be built.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3768 ComponentList clist = inst->_components;
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
3769 int index = clist.operand_position(comp->_name, comp->_usedef, inst);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3770 const char *opcode = machOperEnum(comp->_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
3771 fprintf(fp_cpp, "%s node->set_opnd_array(%d, ", indent, index);
a61af66fc99e Initial load
duke
parents:
diff changeset
3772 fprintf(fp_cpp, "MachOperGenerator(%s, C));\n", opcode);
a61af66fc99e Initial load
duke
parents:
diff changeset
3773 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3774 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3775 else if ( inst->is_chain_of_constant(_globalNames, opType) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3776 // An instruction that chains from a constant!
a61af66fc99e Initial load
duke
parents:
diff changeset
3777 // In this case, we need to subsume the constant into the node
a61af66fc99e Initial load
duke
parents:
diff changeset
3778 // at operand position, oper_input_base().
a61af66fc99e Initial load
duke
parents:
diff changeset
3779 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3780 // Fill in the constant
a61af66fc99e Initial load
duke
parents:
diff changeset
3781 fprintf(fp_cpp, "%s node->_opnd_array[%d] = ", indent,
a61af66fc99e Initial load
duke
parents:
diff changeset
3782 inst->oper_input_base(_globalNames));
a61af66fc99e Initial load
duke
parents:
diff changeset
3783 // #####
a61af66fc99e Initial load
duke
parents:
diff changeset
3784 // Check for multiple constants and then fill them in.
a61af66fc99e Initial load
duke
parents:
diff changeset
3785 // Just like MachOperGenerator
a61af66fc99e Initial load
duke
parents:
diff changeset
3786 const char *opName = inst->_matrule->_rChild->_opType;
a61af66fc99e Initial load
duke
parents:
diff changeset
3787 fprintf(fp_cpp, "new (C) %sOper(", opName);
a61af66fc99e Initial load
duke
parents:
diff changeset
3788 // Grab operand form
a61af66fc99e Initial load
duke
parents:
diff changeset
3789 OperandForm *op = (_globalNames[opName])->is_operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
3790 // Look up the number of constants
a61af66fc99e Initial load
duke
parents:
diff changeset
3791 uint num_consts = op->num_consts(_globalNames);
a61af66fc99e Initial load
duke
parents:
diff changeset
3792 if ( (num_consts > 0) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3793 uint i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3794 path_to_constant(fp_cpp, _globalNames, op->_matrule, i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3795 for ( i = 1; i < num_consts; ++i ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3796 fprintf(fp_cpp, ", ");
a61af66fc99e Initial load
duke
parents:
diff changeset
3797 path_to_constant(fp_cpp, _globalNames, op->_matrule, i);
a61af66fc99e Initial load
duke
parents:
diff changeset
3798 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3799 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3800 fprintf(fp_cpp, " );\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3801 // #####
a61af66fc99e Initial load
duke
parents:
diff changeset
3802 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3803
a61af66fc99e Initial load
duke
parents:
diff changeset
3804 // Fill in the bottom_type where requested
1541
b5fdf39b9749 6953576: bottom_type for matched AddPNodes doesn't always agree with ideal
never
parents: 1489
diff changeset
3805 if ( inst->captures_bottom_type(_globalNames) ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3806 fprintf(fp_cpp, "%s node->_bottom_type = _leaf->bottom_type();\n", indent);
a61af66fc99e Initial load
duke
parents:
diff changeset
3807 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3808 if( inst->is_ideal_if() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3809 fprintf(fp_cpp, "%s node->_prob = _leaf->as_If()->_prob;\n", indent);
a61af66fc99e Initial load
duke
parents:
diff changeset
3810 fprintf(fp_cpp, "%s node->_fcnt = _leaf->as_If()->_fcnt;\n", indent);
a61af66fc99e Initial load
duke
parents:
diff changeset
3811 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3812 if( inst->is_ideal_fastlock() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3813 fprintf(fp_cpp, "%s node->_counters = _leaf->as_FastLock()->counters();\n", indent);
a61af66fc99e Initial load
duke
parents:
diff changeset
3814 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3815
a61af66fc99e Initial load
duke
parents:
diff changeset
3816 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3817
a61af66fc99e Initial load
duke
parents:
diff changeset
3818 //---------------------------declare_cisc_version------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3819 // Build CISC version of this instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
3820 void InstructForm::declare_cisc_version(ArchDesc &AD, FILE *fp_hpp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3821 if( AD.can_cisc_spill() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3822 InstructForm *inst_cisc = cisc_spill_alternate();
a61af66fc99e Initial load
duke
parents:
diff changeset
3823 if (inst_cisc != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3824 fprintf(fp_hpp, " virtual int cisc_operand() const { return %d; }\n", cisc_spill_operand());
a61af66fc99e Initial load
duke
parents:
diff changeset
3825 fprintf(fp_hpp, " virtual MachNode *cisc_version(int offset, Compile* C);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3826 fprintf(fp_hpp, " virtual void use_cisc_RegMask();\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3827 fprintf(fp_hpp, " virtual const RegMask *cisc_RegMask() const { return _cisc_RegMask; }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3828 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3829 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3830 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3831
a61af66fc99e Initial load
duke
parents:
diff changeset
3832 //---------------------------define_cisc_version-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3833 // Build CISC version of this instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
3834 bool InstructForm::define_cisc_version(ArchDesc &AD, FILE *fp_cpp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3835 InstructForm *inst_cisc = this->cisc_spill_alternate();
a61af66fc99e Initial load
duke
parents:
diff changeset
3836 if( AD.can_cisc_spill() && (inst_cisc != NULL) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3837 const char *name = inst_cisc->_ident;
a61af66fc99e Initial load
duke
parents:
diff changeset
3838 assert( inst_cisc->num_opnds() == this->num_opnds(), "Must have same number of operands");
a61af66fc99e Initial load
duke
parents:
diff changeset
3839 OperandForm *cisc_oper = AD.cisc_spill_operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
3840 assert( cisc_oper != NULL, "insanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
3841 const char *cisc_oper_name = cisc_oper->_ident;
a61af66fc99e Initial load
duke
parents:
diff changeset
3842 assert( cisc_oper_name != NULL, "insanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
3843 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3844 // Set the correct reg_mask_or_stack for the cisc operand
a61af66fc99e Initial load
duke
parents:
diff changeset
3845 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3846 fprintf(fp_cpp, "void %sNode::use_cisc_RegMask() {\n", this->_ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
3847 // Lookup the correct reg_mask_or_stack
a61af66fc99e Initial load
duke
parents:
diff changeset
3848 const char *reg_mask_name = cisc_reg_mask_name();
a61af66fc99e Initial load
duke
parents:
diff changeset
3849 fprintf(fp_cpp, " _cisc_RegMask = &STACK_OR_%s;\n", reg_mask_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
3850 fprintf(fp_cpp, "}\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3851 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3852 // Construct CISC version of this instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
3853 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3854 fprintf(fp_cpp, "// Build CISC version of this instruction\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3855 fprintf(fp_cpp, "MachNode *%sNode::cisc_version( int offset, Compile* C ) {\n", this->_ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
3856 // Create the MachNode object
a61af66fc99e Initial load
duke
parents:
diff changeset
3857 fprintf(fp_cpp, " %sNode *node = new (C) %sNode();\n", name, name);
a61af66fc99e Initial load
duke
parents:
diff changeset
3858 // Fill in the bottom_type where requested
1541
b5fdf39b9749 6953576: bottom_type for matched AddPNodes doesn't always agree with ideal
never
parents: 1489
diff changeset
3859 if ( this->captures_bottom_type(AD.globalNames()) ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3860 fprintf(fp_cpp, " node->_bottom_type = bottom_type();\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3861 }
785
2056494941db 6814842: Load shortening optimizations
twisti
parents: 624
diff changeset
3862
2056494941db 6814842: Load shortening optimizations
twisti
parents: 624
diff changeset
3863 uint cur_num_opnds = num_opnds();
2056494941db 6814842: Load shortening optimizations
twisti
parents: 624
diff changeset
3864 if (cur_num_opnds > 1 && cur_num_opnds != num_unique_opnds()) {
2056494941db 6814842: Load shortening optimizations
twisti
parents: 624
diff changeset
3865 fprintf(fp_cpp," node->_num_opnds = %d;\n", num_unique_opnds());
2056494941db 6814842: Load shortening optimizations
twisti
parents: 624
diff changeset
3866 }
2056494941db 6814842: Load shortening optimizations
twisti
parents: 624
diff changeset
3867
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3868 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3869 fprintf(fp_cpp, " // Copy _idx, inputs and operands to new node\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3870 fprintf(fp_cpp, " fill_new_machnode(node, C);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3871 // Construct operand to access [stack_pointer + offset]
a61af66fc99e Initial load
duke
parents:
diff changeset
3872 fprintf(fp_cpp, " // Construct operand to access [stack_pointer + offset]\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3873 fprintf(fp_cpp, " node->set_opnd_array(cisc_operand(), new (C) %sOper(offset));\n", cisc_oper_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
3874 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3875
a61af66fc99e Initial load
duke
parents:
diff changeset
3876 // Return result and exit scope
a61af66fc99e Initial load
duke
parents:
diff changeset
3877 fprintf(fp_cpp, " return node;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3878 fprintf(fp_cpp, "}\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3879 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3880 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3881 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3882 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3883 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3884
a61af66fc99e Initial load
duke
parents:
diff changeset
3885 //---------------------------declare_short_branch_methods----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3886 // Build prototypes for short branch methods
a61af66fc99e Initial load
duke
parents:
diff changeset
3887 void InstructForm::declare_short_branch_methods(FILE *fp_hpp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3888 if (has_short_branch_form()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3889 fprintf(fp_hpp, " virtual MachNode *short_branch_version(Compile* C);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3890 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3891 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3892
a61af66fc99e Initial load
duke
parents:
diff changeset
3893 //---------------------------define_short_branch_methods-----------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3894 // Build definitions for short branch methods
1541
b5fdf39b9749 6953576: bottom_type for matched AddPNodes doesn't always agree with ideal
never
parents: 1489
diff changeset
3895 bool InstructForm::define_short_branch_methods(ArchDesc &AD, FILE *fp_cpp) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3896 if (has_short_branch_form()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3897 InstructForm *short_branch = short_branch_form();
a61af66fc99e Initial load
duke
parents:
diff changeset
3898 const char *name = short_branch->_ident;
a61af66fc99e Initial load
duke
parents:
diff changeset
3899
a61af66fc99e Initial load
duke
parents:
diff changeset
3900 // Construct short_branch_version() method.
a61af66fc99e Initial load
duke
parents:
diff changeset
3901 fprintf(fp_cpp, "// Build short branch version of this instruction\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3902 fprintf(fp_cpp, "MachNode *%sNode::short_branch_version(Compile* C) {\n", this->_ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
3903 // Create the MachNode object
a61af66fc99e Initial load
duke
parents:
diff changeset
3904 fprintf(fp_cpp, " %sNode *node = new (C) %sNode();\n", name, name);
a61af66fc99e Initial load
duke
parents:
diff changeset
3905 if( is_ideal_if() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3906 fprintf(fp_cpp, " node->_prob = _prob;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3907 fprintf(fp_cpp, " node->_fcnt = _fcnt;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3908 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3909 // Fill in the bottom_type where requested
1541
b5fdf39b9749 6953576: bottom_type for matched AddPNodes doesn't always agree with ideal
never
parents: 1489
diff changeset
3910 if ( this->captures_bottom_type(AD.globalNames()) ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3911 fprintf(fp_cpp, " node->_bottom_type = bottom_type();\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3912 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3913
a61af66fc99e Initial load
duke
parents:
diff changeset
3914 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3915 // Short branch version must use same node index for access
a61af66fc99e Initial load
duke
parents:
diff changeset
3916 // through allocator's tables
a61af66fc99e Initial load
duke
parents:
diff changeset
3917 fprintf(fp_cpp, " // Copy _idx, inputs and operands to new node\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3918 fprintf(fp_cpp, " fill_new_machnode(node, C);\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3919
a61af66fc99e Initial load
duke
parents:
diff changeset
3920 // Return result and exit scope
a61af66fc99e Initial load
duke
parents:
diff changeset
3921 fprintf(fp_cpp, " return node;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3922 fprintf(fp_cpp, "}\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3923 fprintf(fp_cpp,"\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3924 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3925 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3926 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3927 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3928
a61af66fc99e Initial load
duke
parents:
diff changeset
3929
a61af66fc99e Initial load
duke
parents:
diff changeset
3930 //---------------------------buildMachNodeGenerator----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3931 // Build switch to invoke appropriate "new" MachNode for an opcode
a61af66fc99e Initial load
duke
parents:
diff changeset
3932 void ArchDesc::buildMachNodeGenerator(FILE *fp_cpp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3933
a61af66fc99e Initial load
duke
parents:
diff changeset
3934 // Build switch to invoke 'new' for a specific MachNode
a61af66fc99e Initial load
duke
parents:
diff changeset
3935 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3936 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3937 fprintf(fp_cpp,
a61af66fc99e Initial load
duke
parents:
diff changeset
3938 "//------------------------- MachNode Generator ---------------\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3939 fprintf(fp_cpp,
a61af66fc99e Initial load
duke
parents:
diff changeset
3940 "// A switch statement on the dense-packed user-defined type system\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
3941 "// that invokes 'new' on the corresponding class constructor.\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3942 fprintf(fp_cpp, "\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3943 fprintf(fp_cpp, "MachNode *State::MachNodeGenerator");
a61af66fc99e Initial load
duke
parents:
diff changeset
3944 fprintf(fp_cpp, "(int opcode, Compile* C)");
a61af66fc99e Initial load
duke
parents:
diff changeset
3945 fprintf(fp_cpp, "{\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3946 fprintf(fp_cpp, " switch(opcode) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3947
a61af66fc99e Initial load
duke
parents:
diff changeset
3948 // Provide constructor for all user-defined instructions
a61af66fc99e Initial load
duke
parents:
diff changeset
3949 _instructions.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
3950 int opIndex = operandFormCount();
a61af66fc99e Initial load
duke
parents:
diff changeset
3951 InstructForm *inst;
a61af66fc99e Initial load
duke
parents:
diff changeset
3952 for( ; (inst = (InstructForm*)_instructions.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3953 // Ensure that matrule is defined.
a61af66fc99e Initial load
duke
parents:
diff changeset
3954 if ( inst->_matrule == NULL ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3955
a61af66fc99e Initial load
duke
parents:
diff changeset
3956 int opcode = opIndex++;
a61af66fc99e Initial load
duke
parents:
diff changeset
3957 const char *opClass = inst->_ident;
a61af66fc99e Initial load
duke
parents:
diff changeset
3958 char *opType = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3959
a61af66fc99e Initial load
duke
parents:
diff changeset
3960 // Generate the case statement for this instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
3961 fprintf(fp_cpp, " case %s_rule:", opClass);
a61af66fc99e Initial load
duke
parents:
diff changeset
3962
a61af66fc99e Initial load
duke
parents:
diff changeset
3963 // Start local scope
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
3964 fprintf(fp_cpp, " {\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3965 // Generate code to construct the new MachNode
a61af66fc99e Initial load
duke
parents:
diff changeset
3966 buildMachNode(fp_cpp, inst, " ");
a61af66fc99e Initial load
duke
parents:
diff changeset
3967 // Return result and exit scope
a61af66fc99e Initial load
duke
parents:
diff changeset
3968 fprintf(fp_cpp, " return node;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3969 fprintf(fp_cpp, " }\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3970 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3971
a61af66fc99e Initial load
duke
parents:
diff changeset
3972 // Generate the default case for switch(opcode)
a61af66fc99e Initial load
duke
parents:
diff changeset
3973 fprintf(fp_cpp, " \n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3974 fprintf(fp_cpp, " default:\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3975 fprintf(fp_cpp, " fprintf(stderr, \"Default MachNode Generator invoked for: \\n\");\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3976 fprintf(fp_cpp, " fprintf(stderr, \" opcode = %cd\\n\", opcode);\n", '%');
a61af66fc99e Initial load
duke
parents:
diff changeset
3977 fprintf(fp_cpp, " break;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3978 fprintf(fp_cpp, " };\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3979
a61af66fc99e Initial load
duke
parents:
diff changeset
3980 // Generate the closing for method Matcher::MachNodeGenerator
a61af66fc99e Initial load
duke
parents:
diff changeset
3981 fprintf(fp_cpp, " return NULL;\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3982 fprintf(fp_cpp, "}\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3983 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3984
a61af66fc99e Initial load
duke
parents:
diff changeset
3985
a61af66fc99e Initial load
duke
parents:
diff changeset
3986 //---------------------------buildInstructMatchCheck--------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
3987 // Output the method to Matcher which checks whether or not a specific
a61af66fc99e Initial load
duke
parents:
diff changeset
3988 // instruction has a matching rule for the host architecture.
a61af66fc99e Initial load
duke
parents:
diff changeset
3989 void ArchDesc::buildInstructMatchCheck(FILE *fp_cpp) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
3990 fprintf(fp_cpp, "\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3991 fprintf(fp_cpp, "const bool Matcher::has_match_rule(int opcode) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3992 fprintf(fp_cpp, " assert(_last_machine_leaf < opcode && opcode < _last_opcode, \"opcode in range\");\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3993 fprintf(fp_cpp, " return _hasMatchRule[opcode];\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3994 fprintf(fp_cpp, "}\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3995
a61af66fc99e Initial load
duke
parents:
diff changeset
3996 fprintf(fp_cpp, "const bool Matcher::_hasMatchRule[_last_opcode] = {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
3997 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
3998 for (i = 0; i < _last_opcode - 1; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3999 fprintf(fp_cpp, " %-5s, // %s\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
4000 _has_match_rule[i] ? "true" : "false",
a61af66fc99e Initial load
duke
parents:
diff changeset
4001 NodeClassNames[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
4002 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4003 fprintf(fp_cpp, " %-5s // %s\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
4004 _has_match_rule[i] ? "true" : "false",
a61af66fc99e Initial load
duke
parents:
diff changeset
4005 NodeClassNames[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
4006 fprintf(fp_cpp, "};\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
4007 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4008
a61af66fc99e Initial load
duke
parents:
diff changeset
4009 //---------------------------buildFrameMethods---------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4010 // Output the methods to Matcher which specify frame behavior
a61af66fc99e Initial load
duke
parents:
diff changeset
4011 void ArchDesc::buildFrameMethods(FILE *fp_cpp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4012 fprintf(fp_cpp,"\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
4013 // Stack Direction
a61af66fc99e Initial load
duke
parents:
diff changeset
4014 fprintf(fp_cpp,"bool Matcher::stack_direction() const { return %s; }\n\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
4015 _frame->_direction ? "true" : "false");
a61af66fc99e Initial load
duke
parents:
diff changeset
4016 // Sync Stack Slots
a61af66fc99e Initial load
duke
parents:
diff changeset
4017 fprintf(fp_cpp,"int Compile::sync_stack_slots() const { return %s; }\n\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
4018 _frame->_sync_stack_slots);
a61af66fc99e Initial load
duke
parents:
diff changeset
4019 // Java Stack Alignment
a61af66fc99e Initial load
duke
parents:
diff changeset
4020 fprintf(fp_cpp,"uint Matcher::stack_alignment_in_bytes() { return %s; }\n\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
4021 _frame->_alignment);
a61af66fc99e Initial load
duke
parents:
diff changeset
4022 // Java Return Address Location
a61af66fc99e Initial load
duke
parents:
diff changeset
4023 fprintf(fp_cpp,"OptoReg::Name Matcher::return_addr() const {");
a61af66fc99e Initial load
duke
parents:
diff changeset
4024 if (_frame->_return_addr_loc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4025 fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
4026 _frame->_return_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
4027 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4028 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4029 fprintf(fp_cpp," return OptoReg::stack2reg(%s); }\n\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
4030 _frame->_return_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
4031 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4032 // Java Stack Slot Preservation
a61af66fc99e Initial load
duke
parents:
diff changeset
4033 fprintf(fp_cpp,"uint Compile::in_preserve_stack_slots() ");
a61af66fc99e Initial load
duke
parents:
diff changeset
4034 fprintf(fp_cpp,"{ return %s; }\n\n", _frame->_in_preserve_slots);
a61af66fc99e Initial load
duke
parents:
diff changeset
4035 // Top Of Stack Slot Preservation, for both Java and C
a61af66fc99e Initial load
duke
parents:
diff changeset
4036 fprintf(fp_cpp,"uint Compile::out_preserve_stack_slots() ");
a61af66fc99e Initial load
duke
parents:
diff changeset
4037 fprintf(fp_cpp,"{ return SharedRuntime::out_preserve_stack_slots(); }\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
4038 // varargs C out slots killed
a61af66fc99e Initial load
duke
parents:
diff changeset
4039 fprintf(fp_cpp,"uint Compile::varargs_C_out_slots_killed() const ");
a61af66fc99e Initial load
duke
parents:
diff changeset
4040 fprintf(fp_cpp,"{ return %s; }\n\n", _frame->_varargs_C_out_slots_killed);
a61af66fc99e Initial load
duke
parents:
diff changeset
4041 // Java Argument Position
a61af66fc99e Initial load
duke
parents:
diff changeset
4042 fprintf(fp_cpp,"void Matcher::calling_convention(BasicType *sig_bt, VMRegPair *regs, uint length, bool is_outgoing) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
4043 fprintf(fp_cpp,"%s\n", _frame->_calling_convention);
a61af66fc99e Initial load
duke
parents:
diff changeset
4044 fprintf(fp_cpp,"}\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
4045 // Native Argument Position
a61af66fc99e Initial load
duke
parents:
diff changeset
4046 fprintf(fp_cpp,"void Matcher::c_calling_convention(BasicType *sig_bt, VMRegPair *regs, uint length) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
4047 fprintf(fp_cpp,"%s\n", _frame->_c_calling_convention);
a61af66fc99e Initial load
duke
parents:
diff changeset
4048 fprintf(fp_cpp,"}\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
4049 // Java Return Value Location
a61af66fc99e Initial load
duke
parents:
diff changeset
4050 fprintf(fp_cpp,"OptoRegPair Matcher::return_value(int ideal_reg, bool is_outgoing) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
4051 fprintf(fp_cpp,"%s\n", _frame->_return_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
4052 fprintf(fp_cpp,"}\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
4053 // Native Return Value Location
a61af66fc99e Initial load
duke
parents:
diff changeset
4054 fprintf(fp_cpp,"OptoRegPair Matcher::c_return_value(int ideal_reg, bool is_outgoing) {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
4055 fprintf(fp_cpp,"%s\n", _frame->_c_return_value);
a61af66fc99e Initial load
duke
parents:
diff changeset
4056 fprintf(fp_cpp,"}\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
4057
a61af66fc99e Initial load
duke
parents:
diff changeset
4058 // Inline Cache Register, mask definition, and encoding
a61af66fc99e Initial load
duke
parents:
diff changeset
4059 fprintf(fp_cpp,"OptoReg::Name Matcher::inline_cache_reg() {");
a61af66fc99e Initial load
duke
parents:
diff changeset
4060 fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
4061 _frame->_inline_cache_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4062 fprintf(fp_cpp,"int Matcher::inline_cache_reg_encode() {");
a61af66fc99e Initial load
duke
parents:
diff changeset
4063 fprintf(fp_cpp," return _regEncode[inline_cache_reg()]; }\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
4064
a61af66fc99e Initial load
duke
parents:
diff changeset
4065 // Interpreter's Method Oop Register, mask definition, and encoding
a61af66fc99e Initial load
duke
parents:
diff changeset
4066 fprintf(fp_cpp,"OptoReg::Name Matcher::interpreter_method_oop_reg() {");
a61af66fc99e Initial load
duke
parents:
diff changeset
4067 fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
4068 _frame->_interpreter_method_oop_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4069 fprintf(fp_cpp,"int Matcher::interpreter_method_oop_reg_encode() {");
a61af66fc99e Initial load
duke
parents:
diff changeset
4070 fprintf(fp_cpp," return _regEncode[interpreter_method_oop_reg()]; }\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
4071
a61af66fc99e Initial load
duke
parents:
diff changeset
4072 // Interpreter's Frame Pointer Register, mask definition, and encoding
a61af66fc99e Initial load
duke
parents:
diff changeset
4073 fprintf(fp_cpp,"OptoReg::Name Matcher::interpreter_frame_pointer_reg() {");
a61af66fc99e Initial load
duke
parents:
diff changeset
4074 if (_frame->_interpreter_frame_pointer_reg == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
4075 fprintf(fp_cpp," return OptoReg::Bad; }\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
4076 else
a61af66fc99e Initial load
duke
parents:
diff changeset
4077 fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
4078 _frame->_interpreter_frame_pointer_reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
4079
a61af66fc99e Initial load
duke
parents:
diff changeset
4080 // Frame Pointer definition
a61af66fc99e Initial load
duke
parents:
diff changeset
4081 /* CNC - I can not contemplate having a different frame pointer between
a61af66fc99e Initial load
duke
parents:
diff changeset
4082 Java and native code; makes my head hurt to think about it.
a61af66fc99e Initial load
duke
parents:
diff changeset
4083 fprintf(fp_cpp,"OptoReg::Name Matcher::frame_pointer() const {");
a61af66fc99e Initial load
duke
parents:
diff changeset
4084 fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
4085 _frame->_frame_pointer);
a61af66fc99e Initial load
duke
parents:
diff changeset
4086 */
a61af66fc99e Initial load
duke
parents:
diff changeset
4087 // (Native) Frame Pointer definition
a61af66fc99e Initial load
duke
parents:
diff changeset
4088 fprintf(fp_cpp,"OptoReg::Name Matcher::c_frame_pointer() const {");
a61af66fc99e Initial load
duke
parents:
diff changeset
4089 fprintf(fp_cpp," return OptoReg::Name(%s_num); }\n\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
4090 _frame->_frame_pointer);
a61af66fc99e Initial load
duke
parents:
diff changeset
4091
a61af66fc99e Initial load
duke
parents:
diff changeset
4092 // Number of callee-save + always-save registers for calling convention
a61af66fc99e Initial load
duke
parents:
diff changeset
4093 fprintf(fp_cpp, "// Number of callee-save + always-save registers\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
4094 fprintf(fp_cpp, "int Matcher::number_of_saved_registers() {\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
4095 RegDef *rdef;
a61af66fc99e Initial load
duke
parents:
diff changeset
4096 int nof_saved_registers = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4097 _register->reset_RegDefs();
a61af66fc99e Initial load
duke
parents:
diff changeset
4098 while( (rdef = _register->iter_RegDefs()) != NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4099 if( !strcmp(rdef->_callconv, "SOE") || !strcmp(rdef->_callconv, "AS") )
a61af66fc99e Initial load
duke
parents:
diff changeset
4100 ++nof_saved_registers;
a61af66fc99e Initial load
duke
parents:
diff changeset
4101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4102 fprintf(fp_cpp, " return %d;\n", nof_saved_registers);
a61af66fc99e Initial load
duke
parents:
diff changeset
4103 fprintf(fp_cpp, "};\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
4104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4105
a61af66fc99e Initial load
duke
parents:
diff changeset
4106
a61af66fc99e Initial load
duke
parents:
diff changeset
4107
a61af66fc99e Initial load
duke
parents:
diff changeset
4108
a61af66fc99e Initial load
duke
parents:
diff changeset
4109 static int PrintAdlcCisc = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4110 //---------------------------identify_cisc_spilling----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4111 // Get info for the CISC_oracle and MachNode::cisc_version()
a61af66fc99e Initial load
duke
parents:
diff changeset
4112 void ArchDesc::identify_cisc_spill_instructions() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4113
6850
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
4114 if (_frame == NULL)
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
4115 return;
d336b3173277 8000592: Improve adlc usability
kvn
parents: 6848
diff changeset
4116
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4117 // Find the user-defined operand for cisc-spilling
a61af66fc99e Initial load
duke
parents:
diff changeset
4118 if( _frame->_cisc_spilling_operand_name != NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4119 const Form *form = _globalNames[_frame->_cisc_spilling_operand_name];
a61af66fc99e Initial load
duke
parents:
diff changeset
4120 OperandForm *oper = form ? form->is_operand() : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4121 // Verify the user's suggestion
a61af66fc99e Initial load
duke
parents:
diff changeset
4122 if( oper != NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4123 // Ensure that match field is defined.
a61af66fc99e Initial load
duke
parents:
diff changeset
4124 if ( oper->_matrule != NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4125 MatchRule &mrule = *oper->_matrule;
a61af66fc99e Initial load
duke
parents:
diff changeset
4126 if( strcmp(mrule._opType,"AddP") == 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4127 MatchNode *left = mrule._lChild;
a61af66fc99e Initial load
duke
parents:
diff changeset
4128 MatchNode *right= mrule._rChild;
a61af66fc99e Initial load
duke
parents:
diff changeset
4129 if( left != NULL && right != NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4130 const Form *left_op = _globalNames[left->_opType]->is_operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
4131 const Form *right_op = _globalNames[right->_opType]->is_operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
4132 if( (left_op != NULL && right_op != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
4133 && (left_op->interface_type(_globalNames) == Form::register_interface)
a61af66fc99e Initial load
duke
parents:
diff changeset
4134 && (right_op->interface_type(_globalNames) == Form::constant_interface) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4135 // Successfully verified operand
a61af66fc99e Initial load
duke
parents:
diff changeset
4136 set_cisc_spill_operand( oper );
a61af66fc99e Initial load
duke
parents:
diff changeset
4137 if( _cisc_spill_debug ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4138 fprintf(stderr, "\n\nVerified CISC-spill operand %s\n\n", oper->_ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
4139 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4141 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4143 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4144 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4146
a61af66fc99e Initial load
duke
parents:
diff changeset
4147 if( cisc_spill_operand() != NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4148 // N^2 comparison of instructions looking for a cisc-spilling version
a61af66fc99e Initial load
duke
parents:
diff changeset
4149 _instructions.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
4150 InstructForm *instr;
a61af66fc99e Initial load
duke
parents:
diff changeset
4151 for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4152 // Ensure that match field is defined.
a61af66fc99e Initial load
duke
parents:
diff changeset
4153 if ( instr->_matrule == NULL ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
4154
a61af66fc99e Initial load
duke
parents:
diff changeset
4155 MatchRule &mrule = *instr->_matrule;
a61af66fc99e Initial load
duke
parents:
diff changeset
4156 Predicate *pred = instr->build_predicate();
a61af66fc99e Initial load
duke
parents:
diff changeset
4157
a61af66fc99e Initial load
duke
parents:
diff changeset
4158 // Grab the machine type of the operand
a61af66fc99e Initial load
duke
parents:
diff changeset
4159 const char *rootOp = instr->_ident;
a61af66fc99e Initial load
duke
parents:
diff changeset
4160 mrule._machType = rootOp;
a61af66fc99e Initial load
duke
parents:
diff changeset
4161
a61af66fc99e Initial load
duke
parents:
diff changeset
4162 // Find result type for match
a61af66fc99e Initial load
duke
parents:
diff changeset
4163 const char *result = instr->reduce_result();
a61af66fc99e Initial load
duke
parents:
diff changeset
4164
a61af66fc99e Initial load
duke
parents:
diff changeset
4165 if( PrintAdlcCisc ) fprintf(stderr, " new instruction %s \n", instr->_ident ? instr->_ident : " ");
a61af66fc99e Initial load
duke
parents:
diff changeset
4166 bool found_cisc_alternate = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4167 _instructions.reset2();
a61af66fc99e Initial load
duke
parents:
diff changeset
4168 InstructForm *instr2;
a61af66fc99e Initial load
duke
parents:
diff changeset
4169 for( ; !found_cisc_alternate && (instr2 = (InstructForm*)_instructions.iter2()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4170 // Ensure that match field is defined.
a61af66fc99e Initial load
duke
parents:
diff changeset
4171 if( PrintAdlcCisc ) fprintf(stderr, " instr2 == %s \n", instr2->_ident ? instr2->_ident : " ");
a61af66fc99e Initial load
duke
parents:
diff changeset
4172 if ( instr2->_matrule != NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
4173 && (instr != instr2 ) // Skip self
a61af66fc99e Initial load
duke
parents:
diff changeset
4174 && (instr2->reduce_result() != NULL) // want same result
a61af66fc99e Initial load
duke
parents:
diff changeset
4175 && (strcmp(result, instr2->reduce_result()) == 0)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4176 MatchRule &mrule2 = *instr2->_matrule;
a61af66fc99e Initial load
duke
parents:
diff changeset
4177 Predicate *pred2 = instr2->build_predicate();
a61af66fc99e Initial load
duke
parents:
diff changeset
4178 found_cisc_alternate = instr->cisc_spills_to(*this, instr2);
a61af66fc99e Initial load
duke
parents:
diff changeset
4179 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4180 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4181 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4183 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4184
a61af66fc99e Initial load
duke
parents:
diff changeset
4185 //---------------------------build_cisc_spilling-------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4186 // Get info for the CISC_oracle and MachNode::cisc_version()
a61af66fc99e Initial load
duke
parents:
diff changeset
4187 void ArchDesc::build_cisc_spill_instructions(FILE *fp_hpp, FILE *fp_cpp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4188 // Output the table for cisc spilling
a61af66fc99e Initial load
duke
parents:
diff changeset
4189 fprintf(fp_cpp, "// The following instructions can cisc-spill\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
4190 _instructions.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
4191 InstructForm *inst = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4192 for(; (inst = (InstructForm*)_instructions.iter()) != NULL; ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4193 // Ensure this is a machine-world instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
4194 if ( inst->ideal_only() ) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
4195 const char *inst_name = inst->_ident;
a61af66fc99e Initial load
duke
parents:
diff changeset
4196 int operand = inst->cisc_spill_operand();
a61af66fc99e Initial load
duke
parents:
diff changeset
4197 if( operand != AdlcVMDeps::Not_cisc_spillable ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4198 InstructForm *inst2 = inst->cisc_spill_alternate();
a61af66fc99e Initial load
duke
parents:
diff changeset
4199 fprintf(fp_cpp, "// %s can cisc-spill operand %d to %s\n", inst->_ident, operand, inst2->_ident);
a61af66fc99e Initial load
duke
parents:
diff changeset
4200 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4202 fprintf(fp_cpp, "\n\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
4203 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4204
a61af66fc99e Initial load
duke
parents:
diff changeset
4205 //---------------------------identify_short_branches----------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4206 // Get info for our short branch replacement oracle.
a61af66fc99e Initial load
duke
parents:
diff changeset
4207 void ArchDesc::identify_short_branches() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4208 // Walk over all instructions, checking to see if they match a short
a61af66fc99e Initial load
duke
parents:
diff changeset
4209 // branching alternate.
a61af66fc99e Initial load
duke
parents:
diff changeset
4210 _instructions.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
4211 InstructForm *instr;
a61af66fc99e Initial load
duke
parents:
diff changeset
4212 while( (instr = (InstructForm*)_instructions.iter()) != NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4213 // The instruction must have a match rule.
a61af66fc99e Initial load
duke
parents:
diff changeset
4214 if (instr->_matrule != NULL &&
a61af66fc99e Initial load
duke
parents:
diff changeset
4215 instr->is_short_branch()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4216
a61af66fc99e Initial load
duke
parents:
diff changeset
4217 _instructions.reset2();
a61af66fc99e Initial load
duke
parents:
diff changeset
4218 InstructForm *instr2;
a61af66fc99e Initial load
duke
parents:
diff changeset
4219 while( (instr2 = (InstructForm*)_instructions.iter2()) != NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4220 instr2->check_branch_variant(*this, instr);
a61af66fc99e Initial load
duke
parents:
diff changeset
4221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4224 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4225
a61af66fc99e Initial load
duke
parents:
diff changeset
4226
a61af66fc99e Initial load
duke
parents:
diff changeset
4227 //---------------------------identify_unique_operands---------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
4228 // Identify unique operands.
a61af66fc99e Initial load
duke
parents:
diff changeset
4229 void ArchDesc::identify_unique_operands() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4230 // Walk over all instructions.
a61af66fc99e Initial load
duke
parents:
diff changeset
4231 _instructions.reset();
a61af66fc99e Initial load
duke
parents:
diff changeset
4232 InstructForm *instr;
a61af66fc99e Initial load
duke
parents:
diff changeset
4233 while( (instr = (InstructForm*)_instructions.iter()) != NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4234 // Ensure this is a machine-world instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
4235 if (!instr->ideal_only()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4236 instr->set_unique_opnds();
a61af66fc99e Initial load
duke
parents:
diff changeset
4237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4238 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4239 }