S/390: Really fix non-offsettable multi-word accesses

Ulrich Weigand weigand@i1.informatik.uni-erlangen.de
Fri Jun 27 21:51:00 GMT 2003


Hello,

as we've noticed in the past:
http://gcc.gnu.org/ml/gcc-patches/2003-03/msg01997.html
the s390 backend runs into trouble when trying to split
a double-word non-offsettable memory reference.

Unfortunately, it now turned out that the above fix solved
the problem only partially.  It did in fact avoid the problem
for memory references generated before reload;  however, what
I had overlooked is that reload itself can generate such
problematic memory references in reload insns ...

This patch now fixes that problem as well.  When loading 
from a non-offsettable double-word memory reference into
a register pair, I can use the existing splitter into a
LOAD ADDRESS / LOAD MULTIPLE pair using one of the destination
registers as temporary to hold the address, after some
reshuffling to avoid having the other splitters trigger
incorrectly.

When storing to memory, this doesn't work because I don't
have a temporary.  Thus, I'm now employing the secondary
output reload mechanism to allocate a temporary in these
situations.

Bootstrapped/regtested on s390-ibm-linux and s390x-ibm-linux
on head and 3.3 branch; applied to both.

Bye,
Ulrich


gcc/ChangeLog:

	* config/s390/s390.h (SECONDARY_OUTPUT_RELOAD_CLASS): Define.
	* config/s390/s390.c (s390_secondary_output_reload_class): New function.
	* config/s390/s390-protos.h (s390_secondary_output_reload_class): 
	Declare it.
	* config/s390/s390.md ("reload_outti", "reload_outdi", 
	"reload_outdf"): New expanders.

	* config/s390/s390.md ("movti" + splitters): Handle non-offsettable
	memory operands as source.
	("movdi" + splitters): Likewise.
	("movdf" + splitters): Likewise.
	* config/s390/s390.c (s390_split_ok_p): New function.
	* config/s390/s390-protos.h (s390_split_ok_p): Declare it.

gcc/testsuite/ChangeLog:

	* gcc.dg/20030627-1.c: New test.


Index: gcc/config/s390/s390-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390-protos.h,v
retrieving revision 1.29
diff -c -p -r1.29 s390-protos.h
*** gcc/config/s390/s390-protos.h	14 May 2003 07:29:52 -0000	1.29
--- gcc/config/s390/s390-protos.h	27 Jun 2003 15:19:36 -0000
*************** extern int s390_single_hi PARAMS ((rtx, 
*** 42,47 ****
--- 42,48 ----
  extern int s390_extract_hi PARAMS ((rtx, enum machine_mode, int));
  extern int s390_single_qi PARAMS ((rtx, enum machine_mode, int));
  extern int s390_extract_qi PARAMS ((rtx, enum machine_mode, int));
+ extern bool s390_split_ok_p PARAMS ((rtx, rtx, enum machine_mode, int));
  extern int tls_symbolic_operand PARAMS ((rtx));
  
  extern int s390_match_ccmode PARAMS ((rtx, enum machine_mode));
*************** extern rtx legitimize_pic_address PARAMS
*** 60,65 ****
--- 61,67 ----
  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 enum reg_class s390_secondary_output_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_symbolic_move PARAMS ((rtx *));
Index: gcc/config/s390/s390.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.c,v
retrieving revision 1.96
diff -c -p -r1.96 s390.c
*** gcc/config/s390/s390.c	23 Jun 2003 20:52:13 -0000	1.96
--- gcc/config/s390/s390.c	27 Jun 2003 15:19:37 -0000
*************** s390_extract_qi (op, mode, part)
*** 863,868 ****
--- 863,904 ----
    abort ();
  }
  
+ /* Check whether we can (and want to) split a double-word 
+    move in mode MODE from SRC to DST into two single-word 
+    moves, moving the subword FIRST_SUBWORD first.  */
+ 
+ bool
+ s390_split_ok_p (dst, src, mode, first_subword)
+      rtx dst;
+      rtx src;
+      enum machine_mode mode;
+      int first_subword;
+ {
+   /* Floating point registers cannot be split.  */
+   if (FP_REG_P (src) || FP_REG_P (dst))
+     return false;
+ 
+   /* We don't need to split if operands are directly accessable.  */
+   if (s_operand (src, mode) || s_operand (dst, mode))
+     return false;
+ 
+   /* Non-offsettable memory references cannot be split.  */
+   if ((GET_CODE (src) == MEM && !offsettable_memref_p (src))
+       || (GET_CODE (dst) == MEM && !offsettable_memref_p (dst)))
+     return false;
+ 
+   /* Moving the first subword must not clobber a register
+      needed to move the second subword.  */
+   if (register_operand (dst, mode))
+     {
+       rtx subreg = operand_subword (dst, first_subword, 0, mode);
+       if (reg_overlap_mentioned_p (subreg, src))
+         return false;
+     }
+ 
+   return true;
+ }
+ 
  
  /* Change optimizations to be performed, depending on the 
     optimization level.
*************** s390_secondary_input_reload_class (class
*** 1710,1715 ****
--- 1746,1774 ----
       rtx in;
  {
    if (s390_plus_operand (in, mode))
+     return ADDR_REGS;
+ 
+   return NO_REGS;
+ }
+ 
+ /* Return the register class of a scratch register needed to
+    store a register of class CLASS in MODE into OUT:
+ 
+    We need a temporary when storing a double-word to a 
+    non-offsettable memory address.  */
+ 
+ enum reg_class
+ s390_secondary_output_reload_class (class, mode, out)
+      enum reg_class class;
+      enum machine_mode mode;
+      rtx out;
+ {
+   if ((TARGET_64BIT ? mode == TImode
+                     : (mode == DImode || mode == DFmode))
+       && reg_classes_intersect_p (GENERAL_REGS, class)
+       && GET_CODE (out) == MEM
+       && !offsettable_memref_p (out)
+       && !s_operand (out, VOIDmode))
      return ADDR_REGS;
  
    return NO_REGS;
Index: gcc/config/s390/s390.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.h,v
retrieving revision 1.74
diff -c -p -r1.74 s390.h
*** gcc/config/s390/s390.h	14 May 2003 07:29:52 -0000	1.74
--- gcc/config/s390/s390.h	27 Jun 2003 15:19:38 -0000
*************** extern const enum reg_class regclass_map
*** 460,465 ****
--- 460,470 ----
  #define SECONDARY_INPUT_RELOAD_CLASS(CLASS, MODE, IN)	\
    s390_secondary_input_reload_class ((CLASS), (MODE), (IN))
  
+ /* We need a secondary reload when storing a double-word
+    to a non-offsettable memory address.  */
+ #define SECONDARY_OUTPUT_RELOAD_CLASS(CLASS, MODE, OUT)	\
+   s390_secondary_output_reload_class ((CLASS), (MODE), (OUT))
+ 
  /* We need secondary memory to move data between GPRs and FPRs.  */
  #define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
   ((CLASS1) != (CLASS2) && ((CLASS1) == FP_REGS || (CLASS2) == FP_REGS))
Index: gcc/config/s390/s390.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.md,v
retrieving revision 1.55
diff -c -p -r1.55 s390.md
*** gcc/config/s390/s390.md	13 May 2003 14:33:16 -0000	1.55
--- gcc/config/s390/s390.md	27 Jun 2003 15:19:40 -0000
***************
*** 905,911 ****
  
  (define_insn "movti"
    [(set (match_operand:TI 0 "nonimmediate_operand" "=d,Q,d,o,Q")
!         (match_operand:TI 1 "general_operand" "Q,d,dKo,d,Q"))]
    "TARGET_64BIT"
    "@
     lmg\\t%0,%N0,%1
--- 905,911 ----
  
  (define_insn "movti"
    [(set (match_operand:TI 0 "nonimmediate_operand" "=d,Q,d,o,Q")
!         (match_operand:TI 1 "general_operand" "Q,d,dKm,d,Q"))]
    "TARGET_64BIT"
    "@
     lmg\\t%0,%N0,%1
***************
*** 920,955 ****
    [(set (match_operand:TI 0 "nonimmediate_operand" "")
          (match_operand:TI 1 "general_operand" ""))]
    "TARGET_64BIT && reload_completed
!    && !s_operand (operands[0], VOIDmode)
!    && !s_operand (operands[1], VOIDmode)
!    && (register_operand (operands[0], VOIDmode)
!        || register_operand (operands[1], VOIDmode))
!    && (!register_operand (operands[0], VOIDmode)
!        || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, TImode),
!                                     operands[1])
!        || !reg_overlap_mentioned_p (operand_subword (operands[0], 1, 0, TImode),
!                                     operands[1]))"
    [(set (match_dup 2) (match_dup 4))
     (set (match_dup 3) (match_dup 5))]
-   "
  {
!   if (!register_operand (operands[0], VOIDmode)
!       || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, TImode),
!                                    operands[1]))
!     {
!       operands[2] = operand_subword (operands[0], 0, 0, TImode);
!       operands[3] = operand_subword (operands[0], 1, 0, TImode);
!       operands[4] = operand_subword (operands[1], 0, 0, TImode);
!       operands[5] = operand_subword (operands[1], 1, 0, TImode);
!     }
!   else
!     {
!       operands[2] = operand_subword (operands[0], 1, 0, TImode);
!       operands[3] = operand_subword (operands[0], 0, 0, TImode);
!       operands[4] = operand_subword (operands[1], 1, 0, TImode);
!       operands[5] = operand_subword (operands[1], 0, 0, TImode);
!     }
! }")
  
  (define_split
    [(set (match_operand:TI 0 "register_operand" "")
--- 920,948 ----
    [(set (match_operand:TI 0 "nonimmediate_operand" "")
          (match_operand:TI 1 "general_operand" ""))]
    "TARGET_64BIT && reload_completed
!    && s390_split_ok_p (operands[0], operands[1], TImode, 0)"
    [(set (match_dup 2) (match_dup 4))
     (set (match_dup 3) (match_dup 5))]
  {
!   operands[2] = operand_subword (operands[0], 0, 0, TImode);
!   operands[3] = operand_subword (operands[0], 1, 0, TImode);
!   operands[4] = operand_subword (operands[1], 0, 0, TImode);
!   operands[5] = operand_subword (operands[1], 1, 0, TImode);
! })
! 
! (define_split
!   [(set (match_operand:TI 0 "nonimmediate_operand" "")
!         (match_operand:TI 1 "general_operand" ""))]
!   "TARGET_64BIT && reload_completed
!    && s390_split_ok_p (operands[0], operands[1], TImode, 1)"
!   [(set (match_dup 2) (match_dup 4))
!    (set (match_dup 3) (match_dup 5))]
! {
!   operands[2] = operand_subword (operands[0], 1, 0, TImode);
!   operands[3] = operand_subword (operands[0], 0, 0, TImode);
!   operands[4] = operand_subword (operands[1], 1, 0, TImode);
!   operands[5] = operand_subword (operands[1], 0, 0, TImode);
! })
  
  (define_split
    [(set (match_operand:TI 0 "register_operand" "")
***************
*** 957,968 ****
    "TARGET_64BIT && reload_completed
     && !s_operand (operands[1], VOIDmode)"
    [(set (match_dup 0) (match_dup 1))]
-   "
  {
    rtx addr = operand_subword (operands[0], 1, 0, TImode);
    s390_load_address (addr, XEXP (operands[1], 0));
    operands[1] = replace_equiv_address (operands[1], addr);
! }")
  
  ;
  ; movdi instruction pattern(s).
--- 950,972 ----
    "TARGET_64BIT && reload_completed
     && !s_operand (operands[1], VOIDmode)"
    [(set (match_dup 0) (match_dup 1))]
  {
    rtx addr = operand_subword (operands[0], 1, 0, TImode);
    s390_load_address (addr, XEXP (operands[1], 0));
    operands[1] = replace_equiv_address (operands[1], addr);
! })
! 
! (define_expand "reload_outti"
!   [(parallel [(match_operand:TI 0 "memory_operand" "")
!               (match_operand:TI 1 "register_operand" "d")
!               (match_operand:DI 2 "register_operand" "=&a")])]
!   "TARGET_64BIT"
! {
!   s390_load_address (operands[2], XEXP (operands[0], 0));
!   operands[0] = replace_equiv_address (operands[0], operands[2]);
!   emit_move_insn (operands[0], operands[1]);
!   DONE;
! })
  
  ;
  ; movdi instruction pattern(s).
***************
*** 1044,1050 ****
  
  (define_insn "*movdi_31"
    [(set (match_operand:DI 0 "nonimmediate_operand" "=d,Q,d,o,!*f,!*f,!m,Q")
!         (match_operand:DI 1 "general_operand" "Q,d,dKo,d,*f,m,*f,Q"))]
    "!TARGET_64BIT"
    "@
     lm\\t%0,%N0,%1
--- 1048,1054 ----
  
  (define_insn "*movdi_31"
    [(set (match_operand:DI 0 "nonimmediate_operand" "=d,Q,d,o,!*f,!*f,!m,Q")
!         (match_operand:DI 1 "general_operand" "Q,d,dKm,d,*f,m,*f,Q"))]
    "!TARGET_64BIT"
    "@
     lm\\t%0,%N0,%1
***************
*** 1062,1114 ****
    [(set (match_operand:DI 0 "nonimmediate_operand" "")
          (match_operand:DI 1 "general_operand" ""))]
    "!TARGET_64BIT && reload_completed
!    && !FP_REG_P (operands[0])
!    && !FP_REG_P (operands[1])
!    && !s_operand (operands[0], VOIDmode)
!    && !s_operand (operands[1], VOIDmode)
!    && (register_operand (operands[0], VOIDmode)
!        || register_operand (operands[1], VOIDmode))
!    && (!register_operand (operands[0], VOIDmode)
!        || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, DImode),
!                                     operands[1])
!        || !reg_overlap_mentioned_p (operand_subword (operands[0], 1, 0, DImode),
!                                     operands[1]))"
    [(set (match_dup 2) (match_dup 4))
     (set (match_dup 3) (match_dup 5))]
-   "
  {
!   if (!register_operand (operands[0], VOIDmode)
!       || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, DImode),
!                                    operands[1]))
!     {
!       operands[2] = operand_subword (operands[0], 0, 0, DImode);
!       operands[3] = operand_subword (operands[0], 1, 0, DImode);
!       operands[4] = operand_subword (operands[1], 0, 0, DImode);
!       operands[5] = operand_subword (operands[1], 1, 0, DImode);
!     }
!   else
!     {
!       operands[2] = operand_subword (operands[0], 1, 0, DImode);
!       operands[3] = operand_subword (operands[0], 0, 0, DImode);
!       operands[4] = operand_subword (operands[1], 1, 0, DImode);
!       operands[5] = operand_subword (operands[1], 0, 0, DImode);
!     }
! }")
  
  (define_split
    [(set (match_operand:DI 0 "register_operand" "")
          (match_operand:DI 1 "memory_operand" ""))]
    "!TARGET_64BIT && reload_completed
     && !FP_REG_P (operands[0])
-    && !FP_REG_P (operands[1])
     && !s_operand (operands[1], VOIDmode)"
    [(set (match_dup 0) (match_dup 1))]
-   "
  {
    rtx addr = operand_subword (operands[0], 1, 0, DImode);
    s390_load_address (addr, XEXP (operands[1], 0));
    operands[1] = replace_equiv_address (operands[1], addr);
! }")
  
  (define_peephole2
    [(set (match_operand:DI 0 "register_operand" "")
--- 1066,1119 ----
    [(set (match_operand:DI 0 "nonimmediate_operand" "")
          (match_operand:DI 1 "general_operand" ""))]
    "!TARGET_64BIT && reload_completed
!    && s390_split_ok_p (operands[0], operands[1], DImode, 0)"
    [(set (match_dup 2) (match_dup 4))
     (set (match_dup 3) (match_dup 5))]
  {
!   operands[2] = operand_subword (operands[0], 0, 0, DImode);
!   operands[3] = operand_subword (operands[0], 1, 0, DImode);
!   operands[4] = operand_subword (operands[1], 0, 0, DImode);
!   operands[5] = operand_subword (operands[1], 1, 0, DImode);
! })
! 
! (define_split
!   [(set (match_operand:DI 0 "nonimmediate_operand" "")
!         (match_operand:DI 1 "general_operand" ""))]
!   "!TARGET_64BIT && reload_completed
!    && s390_split_ok_p (operands[0], operands[1], DImode, 1)"
!   [(set (match_dup 2) (match_dup 4))
!    (set (match_dup 3) (match_dup 5))]
! {
!   operands[2] = operand_subword (operands[0], 1, 0, DImode);
!   operands[3] = operand_subword (operands[0], 0, 0, DImode);
!   operands[4] = operand_subword (operands[1], 1, 0, DImode);
!   operands[5] = operand_subword (operands[1], 0, 0, DImode);
! })
  
  (define_split
    [(set (match_operand:DI 0 "register_operand" "")
          (match_operand:DI 1 "memory_operand" ""))]
    "!TARGET_64BIT && reload_completed
     && !FP_REG_P (operands[0])
     && !s_operand (operands[1], VOIDmode)"
    [(set (match_dup 0) (match_dup 1))]
  {
    rtx addr = operand_subword (operands[0], 1, 0, DImode);
    s390_load_address (addr, XEXP (operands[1], 0));
    operands[1] = replace_equiv_address (operands[1], addr);
! })
! 
! (define_expand "reload_outdi"
!   [(parallel [(match_operand:DI 0 "memory_operand" "")
!               (match_operand:DI 1 "register_operand" "d")
!               (match_operand:SI 2 "register_operand" "=&a")])]
!   "!TARGET_64BIT"
! {
!   s390_load_address (operands[2], XEXP (operands[0], 0));
!   operands[0] = replace_equiv_address (operands[0], operands[2]);
!   emit_move_insn (operands[0], operands[1]);
!   DONE;
! })
  
  (define_peephole2
    [(set (match_operand:DI 0 "register_operand" "")
***************
*** 1354,1360 ****
  
  (define_insn "*movdf_31"
    [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,m,d,Q,d,o,Q")
!         (match_operand:DF 1 "general_operand" "f,m,f,Q,d,dKo,d,Q"))]
    "!TARGET_64BIT"
    "@
     ldr\\t%0,%1
--- 1359,1365 ----
  
  (define_insn "*movdf_31"
    [(set (match_operand:DF 0 "nonimmediate_operand" "=f,f,m,d,Q,d,o,Q")
!         (match_operand:DF 1 "general_operand" "f,m,f,Q,d,dKm,d,Q"))]
    "!TARGET_64BIT"
    "@
     ldr\\t%0,%1
***************
*** 1372,1424 ****
    [(set (match_operand:DF 0 "nonimmediate_operand" "")
          (match_operand:DF 1 "general_operand" ""))]
    "!TARGET_64BIT && reload_completed
!    && !FP_REG_P (operands[0])
!    && !FP_REG_P (operands[1])
!    && !s_operand (operands[0], VOIDmode)
!    && !s_operand (operands[1], VOIDmode)
!    && (register_operand (operands[0], VOIDmode)
!        || register_operand (operands[1], VOIDmode))
!    && (!register_operand (operands[0], VOIDmode)
!        || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, DFmode),
!                                     operands[1])
!        || !reg_overlap_mentioned_p (operand_subword (operands[0], 1, 0, DFmode),
!                                     operands[1]))"
    [(set (match_dup 2) (match_dup 4))
     (set (match_dup 3) (match_dup 5))]
-   "
  {
!   if (!register_operand (operands[0], VOIDmode)
!       || !reg_overlap_mentioned_p (operand_subword (operands[0], 0, 0, DFmode),
!                                    operands[1]))
!     {
!       operands[2] = operand_subword (operands[0], 0, 0, DFmode);
!       operands[3] = operand_subword (operands[0], 1, 0, DFmode);
!       operands[4] = operand_subword (operands[1], 0, 0, DFmode);
!       operands[5] = operand_subword (operands[1], 1, 0, DFmode);
!     }
!   else
!     {
!       operands[2] = operand_subword (operands[0], 1, 0, DFmode);
!       operands[3] = operand_subword (operands[0], 0, 0, DFmode);
!       operands[4] = operand_subword (operands[1], 1, 0, DFmode);
!       operands[5] = operand_subword (operands[1], 0, 0, DFmode);
!     }
! }")
  
  (define_split
    [(set (match_operand:DF 0 "register_operand" "")
          (match_operand:DF 1 "memory_operand" ""))]
    "!TARGET_64BIT && reload_completed
     && !FP_REG_P (operands[0])
-    && !FP_REG_P (operands[1])
     && !s_operand (operands[1], VOIDmode)"
    [(set (match_dup 0) (match_dup 1))]
-   "
  {
    rtx addr = operand_subword (operands[0], 1, 0, DFmode);
    s390_load_address (addr, XEXP (operands[1], 0));
    operands[1] = replace_equiv_address (operands[1], addr);
! }")
  
  ;
  ; movsf instruction pattern(s).
--- 1377,1430 ----
    [(set (match_operand:DF 0 "nonimmediate_operand" "")
          (match_operand:DF 1 "general_operand" ""))]
    "!TARGET_64BIT && reload_completed
!    && s390_split_ok_p (operands[0], operands[1], DFmode, 0)"
    [(set (match_dup 2) (match_dup 4))
     (set (match_dup 3) (match_dup 5))]
  {
!   operands[2] = operand_subword (operands[0], 0, 0, DFmode);
!   operands[3] = operand_subword (operands[0], 1, 0, DFmode);
!   operands[4] = operand_subword (operands[1], 0, 0, DFmode);
!   operands[5] = operand_subword (operands[1], 1, 0, DFmode);
! })
! 
! (define_split
!   [(set (match_operand:DF 0 "nonimmediate_operand" "")
!         (match_operand:DF 1 "general_operand" ""))]
!   "!TARGET_64BIT && reload_completed
!    && s390_split_ok_p (operands[0], operands[1], DFmode, 1)"
!   [(set (match_dup 2) (match_dup 4))
!    (set (match_dup 3) (match_dup 5))]
! {
!   operands[2] = operand_subword (operands[0], 1, 0, DFmode);
!   operands[3] = operand_subword (operands[0], 0, 0, DFmode);
!   operands[4] = operand_subword (operands[1], 1, 0, DFmode);
!   operands[5] = operand_subword (operands[1], 0, 0, DFmode);
! })
  
  (define_split
    [(set (match_operand:DF 0 "register_operand" "")
          (match_operand:DF 1 "memory_operand" ""))]
    "!TARGET_64BIT && reload_completed
     && !FP_REG_P (operands[0])
     && !s_operand (operands[1], VOIDmode)"
    [(set (match_dup 0) (match_dup 1))]
  {
    rtx addr = operand_subword (operands[0], 1, 0, DFmode);
    s390_load_address (addr, XEXP (operands[1], 0));
    operands[1] = replace_equiv_address (operands[1], addr);
! })
! 
! (define_expand "reload_outdf"
!   [(parallel [(match_operand:DF 0 "memory_operand" "")
!               (match_operand:DF 1 "register_operand" "d")
!               (match_operand:SI 2 "register_operand" "=&a")])]
!   "!TARGET_64BIT"
! {
!   s390_load_address (operands[2], XEXP (operands[0], 0));
!   operands[0] = replace_equiv_address (operands[0], operands[2]);
!   emit_move_insn (operands[0], operands[1]);
!   DONE;
! })
  
  ;
  ; movsf instruction pattern(s).
*** /dev/null	Fri Mar 21 22:49:39 2003
--- gcc/testsuite/gcc.dg/20030627-1.c	Fri Jun 27 21:32:22 2003
***************
*** 0 ****
--- 1,20 ----
+ /* This tests whether non-offsettable memory operands are reloaded 
+    correctly in certain corner cases on s390 targets.  */
+ /* { dg-do compile } */
+ /* { dg-options "-std=gnu89" } */
+ 
+ void test_inout (char *bd, int xd, char *bs, int xs)
+ {
+   *(long long *)(bd + xd + 4093) = *(long long *)(bs + xs + 4093);
+ }
+ 
+ void test_in (char *bd, int xd, char *bs, int xs)
+ {
+   *(long long *)(bd + xd) = *(long long *)(bs + xs + 4093);
+ }
+ 
+ void test_out (char *bd, int xd, char *bs, int xs)
+ {
+   *(long long *)(bd + xd + 4093) = *(long long *)(bs + xs);
+ }
+ 

-- 
  Dr. Ulrich Weigand
  weigand@informatik.uni-erlangen.de



More information about the Gcc-patches mailing list