Commit 8056c5f2 by Ian Dall Committed by Richard Henderson

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
parent 4639c5c6
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=
......
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.
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.
......@@ -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
};
......
......@@ -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
......
;;- 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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment