OSDN Git Service

* config/s390/s390-protos.h (legitimize_la_operand,
authoruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 4 Feb 2002 15:51:18 +0000 (15:51 +0000)
committeruweigand <uweigand@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 4 Feb 2002 15:51:18 +0000 (15:51 +0000)
s390_secondary_input_reload_class, s390_plus_operand,
s390_expand_plus_operand): Add prototypes.

config/s390/s390.c (s390_secondary_input_reload_class,
s390_plus_operand, s390_expand_plus_operand): New functions.

(struct s390_address): New member 'pointer'.
(s390_decompose_address): Compute it.
(legitimate_la_operand_p): Use it.
(legitimize_la_operand): New function.
(movti, movdi, movdf splitters): Call it.

config/s390/s390.h (SECONDARY_INPUT_RELOAD_CLASS): Define.
(PREDICATE_CODES): Add s390_plus_operand.

config/s390/s390.md (adddi3_inv_64, addaddr_ccclobber): Delete.
(la_ccclobber): Allow GENERAL_REGS as output operand.

(reload_load_address, *reload_load_address_reg_0, *la, *do_la_reg_0,
*reload_la_64, *reload_la_31 and splitters): Delete, replace by ...
(*la_64, *la_31, reload_indi, reload_insi): ... these.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@49476 138bc75d-0d04-0410-961f-82ee72b054a4

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

index 43c4703..19dd639 100644 (file)
@@ -1,5 +1,30 @@
 2002-02-04  Ulrich Weigand  <uweigand@de.ibm.com>
 
+       * config/s390/s390-protos.h (legitimize_la_operand,
+       s390_secondary_input_reload_class, s390_plus_operand,
+       s390_expand_plus_operand): Add prototypes.
+
+       config/s390/s390.c (s390_secondary_input_reload_class,
+       s390_plus_operand, s390_expand_plus_operand): New functions.
+
+       (struct s390_address): New member 'pointer'.
+       (s390_decompose_address): Compute it.
+       (legitimate_la_operand_p): Use it.
+       (legitimize_la_operand): New function.
+       (movti, movdi, movdf splitters): Call it.
+
+       config/s390/s390.h (SECONDARY_INPUT_RELOAD_CLASS): Define.
+       (PREDICATE_CODES): Add s390_plus_operand.
+
+       config/s390/s390.md (adddi3_inv_64, addaddr_ccclobber): Delete.
+       (la_ccclobber): Allow GENERAL_REGS as output operand.
+
+       (reload_load_address, *reload_load_address_reg_0, *la, *do_la_reg_0,
+       *reload_la_64, *reload_la_31 and splitters): Delete, replace by ...
+       (*la_64, *la_31, reload_indi, reload_insi): ... these.
+
+2002-02-04  Ulrich Weigand  <uweigand@de.ibm.com>
+
        * gcc/config/s390/s390.h (CRT_CALL_STATIC_FUNCTION): Fixed
        register names for regular asm () construct.
 
index b426dac..2ab387a 100644 (file)
@@ -48,6 +48,7 @@ extern int s390_match_ccmode PARAMS ((rtx, enum machine_mode));
 extern enum machine_mode s390_select_ccmode PARAMS ((enum rtx_code, rtx, rtx));
 extern int symbolic_reference_mentioned_p PARAMS ((rtx));
 extern int legitimate_la_operand_p PARAMS ((rtx));
+extern rtx legitimize_la_operand PARAMS ((rtx));
 extern int legitimate_pic_operand_p PARAMS ((rtx));
 extern int legitimate_constant_p PARAMS ((rtx));
 extern int legitimate_reload_constant_p PARAMS ((rtx));
@@ -55,6 +56,9 @@ extern int legitimate_address_p PARAMS ((enum machine_mode, rtx, int));
 extern rtx legitimize_pic_address PARAMS ((rtx, rtx));
 extern rtx legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
 extern enum reg_class s390_preferred_reload_class PARAMS ((rtx, enum reg_class));
+extern enum reg_class s390_secondary_input_reload_class PARAMS ((enum reg_class, enum machine_mode, rtx));
+extern int s390_plus_operand PARAMS ((rtx, enum machine_mode));
+extern void s390_expand_plus_operand PARAMS ((rtx, rtx, rtx));
 extern void emit_pic_move PARAMS ((rtx *, enum machine_mode));
 
 extern void s390_output_symbolic_const PARAMS ((FILE *, rtx));
index 2cf2e41..0167ab8 100644 (file)
@@ -103,6 +103,7 @@ struct s390_address
   rtx base;
   rtx indx;
   rtx disp;
+  int pointer;
 };
 
 /* Structure containing information for prologue and epilogue.  */ 
@@ -1125,6 +1126,107 @@ s390_preferred_reload_class (op, class)
   return class;
 }
 
+/* Return the register class of a scratch register needed to
+   load IN into a register of class CLASS in MODE.
+
+   We need a temporary when loading a PLUS expression which
+   is not a legitimate operand of the LOAD ADDRESS instruction.  */
+
+enum reg_class
+s390_secondary_input_reload_class (class, mode, in)
+     enum reg_class class ATTRIBUTE_UNUSED;
+     enum machine_mode mode;
+     rtx in;
+{
+  if (s390_plus_operand (in, mode))
+    return ADDR_REGS;
+
+  return NO_REGS;
+}
+
+/* Return true if OP is a PLUS that is not a legitimate
+   operand for the LA instruction. 
+   OP is the current operation.
+   MODE is the current operation mode.  */
+
+int
+s390_plus_operand (op, mode)
+     register rtx op;
+     enum machine_mode mode;
+{
+  if (!check_mode (op, &mode) || mode != Pmode)
+    return FALSE;
+
+  if (GET_CODE (op) != PLUS)
+    return FALSE;
+
+  if (legitimate_la_operand_p (op))
+    return FALSE;
+
+  return TRUE;
+}
+
+/* Generate code to load SRC, which is PLUS that is not a
+   legitimate operand for the LA instruction, into TARGET.
+   SCRATCH may be used as scratch register.  */
+
+void
+s390_expand_plus_operand (target, src, scratch)
+     register rtx target;
+     register rtx src;
+     register rtx scratch;
+{
+  /* src must be a PLUS; get its two operands.  */
+  rtx sum1, sum2;
+
+  if (GET_CODE (src) != PLUS || GET_MODE (src) != Pmode)
+    abort ();
+
+  sum1 = XEXP (src, 0);
+  sum2 = XEXP (src, 1);
+
+  /* If one of the two operands is equal to the target,
+     make it the first one.  */
+  if (rtx_equal_p (target, sum2))
+    {
+      sum2 = XEXP (src, 0);
+      sum1 = XEXP (src, 1);
+    }
+
+  /* If the first operand is not an address register,
+     we reload it into the target.  */
+  if (true_regnum (sum1) < 1 || true_regnum (sum1) > 15)
+    {
+      emit_move_insn (target, sum1);
+      sum1 = target;
+    }
+
+  /* Likewise for the second operand.  However, take
+     care not to clobber the target if we already used
+     it for the first operand.  Use the scratch instead.  */
+  if (true_regnum (sum2) < 1 || true_regnum (sum2) > 15)
+    {
+      if (!rtx_equal_p (target, sum1))
+        {
+          emit_move_insn (target, sum2);
+          sum2 = target;
+        }
+      else
+        {
+          emit_move_insn (scratch, sum2);
+          sum2 = scratch;
+        }
+    }
+
+  /* Emit the LOAD ADDRESS pattern.  Note that reload of PLUS
+     is only ever performed on addresses, so we can mark the
+     sum as legitimate for LA in any case.  */
+  src = gen_rtx_PLUS (Pmode, sum1, sum2);
+  src = legitimize_la_operand (src);
+  emit_insn (gen_rtx_SET (VOIDmode, target, src));
+}
+
+
 /* Decompose a RTL expression ADDR for a memory address into
    its components, returned in OUT.  The boolean STRICT 
    specifies whether strict register checking applies.
@@ -1145,6 +1247,7 @@ s390_decompose_address (addr, out, strict)
   rtx base = NULL_RTX;
   rtx indx = NULL_RTX;
   rtx disp = NULL_RTX;
+  int pointer = FALSE;
 
   /* Decompose address into base + index + displacement.  */
 
@@ -1198,6 +1301,7 @@ s390_decompose_address (addr, out, strict)
           if (XVECLEN (base, 0) != 1 || XINT (base, 1) != 101)
              return FALSE;
          base = XVECEXP (base, 0, 0);
+         pointer = TRUE;
        }
 
       if (GET_CODE (base) != REG || GET_MODE (base) != Pmode)
@@ -1206,6 +1310,16 @@ s390_decompose_address (addr, out, strict)
       if ((strict && ! REG_OK_FOR_BASE_STRICT_P (base))
          || (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (base)))
          return FALSE;
+    
+      if (REGNO (base) == BASE_REGISTER
+         || REGNO (base) == STACK_POINTER_REGNUM
+         || REGNO (base) == FRAME_POINTER_REGNUM
+         || ((reload_completed || reload_in_progress)
+             && frame_pointer_needed
+             && REGNO (base) == HARD_FRAME_POINTER_REGNUM)
+          || (flag_pic
+              && REGNO (base) == PIC_OFFSET_TABLE_REGNUM))
+        pointer = TRUE;
     }
 
   /* Validate index register.  */
@@ -1216,6 +1330,7 @@ s390_decompose_address (addr, out, strict)
           if (XVECLEN (indx, 0) != 1 || XINT (indx, 1) != 101)
              return FALSE;
          indx = XVECEXP (indx, 0, 0);
+         pointer = TRUE;
        }
 
       if (GET_CODE (indx) != REG || GET_MODE (indx) != Pmode)
@@ -1224,6 +1339,16 @@ s390_decompose_address (addr, out, strict)
       if ((strict && ! REG_OK_FOR_BASE_STRICT_P (indx))
          || (! strict && ! REG_OK_FOR_BASE_NONSTRICT_P (indx)))
          return FALSE;
+    
+      if (REGNO (indx) == BASE_REGISTER
+         || REGNO (indx) == STACK_POINTER_REGNUM
+         || REGNO (indx) == FRAME_POINTER_REGNUM
+         || ((reload_completed || reload_in_progress)
+             && frame_pointer_needed
+             && REGNO (indx) == HARD_FRAME_POINTER_REGNUM)
+          || (flag_pic
+              && REGNO (indx) == PIC_OFFSET_TABLE_REGNUM))
+        pointer = TRUE;
     }
 
   /* Validate displacement.  */
@@ -1244,6 +1369,8 @@ s390_decompose_address (addr, out, strict)
         {
           if (flag_pic != 1)
             return FALSE;
+
+         pointer = TRUE;
         }
 
       /* We can convert literal pool addresses to 
@@ -1295,14 +1422,20 @@ s390_decompose_address (addr, out, strict)
 
           if (offset)
             disp = plus_constant (disp, offset);
+
+         pointer = TRUE;
         }
     }
 
+  if (!base && !indx)
+    pointer = TRUE;
+   
   if (out)
     {
       out->base = base;
       out->indx = indx;
       out->disp = disp;
+      out->pointer = pointer;
     }
 
   return TRUE;
@@ -1332,28 +1465,36 @@ legitimate_la_operand_p (op)
   if (!s390_decompose_address (op, &addr, FALSE))
     return FALSE;
 
-  if (TARGET_64BIT)
+  if (TARGET_64BIT || addr.pointer)
     return TRUE;
 
-  /* Use of the base or stack pointer implies address.  */
+  return FALSE;
+}
 
-  if (addr.base && GET_CODE (addr.base) == REG)
-    {
-      if (REGNO (addr.base) == BASE_REGISTER
-         || REGNO (addr.base) == STACK_POINTER_REGNUM
-         || REGNO (addr.base) == FRAME_POINTER_REGNUM)
-        return TRUE;
-    }
+/* Return a modified variant of OP that is guaranteed to
+   be accepted by legitimate_la_operand_p.  */
 
-  if (addr.indx && GET_CODE (addr.indx) == REG)
-    {
-      if (REGNO (addr.indx) == BASE_REGISTER
-          || REGNO (addr.indx) == STACK_POINTER_REGNUM
-         || REGNO (addr.base) == FRAME_POINTER_REGNUM)
-        return TRUE;
-    }
+rtx
+legitimize_la_operand (op)
+     register rtx op;
+{
+  struct s390_address addr;
+  if (!s390_decompose_address (op, &addr, FALSE))
+    abort ();
 
-  return FALSE;
+  if (TARGET_64BIT || addr.pointer)
+    return op;
+
+  if (!addr.base)
+    abort ();
+
+  op = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr.base), 101);
+  if (addr.indx)
+    op = gen_rtx_PLUS (Pmode, op, addr.indx);
+  if (addr.disp)
+    op = gen_rtx_PLUS (Pmode, op, addr.disp);
+
+  return op; 
 }
 
 /* Return a legitimate reference for ORIG (an address) using the
index f26cd65..f648505 100644 (file)
@@ -577,6 +577,12 @@ extern enum reg_class regclass_map[FIRST_PSEUDO_REGISTER]; /* smalled class cont
       (GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT ? 2 : 1) :                  \
       (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
 
+/* We need a secondary reload when loading a PLUS which is 
+   not a valid operand for LOAD ADDRESS.  */
+
+#define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN)  \
+       s390_secondary_input_reload_class ((CLASS), (MODE), (IN))
+
 /* If we are copying between FP registers and anything else, we need a memory
    location.  */
 
@@ -1293,7 +1299,8 @@ extern struct rtx_def *s390_compare_op0, *s390_compare_op1;
   {"larl_operand",    { SYMBOL_REF, CONST, CONST_INT, CONST_DOUBLE }}, \
   {"load_multiple_operation", {PARALLEL}},                             \
   {"store_multiple_operation", {PARALLEL}},                            \
-  {"const0_operand",  { CONST_INT, CONST_DOUBLE }},
+  {"const0_operand",  { CONST_INT, CONST_DOUBLE }},                    \
+  {"s390_plus_operand", { PLUS }},
 
 
 /* S/390 constant pool breaks the devices in crtstuff.c to control section
index 0208eff..905092b 100644 (file)
   [(set (match_dup 2) (match_dup 3))
    (set (match_dup 0) (mem:TI (match_dup 2)))]
   "operands[2] = operand_subword (operands[0], 1, 0, TImode);
-   operands[3] = XEXP (operands[1], 0);")
+   operands[3] = legitimize_la_operand (XEXP (operands[1], 0));")
 
 ;
 ; movdi instruction pattern(s).
   [(set (match_dup 2) (match_dup 3))
    (set (match_dup 0) (mem:DI (match_dup 2)))]
   "operands[2] = operand_subword (operands[0], 1, 0, DImode);
-   operands[3] = XEXP (operands[1], 0);")
+   operands[3] = legitimize_la_operand (XEXP (operands[1], 0));")
 
 ;
 ; movsi instruction pattern(s).
   [(set (match_dup 2) (match_dup 3))
    (set (match_dup 0) (mem:DI (match_dup 2)))]
   "operands[2] = operand_subword (operands[0], 1, 0, DFmode);
-   operands[3] = XEXP (operands[1], 0);")
+   operands[3] = legitimize_la_operand (XEXP (operands[1], 0));")
 
 ;
 ; movsf instruction pattern(s).
   [(set_attr "op_type"  "RRE,RI,RXE")
    (set_attr "atype"    "reg,reg,mem")])
 
-;
-; For weakness of reload, need (set (reg x) (plus (reg y) (reg x)))
-;
-
-(define_insn "adddi3_inv_64"
-  [(set (match_operand:DI 0 "register_operand" "=d,d,d")
-        (plus:DI (match_operand:DI 1 "general_operand" "%d,K,m")
-                 (match_operand:DI 2 "register_operand" "0,0,0") ) )
-   (clobber (reg:CC 33))]
-  "TARGET_64BIT"
-  "@
-   agr\\t%0,%1
-   aghi\\t%0,%h1
-   ag\\t%0,%1"
-  [(set_attr "op_type" "RRE,RI,RXE")
-   (set_attr "atype"   "reg,reg,mem")])
-
 (define_insn "adddi3_31"
   [(set (match_operand:DI 0 "register_operand" "=d,d")
         (plus:DI (match_operand:DI 1 "register_operand" "0,0")
   DONE;                
 }")
 
-(define_insn "reload_load_address"
-  [(set (match_operand:DI 0 "register_operand" "=a")
+(define_insn "*la_64"
+  [(set (match_operand:DI 0 "register_operand" "=d")
         (match_operand:QI 1 "address_operand" "p"))]
   "TARGET_64BIT"
   "la\\t%0,%a1"      
    (set_attr "atype"   "mem")
    (set_attr "type"    "la")])
 
-(define_insn "*reload_load_address_reg_0"
-  [(set (match_operand:DI 0 "register_operand" "=d")
-        (plus:DI (match_operand:DI 1 "register_operand" "%0")
-                 (match_operand:DI 2 "register_operand" "d")))]
+(define_expand "reload_indi"
+  [(parallel [(match_operand:DI 0 "register_operand" "=a")
+              (match_operand:DI 1 "s390_plus_operand" "")
+              (match_operand:DI 2 "register_operand" "=&a")])]
   "TARGET_64BIT"
-  "brxlg\\t%0,%2,.+6"
-  [(set_attr "op_type" "RIE")
-   (set_attr "atype"   "reg")])
-
-(define_insn "*reload_la_64"
-  [(set (match_operand:DI 0 "register_operand" "=d")
-        (plus:DI (match_operand:DI 1 "general_operand" "g")
-                 (match_operand:DI 2 "general_operand" "g")))]
-  "TARGET_64BIT && reload_in_progress
-   && !address_operand (gen_rtx_PLUS (DImode, operands[1], operands[2]), QImode)
-   && !rtx_equal_p (operands[0], operands[1])
-   && !rtx_equal_p (operands[0], operands[2])"
-  "#")
-
-(define_split
-  [(set (match_operand:DI 0 "register_operand" "")
-        (plus:DI (match_operand:DI 1 "general_operand" "")
-                 (match_operand:DI 2 "register_operand" "")))]
-  "TARGET_64BIT && reload_completed
-   && !address_operand (gen_rtx_PLUS (DImode, operands[1], operands[2]), QImode)
-   && !rtx_equal_p (operands[0], operands[1])
-   && !rtx_equal_p (operands[0], operands[2])"
-  [(set (match_dup 0) (match_dup 1))
-   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 2)))]
   "
 {
-  if (CONSTANT_P (operands[1]) 
-      && !legitimate_reload_constant_p (operands[1]))
-    operands[1] = force_const_mem (DImode, operands[1]);
+  s390_expand_plus_operand (operands[0], operands[1], operands[2]);
+  DONE;
 }")
 
-(define_split
-  [(set (match_operand:DI 0 "register_operand" "")
-        (plus:DI (match_operand:DI 1 "register_operand" "")
-                 (match_operand:DI 2 "general_operand" "")))]
-  "TARGET_64BIT && reload_completed
-   && !address_operand (gen_rtx_PLUS (DImode, operands[1], operands[2]), QImode)
-   && !rtx_equal_p (operands[0], operands[1])
-   && !rtx_equal_p (operands[0], operands[2])"
-  [(set (match_dup 0) (match_dup 2))
-   (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))]
-  "
-{
-  if (CONSTANT_P (operands[2]) 
-      && !legitimate_reload_constant_p (operands[2]))
-    operands[2] = force_const_mem (DImode, operands[2]);
-}")
  
 ;
 ; addsi3 instruction pattern(s).
 ;
 
 (define_insn "*la_ccclobber"
-  [(set (match_operand:SI 0 "register_operand" "=a")
+  [(set (match_operand:SI 0 "register_operand" "=d")
         (match_operand:QI 1 "address_operand"  "p"))
    (clobber (reg:CC 33))]
   "legitimate_la_operand_p (operands[1])"
     (set_attr "atype"    "mem")
     (set_attr "type"     "la")])
 
-(define_insn "*addaddr_ccclobber"
-  [(set (match_operand:SI 0 "register_operand" "=d,d")
-        (plus:SI (match_operand:SI 1 "register_operand" "%a,a")
-                 (match_operand:SI 2 "nonmemory_operand" "J,a")))
-   (clobber (reg:CC 33))]
-  "(((REGNO (operands[1]) == STACK_POINTER_REGNUM ) ||
-     (REGNO (operands[1]) == FRAME_POINTER_REGNUM ) || 
-     (REGNO (operands[1]) == BASE_REGISTER)) && 
-        (GET_CODE (operands[2]) == REG ||
-        CONST_OK_FOR_LETTER_P (INTVAL (operands[2]),'J')))"
-  "@
-   la\\t%0,%c2(,%1)
-   la\\t%0,0(%1,%2)"
-  [(set_attr "op_type"  "RX")
-   (set_attr "atype"    "mem")
-   (set_attr "type"     "la")])
-
 (define_insn "*addsi3_cc"
   [(set (reg 33) 
         (compare (plus:SI (match_operand:SI 1 "register_operand" "%0,0")
   [(set_attr "op_type"  "RR,RI,RX")
    (set_attr "atype"    "reg,reg,mem")])
 
-(define_insn "*la"
-  [(set (match_operand:SI 0 "register_operand" "=a")
+(define_insn "*la_31"
+  [(set (match_operand:SI 0 "register_operand" "=d")
         (match_operand:QI 1 "address_operand" "p"))]
-  "reload_in_progress || reload_completed
-   || legitimate_la_operand_p (operands[1])"
+  "legitimate_la_operand_p (operands[1])"
   "la\\t%0,%a1"
   [(set_attr "op_type"  "RX")
    (set_attr "atype"    "mem")
    (set_attr "type"     "la")])
 
-(define_insn "*do_la_reg_0"
-  [(set (match_operand:SI 0 "register_operand" "=d")
-        (plus:SI (match_operand:SI 1 "register_operand" "%0")
-                 (match_operand:SI 2 "register_operand" "d")))]
-  "reload_in_progress || reload_completed"
-  "brxle\\t%0,%2,.+4"
-  [(set_attr "op_type" "RSI")
-   (set_attr "atype"   "reg")])
-
-(define_insn "*reload_la_31"
-  [(set (match_operand:SI 0 "register_operand" "=d")
-        (plus:SI (match_operand:SI 1 "general_operand" "g")
-                 (match_operand:SI 2 "general_operand" "g")))]
-  "reload_in_progress
-   && !address_operand (gen_rtx_PLUS (SImode, operands[1], operands[2]), QImode)
-   && !rtx_equal_p (operands[0], operands[1])
-   && !rtx_equal_p (operands[0], operands[2])"
-  "#")
-
-(define_split
-  [(set (match_operand:SI 0 "register_operand" "")
-        (plus:SI (match_operand:SI 1 "general_operand" "")
-                 (match_operand:SI 2 "register_operand" "")))]
-  "reload_completed
-   && !address_operand (gen_rtx_PLUS (SImode, operands[1], operands[2]), QImode)
-   && !rtx_equal_p (operands[0], operands[1])
-   && !rtx_equal_p (operands[0], operands[2])"
-  [(set (match_dup 0) (match_dup 1))
-   (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
-  "
-{
-  if (CONSTANT_P (operands[1]) 
-      && !legitimate_reload_constant_p (operands[1]))
-    operands[1] = force_const_mem (SImode, operands[1]);
-}")
-
-(define_split
-  [(set (match_operand:SI 0 "register_operand" "")
-        (plus:SI (match_operand:SI 1 "register_operand" "")
-                 (match_operand:SI 2 "general_operand" "")))]
-  "reload_completed
-   && !address_operand (gen_rtx_PLUS (SImode, operands[1], operands[2]), QImode)
-   && !rtx_equal_p (operands[0], operands[1])
-   && !rtx_equal_p (operands[0], operands[2])"
-  [(set (match_dup 0) (match_dup 2))
-   (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))]
+(define_expand "reload_insi"
+  [(parallel [(match_operand:SI 0 "register_operand" "=a")
+              (match_operand:SI 1 "s390_plus_operand" "")
+              (match_operand:SI 2 "register_operand" "=&a")])]
+  "!TARGET_64BIT"
   "
 {
-  if (CONSTANT_P (operands[2]) 
-      && !legitimate_reload_constant_p (operands[2]))
-    operands[2] = force_const_mem (SImode, operands[2]);
+  s390_expand_plus_operand (operands[0], operands[1], operands[2]);
+  DONE;
 }")