OSDN Git Service

gcc/ada/
[pf3gnuchains/gcc-fork.git] / gcc / config / s390 / s390.md
index 3fac610..b135033 100644 (file)
@@ -1,5 +1,5 @@
 ;;- Machine description for GNU compiler -- S/390 / zSeries version.
-;;  Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+;;  Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
 ;;  Free Software Foundation, Inc.
 ;;  Contributed by Hartmut Penner (hpenner@de.ibm.com) and
 ;;                 Ulrich Weigand (uweigand@de.ibm.com).
@@ -8,7 +8,7 @@
 
 ;; GCC is free software; you can redistribute it and/or modify it under
 ;; the terms of the GNU General Public License as published by the Free
-;; Software Foundation; either version 2, or (at your option) any later
+;; Software Foundation; either version 3, or (at your option) any later
 ;; version.
 
 ;; GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -17,9 +17,8 @@
 ;; for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GCC; see the file COPYING.  If not, write to the Free
-;; Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-;; 02110-1301, USA.
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
 
 ;;
 ;; See constraints.md for a description of constraints specific to s390.
 ;; Other includes
 (include "tpf.md")
 
-;; Macros
+;; Iterators
 
-;; This mode macro allows floating point patterns to be generated from the
+;; These mode iterators allow floating point patterns to be generated from the
 ;; same template.
-(define_mode_macro FP [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")])
-(define_mode_macro BFP [TF DF SF])
-(define_mode_macro DFP [TD DD])
-(define_mode_macro DFP_ALL [TD DD SD])
-(define_mode_macro DSF [DF SF])
-(define_mode_macro SD_SF [SF SD])
-(define_mode_macro DD_DF [DF DD])
-(define_mode_macro TD_TF [TF TD])
-
-;; These mode macros allow 31-bit and 64-bit TDSI patterns to be generated
+(define_mode_iterator FP [TF DF SF (TD "TARGET_HARD_DFP") (DD "TARGET_HARD_DFP")])
+(define_mode_iterator BFP [TF DF SF])
+(define_mode_iterator DFP [TD DD])
+(define_mode_iterator DFP_ALL [TD DD SD])
+(define_mode_iterator DSF [DF SF])
+(define_mode_iterator SD_SF [SF SD])
+(define_mode_iterator DD_DF [DF DD])
+(define_mode_iterator TD_TF [TF TD])
+
+;; This mode iterator allows 31-bit and 64-bit TDSI patterns to be generated
 ;; from the same template.
-(define_mode_macro TDSI [(TI "TARGET_64BIT") DI SI])
+(define_mode_iterator TDSI [(TI "TARGET_64BIT") DI SI])
 
-;; These mode macros allow 31-bit and 64-bit GPR patterns to be generated
+;; These mode iterators allow 31-bit and 64-bit GPR patterns to be generated
 ;; from the same template.
-(define_mode_macro GPR [(DI "TARGET_64BIT") SI])
-(define_mode_macro DSI [DI SI])
+(define_mode_iterator GPR [(DI "TARGET_64BIT") SI])
+(define_mode_iterator DSI [DI SI])
 
-;; This mode macro allows :P to be used for patterns that operate on
+;; These mode iterators allow :P to be used for patterns that operate on
 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
-(define_mode_macro DP  [(TI "TARGET_64BIT") (DI "!TARGET_64BIT")])
-(define_mode_macro P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")])
+(define_mode_iterator DP  [(TI "TARGET_64BIT") (DI "!TARGET_64BIT")])
+(define_mode_iterator P [(DI "TARGET_64BIT") (SI "!TARGET_64BIT")])
 
-;; This mode macro allows the QI and HI patterns to be defined from
+;; This mode iterator allows the QI and HI patterns to be defined from
 ;; the same template.
-(define_mode_macro HQI [HI QI])
+(define_mode_iterator HQI [HI QI])
 
-;; This mode macro allows the integer patterns to be defined from the
+;; This mode iterator allows the integer patterns to be defined from the
 ;; same template.
-(define_mode_macro INT [(DI "TARGET_64BIT") SI HI QI])
+(define_mode_iterator INT [(DI "TARGET_64BIT") SI HI QI])
 
-;; This macro allows to unify all 'bCOND' expander patterns.
-(define_code_macro COMPARE [eq ne gt gtu lt ltu ge geu le leu unordered 
+;; This iterator allows to unify all 'bCOND' expander patterns.
+(define_code_iterator COMPARE [eq ne gt gtu lt ltu ge geu le leu unordered 
                            ordered uneq unlt ungt unle unge ltgt])
 
-;; This macro allows to unify all 'sCOND' patterns.
-(define_code_macro SCOND [ltu gtu leu geu])
+;; This iterator allows to unify all 'sCOND' patterns.
+(define_code_iterator SCOND [ltu gtu leu geu])
 
-;; This macro allows some 'ashift' and 'lshiftrt' pattern to be defined from
+;; This iterator allows some 'ashift' and 'lshiftrt' pattern to be defined from
 ;; the same template.
-(define_code_macro SHIFT [ashift lshiftrt])
+(define_code_iterator SHIFT [ashift lshiftrt])
 
-;; These macros allow to combine most atomic operations.
-(define_code_macro ATOMIC [and ior xor plus minus mult])
+;; This iterator and attribute allow to combine most atomic operations.
+(define_code_iterator ATOMIC [and ior xor plus minus mult])
 (define_code_attr atomic [(and "and") (ior "ior") (xor "xor") 
                          (plus "add") (minus "sub") (mult "nand")])
 
 (define_mode_attr RXe [(TF "RXE") (DF "RX") (SF "RX")])
 
 ;; The decimal floating point variants of add, sub, div and mul support 3
-;; fp register operands.  The following macros allow to merge the bfp and
+;; fp register operands.  The following attributes allow to merge the bfp and
 ;; dfp variants in a single insn definition.
 
-;; This macro is used to set op_type accordingly.
+;; This attribute is used to set op_type accordingly.
 (define_mode_attr RRer [(TF "RRE") (DF "RRE") (SF "RRE") (TD "RRR") 
                         (DD "RRR") (SD "RRR")])
 
-;; This macro is used in the operand constraint list in order to have the 
+;; This attribute is used in the operand constraint list in order to have the 
 ;; first and the second operand match for bfp modes.
 (define_mode_attr f0 [(TF "0") (DF "0") (SF "0") (TD "f") (DD "f") (DD "f")])
 
-;; This macro is used in the operand list of the instruction to have an 
+;; This attribute is used in the operand list of the instruction to have an 
 ;; additional operand for the dfp instructions.
 (define_mode_attr op1 [(TF "") (DF "") (SF "")
                        (TD "%1,") (DD "%1,") (SD "%1,")])
 ;; This is used to disable the memory alternative in TFmode patterns.
 (define_mode_attr Rf [(TF "f") (DF "R") (SF "R") (TD "f") (DD "f") (SD "f")])
 
-;; This macro adds b for bfp instructions and t for dfp instructions and is used
+;; This attribute adds b for bfp instructions and t for dfp instructions and is used
 ;; within instruction mnemonics.
 (define_mode_attr bt [(TF "b") (DF "b") (SF "b") (TD "t") (DD "t") (SD "t")])
 
 {
   /* Make it explicit that loading a register from memory
      always sign-extends (at least) to SImode.  */
-  if (optimize && !no_new_pseudos
+  if (optimize && can_create_pseudo_p ()
       && register_operand (operands[0], VOIDmode)
       && GET_CODE (operands[1]) == MEM)
     {
 {
   /* On z/Architecture, zero-extending from memory to register
      is just as fast as a QImode load.  */
-  if (TARGET_ZARCH && optimize && !no_new_pseudos
+  if (TARGET_ZARCH && optimize && can_create_pseudo_p ()
       && register_operand (operands[0], VOIDmode)
       && GET_CODE (operands[1]) == MEM)
     {
     FAIL;
 
   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
-  if (no_new_pseudos)
+  if (!can_create_pseudo_p ())
     {
       if (GET_CODE (XEXP (operands[1], 0)) == REG)
        {
 
   operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
 
-  if (no_new_pseudos)
+  if (!can_create_pseudo_p ())
     {
       if (GET_CODE (XEXP (operands[0], 0)) == REG)
        {
 ; Test data class.
 ;
 
+(define_expand "signbit<mode>2"
+  [(set (reg:CCZ CC_REGNUM)
+        (unspec:CCZ [(match_operand:BFP 1 "register_operand" "f") 
+                     (match_dup 2)] 
+                     UNSPEC_TDC_INSN))
+   (set (match_operand:SI 0 "register_operand" "=d")
+        (unspec:SI [(reg:CCZ CC_REGNUM)] UNSPEC_CCZ_TO_INT))]
+  "TARGET_HARD_FLOAT"
+{
+  operands[2] = GEN_INT (S390_TDC_SIGNBIT_SET);
+})
+
 (define_expand "isinf<mode>2"
   [(set (reg:CCZ CC_REGNUM)
         (unspec:CCZ [(match_operand:BFP 1 "register_operand" "f") 
   REAL_VALUE_TYPE cmp, sub;
   
   operands[1] = force_reg (<BFP:MODE>mode, operands[1]);
-  real_2expN (&cmp, GET_MODE_BITSIZE(<GPR:MODE>mode) - 1);
-  real_2expN (&sub, GET_MODE_BITSIZE(<GPR:MODE>mode));
+  real_2expN (&cmp, GET_MODE_BITSIZE(<GPR:MODE>mode) - 1, <BFP:mode>mode);
+  real_2expN (&sub, GET_MODE_BITSIZE(<GPR:MODE>mode), <BFP:mode>mode);
   
   emit_insn (gen_cmp<BFP:mode> (operands[1],
        CONST_DOUBLE_FROM_REAL_VALUE (cmp, <BFP:MODE>mode)));
                         (match_dup 7)))
      (set (match_dup 6) (plus:DI (match_dup 7) (match_dup 8)))])
    (parallel
-    [(set (match_dup 3) (plus:DI (plus:DI (match_dup 4) (match_dup 5))
-                                 (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0))))
+    [(set (match_dup 3) (plus:DI
+                          (plus:DI (ltu:DI (reg:CCL1 CC_REGNUM) (const_int 0))
+                                   (match_dup 4)) (match_dup 5)))
      (clobber (reg:CC CC_REGNUM))])]
   "operands[3] = operand_subword (operands[0], 0, 0, TImode);
    operands[4] = operand_subword (operands[1], 0, 0, TImode);
                         (match_dup 7)))
      (set (match_dup 6) (plus:SI (match_dup 7) (match_dup 8)))])
    (parallel
-    [(set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5))
-                                 (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0))))
+    [(set (match_dup 3) (plus:SI
+                         (plus:SI (ltu:SI (reg:CCL1 CC_REGNUM) (const_int 0))
+                                  (match_dup 4)) (match_dup 5)))
      (clobber (reg:CC CC_REGNUM))])]
   "operands[3] = operand_subword (operands[0], 0, 0, DImode);
    operands[4] = operand_subword (operands[1], 0, 0, DImode);
 ; add(di|si)cc instruction pattern(s).
 ;
 
+; the following 4 patterns are used when the result of an add with
+; carry is checked for an overflow condition
+
+; op1 + op2 + c < op1
+
+; alcr, alc, alcgr, alcg
+(define_insn "*add<mode>3_alc_carry1_cc"
+  [(set (reg CC_REGNUM)
+        (compare
+          (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
+                              (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
+                    (match_operand:GPR 2 "general_operand" "d,m"))
+          (match_dup 1)))
+   (set (match_operand:GPR 0 "register_operand" "=d,d")
+        (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
+  "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
+  "@
+   alc<g>r\t%0,%2
+   alc<g>\t%0,%2"
+  [(set_attr "op_type"  "RRE,RXY")])
+
+; alcr, alc, alcgr, alcg
+(define_insn "*add<mode>3_alc_carry1_cconly"
+  [(set (reg CC_REGNUM)
+        (compare
+          (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
+                              (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
+                    (match_operand:GPR 2 "general_operand" "d,m"))
+          (match_dup 1)))
+   (clobber (match_scratch:GPR 0 "=d,d"))]
+  "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
+  "@
+   alc<g>r\t%0,%2
+   alc<g>\t%0,%2"
+  [(set_attr "op_type"  "RRE,RXY")])
+
+; op1 + op2 + c < op2
+
+; alcr, alc, alcgr, alcg
+(define_insn "*add<mode>3_alc_carry2_cc"
+  [(set (reg CC_REGNUM)
+        (compare
+          (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
+                              (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
+                    (match_operand:GPR 2 "general_operand" "d,m"))
+          (match_dup 2)))
+   (set (match_operand:GPR 0 "register_operand" "=d,d")
+        (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
+  "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
+  "@
+   alc<g>r\t%0,%2
+   alc<g>\t%0,%2"
+  [(set_attr "op_type"  "RRE,RXY")])
+
+; alcr, alc, alcgr, alcg
+(define_insn "*add<mode>3_alc_carry2_cconly"
+  [(set (reg CC_REGNUM)
+        (compare
+          (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
+                              (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
+                    (match_operand:GPR 2 "general_operand" "d,m"))
+          (match_dup 2)))
+   (clobber (match_scratch:GPR 0 "=d,d"))]
+  "s390_match_ccmode (insn, CCL1mode) && TARGET_CPU_ZARCH"
+  "@
+   alc<g>r\t%0,%2
+   alc<g>\t%0,%2"
+  [(set_attr "op_type"  "RRE,RXY")])
+
 ; alcr, alc, alcgr, alcg
 (define_insn "*add<mode>3_alc_cc"
   [(set (reg CC_REGNUM)
         (compare
-          (plus:GPR (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0")
-                              (match_operand:GPR 2 "general_operand" "d,m"))
-                    (match_operand:GPR 3 "s390_alc_comparison" ""))
+          (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
+                              (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
+                    (match_operand:GPR 2 "general_operand" "d,m"))
           (const_int 0)))
    (set (match_operand:GPR 0 "register_operand" "=d,d")
-        (plus:GPR (plus:GPR (match_dup 1) (match_dup 2)) (match_dup 3)))]
+        (plus:GPR (plus:GPR (match_dup 3) (match_dup 1)) (match_dup 2)))]
   "s390_match_ccmode (insn, CCLmode) && TARGET_CPU_ZARCH"
   "@
    alc<g>r\t%0,%2
 ; alcr, alc, alcgr, alcg
 (define_insn "*add<mode>3_alc"
   [(set (match_operand:GPR 0 "register_operand" "=d,d")
-        (plus:GPR (plus:GPR (match_operand:GPR 1 "nonimmediate_operand" "%0,0")
-                            (match_operand:GPR 2 "general_operand" "d,m"))
-                  (match_operand:GPR 3 "s390_alc_comparison" "")))
+        (plus:GPR (plus:GPR (match_operand:GPR 3 "s390_alc_comparison" "")
+                            (match_operand:GPR 1 "nonimmediate_operand" "%0,0"))
+                  (match_operand:GPR 2 "general_operand" "d,m")))
    (clobber (reg:CC CC_REGNUM))]
   "TARGET_CPU_ZARCH"
   "@
   "&& reload_completed"
   [(set (match_dup 0) (const_int 0))
    (parallel
-    [(set (match_dup 0) (plus:GPR (plus:GPR (match_dup 0) (match_dup 0))
-                                  (match_dup 1)))
+    [(set (match_dup 0) (plus:GPR (plus:GPR (match_dup 1) (match_dup 0))
+                                  (match_dup 0)))
      (clobber (reg:CC CC_REGNUM))])]
   "")
 
   "s390_match_ccmode(insn, CCTmode) && TARGET_64BIT"
   "@
    xgr\t%0,%2
-   xr\t%0,%2"
+   xg\t%0,%2"
   [(set_attr "op_type"  "RRE,RXY")])
 
 (define_insn "*xordi3_extimm"