*** empty log message ***
authorJim Wilson <wilson@gcc.gnu.org>
Tue, 14 Apr 1992 17:46:57 +0000 (10:46 -0700)
committerJim Wilson <wilson@gcc.gnu.org>
Tue, 14 Apr 1992 17:46:57 +0000 (10:46 -0700)
From-SVN: r742

gcc/c-lex.c
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.md
gcc/rtl.c
gcc/sched.c

index 07bdf039b1b613e708a19e933b6b6b54e75da4de..897cdec69efff29ff0160b0cfa58c0dcf699858e 100644 (file)
@@ -1613,7 +1613,8 @@ yylex ()
                else if (TREE_UNSIGNED (traditional_type)
                         != TREE_UNSIGNED (ansi_type))
                  warning ("integer constant is unsigned in ANSI C, signed with -traditional");
-               else abort ();
+               else
+                 warning ("width of integer constant may change on other systems with -traditional");
              }
 #endif
 
index 3b5b9c2497008e36acfe60b918b84735b7d19858..83a3a1a8a37c59b260976dfe89b556afe9b763a0 100644 (file)
@@ -1048,63 +1048,53 @@ output_move_double (operands)
       || (optype0 != REGOP && optype0 != CNSTOP && optype1 == REGOP
          && (REGNO (operands[1]) & 1) == 0))
     {
-      rtx op1, op2;
-      rtx base = 0, offset = const0_rtx;
+      rtx addr;
+      rtx base, offset;
 
-      /* OP1 gets the register pair, and OP2 gets the memory address.  */
       if (optype0 == REGOP)
-       op1 = operands[0], op2 = operands[1];
+       addr = operands[1];
       else
-       op1 = operands[1], op2 = operands[0];
+       addr = operands[0];
 
-      /* Now see if we can trust the address to be 8-byte aligned.  */
-      /* Trust double-precision floats in global variables.  */
+      /* Now see if we can trust the address to be 8-byte aligned.
+        Trust double-precision floats in global variables.  */
 
-      if (GET_CODE (XEXP (op2, 0)) == LO_SUM && GET_MODE (op2) == DFmode)
-       {
-         if (final_sequence)
-           abort ();
-         return (op1 == operands[0] ? "ldd %1,%0" : "std %1,%0");
-       }
+      if (GET_CODE (XEXP (addr, 0)) == LO_SUM && GET_MODE (addr) == DFmode)
+       return (addr == operands[1] ? "ldd %1,%0" : "std %1,%0");
 
-      if (GET_CODE (XEXP (op2, 0)) == PLUS)
+      base = 0;
+      if (GET_CODE (XEXP (addr, 0)) == PLUS)
        {
-         rtx temp = XEXP (op2, 0);
-         if (GET_CODE (XEXP (temp, 0)) == REG)
+         rtx temp = XEXP (addr, 0);
+         if (GET_CODE (XEXP (temp, 0)) == REG
+             && GET_CODE (XEXP (temp, 1)) == CONST_INT)
            base = XEXP (temp, 0), offset = XEXP (temp, 1);
-         else if (GET_CODE (XEXP (temp, 1)) == REG)
-           base = XEXP (temp, 1), offset = XEXP (temp, 0);
        }
+      else if (GET_CODE (XEXP (addr, 0)) == REG)
+       base = XEXP (addr, 0), offset = const0_rtx;
 
-      /* Trust round enough offsets from the stack or frame pointer.  */
+      /* Trust round enough offsets from the stack or frame pointer.
+        If TARGET_HOPE_ALIGN, trust round enough offset from any register
+        for DFmode loads.  If it is obviously unaligned, don't ever
+        generate ldd or std.  */
       if (base
          && (REGNO (base) == FRAME_POINTER_REGNUM
-             || REGNO (base) == STACK_POINTER_REGNUM))
+             || REGNO (base) == STACK_POINTER_REGNUM
+             || (TARGET_HOPE_ALIGN && GET_MODE (addr) == DFmode)))
        {
-         if (GET_CODE (offset) == CONST_INT
-             && (INTVAL (offset) & 0x7) == 0)
-           {
-             if (op1 == operands[0])
-               return "ldd %1,%0";
-             else
-               return "std %1,%0";
-           }
+         if ((INTVAL (offset) & 0x7) == 0)
+           return (addr == operands[1] ? "ldd %1,%0" : "std %1,%0");
        }
       /* We know structs not on the stack are properly aligned.  Since a
         double asks for 8-byte alignment, we know it must have got that
         if it is in a struct.  But a DImode need not be 8-byte aligned,
-        because it could be a struct containing two ints or pointers.  */
-      else if (GET_CODE (operands[1]) == MEM
-              && GET_MODE (operands[1]) == DFmode
-              && (CONSTANT_P (XEXP (operands[1], 0))
-                  /* Let user ask for it anyway.  */
-                  || TARGET_HOPE_ALIGN))
-       return "ldd %1,%0";
-      else if (GET_CODE (operands[0]) == MEM
-              && GET_MODE (operands[0]) == DFmode
-              && (CONSTANT_P (XEXP (operands[0], 0))
-                  || TARGET_HOPE_ALIGN))
-       return "std %1,%0";
+        because it could be a struct containing two ints or pointers.
+        Hence, a constant DFmode address will always be 8-byte aligned.
+        If TARGET_HOPE_ALIGN, then assume all doubles are aligned even if this
+        is not a constant address.  */
+      else if (GET_CODE (addr) == MEM && GET_MODE (addr) == DFmode
+              && (CONSTANT_P (addr) || TARGET_HOPE_ALIGN))
+       return (addr == operands[1] ? "ldd %1,%0" : "std %1,%0");
     }
 
   if (optype0 == REGOP && optype1 == REGOP
@@ -1159,6 +1149,9 @@ output_move_double (operands)
   return "";
 }
 \f
+/* Output assembler code to perform a doubleword move insn with perands
+   OPERANDS, one of which must be a floating point register.  */
+
 char *
 output_fp_move_double (operands)
      rtx *operands;
@@ -1169,35 +1162,15 @@ output_fp_move_double (operands)
     {
       if (FP_REG_P (operands[1]))
        return "fmovs %1,%0\n\tfmovs %R1,%R0";
-      if (GET_CODE (operands[1]) == REG)
+      else if (GET_CODE (operands[1]) == REG)
        {
          if ((REGNO (operands[1]) & 1) == 0)
            return "std %1,[%@-8]\n\tldd [%@-8],%0";
          else
            return "st %R1,[%@-4]\n\tst %1,[%@-8]\n\tldd [%@-8],%0";
        }
-      addr = XEXP (operands[1], 0);
-
-      /* Use ldd if known to be aligned.  */
-      if (TARGET_HOPE_ALIGN
-         || (GET_CODE (addr) == PLUS
-             && (((XEXP (addr, 0) == frame_pointer_rtx
-                   || XEXP (addr, 0) == stack_pointer_rtx)
-                  && GET_CODE (XEXP (addr, 1)) == CONST_INT
-                  && (INTVAL (XEXP (addr, 1)) & 0x7) == 0)
-                 /* Arrays are known to be aligned,
-                    and reg+reg addresses are used (on this machine)
-                    only for array accesses.  */
-                 || (REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1)))))
-         || (GET_MODE (operands[0]) == DFmode
-             && (GET_CODE (addr) == LO_SUM || CONSTANT_P (addr))))
-       return "ldd %1,%0";
-
-      /* Otherwise use two ld insns.  */
-      operands[2]
-       = gen_rtx (MEM, GET_MODE (operands[1]),
-                  plus_constant_for_output (addr, 4));
-       return "ld %1,%0\n\tld %2,%R0";
+      else
+       return output_move_double (operands);
     }
   else if (FP_REG_P (operands[1]))
     {
@@ -1208,28 +1181,8 @@ output_fp_move_double (operands)
          else
            return "std %1,[%@-8]\n\tld [%@-4],%R0\n\tld [%@-8],%0";
        }
-      addr = XEXP (operands[0], 0);
-
-      /* Use std if we can be sure it is well-aligned.  */
-      if (TARGET_HOPE_ALIGN
-         || (GET_CODE (addr) == PLUS
-             && (((XEXP (addr, 0) == frame_pointer_rtx
-                   || XEXP (addr, 0) == stack_pointer_rtx)
-                  && GET_CODE (XEXP (addr, 1)) == CONST_INT
-                  && (INTVAL (XEXP (addr, 1)) & 0x7) == 0)
-                 /* Arrays are known to be aligned,
-                    and reg+reg addresses are used (on this machine)
-                    only for array accesses.  */
-                 || (REG_P (XEXP (addr, 0)) && REG_P (XEXP (addr, 1)))))
-         || (GET_MODE (operands[1]) == DFmode
-             && (GET_CODE (addr) == LO_SUM || CONSTANT_P (addr))))
-       return "std %1,%0";
-
-      /* Otherwise use two st insns.  */
-      operands[2]
-       = gen_rtx (MEM, GET_MODE (operands[0]),
-                  plus_constant_for_output (addr, 4));
-      return "st %r1,%0\n\tst %R1,%2";
+      else
+       return output_move_double (operands);
     }
   else abort ();
 }
index 2aa19e616d2655b23a9170b07ec7006764b3d8f4..2693c171205d18da2afdf6255badaaf4c482f842 100644 (file)
 }"
   [(set_attr "type" "fp")
    (set_attr "length" "3")])
+
+;; Allow combiner to combine a fix_truncdfsi2 with a floatsidf2
+;; This eliminates 2 useless instructions.
+;; The first one matches if the fixed result is needed.  The second one
+;; matches if the fixed result is not needed.
+
+(define_insn ""
+  [(set (match_operand:DF 0 "general_operand" "=f")
+       (float:DF (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm")))))
+   (set (match_operand:SI 2 "general_operand" "=rm")
+       (fix:SI (fix:DF (match_dup 1))))]
+  ""
+  "*
+{
+  if (FP_REG_P (operands[1]))
+    output_asm_insn (\"fdtoi %1,%0\", operands);
+  else
+    {
+      output_asm_insn (output_fp_move_double (operands), operands);
+      output_asm_insn (\"fdtoi %0,%0\", operands);
+    }
+  if (GET_CODE (operands[2]) == MEM)
+    return \"st %0,%2\;fitod %0,%0\";
+  else
+    return \"st %0,[%%fp-4]\;fitod %0,%0\;ld [%%fp-4],%2\";
+}"
+  [(set_attr "type" "fp")
+   (set_attr "length" "5")])
+
+(define_insn ""
+  [(set (match_operand:DF 0 "general_operand" "=f")
+       (float:DF (fix:SI (fix:DF (match_operand:DF 1 "general_operand" "fm")))))]
+  ""
+  "*
+{
+  if (FP_REG_P (operands[1]))
+    output_asm_insn (\"fdtoi %1,%0\", operands);
+  else
+    {
+      output_asm_insn (output_fp_move_double (operands), operands);
+      output_asm_insn (\"fdtoi %0,%0\", operands);
+    }
+  return \"fitod %0,%0\";
+}"
+  [(set_attr "type" "fp")
+   (set_attr "length" "3")])
+
+;; Allow combiner to combine a fix_truncsfsi2 with a floatsisf2
+;; This eliminates 2 useless instructions.
+;; The first one matches if the fixed result is needed.  The second one
+;; matches if the fixed result is not needed.
+
+(define_insn ""
+  [(set (match_operand:SF 0 "general_operand" "=f")
+       (float:SF (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm")))))
+   (set (match_operand:SI 2 "general_operand" "=rm")
+       (fix:SI (fix:SF (match_dup 1))))]
+  ""
+  "*
+{
+  if (FP_REG_P (operands[1]))
+    output_asm_insn (\"fstoi %1,%0\", operands);
+  else
+    output_asm_insn (\"ld %1,%0\;fstoi %0,%0\", operands);
+  if (GET_CODE (operands[2]) == MEM)
+    return \"st %0,%2\;fitos %0,%0\";
+  else
+    return \"st %0,[%%fp-4]\;fitos %0,%0\;ld [%%fp-4],%2\";
+}"
+  [(set_attr "type" "fp")
+   (set_attr "length" "5")])
+
+(define_insn ""
+  [(set (match_operand:SF 0 "general_operand" "=f")
+       (float:SF (fix:SI (fix:SF (match_operand:SF 1 "general_operand" "fm")))))]
+  ""
+  "*
+{
+  if (FP_REG_P (operands[1]))
+    output_asm_insn (\"fstoi %1,%0\", operands);
+  else
+    output_asm_insn (\"ld %1,%0\;fstoi %0,%0\", operands);
+  return \"fitos %0,%0\";
+}"
+  [(set_attr "type" "fp")
+   (set_attr "length" "3")])
 \f
 ;;- arithmetic instructions
 
index b82e5f139688d0869f39af167840181618c7bd99..dee61522db3da864604b075dca6fd0b3d407324b 100644 (file)
--- a/gcc/rtl.c
+++ b/gcc/rtl.c
@@ -383,21 +383,39 @@ add_dependence (insn, elem, dep_type)
      rtx elem;
      enum reg_note dep_type;
 {
-  rtx link;
+  rtx link, next;
 
   /* Don't depend an insn on itself.  */
   if (insn == elem)
     return;
 
   /* If elem is part of a sequence that must be scheduled together, then
-     make the dependence point to the last insn of the sequence.  */
-  if (NEXT_INSN (elem) && SCHED_GROUP_P (NEXT_INSN (elem)))
+     make the dependence point to the last insn of the sequence.
+     When HAVE_cc0, it is possible for NOTEs to exist between users and
+     setters of the condition codes, so we must skip past notes here.
+     Otherwise, NOTEs are impossible here.  */
+
+  next = NEXT_INSN (elem);
+
+#ifdef HAVE_cc0
+  while (next && GET_CODE (next) == NOTE)
+    next = NEXT_INSN (next);
+#endif
+
+  if (next && SCHED_GROUP_P (next))
     {
-      while (NEXT_INSN (elem) && SCHED_GROUP_P (NEXT_INSN (elem)))
-       elem = NEXT_INSN (elem);
-      /* Again, don't depend an insn of itself.  */
-      if (insn == elem)
+      /* Notes will never intervene here though, so don't bother checking
+        for them.  */
+      while (next && SCHED_GROUP_P (next))
+       next = NEXT_INSN (next);
+
+      /* Again, don't depend an insn on itself.  */
+      if (insn == next)
        return;
+
+      /* Make the dependence to NEXT, the last insn of the group, instead
+        of the original ELEM.  */
+      elem = next;
     }
 
   /* Check that we don't already have this dependence.  */
index 93e6a07d2f9a1956fa99587078511d252087457d..2a391e5c61698eae74f61d33a0b3df3cff216221 100644 (file)
@@ -1214,18 +1214,24 @@ sched_analyze_2 (x, insn)
 #ifdef HAVE_cc0
     case CC0:
       {
-       rtx link;
+       rtx link, prev;
 
-       /* User of CC0 depends on immediately preceding insn.
-          There may be a note before this insn now, but all notes will
+       /* There may be a note before this insn now, but all notes will
           be removed before we actually try to schedule the insns, so
-          it doesn't matter.  */
+          it won't cause a problem later.  We must avoid it here though.  */
+
+       /* User of CC0 depends on immediately preceding insn.
        SCHED_GROUP_P (insn) = 1;
 
-       /* Make a copy of all dependencies on PREV_INSN, and add to this insn.
-          This is so that all the dependencies will apply to the group.  */
+       /* Make a copy of all dependencies on the immediately previous insn,
+          and add to this insn.  This is so that all the dependencies will
+          apply to the group.  */
+
+       prev = PREV_INSN (insn);
+       while (GET_CODE (prev) == NOTE)
+         prev = PREV_INSN (prev);
 
-       for (link = LOG_LINKS (PREV_INSN (insn)); link; link = XEXP (link, 1))
+       for (link = LOG_LINKS (prev); link; link = XEXP (link, 1))
          add_dependence (insn, XEXP (link, 0), GET_MODE (link));
 
        return;