OSDN Git Service

More MIPS vector cleanup work.
[pf3gnuchains/gcc-fork.git] / gcc / config / mips / mips.md
index 037ee04..54bc7c3 100644 (file)
 ;; fmadd       floating point multiply-add
 ;; fdiv                floating point divide
 ;; frdiv       floating point reciprocal divide
+;; frdiv1      floating point reciprocal divide step 1
+;; frdiv2      floating point reciprocal divide step 2
 ;; fabs                floating point absolute value
 ;; fneg                floating point negation
 ;; fcmp                floating point compare
 ;; fcvt                floating point convert
 ;; fsqrt       floating point square root
 ;; frsqrt       floating point reciprocal square root
+;; frsqrt1      floating point reciprocal square root step1
+;; frsqrt2      floating point reciprocal square root step2
 ;; multi       multiword sequence (or user asm statements)
 ;; nop         no operation
 (define_attr "type"
-  "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,xfer,mthilo,mfhilo,const,arith,shift,slt,clz,trap,imul,imadd,idiv,fmove,fadd,fmul,fmadd,fdiv,frdiv,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,multi,nop"
+  "unknown,branch,jump,call,load,fpload,fpidxload,store,fpstore,fpidxstore,prefetch,prefetchx,condmove,xfer,mthilo,mfhilo,const,arith,shift,slt,clz,trap,imul,imadd,idiv,fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,frsqrt,frsqrt1,frsqrt2,multi,nop"
   (cond [(eq_attr "jal" "!unset") (const_string "call")
         (eq_attr "got" "load") (const_string "load")]
        (const_string "unknown")))
 ;; from the same template.
 (define_code_macro any_shift [ashift ashiftrt lshiftrt])
 
+;; This code macro allows all native floating-point comparisons to be
+;; generated from the same template.
+(define_code_macro fcond [unordered uneq unlt unle eq lt le])
+
 ;; <u> expands to an empty string when doing a signed operation and
 ;; "u" when doing an unsigned operation.
 (define_code_attr u [(sign_extend "") (zero_extend "u")])
 (define_code_attr insn [(ashift "sll")
                        (ashiftrt "sra")
                        (lshiftrt "srl")])
+
+;; <fcond> is the c.cond.fmt condition associated with a particular code.
+(define_code_attr fcond [(unordered "un")
+                        (uneq "ueq")
+                        (unlt "ult")
+                        (unle "ule")
+                        (eq "eq")
+                        (lt "lt")
+                        (le "le")])
 \f
 ;; .........................
 ;;
@@ -3090,12 +3107,15 @@ beq\t%2,%.,1b\;\
 ;;     dsll    op0,op0,16
 ;;     daddiu  op0,op0,%hi(op1)
 ;;     dsll    op0,op0,16
+;;
+;; The split is deferred until after flow2 to allow the peephole2 below
+;; to take effect.
 (define_insn_and_split "*lea_high64"
   [(set (match_operand:DI 0 "register_operand" "=d")
        (high:DI (match_operand:DI 1 "general_symbolic_operand" "")))]
   "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
   "#"
-  "&& reload_completed"
+  "&& flow2_completed"
   [(set (match_dup 0) (high:DI (match_dup 2)))
    (set (match_dup 0) (lo_sum:DI (match_dup 0) (match_dup 2)))
    (set (match_dup 0) (ashift:DI (match_dup 0) (const_int 16)))
@@ -3107,6 +3127,29 @@ beq\t%2,%.,1b\;\
 }
   [(set_attr "length" "20")])
 
+;; Use a scratch register to reduce the latency of the above pattern
+;; on superscalar machines.  The optimized sequence is:
+;;
+;;     lui     op1,%highest(op2)
+;;     lui     op0,%hi(op2)
+;;     daddiu  op1,op1,%higher(op2)
+;;     dsll32  op1,op1,0
+;;     daddu   op1,op1,op0
+(define_peephole2
+  [(match_scratch:DI 0 "d")
+   (set (match_operand:DI 1 "register_operand")
+       (high:DI (match_operand:DI 2 "general_symbolic_operand")))]
+  "TARGET_EXPLICIT_RELOCS && ABI_HAS_64BIT_SYMBOLS"
+  [(set (match_dup 1) (high:DI (match_dup 3)))
+   (set (match_dup 0) (high:DI (match_dup 4)))
+   (set (match_dup 1) (lo_sum:DI (match_dup 1) (match_dup 3)))
+   (set (match_dup 1) (ashift:DI (match_dup 1) (const_int 32)))
+   (set (match_dup 1) (plus:DI (match_dup 1) (match_dup 0)))]
+{
+  operands[3] = mips_unspec_address (operands[2], SYMBOL_64_HIGH);
+  operands[4] = mips_unspec_address (operands[2], SYMBOL_64_LOW);
+})
+
 ;; On most targets, the expansion of (lo_sum (high X) X) for a 64-bit
 ;; SYMBOL_GENERAL X will take 6 cycles.  This next pattern allows combine
 ;; to merge the HIGH and LO_SUM parts of a move if the HIGH part is only
@@ -4233,10 +4276,9 @@ beq\t%2,%.,1b\;\
                      (match_operand:SI 2 "arith_operand" "dI")))]
   "ISA_HAS_ROTR_<MODE>"
 {
-  if ((GET_CODE (operands[2]) == CONST_INT)
-      && (INTVAL (operands[2]) < 0
-         || INTVAL (operands[2]) >= GET_MODE_BITSIZE (<MODE>mode)))
-    abort ();
+  if (GET_CODE (operands[2]) == CONST_INT)
+    gcc_assert (INTVAL (operands[2]) >= 0
+               && INTVAL (operands[2]) < GET_MODE_BITSIZE (<MODE>mode));
 
   return "<d>ror\t%0,%1,%2";
 }
@@ -4731,165 +4773,30 @@ beq\t%2,%.,1b\;\
 ;;
 ;;  ....................
 
-(define_insn "sunordered_df"
-  [(set (match_operand:CC 0 "register_operand" "=z")
-       (unordered:CC (match_operand:DF 1 "register_operand" "f")
-                     (match_operand:DF 2 "register_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
-  "c.un.d\t%Z0%1,%2"
-  [(set_attr "type" "fcmp")
-   (set_attr "mode" "FPSW")])
-
-(define_insn "sunlt_df"
-  [(set (match_operand:CC 0 "register_operand" "=z")
-       (unlt:CC (match_operand:DF 1 "register_operand" "f")
-                (match_operand:DF 2 "register_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
-  "c.ult.d\t%Z0%1,%2"
-  [(set_attr "type" "fcmp")
-   (set_attr "mode" "FPSW")])
-
-(define_insn "suneq_df"
-  [(set (match_operand:CC 0 "register_operand" "=z")
-       (uneq:CC (match_operand:DF 1 "register_operand" "f")
-                (match_operand:DF 2 "register_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
-  "c.ueq.d\t%Z0%1,%2"
-  [(set_attr "type" "fcmp")
-   (set_attr "mode" "FPSW")])
-
-(define_insn "sunle_df"
-  [(set (match_operand:CC 0 "register_operand" "=z")
-       (unle:CC (match_operand:DF 1 "register_operand" "f")
-                (match_operand:DF 2 "register_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
-  "c.ule.d\t%Z0%1,%2"
-  [(set_attr "type" "fcmp")
-   (set_attr "mode" "FPSW")])
-
-(define_insn "seq_df"
-  [(set (match_operand:CC 0 "register_operand" "=z")
-       (eq:CC (match_operand:DF 1 "register_operand" "f")
-              (match_operand:DF 2 "register_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
-  "c.eq.d\t%Z0%1,%2"
-  [(set_attr "type" "fcmp")
-   (set_attr "mode" "FPSW")])
-
-(define_insn "slt_df"
-  [(set (match_operand:CC 0 "register_operand" "=z")
-       (lt:CC (match_operand:DF 1 "register_operand" "f")
-              (match_operand:DF 2 "register_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
-  "c.lt.d\t%Z0%1,%2"
-  [(set_attr "type" "fcmp")
-   (set_attr "mode" "FPSW")])
-
-(define_insn "sle_df"
-  [(set (match_operand:CC 0 "register_operand" "=z")
-       (le:CC (match_operand:DF 1 "register_operand" "f")
-              (match_operand:DF 2 "register_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
-  "c.le.d\t%Z0%1,%2"
-  [(set_attr "type" "fcmp")
-   (set_attr "mode" "FPSW")])
-
-(define_insn "sgt_df"
+(define_insn "s<code>_<mode>"
   [(set (match_operand:CC 0 "register_operand" "=z")
-       (gt:CC (match_operand:DF 1 "register_operand" "f")
-              (match_operand:DF 2 "register_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
-  "c.lt.d\t%Z0%2,%1"
-  [(set_attr "type" "fcmp")
-   (set_attr "mode" "FPSW")])
-
-(define_insn "sge_df"
-  [(set (match_operand:CC 0 "register_operand" "=z")
-       (ge:CC (match_operand:DF 1 "register_operand" "f")
-              (match_operand:DF 2 "register_operand" "f")))]
-  "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
-  "c.le.d\t%Z0%2,%1"
-  [(set_attr "type" "fcmp")
-   (set_attr "mode" "FPSW")])
-
-(define_insn "sunordered_sf"
-  [(set (match_operand:CC 0 "register_operand" "=z")
-       (unordered:CC (match_operand:SF 1 "register_operand" "f")
-                     (match_operand:SF 2 "register_operand" "f")))]
-  "TARGET_HARD_FLOAT"
-  "c.un.s\t%Z0%1,%2"
-  [(set_attr "type" "fcmp")
-   (set_attr "mode" "FPSW")])
-
-(define_insn "sunlt_sf"
-  [(set (match_operand:CC 0 "register_operand" "=z")
-       (unlt:CC (match_operand:SF 1 "register_operand" "f")
-                (match_operand:SF 2 "register_operand" "f")))]
-  "TARGET_HARD_FLOAT"
-  "c.ult.s\t%Z0%1,%2"
-  [(set_attr "type" "fcmp")
-   (set_attr "mode" "FPSW")])
-
-(define_insn "suneq_sf"
-  [(set (match_operand:CC 0 "register_operand" "=z")
-       (uneq:CC (match_operand:SF 1 "register_operand" "f")
-                (match_operand:SF 2 "register_operand" "f")))]
-  "TARGET_HARD_FLOAT"
-  "c.ueq.s\t%Z0%1,%2"
-  [(set_attr "type" "fcmp")
-   (set_attr "mode" "FPSW")])
-
-(define_insn "sunle_sf"
-  [(set (match_operand:CC 0 "register_operand" "=z")
-       (unle:CC (match_operand:SF 1 "register_operand" "f")
-                (match_operand:SF 2 "register_operand" "f")))]
-  "TARGET_HARD_FLOAT"
-  "c.ule.s\t%Z0%1,%2"
-  [(set_attr "type" "fcmp")
-   (set_attr "mode" "FPSW")])
-
-(define_insn "seq_sf"
-  [(set (match_operand:CC 0 "register_operand" "=z")
-       (eq:CC (match_operand:SF 1 "register_operand" "f")
-              (match_operand:SF 2 "register_operand" "f")))]
-  "TARGET_HARD_FLOAT"
-  "c.eq.s\t%Z0%1,%2"
-  [(set_attr "type" "fcmp")
-   (set_attr "mode" "FPSW")])
-
-(define_insn "slt_sf"
-  [(set (match_operand:CC 0 "register_operand" "=z")
-       (lt:CC (match_operand:SF 1 "register_operand" "f")
-              (match_operand:SF 2 "register_operand" "f")))]
-  "TARGET_HARD_FLOAT"
-  "c.lt.s\t%Z0%1,%2"
-  [(set_attr "type" "fcmp")
-   (set_attr "mode" "FPSW")])
-
-(define_insn "sle_sf"
-  [(set (match_operand:CC 0 "register_operand" "=z")
-       (le:CC (match_operand:SF 1 "register_operand" "f")
-              (match_operand:SF 2 "register_operand" "f")))]
-  "TARGET_HARD_FLOAT"
-  "c.le.s\t%Z0%1,%2"
+       (fcond:CC (match_operand:SCALARF 1 "register_operand" "f")
+                 (match_operand:SCALARF 2 "register_operand" "f")))]
+  ""
+  "c.<fcond>.<fmt>\t%Z0%1,%2"
   [(set_attr "type" "fcmp")
    (set_attr "mode" "FPSW")])
 
-(define_insn "sgt_sf"
+(define_insn "sgt_<mode>"
   [(set (match_operand:CC 0 "register_operand" "=z")
-       (gt:CC (match_operand:SF 1 "register_operand" "f")
-              (match_operand:SF 2 "register_operand" "f")))]
-  "TARGET_HARD_FLOAT"
-  "c.lt.s\t%Z0%2,%1"
+       (gt:CC (match_operand:SCALARF 1 "register_operand" "f")
+              (match_operand:SCALARF 2 "register_operand" "f")))]
+  ""
+  "c.lt.<fmt>\t%Z0%2,%1"
   [(set_attr "type" "fcmp")
    (set_attr "mode" "FPSW")])
 
-(define_insn "sge_sf"
+(define_insn "sge_<mode>"
   [(set (match_operand:CC 0 "register_operand" "=z")
-       (ge:CC (match_operand:SF 1 "register_operand" "f")
-              (match_operand:SF 2 "register_operand" "f")))]
-  "TARGET_HARD_FLOAT"
-  "c.le.s\t%Z0%2,%1"
+       (ge:CC (match_operand:SCALARF 1 "register_operand" "f")
+              (match_operand:SCALARF 2 "register_operand" "f")))]
+  ""
+  "c.le.<fmt>\t%Z0%2,%1"
   [(set_attr "type" "fcmp")
    (set_attr "mode" "FPSW")])
 \f
@@ -5575,8 +5482,7 @@ beq\t%2,%.,1b\;\
 {
   REAL_VALUE_TYPE d;
 
-  if (GET_CODE (operands[0]) != CONST_DOUBLE)
-    abort ();
+  gcc_assert (GET_CODE (operands[0]) == CONST_DOUBLE);
   REAL_VALUE_FROM_CONST_DOUBLE (d, operands[0]);
   assemble_real (d, GET_MODE (operands[0]),
                 GET_MODE_BITSIZE (GET_MODE (operands[0])));