1/* hppa-aux.c -- Assembler for the PA - PA-RISC specific support routines 2 Copyright (C) 1989 Free Software Foundation, Inc. 3 4This file is part of GAS, the GNU Assembler. 5 6GAS is free software; you can redistribute it and/or modify 7it under the terms of the GNU General Public License as published by 8the Free Software Foundation; either version 1, or (at your option) 9any later version. 10 11GAS is distributed in the hope that it will be useful, 12but WITHOUT ANY WARRANTY; without even the implied warranty of 13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14GNU General Public License for more details. 15 16You should have received a copy of the GNU General Public License 17along with GAS; see the file COPYING. If not, write to 18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ 19 20/* 21 HP PA-RISC support was contributed by the Center for Software Science 22 at the University of Utah. 23 */ 24 25#include <stdio.h> 26#include <string.h> 27#include <ctype.h> 28 29#include "obstack.h" 30#include "as.h" 31#include "frags.h" 32#include "flonum.h" 33#include "expr.h" 34#include "hash.h" 35#include "md.h" 36#include "symbols.h" 37#include "messages.h" 38#include "hppa-aux.h" 39#include "stuff/hppa.h" 40 41extern char *expr_end; /* defined in hppa.c */ 42 43static const int print_errors = 1; 44 45static int reg_name_search( 46 char *name); 47 48int pa_parse_number(s) 49 char **s; 50{ 51 int num; 52 char *name; 53 char c; 54 symbolS *sym; 55 int status; 56 char * p = *s; 57 58 while ( *p == ' ' || *p == '\t' ) 59 p = p + 1; 60 num=-1; /* assume invalid number to begin with */ 61 if (isdigit(*p)) { 62 num = 0; /* now we know it is a number */ 63 64 if ( *p == '0' 65 && ( *(p+1) == 'x' || *(p+1) == 'X' ) ) { /* hex input */ 66 p = p + 2; 67 while ( isdigit(*p) || ( (*p >= 'a') && (*p <= 'f') ) 68 || ( (*p >= 'A') && (*p <= 'F') ) ){ 69 if ( isdigit(*p) ) 70 num = num*16 + *p-'0'; 71 else if ( *p >= 'a' && *p <= 'f' ) 72 num = num*16 + *p-'a' + 10; 73 else 74 num = num*16 + *p-'A' + 10; 75 ++p; 76 } 77 } 78 else { 79 while (isdigit(*p)) { 80 num= num*10 + *p-'0'; 81 ++p; 82 } 83 } 84 } 85 else if ( *p == '%' ) { /* could be a pre-defined register */ 86 num = 0; 87 name = p; 88 p++; 89 c = *p; 90 91 /* 92 * tege hack: Special case for general registers as the 93 * general code makes a binary search with case translation, 94 * and is VERY slow. 95 */ 96 if (c == 'r') { 97 p++; 98 if (!isdigit(*p)) 99 as_bad("Undefined register: '%s'. ASSUMING 0",name); 100 else { 101 do 102 num= num*10 + *p++ - '0'; 103 while (isdigit(*p)); 104 } 105 } 106 else { 107 while ( is_part_of_name(c) ) { 108 p = p + 1; 109 c = *p; 110 } 111 /* Terminate string with \0. Restore below. */ 112 *p = 0; 113 status = reg_name_search(name); 114 if ( status >= 0 ) 115 num = status; 116 else { 117 if ( print_errors ) 118 as_bad("Undefined register: '%s'. ASSUMING 0",name); 119 else 120 num = -1; 121 } 122 /* Restore orignal value of string. */ 123 *p = c; 124 } 125 } 126 else { 127 num = 0; 128 name = p; 129 c = *p; 130 while ( is_part_of_name(c) ) { 131 p = p + 1; 132 c = *p; 133 } 134 *p = 0; 135 if ( (sym = symbol_table_lookup(name)) != NULL ) { 136 if ( sym->sy_type == N_ABS && sym->sy_other == NO_SECT ) { 137 num = sym->sy_value; 138 } 139 else { 140 if ( print_errors ) 141 as_bad("Non-absolute constant: '%s'. ASSUMING 0",name); 142 else 143 num = -1; 144 } 145 } 146 else { 147 if ( print_errors ) 148 as_bad("Undefined absolute constant: '%s'. ASSUMING 0",name); 149 else 150 num = -1; 151 } 152 *p = c; 153 } 154 155 *s = p; 156 return num; 157} 158 159struct pd_reg { 160 char *name; 161 int value; 162}; 163 164/* List of registers that are pre-defined: 165 166 General Registers: 167 168 Name Value Name Value 169 %r0 0 %r16 16 170 %r1 1 %r17 17 171 %r2 2 %r18 18 172 %r3 3 %r19 19 173 %r4 4 %r20 20 174 %r5 5 %r21 21 175 %r6 6 %r22 22 176 %r7 7 %r23 23 177 %r8 8 %r24 24 178 %r9 9 %r25 25 179 %r10 10 %r26 26 180 %r11 11 %r27 27 181 %r12 12 %r28 28 182 %r13 13 %r29 29 183 %r14 14 %r30 30 184 %r15 15 %r31 31 185 186 Floating-point Registers: 187 [NOTE: Also includes L and R versions of these (e.g. %fr19L, %fr19R)] 188 189 Name Value Name Value 190 %fr0 0 %fr16 16 191 %fr1 1 %fr17 17 192 %fr2 2 %fr18 18 193 %fr3 3 %fr19 19 194 %fr4 4 %fr20 20 195 %fr5 5 %fr21 21 196 %fr6 6 %fr22 22 197 %fr7 7 %fr23 23 198 %fr8 8 %fr24 24 199 %fr9 9 %fr25 25 200 %fr10 10 %fr26 26 201 %fr11 11 %fr27 27 202 %fr12 12 %fr28 28 203 %fr13 13 %fr29 29 204 %fr14 14 %fr30 30 205 %fr15 15 %fr31 31 206 207 Space Registers: 208 209 Name Value Name Value 210 %sr0 0 %sr4 4 211 %sr1 1 %sr5 5 212 %sr2 2 %sr6 6 213 %sr3 3 %sr7 7 214 215 Control registers and their synonyms: 216 217 Names Value 218 %cr0 %rctr 0 219 %cr8 %pidr1 8 220 %cr9 %pidr2 9 221 %cr10 %ccr 10 222 %cr11 %sar 11 223 %cr12 %pidr3 12 224 %cr13 %pidr4 13 225 %cr14 %iva 14 226 %cr15 %eiem 15 227 %cr16 %itmr 16 228 %cr17 %pcsq 17 229 %cr18 %pcoq 18 230 %cr19 %iir 19 231 %cr20 %isr 20 232 %cr21 %ior 21 233 %cr22 %ipsw 22 234 %cr23 %eirr 23 235 %cr24 %tr0 %ppda 24 236 %cr25 %tr1 %hta 25 237 %cr26 %tr2 26 238 %cr27 %tr3 27 239 %cr28 %tr4 28 240 %cr29 %tr5 29 241 %cr30 %tr6 30 242 %cr31 %tr7 31 243 244*/ 245 246/* This table is sorted. Suitable for searching by a binary search. */ 247 248static struct pd_reg pre_defined_registers[] = { 249 { "%ccr", 10 }, 250 { "%cr0", 0 }, 251 { "%cr10", 10 }, 252 { "%cr11", 11 }, 253 { "%cr12", 12 }, 254 { "%cr13", 13 }, 255 { "%cr14", 14 }, 256 { "%cr15", 15 }, 257 { "%cr16", 16 }, 258 { "%cr17", 17 }, 259 { "%cr18", 18 }, 260 { "%cr19", 19 }, 261 { "%cr20", 20 }, 262 { "%cr21", 21 }, 263 { "%cr22", 22 }, 264 { "%cr23", 23 }, 265 { "%cr24", 24 }, 266 { "%cr25", 25 }, 267 { "%cr26", 26 }, 268 { "%cr27", 27 }, 269 { "%cr28", 28 }, 270 { "%cr29", 29 }, 271 { "%cr30", 30 }, 272 { "%cr31", 31 }, 273 { "%cr8", 8 }, 274 { "%cr9", 9 }, 275 { "%eiem", 15 }, 276 { "%eirr", 23 }, 277 { "%fr0", 0 }, 278 { "%fr0L", 0 }, 279 { "%fr0R", 0 }, 280 { "%fr1", 1 }, 281 { "%fr10", 10 }, 282 { "%fr10L", 10 }, 283 { "%fr10R", 10 }, 284 { "%fr11", 11 }, 285 { "%fr11L", 11 }, 286 { "%fr11R", 11 }, 287 { "%fr12", 12 }, 288 { "%fr12L", 12 }, 289 { "%fr12R", 12 }, 290 { "%fr13", 13 }, 291 { "%fr13L", 13 }, 292 { "%fr13R", 13 }, 293 { "%fr14", 14 }, 294 { "%fr14L", 14 }, 295 { "%fr14R", 14 }, 296 { "%fr15", 15 }, 297 { "%fr15L", 15 }, 298 { "%fr15R", 15 }, 299 { "%fr16", 16 }, 300 { "%fr16L", 16 }, 301 { "%fr16R", 16 }, 302 { "%fr17", 17 }, 303 { "%fr17L", 17 }, 304 { "%fr17R", 17 }, 305 { "%fr18", 18 }, 306 { "%fr18L", 18 }, 307 { "%fr18R", 18 }, 308 { "%fr19", 19 }, 309 { "%fr19L", 19 }, 310 { "%fr19R", 19 }, 311 { "%fr1L", 1 }, 312 { "%fr1R", 1 }, 313 { "%fr2", 2 }, 314 { "%fr20", 20 }, 315 { "%fr20L", 20 }, 316 { "%fr20R", 20 }, 317 { "%fr21", 21 }, 318 { "%fr21L", 21 }, 319 { "%fr21R", 21 }, 320 { "%fr22", 22 }, 321 { "%fr22L", 22 }, 322 { "%fr22R", 22 }, 323 { "%fr23", 23 }, 324 { "%fr23L", 23 }, 325 { "%fr23R", 23 }, 326 { "%fr24", 24 }, 327 { "%fr24L", 24 }, 328 { "%fr24R", 24 }, 329 { "%fr25", 25 }, 330 { "%fr25L", 25 }, 331 { "%fr25R", 25 }, 332 { "%fr26", 26 }, 333 { "%fr26L", 26 }, 334 { "%fr26R", 26 }, 335 { "%fr27", 27 }, 336 { "%fr27L", 27 }, 337 { "%fr27R", 27 }, 338 { "%fr28", 28 }, 339 { "%fr28L", 28 }, 340 { "%fr28R", 28 }, 341 { "%fr29", 29 }, 342 { "%fr29L", 29 }, 343 { "%fr29R", 29 }, 344 { "%fr2L", 2 }, 345 { "%fr2R", 2 }, 346 { "%fr3", 3 }, 347 { "%fr30", 30 }, 348 { "%fr30L", 30 }, 349 { "%fr30R", 30 }, 350 { "%fr31", 31 }, 351 { "%fr31L", 31 }, 352 { "%fr31R", 31 }, 353 { "%fr3L", 3 }, 354 { "%fr3R", 3 }, 355 { "%fr4", 4 }, 356 { "%fr4L", 4 }, 357 { "%fr4R", 4 }, 358 { "%fr5", 5 }, 359 { "%fr5L", 5 }, 360 { "%fr5R", 5 }, 361 { "%fr6", 6 }, 362 { "%fr6L", 6 }, 363 { "%fr6R", 6 }, 364 { "%fr7", 7 }, 365 { "%fr7L", 7 }, 366 { "%fr7R", 7 }, 367 { "%fr8", 8 }, 368 { "%fr8L", 8 }, 369 { "%fr8R", 8 }, 370 { "%fr9", 9 }, 371 { "%fr9L", 9 }, 372 { "%fr9R", 9 }, 373 { "%hta", 25 }, 374 { "%iir", 19 }, 375 { "%ior", 21 }, 376 { "%ipsw", 22 }, 377 { "%isr", 20 }, 378 { "%itmr", 16 }, 379 { "%iva", 14 }, 380 { "%pcoq", 18 }, 381 { "%pcsq", 17 }, 382 { "%pidr1", 8 }, 383 { "%pidr2", 9 }, 384 { "%pidr3", 12 }, 385 { "%pidr4", 13 }, 386 { "%ppda", 24 }, 387 { "%r0", 0 }, 388 { "%r1", 1 }, 389 { "%r10", 10 }, 390 { "%r11", 11 }, 391 { "%r12", 12 }, 392 { "%r13", 13 }, 393 { "%r14", 14 }, 394 { "%r15", 15 }, 395 { "%r16", 16 }, 396 { "%r17", 17 }, 397 { "%r18", 18 }, 398 { "%r19", 19 }, 399 { "%r2", 2 }, 400 { "%r20", 20 }, 401 { "%r21", 21 }, 402 { "%r22", 22 }, 403 { "%r23", 23 }, 404 { "%r24", 24 }, 405 { "%r25", 25 }, 406 { "%r26", 26 }, 407 { "%r27", 27 }, 408 { "%r28", 28 }, 409 { "%r29", 29 }, 410 { "%r3", 3 }, 411 { "%r30", 30 }, 412 { "%r31", 31 }, 413 { "%r4", 4 }, 414 { "%r4L", 4 }, 415 { "%r4R", 4 }, 416 { "%r5", 5 }, 417 { "%r5L", 5 }, 418 { "%r5R", 5 }, 419 { "%r6", 6 }, 420 { "%r6L", 6 }, 421 { "%r6R", 6 }, 422 { "%r7", 7 }, 423 { "%r7L", 7 }, 424 { "%r7R", 7 }, 425 { "%r8", 8 }, 426 { "%r8L", 8 }, 427 { "%r8R", 8 }, 428 { "%r9", 9 }, 429 { "%r9L", 9 }, 430 { "%r9R", 9 }, 431 { "%rctr", 0 }, 432 { "%sar", 11 }, 433 { "%sr0", 0 }, 434 { "%sr1", 1 }, 435 { "%sr2", 2 }, 436 { "%sr3", 3 }, 437 { "%sr4", 4 }, 438 { "%sr5", 5 }, 439 { "%sr6", 6 }, 440 { "%sr7", 7 }, 441 { "%tr0", 24 }, 442 { "%tr1", 25 }, 443 { "%tr2", 26 }, 444 { "%tr3", 27 }, 445 { "%tr4", 28 }, 446 { "%tr5", 9 }, 447 { "%tr6", 30 }, 448 { "%tr7", 31 } 449}; 450 451#define REG_NAME_CNT (sizeof(pre_defined_registers) / sizeof(struct pd_reg)) 452 453static 454int 455reg_name_search( 456char *name) 457{ 458 int x,l,r; 459 460 l = 0; 461 r = REG_NAME_CNT - 1; 462 463 do { 464 x = (l + r) / 2; 465 if (strcasecmp(name,pre_defined_registers[x].name) < 0) 466 r = x - 1; 467 else 468 l = x + 1; 469 } while ( !( (strcasecmp(name,pre_defined_registers[x].name) == 0) || 470 (l > r) ) ); 471 472 if ( strcasecmp(name,pre_defined_registers[x].name) == 0 ) 473 return(pre_defined_registers[x].value); 474 else 475 return(-1); 476 477} 478 479static 480int 481is_R_select( 482char *s) 483{ 484 485 if ( *s == 'R' || *s == 'r' ) 486 return(TRUE); 487 else 488 return(FALSE); 489} 490 491static 492int 493is_L_select( 494char *s) 495{ 496 497 if ( *s == 'L' || *s == 'l' ) 498 return(TRUE); 499 else 500 return(FALSE); 501} 502 503int need_89_opcode(insn,result) 504 struct pa_it *insn; 505 struct pa_89_fp_reg_struct *result; 506{ 507 if ( result->L_R_select == 1 && !(insn->fpof1 == DBL && insn->fpof2 == DBL) ) 508 return TRUE; 509 else 510 return FALSE; 511} 512 513int 514pa_89_parse_number(s,result) 515 char **s; 516 struct pa_89_fp_reg_struct *result; 517{ 518 int num; 519 char *name; 520 char c; 521 symbolS *sym; 522 int status; 523 char * p = *s; 524 525 while ( *p == ' ' || *p == '\t' ) 526 p = p + 1; 527 num=-1; /* assume invalid number to begin with */ 528 result->number_part = -1; 529 result->L_R_select = -1; 530 531 if (isdigit(*p)) { 532 num = 0; /* now we know it is a number */ 533 534 if ( *p == '0' && ( *(p+1) == 'x' || *(p+1) == 'X' ) ) { /* hex input */ 535 p = p + 2; 536 while ( isdigit(*p) 537 || ( (*p >= 'a') && (*p <= 'f') ) 538 || ( (*p >= 'A') && (*p <= 'F') ) ){ 539 if ( isdigit(*p) ) 540 num = num*16 + *p-'0'; 541 else if ( *p >= 'a' && *p <= 'f' ) 542 num = num*16 + *p-'a' + 10; 543 else 544 num = num*16 + *p-'A' + 10; 545 ++p; 546 } 547 } 548 else { 549 while (isdigit(*p)) { 550 num= num*10 + *p-'0'; 551 ++p; 552 } 553 } 554 555 result->number_part = num; 556 557 if ( is_R_select(p) ) { 558 result->L_R_select = 1; 559 ++p; 560 } 561 else if ( is_L_select(p) ) { 562 result->L_R_select = 0; 563 ++p; 564 } 565 else 566 result->L_R_select = 0; 567 568 } 569 else if ( *p == '%' ) { /* could be a pre-defined register */ 570 num = 0; 571 name = p; 572 p = p + 1; 573 c = *p; 574 /* tege hack: Special case for general registers 575 as the general code makes a binary search with case translation, 576 and is VERY slow. */ 577 if (c == 'r') { 578 p++; 579 if (!isdigit(*p)) 580 as_bad("Undefined register: '%s'. ASSUMING 0",name); 581 else { 582 do 583 num= num*10 + *p++ - '0'; 584 while (isdigit(*p)); 585 } 586 } 587 else { 588 while ( is_part_of_name(c) ) { 589 p = p + 1; 590 c = *p; 591 } 592 /* Terminate string with \0. Restore below. */ 593 *p = 0; 594 status = reg_name_search(name); 595 if ( status >= 0 ) 596 num = status; 597 else { 598 if ( print_errors ) 599 as_bad("Undefined register: '%s'. ASSUMING 0",name); 600 else 601 num = -1; 602 } 603 *p = c; 604 } 605 606 result->number_part = num; 607 608 if ( is_R_select(p-1) ) 609 result->L_R_select = 1; 610 else if ( is_L_select(p-1) ) 611 result->L_R_select = 0; 612 else 613 result->L_R_select = 0; 614 615 } 616 else { 617 num = 0; 618 name = p; 619 c = *p; 620 while ( is_part_of_name(c) ) { 621 p = p + 1; 622 c = *p; 623 } 624 *p = 0; 625 if ( (sym = symbol_table_lookup(name)) != NULL ) { 626 if ( sym->sy_type == N_ABS && sym->sy_other == NO_SECT ) { 627 num = sym->sy_value; 628 } 629 else { 630 if ( print_errors ) 631 as_bad("Non-absolute constant: '%s'. ASSUMING 0",name); 632 else 633 num = -1; 634 } 635 } 636 else { 637 if ( print_errors ) 638 as_bad("Undefined absolute constant: '%s'. ASSUMING 0",name); 639 else 640 num = -1; 641 } 642 *p = c; 643 644 result->number_part = num; 645 646 if ( is_R_select(p-1) ) { 647 result->L_R_select = 1; 648 } 649 else if ( is_L_select(p-1) ) { 650 result->L_R_select = 0; 651 } 652 else 653 result->L_R_select = 0; 654 } 655 656 *s = p; 657 return num; 658 659} 660 661int pa_parse_fp_cmp_cond(s) 662 char **s; 663{ 664 int cond,i; 665 struct possibleS { 666 char *string; 667 int cond; 668 }; 669 670 /* 671 This table is sorted by order of the length of the string. This is so we 672 check for <> before we check for <. If we had a <> and checked for < first, 673 we would get a false match. 674 */ 675 static struct possibleS poss[] = 676 { 677 { "false?", 0 }, 678 { "false", 1 }, 679 { "true?", 30 }, 680 { "true", 31 }, 681 { "!<=>", 3 }, 682 { "!?>=", 8 }, 683 { "!?<=", 16 }, 684 { "!<>", 7 }, 685 { "!>=", 11 }, 686 { "!?>", 12 }, 687 { "?<=", 14 }, 688 { "!<=", 19 }, 689 { "!?<", 20 }, 690 { "?>=", 22 }, 691 { "!?=", 24 }, 692 { "!=t", 27 }, 693 { "<=>", 29 }, 694 { "=t", 5 }, 695 { "?=", 6 }, 696 { "?<", 10 }, 697 { "<=", 13 }, 698 { "!>", 15 }, 699 { "?>", 18 }, 700 { ">=", 21 }, 701 { "!<", 23 }, 702 { "<>", 25 }, 703 { "!=", 26 }, 704 { "!?", 28 }, 705 { "?", 2 }, 706 { "=", 4 }, 707 { "<", 9 }, 708 { ">", 17 } 709 }; 710 711 cond=0; 712 713 for ( i = 0; i < 32; i++ ) { 714 if ( strncasecmp(*s,poss[i].string,strlen(poss[i].string)) == 0 ) { 715 cond = poss[i].cond; 716 *s += strlen(poss[i].string); 717 while ( **s == ' ' || **s == '\t' ) 718 *s = *s + 1; 719 return cond; 720 } 721 } 722 723 as_bad("Illegal FP Compare Condition: %c",**s); 724 return 0; 725} 726 727FP_Operand_Format pa_parse_fp_format(s) 728 char **s; 729{ 730 int f; 731 732 f = SGL; 733 if ( **s == ',' ) { 734 *s += 1; 735 if ( strncasecmp(*s,"sgl",3) == 0 ) { 736 f = SGL; 737 *s += 4; 738 } 739 else if ( strncasecmp(*s,"dbl",3) == 0 ) { 740 f = DBL; 741 *s += 4; 742 } 743 else if ( strncasecmp(*s,"quad",4) == 0 ) { 744 f = QUAD; 745 *s += 5; 746 } 747 else { 748 f = ILLEGAL_FMT; 749 as_bad("Unrecognized FP Operand Format: %3s",*s); 750 } 751 } 752 while ( **s == ' ' || **s == '\t' || **s == 0 ) 753 *s = *s + 1; 754 755 return f; 756} 757 758int 759getExpression( 760char *str) 761{ 762 char *save_in; 763 segT seg; 764 765 save_in = input_line_pointer; 766 input_line_pointer = str; 767 switch (seg = expression(&the_insn.exp)) { 768 769 case SEG_ABSOLUTE: 770 case SEG_SECT: 771 case SEG_DIFFSECT: 772 case SEG_UNKNOWN: 773 case SEG_NONE: 774 case SEG_BIG: 775 break; 776 777 default: 778 the_insn.error = "illegal segment"; 779 expr_end = input_line_pointer; 780 input_line_pointer=save_in; 781 return 1; 782 } 783 expr_end = input_line_pointer; 784 input_line_pointer = save_in; 785 return 0; 786} 787 788int 789getAbsoluteExpression( 790char *str) 791{ 792 char *save_in; 793 segT seg; 794 795 for ( ; *str == ' ' || *str == '\t' ; str++) 796 ; /* do nothing */ 797 save_in = input_line_pointer; 798 input_line_pointer = str; 799 switch (seg = expression(&the_insn.exp)) { 800 case SEG_ABSOLUTE: 801 break; 802 default: 803 the_insn.error = "segment should be ABSOLUTE"; 804 expr_end = input_line_pointer; 805 input_line_pointer=save_in; 806 return 1; 807 } 808 expr_end = input_line_pointer; 809 input_line_pointer = save_in; 810 return 0; 811} 812 813int 814evaluateAbsolute( 815expressionS exp, 816int field_selector) 817{ 818 int value; 819 uint32_t left21, right14; 820 821 value = exp.X_add_number; 822 calc_hppa_HILO(0, value, &left21, &right14); 823 824 if ( exp.X_add_symbol ) { 825 value += exp.X_add_symbol->sy_value; 826 } 827 if ( exp.X_subtract_symbol ) { 828 value -= exp.X_subtract_symbol->sy_value; 829 } 830 831 switch (field_selector) { 832 case /* no selector */ 0: 833 break; 834 case /* e_lsel */ 1: /* L` */ 835 value = left21; 836 break; 837 838 case /* e_rsel */ 2: /* R` */ 839 value = right14; 840 break; 841 default: 842 BAD_CASE(field_selector); 843 break; 844 } 845 return value; 846} 847 848int pa_parse_nullif(s) 849 char **s; 850{ 851 int nullif; 852 853 nullif = 0; 854 if ( **s == ',' ) { 855 *s = *s + 1; 856 if ( strncasecmp(*s,"n",1) == 0 ) 857 nullif = 1; 858 else { 859 as_bad("Unrecognized Nullification: (%c)",**s); 860 nullif = 0; 861 } 862 *s = *s + 1; 863 } 864 while ( **s == ' ' || **s == '\t' ) 865 *s = *s + 1; 866 867 return nullif; 868} 869 870int pa_parse_nonneg_cmpsub_cmpltr(s) 871 char **s; 872{ 873 int cmpltr; 874 char *name; 875 char c; 876 877 cmpltr = 0; 878 if ( **s == ',' ) { 879 *s+=1; 880 name = *s; 881 while ( **s != ',' && **s != ' ' && **s != '\t' ) 882 *s += 1; 883 c = **s; 884 **s = 0x00; 885 if ( strcmp(name,"=") == 0 ) { 886 cmpltr = 1; 887 } 888 else if ( strcmp(name,"<") == 0 ) { 889 cmpltr = 2; 890 } 891 else if ( strcmp(name,"<=") == 0 ) { 892 cmpltr = 3; 893 } 894 else if ( strcmp(name,"<<") == 0 ) { 895 cmpltr = 4; 896 } 897 else if ( strcmp(name,"<<=") == 0 ) { 898 cmpltr = 5; 899 } 900 else if ( strcasecmp(name,"sv") == 0 ) { 901 cmpltr = 6; 902 } 903 else if ( strcasecmp(name,"od") == 0 ) { 904 cmpltr = 7; 905 } 906 else 907 cmpltr = -1; 908 **s = c; 909 } 910 if ( cmpltr >= 0 ) { 911 while ( **s == ' ' || **s == '\t' ) 912 *s = *s + 1; 913 } 914 915 return cmpltr; 916} 917 918int pa_parse_neg_cmpsub_cmpltr(s) 919 char **s; 920{ 921 int cmpltr; 922 char *name; 923 char c; 924 925 cmpltr = -1; 926 if ( **s == ',' ) { 927 *s+=1; 928 name = *s; 929 while ( **s != ',' && **s != ' ' && **s != '\t' ) 930 *s += 1; 931 c = **s; 932 **s = 0x00; 933 if ( strcasecmp(name,"tr") == 0 ) { 934 cmpltr = 0; 935 } 936 else if ( strcmp(name,"<>") == 0 ) { 937 cmpltr = 1; 938 } 939 else if ( strcmp(name,">=") == 0 ) { 940 cmpltr = 2; 941 } 942 else if ( strcmp(name,">") == 0 ) { 943 cmpltr = 3; 944 } 945 else if ( strcmp(name,">>=") == 0 ) { 946 cmpltr = 4; 947 } 948 else if ( strcmp(name,">>") == 0 ) { 949 cmpltr = 5; 950 } 951 else if ( strcasecmp(name,"nsv") == 0 ) { 952 cmpltr = 6; 953 } 954 else if ( strcasecmp(name,"ev") == 0 ) { 955 cmpltr = 7; 956 } 957 **s = c; 958 } 959 if ( cmpltr >= 0 ) { 960 while ( **s == ' ' || **s == '\t' ) 961 *s = *s + 1; 962 } 963 964 return cmpltr; 965} 966 967int pa_parse_nonneg_add_cmpltr(s) 968 char **s; 969{ 970 int cmpltr; 971 char *name; 972 char c; 973 974 cmpltr = -1; 975 if ( **s == ',' ) { 976 *s+=1; 977 name = *s; 978 while ( **s != ',' && **s != ' ' && **s != '\t' ) 979 *s += 1; 980 c = **s; 981 **s = 0x00; 982 if ( strcmp(name,"=") == 0 ) { 983 cmpltr = 1; 984 } 985 else if ( strcmp(name,"<") == 0 ) { 986 cmpltr = 2; 987 } 988 else if ( strcmp(name,"<=") == 0 ) { 989 cmpltr = 3; 990 } 991 else if ( strcasecmp(name,"nuv") == 0 ) { 992 cmpltr = 4; 993 } 994 else if ( strcasecmp(name,"znv") == 0 ) { 995 cmpltr = 5; 996 } 997 else if ( strcasecmp(name,"sv") == 0 ) { 998 cmpltr = 6; 999 } 1000 else if ( strcasecmp(name,"od") == 0 ) { 1001 cmpltr = 7; 1002 } 1003 **s = c; 1004 } 1005 if ( cmpltr >= 0 ) { 1006 while ( **s == ' ' || **s == '\t' ) 1007 *s = *s + 1; 1008 } 1009 1010 return cmpltr; 1011} 1012 1013int pa_parse_neg_add_cmpltr(s) 1014 char **s; 1015{ 1016 int cmpltr; 1017 char *name; 1018 char c; 1019 1020 cmpltr = -1; 1021 if ( **s == ',' ) { 1022 *s+=1; 1023 name = *s; 1024 while ( **s != ',' && **s != ' ' && **s != '\t' ) 1025 *s += 1; 1026 c = **s; 1027 **s = 0x00; 1028 if ( strcasecmp(name,"tr") == 0 ) { 1029 cmpltr = 0; 1030 } 1031 else if ( strcmp(name,"<>") == 0 ) { 1032 cmpltr = 1; 1033 } 1034 else if ( strcmp(name,">=") == 0 ) { 1035 cmpltr = 2; 1036 } 1037 else if ( strcmp(name,">") == 0 ) { 1038 cmpltr = 3; 1039 } 1040 else if ( strcmp(name,"uv") == 0 ) { 1041 cmpltr = 4; 1042 } 1043 else if ( strcmp(name,"vnz") == 0 ) { 1044 cmpltr = 5; 1045 } 1046 else if ( strcasecmp(name,"nsv") == 0 ) { 1047 cmpltr = 6; 1048 } 1049 else if ( strcasecmp(name,"ev") == 0 ) { 1050 cmpltr = 7; 1051 } 1052 **s = c; 1053 } 1054 if ( cmpltr >= 0 ) { 1055 while ( **s == ' ' || **s == '\t' ) 1056 *s = *s + 1; 1057 } 1058 1059 return cmpltr; 1060} 1061 1062#if 0 1063static int 1064is_same_frag(frag1P,frag2P) 1065 fragS *frag1P; 1066 fragS *frag2P; 1067{ 1068 1069 if ( frag1P == NULL ) 1070 return (FALSE); 1071 else if ( frag2P == NULL ) 1072 return (FALSE); 1073 else if ( frag1P == frag2P ) 1074 return (TRUE); 1075 else if ( frag2P->fr_type == rs_fill && frag2P->fr_fix == 0 ) 1076 return is_same_frag(frag1P,frag2P->fr_next); 1077 else if ( frag2P->fr_type == rs_align ) 1078 return is_same_frag(frag1P,frag2P->fr_next); 1079 else 1080 return (FALSE); 1081} 1082#endif 1083 1084/* end hppa-aux.c */ 1085