OSDN Git Service

* config/rs6000/rs6000.c (output_toc): Make "offset" HOST_WIDE_INT.
[pf3gnuchains/gcc-fork.git] / gcc / config / rs6000 / rs6000.c
index 43c0532..8d51003 100644 (file)
@@ -2260,7 +2260,7 @@ rs6000_expand_vector_init (rtx target, rtx vals)
     {
       rtx copy = copy_rtx (vals);
 
-      /* Load constant part of vector, substititute neighboring value for
+      /* Load constant part of vector, substitute neighboring value for
         varying element.  */
       XVECEXP (copy, 0, one_var) = XVECEXP (vals, 0, (one_var + 1) % n_elts);
       rs6000_expand_vector_init (target, copy);
@@ -2978,8 +2978,13 @@ rs6000_legitimize_tls_address (rtx addr, enum tls_model model)
     {
       rtx r3, got, tga, tmp1, tmp2, eqv;
 
+      /* We currently use relocations like @got@tlsgd for tls, which
+        means the linker will handle allocation of tls entries, placing
+        them in the .got section.  So use a pointer to the .got section,
+        not one to secondary TOC sections used by 64-bit -mminimal-toc,
+        or to secondary GOT sections used by 32-bit -fPIC.  */
       if (TARGET_64BIT)
-       got = gen_rtx_REG (Pmode, TOC_REGISTER);
+       got = gen_rtx_REG (Pmode, 2);
       else
        {
          if (flag_pic == 1)
@@ -3245,16 +3250,21 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
       return x;
     }
 
-#if TARGET_MACHO
   if (GET_CODE (x) == SYMBOL_REF
-      && DEFAULT_ABI == ABI_DARWIN
       && !ALTIVEC_VECTOR_MODE (mode)
+#if TARGET_MACHO
+      && DEFAULT_ABI == ABI_DARWIN
       && (flag_pic || MACHO_DYNAMIC_NO_PIC_P)
+#else
+      && DEFAULT_ABI == ABI_V4
+      && !flag_pic
+#endif
       /* Don't do this for TFmode, since the result isn't offsettable.
         The same goes for DImode without 64-bit gprs.  */
       && mode != TFmode
       && (mode != DImode || TARGET_POWERPC64))
     {
+#if TARGET_MACHO
       if (flag_pic)
        {
          rtx offset = gen_rtx_CONST (Pmode,
@@ -3265,6 +3275,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
                  gen_rtx_HIGH (Pmode, offset)), offset);
        }
       else
+#endif
        x = gen_rtx_LO_SUM (GET_MODE (x),
              gen_rtx_HIGH (Pmode, x), x);
 
@@ -3274,7 +3285,6 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
       *win = 1;
       return x;
     }
-#endif
 
   /* Reload an offset address wrapped by an AND that represents the
      masking of the lower bits.  Strip the outer AND and let reload
@@ -13368,7 +13378,10 @@ rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
          || current_function_calls_alloca
          || info->total_size > 32767)
        {
-         emit_move_insn (operands[1], gen_rtx_MEM (Pmode, frame_rtx));
+         tmp = gen_rtx_MEM (Pmode, frame_rtx);
+         MEM_NOTRAP_P (tmp) = 1;
+         set_mem_alias_set (tmp, rs6000_sr_alias_set);
+         emit_move_insn (operands[1], tmp);
          frame_rtx = operands[1];
        }
       else if (info->push_p)
@@ -13376,6 +13389,8 @@ rs6000_emit_eh_reg_restore (rtx source, rtx scratch)
 
       tmp = plus_constant (frame_rtx, info->lr_save_offset + sp_offset);
       tmp = gen_rtx_MEM (Pmode, tmp);
+      MEM_NOTRAP_P (tmp) = 1;
+      set_mem_alias_set (tmp, rs6000_sr_alias_set);
       emit_move_insn (tmp, operands[0]);
     }
   else
@@ -13448,12 +13463,12 @@ rs6000_aix_emit_builtin_unwind_init (void)
   rtx tocompare = gen_reg_rtx (SImode);
   rtx no_toc_save_needed = gen_label_rtx ();
 
-  mem = gen_rtx_MEM (Pmode, hard_frame_pointer_rtx);
+  mem = gen_frame_mem (Pmode, hard_frame_pointer_rtx);
   emit_move_insn (stack_top, mem);
 
-  mem = gen_rtx_MEM (Pmode,
-                    gen_rtx_PLUS (Pmode, stack_top,
-                                  GEN_INT (2 * GET_MODE_SIZE (Pmode))));
+  mem = gen_frame_mem (Pmode,
+                      gen_rtx_PLUS (Pmode, stack_top,
+                                    GEN_INT (2 * GET_MODE_SIZE (Pmode))));
   emit_move_insn (opcode_addr, mem);
   emit_move_insn (opcode, gen_rtx_MEM (SImode, opcode_addr));
   emit_move_insn (tocompare, gen_int_mode (TARGET_32BIT ? 0x80410014
@@ -13463,9 +13478,9 @@ rs6000_aix_emit_builtin_unwind_init (void)
                           SImode, NULL_RTX, NULL_RTX,
                           no_toc_save_needed);
 
-  mem = gen_rtx_MEM (Pmode,
-                    gen_rtx_PLUS (Pmode, stack_top,
-                                  GEN_INT (5 * GET_MODE_SIZE (Pmode))));
+  mem = gen_frame_mem (Pmode,
+                      gen_rtx_PLUS (Pmode, stack_top,
+                                    GEN_INT (5 * GET_MODE_SIZE (Pmode))));
   emit_move_insn (mem, gen_rtx_REG (Pmode, 2));
   emit_label (no_toc_save_needed);
 }
@@ -15573,7 +15588,7 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
   const char *name = buf;
   const char *real_name;
   rtx base = x;
-  int offset = 0;
+  HOST_WIDE_INT offset = 0;
 
   gcc_assert (!TARGET_NO_TOC);
 
@@ -15840,9 +15855,9 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
       fprintf (file, "\t.tc %s", real_name);
 
       if (offset < 0)
-       fprintf (file, ".N%d", - offset);
+       fprintf (file, ".N" HOST_WIDE_INT_PRINT_UNSIGNED, - offset);
       else if (offset)
-       fprintf (file, ".P%d", offset);
+       fprintf (file, ".P" HOST_WIDE_INT_PRINT_UNSIGNED, offset);
 
       fputs ("[TC],", file);
     }
@@ -15857,9 +15872,9 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
     {
       RS6000_OUTPUT_BASENAME (file, name);
       if (offset < 0)
-       fprintf (file, "%d", offset);
+       fprintf (file, HOST_WIDE_INT_PRINT_DEC, offset);
       else if (offset > 0)
-       fprintf (file, "+%d", offset);
+       fprintf (file, "+" HOST_WIDE_INT_PRINT_DEC, offset);
     }
   else
     output_addr_const (file, x);
@@ -16622,26 +16637,24 @@ rs6000_is_costly_dependence (rtx insn, rtx next, rtx link, int cost,
 static rtx
 get_next_active_insn (rtx insn, rtx tail)
 {
-  rtx next_insn;
-
-  if (!insn || insn == tail)
+  if (insn == NULL_RTX || insn == tail)
     return NULL_RTX;
 
-  next_insn = NEXT_INSN (insn);
-
-  while (next_insn
-        && next_insn != tail
-        && (GET_CODE (next_insn) == NOTE
-            || GET_CODE (PATTERN (next_insn)) == USE
-            || GET_CODE (PATTERN (next_insn)) == CLOBBER))
+  while (1)
     {
-      next_insn = NEXT_INSN (next_insn);
-    }
-
-  if (!next_insn || next_insn == tail)
-    return NULL_RTX;
+      insn = NEXT_INSN (insn);
+      if (insn == NULL_RTX || insn == tail)
+       return NULL_RTX;
 
-  return next_insn;
+      if (CALL_P (insn)
+         || JUMP_P (insn)
+         || (NONJUMP_INSN_P (insn)
+             && GET_CODE (PATTERN (insn)) != USE
+             && GET_CODE (PATTERN (insn)) != CLOBBER
+             && INSN_CODE (insn) != CODE_FOR_stack_tie))
+       break;
+    }
+  return insn;
 }
 
 /* Return whether the presence of INSN causes a dispatch group termination
@@ -18291,12 +18304,6 @@ rs6000_rtx_costs (rtx x, int code, int outer_code, int *total)
          else
            *total = rs6000_cost->fp;
        }
-      else if (GET_CODE (XEXP (x, 0)) == MULT)
-       {
-         /* The rs6000 doesn't have shift-and-add instructions.  */
-         rs6000_rtx_costs (XEXP (x, 0), MULT, PLUS, total);
-         *total += COSTS_N_INSNS (1);
-       }
       else
        *total = COSTS_N_INSNS (1);
       return false;
@@ -18323,12 +18330,6 @@ rs6000_rtx_costs (rtx x, int code, int outer_code, int *total)
          else
            *total = rs6000_cost->fp;
        }
-      else if (GET_CODE (XEXP (x, 0)) == MULT)
-       {
-         /* The rs6000 doesn't have shift-and-sub instructions.  */
-         rs6000_rtx_costs (XEXP (x, 0), MULT, MINUS, total);
-         *total += COSTS_N_INSNS (1);
-       }
       else
        *total = COSTS_N_INSNS (1);
       return false;
@@ -18778,7 +18779,26 @@ rs6000_function_value (tree valtype, tree func ATTRIBUTE_UNUSED)
                                                   GP_ARG_RETURN + 1),
                                      GEN_INT (4))));
     }
-
+  if (TARGET_32BIT && TARGET_POWERPC64 && TYPE_MODE (valtype) == DCmode)
+    {
+      return gen_rtx_PARALLEL (DCmode,
+       gen_rtvec (4,
+                  gen_rtx_EXPR_LIST (VOIDmode,
+                                     gen_rtx_REG (SImode, GP_ARG_RETURN),
+                                     const0_rtx),
+                  gen_rtx_EXPR_LIST (VOIDmode,
+                                     gen_rtx_REG (SImode,
+                                                  GP_ARG_RETURN + 1),
+                                     GEN_INT (4)),
+                  gen_rtx_EXPR_LIST (VOIDmode,
+                                     gen_rtx_REG (SImode,
+                                                  GP_ARG_RETURN + 2),
+                                     GEN_INT (8)),
+                  gen_rtx_EXPR_LIST (VOIDmode,
+                                     gen_rtx_REG (SImode,
+                                                  GP_ARG_RETURN + 3),
+                                     GEN_INT (12))));
+    }
   if ((INTEGRAL_TYPE_P (valtype)
        && TYPE_PRECISION (valtype) < BITS_PER_WORD)
       || POINTER_TYPE_P (valtype))