31
ADLParser::ADLParser(FileBuff& buffer, ArchDesc& archDesc)
32
: _buf(buffer), _AD(archDesc),
33
_globalNames(archDesc.globalNames()) {
34
_AD._syntax_errs = _AD._semantic_errs = 0;
36
_curline = _ptr = nullptr;
39
_preproc_not_taken = 0;
42
_AD._preproc_list.add_signal();
47
ADLParser::~ADLParser() {
49
fprintf(stderr,"---------------------------- Errors and Warnings ----------------------------\n");
51
if (!_AD._quiet_mode) {
52
fprintf(stderr, "**************************************************************\n");
53
fprintf(stderr, "***** WARNING: ASSERT is undefined, assertions disabled. *****\n");
54
fprintf(stderr, "**************************************************************\n");
57
if( _AD._syntax_errs + _AD._semantic_errs + _AD._warnings == 0 ) {
59
fprintf(stderr,"No errors or warnings to report from phase-1 parse.\n" );
62
if( _AD._syntax_errs ) {
63
fprintf(stderr,"%s: Found %d syntax error", _buf._fp->_name, _AD._syntax_errs);
64
if( _AD._syntax_errs > 1 ) fprintf(stderr,"s.\n\n");
65
else fprintf(stderr,".\n\n");
67
if( _AD._semantic_errs ) {
68
fprintf(stderr,"%s: Found %d semantic error", _buf._fp->_name, _AD._semantic_errs);
69
if( _AD._semantic_errs > 1 ) fprintf(stderr,"s.\n\n");
70
else fprintf(stderr,".\n\n");
73
fprintf(stderr,"%s: Found %d warning", _buf._fp->_name, _AD._warnings);
74
if( _AD._warnings > 1 ) fprintf(stderr,"s.\n\n");
75
else fprintf(stderr,".\n\n");
79
fprintf(stderr,"-----------------------------------------------------------------------------\n");
80
_AD._TotalLines += linenum()-1;
89
void ADLParser::parse() {
93
for( next_line(); _curline != nullptr; next_line()) {
97
if (ident == nullptr) {
100
if (!strcmp(ident, "instruct")) instr_parse();
101
else if (!strcmp(ident, "operand")) oper_parse();
102
else if (!strcmp(ident, "opclass")) opclass_parse();
103
else if (!strcmp(ident, "ins_attrib")) ins_attr_parse();
104
else if (!strcmp(ident, "op_attrib")) op_attr_parse();
105
else if (!strcmp(ident, "source")) source_parse();
106
else if (!strcmp(ident, "source_hpp")) source_hpp_parse();
107
else if (!strcmp(ident, "register")) reg_parse();
108
else if (!strcmp(ident, "frame")) frame_parse();
109
else if (!strcmp(ident, "encode")) encode_parse();
110
else if (!strcmp(ident, "pipeline")) pipe_parse();
111
else if (!strcmp(ident, "definitions")) definitions_parse();
112
else if (!strcmp(ident, "peephole")) peep_parse();
113
else if (!strcmp(ident, "#line")) preproc_line();
114
else if (!strcmp(ident, "#define")) preproc_define();
115
else if (!strcmp(ident, "#undef")) preproc_undef();
117
parse_err(SYNERR, "expected one of - instruct, operand, ins_attrib, op_attrib, source, register, pipeline, encode\n Found %s",ident);
121
RegisterForm *regBlock = _AD.get_registers();
122
if (regBlock == nullptr) {
123
parse_err(SEMERR, "Did not declare 'register' definitions");
125
regBlock->addSpillRegClass();
126
regBlock->addDynamicRegClass();
130
if (_preproc_depth != 0) {
131
parse_err(SYNERR, "End of file inside #ifdef");
135
if (_globalNames[AttributeForm::_ins_cost] == nullptr) {
136
parse_err(SEMERR, "Did not declare 'ins_cost' attribute");
138
if (_globalNames[AttributeForm::_op_cost] == nullptr) {
139
parse_err(SEMERR, "Did not declare 'op_cost' attribute");
147
void ADLParser::instr_parse(void) {
151
int match_rules_cnt = 0;
154
if( (ident = get_unique_ident(_globalNames,"instruction")) == nullptr )
156
instr = new InstructForm(ident);
157
instr->_linenum = linenum();
158
_globalNames.Insert(ident, instr);
160
if (_AD._adl_debug > 1)
161
fprintf(stderr,"Parsing Instruction Form %s\n", ident);
165
if (_curchar != '(') {
166
parse_err(SYNERR, "missing '(' in instruct definition\n");
169
else get_oplist(instr->_parameters, instr->_localNames);
172
if ( (_curchar != '%')
173
|| ( next_char(), (_curchar != '{')) ) {
174
parse_err(SYNERR, "missing '%%{' in instruction definition\n");
180
if (ident == nullptr) {
181
parse_err(SYNERR, "keyword identifier expected at %c\n", _curchar);
184
if (!strcmp(ident, "predicate")) instr->_predicate = pred_parse();
185
else if (!strcmp(ident, "match")) {
187
rule = instr->_matrule;
188
if (rule == nullptr) {
190
rule = match_parse(instr->_localNames);
192
instr->_matrule = rule;
194
if( instr->is_ideal_control() ) {
196
rule->_result = "Universe";
199
matchrule_clone_and_swap(rule, instr->_ident, match_rules_cnt);
203
while (rule->_next != nullptr)
206
rule->_next = match_parse(instr->_localNames);
209
if( instr->is_ideal_control() ) {
210
parse_err(SYNERR, "unique match rule expected for %s\n", rule->_name);
213
assert(match_rules_cnt < 100," too many match rule clones");
214
const size_t buf_size = strlen(instr->_ident) + 4;
215
char* buf = (char*) AdlAllocateHeap(buf_size);
216
snprintf_checked(buf, buf_size, "%s_%d", instr->_ident, match_rules_cnt++);
219
matchrule_clone_and_swap(rule, instr->_ident, match_rules_cnt);
223
else if (!strcmp(ident, "encode")) {
224
parse_err(SYNERR, "Instructions specify ins_encode, not encode\n");
226
else if (!strcmp(ident, "ins_encode")) ins_encode_parse(*instr);
228
else if (!strcmp(ident, "postalloc_expand")) postalloc_expand_parse(*instr);
229
else if (!strcmp(ident, "opcode")) instr->_opcode = opcode_parse(instr);
230
else if (!strcmp(ident, "size")) instr->_size = size_parse(instr);
231
else if (!strcmp(ident, "effect")) effect_parse(instr);
232
else if (!strcmp(ident, "flag")) instr->_flag = flag_parse(instr);
233
else if (!strcmp(ident, "expand")) instr->_exprule = expand_parse(instr);
234
else if (!strcmp(ident, "rewrite")) instr->_rewrule = rewrite_parse();
235
else if (!strcmp(ident, "constraint")) {
236
parse_err(SYNERR, "Instructions do not specify a constraint\n");
238
else if (!strcmp(ident, "construct")) {
239
parse_err(SYNERR, "Instructions do not specify a construct\n");
241
else if (!strcmp(ident, "format")) instr->_format = format_parse();
242
else if (!strcmp(ident, "interface")) {
243
parse_err(SYNERR, "Instructions do not specify an interface\n");
245
else if (!strcmp(ident, "ins_pipe")) ins_pipe_parse(*instr);
248
const Form *form = _globalNames[ident];
249
AttributeForm *attr = form ? form->is_attribute() : nullptr;
250
if (attr && (attr->_atype == INS_ATTR)) {
252
Attribute *temp = attr_parse(ident);
253
temp->_next = instr->_attribs;
254
instr->_attribs = temp;
256
parse_err(SYNERR, "expected one of:\n predicate, match, encode, or the name of"
257
" an instruction attribute at %s\n", ident);
261
} while(_curchar != '%');
263
if (_curchar != '}') {
264
parse_err(SYNERR, "missing '%%}' in instruction definition\n");
268
adjust_set_rule(instr);
271
if (instr->expands() || instr->postalloc_expands()) {
272
if (instr->_ins_pipe) {
273
parse_err(WARN, "ins_pipe and expand rule both specified for instruction \"%s\";"
274
" ins_pipe will be unused\n", instr->_ident);
277
if (!instr->_ins_pipe) {
278
parse_err(WARN, "No ins_pipe specified for instruction \"%s\"\n", instr->_ident);
286
rule = instr->_matrule;
287
if (rule != nullptr) {
289
while (rule != nullptr) {
290
ident = (char*)rule->_result;
291
InstructForm *clone = new InstructForm(ident, instr, rule);
292
_globalNames.Insert(ident, clone);
294
if (_AD._adl_debug > 1)
295
fprintf(stderr,"Parsing Instruction Form %s\n", ident);
297
adjust_set_rule(clone);
301
clone->_matrule->_next = nullptr;
309
void ADLParser::matchrule_clone_and_swap(MatchRule* rule, const char* instr_ident, int& match_rules_cnt) {
312
rule->count_commutative_op(count);
315
rule->matchrule_swap_commutative_op(instr_ident, count, match_rules_cnt);
321
void ADLParser::adjust_set_rule(InstructForm *instr) {
322
if (instr->_matrule == nullptr || instr->_matrule->_rChild == nullptr) return;
323
const char *rch = instr->_matrule->_rChild->_opType;
324
const Form *frm = _globalNames[rch];
325
if( (! strcmp(instr->_matrule->_opType,"Set")) &&
326
frm && frm->is_operand() && (! frm->ideal_only()) ) {
328
unsigned position = 0;
329
const char *result = nullptr;
330
const char *name = nullptr;
331
const char *optype = nullptr;
332
MatchNode *right = instr->_matrule->_rChild;
333
if (right->base_operand(position, _globalNames, result, name, optype)) {
335
const char *result2 = nullptr;
336
const char *name2 = nullptr;
337
const char *optype2 = nullptr;
339
if ( ! right->base_operand( position, _globalNames, result2, name2, optype2) ) {
340
if (instr->_predicate != nullptr)
341
parse_err(SYNERR, "ADLC does not support instruction chain rules with predicates");
344
ChainList *lst = (ChainList *)_AD._chainRules[optype];
345
if (lst == nullptr) {
346
lst = new ChainList();
347
_AD._chainRules.Insert(optype, lst);
349
if (!lst->search(instr->_matrule->_lChild->_opType)) {
350
const char *cost = instr->cost();
351
if (cost == nullptr) {
352
cost = ((AttributeForm*)_globalNames[AttributeForm::_ins_cost])->_attrdef;
356
if( frm->is_operand() == nullptr || frm->is_operand()->_predicate == nullptr ) {
357
lst->insert(instr->_matrule->_lChild->_opType,cost,instr->_ident);
361
lst = (ChainList *)_AD._chainRules[result];
362
if (lst == nullptr) {
363
lst = new ChainList();
364
_AD._chainRules.Insert(result, lst);
366
if (!lst->search(instr->_matrule->_lChild->_opType)) {
367
const char *cost = instr->cost();
368
if (cost == nullptr) {
369
cost = ((AttributeForm*)_globalNames[AttributeForm::_ins_cost])->_attrdef;
374
lst->insert(instr->_matrule->_lChild->_opType,cost,instr->_ident);
378
OperandForm *rightOp = _globalNames[right->_opType]->is_operand();
380
const Form *rightRoot = _globalNames[rightOp->_matrule->_opType];
381
if( rightRoot && rightRoot->ideal_only() ) {
382
const char *chain_op = nullptr;
383
if( rightRoot->is_instruction() )
384
chain_op = rightOp->_ident;
387
ChainList *lst = (ChainList *)_AD._chainRules[chain_op];
388
if (lst == nullptr) {
389
lst = new ChainList();
390
_AD._chainRules.Insert(chain_op, lst);
393
const char *cost = instr->cost();
394
if (cost == nullptr) {
395
cost = ((AttributeForm*)_globalNames[AttributeForm::_ins_cost])->_attrdef;
399
lst->insert(instr->_matrule->_lChild->_opType,cost,instr->_ident);
411
void ADLParser::oper_parse(void) {
419
if( (ident = get_unique_ident(_globalNames,"operand")) == nullptr )
421
oper = new OperandForm(ident);
422
oper->_linenum = linenum();
423
_globalNames.Insert(ident, oper);
426
if (_AD._adl_debug > 1) fprintf(stderr,"Parsing Operand Form %s\n", ident);
430
if (_curchar != '(') {
431
parse_err(SYNERR, "missing '(' in operand definition\n");
434
else get_oplist(oper->_parameters, oper->_localNames);
437
if ((_curchar != '%') || (*(_ptr+1) != '{')) {
438
parse_err(SYNERR, "missing '%%{' in operand definition\n");
441
next_char(); next_char();
444
if (ident == nullptr) {
445
parse_err(SYNERR, "keyword identifier expected at %c\n", _curchar);
448
if (!strcmp(ident, "predicate")) oper->_predicate = pred_parse();
449
else if (!strcmp(ident, "match")) {
451
rule = oper->_matrule;
453
while (rule->_next) rule = rule->_next;
455
rule->_next = match_parse(oper->_localNames);
457
rule->_next->_result = oper->_ident;
462
oper->_matrule = match_parse(oper->_localNames);
463
if (oper->_matrule) {
464
oper->_matrule->_result = oper->_ident;
468
else if (!strcmp(ident, "encode")) oper->_interface = interface_parse();
469
else if (!strcmp(ident, "ins_encode")) {
470
parse_err(SYNERR, "Operands specify 'encode', not 'ins_encode'\n");
472
else if (!strcmp(ident, "opcode")) {
473
parse_err(SYNERR, "Operands do not specify an opcode\n");
475
else if (!strcmp(ident, "effect")) {
476
parse_err(SYNERR, "Operands do not specify an effect\n");
478
else if (!strcmp(ident, "expand")) {
479
parse_err(SYNERR, "Operands do not specify an expand\n");
481
else if (!strcmp(ident, "rewrite")) {
482
parse_err(SYNERR, "Operands do not specify a rewrite\n");
484
else if (!strcmp(ident, "constraint"))oper->_constraint= constraint_parse();
485
else if (!strcmp(ident, "construct")) oper->_construct = construct_parse();
486
else if (!strcmp(ident, "format")) oper->_format = format_parse();
487
else if (!strcmp(ident, "interface")) oper->_interface = interface_parse();
489
else if (((attr = _globalNames[ident]->is_attribute()) != nullptr) &&
490
(attr->_atype == OP_ATTR)) oper->_attribs = attr_parse(ident);
492
parse_err(SYNERR, "expected one of - constraint, predicate, match, encode, format, construct, or the name of a defined operand attribute at %s\n", ident);
495
} while(_curchar != '%');
497
if (_curchar != '}') {
498
parse_err(SYNERR, "missing '%%}' in operand definition\n");
507
void ADLParser::opclass_parse(void) {
514
if( (ident = get_unique_ident(_globalNames,"opclass")) == nullptr )
516
opc = new OpClassForm(ident);
517
_globalNames.Insert(ident, opc);
520
if (_AD._adl_debug > 1)
521
fprintf(stderr,"Parsing Operand Class Form %s\n", ident);
525
if (_curchar != '(') {
526
parse_err(SYNERR, "missing '(' in operand definition\n");
532
if (ident == nullptr) {
533
parse_err(SYNERR, "keyword identifier expected at %c\n", _curchar);
537
const Form *form = _globalNames[ident];
538
opForm = form ? form->is_operand() : nullptr;
540
opc->_oplst.addName(ident);
541
opForm->_classes.addName(opc->_ident);
544
parse_err(SYNERR, "expected name of a defined operand at %s\n", ident);
547
} while (_curchar == ',');
549
if (_curchar != ')') {
550
parse_err(SYNERR, "missing ')' or ',' in opclass definition\n");
556
if (_curchar != ';') {
557
parse_err(SYNERR, "missing ';' in opclass definition\n");
566
void ADLParser::ins_attr_parse(void) {
569
AttributeForm *attrib;
573
if( (ident = get_unique_ident(_globalNames,"inst_attrib")) == nullptr )
576
if (_AD._adl_debug > 1) fprintf(stderr,"Parsing Ins_Attribute Form %s\n", ident);
580
if ((aexpr = get_paren_expr("attribute default expression string")) == nullptr) {
581
parse_err(SYNERR, "missing '(' in ins_attrib definition\n");
585
if (_AD._adl_debug > 1) fprintf(stderr,"Attribute Expression: %s\n", aexpr);
588
if (_curchar != ';') {
589
parse_err(SYNERR, "missing ';' in ins_attrib definition\n");
595
attrib = new AttributeForm(ident, INS_ATTR, aexpr);
596
_globalNames.Insert(ident, attrib);
601
void ADLParser::op_attr_parse(void) {
604
AttributeForm *attrib;
608
if( (ident = get_unique_ident(_globalNames,"op_attrib")) == nullptr )
611
if (_AD._adl_debug > 1) fprintf(stderr,"Parsing Op_Attribute Form %s\n", ident);
615
if ((aexpr = get_paren_expr("attribute default expression string")) == nullptr) {
616
parse_err(SYNERR, "missing '(' in op_attrib definition\n");
620
if (_AD._adl_debug > 1) fprintf(stderr,"Attribute Expression: %s\n", aexpr);
623
if (_curchar != ';') {
624
parse_err(SYNERR, "missing ';' in op_attrib definition\n");
630
attrib = new AttributeForm(ident, OP_ATTR, aexpr);
631
_globalNames.Insert(ident, attrib);
636
void ADLParser::definitions_parse(void) {
638
if (_curchar == '%' && *(_ptr+1) == '{') {
639
next_char(); next_char();
641
while (_curchar != '%' && *(_ptr+1) != '}') {
643
char *token = get_ident();
644
if (token == nullptr) {
645
parse_err(SYNERR, "missing identifier inside definitions block.\n");
648
if (strcmp(token,"int_def")==0) { int_def_parse(); }
654
parse_err(SYNERR, "Missing %%{ ... %%} block after definitions keyword.\n");
664
void ADLParser::int_def_parse(void) {
665
char *name = nullptr;
666
char *value = nullptr;
668
char *description = nullptr;
673
if (name == nullptr) {
674
parse_err(SYNERR, "missing definition name after int_def\n");
680
if (_curchar == '(') {
685
if (value == nullptr) {
686
parse_err(SYNERR, "missing value in int_def\n");
689
if( !is_int_token(value, int_value) ) {
690
parse_err(SYNERR, "value in int_def is not recognized as integer\n");
696
if (_curchar == ',') {
699
description = get_expr("int_def description", ")");
700
if (description == nullptr) {
701
parse_err(SYNERR, "invalid or missing description in int_def\n");
707
if (_curchar != ')') {
708
parse_err(SYNERR, "missing ')' in register definition statement\n");
716
if (_curchar != ';') {
717
parse_err(SYNERR, "missing ';' after int_def\n");
723
if (_AD._adl_debug > 1) {
724
fprintf(stderr,"int_def: %s ( %s, %s )\n", name,
725
(value), (description ? description : ""));
729
Expr *expr = new Expr(name, description, int_value, int_value);
730
const Expr *old_expr = _AD.globalDefs().define(name, expr);
731
if (old_expr != nullptr) {
732
parse_err(SYNERR, "Duplicate definition\n");
741
void ADLParser::source_parse(void) {
743
char *rule = nullptr;
746
if ( (rule = find_cpp_block("source block")) == nullptr ) {
747
parse_err(SYNERR, "incorrect or missing block for 'source'.\n");
751
if (_AD._adl_debug > 1) fprintf(stderr,"Source Form: %s\n", rule);
753
source = new SourceForm(rule);
765
void ADLParser::source_hpp_parse(void) {
766
char *rule = nullptr;
769
if ( (rule = find_cpp_block("source_hpp block")) == nullptr ) {
770
parse_err(SYNERR, "incorrect or missing block for 'source_hpp'.\n");
774
if (_AD._adl_debug > 1) fprintf(stderr,"Header Form: %s\n", rule);
776
if (_AD.get_registers() == nullptr) {
778
PreHeaderForm* pre_header = new PreHeaderForm(rule);
779
_AD.addForm(pre_header);
782
HeaderForm* header = new HeaderForm(rule);
788
void ADLParser::reg_parse(void) {
789
RegisterForm *regBlock = _AD.get_registers();
790
if (regBlock == nullptr) {
792
regBlock = new RegisterForm();
793
_AD.addForm(regBlock);
797
if (_curchar == '%' && *(_ptr+1) == '{') {
798
next_char(); next_char();
800
while (_curchar != '%' && *(_ptr+1) != '}') {
801
char *token = get_ident();
802
if (token == nullptr) {
803
parse_err(SYNERR, "missing identifier inside register block.\n");
806
if (strcmp(token,"reg_def")==0) { reg_def_parse(); }
807
else if (strcmp(token,"reg_class")==0) { reg_class_parse(); }
808
else if (strcmp(token, "reg_class_dynamic") == 0) { reg_class_dynamic_parse(); }
809
else if (strcmp(token,"alloc_class")==0) { alloc_class_parse(); }
810
else if (strcmp(token,"#define")==0) { preproc_define(); }
811
else { parse_err(SYNERR, "bad token %s inside register block.\n", token); break; }
816
parse_err(SYNERR, "Missing %c{ ... %c} block after register keyword.\n",'%','%');
822
void ADLParser::encode_parse(void) {
823
EncodeForm *encBlock;
825
_AD.getForm(&encBlock);
826
if ( encBlock == nullptr) {
828
encBlock = new EncodeForm();
829
_AD.addForm(encBlock);
833
if (_curchar == '%' && *(_ptr+1) == '{') {
834
next_char(); next_char();
836
while (_curchar != '%' && *(_ptr+1) != '}') {
837
char *token = get_ident();
838
if (token == nullptr) {
839
parse_err(SYNERR, "missing identifier inside encoding block.\n");
842
if (strcmp(token,"enc_class")==0) { enc_class_parse(); }
847
parse_err(SYNERR, "Missing %c{ ... %c} block after encode keyword.\n",'%','%');
853
void ADLParser::enc_class_parse(void) {
858
ec_name = get_ident();
859
if (ec_name == nullptr) {
860
parse_err(SYNERR, "missing encoding class name after encode.\n");
864
EncClass *encoding = _AD._encode->add_EncClass(ec_name);
865
encoding->_linenum = linenum();
869
if (_curchar == '(') {
871
char *pType = nullptr;
872
char *pName = nullptr;
876
if (_curchar == ')') break;
880
if (pType == nullptr) {
881
parse_err(SYNERR, "parameter type expected at %c\n", _curchar);
888
if (pName == nullptr) {
889
parse_err(SYNERR, "parameter name expected at %c\n", _curchar);
894
encoding->add_parameter( pType, pName );
897
} while(_curchar == ',');
899
if (_curchar != ')') parse_err(SYNERR, "missing ')'\n");
907
if ((_curchar != '%') || (*(_ptr+1) != '{')) {
908
parse_err(SYNERR, "missing '%c{' in enc_class definition\n", '%');
914
enc_class_parse_block(encoding, ec_name);
918
void ADLParser::enc_class_parse_block(EncClass* encoding, char* ec_name) {
921
if (_AD._adlocation_debug) {
922
encoding->add_code(get_line_string());
928
while ( (_curchar != '%') && (*(_ptr+1) != '}') ) {
933
while ((_curchar != '$') && ((_curchar != '%') || (*(_ptr+1) != '}')) ) {
935
if( (_curchar == '/') && ((*(_ptr+1) == '/') || (*(_ptr+1) == '*')) ) {
943
if ( start != _ptr ) {
945
encoding->add_code(start);
951
if (_curchar == '$') {
953
char* rep_var = get_rep_var_ident_dup();
955
encoding->add_rep_var(rep_var);
963
if (_AD._adlocation_debug) {
964
encoding->add_code(end_line_marker());
968
if (_AD._adl_debug > 1) fprintf(stderr,"EncodingClass Form: %s\n", ec_name);
972
void ADLParser::frame_parse(void) {
974
char *desc = nullptr;
978
frame = new FrameForm();
981
if (_curchar == '%' && *(_ptr+1) == '{') {
982
next_char(); next_char();
984
while (_curchar != '%' && *(_ptr+1) != '}') {
985
char *token = get_ident();
986
if (token == nullptr) {
987
parse_err(SYNERR, "missing identifier inside frame block.\n");
990
if (strcmp(token,"sync_stack_slots")==0) {
991
sync_stack_slots_parse(frame);
993
if (strcmp(token,"frame_pointer")==0) {
994
frame_pointer_parse(frame, false);
996
if (strcmp(token,"interpreter_frame_pointer")==0) {
997
interpreter_frame_pointer_parse(frame, false);
999
if (strcmp(token,"inline_cache_reg")==0) {
1000
inline_cache_parse(frame, false);
1002
if (strcmp(token,"compiler_method_oop_reg")==0) {
1003
parse_err(WARN, "Using obsolete Token, compiler_method_oop_reg");
1006
if (strcmp(token,"interpreter_method_oop_reg")==0) {
1007
parse_err(WARN, "Using obsolete Token, interpreter_method_oop_reg");
1010
if (strcmp(token,"interpreter_method_reg")==0) {
1011
parse_err(WARN, "Using obsolete Token, interpreter_method_reg");
1014
if (strcmp(token,"cisc_spilling_operand_name")==0) {
1015
cisc_spilling_operand_name_parse(frame, false);
1017
if (strcmp(token,"stack_alignment")==0) {
1018
stack_alignment_parse(frame);
1020
if (strcmp(token,"return_addr")==0) {
1021
return_addr_parse(frame, false);
1023
if (strcmp(token,"in_preserve_stack_slots")==0) {
1024
parse_err(WARN, "Using obsolete token, in_preserve_stack_slots");
1027
if (strcmp(token,"out_preserve_stack_slots")==0) {
1028
parse_err(WARN, "Using obsolete token, out_preserve_stack_slots");
1031
if (strcmp(token,"varargs_C_out_slots_killed")==0) {
1032
frame->_varargs_C_out_slots_killed = parse_one_arg("varargs C out slots killed");
1034
if (strcmp(token,"calling_convention")==0) {
1035
parse_err(WARN, "Using obsolete token, calling_convention");
1038
if (strcmp(token,"return_value")==0) {
1039
frame->_return_value = return_value_parse();
1041
if (strcmp(token,"c_frame_pointer")==0) {
1042
frame_pointer_parse(frame, true);
1044
if (strcmp(token,"c_return_addr")==0) {
1045
return_addr_parse(frame, true);
1047
if (strcmp(token,"c_calling_convention")==0) {
1048
parse_err(WARN, "Using obsolete token, c_calling_convention");
1051
if (strcmp(token,"c_return_value")==0) {
1052
frame->_c_return_value = return_value_parse();
1059
parse_err(SYNERR, "Missing %c{ ... %c} block after encode keyword.\n",'%','%');
1063
if(frame->_frame_pointer == nullptr) {
1064
parse_err(SYNERR, "missing frame pointer definition in frame section.\n");
1072
if(frame->_alignment == nullptr) {
1073
parse_err(SYNERR, "missing alignment definition in frame section.\n");
1076
if(frame->_return_addr == nullptr) {
1077
parse_err(SYNERR, "missing return address location in frame section.\n");
1080
if(frame->_varargs_C_out_slots_killed == nullptr) {
1081
parse_err(SYNERR, "missing varargs C out slots killed definition in frame section.\n");
1084
if(frame->_return_value == nullptr) {
1085
parse_err(SYNERR, "missing return value definition in frame section.\n");
1089
if(frame->_c_frame_pointer == nullptr) {
1090
frame->_c_frame_pointer = frame->_frame_pointer;
1092
if(frame->_c_return_addr == nullptr) {
1093
frame->_c_return_addr = frame->_return_addr;
1094
frame->_c_return_addr_loc = frame->_return_addr_loc;
1096
if(frame->_c_return_value == nullptr) {
1097
frame->_c_return_value = frame->_return_value;
1101
if (_AD._adl_debug > 1) fprintf(stderr,"Frame Form: %s\n", desc);
1109
void ADLParser::sync_stack_slots_parse(FrameForm *frame) {
1111
frame->_sync_stack_slots = parse_one_arg("sync stack slots entry");
1115
void ADLParser::frame_pointer_parse(FrameForm *frame, bool native) {
1116
char *frame_pointer = parse_one_arg("frame pointer entry");
1118
if (native) { frame->_c_frame_pointer = frame_pointer; }
1119
else { frame->_frame_pointer = frame_pointer; }
1123
void ADLParser::interpreter_frame_pointer_parse(FrameForm *frame, bool native) {
1124
frame->_interpreter_frame_pointer_reg = parse_one_arg("interpreter frame pointer entry");
1128
void ADLParser::inline_cache_parse(FrameForm *frame, bool native) {
1129
frame->_inline_cache_reg = parse_one_arg("inline cache reg entry");
1133
void ADLParser::cisc_spilling_operand_name_parse(FrameForm *frame, bool native) {
1134
frame->_cisc_spilling_operand_name = parse_one_arg("cisc spilling operand name");
1138
void ADLParser::stack_alignment_parse(FrameForm *frame) {
1139
char *alignment = parse_one_arg("stack alignment entry");
1141
frame->_alignment = alignment;
1145
char *ADLParser::parse_one_arg(const char *description) {
1146
char *token = nullptr;
1147
if(_curchar == '(') {
1150
token = get_expr(description, ")");
1151
if (token == nullptr) {
1152
parse_err(SYNERR, "missing value inside %s.\n", description);
1156
if(_curchar != ';') {
1157
parse_err(SYNERR, "missing %c in %s.\n", ';', description);
1163
parse_err(SYNERR, "Missing %c in %s.\n", '(', description);
1172
void ADLParser::return_addr_parse(FrameForm *frame, bool native) {
1173
bool in_register = true;
1174
if(_curchar == '(') {
1177
char *token = get_ident();
1178
if (token == nullptr) {
1179
parse_err(SYNERR, "missing value inside return address entry.\n");
1183
if (strcmp(token, "REG") == 0) {
1186
else if (strcmp(token, "STACK") == 0) {
1187
in_register = false;
1190
parse_err(SYNERR, "invalid value inside return_address entry.\n");
1193
if (native) { frame->_c_return_addr_loc = in_register; }
1194
else { frame->_return_addr_loc = in_register; }
1198
char *token2 = get_expr("return address entry", ")");
1199
if (token2 == nullptr) {
1200
parse_err(SYNERR, "missing value inside return address entry.\n");
1204
if (native) { frame->_c_return_addr = token2; }
1205
else { frame->_return_addr = token2; }
1207
if(_curchar != ';') {
1208
parse_err(SYNERR, "missing %c in return address entry.\n", ';');
1214
parse_err(SYNERR, "Missing %c in return_address entry.\n", '(');
1219
char *ADLParser::return_value_parse() {
1220
char *desc = nullptr;
1223
if ( (desc = find_cpp_block("return value block")) == nullptr ) {
1224
parse_err(SYNERR, "incorrect or missing block for 'return_value'.\n");
1230
void ADLParser::ins_pipe_parse(InstructForm &instr) {
1234
if ( _curchar != '(' ) {
1235
parse_err(SYNERR, "missing \"(\" in ins_pipe definition\n");
1240
ident = get_ident();
1242
if (ident == nullptr) {
1243
parse_err(SYNERR, "keyword identifier expected at %c\n", _curchar);
1248
if ( _curchar != ')' ) {
1249
parse_err(SYNERR, "missing \")\" in ins_pipe definition\n");
1254
if(_curchar != ';') {
1255
parse_err(SYNERR, "missing %c in return value entry.\n", ';');
1261
if (_AD._pipeline && !_AD._pipeline->_classlist.search(ident)) {
1262
parse_err(SYNERR, "\"%s\" is not a valid pipeline class\n", ident);
1267
_AD._pipeline->_classdict[ident]->is_pipeclass()->_instructs.addName(instr._ident);
1270
instr._ins_pipe = ident;
1275
void ADLParser::pipe_parse(void) {
1276
PipelineForm *pipeline;
1279
pipeline = new PipelineForm();
1280
_AD.addForm(pipeline);
1284
if ( (_curchar != '%')
1285
|| ( next_char(), (_curchar != '{')) ) {
1286
parse_err(SYNERR, "missing '%%{' in pipeline definition\n");
1291
ident = get_ident();
1292
if (ident == nullptr) {
1293
parse_err(SYNERR, "keyword identifier expected at %c\n", _curchar);
1296
if (!strcmp(ident, "resources" )) resource_parse(*pipeline);
1297
else if (!strcmp(ident, "pipe_desc" )) pipe_desc_parse(*pipeline);
1298
else if (!strcmp(ident, "pipe_class")) pipe_class_parse(*pipeline);
1299
else if (!strcmp(ident, "define")) {
1301
if ( (_curchar != '%')
1302
|| ( next_char(), (_curchar != '{')) ) {
1303
parse_err(SYNERR, "expected '%%{'\n");
1306
next_char(); skipws();
1308
char *node_class = get_ident();
1309
if (node_class == nullptr) {
1310
parse_err(SYNERR, "expected identifier, found \"%c\"\n", _curchar);
1315
if (_curchar != ',' && _curchar != '=') {
1316
parse_err(SYNERR, "expected `=`, found '%c'\n", _curchar);
1319
next_char(); skipws();
1321
char *pipe_class = get_ident();
1322
if (pipe_class == nullptr) {
1323
parse_err(SYNERR, "expected identifier, found \"%c\"\n", _curchar);
1326
if (_curchar != ';' ) {
1327
parse_err(SYNERR, "expected `;`, found '%c'\n", _curchar);
1333
if ( (_curchar != '%')
1334
|| ( next_char(), (_curchar != '}')) ) {
1335
parse_err(SYNERR, "expected '%%}', found \"%c\"\n", _curchar);
1340
if (_AD._pipeline && !_AD._pipeline->_classlist.search(pipe_class)) {
1341
parse_err(SYNERR, "\"%s\" is not a valid pipeline class\n", pipe_class);
1346
_AD._pipeline->_classdict[pipe_class]->is_pipeclass()->_instructs.addName(node_class);
1348
MachNodeForm *machnode = new MachNodeForm(node_class);
1349
machnode->_machnode_pipe = pipe_class;
1351
_AD.addForm(machnode);
1353
else if (!strcmp(ident, "attributes")) {
1354
bool vsi_seen = false;
1357
if ( (_curchar != '%')
1358
|| ( next_char(), (_curchar != '{')) ) {
1359
parse_err(SYNERR, "expected '%%{'\n");
1362
next_char(); skipws();
1364
while (_curchar != '%') {
1365
ident = get_ident();
1366
if (ident == nullptr)
1369
if (!strcmp(ident, "variable_size_instructions")) {
1371
if (_curchar == ';') {
1372
next_char(); skipws();
1375
pipeline->_variableSizeInstrs = true;
1380
if (!strcmp(ident, "fixed_size_instructions")) {
1382
if (_curchar == ';') {
1383
next_char(); skipws();
1386
pipeline->_variableSizeInstrs = false;
1391
if (!strcmp(ident, "branch_has_delay_slot")) {
1393
if (_curchar == ';') {
1394
next_char(); skipws();
1397
pipeline->_branchHasDelaySlot = true;
1401
if (!strcmp(ident, "max_instructions_per_bundle")) {
1403
if (_curchar != '=') {
1404
parse_err(SYNERR, "expected `=`\n");
1408
next_char(); skipws();
1409
pipeline->_maxInstrsPerBundle = get_int();
1412
if (_curchar == ';') {
1413
next_char(); skipws();
1419
if (!strcmp(ident, "max_bundles_per_cycle")) {
1421
if (_curchar != '=') {
1422
parse_err(SYNERR, "expected `=`\n");
1426
next_char(); skipws();
1427
pipeline->_maxBundlesPerCycle = get_int();
1430
if (_curchar == ';') {
1431
next_char(); skipws();
1437
if (!strcmp(ident, "instruction_unit_size")) {
1439
if (_curchar != '=') {
1440
parse_err(SYNERR, "expected `=`, found '%c'\n", _curchar);
1444
next_char(); skipws();
1445
pipeline->_instrUnitSize = get_int();
1448
if (_curchar == ';') {
1449
next_char(); skipws();
1455
if (!strcmp(ident, "bundle_unit_size")) {
1457
if (_curchar != '=') {
1458
parse_err(SYNERR, "expected `=`, found '%c'\n", _curchar);
1462
next_char(); skipws();
1463
pipeline->_bundleUnitSize = get_int();
1466
if (_curchar == ';') {
1467
next_char(); skipws();
1473
if (!strcmp(ident, "instruction_fetch_unit_size")) {
1475
if (_curchar != '=') {
1476
parse_err(SYNERR, "expected `=`, found '%c'\n", _curchar);
1480
next_char(); skipws();
1481
pipeline->_instrFetchUnitSize = get_int();
1484
if (_curchar == ';') {
1485
next_char(); skipws();
1491
if (!strcmp(ident, "instruction_fetch_units")) {
1493
if (_curchar != '=') {
1494
parse_err(SYNERR, "expected `=`, found '%c'\n", _curchar);
1498
next_char(); skipws();
1499
pipeline->_instrFetchUnits = get_int();
1502
if (_curchar == ';') {
1503
next_char(); skipws();
1509
if (!strcmp(ident, "nops")) {
1511
if (_curchar != '(') {
1512
parse_err(SYNERR, "expected `(`, found '%c'\n", _curchar);
1516
next_char(); skipws();
1518
while (_curchar != ')') {
1519
ident = get_ident();
1520
if (ident == nullptr) {
1521
parse_err(SYNERR, "expected identifier for nop instruction, found '%c'\n", _curchar);
1525
pipeline->_noplist.addName(ident);
1526
pipeline->_nopcnt++;
1529
if (_curchar == ',') {
1530
next_char(); skipws();
1534
next_char(); skipws();
1536
if (_curchar == ';') {
1537
next_char(); skipws();
1543
parse_err(SYNERR, "unknown specifier \"%s\"\n", ident);
1546
if ( (_curchar != '%')
1547
|| ( next_char(), (_curchar != '}')) ) {
1548
parse_err(SYNERR, "expected '%%}', found \"%c\"\n", _curchar);
1550
next_char(); skipws();
1552
if (pipeline->_maxInstrsPerBundle == 0)
1553
parse_err(SYNERR, "\"max_instructions_per_bundle\" unspecified\n");
1554
if (pipeline->_instrUnitSize == 0 && pipeline->_bundleUnitSize == 0)
1555
parse_err(SYNERR, "\"instruction_unit_size\" and \"bundle_unit_size\" unspecified\n");
1556
if (pipeline->_instrFetchUnitSize == 0)
1557
parse_err(SYNERR, "\"instruction_fetch_unit_size\" unspecified\n");
1558
if (pipeline->_instrFetchUnits == 0)
1559
parse_err(SYNERR, "\"instruction_fetch_units\" unspecified\n");
1561
parse_err(SYNERR, "\"variable_size_instruction\" or \"fixed_size_instruction\" unspecified\n");
1564
parse_err(SYNERR, "expected one of \"resources\", \"pipe_desc\", \"pipe_class\", found \"%s\"\n", ident);
1568
if (_curchar == ';')
1570
} while(_curchar != '%');
1573
if (_curchar != '}') {
1574
parse_err(SYNERR, "missing \"%%}\" in pipeline definition\n");
1582
void ADLParser::resource_parse(PipelineForm &pipeline) {
1583
ResourceForm *resource;
1587
pipeline._rescount = 0;
1591
if (_curchar != '(') {
1592
parse_err(SYNERR, "missing \"(\" in resource definition\n");
1598
ident = get_ident();
1600
if (_AD._adl_debug > 1) {
1601
if (ident != nullptr) {
1602
fprintf(stderr, "resource_parse: identifier: %s\n", ident);
1606
if (ident == nullptr) {
1607
parse_err(SYNERR, "keyword identifier expected at \"%c\"\n", _curchar);
1612
if (_curchar != '=') {
1613
mask = (1 << pipeline._rescount++);
1616
next_char(); skipws();
1618
if (expr == nullptr) {
1619
parse_err(SYNERR, "keyword identifier expected at \"%c\"\n", _curchar);
1622
resource = (ResourceForm *) pipeline._resdict[expr];
1623
if (resource == nullptr) {
1624
parse_err(SYNERR, "resource \"%s\" is not defined\n", expr);
1627
mask = resource->mask();
1630
while (_curchar == '|') {
1631
next_char(); skipws();
1634
if (expr == nullptr) {
1635
parse_err(SYNERR, "keyword identifier expected at \"%c\"\n", _curchar);
1639
resource = (ResourceForm *) pipeline._resdict[expr];
1640
if (resource == nullptr) {
1641
parse_err(SYNERR, "resource \"%s\" is not defined\n", expr);
1645
mask |= resource->mask();
1650
resource = new ResourceForm(mask);
1652
pipeline._resdict.Insert(ident, resource);
1653
pipeline._reslist.addName(ident);
1654
} while (_curchar == ',');
1656
if (_curchar != ')') {
1657
parse_err(SYNERR, "\")\" expected at \"%c\"\n", _curchar);
1662
if (_curchar == ';')
1667
void ADLParser::pipe_desc_parse(PipelineForm &pipeline) {
1672
if (_curchar != '(') {
1673
parse_err(SYNERR, "missing \"(\" in pipe_desc definition\n");
1679
ident = get_ident();
1680
if (ident == nullptr) {
1681
parse_err(SYNERR, "keyword identifier expected at \"%c\"\n", _curchar);
1686
pipeline._stages.addName(ident);
1687
pipeline._stagecnt++;
1690
} while (_curchar == ',');
1692
if (_curchar != ')') {
1693
parse_err(SYNERR, "\")\" expected at \"%c\"\n", _curchar);
1698
if (_curchar == ';')
1703
void ADLParser::pipe_class_parse(PipelineForm &pipeline) {
1704
PipeClassForm *pipe_class;
1707
char * read_or_write;
1714
ident = get_ident();
1716
if (ident == nullptr) {
1717
parse_err(SYNERR, "keyword identifier expected at \"%c\"\n", _curchar);
1722
pipe_class = new PipeClassForm(ident, ++pipeline._classcnt);
1723
pipeline._classdict.Insert(ident, pipe_class);
1724
pipeline._classlist.addName(ident);
1728
if (_curchar != '(') {
1729
parse_err(SYNERR, "missing \"(\" in pipe_class definition\n");
1732
else get_oplist(pipe_class->_parameters, pipe_class->_localNames);
1735
if ( (_curchar != '%')
1736
|| ( next_char(), (_curchar != '{')) ) {
1737
parse_err(SYNERR, "missing \"%%{\" in pipe_class definition\n");
1743
ident = get_ident();
1744
if (ident == nullptr) {
1745
parse_err(SYNERR, "keyword identifier expected at \"%c\"\n", _curchar);
1750
if (!strcmp(ident, "fixed_latency")) {
1752
if (_curchar != '(') {
1753
parse_err(SYNERR, "missing \"(\" in latency definition\n");
1756
next_char(); skipws();
1757
if( !isdigit(_curchar) ) {
1758
parse_err(SYNERR, "number expected for \"%c\" in latency definition\n", _curchar);
1761
int fixed_latency = get_int();
1763
if (_curchar != ')') {
1764
parse_err(SYNERR, "missing \")\" in latency definition\n");
1767
next_char(); skipws();
1768
if (_curchar != ';') {
1769
parse_err(SYNERR, "missing \";\" in latency definition\n");
1773
pipe_class->setFixedLatency(fixed_latency);
1774
next_char(); skipws();
1778
if (!strcmp(ident, "zero_instructions") ||
1779
!strcmp(ident, "no_instructions")) {
1781
if (_curchar != ';') {
1782
parse_err(SYNERR, "missing \";\" in latency definition\n");
1786
pipe_class->setInstructionCount(0);
1787
next_char(); skipws();
1791
if (!strcmp(ident, "one_instruction_with_delay_slot") ||
1792
!strcmp(ident, "single_instruction_with_delay_slot")) {
1794
if (_curchar != ';') {
1795
parse_err(SYNERR, "missing \";\" in latency definition\n");
1799
pipe_class->setInstructionCount(1);
1800
pipe_class->setBranchDelay(true);
1801
next_char(); skipws();
1805
if (!strcmp(ident, "one_instruction") ||
1806
!strcmp(ident, "single_instruction")) {
1808
if (_curchar != ';') {
1809
parse_err(SYNERR, "missing \";\" in latency definition\n");
1813
pipe_class->setInstructionCount(1);
1814
next_char(); skipws();
1818
if (!strcmp(ident, "instructions_in_first_bundle") ||
1819
!strcmp(ident, "instruction_count")) {
1822
int number_of_instructions = 1;
1824
if (_curchar != '(') {
1825
parse_err(SYNERR, "\"(\" expected at \"%c\"\n", _curchar);
1829
next_char(); skipws();
1830
number_of_instructions = get_int();
1833
if (_curchar != ')') {
1834
parse_err(SYNERR, "\")\" expected at \"%c\"\n", _curchar);
1838
next_char(); skipws();
1839
if (_curchar != ';') {
1840
parse_err(SYNERR, "missing \";\" in latency definition\n");
1844
pipe_class->setInstructionCount(number_of_instructions);
1845
next_char(); skipws();
1849
if (!strcmp(ident, "multiple_bundles")) {
1851
if (_curchar != ';') {
1852
parse_err(SYNERR, "missing \";\" after multiple bundles\n");
1856
pipe_class->setMultipleBundles(true);
1857
next_char(); skipws();
1861
if (!strcmp(ident, "has_delay_slot")) {
1863
if (_curchar != ';') {
1864
parse_err(SYNERR, "missing \";\" after \"has_delay_slot\"\n");
1868
pipe_class->setBranchDelay(true);
1869
next_char(); skipws();
1873
if (!strcmp(ident, "force_serialization")) {
1875
if (_curchar != ';') {
1876
parse_err(SYNERR, "missing \";\" after \"force_serialization\"\n");
1880
pipe_class->setForceSerialization(true);
1881
next_char(); skipws();
1885
if (!strcmp(ident, "may_have_no_code")) {
1887
if (_curchar != ';') {
1888
parse_err(SYNERR, "missing \";\" after \"may_have_no_code\"\n");
1892
pipe_class->setMayHaveNoCode(true);
1893
next_char(); skipws();
1897
const Form *parm = pipe_class->_localNames[ident];
1898
if (parm != nullptr) {
1899
oper = parm->is_operand();
1900
if (oper == nullptr && !parm->is_opclass()) {
1901
parse_err(SYNERR, "operand name expected at %s\n", ident);
1905
if (_curchar != ':') {
1906
parse_err(SYNERR, "\":\" expected at \"%c\"\n", _curchar);
1909
next_char(); skipws();
1910
stage = get_ident();
1911
if (stage == nullptr) {
1912
parse_err(SYNERR, "pipeline stage identifier expected at \"%c\"\n", _curchar);
1917
if (_curchar != '(') {
1918
parse_err(SYNERR, "\"(\" expected at \"%c\"\n", _curchar);
1923
read_or_write = get_ident();
1924
if (read_or_write == nullptr) {
1925
parse_err(SYNERR, "\"read\" or \"write\" expected at \"%c\"\n", _curchar);
1929
is_read = strcmp(read_or_write, "read") == 0;
1930
is_write = strcmp(read_or_write, "write") == 0;
1931
if (!is_read && !is_write) {
1932
parse_err(SYNERR, "\"read\" or \"write\" expected at \"%c\"\n", _curchar);
1937
if (_curchar != ')') {
1938
parse_err(SYNERR, "\")\" expected at \"%c\"\n", _curchar);
1942
next_char(); skipws();
1943
int more_instrs = 0;
1944
if (_curchar == '+') {
1945
next_char(); skipws();
1946
if (_curchar < '0' || _curchar > '9') {
1947
parse_err(SYNERR, "<number> expected at \"%c\"\n", _curchar);
1950
while (_curchar >= '0' && _curchar <= '9') {
1952
more_instrs += _curchar - '0';
1958
PipeClassOperandForm *pipe_operand = new PipeClassOperandForm(stage, is_write, more_instrs);
1959
pipe_class->_localUsage.Insert(ident, pipe_operand);
1961
if (_curchar == '%')
1964
if (_curchar != ';') {
1965
parse_err(SYNERR, "\";\" expected at \"%c\"\n", _curchar);
1968
next_char(); skipws();
1973
const Form *res = pipeline._resdict[ident];
1974
if (res != nullptr) {
1976
if (_curchar != ':') {
1977
parse_err(SYNERR, "\":\" expected at \"%c\"\n", _curchar);
1980
next_char(); skipws();
1981
stage = get_ident();
1982
if (stage == nullptr) {
1983
parse_err(SYNERR, "pipeline stage identifier expected at \"%c\"\n", _curchar);
1988
if (_curchar == '(') {
1990
cyclecnt = get_int();
1993
if (_curchar != ')') {
1994
parse_err(SYNERR, "\")\" expected at \"%c\"\n", _curchar);
1998
next_char(); skipws();
2001
PipeClassResourceForm *resource = new PipeClassResourceForm(ident, stage, cyclecnt);
2002
int stagenum = pipeline._stages.index(stage);
2003
if (pipeline._maxcycleused < (stagenum+cyclecnt))
2004
pipeline._maxcycleused = (stagenum+cyclecnt);
2005
pipe_class->_resUsage.addForm(resource);
2007
if (_curchar == '%')
2010
if (_curchar != ';') {
2011
parse_err(SYNERR, "\";\" expected at \"%c\"\n", _curchar);
2014
next_char(); skipws();
2018
parse_err(SYNERR, "resource expected at \"%s\"\n", ident);
2020
} while(_curchar != '%');
2023
if (_curchar != '}') {
2024
parse_err(SYNERR, "missing \"%%}\" in pipe_class definition\n");
2032
void ADLParser::peep_parse(void) {
2034
char *desc = nullptr;
2038
peep = new Peephole();
2041
if (_curchar == '%' && *(_ptr+1) == '{') {
2042
next_char(); next_char();
2044
while (_curchar != '%' && *(_ptr+1) != '}') {
2045
char *token = get_ident();
2046
if (token == nullptr) {
2047
parse_err(SYNERR, "missing identifier inside peephole rule.\n");
2051
if (strcmp(token,"peeppredicate")==0) {
2052
peep_predicate_parse(*peep); }
2053
else if (strcmp(token,"peepmatch")==0) {
2054
peep_match_parse(*peep); }
2055
else if (strcmp(token, "peepprocedure")==0) {
2056
peep_procedure_parse(*peep); }
2057
else if (strcmp(token,"peepconstraint")==0) {
2058
peep_constraint_parse(*peep); }
2059
else if (strcmp(token,"peepreplace")==0) {
2060
peep_replace_parse(*peep); }
2063
"expected peeppreddicate, peepmatch, peepprocedure, peepconstraint, peepreplace, received %s.\n",
2070
parse_err(SYNERR, "Missing %%{ ... %%} block after peephole keyword.\n");
2079
Constraint *ADLParser::constraint_parse(void) {
2085
if (_curchar != '(') {
2086
parse_err(SYNERR, "missing constraint expression, (...)\n");
2094
if (func == nullptr) {
2095
parse_err(SYNERR, "missing function in constraint expression.\n");
2098
if (strcmp(func,"ALLOC_IN_RC")==0
2099
|| strcmp(func,"IS_R_CLASS")==0) {
2102
if (_curchar != '(') {
2103
parse_err(SYNERR, "missing '(' for constraint function's argument.\n");
2111
if (arg == nullptr) {
2112
parse_err(SYNERR, "missing argument for constraint function %s\n",func);
2117
if (_curchar != ')') {
2118
parse_err(SYNERR, "missing ')' after constraint function argument %s\n",arg);
2123
parse_err(SYNERR, "Invalid constraint function %s\n",func);
2129
if (_curchar != ')') {
2130
parse_err(SYNERR, "Missing ')' for constraint function %s\n",func);
2135
if (_curchar != ';') {
2136
parse_err(SYNERR, "Missing ';' after constraint.\n");
2142
Constraint *constraint = new Constraint(func,arg);
2147
ConstructRule *ADLParser::construct_parse(void) {
2153
void ADLParser::reg_def_parse(void) {
2158
rname = get_ident();
2159
if (rname == nullptr) {
2160
parse_err(SYNERR, "missing register name after reg_def\n");
2167
char *callconv = nullptr;
2168
char *c_conv = nullptr;
2169
char *idealtype = nullptr;
2170
char *encoding = nullptr;
2171
char *concrete = nullptr;
2172
if (_curchar == '(') {
2174
callconv = get_ident();
2176
if (callconv == nullptr) {
2177
parse_err(SYNERR, "missing register calling convention value\n");
2180
if(strcmp(callconv, "SOC") && strcmp(callconv,"SOE") &&
2181
strcmp(callconv, "NS") && strcmp(callconv, "AS")) {
2182
parse_err(SYNERR, "invalid value for register calling convention\n");
2185
if (_curchar != ',') {
2186
parse_err(SYNERR, "missing comma in register definition statement\n");
2192
c_conv = get_ident();
2193
if (c_conv == nullptr) {
2194
parse_err(SYNERR, "missing register native calling convention value\n");
2197
if(strcmp(c_conv, "SOC") && strcmp(c_conv,"SOE") &&
2198
strcmp(c_conv, "NS") && strcmp(c_conv, "AS")) {
2199
parse_err(SYNERR, "invalid value for register calling convention\n");
2202
if (_curchar != ',') {
2203
parse_err(SYNERR, "missing comma in register definition statement\n");
2210
idealtype = get_ident();
2211
if (idealtype == nullptr) {
2212
parse_err(SYNERR, "missing register save type value\n");
2216
if (_curchar != ',') {
2217
parse_err(SYNERR, "missing comma in register definition statement\n");
2224
encoding = get_expr("encoding", ",");
2225
if (encoding == nullptr) {
2226
parse_err(SYNERR, "missing register encoding value\n");
2230
if (_curchar != ',') {
2231
parse_err(SYNERR, "missing comma in register definition statement\n");
2238
concrete = get_expr("concrete", ")");
2239
if (concrete == nullptr) {
2240
parse_err(SYNERR, "missing vm register name value\n");
2244
if (_curchar != ')') {
2245
parse_err(SYNERR, "missing ')' in register definition statement\n");
2253
if (_curchar != ';') {
2254
parse_err(SYNERR, "missing ';' after reg_def\n");
2260
if (_AD._adl_debug > 1) {
2261
fprintf(stderr,"Register Definition: %s ( %s, %s %s )\n", rname,
2262
(callconv ? callconv : ""), (c_conv ? c_conv : ""), concrete);
2266
_AD._register->addRegDef(rname, callconv, c_conv, idealtype, encoding, concrete);
2271
void ADLParser::reg_class_parse(void) {
2276
cname = get_ident();
2277
if (cname == nullptr) {
2278
parse_err(SYNERR, "missing register class name after 'reg_class'\n");
2282
if (_AD._adl_debug >1) fprintf(stderr,"Register Class: %s\n", cname);
2285
if (_curchar == '(') {
2288
RegClass* reg_class = _AD._register->addRegClass<RegClass>(cname);
2292
while (_curchar != ')') {
2293
char *rname = get_ident();
2294
if (rname==nullptr) {
2295
parse_err(SYNERR, "missing identifier inside reg_class list.\n");
2298
RegDef *regDef = _AD._register->getRegDef(rname);
2300
parse_err(SEMERR, "unknown identifier %s inside reg_class list.\n", rname);
2302
reg_class->addReg(regDef);
2307
if (_curchar == ',') {
2313
} else if (_curchar == '%') {
2316
CodeSnippetRegClass* reg_class = _AD._register->addRegClass<CodeSnippetRegClass>(cname);
2317
char *code = find_cpp_block("reg class");
2318
if (code == nullptr) {
2319
parse_err(SYNERR, "missing code declaration for reg class.\n");
2322
reg_class->set_code_snippet(code);
2328
if (_curchar != ';') {
2329
parse_err(SYNERR, "missing ';' at end of reg_class definition.\n");
2340
void ADLParser::reg_class_dynamic_parse(void) {
2345
cname = get_ident();
2346
if (cname == nullptr) {
2347
parse_err(SYNERR, "missing dynamic register class name after 'reg_class_dynamic'\n");
2351
if (_AD._adl_debug > 1) {
2352
fprintf(stdout, "Dynamic Register Class: %s\n", cname);
2356
if (_curchar != '(') {
2357
parse_err(SYNERR, "missing '(' at the beginning of reg_class_dynamic definition\n");
2365
ConditionalRegClass* reg_class = _AD._register->addRegClass<ConditionalRegClass>(cname);
2367
for (i = 0; i < 2; i++) {
2368
char* name = get_ident();
2369
if (name == nullptr) {
2370
parse_err(SYNERR, "missing class identifier inside reg_class_dynamic list.\n");
2373
RegClass* rc = _AD._register->getRegClass(name);
2374
if (rc == nullptr) {
2375
parse_err(SEMERR, "unknown identifier %s inside reg_class_dynamic list.\n", name);
2377
reg_class->set_rclass_at_index(i, rc);
2381
if (_curchar == ',') {
2385
parse_err(SYNERR, "missing separator ',' inside reg_class_dynamic list.\n");
2391
if (_curchar == '%') {
2392
char* code = find_cpp_block("reg class dynamic");
2393
if (code == nullptr) {
2394
parse_err(SYNERR, "missing code declaration for reg_class_dynamic.\n");
2397
reg_class->set_condition_code(code);
2399
parse_err(SYNERR, "missing %% at the beginning of code block in reg_class_dynamic definition\n");
2404
if (_curchar != ')') {
2405
parse_err(SYNERR, "missing ')' at the end of reg_class_dynamic definition\n");
2411
if (_curchar != ';') {
2412
parse_err(SYNERR, "missing ';' at the end of reg_class_dynamic definition.\n");
2421
void ADLParser::alloc_class_parse(void) {
2427
if (name == nullptr) {
2428
parse_err(SYNERR, "missing allocation class name after 'reg_class'\n");
2432
if (_AD._adl_debug >1) fprintf(stderr,"Allocation Class: %s\n", name);
2434
AllocClass *alloc_class = _AD._register->addAllocClass(name);
2438
if (_curchar == '(') {
2441
while (_curchar != ')') {
2442
char *rname = get_ident();
2443
if (rname==nullptr) {
2444
parse_err(SYNERR, "missing identifier inside reg_class list.\n");
2448
RegDef *regDef = _AD._register->getRegDef(rname);
2450
alloc_class->addReg(regDef);
2454
parse_err(SYNERR, "name %s should be a previously defined reg_def.\n", rname);
2460
if (_curchar == ',') {
2470
if (_curchar != ';') {
2471
parse_err(SYNERR, "missing ';' at end of reg_class definition.\n");
2480
InstructForm *ADLParser::peep_match_child_parse(PeepMatch &match, int parent, int &position, int input){
2481
char *token = nullptr;
2484
InstructForm *inst_seen = nullptr;
2488
while ( lparen >= rparen ) {
2491
if (_curchar == '(') {
2494
( void ) peep_match_child_parse(match, parent, position, rparen);
2497
else if (_curchar == ')') {
2499
if( rparen == lparen ) {
2502
assert( rparen == lparen + 1, "Should only see one extra ')'");
2505
match.add_instruction( parent, position, NameList::_signal, input );
2514
else if ((token = get_ident_dup()) != nullptr) {
2515
const Form *form = _AD._globalNames[token];
2517
InstructForm *inst = form->is_instruction();
2519
if( inst_seen == nullptr ) {
2523
match.add_instruction( parent, position, token, input );
2527
parse_err(SYNERR, "instruction name expected at identifier %s.\n",
2533
parse_err(SYNERR, "missing identifier in peepmatch rule.\n");
2538
parse_err(SYNERR, "missing identifier in peepmatch rule.\n");
2544
assert( false, "ShouldNotReachHere();");
2553
void ADLParser::peep_predicate_parse(Peephole& peep) {
2556
char* rule = nullptr;
2557
if ( (rule = get_paren_expr("pred expression", true)) == nullptr ) {
2558
parse_err(SYNERR, "incorrect or missing expression for 'peeppredicate'\n");
2561
if (_curchar != ';') {
2562
parse_err(SYNERR, "missing ';' in peeppredicate definition\n");
2569
PeepPredicate* predicate = new PeepPredicate(rule);
2570
peep.add_predicate(predicate);
2578
void ADLParser::peep_match_parse(Peephole &peep) {
2583
if (_curchar != '(') {
2584
parse_err(SYNERR, "missing '(' at start of peepmatch rule.\n");
2590
PeepMatch *match = new PeepMatch(_ptr);
2594
InstructForm *root= peep_match_child_parse( *match, parent, position, input);
2595
if( root == nullptr ) {
2596
parse_err(SYNERR, "missing instruction-name at start of peepmatch.\n");
2600
if( _curchar != ')' ) {
2601
parse_err(SYNERR, "missing ')' at end of peepmatch.\n");
2608
if( _curchar != ';' ) {
2609
parse_err(SYNERR, "missing ';' at end of peepmatch.\n");
2615
peep.add_match(match);
2616
root->append_peephole(&peep);
2624
void ADLParser::peep_procedure_parse(Peephole& peep) {
2628
if (_curchar != '(') {
2629
parse_err(SYNERR, "missing '(' at start of peepprocedure rule.\n");
2635
char* name = nullptr;
2636
if ( (name = get_ident_dup()) == nullptr ) {
2637
parse_err(SYNERR, "incorrect or missing expression for 'peepprocedure'\n");
2642
if (_curchar != ')') {
2643
parse_err(SYNERR, "peepprocedure should contain a single identifier only\n");
2647
if (_curchar != ';') {
2648
parse_err(SYNERR, "missing ';' in peepprocedure definition\n");
2655
PeepProcedure* procedure = new PeepProcedure(name);
2656
peep.add_procedure(procedure);
2671
void ADLParser::peep_constraint_parse(Peephole &peep) {
2676
if (_curchar != '(') {
2677
parse_err(SYNERR, "missing '(' at start of peepconstraint rule.\n");
2686
while( _curchar != ')' ) {
2689
int left_inst = get_int();
2692
if( _curchar != '.' ) {
2693
parse_err(SYNERR, "missing '.' in peepconstraint after instruction number.\n");
2697
char *left_op = get_ident_dup();
2701
char *relation = get_relation_dup();
2706
if( isdigit(_curchar) ) {
2707
right_inst = get_int();
2710
if( _curchar != '.' ) {
2711
parse_err(SYNERR, "missing '.' in peepconstraint after instruction number.\n");
2719
char *right_op = get_ident_dup();
2722
PeepConstraint *constraint = new PeepConstraint( left_inst, left_op,
2724
right_inst, right_op );
2726
peep.append_constraint( constraint );
2730
if( _curchar == ',' ) {
2734
else if( _curchar != ')' ) {
2735
parse_err(SYNERR, "expected ',' or ')' after peephole constraint.\n");
2743
if (_curchar != ';') {
2744
parse_err(SYNERR, "missing ';' at end of peepconstraint.\n");
2759
void ADLParser::peep_replace_parse(Peephole &peep) {
2763
char *str = nullptr;
2764
char *token = nullptr;
2768
if (_curchar != '(') {
2769
parse_err(SYNERR, "missing '(' at start of peepreplace rule.\n");
2778
char *inst = get_ident_dup();
2779
const Form *form = _AD._globalNames[inst];
2780
if( form == nullptr || form->is_instruction() == nullptr ) {
2781
parse_err(SYNERR, "Instruction name expected at start of peepreplace.\n");
2786
PeepReplace *replace = new PeepReplace(str);
2787
replace->add_instruction( inst );
2791
if (_curchar != '(') {
2792
parse_err(SYNERR, "missing '(' at peepreplace root's operand-list.\n");
2802
while( _curchar != ')' ) {
2805
int inst_num = get_int();
2808
if( _curchar != '.' ) {
2809
parse_err(SYNERR, "missing '.' in peepreplace after instruction number.\n");
2813
char *inst_op = get_ident_dup();
2814
if( inst_op == nullptr ) {
2815
parse_err(SYNERR, "missing operand identifier in peepreplace.\n");
2820
replace->add_operand( inst_num, inst_op );
2826
assert( _curchar == ')', "While loop should have advanced to ')'.");
2831
if( _curchar != ')' ) {
2832
parse_err(SYNERR, "missing ')' at end of peepmatch.\n");
2833
parse_err(SYNERR, "Support one replacement instruction.\n");
2840
if( _curchar != ';' ) {
2841
parse_err(SYNERR, "missing ';' at end of peepreplace.\n");
2847
peep.add_replace( replace );
2851
Predicate *ADLParser::pred_parse(void) {
2852
Predicate *predicate;
2853
char *rule = nullptr;
2856
int line = linenum();
2857
if ( (rule = get_paren_expr("pred expression", true)) == nullptr ) {
2858
parse_err(SYNERR, "incorrect or missing expression for 'predicate'\n");
2862
if (_AD._adl_debug > 1) fprintf(stderr,"Predicate: %s\n", rule);
2863
if (_curchar != ';') {
2864
parse_err(SYNERR, "missing ';' in predicate definition\n");
2869
predicate = new Predicate(rule);
2877
void ADLParser::ins_encode_parse_block(InstructForm& inst) {
2880
const char* prefix = "__ins_encode_";
2881
const size_t ec_name_size = strlen(inst._ident) + strlen(prefix) + 1;
2882
char* ec_name = (char*) AdlAllocateHeap(ec_name_size);
2883
snprintf_checked(ec_name, ec_name_size, "%s%s", prefix, inst._ident);
2885
assert(_AD._encode->encClass(ec_name) == nullptr, "shouldn't already exist");
2886
EncClass* encoding = _AD._encode->add_EncClass(ec_name);
2887
encoding->_linenum = linenum();
2891
const char* param = nullptr;
2892
inst._parameters.reset();
2893
while ((param = inst._parameters.iter()) != nullptr) {
2894
OpClassForm* opForm = inst._localNames[param]->is_opclass();
2895
assert(opForm != nullptr, "sanity");
2896
encoding->add_parameter(opForm->_ident, param);
2900
ins_encode_parse_block_impl(inst, encoding, ec_name);
2904
InsEncode* encrule = new InsEncode();
2905
NameAndList* params = encrule->add_encode(ec_name);
2906
inst._parameters.reset();
2907
while ((param = inst._parameters.iter()) != nullptr) {
2908
params->add_entry(param);
2913
if (inst._insencode != nullptr) {
2914
parse_err(SYNERR, "Multiple ins_encode sections defined\n");
2919
inst._insencode = encrule;
2923
void ADLParser::ins_encode_parse_block_impl(InstructForm& inst, EncClass* encoding, char* ec_name) {
2924
skipws_no_preproc();
2926
if (_AD._adlocation_debug) {
2927
encoding->add_code(get_line_string());
2933
while ((_curchar != '%') && (*(_ptr+1) != '}')) {
2938
while ((_curchar != '$') && ((_curchar != '%') || (*(_ptr+1) != '}')) ) {
2940
if( (_curchar == '/') && ((*(_ptr+1) == '/') || (*(_ptr+1) == '*')) ) {
2941
skipws_no_preproc();
2944
next_char_or_line();
2948
if (start != _ptr) {
2950
encoding->add_code(start);
2956
if (_curchar == '$') {
2958
char* rep_var = get_rep_var_ident_dup();
2961
encoding->add_rep_var(rep_var);
2966
if (strcmp(rep_var, "constanttablebase") == 0) {
2968
inst.set_needs_constant_base(true);
2969
if (strncmp("MachCall", inst.mach_base_class(_globalNames), strlen("MachCall")) != 0 ) {
2970
inst.set_is_mach_constant(true);
2973
if (_curchar == '(') {
2974
parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument "
2975
"(only constantaddress and constantoffset)", ec_name);
2979
else if ((strcmp(rep_var, "constantaddress") == 0) ||
2980
(strcmp(rep_var, "constantoffset") == 0)) {
2982
inst.set_is_mach_constant(true);
2985
if (_curchar == '(') constant_parse(inst);
2994
if (_AD._adlocation_debug) {
2995
encoding->add_code(end_line_marker());
2999
if (_AD._adl_debug > 1) fprintf(stderr, "EncodingClass Form: %s\n", ec_name);
3023
void ADLParser::ins_encode_parse(InstructForm& inst) {
3027
if (_curchar != '(') {
3029
if ((_curchar == '%') && (*(_ptr+1) == '{')) {
3034
ins_encode_parse_block(inst);
3038
parse_err(SYNERR, "missing '%%{' or '(' in ins_encode definition\n");
3044
InsEncode *encrule = new InsEncode();
3045
encrule->_linenum = linenum();
3046
char *ec_name = nullptr;
3048
while (_curchar != ')') {
3049
ec_name = get_ident();
3050
if (ec_name == nullptr) {
3051
parse_err(SYNERR, "Invalid encode class name after 'ins_encode('.\n");
3055
EncClass *encode_class = _AD._encode->encClass(ec_name);
3056
if (encode_class == nullptr) {
3062
NameAndList *params = encrule->add_encode(ec_name);
3066
if ( _curchar == '(' ) {
3070
while (_curchar != ')') {
3071
char *param = get_ident_or_literal_constant("encoding operand");
3072
if ( param != nullptr ) {
3075
if (strcmp(param, "constanttablebase") == 0) {
3077
inst.set_needs_constant_base(true);
3078
if (strncmp("MachCall", inst.mach_base_class(_globalNames), strlen("MachCall")) != 0 ) {
3079
inst.set_is_mach_constant(true);
3082
if (_curchar == '(') {
3083
parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument "
3084
"(only constantaddress and constantoffset)", ec_name);
3094
if ( (inst._localNames[param] == nullptr) &&
3095
!ADLParser::is_literal_constant(param) &&
3096
(Opcode::as_opcode_type(param) == Opcode::NOT_AN_OPCODE) &&
3097
((_AD._register == nullptr ) || (_AD._register->getRegDef(param) == nullptr)) ) {
3098
parse_err(SYNERR, "Using non-locally defined parameter %s for encoding %s.\n", param, ec_name);
3102
params->add_entry(param);
3105
if (_curchar == ',' ) {
3110
else if (_curchar == ')') {
3115
parse_err(SYNERR, "expected ',' or ')' after parameter %s.\n",
3123
if (_curchar == ',') {
3124
parse_err(SYNERR, "Expected encode parameter before ',' in encoding %s.\n", ec_name);
3127
if (_curchar != ')') {
3128
parse_err(SYNERR, "Expected ')' after encode parameters.\n");
3138
if ( _curchar == ',' ) {
3143
else if ( _curchar != ')' ) {
3145
parse_err(SYNERR, "Expected ')' after encoding %s.\n", ec_name);
3156
if (_curchar != ')') {
3157
parse_err(SYNERR, "Missing ')' at end of ins_encode description.\n");
3163
if ( _curchar != ';' ) {
3164
parse_err(SYNERR, "Missing ';' at end of ins_encode.\n");
3172
if (inst._insencode != nullptr) {
3173
parse_err(SYNERR, "Multiple ins_encode sections defined\n");
3178
if (_AD._adl_debug > 1) fprintf(stderr,"Instruction Encode: %s\n", ec_name);
3181
inst._insencode = encrule;
3192
void ADLParser::postalloc_expand_parse(InstructForm& inst) {
3193
inst._is_postalloc_expand = true;
3197
if (_curchar != '(') {
3199
if ((_curchar == '%') && (*(_ptr+1) == '{')) {
3204
ins_encode_parse_block(inst);
3208
parse_err(SYNERR, "missing '(' in postalloc_expand definition\n");
3214
InsEncode *encrule = new InsEncode();
3215
encrule->_linenum = linenum();
3216
char *ec_name = nullptr;
3218
if (_curchar != ')') {
3219
ec_name = get_ident();
3220
if (ec_name == nullptr) {
3221
parse_err(SYNERR, "Invalid postalloc_expand class name after 'postalloc_expand('.\n");
3225
EncClass *encode_class = _AD._encode->encClass(ec_name);
3228
NameAndList *params = encrule->add_encode(ec_name);
3232
if (_curchar == '(') {
3236
while (_curchar != ')') {
3237
char *param = get_ident_or_literal_constant("encoding operand");
3238
if (param != nullptr) {
3244
if (strcmp(param, "constanttablebase") == 0) {
3246
inst.set_needs_constant_base(true);
3247
if (strncmp("MachCall", inst.mach_base_class(_globalNames), strlen("MachCall")) != 0 ) {
3248
inst.set_is_mach_constant(true);
3251
if (_curchar == '(') {
3252
parse_err(SYNERR, "constanttablebase in instruct %s cannot have an argument "
3253
"(only constantaddress and constantoffset)", ec_name);
3257
else if ((strcmp(param, "constantaddress") == 0) ||
3258
(strcmp(param, "constantoffset") == 0)) {
3260
inst.set_is_mach_constant(true);
3263
if (_curchar == '(') constant_parse(inst);
3271
else if ((inst._localNames[param] == nullptr) &&
3272
!ADLParser::is_literal_constant(param) &&
3273
(Opcode::as_opcode_type(param) == Opcode::NOT_AN_OPCODE) &&
3274
((_AD._register == nullptr) || (_AD._register->getRegDef(param) == nullptr))) {
3275
parse_err(SYNERR, "Using non-locally defined parameter %s for encoding %s.\n", param, ec_name);
3278
params->add_entry(param);
3281
if (_curchar == ',') {
3285
} else if (_curchar == ')') {
3289
parse_err(SYNERR, "expected ',' or ')' after parameter %s.\n", ec_name);
3296
if (_curchar == ',') {
3297
parse_err(SYNERR, "Expected encode parameter before ',' in postalloc_expand %s.\n", ec_name);
3300
if (_curchar != ')') {
3301
parse_err(SYNERR, "Expected ')' after postalloc_expand parameters.\n");
3311
if (_curchar != ')') {
3313
parse_err(SYNERR, "Expected ')' after postalloc_expand %s.\n", ec_name);
3317
if (_curchar != ')') {
3318
parse_err(SYNERR, "Missing ')' at end of postalloc_expand description.\n");
3324
if (_curchar != ';') {
3325
parse_err(SYNERR, "Missing ';' at end of postalloc_expand.\n");
3332
if (_AD._adl_debug > 1) fprintf(stderr, "Instruction postalloc_expand: %s\n", ec_name);
3335
inst._insencode = encrule;
3341
void ADLParser::constant_parse(InstructForm& inst) {
3344
const char* prefix = "__constant_";
3345
const size_t ec_name_size = strlen(inst._ident) + strlen(prefix) + 1;
3346
char* ec_name = (char*) AdlAllocateHeap(ec_name_size);
3347
snprintf_checked(ec_name, ec_name_size, "%s%s", prefix, inst._ident);
3349
assert(_AD._encode->encClass(ec_name) == nullptr, "shouldn't already exist");
3350
EncClass* encoding = _AD._encode->add_EncClass(ec_name);
3351
encoding->_linenum = linenum();
3355
const char* param = nullptr;
3356
inst._parameters.reset();
3357
while ((param = inst._parameters.iter()) != nullptr) {
3358
OpClassForm* opForm = inst._localNames[param]->is_opclass();
3359
assert(opForm != nullptr, "sanity");
3360
encoding->add_parameter(opForm->_ident, param);
3364
constant_parse_expression(encoding, ec_name);
3368
InsEncode* encrule = new InsEncode();
3369
NameAndList* params = encrule->add_encode(ec_name);
3370
inst._parameters.reset();
3371
while ((param = inst._parameters.iter()) != nullptr) {
3372
params->add_entry(param);
3376
inst._constant = encrule;
3381
void ADLParser::constant_parse_expression(EncClass* encoding, char* ec_name) {
3385
if (_AD._adlocation_debug) {
3386
encoding->add_code(get_line_string());
3390
encoding->add_code(" _constant = C->output()->constant_table().add");
3393
encoding->add_code("(this, ");
3395
int parens_depth = 1;
3400
while (parens_depth > 0) {
3401
if (_curchar == '(') {
3403
encoding->add_code("(");
3404
next_char_or_line();
3406
else if (_curchar == ')') {
3408
if (parens_depth > 0)
3409
encoding->add_code(")");
3410
next_char_or_line();
3416
while ((_curchar != '$') && (_curchar != '(') && (_curchar != ')')) {
3417
next_char_or_line();
3420
if (start != _ptr) {
3422
encoding->add_code(start);
3427
if (_curchar == '$') {
3429
char* rep_var = get_rep_var_ident_dup();
3430
encoding->add_rep_var(rep_var);
3436
encoding->add_code(");");
3438
if (_AD._adlocation_debug) {
3439
encoding->add_code(end_line_marker());
3443
if (_AD._adl_debug > 1) fprintf(stderr, "EncodingClass Form: %s\n", ec_name);
3451
char* ADLParser::size_parse(InstructForm *instr) {
3452
char* sizeOfInstr = nullptr;
3458
sizeOfInstr = get_paren_expr("size expression");
3459
if (sizeOfInstr == nullptr) {
3460
parse_err(SYNERR, "size of opcode expected at %c\n", _curchar);
3467
if (_curchar != ';') {
3468
parse_err(SYNERR, "missing ';' in ins_attrib definition\n");
3475
if (_AD._adl_debug > 1) {
3476
if (sizeOfInstr != nullptr) {
3477
fprintf(stderr,"size of opcode: %s\n", sizeOfInstr);
3486
Opcode * ADLParser::opcode_parse(InstructForm *instr) {
3487
char *primary = nullptr;
3488
char *secondary = nullptr;
3489
char *tertiary = nullptr;
3491
char *val = nullptr;
3492
Opcode *opcode = nullptr;
3496
if (_curchar != '(') {
3497
parse_err(SYNERR, "missing '(' in expand instruction declaration\n");
3502
if (_curchar != ')') {
3504
if ( (primary = get_ident_or_literal_constant("primary opcode")) == nullptr ) {
3505
parse_err(SYNERR, "primary hex opcode expected at %c\n", _curchar);
3509
if (_curchar == ',') {
3513
if ( (secondary = get_ident_or_literal_constant("secondary opcode")) == nullptr ) {
3514
parse_err(SYNERR, "secondary hex opcode expected at %c\n", _curchar);
3518
if (_curchar == ',') {
3522
if ( (tertiary = get_ident_or_literal_constant("tertiary opcode")) == nullptr ) {
3523
parse_err(SYNERR,"tertiary hex opcode expected at %c\n", _curchar);
3530
if (_curchar != ')') {
3531
parse_err(SYNERR, "Missing ')' in opcode description\n");
3538
if (_curchar != ';') {
3539
parse_err(SYNERR, "missing ';' in ins_attrib definition\n");
3546
if (_AD._adl_debug > 1) {
3547
if (primary != nullptr) fprintf(stderr,"primary opcode: %s\n", primary);
3548
if (secondary != nullptr) fprintf(stderr,"secondary opcode: %s\n", secondary);
3549
if (tertiary != nullptr) fprintf(stderr,"tertiary opcode: %s\n", tertiary);
3553
opcode = new Opcode(primary, secondary, tertiary);
3559
Interface *ADLParser::interface_parse(void) {
3560
char *iface_name = nullptr;
3561
char *iface_code = nullptr;
3565
if (_curchar != '(') {
3566
parse_err(SYNERR, "Missing '(' at start of interface description.\n");
3571
iface_name = get_ident();
3572
if (iface_name == nullptr) {
3573
parse_err(SYNERR, "missing interface name after 'interface'.\n");
3577
if (_curchar != ')') {
3578
parse_err(SYNERR, "Missing ')' after name of interface.\n");
3585
Interface *inter = nullptr;
3587
if ( _curchar != ';' ) {
3588
if ( strcmp(iface_name,"MEMORY_INTER") == 0 ) {
3589
inter = mem_interface_parse();
3591
else if ( strcmp(iface_name,"COND_INTER") == 0 ) {
3592
inter = cond_interface_parse();
3597
if ( _curchar == ';' ) {
3598
parse_err(SYNERR, "Extra ';' after defining interface block.\n");
3606
if ( strcmp(iface_name,"REG_INTER") == 0 ) {
3607
inter = new RegInterface();
3609
else if ( strcmp(iface_name,"CONST_INTER") == 0 ) {
3610
inter = new ConstInterface();
3615
if (_AD._adl_debug > 1) fprintf(stderr,"Interface Form: %s\n", iface_name);
3623
Interface *ADLParser::mem_interface_parse(void) {
3625
char *base = nullptr;
3626
char *index = nullptr;
3627
char *scale = nullptr;
3628
char *disp = nullptr;
3630
if (_curchar != '%') {
3631
parse_err(SYNERR, "Missing '%%{' for 'interface' block.\n");
3635
if (_curchar != '{') {
3636
parse_err(SYNERR, "Missing '%%{' for 'interface' block.\n");
3642
char *field = get_ident();
3643
if (field == nullptr) {
3644
parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%%}' ending interface.\n");
3647
if ( strcmp(field,"base") == 0 ) {
3648
base = interface_field_parse();
3650
else if ( strcmp(field,"index") == 0 ) {
3651
index = interface_field_parse();
3653
else if ( strcmp(field,"scale") == 0 ) {
3654
scale = interface_field_parse();
3656
else if ( strcmp(field,"disp") == 0 ) {
3657
disp = interface_field_parse();
3660
parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%%}' ending interface.\n");
3663
} while( _curchar != '%' );
3665
if ( _curchar != '}' ) {
3666
parse_err(SYNERR, "Missing '%%}' for 'interface' block.\n");
3672
Interface *inter = new MemInterface(base, index, scale, disp);
3678
Interface *ADLParser::cond_interface_parse(void) {
3682
char *greater_equal;
3687
const char *equal_format = "eq";
3688
const char *not_equal_format = "ne";
3689
const char *less_format = "lt";
3690
const char *greater_equal_format = "ge";
3691
const char *less_equal_format = "le";
3692
const char *greater_format = "gt";
3693
const char *overflow_format = "o";
3694
const char *no_overflow_format = "no";
3696
if (_curchar != '%') {
3697
parse_err(SYNERR, "Missing '%%{' for 'cond_interface' block.\n");
3701
if (_curchar != '{') {
3702
parse_err(SYNERR, "Missing '%%{' for 'cond_interface' block.\n");
3708
char *field = get_ident();
3709
if (field == nullptr) {
3710
parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%%}' ending interface.\n");
3713
if ( strcmp(field,"equal") == 0 ) {
3714
equal = interface_field_parse(&equal_format);
3716
else if ( strcmp(field,"not_equal") == 0 ) {
3717
not_equal = interface_field_parse(¬_equal_format);
3719
else if ( strcmp(field,"less") == 0 ) {
3720
less = interface_field_parse(&less_format);
3722
else if ( strcmp(field,"greater_equal") == 0 ) {
3723
greater_equal = interface_field_parse(&greater_equal_format);
3725
else if ( strcmp(field,"less_equal") == 0 ) {
3726
less_equal = interface_field_parse(&less_equal_format);
3728
else if ( strcmp(field,"greater") == 0 ) {
3729
greater = interface_field_parse(&greater_format);
3731
else if ( strcmp(field,"overflow") == 0 ) {
3732
overflow = interface_field_parse(&overflow_format);
3734
else if ( strcmp(field,"no_overflow") == 0 ) {
3735
no_overflow = interface_field_parse(&no_overflow_format);
3738
parse_err(SYNERR, "Expected keyword, base|index|scale|disp, or '%%}' ending interface.\n");
3741
} while( _curchar != '%' );
3743
if ( _curchar != '}' ) {
3744
parse_err(SYNERR, "Missing '%%}' for 'interface' block.\n");
3750
Interface *inter = new CondInterface(equal, equal_format,
3751
not_equal, not_equal_format,
3753
greater_equal, greater_equal_format,
3754
less_equal, less_equal_format,
3755
greater, greater_format,
3756
overflow, overflow_format,
3757
no_overflow, no_overflow_format);
3763
char *ADLParser::interface_field_parse(const char ** format) {
3764
char *iface_field = nullptr;
3768
if (_curchar != '(') {
3769
parse_err(SYNERR, "Missing '(' at start of interface field.\n");
3774
if ( _curchar != '0' && _curchar != '$' ) {
3775
parse_err(SYNERR, "missing or invalid interface field contents.\n");
3778
iface_field = get_rep_var_ident();
3779
if (iface_field == nullptr) {
3780
parse_err(SYNERR, "missing or invalid interface field contents.\n");
3784
if (format != nullptr && _curchar == ',') {
3787
if (_curchar != '"') {
3788
parse_err(SYNERR, "Missing '\"' in field format .\n");
3793
while ((_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) {
3794
if (_curchar == '\\') next_char();
3795
if (_curchar == '\n') parse_err(SYNERR, "newline in string");
3798
if (_curchar != '"') {
3799
parse_err(SYNERR, "Missing '\"' at end of field format .\n");
3803
if ( start != _ptr ) {
3810
if (_curchar != ')') {
3811
parse_err(SYNERR, "Missing ')' after interface field.\n");
3816
if ( _curchar != ';' ) {
3817
parse_err(SYNERR, "Missing ';' at end of interface field.\n");
3828
MatchRule *ADLParser::match_parse(FormDict &operands) {
3830
char *cnstr = nullptr;
3835
MatchNode *mnode = matchNode_parse(operands, depth, numleaves, true);
3839
if ( _curchar == ';' ) {
3843
else if ((cnstr = find_cpp_block("match constructor")) == nullptr ) {
3844
parse_err(SYNERR, "invalid construction of match rule\n"
3845
"Missing ';' or invalid '%%{' and '%%}' constructor\n");
3848
if (_AD._adl_debug > 1)
3849
if (cnstr) fprintf(stderr,"Match Constructor: %s\n", cnstr);
3851
match = new MatchRule(_AD, mnode, depth, cnstr, numleaves);
3857
FormatRule* ADLParser::format_parse(void) {
3858
char *desc = nullptr;
3859
FormatRule *format = (new FormatRule(desc));
3863
if ( _curchar == ';' ) {
3867
else if ( _curchar == '%' && *(_ptr+1) == '{') {
3872
if (_curchar == '$') {
3873
char* ident = get_rep_var_ident();
3874
if (strcmp(ident, "$$template") == 0) return template_parse();
3875
parse_err(SYNERR, "Unknown \"%s\" directive in format", ident);
3879
if ( _curchar == '"' ) {
3881
if( _curchar == '"' ) {
3883
format->_strings.addName(_ptr);
3891
if ( _curchar == '%' || _curchar == '\n' ) {
3892
if ( _curchar != '"' ) {
3893
parse_err(SYNERR, "missing '\"' at end of format block");
3901
while ((_curchar != '$') && (_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) {
3902
if (_curchar == '\\') {
3904
if ((_curchar == '$') || (_curchar == '%'))
3906
*(_ptr-1) = _curchar;
3908
if (_curchar == '\n') parse_err(SYNERR, "newline in string");
3912
if ( start != _ptr ) {
3914
format->_strings.addName(start);
3920
if ( _curchar == '$' ) {
3922
char* rep_var = get_ident();
3923
rep_var = strdup(rep_var);
3925
format->_rep_vars.addName(rep_var);
3927
format->_strings.addName(NameList::_signal);
3933
if ( _curchar == '"') {
3936
if ( _curchar != '"') {
3947
if ( _curchar != '%' ) {
3948
parse_err(SYNERR, "non-blank characters between closing '\"' and '%%' in format");
3955
if ( _curchar != '%' || *(_ptr+1) != '}' ) {
3956
parse_err(SYNERR, "missing '%%}' at end of format block");
3963
parse_err(SYNERR, "missing ';' after Format expression");
3967
if (_AD._adl_debug > 1) fprintf(stderr,"Format Rule: %s\n", desc);
3975
FormatRule* ADLParser::template_parse(void) {
3976
char *desc = nullptr;
3977
FormatRule *format = (new FormatRule(desc));
3980
while ( (_curchar != '%') && (*(_ptr+1) != '}') ) {
3986
while ((_curchar != '$') && ((_curchar != '%') || (*(_ptr+1) != '}')) ) {
3988
if( (_curchar == '/') && ((*(_ptr+1) == '/') || (*(_ptr+1) == '*')) ) {
3989
skipws_no_preproc();
3992
next_char_or_line();
3996
if ( start != _ptr ) {
3999
format->_strings.addName(NameList::_signal2);
4000
format->_strings.addName(start);
4007
if ( _curchar == '$' ) {
4009
char *rep_var = get_rep_var_ident_dup();
4010
if (strcmp(rep_var, "$emit") == 0) {
4016
if ( _curchar == '"' ) {
4018
if( _curchar == '"' ) {
4020
format->_strings.addName(_ptr);
4028
if ( _curchar == '%' || _curchar == '\n' ) {
4029
parse_err(SYNERR, "missing '\"' at end of format block");
4036
while ((_curchar != '$') && (_curchar != '"') && (_curchar != '%') && (_curchar != '\n')) {
4037
if (_curchar == '\\') next_char();
4038
if (_curchar == '\n') parse_err(SYNERR, "newline in string");
4042
if ( start != _ptr ) {
4044
format->_strings.addName(start);
4050
if ( _curchar == '$' ) {
4052
char* next_rep_var = get_ident();
4053
next_rep_var = strdup(next_rep_var);
4055
format->_rep_vars.addName(next_rep_var);
4057
format->_strings.addName(NameList::_signal);
4063
if ( _curchar == '"') {
4066
if ( _curchar != '"') {
4077
format->_rep_vars.addName(rep_var);
4079
format->_strings.addName(NameList::_signal3);
4086
if ( _curchar != '%' || *(_ptr+1) != '}' ) {
4087
parse_err(SYNERR, "missing '%%}' at end of format block");
4094
if (_AD._adl_debug > 1) fprintf(stderr,"Format Rule: %s\n", desc);
4102
void ADLParser::effect_parse(InstructForm *instr) {
4103
char* desc = nullptr;
4106
if (_curchar != '(') {
4107
parse_err(SYNERR, "missing '(' in effect definition\n");
4111
else get_effectlist(instr->_effects, instr->_localNames, instr->_has_call);
4114
if (_AD._adl_debug > 1) fprintf(stderr,"Effect description: %s\n", desc);
4115
if (_curchar != ';') {
4116
parse_err(SYNERR, "missing ';' in Effect definition\n");
4123
Flag* ADLParser::flag_parse(InstructForm *instr) {
4124
char* ident = nullptr;
4125
Flag* result = nullptr;
4128
if (_curchar != '(') {
4129
parse_err(SYNERR, "missing '(' in flag definition\n");
4135
if (_curchar == ')') break;
4137
ident = get_ident();
4138
if (ident == nullptr) {
4139
parse_err(SYNERR, "flag name expected at %c\n", _curchar);
4142
Flag* newflag = new Flag(ident);
4143
if (result == nullptr) result = newflag;
4144
else result->append_flag(newflag);
4145
if (_AD._adl_debug > 1) fprintf(stderr, "\tFlag Name: %s\n", ident);
4147
} while (_curchar == ',');
4148
if (_curchar != ')') parse_err(SYNERR, "missing ')'\n");
4154
if (_curchar != ';') {
4155
parse_err(SYNERR, "missing ';' in Flag definition\n");
4163
ExpandRule* ADLParser::expand_parse(InstructForm *instr) {
4164
char *ident, *ident2;
4165
NameAndList *instr_and_operands = nullptr;
4166
ExpandRule *exp = new ExpandRule();
4172
if ((_curchar != '%')
4173
|| (next_char(), (_curchar != '{')) ) {
4174
parse_err(SYNERR, "missing '%%{' in expand definition\n");
4179
ident = get_ident();
4180
if (ident == nullptr) {
4181
parse_err(SYNERR, "identifier expected at %c\n", _curchar);
4186
const Form *form = _globalNames[ident];
4187
bool parse_oper = false;
4188
bool parse_ins = false;
4189
if (form == nullptr) {
4194
if (_curchar == '(') parse_ins = true;
4195
} else if (form->is_instruction()) {
4197
} else if (form->is_operand()) {
4200
parse_err(SYNERR, "instruction/operand name expected at %s\n", ident);
4206
OperandForm *oper = form->is_operand();
4207
if (oper == nullptr) {
4208
parse_err(SYNERR, "instruction/operand name expected at %s\n", ident);
4213
ident = get_unique_ident(instr->_localNames,"Operand");
4214
if (ident == nullptr) {
4215
parse_err(SYNERR, "identifier expected at %c\n", _curchar);
4218
exp->_newopers.addName(ident);
4220
instr->_localNames.Insert(ident, oper);
4224
if (_curchar == '%') {
4225
c = find_cpp_block("Operand Constructor");
4227
parse_err(SYNERR, "Invalid code block for operand constructor\n");
4231
exp->_newopconst.Insert(ident, c);
4233
else if (_curchar != ';') {
4234
parse_err(SYNERR, "Missing ; in expand rule operand declaration\n");
4241
assert(parse_ins, "sanity");
4243
instr_and_operands = new NameAndList(ident);
4246
if (_curchar != '(') {
4247
parse_err(SYNERR, "missing '(' in expand instruction declaration\n");
4253
if (_curchar == ')') break;
4254
ident2 = get_ident();
4256
if (ident2 == nullptr) {
4257
parse_err(SYNERR, "identifier expected at %c\n", _curchar);
4260
const Form *form2 = instr->_localNames[ident2];
4262
parse_err(SYNERR, "operand name expected at %s\n", ident2);
4265
OperandForm *oper = form2->is_operand();
4266
if (oper == nullptr && !form2->is_opclass()) {
4267
parse_err(SYNERR, "operand name expected at %s\n", ident2);
4270
instr_and_operands->add_entry(ident2);
4271
} while(_curchar == ',');
4272
if (_curchar != ')') {
4273
parse_err(SYNERR, "missing ')'in expand instruction declaration\n");
4277
if (_curchar != ';') {
4278
parse_err(SYNERR, "missing ';'in expand instruction declaration\n");
4284
exp->add_instruction(instr_and_operands);
4289
} while(_curchar != '%');
4291
if (_curchar != '}') {
4292
parse_err(SYNERR, "missing '%%}' in expand rule definition\n");
4298
if (_AD._adl_debug > 1) fprintf(stderr,"Expand Rule:\n");
4305
RewriteRule* ADLParser::rewrite_parse(void) {
4306
char* params = nullptr;
4307
char* desc = nullptr;
4314
if ((params = get_paren_expr("rewrite parameters")) == nullptr) {
4315
parse_err(SYNERR, "missing '(' in rewrite rule\n");
4319
if (_AD._adl_debug > 1) fprintf(stderr,"Rewrite parameters: %s\n", params);
4323
if ( (desc = find_cpp_block("rewrite block")) == nullptr ) {
4324
parse_err(SYNERR, "incorrect or missing block for 'rewrite'.\n");
4328
if (_AD._adl_debug > 1) fprintf(stderr,"Rewrite Rule: %s\n", desc);
4331
return (new RewriteRule(params,desc));
4335
Attribute *ADLParser::attr_parse(char* ident) {
4337
char *cost = nullptr;
4340
if ( (cost = get_paren_expr("attribute")) == nullptr ) {
4341
parse_err(SYNERR, "incorrect or missing expression for 'attribute'\n");
4345
if (_AD._adl_debug > 1) fprintf(stderr,"Attribute: %s\n", cost);
4346
if (_curchar != ';') {
4347
parse_err(SYNERR, "missing ';' in attribute definition\n");
4353
attrib = new Attribute(ident,cost,INS_ATTR);
4359
MatchNode *ADLParser::matchNode_parse(FormDict &operands, int &depth, int &numleaves, bool atroot) {
4361
int lParens = depth;
4362
int rParens = depth;
4365
MatchNode *lChild = nullptr;
4366
MatchNode *rChild = nullptr;
4370
if (cur_char() != '(')
4376
token = get_ident();
4377
if (token == nullptr) {
4378
parse_err(SYNERR, "missing opcode in match expression\n");
4387
for (int i = _last_machine_leaf + 1; i < _last_opcode; i++) {
4388
if (strcmp(token, NodeClassNames[i]) == 0) {
4389
_AD.has_match_rule(i, true);
4394
const char *result = nullptr;
4395
const char *name = token;
4396
const char *operation = token;
4397
const Form *form = operands[token];
4398
OpClassForm *opcForm = form ? form->is_opclass() : nullptr;
4399
if (opcForm != nullptr) {
4401
if (!opcForm->ideal_only()) {
4402
operation = opcForm->_ident;
4406
else name = nullptr;
4411
if (cur_char() != ')') {
4414
if (strcmp(operation,"Set"))
4415
lChild = matchChild_parse(operands, lParens, numleaves, false);
4417
lChild = matchChild_parse(operands, lParens, numleaves, true);
4420
if (cur_char() != ')' ) {
4421
if(strcmp(operation, "Set"))
4422
rChild = matchChild_parse(operands,rParens,numleaves,false);
4424
rChild = matchChild_parse(operands,rParens,numleaves,true);
4430
if (cur_char() != ')') {
4431
parse_err(SYNERR, "missing ')' in match expression\n");
4436
MatchNode* mroot = new MatchNode(_AD,result,name,operation,lChild,rChild);
4440
mroot->build_internalop();
4443
depth = (lParens > rParens) ? lParens : rParens;
4450
MatchNode *ADLParser::matchChild_parse(FormDict &operands, int &parens, int &numleaves, bool atroot) {
4451
MatchNode *child = nullptr;
4452
const char *result = nullptr;
4453
const char *token = nullptr;
4454
const char *opType = nullptr;
4456
if (cur_char() == '(') {
4458
child = matchNode_parse(operands, parens, numleaves, atroot);
4461
token = get_ident();
4462
const Form *form = operands[token];
4463
OpClassForm *opcForm = form ? form->is_opclass() : nullptr;
4464
if (opcForm != nullptr) {
4465
opType = opcForm->_ident;
4466
result = opcForm->_ident;
4468
parse_err(SYNERR, "undefined operand %s in match rule\n", token);
4472
if (opType == nullptr) {
4473
parse_err(SYNERR, "missing type for argument '%s'\n", token);
4476
child = new MatchNode(_AD, result, token, opType);
4488
char* ADLParser::find_cpp_block(const char* description) {
4490
char* cppBlock = nullptr;
4492
if (_curchar == '%') {
4494
if (_curchar != '{') {
4495
parse_err(SYNERR, "missing '{' in %s \n", description);
4499
skipws_no_preproc();
4501
int line = linenum();
4503
while(((_curchar != '%') || (*next != '}')) && (_curchar != '\0')) {
4504
next_char_or_line();
4507
if (_curchar == '\0') {
4508
parse_err(SYNERR, "invalid termination of %s \n", description);
4516
if (_AD._adlocation_debug) {
4517
char* location = get_line_string(line);
4518
char* end_loc = end_line_marker();
4519
char* result = (char *)AdlAllocateHeap(strlen(location) + strlen(cppBlock) + strlen(end_loc) + 1);
4520
strcpy(result, location);
4521
strcat(result, cppBlock);
4522
strcat(result, end_loc);
4533
char* ADLParser::get_expr(const char *desc, const char *stop_chars) {
4534
char* expr = nullptr;
4538
while (paren > 0 || !strchr(stop_chars, _curchar)) {
4539
if (_curchar == '(') {
4543
else if (_curchar == ')') {
4546
parse_err(SYNERR, "too many )'s, did not find %s after %s\n",
4553
else if (_curchar == '"' || _curchar == '\'') {
4554
int qchar = _curchar;
4557
if (_curchar == qchar) { next_char(); break; }
4558
if (_curchar == '\\') next_char();
4559
if (_curchar == '\n' || _curchar == '\0') {
4560
parse_err(SYNERR, "newline in string in %s\n", desc);
4565
else if (_curchar == '%' && (_ptr[1] == '{' || _ptr[1] == '}')) {
4567
parse_err(SYNERR, "unexpected %%%c in %s\n", _ptr[1], desc);
4570
else if (_curchar == '\0') {
4571
parse_err(SYNERR, "unexpected EOF in %s\n", desc);
4576
char* pre_skip_ptr = _ptr;
4580
if (pre_skip_ptr == _ptr) {
4582
} else if (pre_skip_ptr+strlen(pre_skip_ptr) != _ptr+strlen(_ptr)) {
4583
parse_err(SYNERR, "unimplemented: preprocessor must not elide subexpression in %s", desc);
4588
assert(strchr(stop_chars, _curchar), "non-null return must be at stop-char");
4595
char *ADLParser::get_paren_expr(const char *description, bool include_location) {
4596
int line = linenum();
4597
if (_curchar != '(')
4600
char *token2 = get_expr(description, ")");
4601
if (_curchar == ')')
4604
if (include_location && _AD._adlocation_debug && !is_int_token(token2, junk)) {
4606
char* location = get_line_string(line);
4607
char* end_loc = end_line_marker();
4608
char* result = (char *)AdlAllocateHeap(strlen(location) + strlen(token2) + strlen(end_loc) + 1);
4609
strcpy(result, location);
4610
strcat(result, token2);
4611
strcat(result, end_loc);
4622
char *ADLParser::get_ident_common(bool do_preproc) {
4627
if (_curline == nullptr) {
4631
skipws_common(do_preproc);
4637
} while ( ((c >= 'a') && (c <= 'z')) || ((c >= 'A') && (c <= 'Z'))
4638
|| ((c >= '0') && (c <= '9'))
4639
|| ((c == '_')) || ((c == ':')) || ((c == '#')) );
4643
if (strlen(start) > 24) {
4645
strncpy(buf, start, 20);
4647
strcat(buf, "[...]");
4648
parse_err(SYNERR, "Identifier expected, but found '%s'.", buf);
4650
parse_err(SYNERR, "Identifier expected, but found '%s'.", start);
4662
if (do_preproc && start != nullptr) {
4663
const char* def = _AD.get_preproc_def(start);
4664
if (def != nullptr && strcmp(def, start)) {
4665
const char* def1 = def;
4666
const char* def2 = _AD.get_preproc_def(def1);
4668
if (def2 != nullptr && strcmp(def2, def1)) {
4670
const char* def3 = _AD.get_preproc_def(def2);
4671
if (def3 != nullptr && strcmp(def3, def2) && strcmp(def3, def1)) {
4672
parse_err(SYNERR, "unimplemented: using %s defined as %s => %s => %s",
4673
start, def1, def2, def3);
4676
start = strdup(def);
4686
char *ADLParser::get_ident_dup(void) {
4687
char *ident = get_ident();
4690
if( ident != nullptr ) {
4691
ident = strdup(ident);
4700
char *ADLParser::get_ident_or_literal_constant(const char* description) {
4701
char* param = nullptr;
4703
if (_curchar == '(') {
4705
param = get_paren_expr(description);
4706
if (param[0] != '(') {
4707
const size_t buf_size = strlen(param) + 3;
4708
char* buf = (char*) AdlAllocateHeap(buf_size);
4709
snprintf_checked(buf, buf_size, "(%s)", param);
4712
assert(is_literal_constant(param),
4713
"expr must be recognizable as a constant");
4715
param = get_ident();
4724
char *ADLParser::get_rep_var_ident(void) {
4726
char *rep_var = _ptr;
4729
if ( _curchar == '$' ) {
4733
if ( _curchar == '$' ) {
4738
if ( _curchar == '$' ) {
4743
if( _curchar == '$' ) {
4744
parse_err(SYNERR, "Replacement variables and field specifiers can not start with '$$$$'");
4750
char *rep_var_name = get_ident();
4751
assert( rep_var_name != nullptr,
4752
"Missing identifier after replacement variable indicator '$'");
4764
char *ADLParser::get_rep_var_ident_dup(void) {
4765
if( _curchar != '$' ) return nullptr;
4768
char *rep_var = _ptr;
4771
if ( _curchar == '$' ) {
4776
if ( _curchar == '$' ) {
4781
if( _curchar == '$' ) {
4782
parse_err(SYNERR, "Replacement variables and field specifiers can not start with '$$$$'");
4788
char *rep_var_name = get_ident();
4789
assert( rep_var_name != nullptr,
4790
"Missing identifier after replacement variable indicator '$'");
4791
rep_var = strdup(rep_var);
4801
char *ADLParser::get_unique_ident(FormDict& dict, const char* nameDescription){
4802
char* ident = get_ident();
4804
if (ident == nullptr) {
4805
parse_err(SYNERR, "missing %s identifier at %c\n", nameDescription, _curchar);
4808
if (dict[ident] != nullptr) {
4809
parse_err(SYNERR, "duplicate name %s for %s\n", ident, nameDescription);
4822
int ADLParser::get_int(void) {
4828
if (_curline == nullptr) {
4835
while ((c >= '0' && c <= '9') || (c == '-' && end == start)) {
4840
parse_err(SYNERR, "integer expected at %c\n", c);
4846
result = atoi(start);
4861
char *ADLParser::get_relation_dup(void) {
4862
char *result = nullptr;
4864
if (_curline == nullptr) {
4871
if( (first == '=') || (first == '!') || (first == '<') || (first == '>') ) {
4873
char second = *_ptr;
4874
if( second == '=' ) {
4878
result = strdup(start);
4881
parse_err(SYNERR, "relational operator expected at %s\n", _ptr);
4884
parse_err(SYNERR, "relational operator expected at %s\n", _ptr);
4896
void ADLParser::get_oplist(NameList ¶meters, FormDict &operands) {
4897
OpClassForm *opclass = nullptr;
4898
char *ident = nullptr;
4903
if (_curchar == ')') break;
4906
ident = get_ident();
4907
if (ident == nullptr) {
4908
parse_err(SYNERR, "optype identifier expected at %c\n", _curchar);
4912
const Form *form = _globalNames[ident];
4913
if( form == nullptr ) {
4914
parse_err(SYNERR, "undefined operand type %s\n", ident);
4919
OpClassForm *opc = form->is_opclass();
4920
OperandForm *oper = form->is_operand();
4921
if((oper == nullptr) && (opc == nullptr)) {
4922
parse_err(SYNERR, "identifier %s not operand type\n", ident);
4928
if (_AD._adl_debug > 1) fprintf(stderr, "\tOperand Type: %s\t", ident);
4931
if( (ident = get_unique_ident(operands, "operand")) == nullptr) {
4935
if( _globalNames[ident] != nullptr ) {
4936
parse_err(SYNERR, "Reuse of global name %s as operand.\n",ident);
4939
operands.Insert(ident, opclass);
4940
parameters.addName(ident);
4943
if (_AD._adl_debug > 1) fprintf(stderr, "\tOperand Name: %s\n", ident);
4945
} while(_curchar == ',');
4947
if (_curchar != ')') parse_err(SYNERR, "missing ')'\n");
4959
void ADLParser::get_effectlist(FormDict &effects, FormDict &operands, bool& has_call) {
4960
OperandForm *opForm;
4967
if (_curchar == ')') break;
4970
ident = get_ident();
4971
if (ident == nullptr) {
4972
parse_err(SYNERR, "effect type identifier expected at %c\n", _curchar);
4977
const Form *form = _globalNames[ident];
4978
if( form == nullptr ) {
4979
parse_err(SYNERR, "undefined effect type %s\n", ident);
4983
if( (eForm = form->is_effect()) == nullptr) {
4984
parse_err(SYNERR, "identifier %s not effect type\n", ident);
4990
if (_AD._adl_debug > 1) fprintf(stderr, "\tEffect Type: %s\t", ident);
4992
if (eForm->is(Component::CALL)) {
4993
if (_AD._adl_debug > 1) fprintf(stderr, "\n");
4997
if( (ident = get_unique_ident(effects, "effect")) == nullptr) {
4998
parse_err(SYNERR, "missing operand identifier in effect list\n");
5001
const Form *form = operands[ident];
5002
opForm = form ? form->is_operand() : nullptr;
5003
if( opForm == nullptr ) {
5004
if( form && form->is_opclass() ) {
5005
const char* cname = form->is_opclass()->_ident;
5006
parse_err(SYNERR, "operand classes are illegal in effect lists (found %s %s)\n", cname, ident);
5008
parse_err(SYNERR, "undefined operand %s in effect list\n", ident);
5013
effects.Insert(ident, eForm);
5015
if (_AD._adl_debug > 1) fprintf(stderr, "\tOperand Name: %s\n", ident);
5018
} while(_curchar == ',');
5020
if (_curchar != ')') parse_err(SYNERR, "missing ')'\n");
5029
void ADLParser::preproc_line(void) {
5030
int line = get_int();
5031
skipws_no_preproc();
5032
const char* file = nullptr;
5033
if (_curchar == '"') {
5037
if (_curchar == '\n') {
5038
parse_err(SYNERR, "missing '\"' at end of #line directive");
5041
if (_curchar == '"') {
5044
skipws_no_preproc();
5050
ensure_end_of_line();
5051
if (file != nullptr)
5052
_AD._ADL_file._name = file;
5053
_buf.set_linenum(line);
5058
void ADLParser::preproc_define(void) {
5059
char* flag = get_ident_no_preproc();
5060
skipws_no_preproc();
5062
char* def = get_ident_no_preproc();
5063
_AD.set_preproc_def(flag, def);
5064
skipws_no_preproc();
5065
if (_curchar != '\n') {
5066
parse_err(SYNERR, "non-identifier in preprocessor definition\n");
5072
void ADLParser::preproc_undef(void) {
5073
char* flag = get_ident_no_preproc();
5074
skipws_no_preproc();
5075
ensure_end_of_line();
5076
_AD.set_preproc_def(flag, nullptr);
5083
void ADLParser::parse_err(int flag, const char *fmt, ...) {
5086
va_start(args, fmt);
5088
_AD._syntax_errs += _AD.emit_msg(0, flag, linenum(), fmt, args);
5090
_AD._semantic_errs += _AD.emit_msg(0, flag, linenum(), fmt, args);
5092
_AD._warnings += _AD.emit_msg(0, flag, linenum(), fmt, args);
5094
int error_char = _curchar;
5095
char* error_ptr = _ptr+1;
5096
for(;*_ptr != '\n'; _ptr++) ;
5102
char* error_tail = strchr(error_ptr, '\n');
5103
char tem = *error_ptr;
5104
error_ptr[-1] = '\0';
5105
char* error_head = error_ptr-1;
5106
while (error_head > _curline && *error_head) --error_head;
5107
if (error_tail) *error_tail = '\0';
5108
fprintf(stderr, "Error Context: %s>>>%c<<<%s\n",
5109
error_head, error_char, error_ptr);
5110
if (error_tail) *error_tail = '\n';
5111
error_ptr[-1] = tem;
5118
void ADLParser::ensure_start_of_line(void) {
5119
if (_curchar == '\n') { next_line(); return; }
5120
assert( _ptr >= _curline && _ptr < _curline+strlen(_curline),
5121
"Must be able to find which line we are in" );
5123
for (char *s = _curline; s < _ptr; s++) {
5125
parse_err(SYNERR, "'%c' must be at beginning of line\n", _curchar);
5135
void ADLParser::ensure_end_of_line(void) {
5136
skipws_no_preproc();
5137
if (_curchar != '\n' && _curchar != '\0') {
5138
parse_err(SYNERR, "garbage char '%c' at end of line\n", _curchar);
5140
next_char_or_line();
5161
bool ADLParser::handle_preproc_token() {
5162
assert(*_ptr == '#', "must be at start of preproc");
5163
ensure_start_of_line();
5165
skipws_no_preproc();
5166
char* start_ident = _ptr;
5167
char* ident = (_curchar == '\n') ? nullptr : get_ident_no_preproc();
5168
if (ident == nullptr) {
5169
parse_err(SYNERR, "expected preprocessor command, got end of line\n");
5170
} else if (!strcmp(ident, "ifdef") ||
5171
!strcmp(ident, "ifndef")) {
5172
char* flag = get_ident_no_preproc();
5173
ensure_end_of_line();
5175
bool flag_def = preproc_taken() && (_AD.get_preproc_def(flag) != nullptr);
5176
bool now_taken = !strcmp(ident, "ifdef") ? flag_def : !flag_def;
5177
begin_if_def(now_taken);
5178
} else if (!strcmp(ident, "if")) {
5179
if (preproc_taken())
5180
parse_err(SYNERR, "unimplemented: #%s %s", ident, _ptr+1);
5184
} else if (!strcmp(ident, "else")) {
5185
ensure_end_of_line();
5187
} else if (!strcmp(ident, "endif")) {
5188
ensure_end_of_line();
5190
} else if (preproc_taken()) {
5194
if( _curchar != '#' ) {
5195
parse_err(SYNERR, "no space allowed after # in #define or #undef");
5196
assert(_curchar == '#', "no space allowed after # in #define or #undef");
5207
void ADLParser::skipws_common(bool do_preproc) {
5209
char *next = _ptr + 1;
5211
if (*_ptr == '\0') {
5213
if (_curchar > ' ') return;
5214
if (_curchar == '\n') {
5215
if (!do_preproc) return;
5217
_ptr = _curline; next = _ptr + 1;
5219
else if (_curchar == '#' ||
5220
(_curchar == '/' && (*next == '/' || *next == '*'))) {
5221
parse_err(SYNERR, "unimplemented: comment token in a funny place");
5224
while(_curline != nullptr) {
5225
if (*_ptr == '\n') {
5226
if (!do_preproc) break;
5228
_ptr = _curline; if (_ptr != nullptr) next = _ptr + 1;
5230
else if ((*_ptr == '/') && (*next == '/'))
5231
do { _ptr++; next++; } while(*_ptr != '\n');
5232
else if ((*_ptr == '/') && (*next == '*')) {
5236
if (*_ptr == '\n') {
5238
if (_curline == nullptr) {
5239
parse_err(SYNERR, "end-of-file detected inside comment\n");
5242
_ptr = _curline; next = _ptr + 1;
5244
} while(!((*_ptr == '*') && (*next == '/')));
5245
_ptr = ++next; next++;
5247
else if (do_preproc && *_ptr == '#') {
5249
bool preproc_handled = handle_preproc_token();
5250
if (!preproc_handled) {
5251
if (preproc_taken()) {
5257
} else if(*_ptr > ' ' && !(do_preproc && !preproc_taken())) {
5260
else if (*_ptr == '"' || *_ptr == '\'') {
5261
assert(do_preproc, "only skip strings if doing preproc");
5266
if (*_ptr == qchar) { ++_ptr; break; }
5267
if (*_ptr == '\\') ++_ptr;
5268
if (*_ptr == '\n' || *_ptr == '\0') {
5269
parse_err(SYNERR, "newline in string");
5275
else { ++_ptr; ++next; }
5277
if (_curline != nullptr) {
5283
char ADLParser::cur_char() {
5288
void ADLParser::next_char() {
5289
if (_curchar == '\n') parse_err(WARN, "must call next_line!");
5297
void ADLParser::next_char_or_line() {
5298
if ( _curchar != '\n' ) {
5308
void ADLParser::next_line() {
5309
_curline = _buf.get_line();
5316
char* ADLParser::get_line_string(int linenum) {
5317
const char* file = _AD._ADL_file._name;
5318
int line = linenum ? linenum : this->linenum();
5319
const size_t location_size = strlen(file) + 100;
5320
char* location = (char *)AdlAllocateHeap(location_size);
5321
snprintf_checked(location, location_size, "\n#line %d \"%s\"\n", line, file);
5326
bool ADLParser::is_literal_constant(const char *param) {
5327
if (param[0] == 0) return false;
5328
if (param[0] == '(') return true;
5329
if (param[0] == '0' && (param[1] == 'x' || param[1] == 'X')) {
5333
if( !ADLParser::is_hex_digit(*(param+i)) ) return false;
5335
} while( *(param+i) != 0 );
5342
bool ADLParser::is_hex_digit(char digit) {
5343
return ((digit >= '0') && (digit <= '9'))
5344
||((digit >= 'a') && (digit <= 'f'))
5345
||((digit >= 'A') && (digit <= 'F'));
5349
bool ADLParser::is_int_token(const char* token, int& intval) {
5350
const char* cp = token;
5351
while (*cp != '\0' && *cp <= ' ') cp++;
5352
if (*cp == '-') cp++;
5354
while (*cp >= '0' && *cp <= '9') { cp++; ndigit++; }
5355
while (*cp != '\0' && *cp <= ' ') cp++;
5356
if (ndigit == 0 || *cp != '\0') {
5359
intval = atoi(token);
5363
static const char* skip_expr_ws(const char* str) {
5364
const char * cp = str;
5368
} else if (cp[0] == '#') {
5370
while (cp[0] == ' ') ++cp;
5371
assert(0 == strncmp(cp, "line", 4), "must be a #line directive");
5372
const char* eol = strchr(cp, '\n');
5373
assert(eol != nullptr, "must find end of line");
5374
if (eol == nullptr) eol = cp + strlen(cp);
5384
bool ADLParser::equivalent_expressions(const char* str1, const char* str2) {
5387
else if (str1 == nullptr || str2 == nullptr)
5389
const char* cp1 = str1;
5390
const char* cp2 = str2;
5391
char in_quote = '\0';
5392
while (cp1[0] && cp2[0]) {
5395
const char* cp1a = skip_expr_ws(cp1);
5396
const char* cp2a = skip_expr_ws(cp2);
5397
if (cp1a > cp1 && cp2a > cp2) {
5398
cp1 = cp1a; cp2 = cp2a;
5401
if (cp1a > cp1 || cp2a > cp2) break;
5404
if (cp1[0] != cp2[0]) break;
5408
if (in_quote && ch == '\\') {
5409
if (cp1[0] != cp2[0]) break;
5413
if (in_quote && ch == in_quote) {
5415
} else if (!in_quote && (ch == '"' || ch == '\'')) {
5419
return (!cp1[0] && !cp2[0]);
5424
void ADLParser::trim(char* &token) {
5425
while (*token <= ' ') token++;
5426
char* end = token + strlen(token);
5427
while (end > token && *(end-1) <= ' ') --end;