]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
reload.c (find_reloads): Handle constraint letters marked by EXTRA_ADDRESS_CONSTRAINT...
authorUlrich Weigand <uweigand@de.ibm.com>
Wed, 14 Aug 2002 10:04:51 +0000 (10:04 +0000)
committerUlrich Weigand <uweigand@gcc.gnu.org>
Wed, 14 Aug 2002 10:04:51 +0000 (10:04 +0000)
* 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'.

From-SVN: r56291

13 files changed:
gcc/ChangeLog
gcc/config/s390/s390-protos.h
gcc/config/s390/s390.c
gcc/config/s390/s390.h
gcc/config/s390/s390.md
gcc/defaults.h
gcc/doc/tm.texi
gcc/local-alloc.c
gcc/recog.c
gcc/regclass.c
gcc/reload.c
gcc/reload1.c
gcc/stmt.c

index 3df15190cb6ceea4b492c7778d9d176896657bf6..d7348981e523c1acfeee938ec1159c2850851a05 100644 (file)
@@ -1,3 +1,30 @@
+2002-08-14  Ulrich Weigand  <uweigand@de.ibm.com>
+
+       * 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'.
+
 2002-08-14  Stephane Carrez  <stcarrez@nerim.fr>
 
        * config/m68hc11/m68hc11.h (LINK_SPEC): Support -mrelax.
index a85e350a4daaaf017cdba27ad92c45a4ed885950..38c5c0b20353439dbee0cdd839ea88d55b7eb915 100644 (file)
@@ -31,6 +31,7 @@ extern void s390_emit_epilogue PARAMS ((void));
 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 b43883b137561a0c400a40865ebe3644efa8d582..6a29b764f007b744f06cc855313dc9e62e7614f8 100644 (file)
@@ -995,6 +995,28 @@ s_imm_operand (op, mode)
   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.  */
@@ -1386,6 +1408,15 @@ s390_expand_plus_operand (target, src, scratch_in)
   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
      it the second one.  */
index 05875b4fd76db64aee84dc6544c328bc9c94babb..c5ba4270d37f29248c85bdab0527f62548081272 100644 (file)
@@ -533,9 +533,11 @@ extern const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER]; /* smalled clas
 /* 'Q' means a memory-reference for a S-type operand.  */
 
 #define EXTRA_CONSTRAINT(OP, C)                                \
-     ((C) == 'Q' ?  s_operand (OP, GET_MODE (OP)) :            \
+     ((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;
    but on some machines in some cases it is preferable to use a more
index 35e2d3edc4f5dc31dea8f6f05095959d077b858a..f8ddc2f82aa5c30aa1001b3545aa87da4d140310 100644 (file)
 
 (define_insn "*tmqi_ext"
   [(set (reg 33)
-        (compare (zero_extract:SI (match_operand:QI 0 "s_operand" "Qo")
+        (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)))]
 
 (define_insn "*tmdi_mem"
   [(set (reg 33)
-        (compare (and:DI (match_operand:DI 0 "s_operand" "%Qo")
+        (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
 
 (define_insn "*tmsi_mem"
   [(set (reg 33)
-        (compare (and:SI (match_operand:SI 0 "s_operand" "%Qo")
+        (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))
 
 (define_insn "*tmhi_mem"
   [(set (reg 33)
-        (compare (and:SI (subreg:SI (match_operand:HI 0 "s_operand" "%Qo") 0)
+        (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))
 
 (define_insn "*tmqi_mem"
   [(set (reg 33)
-        (compare (and:SI (subreg:SI (match_operand:QI 0 "s_operand" "%Qo") 0)
+        (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))"
 
 (define_insn "*tsthi"
   [(set (reg 33)
-        (compare (match_operand:HI 0 "s_operand" "Qo")
+        (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))]
 
 (define_insn "*tsthi_cconly"
   [(set (reg 33)
-        (compare (match_operand:HI 0 "s_operand" "Qo")
+        (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)"
 
 (define_insn "*tstqi"
   [(set (reg 33)
-        (compare (match_operand:QI 0 "s_operand" "Qo")
+        (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))]
 
 (define_insn "*tstqi_cconly"
   [(set (reg 33)
-        (compare (match_operand:QI 0 "s_operand" "Qo")
+        (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)"
 (define_insn "*cmphi_ccu"
   [(set (reg 33)
         (compare (match_operand:HI 0 "register_operand" "d")
-                 (match_operand:HI 1 "s_imm_operand" "Qo")))]
+                 (match_operand:HI 1 "s_imm_operand" "Q")))]
   "s390_match_ccmode(insn, CCUmode)"
   "clm\\t%0,3,%1"
   [(set_attr "op_type" "RS")
 (define_insn "*cmpqi_ccu"
   [(set (reg 33)
         (compare (match_operand:QI 0 "register_operand" "d")
-                 (match_operand:QI 1 "s_imm_operand" "Qo")))]
+                 (match_operand:QI 1 "s_imm_operand" "Q")))]
   "s390_match_ccmode(insn, CCUmode)"
   "clm\\t%0,1,%1"
   [(set_attr "op_type" "RS")
 
 (define_insn "*cli"
   [(set (reg 33)
-        (compare (match_operand:QI 0 "s_operand" "Qo")
+        (compare (match_operand:QI 0 "s_operand" "Q")
                  (match_operand:QI 1 "immediate_operand" "n")))]
   "s390_match_ccmode (insn, CCUmode)"
   "cli\\t%0,%b1"
 
 (define_insn "*cmpdi_ccu_mem"
   [(set (reg 33)
-        (compare (match_operand:DI 0 "s_operand" "oQ")
-                 (match_operand:DI 1 "s_imm_operand" "oQ")))]
+        (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")
 
 (define_insn "*cmpsi_ccu_mem"
   [(set (reg 33)
-        (compare (match_operand:SI 0 "s_operand" "oQ")
-                 (match_operand:SI 1 "s_imm_operand" "oQ")))]
+        (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")
 
 (define_insn "*cmphi_ccu_mem"
   [(set (reg 33)
-        (compare (match_operand:HI 0 "s_operand" "oQ")
-                 (match_operand:HI 1 "s_imm_operand" "oQ")))]
+        (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")
 
 (define_insn "*cmpqi_ccu_mem"
   [(set (reg 33)
-        (compare (match_operand:QI 0 "s_operand" "oQ")
-                 (match_operand:QI 1 "s_imm_operand" "oQ")))]
+        (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")
 ;
 
 (define_insn "*movti_ss"
-  [(set (match_operand:TI 0 "s_operand" "=Qo")
-        (match_operand:TI 1 "s_imm_operand" "Qo"))]
+  [(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")
     (set_attr "type"    "la")])
 
 (define_insn "*movdi_ss"
-  [(set (match_operand:DI 0 "s_operand" "=Qo")
-        (match_operand:DI 1 "s_imm_operand" "Qo"))]
+  [(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")
   [(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"))]
+  [(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")
 
 (define_insn "*movstricthi"
   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+d"))
-                         (match_operand:HI 1 "s_imm_operand" "Qo"))
+                         (match_operand:HI 1 "s_imm_operand" "Q"))
    (clobber (reg:CC 33))]
   ""
   "icm\\t%0,3,%1"
 }")
 
 (define_insn "*movdf_ss"
-  [(set (match_operand:DF 0 "s_operand" "=Qo")
-        (match_operand:DF 1 "s_imm_operand" "Qo"))]
+  [(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")
 }")
 
 (define_insn "*movsf_ss"
-  [(set (match_operand:SF 0 "s_operand" "=Qo")
-        (match_operand:SF 1 "s_imm_operand" "Qo"))]
+  [(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")
 (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"))])]
+                        (match_operand:DI 2 "s_operand" "Q"))])]
   ""
   "*
 {
 (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"))])]
+                        (match_operand:SI 2 "s_operand" "Q"))])]
   ""
   "*
 {
 
 (define_insn "*store_multiple_di"
   [(match_parallel 0 "store_multiple_operation"
-                  [(set (match_operand:DI 1 "s_operand" "=oQ")
+                  [(set (match_operand:DI 1 "s_operand" "=Q")
                         (match_operand:DI 2 "register_operand" "r"))])]
   ""
   "*
 
 (define_insn "*store_multiple_si"
   [(match_parallel 0 "store_multiple_operation"
-                  [(set (match_operand:SI 1 "s_operand" "=oQ")
+                  [(set (match_operand:SI 1 "s_operand" "=Q")
                         (match_operand:SI 2 "register_operand" "r"))])]
   ""
   "*
 ; 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"))
+  [(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"
    (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"))
+  [(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"
 ; Clear memory with length less than 256 bytes 
 
 (define_insn "clrstrsico"
-  [(set (match_operand:BLK 0 "s_operand" "=Qo")
+  [(set (match_operand:BLK 0 "s_operand" "=Q")
         (const_int 0))
    (use (match_operand 1 "immediate_operand" "I"))
    (clobber (reg:CC 33))]
 
 (define_insn "cmpstr_const"
   [(set (reg:CCS 33)
-        (compare:CCS (match_operand:BLK 0 "s_operand" "oQ")
-                     (match_operand:BLK 1 "s_operand" "oQ")))
+        (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"
 
 (define_insn "*sethighqisi"
   [(set (match_operand:SI 0 "register_operand" "=d")
-        (unspec:SI [(match_operand:QI 1 "s_operand" "Qo")] 10))
+        (unspec:SI [(match_operand:QI 1 "s_operand" "Q")] 10))
    (clobber (reg:CC 33))]
   ""
   "icm\\t%0,8,%1"
 
 (define_insn "*sethighhisi"
   [(set (match_operand:SI 0 "register_operand" "=d")
-        (unspec:SI [(match_operand:HI 1 "s_operand" "Qo")] 10))
+        (unspec:SI [(match_operand:HI 1 "s_operand" "Q")] 10))
    (clobber (reg:CC 33))]
   ""
   "icm\\t%0,12,%1"
 
 (define_insn "*sethighqidi_64"
   [(set (match_operand:DI 0 "register_operand" "=d")
-        (unspec:DI [(match_operand:QI 1 "s_operand" "Qo")] 10))
+        (unspec:DI [(match_operand:QI 1 "s_operand" "Q")] 10))
    (clobber (reg:CC 33))]
   "TARGET_64BIT"
   "icmh\\t%0,8,%1"
 
 (define_insn "*sethighqidi_31"
   [(set (match_operand:DI 0 "register_operand" "=d")
-        (unspec:DI [(match_operand:QI 1 "s_operand" "Qo")] 10))
+        (unspec:DI [(match_operand:QI 1 "s_operand" "Q")] 10))
    (clobber (reg:CC 33))]
   "!TARGET_64BIT"
   "icm\\t%0,8,%1"
    (set_attr "atype"    "reg,mem")])
 
 (define_insn "*anddi3_ss"
-  [(set (match_operand:DI 0 "s_operand" "=Qo")
+  [(set (match_operand:DI 0 "s_operand" "=Q")
         (and:DI (match_dup 0)
-                (match_operand:DI 1 "s_imm_operand" "Qo")))
+                (match_operand:DI 1 "s_imm_operand" "Q")))
    (clobber (reg:CC 33))]
   ""
   "nc\\t%O0(8,%R0),%1"
    (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")
+  [(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))]
   ""
    (set_attr "atype"    "reg,mem")])
 
 (define_insn "*andsi3_ss"
-  [(set (match_operand:SI 0 "s_operand" "=Qo")
+  [(set (match_operand:SI 0 "s_operand" "=Q")
         (and:SI (match_dup 0)
-                (match_operand:SI 1 "s_imm_operand" "Qo")))
+                (match_operand:SI 1 "s_imm_operand" "Q")))
    (clobber (reg:CC 33))]
   ""
   "nc\\t%O0(4,%R0),%1"
    (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")
+  [(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))]
   ""
    (set_attr "atype"    "reg")])
 
 (define_insn "*andhi3_ss"
-  [(set (match_operand:HI 0 "s_operand" "=Qo")
+  [(set (match_operand:HI 0 "s_operand" "=Q")
         (and:HI (match_dup 0)
-                (match_operand:HI 1 "s_imm_operand" "Qo")))
+                (match_operand:HI 1 "s_imm_operand" "Q")))
    (clobber (reg:CC 33))]
   ""
   "nc\\t%O0(2,%R0),%1"
    (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")
+  [(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))]
   ""
    (set_attr "atype"    "reg")])
 
 (define_insn "*andqi3_ss"
-  [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
+  [(set (match_operand:QI 0 "s_operand" "=Q,Q")
         (and:QI (match_dup 0)
-                (match_operand:QI 1 "s_imm_operand" "n,Qo")))
+                (match_operand:QI 1 "s_imm_operand" "n,Q")))
    (clobber (reg:CC 33))]
   ""
   "@
    (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")
+  [(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))]
   ""
    (set_attr "atype"    "reg,mem")])
 
 (define_insn "*iordi3_ss"
-  [(set (match_operand:DI 0 "s_operand" "=Qo")
+  [(set (match_operand:DI 0 "s_operand" "=Q")
         (ior:DI (match_dup 0)
-                (match_operand:DI 1 "s_imm_operand" "Qo")))
+                (match_operand:DI 1 "s_imm_operand" "Q")))
    (clobber (reg:CC 33))]
   ""
   "oc\\t%O0(8,%R0),%1"
    (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")
+  [(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))]
   ""
    (set_attr "atype"    "reg,mem")])
 
 (define_insn "*iorsi3_ss"
-  [(set (match_operand:SI 0 "s_operand" "=Qo")
+  [(set (match_operand:SI 0 "s_operand" "=Q")
         (ior:SI (match_dup 0)
-                (match_operand:SI 1 "s_imm_operand" "Qo")))
+                (match_operand:SI 1 "s_imm_operand" "Q")))
    (clobber (reg:CC 33))]
   ""
   "oc\\t%O0(4,%R0),%1"
    (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")
+  [(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))]
   ""
    (set_attr "atype"    "reg")])
 
 (define_insn "*iorhi3_ss"
-  [(set (match_operand:HI 0 "s_operand" "=Qo")
+  [(set (match_operand:HI 0 "s_operand" "=Q")
         (ior:HI (match_dup 0)
-                (match_operand:HI 1 "s_imm_operand" "Qo")))
+                (match_operand:HI 1 "s_imm_operand" "Q")))
    (clobber (reg:CC 33))]
   ""
   "oc\\t%O0(2,%R0),%1"
    (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")
+  [(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))]
   ""
    (set_attr "atype"    "reg")])
 
 (define_insn "*iorqi3_ss"
-  [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
+  [(set (match_operand:QI 0 "s_operand" "=Q,Q")
         (ior:QI (match_dup 0)
-                (match_operand:QI 1 "s_imm_operand" "n,Qo")))
+                (match_operand:QI 1 "s_imm_operand" "n,Q")))
    (clobber (reg:CC 33))]
   ""
   "@
    (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")
+  [(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))]
   ""
    (set_attr "atype"    "reg,mem")])
 
 (define_insn "*xordi3_ss"
-  [(set (match_operand:DI 0 "s_operand" "=Qo")
+  [(set (match_operand:DI 0 "s_operand" "=Q")
         (xor:DI (match_dup 0)
-                (match_operand:DI 1 "s_imm_operand" "Qo")))
+                (match_operand:DI 1 "s_imm_operand" "Q")))
    (clobber (reg:CC 33))]
   ""
   "xc\\t%O0(8,%R0),%1"
    (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")
+  [(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))]
   ""
    (set_attr "atype"    "reg,mem")])
 
 (define_insn "*xorsi3_ss"
-  [(set (match_operand:SI 0 "s_operand" "=Qo")
+  [(set (match_operand:SI 0 "s_operand" "=Q")
         (xor:SI (match_dup 0)
-                (match_operand:SI 1 "s_imm_operand" "Qo")))
+                (match_operand:SI 1 "s_imm_operand" "Q")))
    (clobber (reg:CC 33))]
   ""
   "xc\\t%O0(4,%R0),%1"
    (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")
+  [(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))]
   ""
    (set_attr "atype"    "reg")])
 
 (define_insn "*xorhi3_ss"
-  [(set (match_operand:HI 0 "s_operand" "=Qo")
+  [(set (match_operand:HI 0 "s_operand" "=Q")
         (xor:HI (match_dup 0)
-                (match_operand:HI 1 "s_imm_operand" "Qo")))
+                (match_operand:HI 1 "s_imm_operand" "Q")))
    (clobber (reg:CC 33))]
   ""
   "xc\\t%O0(2,%R0),%1"
    (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")
+  [(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))]
   ""
    (set_attr "atype"    "reg")])
 
 (define_insn "*xorqi3_ss"
-  [(set (match_operand:QI 0 "s_operand" "=Qo,Qo")
+  [(set (match_operand:QI 0 "s_operand" "=Q,Q")
         (xor:QI (match_dup 0)
-                (match_operand:QI 1 "s_imm_operand" "n,Qo")))
+                (match_operand:QI 1 "s_imm_operand" "n,Q")))
    (clobber (reg:CC 33))]
   ""
   "@
    (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")
+  [(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 115cc01b403eeaf39e6b56d7c0fcfa8c896be30e..ae115b887fd3208eacd2fe5a4682be86448c09ae 100644 (file)
@@ -590,4 +590,16 @@ You Lose!  You must define PREFERRED_DEBUGGING_TYPE!
 #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 d13b53ee4a4470e104786c74529685775c2f199d..064120d639af3d061b2dd3ddce6079d22c6f2b9d 100644 (file)
@@ -2614,6 +2614,44 @@ letter @samp{Q} is defined as representing a memory address that does
 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
index 77607ba74be5b3e34f9e4ba1ff8cc56b00613693..04e2fbe5a4c7cc5951bb03cc6b223b34b7cc8ac7 100644 (file)
@@ -1342,7 +1342,8 @@ block_alloc (b)
                  /* 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')
+                 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);
 
@@ -2472,7 +2473,8 @@ requires_inout (p)
        break;
 
       default:
-       if (REG_CLASS_FROM_LETTER (c) == NO_REGS)
+       if (REG_CLASS_FROM_LETTER (c) == NO_REGS
+           && !EXTRA_ADDRESS_CONSTRAINT (c))
          break;
        /* FALLTHRU */
       case 'p':
index c56069a053cde10254afef4990dbc22d5dafda57..6bb8670e166c283783ef8cb0663f424b9c5adf1a 100644 (file)
@@ -1848,6 +1848,18 @@ asm_operand_ok (op, constraint)
 #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;
        }
@@ -2287,6 +2299,19 @@ preprocess_constraints ()
                  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;
                }
@@ -2600,6 +2625,28 @@ constrain_operands (strict)
 #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 1451f8a4a75976be2c28afe54da6753d9bfd034e..75335b1603071dae91bbbee4b2481a816ece6c9b 100644 (file)
@@ -1007,7 +1007,8 @@ record_operand_costs (insn, op_costs, reg_pref)
       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')
+      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);
     }
@@ -1709,6 +1710,27 @@ record_reg_classes (n_alts, n_ops, ops, modes,
 #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 41d671d3146769d0f92a66e600b40781fce3151d..67f411b9040b7e8edd4001e173537bd88dfdc71f 100644 (file)
@@ -2641,7 +2641,8 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
       if (*constraints[i] == 0)
        /* Ignore things like match_operator operands.  */
        ;
-      else if (constraints[i][0] == 'p')
+      else if (constraints[i][0] == 'p'
+              || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0]))
        {
          find_reloads_address (VOIDmode, (rtx*) 0,
                                recog_data.operand[i],
@@ -3222,6 +3223,49 @@ find_reloads (insn, replace, ind_levels, live_known, reload_reg_p)
                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
@@ -4291,7 +4335,7 @@ alternative_allows_memconst (constraint, altnum)
   /* 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')
+    if (c == 'm' || c == 'o' || EXTRA_MEMORY_CONSTRAINT (c))
       return 1;
   return 0;
 }
index 23ab50f15708f02bff52af347674b5233dd7fa8a..58b0bd04bce053da881e825492fd83cdd9331744 100644 (file)
@@ -1380,8 +1380,12 @@ maybe_fix_stack_asms ()
                  break;
 
                default:
-                 cls = (int) reg_class_subunion[cls][(int) REG_CLASS_FROM_LETTER (c)];
-
+                 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 550e3e7e2386f47127fde3ee6c7aa5558cd528c8..b2e2cad28c2b7075daec60e3c27b81d29dede922 100644 (file)
@@ -1252,6 +1252,10 @@ parse_output_constraint (constraint_p, operand_num, ninputs, noutputs,
        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
@@ -1377,6 +1381,10 @@ parse_input_constraint (constraint_p, input_num, ninputs, noutputs, ninout,
        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