diff options
author | Richard Henderson <rth@cygnus.com> | 1998-04-04 05:54:32 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 1998-04-04 05:54:32 -0800 |
commit | 4ed43ff85a14916fd33bdf838f9c40b923e312ab (patch) | |
tree | fccd367314057d62ee9a166712156cd219f140ba /gcc | |
parent | 55a9eb72632155cf329d5307050e5b07087cd8ff (diff) | |
download | gcc-4ed43ff85a14916fd33bdf838f9c40b923e312ab.zip gcc-4ed43ff85a14916fd33bdf838f9c40b923e312ab.tar.gz gcc-4ed43ff85a14916fd33bdf838f9c40b923e312ab.tar.bz2 |
haifa-sched.c (split_block_insns): Don't supress insn splitting on subsequent passes.
* haifa-sched.c (split_block_insns): Don't supress insn splitting
on subsequent passes.
* alpha.c (hard_fp_register_operand): New function.
* alpha.h (PREDICATE_CODES): Add it.
* alpha.md (extendsidi2): Kill bogus f<-f cvtql+cvtlq case. Add an
f<-m case and accompanying define_split.
(trapb): Use a unique unspec_volatile number.
From-SVN: r18992
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.c | 12 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.h | 3 | ||||
-rw-r--r-- | gcc/config/alpha/alpha.md | 59 | ||||
-rw-r--r-- | gcc/haifa-sched.c | 42 |
5 files changed, 90 insertions, 37 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0db3735..6f36aff 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +Sat Apr 4 13:50:01 1998 Richard Henderson <rth@cygnus.com> + + * haifa-sched.c (split_block_insns): Don't supress insn splitting + on subsequent passes. + + * alpha.c (hard_fp_register_operand): New function. + * alpha.h (PREDICATE_CODES): Add it. + * alpha.md (extendsidi2): Kill bogus f<-f cvtql+cvtlq case. Add an + f<-m case and accompanying define_split. + (trapb): Use a unique unspec_volatile number. + Sat Apr 4 13:32:08 1998 Richard Henderson <rth@cygnus.com> * configure.in (alpha-*-linux-gnu*): Undo Feb 3 change brought in diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c index b926586..3888b98 100644 --- a/gcc/config/alpha/alpha.c +++ b/gcc/config/alpha/alpha.c @@ -519,6 +519,18 @@ reg_or_fp0_operand (op, mode) return fp0_operand (op, mode) || register_operand (op, mode); } +/* Return 1 if OP is a hard floating-point register. */ + +int +hard_fp_register_operand (op, mode) + register rtx op; + enum machine_mode mode; +{ + return ((GET_CODE (op) == REG && REGNO_REG_CLASS (REGNO (op)) == FLOAT_REGS) + || (GET_CODE (op) == SUBREG + && hard_fp_register_operand (SUBREG_REG (op), mode))); +} + /* Return 1 if OP is a register or a constant integer. */ diff --git a/gcc/config/alpha/alpha.h b/gcc/config/alpha/alpha.h index a2f76aa..da8f6968 100644 --- a/gcc/config/alpha/alpha.h +++ b/gcc/config/alpha/alpha.h @@ -2211,7 +2211,8 @@ do { \ {"aligned_memory_operand", {MEM}}, \ {"unaligned_memory_operand", {MEM}}, \ {"reg_or_unaligned_mem_operand", {SUBREG, REG, MEM}}, \ - {"any_memory_operand", {MEM}}, + {"any_memory_operand", {MEM}}, \ + {"hard_fp_register_operand", {SUBREG, REG}}, /* Tell collect that the object format is ECOFF. */ #define OBJECT_FORMAT_COFF diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md index 1dd05ea..93f7e5f 100644 --- a/gcc/config/alpha/alpha.md +++ b/gcc/config/alpha/alpha.md @@ -20,6 +20,23 @@ ;; Boston, MA 02111-1307, USA. ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. + +;; Uses of UNSPEC in this file: +;; +;; 0 arg_home +;; 1 cttz +;; 2 insxh +;; 3 mskxh +;; 4 cvtlq +;; +;; UNSPEC_VOLATILE: +;; +;; 0 imb +;; 1 blockage +;; 2 builtin_setjmp_receiver +;; 3 builtin_longjmp +;; 4 trapb + ;; Processor type -- this attribute must exactly match the processor_type ;; enumeration in alpha.h. @@ -343,27 +360,47 @@ ; ??? The FPU communicates with memory and the integer register file ; via two fp store units. We need a slot in the fst immediately, and ; a slot in LOW after the operand data is ready. At which point the -; data may be movedeither to the store queue or the integer register +; data may be moved either to the store queue or the integer register ; file and the insn retired. ;; First define the arithmetic insns. Note that the 32-bit forms also ;; sign-extend. -;; Note that we can do sign extensions in both FP and integer registers. -;; However, the result must be in the same type of register as the input. -;; The register preferencing code can't handle this case very well, so, for -;; now, don't let the FP case show up here for preferencing. Also, -;; sign-extends in FP registers take two instructions. +;; Handle 32-64 bit extension from memory to a floating point register +;; specially, since this ocurrs frequently in int->double conversions. +;; This is done with a define_split after reload converting the plain +;; sign-extension into a load+unspec, which of course results in lds+cvtlq. +;; +;; Note that while we must retain the =f case in the insn for reload's +;; benefit, it should be eliminated after reload, so we should never emit +;; code for that case. But we don't reject the possibility. + (define_insn "extendsidi2" - [(set (match_operand:DI 0 "register_operand" "=r,r,*f") - (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,*f")))] + [(set (match_operand:DI 0 "register_operand" "=r,r,?f") + (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "r,m,m")))] "" "@ addl %1,$31,%0 ldl %0,%1 - cvtql %1,%0\;cvtlq %0,%0" - [(set_attr "type" "iadd,ild,fadd")]) + lds %0,%1\;cvtlq %0,%0" + [(set_attr "type" "iadd,ild,fld")]) + +;; Due to issues with CLASS_CANNOT_CHANGE_SIZE, we cannot use a subreg here. +(define_split + [(set (match_operand:DI 0 "hard_fp_register_operand" "") + (sign_extend:DI (match_operand:SI 1 "memory_operand" "")))] + "reload_completed" + [(set (match_dup 2) (match_dup 1)) + (set (match_dup 0) (unspec:DI [(match_dup 2)] 4))] + "operands[2] = gen_rtx_REG (SImode, REGNO (operands[0]));") + +(define_insn "" + [(set (match_operand:DI 0 "register_operand" "=f") + (unspec:DI [(match_operand:SI 1 "register_operand" "f")] 4))] + "" + "cvtlq %1,%0" + [(set_attr "type" "fadd")]) ;; Do addsi3 the way expand_binop would do if we didn't have one. This ;; generates better code. We have the anonymous addsi3 pattern below in @@ -5122,7 +5159,7 @@ ;; by alpha_reorg. (define_insn "trapb" - [(unspec_volatile [(const_int 0)] 3)] + [(unspec_volatile [(const_int 0)] 4)] "" "trapb" [(set_attr "type" "misc")]) diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c index b5f4ace..43e5264 100644 --- a/gcc/haifa-sched.c +++ b/gcc/haifa-sched.c @@ -8234,8 +8234,7 @@ split_block_insns (b) for (insn = basic_block_head[b];; insn = next) { - rtx prev; - rtx set; + rtx set, last, first, notes; /* Can't use `next_real_insn' because that might go across CODE_LABELS and short-out basic blocks. */ @@ -8272,31 +8271,24 @@ split_block_insns (b) } /* Split insns here to get max fine-grain parallelism. */ - prev = PREV_INSN (insn); - /* It is probably not worthwhile to try to split again in - the second pass. However, if flag_schedule_insns is not set, - the first and only (if any) scheduling pass is after reload. */ - if (reload_completed == 0 || ! flag_schedule_insns) + first = PREV_INSN (insn); + notes = REG_NOTES (insn); + last = try_split (PATTERN (insn), insn, 1); + if (last != insn) { - rtx last, first = PREV_INSN (insn); - rtx notes = REG_NOTES (insn); - last = try_split (PATTERN (insn), insn, 1); - if (last != insn) + /* try_split returns the NOTE that INSN became. */ + first = NEXT_INSN (first); + update_flow_info (notes, first, last, insn); + + PUT_CODE (insn, NOTE); + NOTE_SOURCE_FILE (insn) = 0; + NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; + if (insn == basic_block_head[b]) + basic_block_head[b] = first; + if (insn == basic_block_end[b]) { - /* try_split returns the NOTE that INSN became. */ - first = NEXT_INSN (first); - update_flow_info (notes, first, last, insn); - - PUT_CODE (insn, NOTE); - NOTE_SOURCE_FILE (insn) = 0; - NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; - if (insn == basic_block_head[b]) - basic_block_head[b] = first; - if (insn == basic_block_end[b]) - { - basic_block_end[b] = last; - break; - } + basic_block_end[b] = last; + break; } } |