Bug Summary

File:jdk/src/hotspot/share/adlc/output_c.cpp
Warning:line 949, column 39
Although the value stored to 'nop' is used in the enclosing expression, the value is never actually read from 'nop'

Annotated Source Code

Press '?' to see keyboard shortcuts

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