aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Henderson <rth@cygnus.com>1998-04-04 05:54:32 -0800
committerRichard Henderson <rth@gcc.gnu.org>1998-04-04 05:54:32 -0800
commit4ed43ff85a14916fd33bdf838f9c40b923e312ab (patch)
treefccd367314057d62ee9a166712156cd219f140ba /gcc
parent55a9eb72632155cf329d5307050e5b07087cd8ff (diff)
downloadgcc-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/ChangeLog11
-rw-r--r--gcc/config/alpha/alpha.c12
-rw-r--r--gcc/config/alpha/alpha.h3
-rw-r--r--gcc/config/alpha/alpha.md59
-rw-r--r--gcc/haifa-sched.c42
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;
}
}