aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>1998-05-11 01:31:20 -0700
committerRichard Henderson <rth@gcc.gnu.org>1998-05-11 01:31:20 -0700
commite83015a9b5df840bb010174df94c170c842676cd (patch)
treea574426b3ec9ad03f3bce70fbba0368bfa25c0da
parent830bfa74b082c1cd0d5550ee4f0f4364f46f1a0a (diff)
downloadgcc-e83015a9b5df840bb010174df94c170c842676cd.zip
gcc-e83015a9b5df840bb010174df94c170c842676cd.tar.gz
gcc-e83015a9b5df840bb010174df94c170c842676cd.tar.bz2
alpha.h (PRINT_OPERAND_PUNCT_VALID_P): Add '`'.
* 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
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/alpha/alpha.c20
-rw-r--r--gcc/config/alpha/alpha.h9
-rw-r--r--gcc/config/alpha/alpha.md132
4 files changed, 165 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 99d6cc9..b0d3d45 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index a3658125..45e725d 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -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:
diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h
index 8f3f1b4..bb762fb 100644
--- a/gcc/config/alpha/alpha.h
+++ b/gcc/config/alpha/alpha.h
@@ -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) == '-')
/* 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 ();
-
diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md
index 7990f20..3538b48 100644
--- a/gcc/config/alpha/alpha.md
+++ b/gcc/config/alpha/alpha.md
@@ -28,6 +28,7 @@
;; 2 insxh
;; 3 mskxh
;; 4 cvtlq
+;; 5 cvtql
;;
;; UNSPEC_VOLATILE:
;;
@@ -1769,6 +1770,62 @@
[(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")))]
@@ -1785,6 +1842,56 @@
[(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
@@ -4986,3 +5093,28 @@
""
"trapb"
[(set_attr "type" "misc")])
+
+;; 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")