From: Ian Dall Date: Fri, 20 Dec 2002 18:14:18 +0000 (+0000) Subject: ns32k.md (movdi): Use "l" instead of "f" to match all registers capable of holding... X-Git-Tag: releases/gcc-3.4.0~9866 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8056c5f22194f598f64b465121aa5906cf61fef9;p=thirdparty%2Fgcc.git ns32k.md (movdi): Use "l" instead of "f" to match all registers capable of holding a double float. * 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 44abb608a77b..03ec274bb7e6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,26 @@ +2002-12-20 Ian Dall + + * 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 * 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 index 000000000000..46882461d029 --- /dev/null +++ b/gcc/config/ns32k/NOTES @@ -0,0 +1,97 @@ +Copyright (C) 2002 +Free Software Foundation, Inc. + + Implementation Notes + ==================== + +IEEE floating point comparisons + +Ian Dall +------------------------------------ + +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 index 000000000000..2754bf1f07a3 --- /dev/null +++ b/gcc/config/ns32k/STATUS @@ -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. diff --git a/gcc/config/ns32k/ns32k.c b/gcc/config/ns32k/ns32k.c index fba27cf8604e..4e861132fcb5 100644 --- a/gcc/config/ns32k/ns32k.c +++ b/gcc/config/ns32k/ns32k.c @@ -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 }; diff --git a/gcc/config/ns32k/ns32k.h b/gcc/config/ns32k/ns32k.h index ba53a6fc28d4..8e648989fb15 100644 --- a/gcc/config/ns32k/ns32k.h +++ b/gcc/config/ns32k/ns32k.h @@ -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 diff --git a/gcc/config/ns32k/ns32k.md b/gcc/config/ns32k/ns32k.md index 5d93b53d5f4e..218686117b42 100644 --- a/gcc/config/ns32k/ns32k.md +++ b/gcc/config/ns32k/ns32k.md @@ -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) @@ -312,8 +312,8 @@ "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"))] "" "* { @@ -2378,9 +2378,9 @@ "" "bls %l0") -;; "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)) @@ -2392,10 +2392,11 @@ 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)) @@ -2410,7 +2411,7 @@ else return \"beq %l0\"; }") -(define_insn "*ble" +(define_insn "*rbgt" [(set (pc) (if_then_else (gt (cc0) (const_int 0)) @@ -2420,12 +2421,12 @@ "* { 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)) @@ -2434,16 +2435,22 @@ "" "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)) @@ -2452,7 +2459,7 @@ "" "bhs %l0") -(define_insn "*blt" +(define_insn "*rbge" [(set (pc) (if_then_else (ge (cc0) (const_int 0)) @@ -2462,12 +2469,12 @@ "* { 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)) @@ -2476,16 +2483,22 @@ "" "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)) @@ -2918,7 +2931,7 @@ ;; 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") @@ -2927,10 +2940,10 @@ (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