s390.c (legitimize_address): Optimize loading of large displacements.
authorUlrich Weigand <uweigand@de.ibm.com>
Thu, 15 Aug 2002 09:55:31 +0000 (09:55 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Thu, 15 Aug 2002 09:55:31 +0000 (09:55 +0000)
* config/s390/s390.c (legitimize_address): Optimize loading
of large displacements.

From-SVN: r56345

gcc/ChangeLog
gcc/config/s390/s390.c

index ab35fcff585ad50931b9c16d86539e5536736362..71ae78dae207f76979ba4870cee77204940d1e54 100644 (file)
@@ -1,3 +1,8 @@
+2002-08-15  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * config/s390/s390.c (legitimize_address): Optimize loading
+       of large displacements.
+
 2002-08-14  Douglas B Rupp  <rupp@gnat.com>
 
        * config/alpha/alpha-protos.h: Update.
index 6a29b764f007b744f06cc855313dc9e62e7614f8..85952c5bacb24bf0191d2d6cd12a5adf84c7c55c 100644 (file)
@@ -2084,6 +2084,31 @@ legitimize_address (x, oldx, mode)
 
   x = eliminate_constant_term (x, &constant_term);
 
+  /* Optimize loading of large displacements by splitting them
+     into the multiple of 4K and the rest; this allows the
+     former to be CSE'd if possible. 
+
+     Don't do this if the displacement is added to a register
+     pointing into the stack frame, as the offsets will
+     change later anyway.  */
+
+  if (GET_CODE (constant_term) == CONST_INT
+      && (INTVAL (constant_term) < 0
+          || INTVAL (constant_term) >= 4096)
+      && !(REG_P (x) && REGNO_PTR_FRAME_P (REGNO (x))))
+    {
+      HOST_WIDE_INT lower = INTVAL (constant_term) & 0xfff;
+      HOST_WIDE_INT upper = INTVAL (constant_term) ^ lower;
+
+      rtx temp = gen_reg_rtx (Pmode);
+      rtx val  = force_operand (GEN_INT (upper), temp);
+      if (val != temp)
+       emit_move_insn (temp, val);
+
+      x = gen_rtx_PLUS (Pmode, x, temp);
+      constant_term = GEN_INT (lower);
+    }
+
   if (GET_CODE (x) == PLUS)
     {
       if (GET_CODE (XEXP (x, 0)) == REG)