]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
ns32k.md (movdi): Use "l" instead of "f" to match all registers capable of holding...
authorIan Dall <ian@sibyl.beware.dropbear.id.au>
Fri, 20 Dec 2002 18:14:18 +0000 (18:14 +0000)
committerRichard Henderson <rth@gcc.gnu.org>
Fri, 20 Dec 2002 18:14:18 +0000 (10:14 -0800)
        * config/ns32k/ns32k.md (movdi): Use "l" instead of "f" to match
        all registers capable of holding a double float.
        (*rcond): change name of "reverse branch" insns to
        something more meaningful.
        (*rbgt, *rblt, *rbge, *rble): Reverse branches to handle IEEE
        comparisons properly.
        (*ffs): Change operand 0 from write to read-modify-write.
        (*ffsssi2): Drop constraints from define_expand.

        * config/ns32k/ns32k.h (STORE_RATIO, STORE_BY_PIECES): Avoid using
        MOVE_RATIO as default for store operations.

        * config/ns32k/ns32k.h (enum reg_class, REG_CLASS_NAMES): Add
        LONG_REGS class.
        (CANNOT_CHANGE_MODE_CLASS): Can't subreg LONG_REGS.
        (GO_IF_LEGITIMATE_ADDRESS): Remove spurious abort().
        * config/ns32k/ns32k.c (regclass_map): Add LONG_REGS class.

        * config/ns32k/STATUS: New File
        * config/ns32k/NOTES: New file.

From-SVN: r60370

gcc/ChangeLog
gcc/config/ns32k/NOTES [new file with mode: 0644]
gcc/config/ns32k/STATUS [new file with mode: 0644]
gcc/config/ns32k/ns32k.c
gcc/config/ns32k/ns32k.h
gcc/config/ns32k/ns32k.md

index 44abb608a77b0ad6b900057e65d028d769e06107..03ec274bb7e64791c0d81ea4dec9f7de6d73c42d 100644 (file)
@@ -1,3 +1,26 @@
+2002-12-20  Ian Dall  <ian@sibyl.beware.dropbear.id.au>
+
+        * config/ns32k/ns32k.md (movdi): Use "l" instead of "f" to match
+        all registers capable of holding a double float.
+        (*rcond): change name of "reverse branch" insns to
+        something more meaningful.
+        (*rbgt, *rblt, *rbge, *rble): Reverse branches to handle IEEE
+        comparisons properly.
+        (*ffs): Change operand 0 from write to read-modify-write.
+        (*ffsssi2): Drop constraints from define_expand.
+
+        * config/ns32k/ns32k.h (STORE_RATIO, STORE_BY_PIECES): Avoid using
+        MOVE_RATIO as default for store operations.
+
+        * config/ns32k/ns32k.h (enum reg_class, REG_CLASS_NAMES): Add
+        LONG_REGS class.
+        (CANNOT_CHANGE_MODE_CLASS): Can't subreg LONG_REGS.
+        (GO_IF_LEGITIMATE_ADDRESS): Remove spurious abort().
+        * config/ns32k/ns32k.c (regclass_map): Add LONG_REGS class.
+
+        * config/ns32k/STATUS: New File
+        * config/ns32k/NOTES: New file.
+
 2002-12-20  Hartmut Penner  <hpenner@de.ibm.com>
        
                * doc/invoke.texi: Document -mzarch, -mesa, -mcpu= and -march=
diff --git a/gcc/config/ns32k/NOTES b/gcc/config/ns32k/NOTES
new file mode 100644 (file)
index 0000000..4688246
--- /dev/null
@@ -0,0 +1,97 @@
+Copyright (C) 2002
+Free Software Foundation, Inc.
+
+                        Implementation Notes
+                        ====================
+
+IEEE floating point comparisons
+
+Ian Dall <ian@beware.dropbear.id.au>
+------------------------------------
+
+The ns32x81 fpu handles most operands in hardware, but traps on NaN,
+Inf and Denormalized numbers. The correct behaviour can be handled by
+the trap handler. This is mostly transparent to the compiler, but in
+the case of floating point comparisions, the trap handler and the
+compiler must co-operate.
+
+Comparing a Nan with anything (including another Nan) is an unordered
+comparison and a NE test should be true and any other test should be
+false. There is nothing the trap handler can do to the condition codes
+to make, for example ble and bgt (the machine instructions, not the
+gcc insn's) both fail.
+
+The L flag (normally used for unsigned comparisons) is cleared by a floating
+point compare. So, it is possible for the trap handler to communicate that
+it has seen a NaN by setting this flag.
+
+This can get confusing so the following documents the reasoning. There
+are only 3 flags of significance, N, Z and L. In what follows AB is
+the conjunction of A and B ("and") A+B is the disjunction of A and B
+("or"), upper case represents true and lower case represents false. So
+"Zl" is "Z AND (NOT L)".
+
+Also, we can require that the trap handler clears N and Z, whenever it
+sets L. This means that in many cases, we do not need to test if L is
+set or clear. The operations we require are:
+
+       Operator        Expression      Check L
+       GT              Nl              No
+       LT              znl             Yes
+       GE              (Z+N)l          No
+       LE              nl              Yes
+       EQ              Zl              No
+       NE              z+L             No
+
+
+For example, the emitted code for the case of LT is
+
+         bhi 0f
+         blt %0
+       0:
+
+which is, in effect, "branch if ordered and less than."
+
+We also need insns for the reverse branches. These have the PC and
+the label ref opereands reversed. Thus the reverse bgt has a pattern:
+
+ (set (pc)
+       (if_then_else (gt (cc0)
+                         (const_int 0))
+                     (pc)
+                     (label_ref (match_operand 0 "" ""))))
+
+This is identical to a normal branch with the test complimented:
+
+ (set (pc)
+       (if_then_else (not (gt (cc0)
+                         (const_int 0)))
+                     (label_ref (match_operand 0 "" "")
+                     (pc))))
+
+Thus we need a family of (NOT cond) tests. For integers this is easy,
+a reverse blt becomes bge. However, the possibility of unordered
+comparison complicates the floating point case. So, we need to
+compliment the above expressions, using deMorgan's theorem, for the reverse
+branch:
+
+       Operator        Expression      Check L
+       RGT             n+L             Yes
+       RLT             Z+N+L           Yes
+       RGE             zn+L            Yes
+       RLE             N+L             Yes
+       REQ             z+L             No
+       RNE             Zl              No
+
+For example the emitted code for the case of RLT is
+
+   bge %0
+   bhi %0
+
+which is, in effect "branch if not less than and not unordered."
+
+These extra comparisions are safe if the trap handler doesn't set the
+L flag, since in that case the additional "bhi" instructions are never
+taken. Also, these extra branch instructions are controlled by the
+"-mieee-compare" option.
+
diff --git a/gcc/config/ns32k/STATUS b/gcc/config/ns32k/STATUS
new file mode 100644 (file)
index 0000000..2754bf1
--- /dev/null
@@ -0,0 +1,68 @@
+NS32K Port Status      Last updated 19 Dec 2002
+
+Recent development of the ns32k port has been as a cross compiler. As
+such a native bootstrap has not been performed.  Currently the
+compiler successfully builds a NetBSD kernel and has been tested on
+the testsuite with "make check" configured to remotely execute
+tests on a pc532-netbsd.
+
+There are a few remaining failures in the testsuite, none of which
+result in incorrect code generation or unexpected ICEs.
+
+Here follows comments on the outstanding testsuite failures:
+
+gcc.c-torture/compile/20001226-1.c,  -Os
+This typically fails due to a time out or exhausting available memory.
+In the past it has been found to eventually compile in under 6
+minutes, with consuming up to 90MB. The timeout in dejagnu is 5
+minutes.
+
+gcc.c-torture/execute/builtin-constant.c
+I don't understand why this fails. Looking at the generated assembler,
+the first invocation of btest returns "1" and the second "0". Presumably
+the flow analysis is meant to indicate this is a "builtin constant".
+The documentation for __builtin_constant says it is allowed to fail if the
+compiler can't deduce that something is a constant, so the compiler is
+correct if not ideal.
+
+gcc.dg/debug/debug-1.c scan-assembler xyzzy:
+At -O3 level of optimization, variable xyzzy gets eliminated. Isn't it
+reasonable that the debugging info is gone too? Indeed, the
+documentation says this is expected behaviour.
+
+gcc.dg/debug/debug-2.c scan-assembler xyzzy:
+As for the above.
+
+gcc.dg/20010912-1.c
+PIC is supported for the compiler, but we get a link error until we get a
+cross linker which can handle dynamic linking.
+
+gcc.dg/20020304-1.c -O -fssa -fssa-ccp
+ICE -fssa and -fssa-ccp are "experimental" options. Assume not a
+backend problem.
+
+gcc.dg/20021014-1.c (test for excess errors)
+This is a test of the "-p" option. Fails due to lack of mcrt0.o. This
+platform support "-pg" but not "-p"
+
+gcc.dg/20021018-1.c (test for excess errors)
+Fail due to lack of dynamic link support at link time.
+
+gcc.dg/bitfld-3.c (test for excess errors)
+Execution passes, but compilation produces excessive warnings. These warnings
+actually seem reasonable. The code uses __attribute__((aligned (8)), and
+the maximum alignment which makes any sense for this architecture is 4.
+
+gcc.dg/duff-2.c (test for excess errors)
+Execution passes, but compilation produces excessive warnings. Doesn't look
+like a backend problem.
+
+gcc.dg/uninit-A.c -O2 -Wall -S
+Bogus warnings, almost certainly not backend.
+
+gcc.dg/special/weak-1.c execution test
+X  This fails for i386 too. I don't understand what the correct behaviour
+for this test is.
+
+gcc.dg/special/gcsec-1.c (test for excess errors)
+a.out deficiency. -ffunction-sections and -fdata-sections not supported.
index fba27cf8604e9996a70a017b97085274971db2b6..4e861132fcb56647d0884985407337bb354416df 100644 (file)
@@ -57,8 +57,8 @@ const enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
   GENERAL_REGS, GENERAL_REGS, GENERAL_REGS, GENERAL_REGS,
   FLOAT_REG0, LONG_FLOAT_REG0, FLOAT_REGS, FLOAT_REGS,
   FLOAT_REGS, FLOAT_REGS, FLOAT_REGS, FLOAT_REGS,
-  FP_REGS, FP_REGS, FP_REGS, FP_REGS,
-  FP_REGS, FP_REGS, FP_REGS, FP_REGS,
+  LONG_REGS, LONG_REGS, LONG_REGS, LONG_REGS,
+  LONG_REGS, LONG_REGS, LONG_REGS, LONG_REGS,
   FRAME_POINTER_REG, STACK_POINTER_REG
 };
 
index ba53a6fc28d42562cba41d47aa56d5bc5c42d765..8e648989fb158d4cc36d7d86f1565cebb1297c73 100644 (file)
@@ -435,17 +435,17 @@ while (0)
 
 enum reg_class
 { NO_REGS, GENERAL_REGS, FLOAT_REG0, LONG_FLOAT_REG0, FLOAT_REGS,
-  FP_REGS, GEN_AND_FP_REGS, FRAME_POINTER_REG, STACK_POINTER_REG,
-  GEN_AND_MEM_REGS, ALL_REGS, LIM_REG_CLASSES };
+  LONG_REGS, FP_REGS, GEN_AND_FP_REGS, FRAME_POINTER_REG,
+  STACK_POINTER_REG, GEN_AND_MEM_REGS, ALL_REGS, LIM_REG_CLASSES };
 
 #define N_REG_CLASSES (int) LIM_REG_CLASSES
 
 /* Give names of register classes as strings for dump file.   */
 
-#define REG_CLASS_NAMES \
+#define REG_CLASS_NAMES                                                            \
  {"NO_REGS", "GENERAL_REGS", "FLOAT_REG0", "LONG_FLOAT_REG0", "FLOAT_REGS", \
-  "FP_REGS", "GEN_AND_FP_REGS", "FRAME_POINTER_REG", "STACK_POINTER_REG", \
-  "GEN_AND_MEM_REGS", "ALL_REGS" }
+  "LONG_REGS", "FP_REGS", "GEN_AND_FP_REGS", "FRAME_POINTER_REG",          \
+  "STACK_POINTER_REG", "GEN_AND_MEM_REGS", "ALL_REGS" }
 
 /* Define which registers fit in which classes.
    This is an initializer for a vector of HARD_REG_SET
@@ -457,6 +457,7 @@ enum reg_class
         {0x100},               /* FLOAT_REG0 */        \
         {0x300},               /* LONG_FLOAT_REG0 */   \
         {0xff00},              /* FLOAT_REGS */        \
+         {0xff0000},            /* LONG_REGS */         \
          {0xffff00},           /* FP_REGS */           \
          {0xffffff},           /* GEN_AND_FP_REGS */   \
          {0x1000000},          /* FRAME_POINTER_REG */ \
@@ -469,6 +470,13 @@ enum reg_class
    ((ns32k_reg_class_contents[CLASS1][0]               \
      & ~ns32k_reg_class_contents[CLASS2][0]) == 0)
 
+
+/* LONG_REGS are registers which can only hold double precision floats
+ * and can only be accessable by long float instructions.
+ */
+#define CANNOT_CHANGE_MODE_CLASS(FROM, TO) \
+  (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) ? LONG_REGS : NO_REGS)
+
 /* The same information, inverted:
    Return the class number of the smallest class containing
    reg number REGNO.  This could be a conditional expression
@@ -1052,7 +1060,6 @@ __transfer_from_trampoline ()             \
   else if (GET_CODE (xfooy) == PRE_DEC)                                        \
     {                                                                  \
       if (REGNO (XEXP (xfooy, 0)) == STACK_POINTER_REGNUM) goto ADDR;  \
-      else abort ();                                                   \
     }                                                                  \
 }
 
@@ -1123,6 +1130,11 @@ __transfer_from_trampoline ()            \
    We have a smart movstrsi insn */
 #define MOVE_RATIO 0
 
+#define STORE_RATIO (optimize_size ? 3 : 15)
+#define STORE_BY_PIECES_P(SIZE, ALIGN) \
+  (move_by_pieces_ninsns (SIZE, ALIGN) < (unsigned int) STORE_RATIO)
+
+
 /* Nonzero if access to memory by bytes is slow and undesirable.  */
 #define SLOW_BYTE_ACCESS 0
 
index 5d93b53d5f4ea516d4d50277e41e6320bd423d9b..218686117b4267826c920f2be411bc00652b93a6 100644 (file)
@@ -1,5 +1,5 @@
 ;;- Machine description for GNU compiler, ns32000 Version
-;;  Copyright (C) 1988, 1994, 1996, 1998, 1999, 2000, 2001
+;;  Copyright (C) 1988, 1994, 1996, 1998, 1999, 2000, 2001, 2002
 ;;  Free Software Foundation, Inc.
 ;;  Contributed by Michael Tiemann (tiemann@cygnus.com)
 
   "movmd %1,%0,4")
 
 (define_insn "movdi"
-  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm<,*f,rm")
-       (match_operand:DI 1 "general_operand" "gF,g,*f"))]
+  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm<,*l,rm")
+       (match_operand:DI 1 "general_operand" "gF,g,*l"))]
   ""
   "*
 {
   ""
   "bls %l0")
 \f
-;; "Reversed" jump instructions. Are these ever generated?
+;; "Reversed" jump instructions.
 
-(define_insn "*bne"
+(define_insn "*rbeq"
   [(set (pc)
        (if_then_else (eq (cc0)
                          (const_int 0))
     return \"bfs %l0\";
   else if (cc_prev_status.flags & CC_Z_IN_NOT_F)
     return \"bfc %l0\";
-  else return \"bne %l0\";
+  else
+    return \"bne %l0\";
 }")
 
-(define_insn "*beq"
+(define_insn "*rbne"
   [(set (pc)
        (if_then_else (ne (cc0)
                          (const_int 0))
   else return \"beq %l0\";
 }")
 
-(define_insn "*ble"
+(define_insn "*rbgt"
   [(set (pc)
        (if_then_else (gt (cc0)
                          (const_int 0))
   "*
 {
     if (cc_prev_status.flags & CC_UNORD)
-      return \"bhi 0f\;ble %l0\;0:\";
+      return \"ble %l0\;bhi %l0\";
     else
       return \"ble %l0\";
 }")
 
-(define_insn "*bleu"
+(define_insn "*rbgtu"
   [(set (pc)
        (if_then_else (gtu (cc0)
                           (const_int 0))
   ""
   "bls %l0")
 
-(define_insn "*bge"
+(define_insn "*rblt"
   [(set (pc)
        (if_then_else (lt (cc0)
                          (const_int 0))
                      (pc)
                      (label_ref (match_operand 0 "" ""))))]
   ""
-  "bge %l0")
+   "*
+{
+    if (cc_prev_status.flags & CC_UNORD)
+      return \"bge %l0\;bhi %l0\";
+    else
+      return \"bge %l0\";
+}")
 
-(define_insn "*bgeu"
+(define_insn "*rbltu"
   [(set (pc)
        (if_then_else (ltu (cc0)
                           (const_int 0))
   ""
   "bhs %l0")
 
-(define_insn "*blt"
+(define_insn "*rbge"
   [(set (pc)
        (if_then_else (ge (cc0)
                          (const_int 0))
   "*
 {
     if (cc_prev_status.flags & CC_UNORD)
-      return \"bhi 0f\;blt %l0\;0:\";
+      return \"blt %l0\;bhi %l0\";
     else
       return \"blt %l0\";
 }")
 
-(define_insn "*bltu"
+(define_insn "*rbgeu"
   [(set (pc)
        (if_then_else (geu (cc0)
                           (const_int 0))
   ""
   "blo %l0")
 
-(define_insn "*bgt"
+(define_insn "*rble"
   [(set (pc)
        (if_then_else (le (cc0)
                          (const_int 0))
                      (pc)
                      (label_ref (match_operand 0 "" ""))))]
   ""
-  "bgt %l0")
+  "*
+{
+    if (cc_prev_status.flags & CC_UNORD)
+      return \"bgt %l0\;bhi %l0\";
+    else
+      return \"bgt %l0\";
+}")
 
-(define_insn "*bgtu"
+(define_insn "*rbleu"
   [(set (pc)
        (if_then_else (leu (cc0)
                           (const_int 0))
 ;; ffs instructions
 
 (define_insn "*ffs"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=ro")
+  [(set (match_operand:SI 0 "nonimmediate_operand" "+ro")
        (minus:SI 
                (plus:SI (ffs:SI (zero_extract:SI 
                                (match_operand:SI 1 "general_operand" "g") 
                        (match_dup 0)) 
                (const_int 1)))]
   ""
-  "ffsd %1,%0; bfc 1f; addqd %$-1,%0; 1:")
+  "ffsd %1,%0\;bfc 1f\;addqd %$-1,%0\;1:")
 
 (define_expand "ffssi2"
-  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") (const_int 0))
+  [(set (match_operand:SI 0 "nonimmediate_operand" "") (const_int 0))
    (set (match_dup 0)
        (minus:SI 
                (plus:SI (ffs:SI (zero_extract:SI