annotate src/share/vm/adlc/output_c.cpp @ 1721:413ad0331a0c

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