* elf-hppa.h (elf_hppa_reloc_final_type): Handle R_PARISC_GPREL64,
[deliverable/binutils-gdb.git] / gas / config / tc-hppa.c
index 66d72a1b8431319545f3ee3927f52f83eb896f32..da84526fa9513ccf01aa9d27dc8c62f249b7b583 100644 (file)
@@ -1,12 +1,12 @@
 /* tc-hppa.c -- Assemble for the PA
    Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-   2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
    GAS is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
+   the Free Software Foundation; either version 3, or (at your option)
    any later version.
 
    GAS is distributed in the hope that it will be useful,
 /* HP PA-RISC support was contributed by the Center for Software Science
    at the University of Utah.  */
 
-#include <stdio.h>
-
 #include "as.h"
 #include "safe-ctype.h"
 #include "subsegs.h"
+#include "dw2gencfi.h"
 
 #include "bfd/libhppa.h"
 
@@ -584,8 +583,8 @@ const char EXP_CHARS[] = "eE";
    As in 0f12.456 or 0d1.2345e12.
 
    Be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
-   changed in read.c.  Ideally it shouldn't hae to know abou it at
-   all, but nothing is ideal around here.  */
+   changed in read.c.  Ideally it shouldn't have to know about it
+   at all, but nothing is ideal around here.  */
 const char FLT_CHARS[] = "rRsSfFdDxXpP";
 
 static struct pa_it the_insn;
@@ -949,8 +948,8 @@ static const struct selector_entry selector_table[] =
 #ifdef OBJ_SOM
 /* default space and subspace dictionaries */
 
-#define GDB_SYMBOLS          GDB_SYMBOLS_SUBSPACE_NAME
-#define GDB_STRINGS          GDB_STRINGS_SUBSPACE_NAME
+#define GDB_SYMBOLS    GDB_SYMBOLS_SUBSPACE_NAME
+#define GDB_STRINGS    GDB_STRINGS_SUBSPACE_NAME
 
 /* pre-defined subsegments (subspaces) for the HPPA.  */
 #define SUBSEG_CODE   0
@@ -1013,9 +1012,9 @@ static struct default_space_dict pa_def_spaces[] =
     if ((FIELD) > (HIGH) || (FIELD) < (LOW)) \
       { \
        if (! IGNORE) \
-          as_bad (_("Field out of range [%d..%d] (%d)."), (LOW), (HIGH), \
+         as_bad (_("Field out of range [%d..%d] (%d)."), (LOW), (HIGH), \
                  (int) (FIELD));\
-        break; \
+       break; \
       } \
   }
 
@@ -1026,10 +1025,10 @@ static struct default_space_dict pa_def_spaces[] =
   { \
     if ((FIELD) > (HIGH) || (FIELD) < (LOW)) \
       { \
-        as_bad_where ((FILENAME), (LINE), \
+       as_bad_where ((FILENAME), (LINE), \
                      _("Field out of range [%d..%d] (%d)."), (LOW), (HIGH), \
                      (int) (FIELD));\
-        break; \
+       break; \
       } \
   }
 
@@ -1041,9 +1040,9 @@ static struct default_space_dict pa_def_spaces[] =
     if ((FIELD) & ((ALIGN) - 1)) \
       { \
        if (! IGNORE) \
-          as_bad (_("Field not properly aligned [%d] (%d)."), (ALIGN), \
+         as_bad (_("Field not properly aligned [%d] (%d)."), (ALIGN), \
                  (int) (FIELD));\
-        break; \
+       break; \
       } \
   }
 
@@ -1051,6 +1050,10 @@ static struct default_space_dict pa_def_spaces[] =
   ((exp).X_op == O_subtract                    \
    && strcmp (S_GET_NAME ((exp).X_op_symbol), "$global$") == 0)
 
+#define is_SB_relative(exp)                    \
+  ((exp).X_op == O_subtract                    \
+   && strcmp (S_GET_NAME ((exp).X_op_symbol), "$segrel$") == 0)
+
 #define is_PC_relative(exp)                    \
   ((exp).X_op == O_subtract                    \
    && strcmp (S_GET_NAME ((exp).X_op_symbol), "$PIC_pcrel$0") == 0)
@@ -1234,6 +1237,7 @@ fix_new_hppa (fragS *frag,
      it now so as not to confuse write.c.  Ditto for $PIC_pcrel$0.  */
   if (new_fix->fx_subsy
       && (strcmp (S_GET_NAME (new_fix->fx_subsy), "$global$") == 0
+         || strcmp (S_GET_NAME (new_fix->fx_subsy), "$segrel$") == 0
          || strcmp (S_GET_NAME (new_fix->fx_subsy), "$PIC_pcrel$0") == 0
          || strcmp (S_GET_NAME (new_fix->fx_subsy), "$tls_gdidx$") == 0
          || strcmp (S_GET_NAME (new_fix->fx_subsy), "$tls_ldidx$") == 0
@@ -1257,6 +1261,8 @@ cons_fix_new_hppa (fragS *frag, int where, int size, expressionS *exp)
   else if (is_PC_relative (*exp))
     rel_type = R_HPPA_PCREL_CALL;
 #ifdef OBJ_ELF
+  else if (is_SB_relative (*exp))
+    rel_type = R_PARISC_SEGREL32;
   else if (is_tls_gdidx (*exp))
     rel_type = R_PARISC_TLS_GD21L;
   else if (is_tls_ldidx (*exp))
@@ -1336,61 +1342,10 @@ pa_parse_nullif (char **s)
   return nullif;
 }
 
-/* Turn a string in input_line_pointer into a floating point constant of type
-   type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
-   emitted is stored in *sizeP .  An error message or NULL is returned.  */
-
-#define MAX_LITTLENUMS 6
-
 char *
 md_atof (int type, char *litP, int *sizeP)
 {
-  int prec;
-  LITTLENUM_TYPE words[MAX_LITTLENUMS];
-  LITTLENUM_TYPE *wordP;
-  char *t;
-
-  switch (type)
-    {
-
-    case 'f':
-    case 'F':
-    case 's':
-    case 'S':
-      prec = 2;
-      break;
-
-    case 'd':
-    case 'D':
-    case 'r':
-    case 'R':
-      prec = 4;
-      break;
-
-    case 'x':
-    case 'X':
-      prec = 6;
-      break;
-
-    case 'p':
-    case 'P':
-      prec = 6;
-      break;
-
-    default:
-      *sizeP = 0;
-      return _("Bad call to MD_ATOF()");
-    }
-  t = atof_ieee (input_line_pointer, type, words);
-  if (t)
-    input_line_pointer = t;
-  *sizeP = prec * sizeof (LITTLENUM_TYPE);
-  for (wordP = words; prec--;)
-    {
-      md_number_to_chars (litP, (valueT) (*wordP++), sizeof (LITTLENUM_TYPE));
-      litP += sizeof (LITTLENUM_TYPE);
-    }
-  return NULL;
+  return ieee_md_atof (type, litP, sizeP, TRUE);
 }
 
 /* Write out big-endian.  */
@@ -1427,6 +1382,18 @@ tc_gen_reloc (asection *section, fixS *fixp)
 
   reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
+
+  /* Allow fixup_segment to recognize hand-written pc-relative relocations.
+     When we went through cons_fix_new_hppa, we classified them as complex.  */
+  /* ??? It might be better to hide this +8 stuff in tc_cfi_emit_pcrel_expr,
+     undefine DIFF_EXPR_OK, and let these sorts of complex expressions fail
+     when R_HPPA_COMPLEX == R_PARISC_UNIMPLEMENTED.  */
+  if (fixp->fx_r_type == R_HPPA_COMPLEX && fixp->fx_pcrel)
+    {
+      fixp->fx_r_type = R_HPPA_PCREL_CALL;
+      fixp->fx_offset += 8;
+    }
+
   codes = hppa_gen_reloc_type (stdoutput,
                               fixp->fx_r_type,
                               hppa_fixp->fx_r_format,
@@ -1998,7 +1965,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
       case R_PARISC_TLS_LE14R:
       case R_PARISC_TLS_IE21L:
       case R_PARISC_TLS_IE14R:
-        if (fixP->fx_addsy)
+       if (fixP->fx_addsy)
          S_SET_THREAD_LOCAL (fixP->fx_addsy);
        break;
       default:
@@ -2151,8 +2118,8 @@ pa_parse_number (char **s, int is_float)
       p++;
       c = *p;
       /* Tege hack: Special case for general registers as the general
-         code makes a binary search with case translation, and is VERY
-         slow.  */
+        code makes a binary search with case translation, and is VERY
+        slow.  */
       if (c == 'r')
        {
          p++;
@@ -2207,7 +2174,7 @@ pa_parse_number (char **s, int is_float)
   else
     {
       /* And finally, it could be a symbol in the absolute section which
-         is effectively a constant, or a register alias symbol.  */
+        is effectively a constant, or a register alias symbol.  */
       name = p;
       c = *p;
       while (is_part_of_name (c))
@@ -2718,7 +2685,7 @@ pa_parse_nonneg_cmpsub_cmpltr (char **s)
          cmpltr = 7;
        }
       /* If we have something like addb,n then there is no condition
-         completer.  */
+        completer.  */
       else if (strcasecmp (name, "n") == 0)
        {
          cmpltr = 0;
@@ -2792,7 +2759,7 @@ pa_parse_neg_cmpsub_cmpltr (char **s)
          cmpltr = 7;
        }
       /* If we have something like addb,n then there is no condition
-         completer.  */
+        completer.  */
       else if (strcasecmp (name, "n") == 0)
        {
          cmpltr = 0;
@@ -3018,7 +2985,7 @@ pa_parse_nonneg_add_cmpltr (char **s)
          cmpltr = 7;
        }
       /* If we have something like addb,n then there is no condition
-         completer.  */
+        completer.  */
       else if (strcasecmp (name, "n") == 0)
        {
          cmpltr = 0;
@@ -3091,7 +3058,7 @@ pa_parse_neg_add_cmpltr (char **s)
          cmpltr = 7;
        }
       /* If we have something like addb,n then there is no condition
-         completer.  */
+        completer.  */
       else if (strcasecmp (name, "n") == 0)
        {
          cmpltr = 0;
@@ -3192,7 +3159,7 @@ pa_parse_addb_64_cmpltr (char **s)
          cmpltr = 15;
        }
       /* If we have something like addb,n then there is no condition
-         completer.  */
+        completer.  */
       else if (strcasecmp (name, "n") == 0)
        {
          cmpltr = 0;
@@ -3263,7 +3230,7 @@ pa_ip (char *str)
       return;
     }
 
-  /* Look up the opcode in the has table.  */
+  /* Look up the opcode in the hash table.  */
   if ((insn = (struct pa_opcode *) hash_find (op_hash, str)) == NULL)
     {
       as_bad ("Unknown opcode: `%s'", str);
@@ -3290,7 +3257,7 @@ pa_ip (char *str)
        goto failed;
 
       /* Build the opcode, checking as we go to make
-         sure that the operands match.  */
+        sure that the operands match.  */
       for (args = insn->args;; ++args)
        {
          /* Absorb white space in instruction.  */
@@ -3341,12 +3308,12 @@ pa_ip (char *str)
                s = s + 1;
 
              if (!strncasecmp (s, "%sar", 4))
-               {
+               {
                  s += 4;
                  continue;
                }
              else if (!strncasecmp (s, "%cr11", 5))
-               {
+               {
                  s += 5;
                  continue;
                }
@@ -3550,7 +3517,7 @@ pa_ip (char *str)
                      }
                    else if (*args == 'J')
                      {
-                       /* M bit is explicit in the major opcode.  */
+                       /* M bit is explicit in the major opcode.  */
                        INSERT_FIELD_AND_CONTINUE (opcode, a, 2);
                      }
                    else if (*args == 'e')
@@ -3942,7 +3909,7 @@ pa_ip (char *str)
                      permloc[2] = 8;
                      permloc[3] = 6;
                      for (; i < 4; i++)
-                       {
+                       {
                          switch (*s++)
                            {
                            case '0':
@@ -5117,7 +5084,7 @@ pa_ip (char *str)
                  continue;
                }
              else
-               break;
+               break;
 
            /* Handle '%sr0,%r31' implicit operand of be,l instruction.  */
            case 'Y':
@@ -5454,7 +5421,7 @@ pa_ip (char *str)
            /* Handle all floating point registers.  */
            case 'f':
              switch (*++args)
-               {
+               {
                /* Float target register.  */
                case 't':
                  if (!pa_parse_number (&s, 3))
@@ -5582,13 +5549,13 @@ pa_ip (char *str)
                    CHECK_FIELD (num, 31, 0, 0);
                    if (the_insn.fpof1 == SGL)
                      {
-                       if (num < 16)
-                         {
+                       if (num < 16)
+                         {
                            as_bad  (_("Invalid register for single precision fmpyadd or fmpysub"));
                            break;
-                         }
-                       num &= 0xF;
-                       num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0);
+                         }
+                       num &= 0xF;
+                       num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0);
                      }
                    INSERT_FIELD_AND_CONTINUE (opcode, num, 16);
                  }
@@ -5602,13 +5569,13 @@ pa_ip (char *str)
                    CHECK_FIELD (num, 31, 0, 0);
                    if (the_insn.fpof1 == SGL)
                      {
-                       if (num < 16)
-                         {
+                       if (num < 16)
+                         {
                            as_bad  (_("Invalid register for single precision fmpyadd or fmpysub"));
                            break;
-                         }
-                       num &= 0xF;
-                       num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0);
+                         }
+                       num &= 0xF;
+                       num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0);
                      }
                    INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
                  }
@@ -5622,13 +5589,13 @@ pa_ip (char *str)
                    CHECK_FIELD (num, 31, 0, 0);
                    if (the_insn.fpof1 == SGL)
                      {
-                       if (num < 16)
-                         {
+                       if (num < 16)
+                         {
                            as_bad  (_("Invalid register for single precision fmpyadd or fmpysub"));
                            break;
-                         }
-                       num &= 0xF;
-                       num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0);
+                         }
+                       num &= 0xF;
+                       num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0);
                      }
                    INSERT_FIELD_AND_CONTINUE (opcode, num, 6);
                  }
@@ -5642,13 +5609,13 @@ pa_ip (char *str)
                    CHECK_FIELD (num, 31, 0, 0);
                    if (the_insn.fpof1 == SGL)
                      {
-                       if (num < 16)
-                         {
+                       if (num < 16)
+                         {
                            as_bad  (_("Invalid register for single precision fmpyadd or fmpysub"));
                            break;
-                         }
-                       num &= 0xF;
-                       num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0);
+                         }
+                       num &= 0xF;
+                       num |= (pa_number & FP_REG_RSEL ? 1 << 4 : 0);
                      }
                    INSERT_FIELD_AND_CONTINUE (opcode, num, 11);
                  }
@@ -5950,24 +5917,6 @@ pa_call (int unused ATTRIBUTE_UNUSED)
   demand_empty_rest_of_line ();
 }
 
-/* Return TRUE if FRAG1 and FRAG2 are the same.  */
-
-static bfd_boolean
-is_same_frag (fragS *frag1, fragS *frag2)
-{
-
-  if (frag1 == NULL)
-    return FALSE;
-  else if (frag2 == NULL)
-    return FALSE;
-  else if (frag1 == frag2)
-    return TRUE;
-  else if (frag2->fr_type == rs_fill && frag2->fr_fix == 0)
-    return (is_same_frag (frag1, frag2->fr_next));
-  else
-    return FALSE;
-}
-
 #ifdef OBJ_ELF
 /* Build an entry in the UNWIND subspace from the given function
    attributes in CALL_INFO.  This is not needed for SOM as using
@@ -6149,7 +6098,7 @@ pa_callinfo (int unused ATTRIBUTE_UNUSED)
          last_call_info->ci_unwind.descriptor.save_sp = 1;
        }
       /* Is this an unwindable procedure.  If so mark it so
-         in the unwind descriptor.  */
+        in the unwind descriptor.  */
       else if ((strncasecmp (name, "no_unwind", 9) == 0))
        {
          p = input_line_pointer;
@@ -6157,7 +6106,7 @@ pa_callinfo (int unused ATTRIBUTE_UNUSED)
          last_call_info->ci_unwind.descriptor.cannot_unwind = 1;
        }
       /* Is this an interrupt routine.  If so mark it in the
-         unwind descriptor.  */
+        unwind descriptor.  */
       else if ((strncasecmp (name, "hpux_int", 7) == 0))
        {
          p = input_line_pointer;
@@ -6218,7 +6167,7 @@ pa_data (int unused ATTRIBUTE_UNUSED)
 }
 
 /* This is different than the standard GAS s_comm(). On HP9000/800 machines,
-   the .comm pseudo-op has the following symtax:
+   the .comm pseudo-op has the following syntax:
 
    <label> .comm <length>
 
@@ -6260,8 +6209,8 @@ pa_comm (int unused ATTRIBUTE_UNUSED)
       S_SET_EXTERNAL (symbol);
 
       /* colon() has already set the frag to the current location in the
-         current subspace; we need to reset the fragment to the zero address
-         fragment.  We also need to reset the segment pointer.  */
+        current subspace; we need to reset the fragment to the zero address
+        fragment.  We also need to reset the segment pointer.  */
       symbol_set_frag (symbol, &zero_address_frag);
     }
   demand_empty_rest_of_line ();
@@ -6554,11 +6503,11 @@ pa_type_args (symbolS *symbolP, int is_export)
     {
       input_line_pointer += 4;
       /* IMPORTing/EXPORTing CODE types for functions is meaningless for SOM,
-         instead one should be IMPORTing/EXPORTing ENTRY types.
+        instead one should be IMPORTing/EXPORTing ENTRY types.
 
-         Complain if one tries to EXPORT a CODE type since that's never
-         done.  Both GCC and HP C still try to IMPORT CODE types, so
-         silently fix them to be ENTRY types.  */
+        Complain if one tries to EXPORT a CODE type since that's never
+        done.  Both GCC and HP C still try to IMPORT CODE types, so
+        silently fix them to be ENTRY types.  */
       if (S_IS_FUNCTION (symbolP))
        {
          if (is_export)
@@ -6711,10 +6660,10 @@ pa_export (int unused ATTRIBUTE_UNUSED)
   else
     {
       /* OK.  Set the external bits and process argument relocations.
-         For the HP, weak and global are not mutually exclusive.
-         S_SET_EXTERNAL will not set BSF_GLOBAL if WEAK is set.
-         Call S_SET_EXTERNAL to get the other processing.  Manually
-         set BSF_GLOBAL when we get back.  */
+        For the HP, weak and global are not mutually exclusive.
+        S_SET_EXTERNAL will not set BSF_GLOBAL if WEAK is set.
+        Call S_SET_EXTERNAL to get the other processing.  Manually
+        set BSF_GLOBAL when we get back.  */
       S_SET_EXTERNAL (symbol);
       symbol_get_bfdsym (symbol)->flags |= BSF_GLOBAL;
       p = input_line_pointer;
@@ -7125,8 +7074,8 @@ pa_parse_space_stmt (char *space_name, int create_flag)
       print_errors = FALSE;
       ptemp = input_line_pointer + 1;
       /* First see if the space was specified as a number rather than
-         as a name.  According to the PA assembly manual the rest of
-         the line should be ignored.  */
+        as a name.  According to the PA assembly manual the rest of
+        the line should be ignored.  */
       strict = 0;
       pa_parse_number (&ptemp, 0);
       if (pa_number >= 0)
@@ -7222,8 +7171,8 @@ pa_space (int unused ATTRIBUTE_UNUSED)
   else
     {
       /* Check for some of the predefined spaces.   FIXME: most of the code
-         below is repeated several times, can we extract the common parts
-         and place them into a subroutine or something similar?  */
+        below is repeated several times, can we extract the common parts
+        and place them into a subroutine or something similar?  */
       /* FIXME Is this (and the next IF stmt) really right?
         What if INPUT_LINE_POINTER points to "$TEXT$FOO"?  */
       if (strncmp (input_line_pointer, "$TEXT$", 6) == 0)
@@ -7401,7 +7350,7 @@ pa_subspace (int create_new)
       else
        ssd = is_defined_subspace (ss_name);
       /* Allow user to override the builtin attributes of subspaces.  But
-         only allow the attributes to be changed once!  */
+        only allow the attributes to be changed once!  */
       if (ssd && SUBSPACE_DEFINED (ssd))
        {
          subseg_set (ssd->ssd_seg, ssd->ssd_subseg);
@@ -7438,7 +7387,7 @@ pa_subspace (int create_new)
        }
 
       /* We should be working with a new subspace now.  Fill in
-         any information as specified by the user.  */
+        any information as specified by the user.  */
       if (!is_end_of_statement ())
        {
          input_line_pointer++;
@@ -7515,7 +7464,7 @@ pa_subspace (int create_new)
        }
 
       /* Compute a reasonable set of BFD flags based on the information
-         in the .subspace directive.  */
+        in the .subspace directive.  */
       applicable = bfd_applicable_section_flags (stdoutput);
       flags = 0;
       if (loadable)
@@ -7543,12 +7492,12 @@ pa_subspace (int create_new)
       applicable &= flags;
 
       /* If this is an existing subspace, then we want to use the
-         segment already associated with the subspace.
+        segment already associated with the subspace.
 
-         FIXME NOW!  ELF BFD doesn't appear to be ready to deal with
-         lots of sections.  It might be a problem in the PA ELF
-         code, I do not know yet.  For now avoid creating anything
-         but the "standard" sections for ELF.  */
+        FIXME NOW!  ELF BFD doesn't appear to be ready to deal with
+        lots of sections.  It might be a problem in the PA ELF
+        code, I do not know yet.  For now avoid creating anything
+        but the "standard" sections for ELF.  */
       if (create_new)
        section = subseg_force_new (ss_name, 0);
       else if (ssd)
@@ -7570,7 +7519,7 @@ pa_subspace (int create_new)
                           pa_subspace_start (space, quadrant));
 
       /* Now that all the flags are set, update an existing subspace,
-         or create a new one.  */
+        or create a new one.  */
       if (ssd)
 
        current_subspace = update_subspace (space, ss_name, loadable,
@@ -7627,7 +7576,7 @@ pa_spaces_begin (void)
       sd_chain_struct *space;
 
       /* Pick the right name for the new section and pick the right
-         subsegment number.  */
+        subsegment number.  */
       name = pa_def_subspaces[i].name;
       subsegment = 0;
 
@@ -7635,7 +7584,7 @@ pa_spaces_begin (void)
       segment = subseg_new (name, subsegment);
 
       /* For SOM we want to replace the standard .text, .data, and .bss
-         sections with our own.   We also want to set BFD flags for
+        sections with our own.   We also want to set BFD flags for
         all the built-in subspaces.  */
       if (!strcmp (pa_def_subspaces[i].name, "$CODE$"))
        {
@@ -7770,7 +7719,7 @@ create_new_space (char *name,
        }
 
       /* At this point we've found the correct place to add the new
-         entry.  So add it and update the linked lists as appropriate.  */
+        entry.  So add it and update the linked lists as appropriate.  */
       if (prev_chain_pointer)
        {
          chain_entry->sd_next = chain_pointer;
@@ -7854,7 +7803,7 @@ create_new_subspace (sd_chain_struct *space,
        }
 
       /* Now we have somewhere to put the new entry.  Insert it and update
-         the links.  */
+        the links.  */
       if (prev_chain_pointer)
        {
          chain_entry->ssd_next = chain_pointer;
@@ -8151,7 +8100,7 @@ pa_stringer (int append_zero)
            }
        }
     }
-  stringer (append_zero);
+  stringer (8 + append_zero);
   pa_undefine_label ();
 }
 
@@ -8316,7 +8265,7 @@ md_begin (void)
   dummy_symbol = symbol_find_or_make ("L$dummy");
   S_SET_SEGMENT (dummy_symbol, text_section);
   /* Force the symbol to be converted to a real symbol.  */
-  (void) symbol_get_bfdsym (dummy_symbol);
+  symbol_get_bfdsym (dummy_symbol)->flags |= BSF_KEEP;
 #endif
 }
 
@@ -8692,3 +8641,45 @@ const pseudo_typeS md_pseudo_table[] =
   {"word", pa_cons, 4},
   {NULL, 0, 0}
 };
+
+#ifdef OBJ_ELF
+void
+hppa_cfi_frame_initial_instructions (void)
+{
+  cfi_add_CFA_def_cfa (30, 0);
+}
+
+int
+hppa_regname_to_dw2regnum (char *regname)
+{
+  unsigned int regnum = -1;
+  unsigned int i;
+  const char *p;
+  char *q;
+  static struct { char *name; int dw2regnum; } regnames[] =
+    {
+      { "sp", 30 }, { "rp", 2 },
+    };
+
+  for (i = 0; i < ARRAY_SIZE (regnames); ++i)
+    if (strcmp (regnames[i].name, regname) == 0)
+      return regnames[i].dw2regnum;
+
+  if (regname[0] == 'r')
+    {
+      p = regname + 1;
+      regnum = strtoul (p, &q, 10);
+      if (p == q || *q || regnum >= 32)
+       return -1;
+    }
+  else if (regname[0] == 'f' && regname[1] == 'r')
+    {
+      p = regname + 2;
+      regnum = strtoul (p, &q, 10);
+      if (p == q || *q || regnum <= 4 || regnum >= 32)
+       return -1;
+      regnum += 32 - 4;
+    }
+  return regnum;
+}
+#endif
This page took 0.037164 seconds and 4 git commands to generate.