rs6000.c (emit_frame_save): New.
authorAldy Hernandez <aldyh@redhat.com>
Wed, 10 Jul 2002 23:12:53 +0000 (23:12 +0000)
committerAldy Hernandez <aldyh@gcc.gnu.org>
Wed, 10 Jul 2002 23:12:53 +0000 (23:12 +0000)
2002-07-10  Aldy Hernandez  <aldyh@redhat.com>

        * config/rs6000/rs6000.c (emit_frame_save): New.
        (rs6000_frame_related): Replace reg2 before reg.
        (rs6000_emit_prologue): Use emit_frame_save for saving gprs, fprs,
        and eh_return registers.

From-SVN: r55383

gcc/ChangeLog
gcc/config/rs6000/rs6000.c

index a654380521ee7491ac52d9fb39c6c7e79c3798fc..06d7826e1c12d0c387e264dad5fcb7f320a180e7 100644 (file)
@@ -1,3 +1,10 @@
+2002-07-10  Aldy Hernandez  <aldyh@redhat.com>
+
+        * config/rs6000/rs6000.c (emit_frame_save): New.
+        (rs6000_frame_related): Replace reg2 before reg.
+        (rs6000_emit_prologue): Use emit_frame_save for saving gprs, fprs,
+        and eh_return registers.
+
 2002-07-10  Toon Moene  <toon@moene.indiv.nluug.nl>
 
        Revert all patches for optimization of Complex .op. Real.
index 6fcf8909f72c875f78b7ea9ca1c59dd3ea25d146..a88b7f05330f0ac3981d1ace5930ddd69f3065e4 100644 (file)
@@ -140,6 +140,8 @@ static rtx rs6000_generate_compare PARAMS ((enum rtx_code));
 static void rs6000_maybe_dead PARAMS ((rtx));
 static void rs6000_emit_stack_tie PARAMS ((void));
 static void rs6000_frame_related PARAMS ((rtx, rtx, HOST_WIDE_INT, rtx, rtx));
+static void emit_frame_save PARAMS ((rtx, rtx, enum machine_mode,
+                                    unsigned int, int, int));
 static void rs6000_emit_allocate_stack PARAMS ((HOST_WIDE_INT, int));
 static unsigned rs6000_hash_constant PARAMS ((rtx));
 static unsigned toc_hash_function PARAMS ((const void *));
@@ -8452,6 +8454,9 @@ rs6000_frame_related (insn, reg, val, reg2, rreg)
 
   real = copy_rtx (PATTERN (insn));
 
+  if (reg2 != NULL_RTX)
+    real = replace_rtx (real, reg2, rreg);
+  
   real = replace_rtx (real, reg, 
                      gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
                                                        STACK_POINTER_REGNUM),
@@ -8504,9 +8509,6 @@ rs6000_frame_related (insn, reg, val, reg2, rreg)
   else
     abort ();
   
-  if (reg2 != NULL_RTX)
-    real = replace_rtx (real, reg2, rreg);
-  
   RTX_FRAME_RELATED_P (insn) = 1;
   REG_NOTES (insn) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR,
                                        real,
@@ -8575,6 +8577,53 @@ generate_set_vrsave (reg, info, epiloguep)
   return insn;
 }
 
+/* Save a register into the frame, and emit RTX_FRAME_RELATED_P notes.
+   Save REGNO into [FRAME_REG + OFFSET] in mode MODE.  */
+
+static void
+emit_frame_save (frame_reg, frame_ptr, mode, regno, offset, total_size)
+     rtx frame_reg;
+     rtx frame_ptr;
+     enum machine_mode mode;
+     unsigned int regno;
+     int offset;
+     int total_size;
+{
+  rtx reg, offset_rtx, insn, mem, addr, int_rtx;
+  rtx replacea, replaceb;
+
+  int_rtx = GEN_INT (offset);
+
+  /* Some cases that need register indexed addressing.  */
+  if ((TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
+      /* Add more cases here.  */
+      )
+    {
+      /* Whomever calls us must make sure r11 is available in the
+         flow path of instructions in the prologue.  */
+      offset_rtx = gen_rtx_REG (Pmode, 11);
+      emit_move_insn (offset_rtx, int_rtx);
+
+      replacea = offset_rtx;
+      replaceb = int_rtx;
+    }
+  else
+    {
+      offset_rtx = int_rtx;
+      replacea = NULL_RTX;
+      replaceb = NULL_RTX;
+    }
+
+  reg = gen_rtx_REG (mode, regno);
+  addr = gen_rtx_PLUS (Pmode, frame_reg, offset_rtx);
+  mem = gen_rtx_MEM (mode, addr);
+  set_mem_alias_set (mem, rs6000_sr_alias_set);
+
+  insn = emit_move_insn (mem, reg);
+
+  rs6000_frame_related (insn, frame_ptr, total_size, replacea, replaceb);
+}
+
 /* Emit function prologue as insns.  */
 
 void
@@ -8702,20 +8751,10 @@ rs6000_emit_prologue ()
       for (i = 0; i < 64 - info->first_fp_reg_save; i++)
        if ((regs_ever_live[info->first_fp_reg_save+i] 
             && ! call_used_regs[info->first_fp_reg_save+i]))
-         {
-           rtx addr, reg, mem;
-           reg = gen_rtx_REG (DFmode, info->first_fp_reg_save + i);
-           addr = gen_rtx_PLUS (Pmode, frame_reg_rtx,
-                                GEN_INT (info->fp_save_offset 
-                                         + sp_offset 
-                                         + 8 * i));
-           mem = gen_rtx_MEM (DFmode, addr);
-           set_mem_alias_set (mem, rs6000_sr_alias_set);
-
-           insn = emit_move_insn (mem, reg);
-           rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, 
-                                 NULL_RTX, NULL_RTX);
-         }
+         emit_frame_save (frame_reg_rtx, frame_ptr_rtx, DFmode,
+                          info->first_fp_reg_save + i,
+                          info->fp_save_offset + sp_offset + 8 * i,
+                          info->total_size);
     }
   else if (info->first_fp_reg_save != 64)
     {
@@ -8785,20 +8824,10 @@ rs6000_emit_prologue ()
            || (i+info->first_gp_reg_save == RS6000_PIC_OFFSET_TABLE_REGNUM
                && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
                    || (DEFAULT_ABI == ABI_DARWIN && flag_pic))))
-         {
-           rtx addr, reg, mem;
-           reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
-           addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 
-                                GEN_INT (info->gp_save_offset 
-                                         + sp_offset 
-                                         + reg_size * i));
-           mem = gen_rtx_MEM (reg_mode, addr);
-           set_mem_alias_set (mem, rs6000_sr_alias_set);
-
-           insn = emit_move_insn (mem, reg);
-           rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, 
-                                 NULL_RTX, NULL_RTX);
-         }
+         emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode,
+                          info->first_gp_reg_save + i,
+                          info->gp_save_offset + sp_offset + reg_size * i,
+                          info->total_size);
     }
 
   /* ??? There's no need to emit actual instructions here, but it's the
@@ -8809,22 +8838,14 @@ rs6000_emit_prologue ()
 
       for (i = 0; ; ++i)
        {
-         rtx addr, reg, mem;
-
          regno = EH_RETURN_DATA_REGNO (i);
          if (regno == INVALID_REGNUM)
            break;
 
-         reg = gen_rtx_REG (reg_mode, regno);
-         addr = plus_constant (frame_reg_rtx,
-                               info->ehrd_offset + sp_offset
-                               + reg_size * (int) i);
-         mem = gen_rtx_MEM (reg_mode, addr);
-         set_mem_alias_set (mem, rs6000_sr_alias_set);
-
-         insn = emit_move_insn (mem, reg);
-         rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, 
-                               NULL_RTX, NULL_RTX);
+         emit_frame_save (frame_reg_rtx, frame_ptr_rtx, reg_mode, regno,
+                          info->ehrd_offset + sp_offset
+                          + reg_size * (int) i,
+                          info->total_size);
        }
     }