diff options
author | Richard Henderson <rth@cygnus.com> | 1998-05-11 01:31:20 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 1998-05-11 01:31:20 -0700 |
commit | e83015a9b5df840bb010174df94c170c842676cd (patch) | |
tree | a574426b3ec9ad03f3bce70fbba0368bfa25c0da /gcc | |
parent | 830bfa74b082c1cd0d5550ee4f0f4364f46f1a0a (diff) | |
download | gcc-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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.c | 20 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.h | 9 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.md | 132 |
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") |