OSDN Git Service

* pa.c (last_address): Change to unsigned.
[pf3gnuchains/gcc-fork.git] / gcc / config / pa / pa.c
index b4d890c..44ded73 100644 (file)
@@ -1,6 +1,6 @@
 /* Subroutines for insn-output.c for HPPA.
    Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-   2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+   2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
    Contributed by Tim Moore (moore@cs.utah.edu), based on sparc.c
 
 This file is part of GCC.
@@ -86,8 +86,8 @@ hppa_fpstore_bypass_p (rtx out_insn, rtx in_insn)
 static void copy_reg_pointer (rtx, rtx);
 static void fix_range (const char *);
 static bool pa_handle_option (size_t, const char *, int);
-static int hppa_address_cost (rtx);
-static bool hppa_rtx_costs (rtx, int, int, int *);
+static int hppa_address_cost (rtx, bool);
+static bool hppa_rtx_costs (rtx, int, int, int *, bool);
 static inline rtx force_mode (enum machine_mode, rtx);
 static void pa_reorg (void);
 static void pa_combine_instructions (void);
@@ -103,7 +103,7 @@ static void store_reg_modify (int, int, HOST_WIDE_INT);
 static void load_reg (int, HOST_WIDE_INT, int);
 static void set_reg_plus_d (int, int, HOST_WIDE_INT, int);
 static void pa_output_function_prologue (FILE *, HOST_WIDE_INT);
-static void update_total_code_bytes (int);
+static void update_total_code_bytes (unsigned int);
 static void pa_output_function_epilogue (FILE *, HOST_WIDE_INT);
 static int pa_adjust_cost (rtx, rtx, rtx, int);
 static int pa_adjust_priority (rtx, int);
@@ -125,7 +125,7 @@ static void pa_asm_out_destructor (rtx, int);
 static void pa_init_builtins (void);
 static rtx hppa_builtin_saveregs (void);
 static void hppa_va_start (tree, rtx);
-static tree hppa_gimplify_va_arg_expr (tree, tree, tree *, tree *);
+static tree hppa_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *);
 static bool pa_scalar_mode_supported_p (enum machine_mode);
 static bool pa_commutative_p (const_rtx x, int outer_code);
 static void copy_fp_args (rtx) ATTRIBUTE_UNUSED;
@@ -191,7 +191,7 @@ unsigned long total_code_bytes;
 /* The last address of the previous function plus the number of bytes in
    associated thunks that have been output.  This is used to determine if
    a thunk can use an IA-relative branch to reach its target function.  */
-static int last_address;
+static unsigned int last_address;
 
 /* Variables to handle plabels that we discover are necessary at assembly
    output time.  They are output after the current function.  */
@@ -538,7 +538,7 @@ pa_init_builtins (void)
 static struct machine_function *
 pa_init_machine_status (void)
 {
-  return ggc_alloc_cleared (sizeof (machine_function));
+  return GGC_CNEW (machine_function);
 }
 
 /* If FROM is a probable pointer register, mark TO as a probable
@@ -668,6 +668,8 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
   /* Labels need special handling.  */
   if (pic_label_operand (orig, mode))
     {
+      rtx insn;
+
       /* We do not want to go through the movXX expanders here since that
         would create recursion.
 
@@ -678,8 +680,24 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
         So instead we just emit the raw set, which avoids the movXX
         expanders completely.  */
       mark_reg_pointer (reg, BITS_PER_UNIT);
-      emit_insn (gen_rtx_SET (VOIDmode, reg, orig));
-      current_function_uses_pic_offset_table = 1;
+      insn = emit_insn (gen_rtx_SET (VOIDmode, reg, orig));
+
+      /* Put a REG_EQUAL note on this insn, so that it can be optimized.  */
+      REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_EQUAL, orig, REG_NOTES (insn));
+
+      /* During and after reload, we need to generate a REG_LABEL_OPERAND note
+        and update LABEL_NUSES because this is not done automatically.  */
+      if (reload_in_progress || reload_completed)
+       {
+         /* Extract LABEL_REF.  */
+         if (GET_CODE (orig) == CONST)
+           orig = XEXP (XEXP (orig, 0), 0);
+         /* Extract CODE_LABEL.  */
+         orig = XEXP (orig, 0);
+         add_reg_note (insn, REG_LABEL_OPERAND, orig);
+         LABEL_NUSES (orig)++;
+       }
+      crtl->uses_pic_offset_table = 1;
       return reg;
     }
   if (GET_CODE (orig) == SYMBOL_REF)
@@ -694,17 +712,39 @@ legitimize_pic_address (rtx orig, enum machine_mode mode, rtx reg)
       tmp_reg = ((reload_in_progress || reload_completed)
                 ? reg : gen_reg_rtx (Pmode));
 
-      emit_move_insn (tmp_reg,
-                     gen_rtx_PLUS (word_mode, pic_offset_table_rtx,
-                                   gen_rtx_HIGH (word_mode, orig)));
-      pic_ref
-       = gen_const_mem (Pmode,
-                        gen_rtx_LO_SUM (Pmode, tmp_reg,
-                                        gen_rtx_UNSPEC (Pmode,
+      if (function_label_operand (orig, mode))
+       {
+         /* Force function label into memory in word mode.  */
+         orig = XEXP (force_const_mem (word_mode, orig), 0);
+         /* Load plabel address from DLT.  */
+         emit_move_insn (tmp_reg,
+                         gen_rtx_PLUS (word_mode, pic_offset_table_rtx,
+                                       gen_rtx_HIGH (word_mode, orig)));
+         pic_ref
+           = gen_const_mem (Pmode,
+                            gen_rtx_LO_SUM (Pmode, tmp_reg,
+                                            gen_rtx_UNSPEC (Pmode,
                                                         gen_rtvec (1, orig),
                                                         UNSPEC_DLTIND14R)));
+         emit_move_insn (reg, pic_ref);
+         /* Now load address of function descriptor.  */
+         pic_ref = gen_rtx_MEM (Pmode, reg);
+       }
+      else
+       {
+         /* Load symbol reference from DLT.  */
+         emit_move_insn (tmp_reg,
+                         gen_rtx_PLUS (word_mode, pic_offset_table_rtx,
+                                       gen_rtx_HIGH (word_mode, orig)));
+         pic_ref
+           = gen_const_mem (Pmode,
+                            gen_rtx_LO_SUM (Pmode, tmp_reg,
+                                            gen_rtx_UNSPEC (Pmode,
+                                                        gen_rtvec (1, orig),
+                                                        UNSPEC_DLTIND14R)));
+       }
 
-      current_function_uses_pic_offset_table = 1;
+      crtl->uses_pic_offset_table = 1;
       mark_reg_pointer (reg, BITS_PER_UNIT);
       insn = emit_move_insn (reg, pic_ref);
 
@@ -926,7 +966,7 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
       int mask;
 
       mask = (GET_MODE_CLASS (mode) == MODE_FLOAT
-             ? (TARGET_PA_20 ? 0x3fff : 0x1f) : 0x3fff);
+             ? (INT14_OK_STRICT ? 0x3fff : 0x1f) : 0x3fff);
 
       /* Choose which way to round the offset.  Round up if we
         are >= halfway to the next boundary.  */
@@ -1239,7 +1279,8 @@ hppa_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
    as GO_IF_LEGITIMATE_ADDRESS.  */
 
 static int
-hppa_address_cost (rtx X)
+hppa_address_cost (rtx X,
+                  bool speed ATTRIBUTE_UNUSED)
 {
   switch (GET_CODE (X))
     {
@@ -1259,7 +1300,8 @@ hppa_address_cost (rtx X)
    scanned.  In either case, *TOTAL contains the cost result.  */
 
 static bool
-hppa_rtx_costs (rtx x, int code, int outer_code, int *total)
+hppa_rtx_costs (rtx x, int code, int outer_code, int *total,
+               bool speed ATTRIBUTE_UNUSED)
 {
   switch (code)
     {
@@ -1671,8 +1713,7 @@ emit_move_sequence (rtx *operands, enum machine_mode mode, rtx scratch_reg)
                    decl = TREE_OPERAND (decl, 1);
 
                  type = TREE_TYPE (decl);
-                 if (TREE_CODE (type) == ARRAY_TYPE)
-                   type = get_inner_array_type (type);
+                 type = strip_array_types (type);
 
                  if (POINTER_TYPE_P (type))
                    {
@@ -2062,8 +2103,7 @@ reloc_needed (tree exp)
       reloc |= reloc_needed (TREE_OPERAND (exp, 1));
       break;
 
-    case NOP_EXPR:
-    case CONVERT_EXPR:
+    CASE_CONVERT:
     case NON_LVALUE_EXPR:
       reloc = reloc_needed (TREE_OPERAND (exp, 0));
       break;
@@ -3490,7 +3530,7 @@ compute_frame_size (HOST_WIDE_INT size, int *fregs_live)
   /* If the current function calls __builtin_eh_return, then we need
      to allocate stack space for registers that will hold data for
      the exception handler.  */
-  if (DO_FRAME_NOTES && current_function_calls_eh_return)
+  if (DO_FRAME_NOTES && crtl->calls_eh_return)
     {
       unsigned int i;
 
@@ -3529,7 +3569,7 @@ compute_frame_size (HOST_WIDE_INT size, int *fregs_live)
      size of the current function's stack frame.  We don't need to align
      for the outgoing arguments as their alignment is set by the final
      rounding for the frame as a whole.  */
-  size += current_function_outgoing_args_size;
+  size += crtl->outgoing_args_size;
 
   /* Allocate space for the fixed frame marker.  This space must be
      allocated for any function that makes calls or allocates
@@ -3638,7 +3678,7 @@ hppa_expand_prologue (void)
   /* Save RP first.  The calling conventions manual states RP will
      always be stored into the caller's frame at sp - 20 or sp - 16
      depending on which ABI is in use.  */
-  if (df_regs_ever_live_p (2) || current_function_calls_eh_return)
+  if (df_regs_ever_live_p (2) || crtl->calls_eh_return)
     {
       store_reg (2, TARGET_64BIT ? -16 : -20, STACK_POINTER_REGNUM);
       rp_saved = true;
@@ -3738,7 +3778,7 @@ hppa_expand_prologue (void)
       /* Saving the EH return data registers in the frame is the simplest
         way to get the frame unwind information emitted.  We put them
         just before the general registers.  */
-      if (DO_FRAME_NOTES && current_function_calls_eh_return)
+      if (DO_FRAME_NOTES && crtl->calls_eh_return)
        {
          unsigned int i, regno;
 
@@ -3770,7 +3810,7 @@ hppa_expand_prologue (void)
 
       /* Saving the EH return data registers in the frame is the simplest
          way to get the frame unwind information emitted.  */
-      if (DO_FRAME_NOTES && current_function_calls_eh_return)
+      if (DO_FRAME_NOTES && crtl->calls_eh_return)
        {
          unsigned int i, regno;
 
@@ -3946,23 +3986,18 @@ load_reg (int reg, HOST_WIDE_INT disp, int base)
 /* Update the total code bytes output to the text section.  */
 
 static void
-update_total_code_bytes (int nbytes)
+update_total_code_bytes (unsigned int nbytes)
 {
   if ((TARGET_PORTABLE_RUNTIME || !TARGET_GAS || !TARGET_SOM)
       && !IN_NAMED_SECTION_P (cfun->decl))
     {
-      if (INSN_ADDRESSES_SET_P ())
-       {
-         unsigned long old_total = total_code_bytes;
+      unsigned int old_total = total_code_bytes;
 
-         total_code_bytes += nbytes;
+      total_code_bytes += nbytes;
 
-         /* Be prepared to handle overflows.  */
-         if (old_total > total_code_bytes)
-           total_code_bytes = -1;
-       }
-      else
-       total_code_bytes = -1;
+      /* Be prepared to handle overflows.  */
+      if (old_total > total_code_bytes)
+        total_code_bytes = UINT_MAX;
     }
 }
 
@@ -4026,6 +4061,8 @@ pa_output_function_epilogue (FILE *file, HOST_WIDE_INT size ATTRIBUTE_UNUSED)
       last_address = ((last_address + FUNCTION_BOUNDARY / BITS_PER_UNIT - 1)
                      & ~(FUNCTION_BOUNDARY / BITS_PER_UNIT - 1));
     }
+  else
+    last_address = UINT_MAX;
 
   /* Finally, update the total number of code bytes output so far.  */
   update_total_code_bytes (last_address);
@@ -4072,7 +4109,7 @@ hppa_expand_epilogue (void)
 
       /* If the current function calls __builtin_eh_return, then we need
          to restore the saved EH data registers.  */
-      if (DO_FRAME_NOTES && current_function_calls_eh_return)
+      if (DO_FRAME_NOTES && crtl->calls_eh_return)
        {
          unsigned int i, regno;
 
@@ -4100,7 +4137,7 @@ hppa_expand_epilogue (void)
 
       /* If the current function calls __builtin_eh_return, then we need
          to restore the saved EH data registers.  */
-      if (DO_FRAME_NOTES && current_function_calls_eh_return)
+      if (DO_FRAME_NOTES && crtl->calls_eh_return)
        {
          unsigned int i, regno;
 
@@ -4197,7 +4234,7 @@ hppa_expand_epilogue (void)
   if (ret_off != 0)
     load_reg (2, ret_off, STACK_POINTER_REGNUM);
 
-  if (DO_FRAME_NOTES && current_function_calls_eh_return)
+  if (DO_FRAME_NOTES && crtl->calls_eh_return)
     {
       rtx sa = EH_RETURN_STACKADJ_RTX;
 
@@ -5646,19 +5683,19 @@ output_arg_descriptor (rtx call_insn)
 }
 \f
 static enum reg_class
-pa_secondary_reload (bool in_p, rtx x, enum reg_class class,
+pa_secondary_reload (bool in_p, rtx x, enum reg_class rclass,
                     enum machine_mode mode, secondary_reload_info *sri)
 {
   int is_symbolic, regno;
 
   /* Handle the easy stuff first.  */
-  if (class == R1_REGS)
+  if (rclass == R1_REGS)
     return NO_REGS;
 
   if (REG_P (x))
     {
       regno = REGNO (x);
-      if (class == BASE_REG_CLASS && regno < FIRST_PSEUDO_REGISTER)
+      if (rclass == BASE_REG_CLASS && regno < FIRST_PSEUDO_REGISTER)
        return NO_REGS;
     }
   else
@@ -5674,7 +5711,7 @@ pa_secondary_reload (bool in_p, rtx x, enum reg_class class,
      generation requires %r1 as a scratch register.  */
   if (flag_pic
       && (mode == SImode || mode == DImode)
-      && FP_REG_CLASS_P (class)
+      && FP_REG_CLASS_P (rclass)
       && (GET_CODE (x) == CONST_INT || GET_CODE (x) == CONST_DOUBLE))
     {
       sri->icode = (mode == SImode ? CODE_FOR_reload_insi_r1
@@ -5697,7 +5734,7 @@ pa_secondary_reload (bool in_p, rtx x, enum reg_class class,
      memory loads and stores.  */
   if ((regno >= FIRST_PSEUDO_REGISTER || regno == -1)
       && GET_MODE_CLASS (mode) == MODE_INT
-      && FP_REG_CLASS_P (class))
+      && FP_REG_CLASS_P (rclass))
     {
       /* Reload passes (mem:SI (reg/f:DI 30 %r30) when it wants to check
         the secondary reload needed for a pseudo.  It never passes a
@@ -5729,7 +5766,7 @@ pa_secondary_reload (bool in_p, rtx x, enum reg_class class,
 
   /* We need a secondary register (GPR) for copies between the SAR
      and anything other than a general register.  */
-  if (class == SHIFT_REGS && (regno <= 0 || regno >= 32))
+  if (rclass == SHIFT_REGS && (regno <= 0 || regno >= 32))
     {
       sri->icode = in_p ? reload_in_optab[mode] : reload_out_optab[mode];
       return NO_REGS;
@@ -5739,7 +5776,7 @@ pa_secondary_reload (bool in_p, rtx x, enum reg_class class,
      well as secondary memory.  */
   if (regno >= 0 && regno < FIRST_PSEUDO_REGISTER
       && (REGNO_REG_CLASS (regno) == SHIFT_REGS
-      && FP_REG_CLASS_P (class)))
+      && FP_REG_CLASS_P (rclass)))
     {
       sri->icode = in_p ? reload_in_optab[mode] : reload_out_optab[mode];
       return NO_REGS;
@@ -5848,7 +5885,11 @@ enum direction
 function_arg_padding (enum machine_mode mode, const_tree type)
 {
   if (mode == BLKmode
-      || (TARGET_64BIT && type && AGGREGATE_TYPE_P (type)))
+      || (TARGET_64BIT
+         && type
+         && (AGGREGATE_TYPE_P (type)
+             || TREE_CODE (type) == COMPLEX_TYPE
+             || TREE_CODE (type) == VECTOR_TYPE)))
     {
       /* Return none if justification is not required.  */
       if (type
@@ -5894,9 +5935,9 @@ hppa_builtin_saveregs (void)
                ? UNITS_PER_WORD : 0);
 
   if (argadj)
-    offset = plus_constant (current_function_arg_offset_rtx, argadj);
+    offset = plus_constant (crtl->args.arg_offset_rtx, argadj);
   else
-    offset = current_function_arg_offset_rtx;
+    offset = crtl->args.arg_offset_rtx;
 
   if (TARGET_64BIT)
     {
@@ -5904,9 +5945,9 @@ hppa_builtin_saveregs (void)
 
       /* Adjust for varargs/stdarg differences.  */
       if (argadj)
-       offset = plus_constant (current_function_arg_offset_rtx, -argadj);
+       offset = plus_constant (crtl->args.arg_offset_rtx, -argadj);
       else
-       offset = current_function_arg_offset_rtx;
+       offset = crtl->args.arg_offset_rtx;
 
       /* We need to save %r26 .. %r19 inclusive starting at offset -64
         from the incoming arg pointer and growing to larger addresses.  */
@@ -5930,7 +5971,7 @@ hppa_builtin_saveregs (void)
 
   /* Store general registers on the stack.  */
   dest = gen_rtx_MEM (BLKmode,
-                     plus_constant (current_function_internal_arg_pointer,
+                     plus_constant (crtl->args.internal_arg_pointer,
                                     -16));
   set_mem_alias_set (dest, get_varargs_alias_set ());
   set_mem_align (dest, BITS_PER_WORD);
@@ -5948,7 +5989,7 @@ hppa_builtin_saveregs (void)
   emit_insn (gen_blockage ());
 
   return copy_to_reg (expand_binop (Pmode, add_optab,
-                                   current_function_internal_arg_pointer,
+                                   crtl->args.internal_arg_pointer,
                                    offset, 0, 0, OPTAB_LIB_WIDEN));
 }
 
@@ -5960,7 +6001,8 @@ hppa_va_start (tree valist, rtx nextarg)
 }
 
 static tree
-hppa_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
+hppa_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
+                          gimple_seq *post_p)
 {
   if (TARGET_64BIT)
     {
@@ -7336,12 +7378,14 @@ int
 attr_length_call (rtx insn, int sibcall)
 {
   int local_call;
-  rtx call_dest;
+  rtx call, call_dest;
   tree call_decl;
   int length = 0;
   rtx pat = PATTERN (insn);
   unsigned long distance = -1;
 
+  gcc_assert (GET_CODE (insn) == CALL_INSN);
+
   if (INSN_ADDRESSES_SET_P ())
     {
       unsigned long total;
@@ -7352,12 +7396,17 @@ attr_length_call (rtx insn, int sibcall)
        distance = -1;
     }
 
-  /* Determine if this is a local call.  */
-  if (GET_CODE (XVECEXP (pat, 0, 0)) == CALL)
-    call_dest = XEXP (XEXP (XVECEXP (pat, 0, 0), 0), 0);
-  else
-    call_dest = XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0);
+  gcc_assert (GET_CODE (pat) == PARALLEL);
+
+  /* Get the call rtx.  */
+  call = XVECEXP (pat, 0, 0);
+  if (GET_CODE (call) == SET)
+    call = SET_SRC (call);
+
+  gcc_assert (GET_CODE (call) == CALL);
 
+  /* Determine if this is a local call.  */
+  call_dest = XEXP (XEXP (call, 0), 0);
   call_decl = SYMBOL_REF_DECL (call_dest);
   local_call = call_decl && targetm.binds_local_p (call_decl);
 
@@ -7376,14 +7425,13 @@ attr_length_call (rtx insn, int sibcall)
     length += 12;
 
   /* long pc-relative branch sequence.  */
-  else if ((TARGET_SOM && TARGET_LONG_PIC_SDIFF_CALL)
-          || (TARGET_64BIT && !TARGET_GAS)
+  else if (TARGET_LONG_PIC_SDIFF_CALL
           || (TARGET_GAS && !TARGET_SOM
               && (TARGET_LONG_PIC_PCREL_CALL || local_call)))
     {
       length += 20;
 
-      if (!TARGET_PA_20 && !TARGET_NO_SPACE_REGS)
+      if (!TARGET_PA_20 && !TARGET_NO_SPACE_REGS && flag_pic)
        length += 8;
     }
 
@@ -7403,7 +7451,7 @@ attr_length_call (rtx insn, int sibcall)
          if (!sibcall)
            length += 8;
 
-         if (!TARGET_NO_SPACE_REGS)
+         if (!TARGET_NO_SPACE_REGS && flag_pic)
            length += 8;
        }
     }
@@ -7487,7 +7535,7 @@ output_call (rtx insn, rtx call_dest, int sibcall)
             of increasing length and complexity.  In most cases,
              they don't allow an instruction in the delay slot.  */
          if (!((TARGET_LONG_ABS_CALL || local_call) && !flag_pic)
-             && !(TARGET_SOM && TARGET_LONG_PIC_SDIFF_CALL)
+             && !TARGET_LONG_PIC_SDIFF_CALL
              && !(TARGET_GAS && !TARGET_SOM
                   && (TARGET_LONG_PIC_PCREL_CALL || local_call))
              && !TARGET_64BIT)
@@ -7496,7 +7544,9 @@ output_call (rtx insn, rtx call_dest, int sibcall)
          if (seq_length != 0
              && GET_CODE (NEXT_INSN (insn)) != JUMP_INSN
              && !sibcall
-             && (!TARGET_PA_20 || indirect_call))
+             && (!TARGET_PA_20
+                 || indirect_call
+                 || ((TARGET_LONG_ABS_CALL || local_call) && !flag_pic)))
            {
              /* A non-jump insn in the delay slot.  By definition we can
                 emit this insn before the call (and in fact before argument
@@ -7533,13 +7583,12 @@ output_call (rtx insn, rtx call_dest, int sibcall)
            }
          else
            {
-             if ((TARGET_SOM && TARGET_LONG_PIC_SDIFF_CALL)
-                 || (TARGET_64BIT && !TARGET_GAS))
+             if (TARGET_LONG_PIC_SDIFF_CALL)
                {
                  /* The HP assembler and linker can handle relocations
-                    for the difference of two symbols.  GAS and the HP
-                    linker can't do this when one of the symbols is
-                    external.  */
+                    for the difference of two symbols.  The HP assembler
+                    recognizes the sequence as a pc-relative call and
+                    the linker provides stubs when needed.  */
                  xoperands[1] = gen_label_rtx ();
                  output_asm_insn ("{bl|b,l} .+8,%%r1", xoperands);
                  output_asm_insn ("addil L'%0-%l1,%%r1", xoperands);
@@ -7624,20 +7673,20 @@ output_call (rtx insn, rtx call_dest, int sibcall)
                }
              else
                {
-                 if (!TARGET_NO_SPACE_REGS)
+                 if (!TARGET_NO_SPACE_REGS && flag_pic)
                    output_asm_insn ("ldsid (%%r1),%%r31\n\tmtsp %%r31,%%sr0",
                                     xoperands);
 
                  if (sibcall)
                    {
-                     if (TARGET_NO_SPACE_REGS)
+                     if (TARGET_NO_SPACE_REGS || !flag_pic)
                        output_asm_insn ("be 0(%%sr4,%%r1)", xoperands);
                      else
                        output_asm_insn ("be 0(%%sr0,%%r1)", xoperands);
                    }
                  else
                    {
-                     if (TARGET_NO_SPACE_REGS)
+                     if (TARGET_NO_SPACE_REGS || !flag_pic)
                        output_asm_insn ("ble 0(%%sr4,%%r1)", xoperands);
                      else
                        output_asm_insn ("ble 0(%%sr0,%%r1)", xoperands);
@@ -7824,7 +7873,7 @@ hppa_encode_label (rtx sym)
   int len = strlen (str) + 1;
   char *newstr, *p;
 
-  p = newstr = alloca (len + 1);
+  p = newstr = XALLOCAVEC (char, len + 1);
   *p++ = '@';
   strcpy (p, str);
 
@@ -7892,7 +7941,7 @@ pa_asm_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta,
 {
   static unsigned int current_thunk_number;
   int val_14 = VAL_14_BITS_P (delta);
-  int nbytes = 0;
+  unsigned int old_last_address = last_address, nbytes = 0;
   char label[16];
   rtx xoperands[4];
 
@@ -8125,6 +8174,8 @@ pa_asm_output_mi_thunk (FILE *file, tree thunk_fndecl, HOST_WIDE_INT delta,
   nbytes = ((nbytes + FUNCTION_BOUNDARY / BITS_PER_UNIT - 1)
            & ~(FUNCTION_BOUNDARY / BITS_PER_UNIT - 1));
   last_address += nbytes;
+  if (old_last_address > last_address)
+    last_address = UINT_MAX;
   update_total_code_bytes (nbytes);
 }
 
@@ -8457,7 +8508,7 @@ borx_reg_operand (rtx op, enum machine_mode mode)
      profitable to do so when the frame pointer is being eliminated.  */
   if (!reload_completed
       && flag_omit_frame_pointer
-      && !current_function_calls_alloca
+      && !cfun->calls_alloca
       && op == frame_pointer_rtx)
     return 0;
 
@@ -8794,7 +8845,7 @@ pa_reorg (void)
 static void
 pa_combine_instructions (void)
 {
-  rtx anchor, new;
+  rtx anchor, new_rtx;
 
   /* This can get expensive since the basic algorithm is on the
      order of O(n^2) (or worse).  Only do it for -O2 or higher
@@ -8806,8 +8857,8 @@ pa_combine_instructions (void)
      may be combined with "floating" insns.  As the name implies,
      "anchor" instructions don't move, while "floating" insns may
      move around.  */
-  new = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, NULL_RTX, NULL_RTX));
-  new = make_insn_raw (new);
+  new_rtx = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, NULL_RTX, NULL_RTX));
+  new_rtx = make_insn_raw (new_rtx);
 
   for (anchor = get_insns (); anchor; anchor = NEXT_INSN (anchor))
     {
@@ -8863,7 +8914,7 @@ pa_combine_instructions (void)
                {
                  /* If ANCHOR and FLOATER can be combined, then we're
                     done with this pass.  */
-                 if (pa_can_combine_p (new, anchor, floater, 0,
+                 if (pa_can_combine_p (new_rtx, anchor, floater, 0,
                                        SET_DEST (PATTERN (floater)),
                                        XEXP (SET_SRC (PATTERN (floater)), 0),
                                        XEXP (SET_SRC (PATTERN (floater)), 1)))
@@ -8875,7 +8926,7 @@ pa_combine_instructions (void)
                {
                  if (GET_CODE (SET_SRC (PATTERN (floater))) == PLUS)
                    {
-                     if (pa_can_combine_p (new, anchor, floater, 0,
+                     if (pa_can_combine_p (new_rtx, anchor, floater, 0,
                                            SET_DEST (PATTERN (floater)),
                                        XEXP (SET_SRC (PATTERN (floater)), 0),
                                        XEXP (SET_SRC (PATTERN (floater)), 1)))
@@ -8883,7 +8934,7 @@ pa_combine_instructions (void)
                    }
                  else
                    {
-                     if (pa_can_combine_p (new, anchor, floater, 0,
+                     if (pa_can_combine_p (new_rtx, anchor, floater, 0,
                                            SET_DEST (PATTERN (floater)),
                                            SET_SRC (PATTERN (floater)),
                                            SET_SRC (PATTERN (floater))))
@@ -8925,7 +8976,7 @@ pa_combine_instructions (void)
                    {
                      /* If ANCHOR and FLOATER can be combined, then we're
                         done with this pass.  */
-                     if (pa_can_combine_p (new, anchor, floater, 1,
+                     if (pa_can_combine_p (new_rtx, anchor, floater, 1,
                                            SET_DEST (PATTERN (floater)),
                                            XEXP (SET_SRC (PATTERN (floater)),
                                                  0),
@@ -8984,7 +9035,7 @@ pa_combine_instructions (void)
 }
 
 static int
-pa_can_combine_p (rtx new, rtx anchor, rtx floater, int reversed, rtx dest,
+pa_can_combine_p (rtx new_rtx, rtx anchor, rtx floater, int reversed, rtx dest,
                  rtx src1, rtx src2)
 {
   int insn_code_number;
@@ -8997,12 +9048,12 @@ pa_can_combine_p (rtx new, rtx anchor, rtx floater, int reversed, rtx dest,
      If the pattern doesn't match or the constraints
      aren't met keep searching for a suitable floater
      insn.  */
-  XVECEXP (PATTERN (new), 0, 0) = PATTERN (anchor);
-  XVECEXP (PATTERN (new), 0, 1) = PATTERN (floater);
-  INSN_CODE (new) = -1;
-  insn_code_number = recog_memoized (new);
+  XVECEXP (PATTERN (new_rtx), 0, 0) = PATTERN (anchor);
+  XVECEXP (PATTERN (new_rtx), 0, 1) = PATTERN (floater);
+  INSN_CODE (new_rtx) = -1;
+  insn_code_number = recog_memoized (new_rtx);
   if (insn_code_number < 0
-      || (extract_insn (new), ! constrain_operands (1)))
+      || (extract_insn (new_rtx), ! constrain_operands (1)))
     return 0;
 
   if (reversed)
@@ -9615,11 +9666,11 @@ pa_hpux_file_end (void)
 #endif
 
 /* Return true if a change from mode FROM to mode TO for a register
-   in register class CLASS is invalid.  */
+   in register class RCLASS is invalid.  */
 
 bool
 pa_cannot_change_mode_class (enum machine_mode from, enum machine_mode to,
-                            enum reg_class class)
+                            enum reg_class rclass)
 {
   if (from == to)
     return false;
@@ -9637,7 +9688,7 @@ pa_cannot_change_mode_class (enum machine_mode from, enum machine_mode to,
      On the 64-bit target, this conflicts with the definition of
      LOAD_EXTEND_OP.  Thus, we can't allow changing between modes
      with different sizes in the floating-point registers.  */
-  if (MAYBE_FP_REG_CLASS_P (class))
+  if (MAYBE_FP_REG_CLASS_P (rclass))
     return true;
 
   /* HARD_REGNO_MODE_OK places modes with sizes larger than a word