alpha.h (PRINT_OPERAND_PUNCT_VALID_P): Add '`'.
authorRichard Henderson <rth@cygnus.com>
Mon, 11 May 1998 08:31:20 +0000 (01:31 -0700)
committerRichard Henderson <rth@gcc.gnu.org>
Mon, 11 May 1998 08:31:20 +0000 (01:31 -0700)
        * alpha.h (PRINT_OPERAND_PUNCT_VALID_P): Add '`'.
        * alpha.c (print_operand): Handle it.
        * alpha.md (fix_truncdfsi2, fix_truncsfsi2): New patterns and
        related define_splits.  Also add peepholes for SImode reload
        plus sign_extend lossage.

From-SVN: r19664

gcc/ChangeLog
gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.h
gcc/config/alpha/alpha.md

index 99d6cc93f46e0767c8f42d668a99541d33df17e9..b0d3d45c02af292b5ed6d823b463a0eb116e5164 100644 (file)
@@ -1,3 +1,11 @@
+Mon May 11 08:24:18 1998  Richard Henderson <rth@cygnus.com>
+
+       * alpha.h (PRINT_OPERAND_PUNCT_VALID_P): Add '`'.
+       * alpha.c (print_operand): Handle it.
+       * alpha.md (fix_truncdfsi2, fix_truncsfsi2): New patterns and 
+       related define_splits.  Also add peepholes for SImode reload
+       plus sign_extend lossage.
+
 Mon May 11 09:33:10 1998  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu>
 
         * genattr.c: Include stdarg.h/varargs.h.  Change function
index a36581255598726d6db6c32159a25a86bbcc2f7a..45e725dcaa401b600ad592615b6f545c93e39e89 100644 (file)
@@ -2496,6 +2496,23 @@ print_operand (file, x, code)
        fputs ("su", file);
       break;
 
+    case '`':
+      /* Generates trap-mode suffix for instructions that accept the
+        v and sv suffix.  The only instruction that needs this is cvtql.  */
+      switch (alpha_fptm)
+       {
+       case ALPHA_FPTM_N:
+         break;
+       case ALPHA_FPTM_U:
+         fputs ("v", file);
+         break;
+       case ALPHA_FPTM_SU:
+       case ALPHA_FPTM_SUI:
+         fputs ("sv", file);
+         break;
+       }
+      break;
+
     case '(':
       /* Generates trap-mode suffix for instructions that accept the
         v, sv, and svi suffix.  The only instruction that needs this
@@ -2541,7 +2558,8 @@ print_operand (file, x, code)
         suffix (cvtqt and cvtqs).  */
       switch (alpha_fptm)
        {
-       case ALPHA_FPTM_N: case ALPHA_FPTM_U:
+       case ALPHA_FPTM_N:
+       case ALPHA_FPTM_U:
        case ALPHA_FPTM_SU:     /* cvtqt/cvtqs can't cause underflow */
          break;
        case ALPHA_FPTM_SUI:
index 8f3f1b42b2067f164053898b79707a419a09de7d..bb762fb0e2b047c82cae3aa78ef7f1c60702b131 100644 (file)
@@ -1076,6 +1076,7 @@ extern int alpha_memory_latency;
    insns and emitted.  */
 extern struct rtx_def *alpha_emit_set_const ();
 extern struct rtx_def *alpha_emit_set_long_const ();
+extern struct rtx_def *alpha_emit_conditional_branch ();
 extern struct rtx_def *alpha_emit_conditional_move ();
 
 /* Generate necessary RTL for __builtin_saveregs().
@@ -2184,6 +2185,9 @@ do {                                                                      \
    '   Generates trap-mode suffix for instructions that accept the
         su suffix only (cmpt et al).
 
+   `    Generates trap-mode suffix for instructions that accept the
+       v and sv suffix.  The only instruction that needs this is cvtql.
+
    (   Generates trap-mode suffix for instructions that accept the
        v, sv, and svi suffix.  The only instruction that needs this
        is cvttq.
@@ -2203,8 +2207,8 @@ do {                                                                      \
    */
 
 #define PRINT_OPERAND_PUNCT_VALID_P(CODE)                              \
-  ((CODE) == '&' || (CODE) == '\'' || (CODE) == '(' || (CODE) == ')'   \
-   || (CODE) == '+' || (CODE) == ',' || (CODE) == '-')
+  ((CODE) == '&' || (CODE) == '`' || (CODE) == '\'' || (CODE) == '('   \
+   || (CODE) == ')' || (CODE) == '+' || (CODE) == ',' || (CODE) == '-')
 \f
 /* Print a memory address as an operand to reference that memory location.  */
 
@@ -2419,4 +2423,3 @@ do {                                                      \
 
 /* Prototypes for alpha.c functions used in the md file.  */
 extern struct rtx_def *get_unaligned_address ();
index 7990f20e747e87461af53352ceea6a1fcb06a2ae..3538b48a60c720cb344ad6ec827ac449259f8867 100644 (file)
@@ -28,6 +28,7 @@
 ;;     2       insxh
 ;;     3       mskxh
 ;;     4       cvtlq
+;;     5       cvtql
 ;;     
 ;; UNSPEC_VOLATILE:
 ;;
   [(set_attr "type" "fadd")
    (set_attr "trap" "yes")])
 
+;; Define conversion operators between DFmode and SImode, using the cvtql
+;; instruction.  To allow combine et al to do useful things, we keep the
+;; operation as a unit until after reload, at which point we split the
+;; instructions.
+
+(define_split
+  [(set (match_operand:SI 0 "register_operand" "")
+       (fix:SI (match_operand:DF 1 "reg_or_fp0_operand" "")))
+   (clobber (match_scratch:DI 2 ""))]
+  "TARGET_FP && reload_completed"
+  [(set (match_dup 2) (fix:DI (match_dup 1)))
+   (set (match_dup 0) (unspec:SI [(match_dup 2)] 5))]
+  "")
+
+;; Due to issues with CLASS_CANNOT_CHANGE_SIZE, we cannot use a subreg here.
+(define_split
+  [(set (match_operand:SI 0 "register_operand" "")
+       (fix:SI (match_operand:DF 1 "reg_or_fp0_operand" "")))]
+  "TARGET_FP && reload_completed"
+  [(set (match_dup 2) (fix:DI (match_dup 1)))
+   (set (match_dup 0) (unspec:SI [(match_dup 2)] 5))]
+  "operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));")
+
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=f")
+       (unspec:SI [(match_operand:DI 1 "reg_or_fp0_operand" "fG")] 5))]
+  "TARGET_FP"
+  "cvtql%` %R1,%0"
+  [(set_attr "type" "fadd")
+   (set_attr "trap" "yes")])
+
+(define_insn "fix_truncdfsi2_tp"
+  [(set (match_operand:SI 0 "register_operand" "=&f")
+       (fix:SI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))
+   (clobber (match_scratch:DI 2 "=&f"))]
+  "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
+  "#"
+  [(set_attr "type" "fadd")
+   (set_attr "trap" "yes")])
+
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=f")
+       (fix:SI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
+  "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
+  "#"
+  [(set_attr "type" "fadd")
+   (set_attr "trap" "yes")])
+
+(define_expand "fix_truncdfsi2"
+  [(set (match_operand:SI 0 "register_operand" "=f")
+       (fix:SI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
+  "TARGET_FP"
+  "{ if (alpha_tp == ALPHA_TP_INSN)
+       { emit_insn(gen_fix_truncdfsi2_tp(operands[0], operands[1])); DONE; }
+   }")
+
 (define_insn ""
   [(set (match_operand:DI 0 "register_operand" "=&f")
        (fix:DI (match_operand:DF 1 "reg_or_fp0_operand" "fG")))]
   [(set_attr "type" "fadd")
    (set_attr "trap" "yes")])
 
+;; Likewise between SFmode and SImode.
+
+(define_split
+  [(set (match_operand:SI 0 "register_operand" "")
+       (fix:SI (float_extend:DF
+                (match_operand:SF 1 "reg_or_fp0_operand" ""))))
+   (clobber (match_scratch:DI 2 ""))]
+  "TARGET_FP && reload_completed"
+  [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
+   (set (match_dup 0) (unspec:SI [(match_dup 2)] 5))]
+  "")
+
+;; Due to issues with CLASS_CANNOT_CHANGE_SIZE, we cannot use a subreg here.
+(define_split
+  [(set (match_operand:SI 0 "register_operand" "")
+       (fix:SI (float_extend:DF
+                (match_operand:SF 1 "reg_or_fp0_operand" ""))))]
+  "TARGET_FP && reload_completed"
+  [(set (match_dup 2) (fix:DI (float_extend:DF (match_dup 1))))
+   (set (match_dup 0) (unspec:SI [(match_dup 2)] 5))]
+  "operands[2] = gen_rtx_REG (DImode, REGNO (operands[0]));")
+
+(define_insn "fix_truncsfsi2_tp"
+  [(set (match_operand:SI 0 "register_operand" "=&f")
+       (fix:SI (float_extend:DF
+                (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))
+   (clobber (match_scratch:DI 2 "=&f"))]
+  "TARGET_FP && alpha_tp == ALPHA_TP_INSN"
+  "#"
+  [(set_attr "type" "fadd")
+   (set_attr "trap" "yes")])
+
+(define_insn ""
+  [(set (match_operand:SI 0 "register_operand" "=f")
+       (fix:SI (float_extend:DF
+                (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
+  "TARGET_FP && alpha_tp != ALPHA_TP_INSN"
+  "#"
+  [(set_attr "type" "fadd")
+   (set_attr "trap" "yes")])
+
+(define_expand "fix_truncsfsi2"
+  [(set (match_operand:SI 0 "register_operand" "=f")
+       (fix:SI (float_extend:DF
+                (match_operand:SF 1 "reg_or_fp0_operand" "fG"))))]
+  "TARGET_FP"
+  "{ if (alpha_tp == ALPHA_TP_INSN)
+       { emit_insn(gen_fix_truncsfsi2_tp(operands[0], operands[1])); DONE; }
+   }")
+
 (define_insn ""
   [(set (match_operand:DI 0 "register_operand" "=&f")
        (fix:DI (float_extend:DF
   ""
   "trapb"
   [(set_attr "type" "misc")])
+\f
+;; Peepholes go at the end.
+
+;; Optimize sign-extension of SImode loads.  This shows up in the wake of
+;; reload when converting fp->int.
+;;
+;; ??? What to do when we are actually caring about the packing and
+;; alignment of instructions?  Perhaps reload can be enlightened, or
+;; the peephole pass moved up after reload but before sched2.
+
+(define_peephole
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (match_operand:SI 1 "memory_operand" "m"))
+   (set (match_operand:DI 2 "register_operand" "=r")
+        (sign_extend:DI (match_dup 0)))]
+  "dead_or_set_p (insn, operands[0])"
+  "ldl %2,%1")
+
+(define_peephole
+  [(set (match_operand:SI 0 "register_operand" "=r")
+        (match_operand:SI 1 "hard_fp_register_operand" "f"))
+   (set (match_operand:DI 2 "register_operand" "=r")
+        (sign_extend:DI (match_dup 0)))]
+  "TARGET_CIX && dead_or_set_p (insn, operands[0])"
+  "ftois %1,%2")