home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / cctools / as / hppa-aux.c < prev    next >
C/C++ Source or Header  |  1995-02-17  |  21KB  |  1,083 lines

  1. /* hppa-aux.c -- Assembler for the PA - PA-RISC specific support routines
  2.    Copyright (C) 1989 Free Software Foundation, Inc.
  3.  
  4. This file is part of GAS, the GNU Assembler.
  5.  
  6. GAS is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GAS is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GAS; see the file COPYING.  If not, write to
  18. the 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.  
  41. extern char *expr_end; /* defined in hppa.c */
  42.  
  43. static const int print_errors = 1;
  44.  
  45. static int reg_name_search(
  46.     char *name);
  47.  
  48. int 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.  
  159. struct 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.  
  248. static 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.  
  453. static
  454. int
  455. reg_name_search(
  456. char *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.     
  479. static
  480. int
  481. is_R_select(
  482. char *s)
  483. {
  484.  
  485.   if ( *s == 'R' || *s == 'r' )
  486.     return(TRUE);
  487.   else
  488.     return(FALSE);    
  489. }
  490.  
  491. static
  492. int
  493. is_L_select(
  494. char *s)
  495. {
  496.  
  497.   if ( *s == 'L' || *s == 'l' )
  498.     return(TRUE);
  499.   else
  500.     return(FALSE);    
  501. }
  502.  
  503. int 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.  
  513. int
  514. pa_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.  
  661. int 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.  
  727. FP_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.  
  758. int
  759. getExpression(
  760. char *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.  
  788. int
  789. getAbsoluteExpression(
  790. char *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.  
  813. int
  814. evaluateAbsolute(
  815. expressionS exp,
  816. int field_selector)
  817. {
  818.     int value;
  819.     unsigned long 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.  
  848. int 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.  
  870. int 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.  
  918. int 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.  
  967. int 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.  
  1013. int 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. static int
  1063. is_same_frag(frag1P,frag2P)
  1064.      fragS *frag1P;
  1065.      fragS *frag2P;
  1066. {
  1067.  
  1068.   if ( frag1P == NULL )
  1069.     return (FALSE);
  1070.   else if ( frag2P == NULL )
  1071.     return (FALSE);
  1072.   else if ( frag1P == frag2P )
  1073.     return (TRUE);
  1074.   else if ( frag2P->fr_type == rs_fill && frag2P->fr_fix == 0 )
  1075.     return is_same_frag(frag1P,frag2P->fr_next);
  1076.   else if ( frag2P->fr_type == rs_align )
  1077.     return is_same_frag(frag1P,frag2P->fr_next);
  1078.   else
  1079.     return (FALSE);
  1080. }
  1081.  
  1082. /* end hppa-aux.c */
  1083.