Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/adlc/archDesc.cpp
41144 views
1
//
2
// Copyright (c) 1997, 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
26
// archDesc.cpp - Internal format for architecture definition
27
#include "adlc.hpp"
28
29
static FILE *errfile = stderr;
30
31
//--------------------------- utility functions -----------------------------
32
inline char toUpper(char lower) {
33
return (('a' <= lower && lower <= 'z') ? ((char) (lower + ('A'-'a'))) : lower);
34
}
35
char *toUpper(const char *str) {
36
char *upper = new char[strlen(str)+1];
37
char *result = upper;
38
const char *end = str + strlen(str);
39
for (; str < end; ++str, ++upper) {
40
*upper = toUpper(*str);
41
}
42
*upper = '\0';
43
return result;
44
}
45
46
//---------------------------ChainList Methods-------------------------------
47
ChainList::ChainList() {
48
}
49
50
void ChainList::insert(const char *name, const char *cost, const char *rule) {
51
_name.addName(name);
52
_cost.addName(cost);
53
_rule.addName(rule);
54
}
55
56
bool ChainList::search(const char *name) {
57
return _name.search(name);
58
}
59
60
void ChainList::reset() {
61
_name.reset();
62
_cost.reset();
63
_rule.reset();
64
}
65
66
bool ChainList::iter(const char * &name, const char * &cost, const char * &rule) {
67
bool notDone = false;
68
const char *n = _name.iter();
69
const char *c = _cost.iter();
70
const char *r = _rule.iter();
71
72
if (n && c && r) {
73
notDone = true;
74
name = n;
75
cost = c;
76
rule = r;
77
}
78
79
return notDone;
80
}
81
82
void ChainList::dump() {
83
output(stderr);
84
}
85
86
void ChainList::output(FILE *fp) {
87
fprintf(fp, "\nChain Rules: output resets iterator\n");
88
const char *cost = NULL;
89
const char *name = NULL;
90
const char *rule = NULL;
91
bool chains_exist = false;
92
for(reset(); (iter(name,cost,rule)) == true; ) {
93
fprintf(fp, "Chain to <%s> at cost #%s using %s_rule\n",name, cost ? cost : "0", rule);
94
// // Check for transitive chain rules
95
// Form *form = (Form *)_globalNames[rule];
96
// if (form->is_instruction()) {
97
// // chain_rule(fp, indent, name, cost, rule);
98
// chain_rule(fp, indent, name, cost, rule);
99
// }
100
}
101
reset();
102
if( ! chains_exist ) {
103
fprintf(fp, "No entries in this ChainList\n");
104
}
105
}
106
107
108
//---------------------------MatchList Methods-------------------------------
109
bool MatchList::search(const char *opc, const char *res, const char *lch,
110
const char *rch, Predicate *pr) {
111
bool tmp = false;
112
if ((res == _resultStr) || (res && _resultStr && !strcmp(res, _resultStr))) {
113
if ((lch == _lchild) || (lch && _lchild && !strcmp(lch, _lchild))) {
114
if ((rch == _rchild) || (rch && _rchild && !strcmp(rch, _rchild))) {
115
char * predStr = get_pred();
116
char * prStr = pr?pr->_pred:NULL;
117
if (ADLParser::equivalent_expressions(prStr, predStr)) {
118
return true;
119
}
120
}
121
}
122
}
123
if (_next) {
124
tmp = _next->search(opc, res, lch, rch, pr);
125
}
126
return tmp;
127
}
128
129
130
void MatchList::dump() {
131
output(stderr);
132
}
133
134
void MatchList::output(FILE *fp) {
135
fprintf(fp, "\nMatchList output is Unimplemented();\n");
136
}
137
138
139
//---------------------------ArchDesc Constructor and Destructor-------------
140
141
ArchDesc::ArchDesc()
142
: _globalNames(cmpstr,hashstr, Form::arena),
143
_globalDefs(cmpstr,hashstr, Form::arena),
144
_preproc_table(cmpstr,hashstr, Form::arena),
145
_idealIndex(cmpstr,hashstr, Form::arena),
146
_internalOps(cmpstr,hashstr, Form::arena),
147
_internalMatch(cmpstr,hashstr, Form::arena),
148
_chainRules(cmpstr,hashstr, Form::arena),
149
_cisc_spill_operand(NULL),
150
_needs_deep_clone_jvms(false) {
151
152
// Initialize the opcode to MatchList table with NULLs
153
for( int i=0; i<_last_opcode; ++i ) {
154
_mlistab[i] = NULL;
155
}
156
157
// Set-up the global tables
158
initKeywords(_globalNames); // Initialize the Name Table with keywords
159
160
// Prime user-defined types with predefined types: Set, RegI, RegF, ...
161
initBaseOpTypes();
162
163
// Initialize flags & counters
164
_TotalLines = 0;
165
_no_output = 0;
166
_quiet_mode = 0;
167
_disable_warnings = 0;
168
_dfa_debug = 0;
169
_dfa_small = 0;
170
_adl_debug = 0;
171
_adlocation_debug = 0;
172
_internalOpCounter = 0;
173
_cisc_spill_debug = false;
174
_short_branch_debug = false;
175
176
// Initialize match rule flags
177
for (int i = 0; i < _last_opcode; i++) {
178
_has_match_rule[i] = false;
179
}
180
181
// Error/Warning Counts
182
_syntax_errs = 0;
183
_semantic_errs = 0;
184
_warnings = 0;
185
_internal_errs = 0;
186
187
// Initialize I/O Files
188
_ADL_file._name = NULL; _ADL_file._fp = NULL;
189
// Machine dependent output files
190
_DFA_file._name = NULL; _DFA_file._fp = NULL;
191
_HPP_file._name = NULL; _HPP_file._fp = NULL;
192
_CPP_file._name = NULL; _CPP_file._fp = NULL;
193
_bug_file._name = "bugs.out"; _bug_file._fp = NULL;
194
195
// Initialize Register & Pipeline Form Pointers
196
_register = NULL;
197
_encode = NULL;
198
_pipeline = NULL;
199
_frame = NULL;
200
}
201
202
ArchDesc::~ArchDesc() {
203
// Clean-up and quit
204
205
}
206
207
//---------------------------ArchDesc methods: Public ----------------------
208
// Store forms according to type
209
void ArchDesc::addForm(PreHeaderForm *ptr) { _pre_header.addForm(ptr); };
210
void ArchDesc::addForm(HeaderForm *ptr) { _header.addForm(ptr); };
211
void ArchDesc::addForm(SourceForm *ptr) { _source.addForm(ptr); };
212
void ArchDesc::addForm(EncodeForm *ptr) { _encode = ptr; };
213
void ArchDesc::addForm(InstructForm *ptr) { _instructions.addForm(ptr); };
214
void ArchDesc::addForm(MachNodeForm *ptr) { _machnodes.addForm(ptr); };
215
void ArchDesc::addForm(OperandForm *ptr) { _operands.addForm(ptr); };
216
void ArchDesc::addForm(OpClassForm *ptr) { _opclass.addForm(ptr); };
217
void ArchDesc::addForm(AttributeForm *ptr) { _attributes.addForm(ptr); };
218
void ArchDesc::addForm(RegisterForm *ptr) { _register = ptr; };
219
void ArchDesc::addForm(FrameForm *ptr) { _frame = ptr; };
220
void ArchDesc::addForm(PipelineForm *ptr) { _pipeline = ptr; };
221
222
// Build MatchList array and construct MatchLists
223
void ArchDesc::generateMatchLists() {
224
// Call inspection routines to populate array
225
inspectOperands();
226
inspectInstructions();
227
}
228
229
// Build MatchList structures for operands
230
void ArchDesc::inspectOperands() {
231
232
// Iterate through all operands
233
_operands.reset();
234
OperandForm *op;
235
for( ; (op = (OperandForm*)_operands.iter()) != NULL;) {
236
// Construct list of top-level operands (components)
237
op->build_components();
238
239
// Ensure that match field is defined.
240
if ( op->_matrule == NULL ) continue;
241
242
// Type check match rules
243
check_optype(op->_matrule);
244
245
// Construct chain rules
246
build_chain_rule(op);
247
248
MatchRule *mrule = op->_matrule;
249
Predicate *pred = op->_predicate;
250
251
// Grab the machine type of the operand
252
const char *rootOp = op->_ident;
253
mrule->_machType = rootOp;
254
255
// Check for special cases
256
if (strcmp(rootOp,"Universe")==0) continue;
257
if (strcmp(rootOp,"label")==0) continue;
258
// !!!!! !!!!!
259
assert( strcmp(rootOp,"sReg") != 0, "Disable untyped 'sReg'");
260
if (strcmp(rootOp,"sRegI")==0) continue;
261
if (strcmp(rootOp,"sRegP")==0) continue;
262
if (strcmp(rootOp,"sRegF")==0) continue;
263
if (strcmp(rootOp,"sRegD")==0) continue;
264
if (strcmp(rootOp,"sRegL")==0) continue;
265
266
// Cost for this match
267
const char *costStr = op->cost();
268
const char *defaultCost =
269
((AttributeForm*)_globalNames[AttributeForm::_op_cost])->_attrdef;
270
const char *cost = costStr? costStr : defaultCost;
271
272
// Find result type for match.
273
const char *result = op->reduce_result();
274
275
// Construct a MatchList for this entry.
276
// Iterate over the list to enumerate all match cases for operands with multiple match rules.
277
for (; mrule != NULL; mrule = mrule->_next) {
278
mrule->_machType = rootOp;
279
buildMatchList(mrule, result, rootOp, pred, cost);
280
}
281
}
282
}
283
284
// Build MatchList structures for instructions
285
void ArchDesc::inspectInstructions() {
286
287
// Iterate through all instructions
288
_instructions.reset();
289
InstructForm *instr;
290
for( ; (instr = (InstructForm*)_instructions.iter()) != NULL; ) {
291
// Construct list of top-level operands (components)
292
instr->build_components();
293
294
// Ensure that match field is defined.
295
if ( instr->_matrule == NULL ) continue;
296
297
MatchRule &mrule = *instr->_matrule;
298
Predicate *pred = instr->build_predicate();
299
300
// Grab the machine type of the operand
301
const char *rootOp = instr->_ident;
302
mrule._machType = rootOp;
303
304
// Cost for this match
305
const char *costStr = instr->cost();
306
const char *defaultCost =
307
((AttributeForm*)_globalNames[AttributeForm::_ins_cost])->_attrdef;
308
const char *cost = costStr? costStr : defaultCost;
309
310
// Find result type for match
311
const char *result = instr->reduce_result();
312
313
if (( instr->is_ideal_branch() && instr->label_position() == -1) ||
314
(!instr->is_ideal_branch() && instr->label_position() != -1)) {
315
syntax_err(instr->_linenum, "%s: Only branches to a label are supported\n", rootOp);
316
}
317
318
Attribute *attr = instr->_attribs;
319
while (attr != NULL) {
320
if (strcmp(attr->_ident,"ins_short_branch") == 0 &&
321
attr->int_val(*this) != 0) {
322
if (!instr->is_ideal_branch() || instr->label_position() == -1) {
323
syntax_err(instr->_linenum, "%s: Only short branch to a label is supported\n", rootOp);
324
}
325
instr->set_short_branch(true);
326
} else if (strcmp(attr->_ident,"ins_alignment") == 0 &&
327
attr->int_val(*this) != 0) {
328
instr->set_alignment(attr->int_val(*this));
329
}
330
attr = (Attribute *)attr->_next;
331
}
332
333
if (!instr->is_short_branch()) {
334
buildMatchList(instr->_matrule, result, mrule._machType, pred, cost);
335
}
336
}
337
}
338
339
static int setsResult(MatchRule &mrule) {
340
if (strcmp(mrule._name,"Set") == 0) return 1;
341
return 0;
342
}
343
344
const char *ArchDesc::getMatchListIndex(MatchRule &mrule) {
345
if (setsResult(mrule)) {
346
// right child
347
return mrule._rChild->_opType;
348
} else {
349
// first entry
350
return mrule._opType;
351
}
352
}
353
354
355
//------------------------------result of reduction----------------------------
356
357
358
//------------------------------left reduction---------------------------------
359
// Return the left reduction associated with an internal name
360
const char *ArchDesc::reduceLeft(char *internalName) {
361
const char *left = NULL;
362
MatchNode *mnode = (MatchNode*)_internalMatch[internalName];
363
if (mnode->_lChild) {
364
mnode = mnode->_lChild;
365
left = mnode->_internalop ? mnode->_internalop : mnode->_opType;
366
}
367
return left;
368
}
369
370
371
//------------------------------right reduction--------------------------------
372
const char *ArchDesc::reduceRight(char *internalName) {
373
const char *right = NULL;
374
MatchNode *mnode = (MatchNode*)_internalMatch[internalName];
375
if (mnode->_rChild) {
376
mnode = mnode->_rChild;
377
right = mnode->_internalop ? mnode->_internalop : mnode->_opType;
378
}
379
return right;
380
}
381
382
383
//------------------------------check_optype-----------------------------------
384
void ArchDesc::check_optype(MatchRule *mrule) {
385
MatchRule *rule = mrule;
386
387
// !!!!!
388
// // Cycle through the list of match rules
389
// while(mrule) {
390
// // Check for a filled in type field
391
// if (mrule->_opType == NULL) {
392
// const Form *form = operands[_result];
393
// OpClassForm *opcForm = form ? form->is_opclass() : NULL;
394
// assert(opcForm != NULL, "Match Rule contains invalid operand name.");
395
// }
396
// char *opType = opcForm->_ident;
397
// }
398
}
399
400
//------------------------------add_chain_rule_entry--------------------------
401
void ArchDesc::add_chain_rule_entry(const char *src, const char *cost,
402
const char *result) {
403
// Look-up the operation in chain rule table
404
ChainList *lst = (ChainList *)_chainRules[src];
405
if (lst == NULL) {
406
lst = new ChainList();
407
_chainRules.Insert(src, lst);
408
}
409
if (!lst->search(result)) {
410
if (cost == NULL) {
411
cost = ((AttributeForm*)_globalNames[AttributeForm::_op_cost])->_attrdef;
412
}
413
lst->insert(result, cost, result);
414
}
415
}
416
417
//------------------------------build_chain_rule-------------------------------
418
void ArchDesc::build_chain_rule(OperandForm *oper) {
419
MatchRule *rule;
420
421
// Check for chain rules here
422
// If this is only a chain rule
423
if ((oper->_matrule) && (oper->_matrule->_lChild == NULL) &&
424
(oper->_matrule->_rChild == NULL)) {
425
426
{
427
const Form *form = _globalNames[oper->_matrule->_opType];
428
if ((form) && form->is_operand() &&
429
(form->ideal_only() == false)) {
430
add_chain_rule_entry(oper->_matrule->_opType, oper->cost(), oper->_ident);
431
}
432
}
433
// Check for additional chain rules
434
if (oper->_matrule->_next) {
435
rule = oper->_matrule;
436
do {
437
rule = rule->_next;
438
// Any extra match rules after the first must be chain rules
439
const Form *form = _globalNames[rule->_opType];
440
if ((form) && form->is_operand() &&
441
(form->ideal_only() == false)) {
442
add_chain_rule_entry(rule->_opType, oper->cost(), oper->_ident);
443
}
444
} while(rule->_next != NULL);
445
}
446
}
447
else if ((oper->_matrule) && (oper->_matrule->_next)) {
448
// Regardles of whether the first matchrule is a chain rule, check the list
449
rule = oper->_matrule;
450
do {
451
rule = rule->_next;
452
// Any extra match rules after the first must be chain rules
453
const Form *form = _globalNames[rule->_opType];
454
if ((form) && form->is_operand() &&
455
(form->ideal_only() == false)) {
456
assert( oper->cost(), "This case expects NULL cost, not default cost");
457
add_chain_rule_entry(rule->_opType, oper->cost(), oper->_ident);
458
}
459
} while(rule->_next != NULL);
460
}
461
462
}
463
464
//------------------------------buildMatchList---------------------------------
465
// operands and instructions provide the result
466
void ArchDesc::buildMatchList(MatchRule *mrule, const char *resultStr,
467
const char *rootOp, Predicate *pred,
468
const char *cost) {
469
const char *leftstr, *rightstr;
470
MatchNode *mnode;
471
472
leftstr = rightstr = NULL;
473
// Check for chain rule, and do not generate a match list for it
474
if ( mrule->is_chain_rule(_globalNames) ) {
475
return;
476
}
477
478
// Identify index position among ideal operands
479
intptr_t index = _last_opcode;
480
const char *indexStr = getMatchListIndex(*mrule);
481
index = (intptr_t)_idealIndex[indexStr];
482
if (index == 0) {
483
fprintf(stderr, "Ideal node missing: %s\n", indexStr);
484
assert(index != 0, "Failed lookup of ideal node\n");
485
}
486
487
// Check that this will be placed appropriately in the DFA
488
if (index >= _last_opcode) {
489
fprintf(stderr, "Invalid match rule %s <-- ( %s )\n",
490
resultStr ? resultStr : " ",
491
rootOp ? rootOp : " ");
492
assert(index < _last_opcode, "Matching item not in ideal graph\n");
493
return;
494
}
495
496
497
// Walk the MatchRule, generating MatchList entries for each level
498
// of the rule (each nesting of parentheses)
499
// Check for "Set"
500
if (!strcmp(mrule->_opType, "Set")) {
501
mnode = mrule->_rChild;
502
buildMList(mnode, rootOp, resultStr, pred, cost);
503
return;
504
}
505
// Build MatchLists for children
506
// Check each child for an internal operand name, and use that name
507
// for the parent's matchlist entry if it exists
508
mnode = mrule->_lChild;
509
if (mnode) {
510
buildMList(mnode, NULL, NULL, NULL, NULL);
511
leftstr = mnode->_internalop ? mnode->_internalop : mnode->_opType;
512
}
513
mnode = mrule->_rChild;
514
if (mnode) {
515
buildMList(mnode, NULL, NULL, NULL, NULL);
516
rightstr = mnode->_internalop ? mnode->_internalop : mnode->_opType;
517
}
518
// Search for an identical matchlist entry already on the list
519
if ((_mlistab[index] == NULL) ||
520
(_mlistab[index] &&
521
!_mlistab[index]->search(rootOp, resultStr, leftstr, rightstr, pred))) {
522
// Place this match rule at front of list
523
MatchList *mList =
524
new MatchList(_mlistab[index], pred, cost,
525
rootOp, resultStr, leftstr, rightstr);
526
_mlistab[index] = mList;
527
}
528
}
529
530
// Recursive call for construction of match lists
531
void ArchDesc::buildMList(MatchNode *node, const char *rootOp,
532
const char *resultOp, Predicate *pred,
533
const char *cost) {
534
const char *leftstr, *rightstr;
535
const char *resultop;
536
const char *opcode;
537
MatchNode *mnode;
538
Form *form;
539
540
leftstr = rightstr = NULL;
541
// Do not process leaves of the Match Tree if they are not ideal
542
if ((node) && (node->_lChild == NULL) && (node->_rChild == NULL) &&
543
((form = (Form *)_globalNames[node->_opType]) != NULL) &&
544
(!form->ideal_only())) {
545
return;
546
}
547
548
// Identify index position among ideal operands
549
intptr_t index = _last_opcode;
550
const char *indexStr = node ? node->_opType : (char *) " ";
551
index = (intptr_t)_idealIndex[indexStr];
552
if (index == 0) {
553
fprintf(stderr, "error: operand \"%s\" not found\n", indexStr);
554
assert(0, "fatal error");
555
}
556
557
if (node == NULL) {
558
fprintf(stderr, "error: node is NULL\n");
559
assert(0, "fatal error");
560
}
561
// Build MatchLists for children
562
// Check each child for an internal operand name, and use that name
563
// for the parent's matchlist entry if it exists
564
mnode = node->_lChild;
565
if (mnode) {
566
buildMList(mnode, NULL, NULL, NULL, NULL);
567
leftstr = mnode->_internalop ? mnode->_internalop : mnode->_opType;
568
}
569
mnode = node->_rChild;
570
if (mnode) {
571
buildMList(mnode, NULL, NULL, NULL, NULL);
572
rightstr = mnode->_internalop ? mnode->_internalop : mnode->_opType;
573
}
574
// Grab the string for the opcode of this list entry
575
if (rootOp == NULL) {
576
opcode = (node->_internalop) ? node->_internalop : node->_opType;
577
} else {
578
opcode = rootOp;
579
}
580
// Grab the string for the result of this list entry
581
if (resultOp == NULL) {
582
resultop = (node->_internalop) ? node->_internalop : node->_opType;
583
}
584
else resultop = resultOp;
585
// Search for an identical matchlist entry already on the list
586
if ((_mlistab[index] == NULL) || (_mlistab[index] &&
587
!_mlistab[index]->search(opcode, resultop, leftstr, rightstr, pred))) {
588
// Place this match rule at front of list
589
MatchList *mList =
590
new MatchList(_mlistab[index],pred,cost,
591
opcode, resultop, leftstr, rightstr);
592
_mlistab[index] = mList;
593
}
594
}
595
596
// Count number of OperandForms defined
597
int ArchDesc::operandFormCount() {
598
// Only interested in ones with non-NULL match rule
599
int count = 0; _operands.reset();
600
OperandForm *cur;
601
for( ; (cur = (OperandForm*)_operands.iter()) != NULL; ) {
602
if (cur->_matrule != NULL) ++count;
603
};
604
return count;
605
}
606
607
// Count number of OpClassForms defined
608
int ArchDesc::opclassFormCount() {
609
// Only interested in ones with non-NULL match rule
610
int count = 0; _operands.reset();
611
OpClassForm *cur;
612
for( ; (cur = (OpClassForm*)_opclass.iter()) != NULL; ) {
613
++count;
614
};
615
return count;
616
}
617
618
// Count number of InstructForms defined
619
int ArchDesc::instructFormCount() {
620
// Only interested in ones with non-NULL match rule
621
int count = 0; _instructions.reset();
622
InstructForm *cur;
623
for( ; (cur = (InstructForm*)_instructions.iter()) != NULL; ) {
624
if (cur->_matrule != NULL) ++count;
625
};
626
return count;
627
}
628
629
630
//------------------------------get_preproc_def--------------------------------
631
// Return the textual binding for a given CPP flag name.
632
// Return NULL if there is no binding, or it has been #undef-ed.
633
char* ArchDesc::get_preproc_def(const char* flag) {
634
// In case of syntax errors, flag may take the value NULL.
635
SourceForm* deff = NULL;
636
if (flag != NULL)
637
deff = (SourceForm*) _preproc_table[flag];
638
return (deff == NULL) ? NULL : deff->_code;
639
}
640
641
642
//------------------------------set_preproc_def--------------------------------
643
// Change or create a textual binding for a given CPP flag name.
644
// Giving NULL means the flag name is to be #undef-ed.
645
// In any case, _preproc_list collects all names either #defined or #undef-ed.
646
void ArchDesc::set_preproc_def(const char* flag, const char* def) {
647
SourceForm* deff = (SourceForm*) _preproc_table[flag];
648
if (deff == NULL) {
649
deff = new SourceForm(NULL);
650
_preproc_table.Insert(flag, deff);
651
_preproc_list.addName(flag); // this supports iteration
652
}
653
deff->_code = (char*) def;
654
}
655
656
657
bool ArchDesc::verify() {
658
659
if (_register)
660
assert( _register->verify(), "Register declarations failed verification");
661
if (!_quiet_mode)
662
fprintf(stderr,"\n");
663
// fprintf(stderr,"---------------------------- Verify Operands ---------------\n");
664
// _operands.verify();
665
// fprintf(stderr,"\n");
666
// fprintf(stderr,"---------------------------- Verify Operand Classes --------\n");
667
// _opclass.verify();
668
// fprintf(stderr,"\n");
669
// fprintf(stderr,"---------------------------- Verify Attributes ------------\n");
670
// _attributes.verify();
671
// fprintf(stderr,"\n");
672
if (!_quiet_mode)
673
fprintf(stderr,"---------------------------- Verify Instructions ----------------------------\n");
674
_instructions.verify();
675
if (!_quiet_mode)
676
fprintf(stderr,"\n");
677
// if ( _encode ) {
678
// fprintf(stderr,"---------------------------- Verify Encodings --------------\n");
679
// _encode->verify();
680
// }
681
682
//if (_pipeline) _pipeline->verify();
683
684
return true;
685
}
686
687
688
void ArchDesc::dump() {
689
_pre_header.dump();
690
_header.dump();
691
_source.dump();
692
if (_register) _register->dump();
693
fprintf(stderr,"\n");
694
fprintf(stderr,"------------------ Dump Operands ---------------------\n");
695
_operands.dump();
696
fprintf(stderr,"\n");
697
fprintf(stderr,"------------------ Dump Operand Classes --------------\n");
698
_opclass.dump();
699
fprintf(stderr,"\n");
700
fprintf(stderr,"------------------ Dump Attributes ------------------\n");
701
_attributes.dump();
702
fprintf(stderr,"\n");
703
fprintf(stderr,"------------------ Dump Instructions -----------------\n");
704
_instructions.dump();
705
if ( _encode ) {
706
fprintf(stderr,"------------------ Dump Encodings --------------------\n");
707
_encode->dump();
708
}
709
if (_pipeline) _pipeline->dump();
710
}
711
712
713
//------------------------------init_keywords----------------------------------
714
// Load the kewords into the global name table
715
void ArchDesc::initKeywords(FormDict& names) {
716
// Insert keyword strings into Global Name Table. Keywords have a NULL value
717
// field for quick easy identification when checking identifiers.
718
names.Insert("instruct", NULL);
719
names.Insert("operand", NULL);
720
names.Insert("attribute", NULL);
721
names.Insert("source", NULL);
722
names.Insert("register", NULL);
723
names.Insert("pipeline", NULL);
724
names.Insert("constraint", NULL);
725
names.Insert("predicate", NULL);
726
names.Insert("encode", NULL);
727
names.Insert("enc_class", NULL);
728
names.Insert("interface", NULL);
729
names.Insert("opcode", NULL);
730
names.Insert("ins_encode", NULL);
731
names.Insert("match", NULL);
732
names.Insert("effect", NULL);
733
names.Insert("expand", NULL);
734
names.Insert("rewrite", NULL);
735
names.Insert("reg_def", NULL);
736
names.Insert("reg_class", NULL);
737
names.Insert("alloc_class", NULL);
738
names.Insert("resource", NULL);
739
names.Insert("pipe_class", NULL);
740
names.Insert("pipe_desc", NULL);
741
}
742
743
744
//------------------------------internal_err----------------------------------
745
// Issue a parser error message, and skip to the end of the current line
746
void ArchDesc::internal_err(const char *fmt, ...) {
747
va_list args;
748
749
va_start(args, fmt);
750
_internal_errs += emit_msg(0, INTERNAL_ERR, 0, fmt, args);
751
va_end(args);
752
753
_no_output = 1;
754
}
755
756
//------------------------------syntax_err----------------------------------
757
// Issue a parser error message, and skip to the end of the current line
758
void ArchDesc::syntax_err(int lineno, const char *fmt, ...) {
759
va_list args;
760
761
va_start(args, fmt);
762
_internal_errs += emit_msg(0, SYNERR, lineno, fmt, args);
763
va_end(args);
764
765
_no_output = 1;
766
}
767
768
//------------------------------emit_msg---------------------------------------
769
// Emit a user message, typically a warning or error
770
int ArchDesc::emit_msg(int quiet, int flag, int line, const char *fmt,
771
va_list args) {
772
static int last_lineno = -1;
773
int i;
774
const char *pref;
775
776
switch(flag) {
777
case 0: pref = "Warning: "; break;
778
case 1: pref = "Syntax Error: "; break;
779
case 2: pref = "Semantic Error: "; break;
780
case 3: pref = "Internal Error: "; break;
781
default: assert(0, ""); break;
782
}
783
784
if (line == last_lineno) return 0;
785
last_lineno = line;
786
787
if (!quiet) { /* no output if in quiet mode */
788
i = fprintf(errfile, "%s(%d) ", _ADL_file._name, line);
789
while (i++ <= 15) fputc(' ', errfile);
790
fprintf(errfile, "%-8s:", pref);
791
vfprintf(errfile, fmt, args);
792
fprintf(errfile, "\n");
793
fflush(errfile);
794
}
795
return 1;
796
}
797
798
799
// ---------------------------------------------------------------------------
800
//--------Utilities to build mappings for machine registers ------------------
801
// ---------------------------------------------------------------------------
802
803
// Construct the name of the register mask.
804
static const char *getRegMask(const char *reg_class_name) {
805
if( reg_class_name == NULL ) return "RegMask::Empty";
806
807
if (strcmp(reg_class_name,"Universe")==0) {
808
return "RegMask::Empty";
809
} else if (strcmp(reg_class_name,"stack_slots")==0) {
810
return "(Compile::current()->FIRST_STACK_mask())";
811
} else if (strcmp(reg_class_name, "dynamic")==0) {
812
return "*_opnds[0]->in_RegMask(0)";
813
} else {
814
char *rc_name = toUpper(reg_class_name);
815
const char *mask = "_mask";
816
int length = (int)strlen(rc_name) + (int)strlen(mask) + 5;
817
char *regMask = new char[length];
818
sprintf(regMask,"%s%s()", rc_name, mask);
819
delete[] rc_name;
820
return regMask;
821
}
822
}
823
824
// Convert a register class name to its register mask.
825
const char *ArchDesc::reg_class_to_reg_mask(const char *rc_name) {
826
const char *reg_mask = "RegMask::Empty";
827
828
if( _register ) {
829
RegClass *reg_class = _register->getRegClass(rc_name);
830
if (reg_class == NULL) {
831
syntax_err(0, "Use of an undefined register class %s", rc_name);
832
return reg_mask;
833
}
834
835
// Construct the name of the register mask.
836
reg_mask = getRegMask(rc_name);
837
}
838
839
return reg_mask;
840
}
841
842
843
// Obtain the name of the RegMask for an OperandForm
844
const char *ArchDesc::reg_mask(OperandForm &opForm) {
845
const char *regMask = "RegMask::Empty";
846
847
// Check constraints on result's register class
848
const char *result_class = opForm.constrained_reg_class();
849
if (result_class == NULL) {
850
opForm.dump();
851
syntax_err(opForm._linenum,
852
"Use of an undefined result class for operand: %s",
853
opForm._ident);
854
abort();
855
}
856
857
regMask = reg_class_to_reg_mask( result_class );
858
859
return regMask;
860
}
861
862
// Obtain the name of the RegMask for an InstructForm
863
const char *ArchDesc::reg_mask(InstructForm &inForm) {
864
const char *result = inForm.reduce_result();
865
866
if (result == NULL) {
867
syntax_err(inForm._linenum,
868
"Did not find result operand or RegMask"
869
" for this instruction: %s",
870
inForm._ident);
871
abort();
872
}
873
874
// Instructions producing 'Universe' use RegMask::Empty
875
if (strcmp(result,"Universe") == 0) {
876
return "RegMask::Empty";
877
}
878
879
// Lookup this result operand and get its register class
880
Form *form = (Form*)_globalNames[result];
881
if (form == NULL) {
882
syntax_err(inForm._linenum,
883
"Did not find result operand for result: %s", result);
884
abort();
885
}
886
OperandForm *oper = form->is_operand();
887
if (oper == NULL) {
888
syntax_err(inForm._linenum, "Form is not an OperandForm:");
889
form->dump();
890
abort();
891
}
892
return reg_mask( *oper );
893
}
894
895
896
// Obtain the STACK_OR_reg_mask name for an OperandForm
897
char *ArchDesc::stack_or_reg_mask(OperandForm &opForm) {
898
// name of cisc_spillable version
899
const char *reg_mask_name = reg_mask(opForm);
900
901
if (reg_mask_name == NULL) {
902
syntax_err(opForm._linenum,
903
"Did not find reg_mask for opForm: %s",
904
opForm._ident);
905
abort();
906
}
907
908
const char *stack_or = "STACK_OR_";
909
int length = (int)strlen(stack_or) + (int)strlen(reg_mask_name) + 1;
910
char *result = new char[length];
911
sprintf(result,"%s%s", stack_or, reg_mask_name);
912
913
return result;
914
}
915
916
// Record that the register class must generate a stack_or_reg_mask
917
void ArchDesc::set_stack_or_reg(const char *reg_class_name) {
918
if( _register ) {
919
RegClass *reg_class = _register->getRegClass(reg_class_name);
920
reg_class->set_stack_version(true);
921
}
922
}
923
924
925
// Return the type signature for the ideal operation
926
const char *ArchDesc::getIdealType(const char *idealOp) {
927
// Find last character in idealOp, it specifies the type
928
char last_char = 0;
929
const char *ptr = idealOp;
930
for (; *ptr != '\0'; ++ptr) {
931
last_char = *ptr;
932
}
933
934
// Match Vector types.
935
if (strncmp(idealOp, "Vec",3)==0) {
936
switch(last_char) {
937
case 'A': return "TypeVect::VECTA";
938
case 'S': return "TypeVect::VECTS";
939
case 'D': return "TypeVect::VECTD";
940
case 'X': return "TypeVect::VECTX";
941
case 'Y': return "TypeVect::VECTY";
942
case 'Z': return "TypeVect::VECTZ";
943
default:
944
internal_err("Vector type %s with unrecognized type\n",idealOp);
945
}
946
}
947
948
if (strncmp(idealOp, "RegVectMask", 8) == 0) {
949
return "TypeVect::VECTMASK";
950
}
951
952
// !!!!!
953
switch(last_char) {
954
case 'I': return "TypeInt::INT";
955
case 'P': return "TypePtr::BOTTOM";
956
case 'N': return "TypeNarrowOop::BOTTOM";
957
case 'F': return "Type::FLOAT";
958
case 'D': return "Type::DOUBLE";
959
case 'L': return "TypeLong::LONG";
960
case 's': return "TypeInt::CC /*flags*/";
961
default:
962
return NULL;
963
// !!!!!
964
// internal_err("Ideal type %s with unrecognized type\n",idealOp);
965
break;
966
}
967
968
return NULL;
969
}
970
971
972
973
OperandForm *ArchDesc::constructOperand(const char *ident,
974
bool ideal_only) {
975
OperandForm *opForm = new OperandForm(ident, ideal_only);
976
_globalNames.Insert(ident, opForm);
977
addForm(opForm);
978
979
return opForm;
980
}
981
982
983
// Import predefined base types: Set = 1, RegI, RegP, ...
984
void ArchDesc::initBaseOpTypes() {
985
// Create OperandForm and assign type for each opcode.
986
for (int i = 1; i < _last_machine_leaf; ++i) {
987
char *ident = (char *)NodeClassNames[i];
988
constructOperand(ident, true);
989
}
990
// Create InstructForm and assign type for each ideal instruction.
991
for (int j = _last_machine_leaf+1; j < _last_opcode; ++j) {
992
char *ident = (char *)NodeClassNames[j];
993
if (!strcmp(ident, "ConI") || !strcmp(ident, "ConP") ||
994
!strcmp(ident, "ConN") || !strcmp(ident, "ConNKlass") ||
995
!strcmp(ident, "ConF") || !strcmp(ident, "ConD") ||
996
!strcmp(ident, "ConL") || !strcmp(ident, "Con" ) ||
997
!strcmp(ident, "Bool")) {
998
constructOperand(ident, true);
999
} else {
1000
InstructForm *insForm = new InstructForm(ident, true);
1001
// insForm->_opcode = nextUserOpType(ident);
1002
_globalNames.Insert(ident, insForm);
1003
addForm(insForm);
1004
}
1005
}
1006
1007
{ OperandForm *opForm;
1008
// Create operand type "Universe" for return instructions.
1009
const char *ident = "Universe";
1010
opForm = constructOperand(ident, false);
1011
1012
// Create operand type "label" for branch targets
1013
ident = "label";
1014
opForm = constructOperand(ident, false);
1015
1016
// !!!!! Update - when adding a new sReg/stackSlot type
1017
// Create operand types "sReg[IPFDL]" for stack slot registers
1018
opForm = constructOperand("sRegI", false);
1019
opForm->_constraint = new Constraint("ALLOC_IN_RC", "stack_slots");
1020
opForm = constructOperand("sRegP", false);
1021
opForm->_constraint = new Constraint("ALLOC_IN_RC", "stack_slots");
1022
opForm = constructOperand("sRegF", false);
1023
opForm->_constraint = new Constraint("ALLOC_IN_RC", "stack_slots");
1024
opForm = constructOperand("sRegD", false);
1025
opForm->_constraint = new Constraint("ALLOC_IN_RC", "stack_slots");
1026
opForm = constructOperand("sRegL", false);
1027
opForm->_constraint = new Constraint("ALLOC_IN_RC", "stack_slots");
1028
1029
// Create operand type "method" for call targets
1030
ident = "method";
1031
opForm = constructOperand(ident, false);
1032
}
1033
1034
// Create Effect Forms for each of the legal effects
1035
// USE, DEF, USE_DEF, KILL, USE_KILL
1036
{
1037
const char *ident = "USE";
1038
Effect *eForm = new Effect(ident);
1039
_globalNames.Insert(ident, eForm);
1040
ident = "DEF";
1041
eForm = new Effect(ident);
1042
_globalNames.Insert(ident, eForm);
1043
ident = "USE_DEF";
1044
eForm = new Effect(ident);
1045
_globalNames.Insert(ident, eForm);
1046
ident = "KILL";
1047
eForm = new Effect(ident);
1048
_globalNames.Insert(ident, eForm);
1049
ident = "USE_KILL";
1050
eForm = new Effect(ident);
1051
_globalNames.Insert(ident, eForm);
1052
ident = "TEMP";
1053
eForm = new Effect(ident);
1054
_globalNames.Insert(ident, eForm);
1055
ident = "TEMP_DEF";
1056
eForm = new Effect(ident);
1057
_globalNames.Insert(ident, eForm);
1058
ident = "CALL";
1059
eForm = new Effect(ident);
1060
_globalNames.Insert(ident, eForm);
1061
}
1062
1063
//
1064
// Build mapping from ideal names to ideal indices
1065
int idealIndex = 0;
1066
for (idealIndex = 1; idealIndex < _last_machine_leaf; ++idealIndex) {
1067
const char *idealName = NodeClassNames[idealIndex];
1068
_idealIndex.Insert((void*) idealName, (void*) (intptr_t) idealIndex);
1069
}
1070
for (idealIndex = _last_machine_leaf+1;
1071
idealIndex < _last_opcode; ++idealIndex) {
1072
const char *idealName = NodeClassNames[idealIndex];
1073
_idealIndex.Insert((void*) idealName, (void*) (intptr_t) idealIndex);
1074
}
1075
1076
}
1077
1078
1079
//---------------------------addSUNcopyright-------------------------------
1080
// output SUN copyright info
1081
void ArchDesc::addSunCopyright(char* legal, int size, FILE *fp) {
1082
size_t count = fwrite(legal, 1, size, fp);
1083
assert(count == (size_t) size, "copyright info truncated");
1084
fprintf(fp,"\n");
1085
fprintf(fp,"// Machine Generated File. Do Not Edit!\n");
1086
fprintf(fp,"\n");
1087
}
1088
1089
1090
//---------------------------addIncludeGuardStart--------------------------
1091
// output the start of an include guard.
1092
void ArchDesc::addIncludeGuardStart(ADLFILE &adlfile, const char* guardString) {
1093
// Build #include lines
1094
fprintf(adlfile._fp, "\n");
1095
fprintf(adlfile._fp, "#ifndef %s\n", guardString);
1096
fprintf(adlfile._fp, "#define %s\n", guardString);
1097
fprintf(adlfile._fp, "\n");
1098
1099
}
1100
1101
//---------------------------addIncludeGuardEnd--------------------------
1102
// output the end of an include guard.
1103
void ArchDesc::addIncludeGuardEnd(ADLFILE &adlfile, const char* guardString) {
1104
// Build #include lines
1105
fprintf(adlfile._fp, "\n");
1106
fprintf(adlfile._fp, "#endif // %s\n", guardString);
1107
1108
}
1109
1110
//---------------------------addInclude--------------------------
1111
// output the #include line for this file.
1112
void ArchDesc::addInclude(ADLFILE &adlfile, const char* fileName) {
1113
fprintf(adlfile._fp, "#include \"%s\"\n", fileName);
1114
1115
}
1116
1117
void ArchDesc::addInclude(ADLFILE &adlfile, const char* includeDir, const char* fileName) {
1118
fprintf(adlfile._fp, "#include \"%s/%s\"\n", includeDir, fileName);
1119
1120
}
1121
1122
//---------------------------addPreprocessorChecks-----------------------------
1123
// Output C preprocessor code to verify the backend compilation environment.
1124
// The idea is to force code produced by "adlc -DHS64" to be compiled by a
1125
// command of the form "CC ... -DHS64 ...", so that any #ifdefs in the source
1126
// blocks select C code that is consistent with adlc's selections of AD code.
1127
void ArchDesc::addPreprocessorChecks(FILE *fp) {
1128
const char* flag;
1129
_preproc_list.reset();
1130
if (_preproc_list.count() > 0 && !_preproc_list.current_is_signal()) {
1131
fprintf(fp, "// Check consistency of C++ compilation with ADLC options:\n");
1132
}
1133
for (_preproc_list.reset(); (flag = _preproc_list.iter()) != NULL; ) {
1134
if (_preproc_list.current_is_signal()) break;
1135
char* def = get_preproc_def(flag);
1136
fprintf(fp, "// Check adlc ");
1137
if (def)
1138
fprintf(fp, "-D%s=%s\n", flag, def);
1139
else fprintf(fp, "-U%s\n", flag);
1140
fprintf(fp, "#%s %s\n",
1141
def ? "ifndef" : "ifdef", flag);
1142
fprintf(fp, "# error \"%s %s be defined\"\n",
1143
flag, def ? "must" : "must not");
1144
fprintf(fp, "#endif // %s\n", flag);
1145
}
1146
}
1147
1148
1149
// Convert operand name into enum name
1150
const char *ArchDesc::machOperEnum(const char *opName) {
1151
return ArchDesc::getMachOperEnum(opName);
1152
}
1153
1154
// Convert operand name into enum name
1155
const char *ArchDesc::getMachOperEnum(const char *opName) {
1156
return (opName ? toUpper(opName) : opName);
1157
}
1158
1159
//---------------------------buildMustCloneMap-----------------------------
1160
// Flag cases when machine needs cloned values or instructions
1161
void ArchDesc::buildMustCloneMap(FILE *fp_hpp, FILE *fp_cpp) {
1162
// Build external declarations for mappings
1163
fprintf(fp_hpp, "// Mapping from machine-independent opcode to boolean\n");
1164
fprintf(fp_hpp, "// Flag cases where machine needs cloned values or instructions\n");
1165
fprintf(fp_hpp, "extern const char must_clone[];\n");
1166
fprintf(fp_hpp, "\n");
1167
1168
// Build mapping from ideal names to ideal indices
1169
fprintf(fp_cpp, "\n");
1170
fprintf(fp_cpp, "// Mapping from machine-independent opcode to boolean\n");
1171
fprintf(fp_cpp, "const char must_clone[] = {\n");
1172
for (int idealIndex = 0; idealIndex < _last_opcode; ++idealIndex) {
1173
int must_clone = 0;
1174
const char *idealName = NodeClassNames[idealIndex];
1175
// Previously selected constants for cloning
1176
// !!!!!
1177
// These are the current machine-dependent clones
1178
if ( strcmp(idealName,"CmpI") == 0
1179
|| strcmp(idealName,"CmpU") == 0
1180
|| strcmp(idealName,"CmpP") == 0
1181
|| strcmp(idealName,"CmpN") == 0
1182
|| strcmp(idealName,"CmpL") == 0
1183
|| strcmp(idealName,"CmpUL") == 0
1184
|| strcmp(idealName,"CmpD") == 0
1185
|| strcmp(idealName,"CmpF") == 0
1186
|| strcmp(idealName,"FastLock") == 0
1187
|| strcmp(idealName,"FastUnlock") == 0
1188
|| strcmp(idealName,"OverflowAddI") == 0
1189
|| strcmp(idealName,"OverflowAddL") == 0
1190
|| strcmp(idealName,"OverflowSubI") == 0
1191
|| strcmp(idealName,"OverflowSubL") == 0
1192
|| strcmp(idealName,"OverflowMulI") == 0
1193
|| strcmp(idealName,"OverflowMulL") == 0
1194
|| strcmp(idealName,"Bool") == 0
1195
|| strcmp(idealName,"Binary") == 0 ) {
1196
// Removed ConI from the must_clone list. CPUs that cannot use
1197
// large constants as immediates manifest the constant as an
1198
// instruction. The must_clone flag prevents the constant from
1199
// floating up out of loops.
1200
must_clone = 1;
1201
}
1202
fprintf(fp_cpp, " %d%s // %s: %d\n", must_clone,
1203
(idealIndex != (_last_opcode - 1)) ? "," : " // no trailing comma",
1204
idealName, idealIndex);
1205
}
1206
// Finish defining table
1207
fprintf(fp_cpp, "};\n");
1208
}
1209
1210