home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / cctools / as / hppa.c < prev    next >
C/C++ Source or Header  |  1997-01-24  |  47KB  |  1,865 lines

  1. /* hppa.c -- Assemble for the HP-PA
  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. /*
  22.    HP PA-RISC support was contributed by the Center for Software Science
  23.    at the University of Utah.
  24. */
  25.  
  26. /* HP-PA support for Mach-O ... USV */
  27.  
  28. #include <stdio.h>
  29. #include <ctype.h>
  30. #include <string.h>
  31. #include <mach-o/hppa/reloc.h>
  32. #define HPPA_RELOC_12BRANCH (127) /* only used internal in here */
  33.  
  34. #include "obstack.h"
  35. #include "hppa-opcode.h"
  36. #include "as.h"
  37. #include "frags.h"
  38. #include "flonum.h"
  39. #include "hash.h"
  40. #include "md.h"
  41. #include "symbols.h"
  42. #include "hppa-aux.h"
  43. #include "messages.h"
  44. #include "stuff/hppa.h"
  45. #include "sections.h"
  46. #include "symbols.h"
  47.  
  48. /*
  49.  * These are the default cputype and cpusubtype for the hppa architecture.
  50.  */
  51. const cpu_type_t md_cputype = CPU_TYPE_HPPA;
  52. cpu_subtype_t md_cpusubtype = CPU_SUBTYPE_HPPA_ALL;
  53.  
  54. /* This is the byte sex for the hppa architecture */
  55. const enum byte_sex md_target_byte_sex = BIG_ENDIAN_BYTE_SEX;
  56.  
  57. /* These characters start a comment anywhere on the line */
  58. const char md_comment_chars[] = ";";
  59.  
  60. /* These characters only start a comment at the beginning of a line */
  61. const char md_line_comment_chars[] = "#";
  62.  
  63. /*
  64.  * These characters can be used to separate mantissa decimal digits from 
  65.  * exponent decimal digits in floating point numbers.
  66.  */
  67. const char md_EXP_CHARS[] = "eE";
  68.  
  69. /*
  70.  * The characters after a leading 0 that means this number is a floating point
  71.  * constant as in 0f123.456 or 0d1.234E-12 (see md_EXP_CHARS above).
  72.  */
  73. const char md_FLT_CHARS[] = "dDfF";
  74.  
  75. /*
  76.  * This is the machine dependent pseudo opcode table for this target machine.
  77.  */
  78. const pseudo_typeS md_pseudo_table[] =
  79. {
  80.     {0} /* end of table marker */
  81. };
  82.  
  83.  
  84. static int found_jbsr = 0;
  85. static char *toP;
  86.  
  87. const relax_typeS md_relax_table[] = { {0} };
  88.  
  89. /* handle of the OPCODE hash table */
  90. static struct hash_control *op_hash = NULL;
  91.  
  92. struct pa_it the_insn;   /* this structure is defined in pa-aux.h */
  93.  
  94. char *expr_end;
  95.  
  96. static void pa_ip(
  97.     char *str);
  98. static int parse_L_or_R(
  99.     char *str);
  100. static unsigned long parse_completer_with_cache_control_hint(
  101.     char    **s,       /* Note : the function changes '*s' */
  102.     int     option,    /* option = 0 for store instruction */
  103.                        /* option = 1 for load and clear instruction */
  104.     char    completer);/* 'c' or 'C' */
  105. static unsigned long parse_cache_control_hint(
  106.     char    **s,       /* Note : the function changes '*s' */
  107.     int     option);   /* option = 0 for store instruction */
  108.                        /* option = 1 for load and clear instruction */
  109.  
  110. /* This function is called once, at assembler startup time.  It should
  111.    set up all the tables, etc. that the MD part of the assembler will need.  */
  112. void
  113. md_begin(
  114. void)
  115. {
  116.     register char *retval = NULL;
  117.     int lose = 0;
  118.     register unsigned int i = 0;
  119.  
  120.     op_hash = hash_new();
  121.     if (op_hash == NULL)
  122.     as_fatal("Virtual memory exhausted");
  123.  
  124.     while (i < NUMOPCODES) {
  125.         const char *name = pa_opcodes[i].name;
  126.         retval = hash_insert(op_hash, (char *)name,
  127.                      (char *)&pa_opcodes[i]);
  128.         if(retval != NULL && *retval != '\0')  {
  129.             as_fatal("Internal error: can't hash `%s': %s\n",
  130.             pa_opcodes[i].name, retval);
  131.             lose = 1;
  132.         }
  133.         ++i;
  134.     }
  135.  
  136.     if (lose)
  137.         as_fatal ("Broken assembler.  No assembly attempted.");
  138. }
  139.  
  140. void
  141. md_end(
  142. void)
  143. {
  144.     return;
  145. }
  146.  
  147. void
  148. md_assemble(
  149. char *str)
  150. {
  151.  
  152.     assert(str);
  153.     pa_ip(str);
  154.     if (!found_jbsr)
  155.         toP = frag_more(4);
  156.     else
  157.         found_jbsr = 0;
  158.  
  159. #ifdef NeXT    /* mark sections containing instructions */
  160.     /*
  161.      * We are putting a machine instruction in this section so mark it as
  162.      * containg some machine instructions.
  163.      */
  164.     frchain_now->frch_section.flags |= S_ATTR_SOME_INSTRUCTIONS;
  165. #endif /* NeXT */
  166.  
  167.     /* put out the opcode */
  168.     md_number_to_chars(toP, the_insn.opcode, 4);
  169.  
  170.     /* put out the symbol-dependent stuff */
  171.     if (the_insn.reloc != NO_RELOC) {
  172.         fix_new(frag_now,              /* which frag */
  173.             (toP - frag_now->fr_literal), /* where */
  174.             4,                  /* size */
  175.             the_insn.exp.X_add_symbol,
  176.             the_insn.exp.X_subtract_symbol,
  177.             the_insn.exp.X_add_number,      /* offset */
  178.             the_insn.pcrel,
  179.             the_insn.pcrel_reloc,
  180.             the_insn.reloc);
  181.     }
  182. }
  183.  
  184. static
  185. void
  186. pa_ip(
  187. char *str)
  188. {
  189.     char *s;
  190.     const char *args;
  191.     char c;
  192.     unsigned long i;
  193.     struct pa_opcode *insn;
  194.     char *argsStart;
  195.     unsigned long   opcode;
  196.     int match = FALSE;
  197.     int comma = 0;
  198.  
  199.     int reg,reg1,reg2,s2,s3;
  200.     unsigned int im21,im14,im11,im5;
  201.     int m,a,u,f;
  202.     int cmpltr,nullif, flag;
  203.     int sfu, cond;
  204.     char *name;
  205.     char *save_s, *p;
  206.     short reference;
  207.  
  208.     reference = 0;
  209.  
  210. #ifdef PA_DEBUG
  211.     fprintf(stderr,"STATEMENT: \"%s\"\n",str);
  212. #endif
  213.     for (s = str; isupper(*s) || islower(*s) || (*s >= '0' && *s <= '3'); ++s)
  214.         ;
  215.     switch (*s) {
  216.  
  217.     case '\0':
  218.         break;
  219.  
  220.     case ',':
  221.         comma = 1;
  222.  
  223.     /*FALLTHROUGH*/
  224.  
  225.     case ' ':
  226.         *s++ = '\0';
  227.         break;
  228.  
  229.     default:
  230.         as_bad("Unknown opcode: `%s'", str);
  231.         exit(1);
  232.     }
  233.  
  234.     save_s = str;
  235.  
  236.     while ( *save_s ) {
  237.         if ( isupper(*save_s) )
  238.             *save_s = tolower(*save_s);
  239.         save_s++;
  240.     }
  241.  
  242.     if ((insn = (struct pa_opcode *) hash_find(op_hash, str)) == NULL) {
  243.         as_bad("Unknown opcode: `%s'", str);
  244.         return;
  245.     }
  246.     if (comma) {
  247.         *--s = ',';
  248.     }
  249.     argsStart = s;
  250.     for (;;) {
  251.         opcode = insn->match;
  252.         memset(&the_insn, '\0', sizeof(the_insn));
  253.         the_insn.reloc = NO_RELOC;    /* USV */
  254.  
  255. /*
  256. * Build the opcode, checking as we go to make
  257. * sure that the operands match
  258. */
  259.         for (args = insn->args; ; ++args) {
  260.  
  261.             switch (*args) {
  262.  
  263.             case '\0':  /* end of args */
  264.                   if (*s == '\0') {
  265.                     match = TRUE;
  266.                   }
  267.                   break;
  268.  
  269.             case '(':   /* these must match exactly */
  270.             case ')':
  271.             case ',':
  272.             case ' ':
  273.                   if (*s++ == *args)
  274.                     continue;
  275.                   break;
  276.  
  277.             case 'b':   /* 5 bit register field at 10 */
  278.                   reg = pa_parse_number(&s);
  279.                   if ( reg < 32 && reg >= 0 ) {
  280.                     opcode |= reg << 21;
  281.                     continue;
  282.                   }
  283.                   break;
  284.             case 'x':   /* 5 bit register field at 15 */
  285.                   reg = pa_parse_number(&s);
  286.                   if ( reg < 32 && reg >= 0 ) {
  287.                     opcode |= reg << 16;
  288.                     continue;
  289.                   }
  290.                   break;
  291.             case 't':   /* 5 bit register field at 31 */
  292.                   reg = pa_parse_number(&s);
  293.                   if ( reg < 32 && reg >= 0 ) {
  294.                     opcode |= reg;
  295.                     continue;
  296.                   }
  297.                   break;
  298.             case 'T':   /* 5 bit field length at 31 (encoded as 32-T) */
  299.   /*
  300. reg = pa_parse_number(&s);
  301.    */
  302.                 getAbsoluteExpression(s);
  303.                   if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
  304.                     reg = the_insn.exp.X_add_number;
  305.                     if ( reg <= 32 && reg > 0 ) {
  306.                           opcode |= 32 - reg;
  307.                           s = expr_end;
  308.                           continue;
  309.                     }
  310.                   }
  311.                   break;
  312.             case '5':   /* 5 bit immediate at 15 */
  313.                 getAbsoluteExpression(s);
  314. /** PJH: The following 2 calls to as_bad() might eventually **/
  315. /**      want to end up as as_warn().  **/
  316.                 if (   the_insn.exp.X_add_number > 15 ) {
  317.                     as_bad("5 bit immediate: %ld > 15. Set to 15",
  318.                         the_insn.exp.X_add_number);
  319.                     the_insn.exp.X_add_number = 15;
  320.                 }
  321.                 else if ( the_insn.exp.X_add_number < -16 ) {
  322.                         as_bad("5 bit immediate: %ld < -16. Set to -16",
  323.                             the_insn.exp.X_add_number);
  324.                         the_insn.exp.X_add_number = -16;
  325.                     }
  326.  
  327.                 im5 = low_sign_unext(evaluateAbsolute(
  328.                              the_insn.exp,0),5);
  329.                 opcode |= ( im5 << 16 );
  330.                 s = expr_end;
  331.                 continue;
  332.  
  333.             case 's':   /* 2 bit space identifier at 17 */
  334.                 s2 = pa_parse_number(&s);
  335.                 if ( s2 < 4 && s2 >= 0 ) {
  336.                     opcode |= s2 << 14;
  337.                     continue;
  338.                 }
  339.                 break;
  340.             case 'S':   /* 3 bit space identifier at 18 */
  341.                 s3 = pa_parse_number(&s);
  342.                 if ( s3 < 8 && s3 >= 0 ) {
  343.                     s3 = dis_assemble_3(s3);
  344.                     opcode |= s3 << 13;
  345.                     continue;
  346.                 }
  347.                 break;
  348.             case 'c':   /* indexed load completer. */
  349.                 i = m = u = 0;
  350.                 while ( *s == ',' && i < 2 ) {
  351.                     s++;
  352.                     if ( strncasecmp(s,"sm",2) == 0 ) {
  353.                         m = u = 1;
  354.                         s++;
  355.                         i++;
  356.                     }
  357.                     else if ( strncasecmp(s,"m",1) == 0 )
  358.                               m = 1;
  359.                         else if ( strncasecmp(s,"s",1) == 0 )
  360.                                   u = 1;
  361.                             else
  362.                                   as_bad("Unrecognized Indexed Load"
  363.                                     "Completer...assuming 0");
  364.                     s++;
  365.                     i++;
  366.                   }
  367.                   if ( i > 2 )
  368.                     as_bad("Illegal Indexed Load Completer Syntax..."
  369.                         "extras ignored");
  370.                   while ( *s == ' ' || *s == '\t' )
  371.                     s++;
  372.   
  373.                   opcode |= m << 5;
  374.                   opcode |= u << 13;
  375.                   continue;
  376.             case 'C':   /* short load and store completer */
  377.                 m = a = 0;
  378.                 if ( *s == ',' ) {
  379.                     s++;
  380.                     if ( strncasecmp(s,"ma",2) == 0 ) {
  381.                         a = 0;
  382.                         m = 1;
  383.                     }
  384.                     else if ( strncasecmp(s,"mb",2) == 0 ) {
  385.                             m = a = 1;
  386.                         }
  387.                         else
  388.                             as_bad("Unrecognized Indexed Load Completer"
  389.                                 "...assuming 0");
  390.                     s += 2;
  391.                 }
  392.                 while ( *s == ' ' || *s == '\t' )
  393.                     s++;
  394.                 opcode |= m << 5;
  395.                 opcode |= a << 13;
  396.                 continue;
  397.  
  398.             /* bug #41317 .... umeshv@NeXT.com
  399.              * Fri Jul 22 09:43:46 PDT 1994
  400.              *
  401.              * Modified to parse 'cache control hints'
  402.              *
  403.              * These parse ",cc" and encode "cc" in 2 bits at 20,
  404.              * where "cc" encoding is as given in Tables 5-8, 5-9.
  405.              * Refer to 'PA-RISC 1.1 Architecture and Instruction Set
  406.              * Reference Manual, Second Edition' for the tables.
  407.              */
  408.             case 'Y':   /* Store Bytes Short completer */
  409.                         /* with cache control hints    */
  410.             {
  411.                 unsigned long result = (unsigned long)0UL;
  412.                 
  413.                 i = m = a = 0;
  414.                 while ( *s == ',' && i < 3 ) {
  415.                     s++;
  416.                     if ( strncasecmp(s,"m",1) == 0 )
  417.                         m = 1;
  418.                     else if ( strncasecmp(s,"b",1) == 0 &&
  419.                               (strncasecmp((s+1),"c",1) != 0) )
  420.                             a = 0;
  421.                         else if ( strncasecmp(s,"e",1) == 0 )
  422.                                 a = 1;
  423.                             else if ( strncmp(s,",",1) == 0 ) /* no completer */
  424.                                 result |= parse_cache_control_hint(&s, 0);
  425.                             else if ( (strncasecmp(s,"c",1) == 0) ||
  426.                                       (strncasecmp(s,"b",1) == 0) ) {/* just 1 completer */
  427.                                 s--;
  428.                                 result |= parse_cache_control_hint(&s, 0);
  429.                             }
  430.                             else
  431.                                 as_bad("Unrecognized Store Bytes Short"
  432.                                     "Completer with cache control hints"
  433.                                     " ...assuming 0");
  434.                     if (result == (unsigned long)0UL)
  435.                         s++;
  436.                     i++;
  437.                 }
  438. /**        if ( i >= 2 ) **/
  439.                 if ( i > 3 )
  440.                     as_bad("Illegal Store Bytes Short Completer "
  441.                         "with cache control hints ...  extras ignored");
  442.                 while ( *s == ' ' || *s == '\t' ) /* skip to next operand */
  443.                     s++;
  444.                 opcode |= result;
  445.                 opcode |= m << 5;
  446.                 opcode |= a << 13;
  447.                 continue;
  448.             }
  449.             case '<':   /* non-negated compare/subtract conditions. */
  450.                 cmpltr = pa_parse_nonneg_cmpsub_cmpltr(&s);
  451.                 if ( cmpltr < 0 ) {
  452.                     as_bad("Unrecognized Compare/Subtract Condition: %c",*s);
  453.                     cmpltr = 0;
  454.                 }
  455.                 opcode |= cmpltr << 13;
  456.                 continue;
  457.             case '?':   /* negated or non-negated cmp/sub conditions. */
  458.                     /* used only by ``comb'' and ``comib'' pseudo-ops */
  459.                 save_s = s;
  460.                 cmpltr = pa_parse_nonneg_cmpsub_cmpltr(&s);
  461.                 if ( cmpltr < 0 ) {
  462.                     s = save_s;
  463.                     cmpltr = pa_parse_neg_cmpsub_cmpltr(&s);
  464.                     if ( cmpltr < 0 ) {
  465.                         as_bad("Unrecognized Compare/Subtract Condition: %c"
  466.                             ,*s);
  467.                         cmpltr = 0;
  468.                     }
  469.                     else {
  470.                         opcode |= 1 << 27; /* required opcode change to make
  471.                                             COMIBT into a COMIBF or a
  472.                                             COMBT into a COMBF or a
  473.                                             ADDBT into a ADDBF or a
  474.                                             ADDIBT into a ADDIBF */
  475.                     }
  476.                 }
  477.                 opcode |= cmpltr << 13;
  478.                 continue;
  479.             case '!':   /* negated or non-negated add conditions. */
  480.                 /* used only by ``addb'' and ``addib'' pseudo-ops */
  481.                 save_s = s;
  482.                 cmpltr = pa_parse_nonneg_add_cmpltr(&s);
  483.                 if ( cmpltr < 0 ) {
  484.                     s = save_s;
  485.                     cmpltr = pa_parse_neg_add_cmpltr(&s);
  486.                     if ( cmpltr < 0 ) {
  487.                         as_bad("Unrecognized Compare/Subtract Condition: %c",
  488.                             *s);
  489.                         cmpltr = 0;
  490.                     }
  491.                     else {
  492.                         opcode |= 1 << 27; /* required opcode change to make
  493.                                             COMIBT into a COMIBF or a
  494.                                             COMBT into a COMBF or a
  495.                                             ADDBT into a ADDBF or a
  496.                                             ADDIBT into a ADDIBF */
  497.                     }
  498.                 }
  499.                 opcode |= cmpltr << 13;
  500.                 continue;
  501.             case '-':   /* compare/subtract conditions */
  502.                 f = cmpltr = 0;
  503.                 save_s = s;
  504.                 if ( *s == ',' ) {
  505.                     cmpltr = pa_parse_nonneg_cmpsub_cmpltr(&s);
  506.                     if ( cmpltr < 0 ) {
  507.                         f = 1;
  508.                         s = save_s;
  509.                         cmpltr = pa_parse_neg_cmpsub_cmpltr(&s);
  510.                         if ( cmpltr < 0 ) {
  511.                             as_bad("Unrecognized Compare/Subtract Condition");
  512.                         }
  513.                     }
  514.                 }
  515.                 opcode |= cmpltr << 13;
  516.                 opcode |= f << 12;
  517.                 continue;
  518.             case '+':   /* non-negated add conditions */
  519.                 flag = nullif = cmpltr = 0;
  520.                 if ( *s == ',' ) {
  521.                     s++;
  522.                     name = s;
  523.                     while ( *s != ',' && *s != ' ' && *s != '\t' )
  524.                         s += 1;
  525.                     c = *s;
  526.                     *s = 0x00;
  527.                     if ( strcmp(name,"=") == 0 ) {
  528.                         cmpltr = 1;
  529.                         }
  530.                         else if ( strcmp(name,"<") == 0 ) {
  531.                         cmpltr = 2;
  532.                         }
  533.                         else if ( strcmp(name,"<=") == 0 ) {
  534.                         cmpltr = 3;
  535.                         }
  536.                         else if ( strcasecmp(name,"nuv") == 0 ) {
  537.                         cmpltr = 4;
  538.                         }
  539.                         else if ( strcasecmp(name,"znv") == 0 ) {
  540.                         cmpltr = 5;
  541.                         }
  542.                         else if ( strcasecmp(name,"sv") == 0 ) {
  543.                         cmpltr = 6;
  544.                         }
  545.                         else if ( strcasecmp(name,"od") == 0 ) {
  546.                         cmpltr = 7;
  547.                         }
  548.                         else if ( strcasecmp(name,"n") == 0 ) {
  549.                         nullif = 1;
  550.                         }
  551.                         else if ( strcasecmp(name,"tr") == 0 ) {
  552.                         cmpltr = 0;
  553.                         flag   = 1;
  554.                         }
  555.                         else if ( strcasecmp(name,"<>") == 0 ) {
  556.                         flag = cmpltr = 1;
  557.                         }
  558.                         else if ( strcasecmp(name,">=") == 0 ) {
  559.                         cmpltr = 2;
  560.                         flag   = 1;
  561.                         }
  562.                         else if ( strcasecmp(name,">") == 0 ) {
  563.                         cmpltr = 3;
  564.                         flag   = 1;
  565.                         }
  566.                         else if ( strcasecmp(name,"uv") == 0 ) {
  567.                         cmpltr = 4;
  568.                         flag   = 1;
  569.                         }
  570.                         else if ( strcasecmp(name,"vnz") == 0 ) {
  571.                         cmpltr = 5;
  572.                         flag   = 1;
  573.                         }
  574.                         else if ( strcasecmp(name,"nsv") == 0 ) {
  575.                         cmpltr = 6;
  576.                         flag   = 1;
  577.                         }
  578.                         else if ( strcasecmp(name,"ev") == 0 ) {
  579.                         cmpltr = 7;
  580.                         flag   = 1;
  581.                         }
  582.                         else
  583.                         as_bad("Unrecognized Add Condition: %s",name);
  584.                     *s = c;
  585.                 }
  586.                 nullif = pa_parse_nullif(&s);
  587.                 opcode |= nullif << 1;
  588.                 opcode |= cmpltr << 13;
  589.                 opcode |= flag << 12;
  590.                 continue;        
  591.             case '&':   /* logical instruction conditions */
  592.                 f = cmpltr = 0;
  593.                 if ( *s == ',' ) {
  594.                     s++;
  595.                     name = s;
  596.                     while ( *s != ',' && *s != ' ' && *s != '\t' )
  597.                         s += 1;
  598.                     c = *s;
  599.                     *s = 0x00;
  600.                     if ( strcmp(name,"=") == 0 ) {
  601.                         cmpltr = 1;
  602.                         }
  603.                         else if ( strcmp(name,"<") == 0 ) {
  604.                         cmpltr = 2;
  605.                         }
  606.                         else if ( strcmp(name,"<=") == 0 ) {
  607.                         cmpltr = 3;
  608.                         }
  609.                         else if ( strcasecmp(name,"od") == 0 ) {
  610.                         cmpltr = 7;
  611.                         }
  612.                         else if ( strcasecmp(name,"tr") == 0 ) {
  613.                         cmpltr = 0;
  614.                         f = 1;
  615.                         }
  616.                         else if ( strcmp(name,"<>") == 0 ) {
  617.                         f = cmpltr = 1;
  618.                         }
  619.                         else if ( strcmp(name,">=") == 0 ) {
  620.                         cmpltr = 2;
  621.                         f = 1;
  622.                         }
  623.                         else if ( strcmp(name,">") == 0 ) {
  624.                         cmpltr = 3;
  625.                         f = 1;
  626.                         }
  627.                         else if ( strcasecmp(name,"ev") == 0 ) {
  628.                         cmpltr = 7;
  629.                         f = 1;
  630.                         }
  631.                         else
  632.                         as_bad("Unrecognized Logical Instruction Condition:"
  633.                             " %s",name);
  634.                     *s = c;
  635.                 }
  636.                 opcode |= cmpltr << 13;
  637.                 opcode |= f << 12;        
  638.                 continue;
  639.             case 'U':   /* unit instruction conditions */
  640.                 cmpltr = 0;
  641.                 f = 0;
  642.                 if ( *s == ',' ) {
  643.                     s++;
  644.                     if ( strncasecmp(s,"sbz",3) == 0 ) {
  645.                         cmpltr = 2;
  646.                         s += 3;
  647.                         }
  648.                         else if ( strncasecmp(s,"shz",3) == 0 ) {
  649.                         cmpltr = 3;
  650.                         s += 3;
  651.                         }
  652.                         else if ( strncasecmp(s,"sdc",3) == 0 ) {
  653.                         cmpltr = 4;
  654.                         s += 3;
  655.                         }
  656.                         else if ( strncasecmp(s,"sbc",3) == 0 ) {
  657.                         cmpltr = 6;
  658.                         s += 3;
  659.                         }
  660.                         else if ( strncasecmp(s,"shc",3) == 0 ) {
  661.                         cmpltr = 7;
  662.                         s += 3;
  663.                         }
  664.                         else if ( strncasecmp(s,"tr",2) == 0 ) {
  665.                         cmpltr = 0;
  666.                         f = 1;
  667.                         s += 2;
  668.                         }
  669.                         else if ( strncasecmp(s,"nbz",3) == 0 ) {
  670.                         cmpltr = 2;
  671.                         f = 1;
  672.                         s += 3;
  673.                         }
  674.                         else if ( strncasecmp(s,"nhz",3) == 0 ) {
  675.                         cmpltr = 3;
  676.                         f = 1;
  677.                         s += 3;
  678.                         }
  679.                         else if ( strncasecmp(s,"ndc",3) == 0 ) {
  680.                         cmpltr = 4;
  681.                         f = 1;
  682.                         s += 3;
  683.                         }
  684.                         else if ( strncasecmp(s,"nbc",3) == 0 ) {
  685.                         cmpltr = 6;
  686.                         f = 1;
  687.                         s += 3;
  688.                         }
  689.                         else if ( strncasecmp(s,"nhc",3) == 0 ) {
  690.                         cmpltr = 7;
  691.                         f = 1;
  692.                         s += 3;
  693.                         }
  694.                         else
  695.                         as_bad("Unrecognized Logical Instruction Condition:"
  696.                             " %c",*s);
  697.                 }
  698.                 opcode |= cmpltr << 13;
  699.                 opcode |= f << 12;        
  700.                 continue;
  701.             case '>':   /* shift/extract/deposit conditions. */
  702.                 cmpltr = 0;
  703.                 if ( *s == ',' ) {
  704.                     s++;
  705.                     name = s;
  706.                     while ( *s != ',' && *s != ' ' && *s != '\t' )
  707.                         s += 1;
  708.                     c = *s;
  709.                     *s = 0x00;
  710.                     if ( strcmp(name,"=") == 0 ) {
  711.                         cmpltr = 1;
  712.                         }
  713.                         else if ( strcmp(name,"<") == 0 ) {
  714.                         cmpltr = 2;
  715.                         }
  716.                         else if ( strcasecmp(name,"od") == 0 ) {
  717.                         cmpltr = 3;
  718.                         }
  719.                         else if ( strcasecmp(name,"tr") == 0 ) {
  720.                         cmpltr = 4;
  721.                         }
  722.                         else if ( strcmp(name,"<>") == 0 ) {
  723.                         cmpltr = 5;
  724.                         }
  725.                         else if ( strcmp(name,">=") == 0 ) {
  726.                         cmpltr = 6;
  727.                         }
  728.                         else if ( strcasecmp(name,"ev") == 0 ) {
  729.                         cmpltr = 7;
  730.                         }
  731.                         else
  732.                         as_bad("Unrecognized Shift/Extract/Deposit"
  733.                             "Condition: %s",name);
  734.                     *s = c;
  735.                 }
  736.                 opcode |= cmpltr << 13;
  737.                 continue;
  738.             case '~':   /* bvb,bb conditions */
  739.                 cmpltr = 0;
  740.                 if ( *s == ',' ) {
  741.                     s++;
  742.                     if ( strncmp(s,"<",1) == 0 ) {
  743.                         cmpltr = 2;
  744.                         s++;
  745.                         }
  746.                         else if ( strncmp(s,">=",2) == 0 ) {
  747.                         cmpltr = 6;
  748.                         s += 2;
  749.                         }
  750.                         else
  751.                         as_bad("Unrecognized Bit Branch Condition: %c",*s);
  752.                 }
  753.                 opcode |= cmpltr << 13;
  754.                 continue;
  755.             case 'V':   /* 5  bit immediate at 31 */
  756.                 getExpression(s);
  757.                 im5 = low_sign_unext(evaluateAbsolute(
  758.                              the_insn.exp,0),5);
  759.                 opcode |= im5;
  760.                 s = expr_end;
  761.                 continue;
  762.             case 'r':   /* 5  bit immediate at 31 */
  763.                         /* (unsigned value for the break instruction) */
  764.                 getExpression(s);
  765.                 im5 = evaluateAbsolute(the_insn.exp,0);
  766.                 if ( im5 > 31 ) {
  767.                     as_bad("Operand out of range. Was: %d. Should be"
  768.                         "[0..31]. Assuming %d.\n",im5,im5&0x1f);
  769.                     im5 = im5 & 0x1f;
  770.                 }
  771.                 opcode |= im5;
  772.                 s = expr_end;
  773.                 continue;
  774.             case 'R':   /* 5  bit immediate at 15 */
  775. /* (unsigned value for the ssm and rsm instruction) */
  776.                 getExpression(s);
  777.                 im5 = evaluateAbsolute(the_insn.exp,0);
  778.                 if ( im5 > 31 ) {
  779.                     as_bad("Operand out of range. Was: %d. Should be"
  780.                         "[0..31]. Assuming %d.\n",im5,im5&0x1f);
  781.                     im5 = im5 & 0x1f;
  782.                 }
  783.                 opcode |= im5 << 16;
  784.                 s = expr_end;
  785.                 continue;
  786.             case 'i':   /* 11 bit immediate at 31 */
  787.                 getExpression(s);
  788.                 if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
  789.                     im11 = low_sign_unext(evaluateAbsolute(
  790.                             the_insn.exp,0),11);
  791.                     opcode |= im11;
  792.                 }
  793.                 else {
  794.                     the_insn.code = 'i';
  795.                 }
  796.                 s = expr_end;
  797.                 continue;
  798.             case 'j':   /* 14 bit immediate at 31 --- LO14 */
  799.             {
  800.                 int field_selector = parse_L_or_R(s);
  801.                 switch (field_selector) {
  802.                 case 2:    /* found the field selector R`*/
  803.                 case 1:    /* found the field selector L`*/
  804.                     s += 2;  /* eat up L` or R` */
  805.                 case 0: /* not found */
  806.                     getExpression(s);
  807.                     break;
  808.                 default:
  809.                     as_bad("Bad field selector. Was: %.2s. Should be either L` or R`\n",s);
  810.                     break;
  811.                 }
  812.                 if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
  813.                     im14 = low_sign_unext(
  814. evaluateAbsolute(the_insn.exp,field_selector), 14);
  815.  
  816. /* I donot think the mask is necessary here  low_sign_unext() takes */
  817. /* care of putting only 14 bits in im14 ! ...       090993 ... USV  */
  818. /*                    if (field_selector)
  819.                         opcode |= (im14 & 0x7ff);
  820.                     else
  821. */
  822.                     opcode |= im14;
  823.                 }
  824.                 else {
  825.                     the_insn.reloc = HPPA_RELOC_LO14;
  826.                     the_insn.code = 'j';
  827.                 }
  828.                 s = expr_end;
  829.                 continue;
  830.             }  
  831.             case 'z':    /* 17 bit branch displacement (non-pc-relative) */
  832.                 /* for be, ble --- BR17*/
  833.                 /* bl, ble  in absence of L` or R` can have */
  834.                 /* a 17 bit immmidiate number */
  835.             {
  836.                 unsigned long w, w1, w2;
  837.                 int field_selector = parse_L_or_R(s);
  838.                 switch (field_selector) {
  839.                 case 2:    /* found the field selector R`*/
  840.                 case 1:    /* found the field selector L`*/
  841.                     s += 2;  /* eat up L` or R` */
  842.                 case 0: /* not found */
  843.                     getExpression(s);
  844.                     break;
  845.                 default:
  846.                     as_bad("Bad field selector. Was: %.2s." "Should be either L` or R`\n",s);
  847.                     break;
  848.                 }
  849.                 if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
  850.                     im14 = sign_unext(
  851.                         evaluateAbsolute(the_insn.exp,field_selector),
  852.                         17);
  853.                     dis_assemble_17(im14>>2,&w1,&w2,&w);
  854.                     opcode |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
  855.                 }
  856.                 else {
  857.                     the_insn.reloc = HPPA_RELOC_BR17;
  858.                     the_insn.code = 'z';
  859.                 }
  860.                 s = expr_end;
  861.                 continue;
  862.             }
  863.             case 'k':   /* 21 bit immediate at 31 --- HI21 */
  864.             {
  865.                 int field_selector = parse_L_or_R(s);
  866.                 switch (field_selector) {
  867.                 case 2:    /* found the field selector R`*/
  868.                 case 1:    /* found the field selector L`*/
  869.                     s += 2;  /* eat up L` or R` */
  870.                 case 0: /* not found */
  871.                     getExpression(s);
  872.                     break;
  873.                 default:
  874.                     as_bad("Bad field selector. Was: %.2s." "Should be either L` or R`\n",s);
  875.                     break;
  876.                 }
  877.                 if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
  878.                     im21 = dis_assemble_21(
  879. (evaluateAbsolute(the_insn.exp,field_selector) >> 11));
  880.                     opcode |=  im21 ;
  881.                 }
  882.                 else {
  883.                     the_insn.reloc = HPPA_RELOC_HI21;
  884.                     the_insn.code = 'k';
  885.                 }
  886.                 s = expr_end;
  887.                 continue;
  888.               }
  889.             case 'n':   /* nullification for branch instructions */
  890.                 nullif = pa_parse_nullif(&s);
  891.                 opcode |= nullif << 1;
  892.                 continue;        
  893.             case 'w':   /* 12 bit branch displacement */
  894.                 getExpression(s);
  895.                 the_insn.pcrel_reloc = 0;
  896.                 the_insn.pcrel = 1;
  897.                 if ( the_insn.exp.X_add_symbol ) {
  898.                     if ( strcmp(
  899. the_insn.exp.X_add_symbol->sy_nlist.n_un.n_name,"L0\001") == 0 ) {
  900.                         unsigned long w1,w,result;
  901.                     result = sign_unext( (the_insn.exp.X_add_number
  902.                             - 8) >> 2,
  903.                             12);
  904.                     dis_assemble_12(result,&w1,&w);
  905.                     opcode |= ( ( w1 << 2 ) | w );
  906.                     }
  907.                     else {
  908. /* this has to be wrong -- dont know what is right! */
  909. /*  the_insn.reloc = R_PCREL_CALL; */
  910.                         the_insn.reloc = HPPA_RELOC_12BRANCH;
  911.                         the_insn.code = 'w';
  912.                     }
  913.                 }
  914.                 else {
  915.                     unsigned long w1,w,result;
  916.                     result = sign_unext( the_insn.exp.X_add_number >> 
  917.                     2,12);
  918.                     dis_assemble_12(result,&w1,&w);
  919.                     opcode |= ( ( w1 << 2 ) | w );
  920.                 }
  921.                 s = expr_end;
  922.                 continue;
  923.             case 'W':   /* 17 bit branch displacement --- BL17 */
  924.                 getExpression(s);
  925.                 /*
  926.                  * The NeXT linker has the ability to scatter
  927.                  * blocks of sections between labels.  This
  928.                  * requires that brances to labels that survive
  929.                  * to the link phase must be able to be
  930.                  * relocated.
  931.                  */
  932.                 if(the_insn.exp.X_add_symbol != NULL &&
  933.                    (the_insn.exp.X_add_symbol->sy_name[0] != 'L'
  934.                     || flagseen['L']))
  935.                     the_insn.pcrel_reloc = 1;
  936.                 else
  937.                     the_insn.pcrel_reloc = 0;
  938.                 the_insn.pcrel = 1;
  939.                       if ( the_insn.exp.X_add_symbol ) {
  940.                     if ( strcmp(the_insn.exp.X_add_symbol->sy_nlist.n_un.n_name,"L0\001") == 0 ) {
  941.                         unsigned long w2,w1,w,result;
  942.  
  943.                         result = sign_unext( 
  944.                             (the_insn.exp.X_add_number - 8) >> 2,17);
  945.                         dis_assemble_17(result,&w1,&w2,&w);
  946.                         opcode |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
  947.                     }
  948.                     else {
  949.                          if ( (the_insn.reloc == HPPA_RELOC_JBSR) &&
  950.                                 (the_insn.exp.X_add_symbol->sy_name[0] != 'L') )
  951.                             as_fatal("Stub label used in a JBSR must be "
  952.                                 "non-relocatable");
  953.                         the_insn.reloc = HPPA_RELOC_BL17;
  954.                         the_insn.code = 'W';
  955.                     }
  956.                 }
  957.                 else {
  958.                     unsigned long w2,w1,w,result;
  959.  
  960.                     result = sign_unext( the_insn.exp.X_add_number >> 2,17);
  961.                     dis_assemble_17(result,&w1,&w2,&w);
  962.                     opcode |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
  963.                 }
  964.                 s = expr_end;
  965.                 continue;
  966.             case '@':   /* 17 bit branch displacement --- JBSR */
  967.                 /*
  968.                  * If we are assembling -dynamic then if the
  969.                  * symbol name before the ',' has not yet been
  970.                  * seen it will be marked as a non-lazy
  971.                  * reference.
  972.                  */
  973.                 if(flagseen[(int)'k'] == TRUE){
  974.                     p = strchr(s, ',');
  975.                     if(p != NULL)
  976.                     *p = '\0';
  977.                     if(symbol_find(s) == NULL)
  978.                     reference =
  979.                         REFERENCE_FLAG_UNDEFINED_LAZY;
  980.                     else
  981.                     reference =
  982.                         REFERENCE_FLAG_UNDEFINED_NON_LAZY;
  983.                     if(p != NULL)
  984.                     *p = ',';
  985.                 }
  986.                 getExpression(s);
  987.  
  988. /*
  989.  * assumption here is this will only be used in case of jbsr
  990.  * in which case the format is 
  991.  *        jbsr,n symbol,register,label
  992.  * and a relocation entry for symbol needs to be created
  993.  */
  994.  
  995.                 the_insn.pcrel = 0;
  996.                 the_insn.pcrel_reloc = 1;
  997.                 the_insn.reloc = HPPA_RELOC_JBSR;
  998.                 the_insn.code = '@';
  999.                 s = expr_end;
  1000.  /*
  1001.   * The code to hook a frag in the chain should be here.
  1002.   * Then set a flag saying that the next 'W' should not create a relocation
  1003.   * entry. The way 'jbsr' is expected to work is the label will always be
  1004.   * local!
  1005.   * This flag should be reset in 'W'.
  1006.   */
  1007.                 found_jbsr = 1;
  1008.                 toP = frag_more(4);
  1009.                 fix_new(frag_now,
  1010.                     (toP - frag_now->fr_literal),
  1011.                     4,
  1012.                     the_insn.exp.X_add_symbol,
  1013.                     the_insn.exp.X_subtract_symbol,
  1014.                     the_insn.exp.X_add_number,
  1015.                     the_insn.pcrel,
  1016.                     the_insn.pcrel_reloc,
  1017.                     the_insn.reloc);
  1018.                 if(flagseen[(int)'k'] == TRUE)
  1019.                     the_insn.exp.X_add_symbol->sy_desc |=
  1020.                     reference;
  1021.  
  1022.                 continue;
  1023.             case 'B':   /* either "s,b" or "b" where b & s are defined above */
  1024.                 reg1 = pa_parse_number(&s);
  1025.                 if ( *s == ',' ) {
  1026.                     s++;
  1027.                     reg2 = pa_parse_number(&s);
  1028.                 }
  1029.                 else {
  1030.                     reg2 = reg1;
  1031.                     reg1 = 0;
  1032.                 }
  1033.                 if ( reg1 < 4 && reg1 >= 0 ) {
  1034.                     opcode |= reg1 << 14;
  1035.                     opcode |= reg2 << 21;
  1036.                     continue;
  1037.                 }
  1038.                 break;
  1039.             case 'p':   /* 5 bit shift count at 26 (to support SHD instr.) */
  1040.                         /* value is encoded in instr. as 31-p where p is   */
  1041.                         /* the value scanned here */
  1042.                 getExpression(s);
  1043.                 if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
  1044.                     opcode |= ( ( (31 - the_insn.exp.X_add_number) & 0x1f ) << 5 );
  1045.                 }
  1046.                 s = expr_end;
  1047.                 continue;
  1048.             case 'P':   /* 5-bit bit position at 26 */
  1049.                 getExpression(s);
  1050.                 if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
  1051.                     opcode |= ( the_insn.exp.X_add_number & 0x1f ) << 5;
  1052.                 }
  1053.                 s = expr_end;
  1054.                 continue;
  1055.             case 'Q':   /* 5  bit immediate at 10 */
  1056.                         /* (unsigned bit position value for the bb instruction) */
  1057.                 getExpression(s);
  1058.                 im5 = evaluateAbsolute(the_insn.exp,0);
  1059.                 if ( im5 > 31 ) {
  1060.                     as_bad("Operand out of range. Was: %d. Should be"
  1061.                         "[0..31]. Assuming %d.\n",im5,im5&0x1f);
  1062.                     im5 = im5 & 0x1f;
  1063.                 }
  1064.                 opcode |= im5 << 21;
  1065.                 s = expr_end;
  1066.                 continue;
  1067.             case 'A':   /* 13 bit immediate at 18 (to support BREAK instr.) */
  1068.                 getAbsoluteExpression(s);
  1069.                 if ( the_insn.exp.X_seg == SEG_ABSOLUTE )
  1070.                 opcode |= (the_insn.exp.X_add_number & 0x1fff) << 13;
  1071.                   s = expr_end;
  1072.                   continue;
  1073.             case 'Z':   /* System Control Completer(for LDA, LHA, etc.) */
  1074.                   if ( *s == ',' && ( *(s+1) == 'm' || *(s+1) == 'M' ) ) {
  1075.                     m = 1;
  1076.                     s += 2;
  1077.                   }
  1078.                   else
  1079.                     m = 0;
  1080.   
  1081.                   opcode |= m << 5;
  1082.                   while ( *s == ' ' || *s == '\t' ) /* skip to next operand */
  1083.                     s++;
  1084.   
  1085.                   continue;
  1086.             case 'D':   /* 26 bit immediate at 31 (to support DIAG instr.) */
  1087.                           /* the action (and interpretation of this operand is
  1088.                              implementation dependent) */
  1089.                   getExpression(s);
  1090.                   if ( the_insn.exp.X_seg == SEG_ABSOLUTE ) {
  1091.                     opcode |= ( (evaluateAbsolute(the_insn.exp,0) & 0x1ffffff) << 1 );
  1092.                   }
  1093.                   else
  1094.                     as_bad("Illegal DIAG operand");
  1095.                       s = expr_end;
  1096.                   continue;
  1097.             case 'f':   /* 3 bit Special Function Unit (SFU) identifier at 25 */
  1098.                   sfu = pa_parse_number(&s);
  1099.                   if ( (sfu > 7) || (sfu < 0) )
  1100.                     as_bad("Illegal SFU identifier: %02x", sfu);
  1101.                   opcode |= (sfu & 7) << 6;
  1102.                   continue;
  1103.             case 'O':   /* 20 bit SFU op. split between 15 bits at 20 and 5 bits at 31 */
  1104.                   getExpression(s);
  1105.                   s = expr_end;
  1106.                   continue;
  1107.             case 'o':   /* 15 bit Special Function Unit operation at 20 */
  1108.                   getExpression(s);
  1109.                   s = expr_end;
  1110.                   continue;
  1111.             case '2':   /* 22 bit SFU op. split between 17 bits at 20
  1112.                                and 5 bits at 31 */
  1113.                   getExpression(s);
  1114.                   s = expr_end;
  1115.                   continue;
  1116.             case '1':   /* 15 bit SFU op. split between 10 bits at 20
  1117.                                and 5 bits at 31 */
  1118.                   getExpression(s);
  1119.                   s = expr_end;
  1120.                   continue;
  1121.             case '0':   /* 10 bit SFU op. split between 5 bits at 20
  1122.                                and 5 bits at 31 */
  1123.                   getExpression(s);
  1124.                   s = expr_end;
  1125.                   continue;
  1126.             case 'u':   /* 3 bit coprocessor unit identifier at 25 */
  1127.                   getExpression(s);
  1128.                   s = expr_end;
  1129.                   continue;
  1130.             case 'F':   /* Source FP Operand Format Completer (2 bits at 20) */
  1131.                   f = pa_parse_fp_format(&s);
  1132.                   opcode |= (int)f << 11;
  1133.                   the_insn.fpof1 = f;
  1134.                   continue;
  1135.             case 'G':   /* Destination FP Operand Format Completer (2 bits at 18) */
  1136.                   s--;    /* need to pass the previous comma to pa_parse_fp_format */
  1137.                   f = pa_parse_fp_format(&s);
  1138.                   opcode |= (int)f << 13;
  1139.                   the_insn.fpof2 = f;
  1140.                   continue;
  1141.             case 'M':   /* FP Compare Conditions (encoded as 5 bits at 31) */
  1142.                   cond = pa_parse_fp_cmp_cond(&s);
  1143.                   opcode |= cond;
  1144.                   continue;
  1145.  
  1146.             case 'v':   /* a 't' type extended to handle L/R register halves. */
  1147.                   {
  1148.                     struct pa_89_fp_reg_struct result;
  1149.  
  1150.                     pa_89_parse_number(&s,&result);
  1151.                     if ( result.number_part < 32 && result.number_part >= 0 ) {
  1152.                           opcode |= (result.number_part & 0x1f);
  1153.  
  1154.                         /* 0x30 opcodes are FP arithmetic operation opcodes */
  1155.                         /* load/store FP opcodes do not get converted to 0x38 */
  1156.                         /* opcodes like the 0x30 opcodes do */
  1157.                         if ( need_89_opcode(&the_insn,&result) ) {
  1158.                             if ( (opcode & 0xfc000000) == 0x30000000 ) {
  1159.                                 opcode |= (result.L_R_select & 1) << 6;
  1160.                                 opcode |= 1 << 27;
  1161.                             }
  1162.                             else {
  1163.                                 opcode |= (result.L_R_select & 1) << 6;
  1164.                             }
  1165.                         }
  1166.                         continue;
  1167.                     }
  1168.                 }
  1169.                 break;
  1170.             case 'E':   /* a 'b' type extended to handle L/R register halves. */
  1171.                 {
  1172.                     struct pa_89_fp_reg_struct result;
  1173.  
  1174.                     pa_89_parse_number(&s,&result);
  1175.                     if ( result.number_part < 32 && result.number_part >= 0 ) {
  1176.                         opcode |= (result.number_part & 0x1f) << 21;
  1177.                         if ( need_89_opcode(&the_insn,&result) ) {
  1178.                             opcode |= (result.L_R_select & 1) << 7;
  1179.                             opcode |= 1 << 27;
  1180.                         }
  1181.                         continue;
  1182.                     }
  1183.                 }
  1184.                 break;
  1185.  
  1186.             case 'X':   /* an 'x' type extended to handle L/R register halves. */
  1187.                 {
  1188.                     struct pa_89_fp_reg_struct result;
  1189.  
  1190.  
  1191.                     pa_89_parse_number(&s,&result);
  1192.                     if ( result.number_part < 32 && result.number_part >= 0 ) {
  1193.                         opcode |= (result.number_part & 0x1f) << 16;
  1194.                         if ( need_89_opcode(&the_insn,&result) ) {
  1195.                             opcode |= (result.L_R_select & 1) << 12;
  1196.                             opcode |= 1 << 27;
  1197.                         }
  1198.                         continue;
  1199.                     }
  1200.                 }
  1201.                 break;
  1202.  
  1203.             case '4':   /* 5 bit register field at 10
  1204.                         (used in 'fmpyadd' and 'fmpysub') */
  1205.                 {
  1206.                     struct pa_89_fp_reg_struct result;
  1207.                     int status;
  1208.  
  1209.                     status = pa_89_parse_number(&s,&result);
  1210.                     if ( result.number_part < 32 && result.number_part >= 0 ) {
  1211.                         if ( the_insn.fpof1 == SGL ) {
  1212.                             result.number_part &= 0xF;
  1213.                             result.number_part |= (result.L_R_select & 1) << 4;
  1214.                         }
  1215.                         opcode |= result.number_part << 21;
  1216.                         continue;
  1217.                     }
  1218.                 }
  1219.                 break;
  1220.  
  1221.             case '6':   /* 5 bit register field at 15
  1222.                         (used in 'fmpyadd' and 'fmpysub') */
  1223.                 {
  1224.                     struct pa_89_fp_reg_struct result;
  1225.                     int status;
  1226.  
  1227.                     status = pa_89_parse_number(&s,&result);
  1228.                     if ( result.number_part < 32 && result.number_part >= 0 ) {
  1229.                         if ( the_insn.fpof1 == SGL ) {
  1230.                             result.number_part &= 0xF;
  1231.                             result.number_part |= (result.L_R_select & 1) << 4;
  1232.                         }
  1233.                         opcode |= result.number_part << 16;
  1234.                         continue;
  1235.                     }
  1236.                 }
  1237.                 break;
  1238.  
  1239.             case '7':   /* 5 bit register field at 31
  1240.                         (used in 'fmpyadd' and 'fmpysub') */
  1241.                 {
  1242.                     struct pa_89_fp_reg_struct result;
  1243.                     int status;
  1244.  
  1245.                     status = pa_89_parse_number(&s,&result);
  1246.                     if ( result.number_part < 32 && result.number_part >= 0 ) {
  1247.                         if ( the_insn.fpof1 == SGL ) {
  1248.                             result.number_part &= 0xF;
  1249.                             result.number_part |= (result.L_R_select & 1) << 4;
  1250.                         }
  1251.                         opcode |= result.number_part;
  1252.                         continue;
  1253.                     }
  1254.                 }
  1255.                 break;
  1256.  
  1257.             case '8':   /* 5 bit register field at 20
  1258.                         (used in 'fmpyadd' and 'fmpysub') */
  1259.                 {
  1260.                     struct pa_89_fp_reg_struct result;
  1261.                     int status;
  1262.  
  1263.                     status = pa_89_parse_number(&s,&result);
  1264.                     if ( result.number_part < 32 && result.number_part >= 0 ) {
  1265.                         if ( the_insn.fpof1 == SGL ) {
  1266.                             result.number_part &= 0xF;
  1267.                             result.number_part |= (result.L_R_select & 1) << 4;
  1268.                         }
  1269.                         opcode |= result.number_part << 11;
  1270.                         continue;
  1271.                     }
  1272.                 }
  1273.                 break;
  1274.  
  1275.             case '9':   /* 5 bit register field at 25
  1276.                         (used in 'fmpyadd' and 'fmpysub') */
  1277.                 {
  1278.                     struct pa_89_fp_reg_struct result;
  1279.                     int status;
  1280.  
  1281.                     status = pa_89_parse_number(&s,&result);
  1282.                     if ( result.number_part < 32 && result.number_part >= 0 ) {
  1283.                         if ( the_insn.fpof1 == SGL ) {
  1284.                             result.number_part &= 0xF;
  1285.                             result.number_part |= (result.L_R_select & 1) << 4;
  1286.                         }
  1287.                         opcode |= result.number_part << 6;
  1288.                         continue;
  1289.                     }
  1290.                 }
  1291.                 break;
  1292.  
  1293.             case 'H':  /* Floating Point Operand Format at 26 for       */
  1294.                         /* 'fmpyadd' and 'fmpysub' (very similar to 'F') */
  1295.                         /* bits are switched from other FP Operand       */
  1296.                         /* formats. 1=SGL, 1=<none>, 0=DBL               */
  1297.                 f = pa_parse_fp_format(&s);
  1298.                 switch (f) {
  1299.                 case SGL:
  1300.                     opcode |= 0x20;
  1301.                 case DBL:
  1302.                     the_insn.fpof1 = f;
  1303.                     continue;
  1304.  
  1305.                 case QUAD:
  1306.                 case ILLEGAL_FMT:
  1307.                 default:
  1308.                     as_bad("Illegal Floating Point Operand Format for"
  1309.                         "this instruction: '%s'",s);
  1310.                 }
  1311.                 break;
  1312.  
  1313.             case 'y' :  /* nullify at 26 */
  1314.                 nullif = pa_parse_nullif(&s);
  1315.                 opcode |= nullif << 5;
  1316.                 continue;
  1317.                         
  1318. /* bug #41317 .... umeshv@NeXT.com Mon May  2 17:53:29 PDT 1994
  1319.  
  1320.    These are for 'cache control hints'
  1321.     
  1322.     l    Store Instruction Cache Control Hint  (Table 5-8) with
  1323.         Short displacement load and store completers (Table 5-11) 
  1324.          
  1325.     L    Load and Clear Word Cache Control Hint (Table 5-9) with
  1326.         Indexed load completers (Table 5-10)
  1327.  
  1328.     3    Store Instruction Cache Control Hint  (Table 5-8) with
  1329.         Indexed load completers (Table 5-10)
  1330.  
  1331.     a    Load and Clear Word Cache Control Hint (Table 5-9) with
  1332.         Short displacement load and store completers (Table 5-11)
  1333.  
  1334.     These parse ",cc" and encode "cc" in 2 bits at 20,
  1335.     where "cc" encoding is as given in Tables 5-8, 5-9.
  1336.     Refer to 'PA-RISC 1.1 Architecture and Instruction Set Reference
  1337.     Manual, Second Edition' for the tables.
  1338. */
  1339.  
  1340.             case 'l' :  /* Store Instruction Cache Control Hint */
  1341.                         /* Short displacement load and store completers */
  1342.                 opcode |= parse_completer_with_cache_control_hint(&s, 0, 'C');
  1343.                 continue;
  1344.  
  1345.             case 'L' :  /* Load and Clear Word Cache Control Hint */
  1346.                         /* Indexed load completers  */
  1347.                 opcode |= parse_completer_with_cache_control_hint(&s, 1, 'c');
  1348.                 continue;
  1349.  
  1350.             case '3' :  /* Store Instruction Cache Control Hint */
  1351.                         /* Indexed load completers */
  1352.                 opcode |= parse_completer_with_cache_control_hint(&s, 0, 'c');
  1353.                 continue;
  1354.  
  1355.             case 'a' :  /* Load and Clear Word Cache Control Hint */
  1356.                         /* Short displacement load and store completers */
  1357.                 opcode |= parse_completer_with_cache_control_hint(&s, 1, 'C');
  1358.                 continue;
  1359.  
  1360.             default:
  1361.                 abort();
  1362.             }
  1363.             break;
  1364.         }
  1365.  
  1366.         if (match == FALSE)
  1367.         {
  1368.         /* Args don't match.  */
  1369.             if (&insn[1] - pa_opcodes < NUMOPCODES
  1370.                 && !strcmp(insn->name, insn[1].name))
  1371.             {
  1372.                 ++insn;
  1373.                 s = argsStart;
  1374.                 continue;
  1375.             }
  1376.             else
  1377.             {
  1378.                 as_bad("Illegal operands");
  1379.                 return;
  1380.             }
  1381.         }
  1382.         break;
  1383.     }
  1384.  
  1385.     the_insn.opcode = opcode;
  1386.     return;
  1387. }    /* end pa_ip() */
  1388.  
  1389. /*
  1390.     This is identical to the md_atof in m68k.c.  I think this is right,
  1391.     but I'm not sure.
  1392.  
  1393.    Turn a string in input_line_pointer into a floating point constant of type
  1394.    type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
  1395.    emitted is stored in *sizeP .  An error message is returned, or NULL on OK.
  1396.  */
  1397.  
  1398. /* Equal to MAX_PRECISION in atof-ieee.c */
  1399. #define MAX_LITTLENUMS 6
  1400.  
  1401. char *
  1402. md_atof(
  1403. int type,
  1404. char *litP,
  1405. int *sizeP)
  1406. {
  1407.     int    prec;
  1408.     LITTLENUM_TYPE words[MAX_LITTLENUMS];
  1409.     LITTLENUM_TYPE *wordP;
  1410.     char    *t;
  1411.     char    *atof_ieee();
  1412.  
  1413.     switch(type) {
  1414.  
  1415.     case 'f':
  1416.     case 'F':
  1417.     case 's':
  1418.     case 'S':
  1419.     prec = 2;
  1420.     break;
  1421.  
  1422.     case 'd':
  1423.     case 'D':
  1424.     case 'r':
  1425.     case 'R':
  1426.     prec = 4;
  1427.     break;
  1428.  
  1429.     case 'x':
  1430.     case 'X':
  1431.     prec = 6;
  1432.     break;
  1433.  
  1434.     case 'p':
  1435.     case 'P':
  1436.     prec = 6;
  1437.     break;
  1438.  
  1439.     default:
  1440.     *sizeP=0;
  1441.     return "Bad call to MD_ATOF()";
  1442.     }
  1443.     t=atof_ieee(input_line_pointer,type,words);
  1444.     if(t)
  1445.     input_line_pointer=t;
  1446.     *sizeP=prec * sizeof(LITTLENUM_TYPE);
  1447.     for(wordP=words;prec--;) {
  1448.     md_number_to_chars(litP,(long)(*wordP++),sizeof(LITTLENUM_TYPE));
  1449.     litP+=sizeof(LITTLENUM_TYPE);
  1450.     }
  1451.     return "";    /* Someone should teach Dean about null pointers */
  1452. }
  1453.  
  1454. /*
  1455.  * Write out big-endian.
  1456.  */
  1457. void
  1458. md_number_to_chars(
  1459. char *buf,
  1460. long val,
  1461. int n)
  1462. {
  1463.  
  1464.     switch(n) {
  1465.  
  1466.     case 4:
  1467.     *buf++ = val >> 24;
  1468.     *buf++ = val >> 16;
  1469.     case 2:
  1470.     *buf++ = val >> 8;
  1471.     case 1:
  1472.     *buf = val;
  1473.     break;
  1474.  
  1475.     default:
  1476.     abort();
  1477.     }
  1478.     return;
  1479. }
  1480.  
  1481. void
  1482. md_number_to_imm(
  1483. unsigned char *buf,
  1484. long val,
  1485. int n,
  1486. fixS *fixP,
  1487. int nsect)
  1488. {
  1489.     unsigned long w1,w2,w;
  1490.     unsigned new_val = 0;
  1491.     unsigned long left21, right14;
  1492.     
  1493.     if(fixP->fx_r_type == NO_RELOC ||
  1494.        fixP->fx_r_type == HPPA_RELOC_VANILLA){
  1495.         switch(n){
  1496.         case 4:
  1497.         *buf++ = val >> 24;
  1498.         *buf++ = val >> 16;
  1499.         case 2:
  1500.         *buf++ = val >> 8;
  1501.         case 1:
  1502.         *buf = val;
  1503.         break;
  1504.  
  1505.         default:
  1506.         abort();
  1507.         }
  1508.         return;
  1509.     }
  1510.  
  1511.  
  1512.     calc_hppa_HILO(val - fixP->fx_offset, fixP->fx_offset,
  1513.                &left21, &right14);
  1514.  
  1515.     switch (fixP->fx_r_type) {
  1516.     default:
  1517.         break;
  1518. /*     case 'j': */
  1519.     case HPPA_RELOC_LO14 :
  1520.          w = low_sign_unext(right14, 14); 
  1521.         goto fixit;
  1522.  
  1523. /*     case 'k': */
  1524.     case HPPA_RELOC_HI21 :
  1525.         w = dis_assemble_21((left21>>11));
  1526. fixit:
  1527.       /* There is no guarantee that buf is word-aligned,    */
  1528.       /* so the adjustment must be done the hard way.        */
  1529.  
  1530.         new_val  = (*buf & 0xff) << 24;
  1531.         new_val |= (*(buf+1) & 0xff) << 16;
  1532.         new_val |= (*(buf+2) & 0xff) << 8;
  1533.         new_val |= (*(buf+3) & 0xff);
  1534.         new_val |= w;    /* Now, make the adjustment */
  1535.         md_number_to_chars(buf,new_val,4);
  1536.         break;
  1537.  
  1538. /*     case 'W': */
  1539.     case HPPA_RELOC_BL17 :
  1540.         if ( !fixP->fx_addsy ) {
  1541.             val -= 4;    /* PA adjustment: a 0 disp is actually 4 bytes */
  1542.                         /* further because of the delay slot */
  1543.             val >>= 2;
  1544.             dis_assemble_17(val,&w1,&w2,&w);
  1545.         /* There is no guarantee that buf is word-aligned,    */
  1546.         /* so the adjustment must be done the hard way.        */
  1547.  
  1548.         new_val  = (*buf & 0xff) << 24;
  1549.         new_val |= (*(buf+1) & 0xff) << 16;
  1550.         new_val |= (*(buf+2) & 0xff) << 8;
  1551.         new_val |= (*(buf+3) & 0xff);
  1552.         new_val |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
  1553.                       /* Now, do the adjustment */
  1554.         md_number_to_chars(buf,new_val,4);
  1555.       }
  1556.       else {
  1557.         unsigned long result;
  1558.           val -= 4;    /* PA adjustment: a 0 disp is actually 4 bytes */
  1559.                         /* further because of the delay slot */
  1560.         val >>= 2;
  1561.  
  1562.         result = sign_unext( val,17);
  1563.         dis_assemble_17(result,&w1,&w2,&w);
  1564.         /* There is no guarantee that buf is word-aligned,    */
  1565.         /* so the adjustment must be done the hard way.        */
  1566.  
  1567.         new_val  = (*buf & 0xff) << 24;
  1568.         new_val |= (*(buf+1) & 0xff) << 16;
  1569.         new_val |= (*(buf+2) & 0xff) << 8;
  1570.         new_val |= (*(buf+3) & 0xff);
  1571.         new_val |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
  1572.                       /* Now, do the adjustment */
  1573.         md_number_to_chars(buf,new_val,4);
  1574.  
  1575.         }
  1576.         break;
  1577. /*     case 'z': */
  1578.     case HPPA_RELOC_BR17 :
  1579.     {
  1580.         unsigned long result;
  1581.         right14 >>= 2;
  1582.         result = sign_unext(right14,17);
  1583.         dis_assemble_17(result,&w1,&w2,&w);
  1584.     /* There is no guarantee that buf is word-aligned,    */
  1585.     /* so the adjustment must be done the hard way.        */
  1586.  
  1587.         new_val  = (*buf & 0xff) << 24;
  1588.         new_val |= (*(buf+1) & 0xff) << 16;
  1589.         new_val |= (*(buf+2) & 0xff) << 8;
  1590.         new_val |= (*(buf+3) & 0xff);
  1591.         new_val |= ( ( w2 << 2 ) | ( w1 << 16 ) | w );
  1592.                       /* Now, do the adjustment */
  1593.         md_number_to_chars(buf,new_val,4);
  1594.      }
  1595.             break;
  1596. /*     case '@': */
  1597.     case HPPA_RELOC_JBSR :
  1598. /*
  1599.  * In case of the jbsr relocation no bytes are to be written to the 
  1600.  * output.
  1601.  * 
  1602.  * SO DO NOTHING!
  1603.  */
  1604.       break;
  1605.       
  1606. /*      case 'w': */
  1607. /* To take care of 12 bit label */
  1608.       case HPPA_RELOC_12BRANCH :
  1609.         if ( !fixP->fx_addsy ) {
  1610.             val -= 4;    /* PA adjustment: a 0 disp is actually 4 bytes */
  1611.                         /* further because of the delay slot */
  1612.             val >>= 2;
  1613.             dis_assemble_12(val,&w1,&w);
  1614.             /* There is no guarantee that buf is word-aligned,    */
  1615.             /* so the adjustment must be done the hard way.        */
  1616.  
  1617.             new_val  = (*buf & 0xff) << 24;
  1618.             new_val |= (*(buf+1) & 0xff) << 16;
  1619.             new_val |= (*(buf+2) & 0xff) << 8;
  1620.             new_val |= (*(buf+3) & 0xff);
  1621.             new_val |= ( ( w1 << 2 ) | w );    /* Now, do the adjustment */
  1622.             md_number_to_chars(buf,new_val,4);
  1623.         }
  1624.         else {
  1625.             as_bad("Undefined symbol %s", fixP->fx_addsy->sy_name);
  1626.         }
  1627.         
  1628.          break;
  1629.     }
  1630. }
  1631.  
  1632. void
  1633. md_convert_frag(
  1634. fragS *fragP)
  1635. {
  1636.   unsigned int address;
  1637.  
  1638.   if ( fragP -> fr_type == rs_machine_dependent ) {
  1639.     switch ( (int) fragP -> fr_subtype ) {
  1640.     case 0:
  1641.       fragP -> fr_type = rs_fill;
  1642.       know( fragP -> fr_var == 1 );
  1643.       know( fragP -> fr_next );
  1644.       address = fragP -> fr_address + fragP -> fr_fix;
  1645.       if ( address % fragP -> fr_offset ) {
  1646.     fragP -> fr_offset =
  1647.       fragP -> fr_next -> fr_address
  1648.         -   fragP -> fr_address
  1649.           - fragP -> fr_fix;
  1650.       }
  1651.       else
  1652.     fragP -> fr_offset = 0;
  1653.       break;
  1654.     }
  1655.   }
  1656. }
  1657.  
  1658. int
  1659. md_estimate_size_before_relax(
  1660. fragS *fragP,
  1661. int nsect)
  1662. {
  1663.   int size;
  1664.  
  1665.   size = 0;
  1666.  
  1667.   while ( (fragP->fr_fix + size) % fragP->fr_offset )
  1668.     size++;
  1669.  
  1670.   return size;
  1671. }
  1672.  
  1673. int
  1674. md_parse_option(
  1675. char **argP,
  1676. int *cntP,
  1677. char ***vecP)
  1678. {
  1679.     return 1;
  1680. }
  1681.  
  1682. /*
  1683. int is_end_of_statement()
  1684. {
  1685.   return (   (*input_line_pointer == '\n')
  1686.       || (*input_line_pointer == ';')
  1687.       || (*input_line_pointer == '!') );
  1688. }
  1689. */
  1690.  
  1691. static
  1692. int
  1693. parse_L_or_R(
  1694. char *str)
  1695. {
  1696. /* not much work done as yet! */
  1697.     switch (*str) {
  1698.     case '%':
  1699.     case '(':
  1700.         return 0;    /* ie. not found */
  1701.         break;
  1702.     case 'L':
  1703.     case 'l':
  1704.         if (*(str+1) == '\'' || *(str+1) == '`') /* check next character */
  1705.             return 1; /* found */
  1706.         else
  1707.             return 0; /* not found */
  1708.         break;
  1709.     case 'R':
  1710.     case 'r':
  1711.         if (*(str+1) == '\'' || *(str+1) == '`') /* check next character */
  1712.             return 2; /* found */
  1713.         else
  1714.             return 0; /* not found */
  1715.         break;
  1716.     default: /* default is not found ... at least for the time being */
  1717.         return 0;
  1718.         break;
  1719.     }
  1720. }    /* end parse_L_or_R() */
  1721.  
  1722. static
  1723. unsigned long
  1724. parse_cache_control_hint(
  1725. char    **s,       /* Note : the function changes '*s' */
  1726. int     option)    /* option = 0 for store instruction */
  1727.                    /* option = 1 for load and clear instruction */
  1728. {
  1729.     unsigned long cc = NO_CACHE_CONTROL_HINT;
  1730.                 
  1731.     if (**s == ',') {
  1732.         (*s)++;
  1733.         switch (option) {
  1734.         case 0 : /* Store Instruction Cache Control Hint */ 
  1735.             if ( strncasecmp(*s,"bc",2) == 0 ) {
  1736.                 /* BLOCK_COPY */
  1737.                 (*s) += 2;
  1738.                 cc = BC_OR_CO_CACHE_CONTROL_HINT;
  1739.                 /* eat up extra blanks and tabs */
  1740.                 while ( **s == ' ' || **s == '\t' )
  1741.                     (*s)++;
  1742.             } else
  1743.                 as_fatal("Illegal Cache Control Hint: '%s'"
  1744.                     " - expected 'bc'",*s);
  1745.             break;
  1746.             
  1747.         case 1 : /* Load and Clear Word Cache Control Hint */
  1748.             if ( strncasecmp(*s,"co",2) == 0 ) {
  1749.                 /* COHERENT_OPERATION */
  1750.                 (*s) +=2;
  1751.                 cc = BC_OR_CO_CACHE_CONTROL_HINT;
  1752.                 /* eat up extra blanks and tabs */
  1753.                 while ( **s == ' ' || **s == '\t' )
  1754.                     (*s)++;
  1755.             } else
  1756.                 as_fatal("Illegal Cache Control Hint: '%s'"
  1757.                     " - expected 'co'",*s);
  1758.             break;
  1759.             
  1760.         default :
  1761.             as_fatal("Invalid option (%d) for parsing cache control hints",
  1762.                 option);
  1763.             break;
  1764.         }
  1765.     }
  1766.         /* else NO_HINT */
  1767.                 
  1768.     /*
  1769.     * the completers have already eaten up extra blanks
  1770.     * and tabs. So there is no need to do that again here.
  1771.     */
  1772.                  
  1773.     return cc;
  1774.  
  1775. }    /* end parse_cache_control_hint() */
  1776.  
  1777. static
  1778. unsigned long
  1779. parse_completer_with_cache_control_hint(
  1780. char    **s,       /* Note : the function changes '*s' */
  1781. int     option,    /* option = 0 for store instruction */
  1782.                    /* option = 1 for load and clear instruction */
  1783. char    completer) /* 'c' or 'C' */
  1784. {
  1785.     unsigned long i, result = (unsigned long) 0UL;
  1786.     int m, a, u;
  1787.     
  1788.     switch (completer) {
  1789.     case 'c':   /* indexed load completer. */
  1790.         i = m = u = 0;
  1791.         while ( **s == ',' && i < 3 ) {
  1792.             (*s)++;
  1793.             if ( strncasecmp((*s),"sm",2) == 0 ) {
  1794.                 m = u = 1;
  1795.                 (*s)++;
  1796.                 i++;
  1797.             }
  1798.             else if ( strncasecmp((*s),"m",1) == 0 )
  1799.                 m = 1;
  1800.             else if ( strncasecmp((*s),"s",1) == 0 )
  1801.                 u = 1;
  1802.             else if ( strncmp((*s),",",1) == 0 ) /* no completer */
  1803.                 result |= parse_cache_control_hint(s, option);
  1804.             else if ( (strncasecmp((*s),"c",1) == 0) ||
  1805.                       (strncasecmp((*s),"b",1) == 0) ) {/* just 1 completer */
  1806.                 (*s)--;
  1807.                 result |= parse_cache_control_hint(s, option);
  1808.             }
  1809.             else
  1810.                 as_bad("Unrecognized Indexed Load"
  1811.                     "Completer with cache control hints...assuming 0");
  1812.             if (result == (unsigned long)0UL)
  1813.                 (*s)++;
  1814.             i++;
  1815.         }
  1816.         if ( i > 3 )
  1817.             as_bad("Illegal Indexed Load Completer with cache control hints"
  1818.             " Syntax... extras ignored");
  1819.         while ( **s == ' ' || **s == '\t' )
  1820.             (*s)++;
  1821.   
  1822.         result |= m << 5;
  1823.         result |= u << 13;
  1824.         break;
  1825.     case 'C':   /* short load and store completer */
  1826.         i = m = a = 0;
  1827.         while ( **s == ',' && i < 2 ) {
  1828.             (*s)++;
  1829.             if ( strncasecmp((*s),"ma",2) == 0 ) {
  1830.                 a = 0;
  1831.                 m = 1;
  1832.             }
  1833.             else if ( strncasecmp((*s),"mb",2) == 0 ) {
  1834.                 m = a = 1;
  1835.             }
  1836.             else if ( strncmp((*s),",",1) == 0 ) /* no completer */
  1837.                 result |= parse_cache_control_hint(s, option);
  1838.             else if ( (strncasecmp((*s),"c",1) == 0) ||
  1839.                       (strncasecmp((*s),"b",1) == 0) ) {/* just 1 completer */
  1840.                 (*s)--;
  1841.                 result |= parse_cache_control_hint(s, option);
  1842.             }
  1843.             else
  1844.                 as_bad("Unrecognized Indexed Load Completer"
  1845.                 "...assuming 0");
  1846.             i++;
  1847.             (*s) += 2;
  1848.         }
  1849.         while ( **s == ' ' || **s == '\t' )
  1850.             (*s)++;
  1851.         result |= m << 5;
  1852.         result |= a << 13;
  1853.         break;
  1854.         
  1855.         
  1856.     default :
  1857.             as_fatal("Invalid completer (%c) for parsing cache control hints",
  1858.                 completer);
  1859.             break;
  1860.     }
  1861.     return result;
  1862. }    /* end parse_completer_with_cache_control_hint() */
  1863.  
  1864. /* end hppa.c */
  1865.