783 void ADLParser::reg_parse(void) {
784 RegisterForm *regBlock = _AD.get_registers(); // Information about registers encoding
785 if (regBlock == NULL) {
786 // Create the RegisterForm for the architecture description.
787 regBlock = new RegisterForm(); // Build new Source object
788 _AD.addForm(regBlock);
789 }
790
791 skipws(); // Skip leading whitespace
792 if (_curchar == '%' && *(_ptr+1) == '{') {
793 next_char(); next_char(); // Skip "%{"
794 skipws();
795 while (_curchar != '%' && *(_ptr+1) != '}') {
796 char *token = get_ident();
797 if (token == NULL) {
798 parse_err(SYNERR, "missing identifier inside register block.\n");
799 return;
800 }
801 if (strcmp(token,"reg_def")==0) { reg_def_parse(); }
802 else if (strcmp(token,"reg_class")==0) { reg_class_parse(); }
803 else if (strcmp(token,"alloc_class")==0) { alloc_class_parse(); }
804 else if (strcmp(token,"#define")==0) { preproc_define(); }
805 else { parse_err(SYNERR, "bad token %s inside register block.\n", token); break; }
806 skipws();
807 }
808 }
809 else {
810 parse_err(SYNERR, "Missing %c{ ... %c} block after register keyword.\n",'%','%');
811 return;
812 }
813 }
814
815 //------------------------------encode_parse-----------------------------------
816 void ADLParser::encode_parse(void) {
817 EncodeForm *encBlock; // Information about instruction/operand encoding
818
819 _AD.getForm(&encBlock);
820 if ( encBlock == NULL) {
821 // Create the EncodeForm for the architecture description.
822 encBlock = new EncodeForm(); // Build new Source object
2306
2307 // Record new register definition.
2308 _AD._register->addRegDef(rname, callconv, c_conv, idealtype, encoding, concrete);
2309 return;
2310 }
2311
2312 //------------------------------reg_class_parse--------------------------------
2313 void ADLParser::reg_class_parse(void) {
2314 char *cname; // Name of register class being defined
2315
2316 // Get register class name
2317 skipws(); // Skip leading whitespace
2318 cname = get_ident();
2319 if (cname == NULL) {
2320 parse_err(SYNERR, "missing register class name after 'reg_class'\n");
2321 return;
2322 }
2323 // Debug Stuff
2324 if (_AD._adl_debug >1) fprintf(stderr,"Register Class: %s\n", cname);
2325
2326 RegClass *reg_class = _AD._register->addRegClass(cname);
2327
2328 // Collect registers in class
2329 skipws();
2330 if (_curchar == '(') {
2331 next_char(); // Skip '('
2332 skipws();
2333 while (_curchar != ')') {
2334 char *rname = get_ident();
2335 if (rname==NULL) {
2336 parse_err(SYNERR, "missing identifier inside reg_class list.\n");
2337 return;
2338 }
2339 RegDef *regDef = _AD._register->getRegDef(rname);
2340 if (!regDef) {
2341 parse_err(SEMERR, "unknown identifier %s inside reg_class list.\n", rname);
2342 } else {
2343 reg_class->addReg(regDef); // add regDef to regClass
2344 }
2345
2346 // Check for ',' and position to next token.
2347 skipws();
2348 if (_curchar == ',') {
2349 next_char(); // Skip trailing ','
2350 skipws();
2351 }
2352 }
2353 next_char(); // Skip closing ')'
2354 } else if (_curchar == '%') {
2355 char *code = find_cpp_block("reg class");
2356 if (code == NULL) {
2357 parse_err(SYNERR, "missing code declaration for reg class.\n");
2358 return;
2359 }
2360 reg_class->_user_defined = code;
2361 return;
2362 }
2363
2364 // Check for terminating ';'
2365 skipws();
2366 if (_curchar != ';') {
2367 parse_err(SYNERR, "missing ';' at end of reg_class definition.\n");
2368 return;
2369 }
2370 next_char(); // Skip trailing ';'
2371
2372 // Check RegClass size, must be <= 32 registers in class.
2373
2374 return;
2375 }
2376
2377 //------------------------------alloc_class_parse------------------------------
2378 void ADLParser::alloc_class_parse(void) {
2379 char *name; // Name of allocation class being defined
2380
2381 // Get allocation class name
2382 skipws(); // Skip leading whitespace
2383 name = get_ident();
2384 if (name == NULL) {
2385 parse_err(SYNERR, "missing allocation class name after 'reg_class'\n");
2386 return;
2387 }
2388 // Debug Stuff
2389 if (_AD._adl_debug >1) fprintf(stderr,"Allocation Class: %s\n", name);
2390
2391 AllocClass *alloc_class = _AD._register->addAllocClass(name);
2392
|
783 void ADLParser::reg_parse(void) {
784 RegisterForm *regBlock = _AD.get_registers(); // Information about registers encoding
785 if (regBlock == NULL) {
786 // Create the RegisterForm for the architecture description.
787 regBlock = new RegisterForm(); // Build new Source object
788 _AD.addForm(regBlock);
789 }
790
791 skipws(); // Skip leading whitespace
792 if (_curchar == '%' && *(_ptr+1) == '{') {
793 next_char(); next_char(); // Skip "%{"
794 skipws();
795 while (_curchar != '%' && *(_ptr+1) != '}') {
796 char *token = get_ident();
797 if (token == NULL) {
798 parse_err(SYNERR, "missing identifier inside register block.\n");
799 return;
800 }
801 if (strcmp(token,"reg_def")==0) { reg_def_parse(); }
802 else if (strcmp(token,"reg_class")==0) { reg_class_parse(); }
803 else if (strcmp(token, "reg_class_dynamic") == 0) { reg_class_dynamic_parse(); }
804 else if (strcmp(token,"alloc_class")==0) { alloc_class_parse(); }
805 else if (strcmp(token,"#define")==0) { preproc_define(); }
806 else { parse_err(SYNERR, "bad token %s inside register block.\n", token); break; }
807 skipws();
808 }
809 }
810 else {
811 parse_err(SYNERR, "Missing %c{ ... %c} block after register keyword.\n",'%','%');
812 return;
813 }
814 }
815
816 //------------------------------encode_parse-----------------------------------
817 void ADLParser::encode_parse(void) {
818 EncodeForm *encBlock; // Information about instruction/operand encoding
819
820 _AD.getForm(&encBlock);
821 if ( encBlock == NULL) {
822 // Create the EncodeForm for the architecture description.
823 encBlock = new EncodeForm(); // Build new Source object
2307
2308 // Record new register definition.
2309 _AD._register->addRegDef(rname, callconv, c_conv, idealtype, encoding, concrete);
2310 return;
2311 }
2312
2313 //------------------------------reg_class_parse--------------------------------
2314 void ADLParser::reg_class_parse(void) {
2315 char *cname; // Name of register class being defined
2316
2317 // Get register class name
2318 skipws(); // Skip leading whitespace
2319 cname = get_ident();
2320 if (cname == NULL) {
2321 parse_err(SYNERR, "missing register class name after 'reg_class'\n");
2322 return;
2323 }
2324 // Debug Stuff
2325 if (_AD._adl_debug >1) fprintf(stderr,"Register Class: %s\n", cname);
2326
2327 skipws();
2328 if (_curchar == '(') {
2329 // A register list is defined for the register class.
2330 // Collect registers into a generic RegClass register class.
2331 RegClass* reg_class = _AD._register->addRegClass<RegClass>(cname);
2332
2333 next_char(); // Skip '('
2334 skipws();
2335 while (_curchar != ')') {
2336 char *rname = get_ident();
2337 if (rname==NULL) {
2338 parse_err(SYNERR, "missing identifier inside reg_class list.\n");
2339 return;
2340 }
2341 RegDef *regDef = _AD._register->getRegDef(rname);
2342 if (!regDef) {
2343 parse_err(SEMERR, "unknown identifier %s inside reg_class list.\n", rname);
2344 } else {
2345 reg_class->addReg(regDef); // add regDef to regClass
2346 }
2347
2348 // Check for ',' and position to next token.
2349 skipws();
2350 if (_curchar == ',') {
2351 next_char(); // Skip trailing ','
2352 skipws();
2353 }
2354 }
2355 next_char(); // Skip closing ')'
2356 } else if (_curchar == '%') {
2357 // A code snippet is defined for the register class.
2358 // Collect the code snippet into a CodeSnippetRegClass register class.
2359 CodeSnippetRegClass* reg_class = _AD._register->addRegClass<CodeSnippetRegClass>(cname);
2360 char *code = find_cpp_block("reg class");
2361 if (code == NULL) {
2362 parse_err(SYNERR, "missing code declaration for reg class.\n");
2363 return;
2364 }
2365 reg_class->set_code_snippet(code);
2366 return;
2367 }
2368
2369 // Check for terminating ';'
2370 skipws();
2371 if (_curchar != ';') {
2372 parse_err(SYNERR, "missing ';' at end of reg_class definition.\n");
2373 return;
2374 }
2375 next_char(); // Skip trailing ';'
2376
2377 // Check RegClass size, must be <= 32 registers in class.
2378
2379 return;
2380 }
2381
2382 //------------------------------reg_class_dynamic_parse------------------------
2383 void ADLParser::reg_class_dynamic_parse(void) {
2384 char *cname; // Name of dynamic register class being defined
2385
2386 // Get register class name
2387 skipws();
2388 cname = get_ident();
2389 if (cname == NULL) {
2390 parse_err(SYNERR, "missing dynamic register class name after 'reg_class_dynamic'\n");
2391 return;
2392 }
2393
2394 if (_AD._adl_debug > 1) {
2395 fprintf(stdout, "Dynamic Register Class: %s\n", cname);
2396 }
2397
2398 skipws();
2399 if (_curchar != '(') {
2400 parse_err(SYNERR, "missing '(' at the beginning of reg_class_dynamic definition\n");
2401 return;
2402 }
2403 next_char();
2404 skipws();
2405
2406 // Collect two register classes and the C++ code representing the condition code used to
2407 // select between the two classes into a ConditionalRegClass register class.
2408 ConditionalRegClass* reg_class = _AD._register->addRegClass<ConditionalRegClass>(cname);
2409 int i;
2410 for (i = 0; i < 2; i++) {
2411 char* name = get_ident();
2412 if (name == NULL) {
2413 parse_err(SYNERR, "missing class identifier inside reg_class_dynamic list.\n");
2414 return;
2415 }
2416 RegClass* rc = _AD._register->getRegClass(name);
2417 if (rc == NULL) {
2418 parse_err(SEMERR, "unknown identifier %s inside reg_class_dynamic list.\n", name);
2419 } else {
2420 reg_class->set_rclass_at_index(i, rc);
2421 }
2422
2423 skipws();
2424 if (_curchar == ',') {
2425 next_char();
2426 skipws();
2427 } else {
2428 parse_err(SYNERR, "missing separator ',' inside reg_class_dynamic list.\n");
2429 }
2430 }
2431
2432 // Collect the condition code.
2433 skipws();
2434 if (_curchar == '%') {
2435 char* code = find_cpp_block("reg class dynamic");
2436 if (code == NULL) {
2437 parse_err(SYNERR, "missing code declaration for reg_class_dynamic.\n");
2438 return;
2439 }
2440 reg_class->set_condition_code(code);
2441 } else {
2442 parse_err(SYNERR, "missing %% at the beginning of code block in reg_class_dynamic definition\n");
2443 return;
2444 }
2445
2446 skipws();
2447 if (_curchar != ')') {
2448 parse_err(SYNERR, "missing ')' at the end of reg_class_dynamic definition\n");
2449 return;
2450 }
2451 next_char();
2452
2453 skipws();
2454 if (_curchar != ';') {
2455 parse_err(SYNERR, "missing ';' at the end of reg_class_dynamic definition.\n");
2456 return;
2457 }
2458 next_char(); // Skip trailing ';'
2459
2460 return;
2461 }
2462
2463 //------------------------------alloc_class_parse------------------------------
2464 void ADLParser::alloc_class_parse(void) {
2465 char *name; // Name of allocation class being defined
2466
2467 // Get allocation class name
2468 skipws(); // Skip leading whitespace
2469 name = get_ident();
2470 if (name == NULL) {
2471 parse_err(SYNERR, "missing allocation class name after 'reg_class'\n");
2472 return;
2473 }
2474 // Debug Stuff
2475 if (_AD._adl_debug >1) fprintf(stderr,"Allocation Class: %s\n", name);
2476
2477 AllocClass *alloc_class = _AD._register->addAllocClass(name);
2478
|