This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC][PATCH] Support multiple variants of memory addresses


Richard Henderson wrote:
>Looks ok to me.

Great!  I've now committed the patch, together with a s390 backend patch
that starts making use of the new features.  At this point, the use is
rather minimal; mostly the ugly (and strictly speaking, incorrect) 'Qo'
constraint combinations we had to use can now be replaced by just 'Q'.

Backend patches making more extensive use of EXTRA_MEMORY_CONSTRAINT
and EXTRA_ADDRESS_CONSTRAINT will follow.

For reference, I've appended the complete patch I've committed, including
the parts I had already posted.  With this patch applied, I've successfully
completed bootstrap and regression tests (and glibc build / test) on both
s390-ibm-linux and s390x-ibm-linux.


ChangeLog:

      * reload.c (find_reloads): Handle constraint letters marked by
      EXTRA_ADDRESS_CONSTRAINT and EXTRA_MEMORY_CONSTRAINT.
      (alternative_allows_memconst): Likewise.
      * reload1.c (maybe_fix_stack_asms): Likewise.
      * recog.c (asm_operand_ok, preprocess_constraints,
      constrain_operands): Likewise.
      * regclass.c (record_operand_costs, record_reg_classes): Likewise.
      * local-alloc.c (block_alloc, requires_inout): Likewise.
      * stmt.c (parse_output_constraint, parse_input_constraint): Likewise.

      * defaults.h (EXTRA_MEMORY_CONSTRAINT): Provide a default.
      (EXTRA_ADDRESS_CONSTRAINT): Likewise.
      * doc/tm.texi: Document these two new target macros.

      * config/s390/s390.c (s390_expand_plus_operand): Accept already
      valid operands.
      (q_constraint): New function.
      config/s390/s390-protos.h (q_constraint): Declare it.
      config/s390/s390.h (EXTRA_CONSTRAINT): Use it.
      (EXTRA_MEMORY_CONSTRAINT): New macro.

      * config/s390/s390.md: Throughout the machine description,
      replace all instances of the constraint combinations 'Qo'
      or 'oQ' with simply 'Q'.

Index: gcc/defaults.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/defaults.h,v
retrieving revision 1.87
diff -c -p -r1.87 defaults.h
*** gcc/defaults.h      31 Jul 2002 02:10:04 -0000    1.87
--- gcc/defaults.h      14 Aug 2002 09:46:02 -0000
*************** You Lose!  You must define PREFERRED_DEB
*** 590,593 ****
--- 590,605 ----
  #define DEFAULT_USE_CXA_ATEXIT 0
  #endif

+ /* Determine whether extra constraint letter should be handled
+    via address reload (like 'o').  */
+ #ifndef EXTRA_MEMORY_CONSTRAINT
+ #define EXTRA_MEMORY_CONSTRAINT(C) 0
+ #endif
+
+ /* Determine whether extra constraint letter should be handled
+    as an address (like 'p').  */
+ #ifndef EXTRA_ADDRESS_CONSTRAINT
+ #define EXTRA_ADDRESS_CONSTRAINT(C) 0
+ #endif
+
  #endif  /* ! GCC_DEFAULTS_H */
Index: gcc/local-alloc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/local-alloc.c,v
retrieving revision 1.109
diff -c -p -r1.109 local-alloc.c
*** gcc/local-alloc.c   30 May 2002 20:55:09 -0000    1.109
--- gcc/local-alloc.c   14 Aug 2002 09:46:04 -0000
*************** block_alloc (b)
*** 1342,1348 ****
              /* If the operand is an address, find a register in it.
                 There may be more than one register, but we only try one
                 of them.  */
!             if (recog_data.constraints[i][0] == 'p')
                while (GET_CODE (r1) == PLUS || GET_CODE (r1) == MULT)
                  r1 = XEXP (r1, 0);

--- 1342,1349 ----
              /* If the operand is an address, find a register in it.
                 There may be more than one register, but we only try one
                 of them.  */
!             if (recog_data.constraints[i][0] == 'p'
!                 || EXTRA_ADDRESS_CONSTRAINT (recog_data.constraints[i][0]))
                while (GET_CODE (r1) == PLUS || GET_CODE (r1) == MULT)
                  r1 = XEXP (r1, 0);

*************** requires_inout (p)
*** 2472,2478 ****
      break;

        default:
!     if (REG_CLASS_FROM_LETTER (c) == NO_REGS)
        break;
      /* FALLTHRU */
        case 'p':
--- 2473,2480 ----
      break;

        default:
!     if (REG_CLASS_FROM_LETTER (c) == NO_REGS
!         && !EXTRA_ADDRESS_CONSTRAINT (c))
        break;
      /* FALLTHRU */
        case 'p':
Index: gcc/recog.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/recog.c,v
retrieving revision 1.162
diff -c -p -r1.162 recog.c
*** gcc/recog.c   23 Jul 2002 20:50:59 -0000    1.162
--- gcc/recog.c   14 Aug 2002 09:46:06 -0000
*************** asm_operand_ok (op, constraint)
*** 1848,1853 ****
--- 1848,1865 ----
  #ifdef EXTRA_CONSTRAINT
        if (EXTRA_CONSTRAINT (op, c))
          return 1;
+       if (EXTRA_MEMORY_CONSTRAINT (c))
+         {
+           /* Every memory operand can be reloaded to fit.  */
+           if (memory_operand (op, VOIDmode))
+             return 1;
+         }
+       if (EXTRA_ADDRESS_CONSTRAINT (c))
+         {
+           /* Every address operand can be reloaded to fit.  */
+           if (address_operand (op, VOIDmode))
+             return 1;
+         }
  #endif
        break;
      }
*************** preprocess_constraints ()
*** 2287,2292 ****
--- 2299,2317 ----
              break;

            default:
+             if (EXTRA_MEMORY_CONSTRAINT (c))
+               {
+                 op_alt[j].memory_ok = 1;
+                 break;
+               }
+             if (EXTRA_ADDRESS_CONSTRAINT (c))
+               {
+                 op_alt[j].is_address = 1;
+                 op_alt[j].class = reg_class_subunion[(int) op_alt[j].class]
+                   [(int) MODE_BASE_REG_CLASS (VOIDmode)];
+                 break;
+               }
+
              op_alt[j].class = reg_class_subunion[(int) op_alt[j].class][(int) REG_CLASS_FROM_LETTER ((unsigned char) c)];
              break;
            }
*************** constrain_operands (strict)
*** 2600,2605 ****
--- 2625,2652 ----
  #ifdef EXTRA_CONSTRAINT
              else if (EXTRA_CONSTRAINT (op, c))
                win = 1;
+
+             if (EXTRA_MEMORY_CONSTRAINT (c))
+               {
+                 /* Every memory operand can be reloaded to fit,
+                  so copy the condition from the 'm' case.  */
+                 if (GET_CODE (op) == MEM
+                     /* Before reload, accept what reload can turn into mem.  */
+                     || (strict < 0 && CONSTANT_P (op))
+                     /* During reload, accept a pseudo  */
+                     || (reload_in_progress && GET_CODE (op) == REG
+                       && REGNO (op) >= FIRST_PSEUDO_REGISTER))
+                 win = 1;
+               }
+             if (EXTRA_ADDRESS_CONSTRAINT (c))
+               {
+                 /* Every address operand can be reloaded to fit,
+                  so copy the condition from the 'p' case.  */
+                 if (strict <= 0
+                     || (strict_memory_address_p (recog_data.operand_mode[opno],
+                                          op)))
+                   win = 1;
+               }
  #endif
              break;
            }
Index: gcc/regclass.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/regclass.c,v
retrieving revision 1.154
diff -c -p -r1.154 regclass.c
*** gcc/regclass.c      23 Jul 2002 20:50:59 -0000    1.154
--- gcc/regclass.c      14 Aug 2002 09:46:11 -0000
*************** record_operand_costs (insn, op_costs, re
*** 1007,1013 ****
        if (GET_CODE (recog_data.operand[i]) == MEM)
      record_address_regs (XEXP (recog_data.operand[i], 0),
                       MODE_BASE_REG_CLASS (modes[i]), frequency * 2);
!       else if (constraints[i][0] == 'p')
      record_address_regs (recog_data.operand[i],
                       MODE_BASE_REG_CLASS (modes[i]), frequency * 2);
      }
--- 1007,1014 ----
        if (GET_CODE (recog_data.operand[i]) == MEM)
      record_address_regs (XEXP (recog_data.operand[i], 0),
                       MODE_BASE_REG_CLASS (modes[i]), frequency * 2);
!       else if (constraints[i][0] == 'p'
!            || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0]))
      record_address_regs (recog_data.operand[i],
                       MODE_BASE_REG_CLASS (modes[i]), frequency * 2);
      }
*************** record_reg_classes (n_alts, n_ops, ops,
*** 1709,1714 ****
--- 1710,1736 ----
  #ifdef EXTRA_CONSTRAINT
            else if (EXTRA_CONSTRAINT (op, c))
              win = 1;
+
+           if (EXTRA_MEMORY_CONSTRAINT (c))
+             {
+               /* Every MEM can be reloaded to fit.  */
+               allows_mem[i] = 1;
+               if (GET_CODE (op) == MEM)
+                 win = 1;
+             }
+           if (EXTRA_ADDRESS_CONSTRAINT (op))
+             {
+               /* Every address can be reloaded to fit.  */
+               allows_addr = 1;
+               if (address_operand (op, GET_MODE (op)))
+                 win = 1;
+               /* We know this operand is an address, so we want it to be
+                  allocated to a register that can be the base of an
+                  address, ie BASE_REG_CLASS.  */
+               classes[i]
+                 = reg_class_subunion[(int) classes[i]]
+                   [(int) MODE_BASE_REG_CLASS (VOIDmode)];
+             }
  #endif
            break;
            }
Index: gcc/reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.187
diff -c -p -r1.187 reload.c
*** gcc/reload.c  23 Jul 2002 20:51:00 -0000    1.187
--- gcc/reload.c  14 Aug 2002 09:46:17 -0000
*************** find_reloads (insn, replace, ind_levels,
*** 2641,2647 ****
        if (*constraints[i] == 0)
      /* Ignore things like match_operator operands.  */
      ;
!       else if (constraints[i][0] == 'p')
      {
        find_reloads_address (VOIDmode, (rtx*) 0,
                        recog_data.operand[i],
--- 2641,2648 ----
        if (*constraints[i] == 0)
      /* Ignore things like match_operator operands.  */
      ;
!       else if (constraints[i][0] == 'p'
!            || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0]))
      {
        find_reloads_address (VOIDmode, (rtx*) 0,
                        recog_data.operand[i],
*************** find_reloads (insn, replace, ind_levels,
*** 3222,3227 ****
--- 3223,3271 ----
            if (REG_CLASS_FROM_LETTER (c) == NO_REGS)
              {
  #ifdef EXTRA_CONSTRAINT
+               if (EXTRA_MEMORY_CONSTRAINT (c))
+                 {
+                 if (force_reload)
+                   break;
+                   if (EXTRA_CONSTRAINT (operand, c))
+                     win = 1;
+                 /* If the address was already reloaded,
+                    we win as well.  */
+                 if (GET_CODE (operand) == MEM && address_reloaded[i])
+                   win = 1;
+                 /* Likewise if the address will be reloaded because
+                    reg_equiv_address is nonzero.  For reg_equiv_mem
+                    we have to check.  */
+                   if (GET_CODE (operand) == REG
+                     && REGNO (operand) >= FIRST_PSEUDO_REGISTER
+                     && reg_renumber[REGNO (operand)] < 0
+                     && ((reg_equiv_mem[REGNO (operand)] != 0
+                          && EXTRA_CONSTRAINT (reg_equiv_mem[REGNO (operand)], c))
+                         || (reg_equiv_address[REGNO (operand)] != 0)))
+                   win = 1;
+
+                 /* If we didn't already win, we can reload
+                    constants via force_const_mem, and other
+                    MEMs by reloading the address like for 'o'.  */
+                 if ((CONSTANT_P (operand) && GET_CODE (operand) != HIGH)
+                     || GET_CODE (operand) == MEM)
+                   badop = 0;
+                 constmemok = 1;
+                 offmemok = 1;
+                 break;
+                 }
+               if (EXTRA_ADDRESS_CONSTRAINT (c))
+                 {
+                   if (EXTRA_CONSTRAINT (operand, c))
+                     win = 1;
+
+                 /* If we didn't already win, we can reload
+                    the address into a base register.  */
+                 this_alternative[i] = (int) MODE_BASE_REG_CLASS (VOIDmode);
+                 badop = 0;
+                 break;
+                 }
+
                if (EXTRA_CONSTRAINT (operand, c))
                  win = 1;
  #endif
*************** alternative_allows_memconst (constraint,
*** 4291,4297 ****
    /* Scan the requested alternative for 'm' or 'o'.
       If one of them is present, this alternative accepts memory constants.  */
    while ((c = *constraint++) && c != ',' && c != '#')
!     if (c == 'm' || c == 'o')
        return 1;
    return 0;
  }
--- 4335,4341 ----
    /* Scan the requested alternative for 'm' or 'o'.
       If one of them is present, this alternative accepts memory constants.  */
    while ((c = *constraint++) && c != ',' && c != '#')
!     if (c == 'm' || c == 'o' || EXTRA_MEMORY_CONSTRAINT (c))
        return 1;
    return 0;
  }
Index: gcc/reload1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.351
diff -c -p -r1.351 reload1.c
*** gcc/reload1.c 30 Jul 2002 16:42:05 -0000    1.351
--- gcc/reload1.c 14 Aug 2002 09:46:21 -0000
*************** maybe_fix_stack_asms ()
*** 1380,1387 ****
              break;

            default:
!             cls = (int) reg_class_subunion[cls][(int) REG_CLASS_FROM_LETTER (c)];
!
            }
          }
      }
--- 1380,1391 ----
              break;

            default:
!             if (EXTRA_ADDRESS_CONSTRAINT (c))
!               cls = (int) reg_class_subunion[cls]
!                 [(int) MODE_BASE_REG_CLASS (VOIDmode)];
!             else
!               cls = (int) reg_class_subunion[cls]
!                 [(int) REG_CLASS_FROM_LETTER (c)];
            }
          }
      }
Index: gcc/stmt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stmt.c,v
retrieving revision 1.268
diff -c -p -r1.268 stmt.c
*** gcc/stmt.c    5 Aug 2002 18:46:33 -0000     1.268
--- gcc/stmt.c    14 Aug 2002 09:46:26 -0000
*************** parse_output_constraint (constraint_p, o
*** 1252,1257 ****
--- 1252,1261 ----
      if (REG_CLASS_FROM_LETTER (*p) != NO_REGS)
        *allows_reg = true;
  #ifdef EXTRA_CONSTRAINT
+     else if (EXTRA_ADDRESS_CONSTRAINT (*p))
+       *allows_reg = true;
+     else if (EXTRA_MEMORY_CONSTRAINT (*p))
+       *allows_mem = true;
      else
        {
          /* Otherwise we can't assume anything about the nature of
*************** parse_input_constraint (constraint_p, in
*** 1377,1382 ****
--- 1381,1390 ----
      if (REG_CLASS_FROM_LETTER (constraint[j]) != NO_REGS)
        *allows_reg = true;
  #ifdef EXTRA_CONSTRAINT
+     else if (EXTRA_ADDRESS_CONSTRAINT (constraint[j]))
+       *allows_reg = true;
+     else if (EXTRA_MEMORY_CONSTRAINT (constraint[j]))
+       *allows_mem = true;
      else
        {
          /* Otherwise we can't assume anything about the nature of
Index: gcc/config/s390/s390-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390-protos.h,v
retrieving revision 1.10
diff -c -p -r1.10 s390-protos.h
*** gcc/config/s390/s390-protos.h   13 Aug 2002 16:02:52 -0000    1.10
--- gcc/config/s390/s390-protos.h   14 Aug 2002 09:46:28 -0000
*************** extern void s390_emit_epilogue PARAMS ((
*** 31,36 ****
--- 31,37 ----
  extern void s390_function_profiler PARAMS ((FILE *, int));

  #ifdef RTX_CODE
+ extern int q_constraint PARAMS ((rtx));
  extern int const0_operand PARAMS ((rtx, enum machine_mode));
  extern int consttable_operand PARAMS ((rtx, enum machine_mode));
  extern int larl_operand PARAMS ((rtx, enum machine_mode));
Index: gcc/config/s390/s390.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.c,v
retrieving revision 1.45
diff -c -p -r1.45 s390.c
*** gcc/config/s390/s390.c    13 Aug 2002 16:02:52 -0000    1.45
--- gcc/config/s390/s390.c    14 Aug 2002 09:46:30 -0000
*************** s_imm_operand (op, mode)
*** 995,1000 ****
--- 995,1022 ----
    return general_s_operand (op, mode, 1);
  }

+ /* Return true if OP is a valid operand for a 'Q' constraint.
+    This differs from s_operand in that only memory operands
+    without index register are accepted, nothing else.  */
+
+ int
+ q_constraint (op)
+      register rtx op;
+ {
+   struct s390_address addr;
+
+   if (GET_CODE (op) != MEM)
+     return 0;
+
+   if (!s390_decompose_address (XEXP (op, 0), &addr, FALSE))
+     return 0;
+
+   if (addr.indx)
+     return 0;
+
+   return 1;
+ }
+
  /* Return true if OP is a valid operand for the BRAS instruction.
     OP is the current operation.
     MODE is the current operation mode.  */
*************** s390_expand_plus_operand (target, src, s
*** 1385,1390 ****
--- 1407,1421 ----
       float registers occur in an address.  */
    sum1 = find_replacement (&XEXP (src, 0));
    sum2 = find_replacement (&XEXP (src, 1));
+
+   /* Accept already valid addresses.  */
+   src = gen_rtx_PLUS (Pmode, sum1, sum2);
+   if (s390_decompose_address (src, NULL, 1))
+     {
+       src = legitimize_la_operand (src);
+       emit_insn (gen_rtx_SET (VOIDmode, target, src));
+       return;
+     }

    /* If one of the two operands is equal to the target,
       make it the first one.  If one is a constant, make
Index: gcc/config/s390/s390.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.h,v
retrieving revision 1.39
diff -c -p -r1.39 s390.h
*** gcc/config/s390/s390.h    16 Jul 2002 20:59:04 -0000    1.39
--- gcc/config/s390/s390.h    14 Aug 2002 09:46:31 -0000
*************** extern const enum reg_class regclass_map
*** 533,540 ****
  /* 'Q' means a memory-reference for a S-type operand.  */

  #define EXTRA_CONSTRAINT(OP, C)                                 \
!      ((C) == 'Q' ?  s_operand (OP, GET_MODE (OP)) :             \
        (C) == 'S' ?  larl_operand (OP, GET_MODE (OP)) : 0)

  /* Given an rtx X being reloaded into a reg required to be in class CLASS,
     return the class of reg to actually use.  In general this is just CLASS;
--- 533,542 ----
  /* 'Q' means a memory-reference for a S-type operand.  */

  #define EXTRA_CONSTRAINT(OP, C)                                 \
!      ((C) == 'Q' ?  q_constraint (OP) :                   \
        (C) == 'S' ?  larl_operand (OP, GET_MODE (OP)) : 0)
+
+ #define EXTRA_MEMORY_CONSTRAINT(C) ((C) == 'Q')

  /* Given an rtx X being reloaded into a reg required to be in class CLASS,
     return the class of reg to actually use.  In general this is just CLASS;
Index: gcc/config/s390/s390.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/s390/s390.md,v
retrieving revision 1.23
diff -c -p -r1.23 s390.md
*** gcc/config/s390/s390.md   13 Aug 2002 16:02:52 -0000    1.23
--- gcc/config/s390/s390.md   14 Aug 2002 09:46:36 -0000
***************
*** 278,284 ****

  (define_insn "*tmqi_ext"
    [(set (reg 33)
!         (compare (zero_extract:SI (match_operand:QI 0 "s_operand" "Qo")
                                (match_operand:SI 1 "const_int_operand" "n")
                                    (match_operand:SI 2 "const_int_operand" "n"))
                   (const_int 0)))]
--- 278,284 ----

  (define_insn "*tmqi_ext"
    [(set (reg 33)
!         (compare (zero_extract:SI (match_operand:QI 0 "s_operand" "Q")
                                (match_operand:SI 1 "const_int_operand" "n")
                                    (match_operand:SI 2 "const_int_operand" "n"))
                   (const_int 0)))]
***************
*** 345,351 ****

  (define_insn "*tmdi_mem"
    [(set (reg 33)
!         (compare (and:DI (match_operand:DI 0 "s_operand" "%Qo")
                           (match_operand:DI 1 "immediate_operand" "n"))
                   (match_operand:DI 2 "immediate_operand" "n")))]
    "TARGET_64BIT
--- 345,351 ----

  (define_insn "*tmdi_mem"
    [(set (reg 33)
!         (compare (and:DI (match_operand:DI 0 "s_operand" "%Q")
                           (match_operand:DI 1 "immediate_operand" "n"))
                   (match_operand:DI 2 "immediate_operand" "n")))]
    "TARGET_64BIT
***************
*** 365,371 ****

  (define_insn "*tmsi_mem"
    [(set (reg 33)
!         (compare (and:SI (match_operand:SI 0 "s_operand" "%Qo")
                           (match_operand:SI 1 "immediate_operand" "n"))
                   (match_operand:SI 2 "immediate_operand" "n")))]
    "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
--- 365,371 ----

  (define_insn "*tmsi_mem"
    [(set (reg 33)
!         (compare (and:SI (match_operand:SI 0 "s_operand" "%Q")
                           (match_operand:SI 1 "immediate_operand" "n"))
                   (match_operand:SI 2 "immediate_operand" "n")))]
    "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
***************
*** 384,390 ****

  (define_insn "*tmhi_mem"
    [(set (reg 33)
!         (compare (and:SI (subreg:SI (match_operand:HI 0 "s_operand" "%Qo") 0)
                           (match_operand:SI 1 "immediate_operand" "n"))
                   (match_operand:SI 2 "immediate_operand" "n")))]
    "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
--- 384,390 ----

  (define_insn "*tmhi_mem"
    [(set (reg 33)
!         (compare (and:SI (subreg:SI (match_operand:HI 0 "s_operand" "%Q") 0)
                           (match_operand:SI 1 "immediate_operand" "n"))
                   (match_operand:SI 2 "immediate_operand" "n")))]
    "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))
***************
*** 403,409 ****

  (define_insn "*tmqi_mem"
    [(set (reg 33)
!         (compare (and:SI (subreg:SI (match_operand:QI 0 "s_operand" "%Qo") 0)
                           (match_operand:SI 1 "immediate_operand" "n"))
                   (match_operand:SI 2 "immediate_operand" "n")))]
    "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))"
--- 403,409 ----

  (define_insn "*tmqi_mem"
    [(set (reg 33)
!         (compare (and:SI (subreg:SI (match_operand:QI 0 "s_operand" "%Q") 0)
                           (match_operand:SI 1 "immediate_operand" "n"))
                   (match_operand:SI 2 "immediate_operand" "n")))]
    "s390_match_ccmode (insn, s390_tm_ccmode (operands[1], operands[2], 0))"
***************
*** 502,508 ****

  (define_insn "*tsthi"
    [(set (reg 33)
!         (compare (match_operand:HI 0 "s_operand" "Qo")
                   (match_operand:HI 1 "const0_operand" "")))
     (set (match_operand:HI 2 "register_operand" "=d")
          (match_dup 0))]
--- 502,508 ----

  (define_insn "*tsthi"
    [(set (reg 33)
!         (compare (match_operand:HI 0 "s_operand" "Q")
                   (match_operand:HI 1 "const0_operand" "")))
     (set (match_operand:HI 2 "register_operand" "=d")
          (match_dup 0))]
***************
*** 513,519 ****

  (define_insn "*tsthi_cconly"
    [(set (reg 33)
!         (compare (match_operand:HI 0 "s_operand" "Qo")
                   (match_operand:HI 1 "const0_operand" "")))
     (clobber (match_scratch:HI 2 "=d"))]
    "s390_match_ccmode(insn, CCSmode)"
--- 513,519 ----

  (define_insn "*tsthi_cconly"
    [(set (reg 33)
!         (compare (match_operand:HI 0 "s_operand" "Q")
                   (match_operand:HI 1 "const0_operand" "")))
     (clobber (match_scratch:HI 2 "=d"))]
    "s390_match_ccmode(insn, CCSmode)"
***************
*** 523,529 ****

  (define_insn "*tstqi"
    [(set (reg 33)
!         (compare (match_operand:QI 0 "s_operand" "Qo")
                   (match_operand:QI 1 "const0_operand" "")))
     (set (match_operand:QI 2 "register_operand" "=d")
          (match_dup 0))]
--- 523,529 ----

  (define_insn "*tstqi"
    [(set (reg 33)
!         (compare (match_operand:QI 0 "s_operand" "Q")
                   (match_operand:QI 1 "const0_operand" "")))
     (set (match_operand:QI 2 "register_operand" "=d")
          (match_dup 0))]
***************
*** 534,540 ****

  (define_insn "*tstqi_cconly"
    [(set (reg 33)
!         (compare (match_operand:QI 0 "s_operand" "Qo")
                   (match_operand:QI 1 "const0_operand" "")))
     (clobber (match_scratch:QI 2 "=d"))]
    "s390_match_ccmode(insn, CCSmode)"
--- 534,540 ----

  (define_insn "*tstqi_cconly"
    [(set (reg 33)
!         (compare (match_operand:QI 0 "s_operand" "Q")
                   (match_operand:QI 1 "const0_operand" "")))
     (clobber (match_scratch:QI 2 "=d"))]
    "s390_match_ccmode(insn, CCSmode)"
***************
*** 628,634 ****
  (define_insn "*cmphi_ccu"
    [(set (reg 33)
          (compare (match_operand:HI 0 "register_operand" "d")
!                  (match_operand:HI 1 "s_imm_operand" "Qo")))]
    "s390_match_ccmode(insn, CCUmode)"
    "clm\\t%0,3,%1"
    [(set_attr "op_type" "RS")
--- 628,634 ----
  (define_insn "*cmphi_ccu"
    [(set (reg 33)
          (compare (match_operand:HI 0 "register_operand" "d")
!                  (match_operand:HI 1 "s_imm_operand" "Q")))]
    "s390_match_ccmode(insn, CCUmode)"
    "clm\\t%0,3,%1"
    [(set_attr "op_type" "RS")
***************
*** 637,643 ****
  (define_insn "*cmpqi_ccu"
    [(set (reg 33)
          (compare (match_operand:QI 0 "register_operand" "d")
!                  (match_operand:QI 1 "s_imm_operand" "Qo")))]
    "s390_match_ccmode(insn, CCUmode)"
    "clm\\t%0,1,%1"
    [(set_attr "op_type" "RS")
--- 637,643 ----
  (define_insn "*cmpqi_ccu"
    [(set (reg 33)
          (compare (match_operand:QI 0 "register_operand" "d")
!                  (match_operand:QI 1 "s_imm_operand" "Q")))]
    "s390_match_ccmode(insn, CCUmode)"
    "clm\\t%0,1,%1"
    [(set_attr "op_type" "RS")
***************
*** 645,651 ****

  (define_insn "*cli"
    [(set (reg 33)
!         (compare (match_operand:QI 0 "s_operand" "Qo")
                   (match_operand:QI 1 "immediate_operand" "n")))]
    "s390_match_ccmode (insn, CCUmode)"
    "cli\\t%0,%b1"
--- 645,651 ----

  (define_insn "*cli"
    [(set (reg 33)
!         (compare (match_operand:QI 0 "s_operand" "Q")
                   (match_operand:QI 1 "immediate_operand" "n")))]
    "s390_match_ccmode (insn, CCUmode)"
    "cli\\t%0,%b1"
***************
*** 654,661 ****

  (define_insn "*cmpdi_ccu_mem"
    [(set (reg 33)
!         (compare (match_operand:DI 0 "s_operand" "oQ")
!                  (match_operand:DI 1 "s_imm_operand" "oQ")))]
    "s390_match_ccmode(insn, CCUmode)"
    "clc\\t%O0(8,%R0),%1"
    [(set_attr "op_type" "SS")
--- 654,661 ----

  (define_insn "*cmpdi_ccu_mem"
    [(set (reg 33)
!         (compare (match_operand:DI 0 "s_operand" "Q")
!                  (match_operand:DI 1 "s_imm_operand" "Q")))]
    "s390_match_ccmode(insn, CCUmode)"
    "clc\\t%O0(8,%R0),%1"
    [(set_attr "op_type" "SS")
***************
*** 663,670 ****

  (define_insn "*cmpsi_ccu_mem"
    [(set (reg 33)
!         (compare (match_operand:SI 0 "s_operand" "oQ")
!                  (match_operand:SI 1 "s_imm_operand" "oQ")))]
    "s390_match_ccmode(insn, CCUmode)"
    "clc\\t%O0(4,%R0),%1"
     [(set_attr "op_type" "SS")
--- 663,670 ----

  (define_insn "*cmpsi_ccu_mem"
    [(set (reg 33)
!         (compare (match_operand:SI 0 "s_operand" "Q")
!                  (match_operand:SI 1 "s_imm_operand" "Q")))]
    "s390_match_ccmode(insn, CCUmode)"
    "clc\\t%O0(4,%R0),%1"
     [(set_attr "op_type" "SS")
***************
*** 672,679 ****

  (define_insn "*cmphi_ccu_mem"
    [(set (reg 33)
!         (compare (match_operand:HI 0 "s_operand" "oQ")
!                  (match_operand:HI 1 "s_imm_operand" "oQ")))]
    "s390_match_ccmode(insn, CCUmode)"
    "clc\\t%O0(2,%R0),%1"
    [(set_attr "op_type" "SS")
--- 672,679 ----

  (define_insn "*cmphi_ccu_mem"
    [(set (reg 33)
!         (compare (match_operand:HI 0 "s_operand" "Q")
!                  (match_operand:HI 1 "s_imm_operand" "Q")))]
    "s390_match_ccmode(insn, CCUmode)"
    "clc\\t%O0(2,%R0),%1"
    [(set_attr "op_type" "SS")
***************
*** 681,688 ****

  (define_insn "*cmpqi_ccu_mem"
    [(set (reg 33)
!         (compare (match_operand:QI 0 "s_operand" "oQ")
!                  (match_operand:QI 1 "s_imm_operand" "oQ")))]
    "s390_match_ccmode(insn, CCUmode)"
    "clc\\t%O0(1,%R0),%1"
    [(set_attr "op_type" "SS")
--- 681,688 ----

  (define_insn "*cmpqi_ccu_mem"
    [(set (reg 33)
!         (compare (match_operand:QI 0 "s_operand" "Q")
!                  (match_operand:QI 1 "s_imm_operand" "Q")))]
    "s390_match_ccmode(insn, CCUmode)"
    "clc\\t%O0(1,%R0),%1"
    [(set_attr "op_type" "SS")
***************
*** 780,787 ****
  ;

  (define_insn "*movti_ss"
!   [(set (match_operand:TI 0 "s_operand" "=Qo")
!         (match_operand:TI 1 "s_imm_operand" "Qo"))]
    ""
    "mvc\\t%O0(16,%R0),%1"
    [(set_attr "op_type" "SS")
--- 780,787 ----
  ;

  (define_insn "*movti_ss"
!   [(set (match_operand:TI 0 "s_operand" "=Q")
!         (match_operand:TI 1 "s_imm_operand" "Q"))]
    ""
    "mvc\\t%O0(16,%R0),%1"
    [(set_attr "op_type" "SS")
***************
*** 914,921 ****
      (set_attr "type"    "la")])

  (define_insn "*movdi_ss"
!   [(set (match_operand:DI 0 "s_operand" "=Qo")
!         (match_operand:DI 1 "s_imm_operand" "Qo"))]
    ""
    "mvc\\t%O0(8,%R0),%1"
    [(set_attr "op_type" "SS")
--- 914,921 ----
      (set_attr "type"    "la")])

  (define_insn "*movdi_ss"
!   [(set (match_operand:DI 0 "s_operand" "=Q")
!         (match_operand:DI 1 "s_imm_operand" "Q"))]
    ""
    "mvc\\t%O0(8,%R0),%1"
    [(set_attr "op_type" "SS")
***************
*** 1067,1074 ****
    [(set_attr "op_type" "RI")])

  (define_insn "*movsi_ss"
!   [(set (match_operand:SI 0 "s_operand" "=Qo")
!         (match_operand:SI 1 "s_imm_operand" "Qo"))]
    ""
    "mvc\\t%O0(4,%R0),%1"
    [(set_attr "op_type" "SS")
--- 1067,1074 ----
    [(set_attr "op_type" "RI")])

  (define_insn "*movsi_ss"
!   [(set (match_operand:SI 0 "s_operand" "=Q")
!         (match_operand:SI 1 "s_imm_operand" "Q"))]
    ""
    "mvc\\t%O0(4,%R0),%1"
    [(set_attr "op_type" "SS")
***************
*** 1156,1162 ****

  (define_insn "*movstricthi"
    [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
!                          (match_operand:HI 1 "s_imm_operand" "Qo"))
     (clobber (reg:CC 33))]
    ""
    "icm\\t%0,3,%1"
--- 1156,1162 ----

  (define_insn "*movstricthi"
    [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
!                          (match_operand:HI 1 "s_imm_operand" "Q"))
     (clobber (reg:CC 33))]
    ""
    "icm\\t%0,3,%1"
***************
*** 1197,1204 ****
  }")

  (define_insn "*movdf_ss"
!   [(set (match_operand:DF 0 "s_operand" "=Qo")
!         (match_operand:DF 1 "s_imm_operand" "Qo"))]
    ""
    "mvc\\t%O0(8,%R0),%1"
    [(set_attr "op_type" "SS")
--- 1197,1204 ----
  }")

  (define_insn "*movdf_ss"
!   [(set (match_operand:DF 0 "s_operand" "=Q")
!         (match_operand:DF 1 "s_imm_operand" "Q"))]
    ""
    "mvc\\t%O0(8,%R0),%1"
    [(set_attr "op_type" "SS")
***************
*** 1300,1307 ****
  }")

  (define_insn "*movsf_ss"
!   [(set (match_operand:SF 0 "s_operand" "=Qo")
!         (match_operand:SF 1 "s_imm_operand" "Qo"))]
    ""
    "mvc\\t%O0(4,%R0),%1"
    [(set_attr "op_type" "SS")
--- 1300,1307 ----
  }")

  (define_insn "*movsf_ss"
!   [(set (match_operand:SF 0 "s_operand" "=Q")
!         (match_operand:SF 1 "s_imm_operand" "Q"))]
    ""
    "mvc\\t%O0(4,%R0),%1"
    [(set_attr "op_type" "SS")
***************
*** 1388,1394 ****
  (define_insn "*load_multiple_di"
    [(match_parallel 0 "load_multiple_operation"
               [(set (match_operand:DI 1 "register_operand" "=r")
!                  (match_operand:DI 2 "s_operand" "oQ"))])]
    ""
    "*
  {
--- 1388,1394 ----
  (define_insn "*load_multiple_di"
    [(match_parallel 0 "load_multiple_operation"
               [(set (match_operand:DI 1 "register_operand" "=r")
!                  (match_operand:DI 2 "s_operand" "Q"))])]
    ""
    "*
  {
***************
*** 1407,1413 ****
  (define_insn "*load_multiple_si"
    [(match_parallel 0 "load_multiple_operation"
               [(set (match_operand:SI 1 "register_operand" "=r")
!                  (match_operand:SI 2 "s_operand" "oQ"))])]
    ""
    "*
  {
--- 1407,1413 ----
  (define_insn "*load_multiple_si"
    [(match_parallel 0 "load_multiple_operation"
               [(set (match_operand:SI 1 "register_operand" "=r")
!                  (match_operand:SI 2 "s_operand" "Q"))])]
    ""
    "*
  {
***************
*** 1491,1497 ****

  (define_insn "*store_multiple_di"
    [(match_parallel 0 "store_multiple_operation"
!              [(set (match_operand:DI 1 "s_operand" "=oQ")
                   (match_operand:DI 2 "register_operand" "r"))])]
    ""
    "*
--- 1491,1497 ----

  (define_insn "*store_multiple_di"
    [(match_parallel 0 "store_multiple_operation"
!              [(set (match_operand:DI 1 "s_operand" "=Q")
                   (match_operand:DI 2 "register_operand" "r"))])]
    ""
    "*
***************
*** 1511,1517 ****

  (define_insn "*store_multiple_si"
    [(match_parallel 0 "store_multiple_operation"
!              [(set (match_operand:SI 1 "s_operand" "=oQ")
                   (match_operand:SI 2 "register_operand" "r"))])]
    ""
    "*
--- 1511,1517 ----

  (define_insn "*store_multiple_si"
    [(match_parallel 0 "store_multiple_operation"
!              [(set (match_operand:SI 1 "s_operand" "=Q")
                   (match_operand:SI 2 "register_operand" "r"))])]
    ""
    "*
***************
*** 1697,1704 ****
  ; The block length is taken as (operands[2] % 256) + 1.

  (define_insn "movstrdi_short"
!   [(set (match_operand:BLK 0 "s_operand" "=oQ,oQ")
!         (match_operand:BLK 1 "s_operand" "oQ,oQ"))
     (use (match_operand:DI 2 "nonmemory_operand" "n,a"))
     (clobber (match_scratch:DI 3 "=X,&a"))]
    "TARGET_64BIT"
--- 1697,1704 ----
  ; The block length is taken as (operands[2] % 256) + 1.

  (define_insn "movstrdi_short"
!   [(set (match_operand:BLK 0 "s_operand" "=Q,Q")
!         (match_operand:BLK 1 "s_operand" "Q,Q"))
     (use (match_operand:DI 2 "nonmemory_operand" "n,a"))
     (clobber (match_scratch:DI 3 "=X,&a"))]
    "TARGET_64BIT"
***************
*** 1723,1730 ****
     (set_attr "length"  "*,14")])

  (define_insn "movstrsi_short"
!   [(set (match_operand:BLK 0 "s_operand" "=oQ,oQ")
!         (match_operand:BLK 1 "s_operand" "oQ,oQ"))
     (use (match_operand:SI 2 "nonmemory_operand" "n,a"))
     (clobber (match_scratch:SI 3 "=X,&a"))]
    "!TARGET_64BIT"
--- 1723,1730 ----
     (set_attr "length"  "*,14")])

  (define_insn "movstrsi_short"
!   [(set (match_operand:BLK 0 "s_operand" "=Q,Q")
!         (match_operand:BLK 1 "s_operand" "Q,Q"))
     (use (match_operand:SI 2 "nonmemory_operand" "n,a"))
     (clobber (match_scratch:SI 3 "=X,&a"))]
    "!TARGET_64BIT"
***************
*** 1927,1933 ****
  ; Clear memory with length less than 256 bytes

  (define_insn "clrstrsico"
!   [(set (match_operand:BLK 0 "s_operand" "=Qo")
          (const_int 0))
     (use (match_operand 1 "immediate_operand" "I"))
     (clobber (reg:CC 33))]
--- 1927,1933 ----
  ; Clear memory with length less than 256 bytes

  (define_insn "clrstrsico"
!   [(set (match_operand:BLK 0 "s_operand" "=Q")
          (const_int 0))
     (use (match_operand 1 "immediate_operand" "I"))
     (clobber (reg:CC 33))]
***************
*** 2111,2118 ****

  (define_insn "cmpstr_const"
    [(set (reg:CCS 33)
!         (compare:CCS (match_operand:BLK 0 "s_operand" "oQ")
!                      (match_operand:BLK 1 "s_operand" "oQ")))
     (use (match_operand 2 "immediate_operand" "I"))]
    "(unsigned) INTVAL (operands[2]) < 256"
    "clc\\t%O0(%c2,%R0),%1"
--- 2111,2118 ----

  (define_insn "cmpstr_const"
    [(set (reg:CCS 33)
!         (compare:CCS (match_operand:BLK 0 "s_operand" "Q")
!                      (match_operand:BLK 1 "s_operand" "Q")))
     (use (match_operand 2 "immediate_operand" "I"))]
    "(unsigned) INTVAL (operands[2]) < 256"
    "clc\\t%O0(%c2,%R0),%1"
***************
*** 2193,2199 ****

  (define_insn "*sethighqisi"
    [(set (match_operand:SI 0 "register_operand" "=d")
!         (unspec:SI [(match_operand:QI 1 "s_operand" "Qo")] 10))
     (clobber (reg:CC 33))]
    ""
    "icm\\t%0,8,%1"
--- 2193,2199 ----

  (define_insn "*sethighqisi"
    [(set (match_operand:SI 0 "register_operand" "=d")
!         (unspec:SI [(match_operand:QI 1 "s_operand" "Q")] 10))
     (clobber (reg:CC 33))]
    ""
    "icm\\t%0,8,%1"
***************
*** 2202,2208 ****

  (define_insn "*sethighhisi"
    [(set (match_operand:SI 0 "register_operand" "=d")
!         (unspec:SI [(match_operand:HI 1 "s_operand" "Qo")] 10))
     (clobber (reg:CC 33))]
    ""
    "icm\\t%0,12,%1"
--- 2202,2208 ----

  (define_insn "*sethighhisi"
    [(set (match_operand:SI 0 "register_operand" "=d")
!         (unspec:SI [(match_operand:HI 1 "s_operand" "Q")] 10))
     (clobber (reg:CC 33))]
    ""
    "icm\\t%0,12,%1"
***************
*** 2211,2217 ****

  (define_insn "*sethighqidi_64"
    [(set (match_operand:DI 0 "register_operand" "=d")
!         (unspec:DI [(match_operand:QI 1 "s_operand" "Qo")] 10))
     (clobber (reg:CC 33))]
    "TARGET_64BIT"
    "icmh\\t%0,8,%1"
--- 2211,2217 ----

  (define_insn "*sethighqidi_64"
    [(set (match_operand:DI 0 "register_operand" "=d")
!         (unspec:DI [(match_operand:QI 1 "s_operand" "Q")] 10))
     (clobber (reg:CC 33))]
    "TARGET_64BIT"
    "icmh\\t%0,8,%1"
***************
*** 2220,2226 ****

  (define_insn "*sethighqidi_31"
    [(set (match_operand:DI 0 "register_operand" "=d")
!         (unspec:DI [(match_operand:QI 1 "s_operand" "Qo")] 10))
     (clobber (reg:CC 33))]
    "!TARGET_64BIT"
    "icm\\t%0,8,%1"
--- 2220,2226 ----

  (define_insn "*sethighqidi_31"
    [(set (match_operand:DI 0 "register_operand" "=d")
!         (unspec:DI [(match_operand:QI 1 "s_operand" "Q")] 10))
     (clobber (reg:CC 33))]
    "!TARGET_64BIT"
    "icm\\t%0,8,%1"
***************
*** 4486,4494 ****
     (set_attr "atype"    "reg,mem")])

  (define_insn "*anddi3_ss"
!   [(set (match_operand:DI 0 "s_operand" "=Qo")
          (and:DI (match_dup 0)
!                 (match_operand:DI 1 "s_imm_operand" "Qo")))
     (clobber (reg:CC 33))]
    ""
    "nc\\t%O0(8,%R0),%1"
--- 4486,4494 ----
     (set_attr "atype"    "reg,mem")])

  (define_insn "*anddi3_ss"
!   [(set (match_operand:DI 0 "s_operand" "=Q")
          (and:DI (match_dup 0)
!                 (match_operand:DI 1 "s_imm_operand" "Q")))
     (clobber (reg:CC 33))]
    ""
    "nc\\t%O0(8,%R0),%1"
***************
*** 4496,4503 ****
     (set_attr "atype"    "mem")])

  (define_insn "*anddi3_ss_inv"
!   [(set (match_operand:DI 0 "s_operand" "=Qo")
!         (and:DI (match_operand:DI 1 "s_imm_operand" "Qo")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
--- 4496,4503 ----
     (set_attr "atype"    "mem")])

  (define_insn "*anddi3_ss_inv"
!   [(set (match_operand:DI 0 "s_operand" "=Q")
!         (and:DI (match_operand:DI 1 "s_imm_operand" "Q")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
***************
*** 4570,4578 ****
     (set_attr "atype"    "reg,mem")])

  (define_insn "*andsi3_ss"
!   [(set (match_operand:SI 0 "s_operand" "=Qo")
          (and:SI (match_dup 0)
!                 (match_operand:SI 1 "s_imm_operand" "Qo")))
     (clobber (reg:CC 33))]
    ""
    "nc\\t%O0(4,%R0),%1"
--- 4570,4578 ----
     (set_attr "atype"    "reg,mem")])

  (define_insn "*andsi3_ss"
!   [(set (match_operand:SI 0 "s_operand" "=Q")
          (and:SI (match_dup 0)
!                 (match_operand:SI 1 "s_imm_operand" "Q")))
     (clobber (reg:CC 33))]
    ""
    "nc\\t%O0(4,%R0),%1"
***************
*** 4580,4587 ****
     (set_attr "atype"    "mem")])

  (define_insn "*andsi3_ss_inv"
!   [(set (match_operand:SI 0 "s_operand" "=Qo")
!         (and:SI (match_operand:SI 1 "s_imm_operand" "Qo")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
--- 4580,4587 ----
     (set_attr "atype"    "mem")])

  (define_insn "*andsi3_ss_inv"
!   [(set (match_operand:SI 0 "s_operand" "=Q")
!         (and:SI (match_operand:SI 1 "s_imm_operand" "Q")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
***************
*** 4616,4624 ****
     (set_attr "atype"    "reg")])

  (define_insn "*andhi3_ss"
!   [(set (match_operand:HI 0 "s_operand" "=Qo")
          (and:HI (match_dup 0)
!                 (match_operand:HI 1 "s_imm_operand" "Qo")))
     (clobber (reg:CC 33))]
    ""
    "nc\\t%O0(2,%R0),%1"
--- 4616,4624 ----
     (set_attr "atype"    "reg")])

  (define_insn "*andhi3_ss"
!   [(set (match_operand:HI 0 "s_operand" "=Q")
          (and:HI (match_dup 0)
!                 (match_operand:HI 1 "s_imm_operand" "Q")))
     (clobber (reg:CC 33))]
    ""
    "nc\\t%O0(2,%R0),%1"
***************
*** 4626,4633 ****
     (set_attr "atype"    "mem")])

  (define_insn "*andhi3_ss_inv"
!   [(set (match_operand:HI 0 "s_operand" "=Qo")
!         (and:HI (match_operand:HI 1 "s_imm_operand" "Qo")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
--- 4626,4633 ----
     (set_attr "atype"    "mem")])

  (define_insn "*andhi3_ss_inv"
!   [(set (match_operand:HI 0 "s_operand" "=Q")
!         (and:HI (match_operand:HI 1 "s_imm_operand" "Q")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
***************
*** 4662,4670 ****
     (set_attr "atype"    "reg")])

  (define_insn "*andqi3_ss"
!   [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
          (and:QI (match_dup 0)
!                 (match_operand:QI 1 "s_imm_operand" "n,Qo")))
     (clobber (reg:CC 33))]
    ""
    "@
--- 4662,4670 ----
     (set_attr "atype"    "reg")])

  (define_insn "*andqi3_ss"
!   [(set (match_operand:QI 0 "s_operand" "=Q,Q")
          (and:QI (match_dup 0)
!                 (match_operand:QI 1 "s_imm_operand" "n,Q")))
     (clobber (reg:CC 33))]
    ""
    "@
***************
*** 4674,4681 ****
     (set_attr "atype"    "mem")])

  (define_insn "*andqi3_ss_inv"
!   [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
!         (and:QI (match_operand:QI 1 "s_imm_operand" "n,Qo")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
--- 4674,4681 ----
     (set_attr "atype"    "mem")])

  (define_insn "*andqi3_ss_inv"
!   [(set (match_operand:QI 0 "s_operand" "=Q,Q")
!         (and:QI (match_operand:QI 1 "s_imm_operand" "n,Q")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
***************
*** 4757,4765 ****
     (set_attr "atype"    "reg,mem")])

  (define_insn "*iordi3_ss"
!   [(set (match_operand:DI 0 "s_operand" "=Qo")
          (ior:DI (match_dup 0)
!                 (match_operand:DI 1 "s_imm_operand" "Qo")))
     (clobber (reg:CC 33))]
    ""
    "oc\\t%O0(8,%R0),%1"
--- 4757,4765 ----
     (set_attr "atype"    "reg,mem")])

  (define_insn "*iordi3_ss"
!   [(set (match_operand:DI 0 "s_operand" "=Q")
          (ior:DI (match_dup 0)
!                 (match_operand:DI 1 "s_imm_operand" "Q")))
     (clobber (reg:CC 33))]
    ""
    "oc\\t%O0(8,%R0),%1"
***************
*** 4767,4774 ****
     (set_attr "atype"    "mem")])

  (define_insn "*iordi3_ss_inv"
!   [(set (match_operand:DI 0 "s_operand" "=Qo")
!         (ior:DI (match_operand:DI 1 "s_imm_operand" "Qo")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
--- 4767,4774 ----
     (set_attr "atype"    "mem")])

  (define_insn "*iordi3_ss_inv"
!   [(set (match_operand:DI 0 "s_operand" "=Q")
!         (ior:DI (match_operand:DI 1 "s_imm_operand" "Q")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
***************
*** 4841,4849 ****
     (set_attr "atype"    "reg,mem")])

  (define_insn "*iorsi3_ss"
!   [(set (match_operand:SI 0 "s_operand" "=Qo")
          (ior:SI (match_dup 0)
!                 (match_operand:SI 1 "s_imm_operand" "Qo")))
     (clobber (reg:CC 33))]
    ""
    "oc\\t%O0(4,%R0),%1"
--- 4841,4849 ----
     (set_attr "atype"    "reg,mem")])

  (define_insn "*iorsi3_ss"
!   [(set (match_operand:SI 0 "s_operand" "=Q")
          (ior:SI (match_dup 0)
!                 (match_operand:SI 1 "s_imm_operand" "Q")))
     (clobber (reg:CC 33))]
    ""
    "oc\\t%O0(4,%R0),%1"
***************
*** 4851,4858 ****
     (set_attr "atype"    "mem")])

  (define_insn "*iorsi3_ss_inv"
!   [(set (match_operand:SI 0 "s_operand" "=Qo")
!         (ior:SI (match_operand:SI 1 "s_imm_operand" "Qo")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
--- 4851,4858 ----
     (set_attr "atype"    "mem")])

  (define_insn "*iorsi3_ss_inv"
!   [(set (match_operand:SI 0 "s_operand" "=Q")
!         (ior:SI (match_operand:SI 1 "s_imm_operand" "Q")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
***************
*** 4887,4895 ****
     (set_attr "atype"    "reg")])

  (define_insn "*iorhi3_ss"
!   [(set (match_operand:HI 0 "s_operand" "=Qo")
          (ior:HI (match_dup 0)
!                 (match_operand:HI 1 "s_imm_operand" "Qo")))
     (clobber (reg:CC 33))]
    ""
    "oc\\t%O0(2,%R0),%1"
--- 4887,4895 ----
     (set_attr "atype"    "reg")])

  (define_insn "*iorhi3_ss"
!   [(set (match_operand:HI 0 "s_operand" "=Q")
          (ior:HI (match_dup 0)
!                 (match_operand:HI 1 "s_imm_operand" "Q")))
     (clobber (reg:CC 33))]
    ""
    "oc\\t%O0(2,%R0),%1"
***************
*** 4897,4904 ****
     (set_attr "atype"    "mem")])

  (define_insn "*iorhi3_ss_inv"
!   [(set (match_operand:HI 0 "s_operand" "=Qo")
!         (ior:HI (match_operand:HI 1 "s_imm_operand" "Qo")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
--- 4897,4904 ----
     (set_attr "atype"    "mem")])

  (define_insn "*iorhi3_ss_inv"
!   [(set (match_operand:HI 0 "s_operand" "=Q")
!         (ior:HI (match_operand:HI 1 "s_imm_operand" "Q")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
***************
*** 4933,4941 ****
     (set_attr "atype"    "reg")])

  (define_insn "*iorqi3_ss"
!   [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
          (ior:QI (match_dup 0)
!                 (match_operand:QI 1 "s_imm_operand" "n,Qo")))
     (clobber (reg:CC 33))]
    ""
    "@
--- 4933,4941 ----
     (set_attr "atype"    "reg")])

  (define_insn "*iorqi3_ss"
!   [(set (match_operand:QI 0 "s_operand" "=Q,Q")
          (ior:QI (match_dup 0)
!                 (match_operand:QI 1 "s_imm_operand" "n,Q")))
     (clobber (reg:CC 33))]
    ""
    "@
***************
*** 4945,4952 ****
     (set_attr "atype"    "reg,mem")])

  (define_insn "*iorqi3_ss_inv"
!   [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
!         (ior:QI (match_operand:QI 1 "s_imm_operand" "n,Qo")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
--- 4945,4952 ----
     (set_attr "atype"    "reg,mem")])

  (define_insn "*iorqi3_ss_inv"
!   [(set (match_operand:QI 0 "s_operand" "=Q,Q")
!         (ior:QI (match_operand:QI 1 "s_imm_operand" "n,Q")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
***************
*** 5005,5013 ****
     (set_attr "atype"    "reg,mem")])

  (define_insn "*xordi3_ss"
!   [(set (match_operand:DI 0 "s_operand" "=Qo")
          (xor:DI (match_dup 0)
!                 (match_operand:DI 1 "s_imm_operand" "Qo")))
     (clobber (reg:CC 33))]
    ""
    "xc\\t%O0(8,%R0),%1"
--- 5005,5013 ----
     (set_attr "atype"    "reg,mem")])

  (define_insn "*xordi3_ss"
!   [(set (match_operand:DI 0 "s_operand" "=Q")
          (xor:DI (match_dup 0)
!                 (match_operand:DI 1 "s_imm_operand" "Q")))
     (clobber (reg:CC 33))]
    ""
    "xc\\t%O0(8,%R0),%1"
***************
*** 5015,5022 ****
     (set_attr "atype"    "mem")])

  (define_insn "*xordi3_ss_inv"
!   [(set (match_operand:DI 0 "s_operand" "=Qo")
!         (xor:DI (match_operand:DI 1 "s_imm_operand" "Qo")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
--- 5015,5022 ----
     (set_attr "atype"    "mem")])

  (define_insn "*xordi3_ss_inv"
!   [(set (match_operand:DI 0 "s_operand" "=Q")
!         (xor:DI (match_operand:DI 1 "s_imm_operand" "Q")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
***************
*** 5068,5076 ****
     (set_attr "atype"    "reg,mem")])

  (define_insn "*xorsi3_ss"
!   [(set (match_operand:SI 0 "s_operand" "=Qo")
          (xor:SI (match_dup 0)
!                 (match_operand:SI 1 "s_imm_operand" "Qo")))
     (clobber (reg:CC 33))]
    ""
    "xc\\t%O0(4,%R0),%1"
--- 5068,5076 ----
     (set_attr "atype"    "reg,mem")])

  (define_insn "*xorsi3_ss"
!   [(set (match_operand:SI 0 "s_operand" "=Q")
          (xor:SI (match_dup 0)
!                 (match_operand:SI 1 "s_imm_operand" "Q")))
     (clobber (reg:CC 33))]
    ""
    "xc\\t%O0(4,%R0),%1"
***************
*** 5078,5085 ****
     (set_attr "atype"    "mem")])

  (define_insn "*xorsi3_ss_inv"
!   [(set (match_operand:SI 0 "s_operand" "=Qo")
!         (xor:SI (match_operand:SI 1 "s_imm_operand" "Qo")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
--- 5078,5085 ----
     (set_attr "atype"    "mem")])

  (define_insn "*xorsi3_ss_inv"
!   [(set (match_operand:SI 0 "s_operand" "=Q")
!         (xor:SI (match_operand:SI 1 "s_imm_operand" "Q")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
***************
*** 5102,5110 ****
     (set_attr "atype"    "reg")])

  (define_insn "*xorhi3_ss"
!   [(set (match_operand:HI 0 "s_operand" "=Qo")
          (xor:HI (match_dup 0)
!                 (match_operand:HI 1 "s_imm_operand" "Qo")))
     (clobber (reg:CC 33))]
    ""
    "xc\\t%O0(2,%R0),%1"
--- 5102,5110 ----
     (set_attr "atype"    "reg")])

  (define_insn "*xorhi3_ss"
!   [(set (match_operand:HI 0 "s_operand" "=Q")
          (xor:HI (match_dup 0)
!                 (match_operand:HI 1 "s_imm_operand" "Q")))
     (clobber (reg:CC 33))]
    ""
    "xc\\t%O0(2,%R0),%1"
***************
*** 5112,5119 ****
     (set_attr "atype"    "mem")])

  (define_insn "*xorhi3_ss_inv"
!   [(set (match_operand:HI 0 "s_operand" "=Qo")
!         (xor:HI (match_operand:HI 1 "s_imm_operand" "Qo")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
--- 5112,5119 ----
     (set_attr "atype"    "mem")])

  (define_insn "*xorhi3_ss_inv"
!   [(set (match_operand:HI 0 "s_operand" "=Q")
!         (xor:HI (match_operand:HI 1 "s_imm_operand" "Q")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
***************
*** 5136,5144 ****
     (set_attr "atype"    "reg")])

  (define_insn "*xorqi3_ss"
!   [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
          (xor:QI (match_dup 0)
!                 (match_operand:QI 1 "s_imm_operand" "n,Qo")))
     (clobber (reg:CC 33))]
    ""
    "@
--- 5136,5144 ----
     (set_attr "atype"    "reg")])

  (define_insn "*xorqi3_ss"
!   [(set (match_operand:QI 0 "s_operand" "=Q,Q")
          (xor:QI (match_dup 0)
!                 (match_operand:QI 1 "s_imm_operand" "n,Q")))
     (clobber (reg:CC 33))]
    ""
    "@
***************
*** 5148,5155 ****
     (set_attr "atype"    "mem")])

  (define_insn "*xorqi3_ss_inv"
!   [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
!         (xor:QI (match_operand:QI 1 "s_imm_operand" "n,Qo")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
--- 5148,5155 ----
     (set_attr "atype"    "mem")])

  (define_insn "*xorqi3_ss_inv"
!   [(set (match_operand:QI 0 "s_operand" "=Q,Q")
!         (xor:QI (match_operand:QI 1 "s_imm_operand" "n,Q")
                  (match_dup 0)))
     (clobber (reg:CC 33))]
    ""
Index: gcc/doc/tm.texi
===================================================================
RCS file: /cvs/gcc/gcc/gcc/doc/tm.texi,v
retrieving revision 1.155
diff -c -p -r1.155 tm.texi
*** gcc/doc/tm.texi     7 Aug 2002 21:05:12 -0000     1.155
--- gcc/doc/tm.texi     14 Aug 2002 09:46:44 -0000
*************** letter @samp{Q} is defined as representi
*** 2614,2619 ****
--- 2614,2657 ----
  a @samp{Q} constraint on the input and @samp{r} on the output.  The next
  alternative specifies @samp{m} on the input and a register class that
  does not include r0 on the output.
+
+ @findex EXTRA_MEMORY_CONSTRAINT
+ @item EXTRA_MEMORY_CONSTRAINT (@var{c})
+ A C expression that defines the optional machine-dependent constraint
+ letters, amongst those accepted by @code{EXTRA_CONSTRAINT}, that should
+ be treated like memory constraints by the reload pass.
+
+ It should return 1 if the operand type represented by the constraint
+ letter @var{c} comprises a subset of all memory references including
+ all those whose address is simply a base register.  This allows the reload
+ pass to reload an operand, if it does not directly correspond to the operand
+ type of @var{c}, by copying its address into a base register.
+
+ For example, on the S/390, some instructions do not accept arbitrary
+ memory references, but only those that do not make use of an index
+ register.  The constraint letter @samp{Q} is defined via
+ @code{EXTRA_CONSTRAINT} as representing a memory address of this type.
+ If the letter @samp{Q} is marked as @code{EXTRA_MEMORY_CONSTRAINT},
+ a @samp{Q} constraint can handle any memory operand, because the
+ reload pass knows it can be reloaded by copying the memory address
+ into a base register if required.  This is analogous to the way
+ a @samp{o} constraint can handle any memory operand.
+
+ @findex EXTRA_ADDRESS_CONSTRAINT
+ @item EXTRA_ADDRESS_CONSTRAINT (@var{c})
+ A C expression that defines the optional machine-dependent constraint
+ letters, amongst those accepted by @code{EXTRA_CONSTRAINT}, that should
+ be treated like address constraints by the reload pass.
+
+ It should return 1 if the operand type represented by the constraint
+ letter @var{c} comprises a subset of all memory addresses including
+ all those that consist of just a base register.  This allows the reload
+ pass to reload an operand, if it does not directly correspond to the operand
+ type of @var{c}, by copying it into a base register.
+
+ Any constraint marked as @code{EXTRA_ADDRESS_CONSTRAINT} can only
+ be used with the @code{address_operand} predicate.  It is treated
+ analogously to the @samp{p} constraint.
  @end table

  @node Stack and Calling


Mit freundlichen Gruessen / Best Regards

Ulrich Weigand

--
  Dr. Ulrich Weigand
  Linux for S/390 Design & Development
  IBM Deutschland Entwicklung GmbH, Schoenaicher Str. 220, 71032 Boeblingen
  Phone: +49-7031/16-3727   ---   Email: Ulrich.Weigand@de.ibm.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]