haifa-sched.c (split_block_insns): Don't supress insn splitting on subsequent passes.
authorRichard Henderson <rth@cygnus.com>
Sat, 4 Apr 1998 13:54:32 +0000 (05:54 -0800)
committerRichard Henderson <rth@gcc.gnu.org>
Sat, 4 Apr 1998 13:54:32 +0000 (05:54 -0800)
* 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

gcc/ChangeLog
gcc/config/alpha/alpha.c
gcc/config/alpha/alpha.h
gcc/config/alpha/alpha.md
gcc/haifa-sched.c

index 0db3735329db7018efd8c4c2698d4cc711b0abc5..6f36affcdc08233392577571c6b17fceb025b33c 100644 (file)
@@ -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
index b92658699956203d76e4c3e02e6e1c1f8abb5fd3..3888b984ccd56f93fdfa7eceb9d8ca5528488de6 100644 (file)
@@ -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.  */
 
 
index a2f76aa7a9c635c5dd1d796cba22f35e616c3493..da8f6968159dbdbba0f311941da681c2cfa6ff69 100644 (file)
@@ -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}},
 \f
 /* Tell collect that the object format is ECOFF.  */
 #define OBJECT_FORMAT_COFF
index 1dd05ea03fbd673c044c9971ae040296c4b96bb4..93f7e5f3bad4da410159c04d04ceaa6e548ef92b 100644 (file)
 ;; 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
+
 \f
 ;; Processor type -- this attribute must exactly match the processor_type
 ;; enumeration in alpha.h.
 ; ??? 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.
 
 \f
 ;; 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
 ;; by alpha_reorg.
 
 (define_insn "trapb"
-  [(unspec_volatile [(const_int 0)] 3)]
+  [(unspec_volatile [(const_int 0)] 4)]
   ""
   "trapb"
   [(set_attr "type" "misc")])
index b5f4ace1aaf5f16d6a4da052efe948f7ca2f17dd..43e5264d0848bff2d6d11c8790a573aebd08af5e 100644 (file)
@@ -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;
            }
        }