s390-protos.h (s390_return_address_offset): Prototype added.
authorAndreas Krebbel <krebbel1@de.ibm.com>
Mon, 19 Jul 2004 13:59:49 +0000 (13:59 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Mon, 19 Jul 2004 13:59:49 +0000 (13:59 +0000)
2004-07-19  Andreas Krebbel  <krebbel1@de.ibm.com>

* config/s390/s390-protos.h (s390_return_address_offset): Prototype
added.
* config/s390/s390.c (regclass_map initializer): Register 35 added to
ADDR_REGS.
(load_multiple_operation, store_multiple_operation): Removed
pointless sanity check.
(s390_decompose_address): Added check for return_address_pointer_rtx.
(s390_return_addr_rtx): Use return_address_pointer_rtx for count == 0.
(s390_return_address_offset): New function.
* config/s390/s390.h (FIRST_PSEUDO_REGISTER): Increased to 36.
(FRAME_REGNO_P): Added check for register 35.
(FIXED_REGISTERS, CALL_USED_REGISTERS, CALL_REALLY_USED_REGISTERS,
REG_ALLOC_ORDER): Appended entry for register 35.
(REG_CLASS_CONTENTS): Adjusted class masks for register 35.
(EH_RETURN_HANDLER_RTX): Use return_address_pointer_rtx.
(RETURN_ADDRESS_POINTER_REGNUM): New macro.
(ELIMINABLE_REGS, INITIAL_ELIMINATION_OFFSET): Return address pointer
is eliminable using stack pointer or hard frame pointer.
(REGISTER_NAMES): Added name for register 35.
* config/s390/s390.md ("load_multiple", "store_multiple"): Removed
pointless sanity check.

From-SVN: r84918

gcc/ChangeLog
gcc/config/s390/s390-protos.h
gcc/config/s390/s390.c
gcc/config/s390/s390.h
gcc/config/s390/s390.md

index 12667fd13394f6924df257a50a21fdaec47e3049..b70d6d2cb61c2614471c55746dcf7e496fc550b1 100644 (file)
@@ -1,3 +1,27 @@
+2004-07-19  Andreas Krebbel  <krebbel1@de.ibm.com>
+
+       * config/s390/s390-protos.h (s390_return_address_offset): Prototype
+       added.
+       * config/s390/s390.c (regclass_map initializer): Register 35 added to
+       ADDR_REGS.
+       (load_multiple_operation, store_multiple_operation): Removed
+       pointless sanity check. 
+       (s390_decompose_address): Added check for return_address_pointer_rtx.
+       (s390_return_addr_rtx): Use return_address_pointer_rtx for count == 0.
+       (s390_return_address_offset): New function.
+       * config/s390/s390.h (FIRST_PSEUDO_REGISTER): Increased to 36.
+       (FRAME_REGNO_P): Added check for register 35.
+       (FIXED_REGISTERS, CALL_USED_REGISTERS, CALL_REALLY_USED_REGISTERS,
+       REG_ALLOC_ORDER): Appended entry for register 35.
+       (REG_CLASS_CONTENTS): Adjusted class masks for register 35.
+       (EH_RETURN_HANDLER_RTX): Use return_address_pointer_rtx.
+       (RETURN_ADDRESS_POINTER_REGNUM): New macro.
+       (ELIMINABLE_REGS, INITIAL_ELIMINATION_OFFSET): Return address pointer
+       is eliminable using stack pointer or hard frame pointer.
+       (REGISTER_NAMES): Added name for register 35.
+       * config/s390/s390.md ("load_multiple", "store_multiple"): Removed
+       pointless sanity check.
+
 2004-07-19  Roger Sayle  <roger@eyesopen.com>
 
        * fold-const.c (tree_expr_nonzero_p): Add function prototype.
index 447edff9b2108a3bc22a008aa6d45f606a0977af..acb32b23117860dc4e3edb0e3157d6bbf5d4d97e 100644 (file)
@@ -24,6 +24,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 extern void optimization_options (int, int);
 extern void override_options (void);
 extern HOST_WIDE_INT s390_arg_frame_offset (void);
+extern HOST_WIDE_INT s390_return_address_offset (void);
 extern void s390_emit_prologue (void);
 extern void s390_emit_epilogue (bool);
 extern void s390_function_profiler (FILE *, int);
index 9de035051e2cea8e0419dcffa9da35175b5b6566..4ebfbb3fc8c5a71761dab86894eb849f48cdd07c 100644 (file)
@@ -1038,7 +1038,7 @@ const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
   FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
   FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
   FP_REGS,      FP_REGS,   FP_REGS,   FP_REGS,
-  ADDR_REGS,    NO_REGS,   ADDR_REGS
+  ADDR_REGS,    NO_REGS,   ADDR_REGS, ADDR_REGS
 };
 
 /* Return attribute type of insn.  */
@@ -1613,9 +1613,6 @@ load_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
   else
     return 0;
 
-  if (src_addr == frame_pointer_rtx || src_addr == arg_pointer_rtx)
-    return 0;
-
   for (i = 1; i < count; i++)
     {
       rtx elt = XVECEXP (op, 0, i);
@@ -1676,9 +1673,6 @@ store_multiple_operation (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
   else
     return 0;
 
-  if (dest_addr == frame_pointer_rtx || dest_addr == arg_pointer_rtx)
-    return 0;
-
   for (i = 1; i < count; i++)
     {
       rtx elt = XVECEXP (op, 0, i);
@@ -2258,15 +2252,19 @@ s390_decompose_address (register rtx addr, struct s390_address *out)
   /* Validate displacement.  */
   if (!disp)
     {
-      /* If the argument pointer is involved, the displacement will change
-        later anyway as the argument pointer gets eliminated.  This could
-        make a valid displacement invalid, but it is more likely to make
-        an invalid displacement valid, because we sometimes access the
-        register save area via negative offsets to the arg pointer.
+      /* If the argument pointer or the return address pointer are involved,
+        the displacement will change later anyway as the virtual registers get
+        eliminated.  This could make a valid displacement invalid, but it is 
+        more likely to make an invalid displacement valid, because we sometimes
+        access the register save area via negative offsets to one of those 
+        registers.
         Thus we don't check the displacement for validity here.  If after
         elimination the displacement turns out to be invalid after all,
         this is fixed up by reload in any case.  */
-      if (base != arg_pointer_rtx && indx != arg_pointer_rtx)
+      if (base != arg_pointer_rtx 
+         && indx != arg_pointer_rtx 
+         && base != return_address_pointer_rtx 
+         && indx != return_address_pointer_rtx)
        if (!DISP_IN_RANGE (offset))
          return FALSE;
     }
@@ -5499,7 +5497,7 @@ s390_reorg (void)
    frame pointer of that frame.  */
 
 rtx
-s390_return_addr_rtx (int count, rtx frame)
+s390_return_addr_rtx (int count, rtx frame ATTRIBUTE_UNUSED)
 {
   rtx addr;
 
@@ -5512,10 +5510,10 @@ s390_return_addr_rtx (int count, rtx frame)
      value of RETURN_REGNUM is actually saved.  */
 
   if (count == 0)
-    cfun->machine->save_return_addr_p = true;
-
-  /* To retrieve the return address we read the stack slot where the
-     corresponding RETURN_REGNUM value was saved.  */
+    {
+      cfun->machine->save_return_addr_p = true;
+      return gen_rtx_MEM (Pmode, return_address_pointer_rtx);
+    }
 
   addr = plus_constant (frame, RETURN_REGNUM * UNITS_PER_WORD);
   addr = memory_address (Pmode, addr);
@@ -5642,6 +5640,17 @@ s390_arg_frame_offset (void)
   return cfun->machine->frame_size + STACK_POINTER_OFFSET;
 }
 
+/* Return offset between return address pointer (location of r14
+   on the stack) and frame pointer initially after prologue.  */
+
+HOST_WIDE_INT
+s390_return_address_offset (void)
+{
+  s390_frame_info (1, 1);
+
+  return cfun->machine->frame_size + RETURN_REGNUM * UNITS_PER_WORD;
+}
+
 /* Emit insn to save fpr REGNUM at offset OFFSET relative
    to register BASE.  Return generated insn.  */
 
index f4d91fa13bb9f3b38f5f0459c4ccedaf2816cc68..05b8ea932d29d021832e5312762108921a1bad2d 100644 (file)
@@ -284,14 +284,14 @@ if (INTEGRAL_MODE_P (MODE) &&                             \
    Reg 33: Condition code
    Reg 34: Frame pointer  */
 
-#define FIRST_PSEUDO_REGISTER 35
+#define FIRST_PSEUDO_REGISTER 36
 
 /* Standard register usage.  */
 #define GENERAL_REGNO_P(N)     ((int)(N) >= 0 && (N) < 16)
 #define ADDR_REGNO_P(N)                ((N) >= 1 && (N) < 16)
 #define FP_REGNO_P(N)          ((N) >= 16 && (N) < (TARGET_IEEE_FLOAT? 32 : 20))
 #define CC_REGNO_P(N)          ((N) == 33)
-#define FRAME_REGNO_P(N)       ((N) == 32 || (N) == 34)
+#define FRAME_REGNO_P(N)       ((N) == 32 || (N) == 34 || (N) == 35)
 
 #define GENERAL_REG_P(X)       (REG_P (X) && GENERAL_REGNO_P (REGNO (X)))
 #define ADDR_REG_P(X)          (REG_P (X) && ADDR_REGNO_P (REGNO (X)))
@@ -327,7 +327,7 @@ if (INTEGRAL_MODE_P (MODE) &&                               \
   0, 0, 0, 0,                                  \
   0, 0, 0, 0,                                  \
   0, 0, 0, 0,                                  \
-  1, 1, 1 }
+  1, 1, 1, 1 }
 
 #define CALL_USED_REGISTERS                    \
 { 1, 1, 1, 1,                                  \
@@ -338,7 +338,7 @@ if (INTEGRAL_MODE_P (MODE) &&                               \
   1, 1, 1, 1,                                  \
   1, 1, 1, 1,                                  \
   1, 1, 1, 1,                                  \
-  1, 1, 1 }
+  1, 1, 1, 1 }
 
 #define CALL_REALLY_USED_REGISTERS             \
 { 1, 1, 1, 1,                                  \
@@ -349,7 +349,7 @@ if (INTEGRAL_MODE_P (MODE) &&                               \
   1, 1, 1, 1,                                  \
   1, 1, 1, 1,                                  \
   1, 1, 1, 1,                                  \
-  1, 1, 1 }
+  1, 1, 1, 1 }
 
 #define CONDITIONAL_REGISTER_USAGE s390_conditional_register_usage ()
 
@@ -358,7 +358,7 @@ if (INTEGRAL_MODE_P (MODE) &&                               \
 {  1, 2, 3, 4, 5, 0, 13, 12, 11, 10, 9, 8, 7, 6, 14,            \
    16, 17, 18, 19, 20, 21, 22, 23,                              \
    24, 25, 26, 27, 28, 29, 30, 31,                              \
-   15, 32, 33, 34 }
+   15, 32, 33, 34, 35 }
 
 
 /* Fitting values into registers.  */
@@ -449,12 +449,12 @@ enum reg_class
 #define REG_CLASS_CONTENTS \
 {                                                      \
   { 0x00000000, 0x00000000 },  /* NO_REGS */           \
-  { 0x0000fffe, 0x00000005 },  /* ADDR_REGS */         \
-  { 0x0000ffff, 0x00000005 },  /* GENERAL_REGS */      \
+  { 0x0000fffe, 0x0000000d },  /* ADDR_REGS */         \
+  { 0x0000ffff, 0x0000000d },  /* GENERAL_REGS */      \
   { 0xffff0000, 0x00000000 },  /* FP_REGS */           \
-  { 0xfffffffe, 0x00000005 },  /* ADDR_FP_REGS */      \
-  { 0xffffffff, 0x00000005 },  /* GENERAL_FP_REGS */   \
-  { 0xffffffff, 0x00000007 },  /* ALL_REGS */          \
+  { 0xfffffffe, 0x0000000d },  /* ADDR_FP_REGS */      \
+  { 0xffffffff, 0x0000000d },  /* GENERAL_FP_REGS */   \
+  { 0xffffffff, 0x0000000f },  /* ALL_REGS */          \
 }
 
 /* Register -> class mapping.  */
@@ -579,10 +579,8 @@ extern int current_function_outgoing_args_size;
 
 /* Describe how we implement __builtin_eh_return.  */
 #define EH_RETURN_DATA_REGNO(N) ((N) < 4 ? (N) + 6 : INVALID_REGNUM)
-#define EH_RETURN_HANDLER_RTX \
-  gen_rtx_MEM (Pmode, plus_constant (arg_pointer_rtx, \
-               -STACK_POINTER_OFFSET + UNITS_PER_WORD*RETURN_REGNUM))
-
+#define EH_RETURN_HANDLER_RTX gen_rtx_MEM (Pmode, return_address_pointer_rtx)
+       
 /* Select a format to encode pointers in exception handling data.  */
 #define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL)                         \
   (flag_pic                                                                \
@@ -596,6 +594,7 @@ extern int current_function_outgoing_args_size;
 #define FRAME_POINTER_REGNUM 34
 #define HARD_FRAME_POINTER_REGNUM 11
 #define ARG_POINTER_REGNUM 32
+#define RETURN_ADDRESS_POINTER_REGNUM 35
 
 /* The static chain must be call-clobbered, but not used for
    function argument passing.  As register 1 is clobbered by
@@ -614,11 +613,13 @@ extern int current_function_outgoing_args_size;
 
 #define INITIAL_FRAME_POINTER_OFFSET(DEPTH) (DEPTH) = 0
 
-#define ELIMINABLE_REGS                                        \
-{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},                \
- { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},    \
- { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM},          \
- { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
+#define ELIMINABLE_REGS                                             \
+{{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM},                     \
+ { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},         \
+ { ARG_POINTER_REGNUM, STACK_POINTER_REGNUM},               \
+ { ARG_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM},           \
+ { RETURN_ADDRESS_POINTER_REGNUM, STACK_POINTER_REGNUM},     \
+ { RETURN_ADDRESS_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
 
 #define CAN_ELIMINATE(FROM, TO) (1)
 
@@ -633,6 +634,10 @@ extern int current_function_outgoing_args_size;
   { (OFFSET) = s390_arg_frame_offset (); }                                       \
   else if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM)  \
   { (OFFSET) = s390_arg_frame_offset (); }                                       \
+  else if ((FROM) == RETURN_ADDRESS_POINTER_REGNUM                        \
+            && ((TO) == STACK_POINTER_REGNUM                              \
+                || (TO) == HARD_FRAME_POINTER_REGNUM))                    \
+  { (OFFSET) = s390_return_address_offset (); }                          \
   else                                                                   \
     abort();                                                             \
 }
@@ -914,10 +919,10 @@ extern int flag_pic;
    indexed by compiler's hard-register-number (see above).  */
 #define REGISTER_NAMES                                                 \
 { "%r0",  "%r1",  "%r2",  "%r3",  "%r4",  "%r5",  "%r6",  "%r7",       \
-  "%r8",  "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",       \
+  "%r8",  "%r9",  "%r10", "%r11", "%r12", "%r13", "%r14", "%r15",      \
   "%f0",  "%f2",  "%f4",  "%f6",  "%f1",  "%f3",  "%f5",  "%f7",       \
-  "%f8",  "%f10", "%f12", "%f14", "%f9", "%f11", "%f13", "%f15",       \
-  "%ap",  "%cc",  "%fp"                                                        \
+  "%f8",  "%f10", "%f12", "%f14", "%f9",  "%f11", "%f13", "%f15",      \
+  "%ap",  "%cc",  "%fp",  "%rp"                                                \
 }
 
 /* Emit a dtp-relative reference to a TLS variable.  */
index 3f38542bd9a980d9a7d401580d8600c8e6694986..d15e7c9a63c0b342d9257b8b2dc7acfacabb5f97 100644 (file)
        }
       else
        FAIL;
-
-      if (from == frame_pointer_rtx || from == arg_pointer_rtx)
-       FAIL;
     }
   else
     {
        }
       else
        FAIL;
-
-      if (to == frame_pointer_rtx || to == arg_pointer_rtx)
-       FAIL;
     }
   else
     {